Expose generator in pedersen/rangeproof API

This commit is contained in:
Pieter Wuille 2016-07-06 13:46:23 +02:00 committed by Andrew Poelstra
parent 54fa2639e1
commit 9b00b61d9d
8 changed files with 119 additions and 90 deletions

View File

@ -26,9 +26,14 @@ typedef struct {
unsigned char data[33];
} secp256k1_pedersen_commitment;
/**
* Static constant generator 'h' maintained for historical reasons.
*/
extern const secp256k1_generator *secp256k1_generator_h;
/** Parse a 33-byte commitment into a commitment object.
*
* Returns: 1 always
* 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
@ -70,8 +75,9 @@ SECP256K1_WARN_UNUSED_RESULT int secp256k1_pedersen_commit(
const secp256k1_context* ctx,
secp256k1_pedersen_commitment *commit,
const unsigned char *blind,
uint64_t value
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3);
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.
@ -113,8 +119,9 @@ SECP256K1_WARN_UNUSED_RESULT int secp256k1_pedersen_verify_tally(
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);
int64_t excess,
const secp256k1_generator *gen
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(4) SECP256K1_ARG_NONNULL(7);
/** Initialize a context for usage with Pedersen commitments. */
void secp256k1_rangeproof_context_initialize(secp256k1_context* ctx);
@ -135,8 +142,9 @@ SECP256K1_WARN_UNUSED_RESULT int secp256k1_rangeproof_verify(
uint64_t *max_value,
const secp256k1_pedersen_commitment *commit,
const unsigned char *proof,
size_t plen
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4) SECP256K1_ARG_NONNULL(5);
size_t plen,
const secp256k1_generator* gen
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4) SECP256K1_ARG_NONNULL(5) SECP256K1_ARG_NONNULL(7);
/** 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.
@ -164,8 +172,9 @@ SECP256K1_WARN_UNUSED_RESULT int secp256k1_rangeproof_rewind(
uint64_t *max_value,
const secp256k1_pedersen_commitment *commit,
const unsigned char *proof,
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);
size_t plen,
const secp256k1_generator *gen
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(6) SECP256K1_ARG_NONNULL(7) SECP256K1_ARG_NONNULL(8) SECP256K1_ARG_NONNULL(9) SECP256K1_ARG_NONNULL(10) SECP256K1_ARG_NONNULL(12);
/** Author a proof that a committed value is within a range.
* Returns 1: Proof successfully created.
@ -201,8 +210,9 @@ SECP256K1_WARN_UNUSED_RESULT int secp256k1_rangeproof_sign(
int min_bits,
uint64_t value,
const unsigned char *message,
size_t msg_len
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(5) SECP256K1_ARG_NONNULL(6) SECP256K1_ARG_NONNULL(7);
size_t msg_len,
const secp256k1_generator *gen
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(5) SECP256K1_ARG_NONNULL(6) SECP256K1_ARG_NONNULL(7) SECP256K1_ARG_NONNULL(13);
/** Extract some basic information from a range-proof.
* Returns 1: Information successfully extracted.

View File

@ -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, secp256k1_generator_h));
data->len = 5134;
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, NULL, 0));
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, NULL, 0, secp256k1_generator_h));
CHECK(secp256k1_rangeproof_verify(data->ctx, &minv, &maxv, &data->commit, data->proof, data->len, secp256k1_generator_h));
}
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, secp256k1_generator_h);
for (j = 0; j < 4; j++) {
data->proof[j + 2 + 32 *((data->min_bits + 1) >> 1) - 4] = (i >> 8)&255;
}

View File

@ -13,6 +13,20 @@
#include "modules/rangeproof/borromean_impl.h"
#include "modules/rangeproof/rangeproof_impl.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.
* sage: G2 = EllipticCurve ([F (0), F (7)]).lift_x(int(hashlib.sha256('0479be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8'.decode('hex')).hexdigest(),16))
* sage: '%x %x' % (11 - G2.xy()[1].is_square(), G2.xy()[0])
*/
static const secp256k1_generator secp256k1_generator_h_internal = {{
0x11,
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
}};
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]);
@ -32,6 +46,9 @@ int secp256k1_pedersen_commitment_parse(const secp256k1_context* ctx, secp256k1_
VERIFY_CHECK(ctx != NULL);
ARG_CHECK(commit != NULL);
ARG_CHECK(input != NULL);
if ((input[0] & 0xFE) != 8) {
return 0;
}
memcpy(commit->data, input, sizeof(commit->data));
return 1;
}
@ -45,7 +62,8 @@ int secp256k1_pedersen_commitment_serialize(const secp256k1_context* ctx, unsign
}
/* 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) {
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;
@ -55,9 +73,10 @@ int secp256k1_pedersen_commit(const secp256k1_context* ctx, secp256k1_pedersen_c
ARG_CHECK(secp256k1_ecmult_gen_context_is_built(&ctx->ecmult_gen_ctx));
ARG_CHECK(commit != NULL);
ARG_CHECK(blind != 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);
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);
@ -99,7 +118,8 @@ int secp256k1_pedersen_blind_sum(const secp256k1_context* ctx, unsigned char *bl
}
/* 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) {
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, const secp256k1_generator* gen) {
secp256k1_ge genp;
secp256k1_gej accj;
secp256k1_ge add;
size_t i;
@ -107,12 +127,13 @@ int secp256k1_pedersen_verify_tally(const secp256k1_context* ctx, const secp256k
ARG_CHECK(!pcnt || (commits != NULL));
ARG_CHECK(!ncnt || (ncommits != NULL));
secp256k1_gej_set_infinity(&accj);
secp256k1_generator_load(&genp, gen);
if (excess) {
uint64_t ex;
int neg;
/* Take the absolute value, and negate the result if the input was negative. */
neg = secp256k1_sign_and_abs64(&ex, excess);
secp256k1_pedersen_ecmult_small(&accj, ex);
secp256k1_pedersen_ecmult_small(&accj, ex, &genp);
if (neg) {
secp256k1_gej_neg(&accj, &accj);
}
@ -146,8 +167,9 @@ 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, size_t *outlen, const unsigned char *nonce,
uint64_t *min_value, uint64_t *max_value,
const secp256k1_pedersen_commitment *commit, const unsigned char *proof, size_t plen) {
const secp256k1_pedersen_commitment *commit, const unsigned char *proof, size_t plen, const secp256k1_generator* gen) {
secp256k1_ge commitp;
secp256k1_ge genp;
ARG_CHECK(ctx != NULL);
ARG_CHECK(commit != NULL);
ARG_CHECK(proof != NULL);
@ -156,13 +178,15 @@ int secp256k1_rangeproof_rewind(const secp256k1_context* ctx,
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);
secp256k1_generator_load(&genp, gen);
return secp256k1_rangeproof_verify_impl(&ctx->ecmult_ctx, &ctx->ecmult_gen_ctx,
blind_out, value_out, message_out, outlen, nonce, min_value, max_value, &commitp, proof, plen);
blind_out, value_out, message_out, outlen, nonce, min_value, max_value, &commitp, proof, plen, &genp);
}
int secp256k1_rangeproof_verify(const secp256k1_context* ctx, uint64_t *min_value, uint64_t *max_value,
const secp256k1_pedersen_commitment *commit, const unsigned char *proof, size_t plen) {
const secp256k1_pedersen_commitment *commit, const unsigned char *proof, size_t plen, const secp256k1_generator* gen) {
secp256k1_ge commitp;
secp256k1_ge genp;
ARG_CHECK(ctx != NULL);
ARG_CHECK(commit != NULL);
ARG_CHECK(proof != NULL);
@ -170,14 +194,16 @@ int secp256k1_rangeproof_verify(const secp256k1_context* ctx, uint64_t *min_valu
ARG_CHECK(max_value != NULL);
ARG_CHECK(secp256k1_ecmult_context_is_built(&ctx->ecmult_ctx));
secp256k1_pedersen_commitment_load(&commitp, commit);
secp256k1_generator_load(&genp, gen);
return secp256k1_rangeproof_verify_impl(&ctx->ecmult_ctx, NULL,
NULL, NULL, NULL, NULL, NULL, min_value, max_value, &commitp, proof, plen);
NULL, NULL, NULL, NULL, NULL, min_value, max_value, &commitp, proof, plen, &genp);
}
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,
const unsigned char *message, size_t msg_len){
const unsigned char *message, size_t msg_len, const secp256k1_generator* gen){
secp256k1_ge commitp;
secp256k1_ge genp;
ARG_CHECK(ctx != NULL);
ARG_CHECK(proof != NULL);
ARG_CHECK(plen != NULL);
@ -187,8 +213,9 @@ int secp256k1_rangeproof_sign(const secp256k1_context* ctx, unsigned char *proof
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);
secp256k1_generator_load(&genp, gen);
return secp256k1_rangeproof_sign_impl(&ctx->ecmult_ctx, &ctx->ecmult_gen_ctx,
proof, plen, min_value, &commitp, blind, nonce, exp, min_bits, value, message, msg_len);
proof, plen, min_value, &commitp, blind, nonce, exp, min_bits, value, message, msg_len, &genp);
}
#endif

