Skip to content

Commit 574067e

Browse files
committed
Curve25519: lshift of a negative value is undefined in C
Change all left shifts to be of unsigned values. In some cases the values were negative. Added macros to make the code easier to be consistent.
1 parent 5922b5d commit 574067e

1 file changed

Lines changed: 103 additions & 83 deletions

File tree

wolfcrypt/src/fe_operations.c

Lines changed: 103 additions & 83 deletions
Original file line numberDiff line numberDiff line change
@@ -251,6 +251,26 @@ int curve25519_blind(byte* q, const byte* n, const byte* mask, const byte* p,
251251
#endif
252252
#endif /* HAVE_CURVE25519 && !CURVE25519_SMALL && !FREESCALE_LTC_ECC */
253253

254+
/* Reduce a0 back down to 26-bits. c is the overflow and a1 takes it. */
255+
#define TO_26(a0, a1, c) \
256+
c = ((a0) + (sword64)(1UL << 25)) >> 26; a1 += (c); \
257+
a0 -= (sword64)(((word64)(c)) << 26)
258+
/* Reduce a0 back down to 25-bits. c is the overflow and a1 takes it. */
259+
#define TO_25(a0, a1, c) \
260+
c = ((a0) + (sword64)(1UL << 24)) >> 25; a1 += (c); \
261+
a0 -= (sword64)(((word64)(c)) << 25)
262+
/* Reduce a0 back down to 25-bits. c is the overflow and a1 takes 19 times it
263+
* as this is mod 2^255 - 19. */
264+
#define TO_25_RED(a0, a1, c) \
265+
c = ((a0) + (sword64)(1UL << 24)) >> 25; a1 += (c) * 19; \
266+
a0 -= (sword64)(((word64)(c)) << 25)
267+
268+
#define GET_26_FROM_32(a0, a1, c) \
269+
c = (a0) >> 26; a1 += c; a0 -= (sword32)(((word32)(c)) << 26)
270+
#define GET_25_FROM_32(a0, a1, c) \
271+
c = (a0) >> 25; a1 += c; a0 -= (sword32)(((word32)(c)) << 25)
272+
#define TOP_25_FROM_32(a, c) \
273+
c = (a) >> 25; a -= (sword32)(((word32)(c)) << 25)
254274

255275
/*
256276
h = f * f
@@ -368,24 +388,24 @@ void fe_sq(fe h,const fe f)
368388
sword64 carry8;
369389
sword64 carry9;
370390

371-
carry0 = (h0 + (sword64) (1UL<<25)) >> 26; h1 += carry0; h0 -= carry0 << 26;
372-
carry4 = (h4 + (sword64) (1UL<<25)) >> 26; h5 += carry4; h4 -= carry4 << 26;
391+
TO_26(h0, h1, carry0);
392+
TO_26(h4, h5, carry4);
373393

374-
carry1 = (h1 + (sword64) (1UL<<24)) >> 25; h2 += carry1; h1 -= carry1 << 25;
375-
carry5 = (h5 + (sword64) (1UL<<24)) >> 25; h6 += carry5; h5 -= carry5 << 25;
394+
TO_25(h1, h2, carry1);
395+
TO_25(h5, h6, carry5);
376396

377-
carry2 = (h2 + (sword64) (1UL<<25)) >> 26; h3 += carry2; h2 -= carry2 << 26;
378-
carry6 = (h6 + (sword64) (1UL<<25)) >> 26; h7 += carry6; h6 -= carry6 << 26;
397+
TO_26(h2, h3, carry2);
398+
TO_26(h6, h7, carry6);
379399

380-
carry3 = (h3 + (sword64) (1UL<<24)) >> 25; h4 += carry3; h3 -= carry3 << 25;
381-
carry7 = (h7 + (sword64) (1UL<<24)) >> 25; h8 += carry7; h7 -= carry7 << 25;
400+
TO_25(h3, h4, carry3);
401+
TO_25(h7, h8, carry7);
382402

383-
carry4 = (h4 + (sword64) (1UL<<25)) >> 26; h5 += carry4; h4 -= carry4 << 26;
384-
carry8 = (h8 + (sword64) (1UL<<25)) >> 26; h9 += carry8; h8 -= carry8 << 26;
403+
TO_26(h4, h5, carry4);
404+
TO_26(h8, h9, carry8);
385405

386-
carry9 = (h9 + (sword64) (1UL<<24)) >> 25; h0 += carry9 * 19; h9 -= carry9 << 25;
406+
TO_25_RED(h9, h0, carry9);
387407

388-
carry0 = (h0 + (sword64) (1UL<<25)) >> 26; h1 += carry0; h0 -= carry0 << 26;
408+
TO_26(h0, h1, carry0);
389409

390410
h[0] = (sword32)h0;
391411
h[1] = (sword32)h1;
@@ -506,7 +526,7 @@ void fe_tobytes(unsigned char *s,const fe h)
506526
sword32 carry8;
507527
sword32 carry9;
508528

509-
q = (19 * h9 + (((sword32) 1) << 24)) >> 25;
529+
q = (19 * h9 + (sword32)(((word32) 1) << 24)) >> 25;
510530
q = (h0 + q) >> 26;
511531
q = (h1 + q) >> 25;
512532
q = (h2 + q) >> 26;
@@ -522,16 +542,16 @@ void fe_tobytes(unsigned char *s,const fe h)
522542
h0 += 19 * q;
523543
/* Goal: Output h-2^255 q, which is between 0 and 2^255-20. */
524544

525-
carry0 = h0 >> 26; h1 += carry0; h0 -= carry0 << 26;
526-
carry1 = h1 >> 25; h2 += carry1; h1 -= carry1 << 25;
527-
carry2 = h2 >> 26; h3 += carry2; h2 -= carry2 << 26;
528-
carry3 = h3 >> 25; h4 += carry3; h3 -= carry3 << 25;
529-
carry4 = h4 >> 26; h5 += carry4; h4 -= carry4 << 26;
530-
carry5 = h5 >> 25; h6 += carry5; h5 -= carry5 << 25;
531-
carry6 = h6 >> 26; h7 += carry6; h6 -= carry6 << 26;
532-
carry7 = h7 >> 25; h8 += carry7; h7 -= carry7 << 25;
533-
carry8 = h8 >> 26; h9 += carry8; h8 -= carry8 << 26;
534-
carry9 = h9 >> 25; h9 -= carry9 << 25;
545+
GET_26_FROM_32(h0, h1, carry0);
546+
GET_25_FROM_32(h1, h2, carry1);
547+
GET_26_FROM_32(h2, h3, carry2);
548+
GET_25_FROM_32(h3, h4, carry3);
549+
GET_26_FROM_32(h4, h5, carry4);
550+
GET_25_FROM_32(h5, h6, carry5);
551+
GET_26_FROM_32(h6, h7, carry6);
552+
GET_25_FROM_32(h7, h8, carry7);
553+
GET_26_FROM_32(h8, h9, carry8);
554+
TOP_25_FROM_32(h9, carry9);
535555
/* h10 = carry9 */
536556

537557
/*
@@ -544,32 +564,32 @@ void fe_tobytes(unsigned char *s,const fe h)
544564
s[0] = (byte)(h0 >> 0);
545565
s[1] = (byte)(h0 >> 8);
546566
s[2] = (byte)(h0 >> 16);
547-
s[3] = (byte)((h0 >> 24) | (h1 << 2));
567+
s[3] = (byte)((h0 >> 24) | (sword32)((word32)h1 << 2));
548568
s[4] = (byte)(h1 >> 6);
549569
s[5] = (byte)(h1 >> 14);
550-
s[6] = (byte)((h1 >> 22) | (h2 << 3));
570+
s[6] = (byte)((h1 >> 22) | (sword32)((word32)h2 << 3));
551571
s[7] = (byte)(h2 >> 5);
552572
s[8] = (byte)(h2 >> 13);
553-
s[9] = (byte)((h2 >> 21) | (h3 << 5));
573+
s[9] = (byte)((h2 >> 21) | (sword32)((word32)h3 << 5));
554574
s[10] = (byte)(h3 >> 3);
555575
s[11] = (byte)(h3 >> 11);
556-
s[12] = (byte)((h3 >> 19) | (h4 << 6));
576+
s[12] = (byte)((h3 >> 19) | (sword32)((word32)h4 << 6));
557577
s[13] = (byte)(h4 >> 2);
558578
s[14] = (byte)(h4 >> 10);
559579
s[15] = (byte)(h4 >> 18);
560580
s[16] = (byte)(h5 >> 0);
561581
s[17] = (byte)(h5 >> 8);
562582
s[18] = (byte)(h5 >> 16);
563-
s[19] = (byte)((h5 >> 24) | (h6 << 1));
583+
s[19] = (byte)((h5 >> 24) | (sword32)((word32)h6 << 1));
564584
s[20] = (byte)(h6 >> 7);
565585
s[21] = (byte)(h6 >> 15);
566-
s[22] = (byte)((h6 >> 23) | (h7 << 3));
586+
s[22] = (byte)((h6 >> 23) | (sword32)((word32)h7 << 3));
567587
s[23] = (byte)(h7 >> 5);
568588
s[24] = (byte)(h7 >> 13);
569-
s[25] = (byte)((h7 >> 21) | (h8 << 4));
589+
s[25] = (byte)((h7 >> 21) | (sword32)((word32)h8 << 4));
570590
s[26] = (byte)(h8 >> 4);
571591
s[27] = (byte)(h8 >> 12);
572-
s[28] = (byte)((h8 >> 20) | (h9 << 6));
592+
s[28] = (byte)((h8 >> 20) | (sword32)((word32)h9 << 6));
573593
s[29] = (byte)(h9 >> 2);
574594
s[30] = (byte)(h9 >> 10);
575595
s[31] = (byte)(h9 >> 18);
@@ -642,15 +662,15 @@ Ignores top bit of h.
642662
void fe_frombytes(fe h,const unsigned char *s)
643663
{
644664
sword64 h0 = load_4(s);
645-
sword64 h1 = load_3(s + 4) << 6;
646-
sword64 h2 = load_3(s + 7) << 5;
647-
sword64 h3 = load_3(s + 10) << 3;
648-
sword64 h4 = load_3(s + 13) << 2;
665+
sword64 h1 = (sword64)(((word64)load_3(s + 4)) << 6);
666+
sword64 h2 = (sword64)(((word64)load_3(s + 7)) << 5);
667+
sword64 h3 = (sword64)(((word64)load_3(s + 10)) << 3);
668+
sword64 h4 = (sword64)(((word64)load_3(s + 13)) << 2);
649669
sword64 h5 = load_4(s + 16);
650-
sword64 h6 = load_3(s + 20) << 7;
651-
sword64 h7 = load_3(s + 23) << 5;
652-
sword64 h8 = load_3(s + 26) << 4;
653-
sword64 h9 = (load_3(s + 29) & 8388607) << 2;
670+
sword64 h6 = (sword64)(((word64)load_3(s + 20)) << 7);
671+
sword64 h7 = (sword64)(((word64)load_3(s + 23)) << 5);
672+
sword64 h8 = (sword64)(((word64)load_3(s + 26)) << 4);
673+
sword64 h9 = (sword64)(((word64)load_3(s + 29) & 8388607UL) << 2);
654674
sword64 carry0;
655675
sword64 carry1;
656676
sword64 carry2;
@@ -662,17 +682,17 @@ void fe_frombytes(fe h,const unsigned char *s)
662682
sword64 carry8;
663683
sword64 carry9;
664684

665-
carry9 = (h9 + (sword64) (1UL<<24)) >> 25; h0 += carry9 * 19; h9 -= carry9 << 25;
666-
carry1 = (h1 + (sword64) (1UL<<24)) >> 25; h2 += carry1; h1 -= carry1 << 25;
667-
carry3 = (h3 + (sword64) (1UL<<24)) >> 25; h4 += carry3; h3 -= carry3 << 25;
668-
carry5 = (h5 + (sword64) (1UL<<24)) >> 25; h6 += carry5; h5 -= carry5 << 25;
669-
carry7 = (h7 + (sword64) (1UL<<24)) >> 25; h8 += carry7; h7 -= carry7 << 25;
685+
TO_25_RED(h9, h0, carry9);
686+
TO_25(h1, h2, carry1);
687+
TO_25(h3, h4, carry3);
688+
TO_25(h5, h6, carry5);
689+
TO_25(h7, h8, carry7);
670690

671-
carry0 = (h0 + (sword64) (1UL<<25)) >> 26; h1 += carry0; h0 -= carry0 << 26;
672-
carry2 = (h2 + (sword64) (1UL<<25)) >> 26; h3 += carry2; h2 -= carry2 << 26;
673-
carry4 = (h4 + (sword64) (1UL<<25)) >> 26; h5 += carry4; h4 -= carry4 << 26;
674-
carry6 = (h6 + (sword64) (1UL<<25)) >> 26; h7 += carry6; h6 -= carry6 << 26;
675-
carry8 = (h8 + (sword64) (1UL<<25)) >> 26; h9 += carry8; h8 -= carry8 << 26;
691+
TO_26(h0, h1, carry0);
692+
TO_26(h2, h3, carry2);
693+
TO_26(h4, h5, carry4);
694+
TO_26(h6, h7, carry6);
695+
TO_26(h8, h9, carry8);
676696

677697
h[0] = (sword32)h0;
678698
h[1] = (sword32)h1;
@@ -949,46 +969,46 @@ void fe_mul(fe h,const fe f,const fe g)
949969
i.e. |h1| <= 1.7*2^59; narrower ranges for h3, h5, h7, h9
950970
*/
951971

952-
carry0 = (h0 + (sword64) (1UL<<25)) >> 26; h1 += carry0; h0 -= carry0 << 26;
953-
carry4 = (h4 + (sword64) (1UL<<25)) >> 26; h5 += carry4; h4 -= carry4 << 26;
972+
TO_26(h0, h1, carry0);
973+
TO_26(h4, h5, carry4);
954974
/* |h0| <= 2^25 */
955975
/* |h4| <= 2^25 */
956976
/* |h1| <= 1.71*2^59 */
957977
/* |h5| <= 1.71*2^59 */
958978

959-
carry1 = (h1 + (sword64) (1UL<<24)) >> 25; h2 += carry1; h1 -= carry1 << 25;
960-
carry5 = (h5 + (sword64) (1UL<<24)) >> 25; h6 += carry5; h5 -= carry5 << 25;
979+
TO_25(h1, h2, carry1);
980+
TO_25(h5, h6, carry5);
961981
/* |h1| <= 2^24; from now on fits into int32 */
962982
/* |h5| <= 2^24; from now on fits into int32 */
963983
/* |h2| <= 1.41*2^60 */
964984
/* |h6| <= 1.41*2^60 */
965985

966-
carry2 = (h2 + (sword64) (1UL<<25)) >> 26; h3 += carry2; h2 -= carry2 << 26;
967-
carry6 = (h6 + (sword64) (1UL<<25)) >> 26; h7 += carry6; h6 -= carry6 << 26;
986+
TO_26(h2, h3, carry2);
987+
TO_26(h6, h7, carry6);
968988
/* |h2| <= 2^25; from now on fits into int32 unchanged */
969989
/* |h6| <= 2^25; from now on fits into int32 unchanged */
970990
/* |h3| <= 1.71*2^59 */
971991
/* |h7| <= 1.71*2^59 */
972992

973-
carry3 = (h3 + (sword64) (1UL<<24)) >> 25; h4 += carry3; h3 -= carry3 << 25;
974-
carry7 = (h7 + (sword64) (1UL<<24)) >> 25; h8 += carry7; h7 -= carry7 << 25;
993+
TO_25(h3, h4, carry3);
994+
TO_25(h7, h8, carry7);
975995
/* |h3| <= 2^24; from now on fits into int32 unchanged */
976996
/* |h7| <= 2^24; from now on fits into int32 unchanged */
977997
/* |h4| <= 1.72*2^34 */
978998
/* |h8| <= 1.41*2^60 */
979999

980-
carry4 = (h4 + (sword64) (1UL<<25)) >> 26; h5 += carry4; h4 -= carry4 << 26;
981-
carry8 = (h8 + (sword64) (1UL<<25)) >> 26; h9 += carry8; h8 -= carry8 << 26;
1000+
TO_26(h4, h5, carry4);
1001+
TO_26(h8, h9, carry8);
9821002
/* |h4| <= 2^25; from now on fits into int32 unchanged */
9831003
/* |h8| <= 2^25; from now on fits into int32 unchanged */
9841004
/* |h5| <= 1.01*2^24 */
9851005
/* |h9| <= 1.71*2^59 */
9861006

987-
carry9 = (h9 + (sword64) (1UL<<24)) >> 25; h0 += carry9 * 19; h9 -= carry9 << 25;
1007+
TO_25_RED(h9, h0, carry9);
9881008
/* |h9| <= 2^24; from now on fits into int32 unchanged */
9891009
/* |h0| <= 1.1*2^39 */
9901010

991-
carry0 = (h0 + (sword64) (1UL<<25)) >> 26; h1 += carry0; h0 -= carry0 << 26;
1011+
TO_26(h0, h1, carry0);
9921012
/* |h0| <= 2^25; from now on fits into int32 unchanged */
9931013
/* |h1| <= 1.01*2^24 */
9941014

@@ -1122,17 +1142,17 @@ void fe_mul121666(fe h,fe f)
11221142
sword64 carry8;
11231143
sword64 carry9;
11241144

1125-
carry9 = (h9 + (sword64) (1UL<<24)) >> 25; h0 += carry9 * 19; h9 -= carry9 << 25;
1126-
carry1 = (h1 + (sword64) (1UL<<24)) >> 25; h2 += carry1; h1 -= carry1 << 25;
1127-
carry3 = (h3 + (sword64) (1UL<<24)) >> 25; h4 += carry3; h3 -= carry3 << 25;
1128-
carry5 = (h5 + (sword64) (1UL<<24)) >> 25; h6 += carry5; h5 -= carry5 << 25;
1129-
carry7 = (h7 + (sword64) (1UL<<24)) >> 25; h8 += carry7; h7 -= carry7 << 25;
1145+
TO_25_RED(h9, h0, carry9);
1146+
TO_25(h1, h2, carry1);
1147+
TO_25(h3, h4, carry3);
1148+
TO_25(h5, h6, carry5);
1149+
TO_25(h7, h8, carry7);
11301150

1131-
carry0 = (h0 + (sword64) (1UL<<25)) >> 26; h1 += carry0; h0 -= carry0 << 26;
1132-
carry2 = (h2 + (sword64) (1UL<<25)) >> 26; h3 += carry2; h2 -= carry2 << 26;
1133-
carry4 = (h4 + (sword64) (1UL<<25)) >> 26; h5 += carry4; h4 -= carry4 << 26;
1134-
carry6 = (h6 + (sword64) (1UL<<25)) >> 26; h7 += carry6; h6 -= carry6 << 26;
1135-
carry8 = (h8 + (sword64) (1UL<<25)) >> 26; h9 += carry8; h8 -= carry8 << 26;
1151+
TO_26(h0, h1, carry0);
1152+
TO_26(h2, h3, carry2);
1153+
TO_26(h4, h5, carry4);
1154+
TO_26(h6, h7, carry6);
1155+
TO_26(h8, h9, carry8);
11361156

11371157
h[0] = (sword32)h0;
11381158
h[1] = (sword32)h1;
@@ -1274,24 +1294,24 @@ void fe_sq2(fe h,const fe f)
12741294
h8 += h8;
12751295
h9 += h9;
12761296

1277-
carry0 = (h0 + (sword64) (1UL<<25)) >> 26; h1 += carry0; h0 -= carry0 << 26;
1278-
carry4 = (h4 + (sword64) (1UL<<25)) >> 26; h5 += carry4; h4 -= carry4 << 26;
1297+
TO_26(h0, h1, carry0);
1298+
TO_26(h4, h5, carry4);
12791299

1280-
carry1 = (h1 + (sword64) (1UL<<24)) >> 25; h2 += carry1; h1 -= carry1 << 25;
1281-
carry5 = (h5 + (sword64) (1UL<<24)) >> 25; h6 += carry5; h5 -= carry5 << 25;
1300+
TO_25(h1, h2, carry1);
1301+
TO_25(h5, h6, carry5);
12821302

1283-
carry2 = (h2 + (sword64) (1UL<<25)) >> 26; h3 += carry2; h2 -= carry2 << 26;
1284-
carry6 = (h6 + (sword64) (1UL<<25)) >> 26; h7 += carry6; h6 -= carry6 << 26;
1303+
TO_26(h2, h3, carry2);
1304+
TO_26(h6, h7, carry6);
12851305

1286-
carry3 = (h3 + (sword64) (1UL<<24)) >> 25; h4 += carry3; h3 -= carry3 << 25;
1287-
carry7 = (h7 + (sword64) (1UL<<24)) >> 25; h8 += carry7; h7 -= carry7 << 25;
1306+
TO_25(h3, h4, carry3);
1307+
TO_25(h7, h8, carry7);
12881308

1289-
carry4 = (h4 + (sword64) (1UL<<25)) >> 26; h5 += carry4; h4 -= carry4 << 26;
1290-
carry8 = (h8 + (sword64) (1UL<<25)) >> 26; h9 += carry8; h8 -= carry8 << 26;
1309+
TO_26(h4, h5, carry4);
1310+
TO_26(h8, h9, carry8);
12911311

1292-
carry9 = (h9 + (sword64) (1UL<<24)) >> 25; h0 += carry9 * 19; h9 -= carry9 << 25;
1312+
TO_25_RED(h9, h0, carry9);
12931313

1294-
carry0 = (h0 + (sword64) (1UL<<25)) >> 26; h1 += carry0; h0 -= carry0 << 26;
1314+
TO_26(h0, h1, carry0);
12951315

12961316
h[0] = (sword32)h0;
12971317
h[1] = (sword32)h1;

0 commit comments

Comments
 (0)