profile
viewpoint

arowser/google-reader-api 13

Unofficial Google Reader API

arowser/oreilly_android 2

This is the source code referenced in the O'Reilly Online Course: Developing Android Applications with Java. More information can be found here: http://training.oreilly.com/androidapps-java/

arowser/androidnews 1

An rss feader for Android.

arowser/kindlereader 1

Push your Google reader to your kindle

arowser/lightning-xchain-atomic-swap 1

Lightning Cross Chain Atomic Swap

arowser/omniwallet 1

add liteoin support for Mastercoin Hybrid Web-Wallet

arowser/appium 0

:iphone: Automation for iOS, Android, and Windows Apps.

arowser/bips 0

Bitcoin Improvement Proposals

arowser/bitcoin 0

Bitcoin Core integration/staging tree

arowser/bitcoin.org 0

Bitcoin.org website

issue commentbitcoin-core/bitcoincore.org

Disappointing decision from core devs.

Cobra is just lying from top top bottom in his post. It's utterly infuriating because I cannot expose how much he is lying without exposing material which should be kept confidential.

Lucienest

comment created time in 8 minutes

PR opened bitcoin-core/bitcoincore.org

RPC doc generating script: always connect to regtest

See Bitcoin Core PR https://github.com/bitcoin/bitcoin/pull/20987, in particular the discussion https://github.com/bitcoin/bitcoin/pull/20987#discussion_r562762266.

The recommended network for generating RPC docs is regtest, as stated in the script's file header comments: // (2) install bitcoin core, set it up to use regtest

To achieve this, the user previosly needed to manually put regtest=1 into ~/.bitcoin/bitcoin.conf -- the script didn't specify a concrete network, so without config file setting, mainnet was used. With the change in this commit, we will always connect to regtest by passing the -regtest option to the bitcoin-cli invokation.

With this change, harding's well-described way to use the script involving file editing via mighty vi(m) will be reduced to just running the following commands:

$ bitcoind -regtest -daemon
$ go run generate.go
$ bitcoin-cli -regtest stop

Note that I'm far from a golang expert and just tried to wrap my head around variadic functions and slices. Prepending the arguments slice with the chainoption (-regtest) seemed the easiest solution to me, but curious to hear how a more "gothonic" (does that word exist?) approach would look like.

+2 -0

0 comment

1 changed file

pr created time in 23 minutes

issue commentspesmilo/electrum

Support trampoline routing

@Kixunil how would that work unless Electrum is always installed? and is there a cross-platform API to register services?

ecdsa

comment created time in 42 minutes

CommitCommentEvent

PR opened lnbook/lnbook

Keeping fallback as one word for consistency.

Keeping "fallback" as one word for consistency.

+1 -1

0 comment

1 changed file

pr created time in an hour

issue openedtalaia-labs/python-teos

Path eror running c-lightning plugin tests

When running pytest in watchtower-plugin I get the following error for a few of the tests:

Warning: Skipping -wallet path that doesn't exist. Failed to load database path '/tmp/ltests-f54ew0ul/test_watchtower_misbehaving_1/regtest/"test"'. Path does not exist.

Happy to investigate this... But thought I'd see if it's a familiar error or a sign I goofed up during setup

created time in an hour

PR opened lnbook/lnbook

Adding Lightning Network whitepaper link.

Adding Lightning Network whitepaper link.

+1 -1

0 comment

1 changed file

pr created time in an hour

Pull request review commentbitcoin-core/secp256k1

Safegcd inverses, drop Jacobi symbols, remove libgmp