View File

@ -14,9 +14,9 @@
#include <stdint.h>
/** Multiply a small number with the generator: r = gn*G2 */
static void secp256k1_pedersen_ecmult_small(secp256k1_gej *r, uint64_t gn);
static void secp256k1_pedersen_ecmult_small(secp256k1_gej *r, uint64_t gn, const secp256k1_ge* genp);
/* sec * G + value * G2. */
static void secp256k1_pedersen_ecmult(const secp256k1_ecmult_gen_context *ecmult_gen_ctx, secp256k1_gej *rj, const secp256k1_scalar *sec, uint64_t value);
static void secp256k1_pedersen_ecmult(const secp256k1_ecmult_gen_context *ecmult_gen_ctx, secp256k1_gej *rj, const secp256k1_scalar *sec, uint64_t value, const secp256k1_ge* genp);
#endif

View File

@ -17,19 +17,6 @@
#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.
* sage: G2 = EllipticCurve ([F (0), F (7)]).lift_x(int(hashlib.sha256('0479be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8'.decode('hex')).hexdigest(),16))
* sage: '%x %x'%G2.xy()
*/
static const secp256k1_ge secp256k1_ge_const_g2 = SECP256K1_GE_CONST(
0x50929b74UL, 0xc1a04954UL, 0xb78b4b60UL, 0x35e97a5eUL,
0x078a5a0fUL, 0x28ec96d5UL, 0x47bfee9aUL, 0xce803ac0UL,
0x31d3c686UL, 0x3973926eUL, 0x049e637cUL, 0xb1b5f40aUL,
0x36dac28aUL, 0xf1766968UL, 0xc30c2313UL, 0xf3a38904UL
);
static void secp256k1_pedersen_scalar_set_u64(secp256k1_scalar *sec, uint64_t value) {
unsigned char data[32];
int i;
@ -44,18 +31,18 @@ static void secp256k1_pedersen_scalar_set_u64(secp256k1_scalar *sec, uint64_t va
memset(data, 0, 32);
}
static void secp256k1_pedersen_ecmult_small(secp256k1_gej *r, uint64_t gn) {
static void secp256k1_pedersen_ecmult_small(secp256k1_gej *r, uint64_t gn, const secp256k1_ge* genp) {
secp256k1_scalar s;
secp256k1_pedersen_scalar_set_u64(&s, gn);
secp256k1_ecmult_const(r, &secp256k1_ge_const_g2, &s, 64);
secp256k1_ecmult_const(r, genp, &s, 64);
secp256k1_scalar_clear(&s);
}
/* sec * G + value * G2. */
SECP256K1_INLINE static void secp256k1_pedersen_ecmult(const secp256k1_ecmult_gen_context *ecmult_gen_ctx, secp256k1_gej *rj, const secp256k1_scalar *sec, uint64_t value) {
SECP256K1_INLINE static void secp256k1_pedersen_ecmult(const secp256k1_ecmult_gen_context *ecmult_gen_ctx, secp256k1_gej *rj, const secp256k1_scalar *sec, uint64_t value, const secp256k1_ge* genp) {
secp256k1_gej vj;
secp256k1_ecmult_gen(ecmult_gen_ctx, rj, sec);
secp256k1_pedersen_ecmult_small(&vj, value);
secp256k1_pedersen_ecmult_small(&vj, value, genp);
/* FIXME: constant time. */
secp256k1_gej_add_var(rj, rj, &vj, NULL);
secp256k1_gej_clear(&vj);

View File

@ -15,6 +15,6 @@
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, 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);
uint64_t *min_value, uint64_t *max_value, const secp256k1_ge *commit, const unsigned char *proof, size_t plen, const secp256k1_ge* genp);
#endif

View File

@ -19,7 +19,7 @@
#include "modules/rangeproof/borromean.h"
SECP256K1_INLINE static void secp256k1_rangeproof_pub_expand(secp256k1_gej *pubs,
int exp, size_t *rsizes, size_t rings) {
int exp, size_t *rsizes, size_t rings, const secp256k1_ge* genp) {
secp256k1_gej base;
size_t i;
size_t j;
@ -28,7 +28,7 @@ SECP256K1_INLINE static void secp256k1_rangeproof_pub_expand(secp256k1_gej *pubs
if (exp < 0) {
exp = 0;
}
secp256k1_gej_set_ge(&base, &secp256k1_ge_const_g2);
secp256k1_gej_set_ge(&base, genp);
secp256k1_gej_neg(&base, &base);
while (exp--) {
/* Multiplication by 10 */
@ -60,9 +60,9 @@ SECP256K1_INLINE static void secp256k1_rangeproof_serialize_point(unsigned char*
}
SECP256K1_INLINE static int secp256k1_rangeproof_genrand(secp256k1_scalar *sec, secp256k1_scalar *s, unsigned char *message,
size_t *rsizes, size_t rings, const unsigned char *nonce, const secp256k1_ge *commit, const unsigned char *proof, size_t len) {
size_t *rsizes, size_t rings, const unsigned char *nonce, const secp256k1_ge *commit, const unsigned char *proof, size_t len, const secp256k1_ge* genp) {
unsigned char tmp[32];
unsigned char rngseed[32 + 33 + 10];
unsigned char rngseed[32 + 33 + 33 + 10];
secp256k1_rfc6979_hmac_sha256 rng;
secp256k1_scalar acc;
int overflow;
@ -74,8 +74,9 @@ SECP256K1_INLINE static int secp256k1_rangeproof_genrand(secp256k1_scalar *sec,
VERIFY_CHECK(len <= 10);
memcpy(rngseed, nonce, 32);
secp256k1_rangeproof_serialize_point(rngseed + 32, commit);
memcpy(rngseed + 33 + 32, proof, len);
secp256k1_rfc6979_hmac_sha256_initialize(&rng, rngseed, 32 + 33 + len);
secp256k1_rangeproof_serialize_point(rngseed + 32 + 33, genp);
memcpy(rngseed + 33 + 33 + 32, proof, len);
secp256k1_rfc6979_hmac_sha256_initialize(&rng, rngseed, 32 + 33 + 33 + len);
secp256k1_scalar_clear(&acc);
npub = 0;
ret = 1;
@ -192,7 +193,7 @@ SECP256K1_INLINE static int secp256k1_rangeproof_sign_impl(const secp256k1_ecmul
const secp256k1_ecmult_gen_context* ecmult_gen_ctx,
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,
const unsigned char *message, size_t msg_len){
const unsigned char *message, size_t msg_len, const secp256k1_ge* genp){
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. */
@ -246,6 +247,8 @@ SECP256K1_INLINE static int secp256k1_rangeproof_sign_impl(const secp256k1_ecmul
secp256k1_sha256_initialize(&sha256_m);
secp256k1_rangeproof_serialize_point(tmp, commit);
secp256k1_sha256_write(&sha256_m, tmp, 33);
secp256k1_rangeproof_serialize_point(tmp, genp);
secp256k1_sha256_write(&sha256_m, tmp, 33);
secp256k1_sha256_write(&sha256_m, proof, len);
memset(prep, 0, 4096);
@ -265,7 +268,7 @@ SECP256K1_INLINE static int secp256k1_rangeproof_sign_impl(const secp256k1_ecmul
}
prep[idx] = 128;
}
if (!secp256k1_rangeproof_genrand(sec, s, prep, rsizes, rings, nonce, commit, proof, len)) {
if (!secp256k1_rangeproof_genrand(sec, s, prep, rsizes, rings, nonce, commit, proof, len, genp)) {
return 0;
}
memset(prep, 0, 4096);
@ -294,7 +297,7 @@ SECP256K1_INLINE static int secp256k1_rangeproof_sign_impl(const secp256k1_ecmul
npub = 0;
for (i = 0; i < rings; i++) {
/*OPT: Use the precomputed gen2 basis?*/
secp256k1_pedersen_ecmult(ecmult_gen_ctx, &pubs[npub], &sec[i], ((uint64_t)secidx[i] * scale) << (i*2));
secp256k1_pedersen_ecmult(ecmult_gen_ctx, &pubs[npub], &sec[i], ((uint64_t)secidx[i] * scale) << (i*2), genp);
if (secp256k1_gej_is_infinity(&pubs[npub])) {
return 0;
}
@ -314,7 +317,7 @@ SECP256K1_INLINE static int secp256k1_rangeproof_sign_impl(const secp256k1_ecmul
}
npub += rsizes[i];
}
secp256k1_rangeproof_pub_expand(pubs, exp, rsizes, rings);
secp256k1_rangeproof_pub_expand(pubs, exp, rsizes, rings, genp);
secp256k1_sha256_finalize(&sha256_m, tmp);
if (!secp256k1_borromean_sign(ecmult_ctx, ecmult_gen_ctx, &proof[len], s, pubs, k, sec, rsizes, secidx, rings, tmp, 32)) {
return 0;
@ -357,7 +360,7 @@ 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, 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) {
size_t *rsizes, size_t rings, const unsigned char *nonce, const secp256k1_ge *commit, const unsigned char *proof, size_t len, const secp256k1_ge *genp) {
secp256k1_scalar s_orig[128];
secp256k1_scalar sec[32];
secp256k1_scalar stmp;
@ -376,7 +379,7 @@ SECP256K1_INLINE static int secp256k1_rangeproof_rewind_inner(secp256k1_scalar *
VERIFY_CHECK(npub >= 1);
memset(prep, 0, 4096);
/* Reconstruct the provers random values. */
secp256k1_rangeproof_genrand(sec, s_orig, prep, rsizes, rings, nonce, commit, proof, len);
secp256k1_rangeproof_genrand(sec, s_orig, prep, rsizes, rings, nonce, commit, proof, len, genp);
*v = UINT64_MAX;
secp256k1_scalar_clear(blind);
if (rings == 1 && rsizes[0] == 1) {
@ -535,7 +538,7 @@ SECP256K1_INLINE static int secp256k1_rangeproof_getheader_impl(size_t *offset,
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, 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) {
uint64_t *min_value, uint64_t *max_value, const secp256k1_ge *commit, const unsigned char *proof, size_t plen, const secp256k1_ge* genp) {
secp256k1_gej accj;
secp256k1_gej pubs[128];
secp256k1_ge c;
@ -583,6 +586,8 @@ SECP256K1_INLINE static int secp256k1_rangeproof_verify_impl(const secp256k1_ecm
secp256k1_sha256_initialize(&sha256_m);
secp256k1_rangeproof_serialize_point(m, commit);
secp256k1_sha256_write(&sha256_m, m, 33);
secp256k1_rangeproof_serialize_point(m, genp);
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;
@ -597,7 +602,7 @@ SECP256K1_INLINE static int secp256k1_rangeproof_verify_impl(const secp256k1_ecm
npub = 0;
secp256k1_gej_set_infinity(&accj);
if (*min_value) {
secp256k1_pedersen_ecmult_small(&accj, *min_value);
secp256k1_pedersen_ecmult_small(&accj, *min_value, genp);
}
for(i = 0; i < rings - 1; i++) {
secp256k1_fe fe;
@ -620,7 +625,7 @@ SECP256K1_INLINE static int secp256k1_rangeproof_verify_impl(const secp256k1_ecm
if (secp256k1_gej_is_infinity(&pubs[npub])) {
return 0;
}
secp256k1_rangeproof_pub_expand(pubs, exp, rsizes, rings);
secp256k1_rangeproof_pub_expand(pubs, exp, rsizes, rings, genp);
npub += rsizes[rings - 1];
e0 = &proof[offset];
offset += 32;
@ -644,13 +649,13 @@ SECP256K1_INLINE static int secp256k1_rangeproof_verify_impl(const secp256k1_ecm
if (!ecmult_gen_ctx) {
return 0;
}
if (!secp256k1_rangeproof_rewind_inner(&blind, &vv, message_out, outlen, evalues, s, rsizes, rings, nonce, commit, proof, offset_post_header)) {
if (!secp256k1_rangeproof_rewind_inner(&blind, &vv, message_out, outlen, evalues, s, rsizes, rings, nonce, commit, proof, offset_post_header, genp)) {
return 0;
}
/* Unwind apparently successful, see if the commitment can be reconstructed. */
/* FIXME: should check vv is in the mantissa's range. */
vv = (vv * scale) + *min_value;
secp256k1_pedersen_ecmult(ecmult_gen_ctx, &accj, &blind, vv);
secp256k1_pedersen_ecmult(ecmult_gen_ctx, &accj, &blind, vv, genp);
if (secp256k1_gej_is_infinity(&accj)) {
return 0;
}

View File

@ -63,10 +63,10 @@ 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], &blinds[i * 32], values[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, totalv));
CHECK(!secp256k1_pedersen_verify_tally(ctx, cptr, inputs, &cptr[inputs], outputs, totalv + 1));
CHECK(secp256k1_pedersen_verify_tally(ctx, cptr, inputs, &cptr[inputs], outputs, totalv, secp256k1_generator_h));
CHECK(!secp256k1_pedersen_verify_tally(ctx, cptr, inputs, &cptr[inputs], outputs, totalv + 1, secp256k1_generator_h));
random_scalar_order(&s);
for (i = 0; i < 4; i++) {
secp256k1_scalar_get_b32(&blinds[i * 32], &s);
@ -75,14 +75,14 @@ void test_pedersen(void) {
values[1] = 0;
values[2] = 1;
for (i = 0; i < 3; i++) {
CHECK(secp256k1_pedersen_commit(ctx, &commits[i], &blinds[i * 32], values[i]));
CHECK(secp256k1_pedersen_commit(ctx, &commits[i], &blinds[i * 32], values[i], secp256k1_generator_h));
}
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));
CHECK(secp256k1_pedersen_verify_tally(ctx, &cptr[0], 1, &cptr[0], 1, 0));
CHECK(secp256k1_pedersen_verify_tally(ctx, &cptr[0], 1, &cptr[1], 1, INT64_MAX));
CHECK(secp256k1_pedersen_verify_tally(ctx, &cptr[1], 1, &cptr[1], 1, 0));
CHECK(secp256k1_pedersen_verify_tally(ctx, &cptr[1], 1, &cptr[0], 1, -INT64_MAX));
CHECK(secp256k1_pedersen_verify_tally(ctx, &cptr[1], 1, &cptr[2], 1, -1, secp256k1_generator_h));
CHECK(secp256k1_pedersen_verify_tally(ctx, &cptr[2], 1, &cptr[1], 1, 1, secp256k1_generator_h));
CHECK(secp256k1_pedersen_verify_tally(ctx, &cptr[0], 1, &cptr[0], 1, 0, secp256k1_generator_h));
CHECK(secp256k1_pedersen_verify_tally(ctx, &cptr[0], 1, &cptr[1], 1, INT64_MAX, secp256k1_generator_h));
CHECK(secp256k1_pedersen_verify_tally(ctx, &cptr[1], 1, &cptr[1], 1, 0, secp256k1_generator_h));
CHECK(secp256k1_pedersen_verify_tally(ctx, &cptr[1], 1, &cptr[0], 1, -INT64_MAX, secp256k1_generator_h));
}
void test_borromean(void) {
@ -180,7 +180,7 @@ void test_rangeproof(void) {
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, secp256k1_generator_h));
for (vmin = 0; vmin < (i<9 && i > 0 ? 2 : 1); vmin++) {
const unsigned char *input_message = NULL;
size_t input_message_len = 0;
@ -196,10 +196,10 @@ void test_rangeproof(void) {
input_message_len = sizeof(message_long);
}
len = 5134;
CHECK(secp256k1_rangeproof_sign(ctx, proof, &len, vmin, &commit, blind, commit.data, 0, 0, v, input_message, input_message_len));
CHECK(secp256k1_rangeproof_sign(ctx, proof, &len, vmin, &commit, blind, commit.data, 0, 0, v, input_message, input_message_len, secp256k1_generator_h));
CHECK(len <= 5134);
mlen = 4096;
CHECK(secp256k1_rangeproof_rewind(ctx, blindout, &vout, message, &mlen, commit.data, &minv, &maxv, &commit, proof, len));
CHECK(secp256k1_rangeproof_rewind(ctx, blindout, &vout, message, &mlen, commit.data, &minv, &maxv, &commit, proof, len, secp256k1_generator_h));
if (input_message != NULL) {
CHECK(memcmp(message, input_message, input_message_len) == 0);
}
@ -212,9 +212,9 @@ void test_rangeproof(void) {
CHECK(minv <= v);
CHECK(maxv >= v);
len = 5134;
CHECK(secp256k1_rangeproof_sign(ctx, proof, &len, v, &commit, blind, commit.data, -1, 64, v, NULL, 0));
CHECK(secp256k1_rangeproof_sign(ctx, proof, &len, v, &commit, blind, commit.data, -1, 64, v, NULL, 0, secp256k1_generator_h));
CHECK(len <= 73);
CHECK(secp256k1_rangeproof_rewind(ctx, blindout, &vout, NULL, NULL, commit.data, &minv, &maxv, &commit, proof, len));
CHECK(secp256k1_rangeproof_rewind(ctx, blindout, &vout, NULL, NULL, commit.data, &minv, &maxv, &commit, proof, len, secp256k1_generator_h));
CHECK(memcmp(blindout, blind, 32) == 0);
CHECK(vout == v);
CHECK(minv == v);
@ -223,11 +223,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, secp256k1_generator_h));
for (i = 0; i < 19; i++) {
len = 5134;
CHECK(secp256k1_rangeproof_sign(ctx, proof, &len, 0, &commit, blind, commit.data, i, 0, v, NULL, 0));
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, NULL, 0, secp256k1_generator_h));
CHECK(secp256k1_rangeproof_verify(ctx, &minv, &maxv, &commit, proof, len, secp256k1_generator_h));
CHECK(len <= 5134);
CHECK(minv <= v);
CHECK(maxv >= v);
@ -236,16 +236,16 @@ 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, secp256k1_generator_h));
len = 5134;
CHECK(secp256k1_rangeproof_sign(ctx, proof, &len, 0, &commit, blind, commit.data, 0, 3, v, NULL, 0));
CHECK(secp256k1_rangeproof_sign(ctx, proof, &len, 0, &commit, blind, commit.data, 0, 3, v, NULL, 0, secp256k1_generator_h));
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, secp256k1_generator_h));
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, secp256k1_generator_h));
CHECK(minv <= v);
CHECK(maxv >= v);
}
@ -259,7 +259,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, secp256k1_generator_h));
len = 5134;
exp = (int)secp256k1_rands64(0,18)-(int)secp256k1_rands64(0,18);
if (exp < 0) {
@ -269,10 +269,10 @@ void test_rangeproof(void) {
if (min_bits < 0) {
min_bits = -min_bits;
}
CHECK(secp256k1_rangeproof_sign(ctx, proof, &len, vmin, &commit, blind, commit.data, exp, min_bits, v, NULL, 0));
CHECK(secp256k1_rangeproof_sign(ctx, proof, &len, vmin, &commit, blind, commit.data, exp, min_bits, v, NULL, 0, secp256k1_generator_h));
CHECK(len <= 5134);
mlen = 4096;
CHECK(secp256k1_rangeproof_rewind(ctx, blindout, &vout, message, &mlen, commit.data, &minv, &maxv, &commit, proof, len));
CHECK(secp256k1_rangeproof_rewind(ctx, blindout, &vout, message, &mlen, commit.data, &minv, &maxv, &commit, proof, len, secp256k1_generator_h));
for (j = 0; j < mlen; j++) {
CHECK(message[j] == 0);
}
@ -281,7 +281,7 @@ void test_rangeproof(void) {
CHECK(vout == v);
CHECK(minv <= v);
CHECK(maxv >= v);
CHECK(secp256k1_rangeproof_rewind(ctx, blindout, &vout, NULL, NULL, commit.data, &minv, &maxv, &commit, proof, len));
CHECK(secp256k1_rangeproof_rewind(ctx, blindout, &vout, NULL, NULL, commit.data, &minv, &maxv, &commit, proof, len, secp256k1_generator_h));
memcpy(&commit2, &commit, sizeof(commit));
}
for (j = 0; j < 10; j++) {
@ -290,10 +290,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, secp256k1_generator_h));
}
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, secp256k1_generator_h));
}
}