purify
C++ Purify implementation with native circuit and BPP support
Loading...
Searching...
No Matches
core.h
Go to the documentation of this file.
1/*
2 * Legacy Bulletproof circuit core compatibility shim.
3 *
4 * This header is intentionally internal and assumes it is included only from
5 * the Purify secp256k1 bridge translation unit after `secp256k1.c`.
6 */
7
8#ifndef PURIFY_LEGACY_BULLETPROOF_CORE_H
9#define PURIFY_LEGACY_BULLETPROOF_CORE_H
10
11#include <limits.h>
12#include <stdlib.h>
13#include <string.h>
14
15#define SECP256K1_BULLETPROOF_MAX_DEPTH 60
16#define SECP256K1_BULLETPROOF_MAX_PROOF (160 + 66 * 32 + 7)
17
18typedef secp256k1_callback secp256k1_ecmult_context;
19
20/* Defined in src/legacy_bulletproof/scratch_frames.c. This stays out of the
21 * header so the mutable side-table state has one definition per linked target.
22 */
23int secp256k1_scratch_allocate_frame(secp256k1_scratch *scratch, size_t n, size_t objects);
24void secp256k1_scratch_deallocate_frame(secp256k1_scratch *scratch);
25
26#define secp256k1_scratch_alloc(scratch, size) secp256k1_scratch_alloc(&default_error_callback, scratch, size)
27
28typedef struct {
30 secp256k1_scalar scal;
32
36
41
46
59
61 size_t n_gates;
62 size_t n_commits;
63 secp256k1_scalar *al;
64 secp256k1_scalar *ar;
65 secp256k1_scalar *ao;
66 secp256k1_scalar *v;
67};
68
70 size_t n;
71 secp256k1_ge *gens;
72 secp256k1_ge *blinding_gen;
73};
74
75static int purify_checked_mul_size(size_t lhs, size_t rhs, size_t* out) {
76 if (out == NULL) {
77 return 0;
78 }
79 if (lhs != 0 && rhs > SIZE_MAX / lhs) {
80 return 0;
81 }
82 *out = lhs * rhs;
83 return 1;
84}
85
86static int purify_checked_add_size(size_t lhs, size_t rhs, size_t* out) {
87 if (out == NULL) {
88 return 0;
89 }
90 if (rhs > SIZE_MAX - lhs) {
91 return 0;
92 }
93 *out = lhs + rhs;
94 return 1;
95}
96
98 const secp256k1_context *ctx,
99 const secp256k1_generator *blinding_gen,
100 size_t n,
101 size_t precomp_n
102) {
104 secp256k1_rfc6979_hmac_sha256 rng;
105 size_t blinding_offset = 0;
106 size_t generator_slots = 0;
107 size_t allocation_bytes = 0;
108 unsigned char seed[64];
109 secp256k1_gej precompj;
110 size_t i;
111
112 VERIFY_CHECK(ctx != NULL);
113 VERIFY_CHECK(blinding_gen != NULL);
114 VERIFY_CHECK(precomp_n >= 1);
115
116 ret = (secp256k1_bulletproof_generators *)checked_malloc(&ctx->error_callback, sizeof(*ret));
117 if (ret == NULL) {
118 return NULL;
119 }
120 if (!purify_checked_mul_size(precomp_n, n, &blinding_offset) ||
121 !purify_checked_add_size(blinding_offset, precomp_n, &generator_slots) ||
122 !purify_checked_mul_size(generator_slots, sizeof(*ret->gens), &allocation_bytes)) {
123 free(ret);
124 return NULL;
125 }
126 ret->gens = (secp256k1_ge *)checked_malloc(&ctx->error_callback, allocation_bytes);
127 if (ret->gens == NULL) {
128 free(ret);
129 return NULL;
130 }
131 ret->blinding_gen = &ret->gens[blinding_offset];
132 ret->n = n;
133
134 secp256k1_fe_get_b32(&seed[0], &secp256k1_ge_const_g.x);
135 secp256k1_fe_get_b32(&seed[32], &secp256k1_ge_const_g.y);
136
137 secp256k1_rfc6979_hmac_sha256_initialize(&rng, seed, sizeof(seed));
138 for (i = 0; i < n; ++i) {
139 size_t j;
140 unsigned char tmp[32] = {0};
141 secp256k1_generator gen;
142 secp256k1_rfc6979_hmac_sha256_generate(&rng, tmp, sizeof(tmp));
143 CHECK(secp256k1_generator_generate(ctx, &gen, tmp));
144 secp256k1_generator_load(&ret->gens[i], &gen);
145
146 secp256k1_gej_set_ge(&precompj, &ret->gens[i]);
147 for (j = 1; j < precomp_n; ++j) {
148 size_t k;
149 for (k = 0; k < 256 / precomp_n; ++k) {
150 secp256k1_gej_double_var(&precompj, &precompj, NULL);
151 }
152 secp256k1_ge_set_gej(&ret->gens[i + n * j], &precompj);
153 }
154 }
155
156 secp256k1_generator_load(&ret->blinding_gen[0], blinding_gen);
157 secp256k1_gej_set_ge(&precompj, &ret->blinding_gen[0]);
158 for (i = 1; i < precomp_n; ++i) {
159 size_t k;
160 for (k = 0; k < 256 / precomp_n; ++k) {
161 secp256k1_gej_double_var(&precompj, &precompj, NULL);
162 }
163 secp256k1_ge_set_gej(&ret->blinding_gen[i], &precompj);
164 }
165 secp256k1_rfc6979_hmac_sha256_finalize(&rng);
166 return ret;
167}
168
170 const secp256k1_context *ctx,
172) {
173 (void)ctx;
174 if (gen == NULL) {
175 return;
176 }
177 free(gen->gens);
178 free(gen);
179}
180
182 secp256k1_scalar *r1,
183 secp256k1_scalar *r2,
184 const unsigned char *seed,
185 size_t idx
186) {
187 static const unsigned char domain[] = "Purify/Bulletproof/ScalarExpand";
188 unsigned char digest[32];
189 unsigned char idx_bytes[9];
190 secp256k1_sha256 sha256;
191 int overflow = 0;
192 size_t shift;
193
194 VERIFY_CHECK(seed != NULL);
195 for (shift = 0; shift < 8; ++shift) {
196 idx_bytes[shift] = (unsigned char)(idx >> (8 * (7 - shift)));
197 }
198
199 idx_bytes[8] = 0;
200 secp256k1_sha256_initialize(&sha256);
201 secp256k1_sha256_write(&sha256, domain, sizeof(domain) - 1);
202 secp256k1_sha256_write(&sha256, seed, 32);
203 secp256k1_sha256_write(&sha256, idx_bytes, sizeof(idx_bytes));
204 secp256k1_sha256_finalize(&sha256, digest);
205 secp256k1_scalar_set_b32(r1, digest, &overflow);
206 VERIFY_CHECK(!overflow);
207
208 idx_bytes[8] = 1;
209 secp256k1_sha256_initialize(&sha256);
210 secp256k1_sha256_write(&sha256, domain, sizeof(domain) - 1);
211 secp256k1_sha256_write(&sha256, seed, 32);
212 secp256k1_sha256_write(&sha256, idx_bytes, sizeof(idx_bytes));
213 secp256k1_sha256_finalize(&sha256, digest);
214 secp256k1_scalar_set_b32(r2, digest, &overflow);
215 VERIFY_CHECK(!overflow);
216
217 secp256k1_memczero(digest, sizeof(digest), 1);
218}
219
220SECP256K1_INLINE static void secp256k1_pedersen_ecmult_scalar(
221 secp256k1_gej *rj,
222 const secp256k1_scalar *sec,
223 const secp256k1_scalar *value,
224 const secp256k1_ge *value_gen,
225 const secp256k1_ge *blind_gen
226) {
227 secp256k1_gej bj;
228 secp256k1_ge bp;
229
230 secp256k1_ecmult_const(rj, value_gen, value);
231 secp256k1_ecmult_const(&bj, blind_gen, sec);
232 if (!secp256k1_gej_is_infinity(&bj)) {
233 secp256k1_ge_set_gej(&bp, &bj);
234 secp256k1_gej_add_ge(rj, rj, &bp);
235 }
236 secp256k1_gej_clear(&bj);
237 secp256k1_ge_clear(&bp);
238}
239
240#endif
int secp256k1_scratch_allocate_frame(secp256k1_scratch *scratch, size_t n, size_t objects)
secp256k1_callback secp256k1_ecmult_context
Definition core.h:18
static void secp256k1_scalar_chacha20(secp256k1_scalar *r1, secp256k1_scalar *r2, const unsigned char *seed, size_t idx)
Definition core.h:181
static int purify_checked_mul_size(size_t lhs, size_t rhs, size_t *out)
Definition core.h:75
void secp256k1_scratch_deallocate_frame(secp256k1_scratch *scratch)
static secp256k1_bulletproof_generators * secp256k1_bulletproof_generators_create(const secp256k1_context *ctx, const secp256k1_generator *blinding_gen, size_t n, size_t precomp_n)
Definition core.h:97
static void secp256k1_bulletproof_generators_destroy(const secp256k1_context *ctx, secp256k1_bulletproof_generators *gen)
Definition core.h:169
static SECP256K1_INLINE void secp256k1_pedersen_ecmult_scalar(secp256k1_gej *rj, const secp256k1_scalar *sec, const secp256k1_scalar *value, const secp256k1_ge *value_gen, const secp256k1_ge *blind_gen)
Definition core.h:220
static int purify_checked_add_size(size_t lhs, size_t rhs, size_t *out)
Definition core.h:86
secp256k1_bulletproof_wmatrix_row * wl
Definition core.h:52
secp256k1_bulletproof_wmatrix_row * wv
Definition core.h:55
secp256k1_bulletproof_wmatrix_entry * entries
Definition core.h:57
secp256k1_bulletproof_wmatrix_row * wo
Definition core.h:54
secp256k1_bulletproof_wmatrix_row * wr
Definition core.h:53
secp256k1_fast_scalar * c
Definition core.h:56
secp256k1_ge * blinding_gen
Definition core.h:72
Definition core.h:37
secp256k1_fast_scalar scal
Definition core.h:39
size_t idx
Definition core.h:38
secp256k1_bulletproof_wmatrix_entry * entry
Definition core.h:44
secp256k1_scalar scal
Definition core.h:30