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:
authorPeter Dettman <peter.dettman@bouncycastle.org>2013-09-23 11:54:58 +0400
committerPeter Dettman <peter.dettman@bouncycastle.org>2013-09-23 11:54:58 +0400
commit370626d9f71f26fd0d4630f0157a617388da770d (patch)
tree602795d122b021f27a001839b5b19e0a37300cb5 /core/src/main/java/org/bouncycastle/math
parentb64cfd3ce4996f9467094dd51293d652aec5c118 (diff)
ECMultiplier now lives in the ECCurve instead of each point
Add meta-support for using ECCurve with alternative coordinate systems Add ECCurve.configure method to start a fluent configuration, which allows customising (so far) the coordinate system and ECMultiplier to use for calculations. ECPoint objects now required to be on the same curve instance when performing calculations
Diffstat (limited to 'core/src/main/java/org/bouncycastle/math')
-rw-r--r--core/src/main/java/org/bouncycastle/math/ec/ECAlgorithms.java4
-rw-r--r--core/src/main/java/org/bouncycastle/math/ec/ECCurve.java136
2 files changed, 126 insertions, 14 deletions
diff --git a/core/src/main/java/org/bouncycastle/math/ec/ECAlgorithms.java b/core/src/main/java/org/bouncycastle/math/ec/ECAlgorithms.java
index 18f03a1c..13d5d304 100644
--- a/core/src/main/java/org/bouncycastle/math/ec/ECAlgorithms.java
+++ b/core/src/main/java/org/bouncycastle/math/ec/ECAlgorithms.java
@@ -8,7 +8,7 @@ public class ECAlgorithms
ECPoint Q, BigInteger b)
{
ECCurve c = P.getCurve();
- if (!c.equals(Q.getCurve()))
+ if (c != Q.getCurve())
{
throw new IllegalArgumentException("P and Q must be on same curve");
}
@@ -48,7 +48,7 @@ public class ECAlgorithms
public static ECPoint shamirsTrick(ECPoint P, BigInteger k,
ECPoint Q, BigInteger l)
{
- if (!P.getCurve().equals(Q.getCurve()))
+ if (P.getCurve() != Q.getCurve())
{
throw new IllegalArgumentException("P and Q must be on same curve");
}
diff --git a/core/src/main/java/org/bouncycastle/math/ec/ECCurve.java b/core/src/main/java/org/bouncycastle/math/ec/ECCurve.java
index eaf59eee..1338b7ff 100644
--- a/core/src/main/java/org/bouncycastle/math/ec/ECCurve.java
+++ b/core/src/main/java/org/bouncycastle/math/ec/ECCurve.java
@@ -3,22 +3,83 @@ package org.bouncycastle.math.ec;
import java.math.BigInteger;
import java.util.Random;
+import org.bouncycastle.util.BigIntegers;
+
/**
* base class for an elliptic curve
*/
public abstract class ECCurve
{
- ECFieldElement a, b;
+ public static final int COORD_AFFINE = 0;
+ public static final int COORD_HOMOGENEOUS = 1;
+ public static final int COORD_JACOBIAN = 2;
+ public static final int COORD_JACOBIAN_CHUDNOVSKY = 3;
+ public static final int COORD_JACOBIAN_MODIFIED = 4;
+
+ public class Config
+ {
+ protected int coord = COORD_AFFINE;
+ protected ECMultiplier multiplier;
+
+ public Config setCoordinateSystem(int coord)
+ {
+ this.coord = coord;
+ return this;
+ }
+
+ public Config setMultiplier(ECMultiplier multiplier)
+ {
+ this.multiplier = multiplier;
+ return this;
+ }
+
+ public ECCurve create()
+ {
+ if (!supportsCoordinateSystem(coord))
+ {
+ throw new UnsupportedOperationException("unsupported coordinate system");
+ }
+
+ ECCurve c = createCurve(Config.this);
+ if (c == ECCurve.this)
+ {
+ throw new IllegalStateException("implementation returned current curve");
+ }
+
+ return c;
+ }
+ }
+
+ protected ECFieldElement a, b;
+ protected int coord = COORD_AFFINE;
+ protected ECMultiplier multiplier = null;
public abstract int getFieldSize();
public abstract ECFieldElement fromBigInteger(BigInteger x);
+ public Config configure()
+ {
+ return new Config();
+ }
+
public ECPoint createPoint(BigInteger x, BigInteger y)
{
return createPoint(x, y, false);
}
+ protected abstract ECCurve createCurve(Config builder);
+
+ protected ECMultiplier createDefaultMultiplier()
+ {
+ return new DoubleAddMultiplier();
+ }
+
+ protected boolean supportsCoordinateSystem(int coord)
+ {
+ return coord == COORD_AFFINE;
+ }
+
/**
* @deprecated per-point compression property will be removed, use {@link #createPoint(BigInteger, BigInteger)}
* and refer {@link ECPoint#getEncoded(boolean)}
@@ -37,9 +98,26 @@ public abstract class ECCurve
return b;
}
+ public int getCoordinateSystem()
+ {
+ return coord;
+ }
+
protected abstract ECPoint decompressPoint(int yTilde, BigInteger X1);
/**
+ * Sets the default <code>ECMultiplier</code>, unless already set.
+ */
+ public ECMultiplier getMultiplier()
+ {
+ if (this.multiplier == null)
+ {
+ this.multiplier = createDefaultMultiplier();
+ }
+ return this.multiplier;
+ }
+
+ /**
* Decode a point on this curve from its ASN.1 encoding. The different
* encodings are taken account of, including point compression for
* <code>F<sub>p</sub></code> (X9.62 s 4.2.1 pg 17).
@@ -71,7 +149,7 @@ public abstract class ECCurve
}
int yTilde = encoded[0] & 1;
- BigInteger X = fromArray(encoded, 1, expectedLength);
+ BigInteger X = BigIntegers.fromUnsignedByteArray(encoded, 1, expectedLength);
p = decompressPoint(yTilde, X);
break;
@@ -85,8 +163,8 @@ public abstract class ECCurve
throw new IllegalArgumentException("Incorrect length for uncompressed/hybrid encoding");
}
- BigInteger X = fromArray(encoded, 1, expectedLength);
- BigInteger Y = fromArray(encoded, 1 + expectedLength, expectedLength);
+ BigInteger X = BigIntegers.fromUnsignedByteArray(encoded, 1, expectedLength);
+ BigInteger Y = BigIntegers.fromUnsignedByteArray(encoded, 1 + expectedLength, expectedLength);
p = createPoint(X, Y);
break;
@@ -98,13 +176,6 @@ public abstract class ECCurve
return p;
}
- private static BigInteger fromArray(byte[] buf, int off, int length)
- {
- byte[] mag = new byte[length];
- System.arraycopy(buf, off, mag, 0, length);
- return new BigInteger(1, mag);
- }
-
/**
* Elliptic curve over Fp
*/
@@ -117,9 +188,25 @@ public abstract class ECCurve
{
this.q = q;
this.r = ECFieldElement.Fp.calculateResidue(q);
+ this.infinity = new ECPoint.Fp(this, null, null);
this.a = fromBigInteger(a);
this.b = fromBigInteger(b);
+ }
+
+ protected Fp(BigInteger q, BigInteger r, ECFieldElement a, ECFieldElement b)
+ {
+ this.q = q;
+ this.r = r;
this.infinity = new ECPoint.Fp(this, null, null);
+ this.a = a;
+ this.b = b;
+ }
+
+ public ECCurve createCurve(Config builder)
+ {
+ Fp c = new Fp(q, r, a, b);
+ c.multiplier = builder.multiplier;
+ return c;
}
public BigInteger getQ()
@@ -414,6 +501,31 @@ public abstract class ECCurve
this.infinity = new ECPoint.F2m(this, null, null);
}
+ protected F2m(int m, int k1, int k2, int k3, ECFieldElement a, ECFieldElement b, BigInteger n, BigInteger h)
+ {
+ this.m = m;
+ this.k1 = k1;
+ this.k2 = k2;
+ this.k3 = k3;
+ this.n = n;
+ this.h = h;
+ this.a = a;
+ this.b = b;
+ this.infinity = new ECPoint.F2m(this, null, null);
+ }
+
+ public ECCurve createCurve(Config builder)
+ {
+ F2m c = new F2m(m, k1, k2, k3, a, b, n, h);
+ c.multiplier = builder.multiplier;
+ return c;
+ }
+
+ protected ECMultiplier createDefaultMultiplier()
+ {
+ return isKoblitz() ? new WTauNafMultiplier() : new WNafMultiplier();
+ }
+
public int getFieldSize()
{
return m;
@@ -569,7 +681,7 @@ public abstract class ECCurve
}
ECCurve.F2m other = (ECCurve.F2m)anObject;
-
+
return (this.m == other.m) && (this.k1 == other.k1)
&& (this.k2 == other.k2) && (this.k3 == other.k3)
&& a.equals(other.a) && b.equals(other.b);