From d018a8d36dce6e5d2921b4a7e2c4fb0479d196f0 Mon Sep 17 00:00:00 2001 From: Peter Dettman Date: Tue, 1 Oct 2013 14:45:27 +0700 Subject: A few more small improvements to multiply --- .../java/org/bouncycastle/math/ec/IntArray.java | 117 +++++++++++---------- 1 file changed, 60 insertions(+), 57 deletions(-) (limited to 'core/src/main/java/org/bouncycastle/math') diff --git a/core/src/main/java/org/bouncycastle/math/ec/IntArray.java b/core/src/main/java/org/bouncycastle/math/ec/IntArray.java index 7f1158f1..294f1e46 100644 --- a/core/src/main/java/org/bouncycastle/math/ec/IntArray.java +++ b/core/src/main/java/org/bouncycastle/math/ec/IntArray.java @@ -6,25 +6,29 @@ import java.math.BigInteger; class IntArray { - private static final int[] generateSquare8Table() - { - int[] t = new int[256]; - for (int i = 0; i < 256; ++i) - { - int v = 0; - for (int bit = 0; bit < 8; ++bit) - { - if ((i & (1 << bit)) != 0) - { - v ^= i << bit; - } - } - t[i] = v << 16; - } - return t; - } - - private static final int[] SQUARE8_TABLE = generateSquare8Table(); + /* + * This expands 8 bit indices into 16 bit contents, by inserting 0s between bits. + * In a binary field, this operation is the same as squaring an 8 bit number. + */ + private static final int[] EXPANSION_TABLE = new int[] { 0x0000, 0x0001, 0x0004, 0x0005, 0x0010, 0x0011, 0x0014, + 0x0015, 0x0040, 0x0041, 0x0044, 0x0045, 0x0050, 0x0051, 0x0054, 0x0055, 0x0100, 0x0101, 0x0104, 0x0105, 0x0110, + 0x0111, 0x0114, 0x0115, 0x0140, 0x0141, 0x0144, 0x0145, 0x0150, 0x0151, 0x0154, 0x0155, 0x0400, 0x0401, 0x0404, + 0x0405, 0x0410, 0x0411, 0x0414, 0x0415, 0x0440, 0x0441, 0x0444, 0x0445, 0x0450, 0x0451, 0x0454, 0x0455, 0x0500, + 0x0501, 0x0504, 0x0505, 0x0510, 0x0511, 0x0514, 0x0515, 0x0540, 0x0541, 0x0544, 0x0545, 0x0550, 0x0551, 0x0554, + 0x0555, 0x1000, 0x1001, 0x1004, 0x1005, 0x1010, 0x1011, 0x1014, 0x1015, 0x1040, 0x1041, 0x1044, 0x1045, 0x1050, + 0x1051, 0x1054, 0x1055, 0x1100, 0x1101, 0x1104, 0x1105, 0x1110, 0x1111, 0x1114, 0x1115, 0x1140, 0x1141, 0x1144, + 0x1145, 0x1150, 0x1151, 0x1154, 0x1155, 0x1400, 0x1401, 0x1404, 0x1405, 0x1410, 0x1411, 0x1414, 0x1415, 0x1440, + 0x1441, 0x1444, 0x1445, 0x1450, 0x1451, 0x1454, 0x1455, 0x1500, 0x1501, 0x1504, 0x1505, 0x1510, 0x1511, 0x1514, + 0x1515, 0x1540, 0x1541, 0x1544, 0x1545, 0x1550, 0x1551, 0x1554, 0x1555, 0x4000, 0x4001, 0x4004, 0x4005, 0x4010, + 0x4011, 0x4014, 0x4015, 0x4040, 0x4041, 0x4044, 0x4045, 0x4050, 0x4051, 0x4054, 0x4055, 0x4100, 0x4101, 0x4104, + 0x4105, 0x4110, 0x4111, 0x4114, 0x4115, 0x4140, 0x4141, 0x4144, 0x4145, 0x4150, 0x4151, 0x4154, 0x4155, 0x4400, + 0x4401, 0x4404, 0x4405, 0x4410, 0x4411, 0x4414, 0x4415, 0x4440, 0x4441, 0x4444, 0x4445, 0x4450, 0x4451, 0x4454, + 0x4455, 0x4500, 0x4501, 0x4504, 0x4505, 0x4510, 0x4511, 0x4514, 0x4515, 0x4540, 0x4541, 0x4544, 0x4545, 0x4550, + 0x4551, 0x4554, 0x4555, 0x5000, 0x5001, 0x5004, 0x5005, 0x5010, 0x5011, 0x5014, 0x5015, 0x5040, 0x5041, 0x5044, + 0x5045, 0x5050, 0x5051, 0x5054, 0x5055, 0x5100, 0x5101, 0x5104, 0x5105, 0x5110, 0x5111, 0x5114, 0x5115, 0x5140, + 0x5141, 0x5144, 0x5145, 0x5150, 0x5151, 0x5154, 0x5155, 0x5400, 0x5401, 0x5404, 0x5405, 0x5410, 0x5411, 0x5414, + 0x5415, 0x5440, 0x5441, 0x5444, 0x5445, 0x5450, 0x5451, 0x5454, 0x5455, 0x5500, 0x5501, 0x5504, 0x5505, 0x5510, + 0x5511, 0x5514, 0x5515, 0x5540, 0x5541, 0x5544, 0x5545, 0x5550, 0x5551, 0x5554, 0x5555 }; // For toString(); must have length 32 private static final String ZEROES = "00000000000000000000000000000000"; @@ -274,23 +278,21 @@ class IntArray for (int i = 0; i < usedLen; ++i) { int next = m_ints[i]; - m_ints[i] = (next << 1) | (prev >>> 31); - prev = next; + m_ints[i] = (next << 1) | prev; + prev = next >>> 31; } } - private int shiftLeftQuick() + private static int shiftLeftQuick(int[] x, int count) { - int len = m_ints.length; - int prev = 0; - for (int i = 0; i < len; ++i) + for (int i = 0; i < count; ++i) { - int next = m_ints[i]; - m_ints[i] = (next << 1) | (prev >>> 31); - prev = next; + int next = x[i]; + x[i] = (next << 1) | prev; + prev = next >>> 31; } - return prev >>> 31; + return prev; } public IntArray shiftLeft(int n) @@ -328,10 +330,9 @@ class IntArray public void addOneShifted(int shift) { - int newMinUsedLen = 1 + shift; - if (newMinUsedLen > m_ints.length) + if (shift >= m_ints.length) { - m_ints = resizedInts(newMinUsedLen); + m_ints = resizedInts(shift + 1); } m_ints[shift] ^= 1; @@ -342,9 +343,6 @@ class IntArray int words = bits >>> 5; int shift = bits & 0x1F; -// IntArray vzShift = other.shiftLeft(shift); -// addShiftedByWords(vzShift, words); - if (shift == 0) { addShiftedByWords(other, words); @@ -367,10 +365,10 @@ class IntArray for (int i = 0; i < otherUsedLen; ++i) { int next = other.m_ints[i]; - m_ints[i + words] ^= (next << shift) | (prev >>> shiftInv); - prev = next; + m_ints[i + words] ^= (next << shift) | prev; + prev = next >>> shiftInv; } - m_ints[otherUsedLen + words] ^= prev >>> shiftInv; + m_ints[otherUsedLen + words] ^= prev; } public void addShiftedByWords(IntArray other, int words) @@ -393,12 +391,11 @@ class IntArray } } - private void addShiftedByWordsQuick(IntArray other, int words) + private void addShiftedByWordsQuick(int[] x, int xOff, int[] y, int count) { - int otherLen = other.m_ints.length; - for (int i = 0; i < otherLen; ++i) + for (int i = 0; i < count; ++i) { - m_ints[words + i] ^= other.m_ints[i]; + x[xOff + i] ^= y[i]; } } @@ -413,7 +410,7 @@ class IntArray int n = bit >>> 5; if (n < len) { - int shift = bit & 31; + int shift = bit & 0x1F; if (shift == 0) { m_ints[n] ^= word; @@ -437,7 +434,7 @@ class IntArray { return 0; } - int shift = bit & 31; + int shift = bit & 0x1F; if (shift == 0) { return m_ints[n]; @@ -537,30 +534,36 @@ class IntArray return new IntArray(1); } - int mLen = (m + 31) >>> 5; - int t = Math.min(usedLen, mLen); + int otherUsedLen = other.getUsedLength(); + if (otherUsedLen == 0) + { + return new IntArray(1); + } - IntArray b = new IntArray(other.resizedInts(other.getUsedLength() + 1)); - IntArray c = new IntArray(t + b.getLength()); + int[] a = m_ints; + int bLen = otherUsedLen + 1; + int[] b = other.resizedInts(bLen); + int[] c = new int[usedLen + otherUsedLen]; int testBit = 1; for (;;) { - for (int j = 0; j < t; j++) + for (int j = 0; j < usedLen; ++j) { - if ((m_ints[j] & testBit) != 0) + // If the kth bit of a[j] is set... + if ((a[j] & testBit) != 0) { - // The kth bit of m_ints[j] is set - c.addShiftedByWordsQuick(b, j); + addShiftedByWordsQuick(c, j, b, bLen); } } if ((testBit <<= 1) == 0) { break; } - b.shiftLeftQuick(); + + shiftLeftQuick(b, bLen); } - return c; + return new IntArray(c); } // public IntArray multiplyLeftToRight(IntArray other, int m) { @@ -612,7 +615,7 @@ class IntArray } // Instead of flipping the high bits in the loop, explicitly clear any partial word above m bits - int partial = m & 31; + int partial = m & 0x1F; if (partial != 0) { m_ints[mLen - 1] &= (1 << partial) - 1; @@ -644,7 +647,7 @@ class IntArray private void reduceWordWise(int from, int m, int[] ks) { - int pos = m + ((from - m) & ~31); + int pos = m + ((from - m) & ~0x1F); for (int i = pos; i >= m; i -= 32) { int word = getWord(i); @@ -680,7 +683,7 @@ class IntArray private static int square16(int n) { - return (SQUARE8_TABLE[n & 0xFF] >>> 16) | SQUARE8_TABLE[n >>> 8]; + return EXPANSION_TABLE[n & 0xFF] | EXPANSION_TABLE[n >>> 8] << 16; } public boolean equals(Object o) -- cgit v1.2.3