22
33import java .math .BigInteger ;
44
5+ import org .bouncycastle .util .BigIntegers ;
6+
57/**
68 * Class holding methods for point multiplication based on the window
79 * τ-adic nonadjacent form (WTNAF). The algorithms are based on the
@@ -31,12 +33,16 @@ class Tnaf
3133 * The <code>α<sub>u</sub></code>'s for <code>a=0</code> as an array
3234 * of <code>ZTauElement</code>s.
3335 */
34- public static final ZTauElement [] alpha0 = {
35- null ,
36- new ZTauElement (ECConstants .ONE , ECConstants .ZERO ), null ,
37- new ZTauElement (MINUS_THREE , MINUS_ONE ), null ,
38- new ZTauElement (MINUS_ONE , MINUS_ONE ), null ,
39- new ZTauElement (ECConstants .ONE , MINUS_ONE ), null
36+ public static final ZTauElement [] alpha0 =
37+ {
38+ null , new ZTauElement (ECConstants .ONE , ECConstants .ZERO ),
39+ null , new ZTauElement (MINUS_THREE , MINUS_ONE ),
40+ null , new ZTauElement (MINUS_ONE , MINUS_ONE ),
41+ null , new ZTauElement (ECConstants .ONE , MINUS_ONE ),
42+ null , new ZTauElement (MINUS_ONE , ECConstants .ONE ),
43+ null , new ZTauElement (ECConstants .ONE , ECConstants .ONE ),
44+ null , new ZTauElement (ECConstants .THREE , ECConstants .ONE ),
45+ null , new ZTauElement (MINUS_ONE , ECConstants .ZERO ),
4046 };
4147
4248 /**
@@ -51,11 +57,16 @@ class Tnaf
5157 * The <code>α<sub>u</sub></code>'s for <code>a=1</code> as an array
5258 * of <code>ZTauElement</code>s.
5359 */
54- public static final ZTauElement [] alpha1 = {null ,
55- new ZTauElement (ECConstants .ONE , ECConstants .ZERO ), null ,
56- new ZTauElement (MINUS_THREE , ECConstants .ONE ), null ,
57- new ZTauElement (MINUS_ONE , ECConstants .ONE ), null ,
58- new ZTauElement (ECConstants .ONE , ECConstants .ONE ), null
60+ public static final ZTauElement [] alpha1 =
61+ {
62+ null , new ZTauElement (ECConstants .ONE , ECConstants .ZERO ),
63+ null , new ZTauElement (MINUS_THREE , ECConstants .ONE ),
64+ null , new ZTauElement (MINUS_ONE , ECConstants .ONE ),
65+ null , new ZTauElement (ECConstants .ONE , ECConstants .ONE ),
66+ null , new ZTauElement (MINUS_ONE , MINUS_ONE ),
67+ null , new ZTauElement (ECConstants .ONE , MINUS_ONE ),
68+ null , new ZTauElement (ECConstants .THREE , MINUS_ONE ),
69+ null , new ZTauElement (MINUS_ONE , ECConstants .ZERO ),
5970 };
6071
6172 /**
@@ -76,31 +87,29 @@ class Tnaf
7687 */
7788 public static BigInteger norm (final byte mu , ZTauElement lambda )
7889 {
79- BigInteger norm ;
80-
8190 // s1 = u^2
8291 BigInteger s1 = lambda .u .multiply (lambda .u );
8392
8493 // s2 = u * v
85- BigInteger s2 = lambda .u .multiply (lambda .v );
94+ // BigInteger s2 = lambda.u.multiply(lambda.v);
8695
8796 // s3 = 2 * v^2
88- BigInteger s3 = lambda .v .multiply (lambda .v ).shiftLeft (1 );
97+ // BigInteger s3 = lambda.v.multiply(lambda.v).shiftLeft(1);
8998
9099 if (mu == 1 )
91100 {
92- norm = s1 .add (s2 ).add (s3 );
101+ // return s1.add(s2).add(s3);
102+ return lambda .v .shiftLeft (1 ).add (lambda .u ).multiply (lambda .v ).add (s1 );
93103 }
94104 else if (mu == -1 )
95105 {
96- norm = s1 .subtract (s2 ).add (s3 );
106+ // return s1.subtract(s2).add(s3);
107+ return lambda .v .shiftLeft (1 ).subtract (lambda .u ).multiply (lambda .v ).add (s1 );
97108 }
98109 else
99110 {
100111 throw new IllegalArgumentException ("mu must be 1 or -1" );
101112 }
102-
103- return norm ;
104113 }
105114
106115 /**
@@ -650,10 +659,11 @@ public static ECPoint.AbstractF2m multiplyRTnaf(ECPoint.AbstractF2m p, BigIntege
650659 public static ECPoint .AbstractF2m multiplyTnaf (ECPoint .AbstractF2m p , ZTauElement lambda )
651660 {
652661 ECCurve .AbstractF2m curve = (ECCurve .AbstractF2m )p .getCurve ();
662+ ECPoint .AbstractF2m pNeg = (ECPoint .AbstractF2m )p .negate ();
653663 byte mu = getMu (curve .getA ());
654664 byte [] u = tauAdicNaf (mu , lambda );
655665
656- return multiplyFromTnaf (p , u );
666+ return multiplyFromTnaf (p , pNeg , u );
657667 }
658668
659669 /**
@@ -665,11 +675,10 @@ public static ECPoint.AbstractF2m multiplyTnaf(ECPoint.AbstractF2m p, ZTauElemen
665675 * @param u The the TNAF of <code>λ</code>..
666676 * @return <code>λ * p</code>
667677 */
668- public static ECPoint .AbstractF2m multiplyFromTnaf (ECPoint .AbstractF2m p , byte [] u )
678+ public static ECPoint .AbstractF2m multiplyFromTnaf (ECPoint .AbstractF2m p , ECPoint . AbstractF2m pNeg , byte [] u )
669679 {
670680 ECCurve curve = p .getCurve ();
671681 ECPoint .AbstractF2m q = (ECPoint .AbstractF2m )curve .getInfinity ();
672- ECPoint .AbstractF2m pNeg = (ECPoint .AbstractF2m )p .negate ();
673682 int tauCount = 0 ;
674683 for (int i = u .length - 1 ; i >= 0 ; i --)
675684 {
@@ -724,49 +733,71 @@ public static byte[] tauAdicWNaf(byte mu, ZTauElement lambda, int width, int tw,
724733 byte [] u = new byte [maxLength ];
725734
726735 int pow2Width = 1 << width ;
727-
728- // 2^(width - 1)
729- int pow2wMin1 = pow2Width >>> 1 ;
736+ int pow2Mask = pow2Width - 1 ;
737+ int s = 32 - width ;
730738
731739 // Split lambda into two BigIntegers to simplify calculations
732- BigInteger r0 = lambda .u ;
733- BigInteger r1 = lambda .v ;
734- int i = 0 ;
740+ BigInteger R0 = lambda .u ;
741+ BigInteger R1 = lambda .v ;
742+ int uPos = 0 ;
735743
736744 // while lambda <> (0, 0)
737- while (( r0 . signum () | r1 . signum ()) != 0 )
745+ while (R0 . bitLength () > 62 || R1 . bitLength () > 62 )
738746 {
739- if (r0 .testBit (0 ))
747+ if (R0 .testBit (0 ))
740748 {
741- int uUnMod = (r0 .intValue () + (r1 .intValue () * tw )) & (pow2Width - 1 );
749+ int uVal = R0 .intValue () + (R1 .intValue () * tw );
750+ int alphaPos = uVal & pow2Mask ;
742751
743- if (uUnMod >= pow2wMin1 )
744- {
745- u [i ] = (byte )(uUnMod - pow2Width );
746- r0 = r0 .add (alpha [pow2Width - uUnMod ].u );
747- r1 = r1 .add (alpha [pow2Width - uUnMod ].v );
748- }
749- else
750- {
751- u [i ] = (byte )uUnMod ;
752- r0 = r0 .subtract (alpha [uUnMod ].u );
753- r1 = r1 .subtract (alpha [uUnMod ].v );
754- }
752+ u [uPos ] = (byte )((uVal << s ) >> s );
753+ R0 = R0 .subtract (alpha [alphaPos ].u );
754+ R1 = R1 .subtract (alpha [alphaPos ].v );
755755 }
756756
757- ++i ;
757+ ++uPos ;
758758
759- BigInteger t = r0 .shiftRight (1 );
759+ BigInteger t = R0 .shiftRight (1 );
760760 if (mu == 1 )
761761 {
762- r0 = r1 .add (t );
762+ R0 = R1 .add (t );
763763 }
764764 else // mu == -1
765765 {
766- r0 = r1 .subtract (t );
766+ R0 = R1 .subtract (t );
767767 }
768- r1 = t .negate ();
768+ R1 = t .negate ();
769769 }
770+
771+ long r0_64 = BigIntegers .longValueExact (R0 );
772+ long r1_64 = BigIntegers .longValueExact (R1 );
773+
774+ // while lambda <> (0, 0)
775+ while ((r0_64 | r1_64 ) != 0L )
776+ {
777+ if ((r0_64 & 1L ) != 0L )
778+ {
779+ int uVal = (int )r0_64 + ((int )r1_64 * tw );
780+ int alphaPos = uVal & pow2Mask ;
781+
782+ u [uPos ] = (byte )((uVal << s ) >> s );
783+ r0_64 -= alpha [alphaPos ].u .intValue ();
784+ r1_64 -= alpha [alphaPos ].v .intValue ();
785+ }
786+
787+ ++uPos ;
788+
789+ long t_64 = r0_64 >> 1 ;
790+ if (mu == 1 )
791+ {
792+ r0_64 = r1_64 + t_64 ;
793+ }
794+ else // mu == -1
795+ {
796+ r0_64 = r1_64 - t_64 ;
797+ }
798+ r1_64 = -t_64 ;
799+ }
800+
770801 return u ;
771802 }
772803
@@ -778,6 +809,7 @@ public static byte[] tauAdicWNaf(byte mu, ZTauElement lambda, int width, int tw,
778809 */
779810 public static ECPoint .AbstractF2m [] getPreComp (ECPoint .AbstractF2m p , byte a )
780811 {
812+ ECPoint .AbstractF2m pNeg = (ECPoint .AbstractF2m )p .negate ();
781813 byte [][] alphaTnaf = (a == 0 ) ? Tnaf .alpha0Tnaf : Tnaf .alpha1Tnaf ;
782814
783815 ECPoint .AbstractF2m [] pu = new ECPoint .AbstractF2m [(alphaTnaf .length + 1 ) >>> 1 ];
@@ -786,7 +818,7 @@ public static ECPoint.AbstractF2m[] getPreComp(ECPoint.AbstractF2m p, byte a)
786818 int precompLen = alphaTnaf .length ;
787819 for (int i = 3 ; i < precompLen ; i += 2 )
788820 {
789- pu [i >>> 1 ] = Tnaf .multiplyFromTnaf (p , alphaTnaf [i ]);
821+ pu [i >>> 1 ] = Tnaf .multiplyFromTnaf (p , pNeg , alphaTnaf [i ]);
790822 }
791823
792824 p .getCurve ().normalizeAll (pu );
0 commit comments