Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/quite/humla-spongycastle.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorbouncy <bouncy@deimos.tauceti.org.au>2014-01-05 10:46:22 +0400
committerbouncy <bouncy@deimos.tauceti.org.au>2014-01-05 10:46:22 +0400
commitdd05b1353bef72fbd8823a6d85f7396aab968c39 (patch)
tree3d407934cc57b56b03387804cd948afe19053263
parentf98d829d3b5ecbe85d9a2113b8f7fac61b8eb77e (diff)
parent167f29d3c0ca707939759a94e0049b3a1ae12f33 (diff)
Merge remote branch 'origin/master'
-rw-r--r--core/src/main/java/org/bouncycastle/crypto/ec/CustomNamedCurves.java (renamed from core/src/main/java/org/bouncycastle/asn1/sec/SECCustomNamedCurves.java)5
-rw-r--r--core/src/main/java/org/bouncycastle/crypto/tls/TlsECCUtils.java4
-rw-r--r--core/src/main/java/org/bouncycastle/math/ec/ECPoint.java24
-rw-r--r--core/src/main/java/org/bouncycastle/math/ec/custom/sec/Nat256.java296
-rw-r--r--core/src/main/java/org/bouncycastle/math/ec/custom/sec/SecP256K1Field.java26
-rw-r--r--core/src/main/java/org/bouncycastle/math/ec/custom/sec/SecP256R1Field.java23
-rw-r--r--core/src/main/java/org/bouncycastle/math/ec/custom/sec/SecP256R1Point.java2
-rw-r--r--core/src/test/java/org/bouncycastle/math/ec/test/ECPointPerformanceTest.java4
-rw-r--r--core/src/test/java/org/bouncycastle/math/ec/test/ECPointTest.java4
-rw-r--r--pg/src/main/java/org/bouncycastle/bcpg/ECPublicBCPGKey.java7
-rw-r--r--pkix/src/test/java/org/bouncycastle/eac/test/AllTests.java6
-rw-r--r--prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/ec/BCECPublicKey.java5
-rw-r--r--prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/util/EC5Util.java32
-rw-r--r--prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/util/ECUtil.java10
-rw-r--r--prov/src/main/java/org/bouncycastle/jce/ECNamedCurveTable.java22
-rw-r--r--prov/src/test/java/org/bouncycastle/jce/provider/test/ECDSA5Test.java76
16 files changed, 385 insertions, 161 deletions
diff --git a/core/src/main/java/org/bouncycastle/asn1/sec/SECCustomNamedCurves.java b/core/src/main/java/org/bouncycastle/crypto/ec/CustomNamedCurves.java
index 6e85c012..96039c6c 100644
--- a/core/src/main/java/org/bouncycastle/asn1/sec/SECCustomNamedCurves.java
+++ b/core/src/main/java/org/bouncycastle/crypto/ec/CustomNamedCurves.java
@@ -1,9 +1,10 @@
-package org.bouncycastle.asn1.sec;
+package org.bouncycastle.crypto.ec;
import java.util.Enumeration;
import java.util.Hashtable;
import org.bouncycastle.asn1.ASN1ObjectIdentifier;
+import org.bouncycastle.asn1.sec.SECObjectIdentifiers;
import org.bouncycastle.asn1.x9.X9ECParameters;
import org.bouncycastle.asn1.x9.X9ECParametersHolder;
import org.bouncycastle.math.ec.ECCurve;
@@ -13,7 +14,7 @@ import org.bouncycastle.math.ec.custom.sec.SecP256R1Curve;
import org.bouncycastle.util.Strings;
import org.bouncycastle.util.encoders.Hex;
-public class SECCustomNamedCurves
+public class CustomNamedCurves
{
private static ECCurve configureCurve(ECCurve curve)
{
diff --git a/core/src/main/java/org/bouncycastle/crypto/tls/TlsECCUtils.java b/core/src/main/java/org/bouncycastle/crypto/tls/TlsECCUtils.java
index e2a99d87..5adf06cf 100644
--- a/core/src/main/java/org/bouncycastle/crypto/tls/TlsECCUtils.java
+++ b/core/src/main/java/org/bouncycastle/crypto/tls/TlsECCUtils.java
@@ -8,11 +8,11 @@ import java.math.BigInteger;
import java.security.SecureRandom;
import java.util.Hashtable;
-import org.bouncycastle.asn1.sec.SECCustomNamedCurves;
import org.bouncycastle.asn1.x9.ECNamedCurveTable;
import org.bouncycastle.asn1.x9.X9ECParameters;
import org.bouncycastle.crypto.AsymmetricCipherKeyPair;
import org.bouncycastle.crypto.agreement.ECDHBasicAgreement;
+import org.bouncycastle.crypto.ec.CustomNamedCurves;
import org.bouncycastle.crypto.generators.ECKeyPairGenerator;
import org.bouncycastle.crypto.params.ECDomainParameters;
import org.bouncycastle.crypto.params.ECKeyGenerationParameters;
@@ -153,7 +153,7 @@ public class TlsECCUtils
// Parameters are lazily created the first time a particular curve is accessed
- X9ECParameters ecP = SECCustomNamedCurves.getByName(curveName);
+ X9ECParameters ecP = CustomNamedCurves.getByName(curveName);
if (ecP == null)
{
ecP = ECNamedCurveTable.getByName(curveName);
diff --git a/core/src/main/java/org/bouncycastle/math/ec/ECPoint.java b/core/src/main/java/org/bouncycastle/math/ec/ECPoint.java
index 9cd51b6e..6b4ceae9 100644
--- a/core/src/main/java/org/bouncycastle/math/ec/ECPoint.java
+++ b/core/src/main/java/org/bouncycastle/math/ec/ECPoint.java
@@ -1562,9 +1562,27 @@ public abstract class ECPoint
if (b.bitLength() < (curve.getFieldSize() >> 1))
{
ECFieldElement t1 = L1.add(X1).square();
- ECFieldElement t2 = aZ1Sq.square();
- ECFieldElement t3 = curve.getB().multiply(Z1Sq.square());
- L3 = t1.add(T).add(Z1Sq).multiply(t1).add(t2.add(t3)).add(X3).add(a.addOne().multiply(Z3));
+ ECFieldElement t4;
+ if (b.isOne())
+ {
+ t4 = aZ1Sq.add(Z1Sq).square();
+ }
+ else
+ {
+ // TODO t2/t3 can be calculated with one square if we pre-compute sqrt(b)
+ ECFieldElement t2 = aZ1Sq.square();
+ ECFieldElement t3 = b.multiply(Z1Sq.square());
+ t4 = t2.add(t3);
+ }
+ L3 = t1.add(T).add(Z1Sq).multiply(t1).add(t4).add(X3);
+ if (a.isZero())
+ {
+ L3 = L3.add(Z3);
+ }
+ else if (!a.isOne())
+ {
+ L3 = L3.add(a.addOne().multiply(Z3));
+ }
}
else
{
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 2ab81a70..18872410 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
@@ -38,18 +38,6 @@ public abstract class Nat256
return (int)c;
}
- public static int addExt(int[] xx, int[] yy, int[] zz)
- {
- long c = 0;
- for (int i = 0; i < 16; ++i)
- {
- c += (xx[i] & M) + (yy[i] & M);
- zz[i] = (int)c;
- c >>>= 32;
- }
- return (int)c;
- }
-
public static int addBothTo(int[] x, int[] y, int[] z)
{
long c = 0;
@@ -93,7 +81,19 @@ public abstract class Nat256
return c == 0 ? 0 : inc(z, zOff + 2);
}
- public static int addExt(int[] x, int xOff, int[] zz, int zzOff)
+ public static int addExt(int[] xx, int[] yy, int[] zz)
+ {
+ long c = 0;
+ for (int i = 0; i < 16; ++i)
+ {
+ c += (xx[i] & M) + (yy[i] & M);
+ zz[i] = (int)c;
+ c >>>= 32;
+ }
+ return (int)c;
+ }
+
+ public static int addToExt(int[] x, int xOff, int[] zz, int zzOff)
{
// assert zzOff <= 8;
long c = 0;
@@ -204,6 +204,20 @@ public abstract class Nat256
return false;
}
+ public static boolean gteExt(int[] xx, int[] yy)
+ {
+ for (int i = 15; i >= 0; --i)
+ {
+ int xx_i = xx[i] ^ Integer.MIN_VALUE;
+ int yy_i = yy[i] ^ Integer.MIN_VALUE;
+ if (xx_i < yy_i)
+ return false;
+ if (xx_i > yy_i)
+ return true;
+ }
+ return false;
+ }
+
public static int inc(int[] z, int zOff)
{
// assert zOff < 8;
@@ -262,6 +276,22 @@ public abstract class Nat256
return true;
}
+ public static boolean isZeroExt(int[] xx)
+ {
+ if (xx[0] != 0)
+ {
+ return false;
+ }
+ for (int i = 1; i < 16; ++i)
+ {
+ if (xx[i] != 0)
+ {
+ return false;
+ }
+ }
+ return true;
+ }
+
public static void mul(int[] x, int[] y, int[] zz)
{
long y_0 = y[0] & M;
@@ -444,181 +474,144 @@ public abstract class Nat256
return (int)c;
}
- public static int shiftUp(int[] x, int xLen, int bit)
+ public static int shiftUp(int[] x, int xLen, int c)
{
for (int i = 0; i < xLen; ++i)
{
int next = x[i];
- x[i] = (next << 1) | bit;
- bit = next >>> 31;
+ x[i] = (next << 1) | (c >>> 31);
+ c = next;
}
- return bit;
+ return c >>> 31;
}
public static void square(int[] x, int[] zz)
{
+ long x_0 = x[0] & M;
+ long zz_1;
+
{
- int c = 0, i = 8, j = 16;
+ int c = 0, i = 7, j = 16;
do
{
- long xVal = (x[--i] & M);
+ long xVal = (x[i--] & M);
long p = xVal * xVal;
zz[--j] = (c << 31) | (int)(p >>> 33);
zz[--j] = (int)(p >>> 1);
c = (int)p;
}
while (i > 0);
+
+ {
+ long p = x_0 * x_0;
+ zz_1 = ((c << 31) & M) | (p >>> 33);
+ zz[0] = (int)(p >>> 1);
+ }
}
- long x_0 = x[0] & M;
long x_1 = x[1] & M;
- long zz_1 = zz[1] & M;
long zz_2 = zz[2] & M;
{
- long cc = 0;
- cc += x_1 * x_0 + zz_1;
- zz[1] = (int)cc;
- cc >>>= 32;
- zz_2 += cc;
+ zz_1 += x_1 * x_0;
+ zz[1] = (int)zz_1;
+ zz_2 += zz_1 >>> 32;
}
long x_2 = x[2] & M;
long zz_3 = zz[3] & M;
long zz_4 = zz[4] & M;
{
- long cc = 0;
- cc += x_2 * x_0 + zz_2;
- zz[2] = (int)cc;
- cc >>>= 32;
- cc += x_2 * x_1 + zz_3;
- zz_3 = cc & M;
- cc >>>= 32;
- zz_4 += cc;
+ zz_2 += x_2 * x_0;
+ zz[2] = (int)zz_2;
+ zz_3 += (zz_2 >>> 32) + x_2 * x_1;
+ zz_4 += zz_3 >>> 32;
+ zz_3 &= M;
}
long x_3 = x[3] & M;
long zz_5 = zz[5] & M;
long zz_6 = zz[6] & M;
{
- long cc = 0;
- cc += x_3 * x_0 + zz_3;
- zz[3] = (int)cc;
- cc >>>= 32;
- cc += x_3 * x_1 + zz_4;
- zz_4 = cc & M;
- cc >>>= 32;
- cc += x_3 * x_2 + zz_5;
- zz_5 = cc & M;
- cc >>>= 32;
- zz_6 += cc;
+ zz_3 += x_3 * x_0;
+ zz[3] = (int)zz_3;
+ zz_4 += (zz_3 >>> 32) + x_3 * x_1;
+ zz_5 += (zz_4 >>> 32) + x_3 * x_2;
+ zz_4 &= M;
+ zz_6 += zz_5 >>> 32;
+ zz_5 &= M;
}
long x_4 = x[4] & M;
long zz_7 = zz[7] & M;
long zz_8 = zz[8] & M;
{
- long cc = 0;
- cc += x_4 * x_0 + zz_4;
- zz[4] = (int)cc;
- cc >>>= 32;
- cc += x_4 * x_1 + zz_5;
- zz_5 = cc & M;
- cc >>>= 32;
- cc += x_4 * x_2 + zz_6;
- zz_6 = cc & M;
- cc >>>= 32;
- cc += x_4 * x_3 + zz_7;
- zz_7 = cc & M;
- cc >>>= 32;
- zz_8 += cc;
+ zz_4 += x_4 * x_0;
+ zz[4] = (int)zz_4;
+ zz_5 += (zz_4 >>> 32) + x_4 * x_1;
+ zz_6 += (zz_5 >>> 32) + x_4 * x_2;
+ zz_5 &= M;
+ zz_7 += (zz_6 >>> 32) + x_4 * x_3;
+ zz_6 &= M;
+ zz_8 += zz_7 >>> 32;
+ zz_7 &= M;
}
long x_5 = x[5] & M;
long zz_9 = zz[9] & M;
long zz_10 = zz[10] & M;
{
- long cc = 0;
- cc += x_5 * x_0 + zz_5;
- zz[5] = (int)cc;
- cc >>>= 32;
- cc += x_5 * x_1 + zz_6;
- zz_6 = cc & M;
- cc >>>= 32;
- cc += x_5 * x_2 + zz_7;
- zz_7 = cc & M;
- cc >>>= 32;
- cc += x_5 * x_3 + zz_8;
- zz_8 = cc & M;
- cc >>>= 32;
- cc += x_5 * x_4 + zz_9;
- zz_9 = cc & M;
- cc >>>= 32;
- zz_10 += cc;
+ zz_5 += x_5 * x_0;
+ zz[5] = (int)zz_5;
+ zz_6 += (zz_5 >>> 32) + x_5 * x_1;
+ zz_7 += (zz_6 >>> 32) + x_5 * x_2;
+ zz_6 &= M;
+ zz_8 += (zz_7 >>> 32) + x_5 * x_3;
+ zz_7 &= M;
+ zz_9 += (zz_8 >>> 32) + x_5 * x_4;
+ zz_8 &= M;
+ zz_10 += zz_9 >>> 32;
+ zz_9 &= M;
}
long x_6 = x[6] & M;
long zz_11 = zz[11] & M;
long zz_12 = zz[12] & M;
{
- long cc = 0;
- cc += x_6 * x_0 + zz_6;
- zz[6] = (int)cc;
- cc >>>= 32;
- cc += x_6 * x_1 + zz_7;
- zz_7 = cc & M;
- cc >>>= 32;
- cc += x_6 * x_2 + zz_8;
- zz_8 = cc & M;
- cc >>>= 32;
- cc += x_6 * x_3 + zz_9;
- zz_9 = cc & M;
- cc >>>= 32;
- cc += x_6 * x_4 + zz_10;
- zz_10 = cc & M;
- cc >>>= 32;
- cc += x_6 * x_5 + zz_11;
- zz_11 = cc & M;
- cc >>>= 32;
- zz_12 += cc;
+ zz_6 += x_6 * x_0;
+ zz[6] = (int)zz_6;
+ zz_7 += (zz_6 >>> 32) + x_6 * x_1;
+ zz_8 += (zz_7 >>> 32) + x_6 * x_2;
+ zz_7 &= M;
+ zz_9 += (zz_8 >>> 32) + x_6 * x_3;
+ zz_8 &= M;
+ zz_10 += (zz_9 >>> 32) + x_6 * x_4;
+ zz_9 &= M;
+ zz_11 += (zz_10 >>> 32) + x_6 * x_5;
+ zz_10 &= M;
+ zz_12 += zz_11 >>> 32;
+ zz_11 &= M;
}
long x_7 = x[7] & M;
long zz_13 = zz[13] & M;
long zz_14 = zz[14] & M;
{
- long cc = 0;
- cc += x_7 * x_0 + zz_7;
- zz[7] = (int)cc;
- cc >>>= 32;
- cc += x_7 * x_1 + zz_8;
- zz_8 = cc & M;
- cc >>>= 32;
- cc += x_7 * x_2 + zz_9;
- zz_9 = cc & M;
- cc >>>= 32;
- cc += x_7 * x_3 + zz_10;
- zz_10 = cc & M;
- cc >>>= 32;
- cc += x_7 * x_4 + zz_11;
- zz_11 = cc & M;
- cc >>>= 32;
- cc += x_7 * x_5 + zz_12;
- zz_12 = cc & M;
- cc >>>= 32;
- cc += x_7 * x_6 + zz_13;
- zz_13 = cc & M;
- cc >>>= 32;
- zz_14 += cc;
- }
-
- long zz_15 = zz[15] & M;
- {
- long cc = 0;
- cc += zz_14;
- zz[14] = (int)cc;
- cc >>>= 32;
- zz_15 += cc;
+ zz_7 += x_7 * x_0;
+ zz[7] = (int)zz_7;
+ zz_8 += (zz_7 >>> 32) + x_7 * x_1;
+ zz_9 += (zz_8 >>> 32) + x_7 * x_2;
+ zz_8 &= M;
+ zz_10 += (zz_9 >>> 32) + x_7 * x_3;
+ zz_9 &= M;
+ zz_11 += (zz_10 >>> 32) + x_7 * x_4;
+ zz_10 &= M;
+ zz_12 += (zz_11 >>> 32) + x_7 * x_5;
+ zz_11 &= M;
+ zz_13 += (zz_12 >>> 32) + x_7 * x_6;
+ zz_12 &= M;
+ zz_14 += zz_13 >>> 32;
+ zz_13 &= M;
}
zz[8] = (int)zz_8;
@@ -628,9 +621,9 @@ public abstract class Nat256
zz[12] = (int)zz_12;
zz[13] = (int)zz_13;
zz[14] = (int)zz_14;
- zz[15] = (int)zz_15;
+ zz[15] += (int)(zz_14 >>> 32);
- shiftUp(zz, 16, (int)x_0 & 1);
+ shiftUp(zz, 16, (int)x_0 << 31);
}
public static int sub(int[] x, int[] y, int[] z)
@@ -705,6 +698,49 @@ public abstract class Nat256
return x == 0 ? 0 : dec(z, 2);
}
+ public static int subExt(int[] xx, int[] yy, int[] zz)
+ {
+ long c = 0;
+ for (int i = 0; i < 16; ++i)
+ {
+ c += (xx[i] & M) - (yy[i] & M);
+ zz[i] = (int)c;
+ c >>= 32;
+ }
+ return (int)c;
+ }
+
+ public static int subFromExt(int[] x, int xOff, int[] zz, int zzOff)
+ {
+ // assert zzOff <= 8;
+ long c = 0;
+ c += (zz[zzOff + 0] & M) - (x[xOff + 0] & M);
+ zz[zzOff + 0] = (int)c;
+ c >>= 32;
+ c += (zz[zzOff + 1] & M) - (x[xOff + 1] & M);
+ zz[zzOff + 1] = (int)c;
+ c >>= 32;
+ c += (zz[zzOff + 2] & M) - (x[xOff + 2] & M);
+ zz[zzOff + 2] = (int)c;
+ c >>= 32;
+ c += (zz[zzOff + 3] & M) - (x[xOff + 3] & M);
+ zz[zzOff + 3] = (int)c;
+ c >>= 32;
+ c += (zz[zzOff + 4] & M) - (x[xOff + 4] & M);
+ zz[zzOff + 4] = (int)c;
+ c >>= 32;
+ c += (zz[zzOff + 5] & M) - (x[xOff + 5] & M);
+ zz[zzOff + 5] = (int)c;
+ c >>= 32;
+ c += (zz[zzOff + 6] & M) - (x[xOff + 6] & M);
+ zz[zzOff + 6] = (int)c;
+ c >>= 32;
+ c += (zz[zzOff + 7] & M) - (x[xOff + 7] & M);
+ zz[zzOff + 7] = (int)c;
+ c >>= 32;
+ return (int)c;
+ }
+
public static BigInteger toBigInteger(int[] x)
{
byte[] bs = new byte[32];
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 840fe05d..4e032850 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
@@ -10,6 +10,10 @@ public class SecP256K1Field
private static final int[] P = new int[]{ 0xFFFFFC2F, 0xFFFFFFFE, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
0xFFFFFFFF, 0xFFFFFFFF };
private static final int P7 = 0xFFFFFFFF;
+ private 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 PExt15 = 0xFFFFFFFF;
private static final long PInv = 0x00000001000003D1L;
public static void add(int[] x, int[] y, int[] z)
@@ -21,6 +25,15 @@ public class SecP256K1Field
}
}
+ public static void addExt(int[] xx, int[] yy, int[] zz)
+ {
+ int c = Nat256.addExt(xx, yy, zz);
+ if (c != 0 || (zz[15] == PExt15 && Nat256.gteExt(zz, PExt)))
+ {
+ Nat256.subExt(zz, PExt, zz);
+ }
+ }
+
public static void addOne(int[] x, int[] z)
{
System.arraycopy(x, 0, z, 0, 8);
@@ -60,11 +73,11 @@ public class SecP256K1Field
}
}
- private static void reduce(int[] tt, int[] z)
+ public static void reduce(int[] tt, int[] z)
{
long extra = -(tt[8] & M);
extra += Nat256.mulWordAddExt((int)PInv, tt, 8, tt, 0) & M;
- extra += (Nat256.addExt(tt, 8, tt, 1) & M) << 32;
+ extra += (Nat256.addToExt(tt, 8, tt, 1) & M) << 32;
extra += (tt[8] & M);
long c = Nat256.mulWordDwordAdd((int)PInv, extra, tt, 0) & M;
@@ -95,4 +108,13 @@ public class SecP256K1Field
Nat256.subDWord(PInv, z);
}
}
+
+ public static void subtractExt(int[] xx, int[] yy, int[] zz)
+ {
+ int c = Nat256.subExt(xx, yy, zz);
+ if (c != 0)
+ {
+ Nat256.addExt(zz, PExt, zz);
+ }
+ }
}
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 0b53240f..9881a007 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
@@ -10,6 +10,9 @@ public class SecP256R1Field
private static final int[] P = new int[]{ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000, 0x00000000, 0x00000000,
0x00000001, 0xFFFFFFFF };
private static final int P7 = 0xFFFFFFFF;
+ private static final int[] PExt = new int[]{ 0x00000001, 0x00000000, 0x00000000, 0xFFFFFFFE, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFE, 0x00000001, 0xFFFFFFFE, 0x00000001, 0xFFFFFFFE, 0x00000001, 0x00000001, 0xFFFFFFFE,
+ 0x00000002, 0xFFFFFFFE };
public static void add(int[] x, int[] y, int[] z)
{
@@ -20,6 +23,15 @@ public class SecP256R1Field
}
}
+ public static void addExt(int[] xx, int[] yy, int[] zz)
+ {
+ int c = Nat256.addExt(xx, yy, zz);
+ if (c != 0 || Nat256.gteExt(zz, PExt))
+ {
+ Nat256.subExt(zz, PExt, zz);
+ }
+ }
+
public static void addOne(int[] x, int[] z)
{
System.arraycopy(x, 0, z, 0, 8);
@@ -59,7 +71,7 @@ public class SecP256R1Field
}
}
- private static void reduce(int[] tt, int[] z)
+ public static void reduce(int[] tt, int[] z)
{
long t08 = tt[8] & M, t09 = tt[9] & M, t10 = tt[10] & M, t11 = tt[11] & M;
long t12 = tt[12] & M, t13 = tt[13] & M, t14 = tt[14] & M, t15 = tt[15] & M;
@@ -132,4 +144,13 @@ public class SecP256R1Field
Nat256.add(z, P, z);
}
}
+
+ public static void subtractExt(int[] xx, int[] yy, int[] zz)
+ {
+ int c = Nat256.subExt(xx, yy, zz);
+ if (c != 0)
+ {
+ Nat256.addExt(zz, PExt, zz);
+ }
+ }
}
diff --git a/core/src/main/java/org/bouncycastle/math/ec/custom/sec/SecP256R1Point.java b/core/src/main/java/org/bouncycastle/math/ec/custom/sec/SecP256R1Point.java
index d60b2e37..c97a7897 100644
--- a/core/src/main/java/org/bouncycastle/math/ec/custom/sec/SecP256R1Point.java
+++ b/core/src/main/java/org/bouncycastle/math/ec/custom/sec/SecP256R1Point.java
@@ -1,7 +1,5 @@
package org.bouncycastle.math.ec.custom.sec;
-import java.math.BigInteger;
-
import org.bouncycastle.math.ec.ECCurve;
import org.bouncycastle.math.ec.ECFieldElement;
import org.bouncycastle.math.ec.ECPoint;
diff --git a/core/src/test/java/org/bouncycastle/math/ec/test/ECPointPerformanceTest.java b/core/src/test/java/org/bouncycastle/math/ec/test/ECPointPerformanceTest.java
index c919c6bf..c1420051 100644
--- a/core/src/test/java/org/bouncycastle/math/ec/test/ECPointPerformanceTest.java
+++ b/core/src/test/java/org/bouncycastle/math/ec/test/ECPointPerformanceTest.java
@@ -4,9 +4,9 @@ import java.math.BigInteger;
import java.security.SecureRandom;
import junit.framework.TestCase;
-import org.bouncycastle.asn1.sec.SECCustomNamedCurves;
import org.bouncycastle.asn1.x9.ECNamedCurveTable;
import org.bouncycastle.asn1.x9.X9ECParameters;
+import org.bouncycastle.crypto.ec.CustomNamedCurves;
import org.bouncycastle.math.ec.ECCurve;
import org.bouncycastle.math.ec.ECPoint;
@@ -30,7 +30,7 @@ public class ECPointPerformanceTest extends TestCase
randMult(curveName, spec);
}
- spec = SECCustomNamedCurves.getByName(curveName);
+ spec = CustomNamedCurves.getByName(curveName);
if (spec != null)
{
randMult(curveName + " (custom)", spec);
diff --git a/core/src/test/java/org/bouncycastle/math/ec/test/ECPointTest.java b/core/src/test/java/org/bouncycastle/math/ec/test/ECPointTest.java
index 2002da41..e2be2deb 100644
--- a/core/src/test/java/org/bouncycastle/math/ec/test/ECPointTest.java
+++ b/core/src/test/java/org/bouncycastle/math/ec/test/ECPointTest.java
@@ -7,9 +7,9 @@ import java.util.Enumeration;
import junit.framework.Test;
import junit.framework.TestCase;
import junit.framework.TestSuite;
-import org.bouncycastle.asn1.sec.SECCustomNamedCurves;
import org.bouncycastle.asn1.sec.SECNamedCurves;
import org.bouncycastle.asn1.x9.X9ECParameters;
+import org.bouncycastle.crypto.ec.CustomNamedCurves;
import org.bouncycastle.math.ec.ECCurve;
import org.bouncycastle.math.ec.ECPoint;
@@ -446,7 +446,7 @@ public class ECPointTest extends TestCase
X9ECParameters x9ECParameters = SECNamedCurves.getByName(name);
implAddSubtractMultiplyTwiceEncodingTest(x9ECParameters);
- x9ECParameters = SECCustomNamedCurves.getByName(name);
+ x9ECParameters = CustomNamedCurves.getByName(name);
if (x9ECParameters != null)
{
implAddSubtractMultiplyTwiceEncodingTest(x9ECParameters);
diff --git a/pg/src/main/java/org/bouncycastle/bcpg/ECPublicBCPGKey.java b/pg/src/main/java/org/bouncycastle/bcpg/ECPublicBCPGKey.java
index 5983b325..9464af7c 100644
--- a/pg/src/main/java/org/bouncycastle/bcpg/ECPublicBCPGKey.java
+++ b/pg/src/main/java/org/bouncycastle/bcpg/ECPublicBCPGKey.java
@@ -10,6 +10,8 @@ import org.bouncycastle.asn1.x9.ECNamedCurveTable;
import org.bouncycastle.asn1.x9.X9ECParameters;
import org.bouncycastle.math.ec.ECCurve;
import org.bouncycastle.math.ec.ECPoint;
+import org.bouncycastle.math.ec.custom.sec.SecP256R1Curve;
+import org.bouncycastle.util.BigIntegers;
/**
* base class for an EC Public Key.
@@ -136,11 +138,12 @@ public abstract class ECPublicBCPGKey
{
throw new IOException(oid.getId() + " does not match any known curve.");
}
- if (!(curve.getCurve() instanceof ECCurve.Fp))
+ // TODO: fix when custom curves have common interface
+ if (!((curve.getCurve() instanceof ECCurve.Fp) || (curve.getCurve() instanceof SecP256R1Curve)))
{
throw new IOException("Only FPCurves are supported.");
}
- return curve.getCurve().decodePoint(encodedPoint.toByteArray());
+ return curve.getCurve().decodePoint(BigIntegers.asUnsignedByteArray(encodedPoint));
}
}
diff --git a/pkix/src/test/java/org/bouncycastle/eac/test/AllTests.java b/pkix/src/test/java/org/bouncycastle/eac/test/AllTests.java
index a427e334..f8198556 100644
--- a/pkix/src/test/java/org/bouncycastle/eac/test/AllTests.java
+++ b/pkix/src/test/java/org/bouncycastle/eac/test/AllTests.java
@@ -119,7 +119,7 @@ public class AllTests
if (!certHolder.isSignatureValid(verifier))
{
- fail("first signature test failed");
+ fail("second signature test failed");
}
}
@@ -157,7 +157,7 @@ public class AllTests
if (!certHolder.isSignatureValid(verifier))
{
- fail("first signature test failed");
+ fail("second signature test failed");
}
}
@@ -192,7 +192,7 @@ public class AllTests
public static Test suite()
throws Exception
{
- TestSuite suite= new TestSuite("EAC tests");
+ TestSuite suite = new TestSuite("EAC tests");
suite.addTestSuite(AllTests.class);
diff --git a/prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/ec/BCECPublicKey.java b/prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/ec/BCECPublicKey.java
index 0eaae1db..5695e2ef 100644
--- a/prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/ec/BCECPublicKey.java
+++ b/prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/ec/BCECPublicKey.java
@@ -82,6 +82,8 @@ public class BCECPublicKey
ECCurve curve = spec.getParams().getCurve();
EllipticCurve ellipticCurve = EC5Util.convertCurve(curve, spec.getParams().getSeed());
+ // this may seem a little long-winded but it's how we pick up the custom curve.
+ this.q = EC5Util.convertCurve(ellipticCurve).createPoint(spec.getQ().getAffineXCoord().toBigInteger(), spec.getQ().getAffineYCoord().toBigInteger());
this.ecSpec = EC5Util.convertSpec(ellipticCurve, spec.getParams());
}
else
@@ -132,7 +134,6 @@ public class BCECPublicKey
ECDomainParameters dp = params.getParameters();
this.algorithm = algorithm;
- this.q = params.getQ();
if (spec == null)
{
@@ -147,6 +148,8 @@ public class BCECPublicKey
this.ecSpec = EC5Util.convertSpec(ellipticCurve, spec);
}
+ this.q = EC5Util.convertCurve(ecSpec.getCurve()).createPoint(params.getQ().getAffineXCoord().toBigInteger(), params.getQ().getAffineYCoord().toBigInteger());
+
this.configuration = configuration;
}
diff --git a/prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/util/EC5Util.java b/prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/util/EC5Util.java
index 5eea1b92..e409b978 100644
--- a/prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/util/EC5Util.java
+++ b/prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/util/EC5Util.java
@@ -7,13 +7,27 @@ import java.security.spec.ECFieldFp;
import java.security.spec.ECParameterSpec;
import java.security.spec.ECPoint;
import java.security.spec.EllipticCurve;
+import java.util.HashMap;
+import java.util.Map;
+import org.bouncycastle.asn1.sec.SECNamedCurves;
+import org.bouncycastle.crypto.ec.CustomNamedCurves;
import org.bouncycastle.jce.spec.ECNamedCurveParameterSpec;
import org.bouncycastle.jce.spec.ECNamedCurveSpec;
import org.bouncycastle.math.ec.ECCurve;
+import org.bouncycastle.math.ec.custom.sec.SecP256K1Curve;
+import org.bouncycastle.math.ec.custom.sec.SecP256R1Curve;
public class EC5Util
{
+ private static Map customCurves = new HashMap();
+
+ static
+ {
+ customCurves.put(SECNamedCurves.getByName("secp256k1").getCurve(), CustomNamedCurves.getByName("secp256k1").getCurve());
+ customCurves.put(SECNamedCurves.getByName("secp256r1").getCurve(), CustomNamedCurves.getByName("secp256r1").getCurve());
+ }
+
public static EllipticCurve convertCurve(
ECCurve curve,
byte[] seed)
@@ -24,6 +38,15 @@ public class EC5Util
{
return new EllipticCurve(new ECFieldFp(((ECCurve.Fp)curve).getQ()), curve.getA().toBigInteger(), curve.getB().toBigInteger(), null);
}
+ // TODO: really need an interface for these!!
+ else if (curve instanceof SecP256R1Curve)
+ {
+ return new EllipticCurve(new ECFieldFp(((SecP256R1Curve)curve).getQ()), curve.getA().toBigInteger(), curve.getB().toBigInteger(), null);
+ }
+ else if (curve instanceof SecP256K1Curve)
+ {
+ return new EllipticCurve(new ECFieldFp(((SecP256K1Curve)curve).getQ()), curve.getA().toBigInteger(), curve.getB().toBigInteger(), null);
+ }
else
{
ECCurve.F2m curveF2m = (ECCurve.F2m)curve;
@@ -53,7 +76,14 @@ public class EC5Util
if (field instanceof ECFieldFp)
{
- return new ECCurve.Fp(((ECFieldFp)field).getP(), a, b);
+ ECCurve.Fp curve = new ECCurve.Fp(((ECFieldFp)field).getP(), a, b);
+
+ if (customCurves.containsKey(curve))
+ {
+ return (ECCurve)customCurves.get(curve);
+ }
+
+ return curve;
}
else
{
diff --git a/prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/util/ECUtil.java b/prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/util/ECUtil.java
index fea5d9bf..4283273d 100644
--- a/prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/util/ECUtil.java
+++ b/prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/util/ECUtil.java
@@ -8,12 +8,12 @@ import org.bouncycastle.asn1.ASN1ObjectIdentifier;
import org.bouncycastle.asn1.cryptopro.ECGOST3410NamedCurves;
import org.bouncycastle.asn1.nist.NISTNamedCurves;
import org.bouncycastle.asn1.pkcs.PrivateKeyInfo;
-import org.bouncycastle.asn1.sec.SECCustomNamedCurves;
import org.bouncycastle.asn1.sec.SECNamedCurves;
import org.bouncycastle.asn1.teletrust.TeleTrusTNamedCurves;
import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo;
import org.bouncycastle.asn1.x9.X962NamedCurves;
import org.bouncycastle.asn1.x9.X9ECParameters;
+import org.bouncycastle.crypto.ec.CustomNamedCurves;
import org.bouncycastle.crypto.params.AsymmetricKeyParameter;
import org.bouncycastle.crypto.params.ECDomainParameters;
import org.bouncycastle.crypto.params.ECPrivateKeyParameters;
@@ -242,15 +242,15 @@ public class ECUtil
public static X9ECParameters getNamedCurveByOid(
ASN1ObjectIdentifier oid)
{
- X9ECParameters params = X962NamedCurves.getByOID(oid);
-
+ X9ECParameters params = CustomNamedCurves.getByOID(oid);
+
if (params == null)
{
- params = SECCustomNamedCurves.getByOID(oid);
+ params = X962NamedCurves.getByOID(oid);
if (params == null)
{
params = SECNamedCurves.getByOID(oid);
- } else { System.out.println("using custom curve"); }
+ }
if (params == null)
{
params = NISTNamedCurves.getByOID(oid);
diff --git a/prov/src/main/java/org/bouncycastle/jce/ECNamedCurveTable.java b/prov/src/main/java/org/bouncycastle/jce/ECNamedCurveTable.java
index 941f4763..5ad207ac 100644
--- a/prov/src/main/java/org/bouncycastle/jce/ECNamedCurveTable.java
+++ b/prov/src/main/java/org/bouncycastle/jce/ECNamedCurveTable.java
@@ -21,19 +21,35 @@ public class ECNamedCurveTable
public static ECNamedCurveParameterSpec getParameterSpec(
String name)
{
- X9ECParameters ecP = org.bouncycastle.asn1.x9.ECNamedCurveTable.getByName(name);
+ X9ECParameters ecP = org.bouncycastle.crypto.ec.CustomNamedCurves.getByName(name);
if (ecP == null)
{
try
{
- ecP = org.bouncycastle.asn1.x9.ECNamedCurveTable.getByOID(new ASN1ObjectIdentifier(name));
+ ecP = org.bouncycastle.crypto.ec.CustomNamedCurves.getByOID(new ASN1ObjectIdentifier(name));
}
catch (IllegalArgumentException e)
{
// ignore - not an oid
}
+
+ if (ecP == null)
+ {
+ ecP = org.bouncycastle.asn1.x9.ECNamedCurveTable.getByName(name);
+ if (ecP == null)
+ {
+ try
+ {
+ ecP = org.bouncycastle.asn1.x9.ECNamedCurveTable.getByOID(new ASN1ObjectIdentifier(name));
+ }
+ catch (IllegalArgumentException e)
+ {
+ // ignore - not an oid
+ }
+ }
+ }
}
-
+
if (ecP == null)
{
return null;
diff --git a/prov/src/test/java/org/bouncycastle/jce/provider/test/ECDSA5Test.java b/prov/src/test/java/org/bouncycastle/jce/provider/test/ECDSA5Test.java
index 802134c1..24354c80 100644
--- a/prov/src/test/java/org/bouncycastle/jce/provider/test/ECDSA5Test.java
+++ b/prov/src/test/java/org/bouncycastle/jce/provider/test/ECDSA5Test.java
@@ -27,6 +27,8 @@ import java.security.spec.ECPoint;
import java.security.spec.ECPrivateKeySpec;
import java.security.spec.ECPublicKeySpec;
import java.security.spec.EllipticCurve;
+import java.security.spec.PKCS8EncodedKeySpec;
+import java.security.spec.X509EncodedKeySpec;
import org.bouncycastle.asn1.ASN1InputStream;
import org.bouncycastle.asn1.ASN1ObjectIdentifier;
@@ -38,11 +40,14 @@ import org.bouncycastle.asn1.sec.SECObjectIdentifiers;
import org.bouncycastle.asn1.teletrust.TeleTrusTObjectIdentifiers;
import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo;
import org.bouncycastle.asn1.x9.X962Parameters;
+import org.bouncycastle.asn1.x9.X9ECParameters;
import org.bouncycastle.asn1.x9.X9ObjectIdentifiers;
+import org.bouncycastle.jcajce.provider.asymmetric.util.ECUtil;
import org.bouncycastle.jce.ECKeyUtil;
import org.bouncycastle.jce.ECNamedCurveTable;
import org.bouncycastle.jce.ECPointUtil;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
+import org.bouncycastle.math.ec.ECCurve;
import org.bouncycastle.util.BigIntegers;
import org.bouncycastle.util.encoders.Hex;
import org.bouncycastle.util.test.FixedSecureRandom;
@@ -734,6 +739,76 @@ public class ECDSA5Test
}
}
+ private void testNamedCurveSigning()
+ throws Exception
+ {
+ testCustomNamedCurveSigning("secp256r1");
+ testCustomNamedCurveSigning("secp256k1");
+ }
+
+ private void testCustomNamedCurveSigning(String name)
+ throws Exception
+ {
+ X9ECParameters x9Params = ECUtil.getNamedCurveByOid(ECUtil.getNamedCurveOid(name));
+
+ // TODO: one day this may have to change
+ if (x9Params.getCurve() instanceof ECCurve.Fp)
+ {
+ fail("curve not custom curve!!");
+ }
+
+ AlgorithmParameterSpec ecSpec = ECNamedCurveTable.getParameterSpec(name);
+ KeyPairGenerator keygen = KeyPairGenerator.getInstance("EC", "BC");
+ keygen.initialize(ecSpec, new ECRandom());
+
+ KeyPair keys = keygen.generateKeyPair();
+
+ PrivateKeyInfo priv1 = PrivateKeyInfo.getInstance(keys.getPrivate().getEncoded());
+ SubjectPublicKeyInfo pub1 = SubjectPublicKeyInfo.getInstance(keys.getPublic().getEncoded());
+
+ keygen = KeyPairGenerator.getInstance("EC", "BC");
+ keygen.initialize(new ECGenParameterSpec("secp256r1"), new ECRandom());
+
+ Signature ecdsaSigner = Signature.getInstance("ECDSA", "BC");
+
+ ecdsaSigner.initSign(keys.getPrivate());
+
+ ecdsaSigner.update(new byte[100]);
+
+ byte[] sig = ecdsaSigner.sign();
+
+ ecdsaSigner.initVerify(keys.getPublic());
+
+ ecdsaSigner.update(new byte[100]);
+
+ if (!ecdsaSigner.verify(sig))
+ {
+ fail("signature failed to verify");
+ }
+
+ KeyFactory kFact = KeyFactory.getInstance("EC", "BC");
+
+ PublicKey pub = kFact.generatePublic(new X509EncodedKeySpec(pub1.getEncoded()));
+ PrivateKey pri = kFact.generatePrivate(new PKCS8EncodedKeySpec(priv1.getEncoded()));
+
+ ecdsaSigner = Signature.getInstance("ECDSA", "BC");
+
+ ecdsaSigner.initSign(pri);
+
+ ecdsaSigner.update(new byte[100]);
+
+ sig = ecdsaSigner.sign();
+
+ ecdsaSigner.initVerify(pub);
+
+ ecdsaSigner.update(new byte[100]);
+
+ if (!ecdsaSigner.verify(sig))
+ {
+ fail("signature failed to verify");
+ }
+ }
+
protected BigInteger[] derDecode(
byte[] encoding)
throws IOException
@@ -766,6 +841,7 @@ public class ECDSA5Test
testGeneration();
testKeyPairGenerationWithOIDs();
testNamedCurveParameterPreservation();
+ testNamedCurveSigning();
}
public static void main(