diff options
author | Peter Dettman <peter.dettman@bouncycastle.org> | 2013-09-23 11:54:58 +0400 |
---|---|---|
committer | Peter Dettman <peter.dettman@bouncycastle.org> | 2013-09-23 11:54:58 +0400 |
commit | 370626d9f71f26fd0d4630f0157a617388da770d (patch) | |
tree | 602795d122b021f27a001839b5b19e0a37300cb5 /core/src/main/java/org/bouncycastle/math | |
parent | b64cfd3ce4996f9467094dd51293d652aec5c118 (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.java | 4 | ||||
-rw-r--r-- | core/src/main/java/org/bouncycastle/math/ec/ECCurve.java | 136 |
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); |