@@ -310,6 +310,34 @@ static final function MemSet_UInt16(
310
310
}
311
311
}
312
312
313
+ // See MemSet_UInt16.
314
+ // TODO: move to dedicated memory class.
315
+ static final function MemSet_UInt16_Static37 (
316
+ out int S [37 ],
317
+ byte C ,
318
+ int NumBytes ,
319
+ optional int Offset = 0
320
+ )
321
+ {
322
+ local int IntIndex ;
323
+ local int ByteIndex ;
324
+ local int Shift ;
325
+ local int Mask ;
326
+
327
+ Shift = 8 ;
328
+ Mask = 0xff << Shift ;
329
+ IntIndex = Offset ;
330
+ for (ByteIndex = 0 ; ByteIndex < NumBytes ; ++ByteIndex )
331
+ {
332
+ S [IntIndex ] = (S [IntIndex ] & ~Mask ) | ((C & 0xff ) << Shift );
333
+ // Shift = (Shift + 8) % 16;
334
+ Shift = (Shift + 8 ) & 15 ;
335
+ // IntIndex += ByteIndex % 2;
336
+ IntIndex += ByteIndex & 1 ;
337
+ Mask = 0xff << Shift ;
338
+ }
339
+ }
340
+
313
341
/**
314
342
* C-style memset operation.
315
343
* Offset is the number of byte values
@@ -330,6 +358,22 @@ static final function MemSet_Byte(
330
358
}
331
359
}
332
360
361
+ // See MemSet_Byte.
362
+ static final function MemSet_Byte_Static66 (
363
+ out byte S [66 ],
364
+ byte C ,
365
+ int NumBytes ,
366
+ optional int Offset = 0
367
+ )
368
+ {
369
+ local int ByteIndex ;
370
+
371
+ for (ByteIndex = Offset ; ByteIndex < NumBytes ; ++ByteIndex )
372
+ {
373
+ S [ByteIndex ] = C ;
374
+ }
375
+ }
376
+
333
377
/**
334
378
* C-style memcpy operation.
335
379
* Offsets are the number of uint16_t values
@@ -442,6 +486,18 @@ static final function Zero(
442
486
MemSet_UInt16 (X , 0 , ((BitLen + 15 ) >>> 4 ) * SIZEOF_UINT16_T , 1 );
443
487
}
444
488
489
+ // See Zero.
490
+ static final function Zero_Static37 (
491
+ out int X [37 ],
492
+ int BitLen
493
+ )
494
+ {
495
+ // *x ++ = bit_len;
496
+ // memset(x, 0, ((bit_len + 15) >> 4) * sizeof *x);
497
+ X [0 ] = BitLen & 0xFFFF ; // @ALIGN-32-16.
498
+ MemSet_UInt16_Static37 (X , 0 , ((BitLen + 15 ) >>> 4 ) * SIZEOF_UINT16_T , 1 );
499
+ }
500
+
445
501
/*
446
502
* Add b[] to a[] and return the carry (0 or 1). If ctl is 0, then a[]
447
503
* is unmodified, but the carry is still computed and returned. The
@@ -477,6 +533,64 @@ static final function int Add(
477
533
return Cc ;
478
534
}
479
535
536
+ // See Add.
537
+ static final function int Add_Static37 (
538
+ out int A [37 ],
539
+ const out int B [37 ],
540
+ int Ctl
541
+ )
542
+ {
543
+ local int Cc ;
544
+ local int U ;
545
+ local int M ;
546
+ local int Aw ;
547
+ local int Bw ;
548
+ local int Naw ;
549
+
550
+ Cc = 0 ;
551
+ M = (A [0 ] + 31 ) >>> 4 ;
552
+
553
+ for (U = 1 ; U < M ; ++U )
554
+ {
555
+ Aw = A [U ];
556
+ Bw = B [U ];
557
+ Naw = Aw + Bw + Cc ;
558
+ Cc = Naw >>> 15 ;
559
+ A [U ] = MUX (Ctl , Naw & 0x7FFF , Aw ) & 0xFFFF ; // @ALIGN-32-16.
560
+ }
561
+
562
+ return Cc ;
563
+ }
564
+
565
+ // See Add.
566
+ static final function int Add_Static37_DynB (
567
+ out int A [37 ],
568
+ const out array <int> B ,
569
+ int Ctl
570
+ )
571
+ {
572
+ local int Cc ;
573
+ local int U ;
574
+ local int M ;
575
+ local int Aw ;
576
+ local int Bw ;
577
+ local int Naw ;
578
+
579
+ Cc = 0 ;
580
+ M = (A [0 ] + 31 ) >>> 4 ;
581
+
582
+ for (U = 1 ; U < M ; ++U )
583
+ {
584
+ Aw = A [U ];
585
+ Bw = B [U ];
586
+ Naw = Aw + Bw + Cc ;
587
+ Cc = Naw >>> 15 ;
588
+ A [U ] = MUX (Ctl , Naw & 0x7FFF , Aw ) & 0xFFFF ; // @ALIGN-32-16.
589
+ }
590
+
591
+ return Cc ;
592
+ }
593
+
480
594
/*
481
595
* Subtract b[] from a[] and return the carry (0 or 1). If ctl is 0,
482
596
* then a[] is unmodified, but the carry is still computed and returned.
@@ -517,6 +631,65 @@ static final function int Sub(
517
631
return Cc ;
518
632
}
519
633
634
+ // See Sub.
635
+ static final function int Sub_Static37_DynB (
636
+ out int A [37 ],
637
+ const out array <int> B ,
638
+ int Ctl
639
+ )
640
+ {
641
+ local int Cc ;
642
+ local int U ;
643
+ local int M ;
644
+ local int Aw ;
645
+ local int Bw ;
646
+ local int Naw ;
647
+
648
+ Cc = 0 ;
649
+ M = (A [0 ] + 31 ) >>> 4 ;
650
+
651
+ for (U = 1 ; U < M ; ++U )
652
+ {
653
+ Aw = A [U ];
654
+ Bw = B [U ];
655
+ Naw = Aw - Bw - Cc ;
656
+ CC = Naw >>> 31 ;
657
+ A [U ] = MUX (Ctl , Naw & 0x7FFF , Aw ) & 0xFFFF ; // @ALIGN-32-16.
658
+ }
659
+
660
+ return Cc ;
661
+ }
662
+
663
+ // See Sub.
664
+ static final function int Sub_Static37 (
665
+ out int A [37 ],
666
+ const out int B [37 ],
667
+ int Ctl
668
+ )
669
+ {
670
+ local int Cc ;
671
+ local int U ;
672
+ local int M ;
673
+ local int Aw ;
674
+ local int Bw ;
675
+ local int Naw ;
676
+
677
+ Cc = 0 ;
678
+ M = (A [0 ] + 31 ) >>> 4 ;
679
+
680
+ for (U = 1 ; U < M ; ++U )
681
+ {
682
+ Aw = A [U ];
683
+ Bw = B [U ];
684
+ Naw = Aw - Bw - Cc ;
685
+ CC = Naw >>> 31 ;
686
+ A [U ] = MUX (Ctl , Naw & 0x7FFF , Aw ) & 0xFFFF ; // @ALIGN-32-16.
687
+ }
688
+
689
+ return Cc ;
690
+ }
691
+
692
+
520
693
/*
521
694
* Compute the actual bit length of an integer. The argument X should
522
695
* point to the first (least significant) value word of the integer.
@@ -1161,6 +1334,54 @@ static final function Encode(
1161
1334
}
1162
1335
}
1163
1336
1337
+ // See Encode.
1338
+ static final function Encode_Static66 (
1339
+ out byte Dst [66 ],
1340
+ int Len ,
1341
+ const out array <int> X
1342
+ )
1343
+ {
1344
+ local int U ;
1345
+ local int XLen ;
1346
+ local int Acc ;
1347
+ local int AccLen ;
1348
+
1349
+ XLen = (X [0 ] + 15 ) >>> 4 ;
1350
+ if (XLen == 0 )
1351
+ {
1352
+ // NOTE: BearSSL assumes all parameters are user-allocated.
1353
+ // In UnrealScript we'll make an exception here to avoid a bug
1354
+ // where MemSet is called with Len == 0. TODO: SHOULD WE DO THIS?
1355
+ // Probably no way to avoid this since we are not dealing with
1356
+ // pointers in UScript like original BearSSL code does.
1357
+ if (Len == 0 )
1358
+ {
1359
+ Len = 1 ;
1360
+ }
1361
+
1362
+ // memset(dst, 0, len);
1363
+ MemSet_Byte_Static66 (Dst , 0 , Len );
1364
+ return ;
1365
+ }
1366
+ U = 1 ;
1367
+ Acc = 0 ;
1368
+ AccLen = 0 ;
1369
+ while (Len -- > 0 )
1370
+ {
1371
+ if (AccLen < 8 )
1372
+ {
1373
+ if (U <= XLen )
1374
+ {
1375
+ Acc += X [U ++] << AccLen ;
1376
+ }
1377
+ AccLen += 15 ;
1378
+ }
1379
+ Dst [Len ] = Acc ;
1380
+ Acc = Acc >>> 8 ;
1381
+ AccLen -= 8 ;
1382
+ }
1383
+ }
1384
+
1164
1385
/*
1165
1386
* Convert a modular integer back from Montgomery representation. The
1166
1387
* integer x[] MUST be lower than m[], but with the same announced bit
@@ -1847,6 +2068,38 @@ static final function ModPow(
1847
2068
}
1848
2069
}
1849
2070
2071
+ // See ModPow.
2072
+ static final function ModPow_S37_S66_Dyn_S37_S37 (
2073
+ out int X [37 ],
2074
+ const out byte E [66 ],
2075
+ int ELen ,
2076
+ const out array <int> M ,
2077
+ int M0I ,
2078
+ out int T1 [37 ],
2079
+ out int T2 [37 ]
2080
+ )
2081
+ {
2082
+ local int MLen ;
2083
+ local int K ;
2084
+ local int Ctl ;
2085
+
2086
+ // TODO: body for this func.
2087
+
2088
+ MLen = ((M [0 ] + 31 ) >>> 4 ) * SIZEOF_UINT16_T ;
2089
+ // MemCpy(T1, X, MLen);
2090
+ // ToMonty(T1, M);
2091
+ // Zero(X, M[0]);
2092
+ // X[1] = 1;
2093
+ // for (K = 0; K < (ELen << 3); ++K)
2094
+ // {
2095
+ // Ctl = (E[ELen - 1 - (K >>> 3)] >>> (K & 7)) & 1;
2096
+ // MontyMul_S37_S37_S37_DynM(T2, X, T1, M, M0I);
2097
+ // CCOPY(Ctl, X, T2, MLen);
2098
+ // MontyMul_S37_S37_S37_DynM(T2, T1, T1, M, M0I);
2099
+ // MemCpy(T1, T2, MLen);
2100
+ // }
2101
+ }
2102
+
1850
2103
/*
1851
2104
* Compute a modular Montgomery multiplication. d[] is filled with the
1852
2105
* value of x*y/R modulo m[] (where R is the Montgomery factor). The
@@ -1925,6 +2178,76 @@ static final function MontyMul(
1925
2178
Sub (D , M , NEQ (DH , 0 ) | NOT (Sub (D , M , 0 )));
1926
2179
}
1927
2180
2181
+ // See MontyMul.
2182
+ static final function MontyMul_S37_S37_S37_DynM (
2183
+ out int D [37 ],
2184
+ const out int X [37 ],
2185
+ const out int Y [37 ],
2186
+ const out array <int> M ,
2187
+ int M0I
2188
+ )
2189
+ {
2190
+ local int Len ;
2191
+ local int Len4 ;
2192
+ local int U ;
2193
+ local int V ;
2194
+ local int Dh ;
2195
+ local int F ;
2196
+ local int Xu ;
2197
+ local int R ;
2198
+ local int Zh ;
2199
+ local int Z ;
2200
+
2201
+ Len = (M [0 ] + 15 ) >>> 4 ;
2202
+ Len4 = Len & ~3 ;
2203
+ Zero_Static37 (D , M [0 ]);
2204
+ Dh = 0 ;
2205
+ for (U = 0 ; U < Len ; ++U )
2206
+ {
2207
+ Xu = X [U + 1 ];
2208
+ // f = MUL15((d[1] + MUL15(x[u + 1], y[1])) & 0x7FFF, m0i) & 0x7FFF;
2209
+ F = (((D [1 ] + (X [U + 1 ] * Y [1 ])) & 0x7FFF ) * M0I ) & 0x7FFF ;
2210
+ R = 0 ;
2211
+ for (V = 0 ; V < Len4 ; V += 4 )
2212
+ {
2213
+ Z = D [V + 1 ] + (Xu * Y [V + 1 ]) + (F * M [V + 1 ]) + R ;
2214
+ R = Z >>> 15 ;
2215
+ D [V /*+0*/ ] = Z & 0x7FFF ;
2216
+ Z = D [V + 2 ] + (Xu * Y [V + 2 ]) + (F * M [V + 2 ]) + R ;
2217
+ R = Z >>> 15 ;
2218
+ D [V + 1 ] = Z & 0x7FFF ;
2219
+ Z = D [V + 3 ] + (Xu * Y [V + 3 ]) + (F * M [V + 3 ]) + R ;
2220
+ R = Z >>> 15 ;
2221
+ D [V + 2 ] = Z & 0x7FFF ;
2222
+ Z = D [V + 4 ] + (Xu * Y [V + 4 ]) + (F * M [V + 4 ]) + R ;
2223
+ R = Z >>> 15 ;
2224
+ D [V + 3 ] = Z & 0x7FFF ;
2225
+ }
2226
+
2227
+ for (Z = 0 ; V < Len ; ++V )
2228
+ {
2229
+ Z = D [V + 1 ] + (Xu * Y [V + 1 ]) + (F * M [V + 1 ]) + R ;
2230
+ R = Z >>> 15 ;
2231
+ D [V /*+0*/ ] = Z & 0x7FFF ;
2232
+ }
2233
+
2234
+ Zh = Dh + R ;
2235
+ D [Len ] = Zh & 0x7FFF ;
2236
+ Dh = Zh >>> 15 ;
2237
+ }
2238
+
2239
+ /*
2240
+ * Restore the bit length (it was overwritten in the loop above).
2241
+ */
2242
+ D [0 ] = M [0 ];
2243
+
2244
+ /*
2245
+ * d[] may be greater than m[], but it is still lower than twice
2246
+ * the modulus.
2247
+ */
2248
+ Sub_Static37_DynB (D , M , NEQ (DH , 0 ) | NOT (Sub_Static37_DynB (D , M , 0 )));
2249
+ }
2250
+
1928
2251
/*
1929
2252
* Compute a modular exponentiation. x[] MUST be an integer modulo m[]
1930
2253
* (same announced bit length, lower value). m[] MUST be odd. The
0 commit comments