From 87373f51451bed948340d6885111d04051cbfc02 Mon Sep 17 00:00:00 2001 From: Andrew Poelstra Date: Sat, 27 Aug 2022 14:55:38 +0000 Subject: [PATCH] MOVE ONLY: move Pedersen commitment stuff to generator module from rangeproof module You can verify this commit with `git diff --color-moved=zebra` --- include/secp256k1_generator.h | 148 ++++++++++++ include/secp256k1_rangeproof.h | 148 ------------ src/modules/generator/Makefile.am.include | 2 + src/modules/generator/main_impl.h | 219 +++++++++++++++++ .../{rangeproof => generator}/pedersen.h | 0 .../{rangeproof => generator}/pedersen_impl.h | 0 src/modules/generator/tests_impl.h | 163 +++++++++++++ src/modules/rangeproof/Makefile.am.include | 2 - src/modules/rangeproof/main_impl.h | 222 +----------------- src/modules/rangeproof/rangeproof_impl.h | 6 +- src/modules/rangeproof/tests_impl.h | 142 ----------- src/secp256k1.c | 2 - 12 files changed, 538 insertions(+), 516 deletions(-) rename src/modules/{rangeproof => generator}/pedersen.h (100%) rename src/modules/{rangeproof => generator}/pedersen_impl.h (100%) diff --git a/include/secp256k1_generator.h b/include/secp256k1_generator.h index cb55af91..5479fc81 100644 --- a/include/secp256k1_generator.h +++ b/include/secp256k1_generator.h @@ -21,6 +21,11 @@ typedef struct { unsigned char data[64]; } secp256k1_generator; +/** + * Static constant generator 'h' maintained for historical reasons. + */ +SECP256K1_API extern const secp256k1_generator *secp256k1_generator_h; + /** Parse a 33-byte generator byte sequence into a generator object. * * Returns: 1 if input contains a valid generator. @@ -86,6 +91,149 @@ SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_generator_generate_blin const unsigned char *blind32 ) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4); +/** Opaque data structure that stores a Pedersen commitment + * + * The exact representation of data inside is implementation defined and not + * guaranteed to be portable between different platforms or versions. It is + * however guaranteed to be 64 bytes in size, and can be safely copied/moved. + * If you need to convert to a format suitable for storage, transmission, or + * comparison, use secp256k1_pedersen_commitment_serialize and + * secp256k1_pedersen_commitment_parse. + */ +typedef struct { + unsigned char data[64]; +} secp256k1_pedersen_commitment; + +/** Parse a 33-byte commitment into a commitment object. + * + * Returns: 1 if input contains a valid commitment. + * Args: ctx: a secp256k1 context object. + * Out: commit: pointer to the output commitment object + * In: input: pointer to a 33-byte serialized commitment key + */ +SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_pedersen_commitment_parse( + const secp256k1_context* ctx, + secp256k1_pedersen_commitment* commit, + const unsigned char *input +) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3); + +/** Serialize a commitment object into a serialized byte sequence. + * + * Returns: 1 always. + * Args: ctx: a secp256k1 context object. + * Out: output: a pointer to a 33-byte byte array + * In: commit: a pointer to a secp256k1_pedersen_commitment containing an + * initialized commitment + */ +SECP256K1_API int secp256k1_pedersen_commitment_serialize( + const secp256k1_context* ctx, + unsigned char *output, + const secp256k1_pedersen_commitment* commit +) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3); + +/** Generate a pedersen commitment. + * Returns 1: Commitment successfully created. + * 0: Error. The blinding factor is larger than the group order + * (probability for random 32 byte number < 2^-127) or results in the + * point at infinity. Retry with a different factor. + * In: ctx: pointer to a context object, initialized for signing and Pedersen commitment (cannot be NULL) + * blind: pointer to a 32-byte blinding factor (cannot be NULL) + * value: unsigned 64-bit integer value to commit to. + * gen: additional generator 'h' + * Out: commit: pointer to the commitment (cannot be NULL) + * + * Blinding factors can be generated and verified in the same way as secp256k1 private keys for ECDSA. + */ +SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_pedersen_commit( + const secp256k1_context* ctx, + secp256k1_pedersen_commitment *commit, + const unsigned char *blind, + uint64_t value, + const secp256k1_generator *gen +) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(5); + +/** Computes the sum of multiple positive and negative blinding factors. + * Returns 1: Sum successfully computed. + * 0: Error. A blinding factor is larger than the group order + * (probability for random 32 byte number < 2^-127). Retry with + * different factors. + * In: ctx: pointer to a context object (cannot be NULL) + * blinds: pointer to pointers to 32-byte character arrays for blinding factors. (cannot be NULL) + * n: number of factors pointed to by blinds. + * npositive: how many of the initial factors should be treated with a positive sign. + * Out: blind_out: pointer to a 32-byte array for the sum (cannot be NULL) + */ +SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_pedersen_blind_sum( + const secp256k1_context* ctx, + unsigned char *blind_out, + const unsigned char * const *blinds, + size_t n, + size_t npositive +) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3); + +/** Verify a tally of pedersen commitments + * Returns 1: commitments successfully sum to zero. + * 0: Commitments do not sum to zero or other error. + * In: ctx: pointer to a context object (cannot be NULL) + * commits: pointer to array of pointers to the commitments. (cannot be NULL if pcnt is non-zero) + * pcnt: number of commitments pointed to by commits. + * ncommits: pointer to array of pointers to the negative commitments. (cannot be NULL if ncnt is non-zero) + * ncnt: number of commitments pointed to by ncommits. + * + * This computes sum(commit[0..pcnt)) - sum(ncommit[0..ncnt)) == 0. + * + * A pedersen commitment is xG + vA where G and A are generators for the secp256k1 group and x is a blinding factor, + * while v is the committed value. For a collection of commitments to sum to zero, for each distinct generator + * A all blinding factors and all values must sum to zero. + * + */ +SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_pedersen_verify_tally( + const secp256k1_context* ctx, + const secp256k1_pedersen_commitment * const* commits, + size_t pcnt, + const secp256k1_pedersen_commitment * const* ncommits, + size_t ncnt +) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(4); + +/** Sets the final Pedersen blinding factor correctly when the generators themselves + * have blinding factors. + * + * Consider a generator of the form A' = A + rG, where A is the "real" generator + * but A' is the generator provided to verifiers. Then a Pedersen commitment + * P = vA' + r'G really has the form vA + (vr + r')G. To get all these (vr + r') + * to sum to zero for multiple commitments, we take three arrays consisting of + * the `v`s, `r`s, and `r'`s, respectively called `value`s, `generator_blind`s + * and `blinding_factor`s, and sum them. + * + * The function then subtracts the sum of all (vr + r') from the last element + * of the `blinding_factor` array, setting the total sum to zero. + * + * Returns 1: Blinding factor successfully computed. + * 0: Error. A blinding_factor or generator_blind are larger than the group + * order (probability for random 32 byte number < 2^-127). Retry with + * different values. + * + * In: ctx: pointer to a context object + * value: array of asset values, `v` in the above paragraph. + * May not be NULL unless `n_total` is 0. + * generator_blind: array of asset blinding factors, `r` in the above paragraph + * May not be NULL unless `n_total` is 0. + * n_total: Total size of the above arrays + * n_inputs: How many of the initial array elements represent commitments that + * will be negated in the final sum + * In/Out: blinding_factor: array of commitment blinding factors, `r'` in the above paragraph + * May not be NULL unless `n_total` is 0. + * the last value will be modified to get the total sum to zero. + */ +SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_pedersen_blind_generator_blind_sum( + const secp256k1_context* ctx, + const uint64_t *value, + const unsigned char* const* generator_blind, + unsigned char* const* blinding_factor, + size_t n_total, + size_t n_inputs +); + # ifdef __cplusplus } # endif diff --git a/include/secp256k1_rangeproof.h b/include/secp256k1_rangeproof.h index 9bb01454..2d86ab06 100644 --- a/include/secp256k1_rangeproof.h +++ b/include/secp256k1_rangeproof.h @@ -19,154 +19,6 @@ extern "C" { */ #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 - * guaranteed to be portable between different platforms or versions. It is - * however guaranteed to be 64 bytes in size, and can be safely copied/moved. - * If you need to convert to a format suitable for storage, transmission, or - * comparison, use secp256k1_pedersen_commitment_serialize and - * secp256k1_pedersen_commitment_parse. - */ -typedef struct { - unsigned char data[64]; -} secp256k1_pedersen_commitment; - -/** - * Static constant generator 'h' maintained for historical reasons. - */ -SECP256K1_API extern const secp256k1_generator *secp256k1_generator_h; - -/** Parse a 33-byte commitment into a commitment object. - * - * Returns: 1 if input contains a valid commitment. - * Args: ctx: a secp256k1 context object. - * Out: commit: pointer to the output commitment object - * In: input: pointer to a 33-byte serialized commitment key - */ -SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_pedersen_commitment_parse( - const secp256k1_context* ctx, - secp256k1_pedersen_commitment* commit, - const unsigned char *input -) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3); - -/** Serialize a commitment object into a serialized byte sequence. - * - * Returns: 1 always. - * Args: ctx: a secp256k1 context object. - * Out: output: a pointer to a 33-byte byte array - * In: commit: a pointer to a secp256k1_pedersen_commitment containing an - * initialized commitment - */ -SECP256K1_API int secp256k1_pedersen_commitment_serialize( - const secp256k1_context* ctx, - unsigned char *output, - const secp256k1_pedersen_commitment* commit -) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3); - -/** Generate a pedersen commitment. - * Returns 1: Commitment successfully created. - * 0: Error. The blinding factor is larger than the group order - * (probability for random 32 byte number < 2^-127) or results in the - * point at infinity. Retry with a different factor. - * In: ctx: pointer to a context object, initialized for signing and Pedersen commitment (cannot be NULL) - * blind: pointer to a 32-byte blinding factor (cannot be NULL) - * value: unsigned 64-bit integer value to commit to. - * gen: additional generator 'h' - * Out: commit: pointer to the commitment (cannot be NULL) - * - * Blinding factors can be generated and verified in the same way as secp256k1 private keys for ECDSA. - */ -SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_pedersen_commit( - const secp256k1_context* ctx, - secp256k1_pedersen_commitment *commit, - const unsigned char *blind, - uint64_t value, - const secp256k1_generator *gen -) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(5); - -/** Computes the sum of multiple positive and negative blinding factors. - * Returns 1: Sum successfully computed. - * 0: Error. A blinding factor is larger than the group order - * (probability for random 32 byte number < 2^-127). Retry with - * different factors. - * In: ctx: pointer to a context object (cannot be NULL) - * blinds: pointer to pointers to 32-byte character arrays for blinding factors. (cannot be NULL) - * n: number of factors pointed to by blinds. - * npositive: how many of the initial factors should be treated with a positive sign. - * Out: blind_out: pointer to a 32-byte array for the sum (cannot be NULL) - */ -SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_pedersen_blind_sum( - const secp256k1_context* ctx, - unsigned char *blind_out, - const unsigned char * const *blinds, - size_t n, - size_t npositive -) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3); - -/** Verify a tally of pedersen commitments - * Returns 1: commitments successfully sum to zero. - * 0: Commitments do not sum to zero or other error. - * In: ctx: pointer to a context object (cannot be NULL) - * commits: pointer to array of pointers to the commitments. (cannot be NULL if pcnt is non-zero) - * pcnt: number of commitments pointed to by commits. - * ncommits: pointer to array of pointers to the negative commitments. (cannot be NULL if ncnt is non-zero) - * ncnt: number of commitments pointed to by ncommits. - * - * This computes sum(commit[0..pcnt)) - sum(ncommit[0..ncnt)) == 0. - * - * A pedersen commitment is xG + vA where G and A are generators for the secp256k1 group and x is a blinding factor, - * while v is the committed value. For a collection of commitments to sum to zero, for each distinct generator - * A all blinding factors and all values must sum to zero. - * - */ -SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_pedersen_verify_tally( - const secp256k1_context* ctx, - const secp256k1_pedersen_commitment * const* commits, - size_t pcnt, - const secp256k1_pedersen_commitment * const* ncommits, - size_t ncnt -) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(4); - -/** Sets the final Pedersen blinding factor correctly when the generators themselves - * have blinding factors. - * - * Consider a generator of the form A' = A + rG, where A is the "real" generator - * but A' is the generator provided to verifiers. Then a Pedersen commitment - * P = vA' + r'G really has the form vA + (vr + r')G. To get all these (vr + r') - * to sum to zero for multiple commitments, we take three arrays consisting of - * the `v`s, `r`s, and `r'`s, respectively called `value`s, `generator_blind`s - * and `blinding_factor`s, and sum them. - * - * The function then subtracts the sum of all (vr + r') from the last element - * of the `blinding_factor` array, setting the total sum to zero. - * - * Returns 1: Blinding factor successfully computed. - * 0: Error. A blinding_factor or generator_blind are larger than the group - * order (probability for random 32 byte number < 2^-127). Retry with - * different values. - * - * In: ctx: pointer to a context object - * value: array of asset values, `v` in the above paragraph. - * May not be NULL unless `n_total` is 0. - * generator_blind: array of asset blinding factors, `r` in the above paragraph - * May not be NULL unless `n_total` is 0. - * n_total: Total size of the above arrays - * n_inputs: How many of the initial array elements represent commitments that - * will be negated in the final sum - * In/Out: blinding_factor: array of commitment blinding factors, `r'` in the above paragraph - * May not be NULL unless `n_total` is 0. - * the last value will be modified to get the total sum to zero. - */ -SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_pedersen_blind_generator_blind_sum( - const secp256k1_context* ctx, - const uint64_t *value, - const unsigned char* const* generator_blind, - unsigned char* const* blinding_factor, - size_t n_total, - size_t n_inputs -); - /** Verify a proof that a committed value is within a range. * Returns 1: Value is within the range [0..2^64), the specifically proven range is in the min/max value outputs. * 0: Proof failed or other error. diff --git a/src/modules/generator/Makefile.am.include b/src/modules/generator/Makefile.am.include index 69933e99..4119966c 100644 --- a/src/modules/generator/Makefile.am.include +++ b/src/modules/generator/Makefile.am.include @@ -1,4 +1,6 @@ include_HEADERS += include/secp256k1_generator.h +noinst_HEADERS += src/modules/generator/pedersen.h +noinst_HEADERS += src/modules/generator/pedersen_impl.h noinst_HEADERS += src/modules/generator/main_impl.h noinst_HEADERS += src/modules/generator/tests_impl.h if USE_BENCHMARK diff --git a/src/modules/generator/main_impl.h b/src/modules/generator/main_impl.h index c915c791..c9f6ec8b 100644 --- a/src/modules/generator/main_impl.h +++ b/src/modules/generator/main_impl.h @@ -14,6 +14,29 @@ #include "../../hash.h" #include "../../scalar.h" +#include "modules/generator/pedersen_impl.h" + +/** Alternative generator for secp256k1. + * This is the sha256 of 'g' after standard encoding (without compression), + * which happens to be a point on the curve. More precisely, the generator is + * derived by running the following script with the sage mathematics software. + + import hashlib + F = FiniteField (0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F) + G = '0479be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8' + H = EllipticCurve ([F (0), F (7)]).lift_x(F(int(hashlib.sha256(G.decode('hex')).hexdigest(),16))) + print('%x %x' % H.xy()) + */ +static const secp256k1_generator secp256k1_generator_h_internal = {{ + 0x50, 0x92, 0x9b, 0x74, 0xc1, 0xa0, 0x49, 0x54, 0xb7, 0x8b, 0x4b, 0x60, 0x35, 0xe9, 0x7a, 0x5e, + 0x07, 0x8a, 0x5a, 0x0f, 0x28, 0xec, 0x96, 0xd5, 0x47, 0xbf, 0xee, 0x9a, 0xce, 0x80, 0x3a, 0xc0, + 0x31, 0xd3, 0xc6, 0x86, 0x39, 0x73, 0x92, 0x6e, 0x04, 0x9e, 0x63, 0x7c, 0xb1, 0xb5, 0xf4, 0x0a, + 0x36, 0xda, 0xc2, 0x8a, 0xf1, 0x76, 0x69, 0x68, 0xc3, 0x0c, 0x23, 0x13, 0xf3, 0xa3, 0x89, 0x04 +}}; + +const secp256k1_generator *secp256k1_generator_h = &secp256k1_generator_h_internal; + + static void secp256k1_generator_load(secp256k1_ge* ge, const secp256k1_generator* gen) { int succeed; succeed = secp256k1_fe_set_b32(&ge->x, &gen->data[0]); @@ -219,4 +242,200 @@ int secp256k1_generator_generate_blinded(const secp256k1_context* ctx, secp256k1 return secp256k1_generator_generate_internal(ctx, gen, key32, blind32); } +static void secp256k1_pedersen_commitment_load(secp256k1_ge* ge, const secp256k1_pedersen_commitment* commit) { + secp256k1_fe fe; + secp256k1_fe_set_b32(&fe, &commit->data[1]); + secp256k1_ge_set_xquad(ge, &fe); + if (commit->data[0] & 1) { + secp256k1_ge_neg(ge, ge); + } +} + +static void secp256k1_pedersen_commitment_save(secp256k1_pedersen_commitment* commit, secp256k1_ge* ge) { + secp256k1_fe_normalize(&ge->x); + secp256k1_fe_get_b32(&commit->data[1], &ge->x); + commit->data[0] = 9 ^ secp256k1_fe_is_quad_var(&ge->y); +} + +int secp256k1_pedersen_commitment_parse(const secp256k1_context* ctx, secp256k1_pedersen_commitment* commit, const unsigned char *input) { + secp256k1_fe x; + secp256k1_ge ge; + + VERIFY_CHECK(ctx != NULL); + ARG_CHECK(commit != NULL); + ARG_CHECK(input != NULL); + (void) ctx; + + if ((input[0] & 0xFE) != 8 || + !secp256k1_fe_set_b32(&x, &input[1]) || + !secp256k1_ge_set_xquad(&ge, &x)) { + return 0; + } + if (input[0] & 1) { + secp256k1_ge_neg(&ge, &ge); + } + secp256k1_pedersen_commitment_save(commit, &ge); + return 1; +} + +int secp256k1_pedersen_commitment_serialize(const secp256k1_context* ctx, unsigned char *output, const secp256k1_pedersen_commitment* commit) { + secp256k1_ge ge; + + VERIFY_CHECK(ctx != NULL); + ARG_CHECK(output != NULL); + ARG_CHECK(commit != NULL); + + secp256k1_pedersen_commitment_load(&ge, commit); + + output[0] = 9 ^ secp256k1_fe_is_quad_var(&ge.y); + secp256k1_fe_normalize_var(&ge.x); + secp256k1_fe_get_b32(&output[1], &ge.x); + return 1; +} + +/* Generates a pedersen commitment: *commit = blind * G + value * G2. The blinding factor is 32 bytes.*/ +int secp256k1_pedersen_commit(const secp256k1_context* ctx, secp256k1_pedersen_commitment *commit, const unsigned char *blind, uint64_t value, const secp256k1_generator* gen) { + secp256k1_ge genp; + secp256k1_gej rj; + secp256k1_ge r; + secp256k1_scalar sec; + int overflow; + int ret = 0; + VERIFY_CHECK(ctx != NULL); + ARG_CHECK(secp256k1_ecmult_gen_context_is_built(&ctx->ecmult_gen_ctx)); + ARG_CHECK(commit != NULL); + ARG_CHECK(blind != NULL); + ARG_CHECK(gen != NULL); + secp256k1_generator_load(&genp, gen); + secp256k1_scalar_set_b32(&sec, blind, &overflow); + if (!overflow) { + secp256k1_pedersen_ecmult(&ctx->ecmult_gen_ctx, &rj, &sec, value, &genp); + if (!secp256k1_gej_is_infinity(&rj)) { + secp256k1_ge_set_gej(&r, &rj); + secp256k1_pedersen_commitment_save(commit, &r); + ret = 1; + } + secp256k1_gej_clear(&rj); + secp256k1_ge_clear(&r); + } + secp256k1_scalar_clear(&sec); + return ret; +} + +/** Takes a list of n pointers to 32 byte blinding values, the first negs of which are treated with positive sign and the rest + * negative, then calculates an additional blinding value that adds to zero. + */ +int secp256k1_pedersen_blind_sum(const secp256k1_context* ctx, unsigned char *blind_out, const unsigned char * const *blinds, size_t n, size_t npositive) { + secp256k1_scalar acc; + secp256k1_scalar x; + size_t i; + int overflow; + VERIFY_CHECK(ctx != NULL); + ARG_CHECK(blind_out != NULL); + ARG_CHECK(blinds != NULL); + ARG_CHECK(npositive <= n); + (void) ctx; + secp256k1_scalar_set_int(&acc, 0); + for (i = 0; i < n; i++) { + secp256k1_scalar_set_b32(&x, blinds[i], &overflow); + if (overflow) { + return 0; + } + if (i >= npositive) { + secp256k1_scalar_negate(&x, &x); + } + secp256k1_scalar_add(&acc, &acc, &x); + } + secp256k1_scalar_get_b32(blind_out, &acc); + secp256k1_scalar_clear(&acc); + secp256k1_scalar_clear(&x); + return 1; +} + +/* Takes two lists of commitments and sums the first set and subtracts the second and verifies that they sum to excess. */ +int secp256k1_pedersen_verify_tally(const secp256k1_context* ctx, const secp256k1_pedersen_commitment * const* commits, size_t pcnt, const secp256k1_pedersen_commitment * const* ncommits, size_t ncnt) { + secp256k1_gej accj; + secp256k1_ge add; + size_t i; + VERIFY_CHECK(ctx != NULL); + ARG_CHECK(!pcnt || (commits != NULL)); + ARG_CHECK(!ncnt || (ncommits != NULL)); + (void) ctx; + secp256k1_gej_set_infinity(&accj); + for (i = 0; i < ncnt; i++) { + secp256k1_pedersen_commitment_load(&add, ncommits[i]); + secp256k1_gej_add_ge_var(&accj, &accj, &add, NULL); + } + secp256k1_gej_neg(&accj, &accj); + for (i = 0; i < pcnt; i++) { + secp256k1_pedersen_commitment_load(&add, commits[i]); + secp256k1_gej_add_ge_var(&accj, &accj, &add, NULL); + } + return secp256k1_gej_is_infinity(&accj); +} + +int secp256k1_pedersen_blind_generator_blind_sum(const secp256k1_context* ctx, const uint64_t *value, const unsigned char* const* generator_blind, unsigned char* const* blinding_factor, size_t n_total, size_t n_inputs) { + secp256k1_scalar sum; + secp256k1_scalar tmp; + size_t i; + + VERIFY_CHECK(ctx != NULL); + ARG_CHECK(n_total == 0 || value != NULL); + ARG_CHECK(n_total == 0 || generator_blind != NULL); + ARG_CHECK(n_total == 0 || blinding_factor != NULL); + ARG_CHECK(n_total > n_inputs); + (void) ctx; + + if (n_total == 0) { + return 1; + } + + secp256k1_scalar_set_int(&sum, 0); + + /* Here, n_total > 0. Thus the loop runs at least once. + Thus we may use a do-while loop, which checks the loop + condition only at the end. + + The do-while loop helps GCC prove that the loop runs at least + once and suppresses a -Wmaybe-uninitialized warning. */ + i = 0; + do { + int overflow = 0; + secp256k1_scalar addend; + secp256k1_scalar_set_u64(&addend, value[i]); /* s = v */ + + secp256k1_scalar_set_b32(&tmp, generator_blind[i], &overflow); + if (overflow == 1) { + secp256k1_scalar_clear(&tmp); + secp256k1_scalar_clear(&addend); + secp256k1_scalar_clear(&sum); + return 0; + } + secp256k1_scalar_mul(&addend, &addend, &tmp); /* s = vr */ + + secp256k1_scalar_set_b32(&tmp, blinding_factor[i], &overflow); + if (overflow == 1) { + secp256k1_scalar_clear(&tmp); + secp256k1_scalar_clear(&addend); + secp256k1_scalar_clear(&sum); + return 0; + } + secp256k1_scalar_add(&addend, &addend, &tmp); /* s = vr + r' */ + secp256k1_scalar_cond_negate(&addend, i < n_inputs); /* s is negated if it's an input */ + secp256k1_scalar_add(&sum, &sum, &addend); /* sum += s */ + secp256k1_scalar_clear(&addend); + + i++; + } while (i < n_total); + + /* Right now tmp has the last pedersen blinding factor. Subtract the sum from it. */ + secp256k1_scalar_negate(&sum, &sum); + secp256k1_scalar_add(&tmp, &tmp, &sum); + secp256k1_scalar_get_b32(blinding_factor[n_total - 1], &tmp); + + secp256k1_scalar_clear(&tmp); + secp256k1_scalar_clear(&sum); + return 1; +} + #endif diff --git a/src/modules/rangeproof/pedersen.h b/src/modules/generator/pedersen.h similarity index 100% rename from src/modules/rangeproof/pedersen.h rename to src/modules/generator/pedersen.h diff --git a/src/modules/rangeproof/pedersen_impl.h b/src/modules/generator/pedersen_impl.h similarity index 100% rename from src/modules/rangeproof/pedersen_impl.h rename to src/modules/generator/pedersen_impl.h diff --git a/src/modules/generator/tests_impl.h b/src/modules/generator/tests_impl.h index 9f36f83d..b49ecae9 100644 --- a/src/modules/generator/tests_impl.h +++ b/src/modules/generator/tests_impl.h @@ -223,11 +223,174 @@ void test_generator_fixed_vector(void) { CHECK(!secp256k1_generator_parse(ctx, &parse, result)); } +static void test_pedersen_api(void) { + secp256k1_context *none = secp256k1_context_create(SECP256K1_CONTEXT_NONE); + secp256k1_context *sign = secp256k1_context_create(SECP256K1_CONTEXT_SIGN); + secp256k1_context *vrfy = secp256k1_context_create(SECP256K1_CONTEXT_VERIFY); + secp256k1_context *sttc = secp256k1_context_clone(secp256k1_context_no_precomp); + secp256k1_pedersen_commitment commit; + const secp256k1_pedersen_commitment *commit_ptr = &commit; + unsigned char blind[32]; + unsigned char blind_out[32]; + const unsigned char *blind_ptr = blind; + unsigned char *blind_out_ptr = blind_out; + uint64_t val = secp256k1_testrand32(); + int32_t ecount = 0; + + secp256k1_context_set_error_callback(none, counting_illegal_callback_fn, &ecount); + secp256k1_context_set_error_callback(sign, counting_illegal_callback_fn, &ecount); + secp256k1_context_set_error_callback(vrfy, counting_illegal_callback_fn, &ecount); + secp256k1_context_set_error_callback(sttc, counting_illegal_callback_fn, &ecount); + secp256k1_context_set_illegal_callback(none, counting_illegal_callback_fn, &ecount); + secp256k1_context_set_illegal_callback(sign, counting_illegal_callback_fn, &ecount); + secp256k1_context_set_illegal_callback(vrfy, counting_illegal_callback_fn, &ecount); + secp256k1_context_set_illegal_callback(sttc, counting_illegal_callback_fn, &ecount); + + secp256k1_testrand256(blind); + CHECK(secp256k1_pedersen_commit(none, &commit, blind, val, secp256k1_generator_h) != 0); + CHECK(secp256k1_pedersen_commit(vrfy, &commit, blind, val, secp256k1_generator_h) != 0); + CHECK(secp256k1_pedersen_commit(sign, &commit, blind, val, secp256k1_generator_h) != 0); + CHECK(ecount == 0); + CHECK(secp256k1_pedersen_commit(sttc, &commit, blind, val, secp256k1_generator_h) == 0); + CHECK(ecount == 1); + + CHECK(secp256k1_pedersen_commit(sign, NULL, blind, val, secp256k1_generator_h) == 0); + CHECK(ecount == 2); + CHECK(secp256k1_pedersen_commit(sign, &commit, NULL, val, secp256k1_generator_h) == 0); + CHECK(ecount == 3); + CHECK(secp256k1_pedersen_commit(sign, &commit, blind, val, NULL) == 0); + CHECK(ecount == 4); + + CHECK(secp256k1_pedersen_blind_sum(none, blind_out, &blind_ptr, 1, 1) != 0); + CHECK(ecount == 4); + CHECK(secp256k1_pedersen_blind_sum(none, NULL, &blind_ptr, 1, 1) == 0); + CHECK(ecount == 5); + CHECK(secp256k1_pedersen_blind_sum(none, blind_out, NULL, 1, 1) == 0); + CHECK(ecount == 6); + CHECK(secp256k1_pedersen_blind_sum(none, blind_out, &blind_ptr, 0, 1) == 0); + CHECK(ecount == 7); + CHECK(secp256k1_pedersen_blind_sum(none, blind_out, &blind_ptr, 0, 0) != 0); + CHECK(ecount == 7); + + CHECK(secp256k1_pedersen_commit(sign, &commit, blind, val, secp256k1_generator_h) != 0); + CHECK(secp256k1_pedersen_verify_tally(none, &commit_ptr, 1, &commit_ptr, 1) != 0); + CHECK(secp256k1_pedersen_verify_tally(none, NULL, 0, &commit_ptr, 1) == 0); + CHECK(secp256k1_pedersen_verify_tally(none, &commit_ptr, 1, NULL, 0) == 0); + CHECK(secp256k1_pedersen_verify_tally(none, NULL, 0, NULL, 0) != 0); + CHECK(ecount == 7); + CHECK(secp256k1_pedersen_verify_tally(none, NULL, 1, &commit_ptr, 1) == 0); + CHECK(ecount == 8); + CHECK(secp256k1_pedersen_verify_tally(none, &commit_ptr, 1, NULL, 1) == 0); + CHECK(ecount == 9); + + CHECK(secp256k1_pedersen_blind_generator_blind_sum(none, &val, &blind_ptr, &blind_out_ptr, 1, 0) != 0); + CHECK(ecount == 9); + CHECK(secp256k1_pedersen_blind_generator_blind_sum(none, &val, &blind_ptr, &blind_out_ptr, 1, 1) == 0); + CHECK(ecount == 10); + CHECK(secp256k1_pedersen_blind_generator_blind_sum(none, &val, &blind_ptr, &blind_out_ptr, 0, 0) == 0); + CHECK(ecount == 11); + CHECK(secp256k1_pedersen_blind_generator_blind_sum(none, NULL, &blind_ptr, &blind_out_ptr, 1, 0) == 0); + CHECK(ecount == 12); + CHECK(secp256k1_pedersen_blind_generator_blind_sum(none, &val, NULL, &blind_out_ptr, 1, 0) == 0); + CHECK(ecount == 13); + CHECK(secp256k1_pedersen_blind_generator_blind_sum(none, &val, &blind_ptr, NULL, 1, 0) == 0); + CHECK(ecount == 14); + + secp256k1_context_destroy(none); + secp256k1_context_destroy(sign); + secp256k1_context_destroy(vrfy); + secp256k1_context_destroy(sttc); +} + +static void test_pedersen(void) { + secp256k1_pedersen_commitment commits[19]; + const secp256k1_pedersen_commitment *cptr[19]; + unsigned char blinds[32*19]; + const unsigned char *bptr[19]; + secp256k1_scalar s; + uint64_t values[19]; + int64_t totalv; + int i; + int inputs; + int outputs; + int total; + inputs = (secp256k1_testrand32() & 7) + 1; + outputs = (secp256k1_testrand32() & 7) + 2; + total = inputs + outputs; + for (i = 0; i < 19; i++) { + cptr[i] = &commits[i]; + bptr[i] = &blinds[i * 32]; + } + totalv = 0; + for (i = 0; i < inputs; i++) { + values[i] = secp256k1_testrandi64(0, INT64_MAX - totalv); + totalv += values[i]; + } + for (i = 0; i < outputs - 1; i++) { + values[i + inputs] = secp256k1_testrandi64(0, totalv); + totalv -= values[i + inputs]; + } + values[total - 1] = totalv; + + for (i = 0; i < total - 1; i++) { + random_scalar_order(&s); + secp256k1_scalar_get_b32(&blinds[i * 32], &s); + } + CHECK(secp256k1_pedersen_blind_sum(ctx, &blinds[(total - 1) * 32], bptr, total - 1, inputs)); + for (i = 0; i < total; i++) { + CHECK(secp256k1_pedersen_commit(ctx, &commits[i], &blinds[i * 32], values[i], secp256k1_generator_h)); + } + CHECK(secp256k1_pedersen_verify_tally(ctx, cptr, inputs, &cptr[inputs], outputs)); + CHECK(secp256k1_pedersen_verify_tally(ctx, &cptr[inputs], outputs, cptr, inputs)); + if (inputs > 0 && values[0] > 0) { + CHECK(!secp256k1_pedersen_verify_tally(ctx, cptr, inputs - 1, &cptr[inputs], outputs)); + } + random_scalar_order(&s); + for (i = 0; i < 4; i++) { + secp256k1_scalar_get_b32(&blinds[i * 32], &s); + } + values[0] = INT64_MAX; + values[1] = 0; + values[2] = 1; + for (i = 0; i < 3; i++) { + CHECK(secp256k1_pedersen_commit(ctx, &commits[i], &blinds[i * 32], values[i], secp256k1_generator_h)); + } + CHECK(secp256k1_pedersen_verify_tally(ctx, &cptr[0], 1, &cptr[0], 1)); + CHECK(secp256k1_pedersen_verify_tally(ctx, &cptr[1], 1, &cptr[1], 1)); +} + +void test_pedersen_commitment_fixed_vector(void) { + const unsigned char two_g[33] = { + 0x09, + 0xc6, 0x04, 0x7f, 0x94, 0x41, 0xed, 0x7d, 0x6d, 0x30, 0x45, 0x40, 0x6e, 0x95, 0xc0, 0x7c, 0xd8, + 0x5c, 0x77, 0x8e, 0x4b, 0x8c, 0xef, 0x3c, 0xa7, 0xab, 0xac, 0x09, 0xb9, 0x5c, 0x70, 0x9e, 0xe5 + }; + unsigned char result[33]; + secp256k1_pedersen_commitment parse; + + CHECK(secp256k1_pedersen_commitment_parse(ctx, &parse, two_g)); + CHECK(secp256k1_pedersen_commitment_serialize(ctx, result, &parse)); + CHECK(secp256k1_memcmp_var(two_g, result, 33) == 0); + + result[0] = 0x08; + CHECK(secp256k1_pedersen_commitment_parse(ctx, &parse, result)); + result[0] = 0x0c; + CHECK(!secp256k1_pedersen_commitment_parse(ctx, &parse, result)); +} + + void run_generator_tests(void) { + int i; + test_shallue_van_de_woestijne(); test_generator_fixed_vector(); test_generator_api(); test_generator_generate(); + test_pedersen_api(); + test_pedersen_commitment_fixed_vector(); + for (i = 0; i < count / 2 + 1; i++) { + test_pedersen(); + } } #endif diff --git a/src/modules/rangeproof/Makefile.am.include b/src/modules/rangeproof/Makefile.am.include index ff8b8d38..5272f229 100644 --- a/src/modules/rangeproof/Makefile.am.include +++ b/src/modules/rangeproof/Makefile.am.include @@ -1,7 +1,5 @@ include_HEADERS += include/secp256k1_rangeproof.h noinst_HEADERS += src/modules/rangeproof/main_impl.h -noinst_HEADERS += src/modules/rangeproof/pedersen.h -noinst_HEADERS += src/modules/rangeproof/pedersen_impl.h noinst_HEADERS += src/modules/rangeproof/borromean.h noinst_HEADERS += src/modules/rangeproof/borromean_impl.h noinst_HEADERS += src/modules/rangeproof/rangeproof.h diff --git a/src/modules/rangeproof/main_impl.h b/src/modules/rangeproof/main_impl.h index 432f4b95..b1af2a5e 100644 --- a/src/modules/rangeproof/main_impl.h +++ b/src/modules/rangeproof/main_impl.h @@ -9,225 +9,9 @@ #include "../../group.h" -#include "pedersen_impl.h" -#include "borromean_impl.h" -#include "rangeproof_impl.h" - -/** Alternative generator for secp256k1. - * This is the sha256 of 'g' after standard encoding (without compression), - * which happens to be a point on the curve. More precisely, the generator is - * derived by running the following script with the sage mathematics software. - - import hashlib - F = FiniteField (0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F) - G = '0479be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8' - H = EllipticCurve ([F (0), F (7)]).lift_x(F(int(hashlib.sha256(G.decode('hex')).hexdigest(),16))) - print('%x %x' % H.xy()) - */ -static const secp256k1_generator secp256k1_generator_h_internal = {{ - 0x50, 0x92, 0x9b, 0x74, 0xc1, 0xa0, 0x49, 0x54, 0xb7, 0x8b, 0x4b, 0x60, 0x35, 0xe9, 0x7a, 0x5e, - 0x07, 0x8a, 0x5a, 0x0f, 0x28, 0xec, 0x96, 0xd5, 0x47, 0xbf, 0xee, 0x9a, 0xce, 0x80, 0x3a, 0xc0, - 0x31, 0xd3, 0xc6, 0x86, 0x39, 0x73, 0x92, 0x6e, 0x04, 0x9e, 0x63, 0x7c, 0xb1, 0xb5, 0xf4, 0x0a, - 0x36, 0xda, 0xc2, 0x8a, 0xf1, 0x76, 0x69, 0x68, 0xc3, 0x0c, 0x23, 0x13, 0xf3, 0xa3, 0x89, 0x04 -}}; - -const secp256k1_generator *secp256k1_generator_h = &secp256k1_generator_h_internal; - -static void secp256k1_pedersen_commitment_load(secp256k1_ge* ge, const secp256k1_pedersen_commitment* commit) { - secp256k1_fe fe; - secp256k1_fe_set_b32(&fe, &commit->data[1]); - secp256k1_ge_set_xquad(ge, &fe); - if (commit->data[0] & 1) { - secp256k1_ge_neg(ge, ge); - } -} - -static void secp256k1_pedersen_commitment_save(secp256k1_pedersen_commitment* commit, secp256k1_ge* ge) { - secp256k1_fe_normalize(&ge->x); - secp256k1_fe_get_b32(&commit->data[1], &ge->x); - commit->data[0] = 9 ^ secp256k1_fe_is_quad_var(&ge->y); -} - -int secp256k1_pedersen_commitment_parse(const secp256k1_context* ctx, secp256k1_pedersen_commitment* commit, const unsigned char *input) { - secp256k1_fe x; - secp256k1_ge ge; - - VERIFY_CHECK(ctx != NULL); - ARG_CHECK(commit != NULL); - ARG_CHECK(input != NULL); - (void) ctx; - - if ((input[0] & 0xFE) != 8 || - !secp256k1_fe_set_b32(&x, &input[1]) || - !secp256k1_ge_set_xquad(&ge, &x)) { - return 0; - } - if (input[0] & 1) { - secp256k1_ge_neg(&ge, &ge); - } - secp256k1_pedersen_commitment_save(commit, &ge); - return 1; -} - -int secp256k1_pedersen_commitment_serialize(const secp256k1_context* ctx, unsigned char *output, const secp256k1_pedersen_commitment* commit) { - secp256k1_ge ge; - - VERIFY_CHECK(ctx != NULL); - ARG_CHECK(output != NULL); - ARG_CHECK(commit != NULL); - - secp256k1_pedersen_commitment_load(&ge, commit); - - output[0] = 9 ^ secp256k1_fe_is_quad_var(&ge.y); - secp256k1_fe_normalize_var(&ge.x); - secp256k1_fe_get_b32(&output[1], &ge.x); - return 1; -} - -/* Generates a pedersen commitment: *commit = blind * G + value * G2. The blinding factor is 32 bytes.*/ -int secp256k1_pedersen_commit(const secp256k1_context* ctx, secp256k1_pedersen_commitment *commit, const unsigned char *blind, uint64_t value, const secp256k1_generator* gen) { - secp256k1_ge genp; - secp256k1_gej rj; - secp256k1_ge r; - secp256k1_scalar sec; - int overflow; - int ret = 0; - VERIFY_CHECK(ctx != NULL); - ARG_CHECK(secp256k1_ecmult_gen_context_is_built(&ctx->ecmult_gen_ctx)); - ARG_CHECK(commit != NULL); - ARG_CHECK(blind != NULL); - ARG_CHECK(gen != NULL); - secp256k1_generator_load(&genp, gen); - secp256k1_scalar_set_b32(&sec, blind, &overflow); - if (!overflow) { - secp256k1_pedersen_ecmult(&ctx->ecmult_gen_ctx, &rj, &sec, value, &genp); - if (!secp256k1_gej_is_infinity(&rj)) { - secp256k1_ge_set_gej(&r, &rj); - secp256k1_pedersen_commitment_save(commit, &r); - ret = 1; - } - secp256k1_gej_clear(&rj); - secp256k1_ge_clear(&r); - } - secp256k1_scalar_clear(&sec); - return ret; -} - -/** Takes a list of n pointers to 32 byte blinding values, the first negs of which are treated with positive sign and the rest - * negative, then calculates an additional blinding value that adds to zero. - */ -int secp256k1_pedersen_blind_sum(const secp256k1_context* ctx, unsigned char *blind_out, const unsigned char * const *blinds, size_t n, size_t npositive) { - secp256k1_scalar acc; - secp256k1_scalar x; - size_t i; - int overflow; - VERIFY_CHECK(ctx != NULL); - ARG_CHECK(blind_out != NULL); - ARG_CHECK(blinds != NULL); - ARG_CHECK(npositive <= n); - (void) ctx; - secp256k1_scalar_set_int(&acc, 0); - for (i = 0; i < n; i++) { - secp256k1_scalar_set_b32(&x, blinds[i], &overflow); - if (overflow) { - return 0; - } - if (i >= npositive) { - secp256k1_scalar_negate(&x, &x); - } - secp256k1_scalar_add(&acc, &acc, &x); - } - secp256k1_scalar_get_b32(blind_out, &acc); - secp256k1_scalar_clear(&acc); - secp256k1_scalar_clear(&x); - return 1; -} - -/* Takes two lists of commitments and sums the first set and subtracts the second and verifies that they sum to excess. */ -int secp256k1_pedersen_verify_tally(const secp256k1_context* ctx, const secp256k1_pedersen_commitment * const* commits, size_t pcnt, const secp256k1_pedersen_commitment * const* ncommits, size_t ncnt) { - secp256k1_gej accj; - secp256k1_ge add; - size_t i; - VERIFY_CHECK(ctx != NULL); - ARG_CHECK(!pcnt || (commits != NULL)); - ARG_CHECK(!ncnt || (ncommits != NULL)); - (void) ctx; - secp256k1_gej_set_infinity(&accj); - for (i = 0; i < ncnt; i++) { - secp256k1_pedersen_commitment_load(&add, ncommits[i]); - secp256k1_gej_add_ge_var(&accj, &accj, &add, NULL); - } - secp256k1_gej_neg(&accj, &accj); - for (i = 0; i < pcnt; i++) { - secp256k1_pedersen_commitment_load(&add, commits[i]); - secp256k1_gej_add_ge_var(&accj, &accj, &add, NULL); - } - return secp256k1_gej_is_infinity(&accj); -} - -int secp256k1_pedersen_blind_generator_blind_sum(const secp256k1_context* ctx, const uint64_t *value, const unsigned char* const* generator_blind, unsigned char* const* blinding_factor, size_t n_total, size_t n_inputs) { - secp256k1_scalar sum; - secp256k1_scalar tmp; - size_t i; - - VERIFY_CHECK(ctx != NULL); - ARG_CHECK(n_total == 0 || value != NULL); - ARG_CHECK(n_total == 0 || generator_blind != NULL); - ARG_CHECK(n_total == 0 || blinding_factor != NULL); - ARG_CHECK(n_total > n_inputs); - (void) ctx; - - if (n_total == 0) { - return 1; - } - - secp256k1_scalar_set_int(&sum, 0); - - /* Here, n_total > 0. Thus the loop runs at least once. - Thus we may use a do-while loop, which checks the loop - condition only at the end. - - The do-while loop helps GCC prove that the loop runs at least - once and suppresses a -Wmaybe-uninitialized warning. */ - i = 0; - do { - int overflow = 0; - secp256k1_scalar addend; - secp256k1_scalar_set_u64(&addend, value[i]); /* s = v */ - - secp256k1_scalar_set_b32(&tmp, generator_blind[i], &overflow); - if (overflow == 1) { - secp256k1_scalar_clear(&tmp); - secp256k1_scalar_clear(&addend); - secp256k1_scalar_clear(&sum); - return 0; - } - secp256k1_scalar_mul(&addend, &addend, &tmp); /* s = vr */ - - secp256k1_scalar_set_b32(&tmp, blinding_factor[i], &overflow); - if (overflow == 1) { - secp256k1_scalar_clear(&tmp); - secp256k1_scalar_clear(&addend); - secp256k1_scalar_clear(&sum); - return 0; - } - secp256k1_scalar_add(&addend, &addend, &tmp); /* s = vr + r' */ - secp256k1_scalar_cond_negate(&addend, i < n_inputs); /* s is negated if it's an input */ - secp256k1_scalar_add(&sum, &sum, &addend); /* sum += s */ - secp256k1_scalar_clear(&addend); - - i++; - } while (i < n_total); - - /* Right now tmp has the last pedersen blinding factor. Subtract the sum from it. */ - secp256k1_scalar_negate(&sum, &sum); - secp256k1_scalar_add(&tmp, &tmp, &sum); - secp256k1_scalar_get_b32(blinding_factor[n_total - 1], &tmp); - - secp256k1_scalar_clear(&tmp); - secp256k1_scalar_clear(&sum); - return 1; -} +#include "modules/generator/main_impl.h" +#include "modules/rangeproof/borromean_impl.h" +#include "modules/rangeproof/rangeproof_impl.h" int secp256k1_rangeproof_info(const secp256k1_context* ctx, int *exp, int *mantissa, uint64_t *min_value, uint64_t *max_value, const unsigned char *proof, size_t plen) { diff --git a/src/modules/rangeproof/rangeproof_impl.h b/src/modules/rangeproof/rangeproof_impl.h index fbf32b29..dd79b6ad 100644 --- a/src/modules/rangeproof/rangeproof_impl.h +++ b/src/modules/rangeproof/rangeproof_impl.h @@ -13,9 +13,9 @@ #include "../../hash_impl.h" #include "../../util.h" -#include "pedersen.h" -#include "rangeproof.h" -#include "borromean.h" +#include "modules/generator/pedersen.h" +#include "modules/rangeproof/borromean.h" +#include "modules/rangeproof/rangeproof.h" SECP256K1_INLINE static void secp256k1_rangeproof_pub_expand(secp256k1_gej *pubs, int exp, size_t *rsizes, size_t rings, const secp256k1_ge* genp) { diff --git a/src/modules/rangeproof/tests_impl.h b/src/modules/rangeproof/tests_impl.h index 9c920734..61d0492e 100644 --- a/src/modules/rangeproof/tests_impl.h +++ b/src/modules/rangeproof/tests_impl.h @@ -16,66 +16,6 @@ #include "../../../include/secp256k1_rangeproof.h" -static void test_pedersen_api(const secp256k1_context *none, const secp256k1_context *sign, const secp256k1_context *vrfy, const secp256k1_context *sttc, const int32_t *ecount) { - secp256k1_pedersen_commitment commit; - const secp256k1_pedersen_commitment *commit_ptr = &commit; - unsigned char blind[32]; - unsigned char blind_out[32]; - const unsigned char *blind_ptr = blind; - unsigned char *blind_out_ptr = blind_out; - uint64_t val = secp256k1_testrand32(); - - secp256k1_testrand256(blind); - CHECK(secp256k1_pedersen_commit(none, &commit, blind, val, secp256k1_generator_h) != 0); - CHECK(secp256k1_pedersen_commit(vrfy, &commit, blind, val, secp256k1_generator_h) != 0); - CHECK(secp256k1_pedersen_commit(sign, &commit, blind, val, secp256k1_generator_h) != 0); - CHECK(*ecount == 0); - CHECK(secp256k1_pedersen_commit(sttc, &commit, blind, val, secp256k1_generator_h) == 0); - CHECK(*ecount == 1); - - CHECK(secp256k1_pedersen_commit(sign, NULL, blind, val, secp256k1_generator_h) == 0); - CHECK(*ecount == 2); - CHECK(secp256k1_pedersen_commit(sign, &commit, NULL, val, secp256k1_generator_h) == 0); - CHECK(*ecount == 3); - CHECK(secp256k1_pedersen_commit(sign, &commit, blind, val, NULL) == 0); - CHECK(*ecount == 4); - - CHECK(secp256k1_pedersen_blind_sum(none, blind_out, &blind_ptr, 1, 1) != 0); - CHECK(*ecount == 4); - CHECK(secp256k1_pedersen_blind_sum(none, NULL, &blind_ptr, 1, 1) == 0); - CHECK(*ecount == 5); - CHECK(secp256k1_pedersen_blind_sum(none, blind_out, NULL, 1, 1) == 0); - CHECK(*ecount == 6); - CHECK(secp256k1_pedersen_blind_sum(none, blind_out, &blind_ptr, 0, 1) == 0); - CHECK(*ecount == 7); - CHECK(secp256k1_pedersen_blind_sum(none, blind_out, &blind_ptr, 0, 0) != 0); - CHECK(*ecount == 7); - - CHECK(secp256k1_pedersen_commit(sign, &commit, blind, val, secp256k1_generator_h) != 0); - CHECK(secp256k1_pedersen_verify_tally(none, &commit_ptr, 1, &commit_ptr, 1) != 0); - CHECK(secp256k1_pedersen_verify_tally(none, NULL, 0, &commit_ptr, 1) == 0); - CHECK(secp256k1_pedersen_verify_tally(none, &commit_ptr, 1, NULL, 0) == 0); - CHECK(secp256k1_pedersen_verify_tally(none, NULL, 0, NULL, 0) != 0); - CHECK(*ecount == 7); - CHECK(secp256k1_pedersen_verify_tally(none, NULL, 1, &commit_ptr, 1) == 0); - CHECK(*ecount == 8); - CHECK(secp256k1_pedersen_verify_tally(none, &commit_ptr, 1, NULL, 1) == 0); - CHECK(*ecount == 9); - - CHECK(secp256k1_pedersen_blind_generator_blind_sum(none, &val, &blind_ptr, &blind_out_ptr, 1, 0) != 0); - CHECK(*ecount == 9); - CHECK(secp256k1_pedersen_blind_generator_blind_sum(none, &val, &blind_ptr, &blind_out_ptr, 1, 1) == 0); - CHECK(*ecount == 10); - CHECK(secp256k1_pedersen_blind_generator_blind_sum(none, &val, &blind_ptr, &blind_out_ptr, 0, 0) == 0); - CHECK(*ecount == 11); - CHECK(secp256k1_pedersen_blind_generator_blind_sum(none, NULL, &blind_ptr, &blind_out_ptr, 1, 0) == 0); - CHECK(*ecount == 12); - CHECK(secp256k1_pedersen_blind_generator_blind_sum(none, &val, NULL, &blind_out_ptr, 1, 0) == 0); - CHECK(*ecount == 13); - CHECK(secp256k1_pedersen_blind_generator_blind_sum(none, &val, &blind_ptr, NULL, 1, 0) == 0); - CHECK(*ecount == 14); -} - static void test_rangeproof_api(const secp256k1_context *none, const secp256k1_context *sign, const secp256k1_context *vrfy, const secp256k1_context *both, const secp256k1_context *sttc, const int32_t *ecount) { unsigned char proof[5134]; unsigned char blind[32]; @@ -253,8 +193,6 @@ static void test_api(void) { secp256k1_context_set_illegal_callback(sttc, counting_illegal_callback_fn, &ecount); for (i = 0; i < count; i++) { - ecount = 0; - test_pedersen_api(none, sign, vrfy, sttc, &ecount); ecount = 0; test_rangeproof_api(none, sign, vrfy, both, sttc, &ecount); } @@ -266,63 +204,6 @@ static void test_api(void) { secp256k1_context_destroy(sttc); } -static void test_pedersen(void) { - secp256k1_pedersen_commitment commits[19]; - const secp256k1_pedersen_commitment *cptr[19]; - unsigned char blinds[32*19]; - const unsigned char *bptr[19]; - secp256k1_scalar s; - uint64_t values[19]; - int64_t totalv; - int i; - int inputs; - int outputs; - int total; - inputs = (secp256k1_testrand32() & 7) + 1; - outputs = (secp256k1_testrand32() & 7) + 2; - total = inputs + outputs; - for (i = 0; i < 19; i++) { - cptr[i] = &commits[i]; - bptr[i] = &blinds[i * 32]; - } - totalv = 0; - for (i = 0; i < inputs; i++) { - values[i] = secp256k1_testrandi64(0, INT64_MAX - totalv); - totalv += values[i]; - } - for (i = 0; i < outputs - 1; i++) { - values[i + inputs] = secp256k1_testrandi64(0, totalv); - totalv -= values[i + inputs]; - } - values[total - 1] = totalv; - - for (i = 0; i < total - 1; i++) { - random_scalar_order(&s); - secp256k1_scalar_get_b32(&blinds[i * 32], &s); - } - CHECK(secp256k1_pedersen_blind_sum(ctx, &blinds[(total - 1) * 32], bptr, total - 1, inputs)); - for (i = 0; i < total; i++) { - CHECK(secp256k1_pedersen_commit(ctx, &commits[i], &blinds[i * 32], values[i], secp256k1_generator_h)); - } - CHECK(secp256k1_pedersen_verify_tally(ctx, cptr, inputs, &cptr[inputs], outputs)); - CHECK(secp256k1_pedersen_verify_tally(ctx, &cptr[inputs], outputs, cptr, inputs)); - if (inputs > 0 && values[0] > 0) { - CHECK(!secp256k1_pedersen_verify_tally(ctx, cptr, inputs - 1, &cptr[inputs], outputs)); - } - random_scalar_order(&s); - for (i = 0; i < 4; i++) { - secp256k1_scalar_get_b32(&blinds[i * 32], &s); - } - values[0] = INT64_MAX; - values[1] = 0; - values[2] = 1; - for (i = 0; i < 3; i++) { - CHECK(secp256k1_pedersen_commit(ctx, &commits[i], &blinds[i * 32], values[i], secp256k1_generator_h)); - } - CHECK(secp256k1_pedersen_verify_tally(ctx, &cptr[0], 1, &cptr[0], 1)); - CHECK(secp256k1_pedersen_verify_tally(ctx, &cptr[1], 1, &cptr[1], 1)); -} - static void test_borromean(void) { unsigned char e0[32]; secp256k1_scalar s[64]; @@ -1523,25 +1404,6 @@ void test_rangeproof_fixed_vectors_reproducible(void) { } } -void test_pedersen_commitment_fixed_vector(void) { - const unsigned char two_g[33] = { - 0x09, - 0xc6, 0x04, 0x7f, 0x94, 0x41, 0xed, 0x7d, 0x6d, 0x30, 0x45, 0x40, 0x6e, 0x95, 0xc0, 0x7c, 0xd8, - 0x5c, 0x77, 0x8e, 0x4b, 0x8c, 0xef, 0x3c, 0xa7, 0xab, 0xac, 0x09, 0xb9, 0x5c, 0x70, 0x9e, 0xe5 - }; - unsigned char result[33]; - secp256k1_pedersen_commitment parse; - - CHECK(secp256k1_pedersen_commitment_parse(ctx, &parse, two_g)); - CHECK(secp256k1_pedersen_commitment_serialize(ctx, result, &parse)); - CHECK(secp256k1_memcmp_var(two_g, result, 33) == 0); - - result[0] = 0x08; - CHECK(secp256k1_pedersen_commitment_parse(ctx, &parse, result)); - result[0] = 0x0c; - CHECK(!secp256k1_pedersen_commitment_parse(ctx, &parse, result)); -} - void run_rangeproof_tests(void) { int i; test_api(); @@ -1552,10 +1414,6 @@ void run_rangeproof_tests(void) { test_rangeproof_fixed_vectors(); test_rangeproof_fixed_vectors_reproducible(); - test_pedersen_commitment_fixed_vector(); - for (i = 0; i < count / 2 + 1; i++) { - test_pedersen(); - } for (i = 0; i < count / 2 + 1; i++) { test_borromean(); } diff --git a/src/secp256k1.c b/src/secp256k1.c index 6c686e0b..bf6a1c61 100644 --- a/src/secp256k1.c +++ b/src/secp256k1.c @@ -38,8 +38,6 @@ #ifdef ENABLE_MODULE_RANGEPROOF # include "include/secp256k1_rangeproof.h" -# include "modules/rangeproof/pedersen.h" -# include "modules/rangeproof/rangeproof.h" #endif #ifdef ENABLE_MODULE_ECDSA_S2C