+/***********************************************************************+ * Copyright (c) 2020 Peter Dettman                                    *+ * Distributed under the MIT software license, see the accompanying    *+ * file COPYING or https://www.opensource.org/licenses/mit-license.php.*+ **********************************************************************/++#ifndef SECP256K1_MODINV64_IMPL_H+#define SECP256K1_MODINV64_IMPL_H++#include "modinv64.h"++#include "util.h"++/* This file implements modular inversion based on the paper "Fast constant-time gcd computation and+ * modular inversion" by Daniel J. Bernstein and Bo-Yin Yang.+ *+ * For an explanation of the algorithm, see doc/safegcd_implementation.md. This file contains an+ * implementation for N=62, using 62-bit signed limbs represented as int64_t.+ */++/* Optionally negate a signed62 number in range (-2*modulus,modulus), and add multiple of modulus to+ * bring it to [0,modulus). The input must have limbs in range (-2^62,2^62). The output will have+ * limbs in range [0,2^62). */+static void secp256k1_modinv64_normalize_62(secp256k1_modinv64_signed62 *r, int64_t cond_negate, const secp256k1_modinv64_modinfo *modinfo) {+    const int64_t M62 = (int64_t)(UINT64_MAX >> 2);+    int64_t r0 = r->v[0], r1 = r->v[1], r2 = r->v[2], r3 = r->v[3], r4 = r->v[4];+    int64_t cond_add;++    /* In a first step, add the modulus if the input is negative, and then negate if requested.+     * This brings r from range (-2*modulus,modulus) to range (-modulus,modulus). As all input+     * limbs are in range (-2^62,2^62), this cannot overflow an int64_t. */+    cond_add = r4 >> 63;+    r0 += modinfo->modulus.v[0] & cond_add;+    r1 += modinfo->modulus.v[1] & cond_add;+    r2 += modinfo->modulus.v[2] & cond_add;+    r3 += modinfo->modulus.v[3] & cond_add;+    r4 += modinfo->modulus.v[4] & cond_add;+    r0 = (r0 ^ cond_negate) - cond_negate;+    r1 = (r1 ^ cond_negate) - cond_negate;+    r2 = (r2 ^ cond_negate) - cond_negate;+    r3 = (r3 ^ cond_negate) - cond_negate;+    r4 = (r4 ^ cond_negate) - cond_negate;+    /* Propagate the top bits, to bring limbs back to range (-2^62,2^62). */+    r1 += r0 >> 62; r0 &= M62;+    r2 += r1 >> 62; r1 &= M62;+    r3 += r2 >> 62; r2 &= M62;+    r4 += r3 >> 62; r3 &= M62;++    /* In a second step add the modulus again if the result is still negative, bringing+     * r to range [0,modulus). */+    cond_add = r4 >> 63;+    r0 += modinfo->modulus.v[0] & cond_add;+    r1 += modinfo->modulus.v[1] & cond_add;+    r2 += modinfo->modulus.v[2] & cond_add;+    r3 += modinfo->modulus.v[3] & cond_add;+    r4 += modinfo->modulus.v[4] & cond_add;+    /* And propagate again. */+    r1 += r0 >> 62; r0 &= M62;+    r2 += r1 >> 62; r1 &= M62;+    r3 += r2 >> 62; r2 &= M62;+    r4 += r3 >> 62; r3 &= M62;++    r->v[0] = r0;+    r->v[1] = r1;+    r->v[2] = r2;+    r->v[3] = r3;+    r->v[4] = r4;++#ifdef VERIFY+    VERIFY_CHECK(r->v[0] >> 62 == 0);+    VERIFY_CHECK(r->v[1] >> 62 == 0);+    VERIFY_CHECK(r->v[2] >> 62 == 0);+    VERIFY_CHECK(r->v[3] >> 62 == 0);+    VERIFY_CHECK(r->v[4] >>  8 == 0);+#endif+}++/* Data type for transition matrices (see section 3 of explanation).+ *+ * t = [ u  v ]+ *     [ q  r ]+ */+typedef struct {+    int64_t u, v, q, r;+} secp256k1_modinv64_trans2x2;++/* Compute the transition matrix and eta for 62 divsteps.+ *+ * Input:  eta: initial eta+ *         f0:  bottom limb of initial f+ *         g0:  bottom limb of initial g+ * Output: t: transition matrix+ * Return: final eta+ *+ * Implements the divsteps_n_matrix function from the explanation.+ */+static uint64_t secp256k1_modinv64_divsteps_62(uint64_t eta, uint64_t f0, uint64_t g0, secp256k1_modinv64_trans2x2 *t) {+    uint64_t u = 1, v = 0, q = 0, r = 1; /* start with identity matrix */+    uint64_t c1, c2, f = f0, g = g0, x, y, z;+    int i;++    for (i = 0; i < 62; ++i) {+        VERIFY_CHECK((f & 1) == 1); /* f must always be odd */+        VERIFY_CHECK((u * f0 + v * g0) == f << i);+        VERIFY_CHECK((q * f0 + r * g0) == g << i);+        /* Compute conditional masks for (eta < 0) and for (g & 1). */+        c1 = (int64_t)eta >> 63;+        c2 = -(g & 1);+        /* Compute x,y,z, conditionally negated versions of f,u,v. */+        x = (f ^ c1) - c1;+        y = (u ^ c1) - c1;+        z = (v ^ c1) - c1;+        /* Conditionally add x,y,z to g,q,r. */+        g += x & c2;+        q += y & c2;+        r += z & c2;+        /* In what follows, c1 is a condition mask for (eta < 0) and (g & 1). */+        c1 &= c2;+        /* Conditionally negate eta, and unconditionally subtract 1. */+        eta = (eta ^ c1) - (c1 + 1);+        /* Conditionally add g,q,r to f,u,v. */+        f += g & c1;+        u += q & c1;+        v += r & c1;+        /* Shifts */+        g >>= 1;+        u <<= 1;+        v <<= 1;+    }+    /* Return data in t and return value. */+    t->u = (int64_t)u;+    t->v = (int64_t)v;+    t->q = (int64_t)q;+    t->r = (int64_t)r;+    return eta;+}++/* Compute the transition matrix and eta for 62 divsteps (variable time).+ *+ * Input:  eta: initial eta+ *         f0:  bottom limb of initial f+ *         g0:  bottom limb of initial g+ * Output: t: transition matrix+ * Return: final eta+ *+ * Implements the divsteps_n_matrix_var function from the explanation.+ */+static uint64_t secp256k1_modinv64_divsteps_62_var(uint64_t eta, uint64_t f0, uint64_t g0, secp256k1_modinv64_trans2x2 *t) {+    /* inv256[i] = -(2*i+1)^-1 (mod 256) */+    static const uint8_t inv256[128] = {+        0xFF, 0x55, 0x33, 0x49, 0xC7, 0x5D, 0x3B, 0x11, 0x0F, 0xE5, 0xC3, 0x59,+        0xD7, 0xED, 0xCB, 0x21, 0x1F, 0x75, 0x53, 0x69, 0xE7, 0x7D, 0x5B, 0x31,+        0x2F, 0x05, 0xE3, 0x79, 0xF7, 0x0D, 0xEB, 0x41, 0x3F, 0x95, 0x73, 0x89,+        0x07, 0x9D, 0x7B, 0x51, 0x4F, 0x25, 0x03, 0x99, 0x17, 0x2D, 0x0B, 0x61,+        0x5F, 0xB5, 0x93, 0xA9, 0x27, 0xBD, 0x9B, 0x71, 0x6F, 0x45, 0x23, 0xB9,+        0x37, 0x4D, 0x2B, 0x81, 0x7F, 0xD5, 0xB3, 0xC9, 0x47, 0xDD, 0xBB, 0x91,+        0x8F, 0x65, 0x43, 0xD9, 0x57, 0x6D, 0x4B, 0xA1, 0x9F, 0xF5, 0xD3, 0xE9,+        0x67, 0xFD, 0xDB, 0xB1, 0xAF, 0x85, 0x63, 0xF9, 0x77, 0x8D, 0x6B, 0xC1,+        0xBF, 0x15, 0xF3, 0x09, 0x87, 0x1D, 0xFB, 0xD1, 0xCF, 0xA5, 0x83, 0x19,+        0x97, 0xAD, 0x8B, 0xE1, 0xDF, 0x35, 0x13, 0x29, 0xA7, 0x3D, 0x1B, 0xF1,+        0xEF, 0xC5, 0xA3, 0x39, 0xB7, 0xCD, 0xAB, 0x01+    };++    uint64_t u = 1, v = 0, q = 0, r = 1; /* Start with identity matrix */+    uint64_t f = f0, g = g0, m, x, y, z;+    uint32_t w;+    int i = 62, limit, zeros;++    for (;;) {+        /* Use a sentinel bit to count zeros only up to i. */+        zeros = secp256k1_ctz64_var(g | (UINT64_MAX << i));+        /* Perform zeros divsteps at once; they all just divide g by two. */+        g >>= zeros;+        u <<= zeros;+        v <<= zeros;+        eta -= zeros;+        i -= zeros;+        /* We're done once we've done 62 divsteps. */+        if (i == 0) break;+        VERIFY_CHECK((f & 1) == 1);+        VERIFY_CHECK((g & 1) == 1);+        VERIFY_CHECK((u * f0 + v * g0) == f << (62 - i));+        VERIFY_CHECK((q * f0 + r * g0) == g << (62 - i));+        /* If eta is negative, negate it and replace f,g with g,-f. */+        if ((int64_t)eta < 0) {+            eta = -eta;+            x = f; f = g; g = -x;+            y = u; u = q; q = -y;+            z = v; v = r; r = -z;+        }+        /* eta is now >= 0. In what follows we're going to cancel out the bottom bits of g. No more+         * than i can be cancelled out (as we'd be done before that point), and no more than eta+1+         * can be done as its sign will flip once that happens. */+        limit = ((int)eta + 1) > i ? i : ((int)eta + 1);+        /* m is a mask for the bottom min(limit, 8) bits (our table only supports 8 bits). */+        m = (UINT64_MAX >> (64 - limit)) & 255U;

Added a VERIFY_CHECK for the range of limit.

sipa

comment created time in an hour

Pull request review commentbitcoin-core/secp256k1

Safegcd inverses, drop Jacobi symbols, remove libgmp

