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);
88 secp256k1_context*
ctx;
95 secp256k1_context*
ctx;
97 secp256k1_bppp_generators*
gens;
110 if (lhs != 0 && rhs > SIZE_MAX / lhs) {
121 if (rhs > SIZE_MAX - lhs) {
147 size_t allocation_size;
198 secp256k1_scratch_space* replacement;
203 if (required <= resources->scratch_capacity) {
206 replacement = secp256k1_scratch_space_create(resources->
ctx, required);
207 if (replacement == NULL) {
210 secp256k1_scratch_space_destroy(resources->
ctx, resources->
scratch);
211 resources->
scratch = replacement;
225 return malloc(bytes);
237 return calloc(1, bytes);
241 const secp256k1_bppp_generators* generators) {
242 secp256k1_bppp_generators* clone;
243 size_t generator_bytes = 0;
245 if (generators == NULL || generators->gens == NULL || generators->n == 0 ||
250 clone = (secp256k1_bppp_generators*)calloc(1,
sizeof(*clone));
254 clone->n = generators->n;
256 if (clone->gens == NULL) {
260 memcpy(clone->gens, generators->gens, generator_bytes);
267 size_t generator_bytes = 0;
269 if (resources == NULL || resources->
gens == NULL || resources->
gens->gens == NULL ||
276 memcpy(resources->
gens_scratch.gens, resources->
gens->gens, generator_bytes);
296 if (guard != NULL && guard->
resources != NULL) {
305 size_t generator_count = 0;
308 if (ctx == NULL || n_gates == 0 || !secp256k1_is_power_of_two(n_gates)) {
316 if (resources == NULL) {
320 resources->
ctx = ctx;
324 if (resources->
scratch == NULL) {
330 if (resources->
gens == NULL || resources->
gens->
n < generator_count) {
342 size_t generator_count = 0;
344 if (resources == NULL || resources->
ctx == NULL || resources->
n_gates == 0 ||
353 clone->
ctx = resources->
ctx;
362 clone->
ctx, secp256k1_generator_h, generator_count, 1);
363 if (clone->
gens == NULL || clone->
gens->
n < generator_count) {
371 if (resources == NULL) {
374 if (resources->
gens != NULL && resources->
ctx != NULL) {
377 if (resources->
scratch != NULL && resources->
ctx != NULL) {
378 secp256k1_scratch_space_destroy(resources->
ctx, resources->
scratch);
384 const unsigned char* generators33,
385 size_t generators_count) {
387 size_t serialized_len = 0;
390 if (ctx == NULL || generators33 == NULL || generators_count == 0) {
398 if (resources == NULL) {
402 resources->
ctx = ctx;
404 resources->
scratch = secp256k1_scratch_space_create(resources->
ctx, 1u << 24);
405 if (resources->
scratch == NULL) {
410 resources->
gens = secp256k1_bppp_generators_parse(resources->
ctx, generators33, serialized_len);
411 if (resources->
gens == NULL || resources->
gens->n != generators_count) {
430 size_t generator_bytes = 0;
442 clone->
ctx = resources->
ctx;
444 clone->
scratch = secp256k1_scratch_space_create(clone->
ctx, 1u << 24);
450 if (clone->
gens == NULL) {
466 if (resources == NULL) {
469 if (resources->
gens != NULL && resources->
ctx != NULL) {
470 secp256k1_bppp_generators_destroy(resources->
ctx, resources->
gens);
475 if (resources->
scratch != NULL && resources->
ctx != NULL) {
476 secp256k1_scratch_space_destroy(resources->
ctx, resources->
scratch);
482 return (secp256k1_scalar*)scalar;
486 return (
const secp256k1_scalar*)scalar;
547 static const unsigned char zero = 0;
548 secp256k1_sha256 sha256;
550 if (data == NULL && data_len == 0) {
554 secp256k1_sha256_initialize(&sha256);
556 secp256k1_sha256_write(&sha256, data, data_len);
558 secp256k1_sha256_finalize(&sha256, output32);
559 secp256k1_sha256_clear(&sha256);
563 const unsigned char *
const *items,
564 const size_t *item_lens,
565 size_t items_count) {
566 secp256k1_sha256 sha256;
567 if (output32 == NULL) {
570 if (items_count != 0 && (items == NULL || item_lens == NULL)) {
571 memset(output32, 0, 32);
574 secp256k1_sha256_initialize(&sha256);
575 for (
size_t i = 0; i < items_count; ++i) {
576 const unsigned char *item = items[i];
577 size_t item_len = item_lens[i];
580 secp256k1_sha256_clear(&sha256);
581 memset(output32, 0, 32);
587 secp256k1_sha256_write(&sha256, item, item_len);
590 secp256k1_sha256_finalize(&sha256, output32);
591 secp256k1_sha256_clear(&sha256);
596 const unsigned char* key,
size_t key_len,
597 const unsigned char* data,
size_t data_len) {
598 static const unsigned char zero = 0;
599 secp256k1_hmac_sha256 hmac;
601 if (key == NULL && key_len == 0) {
604 if (data == NULL && data_len == 0) {
608 secp256k1_hmac_sha256_initialize(&hmac, key, key_len);
610 secp256k1_hmac_sha256_write(&hmac, data, data_len);
612 secp256k1_hmac_sha256_finalize(&hmac, output32);
613 secp256k1_hmac_sha256_clear(&hmac);
617 unsigned char seckey32[32],
618 unsigned char xonly_pubkey32[32]) {
620 secp256k1_keypair keypair;
621 secp256k1_xonly_pubkey xonly;
625 memset(&keypair, 0,
sizeof(keypair));
626 memset(&xonly, 0,
sizeof(xonly));
627 if (xonly_pubkey32 != NULL) {
628 memset(xonly_pubkey32, 0, 32);
631 if (ctx == NULL || seckey32 == NULL || xonly_pubkey32 == NULL) {
635 ok = secp256k1_keypair_create(ctx, &keypair, seckey32);
637 ok = secp256k1_keypair_xonly_pub(ctx, &xonly, &parity, &keypair);
640 ok = secp256k1_xonly_pubkey_serialize(ctx, xonly_pubkey32, &xonly);
642 if (ok && parity != 0) {
643 ok = secp256k1_ec_seckey_negate(ctx, seckey32);
647 memset(xonly_pubkey32, 0, 32);
656 unsigned char scalar32[32],
657 unsigned char xonly_nonce32[32]) {
659 secp256k1_pubkey pubkey;
660 secp256k1_xonly_pubkey xonly;
664 memset(&pubkey, 0,
sizeof(pubkey));
665 memset(&xonly, 0,
sizeof(xonly));
666 if (xonly_nonce32 != NULL) {
667 memset(xonly_nonce32, 0, 32);
670 if (ctx == NULL || scalar32 == NULL || xonly_nonce32 == NULL) {
674 ok = secp256k1_ec_pubkey_create(ctx, &pubkey, scalar32);
676 ok = secp256k1_xonly_pubkey_from_pubkey(ctx, &xonly, &parity, &pubkey);
679 ok = secp256k1_xonly_pubkey_serialize(ctx, xonly_nonce32, &xonly);
681 if (ok && parity != 0) {
682 ok = secp256k1_ec_seckey_negate(ctx, scalar32);
686 memset(xonly_nonce32, 0, 32);
695 const unsigned char point33[33],
696 unsigned char xonly32[32],
699 secp256k1_pubkey pubkey;
700 secp256k1_xonly_pubkey xonly;
704 memset(&pubkey, 0,
sizeof(pubkey));
705 memset(&xonly, 0,
sizeof(xonly));
706 if (xonly32 != NULL) {
707 memset(xonly32, 0, 32);
709 if (parity_out != NULL) {
713 if (ctx == NULL || point33 == NULL || xonly32 == NULL) {
717 ok = secp256k1_ec_pubkey_parse(ctx, &pubkey, point33, 33);
719 ok = secp256k1_xonly_pubkey_from_pubkey(ctx, &xonly, &parity, &pubkey);
722 ok = secp256k1_xonly_pubkey_serialize(ctx, xonly32, &xonly);
724 if (ok && parity_out != NULL) {
725 *parity_out = parity;
728 memset(xonly32, 0, 32);
737 const unsigned char xonly_pubkey32[32]) {
739 secp256k1_xonly_pubkey xonly;
742 memset(&xonly, 0,
sizeof(xonly));
743 if (ctx == NULL || xonly_pubkey32 == NULL) {
747 ok = secp256k1_xonly_pubkey_parse(ctx, &xonly, xonly_pubkey32);
754 const unsigned char sig64[64]) {
756 secp256k1_xonly_pubkey rxonly;
763 if (ctx == NULL || sig64 == NULL) {
767 ok = secp256k1_xonly_pubkey_parse(ctx, &rxonly, sig64);
769 secp256k1_scalar_set_b32(&s, sig64 + 32, &overflow);
774 secp256k1_scalar_clear(&s);
779 const unsigned char *msg,
size_t msglen,
780 const unsigned char *key32,
781 const unsigned char *xonly_pk32,
782 const unsigned char *algo,
size_t algolen,
791 if (nonce32 == NULL || data == NULL) {
794 memcpy(nonce32, data, 32);
799 unsigned char sig64[64],
800 const unsigned char* msg,
size_t msglen,
801 const unsigned char seckey32[32],
802 const unsigned char nonce32[32]) {
804 secp256k1_keypair keypair;
805 secp256k1_scalar nonce_scalar;
806 secp256k1_schnorrsig_extraparams extraparams = SECP256K1_SCHNORRSIG_EXTRAPARAMS_INIT;
807 unsigned char canonical_nonce32[32];
808 unsigned char xonly_nonce32[32];
817 memset(sig64, 0, 64);
820 if (ctx == NULL || sig64 == NULL || seckey32 == NULL || nonce32 == NULL || (msg == NULL && msglen != 0)) {
824 memcpy(canonical_nonce32, nonce32, 32);
827 ok = secp256k1_memcmp_var(canonical_nonce32, nonce32, 32) == 0;
829 secp256k1_scalar_set_b32(&nonce_scalar, nonce32, &overflow);
830 if (ok && !overflow && !secp256k1_scalar_is_zero(&nonce_scalar)) {
831 ok = secp256k1_keypair_create(ctx, &keypair, seckey32);
834 extraparams.ndata = (
void*)nonce32;
835 ok = secp256k1_schnorrsig_sign_custom(ctx, sig64, msg, msglen, &keypair, &extraparams);
840 secp256k1_scalar_clear(&nonce_scalar);
844 memset(sig64, 0, 64);
850 const unsigned char sig64[64],
851 const unsigned char* msg,
size_t msglen,
852 const unsigned char xonly_pubkey32[32]) {
854 secp256k1_xonly_pubkey pubkey;
857 memset(&pubkey, 0,
sizeof(pubkey));
858 if (ctx == NULL || sig64 == NULL || xonly_pubkey32 == NULL || (msg == NULL && msglen != 0)) {
862 ok = secp256k1_xonly_pubkey_parse(ctx, &pubkey, xonly_pubkey32);
864 ok = secp256k1_schnorrsig_verify(ctx, sig64, msg, msglen, &pubkey);
867 memset(&pubkey, 0,
sizeof(pubkey));
871static int purify_parse_scalar(
const unsigned char input32[32], secp256k1_scalar* scalar,
int reject_zero) {
873 secp256k1_scalar_set_b32(scalar, input32, &overflow);
877 if (reject_zero && secp256k1_scalar_is_zero(scalar)) {
885 for (i = 0; i < count; ++i) {
894 secp256k1_fe_normalize_var(&point->x);
895 secp256k1_fe_normalize_var(&point->y);
896 return secp256k1_bppp_serialize_pt(out33, point);
900 secp256k1_scalar one, two, neg_one, neg_two;
906 secp256k1_scalar_set_int(&one, 1);
907 secp256k1_scalar_set_int(&two, 2);
908 secp256k1_scalar_negate(&neg_one, &one);
909 secp256k1_scalar_negate(&neg_two, &two);
912 if (secp256k1_scalar_is_zero(&scalar->
scal)) {
914 }
else if (secp256k1_scalar_eq(&scalar->
scal, &one)) {
916 }
else if (secp256k1_scalar_eq(&scalar->
scal, &two)) {
918 }
else if (secp256k1_scalar_eq(&scalar->
scal, &neg_one)) {
920 }
else if (secp256k1_scalar_eq(&scalar->
scal, &neg_two)) {
927 secp256k1_generator generator;
928 if (ctx == NULL || generator33 == NULL || out == NULL) {
931 if (!secp256k1_generator_parse(ctx, &generator, generator33)) {
934 secp256k1_generator_load(out, &generator);
939 if (point33 == NULL || out == NULL) {
942 return secp256k1_eckey_pubkey_parse(out, point33, 33);
946 if (circuit == NULL) {
955 memset(circuit, 0,
sizeof(*circuit));
959 if (assignment == NULL) {
962 free(assignment->
al);
963 free(assignment->
ar);
964 free(assignment->
ao);
966 memset(assignment, 0,
sizeof(*assignment));
985 for (i = 0; i < count; ++i) {
986 if (rows[i].size != 0 && (rows[i].indices == NULL || rows[i].scalars32 == NULL)) {
1002 size_t n_constraints,
1006 for (i = 0; i < row_count; ++i) {
1008 out_rows[i].
size = in_rows[i].
size;
1009 out_rows[i].
entry = in_rows[i].
size == 0 ? NULL : entries + *offset;
1010 for (j = 0; j < in_rows[i].
size; ++j) {
1011 size_t entry_idx = *offset + j;
1012 if (in_rows[i].indices[j] >= n_constraints) {
1019 entries[entry_idx] = out_rows[i].
entry[j];
1021 *offset += in_rows[i].
size;
1028 const secp256k1_scalar* assn) {
1030 for (j = 0; j < row->
size; ++j) {
1031 secp256k1_scalar term;
1033 secp256k1_scalar_add(&acc[row->
entry[j].
idx], &acc[row->
entry[j].
idx], &term);
1039 secp256k1_scalar* acc = NULL;
1043 if (circuit == NULL || assignment == NULL) {
1055 for (i = 0; i < assignment->
n_gates; ++i) {
1056 secp256k1_scalar product;
1057 secp256k1_scalar_mul(&product, &assignment->
al[i], &assignment->
ar[i]);
1058 if (!secp256k1_scalar_eq(&product, &assignment->
ao[i])) {
1064 secp256k1_scalar_clear(&acc[i]);
1067 for (i = 0; i < circuit->
n_gates; ++i) {
1072 for (i = 0; i < circuit->
n_commits; ++i) {
1073 secp256k1_scalar negated_v;
1074 secp256k1_scalar_negate(&negated_v, &assignment->
v[i]);
1078 secp256k1_scalar constant_term;
1079 secp256k1_scalar one;
1080 secp256k1_scalar_set_int(&one, 1);
1082 if (!secp256k1_scalar_eq(&acc[i], &constant_term)) {
1096 size_t row_entries = 0;
1097 size_t total_entries = 0;
1104 if (view == NULL || out == NULL || (view->
n_constraints != 0 && view->
c32 == NULL)) {
1110 memset(out, 0,
sizeof(*out));
1134 if ((view->
n_gates != 0 && (out->
wl == NULL || out->
wr == NULL || out->
wo == NULL)) ||
1137 (total_entries != 0 && out->
entries == NULL)) {
1160 if (view == NULL || out == NULL) {
1163 if ((view->
n_gates != 0 && (view->
al32 == NULL || view->
ar32 == NULL || view->
ao32 == NULL)) ||
1168 memset(out, 0,
sizeof(*out));
1175 if ((view->
n_gates != 0 && (out->
al == NULL || out->
ar == NULL || out->
ao == NULL)) ||
1191 size_t proof_size = 0;
1204 const unsigned char* blind32,
1205 const unsigned char value_gen33[33],
1206 const unsigned char nonce32[32],
1207 const unsigned char* extra_commit,
1208 size_t extra_commit_len,
1209 unsigned char commitment_out33[33],
1210 unsigned char* proof_out,
1212 int require_valid_assignment,
1215 secp256k1_context* ctx = NULL;
1216 secp256k1_scratch_space* scratch = NULL;
1220 secp256k1_ge value_gen;
1221 secp256k1_ge commit_points[1];
1222 secp256k1_scalar blinds[1];
1223 size_t n_commits = 0;
1224 size_t required_generators = 0;
1226 int owns_resources = 0;
1228 memset(&bp_circuit, 0,
sizeof(bp_circuit));
1229 memset(&bp_assignment, 0,
sizeof(bp_assignment));
1230 memset(commit_points, 0,
sizeof(commit_points));
1231 memset(blinds, 0,
sizeof(blinds));
1232 if (commitment_out33 != NULL) {
1233 memset(commitment_out33, 0, 33);
1236 if (circuit == NULL || assignment == NULL || value_gen33 == NULL || nonce32 == NULL || proof_out == NULL || proof_len == NULL) {
1239 if (extra_commit == NULL && extra_commit_len != 0) {
1249 if (resources == NULL) {
1251 if (resources == NULL) {
1262 ctx = resources->
ctx;
1264 gens = resources->
gens;
1266 gens->
n < required_generators) {
1274 if (n_commits == 1) {
1275 secp256k1_gej commitj;
1276 if (commitment_out33 == NULL) {
1279 if (blind32 == NULL) {
1280 secp256k1_scalar_clear(&blinds[0]);
1285 if (secp256k1_gej_is_infinity(&commitj)) {
1288 secp256k1_ge_set_gej(&commit_points[0], &commitj);
1292 }
else if (n_commits > 1) {
1297 &ctx->error_callback,
1302 n_commits == 0 ? NULL : commit_points,
1303 n_commits == 0 ? NULL : blinds,
1316 if (owns_resources) {
1325 const unsigned char* blind32,
1326 const unsigned char value_gen33[33],
1327 const unsigned char nonce32[32],
1328 const unsigned char* extra_commit,
1329 size_t extra_commit_len,
1330 unsigned char commitment_out33[33],
1331 unsigned char* proof_out,
1332 size_t* proof_len) {
1334 extra_commit, extra_commit_len, commitment_out33,
1335 proof_out, proof_len, 1, context, NULL);
1341 const unsigned char* blind32,
1342 const unsigned char value_gen33[33],
1343 const unsigned char nonce32[32],
1344 const unsigned char* extra_commit,
1345 size_t extra_commit_len,
1346 unsigned char commitment_out33[33],
1347 unsigned char* proof_out,
1348 size_t* proof_len) {
1350 extra_commit, extra_commit_len, commitment_out33,
1351 proof_out, proof_len, 1, NULL, resources);
1357 const unsigned char* blind32,
1358 const unsigned char value_gen33[33],
1359 const unsigned char nonce32[32],
1360 const unsigned char* extra_commit,
1361 size_t extra_commit_len,
1362 unsigned char commitment_out33[33],
1363 unsigned char* proof_out,
1364 size_t* proof_len) {
1366 extra_commit, extra_commit_len, commitment_out33,
1367 proof_out, proof_len, 0, context, NULL);
1373 const unsigned char* blind32,
1374 const unsigned char value_gen33[33],
1375 const unsigned char nonce32[32],
1376 const unsigned char* extra_commit,
1377 size_t extra_commit_len,
1378 unsigned char commitment_out33[33],
1379 unsigned char* proof_out,
1380 size_t* proof_len) {
1382 extra_commit, extra_commit_len, commitment_out33,
1383 proof_out, proof_len, 0, NULL, resources);
1389 const unsigned char commitment33[33],
1390 const unsigned char value_gen33[33],
1391 const unsigned char* extra_commit,
1392 size_t extra_commit_len,
1393 const unsigned char* proof,
1398 const unsigned char commitment33[33],
1399 const unsigned char value_gen33[33],
1400 const unsigned char* extra_commit,
1401 size_t extra_commit_len,
1402 const unsigned char* proof,
1405 extra_commit, extra_commit_len, proof, proof_len);
1411 const unsigned char commitment33[33],
1412 const unsigned char value_gen33[33],
1413 const unsigned char* extra_commit,
1414 size_t extra_commit_len,
1415 const unsigned char* proof,
1417 secp256k1_context* ctx = NULL;
1418 secp256k1_scratch_space* scratch = NULL;
1421 secp256k1_ge value_gen;
1422 secp256k1_ge commit_points[1];
1423 const secp256k1_ge* commit_ptr = NULL;
1425 const unsigned char* proof_ptr = NULL;
1426 const unsigned char* extra_commit_ptr = NULL;
1427 size_t n_commits = 0;
1428 size_t required_generators = 0;
1430 int owns_resources = 0;
1432 memset(&bp_circuit, 0,
sizeof(bp_circuit));
1433 memset(commit_points, 0,
sizeof(commit_points));
1434 if (circuit == NULL || value_gen33 == NULL || proof == NULL) {
1437 if (extra_commit == NULL && extra_commit_len != 0) {
1443 if (resources == NULL) {
1445 if (resources == NULL) {
1456 ctx = resources->
ctx;
1458 gens = resources->
gens;
1460 gens->
n < required_generators) {
1468 if (n_commits == 1) {
1472 commit_ptr = commit_points;
1473 }
else if (n_commits > 1) {
1477 circuit_ptr = &bp_circuit;
1479 extra_commit_ptr = extra_commit;
1481 &ctx->error_callback,
1486 n_commits == 0 ? NULL : &commit_ptr,
1487 n_commits == 0 ? NULL : &n_commits,
1497 if (owns_resources) {
1505 const unsigned char commitment33[33],
1506 const unsigned char value_gen33[33],
1507 const unsigned char* extra_commit,
1508 size_t extra_commit_len,
1509 const unsigned char* proof,
1512 extra_commit, extra_commit_len, proof, proof_len);
1516 const secp256k1_bppp_generators* gens_vec,
size_t g_len,
1517 const secp256k1_scalar* c_vec,
size_t c_vec_len,
1518 const secp256k1_ge* commit) {
1519 unsigned char ser_commit[33], ser_scalar[32], ser_le64[8];
1521 secp256k1_ge comm = *commit;
1523 secp256k1_bppp_sha256_tagged_commitment_init(transcript);
1529 secp256k1_sha256_write(transcript, ser_commit,
sizeof(ser_commit));
1530 secp256k1_scalar_get_b32(ser_scalar, rho);
1531 secp256k1_sha256_write(transcript, ser_scalar,
sizeof(ser_scalar));
1532 secp256k1_bppp_le64(ser_le64, g_len);
1533 secp256k1_sha256_write(transcript, ser_le64,
sizeof(ser_le64));
1534 secp256k1_bppp_le64(ser_le64, gens_vec->n);
1535 secp256k1_sha256_write(transcript, ser_le64,
sizeof(ser_le64));
1536 for (i = 0; i < gens_vec->n; ++i) {
1537 secp256k1_ge gen = gens_vec->gens[i];
1541 secp256k1_sha256_write(transcript, ser_commit,
sizeof(ser_commit));
1543 secp256k1_bppp_le64(ser_le64, c_vec_len);
1544 secp256k1_sha256_write(transcript, ser_le64,
sizeof(ser_le64));
1545 for (i = 0; i < c_vec_len; ++i) {
1546 secp256k1_scalar_get_b32(ser_scalar, &c_vec[i]);
1547 secp256k1_sha256_write(transcript, ser_scalar,
sizeof(ser_scalar));
1553 secp256k1_scalar** ns, secp256k1_scalar** ls, secp256k1_scalar** cs,
1554 secp256k1_ge** gs,
const secp256k1_scalar* n_vec,
1555 const secp256k1_scalar* l_vec,
const secp256k1_scalar* c_vec,
1556 const secp256k1_ge* gens_vec,
size_t g_len,
size_t h_len) {
1557 size_t scalar_g_bytes = 0;
1558 size_t scalar_h_bytes = 0;
1559 size_t ge_count = 0;
1560 size_t ge_bytes = 0;
1573 if (*ns == NULL || *ls == NULL || *cs == NULL || *gs == NULL) {
1576 memcpy(*ns, n_vec, scalar_g_bytes);
1577 memcpy(*ls, l_vec, scalar_h_bytes);
1578 memcpy(*cs, c_vec, scalar_h_bytes);
1579 memcpy(*gs, gens_vec, ge_bytes);
1584 unsigned char* proof,
size_t* proof_len,
1585 secp256k1_sha256* transcript,
const secp256k1_scalar* rho,
1586 const secp256k1_ge* g_vec,
size_t g_vec_len,
1587 const secp256k1_scalar* n_vec,
size_t n_vec_len,
1588 const secp256k1_scalar* l_vec,
size_t l_vec_len,
1589 const secp256k1_scalar* c_vec,
size_t c_vec_len) {
1590 secp256k1_scalar *ns = NULL, *ls = NULL, *cs = NULL;
1591 secp256k1_ge *gs = NULL;
1592 size_t checkpoint = secp256k1_scratch_checkpoint(&ctx->error_callback, scratch);
1595 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)) {
1596 result = secp256k1_bppp_rangeproof_norm_product_prove(ctx, scratch, proof, proof_len, transcript, rho,
1597 gs, g_vec_len, ns, n_vec_len, ls, l_vec_len, cs, c_vec_len);
1599 secp256k1_scratch_apply_checkpoint(&ctx->error_callback, scratch, checkpoint);
1604 size_t log_g_len, log_h_len, max_log_len, proof_size = 0;
1605 if (n_vec_len == 0 || c_vec_len == 0 || n_vec_len < c_vec_len) {
1608 log_g_len = secp256k1_bppp_log2(n_vec_len);
1609 log_h_len = secp256k1_bppp_log2(c_vec_len);
1610 max_log_len = log_g_len > log_h_len ? log_g_len : log_h_len;
1620 secp256k1_generator generator;
1621 secp256k1_ge ge = secp256k1_ge_const_g;
1624 if (ctx == NULL || out33 == NULL) {
1627 secp256k1_generator_save(&generator, &ge);
1628 ok = secp256k1_generator_serialize(ctx, out33, &generator);
1636 if (ctx == NULL || out33 == NULL) {
1639 ok = secp256k1_generator_serialize(ctx, out33, secp256k1_generator_h);
1645 secp256k1_bppp_generators* gens = NULL;
1646 size_t required = 0;
1649 if (ctx == NULL || out_len == NULL) {
1656 if (*out_len < required || out == NULL) {
1657 *out_len = required;
1660 gens = secp256k1_bppp_generators_create(ctx, count);
1664 ok = secp256k1_bppp_generators_serialize(ctx, gens, out, out_len);
1665 secp256k1_bppp_generators_destroy(ctx, gens);
1670 const unsigned char blind32[32],
const unsigned char value32[32],
1671 const unsigned char value_gen33[33],
const unsigned char blind_gen33[33],
1672 unsigned char commitment_out33[33]) {
1674 secp256k1_scalar blind_scalar, value_scalar;
1675 secp256k1_generator value_generator, blind_generator;
1676 secp256k1_ge value_ge, blind_ge, commit_ge;
1677 secp256k1_gej blind_part, value_part, total;
1680 if (ctx == NULL || blind32 == NULL || value32 == NULL || value_gen33 == NULL || blind_gen33 == NULL || commitment_out33 == NULL) {
1686 if (!secp256k1_generator_parse(ctx, &value_generator, value_gen33) || !secp256k1_generator_parse(ctx, &blind_generator, blind_gen33)) {
1689 secp256k1_generator_load(&value_ge, &value_generator);
1690 secp256k1_generator_load(&blind_ge, &blind_generator);
1691 secp256k1_ecmult_const(&blind_part, &blind_ge, &blind_scalar);
1692 secp256k1_ecmult_const(&value_part, &value_ge, &value_scalar);
1693 secp256k1_gej_add_var(&total, &blind_part, &value_part, NULL);
1694 if (!secp256k1_gej_is_infinity(&total)) {
1695 secp256k1_ge_set_gej(&commit_ge, &total);
1703 const unsigned char rho32[32],
const unsigned char* generators33,
1704 size_t generators_count,
const unsigned char* n_vec32,
size_t n_vec_len,
1705 const unsigned char* l_vec32,
size_t l_vec_len,
1706 const unsigned char* c_vec32,
size_t c_vec_len,
1707 unsigned char commitment_out33[33]) {
1709 secp256k1_scratch_space* scratch = resources != NULL ? resources->
scratch : NULL;
1710 secp256k1_bppp_generators* gens = resources != NULL ? resources->
gens : NULL;
1711 secp256k1_scalar rho, mu;
1712 secp256k1_scalar *n_vec = NULL, *l_vec = NULL, *c_vec = NULL;
1713 secp256k1_ge commit;
1714 size_t expected_generators = 0;
1715 size_t serialized_generators_len = 0;
1718 if (ctx == NULL || rho32 == NULL || (resources == NULL && generators33 == NULL) || n_vec32 == NULL || l_vec32 == NULL || c_vec32 == NULL ||
1719 commitment_out33 == NULL) {
1722 if (n_vec_len == 0 || l_vec_len == 0 || c_vec_len == 0 || l_vec_len != c_vec_len) {
1725 if (!secp256k1_is_power_of_two(n_vec_len) || !secp256k1_is_power_of_two(c_vec_len) ||
1727 generators_count != expected_generators ||
1731 if (resources != NULL && resources->
generators_count != generators_count) {
1737 if (resources == NULL) {
1738 scratch = secp256k1_scratch_space_create(ctx, 1u << 24);
1739 gens = secp256k1_bppp_generators_parse(ctx, generators33, serialized_generators_len);
1744 if (scratch == NULL || gens == NULL || n_vec == NULL || l_vec == NULL || c_vec == NULL) {
1752 secp256k1_scalar_sqr(&mu, &rho);
1753 if (!secp256k1_bppp_commit(ctx, scratch, &commit, gens, n_vec, n_vec_len, l_vec, l_vec_len, c_vec, c_vec_len, &mu)) {
1759 if (n_vec != NULL) free(n_vec);
1760 if (l_vec != NULL) free(l_vec);
1761 if (c_vec != NULL) free(c_vec);
1762 if (resources == NULL) {
1763 if (gens != NULL) secp256k1_bppp_generators_destroy(ctx, gens);
1764 if (scratch != NULL) secp256k1_scratch_space_destroy(ctx, scratch);
1770 const unsigned char rho32[32],
const unsigned char* generators33,
size_t generators_count,
1771 const unsigned char* n_vec32,
size_t n_vec_len,
const unsigned char* l_vec32,
1772 size_t l_vec_len,
const unsigned char* c_vec32,
size_t c_vec_len,
1773 unsigned char commitment_out33[33]) {
1775 l_vec32, l_vec_len, c_vec32, c_vec_len, commitment_out33);
1779 const unsigned char rho32[32],
1780 const unsigned char* n_vec32,
size_t n_vec_len,
1781 const unsigned char* l_vec32,
size_t l_vec_len,
1782 const unsigned char* c_vec32,
size_t c_vec_len,
1783 unsigned char commitment_out33[33]) {
1786 n_vec32, n_vec_len, l_vec32, l_vec_len, c_vec32, c_vec_len,
1792 const unsigned char* generators33,
size_t generators_count,
1793 const unsigned char* n_vec32,
size_t n_vec_len,
1794 const unsigned char* l_vec32,
size_t l_vec_len,
1795 unsigned char commitment_out33[33]) {
1797 secp256k1_scratch_space* scratch = resources != NULL ? resources->
scratch : NULL;
1798 secp256k1_bppp_generators* gens = resources != NULL ? resources->
gens : NULL;
1799 secp256k1_scalar zero;
1800 secp256k1_scalar *n_vec = NULL, *l_vec = NULL;
1801 secp256k1_ge commit;
1802 secp256k1_gej commitj;
1803 ecmult_bp_commit_cb_data data;
1804 size_t expected_generators = 0;
1805 size_t serialized_generators_len = 0;
1808 if (ctx == NULL || (resources == NULL && generators33 == NULL) || n_vec32 == NULL || l_vec32 == NULL || commitment_out33 == NULL) {
1811 if (n_vec_len == 0 || l_vec_len == 0 ||
1813 generators_count != expected_generators ||
1817 if (resources != NULL && resources->
generators_count != generators_count) {
1821 if (resources == NULL) {
1822 scratch = secp256k1_scratch_space_create(ctx, 1u << 24);
1823 gens = secp256k1_bppp_generators_parse(ctx, generators33, serialized_generators_len);
1827 if (scratch == NULL || gens == NULL || n_vec == NULL || l_vec == NULL) {
1835 secp256k1_scalar_set_int(&zero, 0);
1836 data.g = gens->gens;
1839 data.g_len = n_vec_len;
1840 if (!secp256k1_ecmult_multi_var(&ctx->error_callback, scratch, &commitj, &zero, ecmult_bp_commit_cb,
1841 (
void*)&data, expected_generators)) {
1844 if (secp256k1_gej_is_infinity(&commitj)) {
1847 secp256k1_ge_set_gej_var(&commit, &commitj);
1851 if (n_vec != NULL) free(n_vec);
1852 if (l_vec != NULL) free(l_vec);
1853 if (resources == NULL) {
1854 if (gens != NULL) secp256k1_bppp_generators_destroy(ctx, gens);
1855 if (scratch != NULL) secp256k1_scratch_space_destroy(ctx, scratch);
1861 const unsigned char* generators33,
size_t generators_count,
1862 const unsigned char* n_vec32,
size_t n_vec_len,
const unsigned char* l_vec32,
1863 size_t l_vec_len,
unsigned char commitment_out33[33]) {
1865 n_vec32, n_vec_len, l_vec32, l_vec_len, commitment_out33);
1869 const unsigned char* n_vec32,
size_t n_vec_len,
1870 const unsigned char* l_vec32,
size_t l_vec_len,
1871 unsigned char commitment_out33[33]) {
1874 n_vec32, n_vec_len, l_vec32, l_vec_len, commitment_out33);
1878 const unsigned char commitment33[33],
const unsigned char scalar32[32],
1879 unsigned char commitment_out33[33]) {
1881 secp256k1_scalar scalar;
1882 secp256k1_ge commitment_ge, result_ge;
1883 secp256k1_gej commitment_j, offset_j, result_j;
1886 if (ctx == NULL || commitment33 == NULL || scalar32 == NULL || commitment_out33 == NULL) {
1894 secp256k1_gej_set_ge(&commitment_j, &commitment_ge);
1895 secp256k1_ecmult_const(&offset_j, &secp256k1_ge_const_g, &scalar);
1896 secp256k1_gej_add_var(&result_j, &commitment_j, &offset_j, NULL);
1897 if (!secp256k1_gej_is_infinity(&result_j)) {
1898 secp256k1_ge_set_gej(&result_ge, &result_j);
1905 const unsigned char point33[33],
const unsigned char scalar32[32],
1906 unsigned char out33[33]) {
1908 secp256k1_scalar scalar;
1909 secp256k1_ge point_ge, result_ge;
1910 secp256k1_gej result_j;
1913 if (ctx == NULL || point33 == NULL || scalar32 == NULL || out33 == NULL) {
1921 secp256k1_ecmult_const(&result_j, &point_ge, &scalar);
1922 if (!secp256k1_gej_is_infinity(&result_j)) {
1923 secp256k1_ge_set_gej(&result_ge, &result_j);
1930 const unsigned char lhs33[33],
const unsigned char rhs33[33],
1931 unsigned char out33[33]) {
1933 secp256k1_ge lhs_ge, rhs_ge, result_ge;
1934 secp256k1_gej lhs_j, result_j;
1937 if (ctx == NULL || lhs33 == NULL || rhs33 == NULL || out33 == NULL) {
1945 secp256k1_gej_set_ge(&lhs_j, &lhs_ge);
1946 secp256k1_gej_add_ge_var(&result_j, &lhs_j, &rhs_ge, NULL);
1947 if (!secp256k1_gej_is_infinity(&result_j)) {
1948 secp256k1_ge_set_gej(&result_ge, &result_j);
1956 const unsigned char rho32[32],
const unsigned char* generators33,
1957 size_t generators_count,
const unsigned char* n_vec32,
size_t n_vec_len,
1958 const unsigned char* l_vec32,
size_t l_vec_len,
1959 const unsigned char* c_vec32,
size_t c_vec_len,
1960 unsigned char commitment_out33[33],
unsigned char* proof_out,
1961 size_t* proof_len) {
1963 secp256k1_scratch_space* scratch = resources != NULL ? resources->
scratch : NULL;
1964 secp256k1_bppp_generators* gens = NULL;
1965 secp256k1_scalar rho, mu;
1966 secp256k1_scalar *n_vec = NULL, *l_vec = NULL, *c_vec = NULL;
1967 secp256k1_ge commit;
1968 secp256k1_sha256 transcript;
1970 size_t expected_generators = 0;
1971 size_t serialized_generators_len = 0;
1975 if (ctx == NULL || rho32 == NULL || (resources == NULL && generators33 == NULL) || n_vec32 == NULL || l_vec32 == NULL || c_vec32 == NULL ||
1976 commitment_out33 == NULL || proof_out == NULL || proof_len == NULL) {
1979 if (n_vec_len == 0 || l_vec_len == 0 || c_vec_len == 0 || l_vec_len != c_vec_len ||
1980 n_vec_len < c_vec_len) {
1983 if (!secp256k1_is_power_of_two(n_vec_len) || !secp256k1_is_power_of_two(c_vec_len) ||
1985 generators_count != expected_generators ||
1989 if (resources != NULL && resources->
generators_count != generators_count) {
1992 if (*proof_len < required) {
1993 *proof_len = required;
1999 if (resources != NULL) {
2005 scratch = secp256k1_scratch_space_create(ctx, 1u << 24);
2006 gens = secp256k1_bppp_generators_parse(ctx, generators33, serialized_generators_len);
2011 if (scratch == NULL || gens == NULL || n_vec == NULL || l_vec == NULL || c_vec == NULL) {
2019 secp256k1_scalar_sqr(&mu, &rho);
2020 if (!secp256k1_bppp_commit(ctx, scratch, &commit, gens, n_vec, n_vec_len, l_vec, l_vec_len, c_vec, c_vec_len, &mu)) {
2030 gens->gens, gens->n, n_vec, n_vec_len, l_vec, l_vec_len, c_vec, c_vec_len);
2033 if (n_vec != NULL) free(n_vec);
2034 if (l_vec != NULL) free(l_vec);
2035 if (c_vec != NULL) free(c_vec);
2037 if (resources == NULL) {
2038 if (gens != NULL) secp256k1_bppp_generators_destroy(ctx, gens);
2039 if (scratch != NULL) secp256k1_scratch_space_destroy(ctx, scratch);
2045 const unsigned char rho32[32],
const unsigned char* generators33,
size_t generators_count,
2046 const unsigned char* n_vec32,
size_t n_vec_len,
const unsigned char* l_vec32,
2047 size_t l_vec_len,
const unsigned char* c_vec32,
size_t c_vec_len,
2048 unsigned char commitment_out33[33],
unsigned char* proof_out,
size_t* proof_len) {
2050 l_vec32, l_vec_len, c_vec32, c_vec_len, commitment_out33,
2051 proof_out, proof_len);
2055 const unsigned char rho32[32],
2056 const unsigned char* n_vec32,
size_t n_vec_len,
2057 const unsigned char* l_vec32,
size_t l_vec_len,
2058 const unsigned char* c_vec32,
size_t c_vec_len,
2059 unsigned char commitment_out33[33],
unsigned char* proof_out,
2060 size_t* proof_len) {
2063 n_vec32, n_vec_len, l_vec32, l_vec_len, c_vec32, c_vec_len,
2064 commitment_out33, proof_out, proof_len);
2069 const unsigned char rho32[32],
const unsigned char* generators33,
2070 size_t generators_count,
const unsigned char* n_vec32,
2071 size_t n_vec_len,
const unsigned char* l_vec32,
2072 size_t l_vec_len,
const unsigned char* c_vec32,
2073 size_t c_vec_len,
const unsigned char commitment33[33],
2074 unsigned char* proof_out,
size_t* proof_len) {
2076 secp256k1_scratch_space* scratch = resources != NULL ? resources->
scratch : NULL;
2077 secp256k1_bppp_generators* gens = NULL;
2078 secp256k1_scalar rho, mu;
2079 secp256k1_scalar *n_vec = NULL, *l_vec = NULL, *c_vec = NULL;
2080 secp256k1_ge expected_commit, commitment_ge;
2081 secp256k1_sha256 transcript;
2082 unsigned char expected_commitment33[33];
2084 size_t expected_generators = 0;
2085 size_t serialized_generators_len = 0;
2089 memset(expected_commitment33, 0,
sizeof(expected_commitment33));
2090 if (ctx == NULL || rho32 == NULL || (resources == NULL && generators33 == NULL) || n_vec32 == NULL || l_vec32 == NULL || c_vec32 == NULL ||
2091 commitment33 == NULL || proof_out == NULL || proof_len == NULL) {
2094 if (n_vec_len == 0 || l_vec_len == 0 || c_vec_len == 0 || l_vec_len != c_vec_len ||
2095 n_vec_len < c_vec_len) {
2098 if (!secp256k1_is_power_of_two(n_vec_len) || !secp256k1_is_power_of_two(c_vec_len) ||
2100 generators_count != expected_generators ||
2104 if (resources != NULL && resources->
generators_count != generators_count) {
2107 if (*proof_len < required) {
2108 *proof_len = required;
2114 if (resources != NULL) {
2120 scratch = secp256k1_scratch_space_create(ctx, 1u << 24);
2121 gens = secp256k1_bppp_generators_parse(ctx, generators33, serialized_generators_len);
2126 if (scratch == NULL || gens == NULL || n_vec == NULL || l_vec == NULL || c_vec == NULL) {
2134 secp256k1_scalar_sqr(&mu, &rho);
2135 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)) {
2141 if (secp256k1_memcmp_var(expected_commitment33, commitment33,
sizeof(expected_commitment33)) != 0) {
2148 gens->gens, gens->n, n_vec, n_vec_len, l_vec, l_vec_len, c_vec, c_vec_len);
2151 if (n_vec != NULL) free(n_vec);
2152 if (l_vec != NULL) free(l_vec);
2153 if (c_vec != NULL) free(c_vec);
2155 if (resources == NULL) {
2156 if (gens != NULL) secp256k1_bppp_generators_destroy(ctx, gens);
2157 if (scratch != NULL) secp256k1_scratch_space_destroy(ctx, scratch);
2163 const unsigned char rho32[32],
const unsigned char* generators33,
size_t generators_count,
2164 const unsigned char* n_vec32,
size_t n_vec_len,
const unsigned char* l_vec32,
2165 size_t l_vec_len,
const unsigned char* c_vec32,
size_t c_vec_len,
2166 const unsigned char commitment33[33],
unsigned char* proof_out,
size_t* proof_len) {
2168 n_vec32, n_vec_len, l_vec32, l_vec_len, c_vec32, c_vec_len,
2169 commitment33, proof_out, proof_len);
2173 const unsigned char rho32[32],
2174 const unsigned char* n_vec32,
size_t n_vec_len,
2175 const unsigned char* l_vec32,
size_t l_vec_len,
2176 const unsigned char* c_vec32,
size_t c_vec_len,
2177 const unsigned char commitment33[33],
2178 unsigned char* proof_out,
size_t* proof_len) {
2181 n_vec32, n_vec_len, l_vec32, l_vec_len, c_vec32, c_vec_len,
2182 commitment33, proof_out, proof_len);
2187 const unsigned char rho32[32],
const unsigned char* generators33,
2188 size_t generators_count,
const unsigned char* c_vec32,
size_t c_vec_len,
2189 size_t n_vec_len,
const unsigned char commitment33[33],
2190 const unsigned char* proof,
size_t proof_len) {
2192 secp256k1_scratch_space* scratch = resources != NULL ? resources->
scratch : NULL;
2193 secp256k1_bppp_generators* gens = resources != NULL ? resources->
gens : NULL;
2194 secp256k1_scalar rho, *c_vec = NULL;
2195 secp256k1_ge commit;
2196 secp256k1_sha256 transcript;
2197 size_t expected_generators = 0;
2198 size_t serialized_generators_len = 0;
2201 if (ctx == NULL || rho32 == NULL || (resources == NULL && generators33 == NULL) || c_vec32 == NULL || commitment33 == NULL || proof == NULL) {
2206 if (n_vec_len == 0 || c_vec_len == 0 || n_vec_len < c_vec_len ||
2208 generators_count != expected_generators ||
2212 if (!secp256k1_is_power_of_two(n_vec_len) || !secp256k1_is_power_of_two(c_vec_len)) {
2215 if (resources != NULL && resources->
generators_count != generators_count) {
2218 if (!
purify_parse_scalar(rho32, &rho, 1) || !secp256k1_ge_parse_ext(&commit, commitment33)) {
2221 if (resources == NULL) {
2222 scratch = secp256k1_scratch_space_create(ctx, 1u << 24);
2223 gens = secp256k1_bppp_generators_parse(ctx, generators33, serialized_generators_len);
2226 if (scratch == NULL || gens == NULL || c_vec == NULL) {
2235 ok = secp256k1_bppp_rangeproof_norm_product_verify(ctx, scratch, proof, proof_len, &transcript, &rho,
2236 gens, n_vec_len, c_vec, c_vec_len, &commit);
2239 if (c_vec != NULL) free(c_vec);
2240 if (resources == NULL) {
2241 if (gens != NULL) secp256k1_bppp_generators_destroy(ctx, gens);
2242 if (scratch != NULL) secp256k1_scratch_space_destroy(ctx, scratch);
2248 const unsigned char rho32[32],
const unsigned char* generators33,
size_t generators_count,
2249 const unsigned char* c_vec32,
size_t c_vec_len,
size_t n_vec_len,
2250 const unsigned char commitment33[33],
const unsigned char* proof,
size_t proof_len) {
2252 c_vec32, c_vec_len, n_vec_len, commitment33, proof, proof_len);
2256 const unsigned char rho32[32],
2257 const unsigned char* c_vec32,
size_t c_vec_len,
size_t n_vec_len,
2258 const unsigned char commitment33[33],
const unsigned char* proof,
2262 c_vec32, c_vec_len, n_vec_len, commitment33, proof, proof_len);
static secp256k1_scalar * purify_scalar_cast(purify_scalar *scalar)
static int purify_bulletproof_add_scratch_frame(size_t *total, size_t bytes, size_t objects)
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 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)
static int purify_bulletproof_circuit_scratch_size(const secp256k1_bulletproof_circuit *circuit, 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)
static int purify_bulletproof_reserve_circuit_scratch(purify_bulletproof_backend_resources *resources, const secp256k1_bulletproof_circuit *circuit)
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.
static const size_t purify_bulletproof_msm_scratch_size
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)
static int 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)
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)
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
static SECP256K1_INLINE size_t secp256k1_floor_lg(size_t n)