mirror of https://github.com/zcash/pasta.git
Make map_to_curve_simple_swu take a single input again (since we no longer need batch inversion).
Also make it clearer that we don't depend on Sage's elliptic curve impl except for debugging. Signed-off-by: Daira Hopwood <daira@jacaranda.org>
This commit is contained in:
parent
c0f2b2d8b6
commit
fd7283a979
|
@ -93,7 +93,7 @@ def select_z_nz(s, ifz, ifnz):
|
||||||
# This should be constant-time in a real implementation.
|
# This should be constant-time in a real implementation.
|
||||||
return ifz if (s == 0) else ifnz
|
return ifz if (s == 0) else ifnz
|
||||||
|
|
||||||
def map_to_curve_simple_swu(F, E, Z, us, c):
|
def map_to_curve_simple_swu(F, E, Z, u, c):
|
||||||
# would be precomputed
|
# would be precomputed
|
||||||
h = F.g
|
h = F.g
|
||||||
(0, 0, 0, A, B) = E.a_invariants()
|
(0, 0, 0, A, B) = E.a_invariants()
|
||||||
|
@ -103,8 +103,6 @@ def map_to_curve_simple_swu(F, E, Z, us, c):
|
||||||
assert (Z/h).is_square()
|
assert (Z/h).is_square()
|
||||||
theta = sqrt(Z/h)
|
theta = sqrt(Z/h)
|
||||||
|
|
||||||
Qs = []
|
|
||||||
for u in us:
|
|
||||||
# 1. tv1 = inv0(Z^2 * u^4 + Z * u^2)
|
# 1. tv1 = inv0(Z^2 * u^4 + Z * u^2)
|
||||||
# 2. x1 = (-B / A) * (1 + tv1)
|
# 2. x1 = (-B / A) * (1 + tv1)
|
||||||
# 3. If tv1 == 0, set x1 = B / (Z * A)
|
# 3. If tv1 == 0, set x1 = B / (Z * A)
|
||||||
|
@ -177,9 +175,8 @@ def map_to_curve_simple_swu(F, E, Z, us, c):
|
||||||
|
|
||||||
# 9. If sgn0(u) != sgn0(y), set y = -y
|
# 9. If sgn0(u) != sgn0(y), set y = -y
|
||||||
y = select_z_nz((int(u) % 2) - (int(y) % 2), y, -y)
|
y = select_z_nz((int(u) % 2) - (int(y) % 2), y, -y)
|
||||||
Qs.append(E((x, y)))
|
|
||||||
|
|
||||||
return Qs
|
return (x, y)
|
||||||
|
|
||||||
|
|
||||||
# iso_Ep = Isogeny of degree 3 from Elliptic Curve defined by y^2 = x^3 + 10949663248450308183708987909873589833737836120165333298109615750520499732811*x + 1265 over Fp
|
# iso_Ep = Isogeny of degree 3 from Elliptic Curve defined by y^2 = x^3 + 10949663248450308183708987909873589833737836120165333298109615750520499732811*x + 1265 over Fp
|
||||||
|
@ -303,38 +300,43 @@ def hash_to_curve_affine(msg, DST, uniform=True):
|
||||||
c = Cost()
|
c = Cost()
|
||||||
us = hash_to_field(msg, DST, 2 if uniform else 1)
|
us = hash_to_field(msg, DST, 2 if uniform else 1)
|
||||||
#print("u = ", u)
|
#print("u = ", u)
|
||||||
Qs = map_to_curve_simple_swu(F_p, E_isop, Z_isop, us, c)
|
(Q0x, Q0y) = map_to_curve_simple_swu(F_p, E_isop, Z_isop, us[0], c)
|
||||||
|
|
||||||
if uniform:
|
if uniform:
|
||||||
|
(Q1x, Q1y) = map_to_curve_simple_swu(F_p, E_isop, Z_isop, us[1], c)
|
||||||
|
|
||||||
# Complete addition using affine coordinates: I + 2M + 2S
|
# Complete addition using affine coordinates: I + 2M + 2S
|
||||||
# (S for x1^2; compute numerator and denominator of the division for the correct case;
|
# (S for x1^2; compute numerator and denominator of the division for the correct case;
|
||||||
# I + M to divide; S + M to compute x and y of the result.)
|
# I + M to divide; S + M to compute x and y of the result.)
|
||||||
R = Qs[0] + Qs[1]
|
|
||||||
|
# Just use Sage's implementation, since this is mainly for comparison to the Jacobian impl.
|
||||||
|
R = E_isop((Q0x, Q0y)) + E_isop((Q1x, Q1y))
|
||||||
#print("R = ", R)
|
#print("R = ", R)
|
||||||
c.invs += 1
|
c.invs += 1
|
||||||
c.sqrs += 2
|
c.sqrs += 2
|
||||||
c.muls += 2
|
c.muls += 2
|
||||||
|
(Rx, Ry) = R.xy()
|
||||||
else:
|
else:
|
||||||
R = Qs[0]
|
(Rx, Ry) = (Q0x, Q0y)
|
||||||
|
|
||||||
# no cofactor clearing needed since Pallas and Vesta are prime-order
|
# no cofactor clearing needed since Pallas and Vesta are prime-order
|
||||||
(x, y) = R.xy()
|
P = E_p(isop_map_affine(Rx, Ry, c))
|
||||||
P = E_p(isop_map_affine(x, y, c))
|
|
||||||
return (P, c)
|
return (P, c)
|
||||||
|
|
||||||
def hash_to_curve_jacobian(msg, DST):
|
def hash_to_curve_jacobian(msg, DST):
|
||||||
c = Cost()
|
c = Cost()
|
||||||
us = hash_to_field(msg, DST, 2)
|
us = hash_to_field(msg, DST, 2)
|
||||||
#print("u = ", u)
|
#print("u = ", u)
|
||||||
Qs = map_to_curve_simple_swu(F_p, E_isop, Z_isop, us, c)
|
(Q0x, Q0y) = map_to_curve_simple_swu(F_p, E_isop, Z_isop, us[0], c)
|
||||||
|
(Q1x, Q1y) = map_to_curve_simple_swu(F_p, E_isop, Z_isop, us[1], c)
|
||||||
|
|
||||||
R = Qs[0] + Qs[1]
|
if DEBUG:
|
||||||
|
R = E_isop((Q0x, Q0y)) + E_isop((Q1x, Q1y))
|
||||||
#print("R = ", R)
|
#print("R = ", R)
|
||||||
|
|
||||||
(Q0x, Q0y) = Qs[0].xy()
|
|
||||||
(Q1x, Q1y) = Qs[1].xy()
|
|
||||||
(Rx, Ry, Rz) = unified_mmadd_jacobian(E_isop_A, Q0x, Q0y, Q1x, Q1y, c)
|
(Rx, Ry, Rz) = unified_mmadd_jacobian(E_isop_A, Q0x, Q0y, Q1x, Q1y, c)
|
||||||
assert E_isop((Rx / Rz^2, Ry / Rz^3)) == R
|
|
||||||
|
if DEBUG: assert E_isop((Rx / Rz^2, Ry / Rz^3)) == R
|
||||||
|
|
||||||
# no cofactor clearing needed since Pallas and Vesta are prime-order
|
# no cofactor clearing needed since Pallas and Vesta are prime-order
|
||||||
(Px, Py, Pz) = isop_map_jacobian(Rx, Ry, Rz, c)
|
(Px, Py, Pz) = isop_map_jacobian(Rx, Ry, Rz, c)
|
||||||
|
|
Loading…
Reference in New Issue