Skip to content

Commit 1b21aa5

Browse files
committed
Merge #1078: group: Save a normalize_to_zero in gej_add_ge
e089eec group: Further simply gej_add_ge (Tim Ruffing) ac71020 group: Save a normalize_to_zero in gej_add_ge (Tim Ruffing) Pull request description: As discovered by sipa in #1033. See commit message for reasoning but note that the infinity handling will be replaced in the second commit again. ACKs for top commit: sipa: ACK e089eec apoelstra: ACK e089eec Tree-SHA512: fb1b5742e73dd8b2172b4d3e2852490cfd626e8673b72274d281fa34b04e9368a186895fb9cd232429c22b14011df136f4c09bdc7332beef2b3657f7f2798d66
2 parents 1cca7c1 + e089eec commit 1b21aa5

File tree

2 files changed

+34
-27
lines changed

2 files changed

+34
-27
lines changed

sage/prove_group_implementations.sage

+9-17
Original file line numberDiff line numberDiff line change
@@ -148,7 +148,7 @@ def formula_secp256k1_gej_add_ge(branch, a, b):
148148
zeroes = {}
149149
nonzeroes = {}
150150
a_infinity = False
151-
if (branch & 4) != 0:
151+
if (branch & 2) != 0:
152152
nonzeroes.update({a.Infinity : 'a_infinite'})
153153
a_infinity = True
154154
else:
@@ -167,15 +167,11 @@ def formula_secp256k1_gej_add_ge(branch, a, b):
167167
m_alt = -u2
168168
tt = u1 * m_alt
169169
rr = rr + tt
170-
degenerate = (branch & 3) == 3
171-
if (branch & 1) != 0:
170+
degenerate = (branch & 1) != 0
171+
if degenerate:
172172
zeroes.update({m : 'm_zero'})
173173
else:
174174
nonzeroes.update({m : 'm_nonzero'})
175-
if (branch & 2) != 0:
176-
zeroes.update({rr : 'rr_zero'})
177-
else:
178-
nonzeroes.update({rr : 'rr_nonzero'})
179175
rr_alt = s1
180176
rr_alt = rr_alt * 2
181177
m_alt = m_alt + u1
@@ -190,13 +186,6 @@ def formula_secp256k1_gej_add_ge(branch, a, b):
190186
n = m
191187
t = rr_alt^2
192188
rz = a.Z * m_alt
193-
infinity = False
194-
if (branch & 8) != 0:
195-
if not a_infinity:
196-
infinity = True
197-
zeroes.update({rz : 'r.z=0'})
198-
else:
199-
nonzeroes.update({rz : 'r.z!=0'})
200189
t = t + q
201190
rx = t
202191
t = t * 2
@@ -209,8 +198,11 @@ def formula_secp256k1_gej_add_ge(branch, a, b):
209198
rx = b.X
210199
ry = b.Y
211200
rz = 1
212-
if infinity:
201+
if (branch & 4) != 0:
202+
zeroes.update({rz : 'r.z = 0'})
213203
return (constraints(zero={b.Z - 1 : 'b.z=1', b.Infinity : 'b_finite'}), constraints(zero=zeroes, nonzero=nonzeroes), point_at_infinity())
204+
else:
205+
nonzeroes.update({rz : 'r.z != 0'})
214206
return (constraints(zero={b.Z - 1 : 'b.z=1', b.Infinity : 'b_finite'}), constraints(zero=zeroes, nonzero=nonzeroes), jacobianpoint(rx, ry, rz))
215207

