shallue_van_de_woestijne rewrite
The previous implementation returns an off-curve point for the input t=0. This rewrite addresses that issue by implicity returning the on-curve point (d, sqrt(1 + b)), which is the point that the paper Indifferentiable Hashing to Barreto–Naehrig Curves suggests returning in this case. Note: At the moment it is cryptographically impossible for the input t to be 0.
This commit is contained in:
parent
eb4fb6db05
commit
5d87e80c69
@ -107,61 +107,50 @@ static void shallue_van_de_woestijne(secp256k1_ge* ge, const secp256k1_fe* t) {
|
||||
x2 = -(x1 + 1)
|
||||
x3 = 1 + 1/w^2
|
||||
|
||||
To avoid the 2 divisions, compute the above in numerator/denominator form:
|
||||
wn = c * t
|
||||
wd = 1 + 7 + t^2
|
||||
x1n = d*wd - t*wn
|
||||
x1d = wd
|
||||
x2n = -(x1n + wd)
|
||||
x2d = wd
|
||||
x3n = wd^2 + c^2 * t^2
|
||||
x3d = (c * t)^2
|
||||
To avoid the 2 divisions, compute the joint denominator j = wd * x3d, where
|
||||
wd = 1 + b + t^2
|
||||
x3d = c^2 * t^2 = -3 * t^2
|
||||
|
||||
The joint denominator j = wd * c^2 * t^2, and
|
||||
1 / x1d = 1/j * c^2 * t^2
|
||||
1 / x2d = x3d = 1/j * wd
|
||||
so that
|
||||
|
||||
1 / wd = 1/j * x3d
|
||||
1 / x3d = 1/j * wd
|
||||
*/
|
||||
|
||||
static const secp256k1_fe c = SECP256K1_FE_CONST(0x0a2d2ba9, 0x3507f1df, 0x233770c2, 0xa797962c, 0xc61f6d15, 0xda14ecd4, 0x7d8d27ae, 0x1cd5f852);
|
||||
static const secp256k1_fe negc = SECP256K1_FE_CONST(0xf5d2d456, 0xcaf80e20, 0xdcc88f3d, 0x586869d3, 0x39e092ea, 0x25eb132b, 0x8272d850, 0xe32a03dd);
|
||||
static const secp256k1_fe d = SECP256K1_FE_CONST(0x851695d4, 0x9a83f8ef, 0x919bb861, 0x53cbcb16, 0x630fb68a, 0xed0a766a, 0x3ec693d6, 0x8e6afa40);
|
||||
static const secp256k1_fe b = SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 7);
|
||||
static const secp256k1_fe b_plus_one = SECP256K1_FE_CONST(0, 0, 0, 0, 0, 0, 0, 8);
|
||||
|
||||
secp256k1_fe wn, wd, x1n, x2n, x3n, x3d, jinv, tmp, x1, x2, x3, alphain, betain, gammain, y1, y2, y3;
|
||||
secp256k1_fe wd, x3d, jinv, tmp, x1, x2, x3, alphain, betain, gammain, y1, y2, y3;
|
||||
int alphaquad, betaquad;
|
||||
|
||||
secp256k1_fe_mul(&wn, &c, t); /* mag 1 */
|
||||
secp256k1_fe_sqr(&wd, t); /* mag 1 */
|
||||
secp256k1_fe_add(&wd, &b_plus_one); /* mag 2 */
|
||||
secp256k1_fe_mul(&tmp, t, &wn); /* mag 1 */
|
||||
secp256k1_fe_negate(&tmp, &tmp, 1); /* mag 2 */
|
||||
secp256k1_fe_mul(&x1n, &d, &wd); /* mag 1 */
|
||||
secp256k1_fe_add(&x1n, &tmp); /* mag 3 */
|
||||
x2n = x1n; /* mag 3 */
|
||||
secp256k1_fe_add(&x2n, &wd); /* mag 5 */
|
||||
secp256k1_fe_negate(&x2n, &x2n, 5); /* mag 6 */
|
||||
secp256k1_fe_mul(&x3d, &c, t); /* mag 1 */
|
||||
secp256k1_fe_sqr(&x3d, &x3d); /* mag 1 */
|
||||
secp256k1_fe_sqr(&x3n, &wd); /* mag 1 */
|
||||
secp256k1_fe_add(&x3n, &x3d); /* mag 2 */
|
||||
secp256k1_fe_mul(&jinv, &x3d, &wd); /* mag 1 */
|
||||
secp256k1_fe_mul(&x1, &negc, &wd); /* mag 1 */
|
||||
x3d = wd; /* mag 1 */
|
||||
secp256k1_fe_mul_int(&x3d, 3); /* mag 3 */
|
||||
secp256k1_fe_negate(&x3d, &x3d, 3); /* mag 4 */
|
||||
secp256k1_fe_add_int(&wd, SECP256K1_B + 1); /* mag 2 */
|
||||
secp256k1_fe_mul(&jinv, &wd, &x3d); /* mag 1 */
|
||||
secp256k1_fe_inv(&jinv, &jinv); /* mag 1 */
|
||||
secp256k1_fe_mul(&x1, &x1n, &x3d); /* mag 1 */
|
||||
secp256k1_fe_mul(&x1, &x1, &x3d); /* mag 1 */
|
||||
secp256k1_fe_mul(&x1, &x1, &jinv); /* mag 1 */
|
||||
secp256k1_fe_mul(&x2, &x2n, &x3d); /* mag 1 */
|
||||
secp256k1_fe_mul(&x2, &x2, &jinv); /* mag 1 */
|
||||
secp256k1_fe_mul(&x3, &x3n, &wd); /* mag 1 */
|
||||
secp256k1_fe_add(&x1, &d); /* mag 2 */
|
||||
x2 = x1; /* mag 2 */
|
||||
secp256k1_fe_add_int(&x2, 1); /* mag 3 */
|
||||
secp256k1_fe_negate(&x2, &x2, 3); /* mag 4 */
|
||||
secp256k1_fe_sqr(&x3, &wd); /* mag 1 */
|
||||
secp256k1_fe_mul(&x3, &x3, &wd); /* mag 1 */
|
||||
secp256k1_fe_mul(&x3, &x3, &jinv); /* mag 1 */
|
||||
secp256k1_fe_add_int(&x3, 1); /* mag 2 */
|
||||
|
||||
secp256k1_fe_sqr(&alphain, &x1); /* mag 1 */
|
||||
secp256k1_fe_mul(&alphain, &alphain, &x1); /* mag 1 */
|
||||
secp256k1_fe_add(&alphain, &b); /* mag 2 */
|
||||
secp256k1_fe_add_int(&alphain, SECP256K1_B); /* mag 2 */
|
||||
secp256k1_fe_sqr(&betain, &x2); /* mag 1 */
|
||||
secp256k1_fe_mul(&betain, &betain, &x2); /* mag 1 */
|
||||
secp256k1_fe_add(&betain, &b); /* mag 2 */
|
||||
secp256k1_fe_add_int(&betain, SECP256K1_B); /* mag 2 */
|
||||
secp256k1_fe_sqr(&gammain, &x3); /* mag 1 */
|
||||
secp256k1_fe_mul(&gammain, &gammain, &x3); /* mag 1 */
|
||||
secp256k1_fe_add(&gammain, &b); /* mag 2 */
|
||||
secp256k1_fe_add_int(&gammain, SECP256K1_B); /* mag 2 */
|
||||
|
||||
alphaquad = secp256k1_fe_sqrt(&y1, &alphain);
|
||||
betaquad = secp256k1_fe_sqrt(&y2, &betain);
|
||||
|
Loading…
x
Reference in New Issue
Block a user