|
25 | 25 |
|
26 | 26 | package sun.security.util.math; |
27 | 27 |
|
| 28 | +import sun.security.util.math.intpoly.IntegerPolynomialP256; |
| 29 | +import sun.security.util.math.intpoly.P256OrderField; |
| 30 | + |
28 | 31 | import java.math.BigInteger; |
29 | 32 |
|
30 | 33 | /** |
@@ -163,7 +166,7 @@ default ImmutableIntegerModuloP multiplicativeInverse() { |
163 | 166 | // might be zero (infinity). However, since the infinity |
164 | 167 | // is represented as (0, 0) in 2D, it's OK returning 0 as |
165 | 168 | // the inverse of 0, i.e. (1, 1, 0) == (1/0, 1/0) == (0, 0). |
166 | | - return pow(getField().getSize().subtract(BigInteger.valueOf(2))); |
| 169 | + return MultiplicativeInverser.of(getField().getSize()).inverse(this); |
167 | 170 | } |
168 | 171 |
|
169 | 172 | /** |
@@ -208,5 +211,201 @@ default ImmutableIntegerModuloP pow(BigInteger b) { |
208 | 211 | return y.fixed(); |
209 | 212 | } |
210 | 213 |
|
211 | | -} |
| 214 | + sealed interface MultiplicativeInverser { |
| 215 | + static MultiplicativeInverser of(BigInteger m) { |
| 216 | + if (m.equals(IntegerPolynomialP256.MODULUS)) { |
| 217 | + return Secp256R1.instance; |
| 218 | + } else if (m.equals(P256OrderField.MODULUS)) { |
| 219 | + return Secp256R1Field.instance; |
| 220 | + } else { |
| 221 | + return new Default(m); |
| 222 | + } |
| 223 | + } |
| 224 | + |
| 225 | + /** |
| 226 | + * Compute the multiplicative inverse of {@code imp}. |
| 227 | + * |
| 228 | + * @return the multiplicative inverse (1 / imp) |
| 229 | + */ |
| 230 | + ImmutableIntegerModuloP inverse(IntegerModuloP imp); |
| 231 | + |
| 232 | + final class Default implements MultiplicativeInverser { |
| 233 | + private final BigInteger b; |
| 234 | + |
| 235 | + Default(BigInteger b) { |
| 236 | + this.b = b.subtract(BigInteger.TWO); |
| 237 | + } |
| 238 | + |
| 239 | + @Override |
| 240 | + public ImmutableIntegerModuloP inverse(IntegerModuloP imp) { |
| 241 | + MutableIntegerModuloP y = imp.getField().get1().mutable(); |
| 242 | + MutableIntegerModuloP x = imp.mutable(); |
| 243 | + int bitLength = b.bitLength(); |
| 244 | + for (int bit = 0; bit < bitLength; bit++) { |
| 245 | + if (b.testBit(bit)) { |
| 246 | + // odd |
| 247 | + y.setProduct(x); |
| 248 | + } |
| 249 | + x.setSquare(); |
| 250 | + } |
| 251 | + |
| 252 | + return y.fixed(); |
| 253 | + } |
| 254 | + } |
| 255 | + |
| 256 | + final class Secp256R1 implements MultiplicativeInverser { |
| 257 | + private static final Secp256R1 instance = new Secp256R1(); |
| 258 | + |
| 259 | + @Override |
| 260 | + public ImmutableIntegerModuloP inverse(IntegerModuloP imp) { |
| 261 | + // Invert imp with a modular exponentiation: the modulus is |
| 262 | + // p = FFFFFFFF 00000001 00000000 00000000 |
| 263 | + // 00000000 FFFFFFFF FFFFFFFF FFFFFFFF |
| 264 | + // and the exponent is (p -2). |
| 265 | + // p -2 = FFFFFFFF 00000001 00000000 00000000 |
| 266 | + // 00000000 FFFFFFFF FFFFFFFF FFFFFFFD |
| 267 | + // |
| 268 | + // There are 3 contiguous 32-bit set, and 1 contiguous 30-bit |
| 269 | + // set. Thus values imp^(2^32 - 1) and imp^(2^30 - 1) are |
| 270 | + // pre-computed to speed up the computation. |
| 271 | + |
| 272 | + // calculate imp ^ (2^32 - 1) |
| 273 | + MutableIntegerModuloP t = imp.mutable(); |
| 274 | + MutableIntegerModuloP v = null; |
| 275 | + MutableIntegerModuloP w = null; |
| 276 | + for (int i = 0; i < 31; i++) { |
| 277 | + t.setSquare(); |
| 278 | + switch (i) { |
| 279 | + case 0 -> { |
| 280 | + t.setProduct(imp); |
| 281 | + v = t.mutable(); // 2: imp ^ (2^2 - 1) |
| 282 | + } |
| 283 | + case 4 -> { |
| 284 | + t.setProduct(v); |
| 285 | + w = t.mutable(); // 4: imp ^ (2^6 - 1) |
| 286 | + } |
| 287 | + case 12, 28 -> { |
| 288 | + t.setProduct(w); |
| 289 | + w = t.mutable(); // 12: imp ^ (2^14 - 1) |
| 290 | + // 28: imp ^ (2^30 - 1) |
| 291 | + } |
| 292 | + case 2, 6, 14, 30 -> { |
| 293 | + t.setProduct(v); |
| 294 | + } |
| 295 | + } |
| 296 | + } |
212 | 297 |
|
| 298 | + // here we have: |
| 299 | + // v = imp ^ (2^2 - 1) |
| 300 | + // w = imp ^ (2^30 - 1) |
| 301 | + // t = imp ^ (2^32 - 1) |
| 302 | + |
| 303 | + // calculate (1 / imp) |
| 304 | + MutableIntegerModuloP d = t.mutable(); |
| 305 | + for (int i = 32; i < 256; i++) { |
| 306 | + d.setSquare(); |
| 307 | + switch (i) { |
| 308 | + // For contiguous 32-bit set. |
| 309 | + case 191, 223 -> { |
| 310 | + d.setProduct(t); |
| 311 | + } |
| 312 | + // For contiguous 30-bit set. |
| 313 | + case 253 -> { |
| 314 | + d.setProduct(w); |
| 315 | + } |
| 316 | + // For individual 1-bit set. |
| 317 | + case 63, 255 -> { |
| 318 | + d.setProduct(imp); |
| 319 | + } |
| 320 | + } |
| 321 | + } |
| 322 | + |
| 323 | + return d.fixed(); |
| 324 | + } |
| 325 | + } |
| 326 | + |
| 327 | + final class Secp256R1Field implements MultiplicativeInverser { |
| 328 | + private static final Secp256R1Field instance = new Secp256R1Field(); |
| 329 | + private static final BigInteger b = |
| 330 | + P256OrderField.MODULUS.subtract(BigInteger.TWO); |
| 331 | + @Override |
| 332 | + public ImmutableIntegerModuloP inverse(IntegerModuloP imp) { |
| 333 | + // Invert imp with a modular exponentiation: the modulus is |
| 334 | + // n = FFFFFFFF 00000000 FFFFFFFF FFFFFFFF |
| 335 | + // BCE6FAAD A7179E84 F3B9CAC2 FC632551 |
| 336 | + // and the exponent is (n -2). |
| 337 | + // n - 2 = FFFFFFFF 00000000 FFFFFFFF FFFFFFFF |
| 338 | + // BCE6FAAD A7179E84 F3B9CAC2 FC63254F |
| 339 | + // |
| 340 | + // There are 3 contiguous 32-bit set, and imp^(2^32 - 1) |
| 341 | + // is pre-computed to speed up the computation. |
| 342 | + |
| 343 | + // calculate and cache imp ^ (2^2 - 1) - imp ^ (2^4 - 1) |
| 344 | + IntegerModuloP[] w = new IntegerModuloP[4]; |
| 345 | + w[0] = imp.fixed(); |
| 346 | + MutableIntegerModuloP t = imp.mutable(); |
| 347 | + for (int i = 1; i < 4; i++) { |
| 348 | + t.setSquare(); |
| 349 | + t.setProduct(imp); |
| 350 | + w[i] = t.fixed(); |
| 351 | + } |
| 352 | + |
| 353 | + // calculate imp ^ (2^32 - 1) |
| 354 | + MutableIntegerModuloP d = null; |
| 355 | + for (int i = 4; i < 32; i++) { |
| 356 | + t.setSquare(); |
| 357 | + switch (i) { |
| 358 | + case 7 -> { |
| 359 | + t.setProduct(w[3]); |
| 360 | + d = t.mutable(); // 7: imp ^ (2^8 - 1) |
| 361 | + } |
| 362 | + case 15 -> { |
| 363 | + t.setProduct(d); |
| 364 | + d = t.mutable(); // 15: imp ^ (2^16 - 1) |
| 365 | + } |
| 366 | + case 31 -> { |
| 367 | + t.setProduct(d); // 31: imp ^ (2^32 - 1) |
| 368 | + } |
| 369 | + } |
| 370 | + } |
| 371 | + |
| 372 | + // Here we have: |
| 373 | + // w[i] = imp ^ (2 ^ ( i + 1) - 1), i = {0, 1, 2, 3} |
| 374 | + // t = imp ^ (2^32 - 1) |
| 375 | + // |
| 376 | + // calculate for bit 32-128, for contiguous 32-bit set. |
| 377 | + d = t.mutable(); |
| 378 | + for (int i = 32; i < 128; i++) { |
| 379 | + d.setSquare(); |
| 380 | + if (i == 95 || i == 127) { |
| 381 | + d.setProduct(t); |
| 382 | + } |
| 383 | + } |
| 384 | + |
| 385 | + // Calculate for bit 128-255, for individual 1-bit set. |
| 386 | + for (int k = -1, i = 127; i >= 0; i--) { |
| 387 | + if (b.testBit(i)) { |
| 388 | + if (k == w.length - 2) { |
| 389 | + // calculate the current & reserved bits |
| 390 | + d.setSquare(); |
| 391 | + d.setProduct(w[w.length - 1]); |
| 392 | + k = -1; |
| 393 | + } else { |
| 394 | + k++; |
| 395 | + d.setSquare(); |
| 396 | + } |
| 397 | + } else { // calculate the reserved bits |
| 398 | + if (k >= 0) { |
| 399 | + // add back the reserved bits |
| 400 | + d.setProduct(w[k]); |
| 401 | + k = -1; |
| 402 | + } |
| 403 | + d.setSquare(); |
| 404 | + } |
| 405 | + } |
| 406 | + |
| 407 | + return d.fixed(); |
| 408 | + } |
| 409 | + } |
| 410 | + } |
| 411 | +} |
0 commit comments