@@ -502,15 +502,110 @@ static final function int RunCode(
502
502
return R ;
503
503
}
504
504
505
+ static final function SetOne (
506
+ out int X [37 ],
507
+ const out int P [37 ]
508
+ )
509
+ {
510
+ local int PLen ;
511
+
512
+ PLen = (P [0 ] + 31 ) >>> 4 ;
513
+ // memset(x, 0, plen * sizeof *x);
514
+ X [0 ] = P [0 ];
515
+ X [1 ] = 0x0001 ;
516
+ }
517
+
518
+ static final function PointZero (
519
+ out Jacobian P ,
520
+ const out CurveParams Cc
521
+ )
522
+ {
523
+ // memset(P, 0, sizeof *P);
524
+ P .C [0 ].X [0 ] = Cc .P [0 ];
525
+ P .C [1 ].X [0 ] = Cc .P [0 ];
526
+ P .C [2 ].X [0 ] = Cc .P [0 ];
527
+ }
528
+
529
+ static final function PointDouble (
530
+ out Jacobian P ,
531
+ const out CurveParams Cc
532
+ )
533
+ {
534
+ RunCode (P , P , Cc , default .CodeDouble );
535
+ }
536
+
537
+ static final function int PointAdd (
538
+ out Jacobian P1 ,
539
+ const out Jacobian P2 ,
540
+ const out CurveParams Cc
541
+ )
542
+ {
543
+ return RunCode (P1 , P2 , Cc , default .CodeAdd );
544
+ }
545
+
546
+ static final function PointMul (
547
+ out Jacobian P ,
548
+ const out array <byte> X ,
549
+ int XLen ,
550
+ const out CurveParams Cc
551
+ )
552
+ {
553
+ local int Qz ;
554
+ local int K ;
555
+ local int Bits ;
556
+ local int Bnz ;
557
+ local Jacobian P2 ;
558
+ local Jacobian P3 ;
559
+ local Jacobian Q ;
560
+ local Jacobian T ;
561
+ local Jacobian U ;
562
+
563
+ /*
564
+ * We do a simple double-and-add ladder with a 2-bit window
565
+ * to make only one add every two doublings. We thus first
566
+ * precompute 2P and 3P in some local buffers.
567
+ *
568
+ * We always perform two doublings and one addition; the
569
+ * addition is with P, 2P and 3P and is done in a temporary
570
+ * array.
571
+ *
572
+ * The addition code cannot handle cases where one of the
573
+ * operands is infinity, which is the case at the start of the
574
+ * ladder. We therefore need to maintain a flag that controls
575
+ * this situation.
576
+ */
577
+
578
+ // memcpy(&P2, P, sizeof P2);
579
+ PointDouble (P2 , Cc );
580
+ // memcpy(&P3, P, sizeof P3);
581
+ PointAdd (P3 , P2 , Cc );
582
+
583
+ PointZero (Q , Cc );
584
+ Qz = 1 ;
585
+ while (XLen -- > 0 )
586
+ {
587
+ for (K = 6 ; K >= 0 ; K -= 2 )
588
+ {
589
+ PointDouble (Q , Cc );
590
+ PointDouble (Q , Cc );
591
+ // memcpy(&T, P, sizeof T);
592
+ // memcpy(&U, &Q, sizeof U);
593
+ // TODO: offset parameter needed for X?
594
+ Bits = (X [0 ] >>> K ) & 3 ;
595
+ Bnz = class 'FCryptoBigInt' .static .NEQ (Bits , 0 );
596
+ // TODO:
597
+ // class'FCryptoBigInt'.static.CCOPY(class'FCryptoBigInt'.static.EQ(Bits, 2), T, P2, 0 /* sizeof T */);
598
+ // class'FCryptoBigInt'.static.CCOPY(class'FCryptoBigInt'.static.EQ(Bits, 3), T, P3, 0 /* sizeof T */);
599
+ }
600
+ }
601
+ }
602
+
505
603
// Differs from C version: const out param for performance.
506
604
// TODO: benchmark the actual difference when this has a return value struct.
507
605
static final function IdToCurve (
508
606
EFCEllipticCurve Curve ,
509
607
const out CurveParams out_CurveParams
510
608
)
511
- {
512
- out_CurveParams = default ._PP [Curve - FCEC_Secp256r1 ];
513
- };
514
609
515
610
static function array <byte > Generator (EFCEllipticCurve Curve , out int Len )
516
611
{
0 commit comments