rangeproof: several API changes
* add summing function for blinded generators * drop `excess` and `gen` from `verify_tally` * add extra_commit to rangeproof sign and verify
This commit is contained in:
committed by
Pieter Wuille
parent
c3db107c44
commit
f948ca216d
@@ -12,6 +12,7 @@
|
||||
#include "field.h"
|
||||
#include "group.h"
|
||||
#include "hash.h"
|
||||
#include "scalar.h"
|
||||
|
||||
static void secp256k1_generator_load(secp256k1_ge* ge, const secp256k1_generator* gen) {
|
||||
secp256k1_fe fe;
|
||||
|
||||
@@ -118,8 +118,7 @@ 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, const secp256k1_generator* gen) {
|
||||
secp256k1_ge genp;
|
||||
int secp256k1_pedersen_verify_tally(const secp256k1_context* ctx, const secp256k1_pedersen_commitment * const* commits, size_t pcnt, const secp256k1_pedersen_commitment * const* ncommits, size_t ncnt) {
|
||||
secp256k1_gej accj;
|
||||
secp256k1_ge add;
|
||||
size_t i;
|
||||
@@ -127,17 +126,6 @@ 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, &genp);
|
||||
if (neg) {
|
||||
secp256k1_gej_neg(&accj, &accj);
|
||||
}
|
||||
}
|
||||
for (i = 0; i < ncnt; i++) {
|
||||
secp256k1_pedersen_commitment_load(&add, ncommits[i]);
|
||||
secp256k1_gej_add_ge_var(&accj, &accj, &add, NULL);
|
||||
@@ -150,6 +138,60 @@ int secp256k1_pedersen_verify_tally(const secp256k1_context* ctx, const secp256k
|
||||
return secp256k1_gej_is_infinity(&accj);
|
||||
}
|
||||
|
||||
int secp256k1_pedersen_blind_generator_blind_sum(const secp256k1_context* ctx, const uint64_t *value, const unsigned char* const* generator_blind, unsigned char* const* blinding_factor, size_t n_total, size_t n_inputs) {
|
||||
secp256k1_scalar sum;
|
||||
secp256k1_scalar tmp;
|
||||
size_t i;
|
||||
|
||||
VERIFY_CHECK(ctx != NULL);
|
||||
ARG_CHECK(n_total == 0 || value != NULL);
|
||||
ARG_CHECK(n_total == 0 || generator_blind != NULL);
|
||||
ARG_CHECK(n_total == 0 || blinding_factor != NULL);
|
||||
ARG_CHECK(n_total > n_inputs);
|
||||
(void) ctx;
|
||||
|
||||
if (n_total == 0) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
secp256k1_scalar_set_int(&sum, 0);
|
||||
for (i = 0; i < n_total; i++) {
|
||||
int overflow = 0;
|
||||
secp256k1_scalar addend;
|
||||
secp256k1_scalar_set_u64(&addend, value[i]); /* s = v */
|
||||
|
||||
secp256k1_scalar_set_b32(&tmp, generator_blind[i], &overflow);
|
||||
if (overflow == 1) {
|
||||
secp256k1_scalar_clear(&tmp);
|
||||
secp256k1_scalar_clear(&addend);
|
||||
secp256k1_scalar_clear(&sum);
|
||||
return 0;
|
||||
}
|
||||
secp256k1_scalar_mul(&addend, &addend, &tmp); /* s = vr */
|
||||
|
||||
secp256k1_scalar_set_b32(&tmp, blinding_factor[i], &overflow);
|
||||
if (overflow == 1) {
|
||||
secp256k1_scalar_clear(&tmp);
|
||||
secp256k1_scalar_clear(&addend);
|
||||
secp256k1_scalar_clear(&sum);
|
||||
return 0;
|
||||
}
|
||||
secp256k1_scalar_add(&addend, &addend, &tmp); /* s = vr + r' */
|
||||
secp256k1_scalar_cond_negate(&addend, i < n_inputs); /* s is negated if it's an input */
|
||||
secp256k1_scalar_add(&sum, &sum, &addend); /* sum += s */
|
||||
secp256k1_scalar_clear(&addend);
|
||||
}
|
||||
|
||||
/* Right now tmp has the last pedersen blinding factor. Subtract the sum from it. */
|
||||
secp256k1_scalar_negate(&sum, &sum);
|
||||
secp256k1_scalar_add(&tmp, &tmp, &sum);
|
||||
secp256k1_scalar_get_b32(blinding_factor[n_total - 1], &tmp);
|
||||
|
||||
secp256k1_scalar_clear(&tmp);
|
||||
secp256k1_scalar_clear(&sum);
|
||||
return 1;
|
||||
}
|
||||
|
||||
int secp256k1_rangeproof_info(const secp256k1_context* ctx, int *exp, int *mantissa,
|
||||
uint64_t *min_value, uint64_t *max_value, const unsigned char *proof, size_t plen) {
|
||||
size_t offset;
|
||||
@@ -167,7 +209,7 @@ 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_generator* gen) {
|
||||
const secp256k1_pedersen_commitment *commit, const unsigned char *proof, size_t plen, const unsigned char *extra_commit, size_t extra_commit_len, const secp256k1_generator* gen) {
|
||||
secp256k1_ge commitp;
|
||||
secp256k1_ge genp;
|
||||
ARG_CHECK(ctx != NULL);
|
||||
@@ -180,11 +222,11 @@ int secp256k1_rangeproof_rewind(const secp256k1_context* 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, &genp);
|
||||
blind_out, value_out, message_out, outlen, nonce, min_value, max_value, &commitp, proof, plen, extra_commit, extra_commit_len, &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_generator* gen) {
|
||||
const secp256k1_pedersen_commitment *commit, const unsigned char *proof, size_t plen, const unsigned char *extra_commit, size_t extra_commit_len, const secp256k1_generator* gen) {
|
||||
secp256k1_ge commitp;
|
||||
secp256k1_ge genp;
|
||||
ARG_CHECK(ctx != NULL);
|
||||
@@ -196,12 +238,12 @@ int secp256k1_rangeproof_verify(const secp256k1_context* ctx, uint64_t *min_valu
|
||||
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, &genp);
|
||||
NULL, NULL, NULL, NULL, NULL, min_value, max_value, &commitp, proof, plen, extra_commit, extra_commit_len, &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 secp256k1_generator* gen){
|
||||
const unsigned char *message, size_t msg_len, const unsigned char *extra_commit, size_t extra_commit_len, const secp256k1_generator* gen){
|
||||
secp256k1_ge commitp;
|
||||
secp256k1_ge genp;
|
||||
ARG_CHECK(ctx != NULL);
|
||||
@@ -215,7 +257,7 @@ int secp256k1_rangeproof_sign(const secp256k1_context* ctx, unsigned char *proof
|
||||
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, &genp);
|
||||
proof, plen, min_value, &commitp, blind, nonce, exp, min_bits, value, message, msg_len, extra_commit, extra_commit_len, &genp);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
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, const secp256k1_ge* genp);
|
||||
uint64_t *min_value, uint64_t *max_value, const secp256k1_ge *commit, const unsigned char *proof, size_t plen,
|
||||
const unsigned char *extra_commit, size_t extra_commit_len, const secp256k1_ge* genp);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -193,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 secp256k1_ge* genp){
|
||||
const unsigned char *message, size_t msg_len, const unsigned char *extra_commit, size_t extra_commit_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. */
|
||||
@@ -318,6 +318,9 @@ SECP256K1_INLINE static int secp256k1_rangeproof_sign_impl(const secp256k1_ecmul
|
||||
npub += rsizes[i];
|
||||
}
|
||||
secp256k1_rangeproof_pub_expand(pubs, exp, rsizes, rings, genp);
|
||||
if (extra_commit != NULL) {
|
||||
secp256k1_sha256_write(&sha256_m, extra_commit, extra_commit_len);
|
||||
}
|
||||
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;
|
||||
@@ -538,7 +541,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, const secp256k1_ge* genp) {
|
||||
uint64_t *min_value, uint64_t *max_value, const secp256k1_ge *commit, const unsigned char *proof, size_t plen, const unsigned char *extra_commit, size_t extra_commit_len, const secp256k1_ge* genp) {
|
||||
secp256k1_gej accj;
|
||||
secp256k1_gej pubs[128];
|
||||
secp256k1_ge c;
|
||||
@@ -640,6 +643,9 @@ SECP256K1_INLINE static int secp256k1_rangeproof_verify_impl(const secp256k1_ecm
|
||||
/*Extra data found, reject.*/
|
||||
return 0;
|
||||
}
|
||||
if (extra_commit != NULL) {
|
||||
secp256k1_sha256_write(&sha256_m, extra_commit, extra_commit_len);
|
||||
}
|
||||
secp256k1_sha256_finalize(&sha256_m, m);
|
||||
ret = secp256k1_borromean_verify(ecmult_ctx, nonce ? evalues : NULL, e0, s, pubs, rsizes, rings, m, 32);
|
||||
if (ret && nonce) {
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
|
||||
#include "include/secp256k1_rangeproof.h"
|
||||
|
||||
void test_pedersen(void) {
|
||||
static void test_pedersen(void) {
|
||||
secp256k1_pedersen_commitment commits[19];
|
||||
const secp256k1_pedersen_commitment *cptr[19];
|
||||
unsigned char blinds[32*19];
|
||||
@@ -40,23 +40,12 @@ void test_pedersen(void) {
|
||||
values[i] = secp256k1_rands64(0, INT64_MAX - totalv);
|
||||
totalv += values[i];
|
||||
}
|
||||
if (secp256k1_rand32() & 1) {
|
||||
for (i = 0; i < outputs; i++) {
|
||||
int64_t max = INT64_MAX;
|
||||
if (totalv < 0) {
|
||||
max += totalv;
|
||||
}
|
||||
values[i + inputs] = secp256k1_rands64(0, max);
|
||||
totalv -= values[i + inputs];
|
||||
}
|
||||
} else {
|
||||
for (i = 0; i < outputs - 1; i++) {
|
||||
values[i + inputs] = secp256k1_rands64(0, totalv);
|
||||
totalv -= values[i + inputs];
|
||||
}
|
||||
values[total - 1] = totalv >> (secp256k1_rand32() & 1);
|
||||
totalv -= values[total - 1];
|
||||
for (i = 0; i < outputs - 1; i++) {
|
||||
values[i + inputs] = secp256k1_rands64(0, totalv);
|
||||
totalv -= values[i + inputs];
|
||||
}
|
||||
values[total - 1] = totalv;
|
||||
|
||||
for (i = 0; i < total - 1; i++) {
|
||||
random_scalar_order(&s);
|
||||
secp256k1_scalar_get_b32(&blinds[i * 32], &s);
|
||||
@@ -65,8 +54,11 @@ void test_pedersen(void) {
|
||||
for (i = 0; i < total; i++) {
|
||||
CHECK(secp256k1_pedersen_commit(ctx, &commits[i], &blinds[i * 32], values[i], secp256k1_generator_h));
|
||||
}
|
||||
CHECK(secp256k1_pedersen_verify_tally(ctx, cptr, inputs, &cptr[inputs], outputs, totalv, secp256k1_generator_h));
|
||||
CHECK(!secp256k1_pedersen_verify_tally(ctx, cptr, inputs, &cptr[inputs], outputs, totalv + 1, secp256k1_generator_h));
|
||||
CHECK(secp256k1_pedersen_verify_tally(ctx, cptr, inputs, &cptr[inputs], outputs));
|
||||
CHECK(secp256k1_pedersen_verify_tally(ctx, &cptr[inputs], outputs, cptr, inputs));
|
||||
if (inputs > 0 && values[0] > 0) {
|
||||
CHECK(!secp256k1_pedersen_verify_tally(ctx, cptr, inputs - 1, &cptr[inputs], outputs));
|
||||
}
|
||||
random_scalar_order(&s);
|
||||
for (i = 0; i < 4; i++) {
|
||||
secp256k1_scalar_get_b32(&blinds[i * 32], &s);
|
||||
@@ -77,15 +69,11 @@ void test_pedersen(void) {
|
||||
for (i = 0; i < 3; i++) {
|
||||
CHECK(secp256k1_pedersen_commit(ctx, &commits[i], &blinds[i * 32], values[i], secp256k1_generator_h));
|
||||
}
|
||||
CHECK(secp256k1_pedersen_verify_tally(ctx, &cptr[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));
|
||||
CHECK(secp256k1_pedersen_verify_tally(ctx, &cptr[0], 1, &cptr[0], 1));
|
||||
CHECK(secp256k1_pedersen_verify_tally(ctx, &cptr[1], 1, &cptr[1], 1));
|
||||
}
|
||||
|
||||
void test_borromean(void) {
|
||||
static void test_borromean(void) {
|
||||
unsigned char e0[32];
|
||||
secp256k1_scalar s[64];
|
||||
secp256k1_gej pubs[64];
|
||||
@@ -150,7 +138,7 @@ void test_borromean(void) {
|
||||
}
|
||||
}
|
||||
|
||||
void test_rangeproof(void) {
|
||||
static 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};
|
||||
secp256k1_pedersen_commitment commit;
|
||||
secp256k1_pedersen_commitment commit2;
|
||||
@@ -196,10 +184,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, secp256k1_generator_h));
|
||||
CHECK(secp256k1_rangeproof_sign(ctx, proof, &len, vmin, &commit, blind, commit.data, 0, 0, v, input_message, input_message_len, 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, secp256k1_generator_h));
|
||||
CHECK(secp256k1_rangeproof_rewind(ctx, blindout, &vout, message, &mlen, commit.data, &minv, &maxv, &commit, proof, len, NULL, 0, secp256k1_generator_h));
|
||||
if (input_message != NULL) {
|
||||
CHECK(memcmp(message, input_message, input_message_len) == 0);
|
||||
}
|
||||
@@ -212,9 +200,21 @@ 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, secp256k1_generator_h));
|
||||
CHECK(secp256k1_rangeproof_sign(ctx, proof, &len, v, &commit, blind, commit.data, -1, 64, v, NULL, 0, NULL, 0, secp256k1_generator_h));
|
||||
CHECK(len <= 73);
|
||||
CHECK(secp256k1_rangeproof_rewind(ctx, blindout, &vout, NULL, NULL, commit.data, &minv, &maxv, &commit, proof, len, secp256k1_generator_h));
|
||||
CHECK(secp256k1_rangeproof_rewind(ctx, blindout, &vout, NULL, NULL, commit.data, &minv, &maxv, &commit, proof, len, NULL, 0, secp256k1_generator_h));
|
||||
CHECK(memcmp(blindout, blind, 32) == 0);
|
||||
CHECK(vout == v);
|
||||
CHECK(minv == v);
|
||||
CHECK(maxv == v);
|
||||
|
||||
/* Check with a committed message */
|
||||
len = 5134;
|
||||
CHECK(secp256k1_rangeproof_sign(ctx, proof, &len, v, &commit, blind, commit.data, -1, 64, v, NULL, 0, message_short, sizeof(message_short), secp256k1_generator_h));
|
||||
CHECK(len <= 73);
|
||||
CHECK(!secp256k1_rangeproof_rewind(ctx, blindout, &vout, NULL, NULL, commit.data, &minv, &maxv, &commit, proof, len, NULL, 0, secp256k1_generator_h));
|
||||
CHECK(!secp256k1_rangeproof_rewind(ctx, blindout, &vout, NULL, NULL, commit.data, &minv, &maxv, &commit, proof, len, message_long, sizeof(message_long), secp256k1_generator_h));
|
||||
CHECK(secp256k1_rangeproof_rewind(ctx, blindout, &vout, NULL, NULL, commit.data, &minv, &maxv, &commit, proof, len, message_short, sizeof(message_short), secp256k1_generator_h));
|
||||
CHECK(memcmp(blindout, blind, 32) == 0);
|
||||
CHECK(vout == v);
|
||||
CHECK(minv == v);
|
||||
@@ -226,11 +226,13 @@ void test_rangeproof(void) {
|
||||
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, secp256k1_generator_h));
|
||||
CHECK(secp256k1_rangeproof_verify(ctx, &minv, &maxv, &commit, proof, len, secp256k1_generator_h));
|
||||
CHECK(secp256k1_rangeproof_sign(ctx, proof, &len, 0, &commit, blind, commit.data, i, 0, v, NULL, 0, NULL, 0, secp256k1_generator_h));
|
||||
CHECK(secp256k1_rangeproof_verify(ctx, &minv, &maxv, &commit, proof, len, NULL, 0, secp256k1_generator_h));
|
||||
CHECK(len <= 5134);
|
||||
CHECK(minv <= v);
|
||||
CHECK(maxv >= v);
|
||||
/* Make sure it fails when validating with a committed message */
|
||||
CHECK(!secp256k1_rangeproof_verify(ctx, &minv, &maxv, &commit, proof, len, message_short, sizeof(message_short), secp256k1_generator_h));
|
||||
}
|
||||
secp256k1_rand256(blind);
|
||||
{
|
||||
@@ -238,14 +240,14 @@ void test_rangeproof(void) {
|
||||
v = secp256k1_rands64(0, 255);
|
||||
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, secp256k1_generator_h));
|
||||
CHECK(secp256k1_rangeproof_sign(ctx, proof, &len, 0, &commit, blind, commit.data, 0, 3, v, NULL, 0, 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, secp256k1_generator_h));
|
||||
CHECK(!secp256k1_rangeproof_verify(ctx, &minv, &maxv, &commit, proof, len, NULL, 0, secp256k1_generator_h));
|
||||
proof[i >> 3] ^= 1 << (i & 7);
|
||||
}
|
||||
CHECK(secp256k1_rangeproof_verify(ctx, &minv, &maxv, &commit, proof, len, secp256k1_generator_h));
|
||||
CHECK(secp256k1_rangeproof_verify(ctx, &minv, &maxv, &commit, proof, len, NULL, 0, secp256k1_generator_h));
|
||||
CHECK(minv <= v);
|
||||
CHECK(maxv >= v);
|
||||
}
|
||||
@@ -269,10 +271,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, secp256k1_generator_h));
|
||||
CHECK(secp256k1_rangeproof_sign(ctx, proof, &len, vmin, &commit, blind, commit.data, exp, min_bits, v, NULL, 0, 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, secp256k1_generator_h));
|
||||
CHECK(secp256k1_rangeproof_rewind(ctx, blindout, &vout, message, &mlen, commit.data, &minv, &maxv, &commit, proof, len, NULL, 0, secp256k1_generator_h));
|
||||
for (j = 0; j < mlen; j++) {
|
||||
CHECK(message[j] == 0);
|
||||
}
|
||||
@@ -281,7 +283,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, secp256k1_generator_h));
|
||||
CHECK(secp256k1_rangeproof_rewind(ctx, blindout, &vout, NULL, NULL, commit.data, &minv, &maxv, &commit, proof, len, NULL, 0, secp256k1_generator_h));
|
||||
memcpy(&commit2, &commit, sizeof(commit));
|
||||
}
|
||||
for (j = 0; j < 10; j++) {
|
||||
@@ -290,13 +292,69 @@ void test_rangeproof(void) {
|
||||
}
|
||||
for (k = 0; k < 128; k++) {
|
||||
len = k;
|
||||
CHECK(!secp256k1_rangeproof_verify(ctx, &minv, &maxv, &commit2, proof, len, secp256k1_generator_h));
|
||||
CHECK(!secp256k1_rangeproof_verify(ctx, &minv, &maxv, &commit2, proof, len, NULL, 0, secp256k1_generator_h));
|
||||
}
|
||||
len = secp256k1_rands64(0, 3072);
|
||||
CHECK(!secp256k1_rangeproof_verify(ctx, &minv, &maxv, &commit2, proof, len, secp256k1_generator_h));
|
||||
CHECK(!secp256k1_rangeproof_verify(ctx, &minv, &maxv, &commit2, proof, len, NULL, 0, secp256k1_generator_h));
|
||||
}
|
||||
}
|
||||
|
||||
#define MAX_N_GENS 30
|
||||
void test_multiple_generators(void) {
|
||||
const size_t n_inputs = (secp256k1_rand32() % (MAX_N_GENS / 2)) + 1;
|
||||
const size_t n_outputs = (secp256k1_rand32() % (MAX_N_GENS / 2)) + 1;
|
||||
const size_t n_generators = n_inputs + n_outputs;
|
||||
unsigned char *generator_blind[MAX_N_GENS];
|
||||
unsigned char *pedersen_blind[MAX_N_GENS];
|
||||
secp256k1_generator generator[MAX_N_GENS];
|
||||
secp256k1_pedersen_commitment commit[MAX_N_GENS];
|
||||
const secp256k1_pedersen_commitment *commit_ptr[MAX_N_GENS];
|
||||
size_t i;
|
||||
int64_t total_value;
|
||||
uint64_t value[MAX_N_GENS];
|
||||
|
||||
secp256k1_scalar s;
|
||||
|
||||
unsigned char generator_seed[32];
|
||||
random_scalar_order(&s);
|
||||
secp256k1_scalar_get_b32(generator_seed, &s);
|
||||
/* Create all the needed generators */
|
||||
for (i = 0; i < n_generators; i++) {
|
||||
generator_blind[i] = (unsigned char*) malloc(32);
|
||||
pedersen_blind[i] = (unsigned char*) malloc(32);
|
||||
|
||||
random_scalar_order(&s);
|
||||
secp256k1_scalar_get_b32(generator_blind[i], &s);
|
||||
random_scalar_order(&s);
|
||||
secp256k1_scalar_get_b32(pedersen_blind[i], &s);
|
||||
|
||||
CHECK(secp256k1_generator_generate_blinded(ctx, &generator[i], generator_seed, generator_blind[i]));
|
||||
|
||||
commit_ptr[i] = &commit[i];
|
||||
}
|
||||
|
||||
/* Compute all the values -- can be positive or negative */
|
||||
total_value = 0;
|
||||
for (i = 0; i < n_outputs; i++) {
|
||||
value[n_inputs + i] = secp256k1_rands64(0, INT64_MAX - total_value);
|
||||
total_value += value[n_inputs + i];
|
||||
}
|
||||
for (i = 0; i < n_inputs - 1; i++) {
|
||||
value[i] = secp256k1_rands64(0, total_value);
|
||||
total_value -= value[i];
|
||||
}
|
||||
value[i] = total_value;
|
||||
|
||||
/* Correct for blinding factors and do the commitments */
|
||||
CHECK(secp256k1_pedersen_blind_generator_blind_sum(ctx, value, (const unsigned char * const *) generator_blind, pedersen_blind, n_generators, n_inputs));
|
||||
for (i = 0; i < n_generators; i++) {
|
||||
CHECK(secp256k1_pedersen_commit(ctx, &commit[i], pedersen_blind[i], value[i], &generator[i]));
|
||||
}
|
||||
|
||||
/* Verify */
|
||||
CHECK(secp256k1_pedersen_verify_tally(ctx, &commit_ptr[0], n_inputs, &commit_ptr[n_inputs], n_outputs));
|
||||
}
|
||||
|
||||
void run_rangeproof_tests(void) {
|
||||
int i;
|
||||
for (i = 0; i < 10*count; i++) {
|
||||
@@ -306,6 +364,7 @@ void run_rangeproof_tests(void) {
|
||||
test_borromean();
|
||||
}
|
||||
test_rangeproof();
|
||||
test_multiple_generators();
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user