diff options
author | Peter Dettman <peter.dettman@bouncycastle.org> | 2014-03-03 18:09:40 +0400 |
---|---|---|
committer | Peter Dettman <peter.dettman@bouncycastle.org> | 2014-03-03 18:09:40 +0400 |
commit | cbbc76fd0a6884eb308b66ecf41cab7b3868fc12 (patch) | |
tree | 72d229a5d80336bb0f808096d411cb39ac00034c /core/src/main/java/org | |
parent | a82d1f6bf794088c7d0b4d6fba80398a3a3307a7 (diff) |
Refactoring in the Nat* classes and some new method variations
Improved reduction in some fields
Diffstat (limited to 'core/src/main/java/org')
14 files changed, 631 insertions, 184 deletions
diff --git a/core/src/main/java/org/bouncycastle/math/ec/Nat.java b/core/src/main/java/org/bouncycastle/math/ec/Nat.java index 2cf00c59..75d9de19 100644 --- a/core/src/main/java/org/bouncycastle/math/ec/Nat.java +++ b/core/src/main/java/org/bouncycastle/math/ec/Nat.java @@ -44,18 +44,28 @@ public abstract class Nat return (int)c; } - // TODO Re-write to allow full range for x? - public static int addDWord(int len, long x, int[] z, int zOff) + public static int addDWordAt(int len, long x, int[] z, int zPos) { - // assert zOff <= (len - 2); - long c = x; - c += (z[zOff + 0] & M); - z[zOff + 0] = (int)c; + // assert zPos <= (len - 2); + long c = (z[zPos + 0] & M) + (x & M); + z[zPos + 0] = (int)c; c >>>= 32; - c += (z[zOff + 1] & M); - z[zOff + 1] = (int)c; + c += (z[zPos + 1] & M) + (x >>> 32); + z[zPos + 1] = (int)c; c >>>= 32; - return c == 0 ? 0 : inc(len, z, zOff + 2); + return c == 0 ? 0 : incAt(len, z, zPos + 2); + } + + public static int addTo(int len, int[] x, int[] z) + { + long c = 0; + for (int i = 0; i < len; ++i) + { + c += (x[i] & M) + (z[i] & M); + z[i] = (int)c; + c >>>= 32; + } + return (int)c; } public static int addTo(int len, int[] x, int xOff, int[] z, int zOff) @@ -70,23 +80,22 @@ public abstract class Nat return (int)c; } - public static int addWord(int len, int x, int[] z, int zOff) + public static int addWordAt(int len, int x, int[] z, int zPos) { - // assert zOff < len; - long c = (x & M) + (z[zOff + 0] & M); - z[zOff + 0] = (int)c; + // assert zPos <= (len - 1); + long c = (x & M) + (z[zPos] & M); + z[zPos] = (int)c; c >>>= 32; - return c == 0 ? 0 : inc(len, z, zOff + 1); + return c == 0 ? 0 : incAt(len, z, zPos + 1); } - public static int addWordExt(int len, int x, int[] zz, int zzOff) + public static int addWordAt(int len, int x, int[] z, int zOff, int zPos) { - int extLen = len << 1; - // assert zzOff < extLen; - long c = (x & M) + (zz[zzOff + 0] & M); - zz[zzOff + 0] = (int)c; + // assert zPos <= (len - 1); + long c = (x & M) + (z[zOff + zPos] & M); + z[zOff + zPos] = (int)c; c >>>= 32; - return c == 0 ? 0 : inc(extLen, zz, zzOff + 1); + return c == 0 ? 0 : incAt(len, z, zOff, zPos + 1); } public static int[] copy(int len, int[] x) @@ -106,10 +115,38 @@ public abstract class Nat return new int[len]; } - public static int dec(int len, int[] z, int zOff) + public static int dec(int len, int[] z) + { + for (int i = 0; i < len; ++i) + { + if (--z[i] != -1) + { + return 0; + } + } + return -1; + } + + public static int dec(int len, int[] x, int[] z) + { + int i = 0; + while (i < len) + { + int c = x[i] - 1; + z[i++] = c; + if (c != -1) + { + System.arraycopy(x, i, z, i, len - i); + return 0; + } + } + return -1; + } + + public static int decAt(int len, int[] z, int zPos) { - // assert zOff <= len; - for (int i = zOff; i < len; ++i) + // assert zPos <= len; + for (int i = zPos; i < len; ++i) { if (--z[i] != -1) { @@ -119,6 +156,19 @@ public abstract class Nat return -1; } + public static int decAt(int len, int[] z, int zOff, int zPos) + { + // assert zPos <= len; + for (int i = zPos; i < len; ++i) + { + if (--z[zOff + i] != -1) + { + return 0; + } + } + return -1; + } + public static boolean eq(int len, int[] x, int[] y) { for (int i = len - 1; i >= 0; --i) @@ -178,10 +228,38 @@ public abstract class Nat return true; } - public static int inc(int len, int[] z, int zOff) + public static int inc(int len, int[] z) + { + for (int i = 0; i < len; ++i) + { + if (++z[i] != 0) + { + return 0; + } + } + return 1; + } + + public static int inc(int len, int[] x, int[] z) + { + int i = 0; + while (i < len) + { + int c = x[i] + 1; + z[i++] = c; + if (c != 0) + { + System.arraycopy(x, i, z, i, len - i); + return 0; + } + } + return 1; + } + + public static int incAt(int len, int[] z, int zPos) { - // assert zOff <= len; - for (int i = zOff; i < len; ++i) + // assert zPos <= len; + for (int i = zPos; i < len; ++i) { if (++z[i] != 0) { @@ -191,6 +269,19 @@ public abstract class Nat return 1; } + public static int incAt(int len, int[] z, int zOff, int zPos) + { + // assert zPos <= len; + for (int i = zPos; i < len; ++i) + { + if (++z[zOff + i] != 0) + { + return 0; + } + } + return 1; + } + public static boolean isOne(int len, int[] x) { if (x[0] != 1) @@ -231,7 +322,7 @@ public abstract class Nat public static void mul(int len, int[] x, int xOff, int[] y, int yOff, int[] zz, int zzOff) { - zz[zzOff + len] = mulWord(len, x[xOff + 0], y, yOff, zz, zzOff); + zz[zzOff + len] = mulWord(len, x[xOff], y, yOff, zz, zzOff); for (int i = 1; i < len; ++i) { @@ -295,20 +386,20 @@ public abstract class Nat return (int)c; } - public static int mulWordDwordAdd(int len, int x, long y, int[] z, int zOff) + public static int mulWordDwordAddAt(int len, int x, long y, int[] z, int zPos) { - // assert zOff <= (len - 3); + // assert zPos <= (len - 3); long c = 0, xVal = x & M; - c += xVal * (y & M) + (z[zOff + 0] & M); - z[zOff + 0] = (int)c; + c += xVal * (y & M) + (z[zPos + 0] & M); + z[zPos + 0] = (int)c; c >>>= 32; - c += xVal * (y >>> 32) + (z[zOff + 1] & M); - z[zOff + 1] = (int)c; + c += xVal * (y >>> 32) + (z[zPos + 1] & M); + z[zPos + 1] = (int)c; c >>>= 32; - c += (z[zOff + 2] & M); - z[zOff + 2] = (int)c; + c += (z[zPos + 2] & M); + z[zPos + 2] = (int)c; c >>>= 32; - return c == 0 ? 0 : inc(len, z, zOff + 3); + return c == 0 ? 0 : incAt(len, z, zPos + 3); } public static int shiftDownBit(int len, int[] z, int c) @@ -323,6 +414,18 @@ public abstract class Nat return c << 31; } + public static int shiftDownBit(int len, int[] z, int zOff, int c) + { + int i = len; + while (--i >= 0) + { + int next = z[zOff + i]; + z[zOff + i] = (next >>> 1) | (c << 31); + c = next; + } + return c << 31; + } + public static int shiftDownBit(int len, int[] x, int c, int[] z) { int i = len; @@ -335,6 +438,18 @@ public abstract class Nat return c << 31; } + public static int shiftDownBit(int len, int[] x, int xOff, int c, int[] z, int zOff) + { + int i = len; + while (--i >= 0) + { + int next = x[xOff + i]; + z[zOff + i] = (next >>> 1) | (c << 31); + c = next; + } + return c << 31; + } + public static int shiftDownBits(int len, int[] z, int bits, int c) { // assert bits > 0 && bits < 32; @@ -348,19 +463,45 @@ public abstract class Nat return c << -bits; } - public static int shiftDownBits(int len, int[] x, int xOff, int bits, int c, int[] z) + public static int shiftDownBits(int len, int[] z, int zOff, int bits, int c) { // assert bits > 0 && bits < 32; int i = len; while (--i >= 0) { - int next = x[xOff + i]; + int next = z[zOff + i]; + z[zOff + i] = (next >>> bits) | (c << -bits); + c = next; + } + return c << -bits; + } + + public static int shiftDownBits(int len, int[] x, int bits, int c, int[] z) + { +// assert bits > 0 && bits < 32; + int i = len; + while (--i >= 0) + { + int next = x[i]; z[i] = (next >>> bits) | (c << -bits); c = next; } return c << -bits; } + public static int shiftDownBits(int len, int[] x, int xOff, int bits, int c, int[] z, int zOff) + { +// assert bits > 0 && bits < 32; + int i = len; + while (--i >= 0) + { + int next = x[xOff + i]; + z[zOff + i] = (next >>> bits) | (c << -bits); + c = next; + } + return c << -bits; + } + public static int shiftDownWord(int len, int[] z, int c) { int i = len; @@ -406,12 +547,12 @@ public abstract class Nat return c >>> 31; } - public static int shiftUpBit(int len, int[] x, int xOff, int c, int[] z) + public static int shiftUpBit(int len, int[] x, int xOff, int c, int[] z, int zOff) { for (int i = 0; i < len; ++i) { int next = x[xOff + i]; - z[i] = (next << 1) | (c >>> 31); + z[zOff + i] = (next << 1) | (c >>> 31); c = next; } return c >>> 31; @@ -429,6 +570,18 @@ public abstract class Nat return c >>> -bits; } + public static int shiftUpBits(int len, int[] z, int zOff, int bits, int c) + { +// assert bits > 0 && bits < 32; + for (int i = 0; i < len; ++i) + { + int next = z[zOff + i]; + z[zOff + i] = (next << bits) | (c >>> -bits); + c = next; + } + return c >>> -bits; + } + public static int shiftUpBits(int len, int[] x, int bits, int c, int[] z) { // assert bits > 0 && bits < 32; @@ -441,6 +594,18 @@ public abstract class Nat return c >>> -bits; } + public static int shiftUpBits(int len, int[] x, int xOff, int bits, int c, int[] z, int zOff) + { +// assert bits > 0 && bits < 32; + for (int i = 0; i < len; ++i) + { + int next = x[xOff + i]; + z[zOff + i] = (next << bits) | (c >>> -bits); + c = next; + } + return c >>> -bits; + } + public static void square(int len, int[] x, int[] zz) { int extLen = len << 1; @@ -459,12 +624,36 @@ public abstract class Nat for (int i = 1; i < len; ++i) { c = squareWordAdd(x, i, zz); - addWordExt(len, c, zz, i << 1); + addWordAt(extLen, c, zz, i << 1); } shiftUpBit(extLen, zz, x[0] << 31); } + public static void square(int len, int[] x, int xOff, int[] zz, int zzOff) + { + int extLen = len << 1; + int c = 0; + int j = len, k = extLen; + do + { + long xVal = (x[xOff + --j] & M); + long p = xVal * xVal; + zz[zzOff + --k] = (c << 31) | (int)(p >>> 33); + zz[zzOff + --k] = (int)(p >>> 1); + c = (int)p; + } + while (j > 0); + + for (int i = 1; i < len; ++i) + { + c = squareWordAdd(x, xOff, i, zz, zzOff); + addWordAt(extLen, c, zz, zzOff, i << 1); + } + + shiftUpBit(extLen, zz, zzOff, x[xOff] << 31); + } + public static int squareWordAdd(int[] x, int xPos, int[] z) { long c = 0, xVal = x[xPos] & M; @@ -479,6 +668,21 @@ public abstract class Nat return (int)c; } + public static int squareWordAdd(int[] x, int xOff, int xPos, int[] z, int zOff) + { + long c = 0, xVal = x[xOff + xPos] & M; + int i = 0; + do + { + c += xVal * (x[xOff + i] & M) + (z[xPos + zOff] & M); + z[xPos + zOff] = (int)c; + c >>>= 32; + ++zOff; + } + while (++i < xPos); + return (int)c; + } + public static int sub(int len, int[] x, int[] y, int[] z) { long c = 0; @@ -491,6 +695,18 @@ public abstract class Nat return (int)c; } + public static int sub(int len, int[] x, int xOff, int[] y, int yOff, int[] z, int zOff) + { + long c = 0; + for (int i = 0; i < len; ++i) + { + c += (x[xOff + i] & M) - (y[yOff + i] & M); + z[zOff + i] = (int)c; + c >>= 32; + } + return (int)c; + } + public static int subBothFrom(int len, int[] x, int[] y, int[] z) { long c = 0; @@ -515,18 +731,28 @@ public abstract class Nat return (int)c; } - // TODO Re-write to allow full range for x? - public static int subDWord(int len, long x, int[] z) + public static int subDWordAt(int len, long x, int[] z, int zPos) { - // assert 0 <= (len - 2); - long c = -x; - c += (z[0] & M); - z[0] = (int)c; + // assert zPos <= (len - 2); + long c = (z[zPos + 0] & M) - (x & M); + z[zPos + 0] = (int)c; c >>= 32; - c += (z[1] & M); - z[1] = (int)c; + c += (z[zPos + 1] & M) - (x >>> 32); + z[zPos + 1] = (int)c; c >>= 32; - return c == 0 ? 0 : dec(len, z, 2); + return c == 0 ? 0 : decAt(len, z, zPos + 2); + } + + public static int subFrom(int len, int[] x, int[] z) + { + long c = 0; + for (int i = 0; i < len; ++i) + { + c += (z[i] & M) - (x[i] & M); + z[i] = (int)c; + c >>= 32; + } + return (int)c; } public static int subFrom(int len, int[] x, int xOff, int[] z, int zOff) @@ -541,6 +767,24 @@ public abstract class Nat return (int)c; } + public static int subWordAt(int len, int x, int[] z, int zPos) + { + // assert zPos <= (len - 1); + long c = (z[zPos] & M) - (x & M); + z[zPos] = (int)c; + c >>= 32; + return c == 0 ? 0 : decAt(len, z, zPos + 1); + } + + public static int subWordAt(int len, int x, int[] z, int zOff, int zPos) + { + // assert zPos <= (len - 1); + long c = (z[zOff + zPos] & M) - (x & M); + z[zOff + zPos] = (int)c; + c >>= 32; + return c == 0 ? 0 : decAt(len, z, zOff, zPos + 1); + } + public static BigInteger toBigInteger(int len, int[] x) { byte[] bs = new byte[len << 2]; diff --git a/core/src/main/java/org/bouncycastle/math/ec/custom/sec/Curve25519Field.java b/core/src/main/java/org/bouncycastle/math/ec/custom/sec/Curve25519Field.java index 5cf9fea8..6e38b34e 100644 --- a/core/src/main/java/org/bouncycastle/math/ec/custom/sec/Curve25519Field.java +++ b/core/src/main/java/org/bouncycastle/math/ec/custom/sec/Curve25519Field.java @@ -48,10 +48,9 @@ public class Curve25519Field public static int[] fromBigInteger(BigInteger x) { int[] z = Nat256.fromBigInteger(x); - if (Nat256.gte(z, P)) + while (Nat256.gte(z, P)) { - Nat256.addWord(PInv, z, 0); - z[7] &= P7; + Nat256.subFrom(P, z); } return z; } @@ -93,7 +92,7 @@ public class Curve25519Field // assert xx[15] >>> 30 == 0; int xx07 = xx[7]; - Nat.shiftUpBit(8, xx, 8, xx07, z); + Nat.shiftUpBit(8, xx, 8, xx07, z, 0); int c = Nat256.mulByWordAddTo(PInv, xx, z) << 1; int z07 = z[7]; z[7] = z07 & P7; diff --git a/core/src/main/java/org/bouncycastle/math/ec/custom/sec/Nat192.java b/core/src/main/java/org/bouncycastle/math/ec/custom/sec/Nat192.java index e97ee574..65430adc 100644 --- a/core/src/main/java/org/bouncycastle/math/ec/custom/sec/Nat192.java +++ b/core/src/main/java/org/bouncycastle/math/ec/custom/sec/Nat192.java @@ -82,6 +82,30 @@ public abstract class Nat192 return (int)c; } + public static int addTo(int[] x, int[] z) + { + long c = 0; + c += (x[0] & M) + (z[0] & M); + z[0] = (int)c; + c >>>= 32; + c += (x[1] & M) + (z[1] & M); + z[1] = (int)c; + c >>>= 32; + c += (x[2] & M) + (z[2] & M); + z[2] = (int)c; + c >>>= 32; + c += (x[3] & M) + (z[3] & M); + z[3] = (int)c; + c >>>= 32; + c += (x[4] & M) + (z[4] & M); + z[4] = (int)c; + c >>>= 32; + c += (x[5] & M) + (z[5] & M); + z[5] = (int)c; + c >>>= 32; + return (int)c; + } + public static int addTo(int[] x, int xOff, int[] z, int zOff, int cIn) { long c = cIn & M; @@ -1057,27 +1081,50 @@ public abstract class Nat192 return (int)c; } - public static int subFromExt(int[] x, int xOff, int[] zz, int zzOff) + public static int subFrom(int[] x, int[] z) { - // assert zzOff <= 6; long c = 0; - c += (zz[zzOff + 0] & M) - (x[xOff + 0] & M); - zz[zzOff + 0] = (int)c; + c += (z[0] & M) - (x[0] & M); + z[0] = (int)c; c >>= 32; - c += (zz[zzOff + 1] & M) - (x[xOff + 1] & M); - zz[zzOff + 1] = (int)c; + c += (z[1] & M) - (x[1] & M); + z[1] = (int)c; c >>= 32; - c += (zz[zzOff + 2] & M) - (x[xOff + 2] & M); - zz[zzOff + 2] = (int)c; + c += (z[2] & M) - (x[2] & M); + z[2] = (int)c; c >>= 32; - c += (zz[zzOff + 3] & M) - (x[xOff + 3] & M); - zz[zzOff + 3] = (int)c; + c += (z[3] & M) - (x[3] & M); + z[3] = (int)c; c >>= 32; - c += (zz[zzOff + 4] & M) - (x[xOff + 4] & M); - zz[zzOff + 4] = (int)c; + c += (z[4] & M) - (x[4] & M); + z[4] = (int)c; c >>= 32; - c += (zz[zzOff + 5] & M) - (x[xOff + 5] & M); - zz[zzOff + 5] = (int)c; + c += (z[5] & M) - (x[5] & M); + z[5] = (int)c; + c >>= 32; + return (int)c; + } + + public static int subFrom(int[] x, int xOff, int[] z, int zOff) + { + long c = 0; + c += (z[zOff + 0] & M) - (x[xOff + 0] & M); + z[zOff + 0] = (int)c; + c >>= 32; + c += (z[zOff + 1] & M) - (x[xOff + 1] & M); + z[zOff + 1] = (int)c; + c >>= 32; + c += (z[zOff + 2] & M) - (x[xOff + 2] & M); + z[zOff + 2] = (int)c; + c >>= 32; + c += (z[zOff + 3] & M) - (x[xOff + 3] & M); + z[zOff + 3] = (int)c; + c >>= 32; + c += (z[zOff + 4] & M) - (x[xOff + 4] & M); + z[zOff + 4] = (int)c; + c >>= 32; + c += (z[zOff + 5] & M) - (x[xOff + 5] & M); + z[zOff + 5] = (int)c; c >>= 32; return (int)c; } diff --git a/core/src/main/java/org/bouncycastle/math/ec/custom/sec/Nat224.java b/core/src/main/java/org/bouncycastle/math/ec/custom/sec/Nat224.java index 19c1b1f7..7bd29cb7 100644 --- a/core/src/main/java/org/bouncycastle/math/ec/custom/sec/Nat224.java +++ b/core/src/main/java/org/bouncycastle/math/ec/custom/sec/Nat224.java @@ -142,6 +142,33 @@ public abstract class Nat224 return (int)c; } + public static int addTo(int[] x, int[] z) + { + long c = 0; + c += (x[0] & M) + (z[0] & M); + z[0] = (int)c; + c >>>= 32; + c += (x[1] & M) + (z[1] & M); + z[1] = (int)c; + c >>>= 32; + c += (x[2] & M) + (z[2] & M); + z[2] = (int)c; + c >>>= 32; + c += (x[3] & M) + (z[3] & M); + z[3] = (int)c; + c >>>= 32; + c += (x[4] & M) + (z[4] & M); + z[4] = (int)c; + c >>>= 32; + c += (x[5] & M) + (z[5] & M); + z[5] = (int)c; + c >>>= 32; + c += (x[6] & M) + (z[6] & M); + z[6] = (int)c; + c >>>= 32; + return (int)c; + } + public static int addTo(int[] x, int xOff, int[] z, int zOff, int cIn) { long c = cIn & M; @@ -1253,30 +1280,56 @@ public abstract class Nat224 return (int)c; } - public static int subFromExt(int[] x, int xOff, int[] zz, int zzOff) + public static int subFrom(int[] x, int[] z) { - // assert zzOff <= 7; long c = 0; - c += (zz[zzOff + 0] & M) - (x[xOff + 0] & M); - zz[zzOff + 0] = (int)c; + c += (z[0] & M) - (x[0] & M); + z[0] = (int)c; + c >>= 32; + c += (z[1] & M) - (x[1] & M); + z[1] = (int)c; c >>= 32; - c += (zz[zzOff + 1] & M) - (x[xOff + 1] & M); - zz[zzOff + 1] = (int)c; + c += (z[2] & M) - (x[2] & M); + z[2] = (int)c; + c >>= 32; + c += (z[3] & M) - (x[3] & M); + z[3] = (int)c; c >>= 32; - c += (zz[zzOff + 2] & M) - (x[xOff + 2] & M); - zz[zzOff + 2] = (int)c; + c += (z[4] & M) - (x[4] & M); + z[4] = (int)c; c >>= 32; - c += (zz[zzOff + 3] & M) - (x[xOff + 3] & M); - zz[zzOff + 3] = (int)c; + c += (z[5] & M) - (x[5] & M); + z[5] = (int)c; c >>= 32; - c += (zz[zzOff + 4] & M) - (x[xOff + 4] & M); - zz[zzOff + 4] = (int)c; + c += (z[6] & M) - (x[6] & M); + z[6] = (int)c; c >>= 32; - c += (zz[zzOff + 5] & M) - (x[xOff + 5] & M); - zz[zzOff + 5] = (int)c; + return (int)c; + } + + public static int subFrom(int[] x, int xOff, int[] z, int zOff) + { + long c = 0; + c += (z[zOff + 0] & M) - (x[xOff + 0] & M); + z[zOff + 0] = (int)c; c >>= 32; - c += (zz[zzOff + 6] & M) - (x[xOff + 6] & M); - zz[zzOff + 6] = (int)c; + c += (z[zOff + 1] & M) - (x[xOff + 1] & M); + z[zOff + 1] = (int)c; + c >>= 32; + c += (z[zOff + 2] & M) - (x[xOff + 2] & M); + z[zOff + 2] = (int)c; + c >>= 32; + c += (z[zOff + 3] & M) - (x[xOff + 3] & M); + z[zOff + 3] = (int)c; + c >>= 32; + c += (z[zOff + 4] & M) - (x[xOff + 4] & M); + z[zOff + 4] = (int)c; + c >>= 32; + c += (z[zOff + 5] & M) - (x[xOff + 5] & M); + z[zOff + 5] = (int)c; + c >>= 32; + c += (z[zOff + 6] & M) - (x[xOff + 6] & M); + z[zOff + 6] = (int)c; c >>= 32; return (int)c; } diff --git a/core/src/main/java/org/bouncycastle/math/ec/custom/sec/Nat256.java b/core/src/main/java/org/bouncycastle/math/ec/custom/sec/Nat256.java index 279e3bc5..cb8ec7c8 100644 --- a/core/src/main/java/org/bouncycastle/math/ec/custom/sec/Nat256.java +++ b/core/src/main/java/org/bouncycastle/math/ec/custom/sec/Nat256.java @@ -68,6 +68,17 @@ public abstract class Nat256 return (int)c; } + public static int add33To(int x, int[] z) + { + long c = (z[0] & M) + (x & M); + z[0] = (int)c; + c >>>= 32; + c += (z[1] & M) + 1L; + z[1] = (int)c; + c >>>= 32; + return c == 0 ? 0 : inc(z, 2); + } + public static int addBothTo(int[] x, int[] y, int[] z) { long c = 0; @@ -128,18 +139,16 @@ public abstract class Nat256 return (int)c; } - // TODO Re-write to allow full range for x? - public static int addDWord(long x, int[] z, int zOff) + public static int addDWordAt(long x, int[] z, int zPos) { - // assert zOff <= 6; - long c = x; - c += (z[zOff + 0] & M); - z[zOff + 0] = (int)c; + // assert zPos <= 6; + long c = (z[zPos + 0] & M) + (x & M); + z[zPos + 0] = (int)c; c >>>= 32; - c += (z[zOff + 1] & M); - z[zOff + 1] = (int)c; + c += (z[zPos + 1] & M) + (x >>> 32); + z[zPos + 1] = (int)c; c >>>= 32; - return c == 0 ? 0 : inc(z, zOff + 2); + return c == 0 ? 0 : inc(z, zPos + 2); } public static int addExt(int[] xx, int[] yy, int[] zz) @@ -154,6 +163,36 @@ public abstract class Nat256 return (int)c; } + public static int addTo(int[] x, int[] z) + { + long c = 0; + c += (x[0] & M) + (z[0] & M); + z[0] = (int)c; + c >>>= 32; + c += (x[1] & M) + (z[1] & M); + z[1] = (int)c; + c >>>= 32; + c += (x[2] & M) + (z[2] & M); + z[2] = (int)c; + c >>>= 32; + c += (x[3] & M) + (z[3] & M); + z[3] = (int)c; + c >>>= 32; + c += (x[4] & M) + (z[4] & M); + z[4] = (int)c; + c >>>= 32; + c += (x[5] & M) + (z[5] & M); + z[5] = (int)c; + c >>>= 32; + c += (x[6] & M) + (z[6] & M); + z[6] = (int)c; + c >>>= 32; + c += (x[7] & M) + (z[7] & M); + z[7] = (int)c; + c >>>= 32; + return (int)c; + } + public static int addTo(int[] x, int xOff, int[] z, int zOff, int cIn) { long c = cIn & M; @@ -1304,6 +1343,17 @@ public abstract class Nat256 return (int)c; } + public static int sub33From(int x, int[] z) + { + long c = (z[0] & M) - (x & M); + z[0] = (int)c; + c >>= 32; + c += (z[1] & M) - 1; + z[1] = (int)c; + c >>= 32; + return c == 0 ? 0 : dec(z, 2); + } + public static int subBothFrom(int[] x, int[] y, int[] z) { long c = 0; @@ -1334,17 +1384,16 @@ public abstract class Nat256 return (int)c; } - // TODO Re-write to allow full range for x? - public static int subDWord(long x, int[] z) + public static int subDWordAt(long x, int[] z, int zPos) { - long c = -x; - c += (z[0] & M); - z[0] = (int)c; + // assert zPos <= 6; + long c = (z[zPos + 0] & M) - (x & M); + z[zPos + 0] = (int)c; c >>= 32; - c += (z[1] & M); - z[1] = (int)c; + c += (z[zPos + 1] & M) - (x >>> 32); + z[zPos + 1] = (int)c; c >>= 32; - return c == 0 ? 0 : dec(z, 2); + return c == 0 ? 0 : dec(z, zPos + 2); } public static int subExt(int[] xx, int[] yy, int[] zz) @@ -1359,33 +1408,62 @@ public abstract class Nat256 return (int)c; } - public static int subFromExt(int[] x, int xOff, int[] zz, int zzOff) + public static int subFrom(int[] x, int[] z) { - // assert zzOff <= 8; long c = 0; - c += (zz[zzOff + 0] & M) - (x[xOff + 0] & M); - zz[zzOff + 0] = (int)c; + c += (z[0] & M) - (x[0] & M); + z[0] = (int)c; + c >>= 32; + c += (z[1] & M) - (x[1] & M); + z[1] = (int)c; c >>= 32; - c += (zz[zzOff + 1] & M) - (x[xOff + 1] & M); - zz[zzOff + 1] = (int)c; + c += (z[2] & M) - (x[2] & M); + z[2] = (int)c; c >>= 32; - c += (zz[zzOff + 2] & M) - (x[xOff + 2] & M); - zz[zzOff + 2] = (int)c; + c += (z[3] & M) - (x[3] & M); + z[3] = (int)c; c >>= 32; - c += (zz[zzOff + 3] & M) - (x[xOff + 3] & M); - zz[zzOff + 3] = (int)c; + c += (z[4] & M) - (x[4] & M); + z[4] = (int)c; c >>= 32; - c += (zz[zzOff + 4] & M) - (x[xOff + 4] & M); - zz[zzOff + 4] = (int)c; + c += (z[5] & M) - (x[5] & M); + z[5] = (int)c; c >>= 32; - c += (zz[zzOff + 5] & M) - (x[xOff + 5] & M); - zz[zzOff + 5] = (int)c; + c += (z[6] & M) - (x[6] & M); + z[6] = (int)c; c >>= 32; - c += (zz[zzOff + 6] & M) - (x[xOff + 6] & M); - zz[zzOff + 6] = (int)c; + c += (z[7] & M) - (x[7] & M); + z[7] = (int)c; c >>= 32; - c += (zz[zzOff + 7] & M) - (x[xOff + 7] & M); - zz[zzOff + 7] = (int)c; + return (int)c; + } + + public static int subFrom(int[] x, int xOff, int[] z, int zOff) + { + long c = 0; + c += (z[zOff + 0] & M) - (x[xOff + 0] & M); + z[zOff + 0] = (int)c; + c >>= 32; + c += (z[zOff + 1] & M) - (x[xOff + 1] & M); + z[zOff + 1] = (int)c; + c >>= 32; + c += (z[zOff + 2] & M) - (x[xOff + 2] & M); + z[zOff + 2] = (int)c; + c >>= 32; + c += (z[zOff + 3] & M) - (x[xOff + 3] & M); + z[zOff + 3] = (int)c; + c >>= 32; + c += (z[zOff + 4] & M) - (x[xOff + 4] & M); + z[zOff + 4] = (int)c; + c >>= 32; + c += (z[zOff + 5] & M) - (x[xOff + 5] & M); + z[zOff + 5] = (int)c; + c >>= 32; + c += (z[zOff + 6] & M) - (x[xOff + 6] & M); + z[zOff + 6] = (int)c; + c >>= 32; + c += (z[zOff + 7] & M) - (x[xOff + 7] & M); + z[zOff + 7] = (int)c; c >>= 32; return (int)c; } diff --git a/core/src/main/java/org/bouncycastle/math/ec/custom/sec/Nat384.java b/core/src/main/java/org/bouncycastle/math/ec/custom/sec/Nat384.java index 67e2dd05..1a55e12c 100644 --- a/core/src/main/java/org/bouncycastle/math/ec/custom/sec/Nat384.java +++ b/core/src/main/java/org/bouncycastle/math/ec/custom/sec/Nat384.java @@ -20,7 +20,7 @@ public abstract class Nat384 Nat192.mul(dx, dy, tt); c18 += neg ? Nat.addTo(12, tt, 0, zz, 6) : Nat.subFrom(12, tt, 0, zz, 6); - Nat.addWordExt(12, c18, zz, 18); + Nat.addWordAt(24, c18, zz, 18); } public static void square(int[] x, int[] zz) @@ -39,6 +39,6 @@ public abstract class Nat384 Nat192.square(dx, tt); c18 += Nat.subFrom(12, tt, 0, zz, 6); - Nat.addWordExt(12, c18, zz, 18); + Nat.addWordAt(24, c18, zz, 18); } } diff --git a/core/src/main/java/org/bouncycastle/math/ec/custom/sec/Nat512.java b/core/src/main/java/org/bouncycastle/math/ec/custom/sec/Nat512.java index 957f7109..59399617 100644 --- a/core/src/main/java/org/bouncycastle/math/ec/custom/sec/Nat512.java +++ b/core/src/main/java/org/bouncycastle/math/ec/custom/sec/Nat512.java @@ -20,7 +20,7 @@ public abstract class Nat512 Nat256.mul(dx, dy, tt); c24 += neg ? Nat.addTo(16, tt, 0, zz, 8) : Nat.subFrom(16, tt, 0, zz, 8); - Nat.addWordExt(16, c24, zz, 24); + Nat.addWordAt(32, c24, zz, 24); } public static void square(int[] x, int[] zz) @@ -39,6 +39,6 @@ public abstract class Nat512 Nat256.square(dx, tt); c24 += Nat.subFrom(16, tt, 0, zz, 8); - Nat.addWordExt(16, c24, zz, 24); + Nat.addWordAt(32, c24, zz, 24); } } diff --git a/core/src/main/java/org/bouncycastle/math/ec/custom/sec/SecP192K1Field.java b/core/src/main/java/org/bouncycastle/math/ec/custom/sec/SecP192K1Field.java index e310529d..63d38ad9 100644 --- a/core/src/main/java/org/bouncycastle/math/ec/custom/sec/SecP192K1Field.java +++ b/core/src/main/java/org/bouncycastle/math/ec/custom/sec/SecP192K1Field.java @@ -46,7 +46,7 @@ public class SecP192K1Field int[] z = Nat192.fromBigInteger(x); if (z[5] == P5 && Nat192.gte(z, P)) { - Nat192.addDWord(PInv, z, 0); + Nat192.subFrom(P, z); } return z; } diff --git a/core/src/main/java/org/bouncycastle/math/ec/custom/sec/SecP192R1Field.java b/core/src/main/java/org/bouncycastle/math/ec/custom/sec/SecP192R1Field.java index 7f026009..84cebebe 100644 --- a/core/src/main/java/org/bouncycastle/math/ec/custom/sec/SecP192R1Field.java +++ b/core/src/main/java/org/bouncycastle/math/ec/custom/sec/SecP192R1Field.java @@ -18,7 +18,7 @@ public class SecP192R1Field int c = Nat192.add(x, y, z); if (c != 0 || (z[5] == P5 && Nat192.gte(z, P))) { - Nat192.sub(z, P, z); + Nat192.subFrom(P, z); } } @@ -37,7 +37,7 @@ public class SecP192R1Field int c = Nat192.inc(z, 0); if (c != 0 || (z[5] == P5 && Nat192.gte(z, P))) { - Nat192.sub(z, P, z); + Nat192.subFrom(P, z); } } @@ -46,7 +46,7 @@ public class SecP192R1Field int[] z = Nat192.fromBigInteger(x); if (z[5] == P5 && Nat192.gte(z, P)) { - Nat192.sub(z, P, z); + Nat192.subFrom(P, z); } return z; } @@ -127,7 +127,7 @@ public class SecP192R1Field if ((x != 0 && (Nat192.addWord(x, z, 0) + Nat192.addWord(x, z, 2) != 0)) || (z[5] == P5 && Nat192.gte(z, P))) { - Nat192.sub(z, P, z); + Nat192.subFrom(P, z); } } @@ -158,7 +158,7 @@ public class SecP192R1Field int c = Nat192.sub(x, y, z); if (c != 0) { - Nat192.add(z, P, z); + Nat192.addTo(P, z); } } @@ -176,7 +176,7 @@ public class SecP192R1Field int c = Nat192.shiftUpBit(x, 0, z); if (c != 0 || (z[5] == P5 && Nat192.gte(z, P))) { - Nat192.sub(z, P, z); + Nat192.subFrom(P, z); } } } diff --git a/core/src/main/java/org/bouncycastle/math/ec/custom/sec/SecP224R1Field.java b/core/src/main/java/org/bouncycastle/math/ec/custom/sec/SecP224R1Field.java index ef851d8f..4eabd3a4 100644 --- a/core/src/main/java/org/bouncycastle/math/ec/custom/sec/SecP224R1Field.java +++ b/core/src/main/java/org/bouncycastle/math/ec/custom/sec/SecP224R1Field.java @@ -18,7 +18,7 @@ public class SecP224R1Field int c = Nat224.add(x, y, z); if (c != 0 || (z[6] == P6 && Nat224.gte(z, P))) { - Nat224.sub(z, P, z); + Nat224.subFrom(P, z); } } @@ -37,7 +37,7 @@ public class SecP224R1Field int c = Nat224.inc(z, 0); if (c != 0 || (z[6] == P6 && Nat224.gte(z, P))) { - Nat224.sub(z, P, z); + Nat224.subFrom(P, z); } } @@ -46,7 +46,7 @@ public class SecP224R1Field int[] z = Nat224.fromBigInteger(x); if (z[6] == P6 && Nat224.gte(z, P)) { - Nat224.sub(z, P, z); + Nat224.subFrom(P, z); } return z; } @@ -122,10 +122,7 @@ public class SecP224R1Field } else { - while (c < 0) - { - c += Nat224.add(z, P, z); - } + Nat224.addTo(P, z); } } @@ -134,7 +131,7 @@ public class SecP224R1Field if ((x != 0 && (Nat224.subWord(x, z, 0) + Nat224.addWord(x, z, 3) != 0)) || (z[6] == P6 && Nat224.gte(z, P))) { - Nat224.sub(z, P, z); + Nat224.subFrom(P, z); } } @@ -165,7 +162,7 @@ public class SecP224R1Field int c = Nat224.sub(x, y, z); if (c != 0) { - Nat224.add(z, P, z); + Nat224.addTo(P, z); } } @@ -183,7 +180,7 @@ public class SecP224R1Field int c = Nat224.shiftUpBit(x, 0, z); if (c != 0 || (z[6] == P6 && Nat224.gte(z, P))) { - Nat224.sub(z, P, z); + Nat224.subFrom(P, z); } } } diff --git a/core/src/main/java/org/bouncycastle/math/ec/custom/sec/SecP256K1Field.java b/core/src/main/java/org/bouncycastle/math/ec/custom/sec/SecP256K1Field.java index b4c47fbe..ad92be7f 100644 --- a/core/src/main/java/org/bouncycastle/math/ec/custom/sec/SecP256K1Field.java +++ b/core/src/main/java/org/bouncycastle/math/ec/custom/sec/SecP256K1Field.java @@ -2,17 +2,20 @@ package org.bouncycastle.math.ec.custom.sec; import java.math.BigInteger; +import org.bouncycastle.math.ec.Nat; + public class SecP256K1Field { // 2^256 - 2^32 - 2^9 - 2^8 - 2^7 - 2^6 - 2^4 - 1 static final int[] P = new int[]{ 0xFFFFFC2F, 0xFFFFFFFE, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF }; - private static final int P7 = 0xFFFFFFFF; static final int[] PExt = new int[]{ 0x000E90A1, 0x000007A2, 0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xFFFFF85E, 0xFFFFFFFD, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF }; + private static final int[] PExtInv = new int[]{ 0xFFF16F5F, 0xFFFFF85D, 0xFFFFFFFE, 0xFFFFFFFF, 0xFFFFFFFF, + 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x000007A1, 0x00000002 }; + private static final int P7 = 0xFFFFFFFF; private static final int PExt15 = 0xFFFFFFFF; - private static final long PInv = 0x00000001000003D1L; private static final int PInv33 = 0x3D1; public static void add(int[] x, int[] y, int[] z) @@ -20,7 +23,7 @@ public class SecP256K1Field int c = Nat256.add(x, y, z); if (c != 0 || (z[7] == P7 && Nat256.gte(z, P))) { - Nat256.addDWord(PInv, z, 0); + Nat256.add33To(PInv33, z); } } @@ -29,7 +32,10 @@ public class SecP256K1Field int c = Nat256.addExt(xx, yy, zz); if (c != 0 || (zz[15] == PExt15 && Nat256.gteExt(zz, PExt))) { - Nat256.subExt(zz, PExt, zz); + if (Nat.addTo(PExtInv.length, PExtInv, zz) != 0) + { + Nat256.incExt(zz, PExtInv.length); + } } } @@ -39,7 +45,7 @@ public class SecP256K1Field int c = Nat256.inc(z, 0); if (c != 0 || (z[7] == P7 && Nat256.gte(z, P))) { - Nat256.addDWord(PInv, z, 0); + Nat256.add33To(PInv33, z); } } @@ -48,7 +54,7 @@ public class SecP256K1Field int[] z = Nat256.fromBigInteger(x); if (z[7] == P7 && Nat256.gte(z, P)) { - Nat256.addDWord(PInv, z, 0); + Nat256.subFrom(P, z); } return z; } @@ -94,7 +100,7 @@ public class SecP256K1Field if (c != 0 || (z[7] == P7 && Nat256.gte(z, P))) { - Nat256.addDWord(PInv, z, 0); + Nat256.add33To(PInv33, z); } } @@ -103,7 +109,7 @@ public class SecP256K1Field if ((x != 0 && Nat256.mul33WordAdd(PInv33, x, z, 0) != 0) || (z[7] == P7 && Nat256.gte(z, P))) { - Nat256.addDWord(PInv, z, 0); + Nat256.add33To(PInv33, z); } } @@ -134,7 +140,7 @@ public class SecP256K1Field int c = Nat256.sub(x, y, z); if (c != 0) { - Nat256.subDWord(PInv, z); + Nat256.sub33From(PInv33, z); } } @@ -143,7 +149,10 @@ public class SecP256K1Field int c = Nat256.subExt(xx, yy, zz); if (c != 0) { - Nat256.addExt(zz, PExt, zz); + if (Nat.subFrom(PExtInv.length, PExtInv, zz) != 0) + { + Nat256.decExt(zz, PExtInv.length); + } } } @@ -152,7 +161,7 @@ public class SecP256K1Field int c = Nat256.shiftUpBit(x, 0, z); if (c != 0 || (z[7] == P7 && Nat256.gte(z, P))) { - Nat256.addDWord(PInv, z, 0); + Nat256.add33To(PInv33, z); } } } diff --git a/core/src/main/java/org/bouncycastle/math/ec/custom/sec/SecP256R1Field.java b/core/src/main/java/org/bouncycastle/math/ec/custom/sec/SecP256R1Field.java index 8315935c..b7889258 100644 --- a/core/src/main/java/org/bouncycastle/math/ec/custom/sec/SecP256R1Field.java +++ b/core/src/main/java/org/bouncycastle/math/ec/custom/sec/SecP256R1Field.java @@ -21,7 +21,7 @@ public class SecP256R1Field int c = Nat256.add(x, y, z); if (c != 0 || (z[7] == P7 && Nat256.gte(z, P))) { - Nat256.sub(z, P, z); + Nat256.subFrom(P, z); } } @@ -40,7 +40,7 @@ public class SecP256R1Field int c = Nat256.inc(z, 0); if (c != 0 || (z[7] == P7 && Nat256.gte(z, P))) { - Nat256.sub(z, P, z); + Nat256.subFrom(P, z); } } @@ -49,7 +49,7 @@ public class SecP256R1Field int[] z = Nat256.fromBigInteger(x); if (z[7] == P7 && Nat256.gte(z, P)) { - Nat256.sub(z, P, z); + Nat256.subFrom(P, z); } return z; } @@ -134,11 +134,11 @@ public class SecP256R1Field { while (c < -1) { - c += Nat256.add(z, _2P, z) + 1; + c += Nat256.addTo(_2P, z) + 1; } while (c < 0) { - c += Nat256.add(z, P, z); + c += Nat256.addTo(P, z); } } } @@ -181,7 +181,7 @@ public class SecP256R1Field if (cc != 0 || (z[7] == P7 && Nat256.gte(z, P))) { - Nat256.sub(z, P, z); + Nat256.subFrom(P, z); } } @@ -212,7 +212,7 @@ public class SecP256R1Field int c = Nat256.sub(x, y, z); if (c != 0) { - Nat256.add(z, P, z); + Nat256.addTo(P, z); } } @@ -230,7 +230,7 @@ public class SecP256R1Field int c = Nat256.shiftUpBit(x, 0, z); if (c != 0 || (z[7] == P7 && Nat256.gte(z, P))) { - Nat256.sub(z, P, z); + Nat256.subFrom(P, z); } } } diff --git a/core/src/main/java/org/bouncycastle/math/ec/custom/sec/SecP384R1Field.java b/core/src/main/java/org/bouncycastle/math/ec/custom/sec/SecP384R1Field.java index b4df7ec0..2ab01885 100644 --- a/core/src/main/java/org/bouncycastle/math/ec/custom/sec/SecP384R1Field.java +++ b/core/src/main/java/org/bouncycastle/math/ec/custom/sec/SecP384R1Field.java @@ -14,6 +14,10 @@ public class SecP384R1Field static final int[] PExt = new int[]{ 0x00000001, 0xFFFFFFFE, 0x00000000, 0x00000002, 0x00000000, 0xFFFFFFFE, 0x00000000, 0x00000002, 0x00000001, 0x00000000, 0x00000000, 0x00000000, 0xFFFFFFFE, 0x00000001, 0x00000000, 0xFFFFFFFE, 0xFFFFFFFD, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF }; + private static final int[] PInv = new int[]{ 0x00000001, 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000, 0x00000001 }; + private static final int[] PExtInv = new int[]{ 0xFFFFFFFF, 0x00000001, 0xFFFFFFFF, 0xFFFFFFFD, 0xFFFFFFFF, 0x00000001, + 0xFFFFFFFF, 0xFFFFFFFD, 0xFFFFFFFE, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x00000001, 0xFFFFFFFE, 0xFFFFFFFF, + 0x00000001, 0x00000002 }; private static final int P11 = 0xFFFFFFFF; private static final int PExt23 = 0xFFFFFFFF; @@ -22,7 +26,10 @@ public class SecP384R1Field int c = Nat.add(12, x, y, z); if (c != 0 || (z[11] == P11 && Nat.gte(12, z, P))) { - Nat.sub(12, z, P, z); + if (Nat.addTo(PInv.length, PInv, z) != 0) + { + Nat.incAt(12, z, PInv.length); + } } } @@ -31,17 +38,22 @@ public class SecP384R1Field int c = Nat.add(24, xx, yy, zz); if (c != 0 || (zz[23] == PExt23 && Nat.gte(24, zz, PExt))) { - Nat.sub(24, zz, PExt, zz); + if (Nat.addTo(PExtInv.length, PExtInv, zz) != 0) + { + Nat.incAt(24, zz, PExtInv.length); + } } } public static void addOne(int[] x, int[] z) { - Nat.copy(12, x, z); - int c = Nat.inc(12, z, 0); + int c = Nat.inc(12, x, z); if (c != 0 || (z[11] == P11 && Nat.gte(12, z, P))) { - Nat.sub(12, z, P, z); + if (Nat.addTo(PInv.length, PInv, z) != 0) + { + Nat.incAt(12, z, PInv.length); + } } } @@ -50,7 +62,7 @@ public class SecP384R1Field int[] z = Nat.fromBigInteger(384, x); if (z[11] == P11 && Nat.gte(12, z, P)) { - Nat.sub(12, z, P, z); + Nat.subFrom(12, P, z); } return z; } @@ -136,12 +148,9 @@ public class SecP384R1Field { reduce32(c, z); } - else + else if (Nat.subFrom(PInv.length, PInv, z) != 0) { - while (c < 0) - { - c += Nat256.add(z, P, z); - } + Nat.decAt(12, z, PInv.length); } } @@ -172,10 +181,13 @@ public class SecP384R1Field // assert cc == 0 || cc == 1; } - if ((cc != 0 && Nat.inc(12, z, 5) != 0) + if ((cc != 0 && Nat.incAt(12, z, 5) != 0) || (z[11] == P11 && Nat.gte(12, z, P))) { - Nat.sub(12, z, P, z); + if (Nat.addTo(PInv.length, PInv, z) != 0) + { + Nat.incAt(12, z, PInv.length); + } } } @@ -206,7 +218,10 @@ public class SecP384R1Field int c = Nat.sub(12, x, y, z); if (c != 0) { - Nat.add(12, z, P, z); + if (Nat.subFrom(PInv.length, PInv, z) != 0) + { + Nat.decAt(12, z, PInv.length); + } } } @@ -215,7 +230,10 @@ public class SecP384R1Field int c = Nat.sub(24, xx, yy, zz); if (c != 0) { - Nat.add(24, zz, PExt, zz); + if (Nat.subFrom(PExtInv.length, PExtInv, zz) != 0) + { + Nat.decAt(24, zz, PExtInv.length); + } } } @@ -224,7 +242,10 @@ public class SecP384R1Field int c = Nat.shiftUpBit(12, x, 0, z); if (c != 0 || (z[11] == P11 && Nat.gte(12, z, P))) { - Nat.sub(12, z, P, z); + if (Nat.addTo(PInv.length, PInv, z) != 0) + { + Nat.incAt(12, z, PInv.length); + } } } } diff --git a/core/src/main/java/org/bouncycastle/math/ec/custom/sec/SecP521R1Field.java b/core/src/main/java/org/bouncycastle/math/ec/custom/sec/SecP521R1Field.java index df353034..a90c08bc 100644 --- a/core/src/main/java/org/bouncycastle/math/ec/custom/sec/SecP521R1Field.java +++ b/core/src/main/java/org/bouncycastle/math/ec/custom/sec/SecP521R1Field.java @@ -16,7 +16,7 @@ public class SecP521R1Field int c = Nat.add(16, x, y, z) + x[16] + y[16]; if (c > P16 || (c == P16 && Nat.eq(16, z, P))) { - c += Nat.inc(16, z, 0); + c += Nat.inc(16, z); c &= P16; } z[16] = c; @@ -24,11 +24,10 @@ public class SecP521R1Field public static void addOne(int[] x, int[] z) { - Nat.copy(16, x, z); - int c = Nat.inc(16, z, 0) + x[16]; + int c = Nat.inc(16, x, z) + x[16]; if (c > P16 || (c == P16 && Nat.eq(16, z, P))) { - c += Nat.inc(16, z, 0); + c += Nat.inc(16, z); c &= P16; } z[16] = c; @@ -75,12 +74,12 @@ public class SecP521R1Field // assert xx[32] >>> 18 == 0; int xx32 = xx[32]; - int c = Nat.shiftDownBits(16, xx, 16, 9, xx32, z) >>> 23; + int c = Nat.shiftDownBits(16, xx, 16, 9, xx32, z, 0) >>> 23; c += xx32 >>> 9; c += Nat.add(16, z, xx, z); if (c > P16 || (c == P16 && Nat.eq(16, z, P))) { - c += Nat.inc(16, z, 0); + c += Nat.inc(16, z); c &= P16; } z[16] = c; @@ -89,10 +88,10 @@ public class SecP521R1Field public static void reduce23(int[] z) { int z16 = z[16]; - int c = Nat.addWord(16, z16 >>> 9, z, 0) + (z16 & P16); + int c = Nat.addWordAt(16, z16 >>> 9, z, 0) + (z16 & P16); if (c > P16 || (c == P16 && Nat.eq(16, z, P))) { - c += Nat.inc(16, z, 0); + c += Nat.inc(16, z); c &= P16; } z[16] = c; @@ -125,7 +124,7 @@ public class SecP521R1Field int c = Nat.sub(16, x, y, z) + x[16] - y[16]; if (c < 0) { - c += Nat.dec(16, z, 0); + c += Nat.dec(16, z); c &= P16; } z[16] = c; |