Skip to content

Commit

Permalink
Merge pull request #48 from jaspervdm/rewind
Browse files Browse the repository at this point in the history
Support new Bulletproof rewind scheme
  • Loading branch information
yeastplume authored Jun 2, 2019
2 parents 07a94be + cb411c6 commit 84563ed
Show file tree
Hide file tree
Showing 5 changed files with 36 additions and 46 deletions.
8 changes: 3 additions & 5 deletions include/secp256k1_bulletproofs.h
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,6 @@ SECP256K1_WARN_UNUSED_RESULT SECP256K1_API int secp256k1_bulletproof_rangeproof_
* Returns: 1: value and blinding factor were extracted and matched the input commit
* 0: one of the above was not true, extraction failed
* Args: ctx: pointer to a context object (cannot be NULL)
* gens: generator set used to make original proof (cannot be NULL)
* Out: value: pointer to value that will be extracted
* blind: pointer to 32-byte array for blinding factor to be extracted
* In: proof: byte-serialized rangeproof (cannot be NULL)
Expand All @@ -118,11 +117,10 @@ SECP256K1_WARN_UNUSED_RESULT SECP256K1_API int secp256k1_bulletproof_rangeproof_
* nonce: random 32-byte seed used to derive blinding factors (cannot be NULL)
* extra_commit: additional data committed to by the rangeproof
* extra_commit_len: length of additional data
* message: optional 16 bytes of message to recover
* message: optional 20 bytes of message to recover
*/
SECP256K1_WARN_UNUSED_RESULT SECP256K1_API int secp256k1_bulletproof_rangeproof_rewind(
const secp256k1_context* ctx,
const secp256k1_bulletproof_generators* gens,
uint64_t* value,
unsigned char* blind,
const unsigned char* proof,
Expand All @@ -134,7 +132,7 @@ SECP256K1_WARN_UNUSED_RESULT SECP256K1_API int secp256k1_bulletproof_rangeproof_
const unsigned char* extra_commit,
size_t extra_commit_len,
unsigned char* message
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4) SECP256K1_ARG_NONNULL(5) SECP256K1_ARG_NONNULL(8) SECP256K1_ARG_NONNULL(9);
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4) SECP256K1_ARG_NONNULL(7) SECP256K1_ARG_NONNULL(8);

