norm arg: allow X and R to be the point at infinity

Add test vector
This commit is contained in:
Jonas Nick
2023-03-01 12:51:15 +00:00
parent f22834f202
commit c0de361fc5
4 changed files with 115 additions and 22 deletions

View File

@@ -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.