Skip to content

Commit

Permalink
Squashed 'src/secp256k1/' changes from 7a30cb0c9d9..14620d13125
Browse files Browse the repository at this point in the history
14620d13125 rangeproof: add a "net blinding factor" API for Elements
d22774e248c Merge BlockstreamResearch/secp256k1-zkp#203: MuSig doc fixes
dd83e72d52d Add ordinary tweak info
d26100cab26 Exclude nonce_process from pre-processing steps
b7607f93f23 Fix reference to xonly_tweak_add
f7e9a8544f3 Merge BlockstreamResearch/secp256k1-zkp#201: rangeproof: add secp256k1_rangeproof_max_size function to estimate rangeproof size
6b6ced9839f rangeproof: add more max_size tests
34876ecb5fa rangeproof: add more static test vectors
310e5170619 rangeproof: add a bunch more testing
f1410cb67a2 rangeproof: add secp256k1_rangeproof_max_size function to estimate rangeproof size
c137ddbdff7 Merge BlockstreamResearch/secp256k1-zkp#200: build: automatically enable module dependencies
0202d839fb1 Merge BlockstreamResearch/secp256k1-zkp#199: surjectionproof: make sure that n_used_pubkeys > 0 in generate
5ac8fb035e8 surjectionproof: make sure that n_used_pubkeys > 0 in generate
7ff446df8b9 Merge BlockstreamResearch/secp256k1-zkp#198: rangeproof: add a test for all-zero blinding factors
5a40f3d99bb replace memcmp with secp256k1_memcmp_var throughout the codebase
92820d944b5 rangeproof: add a test for all-zero blinding factors
171b294a1c7 build: improve error message if --enable-experimental is missed
58ab152bb4b build: move all output concerning enabled modules at single place
1493113e61e build: automatically enable module dependencies
4fd7e1eabda Merge BlockstreamResearch/secp256k1-zkp#197: fix include paths in all the -zkp modules
347f96d94a6 fix include paths in all the -zkp modules
d1d6e47c17c Merge BlockstreamResearch/secp256k1-zkp#196: surjectionproof: fail to generate proofs when an input equals the output
d1175d265d5 surjectionproof: use secp256k1_memcmp_var rather than bare memcmp
bf18ff5a8c6 surjectionproof: fix generation to fail when any input == the output
4ff6e4274d4 surjectionproof: add test for existing behavior on input=output proofs
71a206fa5bb Merge BlockstreamResearch/secp256k1-zkp#194: extrakeys: rename swap/swap64 to fix OpenBSD 7.1 compilation
db648478c3c extrakeys: rename swap/swap64 to fix OpenBSD 7.1 compilation

git-subtree-dir: src/secp256k1
git-subtree-split: 14620d131250b141f4d3ab352fedac0aef45eb30
  • Loading branch information
apoelstra committed Sep 11, 2022
1 parent 35d6112 commit c443375
Show file tree
Hide file tree
Showing 25 changed files with 1,320 additions and 197 deletions.
83 changes: 33 additions & 50 deletions configure.ac
Original file line number Diff line number Diff line change
Expand Up @@ -385,6 +385,10 @@ SECP_CFLAGS="$SECP_CFLAGS $WERROR_CFLAGS"
### Handle module options
###

# Besides testing whether modules are enabled, the following code also enables
# module dependencies. The order of the tests matters: the dependency must be
# tested first.

if test x"$enable_module_ecdh" = x"yes"; then
AC_DEFINE(ENABLE_MODULE_ECDH, 1, [Define this symbol to enable the ECDH module])
fi
Expand All @@ -398,30 +402,30 @@ if test x"$enable_module_recovery" = x"yes"; then
AC_DEFINE(ENABLE_MODULE_RECOVERY, 1, [Define this symbol to enable the ECDSA pubkey recovery module])
fi

