aboutsummaryrefslogtreecommitdiffstats
path: root/src/org/bouncycastle/math/ec/ECPoint.java
diff options
context:
space:
mode:
authorKenny Root <kenny@the-b.org>2013-04-12 06:57:21 -0700
committerKenny Root <kenny@the-b.org>2013-04-12 06:57:21 -0700
commit82da776132927427339c6c801e955f75c70e4435 (patch)
treee7431dc664ed8e2c7e413fac47bc69bf173f7a86 /src/org/bouncycastle/math/ec/ECPoint.java
parentf7beb3b827f0eb6d03d8ff3589782a0df14fd2f5 (diff)
downloadconnectbot-82da776132927427339c6c801e955f75c70e4435.tar.gz
connectbot-82da776132927427339c6c801e955f75c70e4435.tar.bz2
connectbot-82da776132927427339c6c801e955f75c70e4435.zip
Add missing EC math files
Diffstat (limited to 'src/org/bouncycastle/math/ec/ECPoint.java')
-rw-r--r--src/org/bouncycastle/math/ec/ECPoint.java335
1 files changed, 335 insertions, 0 deletions
diff --git a/src/org/bouncycastle/math/ec/ECPoint.java b/src/org/bouncycastle/math/ec/ECPoint.java
new file mode 100644
index 0000000..f4056bb
--- /dev/null
+++ b/src/org/bouncycastle/math/ec/ECPoint.java
@@ -0,0 +1,335 @@
+package org.bouncycastle.math.ec;
+
+import java.math.BigInteger;
+
+/**
+ * base class for points on elliptic curves.
+ */
+public abstract class ECPoint
+{
+ ECCurve curve;
+ ECFieldElement x;
+ ECFieldElement y;
+
+ protected boolean withCompression;
+
+ protected ECMultiplier multiplier = null;
+
+ protected PreCompInfo preCompInfo = null;
+
+// private static X9IntegerConverter converter = new X9IntegerConverter();
+
+ protected ECPoint(ECCurve curve, ECFieldElement x, ECFieldElement y)
+ {
+ this.curve = curve;
+ this.x = x;
+ this.y = y;
+ }
+
+ public ECCurve getCurve()
+ {
+ return curve;
+ }
+
+ public ECFieldElement getX()
+ {
+ return x;
+ }
+
+ public ECFieldElement getY()
+ {
+ return y;
+ }
+
+ public boolean isInfinity()
+ {
+ return x == null && y == null;
+ }
+
+ public boolean isCompressed()
+ {
+ return withCompression;
+ }
+
+ @Override
+ public boolean equals(
+ Object other)
+ {
+ if (other == this)
+ {
+ return true;
+ }
+
+ if (!(other instanceof ECPoint))
+ {
+ return false;
+ }
+
+ ECPoint o = (ECPoint)other;
+
+ if (this.isInfinity())
+ {
+ return o.isInfinity();
+ }
+
+ return x.equals(o.x) && y.equals(o.y);
+ }
+
+ @Override
+ public int hashCode()
+ {
+ if (this.isInfinity())
+ {
+ return 0;
+ }
+
+ return x.hashCode() ^ y.hashCode();
+ }
+
+// /**
+// * Mainly for testing. Explicitly set the <code>ECMultiplier</code>.
+// * @param multiplier The <code>ECMultiplier</code> to be used to multiply
+// * this <code>ECPoint</code>.
+// */
+// public void setECMultiplier(ECMultiplier multiplier)
+// {
+// this.multiplier = multiplier;
+// }
+
+ /**
+ * Sets the <code>PreCompInfo</code>. Used by <code>ECMultiplier</code>s
+ * to save the precomputation for this <code>ECPoint</code> to store the
+ * precomputation result for use by subsequent multiplication.
+ * @param preCompInfo The values precomputed by the
+ * <code>ECMultiplier</code>.
+ */
+ void setPreCompInfo(PreCompInfo preCompInfo)
+ {
+ this.preCompInfo = preCompInfo;
+ }
+
+ public abstract byte[] getEncoded();
+
+ public abstract ECPoint add(ECPoint b);
+ public abstract ECPoint subtract(ECPoint b);
+ public abstract ECPoint negate();
+ public abstract ECPoint twice();
+
+ /**
+ * Sets the default <code>ECMultiplier</code>, unless already set.
+ */
+ synchronized void assertECMultiplier()
+ {
+ if (this.multiplier == null)
+ {
+ this.multiplier = new FpNafMultiplier();
+ }
+ }
+
+ /**
+ * Multiplies this <code>ECPoint</code> by the given number.
+ * @param k The multiplicator.
+ * @return <code>k * this</code>.
+ */
+ public ECPoint multiply(BigInteger k)
+ {
+ if (k.signum() < 0)
+ {
+ throw new IllegalArgumentException("The multiplicator cannot be negative");
+ }
+
+ if (this.isInfinity())
+ {
+ return this;
+ }
+
+ if (k.signum() == 0)
+ {
+ return this.curve.getInfinity();
+ }
+
+ assertECMultiplier();
+ return this.multiplier.multiply(this, k, preCompInfo);
+ }
+
+ /**
+ * Elliptic curve points over Fp
+ */
+ public static class Fp extends ECPoint
+ {
+
+ /**
+ * Create a point which encodes with point compression.
+ *
+ * @param curve the curve to use
+ * @param x affine x co-ordinate
+ * @param y affine y co-ordinate
+ */
+ public Fp(ECCurve curve, ECFieldElement x, ECFieldElement y)
+ {
+ this(curve, x, y, false);
+ }
+
+ /**
+ * Create a point that encodes with or without point compresion.
+ *
+ * @param curve the curve to use
+ * @param x affine x co-ordinate
+ * @param y affine y co-ordinate
+ * @param withCompression if true encode with point compression
+ */
+ public Fp(ECCurve curve, ECFieldElement x, ECFieldElement y, boolean withCompression)
+ {
+ super(curve, x, y);
+
+ if ((x != null && y == null) || (x == null && y != null))
+ {
+ throw new IllegalArgumentException("Exactly one of the field elements is null");
+ }
+
+ this.withCompression = withCompression;
+ }
+
+ /**
+ * return the field element encoded with point compression. (S 4.3.6)
+ */
+ public byte[] getEncoded()
+ {
+ return null;
+ // BEGIN connectbot-removed
+// if (this.isInfinity())
+// {
+// return new byte[1];
+// }
+//
+// int qLength = converter.getByteLength(x);
+//
+// if (withCompression)
+// {
+// byte PC;
+//
+// if (this.getY().toBigInteger().testBit(0))
+// {
+// PC = 0x03;
+// }
+// else
+// {
+// PC = 0x02;
+// }
+//
+// byte[] X = converter.integerToBytes(this.getX().toBigInteger(), qLength);
+// byte[] PO = new byte[X.length + 1];
+//
+// PO[0] = PC;
+// System.arraycopy(X, 0, PO, 1, X.length);
+//
+// return PO;
+// }
+// else
+// {
+// byte[] X = converter.integerToBytes(this.getX().toBigInteger(), qLength);
+// byte[] Y = converter.integerToBytes(this.getY().toBigInteger(), qLength);
+// byte[] PO = new byte[X.length + Y.length + 1];
+//
+// PO[0] = 0x04;
+// System.arraycopy(X, 0, PO, 1, X.length);
+// System.arraycopy(Y, 0, PO, X.length + 1, Y.length);
+//
+// return PO;
+// }
+ }
+
+ // B.3 pg 62
+ @Override
+ public ECPoint add(ECPoint b)
+ {
+ if (this.isInfinity())
+ {
+ return b;
+ }
+
+ if (b.isInfinity())
+ {
+ return this;
+ }
+
+ // Check if b = this or b = -this
+ if (this.x.equals(b.x))
+ {
+ if (this.y.equals(b.y))
+ {
+ // this = b, i.e. this must be doubled
+ return this.twice();
+ }
+
+ // this = -b, i.e. the result is the point at infinity
+ return this.curve.getInfinity();
+ }
+
+ ECFieldElement gamma = b.y.subtract(this.y).divide(b.x.subtract(this.x));
+
+ ECFieldElement x3 = gamma.square().subtract(this.x).subtract(b.x);
+ ECFieldElement y3 = gamma.multiply(this.x.subtract(x3)).subtract(this.y);
+
+ return new ECPoint.Fp(curve, x3, y3);
+ }
+
+ // B.3 pg 62
+ @Override
+ public ECPoint twice()
+ {
+ if (this.isInfinity())
+ {
+ // Twice identity element (point at infinity) is identity
+ return this;
+ }
+
+ if (this.y.toBigInteger().signum() == 0)
+ {
+ // if y1 == 0, then (x1, y1) == (x1, -y1)
+ // and hence this = -this and thus 2(x1, y1) == infinity
+ return this.curve.getInfinity();
+ }
+
+ ECFieldElement TWO = this.curve.fromBigInteger(BigInteger.valueOf(2));
+ ECFieldElement THREE = this.curve.fromBigInteger(BigInteger.valueOf(3));
+ ECFieldElement gamma = this.x.square().multiply(THREE).add(curve.a).divide(y.multiply(TWO));
+
+ ECFieldElement x3 = gamma.square().subtract(this.x.multiply(TWO));
+ ECFieldElement y3 = gamma.multiply(this.x.subtract(x3)).subtract(this.y);
+
+ return new ECPoint.Fp(curve, x3, y3, this.withCompression);
+ }
+
+ // D.3.2 pg 102 (see Note:)
+ @Override
+ public ECPoint subtract(ECPoint b)
+ {
+ if (b.isInfinity())
+ {
+ return this;
+ }
+
+ // Add -b
+ return add(b.negate());
+ }
+
+ @Override
+ public ECPoint negate()
+ {
+ return new ECPoint.Fp(curve, this.x, this.y.negate(), this.withCompression);
+ }
+
+ /**
+ * Sets the default <code>ECMultiplier</code>, unless already set.
+ */
+ @Override
+ synchronized void assertECMultiplier()
+ {
+ if (this.multiplier == null)
+ {
+ this.multiplier = new WNafMultiplier();
+ }
+ }
+ }
+}