+/***********************************************************************+ * Copyright (c) 2020 Peter Dettman                                    *+ * Distributed under the MIT software license, see the accompanying    *+ * file COPYING or https://www.opensource.org/licenses/mit-license.php.*+ **********************************************************************/++#ifndef SECP256K1_MODINV64_IMPL_H+#define SECP256K1_MODINV64_IMPL_H++#include "modinv64.h"++#include "util.h"++/* This file implements modular inversion based on the paper "Fast constant-time gcd computation and+ * modular inversion" by Daniel J. Bernstein and Bo-Yin Yang.+ *+ * For an explanation of the algorithm, see doc/safegcd_implementation.md. This file contains an+ * implementation for N=62, using 62-bit signed limbs represented as int64_t.+ */++/* Optionally negate a signed62 number in range (-2*modulus,modulus), and add multiple of modulus to+ * bring it to [0,modulus). The input must have limbs in range (-2^62,2^62). The output will have+ * limbs in range [0,2^62). */+static void secp256k1_modinv64_normalize_62(secp256k1_modinv64_signed62 *r, int64_t cond_negate, const secp256k1_modinv64_modinfo *modinfo) {+    const int64_t M62 = (int64_t)(UINT64_MAX >> 2);+    int64_t r0 = r->v[0], r1 = r->v[1], r2 = r->v[2], r3 = r->v[3], r4 = r->v[4];+    int64_t cond_add;++    /* In a first step, add the modulus if the input is negative, and then negate if requested.+     * This brings r from range (-2*modulus,modulus) to range (-modulus,modulus). As all input+     * limbs are in range (-2^62,2^62), this cannot overflow an int64_t. */+    cond_add = r4 >> 63;+    r0 += modinfo->modulus.v[0] & cond_add;+    r1 += modinfo->modulus.v[1] & cond_add;+    r2 += modinfo->modulus.v[2] & cond_add;+    r3 += modinfo->modulus.v[3] & cond_add;+    r4 += modinfo->modulus.v[4] & cond_add;+    r0 = (r0 ^ cond_negate) - cond_negate;+    r1 = (r1 ^ cond_negate) - cond_negate;+    r2 = (r2 ^ cond_negate) - cond_negate;+    r3 = (r3 ^ cond_negate) - cond_negate;+    r4 = (r4 ^ cond_negate) - cond_negate;+    /* Propagate the top bits, to bring limbs back to range (-2^62,2^62). */+    r1 += r0 >> 62; r0 &= M62;+    r2 += r1 >> 62; r1 &= M62;+    r3 += r2 >> 62; r2 &= M62;+    r4 += r3 >> 62; r3 &= M62;++    /* In a second step add the modulus again if the result is still negative, bringing+     * r to range [0,modulus). */+    cond_add = r4 >> 63;+    r0 += modinfo->modulus.v[0] & cond_add;+    r1 += modinfo->modulus.v[1] & cond_add;+    r2 += modinfo->modulus.v[2] & cond_add;+    r3 += modinfo->modulus.v[3] & cond_add;+    r4 += modinfo->modulus.v[4] & cond_add;+    /* And propagate again. */+    r1 += r0 >> 62; r0 &= M62;+    r2 += r1 >> 62; r1 &= M62;+    r3 += r2 >> 62; r2 &= M62;+    r4 += r3 >> 62; r3 &= M62;++    r->v[0] = r0;+    r->v[1] = r1;+    r->v[2] = r2;+    r->v[3] = r3;+    r->v[4] = r4;++#ifdef VERIFY+    VERIFY_CHECK(r->v[0] >> 62 == 0);+    VERIFY_CHECK(r->v[1] >> 62 == 0);+    VERIFY_CHECK(r->v[2] >> 62 == 0);+    VERIFY_CHECK(r->v[3] >> 62 == 0);+    VERIFY_CHECK(r->v[4] >>  8 == 0);+#endif+}++/* Data type for transition matrices (see section 3 of explanation).+ *+ * t = [ u  v ]+ *     [ q  r ]+ */+typedef struct {+    int64_t u, v, q, r;+} secp256k1_modinv64_trans2x2;++/* Compute the transition matrix and eta for 62 divsteps.+ *+ * Input:  eta: initial eta+ *         f0:  bottom limb of initial f+ *         g0:  bottom limb of initial g+ * Output: t: transition matrix+ * Return: final eta+ *+ * Implements the divsteps_n_matrix function from the explanation.+ */+static uint64_t secp256k1_modinv64_divsteps_62(uint64_t eta, uint64_t f0, uint64_t g0, secp256k1_modinv64_trans2x2 *t) {+    uint64_t u = 1, v = 0, q = 0, r = 1; /* start with identity matrix */+    uint64_t c1, c2, f = f0, g = g0, x, y, z;+    int i;++    for (i = 0; i < 62; ++i) {+        VERIFY_CHECK((f & 1) == 1); /* f must always be odd */+        VERIFY_CHECK((u * f0 + v * g0) == f << i);+        VERIFY_CHECK((q * f0 + r * g0) == g << i);+        /* Compute conditional masks for (eta < 0) and for (g & 1). */+        c1 = (int64_t)eta >> 63;+        c2 = -(g & 1);+        /* Compute x,y,z, conditionally negated versions of f,u,v. */+        x = (f ^ c1) - c1;+        y = (u ^ c1) - c1;+        z = (v ^ c1) - c1;+        /* Conditionally add x,y,z to g,q,r. */+        g += x & c2;+        q += y & c2;+        r += z & c2;+        /* In what follows, c1 is a condition mask for (eta < 0) and (g & 1). */+        c1 &= c2;+        /* Conditionally negate eta, and unconditionally subtract 1. */+        eta = (eta ^ c1) - (c1 + 1);+        /* Conditionally add g,q,r to f,u,v. */+        f += g & c1;+        u += q & c1;+        v += r & c1;+        /* Shifts */+        g >>= 1;+        u <<= 1;+        v <<= 1;+    }+    /* Return data in t and return value. */+    t->u = (int64_t)u;+    t->v = (int64_t)v;+    t->q = (int64_t)q;+    t->r = (int64_t)r;+    return eta;+}++/* Compute the transition matrix and eta for 62 divsteps (variable time).+ *+ * Input:  eta: initial eta+ *         f0:  bottom limb of initial f+ *         g0:  bottom limb of initial g+ * Output: t: transition matrix+ * Return: final eta+ *+ * Implements the divsteps_n_matrix_var function from the explanation.+ */+static uint64_t secp256k1_modinv64_divsteps_62_var(uint64_t eta, uint64_t f0, uint64_t g0, secp256k1_modinv64_trans2x2 *t) {+    /* inv256[i] = -(2*i+1)^-1 (mod 256) */+    static const uint8_t inv256[128] = {+        0xFF, 0x55, 0x33, 0x49, 0xC7, 0x5D, 0x3B, 0x11, 0x0F, 0xE5, 0xC3, 0x59,+        0xD7, 0xED, 0xCB, 0x21, 0x1F, 0x75, 0x53, 0x69, 0xE7, 0x7D, 0x5B, 0x31,+        0x2F, 0x05, 0xE3, 0x79, 0xF7, 0x0D, 0xEB, 0x41, 0x3F, 0x95, 0x73, 0x89,+        0x07, 0x9D, 0x7B, 0x51, 0x4F, 0x25, 0x03, 0x99, 0x17, 0x2D, 0x0B, 0x61,+        0x5F, 0xB5, 0x93, 0xA9, 0x27, 0xBD, 0x9B, 0x71, 0x6F, 0x45, 0x23, 0xB9,+        0x37, 0x4D, 0x2B, 0x81, 0x7F, 0xD5, 0xB3, 0xC9, 0x47, 0xDD, 0xBB, 0x91,+        0x8F, 0x65, 0x43, 0xD9, 0x57, 0x6D, 0x4B, 0xA1, 0x9F, 0xF5, 0xD3, 0xE9,+        0x67, 0xFD, 0xDB, 0xB1, 0xAF, 0x85, 0x63, 0xF9, 0x77, 0x8D, 0x6B, 0xC1,+        0xBF, 0x15, 0xF3, 0x09, 0x87, 0x1D, 0xFB, 0xD1, 0xCF, 0xA5, 0x83, 0x19,+        0x97, 0xAD, 0x8B, 0xE1, 0xDF, 0x35, 0x13, 0x29, 0xA7, 0x3D, 0x1B, 0xF1,+        0xEF, 0xC5, 0xA3, 0x39, 0xB7, 0xCD, 0xAB, 0x01+    };++    uint64_t u = 1, v = 0, q = 0, r = 1; /* Start with identity matrix */+    uint64_t f = f0, g = g0, m, x, y, z;+    uint32_t w;+    int i = 62, limit, zeros;++    for (;;) {+        /* Use a sentinel bit to count zeros only up to i. */+        zeros = secp256k1_ctz64_var(g | (UINT64_MAX << i));+        /* Perform zeros divsteps at once; they all just divide g by two. */+        g >>= zeros;+        u <<= zeros;+        v <<= zeros;+        eta -= zeros;+        i -= zeros;+        /* We're done once we've done 62 divsteps. */+        if (i == 0) break;+        VERIFY_CHECK((f & 1) == 1);+        VERIFY_CHECK((g & 1) == 1);+        VERIFY_CHECK((u * f0 + v * g0) == f << (62 - i));+        VERIFY_CHECK((q * f0 + r * g0) == g << (62 - i));+        /* If eta is negative, negate it and replace f,g with g,-f. */+        if ((int64_t)eta < 0) {+            eta = -eta;+            x = f; f = g; g = -x;+            y = u; u = q; q = -y;+            z = v; v = r; r = -z;+        }+        /* eta is now >= 0. In what follows we're going to cancel out the bottom bits of g. No more+         * than i can be cancelled out (as we'd be done before that point), and no more than eta+1+         * can be done as its sign will flip once that happens. */+        limit = ((int)eta + 1) > i ? i : ((int)eta + 1);

