diff --git a/include/secp256k1_rangeproof.h b/include/secp256k1_rangeproof.h index 54b454ef..94cfaee8 100644 --- a/include/secp256k1_rangeproof.h +++ b/include/secp256k1_rangeproof.h @@ -9,6 +9,50 @@ extern "C" { #include +/** 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 33 bytes in size, and can be safely copied/moved. + * If you need to convert to a format suitable for storage or transmission, use + * the secp256k1_pedersen_commitment_serialize_* and + * secp256k1_pedersen_commitment_serialize_* functions. + * + * Furthermore, it is guaranteed to identical signatures will have identical + * representation, so they can be memcmp'ed. + */ +typedef struct { + unsigned char data[33]; +} secp256k1_pedersen_commitment; + +/** Parse a 33-byte commitment into a commitment object. + * + * Returns: 1 always + * 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); + + /** Initialize a context for usage with Pedersen commitments. */ void secp256k1_pedersen_context_initialize(secp256k1_context* ctx); @@ -18,14 +62,14 @@ void secp256k1_pedersen_context_initialize(secp256k1_context* ctx); * 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. - * Out: commit: pointer to a 33-byte array for the commitment (cannot be NULL) + * 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_WARN_UNUSED_RESULT int secp256k1_pedersen_commit( const secp256k1_context* ctx, - unsigned char *commit, - unsigned char *blind, + secp256k1_pedersen_commitment *commit, + const unsigned char *blind, uint64_t value ) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3); @@ -42,17 +86,17 @@ SECP256K1_WARN_UNUSED_RESULT int secp256k1_pedersen_blind_sum( const secp256k1_context* ctx, unsigned char *blind_out, const unsigned char * const *blinds, - int n, - int npositive + 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, initialized for Pedersen commitment (cannot be NULL) - * commits: pointer to pointers to 33-byte character arrays for the commitments. (cannot be NULL if pcnt is non-zero) + * 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 pointers to 33-byte character arrays for negative commitments. (cannot be NULL if ncnt is non-zero) + * 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. * excess: signed 64bit amount to add to the total to bring it to zero, can be negative. * @@ -65,10 +109,10 @@ SECP256K1_WARN_UNUSED_RESULT int secp256k1_pedersen_blind_sum( */ SECP256K1_WARN_UNUSED_RESULT int secp256k1_pedersen_verify_tally( const secp256k1_context* ctx, - const unsigned char * const *commits, - int pcnt, - const unsigned char * const *ncommits, - int ncnt, + const secp256k1_pedersen_commitment * const* commits, + size_t pcnt, + const secp256k1_pedersen_commitment * const* ncommits, + size_t ncnt, int64_t excess ) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(4); @@ -79,7 +123,7 @@ void secp256k1_rangeproof_context_initialize(secp256k1_context* ctx); * 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. * In: ctx: pointer to a context object, initialized for range-proof and commitment (cannot be NULL) - * commit: the 33-byte commitment being proved. (cannot be NULL) + * commit: the commitment being proved. (cannot be NULL) * proof: pointer to character array with the proof. (cannot be NULL) * plen: length of proof in bytes. * Out: min_value: pointer to a unsigned int64 which will be updated with the minimum value that commit could have. (cannot be NULL) @@ -89,16 +133,16 @@ SECP256K1_WARN_UNUSED_RESULT int secp256k1_rangeproof_verify( const secp256k1_context* ctx, uint64_t *min_value, uint64_t *max_value, - const unsigned char *commit, + const secp256k1_pedersen_commitment *commit, const unsigned char *proof, - int plen + size_t plen ) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4) SECP256K1_ARG_NONNULL(5); /** Verify a range proof proof and rewind the proof to recover information sent by its author. * Returns 1: Value is within the range [0..2^64), the specifically proven range is in the min/max value outputs, and the value and blinding were recovered. * 0: Proof failed, rewind failed, or other error. * In: ctx: pointer to a context object, initialized for range-proof and Pedersen commitment (cannot be NULL) - * commit: the 33-byte commitment being proved. (cannot be NULL) + * commit: the commitment being proved. (cannot be NULL) * proof: pointer to character array with the proof. (cannot be NULL) * plen: length of proof in bytes. * nonce: 32-byte secret nonce used by the prover (cannot be NULL) @@ -114,13 +158,13 @@ SECP256K1_WARN_UNUSED_RESULT int secp256k1_rangeproof_rewind( unsigned char *blind_out, uint64_t *value_out, unsigned char *message_out, - int *outlen, + size_t *outlen, const unsigned char *nonce, uint64_t *min_value, uint64_t *max_value, - const unsigned char *commit, + const secp256k1_pedersen_commitment *commit, const unsigned char *proof, - int plen + size_t plen ) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(6) SECP256K1_ARG_NONNULL(7) SECP256K1_ARG_NONNULL(8) SECP256K1_ARG_NONNULL(9) SECP256K1_ARG_NONNULL(10); /** Author a proof that a committed value is within a range. @@ -129,7 +173,7 @@ SECP256K1_WARN_UNUSED_RESULT int secp256k1_rangeproof_rewind( * In: ctx: pointer to a context object, initialized for range-proof, signing, and Pedersen commitment (cannot be NULL) * 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: 33-byte array with the commitment being proved. + * commit: the commitment being proved. * blind: 32-byte blinding factor used by commit. * 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. @@ -148,9 +192,9 @@ SECP256K1_WARN_UNUSED_RESULT int secp256k1_rangeproof_rewind( SECP256K1_WARN_UNUSED_RESULT int secp256k1_rangeproof_sign( const secp256k1_context* ctx, unsigned char *proof, - int *plen, + size_t *plen, uint64_t min_value, - const unsigned char *commit, + const secp256k1_pedersen_commitment *commit, const unsigned char *blind, const unsigned char *nonce, int exp, @@ -176,7 +220,7 @@ SECP256K1_WARN_UNUSED_RESULT int secp256k1_rangeproof_info( uint64_t *min_value, uint64_t *max_value, const unsigned char *proof, - int plen + size_t plen ) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4) SECP256K1_ARG_NONNULL(5); # ifdef __cplusplus diff --git a/src/bench_rangeproof.c b/src/bench_rangeproof.c index f3faafb5..76466574 100644 --- a/src/bench_rangeproof.c +++ b/src/bench_rangeproof.c @@ -12,10 +12,10 @@ typedef struct { secp256k1_context* ctx; - unsigned char commit[33]; + secp256k1_pedersen_commitment commit; unsigned char proof[5134]; unsigned char blind[32]; - int len; + size_t len; int min_bits; uint64_t v; } bench_rangeproof_t; @@ -28,10 +28,10 @@ static void bench_rangeproof_setup(void* arg) { data->v = 0; for (i = 0; i < 32; i++) data->blind[i] = i + 1; - CHECK(secp256k1_pedersen_commit(data->ctx, data->commit, data->blind, data->v)); + CHECK(secp256k1_pedersen_commit(data->ctx, &data->commit, data->blind, data->v)); data->len = 5134; - CHECK(secp256k1_rangeproof_sign(data->ctx, data->proof, &data->len, 0, data->commit, data->blind, data->commit, 0, data->min_bits, data->v)); - CHECK(secp256k1_rangeproof_verify(data->ctx, &minv, &maxv, data->commit, data->proof, data->len)); + CHECK(secp256k1_rangeproof_sign(data->ctx, data->proof, &data->len, 0, &data->commit, data->blind, (const unsigned char*)&data->commit, 0, data->min_bits, data->v)); + CHECK(secp256k1_rangeproof_verify(data->ctx, &minv, &maxv, &data->commit, data->proof, data->len)); } static void bench_rangeproof(void* arg) { @@ -42,7 +42,7 @@ static void bench_rangeproof(void* arg) { int j; uint64_t minv; uint64_t maxv; - j = secp256k1_rangeproof_verify(data->ctx, &minv, &maxv, data->commit, data->proof, data->len); + j = secp256k1_rangeproof_verify(data->ctx, &minv, &maxv, &data->commit, data->proof, data->len); for (j = 0; j < 4; j++) { data->proof[j + 2 + 32 *((data->min_bits + 1) >> 1) - 4] = (i >> 8)&255; } diff --git a/src/modules/rangeproof/borromean.h b/src/modules/rangeproof/borromean.h index 11fd6c5b..8f8cfedd 100644 --- a/src/modules/rangeproof/borromean.h +++ b/src/modules/rangeproof/borromean.h @@ -15,10 +15,10 @@ #include "ecmult_gen.h" int secp256k1_borromean_verify(const secp256k1_ecmult_context* ecmult_ctx, secp256k1_scalar *evalues, const unsigned char *e0, const secp256k1_scalar *s, - const secp256k1_gej *pubs, const int *rsizes, int nrings, const unsigned char *m, int mlen); + const secp256k1_gej *pubs, const size_t *rsizes, size_t nrings, const unsigned char *m, size_t mlen); int secp256k1_borromean_sign(const secp256k1_ecmult_context* ecmult_ctx, const secp256k1_ecmult_gen_context *ecmult_gen_ctx, unsigned char *e0, secp256k1_scalar *s, const secp256k1_gej *pubs, const secp256k1_scalar *k, const secp256k1_scalar *sec, - const int *rsizes, const int *secidx, int nrings, const unsigned char *m, int mlen); + const size_t *rsizes, const size_t *secidx, size_t nrings, const unsigned char *m, size_t mlen); #endif diff --git a/src/modules/rangeproof/borromean_impl.h b/src/modules/rangeproof/borromean_impl.h index 73a4d1ef..0f46eb3c 100644 --- a/src/modules/rangeproof/borromean_impl.h +++ b/src/modules/rangeproof/borromean_impl.h @@ -11,11 +11,14 @@ #include "scalar.h" #include "field.h" #include "group.h" +#include "hash.h" +#include "eckey.h" #include "ecmult.h" #include "ecmult_gen.h" #include "borromean.h" #include +#include #ifdef WORDS_BIGENDIAN #define BE32(x) (x) @@ -23,8 +26,8 @@ #define BE32(p) ((((p) & 0xFF) << 24) | (((p) & 0xFF00) << 8) | (((p) & 0xFF0000) >> 8) | (((p) & 0xFF000000) >> 24)) #endif -SECP256K1_INLINE static void secp256k1_borromean_hash(unsigned char *hash, const unsigned char *m, int mlen, const unsigned char *e, int elen, - int ridx, int eidx) { +SECP256K1_INLINE static void secp256k1_borromean_hash(unsigned char *hash, const unsigned char *m, size_t mlen, const unsigned char *e, size_t elen, + size_t ridx, size_t eidx) { uint32_t ring; uint32_t epos; secp256k1_sha256_t sha256_en; @@ -53,15 +56,15 @@ SECP256K1_INLINE static void secp256k1_borromean_hash(unsigned char *hash, const * | return e_0 ==== H(r_{0..i}||m) */ int secp256k1_borromean_verify(const secp256k1_ecmult_context* ecmult_ctx, secp256k1_scalar *evalues, const unsigned char *e0, - const secp256k1_scalar *s, const secp256k1_gej *pubs, const int *rsizes, int nrings, const unsigned char *m, int mlen) { + const secp256k1_scalar *s, const secp256k1_gej *pubs, const size_t *rsizes, size_t nrings, const unsigned char *m, size_t mlen) { secp256k1_gej rgej; secp256k1_ge rge; secp256k1_scalar ens; secp256k1_sha256_t sha256_e0; unsigned char tmp[33]; - int i; - int j; - int count; + size_t i; + size_t j; + size_t count; size_t size; int overflow; VERIFY_CHECK(ecmult_ctx != NULL); @@ -108,15 +111,15 @@ int secp256k1_borromean_verify(const secp256k1_ecmult_context* ecmult_ctx, secp2 int secp256k1_borromean_sign(const secp256k1_ecmult_context* ecmult_ctx, const secp256k1_ecmult_gen_context *ecmult_gen_ctx, unsigned char *e0, secp256k1_scalar *s, const secp256k1_gej *pubs, const secp256k1_scalar *k, const secp256k1_scalar *sec, - const int *rsizes, const int *secidx, int nrings, const unsigned char *m, int mlen) { + const size_t *rsizes, const size_t *secidx, size_t nrings, const unsigned char *m, size_t mlen) { secp256k1_gej rgej; secp256k1_ge rge; secp256k1_scalar ens; secp256k1_sha256_t sha256_e0; unsigned char tmp[33]; - int i; - int j; - int count; + size_t i; + size_t j; + size_t count; size_t size; int overflow; VERIFY_CHECK(ecmult_ctx != NULL); diff --git a/src/modules/rangeproof/main_impl.h b/src/modules/rangeproof/main_impl.h index 20f05a05..a1ad6715 100644 --- a/src/modules/rangeproof/main_impl.h +++ b/src/modules/rangeproof/main_impl.h @@ -7,16 +7,48 @@ #ifndef SECP256K1_MODULE_RANGEPROOF_MAIN #define SECP256K1_MODULE_RANGEPROOF_MAIN +#include "group.h" + #include "modules/rangeproof/pedersen_impl.h" #include "modules/rangeproof/borromean_impl.h" #include "modules/rangeproof/rangeproof_impl.h" -/* Generates a pedersen commitment: *commit = blind * G + value * G2. The commitment is 33 bytes, the blinding factor is 32 bytes.*/ -int secp256k1_pedersen_commit(const secp256k1_context* ctx, unsigned char *commit, unsigned char *blind, uint64_t value) { +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) { + VERIFY_CHECK(ctx != NULL); + ARG_CHECK(commit != NULL); + ARG_CHECK(input != NULL); + memcpy(commit->data, input, sizeof(commit->data)); + return 1; +} + +int secp256k1_pedersen_commitment_serialize(const secp256k1_context* ctx, unsigned char *output, const secp256k1_pedersen_commitment* commit) { + VERIFY_CHECK(ctx != NULL); + ARG_CHECK(output != NULL); + ARG_CHECK(commit != NULL); + memcpy(output, commit->data, sizeof(commit->data)); + 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) { secp256k1_gej rj; secp256k1_ge r; secp256k1_scalar sec; - size_t sz; int overflow; int ret = 0; ARG_CHECK(ctx != NULL); @@ -28,8 +60,8 @@ int secp256k1_pedersen_commit(const secp256k1_context* ctx, unsigned char *commi secp256k1_pedersen_ecmult(&ctx->ecmult_gen_ctx, &rj, &sec, value); if (!secp256k1_gej_is_infinity(&rj)) { secp256k1_ge_set_gej(&r, &rj); - sz = 33; - ret = secp256k1_eckey_pubkey_serialize(&r, commit, &sz, 1); + secp256k1_pedersen_commitment_save(commit, &r); + ret = 1; } secp256k1_gej_clear(&rj); secp256k1_ge_clear(&r); @@ -41,10 +73,10 @@ int secp256k1_pedersen_commit(const secp256k1_context* ctx, unsigned char *commi /** 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, int n, int npositive) { +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; - int i; + size_t i; int overflow; ARG_CHECK(ctx != NULL); ARG_CHECK(blind_out != NULL); @@ -66,12 +98,11 @@ int secp256k1_pedersen_blind_sum(const secp256k1_context* ctx, unsigned char *bl return 1; } -/* Takes two list of 33-byte 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 unsigned char * const *commits, int pcnt, - const unsigned char * const *ncommits, int ncnt, int64_t excess) { +/* 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, int64_t excess) { secp256k1_gej accj; secp256k1_ge add; - int i; + size_t i; ARG_CHECK(ctx != NULL); ARG_CHECK(!pcnt || (commits != NULL)); ARG_CHECK(!ncnt || (ncommits != NULL)); @@ -87,24 +118,20 @@ int secp256k1_pedersen_verify_tally(const secp256k1_context* ctx, const unsigned } } for (i = 0; i < ncnt; i++) { - if (!secp256k1_eckey_pubkey_parse(&add, ncommits[i], 33)) { - return 0; - } + 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++) { - if (!secp256k1_eckey_pubkey_parse(&add, commits[i], 33)) { - return 0; - } + secp256k1_pedersen_commitment_load(&add, commits[i]); secp256k1_gej_add_ge_var(&accj, &accj, &add, NULL); } return secp256k1_gej_is_infinity(&accj); } int secp256k1_rangeproof_info(const secp256k1_context* ctx, int *exp, int *mantissa, - uint64_t *min_value, uint64_t *max_value, const unsigned char *proof, int plen) { - int offset; + uint64_t *min_value, uint64_t *max_value, const unsigned char *proof, size_t plen) { + size_t offset; uint64_t scale; ARG_CHECK(exp != NULL); ARG_CHECK(mantissa != NULL); @@ -117,9 +144,10 @@ int secp256k1_rangeproof_info(const secp256k1_context* ctx, int *exp, int *manti } int secp256k1_rangeproof_rewind(const secp256k1_context* ctx, - unsigned char *blind_out, uint64_t *value_out, unsigned char *message_out, int *outlen, const unsigned char *nonce, + unsigned char *blind_out, uint64_t *value_out, unsigned char *message_out, size_t *outlen, const unsigned char *nonce, uint64_t *min_value, uint64_t *max_value, - const unsigned char *commit, const unsigned char *proof, int plen) { + const secp256k1_pedersen_commitment *commit, const unsigned char *proof, size_t plen) { + secp256k1_ge commitp; ARG_CHECK(ctx != NULL); ARG_CHECK(commit != NULL); ARG_CHECK(proof != NULL); @@ -127,24 +155,28 @@ int secp256k1_rangeproof_rewind(const secp256k1_context* ctx, ARG_CHECK(max_value != NULL); ARG_CHECK(secp256k1_ecmult_context_is_built(&ctx->ecmult_ctx)); ARG_CHECK(secp256k1_ecmult_gen_context_is_built(&ctx->ecmult_gen_ctx)); + secp256k1_pedersen_commitment_load(&commitp, commit); return secp256k1_rangeproof_verify_impl(&ctx->ecmult_ctx, &ctx->ecmult_gen_ctx, - blind_out, value_out, message_out, outlen, nonce, min_value, max_value, commit, proof, plen); + blind_out, value_out, message_out, outlen, nonce, min_value, max_value, &commitp, proof, plen); } int secp256k1_rangeproof_verify(const secp256k1_context* ctx, uint64_t *min_value, uint64_t *max_value, - const unsigned char *commit, const unsigned char *proof, int plen) { + const secp256k1_pedersen_commitment *commit, const unsigned char *proof, size_t plen) { + secp256k1_ge commitp; ARG_CHECK(ctx != NULL); ARG_CHECK(commit != NULL); ARG_CHECK(proof != NULL); ARG_CHECK(min_value != NULL); ARG_CHECK(max_value != NULL); ARG_CHECK(secp256k1_ecmult_context_is_built(&ctx->ecmult_ctx)); + secp256k1_pedersen_commitment_load(&commitp, commit); return secp256k1_rangeproof_verify_impl(&ctx->ecmult_ctx, NULL, - NULL, NULL, NULL, NULL, NULL, min_value, max_value, commit, proof, plen); + NULL, NULL, NULL, NULL, NULL, min_value, max_value, &commitp, proof, plen); } -int secp256k1_rangeproof_sign(const secp256k1_context* ctx, unsigned char *proof, int *plen, uint64_t min_value, - const unsigned char *commit, const unsigned char *blind, const unsigned char *nonce, int exp, int min_bits, uint64_t value){ +int secp256k1_rangeproof_sign(const secp256k1_context* ctx, unsigned char *proof, size_t *plen, uint64_t min_value, + const secp256k1_pedersen_commitment *commit, const unsigned char *blind, const unsigned char *nonce, int exp, int min_bits, uint64_t value){ + secp256k1_ge commitp; ARG_CHECK(ctx != NULL); ARG_CHECK(proof != NULL); ARG_CHECK(plen != NULL); @@ -153,8 +185,9 @@ int secp256k1_rangeproof_sign(const secp256k1_context* ctx, unsigned char *proof ARG_CHECK(nonce != NULL); ARG_CHECK(secp256k1_ecmult_context_is_built(&ctx->ecmult_ctx)); ARG_CHECK(secp256k1_ecmult_gen_context_is_built(&ctx->ecmult_gen_ctx)); + secp256k1_pedersen_commitment_load(&commitp, commit); return secp256k1_rangeproof_sign_impl(&ctx->ecmult_ctx, &ctx->ecmult_gen_ctx, - proof, plen, min_value, commit, blind, nonce, exp, min_bits, value); + proof, plen, min_value, &commitp, blind, nonce, exp, min_bits, value); } #endif diff --git a/src/modules/rangeproof/pedersen.h b/src/modules/rangeproof/pedersen.h index cdfe2f8e..84dd20b4 100644 --- a/src/modules/rangeproof/pedersen.h +++ b/src/modules/rangeproof/pedersen.h @@ -7,6 +7,7 @@ #ifndef _SECP256K1_PEDERSEN_H_ #define _SECP256K1_PEDERSEN_H_ +#include "ecmult_gen.h" #include "group.h" #include "scalar.h" diff --git a/src/modules/rangeproof/pedersen_impl.h b/src/modules/rangeproof/pedersen_impl.h index 3ce2767c..991c60b3 100644 --- a/src/modules/rangeproof/pedersen_impl.h +++ b/src/modules/rangeproof/pedersen_impl.h @@ -7,6 +7,16 @@ #ifndef _SECP256K1_PEDERSEN_IMPL_H_ #define _SECP256K1_PEDERSEN_IMPL_H_ +#include + +#include "eckey.h" +#include "ecmult_const.h" +#include "ecmult_gen.h" +#include "group.h" +#include "field.h" +#include "scalar.h" +#include "util.h" + /** Alternative generator for secp256k1. * This is the sha256 of 'g' after DER encoding (without compression), * which happens to be a point on the curve. diff --git a/src/modules/rangeproof/rangeproof.h b/src/modules/rangeproof/rangeproof.h index b0f53696..85f94bc4 100644 --- a/src/modules/rangeproof/rangeproof.h +++ b/src/modules/rangeproof/rangeproof.h @@ -9,10 +9,12 @@ #include "scalar.h" #include "group.h" +#include "ecmult.h" +#include "ecmult_gen.h" static int secp256k1_rangeproof_verify_impl(const secp256k1_ecmult_context* ecmult_ctx, const secp256k1_ecmult_gen_context* ecmult_gen_ctx, - unsigned char *blindout, uint64_t *value_out, unsigned char *message_out, int *outlen, const unsigned char *nonce, - uint64_t *min_value, uint64_t *max_value, const unsigned char *commit, const unsigned char *proof, int plen); + unsigned char *blindout, uint64_t *value_out, unsigned char *message_out, size_t *outlen, const unsigned char *nonce, + uint64_t *min_value, uint64_t *max_value, const secp256k1_ge *commit, const unsigned char *proof, size_t plen); #endif diff --git a/src/modules/rangeproof/rangeproof_impl.h b/src/modules/rangeproof/rangeproof_impl.h index 94956eb8..42d622a0 100644 --- a/src/modules/rangeproof/rangeproof_impl.h +++ b/src/modules/rangeproof/rangeproof_impl.h @@ -7,20 +7,23 @@ #ifndef _SECP256K1_RANGEPROOF_IMPL_H_ #define _SECP256K1_RANGEPROOF_IMPL_H_ +#include "eckey.h" #include "scalar.h" #include "group.h" #include "rangeproof.h" #include "hash_impl.h" +#include "pedersen_impl.h" +#include "util.h" #include "modules/rangeproof/pedersen.h" #include "modules/rangeproof/borromean.h" SECP256K1_INLINE static void secp256k1_rangeproof_pub_expand(secp256k1_gej *pubs, - int exp, int *rsizes, int rings) { + int exp, size_t *rsizes, size_t rings) { secp256k1_gej base; - int i; - int j; - int npub; + size_t i; + size_t j; + size_t npub; VERIFY_CHECK(exp < 19); if (exp < 0) { exp = 0; @@ -48,22 +51,30 @@ SECP256K1_INLINE static void secp256k1_rangeproof_pub_expand(secp256k1_gej *pubs } } +SECP256K1_INLINE static void secp256k1_rangeproof_serialize_point(unsigned char* data, const secp256k1_ge *point) { + secp256k1_fe pointx; + pointx = point->x; + secp256k1_fe_normalize(&pointx); + data[0] = !secp256k1_fe_is_quad_var(&point->y); + secp256k1_fe_get_b32(data + 1, &pointx); +} + SECP256K1_INLINE static int secp256k1_rangeproof_genrand(secp256k1_scalar *sec, secp256k1_scalar *s, unsigned char *message, - int *rsizes, int rings, const unsigned char *nonce, const unsigned char *commit, const unsigned char *proof, int len) { + size_t *rsizes, size_t rings, const unsigned char *nonce, const secp256k1_ge *commit, const unsigned char *proof, size_t len) { unsigned char tmp[32]; unsigned char rngseed[32 + 33 + 10]; secp256k1_rfc6979_hmac_sha256_t rng; secp256k1_scalar acc; int overflow; int ret; - int i; - int j; + size_t i; + size_t j; int b; - int npub; + size_t npub; VERIFY_CHECK(len <= 10); memcpy(rngseed, nonce, 32); - memcpy(rngseed + 32, commit, 33); - memcpy(rngseed + 65, proof, len); + secp256k1_rangeproof_serialize_point(rngseed + 32, commit); + memcpy(rngseed + 33 + 32, proof, len); secp256k1_rfc6979_hmac_sha256_initialize(&rng, rngseed, 32 + 33 + len); secp256k1_scalar_clear(&acc); npub = 0; @@ -99,9 +110,9 @@ SECP256K1_INLINE static int secp256k1_rangeproof_genrand(secp256k1_scalar *sec, return ret; } -SECP256K1_INLINE static int secp256k1_range_proveparams(uint64_t *v, int *rings, int *rsizes, int *npub, int *secidx, uint64_t *min_value, +SECP256K1_INLINE static int secp256k1_range_proveparams(uint64_t *v, size_t *rings, size_t *rsizes, size_t *npub, size_t *secidx, uint64_t *min_value, int *mantissa, uint64_t *scale, int *exp, int *min_bits, uint64_t value) { - int i; + size_t i; *rings = 1; rsizes[0] = 1; secidx[0] = 0; @@ -135,13 +146,13 @@ SECP256K1_INLINE static int secp256k1_range_proveparams(uint64_t *v, int *rings, *v = value - *min_value; /* If the user has asked for more bits of proof then there is room for in the exponent, reduce the exponent. */ v2 = *min_bits ? (UINT64_MAX>>(64-*min_bits)) : 0; - for (i = 0; i < *exp && (v2 <= UINT64_MAX / 10); i++) { + for (i = 0; (int) i < *exp && (v2 <= UINT64_MAX / 10); i++) { *v /= 10; v2 *= 10; } *exp = i; v2 = *v; - for (i = 0; i < *exp; i++) { + for (i = 0; (int) i < *exp; i++) { v2 *= 10; *scale *= 10; } @@ -179,8 +190,8 @@ SECP256K1_INLINE static int secp256k1_range_proveparams(uint64_t *v, int *rings, /* strawman interface, writes proof in proof, a buffer of plen, proves with respect to min_value the range for commit which has the provided blinding factor and value. */ SECP256K1_INLINE static int secp256k1_rangeproof_sign_impl(const secp256k1_ecmult_context* ecmult_ctx, const secp256k1_ecmult_gen_context* ecmult_gen_ctx, - unsigned char *proof, int *plen, uint64_t min_value, - const unsigned char *commit, const unsigned char *blind, const unsigned char *nonce, int exp, int min_bits, uint64_t value){ + unsigned char *proof, size_t *plen, uint64_t min_value, + const secp256k1_ge *commit, const unsigned char *blind, const unsigned char *nonce, int exp, int min_bits, uint64_t value){ secp256k1_gej pubs[128]; /* Candidate digits for our proof, most inferred. */ secp256k1_scalar s[128]; /* Signatures in our proof, most forged. */ secp256k1_scalar sec[32]; /* Blinding factors for the correct digits. */ @@ -193,13 +204,13 @@ SECP256K1_INLINE static int secp256k1_rangeproof_sign_impl(const secp256k1_ecmul uint64_t v; uint64_t scale; /* scale = 10^exp. */ int mantissa; /* Number of bits proven in the blinded value. */ - int rings; /* How many digits will our proof cover. */ - int rsizes[32]; /* How many possible values there are for each place. */ - int secidx[32]; /* Which digit is the correct one. */ - int len; /* Number of bytes used so far. */ - int i; + size_t rings; /* How many digits will our proof cover. */ + size_t rsizes[32]; /* How many possible values there are for each place. */ + size_t secidx[32]; /* Which digit is the correct one. */ + size_t len; /* Number of bytes used so far. */ + size_t i; int overflow; - int npub; + size_t npub; len = 0; if (*plen < 65 || min_value > value || min_bits > 64 || min_bits < 0 || exp < -1 || exp > 18) { return 0; @@ -225,13 +236,14 @@ SECP256K1_INLINE static int secp256k1_rangeproof_sign_impl(const secp256k1_ecmul return 0; } secp256k1_sha256_initialize(&sha256_m); - secp256k1_sha256_write(&sha256_m, commit, 33); + secp256k1_rangeproof_serialize_point(tmp, commit); + secp256k1_sha256_write(&sha256_m, tmp, 33); secp256k1_sha256_write(&sha256_m, proof, len); memset(prep, 0, 4096); /* Note, the data corresponding to the blinding factors must be zero. */ if (rsizes[rings - 1] > 1) { - int idx; + size_t idx; /* Value encoding sidechannel. */ idx = rsizes[rings - 1] - 1; idx -= secidx[rings - 1] == idx; @@ -276,16 +288,17 @@ SECP256K1_INLINE static int secp256k1_rangeproof_sign_impl(const secp256k1_ecmul return 0; } if (i < rings - 1) { - size_t size = 33; + unsigned char tmpc[33]; secp256k1_ge c; + unsigned char quadness; /*OPT: split loop and batch invert.*/ + /*OPT: do not compute full pubs[npub] in ge form; we only need x */ secp256k1_ge_set_gej_var(&c, &pubs[npub]); - if(!secp256k1_eckey_pubkey_serialize(&c, tmp, &size, 1)) { - return 0; - } - secp256k1_sha256_write(&sha256_m, tmp, 33); - signs[i>>3] |= (tmp[0] == 3) << (i&7); - memcpy(&proof[len], &tmp[1], 32); + secp256k1_rangeproof_serialize_point(tmpc, &c); + quadness = tmpc[0]; + secp256k1_sha256_write(&sha256_m, tmpc, 33); + signs[i>>3] |= quadness << (i&7); + memcpy(&proof[len], tmpc + 1, 32); len += 32; } npub += rsizes[i]; @@ -332,21 +345,21 @@ SECP256K1_INLINE static void secp256k1_rangeproof_ch32xor(unsigned char *x, cons } SECP256K1_INLINE static int secp256k1_rangeproof_rewind_inner(secp256k1_scalar *blind, uint64_t *v, - unsigned char *m, int *mlen, secp256k1_scalar *ev, secp256k1_scalar *s, - int *rsizes, int rings, const unsigned char *nonce, const unsigned char *commit, const unsigned char *proof, int len) { + unsigned char *m, size_t *mlen, secp256k1_scalar *ev, secp256k1_scalar *s, + size_t *rsizes, size_t rings, const unsigned char *nonce, const secp256k1_ge *commit, const unsigned char *proof, size_t len) { secp256k1_scalar s_orig[128]; secp256k1_scalar sec[32]; secp256k1_scalar stmp; unsigned char prep[4096]; unsigned char tmp[32]; uint64_t value; - int offset; - int i; - int j; + size_t offset; + size_t i; + size_t j; int b; - int skip1; - int skip2; - int npub; + size_t skip1; + size_t skip2; + size_t npub; npub = ((rings - 1) << 2) + rsizes[rings-1]; VERIFY_CHECK(npub <= 128); VERIFY_CHECK(npub >= 1); @@ -368,7 +381,7 @@ SECP256K1_INLINE static int secp256k1_rangeproof_rewind_inner(secp256k1_scalar * } npub = (rings - 1) << 2; for (j = 0; j < 2; j++) { - int idx; + size_t idx; /* Look for a value encoding in the last ring. */ idx = npub + rsizes[rings - 1] - 1 - j; secp256k1_scalar_get_b32(tmp, &s[idx]); @@ -417,7 +430,7 @@ SECP256K1_INLINE static int secp256k1_rangeproof_rewind_inner(secp256k1_scalar * offset = 0; npub = 0; for (i = 0; i < rings; i++) { - int idx; + size_t idx; idx = (value >> (i << 1)) & 3; for (j = 0; j < rsizes[i]; j++) { if (npub == skip1 || npub == skip2) { @@ -454,8 +467,8 @@ SECP256K1_INLINE static int secp256k1_rangeproof_rewind_inner(secp256k1_scalar * return 1; } -SECP256K1_INLINE static int secp256k1_rangeproof_getheader_impl(int *offset, int *exp, int *mantissa, uint64_t *scale, - uint64_t *min_value, uint64_t *max_value, const unsigned char *proof, int plen) { +SECP256K1_INLINE static int secp256k1_rangeproof_getheader_impl(size_t *offset, int *exp, int *mantissa, uint64_t *scale, + uint64_t *min_value, uint64_t *max_value, const unsigned char *proof, size_t plen) { int i; int has_nz_range; int has_min; @@ -507,27 +520,26 @@ SECP256K1_INLINE static int secp256k1_rangeproof_getheader_impl(int *offset, int return 1; } -/* Verifies range proof (len plen) for 33-byte commit, the min/max values proven are put in the min/max arguments; returns 0 on failure 1 on success.*/ +/* Verifies range proof (len plen) for commit, the min/max values proven are put in the min/max arguments; returns 0 on failure 1 on success.*/ SECP256K1_INLINE static int secp256k1_rangeproof_verify_impl(const secp256k1_ecmult_context* ecmult_ctx, const secp256k1_ecmult_gen_context* ecmult_gen_ctx, - unsigned char *blindout, uint64_t *value_out, unsigned char *message_out, int *outlen, const unsigned char *nonce, - uint64_t *min_value, uint64_t *max_value, const unsigned char *commit, const unsigned char *proof, int plen) { + unsigned char *blindout, uint64_t *value_out, unsigned char *message_out, size_t *outlen, const unsigned char *nonce, + uint64_t *min_value, uint64_t *max_value, const secp256k1_ge *commit, const unsigned char *proof, size_t plen) { secp256k1_gej accj; secp256k1_gej pubs[128]; secp256k1_ge c; secp256k1_scalar s[128]; secp256k1_scalar evalues[128]; /* Challenges, only used during proof rewind. */ secp256k1_sha256_t sha256_m; - int rsizes[32]; + size_t rsizes[32]; int ret; - int i; - size_t size; + size_t i; int exp; int mantissa; - int offset; - int rings; + size_t offset; + size_t rings; int overflow; - int npub; + size_t npub; int offset_post_header; uint64_t scale; unsigned char signs[31]; @@ -558,7 +570,8 @@ SECP256K1_INLINE static int secp256k1_rangeproof_verify_impl(const secp256k1_ecm return 0; } secp256k1_sha256_initialize(&sha256_m); - secp256k1_sha256_write(&sha256_m, commit, 33); + secp256k1_rangeproof_serialize_point(m, commit); + secp256k1_sha256_write(&sha256_m, m, 33); secp256k1_sha256_write(&sha256_m, proof, offset); for(i = 0; i < rings - 1; i++) { signs[i] = (proof[offset + ( i>> 3)] & (1 << (i & 7))) != 0; @@ -576,22 +589,23 @@ SECP256K1_INLINE static int secp256k1_rangeproof_verify_impl(const secp256k1_ecm secp256k1_pedersen_ecmult_small(&accj, *min_value); } for(i = 0; i < rings - 1; i++) { - memcpy(&m[1], &proof[offset], 32); - m[0] = 2 + signs[i]; - if (!secp256k1_eckey_pubkey_parse(&c, m, 33)) { - return 0; + secp256k1_fe fe; + secp256k1_fe_set_b32(&fe, &proof[offset]); + secp256k1_ge_set_xquad(&c, &fe); + if (signs[i]) { + secp256k1_ge_neg(&c, &c); } - secp256k1_sha256_write(&sha256_m, m, 33); + /* Not using secp256k1_rangeproof_serialize_point as we almost have it + * serialized form already. */ + secp256k1_sha256_write(&sha256_m, &signs[i], 1); + secp256k1_sha256_write(&sha256_m, &proof[offset], 32); secp256k1_gej_set_ge(&pubs[npub], &c); secp256k1_gej_add_ge_var(&accj, &accj, &c, NULL); offset += 32; npub += rsizes[i]; } secp256k1_gej_neg(&accj, &accj); - if (!secp256k1_eckey_pubkey_parse(&c, commit, 33)) { - return 0; - } - secp256k1_gej_add_ge_var(&pubs[npub], &accj, &c, NULL); + secp256k1_gej_add_ge_var(&pubs[npub], &accj, commit, NULL); if (secp256k1_gej_is_infinity(&pubs[npub])) { return 0; } @@ -615,7 +629,6 @@ SECP256K1_INLINE static int secp256k1_rangeproof_verify_impl(const secp256k1_ecm if (ret && nonce) { /* Given the nonce, try rewinding the witness to recover its initial state. */ secp256k1_scalar blind; - unsigned char commitrec[33]; uint64_t vv; if (!ecmult_gen_ctx) { return 0; @@ -630,10 +643,9 @@ SECP256K1_INLINE static int secp256k1_rangeproof_verify_impl(const secp256k1_ecm if (secp256k1_gej_is_infinity(&accj)) { return 0; } - secp256k1_ge_set_gej(&c, &accj); - size = 33; - secp256k1_eckey_pubkey_serialize(&c, commitrec, &size, 1); - if (size != 33 || memcmp(commitrec, commit, 33) != 0) { + secp256k1_gej_neg(&accj, &accj); + secp256k1_gej_add_ge_var(&accj, &accj, commit, NULL); + if (!secp256k1_gej_is_infinity(&accj)) { return 0; } if (blindout) { diff --git a/src/modules/rangeproof/tests_impl.h b/src/modules/rangeproof/tests_impl.h index 4e601697..7cd27969 100644 --- a/src/modules/rangeproof/tests_impl.h +++ b/src/modules/rangeproof/tests_impl.h @@ -7,11 +7,16 @@ #ifndef SECP256K1_MODULE_RANGEPROOF_TESTS #define SECP256K1_MODULE_RANGEPROOF_TESTS +#include "group.h" +#include "scalar.h" +#include "testrand.h" +#include "util.h" + #include "include/secp256k1_rangeproof.h" void test_pedersen(void) { - unsigned char commits[33*19]; - const unsigned char *cptr[19]; + secp256k1_pedersen_commitment commits[19]; + const secp256k1_pedersen_commitment *cptr[19]; unsigned char blinds[32*19]; const unsigned char *bptr[19]; secp256k1_scalar s; @@ -25,7 +30,7 @@ void test_pedersen(void) { outputs = (secp256k1_rand32() & 7) + 2; total = inputs + outputs; for (i = 0; i < 19; i++) { - cptr[i] = &commits[i * 33]; + cptr[i] = &commits[i]; bptr[i] = &blinds[i * 32]; } totalv = 0; @@ -56,7 +61,7 @@ void test_pedersen(void) { } 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 * 33], &blinds[i * 32], values[i])); + CHECK(secp256k1_pedersen_commit(ctx, &commits[i], &blinds[i * 32], values[i])); } CHECK(secp256k1_pedersen_verify_tally(ctx, cptr, inputs, &cptr[inputs], outputs, totalv)); CHECK(!secp256k1_pedersen_verify_tally(ctx, cptr, inputs, &cptr[inputs], outputs, totalv + 1)); @@ -68,7 +73,7 @@ void test_pedersen(void) { values[1] = 0; values[2] = 1; for (i = 0; i < 3; i++) { - CHECK(secp256k1_pedersen_commit(ctx, &commits[i * 33], &blinds[i * 32], values[i])); + CHECK(secp256k1_pedersen_commit(ctx, &commits[i], &blinds[i * 32], values[i])); } CHECK(secp256k1_pedersen_verify_tally(ctx, &cptr[1], 1, &cptr[2], 1, -1)); CHECK(secp256k1_pedersen_verify_tally(ctx, &cptr[2], 1, &cptr[1], 1, 1)); @@ -87,11 +92,11 @@ void test_borromean(void) { secp256k1_ge ge; secp256k1_scalar one; unsigned char m[32]; - int rsizes[8]; - int secidx[8]; - int nrings; - int i; - int j; + size_t rsizes[8]; + size_t secidx[8]; + size_t nrings; + size_t i; + size_t j; int c; secp256k1_rand256_test(m); nrings = 1 + (secp256k1_rand32()&7); @@ -145,32 +150,32 @@ void test_borromean(void) { void test_rangeproof(void) { const uint64_t testvs[11] = {0, 1, 5, 11, 65535, 65537, INT32_MAX, UINT32_MAX, INT64_MAX - 1, INT64_MAX, UINT64_MAX}; - unsigned char commit[33]; - unsigned char commit2[33]; + secp256k1_pedersen_commitment commit; + secp256k1_pedersen_commitment commit2; unsigned char proof[5134]; unsigned char blind[32]; unsigned char blindout[32]; unsigned char message[4096]; - int mlen; + size_t mlen; uint64_t v; uint64_t vout; uint64_t vmin; uint64_t minv; uint64_t maxv; - int len; - int i; - int j; - int k; + size_t len; + size_t i; + size_t j; + size_t k; secp256k1_rand256(blind); for (i = 0; i < 11; i++) { v = testvs[i]; - CHECK(secp256k1_pedersen_commit(ctx, commit, blind, v)); + CHECK(secp256k1_pedersen_commit(ctx, &commit, blind, v)); for (vmin = 0; vmin < (i<9 && i > 0 ? 2 : 1); vmin++) { len = 5134; - CHECK(secp256k1_rangeproof_sign(ctx, proof, &len, vmin, commit, blind, commit, 0, 0, v)); + CHECK(secp256k1_rangeproof_sign(ctx, proof, &len, vmin, &commit, blind, commit.data, 0, 0, v)); CHECK(len <= 5134); mlen = 4096; - CHECK(secp256k1_rangeproof_rewind(ctx, blindout, &vout, message, &mlen, commit, &minv, &maxv, commit, proof, len)); + CHECK(secp256k1_rangeproof_rewind(ctx, blindout, &vout, message, &mlen, commit.data, &minv, &maxv, &commit, proof, len)); for (j = 0; j < mlen; j++) { CHECK(message[j] == 0); } @@ -180,9 +185,9 @@ void test_rangeproof(void) { CHECK(minv <= v); CHECK(maxv >= v); len = 5134; - CHECK(secp256k1_rangeproof_sign(ctx, proof, &len, v, commit, blind, commit, -1, 64, v)); + CHECK(secp256k1_rangeproof_sign(ctx, proof, &len, v, &commit, blind, commit.data, -1, 64, v)); CHECK(len <= 73); - CHECK(secp256k1_rangeproof_rewind(ctx, blindout, &vout, NULL, NULL, commit, &minv, &maxv, commit, proof, len)); + CHECK(secp256k1_rangeproof_rewind(ctx, blindout, &vout, NULL, NULL, commit.data, &minv, &maxv, &commit, proof, len)); CHECK(memcmp(blindout, blind, 32) == 0); CHECK(vout == v); CHECK(minv == v); @@ -191,11 +196,11 @@ void test_rangeproof(void) { } secp256k1_rand256(blind); v = INT64_MAX - 1; - CHECK(secp256k1_pedersen_commit(ctx, commit, blind, v)); + CHECK(secp256k1_pedersen_commit(ctx, &commit, blind, v)); for (i = 0; i < 19; i++) { len = 5134; - CHECK(secp256k1_rangeproof_sign(ctx, proof, &len, 0, commit, blind, commit, i, 0, v)); - CHECK(secp256k1_rangeproof_verify(ctx, &minv, &maxv, commit, proof, len)); + CHECK(secp256k1_rangeproof_sign(ctx, proof, &len, 0, &commit, blind, commit.data, i, 0, v)); + CHECK(secp256k1_rangeproof_verify(ctx, &minv, &maxv, &commit, proof, len)); CHECK(len <= 5134); CHECK(minv <= v); CHECK(maxv >= v); @@ -204,21 +209,21 @@ void test_rangeproof(void) { { /*Malleability test.*/ v = secp256k1_rands64(0, 255); - CHECK(secp256k1_pedersen_commit(ctx, commit, blind, v)); + CHECK(secp256k1_pedersen_commit(ctx, &commit, blind, v)); len = 5134; - CHECK(secp256k1_rangeproof_sign(ctx, proof, &len, 0, commit, blind, commit, 0, 3, v)); + CHECK(secp256k1_rangeproof_sign(ctx, proof, &len, 0, &commit, blind, commit.data, 0, 3, v)); CHECK(len <= 5134); for (i = 0; i < len*8; i++) { proof[i >> 3] ^= 1 << (i & 7); - CHECK(!secp256k1_rangeproof_verify(ctx, &minv, &maxv, commit, proof, len)); + CHECK(!secp256k1_rangeproof_verify(ctx, &minv, &maxv, &commit, proof, len)); proof[i >> 3] ^= 1 << (i & 7); } - CHECK(secp256k1_rangeproof_verify(ctx, &minv, &maxv, commit, proof, len)); + CHECK(secp256k1_rangeproof_verify(ctx, &minv, &maxv, &commit, proof, len)); CHECK(minv <= v); CHECK(maxv >= v); } - memcpy(commit2, commit, 33); - for (i = 0; i < 10 * count; i++) { + memcpy(&commit2, &commit, sizeof(commit)); + for (i = 0; i < 10 * (size_t) count; i++) { int exp; int min_bits; v = secp256k1_rands64(0, UINT64_MAX >> (secp256k1_rand32()&63)); @@ -227,7 +232,7 @@ void test_rangeproof(void) { vmin = secp256k1_rands64(0, v); } secp256k1_rand256(blind); - CHECK(secp256k1_pedersen_commit(ctx, commit, blind, v)); + CHECK(secp256k1_pedersen_commit(ctx, &commit, blind, v)); len = 5134; exp = (int)secp256k1_rands64(0,18)-(int)secp256k1_rands64(0,18); if (exp < 0) { @@ -237,10 +242,10 @@ void test_rangeproof(void) { if (min_bits < 0) { min_bits = -min_bits; } - CHECK(secp256k1_rangeproof_sign(ctx, proof, &len, vmin, commit, blind, commit, exp, min_bits, v)); + CHECK(secp256k1_rangeproof_sign(ctx, proof, &len, vmin, &commit, blind, commit.data, exp, min_bits, v)); CHECK(len <= 5134); mlen = 4096; - CHECK(secp256k1_rangeproof_rewind(ctx, blindout, &vout, message, &mlen, commit, &minv, &maxv, commit, proof, len)); + CHECK(secp256k1_rangeproof_rewind(ctx, blindout, &vout, message, &mlen, commit.data, &minv, &maxv, &commit, proof, len)); for (j = 0; j < mlen; j++) { CHECK(message[j] == 0); } @@ -249,8 +254,8 @@ void test_rangeproof(void) { CHECK(vout == v); CHECK(minv <= v); CHECK(maxv >= v); - CHECK(secp256k1_rangeproof_rewind(ctx, blindout, &vout, NULL, NULL, commit, &minv, &maxv, commit, proof, len)); - memcpy(commit2, commit, 33); + CHECK(secp256k1_rangeproof_rewind(ctx, blindout, &vout, NULL, NULL, commit.data, &minv, &maxv, &commit, proof, len)); + memcpy(&commit2, &commit, sizeof(commit)); } for (j = 0; j < 10; j++) { for (i = 0; i < 96; i++) { @@ -258,10 +263,10 @@ void test_rangeproof(void) { } for (k = 0; k < 128; k++) { len = k; - CHECK(!secp256k1_rangeproof_verify(ctx, &minv, &maxv, commit2, proof, len)); + CHECK(!secp256k1_rangeproof_verify(ctx, &minv, &maxv, &commit2, proof, len)); } len = secp256k1_rands64(0, 3072); - CHECK(!secp256k1_rangeproof_verify(ctx, &minv, &maxv, commit2, proof, len)); + CHECK(!secp256k1_rangeproof_verify(ctx, &minv, &maxv, &commit2, proof, len)); } } diff --git a/src/secp256k1.c b/src/secp256k1.c index 95759ba7..db78be7d 100644 --- a/src/secp256k1.c +++ b/src/secp256k1.c @@ -19,6 +19,7 @@ #include "hash_impl.h" #ifdef ENABLE_MODULE_RANGEPROOF +# include "include/secp256k1_rangeproof.h" # include "modules/rangeproof/pedersen.h" # include "modules/rangeproof/rangeproof.h" #endif