Skip to content

Commit a06826e

Browse files
committed
Expose BP++ Apis
1 parent 707557a commit a06826e

File tree

3 files changed

+234
-37
lines changed

3 files changed

+234
-37
lines changed

include/secp256k1_bppp.h

Lines changed: 96 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@ extern "C" {
99

1010
#include <stdint.h>
1111

12+
#include "include/secp256k1_generator.h"
13+
1214
/** Opaque structure representing a large number of NUMS generators */
1315
typedef struct secp256k1_bppp_generators secp256k1_bppp_generators;
1416

@@ -19,10 +21,6 @@ typedef struct secp256k1_bppp_rangeproof_prover_context secp256k1_bppp_rangeproo
1921
* Returns a list of generators, or calls the error callback if the allocation fails.
2022
* Args: ctx: pointer to a context object
2123
* n: number of NUMS generators to produce.
22-
*
23-
* TODO: In a followup range-proof PR, this is would still require 16 + 8 = 24 NUMS
24-
* points. We will later use G = H0(required for compatibility with pedersen_commitment DS)
25-
* in a separate commit to make review easier.
2624
*/
2725
SECP256K1_API secp256k1_bppp_generators *secp256k1_bppp_generators_create(
2826
const secp256k1_context *ctx,
@@ -46,11 +44,9 @@ SECP256K1_API secp256k1_bppp_generators *secp256k1_bppp_generators_parse(
4644
* Args: ctx: pointer to a context object
4745
* gen: pointer to the generator set to be serialized
4846
* Out: data: pointer to buffer into which the generators will be serialized
49-
* In/Out: data_len: the length of the `data` buffer. Should be at least
50-
* k = 33 * num_gens. Will be set to k on successful return
51-
*
52-
* TODO: For ease of review, this setting G = H0 is not included in this commit. We will
53-
* add it in the follow-up rangeproof PR.
47+
* In/Out: data_len: the length of the `data` buffer. Should be initially set to at
48+
* least 33 times the number of generators plus one(33 * (num_gens - 1)).
49+
* Upon success, data_len will be set to the (33 * (num_gens - 1)).
5450
*/
5551
SECP256K1_API int secp256k1_bppp_generators_serialize(
5652
const secp256k1_context *ctx,
@@ -69,6 +65,97 @@ SECP256K1_API void secp256k1_bppp_generators_destroy(
6965
secp256k1_bppp_generators *gen
7066
) SECP256K1_ARG_NONNULL(1);
7167

68+
/** Returns the serialized size of an bulletproofs++ proof of a given number
69+
* of bits and the base. Both base and n_bits must be a power of two. The number
70+
* of digits required to represent number of bits in the given base must also be
71+
* a power of two. Specifically, all of n_bits, base and num_digits = (n_bits / log2(base))
72+
* must all be a power of two.
73+
* Args: ctx: pointer to a context object
74+
* Out: len: 0 if the parameters and num_digits (n_bits/log2(base)) are not a power of two
75+
* length of the serialized proof otherwise
76+
* In: n_bits: number of bits to prove (max 64, should usually be 64)
77+
* base: base representation to be used in proof construction (max 256, recommended 16)
78+
*/
79+
SECP256K1_API size_t secp256k1_bppp_rangeproof_proof_length(
80+
const secp256k1_context* ctx,
81+
size_t n_bits,
82+
size_t base
83+
) SECP256K1_ARG_NONNULL(1);
84+
85+
/** Produces a Bulletproofs++ rangeproof. Returns 1 on success, 0 on failure.
86+
* Proof creation can only fail if the arguments are invalid. The documentation
87+
* below specifies the constraints on inputs and arguments under which this API
88+
* can fail.
89+
* Args: ctx: pointer to a context object
90+
* scratch: pointer to a scratch space
91+
* gens: pointer to the generator set to use, which must have exactly
92+
* `n = max(num_digits, base) + 7` generators, where num_digits is the number.
93+
* asset_gen: pointer to the asset generator for the Pedersen/CT commitment
94+
* Out: proof: pointer to a byte array to output the proof into
95+
* In/Out: plen: pointer to the size of the above array; will be set to the actual size of
96+
* the serialized proof. To learn this value in advance, to allocate a sufficient
97+
* buffer, call `secp256k1_bppp_rangeproof_proof_length`
98+
* In: n_bits: size of range being proven, in bits. Must be a power of two,
99+
* and at most 64.
100+
* base: base representation to be used in proof construction. Must be a power of two,
101+
* value: value committed in the Pedersen commitment. Must be less
102+
* than 2^n_bits.
103+
* min_value: minimum value of the range being proven. Must be less than value
104+
* commit: the Pedersen commitment being proven
105+
* blind: blinding factor for the Pedersen commitment. Must be a 32 byte
106+
* valid scalar within secp curve order.
107+
* nonce: seed for the RNG used to generate random data during proving
108+
* extra_commit: arbitrary extra data that the proof commits to (may be NULL if extra_commit_len is 0)
109+
* extra_commit_len: length of the arbitrary extra data.
110+
*/
111+
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_bppp_rangeproof_prove(
112+
const secp256k1_context* ctx,
113+
secp256k1_scratch_space *scratch,
114+
const secp256k1_bppp_generators* gens,
115+
const secp256k1_generator* asset_gen,
116+
unsigned char* proof,
117+
size_t* plen,
118+
const size_t n_bits,
119+
const size_t base,
120+
const uint64_t value,
121+
const uint64_t min_value,
122+
const secp256k1_pedersen_commitment* commit,
123+
const unsigned char* blind,
124+
const unsigned char* nonce,
125+
const unsigned char* extra_commit,
126+
size_t extra_commit_len
127+
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4) SECP256K1_ARG_NONNULL(5) SECP256K1_ARG_NONNULL(11) SECP256K1_ARG_NONNULL(12) SECP256K1_ARG_NONNULL(13);
128+
129+
/** Verifies an Bulletproofs++ rangeproof. Returns 1 on success, 0 on failure.
130+
* Args: ctx: pointer to a context object
131+
* scratch: pointer to a scratch space
132+
* gens: pointer to the generator set to use, which must have at least 2*n_bits generators
133+
* asset_gen: pointer to the asset generator for the CT commitment
134+
* In: proof: pointer to a byte array containing the serialized proof
135+
* plen: length of the serialized proof
136+
* n_bits: size of range being proven, in bits. Must be a power of two,
137+
* and at most 64.
138+
* base: base representation to be used in proof construction. Must be a power of two,
139+
* min_value: minimum value of the range being proven
140+
* commit: the Pedersen commitment being proven
141+
* extra_commit: arbitrary extra data that the proof commits to (may be NULL if extra_commit_len is 0)
142+
* extra_commit_len: length of the arbitrary extra data
143+
*/
144+
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_bppp_rangeproof_verify(
145+
const secp256k1_context* ctx,
146+
secp256k1_scratch_space *scratch,
147+
const secp256k1_bppp_generators* gens,
148+
const secp256k1_generator* asset_gen,
149+
const unsigned char* proof,
150+
const size_t plen,
151+
const uint64_t n_bits,
152+
const uint64_t base,
153+
const uint64_t min_value,
154+
const secp256k1_pedersen_commitment* commit,
155+
const unsigned char* extra_commit,
156+
size_t extra_commit_len
157+
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4) SECP256K1_ARG_NONNULL(5) SECP256K1_ARG_NONNULL(10);
158+
72159
# ifdef __cplusplus
73160
}
74161
# endif

src/modules/bppp/bppp_rangeproof_impl.h

Lines changed: 27 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -8,16 +8,16 @@
88
#define _SECP256K1_MODULE_BPP_RANGEPROOF_IMPL_
99

1010

11-
#include "group.h"
12-
#include "scalar.h"
13-
#include "secp256k1.h"
14-
#include "ecmult_const.h"
15-
#include "field.h"
16-
#include "include/secp256k1_bppp.h"
11+
#include "../../group.h"
12+
#include "../../scalar.h"
13+
#include "../../../include/secp256k1.h"
14+
#include "../../ecmult_const.h"
15+
#include "../../field.h"
16+
#include "../../../include/secp256k1_bppp.h"
1717

18-
#include "modules/bppp/bppp_util.h"
19-
#include "modules/bppp/bppp_transcript_impl.h"
20-
#include "modules/bppp/bppp_norm_product_impl.h"
18+
#include "../bppp/bppp_util.h"
19+
#include "../bppp/bppp_transcript_impl.h"
20+
#include "../bppp/bppp_norm_product_impl.h"
2121

2222
struct secp256k1_bppp_rangeproof_prover_context {
2323

@@ -72,7 +72,6 @@ static void secp256k1_bppp_rangeproof_prove_round1_impl(
7272
) {
7373
size_t log_base = secp256k1_bppp_log2(digit_base);
7474
size_t i, j;
75-
size_t log_num_digits = secp256k1_bppp_log2(num_digits);
7675
size_t g_offset = digit_base > num_digits ? digit_base : num_digits;
7776
secp256k1_gej d_commj, m_commj;
7877
uint16_t multiplicities[64]; /* SECP256K1_BPP_MAX_BASE = 64. TODO: Check this in high level API */
@@ -91,7 +90,7 @@ static void secp256k1_bppp_rangeproof_prove_round1_impl(
9190
}
9291

9392
/* Commit to the vector d in gens */
94-
secp256k1_ecmult_const(&d_commj, asset_genp, &prover_ctx->r_d_0, 256);
93+
secp256k1_ecmult_const(&d_commj, asset_genp, &prover_ctx->r_d_0);
9594

9695
for (i = 0; i < num_digits; i++) {
9796
secp256k1_gej resj;
@@ -103,7 +102,7 @@ static void secp256k1_bppp_rangeproof_prove_round1_impl(
103102
multiplicities[j] += (j == digit);
104103
}
105104
secp256k1_scalar_set_int(&prover_ctx->d[i], digit);
106-
secp256k1_ecmult_const(&resj, &gens->gens[i], &prover_ctx->d[i], log_base + 1); /* (I think ) there should there be +1 here? */
105+
secp256k1_ecmult_const(&resj, &gens->gens[i], &prover_ctx->d[i]); /* should be = log_base + 1 bits here */
107106
secp256k1_ge_set_gej(&d_comm, &d_commj);
108107
secp256k1_gej_add_ge(&d_commj, &resj, &d_comm); /* d_comm cannot be zero */
109108
}
@@ -119,29 +118,29 @@ static void secp256k1_bppp_rangeproof_prove_round1_impl(
119118

120119
secp256k1_scalar_clear(&prover_ctx->r_m_1_vec[3]); /* r_m_1_vec[3] = 0 */
121120
secp256k1_scalar_clear(&prover_ctx->r_m_1_vec[6]); /* r_m_1_vec[6] = 0 */
122-
secp256k1_ecmult_const(&resj, &gens->gens[g_offset + 2], &prover_ctx->r_d_1_vec_2, 256);
121+
secp256k1_ecmult_const(&resj, &gens->gens[g_offset + 2], &prover_ctx->r_d_1_vec_2);
123122
secp256k1_ge_set_gej(&d_comm, &d_commj);
124123
secp256k1_gej_add_ge(&d_commj, &resj, &d_comm);
125-
secp256k1_ecmult_const(&resj, &gens->gens[g_offset + 5], &prover_ctx->r_d_1_vec_5, 256);
124+
secp256k1_ecmult_const(&resj, &gens->gens[g_offset + 5], &prover_ctx->r_d_1_vec_5);
126125
secp256k1_ge_set_gej(&d_comm, &d_commj);
127126
secp256k1_gej_add_ge(&d_commj, &resj, &d_comm);
128127
}
129128

130129
/* Compute the m vector as multiplicity of each digit */
131-
secp256k1_ecmult_const(&m_commj, asset_genp, &prover_ctx->r_m_0, 256);
130+
secp256k1_ecmult_const(&m_commj, asset_genp, &prover_ctx->r_m_0);
132131
for (i = 0; i < digit_base; i++) {
133132
secp256k1_gej resj;
134133
secp256k1_ge m_comm;
135134
secp256k1_scalar_set_int(&prover_ctx->m[i], multiplicities[i]);
136-
secp256k1_ecmult_const(&resj, &gens->gens[i], &prover_ctx->m[i], log_num_digits + 1); /* (I think ) there should there be +1 here? */
135+
secp256k1_ecmult_const(&resj, &gens->gens[i], &prover_ctx->m[i]); /* , log_num_digits + 1 (I think ) there should there be +1 here? */
137136
secp256k1_ge_set_gej(&m_comm, &m_commj);
138137
secp256k1_gej_add_ge(&m_commj, &resj, &m_comm); /* m_comm cannot be zero*/
139138
}
140139

141140
for (i = 0; i < 8; i++) {
142141
secp256k1_gej resj;
143142
secp256k1_ge m_comm;
144-
secp256k1_ecmult_const(&resj, &gens->gens[g_offset + i], &prover_ctx->r_m_1_vec[i], 256);
143+
secp256k1_ecmult_const(&resj, &gens->gens[g_offset + i], &prover_ctx->r_m_1_vec[i]);
145144
secp256k1_ge_set_gej(&m_comm, &m_commj);
146145
secp256k1_gej_add_ge(&m_commj, &resj, &m_comm); /* m_comm cannot be zero */
147146
}
@@ -191,13 +190,13 @@ static void secp256k1_bppp_rangeproof_prove_round2_impl(
191190
secp256k1_scalar_chacha20(&prover_ctx->r_r_0, &prover_ctx->r_r_0, nonce, 5);
192191

193192
/* Commit to the vector d in gens */
194-
secp256k1_ecmult_const(&r_commj, asset_genp, &prover_ctx->r_r_0, 256);
193+
secp256k1_ecmult_const(&r_commj, asset_genp, &prover_ctx->r_r_0);
195194
for (i = 0; i < num_digits; i++) {
196195
secp256k1_gej resj;
197196
secp256k1_ge r_comm;
198197
secp256k1_scalar_add(&prover_ctx->r[i], &prover_ctx->d[i], &prover_ctx->alpha);
199198
secp256k1_scalar_inverse(&prover_ctx->r[i], &prover_ctx->r[i]); /* r_i cannot be zero as it added by random value `alpha`*/
200-
secp256k1_ecmult_const(&resj, &gens->gens[i], &prover_ctx->r[i], 256);
199+
secp256k1_ecmult_const(&resj, &gens->gens[i], &prover_ctx->r[i]);
201200
secp256k1_ge_set_gej(&r_comm, &r_commj);
202201
secp256k1_gej_add_ge(&r_commj, &resj, &r_comm); /* r_comm cannot be zero */
203202
}
@@ -211,12 +210,12 @@ static void secp256k1_bppp_rangeproof_prove_round2_impl(
211210
secp256k1_scalar tmp;
212211

213212
secp256k1_scalar_negate(&tmp, &prover_ctx->r_d_1_vec_2);
214-
secp256k1_ecmult_const(&resj, &gens->gens[g_offset + 1], &tmp, 256);
213+
secp256k1_ecmult_const(&resj, &gens->gens[g_offset + 1], &tmp);
215214
secp256k1_ge_set_gej(&r_comm, &r_commj);
216215
secp256k1_gej_add_ge(&r_commj, &resj, &r_comm);
217216

218217
secp256k1_scalar_negate(&tmp, &prover_ctx->r_d_1_vec_5);
219-
secp256k1_ecmult_const(&resj, &gens->gens[g_offset + 4], &tmp, 256);
218+
secp256k1_ecmult_const(&resj, &gens->gens[g_offset + 4], &tmp);
220219
secp256k1_ge_set_gej(&r_comm, &r_commj);
221220
secp256k1_gej_add_ge(&r_commj, &resj, &r_comm);
222221
}
@@ -457,19 +456,19 @@ static void secp256k1_bppp_rangeproof_prove_round3_impl(
457456
secp256k1_scalar_negate(&prover_ctx->r_s_1_vec[6], &w_w_q[TPOW(6)]); /* T^7 */
458457
}
459458
/* Commit to the vector s in gens, with r_s_0 along asset and l in H_vec */
460-
secp256k1_ecmult_const(&s_commj, asset_genp, &prover_ctx->r_s_0, 256);
459+
secp256k1_ecmult_const(&s_commj, asset_genp, &prover_ctx->r_s_0);
461460
for (i = 0; i < g_offset; i++) {
462461
secp256k1_gej resj;
463462
secp256k1_ge s_comm;
464-
secp256k1_ecmult_const(&resj, &gens->gens[i], &prover_ctx->s[i], 256);
463+
secp256k1_ecmult_const(&resj, &gens->gens[i], &prover_ctx->s[i]);
465464
secp256k1_ge_set_gej(&s_comm, &s_commj);
466465
secp256k1_gej_add_ge(&s_commj, &resj, &s_comm); /* s_comm cannot be 0 */
467466
}
468467

469468
for (i = 0; i < 7; i++) {
470469
secp256k1_gej resj;
471470
secp256k1_ge s_comm;
472-
secp256k1_ecmult_const(&resj, &gens->gens[g_offset + i], &prover_ctx->r_s_1_vec[i], 256);
471+
secp256k1_ecmult_const(&resj, &gens->gens[g_offset + i], &prover_ctx->r_s_1_vec[i]);
473472
secp256k1_ge_set_gej(&s_comm, &s_commj);
474473
secp256k1_gej_add_ge(&s_commj, &resj, &s_comm); /* s_comm cannot be 0 */
475474
}
@@ -614,14 +613,14 @@ static int secp256k1_bppp_rangeproof_prove_impl(
614613
const secp256k1_context* ctx,
615614
secp256k1_scratch_space* scratch,
616615
const secp256k1_bppp_generators* gens,
617-
const secp256k1_ge* asset_genp,
616+
secp256k1_ge* asset_genp,
618617
unsigned char* proof,
619618
size_t* proof_len,
620619
const size_t n_bits,
621620
const size_t digit_base,
622621
const uint64_t value,
623622
const uint64_t min_value,
624-
const secp256k1_ge* commitp,
623+
secp256k1_ge* commitp,
625624
const secp256k1_scalar* gamma,
626625
const unsigned char* nonce,
627626
const unsigned char* extra_commit,
@@ -817,13 +816,13 @@ static int secp256k1_bppp_rangeproof_verify_impl(
817816
const secp256k1_context* ctx,
818817
secp256k1_scratch_space* scratch,
819818
const secp256k1_bppp_generators* gens,
820-
const secp256k1_ge* asset_genp,
819+
secp256k1_ge* asset_genp,
821820
const unsigned char* proof,
822821
const size_t proof_len,
823822
const size_t n_bits,
824823
const size_t digit_base,
825824
const uint64_t min_value,
826-
const secp256k1_ge* commitp,
825+
secp256k1_ge* commitp,
827826
const unsigned char* extra_commit,
828827
size_t extra_commit_len
829828
) {

0 commit comments

Comments
 (0)