I've added VERIFY_CHECK statements to check the range of eta.

sipa

comment created time in an hour

push eventsipa/secp256k1

Pieter Wuille

commit sha 9b6f36d7564ea29d3a193c99d59397cdb6759980

Make scalar_inverse{,_var} benchmark scale with SECP256K1_BENCH_ITERS

view details

push time in an hour

Pull request review commentbitcoin-core/secp256k1

Safegcd inverses, drop Jacobi symbols, remove libgmp

+/***********************************************************************+ * Copyright (c) 2020 Peter Dettman                                    *+ * Distributed under the MIT software license, see the accompanying    *+ * file COPYING or https://www.opensource.org/licenses/mit-license.php.*+ **********************************************************************/++#ifndef SECP256K1_MODINV64_IMPL_H+#define SECP256K1_MODINV64_IMPL_H++#include "modinv64.h"++#include "util.h"++/* This file implements modular inversion based on the paper "Fast constant-time gcd computation and+ * modular inversion" by Daniel J. Bernstein and Bo-Yin Yang.+ *+ * For an explanation of the algorithm, see doc/safegcd_implementation.md. This file contains an+ * implementation for N=62, using 62-bit signed limbs represented as int64_t.+ */++/* Optionally negate a signed62 number in range (-2*modulus,modulus), and add multiple of modulus to+ * bring it to [0,modulus). The input must have limbs in range (-2^62,2^62). The output will have+ * limbs in range [0,2^62). */+static void secp256k1_modinv64_normalize_62(secp256k1_modinv64_signed62 *r, int64_t cond_negate, const secp256k1_modinv64_modinfo *modinfo) {+    const int64_t M62 = (int64_t)(UINT64_MAX >> 2);+    int64_t r0 = r->v[0], r1 = r->v[1], r2 = r->v[2], r3 = r->v[3], r4 = r->v[4];+    int64_t cond_add;++    /* In a first step, add the modulus if the input is negative, and then negate if requested.+     * This brings r from range (-2*modulus,modulus) to range (-modulus,modulus). As all input+     * limbs are in range (-2^62,2^62), this cannot overflow an int64_t. */+    cond_add = r4 >> 63;+    r0 += modinfo->modulus.v[0] & cond_add;+    r1 += modinfo->modulus.v[1] & cond_add;+    r2 += modinfo->modulus.v[2] & cond_add;+    r3 += modinfo->modulus.v[3] & cond_add;+    r4 += modinfo->modulus.v[4] & cond_add;+    r0 = (r0 ^ cond_negate) - cond_negate;+    r1 = (r1 ^ cond_negate) - cond_negate;+    r2 = (r2 ^ cond_negate) - cond_negate;+    r3 = (r3 ^ cond_negate) - cond_negate;+    r4 = (r4 ^ cond_negate) - cond_negate;+    /* Propagate the top bits, to bring limbs back to range (-2^62,2^62). */+    r1 += r0 >> 62; r0 &= M62;+    r2 += r1 >> 62; r1 &= M62;+    r3 += r2 >> 62; r2 &= M62;+    r4 += r3 >> 62; r3 &= M62;++    /* In a second step add the modulus again if the result is still negative, bringing+     * r to range [0,modulus). */+    cond_add = r4 >> 63;+    r0 += modinfo->modulus.v[0] & cond_add;+    r1 += modinfo->modulus.v[1] & cond_add;+    r2 += modinfo->modulus.v[2] & cond_add;+    r3 += modinfo->modulus.v[3] & cond_add;+    r4 += modinfo->modulus.v[4] & cond_add;+    /* And propagate again. */+    r1 += r0 >> 62; r0 &= M62;+    r2 += r1 >> 62; r1 &= M62;+    r3 += r2 >> 62; r2 &= M62;+    r4 += r3 >> 62; r3 &= M62;++    r->v[0] = r0;+    r->v[1] = r1;+    r->v[2] = r2;+    r->v[3] = r3;+    r->v[4] = r4;++#ifdef VERIFY+    VERIFY_CHECK(r->v[0] >> 62 == 0);+    VERIFY_CHECK(r->v[1] >> 62 == 0);+    VERIFY_CHECK(r->v[2] >> 62 == 0);+    VERIFY_CHECK(r->v[3] >> 62 == 0);+    VERIFY_CHECK(r->v[4] >>  8 == 0);+#endif+}++/* Data type for transition matrices (see section 3 of explanation).+ *+ * t = [ u  v ]+ *     [ q  r ]+ */+typedef struct {+    int64_t u, v, q, r;+} secp256k1_modinv64_trans2x2;++/* Compute the transition matrix and eta for 62 divsteps.+ *+ * Input:  eta: initial eta+ *         f0:  bottom limb of initial f+ *         g0:  bottom limb of initial g+ * Output: t: transition matrix+ * Return: final eta+ *+ * Implements the divsteps_n_matrix function from the explanation.+ */+static uint64_t secp256k1_modinv64_divsteps_62(uint64_t eta, uint64_t f0, uint64_t g0, secp256k1_modinv64_trans2x2 *t) {+    uint64_t u = 1, v = 0, q = 0, r = 1; /* start with identity matrix */+    uint64_t c1, c2, f = f0, g = g0, x, y, z;+    int i;++    for (i = 0; i < 62; ++i) {+        VERIFY_CHECK((f & 1) == 1); /* f must always be odd */+        VERIFY_CHECK((u * f0 + v * g0) == f << i);+        VERIFY_CHECK((q * f0 + r * g0) == g << i);+        /* Compute conditional masks for (eta < 0) and for (g & 1). */+        c1 = (int64_t)eta >> 63;+        c2 = -(g & 1);+        /* Compute x,y,z, conditionally negated versions of f,u,v. */+        x = (f ^ c1) - c1;+        y = (u ^ c1) - c1;+        z = (v ^ c1) - c1;+        /* Conditionally add x,y,z to g,q,r. */+        g += x & c2;+        q += y & c2;+        r += z & c2;+        /* In what follows, c1 is a condition mask for (eta < 0) and (g & 1). */+        c1 &= c2;+        /* Conditionally negate eta, and unconditionally subtract 1. */+        eta = (eta ^ c1) - (c1 + 1);+        /* Conditionally add g,q,r to f,u,v. */+        f += g & c1;+        u += q & c1;+        v += r & c1;+        /* Shifts */+        g >>= 1;+        u <<= 1;+        v <<= 1;+    }+    /* Return data in t and return value. */+    t->u = (int64_t)u;+    t->v = (int64_t)v;+    t->q = (int64_t)q;+    t->r = (int64_t)r;+    return eta;+}++/* Compute the transition matrix and eta for 62 divsteps (variable time).+ *+ * Input:  eta: initial eta+ *         f0:  bottom limb of initial f+ *         g0:  bottom limb of initial g+ * Output: t: transition matrix+ * Return: final eta+ *+ * Implements the divsteps_n_matrix_var function from the explanation.+ */+static uint64_t secp256k1_modinv64_divsteps_62_var(uint64_t eta, uint64_t f0, uint64_t g0, secp256k1_modinv64_trans2x2 *t) {+    /* inv256[i] = -(2*i+1)^-1 (mod 256) */+    static const uint8_t inv256[128] = {+        0xFF, 0x55, 0x33, 0x49, 0xC7, 0x5D, 0x3B, 0x11, 0x0F, 0xE5, 0xC3, 0x59,+        0xD7, 0xED, 0xCB, 0x21, 0x1F, 0x75, 0x53, 0x69, 0xE7, 0x7D, 0x5B, 0x31,+        0x2F, 0x05, 0xE3, 0x79, 0xF7, 0x0D, 0xEB, 0x41, 0x3F, 0x95, 0x73, 0x89,+        0x07, 0x9D, 0x7B, 0x51, 0x4F, 0x25, 0x03, 0x99, 0x17, 0x2D, 0x0B, 0x61,+        0x5F, 0xB5, 0x93, 0xA9, 0x27, 0xBD, 0x9B, 0x71, 0x6F, 0x45, 0x23, 0xB9,+        0x37, 0x4D, 0x2B, 0x81, 0x7F, 0xD5, 0xB3, 0xC9, 0x47, 0xDD, 0xBB, 0x91,+        0x8F, 0x65, 0x43, 0xD9, 0x57, 0x6D, 0x4B, 0xA1, 0x9F, 0xF5, 0xD3, 0xE9,+        0x67, 0xFD, 0xDB, 0xB1, 0xAF, 0x85, 0x63, 0xF9, 0x77, 0x8D, 0x6B, 0xC1,+        0xBF, 0x15, 0xF3, 0x09, 0x87, 0x1D, 0xFB, 0xD1, 0xCF, 0xA5, 0x83, 0x19,+        0x97, 0xAD, 0x8B, 0xE1, 0xDF, 0x35, 0x13, 0x29, 0xA7, 0x3D, 0x1B, 0xF1,+        0xEF, 0xC5, 0xA3, 0x39, 0xB7, 0xCD, 0xAB, 0x01+    };++    uint64_t u = 1, v = 0, q = 0, r = 1; /* Start with identity matrix */+    uint64_t f = f0, g = g0, m, x, y, z;+    uint32_t w;+    int i = 62, limit, zeros;++    for (;;) {+        /* Use a sentinel bit to count zeros only up to i. */+        zeros = secp256k1_ctz64_var(g | (UINT64_MAX << i));+        /* Perform zeros divsteps at once; they all just divide g by two. */+        g >>= zeros;+        u <<= zeros;+        v <<= zeros;+        eta -= zeros;+        i -= zeros;+        /* We're done once we've done 62 divsteps. */+        if (i == 0) break;+        VERIFY_CHECK((f & 1) == 1);+        VERIFY_CHECK((g & 1) == 1);+        VERIFY_CHECK((u * f0 + v * g0) == f << (62 - i));+        VERIFY_CHECK((q * f0 + r * g0) == g << (62 - i));+        /* If eta is negative, negate it and replace f,g with g,-f. */+        if ((int64_t)eta < 0) {+            eta = -eta;+            x = f; f = g; g = -x;+            y = u; u = q; q = -y;+            z = v; v = r; r = -z;

