From 5e7c2c178dc22779ad0f23d39aea39fba0746687 Mon Sep 17 00:00:00 2001 From: Andrew Poelstra Date: Fri, 10 May 2024 13:25:56 +0000 Subject: [PATCH 1/2] generator: massively speed up serialization `secp256k1_pedersen_commit_serialize` would call `_load` (which does a sqrt to fully decompress the key, then a conditional negation based on the flag), then check the Jacobian symbol of the resulting y-coordinate, then re-serialize based on this. Instead, don't do any of this stuff. Copy the flag directly out of the internal representation and copy the x-coordinate directly out of the internal representation. Checked that none of the other _serialize methods in the modules do this. Fixes #293 --- src/modules/generator/main_impl.h | 8 +------- src/modules/generator/tests_impl.h | 6 ++++++ 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/modules/generator/main_impl.h b/src/modules/generator/main_impl.h index f1cd07797..c20d4cc33 100644 --- a/src/modules/generator/main_impl.h +++ b/src/modules/generator/main_impl.h @@ -296,17 +296,11 @@ int secp256k1_pedersen_commitment_parse(const secp256k1_context* ctx, secp256k1_ } int secp256k1_pedersen_commitment_serialize(const secp256k1_context* ctx, unsigned char *output, const secp256k1_pedersen_commitment* commit) { - secp256k1_ge ge; - VERIFY_CHECK(ctx != NULL); ARG_CHECK(output != NULL); ARG_CHECK(commit != NULL); - secp256k1_pedersen_commitment_load(&ge, commit); - - output[0] = 9 ^ secp256k1_fe_is_square_var(&ge.y); - secp256k1_fe_normalize_var(&ge.x); - secp256k1_fe_get_b32(&output[1], &ge.x); + memcpy(output, commit->data, 33); return 1; } diff --git a/src/modules/generator/tests_impl.h b/src/modules/generator/tests_impl.h index 14a993b93..f5a34bc65 100644 --- a/src/modules/generator/tests_impl.h +++ b/src/modules/generator/tests_impl.h @@ -264,7 +264,13 @@ static void test_pedersen(void) { } CHECK(secp256k1_pedersen_blind_sum(CTX, &blinds[(total - 1) * 32], bptr, total - 1, inputs)); for (i = 0; i < total; i++) { + unsigned char result[33]; + secp256k1_pedersen_commitment parse; + CHECK(secp256k1_pedersen_commit(CTX, &commits[i], &blinds[i * 32], values[i], secp256k1_generator_h)); + CHECK(secp256k1_pedersen_commitment_serialize(CTX, result, &commits[i])); + CHECK(secp256k1_pedersen_commitment_parse(CTX, &parse, result)); + CHECK(secp256k1_memcmp_var(&commits[i], &parse, 33) == 0); } CHECK(secp256k1_pedersen_verify_tally(CTX, cptr, inputs, &cptr[inputs], outputs)); CHECK(secp256k1_pedersen_verify_tally(CTX, &cptr[inputs], outputs, cptr, inputs)); From 6361266013ad14428c89334013c74f8dec6f8e9d Mon Sep 17 00:00:00 2001 From: Andrew Poelstra Date: Thu, 16 May 2024 14:10:52 +0000 Subject: [PATCH 2/2] generator: speed up parsing Similar to speeding up serialization; in our parsing logic we did a bunch of expensive stuff then expensively inverted it. Drop everything except the essential checks and then memcpy. --- src/modules/generator/main_impl.h | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/src/modules/generator/main_impl.h b/src/modules/generator/main_impl.h index c20d4cc33..d3dce9fa8 100644 --- a/src/modules/generator/main_impl.h +++ b/src/modules/generator/main_impl.h @@ -276,7 +276,6 @@ static void secp256k1_pedersen_commitment_save(secp256k1_pedersen_commitment* co int secp256k1_pedersen_commitment_parse(const secp256k1_context* ctx, secp256k1_pedersen_commitment* commit, const unsigned char *input) { secp256k1_fe x; - secp256k1_ge ge; VERIFY_CHECK(ctx != NULL); ARG_CHECK(commit != NULL); @@ -285,13 +284,11 @@ int secp256k1_pedersen_commitment_parse(const secp256k1_context* ctx, secp256k1_ if ((input[0] & 0xFE) != 8 || !secp256k1_fe_set_b32_limit(&x, &input[1]) || - !secp256k1_ge_set_xquad(&ge, &x)) { + !secp256k1_ge_x_on_curve_var(&x)) { return 0; } - if (input[0] & 1) { - secp256k1_ge_neg(&ge, &ge); - } - secp256k1_pedersen_commitment_save(commit, &ge); + + memcpy(commit->data, input, 33); return 1; }