Skip to content

Commit 72ffc02

Browse files
committed
bulletproofs: add module, full support for rangeproofs
1 parent 0ac92f4 commit 72ffc02

12 files changed

+2568
-0
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ bench_recover
88
bench_internal
99
bench_generator
1010
bench_rangeproof
11+
bench_bulletproof
1112
tests
1213
exhaustive_tests
1314
gen_context

Makefile.am

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -202,6 +202,10 @@ if ENABLE_MODULE_RANGEPROOF
202202
include src/modules/rangeproof/Makefile.am.include
203203
endif
204204

205+
if ENABLE_MODULE_BULLETPROOF
206+
include src/modules/bulletproofs/Makefile.am.include
207+
endif
208+
205209
if ENABLE_MODULE_WHITELIST
206210
include src/modules/whitelist/Makefile.am.include
207211
endif

configure.ac

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -159,6 +159,12 @@ AC_ARG_ENABLE(module_rangeproof,
159159
[enable_module_rangeproof=$enableval],
160160
[enable_module_rangeproof=no])
161161

162+
AC_ARG_ENABLE(module_bulletproof,
163+
AS_HELP_STRING([--enable-module-bulletproof],[enable Pedersen / zero-knowledge bulletproofs module (default is no)]),
164+
[enable_module_bulletproof=$enableval],
165+
[enable_module_bulletproof=no])
166+
167+
162168
AC_ARG_ENABLE(module_whitelist,
163169
AS_HELP_STRING([--enable-module-whitelist],[enable key whitelisting module (default is no)]),
164170
[enable_module_whitelist=$enableval],
@@ -208,6 +214,19 @@ AC_COMPILE_IFELSE([AC_LANG_SOURCE([[void myfunc() {__builtin_popcount(0);}]])],
208214
[ AC_MSG_RESULT([no])
209215
])
210216

217+
AC_MSG_CHECKING([for __builtin_popcountl])
218+
AC_COMPILE_IFELSE([AC_LANG_SOURCE([[void myfunc() {__builtin_popcountl(0);}]])],
219+
[ AC_MSG_RESULT([yes]);AC_DEFINE(HAVE_BUILTIN_POPCOUNTL,1,[Define this symbol if __builtin_popcountl is available]) ],
220+
[ AC_MSG_RESULT([no])
221+
])
222+
223+
AC_MSG_CHECKING([for __builtin_ctzl])
224+
AC_COMPILE_IFELSE([AC_LANG_SOURCE([[void myfunc() {__builtin_ctzl(0);}]])],
225+
[ AC_MSG_RESULT([yes]);AC_DEFINE(HAVE_BUILTIN_CTZL,1,[Define this symbol if __builtin_ctzl is available]) ],
226+
[ AC_MSG_RESULT([no])
227+
])
228+
229+
211230
if test x"$use_ecmult_static_precomputation" != x"no"; then
212231
save_cross_compiling=$cross_compiling
213232
cross_compiling=no
@@ -502,6 +521,10 @@ if test x"$enable_module_rangeproof" = x"yes"; then
502521
AC_DEFINE(ENABLE_MODULE_RANGEPROOF, 1, [Define this symbol to enable the zero knowledge range proof module])
503522
fi
504523

524+
if test x"$enable_module_bulletproof" = x"yes"; then
525+
AC_DEFINE(ENABLE_MODULE_BULLETPROOF, 1, [Define this symbol to enable the Pedersen / zero knowledge bulletproof module])
526+
fi
527+
505528
if test x"$enable_module_whitelist" = x"yes"; then
506529
AC_DEFINE(ENABLE_MODULE_WHITELIST, 1, [Define this symbol to enable the key whitelisting module])
507530
fi
@@ -536,6 +559,7 @@ if test x"$enable_experimental" = x"yes"; then
536559
AC_MSG_NOTICE([Building NUMS generator module: $enable_module_generator])
537560
AC_MSG_NOTICE([Building Pedersen commitment module: $enable_module_commitment])
538561
AC_MSG_NOTICE([Building range proof module: $enable_module_rangeproof])
562+
AC_MSG_NOTICE([Building bulletproof module: $enable_module_bulletproof])
539563
AC_MSG_NOTICE([Building key whitelisting module: $enable_module_whitelist])
540564
AC_MSG_NOTICE([Building surjection proof module: $enable_module_surjectionproof])
541565
AC_MSG_NOTICE([Building schnorrsig module: $enable_module_schnorrsig])
@@ -553,12 +577,18 @@ if test x"$enable_experimental" = x"yes"; then
553577
if test x"$enable_module_commitment" = x"yes"; then
554578
AC_MSG_ERROR([Commitment module requires the generator module. Use --enable-module-generator to allow.])
555579
fi
580+
if test x"$enable_module_bulletproof" = x"yes"; then
581+
AC_MSG_ERROR([Bulletproof module requires the generator module. Use --enable-module-generator to allow.])
582+
fi
556583
fi
557584

558585
if test x"$enable_module_commitment" != x"yes"; then
559586
if test x"$enable_module_rangeproof" = x"yes"; then
560587
AC_MSG_ERROR([Rangeproof module requires the commitment module. Use --enable-module-commitment to allow.])
561588
fi
589+
if test x"$enable_module_bulletproof" = x"yes"; then
590+
AC_MSG_ERROR([Bulletproof module requires the commitment module. Use --enable-module-commitment to allow.])
591+
fi
562592
fi
563593

564594
if test x"$enable_module_rangeproof" != x"yes"; then
@@ -591,6 +621,9 @@ else
591621
if test x"$enable_module_rangeproof" = x"yes"; then
592622
AC_MSG_ERROR([Range proof module is experimental. Use --enable-experimental to allow.])
593623
fi
624+
if test x"$enable_module_bulletproof" = x"yes"; then
625+
AC_MSG_ERROR([Bulletproof module is experimental. Use --enable-experimental to allow.])
626+
fi
594627
if test x"$enable_module_whitelist" = x"yes"; then
595628
AC_MSG_ERROR([Key whitelisting module is experimental. Use --enable-experimental to allow.])
596629
fi
@@ -618,6 +651,7 @@ AM_CONDITIONAL([ENABLE_MODULE_RECOVERY], [test x"$enable_module_recovery" = x"ye
618651
AM_CONDITIONAL([ENABLE_MODULE_GENERATOR], [test x"$enable_module_generator" = x"yes"])
619652
AM_CONDITIONAL([ENABLE_MODULE_COMMITMENT], [test x"$enable_module_commitment" = x"yes"])
620653
AM_CONDITIONAL([ENABLE_MODULE_RANGEPROOF], [test x"$enable_module_rangeproof" = x"yes"])
654+
AM_CONDITIONAL([ENABLE_MODULE_BULLETPROOF], [test x"$enable_module_bulletproof" = x"yes"])
621655
AM_CONDITIONAL([ENABLE_MODULE_WHITELIST], [test x"$enable_module_whitelist" = x"yes"])
622656
AM_CONDITIONAL([USE_JNI], [test x"$use_jni" == x"yes"])
623657
AM_CONDITIONAL([USE_EXTERNAL_ASM], [test x"$use_external_asm" = x"yes"])

include/secp256k1_bulletproofs.h

Lines changed: 146 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,146 @@
1+
#ifndef _SECP256K1_BULLETPROOF_
2+
# define _SECP256K1_BULLETPROOF_
3+
4+
# include "secp256k1.h"
5+
# include "secp256k1_generator.h"
6+
# include "secp256k1_rangeproof.h"
7+
8+
# ifdef __cplusplus
9+
extern "C" {
10+
# endif
11+
12+
/** Opaque structure representing a large number of NUMS generators */
13+
typedef struct secp256k1_bulletproof_generators secp256k1_bulletproof_generators;
14+
15+
/* Maximum depth of 31 lets us validate an aggregate of 2^25 64-bit proofs */
16+
#define SECP256K1_BULLETPROOF_MAX_DEPTH 31
17+
18+
/* Size of a hypothetical 31-depth rangeproof, in bytes */
19+
#define SECP256K1_BULLETPROOF_MAX_PROOF (160 + 66*32 + 7)
20+
21+
/** Allocates and initializes a list of NUMS generators, along with precomputation data
22+
* Returns a list of generators, or NULL if allocation failed.
23+
* Args: ctx: pointer to a context object (cannot be NULL)
24+
* In: blinding_gen: generator that blinding factors will be multiplied by (cannot be NULL)
25+
* n: number of NUMS generators to produce
26+
*/
27+
SECP256K1_API secp256k1_bulletproof_generators *secp256k1_bulletproof_generators_create(
28+
const secp256k1_context* ctx,
29+
const secp256k1_generator *blinding_gen,
30+
size_t n
31+
) SECP256K1_ARG_NONNULL(1);
32+
33+
/** Destroys a list of NUMS generators, freeing allocated memory
34+
* Args: ctx: pointer to a context object (cannot be NULL)
35+
* gen: pointer to the generator set to be destroyed
36+
*/
37+
SECP256K1_API void secp256k1_bulletproof_generators_destroy(
38+
const secp256k1_context* ctx,
39+
secp256k1_bulletproof_generators *gen
40+
) SECP256K1_ARG_NONNULL(1);
41+
42+
/** Verifies a single bulletproof (aggregate) rangeproof
43+
* Returns: 1: rangeproof was valid
44+
* 0: rangeproof was invalid, or out of memory
45+
* Args: ctx: pointer to a context object initialized for verification (cannot be NULL)
46+
* scratch: scratch space with enough memory for verification (cannot be NULL)
47+
* gens: generator set with at least 2*nbits*n_commits many generators (cannot be NULL)
48+
* In: proof: byte-serialized rangeproof (cannot be NULL)
49+
* plen: length of the proof
50+
* min_value: array of minimum values to prove ranges above, or NULL for all-zeroes
51+
* commit: array of pedersen commitment that this rangeproof is over (cannot be NULL)
52+
* n_commits: number of commitments in the above array (cannot be 0)
53+
* nbits: number of bits proven for each range
54+
* value_gen: generator multiplied by value in pedersen commitments (cannot be NULL)
55+
* extra_commit: additonal data committed to by the rangeproof (may be NULL if `extra_commit_len` is 0)
56+
* extra_commit_len: length of additional data
57+
*/
58+
SECP256K1_API int secp256k1_bulletproof_rangeproof_verify(
59+
const secp256k1_context* ctx,
60+
secp256k1_scratch_space* scratch,
61+
const secp256k1_bulletproof_generators *gens,
62+
const unsigned char* proof,
63+
size_t plen,
64+
const uint64_t* min_value,
65+
const secp256k1_pedersen_commitment* commit,
66+
size_t n_commits,
67+
size_t nbits,
68+
const secp256k1_generator* value_gen,
69+
const unsigned char* extra_commit,
70+
size_t extra_commit_len
71+
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4) SECP256K1_ARG_NONNULL(7) SECP256K1_ARG_NONNULL(10);
72+
73+
/** Batch-verifies multiple bulletproof (aggregate) rangeproofs of the same size using same generator
74+
* Returns: 1: all rangeproofs were valid
75+
* 0: some rangeproof was invalid, or out of memory
76+
* Args: ctx: pointer to a context object initialized for verification (cannot be NULL)
77+
* scratch: scratch space with enough memory for verification (cannot be NULL)
78+
* gens: generator set with at least 2*nbits*n_commits many generators (cannot be NULL)
79+
* In: proof: array of byte-serialized rangeproofs (cannot be NULL)
80+
* n_proofs: number of proofs in the above array, and number of arrays in the `commit` array
81+
* plen: length of every individual proof
82+
* min_value: array of arrays of minimum values to prove ranges above, or NULL for all-zeroes
83+
* commit: array of arrays of pedersen commitment that the rangeproofs is over (cannot be NULL)
84+
* n_commits: number of commitments in each element of the above array (cannot be 0)
85+
* nbits: number of bits in each proof
86+
* value_gen: generator multiplied by value in pedersen commitments (cannot be NULL)
87+
* extra_commit: additonal data committed to by the rangeproof (may be NULL if `extra_commit_len` is 0)
88+
* extra_commit_len: array of lengths of additional data
89+
*/
90+
SECP256K1_API int secp256k1_bulletproof_rangeproof_verify_multi(
91+
const secp256k1_context* ctx,
92+
secp256k1_scratch_space* scratch,
93+
const secp256k1_bulletproof_generators *gens,
94+
const unsigned char* const* proof,
95+
size_t n_proofs,
96+
size_t plen,
97+
const uint64_t* const* min_value,
98+
const secp256k1_pedersen_commitment* const* commit,
99+
size_t n_commits,
100+
size_t nbits,
101+
const secp256k1_generator* value_gen,
102+
const unsigned char* const* extra_commit,
103+
size_t *extra_commit_len
104+
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4) SECP256K1_ARG_NONNULL(8);
105+
106+
107+
/** Produces an aggregate Bulletproof rangeproof for a set of Pedersen commitments
108+
* Returns: 1: rangeproof was successfully created
109+
* 0: rangeproof could not be created, or out of memory
110+
* Args: ctx: pointer to a context object initialized for signing and verification (cannot be NULL)
111+
* scratch: scratch space with enough memory for verification (cannot be NULL)
112+
* gens: generator set with at least 2*nbits*n_commits many generators (cannot be NULL)
113+
* Out: proof: byte-serialized rangeproof (cannot be NULL)
114+
* In/out: plen: pointer to size of `proof`, to be replaced with actual length of proof (cannot be NULL)
115+
* In: value: array of values committed by the Pedersen commitments (cannot be NULL)
116+
* min_value: array of minimum values to prove ranges above, or NULL for all-zeroes
117+
* blind: array of blinding factors of the Pedersen commitments (cannot be NULL)
118+
* n_commits: number of entries in the `value` and `blind` arrays
119+
* value_gen: generator multiplied by value in pedersen commitments (cannot be NULL)
120+
* nbits: number of bits proven for each range
121+
* nonce: random 32-byte seed used to derive blinding factors (cannot be NULL)
122+
* extra_commit: additonal data committed to by the rangeproof
123+
* extra_commit_len: length of additional data
124+
*/
125+
SECP256K1_API int secp256k1_bulletproof_rangeproof_prove(
126+
const secp256k1_context* ctx,
127+
secp256k1_scratch_space* scratch,
128+
const secp256k1_bulletproof_generators *gens,
129+
unsigned char* proof,
130+
size_t* plen,
131+
const uint64_t *value,
132+
const uint64_t *min_value,
133+
const unsigned char* const* blind,
134+
size_t n_commits,
135+
const secp256k1_generator* value_gen,
136+
size_t nbits,
137+
const unsigned char* nonce,
138+
const unsigned char* extra_commit,
139+
size_t extra_commit_len
140+
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4) SECP256K1_ARG_NONNULL(5) SECP256K1_ARG_NONNULL(6) SECP256K1_ARG_NONNULL(8) SECP256K1_ARG_NONNULL(10) SECP256K1_ARG_NONNULL(12);
141+
142+
# ifdef __cplusplus
143+
}
144+
# endif
145+
146+
#endif
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
include_HEADERS += include/secp256k1_bulletproofs.h
2+
noinst_HEADERS += src/modules/bulletproofs/inner_product_impl.h
3+
noinst_HEADERS += src/modules/bulletproofs/rangeproof_impl.h
4+
noinst_HEADERS += src/modules/bulletproofs/main_impl.h
5+
noinst_HEADERS += src/modules/bulletproofs/tests_impl.h
6+
noinst_HEADERS += src/modules/bulletproofs/util.h

0 commit comments

Comments
 (0)