Done. Changed for a local tmp variable.

sipa

comment created time in an hour

push eventsipa/secp256k1

Peter Dettman

commit sha a225f12d436be7286681495e7a4682f62a997f8a

Add safegcd based modular inverse modules Refactored by: Pieter Wuille <pieter@wuille.net>

view details

Pieter Wuille

commit sha ae776cc0f58db0643e7705ed5d14c0bc833a5950

Add extensive comments on the safegcd algorithm and implementation This adds a long comment explaining the algorithm and implementation choices by building it up step by step in Python. Comments in the code are also reworked/added, with references to the long explanation.

view details

Pieter Wuille

commit sha 00da5d475de47a0439bbbae5d7c17e2a1a3b26a2

Add tests for modinv modules This adds tests for the modinv{32,64}_impl.h directly (before the functions are used inside the field/scalar code). It uses a naive implementation of modular multiplication and gcds in order to verify the modular inverses themselves.

view details

Pieter Wuille

commit sha 3a392d3e1d5b0f92845e7f2f45d6bafeb97ec14a

Improve bounds checks in modinv modules This commit adds functions to verify and compare numbers in signed{30,62} notation, and uses that to do more extensive bounds checking on various variables in the modinv code.

view details

Pieter Wuille

commit sha 94936ef627b665a762a51e51d90e524289a8e4bc