if test x"$enable_module_generator" = x"yes"; then
AC_DEFINE(ENABLE_MODULE_GENERATOR, 1, [Define this symbol to enable the NUMS generator module])
if test x"$enable_module_whitelist" = x"yes"; then
enable_module_rangeproof=yes
AC_DEFINE(ENABLE_MODULE_WHITELIST, 1, [Define this symbol to enable the key whitelisting module])
fi

if test x"$enable_module_surjectionproof" = x"yes"; then
enable_module_rangeproof=yes
AC_DEFINE(ENABLE_MODULE_SURJECTIONPROOF, 1, [Define this symbol to enable the surjection proof module])
fi

if test x"$enable_module_rangeproof" = x"yes"; then
enable_module_generator=yes
AC_DEFINE(ENABLE_MODULE_RANGEPROOF, 1, [Define this symbol to enable the Pedersen / zero knowledge range proof module])
fi

if test x"$enable_module_whitelist" = x"yes"; then
AC_DEFINE(ENABLE_MODULE_WHITELIST, 1, [Define this symbol to enable the key whitelisting module])
if test x"$enable_module_generator" = x"yes"; then
AC_DEFINE(ENABLE_MODULE_GENERATOR, 1, [Define this symbol to enable the NUMS generator module])
fi

if test x"$enable_module_surjectionproof" = x"yes"; then
AC_DEFINE(ENABLE_MODULE_SURJECTIONPROOF, 1, [Define this symbol to enable the surjection proof module])
fi
# Test if extrakeys is set _after_ the MuSig module to allow the MuSig
# module to set enable_module_schnorrsig=yes
if test x"$enable_module_schnorrsig" = x"yes"; then
AC_DEFINE(ENABLE_MODULE_SCHNORRSIG, 1, [Define this symbol to enable the schnorrsig module])
enable_module_extrakeys=yes
fi

# Test if extrakeys is set after the schnorrsig module to allow the schnorrsig
# module to set enable_module_extrakeys=yes
if test x"$enable_module_extrakeys" = x"yes"; then
AC_DEFINE(ENABLE_MODULE_EXTRAKEYS, 1, [Define this symbol to enable the extrakeys module])
fi
Expand Down Expand Up @@ -450,37 +454,24 @@ if test x"$enable_experimental" = x"yes"; then
AC_MSG_NOTICE([******])
AC_MSG_NOTICE([WARNING: experimental build])
AC_MSG_NOTICE([Experimental features do not have stable APIs or properties, and may not be safe for production use.])
AC_MSG_NOTICE([Building NUMS generator module: $enable_module_generator])
AC_MSG_NOTICE([Building range proof module: $enable_module_rangeproof])
AC_MSG_NOTICE([Building key whitelisting module: $enable_module_whitelist])
AC_MSG_NOTICE([Building surjection proof module: $enable_module_surjectionproof])
AC_MSG_NOTICE([Building MuSig module: $enable_module_musig])
AC_MSG_NOTICE([Building ECDSA sign-to-contract module: $enable_module_ecdsa_s2c])
AC_MSG_NOTICE([Building ECDSA adaptor signatures module: $enable_module_ecdsa_adaptor])
AC_MSG_NOTICE([******])


if test x"$enable_module_schnorrsig" != x"yes"; then
if test x"$enable_module_musig" = x"yes"; then
AC_MSG_ERROR([MuSig module requires the schnorrsig module. Use --enable-module-schnorrsig to allow.])
fi
else
# The order of the following tests matters. If the user enables a dependent
# module (which automatically enables the module dependencies) we want to
# print an error for the dependent module, not the module dependency. Hence,
# we first test dependent modules.
if test x"$enable_module_whitelist" = x"yes"; then
AC_MSG_ERROR([Key whitelisting module is experimental. Use --enable-experimental to allow.])
fi

if test x"$enable_module_generator" != x"yes"; then
if test x"$enable_module_rangeproof" = x"yes"; then
AC_MSG_ERROR([Rangeproof module requires the generator module. Use --enable-module-generator to allow.])
fi
if test x"$enable_module_surjectionproof" = x"yes"; then
AC_MSG_ERROR([Surjection proof module is experimental. Use --enable-experimental to allow.])
fi

