From a118acc02beac099f63f82d1e619c2bf33451b13 Mon Sep 17 00:00:00 2001 From: Andrew Poelstra Date: Tue, 30 Apr 2019 22:46:05 +0000 Subject: [PATCH] surjectionproof: reduce stack usage --- src/modules/surjection/main_impl.h | 22 ++++------------------ src/modules/surjection/surjection_impl.h | 19 +++++++++++-------- src/modules/surjection/tests_impl.h | 4 +--- 3 files changed, 16 insertions(+), 29 deletions(-) diff --git a/src/modules/surjection/main_impl.h b/src/modules/surjection/main_impl.h index 13e8f97e..d08712a0 100644 --- a/src/modules/surjection/main_impl.h +++ b/src/modules/surjection/main_impl.h @@ -272,8 +272,6 @@ int secp256k1_surjectionproof_generate(const secp256k1_context* ctx, secp256k1_s size_t ring_input_index = 0; secp256k1_gej ring_pubkeys[SECP256K1_SURJECTIONPROOF_MAX_N_INPUTS]; secp256k1_scalar borromean_s[SECP256K1_SURJECTIONPROOF_MAX_N_INPUTS]; - secp256k1_ge inputs[SECP256K1_SURJECTIONPROOF_MAX_N_INPUTS]; - secp256k1_ge output; unsigned char msg32[32]; VERIFY_CHECK(ctx != NULL); @@ -312,17 +310,12 @@ int secp256k1_surjectionproof_generate(const secp256k1_context* ctx, secp256k1_s return 0; } - secp256k1_generator_load(&output, ephemeral_output_tag); - for (i = 0; i < n_total_pubkeys; i++) { - secp256k1_generator_load(&inputs[i], &ephemeral_input_tags[i]); - } - - secp256k1_surjection_compute_public_keys(ring_pubkeys, n_used_pubkeys, inputs, n_total_pubkeys, proof->used_inputs, &output, input_index, &ring_input_index); + secp256k1_surjection_compute_public_keys(ring_pubkeys, n_used_pubkeys, ephemeral_input_tags, n_total_pubkeys, proof->used_inputs, ephemeral_output_tag, input_index, &ring_input_index); /* Produce signature */ rsizes[0] = (int) n_used_pubkeys; indices[0] = (int) ring_input_index; - secp256k1_surjection_genmessage(msg32, inputs, n_total_pubkeys, &output); + secp256k1_surjection_genmessage(msg32, ephemeral_input_tags, n_total_pubkeys, ephemeral_output_tag); if (secp256k1_surjection_genrand(borromean_s, n_used_pubkeys, &blinding_key) == 0) { return 0; } @@ -347,8 +340,6 @@ int secp256k1_surjectionproof_verify(const secp256k1_context* ctx, const secp256 size_t n_used_pubkeys; secp256k1_gej ring_pubkeys[SECP256K1_SURJECTIONPROOF_MAX_N_INPUTS]; secp256k1_scalar borromean_s[SECP256K1_SURJECTIONPROOF_MAX_N_INPUTS]; - secp256k1_ge inputs[SECP256K1_SURJECTIONPROOF_MAX_N_INPUTS]; - secp256k1_ge output; unsigned char msg32[32]; VERIFY_CHECK(ctx != NULL); @@ -364,12 +355,7 @@ int secp256k1_surjectionproof_verify(const secp256k1_context* ctx, const secp256 return 0; } - secp256k1_generator_load(&output, ephemeral_output_tag); - for (i = 0; i < n_total_pubkeys; i++) { - secp256k1_generator_load(&inputs[i], &ephemeral_input_tags[i]); - } - - if (secp256k1_surjection_compute_public_keys(ring_pubkeys, n_used_pubkeys, inputs, n_total_pubkeys, proof->used_inputs, &output, 0, NULL) == 0) { + if (secp256k1_surjection_compute_public_keys(ring_pubkeys, n_used_pubkeys, ephemeral_input_tags, n_total_pubkeys, proof->used_inputs, ephemeral_output_tag, 0, NULL) == 0) { return 0; } @@ -382,7 +368,7 @@ int secp256k1_surjectionproof_verify(const secp256k1_context* ctx, const secp256 return 0; } } - secp256k1_surjection_genmessage(msg32, inputs, n_total_pubkeys, &output); + secp256k1_surjection_genmessage(msg32, ephemeral_input_tags, n_total_pubkeys, ephemeral_output_tag); return secp256k1_borromean_verify(&ctx->ecmult_ctx, NULL, &proof->data[0], borromean_s, ring_pubkeys, rsizes, 1, msg32, 32); } diff --git a/src/modules/surjection/surjection_impl.h b/src/modules/surjection/surjection_impl.h index f58026de..c90c5767 100644 --- a/src/modules/surjection/surjection_impl.h +++ b/src/modules/surjection/surjection_impl.h @@ -15,7 +15,7 @@ #include "scalar.h" #include "hash.h" -SECP256K1_INLINE static void secp256k1_surjection_genmessage(unsigned char *msg32, secp256k1_ge *ephemeral_input_tags, size_t n_input_tags, secp256k1_ge *ephemeral_output_tag) { +SECP256K1_INLINE static void secp256k1_surjection_genmessage(unsigned char *msg32, const secp256k1_generator *ephemeral_input_tags, size_t n_input_tags, const secp256k1_generator *ephemeral_output_tag) { /* compute message */ size_t i; unsigned char pk_ser[33]; @@ -24,12 +24,12 @@ SECP256K1_INLINE static void secp256k1_surjection_genmessage(unsigned char *msg3 secp256k1_sha256_initialize(&sha256_en); for (i = 0; i < n_input_tags; i++) { - secp256k1_eckey_pubkey_serialize(&ephemeral_input_tags[i], pk_ser, &pk_len, 1); - assert(pk_len == sizeof(pk_ser)); + pk_ser[0] = 2 + (ephemeral_input_tags[i].data[63] & 1); + memcpy(&pk_ser[1], &ephemeral_input_tags[i].data[0], 32); secp256k1_sha256_write(&sha256_en, pk_ser, pk_len); } - secp256k1_eckey_pubkey_serialize(ephemeral_output_tag, pk_ser, &pk_len, 1); - assert(pk_len == sizeof(pk_ser)); + pk_ser[0] = 2 + (ephemeral_output_tag->data[63] & 1); + memcpy(&pk_ser[1], &ephemeral_output_tag->data[0], 32); secp256k1_sha256_write(&sha256_en, pk_ser, pk_len); secp256k1_sha256_finalize(&sha256_en, msg32); } @@ -61,15 +61,18 @@ SECP256K1_INLINE static int secp256k1_surjection_genrand(secp256k1_scalar *s, si return 1; } -SECP256K1_INLINE static int secp256k1_surjection_compute_public_keys(secp256k1_gej *pubkeys, size_t n_pubkeys, const secp256k1_ge *input_tags, size_t n_input_tags, const unsigned char *used_tags, const secp256k1_ge *output_tag, size_t input_index, size_t *ring_input_index) { +SECP256K1_INLINE static int secp256k1_surjection_compute_public_keys(secp256k1_gej *pubkeys, size_t n_pubkeys, const secp256k1_generator *input_tags, size_t n_input_tags, const unsigned char *used_tags, const secp256k1_generator *output_tag, size_t input_index, size_t *ring_input_index) { size_t i; size_t j = 0; for (i = 0; i < n_input_tags; i++) { if (used_tags[i / 8] & (1 << (i % 8))) { secp256k1_ge tmpge; - secp256k1_ge_neg(&tmpge, &input_tags[i]); + secp256k1_generator_load(&tmpge, &input_tags[i]); + secp256k1_ge_neg(&tmpge, &tmpge); secp256k1_gej_set_ge(&pubkeys[j], &tmpge); - secp256k1_gej_add_ge_var(&pubkeys[j], &pubkeys[j], output_tag, NULL); + + secp256k1_generator_load(&tmpge, output_tag); + secp256k1_gej_add_ge_var(&pubkeys[j], &pubkeys[j], &tmpge, NULL); if (ring_input_index != NULL && input_index == i) { *ring_input_index = j; } diff --git a/src/modules/surjection/tests_impl.h b/src/modules/surjection/tests_impl.h index c6f0c64b..49f36847 100644 --- a/src/modules/surjection/tests_impl.h +++ b/src/modules/surjection/tests_impl.h @@ -456,7 +456,6 @@ static void test_no_used_inputs_verify(void) { size_t n_ephemeral_input_tags = 1; secp256k1_generator ephemeral_output_tag; unsigned char blinding_key[32]; - secp256k1_ge inputs[1]; secp256k1_ge output; secp256k1_sha256 sha256_e0; int result; @@ -477,8 +476,7 @@ static void test_no_used_inputs_verify(void) { /* create "borromean signature" which is just a hash of metadata (pubkeys, etc) in this case */ secp256k1_generator_load(&output, &ephemeral_output_tag); - secp256k1_generator_load(&inputs[0], &ephemeral_input_tags[0]); - secp256k1_surjection_genmessage(proof.data, inputs, 1, &output); + secp256k1_surjection_genmessage(proof.data, ephemeral_input_tags, 1, &ephemeral_output_tag); secp256k1_sha256_initialize(&sha256_e0); secp256k1_sha256_write(&sha256_e0, proof.data, 32); secp256k1_sha256_finalize(&sha256_e0, proof.data);