Move secp256k1_scalar_{inverse{_var},is_even} to per-impl files This temporarily duplicates the inversion code across the 4x64 and 8x32 implementations. Those implementations will be replaced in a later commit.

view details

Pieter Wuille

commit sha 8e88f24f50d02eb22d0765989a6c052ad73781ee

Move secp256k1_fe_inverse{_var} to per-impl files This temporarily duplicates the inversion code across the 5x52 and 10x26 implementations. Those implementations will be replaced in a next commit.

view details

Pieter Wuille

commit sha 1a174f186d5592bbff301b27c58e5c3454e77a22

Make field/scalar code use the new modinv modules for inverses

view details

Pieter Wuille

commit sha d4cd0f35c403e7f03b708ffef7cc4563c912c541

Improve field/scalar inverse tests Add a new run_inverse_tests that replaces all existing field/scalar inverse tests, and tests a few identities for fixed inputs, small numbers (-999...999), random inputs (structured and unstructured), as well as comparing with the output of secp256k1_fe_inv_all_var.

view details

Pieter Wuille

commit sha 938cdcbf2d69d2a7aa4b3e02079ad9a45b899f86

Remove unused Jacobi symbol support No exposed functions rely on Jacobi symbol computation anymore. Remove it; it can always be brough back later if needed.

view details

Pieter Wuille

commit sha 89df653e7845ac626347106589d5de166b1c94d8

Remove num/gmp support The whole "num" API and its libgmp-based implementation are now unused. Remove them.

view details

Pieter Wuille

commit sha 5b4985a57b3f07831954909e4d873e1aef9f1b30

Optimization: special-case zero modulus limbs in modinv64 Both the field and scalar modulus can be written in signed{30,62} notation with one or more zero limbs. Make use of this in the update_de function to avoid a few wide multiplications when that is the case. This doesn't appear to be a win in the 32-bit implementation, so only do it for the 64-bit one.

view details

Peter Dettman

commit sha ea4fae83187f535563153896a3215b7fd10112ad

Optimization: use formulas instead of lookup tables for cancelling g bits This only seems to be a win on 64-bit platforms, so only do it there. Refactored by: Pieter Wuille <pieter@wuille.net>

view details

Peter Dettman

commit sha 2936705e8ee24caa223b77453b7278ec85b6bb9e

Optimization: track f,g limb count and pass to new variable-time update_fg_var The magnitude of the f and g variables generally goes down as the algorithm progresses. Make use of this by keeping tracking how many limbs are used, and when the number becomes small enough, make use of this to reduce the complexity of arithmetic on them. Refactored by: Pieter Wuille <pieter@wuille.net>

view details

push time in an hour

issue openedlightningnetwork/lnd

pathfinding: add a routing fee-inclusive option to query routes and send payment

Now that KeySend and MPP record support is more widely distributed, it can be safe to send a payment to a recipient which is routing fee inclusive instead of a static value.

For example, if a user were to make a withdrawal from an exchange, the exchange could KeySend to their public key a withdrawal sum that is inclusive of the routing fees required to fulfill that withdrawal. It is good practice to pass forward these types of routing fees to the recipient given that they may themselves be part of the routing path.

In the current QueryRoutes and SendPayment APIs, there is no way to specify that the total value of the payment should be inclusive of the routing fees. An extension to these APIs would allow for modifying that final HTLC value down.

With this API the exchange or other custodial wallet could offer a button to "withdraw all LN funds" without concerning themselves with the possibility of over-withdrawing. A UX issue that is present in some of these wallets today is that they do not allow withdrawing more than 99% of the value of the wallet value over LN in order to preserve funds for the routing fee.

This is something that can be worked around in various other ways but it could be more optimal and easier to integrate if incorporated into the pathfinding API calls themselves.

created time in 2 hours

PR opened lnbook/lnbook

rewording

rewording

+3 -3

0 comment

1 changed file

pr created time in 2 hours

PR opened lnbook/lnbook

Breaking up a long note into two paragraphs.

Breaking up a long note into two paragraphs.

+1 -0

0 comment

1 changed file

pr created time in 2 hours

PR opened lnbook/lnbook

Changing buttlet point list to numbered list to match the below refer…

Changing bullet point list to numbered list to match the below reference to question numbers.

+3 -3

0 comment

1 changed file

pr created time in 2 hours

PR opened lnbook/lnbook

Adding alt text to images

Added alt text to images in Chapter 2.

+10 -10

0 comment

1 changed file

pr created time in 2 hours

issue commentbitcoin-core/bitcoincore.org

Disappointing decision from core devs.

@harding Just to be clear, your understanding that this was discussed privately for "a few days" beforehand is mistaken, I believe Greg is referring to initially wanting me to not share the news of the letters for a while after we all received the letters, not that it was discussed prior. It seems that the whitepaper was removed basically a few hours after the threats were sent out. Greg says I broke confidentiality in that Reddit post, but that's not true, both the letters and the activity on this repo were public knowledge and were already being circulated before bitcoin.org put up the statement. That's generally how Craig operates, he shouts about what he's doing or will do, and if he sends you legal papers you can assume it'll be public knowledge a short while after. Speaking of that, see my screenshot below where he just told me about his upcoming plans a few moments ago. [1]

I chose to respond publicly and firmly to his nonsense because I was worried that mainstream media would pick up on Core's removal of the whitepaper, if it got picked up by dubious crypto media, like what happened with the recent double spending rubbish, and without a compelling counter-narrative, it could have spun out of control. Instead, because I acted, we ended up setting the narrative, and hundreds of companies and individuals have now joined us in rejecting Craig's claims over the whitepaper. It would have been nice for Bitcoin Core to reject him too.

Bitcoin Core developers saying the licensing status of the whitepaper is unclear is extremely dangerous. The whitepaper was bundled along with the original source code as an associated documentation file, and is clearly MIT licensed. In legal terms, it's just as much a part of the Bitcoin Core project as the genesis block or any line of code, because the MIT license bundles both the associated documentation files and the source code together as "the Software". When you cast doubt on the licensing status of the whitepaper by hastily removing it, from the Bitcoin Core site no less, you're also essentially saying the licensing status of the initial Bitcoin software released by Satoshi is unclear as it's all bundled together. Some Core developers defended the removal claiming it's not a hill worth dying on, and they would only fight back if he comes for the actual code, but they're missing the point, the whitepaper for all intents and purpose was the code, it was included in the initial software Satoshi released, they had no right to get you to take it down.