216208
def formula_secp256k1_gej_add_ge_old(branch, a, b):
@@ -280,14 +272,14 @@ if __name__ == "__main__":
280272
success = success & check_symbolic_jacobian_weierstrass("secp256k1_gej_add_var", 0, 7, 5, formula_secp256k1_gej_add_var)
281273
success = success & check_symbolic_jacobian_weierstrass("secp256k1_gej_add_ge_var", 0, 7, 5, formula_secp256k1_gej_add_ge_var)
282274
success = success & check_symbolic_jacobian_weierstrass("secp256k1_gej_add_zinv_var", 0, 7, 5, formula_secp256k1_gej_add_zinv_var)
283-
success = success & check_symbolic_jacobian_weierstrass("secp256k1_gej_add_ge", 0, 7, 16, formula_secp256k1_gej_add_ge)
275+
success = success & check_symbolic_jacobian_weierstrass("secp256k1_gej_add_ge", 0, 7, 8, formula_secp256k1_gej_add_ge)
284276
success = success & (not check_symbolic_jacobian_weierstrass("secp256k1_gej_add_ge_old [should fail]", 0, 7, 4, formula_secp256k1_gej_add_ge_old))
285277

286278
if len(sys.argv) >= 2 and sys.argv[1] == "--exhaustive":
287279
success = success & check_exhaustive_jacobian_weierstrass("secp256k1_gej_add_var", 0, 7, 5, formula_secp256k1_gej_add_var, 43)
288280
success = success & check_exhaustive_jacobian_weierstrass("secp256k1_gej_add_ge_var", 0, 7, 5, formula_secp256k1_gej_add_ge_var, 43)
289281
success = success & check_exhaustive_jacobian_weierstrass("secp256k1_gej_add_zinv_var", 0, 7, 5, formula_secp256k1_gej_add_zinv_var, 43)
290-
success = success & check_exhaustive_jacobian_weierstrass("secp256k1_gej_add_ge", 0, 7, 16, formula_secp256k1_gej_add_ge, 43)
282+
success = success & check_exhaustive_jacobian_weierstrass("secp256k1_gej_add_ge", 0, 7, 8, formula_secp256k1_gej_add_ge, 43)
291283
success = success & (not check_exhaustive_jacobian_weierstrass("secp256k1_gej_add_ge_old [should fail]", 0, 7, 4, formula_secp256k1_gej_add_ge_old, 43))
292284

293285
sys.exit(int(not success))

src/group_impl.h