if test x"$enable_module_rangeproof" != x"yes"; then
if test x"$enable_module_whitelist" = x"yes"; then
AC_MSG_ERROR([Whitelist module requires the rangeproof module. Use --enable-module-rangeproof to allow.])
fi
if test x"$enable_module_surjectionproof" = x"yes"; then
AC_MSG_ERROR([Surjection proof module requires the rangeproof module. Use --enable-module-rangeproof to allow.])
fi
if test x"$enable_module_rangeproof" = x"yes"; then
AC_MSG_ERROR([Range proof module is experimental. Use --enable-experimental to allow.])
fi
if test x"$enable_module_generator" = x"yes"; then
AC_MSG_ERROR([NUMS generator module is experimental. Use --enable-experimental to allow.])
fi
else
if test x"$enable_module_musig" = x"yes"; then
AC_MSG_ERROR([MuSig module is experimental. Use --enable-experimental to allow.])
fi
Expand All @@ -493,18 +484,6 @@ else
if test x"$set_asm" = x"arm"; then
AC_MSG_ERROR([ARM assembly optimization is experimental. Use --enable-experimental to allow.])
fi
if test x"$enable_module_generator" = x"yes"; then
AC_MSG_ERROR([NUMS generator module is experimental. Use --enable-experimental to allow.])
fi
if test x"$enable_module_rangeproof" = x"yes"; then
AC_MSG_ERROR([Range proof module is experimental. Use --enable-experimental to allow.])
fi
if test x"$enable_module_whitelist" = x"yes"; then
AC_MSG_ERROR([Key whitelisting module is experimental. Use --enable-experimental to allow.])
fi
if test x"$enable_module_surjectionproof" = x"yes"; then
AC_MSG_ERROR([Surjection proof module is experimental. Use --enable-experimental to allow.])
fi
fi