I think it's somewhat understandable to be spooked by Craig's threats, but painting what Core did here as part of some strategic calculated move is just not true, it was a panicked and rushed change, pushed through after only a few hours of receiving a dubious copyright claim, I doubt an attorney was even consulted, as no credible attorney would advise to comply with frivolous copyright claims. Do you think hundreds of companies and individuals would willingly host his alleged "copyrighted material" if his claims had any merit?

I think @ryanofsky and many other people have every right to feel uncomfortable about this, as you can see from my screenshot below, Craig doesn't plan on stopping, and complying with his demands just for the sake of preventing legal trouble isn't wise, because the goal is to get you to court, not to actually get the whitepaper taken down, so he will just sue you over something else, and subsequent attacks might be harder to defend against than a clear and cut case of hosting MIT content. The developers haven't actually "avoided" any legal trouble here.

[1]. Craig's words a short while ago: csw

Lucienest

comment created time in 2 hours

Pull request review commentlightningnetwork/lnd

[WIP] discovery: pinned syncers

 func testGraphTopologyNotifications(net *lntest.NetworkHarness, t *harnessTest)  	const chanAmt = funding.MaxBtcFundingAmount +	alice, err := net.NewNode("alice", nil)+	require.NoError(t.t, err)+	defer shutdownAndAssert(net, t, alice)++	bob, err := net.NewNode("bob", nil)+	require.NoError(t.t, err)+	defer shutdownAndAssert(net, t, bob)++	// Connect Alice and Bob.+	ctxt, _ := context.WithTimeout(ctxb, defaultTimeout)+	err = net.EnsureConnected(ctxt, alice, bob)+	require.NoError(t.t, err)++	// Alice stimmy.

:joy:

cfromknecht

comment created time in 2 hours

Pull request review commentlightningnetwork/lnd

