Skip to content

Commit df8e037

Browse files
committed
bulletproofs: add benchmark
1 parent 5b88fe2 commit df8e037

File tree

2 files changed

+249
-0
lines changed

2 files changed

+249
-0
lines changed

src/bench_bulletproof.c

+243
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,243 @@
1+
/**********************************************************************
2+
* Copyright (c) 2017 Andrew Poelstra *
3+
* Distributed under the MIT software license, see the accompanying *
4+
* file COPYING or http://www.opensource.org/licenses/mit-license.php.*
5+
**********************************************************************/
6+
7+
#include <stdint.h>
8+
9+
#include "include/secp256k1_generator.h"
10+
#include "include/secp256k1_commitment.h"
11+
#include "include/secp256k1_bulletproofs.h"
12+
#include "util.h"
13+
#include "bench.h"
14+
15+
#define MAX_PROOF_SIZE 2000
16+
17+
typedef struct {
18+
secp256k1_context *ctx;
19+
secp256k1_scratch_space *scratch;
20+
unsigned char nonce[32];
21+
unsigned char **proof;
22+
secp256k1_bulletproof_generators *generators;
23+
secp256k1_generator *value_gen;
24+
secp256k1_generator blind_gen;
25+
size_t n_proofs;
26+
size_t plen;
27+
size_t iters;
28+
} bench_bulletproof_t;
29+
30+
typedef struct {
31+
bench_bulletproof_t *common;
32+
secp256k1_pedersen_commitment **commit;
33+
const unsigned char **blind;
34+
size_t *value;
35+
size_t n_commits;
36+
size_t nbits;
37+
} bench_bulletproof_rangeproof_t;
38+
39+
static void bench_bulletproof_common_setup(bench_bulletproof_t *data) {
40+
size_t i;
41+
const unsigned char nonce[32] = "my kingdom for some randomness!!";
42+
const unsigned char genbd[32] = "yet more blinding, for the asset";
43+
44+
memcpy(data->nonce, nonce, 32);
45+
data->proof = (unsigned char **)malloc(data->n_proofs * sizeof(*data->proof));
46+
data->value_gen = (secp256k1_generator *)malloc(data->n_proofs * sizeof(*data->value_gen));
47+
for (i = 0; i < data->n_proofs; i++) {
48+
data->proof[i] = (unsigned char *)malloc(MAX_PROOF_SIZE);
49+
CHECK(secp256k1_generator_generate(data->ctx, &data->value_gen[i], genbd));
50+
}
51+
data->plen = MAX_PROOF_SIZE;
52+
}
53+
54+
static void bench_bulletproof_rangeproof_setup(void* arg) {
55+
bench_bulletproof_rangeproof_t *data = (bench_bulletproof_rangeproof_t*)arg;
56+
size_t i;
57+
size_t v;
58+
59+
unsigned char blind[32] = "and my kingdom too for a blinder";
60+
61+
bench_bulletproof_common_setup (data->common);
62+
63+
data->commit = (secp256k1_pedersen_commitment **)malloc(data->common->n_proofs * sizeof(*data->commit));
64+
data->blind = (const unsigned char **)malloc(data->n_commits * sizeof(*data->blind));
65+
data->value = (size_t *)malloc(data->n_commits * sizeof(*data->commit));
66+
67+
for (i = 0; i < data->common->n_proofs; i++) {
68+
data->commit[i] = (secp256k1_pedersen_commitment *)malloc(data->n_commits * sizeof(*data->commit[i]));
69+
}
70+
71+
for (i = 0; i < data->n_commits; i++) {
72+
data->blind[i] = malloc(32);
73+
blind[0] = i;
74+
blind[1] = i >> 8;
75+
memcpy((unsigned char*) data->blind[i], blind, 32);
76+
data->value[i] = i * 17;
77+
CHECK(secp256k1_pedersen_commit(data->common->ctx, &data->commit[0][i], data->blind[i], data->value[i], &data->common->value_gen[0], &data->common->blind_gen));
78+
}
79+
for (i = 1; i < data->common->n_proofs; i++) {
80+
memcpy(data->commit[i], data->commit[0], data->n_commits * sizeof(*data->commit[0]));
81+
}
82+
83+
CHECK(secp256k1_bulletproof_rangeproof_prove(data->common->ctx, data->common->scratch, data->common->generators, data->common->proof[0], &data->common->plen, data->value, NULL, data->blind, data->n_commits, data->common->value_gen, data->nbits, data->common->nonce, NULL, 0) == 1);
84+
for (i = 1; i < data->common->n_proofs; i++) {
85+
memcpy(data->common->proof[i], data->common->proof[0], data->common->plen);
86+
CHECK(secp256k1_bulletproof_rangeproof_verify(data->common->ctx, data->common->scratch, data->common->generators, data->common->proof[i], data->common->plen, NULL, data->commit[i], data->n_commits, data->nbits, &data->common->value_gen[0], NULL, 0) == 1);
87+
}
88+
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);
89+
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);
90+
if (data->n_commits == 1) {
91+
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) == 1);
92+
}
93+
}
94+
95+
static void bench_bulletproof_common_teardown(bench_bulletproof_t *data) {
96+
size_t i;
97+
98+
for (i = 0; i < data->n_proofs; i++) {
99+
free(data->proof[i]);
100+
}
101+
free(data->proof);
102+
free(data->value_gen);
103+
}
104+
105+
static void bench_bulletproof_rangeproof_teardown(void* arg) {
106+
bench_bulletproof_rangeproof_t *data = (bench_bulletproof_rangeproof_t*)arg;
107+
size_t i;
108+
109+
if (data->blind != NULL) {
110+
for (i = 0; i < data->n_commits; i++) {
111+
free((unsigned char*) data->blind[i]);
112+
}
113+
}
114+
if (data->commit != NULL) {
115+
for (i = 0; i < data->common->n_proofs; i++) {
116+
free(data->commit[i]);
117+
}
118+
free(data->commit);
119+
}
120+
free(data->blind);
121+
free(data->value);
122+
123+
bench_bulletproof_common_teardown(data->common);
124+
}
125+
126+
static void bench_bulletproof_rangeproof_prove(void* arg) {
127+
bench_bulletproof_rangeproof_t *data = (bench_bulletproof_rangeproof_t*)arg;
128+
size_t i;
129+
for (i = 0; i < 25; i++) {
130+
CHECK(secp256k1_bulletproof_rangeproof_prove(data->common->ctx, data->common->scratch, data->common->generators, data->common->proof[0], &data->common->plen, data->value, NULL, data->blind, data->n_commits, data->common->value_gen, data->nbits, data->common->nonce, NULL, 0) == 1);
131+
}
132+
}
133+
134+
static void bench_bulletproof_rangeproof_verify(void* arg) {
135+
size_t i;
136+
bench_bulletproof_rangeproof_t *data = (bench_bulletproof_rangeproof_t*)arg;
137+
138+
for (i = 0; i < data->common->iters; i++) {
139+
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);
140+
}
141+
}
142+
143+
static void bench_bulletproof_rangeproof_rewind_succeed(void* arg) {
144+
size_t i;
145+
size_t v;
146+
unsigned char blind[32];
147+
bench_bulletproof_rangeproof_t *data = (bench_bulletproof_rangeproof_t*)arg;
148+
149+
for (i = 0; i < data->common->iters; i++) {
150+
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) == 1);
151+
}
152+
}
153+
154+
static void bench_bulletproof_rangeproof_rewind_fail(void* arg) {
155+
size_t i;
156+
size_t v;
157+
unsigned char blind[32];
158+
bench_bulletproof_rangeproof_t *data = (bench_bulletproof_rangeproof_t*)arg;
159+
160+
data->common->nonce[0] ^= 1;
161+
for (i = 0; i < data->common->iters; i++) {
162+
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) == 0);
163+
}
164+
data->common->nonce[0] ^= 1;
165+
}
166+
167+
static void run_rangeproof_test(bench_bulletproof_rangeproof_t *data, size_t nbits, size_t n_commits) {
168+
char str[64];
169+
170+
data->nbits = nbits;
171+
data->n_commits = n_commits;
172+
data->common->iters = 100;
173+
174+
data->common->n_proofs = 1;
175+
sprintf(str, "bulletproof_prove, %i, %i, 0, ", (int)nbits, (int) n_commits);
176+
run_benchmark(str, bench_bulletproof_rangeproof_prove, bench_bulletproof_rangeproof_setup, bench_bulletproof_rangeproof_teardown, (void *)data, 5, 25);
177+
178+
data->common->n_proofs = 1;
179+
sprintf(str, "bulletproof_verify, %i, %i, 1, ", (int)nbits, (int) n_commits);
180+
run_benchmark(str, bench_bulletproof_rangeproof_verify, bench_bulletproof_rangeproof_setup, bench_bulletproof_rangeproof_teardown, (void *)data, 5, data->common->iters);
181+
182+
if (n_commits == 1) {
183+
sprintf(str, "bulletproof_rewind_succeed, %i, ", (int)nbits);
184+
run_benchmark(str, bench_bulletproof_rangeproof_rewind_succeed, bench_bulletproof_rangeproof_setup, bench_bulletproof_rangeproof_teardown, (void *)data, 5, data->common->iters);
185+
sprintf(str, "bulletproof_rewind_fail, %i, ", (int)nbits);
186+
run_benchmark(str, bench_bulletproof_rangeproof_rewind_fail, bench_bulletproof_rangeproof_setup, bench_bulletproof_rangeproof_teardown, (void *)data, 5, data->common->iters);
187+
}
188+
189+
data->common->n_proofs = 2;
190+
sprintf(str, "bulletproof_verify, %i, %i, 2, ", (int)nbits, (int) n_commits);
191+
run_benchmark(str, bench_bulletproof_rangeproof_verify, bench_bulletproof_rangeproof_setup, bench_bulletproof_rangeproof_teardown, (void *)data, 5, data->common->iters);
192+
193+
data->common->iters = 10;
194+
data->common->n_proofs = 50;
195+
sprintf(str, "bulletproof_verify, %i, %i, 50, ", (int)nbits, (int) n_commits);
196+
run_benchmark(str, bench_bulletproof_rangeproof_verify, bench_bulletproof_rangeproof_setup, bench_bulletproof_rangeproof_teardown, (void *)data, 5, data->common->iters);
197+
198+
data->common->iters = 1;
199+
data->common->n_proofs = 100;
200+
sprintf(str, "bulletproof_verify, %i, %i, 100, ", (int)nbits, (int) n_commits);
201+
run_benchmark(str, bench_bulletproof_rangeproof_verify, bench_bulletproof_rangeproof_setup, bench_bulletproof_rangeproof_teardown, (void *)data, 5, data->common->iters);
202+
203+
data->common->n_proofs = 500;
204+
sprintf(str, "bulletproof_verify, %i, %i, 500, ", (int)nbits, (int) n_commits);
205+
run_benchmark(str, bench_bulletproof_rangeproof_verify, bench_bulletproof_rangeproof_setup, bench_bulletproof_rangeproof_teardown, (void *)data, 5, data->common->iters);
206+
207+
data->common->n_proofs = 1000;
208+
sprintf(str, "bulletproof_verify, %i, %i, 1000, ", (int)nbits, (int) n_commits);
209+
run_benchmark(str, bench_bulletproof_rangeproof_verify, bench_bulletproof_rangeproof_setup, bench_bulletproof_rangeproof_teardown, (void *)data, 5, data->common->iters);
210+
}
211+
212+
int main(void) {
213+
bench_bulletproof_t data;
214+
bench_bulletproof_rangeproof_t rp_data;
215+
216+
data.blind_gen = secp256k1_generator_const_g;
217+
data.ctx = secp256k1_context_create(SECP256K1_CONTEXT_SIGN | SECP256K1_CONTEXT_VERIFY);
218+
data.scratch = secp256k1_scratch_space_create(data.ctx, 1024 * 1024 * 1024);
219+
data.generators = secp256k1_bulletproof_generators_create(data.ctx, &data.blind_gen, 64 * 1024);
220+
221+
rp_data.common = &data;
222+
223+
run_rangeproof_test(&rp_data, 8, 1);
224+
run_rangeproof_test(&rp_data, 16, 1);
225+
run_rangeproof_test(&rp_data, 32, 1);
226+
227+
run_rangeproof_test(&rp_data, 64, 1);
228+
run_rangeproof_test(&rp_data, 64, 2);
229+
run_rangeproof_test(&rp_data, 64, 4);
230+
run_rangeproof_test(&rp_data, 64, 8);
231+
run_rangeproof_test(&rp_data, 64, 16);
232+
run_rangeproof_test(&rp_data, 64, 32);
233+
run_rangeproof_test(&rp_data, 64, 64);
234+
run_rangeproof_test(&rp_data, 64, 128);
235+
run_rangeproof_test(&rp_data, 64, 256);
236+
run_rangeproof_test(&rp_data, 64, 512);
237+
/* to add more, increase the number of generators above in `data.generators = ...` */
238+
239+
secp256k1_bulletproof_generators_destroy(data.ctx, data.generators);
240+
secp256k1_scratch_space_destroy(data.scratch);
241+
secp256k1_context_destroy(data.ctx);
242+
return 0;
243+
}

src/modules/bulletproofs/Makefile.am.include

+6
Original file line numberDiff line numberDiff line change
@@ -4,3 +4,9 @@ noinst_HEADERS += src/modules/bulletproofs/rangeproof_impl.h
44
noinst_HEADERS += src/modules/bulletproofs/main_impl.h
55
noinst_HEADERS += src/modules/bulletproofs/tests_impl.h
66
noinst_HEADERS += src/modules/bulletproofs/util.h
7+
if USE_BENCHMARK
8+
noinst_PROGRAMS += bench_bulletproof
9+
bench_bulletproof_SOURCES = src/bench_bulletproof.c
10+
bench_bulletproof_LDADD = libsecp256k1.la $(SECP_LIBS)
11+
bench_bulletproof_LDFLAGS = -static
12+
endif

0 commit comments

Comments
 (0)