Skip to content

Commit ecbfe62

Browse files
committed
Expose BP++ Apis
1 parent b081471 commit ecbfe62

File tree

2 files changed

+198
-9
lines changed

2 files changed

+198
-9
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/main_impl.h

Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -164,4 +164,106 @@ size_t secp256k1_bppp_rangeproof_proof_length(
164164
return 33 * 4 + 65*n_rounds + 64;
165165
}
166166

167+
int secp256k1_bppp_rangeproof_prove(
168+
const secp256k1_context* ctx,
169+
secp256k1_scratch_space *scratch,
170+
const secp256k1_bppp_generators* gens,
171+
const secp256k1_generator* asset_gen,
172+
unsigned char* proof,
173+
size_t* plen,
174+
const size_t n_bits,
175+
const size_t base,
176+
const uint64_t value,
177+
const uint64_t min_value,
178+
const secp256k1_pedersen_commitment* commit,
179+
const unsigned char* blind,
180+
const unsigned char* nonce,
181+
const unsigned char* extra_commit,
182+
size_t extra_commit_len
183+
) {
184+
secp256k1_ge commitp, asset_genp;
185+
secp256k1_scalar blinds;
186+
int overflow;
187+
188+
VERIFY_CHECK(ctx != NULL);
189+
VERIFY_CHECK(scratch != NULL);
190+
ARG_CHECK(gens != NULL);
191+
ARG_CHECK(asset_gen != NULL);
192+
ARG_CHECK(proof != NULL);
193+
ARG_CHECK(plen != NULL);
194+
ARG_CHECK(commit != NULL);
195+
ARG_CHECK(blind != NULL);
196+
ARG_CHECK(nonce != NULL);
197+
ARG_CHECK(extra_commit != NULL || extra_commit_len == 0);
198+
199+
secp256k1_scalar_set_b32(&blinds, blind, &overflow);
200+
if (overflow) {
201+
return 0;
202+
}
203+
204+
secp256k1_pedersen_commitment_load(&commitp, commit);
205+
secp256k1_generator_load(&asset_genp, asset_gen);
206+
207+
return secp256k1_bppp_rangeproof_prove_impl(
208+
ctx,
209+
scratch,
210+
gens,
211+
&asset_genp,
212+
proof,
213+
plen,
214+
n_bits,
215+
base,
216+
value,
217+
min_value,
218+
&commitp,
219+
&blinds,
220+
nonce,
221+
extra_commit,
222+
extra_commit_len
223+
);
224+
}
225+
226+
int secp256k1_bppp_rangeproof_verify(
227+
const secp256k1_context* ctx,
228+
secp256k1_scratch_space *scratch,
229+
const secp256k1_bppp_generators* gens,
230+
const secp256k1_generator* asset_gen,
231+
const unsigned char* proof,
232+
const size_t plen,
233+
const uint64_t n_bits,
234+
const uint64_t base,
235+
const uint64_t min_value,
236+
const secp256k1_pedersen_commitment* commit,
237+
const unsigned char* extra_commit,
238+
size_t extra_commit_len
239+
) {
240+
secp256k1_ge commitp, asset_genp;
241+
242+
VERIFY_CHECK(ctx != NULL);
243+
VERIFY_CHECK(scratch != NULL);
244+
ARG_CHECK(gens != NULL);
245+
ARG_CHECK(asset_gen != NULL);
246+
ARG_CHECK(proof != NULL);
247+
ARG_CHECK(commit != NULL);
248+
ARG_CHECK(extra_commit != NULL || extra_commit_len == 0);
249+
250+
secp256k1_pedersen_commitment_load(&commitp, commit);
251+
secp256k1_generator_load(&asset_genp, asset_gen);
252+
253+
return secp256k1_bppp_rangeproof_verify_impl(
254+
ctx,
255+
scratch,
256+
gens,
257+
&asset_genp,
258+
proof,
259+
plen,
260+
n_bits,
261+
base,
262+
min_value,
263+
&commitp,
264+
extra_commit,
265+
extra_commit_len
266+
);
267+
}
268+
167269
#endif

0 commit comments

Comments
 (0)