###
Expand Down Expand Up @@ -555,6 +534,10 @@ echo " module ecdh = $enable_module_ecdh"
echo " module recovery = $enable_module_recovery"
echo " module extrakeys = $enable_module_extrakeys"
echo " module schnorrsig = $enable_module_schnorrsig"
echo " module generator = $enable_module_generator"
echo " module rangeproof = $enable_module_rangeproof"
echo " module surjectionproof = $enable_module_surjectionproof"
echo " module whitelist = $enable_module_whitelist"
echo " module musig = $enable_module_musig"
echo " module ecdsa-s2c = $enable_module_ecdsa_s2c"
echo " module ecdsa-adaptor = $enable_module_ecdsa_adaptor"
Expand Down
82 changes: 81 additions & 1 deletion include/secp256k1_rangeproof.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,15 @@ extern "C" {

#include <stdint.h>

/** Length of a message that can be embedded into a maximally-sized rangeproof
*
* It is not be possible to fit a message of this size into a non-maximally-sized
* rangeproof, but it is guaranteed that any embeddable message can fit into an
* array of this size. This constant is intended to be used for memory allocations
* and sanity checks.
*/
#define SECP256K1_RANGEPROOF_MAX_MESSAGE_LEN 3968

/** Opaque data structure that stores a Pedersen commitment
*
* The exact representation of data inside is implementation defined and not
Expand Down Expand Up @@ -119,6 +128,49 @@ SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_pedersen_verify_tally(
size_t ncnt
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(4);

/** Compute the "net blinding factor" for an asset/amount pair of Pedersen commitments
*
* Returns 0 if either input is out of range, otherwise 1
* Args: ctx: a secp256k1 context object.
* Out: output: 32-byte array into which the result will be written
* In: val: the value of the amount commitment
* vbf: the amount commitment's blinding factor
* abf: the asset commitment's blinding factor
*
* This computse val*abf + vbf
*/
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_netbf_compute(
const secp256k1_context* ctx,
unsigned char* output,
uint64_t val,
const unsigned char* vbf,
const unsigned char* abf
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(4) SECP256K1_ARG_NONNULL(5);

/** Accumulate a net blinding factor
*
* Returns 0 if the input is out of range, otherwise 1
* Args: ctx: a secp256k1 context object.
* In/Out: acc: initially set to the current state of the accumulator; updated in place
* In: nbf: the net blinding factor to add to the accumulator
*/
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_netbf_acc(
const secp256k1_context* ctx,
unsigned char* acc,
const unsigned char* nbf
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3);

/** Negate a(n accumulated) net blinding factor
*
* Returns 0 if the input is out of range, otherwise 1
* Args: ctx: a secp256k1 context object.
* In/Out: acc: initially set to the bf to negate; changed to the negated version
*/
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_netbf_neg(
const secp256k1_context* ctx,
unsigned char* output
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2);

/** Sets the final Pedersen blinding factor correctly when the generators themselves
* have blinding factors.
*
Expand Down Expand Up @@ -227,7 +279,8 @@ SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_rangeproof_rewind(
* proof: pointer to array to receive the proof, can be up to 5134 bytes. (cannot be NULL)
* min_value: constructs a proof where the verifer can tell the minimum value is at least the specified amount.
* commit: the commitment being proved.
* blind: 32-byte blinding factor used by commit.
* blind: 32-byte blinding factor used by commit. The blinding factor may be all-zeros as long as min_bits is set to 3 or greater.
* This is a side-effect of the underlying crypto, not a deliberate API choice, but it may be useful when balancing CT transactions.
* nonce: 32-byte secret nonce used to initialize the proof (value can be reverse-engineered out of the proof if this secret is known.)
* exp: Base-10 exponent. Digits below above will be made public, but the proof will be made smaller. Allowed range is -1 to 18.
* (-1 is a special case that makes the value public. 0 is the most private.)
Expand Down Expand Up @@ -286,6 +339,33 @@ SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_rangeproof_info(
size_t plen
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4) SECP256K1_ARG_NONNULL(5);

/** Returns an upper bound on the size of a rangeproof with the given parameters
*
* An actual rangeproof may be smaller, for example if the actual value
* is less than both the provided `max_value` and 2^`min_bits`, or if
* the `exp` parameter to `secp256k1_rangeproof_sign` is set such that
* the proven range is compressed. In particular this function will always
* overestimate the size of single-value proofs. Also, if `min_value`
* is set to 0 in the proof, the result will usually, but not always,
* be 8 bytes smaller than if a nonzero value had been passed.
*
* The goal of this function is to provide a useful upper bound for
* memory allocation or fee estimation purposes, without requiring
* too many parameters be fixed in advance.
*
* To obtain the size of largest possible proof, set `max_value` to
* `UINT64_MAX` (and `min_bits` to any valid value such as 0).
*
* In: ctx: pointer to a context object
* max_value: the maximum value that might be passed for `value` for the proof.
* min_bits: the value that will be passed as `min_bits` for the proof.
*/
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT size_t secp256k1_rangeproof_max_size(
const secp256k1_context* ctx,
uint64_t max_value,
int min_bits
) SECP256K1_ARG_NONNULL(1);

# ifdef __cplusplus
}
# endif
Expand Down
4 changes: 2 additions & 2 deletions src/modules/ecdsa_adaptor/main_impl.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@
#ifndef SECP256K1_MODULE_ECDSA_ADAPTOR_MAIN_H
#define SECP256K1_MODULE_ECDSA_ADAPTOR_MAIN_H

#include "include/secp256k1_ecdsa_adaptor.h"
#include "modules/ecdsa_adaptor/dleq_impl.h"
#include "../../../include/secp256k1_ecdsa_adaptor.h"
#include "dleq_impl.h"

/* (R, R', s', dleq_proof) */
static int secp256k1_ecdsa_adaptor_sig_serialize(unsigned char *adaptor_sig162, secp256k1_ge *r, secp256k1_ge *rp, const secp256k1_scalar *sp, const secp256k1_scalar *dleq_proof_e, const secp256k1_scalar *dleq_proof_s) {
Expand Down
2 changes: 1 addition & 1 deletion src/modules/ecdsa_adaptor/tests_impl.h
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
#ifndef SECP256K1_MODULE_ECDSA_ADAPTOR_TESTS_H
#define SECP256K1_MODULE_ECDSA_ADAPTOR_TESTS_H

#include "include/secp256k1_ecdsa_adaptor.h"
#include "../../../include/secp256k1_ecdsa_adaptor.h"

void rand_scalar(secp256k1_scalar *scalar) {
unsigned char buf32[32];
Expand Down
4 changes: 2 additions & 2 deletions src/modules/ecdsa_s2c/main_impl.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@
#ifndef SECP256K1_MODULE_ECDSA_S2C_MAIN_H
#define SECP256K1_MODULE_ECDSA_S2C_MAIN_H

#include "include/secp256k1.h"
#include "include/secp256k1_ecdsa_s2c.h"
#include "../../../include/secp256k1.h"
#include "../../../include/secp256k1_ecdsa_s2c.h"

static void secp256k1_ecdsa_s2c_opening_save(secp256k1_ecdsa_s2c_opening* opening, secp256k1_ge* ge) {
secp256k1_pubkey_save((secp256k1_pubkey*) opening, ge);
Expand Down
10 changes: 5 additions & 5 deletions src/modules/ecdsa_s2c/tests_impl.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
#ifndef SECP256K1_MODULE_ECDSA_S2C_TESTS_H
#define SECP256K1_MODULE_ECDSA_S2C_TESTS_H

#include "include/secp256k1_ecdsa_s2c.h"
#include "../../../include/secp256k1_ecdsa_s2c.h"

static void test_ecdsa_s2c_tagged_hash(void) {
unsigned char tag_data[14] = "s2c/ecdsa/data";
Expand Down Expand Up @@ -78,7 +78,7 @@ void run_s2c_opening_test(void) {
* points' x-coordinates are uniformly random */
if (secp256k1_ecdsa_s2c_opening_parse(none, &opening, input) == 1) {
CHECK(secp256k1_ecdsa_s2c_opening_serialize(none, output, &opening) == 1);
CHECK(memcmp(output, input, sizeof(output)) == 0);
CHECK(secp256k1_memcmp_var(output, input, sizeof(output)) == 0);
}
secp256k1_testrand256(&input[1]);
/* Set pubkey oddness tag to first bit of input[1] */
Expand Down Expand Up @@ -255,7 +255,7 @@ static void test_ecdsa_s2c_fixed_vectors(void) {
secp256k1_ecdsa_signature signature;
CHECK(secp256k1_ecdsa_s2c_sign(ctx, &signature, &s2c_opening, message, privkey, test->s2c_data) == 1);
CHECK(secp256k1_ecdsa_s2c_opening_serialize(ctx, opening_ser, &s2c_opening) == 1);
CHECK(memcmp(test->expected_s2c_opening, opening_ser, sizeof(opening_ser)) == 0);
CHECK(secp256k1_memcmp_var(test->expected_s2c_opening, opening_ser, sizeof(opening_ser)) == 0);
CHECK(secp256k1_ecdsa_s2c_verify_commit(ctx, &signature, test->s2c_data, &s2c_opening) == 1);
}
}
Expand Down Expand Up @@ -331,7 +331,7 @@ static void test_ecdsa_anti_exfil_signer_commit(void) {
const ecdsa_s2c_test *test = &ecdsa_s2c_tests[i];
CHECK(secp256k1_ecdsa_anti_exfil_signer_commit(ctx, &s2c_opening, message, privkey, test->s2c_data) == 1);
CHECK(secp256k1_ecdsa_s2c_opening_serialize(ctx, buf, &s2c_opening) == 1);
CHECK(memcmp(test->expected_s2c_exfil_opening, buf, sizeof(buf)) == 0);
CHECK(secp256k1_memcmp_var(test->expected_s2c_exfil_opening, buf, sizeof(buf)) == 0);
}
}

Expand Down Expand Up @@ -397,7 +397,7 @@ static void test_ecdsa_anti_exfil(void) {
CHECK(secp256k1_ecdsa_verify(ctx, &signature, host_msg, &signer_pubkey) == 1);
CHECK(secp256k1_anti_exfil_host_verify(ctx, &signature, host_msg, &signer_pubkey, host_nonce_contribution, &s2c_opening) == 0);
CHECK(secp256k1_anti_exfil_host_verify(ctx, &signature, host_msg, &signer_pubkey, bad_nonce_contribution, &s2c_opening) == 1);
CHECK(memcmp(&s2c_opening, &orig_opening, sizeof(s2c_opening)) != 0);
CHECK(secp256k1_memcmp_var(&s2c_opening, &orig_opening, sizeof(s2c_opening)) != 0);
}
}

Expand Down
14 changes: 7 additions & 7 deletions src/modules/extrakeys/hsort_impl.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,20 +23,20 @@ static SECP256K1_INLINE size_t child2(size_t i) {
return child1(i)+1;
}

static SECP256K1_INLINE void swap64(unsigned char *a, size_t i, size_t j, size_t stride) {
static SECP256K1_INLINE void heap_swap64(unsigned char *a, size_t i, size_t j, size_t stride) {
unsigned char tmp[64];
VERIFY_CHECK(stride <= 64);
memcpy(tmp, a + i*stride, stride);
memmove(a + i*stride, a + j*stride, stride);
memcpy(a + j*stride, tmp, stride);
}

static SECP256K1_INLINE void swap(unsigned char *a, size_t i, size_t j, size_t stride) {
static SECP256K1_INLINE void heap_swap(unsigned char *a, size_t i, size_t j, size_t stride) {
while (64 < stride) {
swap64(a + (stride - 64), i, j, 64);
heap_swap64(a + (stride - 64), i, j, 64);
stride -= 64;
}
swap64(a, i, j, stride);
heap_swap64(a, i, j, stride);
}

static SECP256K1_INLINE void heap_down(unsigned char *a, size_t i, size_t heap_size, size_t stride,
Expand Down Expand Up @@ -71,7 +71,7 @@ static SECP256K1_INLINE void heap_down(unsigned char *a, size_t i, size_t heap_s
if (child2(i) < heap_size
&& 0 <= cmp(a + child2(i)*stride, a + child1(i)*stride, cmp_data)) {
if (0 < cmp(a + child2(i)*stride, a + i*stride, cmp_data)) {
swap(a, i, child2(i), stride);
heap_swap(a, i, child2(i), stride);
i = child2(i);
} else {
/* At this point we have [child2(i)] >= [child1(i)] and we have
Expand All @@ -80,7 +80,7 @@ static SECP256K1_INLINE void heap_down(unsigned char *a, size_t i, size_t heap_s
return;
}
} else if (0 < cmp(a + child1(i)*stride, a + i*stride, cmp_data)) {
swap(a, i, child1(i), stride);
heap_swap(a, i, child1(i), stride);
i = child1(i);
} else {
return;
Expand All @@ -106,7 +106,7 @@ static void secp256k1_hsort(void *ptr, size_t count, size_t size,
}
for(i = count; 1 < i; --i) {
/* Extract the largest value from the heap */
swap(ptr, 0, i-1, size);
heap_swap(ptr, 0, i-1, size);

/* Repair the heap condition */
heap_down(ptr, 0, i-1, size, cmp, cmp_data);
Expand Down
8 changes: 4 additions & 4 deletions src/modules/generator/main_impl.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,10 @@

#include <stdio.h>

#include "field.h"
#include "group.h"
#include "hash.h"
#include "scalar.h"
#include "../../field.h"
#include "../../group.h"
#include "../../hash.h"
#include "../../scalar.h"

static void secp256k1_generator_load(secp256k1_ge* ge, const secp256k1_generator* gen) {
int succeed;
Expand Down
Loading

0 comments on commit c443375

Please sign in to comment.