10#define SECP256K1_BUILD
11#define ENABLE_MODULE_GENERATOR 1
12#define ENABLE_MODULE_BPPP 1
13#define ENABLE_MODULE_EXTRAKEYS 1
14#define ENABLE_MODULE_SCHNORRSIG 1
24#include "third_party/secp256k1-zkp/include/secp256k1_extrakeys.h"
25#include "third_party/secp256k1-zkp/include/secp256k1_schnorrsig.h"
26#include "third_party/secp256k1-zkp/src/secp256k1.c"
27#include "third_party/secp256k1-zkp/src/precomputed_ecmult.c"
28#include "third_party/secp256k1-zkp/src/precomputed_ecmult_gen.c"
31#undef secp256k1_scratch_alloc
33_Static_assert(
sizeof(
purify_scalar) ==
sizeof(secp256k1_scalar),
"purify_scalar size mismatch");
34_Static_assert(_Alignof(
purify_scalar) >= _Alignof(secp256k1_scalar),
"purify_scalar alignment mismatch");
37 secp256k1_context*
ctx;
43 return context != NULL ? context->
ctx : NULL;
47 unsigned char seed32[32] = {0};
50 if (context == NULL) {
53 context->
ctx = secp256k1_context_create(SECP256K1_CONTEXT_NONE);
54 if (context->
ctx == NULL) {
59 || !secp256k1_context_randomize(context->
ctx, seed32)) {
61 secp256k1_context_destroy(context->
ctx);
70 if (context == NULL) {
73 if (context->
ctx != NULL) {
74 secp256k1_context_destroy(context->
ctx);
80 if (data != NULL && size != 0u) {
81 secp256k1_memclear_explicit(data, size);
87 secp256k1_context*
ctx;
94 secp256k1_context*
ctx;
96 secp256k1_bppp_generators*
gens;
109 if (lhs != 0 && rhs > SIZE_MAX / lhs) {
120 if (rhs > SIZE_MAX - lhs) {
136 return malloc(bytes);
148 return calloc(1, bytes);
152 const secp256k1_bppp_generators*
generators) {
153 secp256k1_bppp_generators* clone;
154 size_t generator_bytes = 0;
161 clone = (secp256k1_bppp_generators*)calloc(1,
sizeof(*clone));
167 if (clone->gens == NULL) {
171 memcpy(clone->gens,
generators->gens, generator_bytes);
178 size_t generator_bytes = 0;
180 if (resources == NULL || resources->
gens == NULL || resources->
gens->gens == NULL ||
187 memcpy(resources->
gens_scratch.gens, resources->
gens->gens, generator_bytes);
207 if (guard != NULL && guard->
resources != NULL) {
219 if (ctx == NULL || n_gates == 0 || !secp256k1_is_power_of_two(n_gates)) {
227 if (resources == NULL) {
231 resources->
ctx = ctx;
233 resources->
scratch = secp256k1_scratch_space_create(resources->
ctx, 1u << 24);
234 if (resources->
scratch == NULL) {
254 if (resources == NULL || resources->
ctx == NULL || resources->
n_gates == 0 ||
263 clone->
ctx = resources->
ctx;
265 clone->
scratch = secp256k1_scratch_space_create(clone->
ctx, 1u << 24);
280 if (resources == NULL) {
283 if (resources->
gens != NULL && resources->
ctx != NULL) {
286 if (resources->
scratch != NULL && resources->
ctx != NULL) {
287 secp256k1_scratch_space_destroy(resources->
ctx, resources->
scratch);
293 const unsigned char* generators33,
294 size_t generators_count) {
296 size_t serialized_len = 0;
299 if (ctx == NULL || generators33 == NULL || generators_count == 0) {
307 if (resources == NULL) {
311 resources->
ctx = ctx;
313 resources->
scratch = secp256k1_scratch_space_create(resources->
ctx, 1u << 24);
314 if (resources->
scratch == NULL) {
319 resources->
gens = secp256k1_bppp_generators_parse(resources->
ctx, generators33, serialized_len);
320 if (resources->
gens == NULL || resources->
gens->n != generators_count) {
339 size_t generator_bytes = 0;
351 clone->
ctx = resources->
ctx;
353 clone->
scratch = secp256k1_scratch_space_create(clone->
ctx, 1u << 24);
359 if (clone->
gens == NULL) {
375 if (resources == NULL) {
378 if (resources->
gens != NULL && resources->
ctx != NULL) {
379 secp256k1_bppp_generators_destroy(resources->
ctx, resources->
gens);
384 if (resources->
scratch != NULL && resources->
ctx != NULL) {
385 secp256k1_scratch_space_destroy(resources->
ctx, resources->
scratch);
391 return (secp256k1_scalar*)
scalar;
395 return (
const secp256k1_scalar*)
scalar;
456 static const unsigned char zero = 0;
457 secp256k1_sha256 sha256;
459 if (data == NULL && data_len == 0) {
463 secp256k1_sha256_initialize(&sha256);
465 secp256k1_sha256_write(&sha256, data, data_len);
467 secp256k1_sha256_finalize(&sha256, output32);
468 secp256k1_sha256_clear(&sha256);
472 const unsigned char *
const *items,
473 const size_t *item_lens,
474 size_t items_count) {
475 secp256k1_sha256 sha256;
476 if (output32 == NULL) {
479 if (items_count != 0 && (items == NULL || item_lens == NULL)) {
480 memset(output32, 0, 32);
483 secp256k1_sha256_initialize(&sha256);
484 for (
size_t i = 0; i < items_count; ++i) {
485 const unsigned char *item = items[i];
486 size_t item_len = item_lens[i];
489 secp256k1_sha256_clear(&sha256);
490 memset(output32, 0, 32);
496 secp256k1_sha256_write(&sha256, item, item_len);
499 secp256k1_sha256_finalize(&sha256, output32);
500 secp256k1_sha256_clear(&sha256);
505 const unsigned char* key,
size_t key_len,
506 const unsigned char* data,
size_t data_len) {
507 static const unsigned char zero = 0;
508 secp256k1_hmac_sha256 hmac;
510 if (key == NULL && key_len == 0) {
513 if (data == NULL && data_len == 0) {
517 secp256k1_hmac_sha256_initialize(&hmac, key, key_len);
519 secp256k1_hmac_sha256_write(&hmac, data, data_len);
521 secp256k1_hmac_sha256_finalize(&hmac, output32);
522 secp256k1_hmac_sha256_clear(&hmac);
526 unsigned char seckey32[32],
527 unsigned char xonly_pubkey32[32]) {
529 secp256k1_keypair keypair;
530 secp256k1_xonly_pubkey xonly;
534 memset(&keypair, 0,
sizeof(keypair));
535 memset(&xonly, 0,
sizeof(xonly));
536 if (xonly_pubkey32 != NULL) {
537 memset(xonly_pubkey32, 0, 32);
540 if (ctx == NULL || seckey32 == NULL || xonly_pubkey32 == NULL) {
544 ok = secp256k1_keypair_create(ctx, &keypair, seckey32);
546 ok = secp256k1_keypair_xonly_pub(ctx, &xonly, &parity, &keypair);
549 ok = secp256k1_xonly_pubkey_serialize(ctx, xonly_pubkey32, &xonly);
551 if (ok && parity != 0) {
552 ok = secp256k1_ec_seckey_negate(ctx, seckey32);
556 memset(xonly_pubkey32, 0, 32);
565 unsigned char scalar32[32],
566 unsigned char xonly_nonce32[32]) {
568 secp256k1_pubkey pubkey;
569 secp256k1_xonly_pubkey xonly;
573 memset(&pubkey, 0,
sizeof(pubkey));
574 memset(&xonly, 0,
sizeof(xonly));
575 if (xonly_nonce32 != NULL) {
576 memset(xonly_nonce32, 0, 32);
579 if (ctx == NULL || scalar32 == NULL || xonly_nonce32 == NULL) {
583 ok = secp256k1_ec_pubkey_create(ctx, &pubkey, scalar32);
585 ok = secp256k1_xonly_pubkey_from_pubkey(ctx, &xonly, &parity, &pubkey);
588 ok = secp256k1_xonly_pubkey_serialize(ctx, xonly_nonce32, &xonly);
590 if (ok && parity != 0) {
591 ok = secp256k1_ec_seckey_negate(ctx, scalar32);
595 memset(xonly_nonce32, 0, 32);
604 const unsigned char point33[33],
605 unsigned char xonly32[32],
608 secp256k1_pubkey pubkey;
609 secp256k1_xonly_pubkey xonly;
613 memset(&pubkey, 0,
sizeof(pubkey));
614 memset(&xonly, 0,
sizeof(xonly));
615 if (xonly32 != NULL) {
616 memset(xonly32, 0, 32);
618 if (parity_out != NULL) {
622 if (ctx == NULL || point33 == NULL || xonly32 == NULL) {
626 ok = secp256k1_ec_pubkey_parse(ctx, &pubkey, point33, 33);
628 ok = secp256k1_xonly_pubkey_from_pubkey(ctx, &xonly, &parity, &pubkey);
631 ok = secp256k1_xonly_pubkey_serialize(ctx, xonly32, &xonly);
633 if (ok && parity_out != NULL) {
634 *parity_out = parity;
637 memset(xonly32, 0, 32);
646 const unsigned char xonly_pubkey32[32]) {
648 secp256k1_xonly_pubkey xonly;
651 memset(&xonly, 0,
sizeof(xonly));
652 if (ctx == NULL || xonly_pubkey32 == NULL) {
656 ok = secp256k1_xonly_pubkey_parse(ctx, &xonly, xonly_pubkey32);
663 const unsigned char sig64[64]) {
665 secp256k1_xonly_pubkey rxonly;
672 if (ctx == NULL || sig64 == NULL) {
676 ok = secp256k1_xonly_pubkey_parse(ctx, &rxonly, sig64);
678 secp256k1_scalar_set_b32(&s, sig64 + 32, &overflow);
683 secp256k1_scalar_clear(&s);
688 const unsigned char *msg,
size_t msglen,
689 const unsigned char *key32,
690 const unsigned char *xonly_pk32,
691 const unsigned char *algo,
size_t algolen,
700 if (nonce32 == NULL || data == NULL) {
703 memcpy(nonce32, data, 32);
708 unsigned char sig64[64],
709 const unsigned char* msg,
size_t msglen,
710 const unsigned char seckey32[32],
711 const unsigned char nonce32[32]) {
713 secp256k1_keypair keypair;
714 secp256k1_scalar nonce_scalar;
715 secp256k1_schnorrsig_extraparams extraparams = SECP256K1_SCHNORRSIG_EXTRAPARAMS_INIT;
716 unsigned char canonical_nonce32[32];
717 unsigned char xonly_nonce32[32];
726 memset(sig64, 0, 64);
729 if (ctx == NULL || sig64 == NULL || seckey32 == NULL || nonce32 == NULL || (msg == NULL && msglen != 0)) {
733 memcpy(canonical_nonce32, nonce32, 32);
736 ok = secp256k1_memcmp_var(canonical_nonce32, nonce32, 32) == 0;
738 secp256k1_scalar_set_b32(&nonce_scalar, nonce32, &overflow);
739 if (ok && !overflow && !secp256k1_scalar_is_zero(&nonce_scalar)) {
740 ok = secp256k1_keypair_create(ctx, &keypair, seckey32);
743 extraparams.ndata = (
void*)nonce32;
744 ok = secp256k1_schnorrsig_sign_custom(ctx, sig64, msg, msglen, &keypair, &extraparams);
749 secp256k1_scalar_clear(&nonce_scalar);
753 memset(sig64, 0, 64);
759 const unsigned char sig64[64],
760 const unsigned char* msg,
size_t msglen,
761 const unsigned char xonly_pubkey32[32]) {
763 secp256k1_xonly_pubkey pubkey;
766 memset(&pubkey, 0,
sizeof(pubkey));
767 if (ctx == NULL || sig64 == NULL || xonly_pubkey32 == NULL || (msg == NULL && msglen != 0)) {
771 ok = secp256k1_xonly_pubkey_parse(ctx, &pubkey, xonly_pubkey32);
773 ok = secp256k1_schnorrsig_verify(ctx, sig64, msg, msglen, &pubkey);
776 memset(&pubkey, 0,
sizeof(pubkey));
782 secp256k1_scalar_set_b32(
scalar, input32, &overflow);
786 if (reject_zero && secp256k1_scalar_is_zero(
scalar)) {
794 for (i = 0; i < count; ++i) {
803 secp256k1_fe_normalize_var(&point->x);
804 secp256k1_fe_normalize_var(&point->y);
805 return secp256k1_bppp_serialize_pt(out33, point);
809 secp256k1_scalar one, two, neg_one, neg_two;
815 secp256k1_scalar_set_int(&one, 1);
816 secp256k1_scalar_set_int(&two, 2);
817 secp256k1_scalar_negate(&neg_one, &one);
818 secp256k1_scalar_negate(&neg_two, &two);
821 if (secp256k1_scalar_is_zero(&
scalar->scal)) {
823 }
else if (secp256k1_scalar_eq(&
scalar->scal, &one)) {
825 }
else if (secp256k1_scalar_eq(&
scalar->scal, &two)) {
827 }
else if (secp256k1_scalar_eq(&
scalar->scal, &neg_one)) {
829 }
else if (secp256k1_scalar_eq(&
scalar->scal, &neg_two)) {
836 secp256k1_generator generator;
837 if (ctx == NULL || generator33 == NULL || out == NULL) {
840 if (!secp256k1_generator_parse(ctx, &generator, generator33)) {
843 secp256k1_generator_load(out, &generator);
848 if (point33 == NULL || out == NULL) {
851 return secp256k1_eckey_pubkey_parse(out, point33, 33);
855 if (circuit == NULL) {
864 memset(circuit, 0,
sizeof(*circuit));
868 if (assignment == NULL) {
871 free(assignment->
al);
872 free(assignment->
ar);
873 free(assignment->
ao);
875 memset(assignment, 0,
sizeof(*assignment));
894 for (i = 0; i < count; ++i) {
895 if (rows[i].size != 0 && (rows[i].indices == NULL || rows[i].scalars32 == NULL)) {
911 size_t n_constraints,
915 for (i = 0; i < row_count; ++i) {
918 out_rows[i].
entry = in_rows[i].
size == 0 ? NULL : entries + *offset;
919 for (j = 0; j < in_rows[i].
size; ++j) {
920 size_t entry_idx = *offset + j;
921 if (in_rows[i].indices[j] >= n_constraints) {
928 entries[entry_idx] = out_rows[i].
entry[j];
930 *offset += in_rows[i].
size;
937 const secp256k1_scalar* assn) {
939 for (j = 0; j < row->
size; ++j) {
940 secp256k1_scalar term;
942 secp256k1_scalar_add(&acc[row->
entry[j].
idx], &acc[row->
entry[j].
idx], &term);
948 secp256k1_scalar* acc = NULL;
952 if (circuit == NULL || assignment == NULL) {
964 for (i = 0; i < assignment->
n_gates; ++i) {
965 secp256k1_scalar product;
966 secp256k1_scalar_mul(&product, &assignment->
al[i], &assignment->
ar[i]);
967 if (!secp256k1_scalar_eq(&product, &assignment->
ao[i])) {
973 secp256k1_scalar_clear(&acc[i]);
976 for (i = 0; i < circuit->
n_gates; ++i) {
981 for (i = 0; i < circuit->
n_commits; ++i) {
982 secp256k1_scalar negated_v;
983 secp256k1_scalar_negate(&negated_v, &assignment->
v[i]);
987 secp256k1_scalar constant_term;
988 secp256k1_scalar one;
989 secp256k1_scalar_set_int(&one, 1);
991 if (!secp256k1_scalar_eq(&acc[i], &constant_term)) {
1005 size_t row_entries = 0;
1006 size_t total_entries = 0;
1013 if (view == NULL || out == NULL || (view->
n_constraints != 0 && view->
c32 == NULL)) {
1019 memset(out, 0,
sizeof(*out));
1043 if ((view->
n_gates != 0 && (out->
wl == NULL || out->
wr == NULL || out->
wo == NULL)) ||
1046 (total_entries != 0 && out->
entries == NULL)) {
1069 if (view == NULL || out == NULL) {
1072 if ((view->
n_gates != 0 && (view->
al32 == NULL || view->
ar32 == NULL || view->
ao32 == NULL)) ||
1077 memset(out, 0,
sizeof(*out));
1084 if ((view->
n_gates != 0 && (out->
al == NULL || out->
ar == NULL || out->
ao == NULL)) ||
1100 size_t proof_size = 0;
1113 const unsigned char* blind32,
1114 const unsigned char value_gen33[33],
1115 const unsigned char nonce32[32],
1116 const unsigned char* extra_commit,
1117 size_t extra_commit_len,
1118 unsigned char commitment_out33[33],
1119 unsigned char* proof_out,
1121 int require_valid_assignment,
1124 secp256k1_context* ctx = NULL;
1125 secp256k1_scratch_space* scratch = NULL;
1129 secp256k1_ge value_gen;
1130 secp256k1_ge commit_points[1];
1131 secp256k1_scalar blinds[1];
1132 size_t n_commits = 0;
1133 size_t required_generators = 0;
1135 int owns_resources = 0;
1137 memset(&bp_circuit, 0,
sizeof(bp_circuit));
1138 memset(&bp_assignment, 0,
sizeof(bp_assignment));
1139 memset(commit_points, 0,
sizeof(commit_points));
1140 memset(blinds, 0,
sizeof(blinds));
1141 if (commitment_out33 != NULL) {
1142 memset(commitment_out33, 0, 33);
1145 if (circuit == NULL || assignment == NULL || value_gen33 == NULL || nonce32 == NULL || proof_out == NULL || proof_len == NULL) {
1148 if (extra_commit == NULL && extra_commit_len != 0) {
1158 if (resources == NULL) {
1160 if (resources == NULL) {
1168 ctx = resources->
ctx;
1170 gens = resources->
gens;
1172 gens->
n < required_generators) {
1180 if (n_commits == 1) {
1181 secp256k1_gej commitj;
1182 if (commitment_out33 == NULL) {
1185 if (blind32 == NULL) {
1186 secp256k1_scalar_clear(&blinds[0]);
1191 if (secp256k1_gej_is_infinity(&commitj)) {
1194 secp256k1_ge_set_gej(&commit_points[0], &commitj);
1198 }
else if (n_commits > 1) {
1203 &ctx->error_callback,
1208 n_commits == 0 ? NULL : commit_points,
1209 n_commits == 0 ? NULL : blinds,
1222 if (owns_resources) {
1231 const unsigned char* blind32,
1232 const unsigned char value_gen33[33],
1233 const unsigned char nonce32[32],
1234 const unsigned char* extra_commit,
1235 size_t extra_commit_len,
1236 unsigned char commitment_out33[33],
1237 unsigned char* proof_out,
1238 size_t* proof_len) {
1240 extra_commit, extra_commit_len, commitment_out33,
1241 proof_out, proof_len, 1, context, NULL);
1247 const unsigned char* blind32,
1248 const unsigned char value_gen33[33],
1249 const unsigned char nonce32[32],
1250 const unsigned char* extra_commit,
1251 size_t extra_commit_len,
1252 unsigned char commitment_out33[33],
1253 unsigned char* proof_out,
1254 size_t* proof_len) {
1256 extra_commit, extra_commit_len, commitment_out33,
1257 proof_out, proof_len, 1, NULL, resources);
1263 const unsigned char* blind32,
1264 const unsigned char value_gen33[33],
1265 const unsigned char nonce32[32],
1266 const unsigned char* extra_commit,
1267 size_t extra_commit_len,
1268 unsigned char commitment_out33[33],
1269 unsigned char* proof_out,
1270 size_t* proof_len) {
1272 extra_commit, extra_commit_len, commitment_out33,
1273 proof_out, proof_len, 0, context, NULL);
1279 const unsigned char* blind32,
1280 const unsigned char value_gen33[33],
1281 const unsigned char nonce32[32],
1282 const unsigned char* extra_commit,
1283 size_t extra_commit_len,
1284 unsigned char commitment_out33[33],
1285 unsigned char* proof_out,
1286 size_t* proof_len) {
1288 extra_commit, extra_commit_len, commitment_out33,
1289 proof_out, proof_len, 0, NULL, resources);
1295 const unsigned char commitment33[33],
1296 const unsigned char value_gen33[33],
1297 const unsigned char* extra_commit,
1298 size_t extra_commit_len,
1299 const unsigned char* proof,
1304 const unsigned char commitment33[33],
1305 const unsigned char value_gen33[33],
1306 const unsigned char* extra_commit,
1307 size_t extra_commit_len,
1308 const unsigned char* proof,
1311 extra_commit, extra_commit_len, proof, proof_len);
1317 const unsigned char commitment33[33],
1318 const unsigned char value_gen33[33],
1319 const unsigned char* extra_commit,
1320 size_t extra_commit_len,
1321 const unsigned char* proof,
1323 secp256k1_context* ctx = NULL;
1324 secp256k1_scratch_space* scratch = NULL;
1327 secp256k1_ge value_gen;
1328 secp256k1_ge commit_points[1];
1329 const secp256k1_ge* commit_ptr = NULL;
1331 const unsigned char* proof_ptr = NULL;
1332 const unsigned char* extra_commit_ptr = NULL;
1333 size_t n_commits = 0;
1334 size_t required_generators = 0;
1336 int owns_resources = 0;
1338 memset(&bp_circuit, 0,
sizeof(bp_circuit));
1339 memset(commit_points, 0,
sizeof(commit_points));
1340 if (circuit == NULL || value_gen33 == NULL || proof == NULL) {
1343 if (extra_commit == NULL && extra_commit_len != 0) {
1349 if (resources == NULL) {
1351 if (resources == NULL) {
1359 ctx = resources->
ctx;
1361 gens = resources->
gens;
1363 gens->
n < required_generators) {
1371 if (n_commits == 1) {
1375 commit_ptr = commit_points;
1376 }
else if (n_commits > 1) {
1380 circuit_ptr = &bp_circuit;
1382 extra_commit_ptr = extra_commit;
1384 &ctx->error_callback,
1389 n_commits == 0 ? NULL : &commit_ptr,
1390 n_commits == 0 ? NULL : &n_commits,
1400 if (owns_resources) {
1408 const unsigned char commitment33[33],
1409 const unsigned char value_gen33[33],
1410 const unsigned char* extra_commit,
1411 size_t extra_commit_len,
1412 const unsigned char* proof,
1415 extra_commit, extra_commit_len, proof, proof_len);
1419 const secp256k1_bppp_generators* gens_vec,
size_t g_len,
1420 const secp256k1_scalar*
c_vec,
size_t c_vec_len,
1421 const secp256k1_ge* commit) {
1422 unsigned char ser_commit[33], ser_scalar[32], ser_le64[8];
1424 secp256k1_ge comm = *commit;
1426 secp256k1_bppp_sha256_tagged_commitment_init(transcript);
1428 secp256k1_sha256_write(transcript, ser_commit,
sizeof(ser_commit));
1429 secp256k1_scalar_get_b32(ser_scalar,
rho);
1430 secp256k1_sha256_write(transcript, ser_scalar,
sizeof(ser_scalar));
1431 secp256k1_bppp_le64(ser_le64, g_len);
1432 secp256k1_sha256_write(transcript, ser_le64,
sizeof(ser_le64));
1433 secp256k1_bppp_le64(ser_le64, gens_vec->n);
1434 secp256k1_sha256_write(transcript, ser_le64,
sizeof(ser_le64));
1435 for (i = 0; i < gens_vec->n; ++i) {
1436 secp256k1_ge gen = gens_vec->gens[i];
1438 secp256k1_sha256_write(transcript, ser_commit,
sizeof(ser_commit));
1440 secp256k1_bppp_le64(ser_le64, c_vec_len);
1441 secp256k1_sha256_write(transcript, ser_le64,
sizeof(ser_le64));
1442 for (i = 0; i < c_vec_len; ++i) {
1443 secp256k1_scalar_get_b32(ser_scalar, &
c_vec[i]);
1444 secp256k1_sha256_write(transcript, ser_scalar,
sizeof(ser_scalar));
1449 secp256k1_scalar** ns, secp256k1_scalar** ls, secp256k1_scalar** cs,
1450 secp256k1_ge** gs,
const secp256k1_scalar*
n_vec,
1451 const secp256k1_scalar*
l_vec,
const secp256k1_scalar*
c_vec,
1452 const secp256k1_ge* gens_vec,
size_t g_len,
size_t h_len) {
1453 size_t scalar_g_bytes = 0;
1454 size_t scalar_h_bytes = 0;
1455 size_t ge_count = 0;
1456 size_t ge_bytes = 0;
1469 if (*ns == NULL || *ls == NULL || *cs == NULL || *gs == NULL) {
1472 memcpy(*ns,
n_vec, scalar_g_bytes);
1473 memcpy(*ls,
l_vec, scalar_h_bytes);
1474 memcpy(*cs,
c_vec, scalar_h_bytes);
1475 memcpy(*gs, gens_vec, ge_bytes);
1480 unsigned char* proof,
size_t* proof_len,
1481 secp256k1_sha256* transcript,
const secp256k1_scalar*
rho,
1482 const secp256k1_ge* g_vec,
size_t g_vec_len,
1483 const secp256k1_scalar*
n_vec,
size_t n_vec_len,
1484 const secp256k1_scalar*
l_vec,
size_t l_vec_len,
1485 const secp256k1_scalar*
c_vec,
size_t c_vec_len) {
1486 secp256k1_scalar *ns = NULL, *ls = NULL, *cs = NULL;
1487 secp256k1_ge *gs = NULL;
1488 size_t checkpoint = secp256k1_scratch_checkpoint(&ctx->error_callback, scratch);
1491 if (
purify_copy_vectors_into_scratch(ctx, scratch, &ns, &ls, &cs, &gs,
n_vec,
l_vec,
c_vec, g_vec, n_vec_len, l_vec_len)) {
1492 result = secp256k1_bppp_rangeproof_norm_product_prove(ctx, scratch, proof, proof_len, transcript,
rho,
1493 gs, g_vec_len, ns, n_vec_len, ls, l_vec_len, cs, c_vec_len);
1495 secp256k1_scratch_apply_checkpoint(&ctx->error_callback, scratch, checkpoint);
1500 size_t log_g_len, log_h_len, max_log_len, proof_size = 0;
1501 if (n_vec_len == 0 || c_vec_len == 0) {
1504 log_g_len = secp256k1_bppp_log2(n_vec_len);
1505 log_h_len = secp256k1_bppp_log2(c_vec_len);
1506 max_log_len = log_g_len > log_h_len ? log_g_len : log_h_len;
1516 secp256k1_generator generator;
1517 secp256k1_ge ge = secp256k1_ge_const_g;
1520 if (ctx == NULL || out33 == NULL) {
1523 secp256k1_generator_save(&generator, &ge);
1524 ok = secp256k1_generator_serialize(ctx, out33, &generator);
1532 if (ctx == NULL || out33 == NULL) {
1535 ok = secp256k1_generator_serialize(ctx, out33, secp256k1_generator_h);
1541 secp256k1_bppp_generators* gens = NULL;
1542 size_t required = 0;
1545 if (ctx == NULL || out_len == NULL) {
1552 if (*out_len < required || out == NULL) {
1553 *out_len = required;
1556 gens = secp256k1_bppp_generators_create(ctx, count);
1560 ok = secp256k1_bppp_generators_serialize(ctx, gens, out, out_len);
1561 secp256k1_bppp_generators_destroy(ctx, gens);
1566 const unsigned char blind32[32],
const unsigned char value32[32],
1567 const unsigned char value_gen33[33],
const unsigned char blind_gen33[33],
1568 unsigned char commitment_out33[33]) {
1570 secp256k1_scalar blind_scalar, value_scalar;
1571 secp256k1_generator value_generator, blind_generator;
1572 secp256k1_ge value_ge, blind_ge, commit_ge;
1573 secp256k1_gej blind_part, value_part, total;
1576 if (ctx == NULL || blind32 == NULL || value32 == NULL || value_gen33 == NULL || blind_gen33 == NULL || commitment_out33 == NULL) {
1582 if (!secp256k1_generator_parse(ctx, &value_generator, value_gen33) || !secp256k1_generator_parse(ctx, &blind_generator, blind_gen33)) {
1585 secp256k1_generator_load(&value_ge, &value_generator);
1586 secp256k1_generator_load(&blind_ge, &blind_generator);
1587 secp256k1_ecmult_const(&blind_part, &blind_ge, &blind_scalar);
1588 secp256k1_ecmult_const(&value_part, &value_ge, &value_scalar);
1589 secp256k1_gej_add_var(&total, &blind_part, &value_part, NULL);
1590 if (!secp256k1_gej_is_infinity(&total)) {
1591 secp256k1_ge_set_gej(&commit_ge, &total);
1599 const unsigned char rho32[32],
const unsigned char* generators33,
1600 size_t generators_count,
const unsigned char* n_vec32,
size_t n_vec_len,
1601 const unsigned char* l_vec32,
size_t l_vec_len,
1602 const unsigned char* c_vec32,
size_t c_vec_len,
1603 unsigned char commitment_out33[33]) {
1605 secp256k1_scratch_space* scratch = resources != NULL ? resources->
scratch : NULL;
1606 secp256k1_bppp_generators* gens = resources != NULL ? resources->
gens : NULL;
1607 secp256k1_scalar
rho, mu;
1609 secp256k1_ge commit;
1610 size_t expected_generators = 0;
1611 size_t serialized_generators_len = 0;
1614 if (ctx == NULL || rho32 == NULL || (resources == NULL && generators33 == NULL) || n_vec32 == NULL || l_vec32 == NULL || c_vec32 == NULL ||
1615 commitment_out33 == NULL) {
1618 if (n_vec_len == 0 || l_vec_len == 0 || c_vec_len == 0 || l_vec_len != c_vec_len) {
1621 if (!secp256k1_is_power_of_two(n_vec_len) || !secp256k1_is_power_of_two(c_vec_len) ||
1623 generators_count != expected_generators ||
1627 if (resources != NULL && resources->
generators_count != generators_count) {
1633 if (resources == NULL) {
1634 scratch = secp256k1_scratch_space_create(ctx, 1u << 24);
1635 gens = secp256k1_bppp_generators_parse(ctx, generators33, serialized_generators_len);
1640 if (scratch == NULL || gens == NULL ||
n_vec == NULL ||
l_vec == NULL ||
c_vec == NULL) {
1648 secp256k1_scalar_sqr(&mu, &
rho);
1649 if (!secp256k1_bppp_commit(ctx, scratch, &commit, gens,
n_vec, n_vec_len,
l_vec, l_vec_len,
c_vec, c_vec_len, &mu)) {
1658 if (resources == NULL) {
1659 if (gens != NULL) secp256k1_bppp_generators_destroy(ctx, gens);
1660 if (scratch != NULL) secp256k1_scratch_space_destroy(ctx, scratch);
1666 const unsigned char rho32[32],
const unsigned char* generators33,
size_t generators_count,
1667 const unsigned char* n_vec32,
size_t n_vec_len,
const unsigned char* l_vec32,
1668 size_t l_vec_len,
const unsigned char* c_vec32,
size_t c_vec_len,
1669 unsigned char commitment_out33[33]) {
1671 l_vec32, l_vec_len, c_vec32, c_vec_len, commitment_out33);
1675 const unsigned char rho32[32],
1676 const unsigned char* n_vec32,
size_t n_vec_len,
1677 const unsigned char* l_vec32,
size_t l_vec_len,
1678 const unsigned char* c_vec32,
size_t c_vec_len,
1679 unsigned char commitment_out33[33]) {
1682 n_vec32, n_vec_len, l_vec32, l_vec_len, c_vec32, c_vec_len,
1688 const unsigned char* generators33,
size_t generators_count,
1689 const unsigned char* n_vec32,
size_t n_vec_len,
1690 const unsigned char* l_vec32,
size_t l_vec_len,
1691 unsigned char commitment_out33[33]) {
1693 secp256k1_scratch_space* scratch = resources != NULL ? resources->
scratch : NULL;
1694 secp256k1_bppp_generators* gens = resources != NULL ? resources->
gens : NULL;
1695 secp256k1_scalar zero;
1696 secp256k1_scalar *
n_vec = NULL, *
l_vec = NULL;
1697 secp256k1_ge commit;
1698 secp256k1_gej commitj;
1699 ecmult_bp_commit_cb_data data;
1700 size_t expected_generators = 0;
1701 size_t serialized_generators_len = 0;
1704 if (ctx == NULL || (resources == NULL && generators33 == NULL) || n_vec32 == NULL || l_vec32 == NULL || commitment_out33 == NULL) {
1707 if (n_vec_len == 0 || l_vec_len == 0 ||
1709 generators_count != expected_generators ||
1713 if (resources != NULL && resources->
generators_count != generators_count) {
1717 if (resources == NULL) {
1718 scratch = secp256k1_scratch_space_create(ctx, 1u << 24);
1719 gens = secp256k1_bppp_generators_parse(ctx, generators33, serialized_generators_len);
1723 if (scratch == NULL || gens == NULL ||
n_vec == NULL ||
l_vec == NULL) {
1731 secp256k1_scalar_set_int(&zero, 0);
1732 data.g = gens->gens;
1735 data.g_len = n_vec_len;
1736 if (!secp256k1_ecmult_multi_var(&ctx->error_callback, scratch, &commitj, &zero, ecmult_bp_commit_cb,
1737 (
void*)&data, expected_generators)) {
1740 if (secp256k1_gej_is_infinity(&commitj)) {
1743 secp256k1_ge_set_gej_var(&commit, &commitj);
1749 if (resources == NULL) {
1750 if (gens != NULL) secp256k1_bppp_generators_destroy(ctx, gens);
1751 if (scratch != NULL) secp256k1_scratch_space_destroy(ctx, scratch);
1757 const unsigned char* generators33,
size_t generators_count,
1758 const unsigned char* n_vec32,
size_t n_vec_len,
const unsigned char* l_vec32,
1759 size_t l_vec_len,
unsigned char commitment_out33[33]) {
1761 n_vec32, n_vec_len, l_vec32, l_vec_len, commitment_out33);
1765 const unsigned char* n_vec32,
size_t n_vec_len,
1766 const unsigned char* l_vec32,
size_t l_vec_len,
1767 unsigned char commitment_out33[33]) {
1770 n_vec32, n_vec_len, l_vec32, l_vec_len, commitment_out33);
1774 const unsigned char commitment33[33],
const unsigned char scalar32[32],
1775 unsigned char commitment_out33[33]) {
1778 secp256k1_ge commitment_ge, result_ge;
1779 secp256k1_gej commitment_j, offset_j, result_j;
1782 if (ctx == NULL || commitment33 == NULL || scalar32 == NULL || commitment_out33 == NULL) {
1790 secp256k1_gej_set_ge(&commitment_j, &commitment_ge);
1791 secp256k1_ecmult_const(&offset_j, &secp256k1_ge_const_g, &
scalar);
1792 secp256k1_gej_add_var(&result_j, &commitment_j, &offset_j, NULL);
1793 if (!secp256k1_gej_is_infinity(&result_j)) {
1794 secp256k1_ge_set_gej(&result_ge, &result_j);
1801 const unsigned char point33[33],
const unsigned char scalar32[32],
1802 unsigned char out33[33]) {
1805 secp256k1_ge point_ge, result_ge;
1806 secp256k1_gej result_j;
1809 if (ctx == NULL || point33 == NULL || scalar32 == NULL || out33 == NULL) {
1817 secp256k1_ecmult_const(&result_j, &point_ge, &
scalar);
1818 if (!secp256k1_gej_is_infinity(&result_j)) {
1819 secp256k1_ge_set_gej(&result_ge, &result_j);
1826 const unsigned char lhs33[33],
const unsigned char rhs33[33],
1827 unsigned char out33[33]) {
1829 secp256k1_ge lhs_ge, rhs_ge, result_ge;
1830 secp256k1_gej lhs_j, result_j;
1833 if (ctx == NULL || lhs33 == NULL || rhs33 == NULL || out33 == NULL) {
1841 secp256k1_gej_set_ge(&lhs_j, &lhs_ge);
1842 secp256k1_gej_add_ge_var(&result_j, &lhs_j, &rhs_ge, NULL);
1843 if (!secp256k1_gej_is_infinity(&result_j)) {
1844 secp256k1_ge_set_gej(&result_ge, &result_j);
1852 const unsigned char rho32[32],
const unsigned char* generators33,
1853 size_t generators_count,
const unsigned char* n_vec32,
size_t n_vec_len,
1854 const unsigned char* l_vec32,
size_t l_vec_len,
1855 const unsigned char* c_vec32,
size_t c_vec_len,
1856 unsigned char commitment_out33[33],
unsigned char* proof_out,
1857 size_t* proof_len) {
1859 secp256k1_scratch_space* scratch = resources != NULL ? resources->
scratch : NULL;
1860 secp256k1_bppp_generators* gens = NULL;
1861 secp256k1_scalar
rho, mu;
1863 secp256k1_ge commit;
1864 secp256k1_sha256 transcript;
1866 size_t expected_generators = 0;
1867 size_t serialized_generators_len = 0;
1871 if (ctx == NULL || rho32 == NULL || (resources == NULL && generators33 == NULL) || n_vec32 == NULL || l_vec32 == NULL || c_vec32 == NULL ||
1872 commitment_out33 == NULL || proof_out == NULL || proof_len == NULL) {
1875 if (n_vec_len == 0 || l_vec_len == 0 || c_vec_len == 0 || l_vec_len != c_vec_len) {
1878 if (!secp256k1_is_power_of_two(n_vec_len) || !secp256k1_is_power_of_two(c_vec_len) ||
1880 generators_count != expected_generators ||
1884 if (resources != NULL && resources->
generators_count != generators_count) {
1887 if (*proof_len < required) {
1888 *proof_len = required;
1894 if (resources != NULL) {
1900 scratch = secp256k1_scratch_space_create(ctx, 1u << 24);
1901 gens = secp256k1_bppp_generators_parse(ctx, generators33, serialized_generators_len);
1906 if (scratch == NULL || gens == NULL ||
n_vec == NULL ||
l_vec == NULL ||
c_vec == NULL) {
1914 secp256k1_scalar_sqr(&mu, &
rho);
1915 if (!secp256k1_bppp_commit(ctx, scratch, &commit, gens,
n_vec, n_vec_len,
l_vec, l_vec_len,
c_vec, c_vec_len, &mu)) {
1923 gens->gens, gens->n,
n_vec, n_vec_len,
l_vec, l_vec_len,
c_vec, c_vec_len);
1930 if (resources == NULL) {
1931 if (gens != NULL) secp256k1_bppp_generators_destroy(ctx, gens);
1932 if (scratch != NULL) secp256k1_scratch_space_destroy(ctx, scratch);
1938 const unsigned char rho32[32],
const unsigned char* generators33,
size_t generators_count,
1939 const unsigned char* n_vec32,
size_t n_vec_len,
const unsigned char* l_vec32,
1940 size_t l_vec_len,
const unsigned char* c_vec32,
size_t c_vec_len,
1941 unsigned char commitment_out33[33],
unsigned char* proof_out,
size_t* proof_len) {
1943 l_vec32, l_vec_len, c_vec32, c_vec_len, commitment_out33,
1944 proof_out, proof_len);
1948 const unsigned char rho32[32],
1949 const unsigned char* n_vec32,
size_t n_vec_len,
1950 const unsigned char* l_vec32,
size_t l_vec_len,
1951 const unsigned char* c_vec32,
size_t c_vec_len,
1952 unsigned char commitment_out33[33],
unsigned char* proof_out,
1953 size_t* proof_len) {
1956 n_vec32, n_vec_len, l_vec32, l_vec_len, c_vec32, c_vec_len,
1957 commitment_out33, proof_out, proof_len);
1962 const unsigned char rho32[32],
const unsigned char* generators33,
1963 size_t generators_count,
const unsigned char* n_vec32,
1964 size_t n_vec_len,
const unsigned char* l_vec32,
1965 size_t l_vec_len,
const unsigned char* c_vec32,
1966 size_t c_vec_len,
const unsigned char commitment33[33],
1967 unsigned char* proof_out,
size_t* proof_len) {
1969 secp256k1_scratch_space* scratch = resources != NULL ? resources->
scratch : NULL;
1970 secp256k1_bppp_generators* gens = NULL;
1971 secp256k1_scalar
rho, mu;
1973 secp256k1_ge expected_commit, commitment_ge;
1974 secp256k1_sha256 transcript;
1975 unsigned char expected_commitment33[33];
1977 size_t expected_generators = 0;
1978 size_t serialized_generators_len = 0;
1982 memset(expected_commitment33, 0,
sizeof(expected_commitment33));
1983 if (ctx == NULL || rho32 == NULL || (resources == NULL && generators33 == NULL) || n_vec32 == NULL || l_vec32 == NULL || c_vec32 == NULL ||
1984 commitment33 == NULL || proof_out == NULL || proof_len == NULL) {
1987 if (n_vec_len == 0 || l_vec_len == 0 || c_vec_len == 0 || l_vec_len != c_vec_len) {
1990 if (!secp256k1_is_power_of_two(n_vec_len) || !secp256k1_is_power_of_two(c_vec_len) ||
1992 generators_count != expected_generators ||
1996 if (resources != NULL && resources->
generators_count != generators_count) {
1999 if (*proof_len < required) {
2000 *proof_len = required;
2006 if (resources != NULL) {
2012 scratch = secp256k1_scratch_space_create(ctx, 1u << 24);
2013 gens = secp256k1_bppp_generators_parse(ctx, generators33, serialized_generators_len);
2018 if (scratch == NULL || gens == NULL ||
n_vec == NULL ||
l_vec == NULL ||
c_vec == NULL) {
2026 secp256k1_scalar_sqr(&mu, &
rho);
2027 if (!secp256k1_bppp_commit(ctx, scratch, &expected_commit, gens,
n_vec, n_vec_len,
l_vec, l_vec_len,
c_vec, c_vec_len, &mu)) {
2033 if (secp256k1_memcmp_var(expected_commitment33, commitment33,
sizeof(expected_commitment33)) != 0) {
2038 gens->gens, gens->n,
n_vec, n_vec_len,
l_vec, l_vec_len,
c_vec, c_vec_len);
2045 if (resources == NULL) {
2046 if (gens != NULL) secp256k1_bppp_generators_destroy(ctx, gens);
2047 if (scratch != NULL) secp256k1_scratch_space_destroy(ctx, scratch);
2053 const unsigned char rho32[32],
const unsigned char* generators33,
size_t generators_count,
2054 const unsigned char* n_vec32,
size_t n_vec_len,
const unsigned char* l_vec32,
2055 size_t l_vec_len,
const unsigned char* c_vec32,
size_t c_vec_len,
2056 const unsigned char commitment33[33],
unsigned char* proof_out,
size_t* proof_len) {
2058 n_vec32, n_vec_len, l_vec32, l_vec_len, c_vec32, c_vec_len,
2059 commitment33, proof_out, proof_len);
2063 const unsigned char rho32[32],
2064 const unsigned char* n_vec32,
size_t n_vec_len,
2065 const unsigned char* l_vec32,
size_t l_vec_len,
2066 const unsigned char* c_vec32,
size_t c_vec_len,
2067 const unsigned char commitment33[33],
2068 unsigned char* proof_out,
size_t* proof_len) {
2071 n_vec32, n_vec_len, l_vec32, l_vec_len, c_vec32, c_vec_len,
2072 commitment33, proof_out, proof_len);
2077 const unsigned char rho32[32],
const unsigned char* generators33,
2078 size_t generators_count,
const unsigned char* c_vec32,
size_t c_vec_len,
2079 size_t n_vec_len,
const unsigned char commitment33[33],
2080 const unsigned char* proof,
size_t proof_len) {
2082 secp256k1_scratch_space* scratch = resources != NULL ? resources->
scratch : NULL;
2083 secp256k1_bppp_generators* gens = resources != NULL ? resources->
gens : NULL;
2084 secp256k1_scalar
rho, *
c_vec = NULL;
2085 secp256k1_ge commit;
2086 secp256k1_sha256 transcript;
2087 size_t expected_generators = 0;
2088 size_t serialized_generators_len = 0;
2091 if (ctx == NULL || rho32 == NULL || (resources == NULL && generators33 == NULL) || c_vec32 == NULL || commitment33 == NULL || proof == NULL) {
2094 if (n_vec_len == 0 || c_vec_len == 0 ||
2096 generators_count != expected_generators ||
2100 if (!secp256k1_is_power_of_two(n_vec_len) || !secp256k1_is_power_of_two(c_vec_len)) {
2103 if (resources != NULL && resources->
generators_count != generators_count) {
2109 if (resources == NULL) {
2110 scratch = secp256k1_scratch_space_create(ctx, 1u << 24);
2111 gens = secp256k1_bppp_generators_parse(ctx, generators33, serialized_generators_len);
2114 if (scratch == NULL || gens == NULL ||
c_vec == NULL) {
2121 ok = secp256k1_bppp_rangeproof_norm_product_verify(ctx, scratch, proof, proof_len, &transcript, &
rho,
2122 gens, n_vec_len,
c_vec, c_vec_len, &commit);
2126 if (resources == NULL) {
2127 if (gens != NULL) secp256k1_bppp_generators_destroy(ctx, gens);
2128 if (scratch != NULL) secp256k1_scratch_space_destroy(ctx, scratch);
2134 const unsigned char rho32[32],
const unsigned char* generators33,
size_t generators_count,
2135 const unsigned char* c_vec32,
size_t c_vec_len,
size_t n_vec_len,
2136 const unsigned char commitment33[33],
const unsigned char* proof,
size_t proof_len) {
2138 c_vec32, c_vec_len, n_vec_len, commitment33, proof, proof_len);
2142 const unsigned char rho32[32],
2143 const unsigned char* c_vec32,
size_t c_vec_len,
size_t n_vec_len,
2144 const unsigned char commitment33[33],
const unsigned char* proof,
2148 c_vec32, c_vec_len, n_vec_len, commitment33, proof, proof_len);
static secp256k1_scalar * purify_scalar_cast(purify_scalar *scalar)
static void purify_bulletproof_circuit_evaluate_sum_row(secp256k1_scalar *acc, const secp256k1_bulletproof_wmatrix_row *row, const secp256k1_scalar *assn)
void purify_scalar_mul(purify_scalar *out, const purify_scalar *lhs, const purify_scalar *rhs)
Multiplies two scalars modulo the backend field.
int purify_bppp_prove_norm_arg_to_commitment_with_resources(purify_bppp_backend_resources *resources, const unsigned char rho32[32], const unsigned char *n_vec32, size_t n_vec_len, const unsigned char *l_vec32, size_t l_vec_len, const unsigned char *c_vec32, size_t c_vec_len, const unsigned char commitment33[33], unsigned char *proof_out, size_t *proof_len)
static int purify_parse_scalar_array(const unsigned char *input32, size_t count, secp256k1_scalar *out)
static int purify_bppp_backend_resources_reset_scratch_gens(purify_bppp_backend_resources *resources)
static int purify_bppp_rangeproof_norm_product_prove_const(const secp256k1_context *ctx, secp256k1_scratch_space *scratch, unsigned char *proof, size_t *proof_len, secp256k1_sha256 *transcript, const secp256k1_scalar *rho, const secp256k1_ge *g_vec, size_t g_vec_len, const secp256k1_scalar *n_vec, size_t n_vec_len, const secp256k1_scalar *l_vec, size_t l_vec_len, const secp256k1_scalar *c_vec, size_t c_vec_len)
static int purify_build_row_family(secp256k1_bulletproof_wmatrix_row *out_rows, size_t row_count, const purify_bulletproof_row_view *in_rows, size_t n_constraints, secp256k1_bulletproof_wmatrix_entry *entries, size_t *offset)
int purify_bulletproof_prove_circuit(purify_secp_context *context, const purify_bulletproof_circuit_view *circuit, const purify_bulletproof_assignment_view *assignment, const unsigned char *blind32, const unsigned char value_gen33[33], const unsigned char nonce32[32], const unsigned char *extra_commit, size_t extra_commit_len, unsigned char commitment_out33[33], unsigned char *proof_out, size_t *proof_len)
static secp256k1_bppp_generators * purify_bppp_backend_resources_acquire_scratch_gens(purify_bppp_backend_resources *resources, purify_bppp_mutable_generators_guard *guard)
static int purify_parse_scalar(const unsigned char input32[32], secp256k1_scalar *scalar, int reject_zero)
static int purify_build_bulletproof_assignment(const purify_bulletproof_assignment_view *view, secp256k1_bulletproof_circuit_assignment *out)
int purify_bppp_commit_witness_only_with_resources(purify_bppp_backend_resources *resources, const unsigned char *n_vec32, size_t n_vec_len, const unsigned char *l_vec32, size_t l_vec_len, unsigned char commitment_out33[33])
int purify_bulletproof_prove_circuit_with_resources(purify_bulletproof_backend_resources *resources, const purify_bulletproof_circuit_view *circuit, const purify_bulletproof_assignment_view *assignment, const unsigned char *blind32, const unsigned char value_gen33[33], const unsigned char nonce32[32], const unsigned char *extra_commit, size_t extra_commit_len, unsigned char commitment_out33[33], unsigned char *proof_out, size_t *proof_len)
int purify_scalar_is_zero(const purify_scalar *value)
Returns nonzero when the scalar is zero.
int purify_bip340_xonly_from_point(purify_secp_context *context, const unsigned char point33[33], unsigned char xonly32[32], int *parity_out)
Converts a compressed secp256k1 point into its x-only public key encoding.
int purify_bulletproof_verify_circuit(purify_secp_context *context, const purify_bulletproof_circuit_view *circuit, const unsigned char commitment33[33], const unsigned char value_gen33[33], const unsigned char *extra_commit, size_t extra_commit_len, const unsigned char *proof, size_t proof_len)
int purify_bulletproof_prove_circuit_assume_valid(purify_secp_context *context, const purify_bulletproof_circuit_view *circuit, const purify_bulletproof_assignment_view *assignment, const unsigned char *blind32, const unsigned char value_gen33[33], const unsigned char nonce32[32], const unsigned char *extra_commit, size_t extra_commit_len, unsigned char commitment_out33[33], unsigned char *proof_out, size_t *proof_len)
int purify_bip340_key_from_seckey(purify_secp_context *context, unsigned char seckey32[32], unsigned char xonly_pubkey32[32])
Canonicalizes a valid secp256k1 secret key for BIP340 and derives its x-only public key.
int purify_scalar_add(purify_scalar *out, const purify_scalar *lhs, const purify_scalar *rhs)
Adds two scalars modulo the backend field.
int purify_bip340_nonce_from_scalar(purify_secp_context *context, unsigned char scalar32[32], unsigned char xonly_nonce32[32])
Canonicalizes a valid secp256k1 nonce scalar for BIP340 and derives its x-only public nonce.
int purify_point_scale(purify_secp_context *context, const unsigned char point33[33], const unsigned char scalar32[32], unsigned char out33[33])
void purify_scalar_set_int(purify_scalar *out, unsigned int value)
Initializes a scalar from an unsigned integer.
void purify_scalar_cmov(purify_scalar *dst, const purify_scalar *src, int flag)
Conditionally assigns src into dst when flag is nonzero.
static void purify_norm_arg_commit_initial_data(secp256k1_sha256 *transcript, const secp256k1_scalar *rho, const secp256k1_bppp_generators *gens_vec, size_t g_len, const secp256k1_scalar *c_vec, size_t c_vec_len, const secp256k1_ge *commit)
static int purify_copy_vectors_into_scratch(const secp256k1_context *ctx, secp256k1_scratch_space *scratch, secp256k1_scalar **ns, secp256k1_scalar **ls, secp256k1_scalar **cs, secp256k1_ge **gs, const secp256k1_scalar *n_vec, const secp256k1_scalar *l_vec, const secp256k1_scalar *c_vec, const secp256k1_ge *gens_vec, size_t g_len, size_t h_len)
static int purify_bridge_checked_mul_size(size_t lhs, size_t rhs, size_t *out)
int purify_bulletproof_verify_circuit_with_resources(purify_bulletproof_backend_resources *resources, const purify_bulletproof_circuit_view *circuit, const unsigned char commitment33[33], const unsigned char value_gen33[33], const unsigned char *extra_commit, size_t extra_commit_len, const unsigned char *proof, size_t proof_len)
static int purify_parse_point_as_ge(const unsigned char point33[33], secp256k1_ge *out)
int purify_bip340_sign_with_fixed_nonce(purify_secp_context *context, unsigned char sig64[64], const unsigned char *msg, size_t msglen, const unsigned char seckey32[32], const unsigned char nonce32[32])
Signs a message with a caller-supplied BIP340 nonce scalar.
static int purify_bulletproof_verify_circuit_impl(purify_secp_context *context, purify_bulletproof_backend_resources *resources, const purify_bulletproof_circuit_view *circuit, const unsigned char commitment33[33], const unsigned char value_gen33[33], const unsigned char *extra_commit, size_t extra_commit_len, const unsigned char *proof, size_t proof_len)
int purify_scalar_is_even(const purify_scalar *value)
Returns nonzero when the scalar is even.
static void purify_free_bulletproof_circuit(secp256k1_bulletproof_circuit *circuit)
static int purify_bppp_commit_norm_arg_impl(purify_secp_context *context, purify_bppp_backend_resources *resources, const unsigned char rho32[32], const unsigned char *generators33, size_t generators_count, const unsigned char *n_vec32, size_t n_vec_len, const unsigned char *l_vec32, size_t l_vec_len, const unsigned char *c_vec32, size_t c_vec_len, unsigned char commitment_out33[33])
static int purify_fixed_nonce_function(unsigned char *nonce32, const unsigned char *msg, size_t msglen, const unsigned char *key32, const unsigned char *xonly_pk32, const unsigned char *algo, size_t algolen, void *data)
int purify_sha256_many(unsigned char output32[32], const unsigned char *const *items, const size_t *item_lens, size_t items_count)
Computes SHA-256 over a set of byte strings.
int purify_bppp_prove_norm_arg(purify_secp_context *context, const unsigned char rho32[32], const unsigned char *generators33, size_t generators_count, const unsigned char *n_vec32, size_t n_vec_len, const unsigned char *l_vec32, size_t l_vec_len, const unsigned char *c_vec32, size_t c_vec_len, unsigned char commitment_out33[33], unsigned char *proof_out, size_t *proof_len)
Produces a standalone BPPP norm argument.
static int purify_bppp_prove_norm_arg_to_commitment_impl(purify_secp_context *context, purify_bppp_backend_resources *resources, const unsigned char rho32[32], const unsigned char *generators33, size_t generators_count, const unsigned char *n_vec32, size_t n_vec_len, const unsigned char *l_vec32, size_t l_vec_len, const unsigned char *c_vec32, size_t c_vec_len, const unsigned char commitment33[33], unsigned char *proof_out, size_t *proof_len)
int purify_bppp_commit_witness_only(purify_secp_context *context, const unsigned char *generators33, size_t generators_count, const unsigned char *n_vec32, size_t n_vec_len, const unsigned char *l_vec32, size_t l_vec_len, unsigned char commitment_out33[33])
int purify_bppp_commit_norm_arg(purify_secp_context *context, const unsigned char rho32[32], const unsigned char *generators33, size_t generators_count, const unsigned char *n_vec32, size_t n_vec_len, const unsigned char *l_vec32, size_t l_vec_len, const unsigned char *c_vec32, size_t c_vec_len, unsigned char commitment_out33[33])
static void purify_free_bulletproof_assignment(secp256k1_bulletproof_circuit_assignment *assignment)
void purify_sha256(unsigned char output32[32], const unsigned char *data, size_t data_len)
Computes SHA-256 over a byte string.
static int purify_bppp_verify_norm_arg_impl(purify_secp_context *context, purify_bppp_backend_resources *resources, const unsigned char rho32[32], const unsigned char *generators33, size_t generators_count, const unsigned char *c_vec32, size_t c_vec_len, size_t n_vec_len, const unsigned char commitment33[33], const unsigned char *proof, size_t proof_len)
int purify_scalar_is_one(const purify_scalar *value)
Returns nonzero when the scalar is one.
static size_t purify_total_row_entries(const purify_bulletproof_row_view *rows, size_t count, int *ok)
int purify_bip340_validate_signature(purify_secp_context *context, const unsigned char sig64[64])
Returns nonzero when the 64-byte BIP340 signature has a syntactically valid encoding.
void purify_secp_context_destroy(purify_secp_context *context)
Destroys a context returned by purify_secp_context_create.
void purify_bppp_backend_resources_destroy(purify_bppp_backend_resources *resources)
void purify_scalar_inverse(purify_scalar *out, const purify_scalar *value)
Computes the multiplicative inverse of a scalar in constant time.
int purify_bppp_value_generator_h(purify_secp_context *context, unsigned char out33[33])
Serializes the alternate value generator used by Pedersen commitments.
int purify_bppp_create_generators(purify_secp_context *context, size_t count, unsigned char *out, size_t *out_len)
Expands the generator list required by the BPPP prover and verifier.
purify_bppp_backend_resources * purify_bppp_backend_resources_clone(const purify_bppp_backend_resources *resources)
static const secp256k1_scalar * purify_scalar_cast_const(const purify_scalar *scalar)
static int purify_bulletproof_circuit_evaluate(const secp256k1_bulletproof_circuit *circuit, const secp256k1_bulletproof_circuit_assignment *assignment)
int purify_point_add(purify_secp_context *context, const unsigned char lhs33[33], const unsigned char rhs33[33], unsigned char out33[33])
int purify_bppp_verify_norm_arg(purify_secp_context *context, const unsigned char rho32[32], const unsigned char *generators33, size_t generators_count, const unsigned char *c_vec32, size_t c_vec_len, size_t n_vec_len, const unsigned char commitment33[33], const unsigned char *proof, size_t proof_len)
Verifies a standalone BPPP norm argument.
int purify_pedersen_commit_char(purify_secp_context *context, const unsigned char blind32[32], const unsigned char value32[32], const unsigned char value_gen33[33], const unsigned char blind_gen33[33], unsigned char commitment_out33[33])
Computes a Pedersen commitment to an arbitrary 32-byte scalar value.
void purify_scalar_inverse_var(purify_scalar *out, const purify_scalar *value)
Computes the multiplicative inverse of a scalar.
int purify_bip340_validate_xonly_pubkey(purify_secp_context *context, const unsigned char xonly_pubkey32[32])
Returns nonzero when the x-only public key encoding parses successfully.
static secp256k1_context * purify_context_handle(const purify_secp_context *context)
static void purify_bridge_secure_clear(void *data, size_t size)
int purify_bppp_prove_norm_arg_with_resources(purify_bppp_backend_resources *resources, const unsigned char rho32[32], const unsigned char *n_vec32, size_t n_vec_len, const unsigned char *l_vec32, size_t l_vec_len, const unsigned char *c_vec32, size_t c_vec_len, unsigned char commitment_out33[33], unsigned char *proof_out, size_t *proof_len)
int purify_scalar_eq(const purify_scalar *lhs, const purify_scalar *rhs)
Returns nonzero when two scalars are equal.
int purify_bulletproof_prove_circuit_assume_valid_with_resources(purify_bulletproof_backend_resources *resources, const purify_bulletproof_circuit_view *circuit, const purify_bulletproof_assignment_view *assignment, const unsigned char *blind32, const unsigned char value_gen33[33], const unsigned char nonce32[32], const unsigned char *extra_commit, size_t extra_commit_len, unsigned char commitment_out33[33], unsigned char *proof_out, size_t *proof_len)
static int purify_parse_generator_as_ge(const secp256k1_context *ctx, const unsigned char generator33[33], secp256k1_ge *out)
int purify_bppp_offset_commitment(purify_secp_context *context, const unsigned char commitment33[33], const unsigned char scalar32[32], unsigned char commitment_out33[33])
static int purify_parse_fast_scalar(const unsigned char input32[32], secp256k1_fast_scalar *scalar)
void purify_scalar_negate(purify_scalar *out, const purify_scalar *value)
Computes the additive inverse of a scalar.
void purify_bulletproof_backend_resources_destroy(purify_bulletproof_backend_resources *resources)
purify_secp_context * purify_secp_context_create(void)
Creates one reusable secp256k1 context for the Purify bridge and public APIs.
int purify_bppp_prove_norm_arg_to_commitment(purify_secp_context *context, const unsigned char rho32[32], const unsigned char *generators33, size_t generators_count, const unsigned char *n_vec32, size_t n_vec_len, const unsigned char *l_vec32, size_t l_vec_len, const unsigned char *c_vec32, size_t c_vec_len, const unsigned char commitment33[33], unsigned char *proof_out, size_t *proof_len)
purify_bulletproof_backend_resources * purify_bulletproof_backend_resources_create(purify_secp_context *context, size_t n_gates)
purify_bulletproof_backend_resources * purify_bulletproof_backend_resources_clone(const purify_bulletproof_backend_resources *resources)
int purify_bppp_base_generator(purify_secp_context *context, unsigned char out33[33])
Serializes the secp256k1 base generator into compressed form.
int purify_bppp_commit_norm_arg_with_resources(purify_bppp_backend_resources *resources, const unsigned char rho32[32], const unsigned char *n_vec32, size_t n_vec_len, const unsigned char *l_vec32, size_t l_vec_len, const unsigned char *c_vec32, size_t c_vec_len, unsigned char commitment_out33[33])
size_t purify_bppp_required_proof_size(size_t n_vec_len, size_t c_vec_len)
Computes the maximum serialized size of a BPPP norm proof.
static secp256k1_bppp_generators * purify_bppp_generators_clone(const secp256k1_bppp_generators *generators)
static int purify_bppp_prove_norm_arg_impl(purify_secp_context *context, purify_bppp_backend_resources *resources, const unsigned char rho32[32], const unsigned char *generators33, size_t generators_count, const unsigned char *n_vec32, size_t n_vec_len, const unsigned char *l_vec32, size_t l_vec_len, const unsigned char *c_vec32, size_t c_vec_len, unsigned char commitment_out33[33], unsigned char *proof_out, size_t *proof_len)
static void * purify_malloc_array(size_t count, size_t elem_size)
void purify_scalar_set_u64(purify_scalar *out, uint64_t value)
Initializes a scalar from a 64-bit unsigned integer.
void purify_hmac_sha256(unsigned char output32[32], const unsigned char *key, size_t key_len, const unsigned char *data, size_t data_len)
Computes HMAC-SHA256 over a byte string.
static void purify_bppp_backend_resources_release_scratch_gens(purify_bppp_mutable_generators_guard *guard)
void purify_scalar_get_b32(unsigned char output32[32], const purify_scalar *value)
Serializes a scalar as 32 big-endian bytes.
size_t purify_bulletproof_required_proof_size(size_t n_gates)
purify_bppp_backend_resources * purify_bppp_backend_resources_create(purify_secp_context *context, const unsigned char *generators33, size_t generators_count)
static int purify_bulletproof_prove_circuit_impl(const purify_bulletproof_circuit_view *circuit, const purify_bulletproof_assignment_view *assignment, const unsigned char *blind32, const unsigned char value_gen33[33], const unsigned char nonce32[32], const unsigned char *extra_commit, size_t extra_commit_len, unsigned char commitment_out33[33], unsigned char *proof_out, size_t *proof_len, int require_valid_assignment, purify_secp_context *context, purify_bulletproof_backend_resources *resources)
static int purify_bridge_checked_add_size(size_t lhs, size_t rhs, size_t *out)
int purify_bip340_verify(purify_secp_context *context, const unsigned char sig64[64], const unsigned char *msg, size_t msglen, const unsigned char xonly_pubkey32[32])
Verifies a BIP340 signature against a serialized x-only public key.
static void * purify_calloc_array(size_t count, size_t elem_size)
static int purify_serialize_point(unsigned char out33[33], secp256k1_ge *point)
int purify_bppp_verify_norm_arg_with_resources(purify_bppp_backend_resources *resources, const unsigned char rho32[32], const unsigned char *c_vec32, size_t c_vec_len, size_t n_vec_len, const unsigned char commitment33[33], const unsigned char *proof, size_t proof_len)
void purify_scalar_set_b32(purify_scalar *out, const unsigned char input32[32], int *overflow)
Parses a big-endian 32-byte scalar.
static int purify_build_bulletproof_circuit(const purify_bulletproof_circuit_view *view, secp256k1_bulletproof_circuit *out)
static int purify_bppp_commit_witness_only_impl(purify_secp_context *context, purify_bppp_backend_resources *resources, const unsigned char *generators33, size_t generators_count, const unsigned char *n_vec32, size_t n_vec_len, const unsigned char *l_vec32, size_t l_vec_len, unsigned char commitment_out33[33])
C ABI bridging Purify C++ code to secp256k1-zkp BPPP functionality.
static void secp256k1_fast_scalar_mul(secp256k1_scalar *r, const secp256k1_fast_scalar *a, const secp256k1_scalar *b)
static int secp256k1_bulletproof_relation66_verify_impl(const secp256k1_ecmult_context *ecmult_ctx, secp256k1_scratch *scratch, const unsigned char *const *proof, size_t n_proofs, size_t plen, const secp256k1_ge *const *commitp, size_t *nc, const secp256k1_ge *value_gen, const secp256k1_bulletproof_circuit *const *circ, const secp256k1_bulletproof_generators *gens, const unsigned char **extra_commit, size_t *extra_commit_len)
static int secp256k1_bulletproof_relation66_prove_impl(const secp256k1_ecmult_context *ecmult_ctx, secp256k1_scratch *scratch, unsigned char *proof, size_t *plen, const secp256k1_bulletproof_circuit_assignment *assn, const secp256k1_ge *commitp, const secp256k1_scalar *blinds, size_t nc, const secp256k1_ge *value_gen, const secp256k1_bulletproof_circuit *circ, const secp256k1_bulletproof_generators *gens, const unsigned char *nonce, const unsigned char *extra_commit, size_t extra_commit_len)
size_t secp256k1_bulletproof_innerproduct_proof_length(size_t n)
static secp256k1_bulletproof_generators * secp256k1_bulletproof_generators_create(const secp256k1_context *ctx, const secp256k1_generator *blinding_gen, size_t n, size_t precomp_n)
static void secp256k1_bulletproof_generators_destroy(const secp256k1_context *ctx, secp256k1_bulletproof_generators *gen)
#define secp256k1_scratch_alloc(scratch, size)
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)
std::size_t generator_count
std::vector< FieldElement > c_vec
std::vector< FieldElement > l_vec
std::vector< PointBytes > generators
std::vector< FieldElement > n_vec
Public C core for Purify key validation, key derivation, key generation, and evaluation.
purify_error_code purify_fill_secure_random(unsigned char *bytes, size_t bytes_len)
Fills a caller-owned buffer with secure operating-system randomness.
Narrow C ABI exposing secp256k1 scalar and HMAC helpers to the C++ headers.
secp256k1_scratch_space * scratch
secp256k1_bppp_generators * gens
secp256k1_bppp_generators gens_scratch
purify_bppp_backend_resources * resources
const unsigned char * ar32
const unsigned char * al32
const unsigned char * ao32
const unsigned char * v32
secp256k1_scratch_space * scratch
secp256k1_bulletproof_generators * gens
const purify_bulletproof_row_view * wr
const purify_bulletproof_row_view * wo
const purify_bulletproof_row_view * wl
const purify_bulletproof_row_view * wv
const unsigned char * c32
Opaque scalar storage compatible with secp256k1-zkp internal scalar storage.
secp256k1_bulletproof_wmatrix_row * wl
secp256k1_bulletproof_wmatrix_row * wv
secp256k1_bulletproof_wmatrix_entry * entries
secp256k1_bulletproof_wmatrix_row * wo
secp256k1_bulletproof_wmatrix_row * wr
secp256k1_fast_scalar * c
secp256k1_ge * blinding_gen
secp256k1_fast_scalar scal
secp256k1_bulletproof_wmatrix_entry * entry