Expose generator in pedersen/rangeproof API
This commit is contained in:
parent
54fa2639e1
commit
9b00b61d9d
@ -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.
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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));
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user