66import org .bouncycastle .crypto .EncapsulatedSecretExtractor ;
77import org .bouncycastle .crypto .params .SAKKEPrivateKeyParameters ;
88import org .bouncycastle .crypto .params .SAKKEPublicKeyParameters ;
9+ import org .bouncycastle .math .ec .ECAlgorithms ;
910import org .bouncycastle .math .ec .ECCurve ;
1011import org .bouncycastle .math .ec .ECPoint ;
1112import org .bouncycastle .util .Arrays ;
@@ -93,9 +94,22 @@ public byte[] extractSecret(byte[] encapsulation)
9394 BigInteger r = SAKKEKEMSGenerator .hashToIntegerRange (Arrays .concatenate (ssv .toByteArray (), b .toByteArray ()), q , digest );
9495
9596 // Step 5: Validate R_bS
96- ECPoint bP = P .multiply (b ).normalize ();
97- ECPoint Test = bP .add (Z_S ).multiply (r ).normalize ();
98- if (!R_bS .equals (Test ))
97+ ECPoint Test ;
98+
99+ BigInteger order = curve .getOrder ();
100+ if (order == null )
101+ {
102+ Test = P .multiply (b ).add (Z_S ).multiply (r );
103+ }
104+ else
105+ {
106+ BigInteger a = b .multiply (r ).mod (order );
107+ Test = ECAlgorithms .sumOfTwoMultiplies (P , a , Z_S , r );
108+ }
109+
110+ Test = Test .subtract (R_bS );
111+
112+ if (!Test .isInfinity ())
99113 {
100114 throw new IllegalStateException ("Validation of R_bS failed" );
101115 }
@@ -122,7 +136,7 @@ public int getEncapsulationLength()
122136 static BigInteger computePairing (ECPoint R , ECPoint Q , BigInteger p , BigInteger q )
123137 {
124138 // v = (1,0) in F_p^2
125- BigInteger [] v = new BigInteger []{BigInteger .ONE , BigInteger .ZERO };
139+ BigInteger [] v = new BigInteger []{ BigInteger .ONE , BigInteger .ZERO };
126140 ECPoint C = R ;
127141
128142 BigInteger qMinusOne = q .subtract (BigInteger .ONE );
@@ -131,23 +145,21 @@ static BigInteger computePairing(ECPoint R, ECPoint Q, BigInteger p, BigInteger
131145 BigInteger Qy = Q .getAffineYCoord ().toBigInteger ();
132146 BigInteger Rx = R .getAffineXCoord ().toBigInteger ();
133147 BigInteger Ry = R .getAffineYCoord ().toBigInteger ();
134- BigInteger l , Cx , Cy ;
135148 final BigInteger three = BigInteger .valueOf (3 );
136- final BigInteger two = BigInteger .valueOf (2 );
137149
138150 // Miller loop
139151 for (int i = numBits - 2 ; i >= 0 ; i --)
140152 {
141- Cx = C .getAffineXCoord ().toBigInteger ();
142- Cy = C .getAffineYCoord ().toBigInteger ();
153+ BigInteger Cx = C .getAffineXCoord ().toBigInteger ();
154+ BigInteger Cy = C .getAffineYCoord ().toBigInteger ();
143155
144156 // Compute l = (3 * (Cx^2 - 1)) / (2 * Cy) mod p
145- l = three .multiply (Cx . multiply ( Cx ).subtract (BigInteger .ONE ))
146- .multiply (Cy . multiply ( two ). modInverse ( p )).mod (p );
157+ BigInteger l = Cx .multiply (Cx ). mod ( p ).subtract (BigInteger .ONE ). multiply ( three )
158+ .multiply (BigIntegers . modOddInverse ( p , Cy . shiftLeft ( 1 ) )).mod (p );
147159
148160 // Compute v = v^2 * ( l*( Q_x + C_x ) + ( i*Q_y - C_y ) )
149161 v = fp2PointSquare (v [0 ], v [1 ], p );
150- v = fp2Multiply (v [0 ], v [1 ], l .multiply (Qx .add (Cx )).subtract (Cy ), Qy , p );
162+ v = fp2Multiply (v [0 ], v [1 ], l .multiply (Qx .add (Cx )).subtract (Cy ). mod ( p ) , Qy , p );
151163
152164 C = C .twice ().normalize (); // C = [2]C
153165
@@ -157,55 +169,56 @@ static BigInteger computePairing(ECPoint R, ECPoint Q, BigInteger p, BigInteger
157169 Cy = C .getAffineYCoord ().toBigInteger ();
158170
159171 // Compute l = (Cy - Ry) / (Cx - Rx) mod p
160- l = Cy .subtract (Ry ).multiply (Cx .subtract (Rx ). modInverse ( p )).mod (p );
172+ l = Cy .subtract (Ry ).multiply (BigIntegers . modOddInverse ( p , Cx .subtract (Rx ))).mod (p );
161173
162174 // Compute v = v * ( l*( Q_x + C_x ) + ( i*Q_y - C_y ) )
163- v = fp2Multiply (v [0 ], v [1 ], l .multiply (Qx .add (Cx )).subtract (Cy ), Qy , p );
175+ v = fp2Multiply (v [0 ], v [1 ], l .multiply (Qx .add (Cx )).subtract (Cy ). mod ( p ) , Qy , p );
164176
165- C = C .add (R ).normalize ();
177+ if (i > 0 )
178+ {
179+ C = C .add (R ).normalize ();
180+ }
166181 }
167182 }
168183
169184 // Final exponentiation: t = v^c
170185 v = fp2PointSquare (v [0 ], v [1 ], p );
171186 v = fp2PointSquare (v [0 ], v [1 ], p );
172- return v [1 ].multiply (v [0 ].modInverse (p )).mod (p );
187+ BigInteger v0Inv = BigIntegers .modOddInverse (p , v [0 ]);
188+ return v [1 ].multiply (v0Inv ).mod (p );
173189 }
174190
175191 /**
176192 * Performs multiplication in F_p^2 field.
177193 *
178- * @param x_real Real component of first operand
179- * @param x_imag Imaginary component of first operand
180- * @param y_real Real component of second operand
181- * @param y_imag Imaginary component of second operand
194+ * @param a0 Real component of first operand
195+ * @param b0 Imaginary component of first operand
196+ * @param a1 Real component of second operand
197+ * @param b1 Imaginary component of second operand
182198 * @param p Prime field characteristic
183199 * @return Result of multiplication in F_p^2 as [real, imaginary] array
184200 */
185- static BigInteger [] fp2Multiply (BigInteger x_real , BigInteger x_imag , BigInteger y_real , BigInteger y_imag , BigInteger p )
201+ static BigInteger [] fp2Multiply (BigInteger a0 , BigInteger b0 , BigInteger a1 , BigInteger b1 , BigInteger p )
186202 {
187203 return new BigInteger []{
188- x_real .multiply (y_real ).subtract (x_imag .multiply (y_imag )).mod (p ),
189- x_real .multiply (y_imag ).add (x_imag .multiply (y_real )).mod (p )
204+ a0 .multiply (a1 ).subtract (b0 .multiply (b1 )).mod (p ),
205+ a0 .multiply (b1 ).add (b0 .multiply (a1 )).mod (p )
190206 };
191207 }
192208
193209 /**
194210 * Computes squaring operation in F_p^2 field.
195211 *
196- * @param currentX Real component of input
197- * @param currentY Imaginary component of input
212+ * @param a Real component of input
213+ * @param b Imaginary component of input
198214 * @param p Prime field characteristic
199215 * @return Squared result in F_p^2 as [newX, newY] array
200216 */
201- static BigInteger [] fp2PointSquare (BigInteger currentX , BigInteger currentY , BigInteger p )
217+ static BigInteger [] fp2PointSquare (BigInteger a , BigInteger b , BigInteger p )
202218 {
203- BigInteger xPlusY = currentX .add (currentY ).mod (p );
204- BigInteger xMinusY = currentX .subtract (currentY ).mod (p );
205- BigInteger newX = xPlusY .multiply (xMinusY ).mod (p );
206-
207- // Compute newY = 2xy mod p
208- BigInteger newY = currentX .multiply (currentY ).multiply (BigInteger .valueOf (2 )).mod (p );
209- return new BigInteger []{newX , newY };
219+ return new BigInteger []{
220+ a .add (b ).multiply (a .subtract (b )).mod (p ),
221+ a .multiply (b ).shiftLeft (1 ).mod (p )
222+ };
210223 }
211224}
0 commit comments