/** Produces an aggregate Bulletproof rangeproof for a set of Pedersen commitments
* Returns: 1: rangeproof was successfully created
Expand All @@ -158,7 +156,7 @@ SECP256K1_WARN_UNUSED_RESULT SECP256K1_API int secp256k1_bulletproof_rangeproof_
* private_nonce: only for multi-party; random 32-byte seed used to derive private blinding factors
* extra_commit: additonal data committed to by the rangeproof
* extra_commit_len: length of additional data
* message: optional 16 bytes of message that can be recovered by rewinding with the correct nonce
* message: optional 20 bytes of message that can be recovered by rewinding with the correct nonce
*/
SECP256K1_WARN_UNUSED_RESULT SECP256K1_API int secp256k1_bulletproof_rangeproof_prove(
const secp256k1_context* ctx,
Expand Down
6 changes: 3 additions & 3 deletions src/bench_bulletproof.c
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ static void bench_bulletproof_rangeproof_setup(void* arg) {
CHECK(secp256k1_bulletproof_rangeproof_verify(data->common->ctx, data->common->scratch, data->common->generators, data->common->proof[0], data->common->plen, NULL, data->commit[0], data->n_commits, data->nbits, data->common->value_gen, NULL, 0) == 1);
CHECK(secp256k1_bulletproof_rangeproof_verify_multi(data->common->ctx, data->common->scratch, data->common->generators, (const unsigned char **) data->common->proof, data->common->n_proofs, data->common->plen, NULL, (const secp256k1_pedersen_commitment **) data->commit, data->n_commits, data->nbits, data->common->value_gen, NULL, 0) == 1);
if (data->n_commits == 1) {
CHECK(secp256k1_bulletproof_rangeproof_rewind(data->common->ctx, data->common->generators, &v, blind, data->common->proof[0], data->common->plen, 0, data->commit[0], &data->common->value_gen[0], data->common->nonce, NULL, 0, NULL) == 1);
CHECK(secp256k1_bulletproof_rangeproof_rewind(data->common->ctx, &v, blind, data->common->proof[0], data->common->plen, 0, data->commit[0], &data->common->value_gen[0], data->common->nonce, NULL, 0, NULL) == 1);
}
}

Expand Down Expand Up @@ -147,7 +147,7 @@ static void bench_bulletproof_rangeproof_rewind_succeed(void* arg) {
bench_bulletproof_rangeproof_t *data = (bench_bulletproof_rangeproof_t*)arg;

for (i = 0; i < data->common->iters; i++) {
CHECK(secp256k1_bulletproof_rangeproof_rewind(data->common->ctx, data->common->generators, &v, blind, data->common->proof[0], data->common->plen, 0, data->commit[0], &data->common->value_gen[0], data->common->nonce, NULL, 0, NULL) == 1);
CHECK(secp256k1_bulletproof_rangeproof_rewind(data->common->ctx, &v, blind, data->common->proof[0], data->common->plen, 0, data->commit[0], &data->common->value_gen[0], data->common->nonce, NULL, 0, NULL) == 1);
}
}

Expand All @@ -159,7 +159,7 @@ static void bench_bulletproof_rangeproof_rewind_fail(void* arg) {

data->common->nonce[0] ^= 1;
for (i = 0; i < data->common->iters; i++) {
CHECK(secp256k1_bulletproof_rangeproof_rewind(data->common->ctx, data->common->generators, &v, blind, data->common->proof[0], data->common->plen, 0, data->commit[0], &data->common->value_gen[0], data->common->nonce, NULL, 0, NULL) == 0);
CHECK(secp256k1_bulletproof_rangeproof_rewind(data->common->ctx, &v, blind, data->common->proof[0], data->common->plen, 0, data->commit[0], &data->common->value_gen[0], data->common->nonce, NULL, 0, NULL) == 0);
}
data->common->nonce[0] ^= 1;
}
Expand Down
7 changes: 3 additions & 4 deletions src/modules/bulletproofs/main_impl.h
Original file line number Diff line number Diff line change
Expand Up @@ -161,21 +161,20 @@ int secp256k1_bulletproof_rangeproof_verify_multi(const secp256k1_context* ctx,
return ret;
}

int secp256k1_bulletproof_rangeproof_rewind(const secp256k1_context* ctx, const secp256k1_bulletproof_generators *gens, uint64_t *value, unsigned char *blind, const unsigned char *proof, size_t plen, uint64_t min_value, const secp256k1_pedersen_commitment* commit, const secp256k1_generator *value_gen, const unsigned char *nonce, const unsigned char *extra_commit, size_t extra_commit_len, unsigned char *message) {
int secp256k1_bulletproof_rangeproof_rewind(const secp256k1_context* ctx, uint64_t *value, unsigned char *blind, const unsigned char *proof, size_t plen, uint64_t min_value, const secp256k1_pedersen_commitment* commit, const secp256k1_generator *value_gen, const unsigned char *nonce, const unsigned char *extra_commit, size_t extra_commit_len, unsigned char *message) {
secp256k1_scalar blinds;
int ret;

VERIFY_CHECK(ctx != NULL);
ARG_CHECK(value != NULL);
ARG_CHECK(blind != NULL);
ARG_CHECK(gens != NULL);
ARG_CHECK(proof != NULL);
ARG_CHECK(commit != NULL);
ARG_CHECK(value_gen != NULL);
ARG_CHECK(nonce != NULL);
ARG_CHECK(extra_commit != NULL || extra_commit_len == 0);

ret = secp256k1_bulletproof_rangeproof_rewind_impl(value, &blinds, proof, plen, min_value, commit, value_gen, gens->blinding_gen, nonce, extra_commit, extra_commit_len, message);
ret = secp256k1_bulletproof_rangeproof_rewind_impl(value, &blinds, proof, plen, min_value, commit, value_gen, nonce, extra_commit, extra_commit_len, message);
if (ret == 1) {
secp256k1_scalar_get_b32(blind, &blinds);
}
Expand Down Expand Up @@ -205,7 +204,7 @@ int secp256k1_bulletproof_rangeproof_prove(
ARG_CHECK(gens != NULL);
ARG_CHECK(gens->n >= 2 * nbits * n_commits);
ARG_CHECK(
(proof != NULL && plen != NULL && tau_x == NULL && t_one == NULL && t_two == NULL && commits == NULL && private_nonce == NULL) ||
(proof != NULL && plen != NULL && tau_x == NULL && t_one == NULL && t_two == NULL && commits == NULL) ||
(proof == NULL && plen == NULL && tau_x == NULL && t_one != NULL && t_two != NULL && commits != NULL && private_nonce != NULL) ||
(proof == NULL && plen == NULL && tau_x != NULL && t_one != NULL && t_two != NULL && commits != NULL && private_nonce != NULL) ||
(proof != NULL && plen != NULL && tau_x != NULL && t_one != NULL && t_two != NULL && commits != NULL && private_nonce != NULL)
Expand Down
23 changes: 9 additions & 14 deletions src/modules/bulletproofs/rangeproof_impl.h
Original file line number Diff line number Diff line change
Expand Up @@ -528,10 +528,10 @@ static int secp256k1_bulletproof_rangeproof_prove_impl(
secp256k1_scalar vals;
secp256k1_scalar_set_u64(&vals, value[0]);
if (message != NULL) {
/* Combine value with 16 bytes of optional message */
/* Combine value with 20 bytes of optional message */
secp256k1_scalar_get_b32(vals_bytes, &vals);
for (i=0; i<16; i++) {
vals_bytes[i+8] = message[i];
for (i=0; i<20; i++) {
vals_bytes[i+4] = message[i];
}
secp256k1_scalar_set_b32(&vals, vals_bytes, &overflow);
}
Expand Down Expand Up @@ -721,16 +721,15 @@ static int secp256k1_bulletproof_rangeproof_prove_impl(
return 1;
}

static int secp256k1_bulletproof_rangeproof_rewind_impl(uint64_t *value, secp256k1_scalar *blind, const unsigned char *proof, const size_t plen, uint64_t min_value, const secp256k1_pedersen_commitment *pcommit, const secp256k1_generator *value_gen, const secp256k1_ge *blind_gen, const unsigned char *nonce, const unsigned char *extra_commit, size_t extra_commit_len, unsigned char *message) {
static int secp256k1_bulletproof_rangeproof_rewind_impl(uint64_t *value, secp256k1_scalar *blind, const unsigned char *proof, const size_t plen, uint64_t min_value, const secp256k1_pedersen_commitment *pcommit, const secp256k1_generator *value_gen, const unsigned char *nonce, const unsigned char *extra_commit, size_t extra_commit_len, unsigned char *message) {
secp256k1_sha256 sha256;
static const unsigned char zero8[8] = { 0 };
static const unsigned char zero4[4] = { 0 };
unsigned char commit[32] = { 0 };
unsigned char lrparity;
secp256k1_scalar taux, mu;
secp256k1_scalar alpha, rho, tau1, tau2;
secp256k1_scalar x, z;
secp256k1_ge commitp, value_genp;
secp256k1_gej rewind_commitj;
int overflow, i;

if (plen < 64 + 128 + 1 || plen > SECP256K1_BULLETPROOF_MAX_PROOF) {
Expand Down Expand Up @@ -819,7 +818,7 @@ static int secp256k1_bulletproof_rangeproof_rewind_impl(uint64_t *value, secp256
secp256k1_scalar_add(&mu, &mu, &alpha);

secp256k1_scalar_get_b32(commit, &mu);
if (memcmp(commit, zero8, 8) != 0) {
if (memcmp(commit, zero4, 4) != 0) {
return 0;
}
*value = commit[31] + ((uint64_t) commit[30] << 8) +
Expand All @@ -828,8 +827,8 @@ static int secp256k1_bulletproof_rangeproof_rewind_impl(uint64_t *value, secp256
((uint64_t) commit[25] << 48) + ((uint64_t) commit[24] << 56);

if (message != NULL) {
for (i=23; i >= 8; i--) {
message[i-8] = commit[i];
for (i=23; i >= 4; i--) {
message[i-4] = commit[i];
}
}

Expand All @@ -846,11 +845,7 @@ static int secp256k1_bulletproof_rangeproof_rewind_impl(uint64_t *value, secp256
secp256k1_scalar_mul(blind, &taux, &z);
secp256k1_scalar_negate(blind, blind);

secp256k1_pedersen_ecmult(&rewind_commitj, blind, *value, &value_genp, blind_gen);
secp256k1_gej_neg(&rewind_commitj, &rewind_commitj);
secp256k1_gej_add_ge_var(&rewind_commitj, &rewind_commitj, &commitp, NULL);

return secp256k1_gej_is_infinity(&rewind_commitj);
return 1;
}

#endif
38 changes: 18 additions & 20 deletions src/modules/bulletproofs/tests_impl.h
Original file line number Diff line number Diff line change
Expand Up @@ -216,32 +216,30 @@ static void test_bulletproof_api(void) {

/* Rewind */
ecount = 0;
CHECK(secp256k1_bulletproof_rangeproof_rewind(none, gens, &rewind_v, rewind_blind, proof, plen, min_value[0], pcommit, &value_gen, blind, blind, 32, NULL) == 1);
CHECK(secp256k1_bulletproof_rangeproof_rewind(none, &rewind_v, rewind_blind, proof, plen, min_value[0], pcommit, &value_gen, blind, blind, 32, NULL) == 1);
CHECK(ecount == 0);
CHECK(secp256k1_bulletproof_rangeproof_rewind(none, NULL, &rewind_v, rewind_blind, proof, plen, min_value[0], pcommit, &value_gen, blind, blind, 32, NULL) == 0);
CHECK(secp256k1_bulletproof_rangeproof_rewind(none, NULL, rewind_blind, proof, plen, min_value[0], pcommit, &value_gen, blind, blind, 32, NULL) == 0);
CHECK(ecount == 1);
CHECK(secp256k1_bulletproof_rangeproof_rewind(none, gens, NULL, rewind_blind, proof, plen, min_value[0], pcommit, &value_gen, blind, blind, 32, NULL) == 0);
CHECK(secp256k1_bulletproof_rangeproof_rewind(none, &rewind_v, NULL, proof, plen, min_value[0], pcommit, &value_gen, blind, blind, 32, NULL) == 0);
CHECK(ecount == 2);
CHECK(secp256k1_bulletproof_rangeproof_rewind(none, gens, &rewind_v, NULL, proof, plen, min_value[0], pcommit, &value_gen, blind, blind, 32, NULL) == 0);
CHECK(secp256k1_bulletproof_rangeproof_rewind(none, &rewind_v, rewind_blind, NULL, plen, min_value[0], pcommit, &value_gen, blind, blind, 32, NULL) == 0);
CHECK(ecount == 3);
CHECK(secp256k1_bulletproof_rangeproof_rewind(none, gens, &rewind_v, rewind_blind, NULL, plen, min_value[0], pcommit, &value_gen, blind, blind, 32, NULL) == 0);
CHECK(ecount == 4);
CHECK(secp256k1_bulletproof_rangeproof_rewind(none, gens, &rewind_v, rewind_blind, proof, 0, min_value[0], pcommit, &value_gen, blind, blind, 32, NULL) == 0);
CHECK(ecount == 4);
CHECK(secp256k1_bulletproof_rangeproof_rewind(none, gens, &rewind_v, rewind_blind, proof, plen, 0, pcommit, &value_gen, blind, blind, 32, NULL) == 0);
CHECK(secp256k1_bulletproof_rangeproof_rewind(none, &rewind_v, rewind_blind, proof, 0, min_value[0], pcommit, &value_gen, blind, blind, 32, NULL) == 0);
CHECK(ecount == 3);
CHECK(secp256k1_bulletproof_rangeproof_rewind(none, &rewind_v, rewind_blind, proof, plen, 0, pcommit, &value_gen, blind, blind, 32, NULL) == 0);
CHECK(ecount == 3);
CHECK(secp256k1_bulletproof_rangeproof_rewind(none, &rewind_v, rewind_blind, proof, plen, min_value[0], NULL, &value_gen, blind, blind, 32, NULL) == 0);
CHECK(ecount == 4);
CHECK(secp256k1_bulletproof_rangeproof_rewind(none, gens, &rewind_v, rewind_blind, proof, plen, min_value[0], NULL, &value_gen, blind, blind, 32, NULL) == 0);
CHECK(secp256k1_bulletproof_rangeproof_rewind(none, &rewind_v, rewind_blind, proof, plen, min_value[0], pcommit, NULL, blind, blind, 32, NULL) == 0);
CHECK(ecount == 5);
CHECK(secp256k1_bulletproof_rangeproof_rewind(none, gens, &rewind_v, rewind_blind, proof, plen, min_value[0], pcommit, NULL, blind, blind, 32, NULL) == 0);
CHECK(secp256k1_bulletproof_rangeproof_rewind(none, &rewind_v, rewind_blind, proof, plen, min_value[0], pcommit, &value_gen, NULL, blind, 32, NULL) == 0);
CHECK(ecount == 6);
CHECK(secp256k1_bulletproof_rangeproof_rewind(none, gens, &rewind_v, rewind_blind, proof, plen, min_value[0], pcommit, &value_gen, NULL, blind, 32, NULL) == 0);
CHECK(secp256k1_bulletproof_rangeproof_rewind(none, &rewind_v, rewind_blind, proof, plen, min_value[0], pcommit, &value_gen, blind, NULL, 32, NULL) == 0);
CHECK(ecount == 7);
CHECK(secp256k1_bulletproof_rangeproof_rewind(none, &rewind_v, rewind_blind, proof, plen, min_value[0], pcommit, &value_gen, blind, blind, 0, NULL) == 0);
CHECK(ecount == 7);
CHECK(secp256k1_bulletproof_rangeproof_rewind(none, &rewind_v, rewind_blind, proof, plen, min_value[0], pcommit, &value_gen, blind, NULL, 0, NULL) == 0);
CHECK(ecount == 7);
CHECK(secp256k1_bulletproof_rangeproof_rewind(none, gens, &rewind_v, rewind_blind, proof, plen, min_value[0], pcommit, &value_gen, blind, NULL, 32, NULL) == 0);
CHECK(ecount == 8);
CHECK(secp256k1_bulletproof_rangeproof_rewind(none, gens, &rewind_v, rewind_blind, proof, plen, min_value[0], pcommit, &value_gen, blind, blind, 0, NULL) == 0);
CHECK(ecount == 8);
CHECK(secp256k1_bulletproof_rangeproof_rewind(none, gens, &rewind_v, rewind_blind, proof, plen, min_value[0], pcommit, &value_gen, blind, NULL, 0, NULL) == 0);
CHECK(ecount == 8);

secp256k1_bulletproof_generators_destroy(none, gens);
secp256k1_bulletproof_generators_destroy(none, NULL);
Expand Down Expand Up @@ -514,12 +512,12 @@ void test_bulletproof_rangeproof(size_t nbits, size_t expected_size, const secp2
CHECK(secp256k1_bulletproof_rangeproof_verify_impl(&ctx->ecmult_ctx, scratch, proof_ptr, 3, plen, nbits, NULL, commitp_ptr, 1, value_gen, gens, NULL, 0) == 1);

/* Rewind */
CHECK(secp256k1_bulletproof_rangeproof_rewind_impl(&v_recovered, &blind_recovered, proof, plen, 0, &pcommit, &secp256k1_generator_const_g, gens->blinding_gen, nonce, NULL, 0, NULL) == 1);
CHECK(secp256k1_bulletproof_rangeproof_rewind_impl(&v_recovered, &blind_recovered, proof, plen, 0, &pcommit, &secp256k1_generator_const_g, nonce, NULL, 0, NULL) == 1);
CHECK(v_recovered == v);
CHECK(secp256k1_scalar_eq(&blind_recovered, &blind) == 1);

nonce[0] ^= 111;
CHECK(secp256k1_bulletproof_rangeproof_rewind_impl(&v_recovered, &blind_recovered, proof, plen, 0, &pcommit, &secp256k1_generator_const_g, gens->blinding_gen, nonce, NULL, 0, NULL) == 0);
CHECK(secp256k1_bulletproof_rangeproof_rewind_impl(&v_recovered, &blind_recovered, proof, plen, 0, &pcommit, &secp256k1_generator_const_g, nonce, NULL, 0, NULL) == 0);

secp256k1_scratch_destroy(scratch);
}
Expand Down

0 comments on commit 84563ed

Please sign in to comment.