summaryrefslogtreecommitdiff
path: root/bcprov/src/main/java/org/bouncycastle/math
diff options
context:
space:
mode:
authorBrian Carlstrom <bdc@google.com>2013-05-24 19:14:15 -0700
committerBrian Carlstrom <bdc@google.com>2013-06-03 14:01:40 -0700
commita198e1ecc615e26a167d0f2dca9fa7e5fc62de10 (patch)
tree6ac741d0b1ccd61f033299754a0b9a3a54985e18 /bcprov/src/main/java/org/bouncycastle/math
parent67e643cbf3cff776bf1a8fe1ea50a14ccf2d41e4 (diff)
downloadbouncycastle-a198e1ecc615e26a167d0f2dca9fa7e5fc62de10.tar.gz
bouncycastle 1.49 upgrade
Change-Id: Icbf5a147409c810060a5acc884834fb2a778e860
Diffstat (limited to 'bcprov/src/main/java/org/bouncycastle/math')
-rw-r--r--bcprov/src/main/java/org/bouncycastle/math/ec/ECCurve.java243
-rw-r--r--bcprov/src/main/java/org/bouncycastle/math/ec/ECPoint.java17
2 files changed, 109 insertions, 151 deletions
diff --git a/bcprov/src/main/java/org/bouncycastle/math/ec/ECCurve.java b/bcprov/src/main/java/org/bouncycastle/math/ec/ECCurve.java
index c9841048..58281af7 100644
--- a/bcprov/src/main/java/org/bouncycastle/math/ec/ECCurve.java
+++ b/bcprov/src/main/java/org/bouncycastle/math/ec/ECCurve.java
@@ -16,8 +16,6 @@ public abstract class ECCurve
public abstract ECPoint createPoint(BigInteger x, BigInteger y, boolean withCompression);
- public abstract ECPoint decodePoint(byte[] encoded);
-
public abstract ECPoint getInfinity();
public ECFieldElement getA()
@@ -30,6 +28,74 @@ public abstract class ECCurve
return b;
}
+ protected abstract ECPoint decompressPoint(int yTilde, BigInteger X1);
+
+ /**
+ * 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).
+ * @return The decoded point.
+ */
+ public ECPoint decodePoint(byte[] encoded)
+ {
+ ECPoint p = null;
+ int expectedLength = (getFieldSize() + 7) / 8;
+
+ switch (encoded[0])
+ {
+ case 0x00: // infinity
+ {
+ if (encoded.length != 1)
+ {
+ throw new IllegalArgumentException("Incorrect length for infinity encoding");
+ }
+
+ p = getInfinity();
+ break;
+ }
+ case 0x02: // compressed
+ case 0x03: // compressed
+ {
+ if (encoded.length != (expectedLength + 1))
+ {
+ throw new IllegalArgumentException("Incorrect length for compressed encoding");
+ }
+
+ int yTilde = encoded[0] & 1;
+ BigInteger X1 = fromArray(encoded, 1, expectedLength);
+
+ p = decompressPoint(yTilde, X1);
+ break;
+ }
+ case 0x04: // uncompressed
+ case 0x06: // hybrid
+ case 0x07: // hybrid
+ {
+ if (encoded.length != (2 * expectedLength + 1))
+ {
+ throw new IllegalArgumentException("Incorrect length for uncompressed/hybrid encoding");
+ }
+
+ BigInteger X1 = fromArray(encoded, 1, expectedLength);
+ BigInteger Y1 = fromArray(encoded, 1 + expectedLength, expectedLength);
+
+ p = createPoint(X1, Y1, false);
+ break;
+ }
+ default:
+ throw new IllegalArgumentException("Invalid point encoding 0x" + Integer.toString(encoded[0], 16));
+ }
+
+ 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
*/
@@ -66,79 +132,31 @@ public abstract class ECCurve
return new ECPoint.Fp(this, fromBigInteger(x), fromBigInteger(y), withCompression);
}
- /**
- * 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).
- * @return The decoded point.
- */
- public ECPoint decodePoint(byte[] encoded)
+ protected ECPoint decompressPoint(int yTilde, BigInteger X1)
{
- ECPoint p = null;
+ ECFieldElement x = fromBigInteger(X1);
+ ECFieldElement alpha = x.multiply(x.square().add(a)).add(b);
+ ECFieldElement beta = alpha.sqrt();
- switch (encoded[0])
+ //
+ // if we can't find a sqrt we haven't got a point on the
+ // curve - run!
+ //
+ if (beta == null)
{
- // infinity
- case 0x00:
- if (encoded.length > 1)
- {
- throw new RuntimeException("Invalid point encoding");
- }
- p = getInfinity();
- break;
- // compressed
- case 0x02:
- case 0x03:
- int ytilde = encoded[0] & 1;
- byte[] i = new byte[encoded.length - 1];
-
- System.arraycopy(encoded, 1, i, 0, i.length);
-
- ECFieldElement x = new ECFieldElement.Fp(this.q, new BigInteger(1, i));
- ECFieldElement alpha = x.multiply(x.square().add(a)).add(b);
- ECFieldElement beta = alpha.sqrt();
-
- //
- // if we can't find a sqrt we haven't got a point on the
- // curve - run!
- //
- if (beta == null)
- {
- throw new RuntimeException("Invalid point compression");
- }
+ throw new RuntimeException("Invalid point compression");
+ }
- int bit0 = (beta.toBigInteger().testBit(0) ? 1 : 0);
+ BigInteger betaValue = beta.toBigInteger();
+ int bit0 = betaValue.testBit(0) ? 1 : 0;
- if (bit0 == ytilde)
- {
- p = new ECPoint.Fp(this, x, beta, true);
- }
- else
- {
- p = new ECPoint.Fp(this, x,
- new ECFieldElement.Fp(this.q, q.subtract(beta.toBigInteger())), true);
- }
- break;
- // uncompressed
- case 0x04:
- // hybrid
- case 0x06:
- case 0x07:
- byte[] xEnc = new byte[(encoded.length - 1) / 2];
- byte[] yEnc = new byte[(encoded.length - 1) / 2];
-
- System.arraycopy(encoded, 1, xEnc, 0, xEnc.length);
- System.arraycopy(encoded, xEnc.length + 1, yEnc, 0, yEnc.length);
-
- p = new ECPoint.Fp(this,
- new ECFieldElement.Fp(this.q, new BigInteger(1, xEnc)),
- new ECFieldElement.Fp(this.q, new BigInteger(1, yEnc)));
- break;
- default:
- throw new RuntimeException("Invalid point encoding 0x" + Integer.toString(encoded[0], 16));
+ if (bit0 != yTilde)
+ {
+ // Use the other root
+ beta = fromBigInteger(q.subtract(betaValue));
}
- return p;
+ return new ECPoint.Fp(this, x, beta, true);
}
public ECPoint getInfinity()
@@ -403,62 +421,6 @@ public abstract class ECCurve
return new ECPoint.F2m(this, fromBigInteger(x), fromBigInteger(y), withCompression);
}
- /* (non-Javadoc)
- * @see org.bouncycastle.math.ec.ECCurve#decodePoint(byte[])
- */
- public ECPoint decodePoint(byte[] encoded)
- {
- ECPoint p = null;
-
- switch (encoded[0])
- {
- // infinity
- case 0x00:
- if (encoded.length > 1)
- {
- throw new RuntimeException("Invalid point encoding");
- }
- p = getInfinity();
- break;
- // compressed
- case 0x02:
- case 0x03:
- byte[] enc = new byte[encoded.length - 1];
- System.arraycopy(encoded, 1, enc, 0, enc.length);
- if (encoded[0] == 0x02)
- {
- p = decompressPoint(enc, 0);
- }
- else
- {
- p = decompressPoint(enc, 1);
- }
- break;
- // uncompressed
- case 0x04:
- // hybrid
- case 0x06:
- case 0x07:
- byte[] xEnc = new byte[(encoded.length - 1) / 2];
- byte[] yEnc = new byte[(encoded.length - 1) / 2];
-
- System.arraycopy(encoded, 1, xEnc, 0, xEnc.length);
- System.arraycopy(encoded, xEnc.length + 1, yEnc, 0, yEnc.length);
-
- p = new ECPoint.F2m(this,
- new ECFieldElement.F2m(this.m, this.k1, this.k2, this.k3,
- new BigInteger(1, xEnc)),
- new ECFieldElement.F2m(this.m, this.k1, this.k2, this.k3,
- new BigInteger(1, yEnc)), false);
- break;
-
- default:
- throw new RuntimeException("Invalid point encoding 0x" + Integer.toString(encoded[0], 16));
- }
-
- return p;
- }
-
public ECPoint getInfinity()
{
return infinity;
@@ -508,18 +470,15 @@ public abstract class ECCurve
/**
* Decompresses a compressed point P = (xp, yp) (X9.62 s 4.2.2).
*
- * @param xEnc
- * The encoding of field element xp.
- * @param ypBit
+ * @param yTilde
* ~yp, an indication bit for the decompression of yp.
+ * @param X1
+ * The field element xp.
* @return the decompressed point.
*/
- private ECPoint decompressPoint(
- byte[] xEnc,
- int ypBit)
+ protected ECPoint decompressPoint(int yTilde, BigInteger X1)
{
- ECFieldElement xp = new ECFieldElement.F2m(
- this.m, this.k1, this.k2, this.k3, new BigInteger(1, xEnc));
+ ECFieldElement xp = fromBigInteger(X1);
ECFieldElement yp = null;
if (xp.toBigInteger().equals(ECConstants.ZERO))
{
@@ -531,27 +490,21 @@ public abstract class ECCurve
}
else
{
- ECFieldElement beta = xp.add(a).add(
- b.multiply(xp.square().invert()));
+ ECFieldElement beta = xp.add(a).add(b.multiply(xp.square().invert()));
ECFieldElement z = solveQuadradicEquation(beta);
if (z == null)
{
- throw new RuntimeException("Invalid point compression");
+ throw new IllegalArgumentException("Invalid point compression");
}
- int zBit = 0;
- if (z.toBigInteger().testBit(0))
+ int zBit = z.toBigInteger().testBit(0) ? 1 : 0;
+ if (zBit != yTilde)
{
- zBit = 1;
- }
- if (zBit != ypBit)
- {
- z = z.add(new ECFieldElement.F2m(this.m, this.k1, this.k2,
- this.k3, ECConstants.ONE));
+ z = z.add(fromBigInteger(ECConstants.ONE));
}
yp = xp.multiply(z);
}
-
- return new ECPoint.F2m(this, xp, yp);
+
+ return new ECPoint.F2m(this, xp, yp, true);
}
/**
diff --git a/bcprov/src/main/java/org/bouncycastle/math/ec/ECPoint.java b/bcprov/src/main/java/org/bouncycastle/math/ec/ECPoint.java
index b14e4c15..cbc5aaf4 100644
--- a/bcprov/src/main/java/org/bouncycastle/math/ec/ECPoint.java
+++ b/bcprov/src/main/java/org/bouncycastle/math/ec/ECPoint.java
@@ -108,7 +108,12 @@ public abstract class ECPoint
this.preCompInfo = preCompInfo;
}
- public abstract byte[] getEncoded();
+ public byte[] getEncoded()
+ {
+ return getEncoded(withCompression);
+ }
+
+ public abstract byte[] getEncoded(boolean compressed);
public abstract ECPoint add(ECPoint b);
public abstract ECPoint subtract(ECPoint b);
@@ -193,7 +198,7 @@ public abstract class ECPoint
/**
* return the field element encoded with point compression. (S 4.3.6)
*/
- public byte[] getEncoded()
+ public byte[] getEncoded(boolean compressed)
{
if (this.isInfinity())
{
@@ -202,7 +207,7 @@ public abstract class ECPoint
int qLength = converter.getByteLength(x);
- if (withCompression)
+ if (compressed)
{
byte PC;
@@ -268,7 +273,7 @@ public abstract class ECPoint
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);
+ return new ECPoint.Fp(curve, x3, y3, withCompression);
}
// B.3 pg 62
@@ -374,7 +379,7 @@ public abstract class ECPoint
/* (non-Javadoc)
* @see org.bouncycastle.math.ec.ECPoint#getEncoded()
*/
- public byte[] getEncoded()
+ public byte[] getEncoded(boolean compressed)
{
if (this.isInfinity())
{
@@ -385,7 +390,7 @@ public abstract class ECPoint
byte[] X = converter.integerToBytes(this.getX().toBigInteger(), byteCount);
byte[] PO;
- if (withCompression)
+ if (compressed)
{
// See X9.62 4.3.6 and 4.2.2
PO = new byte[byteCount + 1];