diff --git a/src/modules/surjection/main_impl.h b/src/modules/surjection/main_impl.h index 1b0e5359..13e8f97e 100644 --- a/src/modules/surjection/main_impl.h +++ b/src/modules/surjection/main_impl.h @@ -55,6 +55,15 @@ int secp256k1_surjectionproof_parse(const secp256k1_context* ctx, secp256k1_surj return 0; } + /* Check that the bitvector of used inputs is of the claimed + * length; i.e. the final byte has no "padding bits" set */ + if (n_inputs % 8 != 0) { + const unsigned char padding_mask = (~0U) << (n_inputs % 8); + if ((input[2 + (n_inputs + 7) / 8 - 1] & padding_mask) != 0) { + return 0; + } + } + signature_len = 32 * (1 + secp256k1_count_bits_set(&input[2], (n_inputs + 7) / 8)); if (inputlen != 2 + (n_inputs + 7) / 8 + signature_len) { return 0; diff --git a/src/modules/surjection/tests_impl.h b/src/modules/surjection/tests_impl.h index c2fc8237..c6f0c64b 100644 --- a/src/modules/surjection/tests_impl.h +++ b/src/modules/surjection/tests_impl.h @@ -644,18 +644,18 @@ void test_fixed_vectors(void) { bad[2] = 0x3f; /* 0x1f -> 0x3f */ CHECK(!secp256k1_surjectionproof_parse(ctx, &proof, bad, total5_used5_len)); /* Correct for the length */ - CHECK(secp256k1_surjectionproof_parse(ctx, &proof, bad, total5_used5_len + 32)); /* FIXME */ + CHECK(!secp256k1_surjectionproof_parse(ctx, &proof, bad, total5_used5_len + 32)); /* Alternately just turn off one of the "legit" bits */ bad[2] = 0x37; /* 0x1f -> 0x37 */ - CHECK(secp256k1_surjectionproof_parse(ctx, &proof, bad, total5_used5_len)); /* FIXME */ + CHECK(!secp256k1_surjectionproof_parse(ctx, &proof, bad, total5_used5_len)); /* Similarly try setting 4 bits on the total5-used-3, with one bit out of range */ memcpy(bad, total5_used3, total5_used3_len); bad[2] = 0x35; /* 0x15 -> 0x35 */ CHECK(!secp256k1_surjectionproof_parse(ctx, &proof, bad, total5_used3_len)); - CHECK(secp256k1_surjectionproof_parse(ctx, &proof, bad, total5_used3_len + 32)); /* FIXME */ + CHECK(!secp256k1_surjectionproof_parse(ctx, &proof, bad, total5_used3_len + 32)); bad[2] = 0x34; /* 0x15 -> 0x34 */ - CHECK(secp256k1_surjectionproof_parse(ctx, &proof, bad, total5_used3_len)); /* FIXME */ + CHECK(!secp256k1_surjectionproof_parse(ctx, &proof, bad, total5_used3_len)); } void run_surjection_tests(void) {