norm arg: allow X and R to be the point at infinity
Add test vector
This commit is contained in:
parent
f22834f202
commit
c0de361fc5
@ -300,17 +300,8 @@ static int secp256k1_bppp_rangeproof_norm_product_prove(
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* We only fail here because we cannot serialize points at infinity. */
|
||||
if (secp256k1_gej_is_infinity(&xj) || secp256k1_gej_is_infinity(&rj)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
secp256k1_ge_set_gej_var(&x_ge, &xj);
|
||||
secp256k1_fe_normalize_var(&x_ge.x);
|
||||
secp256k1_fe_normalize_var(&x_ge.y);
|
||||
secp256k1_ge_set_gej_var(&r_ge, &rj);
|
||||
secp256k1_fe_normalize_var(&r_ge.x);
|
||||
secp256k1_fe_normalize_var(&r_ge.y);
|
||||
secp256k1_bppp_serialize_points(&proof[proof_idx], &x_ge, &r_ge);
|
||||
proof_idx += 65;
|
||||
|
||||
@ -379,16 +370,12 @@ static int ec_mult_verify_cb1(secp256k1_scalar *sc, secp256k1_ge *pt, size_t idx
|
||||
}
|
||||
idx -= 1;
|
||||
if (idx % 2 == 0) {
|
||||
unsigned char pk_buf[33];
|
||||
idx /= 2;
|
||||
*sc = data->gammas[idx];
|
||||
pk_buf[0] = 2 | (data->proof[65*idx] >> 1);
|
||||
memcpy(&pk_buf[1], &data->proof[65*idx + 1], 32);
|
||||
if (!secp256k1_eckey_pubkey_parse(pt, pk_buf, sizeof(pk_buf))) {
|
||||
if (!secp256k1_bppp_parse_one_of_points(pt, &data->proof[65*idx], 0)) {
|
||||
return 0;
|
||||
}
|
||||
} else {
|
||||
unsigned char pk_buf[33];
|
||||
secp256k1_scalar neg_one;
|
||||
idx /= 2;
|
||||
secp256k1_scalar_set_int(&neg_one, 1);
|
||||
@ -396,9 +383,7 @@ static int ec_mult_verify_cb1(secp256k1_scalar *sc, secp256k1_ge *pt, size_t idx
|
||||
*sc = data->gammas[idx];
|
||||
secp256k1_scalar_sqr(sc, sc);
|
||||
secp256k1_scalar_add(sc, sc, &neg_one);
|
||||
pk_buf[0] = 2 | data->proof[65*idx];
|
||||
memcpy(&pk_buf[1], &data->proof[65*idx + 33], 32);
|
||||
if (!secp256k1_eckey_pubkey_parse(pt, pk_buf, sizeof(pk_buf))) {
|
||||
if (!secp256k1_bppp_parse_one_of_points(pt, &data->proof[65*idx], 1)) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
@ -15,10 +15,33 @@
|
||||
/* Outputs a pair of points, amortizing the parity byte between them
|
||||
* Assumes both points' coordinates have been normalized.
|
||||
*/
|
||||
static void secp256k1_bppp_serialize_points(unsigned char *output, const secp256k1_ge *lpt, const secp256k1_ge *rpt) {
|
||||
output[0] = (secp256k1_fe_is_odd(&lpt->y) << 1) + secp256k1_fe_is_odd(&rpt->y);
|
||||
secp256k1_fe_get_b32(&output[1], &lpt->x);
|
||||
secp256k1_fe_get_b32(&output[33], &rpt->x);
|
||||
static void secp256k1_bppp_serialize_points(unsigned char *output, secp256k1_ge *lpt, secp256k1_ge *rpt) {
|
||||
unsigned char tmp[33];
|
||||
secp256k1_ge_serialize_ext(tmp, lpt);
|
||||
output[0] = (tmp[0] & 1) << 1;
|
||||
memcpy(&output[1], &tmp[1], 32);
|
||||
secp256k1_ge_serialize_ext(tmp, rpt);
|
||||
output[0] |= (tmp[0] & 1);
|
||||
memcpy(&output[33], &tmp[1], 32);
|
||||
}
|
||||
|
||||
static int secp256k1_bppp_parse_one_of_points(secp256k1_ge *pt, const unsigned char *in65, int idx) {
|
||||
unsigned char tmp[33] = { 0 };
|
||||
if (in65[0] > 3) {
|
||||
return 0;
|
||||
}
|
||||
/* Check if the input array encodes the point at infinity */
|
||||
if ((secp256k1_memcmp_var(tmp, &in65[1 + 32*idx], 32)) != 0) {
|
||||
tmp[0] = 2 | ((in65[0] & (2 - idx)) >> (1 - idx));
|
||||
memcpy(&tmp[1], &in65[1 + 32*idx], 32);
|
||||
} else {
|
||||
/* If we're parsing the point at infinity, enforce that the sign bit is
|
||||
* 0. */
|
||||
if ((in65[0] & (2 - idx)) != 0) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return secp256k1_ge_parse_ext(pt, tmp);
|
||||
}
|
||||
|
||||
/* Outputs a serialized point in compressed form. Returns 0 at point at infinity.
|
||||
|
@ -69,4 +69,11 @@ static secp256k1_scalar verify_vector_9_c_vec[1];
|
||||
static const unsigned char verify_vector_9_r32[32] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xBA, 0xAE, 0xDC, 0xE6, 0xAF, 0x48, 0xA0, 0x3B, 0xBF, 0xD2, 0x5E, 0x8C, 0xD0, 0x36, 0x41, 0x34 };
|
||||
static const unsigned char verify_vector_9_proof[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
|
||||
static const int verify_vector_9_result = 1;
|
||||
static const unsigned char verify_vector_10_commit33[33] = { 0x03, 0x62, 0x8A, 0xC2, 0xF1, 0xF2, 0x00, 0xE0, 0x81, 0xBD, 0xA0, 0xA9, 0x6D, 0x25, 0x53, 0xB4, 0x17, 0xC1, 0x02, 0x93, 0x50, 0x3E, 0x91, 0xD4, 0xD1, 0x3A, 0x82, 0x89, 0x02, 0x24, 0x78, 0x49, 0xA5 };
|
||||
static const size_t verify_vector_10_n_vec_len = 2;
|
||||
static const unsigned char verify_vector_10_c_vec32[1][32] = { { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xBA, 0xAE, 0xDC, 0xE6, 0xAF, 0x48, 0xA0, 0x3B, 0xBF, 0xD2, 0x5E, 0x8C, 0xD0, 0x36, 0x41, 0x3C } };
|
||||
static secp256k1_scalar verify_vector_10_c_vec[1];
|
||||
static const unsigned char verify_vector_10_r32[32] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xBA, 0xAE, 0xDC, 0xE6, 0xAF, 0x48, 0xA0, 0x3B, 0xBF, 0xD2, 0x5E, 0x8C, 0xD0, 0x36, 0x41, 0x34 };
|
||||
static const unsigned char verify_vector_10_proof[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xBA, 0xAE, 0xDC, 0xE6, 0xAF, 0x48, 0xA0, 0x3B, 0xBF, 0xD2, 0x5E, 0x8C, 0xD0, 0x36, 0x41, 0x3A };
|
||||
static const int verify_vector_10_result = 1;
|
||||
|
||||
|
@ -212,6 +212,80 @@ void test_norm_util_helpers(void) {
|
||||
secp256k1_scalar_set_int(&res, 256); CHECK(secp256k1_scalar_eq(&res, &rho_pows[3]));
|
||||
}
|
||||
|
||||
|
||||
void test_serialize_two_points_roundtrip(secp256k1_ge *X, secp256k1_ge *R) {
|
||||
secp256k1_ge X_tmp, R_tmp;
|
||||
unsigned char buf[65];
|
||||
secp256k1_bppp_serialize_points(buf, X, R);
|
||||
CHECK(secp256k1_bppp_parse_one_of_points(&X_tmp, buf, 0));
|
||||
CHECK(secp256k1_bppp_parse_one_of_points(&R_tmp, buf, 1));
|
||||
ge_equals_ge(X, &X_tmp);
|
||||
ge_equals_ge(R, &R_tmp);
|
||||
}
|
||||
|
||||
void test_serialize_two_points(void) {
|
||||
secp256k1_ge X, R;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < count; i++) {
|
||||
random_group_element_test(&X);
|
||||
random_group_element_test(&R);
|
||||
test_serialize_two_points_roundtrip(&X, &R);
|
||||
}
|
||||
|
||||
for (i = 0; i < count; i++) {
|
||||
random_group_element_test(&X);
|
||||
secp256k1_ge_set_infinity(&R);
|
||||
test_serialize_two_points_roundtrip(&X, &R);
|
||||
}
|
||||
|
||||
for (i = 0; i < count; i++) {
|
||||
secp256k1_ge_set_infinity(&X);
|
||||
random_group_element_test(&R);
|
||||
test_serialize_two_points_roundtrip(&X, &R);
|
||||
}
|
||||
|
||||
secp256k1_ge_set_infinity(&X);
|
||||
secp256k1_ge_set_infinity(&R);
|
||||
test_serialize_two_points_roundtrip(&X, &R);
|
||||
|
||||
/* Test invalid sign byte */
|
||||
{
|
||||
secp256k1_ge X_tmp, R_tmp;
|
||||
unsigned char buf[65];
|
||||
random_group_element_test(&X);
|
||||
random_group_element_test(&R);
|
||||
secp256k1_bppp_serialize_points(buf, &X, &R);
|
||||
buf[0] |= 4 + (unsigned char)secp256k1_testrandi64(4, 255);
|
||||
CHECK(!secp256k1_bppp_parse_one_of_points(&X_tmp, buf, 0));
|
||||
CHECK(!secp256k1_bppp_parse_one_of_points(&R_tmp, buf, 0));
|
||||
}
|
||||
/* Check that sign bit is 0 for point at infinity */
|
||||
for (i = 0; i < count; i++) {
|
||||
secp256k1_ge X_tmp, R_tmp;
|
||||
unsigned char buf[65];
|
||||
int expect;
|
||||
random_group_element_test(&X);
|
||||
random_group_element_test(&R);
|
||||
secp256k1_bppp_serialize_points(buf, &X, &R);
|
||||
memset(&buf[1], 0, 32);
|
||||
if ((buf[0] & 2) == 0) {
|
||||
expect = 1;
|
||||
} else {
|
||||
expect = 0;
|
||||
}
|
||||
CHECK(secp256k1_bppp_parse_one_of_points(&X_tmp, buf, 0) == expect);
|
||||
CHECK(secp256k1_bppp_parse_one_of_points(&R_tmp, buf, 1));
|
||||
memset(&buf[33], 0, 32);
|
||||
if ((buf[0] & 1) == 0) {
|
||||
expect = 1;
|
||||
} else {
|
||||
expect = 0;
|
||||
}
|
||||
CHECK(secp256k1_bppp_parse_one_of_points(&R_tmp, buf, 1) == expect);
|
||||
}
|
||||
}
|
||||
|
||||
static void secp256k1_norm_arg_commit_initial_data(
|
||||
secp256k1_sha256* transcript,
|
||||
const secp256k1_scalar* rho,
|
||||
@ -416,7 +490,9 @@ void norm_arg_zero(void) {
|
||||
random_scalar_order(&c_vec[i]);
|
||||
}
|
||||
CHECK(secp256k1_bppp_commit(ctx, scratch, &commit, gs, n_vec, n_vec_len, l_vec, c_vec_len, c_vec, c_vec_len, &mu));
|
||||
CHECK(!secp256k1_norm_arg_prove(scratch, proof, &plen, &rho, gs, n_vec, n_vec_len, l_vec, c_vec_len, c_vec, c_vec_len, &commit));
|
||||
CHECK(secp256k1_norm_arg_prove(scratch, proof, &plen, &rho, gs, n_vec, n_vec_len, l_vec, c_vec_len, c_vec, c_vec_len, &commit));
|
||||
secp256k1_sha256_initialize(&transcript);
|
||||
CHECK(secp256k1_norm_arg_verify(scratch, proof, plen, &rho, gs, n_vec_len, c_vec, c_vec_len, &commit));
|
||||
secp256k1_bppp_generators_destroy(ctx, gs);
|
||||
}
|
||||
|
||||
@ -558,6 +634,7 @@ void norm_arg_verify_vectors(void) {
|
||||
CHECK(IDX_TO_TEST(7));
|
||||
CHECK(IDX_TO_TEST(8));
|
||||
CHECK(IDX_TO_TEST(9));
|
||||
CHECK(IDX_TO_TEST(10));
|
||||
|
||||
CHECK(alloc == scratch->alloc_size);
|
||||
secp256k1_scratch_space_destroy(ctx, scratch);
|
||||
@ -567,6 +644,7 @@ void norm_arg_verify_vectors(void) {
|
||||
void run_bppp_tests(void) {
|
||||
test_log_exp();
|
||||
test_norm_util_helpers();
|
||||
test_serialize_two_points();
|
||||
test_bppp_generators_api();
|
||||
test_bppp_generators_fixed();
|
||||
test_bppp_tagged_hash();
|
||||
|
Loading…
x
Reference in New Issue
Block a user