[WIP] discovery: pinned syncers

 type Config struct {  	Routing *lncfg.Routing `group:"routing" namespace:"routing"` +	Gossip *lncfg.Gossip `group:"gossip" namespace:"gossip"`

Thoughts on moving the existing numgraphsyncpeers flag here and deprecating the top-level one while still parsing it? Then we can remove the top-level one at a later release.

cfromknecht

comment created time in 2 hours

Pull request review commentlightningnetwork/lnd

[WIP] discovery: pinned syncers

 func (m *SyncManager) syncerHandler() { 		initialHistoricalSyncSignal chan struct{} 	) +	setHistoricalSyncer := func(s *GossipSyncer) {

Nit: rename to setInitialHistoricalSyncer.

cfromknecht

comment created time in 2 hours

Pull request review commentlightningnetwork/lnd

[WIP] discovery: pinned syncers

 message Peer {         Denotes that we are not receiving new graph updates from the peer.         */         PASSIVE_SYNC = 2;++        /*+        Denotes that this peer is pinned into an active sync.+        */+        PINNED_ACTIVE_SYNC = 3;++        PINNED_PASSIVE_SYNC = 4;

Missing comment. Maybe this state distinction isn't needed after all though, as pinned passive will eventually become pinned active with the current logic.

cfromknecht

comment created time in 2 hours

Pull request review commentlightningnetwork/lnd

[WIP] discovery: pinned syncers

 func (m *SyncManager) syncerHandler() { 			// keep track of the corresponding syncer to properly 			// handle disconnects. We'll also use a signal to know 			// when the historical sync completed.-			setHistoricalSyncer(s)+			if !isPinnedSyncer {+				setHistoricalSyncer(s)

Seems like this should be done for our first pinned syncer as well? This would allow us to detect when they disconnect and start one with a different peer.

cfromknecht

comment created time in 2 hours

Pull request review commentlightningnetwork/lnd

[WIP] discovery: pinned syncers

 func (m *SyncManager) syncerHandler() {  			s := m.createGossipSyncer(newSyncer.peer) +			isPinnedSyncer := m.isPinnedSyncer(s)+ 			// attemptHistoricalSync determines whether we should 			// attempt an initial historical sync when a new peer 			// connects. 			attemptHistoricalSync := false  			m.syncersMu.Lock() 			switch {+			// For pinned syncers, we will immediately transition+			// the peer into an active (pinned) sync state.+			case isPinnedSyncer:

Seems like this should be handled further below in case this is the first syncer we see so that we attempt the historical sync and still keep them as pinned active?

cfromknecht

comment created time in 2 hours

Pull request review commentlightningnetwork/lnd

[WIP] discovery: pinned syncers

 type SyncManager struct { 	// currently receiving new graph updates from. 	inactiveSyncers map[route.Vertex]*GossipSyncer +	pinnedSyncers map[route.Vertex]struct{}

Nit: any reason to have these given that they're already present in the config?

cfromknecht

comment created time in 2 hours

Pull request review commentlightningnetwork/lnd

[WIP] discovery: pinned syncers

 func (m *SyncManager) syncerHandler() { 		// Our HistoricalSyncTicker has ticked, so we'll randomly select 		// a peer and force a historical sync with them. 		case <-m.cfg.HistoricalSyncTicker.Ticks():-			s := m.forceHistoricalSync()+			// If we've already performed an initial historical+			// sync, we won't try again with our passive peers.+			if m.IsGraphSynced() {

This should remain where it was, as the idea is to periodically perform historical syncs after our initial one to ensure we converge towards the full graph through different peers. The continue for the IsGraphSynced call previously was to avoid tracking the syncer we chose as the historical one. Maybe adding a comment would make that more clear?

cfromknecht

comment created time in 2 hours

Pull request review commentlightningnetwork/lnd

[WIP] discovery: pinned syncers

 func (m *SyncManager) syncerHandler() { 			// If we've already performed an initial historical 			// sync, we won't try again with our passive peers. 			if m.IsGraphSynced() {+				m.cfg.HistoricalSyncTicker.Pause()

Given my previous comment, we want to keep the ticker running here and below.

cfromknecht

comment created time in 2 hours

Pull request review commentbitcoin-core/secp256k1

schnorrsig API overhaul

 typedef int (*secp256k1_nonce_function_hardened)(  *  *  If a data pointer is passed, it is assumed to be a pointer to 32 bytes of  *  auxiliary random data as defined in BIP-340. If the data pointer is NULL,- *  schnorrsig_sign does not produce BIP-340 compliant signatures. The algo16- *  argument must be non-NULL, otherwise the function will fail and return 0.- *  The hash will be tagged with algo16 after removing all terminating null- *  bytes. Therefore, to create BIP-340 compliant signatures, algo16 must be set- *  to "BIP0340/nonce\0\0\0"+ *  schnorrsig_sign does not follow the BIP-340 nonce derivation procedure+ *  exactly. The algo16 argument must be non-NULL, otherwise the function will+ *  fail and return 0. The hash will be tagged with algo16 after removing all+ *  terminating null bytes. Therefore, to create BIP-340 compliant signatures,+ *  algo16 must be set to "BIP0340/nonce\0\0\0"

added algolen argument

jonasnick

comment created time in 2 hours

Pull request review commentbitcoin-core/secp256k1

schnorrsig API overhaul

 typedef int (*secp256k1_nonce_function_hardened)(  *  *  If a data pointer is passed, it is assumed to be a pointer to 32 bytes of  *  auxiliary random data as defined in BIP-340. If the data pointer is NULL,- *  schnorrsig_sign does not produce BIP-340 compliant signatures. The algo16- *  argument must be non-NULL, otherwise the function will fail and return 0.- *  The hash will be tagged with algo16 after removing all terminating null- *  bytes. Therefore, to create BIP-340 compliant signatures, algo16 must be set- *  to "BIP0340/nonce\0\0\0"+ *  schnorrsig_sign does not follow the BIP-340 nonce derivation procedure+ *  exactly. The algo16 argument must be non-NULL, otherwise the function will+ *  fail and return 0. The hash will be tagged with algo16 after removing all+ *  terminating null bytes. Therefore, to create BIP-340 compliant signatures,+ *  algo16 must be set to "BIP0340/nonce\0\0\0"  */ SECP256K1_API extern const secp256k1_nonce_function_hardened secp256k1_nonce_function_bip340; +/** Opaque data structure that holds additional arguments for schnorrsig signing.+ */+typedef struct secp256k1_schnorrsig_config_struct secp256k1_schnorrsig_config;+ /** Create a Schnorr signature.  *  *  Does _not_ strictly follow BIP-340 because it does not verify the resulting  *  signature. Instead, you can manually use secp256k1_schnorrsig_verify and  *  abort if it fails.  *- *  Otherwise BIP-340 compliant if the noncefp argument is NULL or- *  secp256k1_nonce_function_bip340 and the ndata argument is 32-byte auxiliary- *  randomness.- *  *  Returns 1 on success, 0 on failure.  *  Args:    ctx: pointer to a context object, initialized for signing (cannot be NULL)  *  Out:   sig64: pointer to a 64-byte array to store the serialized signature (cannot be NULL)- *  In:    msg32: the 32-byte message being signed (cannot be NULL)+ *  In:      msg: the message being signed (cannot be NULL)+ *       msg_len: length of the message  *       keypair: pointer to an initialized keypair (cannot be NULL)- *       noncefp: pointer to a nonce generation function. If NULL, secp256k1_nonce_function_bip340 is used- *         ndata: pointer to arbitrary data used by the nonce generation- *                function (can be NULL). If it is non-NULL and- *                secp256k1_nonce_function_bip340 is used, then ndata must be a- *                pointer to 32-byte auxiliary randomness as per BIP-340.+ *    aux_rand32: 32 bytes of fresh randomness. While recommended to provide+ *                this, it is only supplemental to security and can be NULL. See+ *                BIP-340 for a full explanation of this argument and for+ *                guidance if randomness is expensive.  */ SECP256K1_API int secp256k1_schnorrsig_sign(     const secp256k1_context* ctx,     unsigned char *sig64,-    const unsigned char *msg32,+    const unsigned char *msg,+    size_t msg_len,     const secp256k1_keypair *keypair,+    unsigned char *aux_rand32+) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(5);++/** Create a schnorrsig config (in dynamically allocated memory).+ *+ *  This function uses malloc to allocate memory. It is guaranteed that malloc is+ *  called at most once for every call of this function.+ *+ *  The allocated memory must be freed with secp256k1_schnorrsig_config_destroy.+ *+ *  Returns: a newly created schnorrsig config+ *  Args: ctx:  an existing context object (cannot be NULL)+ */+SECP256K1_API secp256k1_schnorrsig_config* secp256k1_schnorrsig_config_create(+    const secp256k1_context* ctx+) SECP256K1_ARG_NONNULL(1);++/** Destroy a schnorrsig config (created in dynamically allocated memory).+ *+ *  The config pointer may not be used afterwards.+ *  Args:  ctx: a secp256k1 context object+ *  In: config: the config to destroy+ */+SECP256K1_API void secp256k1_schnorrsig_config_destroy(+    const secp256k1_context* ctx,+    secp256k1_schnorrsig_config *config+) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2);++/** Set nonce function pointer and nonce data of a config object+ *+ *  Returns: 1 if the arguments are valid. 0 otherwise+ *  Args:  ctx: a secp256k1 context object+ *  In: config: the config to set the noncefp and ndata for+ *     noncefp: the nonce function pointer to set+ *       ndata: the nonce data to set+ */+SECP256K1_API int secp256k1_schnorrsig_config_set_nonce(+    const secp256k1_context* ctx,+    secp256k1_schnorrsig_config *config,     secp256k1_nonce_function_hardened noncefp,     void *ndata-) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4);+) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2);++/** Create a Schnorr signature with a more flexible API.+ *+ *  Same arguments as secp256k1_schnorrsig_sign except that it accepts a pointer+ *  to a config object that allows customizing signing by passing additional+ *  arguments.+ *+ *  In: noncefp: pointer to a nonce generation function. If NULL,+ *               secp256k1_nonce_function_bip340 is used+ *        ndata: pointer to arbitrary data used by the nonce generation function+ *               (can be NULL). If it is non-NULL and+ *               secp256k1_nonce_function_bip340 is used, then ndata must be a+ *               pointer to 32-byte auxiliary randomness as per BIP-340.+ *       config: pointer to a config object.+ */

fixed

jonasnick

comment created time in 2 hours

pull request commentbitcoin-core/secp256k1

WIP: schnorrsig API overhaul

I pushed a new version of this PR with two major change:

  1. The versioned struct for extra sign_custom parameters is removed. Versioned structs are useful for forward compatibility (i.e. application expecting newer library actually calls older library), but it's not clear what to do in case we add sign to contract members to the struct, but the library doesn't understand S2C yet. We can abort, but that's not really forward compatibility. Instead it's a simple struct now with a magic value which can be used to achieve backward compatibility. If we decide to change the struct, we also change the magic which then acts as a version number and allows libsecp to distinguish between different structs.
  2. The schnorrsig_sign function only accepts 32-byte messages again. Also, I added the public secp256k1_tagged_sha256 function to create tagged hashes according to BIP-340. The schnorrsig_sign doc explains that for messages that are not 32 bytes, one should use secp256k1_tagged_sha256 with a domain seperator. schnorrsig_sign_custom still allows truly signing variable length messages. As such, with libsecp both methods for variable length messages can be used, but one is clearly recommended to not confuse users and that's the one that currently has the most adoption (Taproot, DLCs, Lightning offers). And the additional tag argument to secp256k1_tagged_sha256 makes it harder to miss domain separation.

I also added tests and docs. Since this PR doesn't contradict the discussed BIP-340 changes, I removed the WIP status.

jonasnick

comment created time in 2 hours

more