+25-10
Original file line numberDiff line numberDiff line change
@@ -532,11 +532,11 @@ static void secp256k1_gej_add_ge(secp256k1_gej *r, const secp256k1_gej *a, const
532532
/* Operations: 7 mul, 5 sqr, 24 add/cmov/half/mul_int/negate/normalize_weak/normalizes_to_zero */
533533
secp256k1_fe zz, u1, u2, s1, s2, t, tt, m, n, q, rr;
534534
secp256k1_fe m_alt, rr_alt;
535-
int infinity, degenerate;
535+
int degenerate;
536536
VERIFY_CHECK(!b->infinity);
537537
VERIFY_CHECK(a->infinity == 0 || a->infinity == 1);
538538

539-
/** In:
539+
/* In:
540540
* Eric Brier and Marc Joye, Weierstrass Elliptic Curves and Side-Channel Attacks.
541541
* In D. Naccache and P. Paillier, Eds., Public Key Cryptography, vol. 2274 of Lecture Notes in Computer Science, pages 335-345. Springer-Verlag, 2002.
542542
* we find as solution for a unified addition/doubling formula:
@@ -598,10 +598,9 @@ static void secp256k1_gej_add_ge(secp256k1_gej *r, const secp256k1_gej *a, const
598598
secp256k1_fe_negate(&m_alt, &u2, 1); /* Malt = -X2*Z1^2 */
599599
secp256k1_fe_mul(&tt, &u1, &m_alt); /* tt = -U1*U2 (2) */
600600
secp256k1_fe_add(&rr, &tt); /* rr = R = T^2-U1*U2 (3) */
601-
/** If lambda = R/M = 0/0 we have a problem (except in the "trivial"
602-
* case that Z = z1z2 = 0, and this is special-cased later on). */
603-
degenerate = secp256k1_fe_normalizes_to_zero(&m) &
604-
secp256k1_fe_normalizes_to_zero(&rr);
601+
/* If lambda = R/M = R/0 we have a problem (except in the "trivial"
602+
* case that Z = z1z2 = 0, and this is special-cased later on). */
603+
degenerate = secp256k1_fe_normalizes_to_zero(&m);
605604
/* This only occurs when y1 == -y2 and x1^3 == x2^3, but x1 != x2.
606605
* This means either x1 == beta*x2 or beta*x1 == x2, where beta is
607606
* a nontrivial cube root of one. In either case, an alternate
@@ -613,7 +612,7 @@ static void secp256k1_gej_add_ge(secp256k1_gej *r, const secp256k1_gej *a, const
613612

614613
secp256k1_fe_cmov(&rr_alt, &rr, !degenerate);
615614
secp256k1_fe_cmov(&m_alt, &m, !degenerate);
616-
/* Now Ralt / Malt = lambda and is guaranteed not to be 0/0.
615+
/* Now Ralt / Malt = lambda and is guaranteed not to be Ralt / 0.
617616
* From here on out Ralt and Malt represent the numerator
618617
* and denominator of lambda; R and M represent the explicit
619618
* expressions x1^2 + x2^2 + x1x2 and y1 + y2. */
@@ -628,7 +627,6 @@ static void secp256k1_gej_add_ge(secp256k1_gej *r, const secp256k1_gej *a, const
628627
secp256k1_fe_cmov(&n, &m, degenerate); /* n = M^3 * Malt (2) */
629628
secp256k1_fe_sqr(&t, &rr_alt); /* t = Ralt^2 (1) */
630629
secp256k1_fe_mul(&r->z, &a->z, &m_alt); /* r->z = Z3 = Malt*Z (1) */
631-
infinity = secp256k1_fe_normalizes_to_zero(&r->z) & ~a->infinity;
632630
secp256k1_fe_add(&t, &q); /* t = Ralt^2 + Q (2) */
633631
r->x = t; /* r->x = X3 = Ralt^2 + Q (2) */
634632
secp256k1_fe_mul_int(&t, 2); /* t = 2*X3 (4) */
@@ -638,11 +636,28 @@ static void secp256k1_gej_add_ge(secp256k1_gej *r, const secp256k1_gej *a, const
638636
secp256k1_fe_negate(&r->y, &t, 3); /* r->y = -(Ralt*(2*X3 + Q) + M^3*Malt) (4) */
639637
secp256k1_fe_half(&r->y); /* r->y = Y3 = -(Ralt*(2*X3 + Q) + M^3*Malt)/2 (3) */
640638

641-
/** In case a->infinity == 1, replace r with (b->x, b->y, 1). */
639+
/* In case a->infinity == 1, replace r with (b->x, b->y, 1). */
642640
secp256k1_fe_cmov(&r->x, &b->x, a->infinity);
643641
secp256k1_fe_cmov(&r->y, &b->y, a->infinity);
644642
secp256k1_fe_cmov(&r->z, &secp256k1_fe_one, a->infinity);
645-
r->infinity = infinity;
643+
644+
/* Set r->infinity if r->z is 0.
645+
*
646+
* If a->infinity is set, then r->infinity = (r->z == 0) = (1 == 0) = false,
647+
* which is correct because the function assumes that b is not infinity.
648+
*
649+
* Now assume !a->infinity. This implies Z = Z1 != 0.
650+
*
651+
* Case y1 = -y2:
652+
* In this case we could have a = -b, namely if x1 = x2.
653+
* We have degenerate = true, r->z = (x1 - x2) * Z.
654+
* Then r->infinity = ((x1 - x2)Z == 0) = (x1 == x2) = (a == -b).
655+
*
656+
* Case y1 != -y2:
657+
* In this case, we can't have a = -b.
658+
* We have degenerate = false, r->z = (y1 + y2) * Z.
659+
* Then r->infinity = ((y1 + y2)Z == 0) = (y1 == -y2) = false. */
660+
r->infinity = secp256k1_fe_normalizes_to_zero(&r->z);
646661
}
647662

648663
static void secp256k1_gej_rescale(secp256k1_gej *r, const secp256k1_fe *s) {

0 commit comments

Comments
 (0)