[openssl-dev] [openssl.org #4284] Bug in nistz256 assembly code.

Jun Sun via RT rt at openssl.org
Mon Feb 1 19:59:45 UTC 2016


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.



More information about the openssl-dev mailing list