@@ -27,11 +27,6 @@ class Tnaf
2727 */
2828 public static final byte WIDTH = 4 ;
2929
30- /**
31- * 2<sup>4</sup>
32- */
33- public static final byte POW_2_WIDTH = 16 ;
34-
3530 /**
3631 * The <code>α<sub>u</sub></code>'s for <code>a=0</code> as an array
3732 * of <code>ZTauElement</code>s.
@@ -451,10 +446,7 @@ public static BigInteger[] getLucas(byte mu, int k, boolean doV)
451446 throw new IllegalArgumentException ("mu must be 1 or -1" );
452447 }
453448
454- BigInteger u0 ;
455- BigInteger u1 ;
456- BigInteger u2 ;
457-
449+ BigInteger u0 , u1 , u2 ;
458450 if (doV )
459451 {
460452 u0 = ECConstants .TWO ;
@@ -469,26 +461,18 @@ public static BigInteger[] getLucas(byte mu, int k, boolean doV)
469461 for (int i = 1 ; i < k ; i ++)
470462 {
471463 // u2 = mu*u1 - 2*u0;
472- BigInteger s = null ;
473- if (mu == 1 )
464+ BigInteger s = u1 ;
465+ if (mu < 0 )
474466 {
475- s = u1 ;
467+ s = s . negate () ;
476468 }
477- else
478- {
479- // mu == -1
480- s = u1 .negate ();
481- }
482-
469+
483470 u2 = s .subtract (u0 .shiftLeft (1 ));
484471 u0 = u1 ;
485472 u1 = u2 ;
486- // System.out.println(i + ": " + u2);
487- // System.out.println();
488473 }
489474
490- BigInteger [] retVal = {u0 , u1 };
491- return retVal ;
475+ return new BigInteger []{ u0 , u1 };
492476 }
493477
494478 /**
@@ -519,11 +503,7 @@ public static BigInteger getTw(byte mu, int w)
519503 BigInteger [] us = getLucas (mu , w , false );
520504 BigInteger twoToW = ECConstants .ZERO .setBit (w );
521505 BigInteger u1invert = us [1 ].modInverse (twoToW );
522- BigInteger tw ;
523- tw = ECConstants .TWO .multiply (us [0 ]).multiply (u1invert ).mod (twoToW );
524- // System.out.println("mu = " + mu);
525- // System.out.println("tw = " + tw);
526- return tw ;
506+ return us [0 ].shiftLeft (1 ).multiply (u1invert ).mod (twoToW );
527507 }
528508 }
529509
@@ -542,22 +522,7 @@ public static BigInteger[] getSi(ECCurve.AbstractF2m curve)
542522 throw new IllegalArgumentException ("si is defined for Koblitz curves only" );
543523 }
544524
545- int m = curve .getFieldSize ();
546- int a = curve .getA ().toBigInteger ().intValue ();
547- byte mu = getMu (a );
548- int shifts = getShiftsForCofactor (curve .getCofactor ());
549- int index = m + 3 - a ;
550- BigInteger [] ui = getLucas (mu , index , false );
551- if (mu == 1 )
552- {
553- ui [0 ] = ui [0 ].negate ();
554- ui [1 ] = ui [1 ].negate ();
555- }
556-
557- BigInteger dividend0 = ECConstants .ONE .add (ui [1 ]).shiftRight (shifts );
558- BigInteger dividend1 = ECConstants .ONE .add (ui [0 ]).shiftRight (shifts ).negate ();
559-
560- return new BigInteger [] { dividend0 , dividend1 };
525+ return getSi (curve .getFieldSize (), curve .getA ().toBigInteger ().intValue (), curve .getCofactor ());
561526 }
562527
563528 public static BigInteger [] getSi (int fieldSize , int curveA , BigInteger cofactor )
@@ -608,9 +573,11 @@ protected static int getShiftsForCofactor(BigInteger h)
608573 * modular reduction.
609574 * @return <code>ρ := k partmod (τ<sup>m</sup> - 1)/(τ - 1)</code>
610575 */
611- public static ZTauElement partModReduction (BigInteger k , int m , byte a ,
612- BigInteger [] s , byte mu , byte c )
576+ public static ZTauElement partModReduction (ECCurve .AbstractF2m curve , BigInteger k , byte a , byte mu , byte c )
613577 {
578+ int m = curve .getFieldSize ();
579+ BigInteger [] s = curve .getSi ();
580+
614581 // d0 = s[0] + mu*s[1]; mu is either 1 or -1
615582 BigInteger d0 ;
616583 if (mu == 1 )
@@ -622,20 +589,29 @@ public static ZTauElement partModReduction(BigInteger k, int m, byte a,
622589 d0 = s [0 ].subtract (s [1 ]);
623590 }
624591
625- BigInteger [] v = getLucas (mu , m , true );
626- BigInteger vm = v [1 ];
592+ BigInteger vm ;
593+ if (curve .isKoblitz ())
594+ {
595+ /*
596+ * Jerome A. Solinas, "Improved Algorithms for Arithmetic on Anomalous Binary Curves", (21).
597+ */
598+ vm = ECConstants .ONE .shiftLeft (m ).add (ECConstants .ONE ).subtract (
599+ curve .getOrder ().multiply (curve .getCofactor ()));
600+ }
601+ else
602+ {
603+ BigInteger [] v = getLucas (mu , m , true );
604+ vm = v [1 ];
605+ }
627606
628- SimpleBigDecimal lambda0 = approximateDivisionByN (
629- k , s [0 ], vm , a , m , c );
630-
631- SimpleBigDecimal lambda1 = approximateDivisionByN (
632- k , s [1 ], vm , a , m , c );
607+ SimpleBigDecimal lambda0 = approximateDivisionByN (k , s [0 ], vm , a , m , c );
608+ SimpleBigDecimal lambda1 = approximateDivisionByN (k , s [1 ], vm , a , m , c );
633609
634610 ZTauElement q = round (lambda0 , lambda1 , mu );
635611
636612 // r0 = n - d0*q0 - 2*s1*q1
637613 BigInteger r0 = k .subtract (d0 .multiply (q .u )).subtract (
638- BigInteger . valueOf ( 2 ). multiply ( s [1 ]) .multiply (q .v ));
614+ s [1 ].multiply (q .v ). shiftLeft ( 1 ));
639615
640616 // r1 = s1*q0 - s0*q1
641617 BigInteger r1 = s [1 ].multiply (q .u ).subtract (s [0 ].multiply (q .v ));
@@ -654,11 +630,10 @@ public static ZTauElement partModReduction(BigInteger k, int m, byte a,
654630 public static ECPoint .AbstractF2m multiplyRTnaf (ECPoint .AbstractF2m p , BigInteger k )
655631 {
656632 ECCurve .AbstractF2m curve = (ECCurve .AbstractF2m ) p .getCurve ();
657- int m = curve .getFieldSize ();
658633 int a = curve .getA ().toBigInteger ().intValue ();
659634 byte mu = getMu (a );
660- BigInteger [] s = curve . getSi ();
661- ZTauElement rho = partModReduction (k , m , (byte )a , s , mu , (byte )10 );
635+
636+ ZTauElement rho = partModReduction (curve , k , (byte )a , mu , (byte )10 );
662637
663638 return multiplyTnaf (p , rho );
664639 }
@@ -678,9 +653,7 @@ public static ECPoint.AbstractF2m multiplyTnaf(ECPoint.AbstractF2m p, ZTauElemen
678653 byte mu = getMu (curve .getA ());
679654 byte [] u = tauAdicNaf (mu , lambda );
680655
681- ECPoint .AbstractF2m q = multiplyFromTnaf (p , u );
682-
683- return q ;
656+ return multiplyFromTnaf (p , u );
684657 }
685658
686659 /**
@@ -732,10 +705,9 @@ public static ECPoint.AbstractF2m multiplyFromTnaf(ECPoint.AbstractF2m p, byte[]
732705 * @return The <code>[τ]</code>-adic window NAF of
733706 * <code>λ</code>.
734707 */
735- public static byte [] tauAdicWNaf (byte mu , ZTauElement lambda ,
736- byte width , BigInteger pow2w , BigInteger tw , ZTauElement [] alpha )
708+ public static byte [] tauAdicWNaf (byte mu , ZTauElement lambda , int width , int tw , ZTauElement [] alpha )
737709 {
738- if (!(( mu == 1 ) || ( mu == -1 ) ))
710+ if (!(mu == 1 || mu == -1 ))
739711 {
740712 throw new IllegalArgumentException ("mu must be 1 or -1" );
741713 }
@@ -751,74 +723,49 @@ public static byte[] tauAdicWNaf(byte mu, ZTauElement lambda,
751723 // The array holding the TNAF
752724 byte [] u = new byte [maxLength ];
753725
726+ int pow2Width = 1 << width ;
727+
754728 // 2^(width - 1)
755- BigInteger pow2wMin1 = pow2w . shiftRight ( 1 ) ;
729+ int pow2wMin1 = pow2Width >>> 1 ;
756730
757731 // Split lambda into two BigIntegers to simplify calculations
758732 BigInteger r0 = lambda .u ;
759733 BigInteger r1 = lambda .v ;
760734 int i = 0 ;
761735
762736 // while lambda <> (0, 0)
763- while (!(( r0 .equals ( ECConstants . ZERO ))&&( r1 .equals ( ECConstants . ZERO ))) )
737+ while (( r0 .signum () | r1 .signum ()) != 0 )
764738 {
765- // if r0 is odd
766739 if (r0 .testBit (0 ))
767740 {
768- // uUnMod = r0 + r1*tw mod 2^width
769- BigInteger uUnMod
770- = r0 .add (r1 .multiply (tw )).mod (pow2w );
771-
772- byte uLocal ;
773- // if uUnMod >= 2^(width - 1)
774- if (uUnMod .compareTo (pow2wMin1 ) >= 0 )
775- {
776- uLocal = (byte ) uUnMod .subtract (pow2w ).intValue ();
777- }
778- else
779- {
780- uLocal = (byte ) uUnMod .intValue ();
781- }
782- // uLocal is now in [-2^(width-1), 2^(width-1)-1]
741+ int uUnMod = (r0 .intValue () + (r1 .intValue () * tw )) & (pow2Width - 1 );
783742
784- u [i ] = uLocal ;
785- boolean s = true ;
786- if (uLocal < 0 )
743+ if (uUnMod >= pow2wMin1 )
787744 {
788- s = false ;
789- uLocal = (byte )-uLocal ;
790- }
791- // uLocal is now >= 0
792-
793- if (s )
794- {
795- r0 = r0 .subtract (alpha [uLocal ].u );
796- r1 = r1 .subtract (alpha [uLocal ].v );
745+ u [i ] = (byte )(uUnMod - pow2Width );
746+ r0 = r0 .add (alpha [pow2Width - uUnMod ].u );
747+ r1 = r1 .add (alpha [pow2Width - uUnMod ].v );
797748 }
798749 else
799750 {
800- r0 = r0 .add (alpha [uLocal ].u );
801- r1 = r1 .add (alpha [uLocal ].v );
751+ u [i ] = (byte )uUnMod ;
752+ r0 = r0 .subtract (alpha [uUnMod ].u );
753+ r1 = r1 .subtract (alpha [uUnMod ].v );
802754 }
803755 }
804- else
805- {
806- u [i ] = 0 ;
807- }
808756
809- BigInteger t = r0 ;
757+ ++ i ;
810758
759+ BigInteger t = r0 .shiftRight (1 );
811760 if (mu == 1 )
812761 {
813- r0 = r1 .add (r0 . shiftRight ( 1 ) );
762+ r0 = r1 .add (t );
814763 }
815- else
764+ else // mu == -1
816765 {
817- // mu == -1
818- r0 = r1 .subtract (r0 .shiftRight (1 ));
766+ r0 = r1 .subtract (t );
819767 }
820- r1 = t .shiftRight (1 ).negate ();
821- i ++;
768+ r1 = t .negate ();
822769 }
823770 return u ;
824771 }
0 commit comments