I verified this bug. At least, I think so. Input point: P 88c38b77f62c7646 8761482ed66be7ec e29c7ff650f1ad3d a075da5d50ae8d0f 7aecc07d9b4b9a78 11c14dd2ab2cc516 e11dc6d90097e6b6 0ccfcffded344d8c 5723476edeccc439 0ad224b227c5b4e8 c2f7280137f60ac6 c97c65b4fe0fa310 after ecp_nistz256_point_add(A, P, P) 0000000000000000 0000000000000000 0000000000000000 0000000000000000 0000000000000000 0000000000000000 0000000000000000 0000000000000000 0000000000000000 0000000000000000 0000000000000000 0000000000000000 after ecp_nistz256_point_double(B, P) 5dc647edcf585e47 8a1234279b722778 d1fe20832426c68a 8854b03358f4812f fe8c5c9008a694e5 5187b8b82213bc83 0c1da0ab8aced06c cc08ba7a7c7c7474 88cc2b97e5151f2f fe3275dcd154755a e98898ead6ffac57 282dd53b1eea1cf2
Basically the asm degenerates to 337 if (is_equal(U1, U2) && !in1infty && !in2infty) { 342 memset(r, 0, sizeof(*r)); 343 return; 345 } Since the subsequent (after jz branch taken) point_add arithmetic causes everything to zero out, so you're left with the point at infinity. Note that ecp_nistz256_point_add adds two projective points, so it doesn't get called for all EC_POINT_mul code paths. BBB On Mon, Feb 1, 2016 at 9:59 PM, Jun Sun via RT <r...@openssl.org> wrote: > Hi openssl team, > > In function ecp_nistz256_point_add (in ecp_nistz256.c), in the case when U1 > == U2 and S1 == S2, in C reference code, the logic is call > ecp_nistz256_point_double (line 339) to do a point double operation: > > > 337 if (is_equal(U1, U2) && !in1infty && !in2infty) { > > 338 if (is_equal(S1, S2)) { > > 339 ecp_nistz256_point_double(r, a); > > 340 return; > > 341 } else { > > 342 memset(r, 0, sizeof(*r)); > > 343 return; > > 344 } > > 345 } > > > > > This is correct and follow what is described in S.Gueron and V.Krasnov's > paper. But in x86_64 assembly code (ecp_nistz256-x86_64.pl), this logic is > not implemented, it fall back to point adding code again: > > > 2385 .byte 0x3e # predict taken > > 2386 jnz .Ladd_proceed$x # is_equal(U1,U2)? > > 2387 movq %xmm2, $acc0 > > 2388 movq %xmm3, $acc1 > > 2389 test $acc0, $acc0 > > 2390 jnz .Ladd_proceed$x # (in1infty || in2infty)? > > 2391 test $acc1, $acc1 > > 2392 jz .Ladd_proceed$x # is_equal(S1,S2)? > > > > > The difference be seen in the latest ectest.c for the group order tests, even > though both C code and assembly code does not generate any error, but they > generate different values: > > > 201 scalars[0] = n1; > > 202 points[0] = Q; /* => infinity */ > > 203 scalars[1] = n2; > > 204 points[1] = P; /* => -P */ > > 205 scalars[2] = n1; > > 206 points[2] = Q; /* => infinity */ > > 207 scalars[3] = n2; > > 208 points[3] = Q; /* => infinity */ > > 209 scalars[4] = n1; > > 210 points[4] = P; /* => P */ > > 211 scalars[5] = n2; > > 212 points[5] = Q; /* => infinity */ > > 213 if (!EC_POINTs_mul(group, P, NULL, 6, points, scalars, ctx)) > > 214 ABORT; > > 215 if (!EC_POINT_is_at_infinity(group, P)) > > 216 ABORT; > > > P is holding different values between C reference C code and assembly code. > This should not happen if the point doubling function is called in assembly > code as well. > > > > Jun Sun > > This email and any attachments are for the sole use of the intended > recipients and may be privileged or confidential. Any distribution, printing > or other use by anyone else is prohibited. If you are not an intended > recipient, please contact the sender immediately, and permanently delete this > email and attachments. > > _______________________________________________ > openssl-dev mailing list > To unsubscribe: https://mta.openssl.org/mailman/listinfo/openssl-dev _______________________________________________ openssl-dev mailing list To unsubscribe: https://mta.openssl.org/mailman/listinfo/openssl-dev