diff --git a/crypto/src/math/ec/ECAlgorithms.cs b/crypto/src/math/ec/ECAlgorithms.cs
index d82cafedf..3c911b173 100644
--- a/crypto/src/math/ec/ECAlgorithms.cs
+++ b/crypto/src/math/ec/ECAlgorithms.cs
@@ -49,10 +49,10 @@ namespace Org.BouncyCastle.Math.EC
GlvEndomorphism glvEndomorphism = c.GetEndomorphism() as GlvEndomorphism;
if (glvEndomorphism != null)
{
- return ImplSumOfMultipliesGlv(imported, ks, glvEndomorphism);
+ return ValidatePoint(ImplSumOfMultipliesGlv(imported, ks, glvEndomorphism));
}
- return ImplSumOfMultiplies(imported, ks);
+ return ValidatePoint(ImplSumOfMultiplies(imported, ks));
}
public static ECPoint SumOfTwoMultiplies(ECPoint P, BigInteger a, ECPoint Q, BigInteger b)
@@ -66,17 +66,18 @@ namespace Org.BouncyCastle.Math.EC
F2mCurve f2mCurve = (F2mCurve) cp;
if (f2mCurve.IsKoblitz)
{
- return P.Multiply(a).Add(Q.Multiply(b));
+ return ValidatePoint(P.Multiply(a).Add(Q.Multiply(b)));
}
}
GlvEndomorphism glvEndomorphism = cp.GetEndomorphism() as GlvEndomorphism;
if (glvEndomorphism != null)
{
- return ImplSumOfMultipliesGlv(new ECPoint[] { P, Q }, new BigInteger[] { a, b }, glvEndomorphism);
+ return ValidatePoint(
+ ImplSumOfMultipliesGlv(new ECPoint[] { P, Q }, new BigInteger[] { a, b }, glvEndomorphism));
}
- return ImplShamirsTrickWNaf(P, a, Q, b);
+ return ValidatePoint(ImplShamirsTrickWNaf(P, a, Q, b));
}
/*
@@ -102,7 +103,7 @@ namespace Org.BouncyCastle.Math.EC
ECCurve cp = P.Curve;
Q = ImportPoint(cp, Q);
- return ImplShamirsTrickJsf(P, k, Q, l);
+ return ValidatePoint(ImplShamirsTrickJsf(P, k, Q, l));
}
public static ECPoint ImportPoint(ECCurve c, ECPoint p)
@@ -145,6 +146,47 @@ namespace Org.BouncyCastle.Math.EC
zs[off] = u;
}
+ /**
+ * Simple shift-and-add multiplication. Serves as reference implementation
+ * to verify (possibly faster) implementations, and for very small scalars.
+ *
+ * @param p
+ * The point to multiply.
+ * @param k
+ * The multiplier.
+ * @return The result of the point multiplication <code>kP</code>.
+ */
+ public static ECPoint ReferenceMultiply(ECPoint p, BigInteger k)
+ {
+ BigInteger x = k.Abs();
+ ECPoint q = p.Curve.Infinity;
+ int t = x.BitLength;
+ if (t > 0)
+ {
+ if (x.TestBit(0))
+ {
+ q = p;
+ }
+ for (int i = 1; i < t; i++)
+ {
+ p = p.Twice();
+ if (x.TestBit(i))
+ {
+ q = q.Add(p);
+ }
+ }
+ }
+ return k.SignValue < 0 ? q.Negate() : q;
+ }
+
+ public static ECPoint ValidatePoint(ECPoint p)
+ {
+ if (!p.IsValid())
+ throw new ArgumentException("Invalid point", "p");
+
+ return p;
+ }
+
internal static ECPoint ImplShamirsTrickJsf(ECPoint P, BigInteger k, ECPoint Q, BigInteger l)
{
ECCurve curve = P.Curve;
diff --git a/crypto/src/math/ec/ECCurve.cs b/crypto/src/math/ec/ECCurve.cs
index 9c16375e6..889da292f 100644
--- a/crypto/src/math/ec/ECCurve.cs
+++ b/crypto/src/math/ec/ECCurve.cs
@@ -102,6 +102,27 @@ namespace Org.BouncyCastle.Math.EC
return new Config(this, this.m_coord, this.m_endomorphism, this.m_multiplier);
}
+ public virtual ECPoint ValidatePoint(BigInteger x, BigInteger y)
+ {
+ ECPoint p = CreatePoint(x, y);
+ if (!p.IsValid())
+ {
+ throw new ArgumentException("Invalid point coordinates");
+ }
+ return p;
+ }
+
+ [Obsolete("Per-point compression property will be removed")]
+ public virtual ECPoint ValidatePoint(BigInteger x, BigInteger y, bool withCompression)
+ {
+ ECPoint p = CreatePoint(x, y, withCompression);
+ if (!p.IsValid())
+ {
+ throw new ArgumentException("Invalid point coordinates");
+ }
+ return p;
+ }
+
public virtual ECPoint CreatePoint(BigInteger x, BigInteger y)
{
return CreatePoint(x, y, false);
@@ -185,7 +206,7 @@ namespace Org.BouncyCastle.Math.EC
// TODO Default behaviour could be improved if the two curves have the same coordinate system by copying any Z coordinates.
p = p.Normalize();
- return CreatePoint(p.XCoord.ToBigInteger(), p.YCoord.ToBigInteger(), p.IsCompressed);
+ return ValidatePoint(p.XCoord.ToBigInteger(), p.YCoord.ToBigInteger(), p.IsCompressed);
}
/**
@@ -344,7 +365,8 @@ namespace Org.BouncyCastle.Math.EC
ECPoint p = null;
int expectedLength = (FieldSize + 7) / 8;
- switch (encoded[0])
+ byte type = encoded[0];
+ switch (type)
{
case 0x00: // infinity
{
@@ -361,7 +383,7 @@ namespace Org.BouncyCastle.Math.EC
if (encoded.Length != (expectedLength + 1))
throw new ArgumentException("Incorrect length for compressed encoding", "encoded");
- int yTilde = encoded[0] & 1;
+ int yTilde = type & 1;
BigInteger X = new BigInteger(1, encoded, 1, expectedLength);
p = DecompressPoint(yTilde, X);
@@ -376,7 +398,7 @@ namespace Org.BouncyCastle.Math.EC
BigInteger X = new BigInteger(1, encoded, 1, expectedLength);
BigInteger Y = new BigInteger(1, encoded, 1 + expectedLength, expectedLength);
- p = CreatePoint(X, Y);
+ p = ValidatePoint(X, Y);
break;
}
@@ -389,26 +411,59 @@ namespace Org.BouncyCastle.Math.EC
BigInteger X = new BigInteger(1, encoded, 1, expectedLength);
BigInteger Y = new BigInteger(1, encoded, 1 + expectedLength, expectedLength);
- if (Y.TestBit(0) != (encoded[0] == 0x07))
+ if (Y.TestBit(0) != (type == 0x07))
throw new ArgumentException("Inconsistent Y coordinate in hybrid encoding", "encoded");
- p = CreatePoint(X, Y);
+ p = ValidatePoint(X, Y);
break;
}
default:
- throw new FormatException("Invalid point encoding " + encoded[0]);
+ throw new FormatException("Invalid point encoding " + type);
}
+ if (type != 0x00 && p.IsInfinity)
+ throw new ArgumentException("Invalid infinity encoding", "encoded");
+
return p;
}
}
+ public abstract class AbstractFpCurve
+ : ECCurve
+ {
+ protected AbstractFpCurve(BigInteger q)
+ : base(FiniteFields.GetPrimeField(q))
+ {
+ }
+
+ protected override ECPoint DecompressPoint(int yTilde, BigInteger X1)
+ {
+ ECFieldElement x = FromBigInteger(X1);
+ ECFieldElement rhs = x.Square().Add(A).Multiply(x).Add(B);
+ ECFieldElement y = rhs.Sqrt();
+
+ /*
+ * If y is not a square, then we haven't got a point on the curve
+ */
+ if (y == null)
+ throw new ArgumentException("Invalid point compression");
+
+ if (y.TestBitZero() != (yTilde == 1))
+ {
+ // Use the other root
+ y = y.Negate();
+ }
+
+ return CreateRawPoint(x, y, true);
+ }
+ }
+
/**
* Elliptic curve over Fp
*/
public class FpCurve
- : ECCurve
+ : AbstractFpCurve
{
private const int FP_DEFAULT_COORDS = COORD_JACOBIAN_MODIFIED;
@@ -421,7 +476,7 @@ namespace Org.BouncyCastle.Math.EC
}
public FpCurve(BigInteger q, BigInteger a, BigInteger b, BigInteger order, BigInteger cofactor)
- : base(FiniteFields.GetPrimeField(q))
+ : base(q)
{
this.m_q = q;
this.m_r = FpFieldElement.CalculateResidue(q);
@@ -440,7 +495,7 @@ namespace Org.BouncyCastle.Math.EC
}
protected FpCurve(BigInteger q, BigInteger r, ECFieldElement a, ECFieldElement b, BigInteger order, BigInteger cofactor)
- : base(FiniteFields.GetPrimeField(q))
+ : base(q)
{
this.m_q = q;
this.m_r = r;
@@ -523,38 +578,11 @@ namespace Org.BouncyCastle.Math.EC
return base.ImportPoint(p);
}
-
- protected override ECPoint DecompressPoint(int yTilde, BigInteger X1)
- {
- ECFieldElement x = FromBigInteger(X1);
- ECFieldElement alpha = x.Square().Add(m_a).Multiply(x).Add(m_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 ArithmeticException("Invalid point compression");
-
- if (beta.TestBitZero() != (yTilde == 1))
- {
- // Use the other root
- beta = beta.Negate();
- }
-
- return new FpPoint(this, x, beta, true);
- }
}
- /**
- * Elliptic curves over F2m. The Weierstrass equation is given by
- * <code>y<sup>2</sup> + xy = x<sup>3</sup> + ax<sup>2</sup> + b</code>.
- */
- public class F2mCurve : ECCurve
+ public abstract class AbstractF2mCurve
+ : ECCurve
{
- private const int F2M_DEFAULT_COORDS = COORD_LAMBDA_PROJECTIVE;
-
private static IFiniteField BuildField(int m, int k1, int k2, int k3)
{
if (k1 == 0)
@@ -585,6 +613,21 @@ namespace Org.BouncyCastle.Math.EC
return FiniteFields.GetBinaryExtensionField(new int[]{ 0, k1, k2, k3, m });
}
+ protected AbstractF2mCurve(int m, int k1, int k2, int k3)
+ : base(BuildField(m, k1, k2, k3))
+ {
+ }
+ }
+
+ /**
+ * Elliptic curves over F2m. The Weierstrass equation is given by
+ * <code>y<sup>2</sup> + xy = x<sup>3</sup> + ax<sup>2</sup> + b</code>.
+ */
+ public class F2mCurve
+ : AbstractF2mCurve
+ {
+ private const int F2M_DEFAULT_COORDS = COORD_LAMBDA_PROJECTIVE;
+
/**
* The exponent <code>m</code> of <code>F<sub>2<sup>m</sup></sub></code>.
*/
@@ -748,7 +791,7 @@ namespace Org.BouncyCastle.Math.EC
BigInteger b,
BigInteger order,
BigInteger cofactor)
- : base(BuildField(m, k1, k2, k3))
+ : base(m, k1, k2, k3)
{
this.m = m;
this.k1 = k1;
@@ -781,7 +824,7 @@ namespace Org.BouncyCastle.Math.EC
}
protected F2mCurve(int m, int k1, int k2, int k3, ECFieldElement a, ECFieldElement b, BigInteger order, BigInteger cofactor)
- : base(BuildField(m, k1, k2, k3))
+ : base(m, k1, k2, k3)
{
this.m = m;
this.k1 = k1;
@@ -936,7 +979,7 @@ namespace Org.BouncyCastle.Math.EC
protected override ECPoint DecompressPoint(int yTilde, BigInteger X1)
{
- ECFieldElement xp = FromBigInteger(X1), yp;
+ ECFieldElement xp = FromBigInteger(X1), yp = null;
if (xp.IsZero)
{
yp = m_b.Sqrt();
@@ -946,31 +989,34 @@ namespace Org.BouncyCastle.Math.EC
ECFieldElement beta = xp.Square().Invert().Multiply(B).Add(A).Add(xp);
ECFieldElement z = SolveQuadradicEquation(beta);
- if (z == null)
- throw new ArithmeticException("Invalid point compression");
-
- if (z.TestBitZero() != (yTilde == 1))
- {
- z = z.AddOne();
- }
-
- switch (this.CoordinateSystem)
+ if (z != null)
{
- case COORD_LAMBDA_AFFINE:
- case COORD_LAMBDA_PROJECTIVE:
+ if (z.TestBitZero() != (yTilde == 1))
{
- yp = z.Add(xp);
- break;
+ z = z.AddOne();
}
- default:
+
+ switch (this.CoordinateSystem)
{
- yp = z.Multiply(xp);
- break;
+ case COORD_LAMBDA_AFFINE:
+ case COORD_LAMBDA_PROJECTIVE:
+ {
+ yp = z.Add(xp);
+ break;
+ }
+ default:
+ {
+ yp = z.Multiply(xp);
+ break;
+ }
}
}
}
- return new F2mPoint(this, xp, yp, true);
+ if (yp == null)
+ throw new ArgumentException("Invalid point compression");
+
+ return CreateRawPoint(xp, yp, true);
}
/**
diff --git a/crypto/src/math/ec/ECPoint.cs b/crypto/src/math/ec/ECPoint.cs
index 0430a6110..dbeaf31aa 100644
--- a/crypto/src/math/ec/ECPoint.cs
+++ b/crypto/src/math/ec/ECPoint.cs
@@ -67,6 +67,8 @@ namespace Org.BouncyCastle.Math.EC
this.m_withCompression = withCompression;
}
+ protected abstract bool SatisfiesCurveEquation();
+
public ECPoint GetDetachedPoint()
{
return Normalize().Detach();
@@ -289,6 +291,30 @@ namespace Org.BouncyCastle.Math.EC
get { return m_withCompression; }
}
+ public bool IsValid()
+ {
+ if (IsInfinity)
+ return true;
+
+ // TODO Sanity-check the field elements
+
+ ECCurve curve = Curve;
+ if (curve != null)
+ {
+ if (!SatisfiesCurveEquation())
+ return false;
+
+ BigInteger h = curve.Cofactor;
+ if (h != null && !h.Equals(BigInteger.One)
+ && ECAlgorithms.ReferenceMultiply(this, h).IsInfinity)
+ {
+ return false;
+ }
+ }
+
+ return true;
+ }
+
public virtual ECPoint ScaleX(ECFieldElement scale)
{
return IsInfinity
@@ -497,14 +523,84 @@ namespace Org.BouncyCastle.Math.EC
}
}
+ public abstract class AbstractFpPoint
+ : ECPointBase
+ {
+ protected AbstractFpPoint(ECCurve curve, ECFieldElement x, ECFieldElement y, bool withCompression)
+ : base(curve, x, y, withCompression)
+ {
+ }
+
+ protected AbstractFpPoint(ECCurve curve, ECFieldElement x, ECFieldElement y, ECFieldElement[] zs, bool withCompression)
+ : base(curve, x, y, zs, withCompression)
+ {
+ }
+
+ protected internal override bool CompressionYTilde
+ {
+ get { return this.AffineYCoord.TestBitZero(); }
+ }
+
+ protected override bool SatisfiesCurveEquation()
+ {
+ ECFieldElement X = this.RawXCoord, Y = this.RawYCoord, A = Curve.A, B = Curve.B;
+ ECFieldElement lhs = Y.Square();
+
+ switch (CurveCoordinateSystem)
+ {
+ case ECCurve.COORD_AFFINE:
+ break;
+ case ECCurve.COORD_HOMOGENEOUS:
+ {
+ ECFieldElement Z = this.RawZCoords[0];
+ if (!Z.IsOne)
+ {
+ ECFieldElement Z2 = Z.Square(), Z3 = Z.Multiply(Z2);
+ lhs = lhs.Multiply(Z);
+ A = A.Multiply(Z2);
+ B = B.Multiply(Z3);
+ }
+ break;
+ }
+ case ECCurve.COORD_JACOBIAN:
+ case ECCurve.COORD_JACOBIAN_CHUDNOVSKY:
+ case ECCurve.COORD_JACOBIAN_MODIFIED:
+ {
+ ECFieldElement Z = this.RawZCoords[0];
+ if (!Z.IsOne)
+ {
+ ECFieldElement Z2 = Z.Square(), Z4 = Z2.Square(), Z6 = Z2.Multiply(Z4);
+ A = A.Multiply(Z4);
+ B = B.Multiply(Z6);
+ }
+ break;
+ }
+ default:
+ throw new InvalidOperationException("unsupported coordinate system");
+ }
+
+ ECFieldElement rhs = X.Square().Add(A).Multiply(X).Add(B);
+ return lhs.Equals(rhs);
+ }
+
+ public override ECPoint Subtract(ECPoint b)
+ {
+ if (b.IsInfinity)
+ return this;
+
+ // Add -b
+ return Add(b.Negate());
+ }
+ }
+
/**
* Elliptic curve points over Fp
*/
public class FpPoint
- : ECPointBase
+ : AbstractFpPoint
{
/**
- * Create a point which encodes with point compression.
+ * Create a point which encodes without point compression.
*
* @param curve the curve to use
* @param x affine x co-ordinate
@@ -516,7 +612,7 @@ namespace Org.BouncyCastle.Math.EC
}
/**
- * Create a point that encodes with or without point compresion.
+ * Create a point that encodes with or without point compression.
*
* @param curve the curve to use
* @param x affine x co-ordinate
@@ -540,11 +636,6 @@ namespace Org.BouncyCastle.Math.EC
return new FpPoint(null, AffineXCoord, AffineYCoord);
}
- protected internal override bool CompressionYTilde
- {
- get { return this.AffineYCoord.TestBitZero(); }
- }
-
public override ECFieldElement GetZCoord(int index)
{
if (index == 1 && ECCurve.COORD_JACOBIAN_MODIFIED == this.CurveCoordinateSystem)
@@ -1135,16 +1226,6 @@ namespace Org.BouncyCastle.Math.EC
return a.Add(b).Square().Subtract(aSquared).Subtract(bSquared);
}
- public override ECPoint Subtract(
- ECPoint b)
- {
- if (b.IsInfinity)
- return this;
-
- // Add -b
- return Add(b.Negate());
- }
-
public override ECPoint Negate()
{
if (IsInfinity)
@@ -1217,11 +1298,96 @@ namespace Org.BouncyCastle.Math.EC
}
}
+ public abstract class AbstractF2mPoint
+ : ECPointBase
+ {
+ protected AbstractF2mPoint(ECCurve curve, ECFieldElement x, ECFieldElement y, bool withCompression)
+ : base(curve, x, y, withCompression)
+ {
+ }
+
+ protected AbstractF2mPoint(ECCurve curve, ECFieldElement x, ECFieldElement y, ECFieldElement[] zs, bool withCompression)
+ : base(curve, x, y, zs, withCompression)
+ {
+ }
+
+ protected override bool SatisfiesCurveEquation()
+ {
+ ECCurve curve = Curve;
+ ECFieldElement X = this.RawXCoord, Y = this.RawYCoord, A = curve.A, B = curve.B;
+ ECFieldElement lhs, rhs;
+
+ int coord = curve.CoordinateSystem;
+ if (coord == ECCurve.COORD_LAMBDA_PROJECTIVE)
+ {
+ ECFieldElement Z = this.RawZCoords[0];
+ bool ZIsOne = Z.IsOne;
+
+ if (X.IsZero)
+ {
+ // NOTE: For x == 0, we expect the affine-y instead of the lambda-y
+ lhs = Y.Square();
+ rhs = B;
+ if (!ZIsOne)
+ {
+ ECFieldElement Z2 = Z.Square();
+ rhs = rhs.Multiply(Z2);
+ }
+ }
+ else
+ {
+ ECFieldElement L = Y, X2 = X.Square();
+ if (ZIsOne)
+ {
+ lhs = L.Square().Add(L).Add(A);
+ rhs = X2.Square().Add(B);
+ }
+ else
+ {
+ ECFieldElement Z2 = Z.Square(), Z4 = Z2.Square();
+ lhs = L.Add(Z).MultiplyPlusProduct(L, A, Z2);
+ // TODO If sqrt(b) is precomputed this can be simplified to a single square
+ rhs = X2.SquarePlusProduct(B, Z4);
+ }
+ lhs = lhs.Multiply(X2);
+ }
+ }
+ else
+ {
+ lhs = Y.Add(X).Multiply(Y);
+
+ switch (coord)
+ {
+ case ECCurve.COORD_AFFINE:
+ break;
+ case ECCurve.COORD_HOMOGENEOUS:
+ {
+ ECFieldElement Z = this.RawZCoords[0];
+ if (!Z.IsOne)
+ {
+ ECFieldElement Z2 = Z.Square(), Z3 = Z.Multiply(Z2);
+ lhs = lhs.Multiply(Z);
+ A = A.Multiply(Z);
+ B = B.Multiply(Z3);
+ }
+ break;
+ }
+ default:
+ throw new InvalidOperationException("unsupported coordinate system");
+ }
+
+ rhs = X.Add(A).Multiply(X.Square()).Add(B);
+ }
+
+ return lhs.Equals(rhs);
+ }
+ }
+
/**
* Elliptic curve points over F2m
*/
public class F2mPoint
- : ECPointBase
+ : AbstractF2mPoint
{
/**
* @param curve base curve
diff --git a/crypto/src/math/ec/custom/djb/Curve25519.cs b/crypto/src/math/ec/custom/djb/Curve25519.cs
index 3dbdac051..712b68f29 100644
--- a/crypto/src/math/ec/custom/djb/Curve25519.cs
+++ b/crypto/src/math/ec/custom/djb/Curve25519.cs
@@ -1,13 +1,12 @@
using System;
using Org.BouncyCastle.Math.EC.Custom.Sec;
-using Org.BouncyCastle.Math.Field;
using Org.BouncyCastle.Utilities.Encoders;
namespace Org.BouncyCastle.Math.EC.Custom.Djb
{
internal class Curve25519
- : ECCurve
+ : AbstractFpCurve
{
public static readonly BigInteger q = Nat256.ToBigInteger(Curve25519Field.P);
@@ -16,7 +15,7 @@ namespace Org.BouncyCastle.Math.EC.Custom.Djb
protected readonly Curve25519Point m_infinity;
public Curve25519()
- : base(FiniteFields.GetPrimeField(q))
+ : base(q)
{
this.m_infinity = new Curve25519Point(this, null, null);
@@ -74,27 +73,5 @@ namespace Org.BouncyCastle.Math.EC.Custom.Djb
{
return new Curve25519Point(this, x, y, zs, withCompression);
}
-
- protected override ECPoint DecompressPoint(int yTilde, BigInteger X1)
- {
- ECFieldElement x = FromBigInteger(X1);
- ECFieldElement alpha = x.Square().Add(A).Multiply(x).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 ArithmeticException("Invalid point compression");
-
- if (beta.TestBitZero() != (yTilde == 1))
- {
- // Use the other root
- beta = beta.Negate();
- }
-
- return new Curve25519Point(this, x, beta, true);
- }
}
}
diff --git a/crypto/src/math/ec/custom/djb/Curve25519Point.cs b/crypto/src/math/ec/custom/djb/Curve25519Point.cs
index f3da59d16..bfec1d11d 100644
--- a/crypto/src/math/ec/custom/djb/Curve25519Point.cs
+++ b/crypto/src/math/ec/custom/djb/Curve25519Point.cs
@@ -5,7 +5,7 @@ using Org.BouncyCastle.Math.EC.Custom.Sec;
namespace Org.BouncyCastle.Math.EC.Custom.Djb
{
internal class Curve25519Point
- : ECPointBase
+ : AbstractFpPoint
{
/**
* Create a point which encodes with point compression.
@@ -48,11 +48,6 @@ namespace Org.BouncyCastle.Math.EC.Custom.Djb
return new Curve25519Point(null, AffineXCoord, AffineYCoord);
}
- protected internal override bool CompressionYTilde
- {
- get { return this.AffineYCoord.TestBitZero(); }
- }
-
public override ECFieldElement GetZCoord(int index)
{
if (index == 1)
@@ -224,14 +219,6 @@ namespace Org.BouncyCastle.Math.EC.Custom.Djb
return TwiceJacobianModified(false).Add(this);
}
- public override ECPoint Subtract(ECPoint b)
- {
- if (b.IsInfinity)
- return this;
-
- return Add(b.Negate());
- }
-
public override ECPoint Negate()
{
if (IsInfinity)
diff --git a/crypto/src/math/ec/custom/sec/SecP192K1Curve.cs b/crypto/src/math/ec/custom/sec/SecP192K1Curve.cs
index 54b87588b..81f77197e 100644
--- a/crypto/src/math/ec/custom/sec/SecP192K1Curve.cs
+++ b/crypto/src/math/ec/custom/sec/SecP192K1Curve.cs
@@ -1,12 +1,11 @@
using System;
-using Org.BouncyCastle.Math.Field;
using Org.BouncyCastle.Utilities.Encoders;
namespace Org.BouncyCastle.Math.EC.Custom.Sec
{
internal class SecP192K1Curve
- : ECCurve
+ : AbstractFpCurve
{
public static readonly BigInteger q = new BigInteger(1,
Hex.Decode("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFEE37"));
@@ -16,7 +15,7 @@ namespace Org.BouncyCastle.Math.EC.Custom.Sec
protected readonly SecP192K1Point m_infinity;
public SecP192K1Curve()
- : base(FiniteFields.GetPrimeField(q))
+ : base(q)
{
this.m_infinity = new SecP192K1Point(this, null, null);
@@ -72,27 +71,5 @@ namespace Org.BouncyCastle.Math.EC.Custom.Sec
{
return new SecP192K1Point(this, x, y, zs, withCompression);
}
-
- protected override ECPoint DecompressPoint(int yTilde, BigInteger X1)
- {
- ECFieldElement x = FromBigInteger(X1);
- ECFieldElement alpha = x.Square().Multiply(x).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 ArithmeticException("Invalid point compression");
-
- if (beta.TestBitZero() != (yTilde == 1))
- {
- // Use the other root
- beta = beta.Negate();
- }
-
- return new SecP192K1Point(this, x, beta, true);
- }
}
}
diff --git a/crypto/src/math/ec/custom/sec/SecP192K1Point.cs b/crypto/src/math/ec/custom/sec/SecP192K1Point.cs
index 561324f8e..648aca502 100644
--- a/crypto/src/math/ec/custom/sec/SecP192K1Point.cs
+++ b/crypto/src/math/ec/custom/sec/SecP192K1Point.cs
@@ -3,7 +3,7 @@
namespace Org.BouncyCastle.Math.EC.Custom.Sec
{
internal class SecP192K1Point
- : ECPointBase
+ : AbstractFpPoint
{
/**
* Create a point which encodes with point compression.
@@ -55,11 +55,6 @@ namespace Org.BouncyCastle.Math.EC.Custom.Sec
return new SecP192K1Point(null, AffineXCoord, AffineYCoord);
}
- protected internal override bool CompressionYTilde
- {
- get { return this.AffineYCoord.TestBitZero(); }
- }
-
public override ECPoint Add(ECPoint b)
{
if (this.IsInfinity)
@@ -259,14 +254,6 @@ namespace Org.BouncyCastle.Math.EC.Custom.Sec
return Twice().Add(this);
}
- public override ECPoint Subtract(ECPoint b)
- {
- if (b.IsInfinity)
- return this;
-
- return Add(b.Negate());
- }
-
public override ECPoint Negate()
{
if (IsInfinity)
diff --git a/crypto/src/math/ec/custom/sec/SecP192R1Curve.cs b/crypto/src/math/ec/custom/sec/SecP192R1Curve.cs
index 57b20d31e..cb3a981c8 100644
--- a/crypto/src/math/ec/custom/sec/SecP192R1Curve.cs
+++ b/crypto/src/math/ec/custom/sec/SecP192R1Curve.cs
@@ -1,12 +1,11 @@
using System;
-using Org.BouncyCastle.Math.Field;
using Org.BouncyCastle.Utilities.Encoders;
namespace Org.BouncyCastle.Math.EC.Custom.Sec
{
internal class SecP192R1Curve
- : ECCurve
+ : AbstractFpCurve
{
public static readonly BigInteger q = new BigInteger(1,
Hex.Decode("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFF"));
@@ -16,7 +15,7 @@ namespace Org.BouncyCastle.Math.EC.Custom.Sec
protected readonly SecP192R1Point m_infinity;
public SecP192R1Curve()
- : base(FiniteFields.GetPrimeField(q))
+ : base(q)
{
this.m_infinity = new SecP192R1Point(this, null, null);
@@ -75,27 +74,5 @@ namespace Org.BouncyCastle.Math.EC.Custom.Sec
{
return new SecP192R1Point(this, x, y, zs, withCompression);
}
-
- protected override ECPoint DecompressPoint(int yTilde, BigInteger X1)
- {
- ECFieldElement x = FromBigInteger(X1);
- ECFieldElement alpha = x.Square().Add(A).Multiply(x).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 ArithmeticException("Invalid point compression");
-
- if (beta.TestBitZero() != (yTilde == 1))
- {
- // Use the other root
- beta = beta.Negate();
- }
-
- return new SecP192R1Point(this, x, beta, true);
- }
}
}
diff --git a/crypto/src/math/ec/custom/sec/SecP192R1Point.cs b/crypto/src/math/ec/custom/sec/SecP192R1Point.cs
index c249c1269..797a8de35 100644
--- a/crypto/src/math/ec/custom/sec/SecP192R1Point.cs
+++ b/crypto/src/math/ec/custom/sec/SecP192R1Point.cs
@@ -3,7 +3,7 @@
namespace Org.BouncyCastle.Math.EC.Custom.Sec
{
internal class SecP192R1Point
- : ECPointBase
+ : AbstractFpPoint
{
/**
* Create a point which encodes with point compression.
@@ -54,11 +54,6 @@ namespace Org.BouncyCastle.Math.EC.Custom.Sec
return new SecP192R1Point(null, AffineXCoord, AffineYCoord);
}
- protected internal override bool CompressionYTilde
- {
- get { return this.AffineYCoord.TestBitZero(); }
- }
-
public override ECPoint Add(ECPoint b)
{
if (this.IsInfinity)
@@ -271,14 +266,6 @@ namespace Org.BouncyCastle.Math.EC.Custom.Sec
return Twice().Add(this);
}
- public override ECPoint Subtract(ECPoint b)
- {
- if (b.IsInfinity)
- return this;
-
- return Add(b.Negate());
- }
-
public override ECPoint Negate()
{
if (IsInfinity)
diff --git a/crypto/src/math/ec/custom/sec/SecP224K1Curve.cs b/crypto/src/math/ec/custom/sec/SecP224K1Curve.cs
index 70de308bb..d4be7d8de 100644
--- a/crypto/src/math/ec/custom/sec/SecP224K1Curve.cs
+++ b/crypto/src/math/ec/custom/sec/SecP224K1Curve.cs
@@ -1,12 +1,11 @@
using System;
-using Org.BouncyCastle.Math.Field;
using Org.BouncyCastle.Utilities.Encoders;
namespace Org.BouncyCastle.Math.EC.Custom.Sec
{
internal class SecP224K1Curve
- : ECCurve
+ : AbstractFpCurve
{
public static readonly BigInteger q = new BigInteger(1,
Hex.Decode("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFE56D"));
@@ -16,7 +15,7 @@ namespace Org.BouncyCastle.Math.EC.Custom.Sec
protected readonly SecP224K1Point m_infinity;
public SecP224K1Curve()
- : base(FiniteFields.GetPrimeField(q))
+ : base(q)
{
this.m_infinity = new SecP224K1Point(this, null, null);
@@ -72,27 +71,5 @@ namespace Org.BouncyCastle.Math.EC.Custom.Sec
{
return new SecP224K1Point(this, x, y, zs, withCompression);
}
-
- protected override ECPoint DecompressPoint(int yTilde, BigInteger X1)
- {
- ECFieldElement x = FromBigInteger(X1);
- ECFieldElement alpha = x.Square().Multiply(x).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 ArithmeticException("Invalid point compression");
-
- if (beta.TestBitZero() != (yTilde == 1))
- {
- // Use the other root
- beta = beta.Negate();
- }
-
- return new SecP224K1Point(this, x, beta, true);
- }
}
}
diff --git a/crypto/src/math/ec/custom/sec/SecP224K1Point.cs b/crypto/src/math/ec/custom/sec/SecP224K1Point.cs
index dd6faa829..8cbd29699 100644
--- a/crypto/src/math/ec/custom/sec/SecP224K1Point.cs
+++ b/crypto/src/math/ec/custom/sec/SecP224K1Point.cs
@@ -3,7 +3,7 @@
namespace Org.BouncyCastle.Math.EC.Custom.Sec
{
internal class SecP224K1Point
- : ECPointBase
+ : AbstractFpPoint
{
/**
* Create a point which encodes with point compression.
@@ -55,11 +55,6 @@ namespace Org.BouncyCastle.Math.EC.Custom.Sec
return new SecP224K1Point(null, AffineXCoord, AffineYCoord);
}
- protected internal override bool CompressionYTilde
- {
- get { return this.AffineYCoord.TestBitZero(); }
- }
-
public override ECPoint Add(ECPoint b)
{
if (this.IsInfinity)
@@ -259,14 +254,6 @@ namespace Org.BouncyCastle.Math.EC.Custom.Sec
return Twice().Add(this);
}
- public override ECPoint Subtract(ECPoint b)
- {
- if (b.IsInfinity)
- return this;
-
- return Add(b.Negate());
- }
-
public override ECPoint Negate()
{
if (IsInfinity)
diff --git a/crypto/src/math/ec/custom/sec/SecP224R1Curve.cs b/crypto/src/math/ec/custom/sec/SecP224R1Curve.cs
index 33b66be82..cda8781ff 100644
--- a/crypto/src/math/ec/custom/sec/SecP224R1Curve.cs
+++ b/crypto/src/math/ec/custom/sec/SecP224R1Curve.cs
@@ -1,12 +1,11 @@
using System;
-using Org.BouncyCastle.Math.Field;
using Org.BouncyCastle.Utilities.Encoders;
namespace Org.BouncyCastle.Math.EC.Custom.Sec
{
internal class SecP224R1Curve
- : ECCurve
+ : AbstractFpCurve
{
public static readonly BigInteger q = new BigInteger(1,
Hex.Decode("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000000000000000000001"));
@@ -16,7 +15,7 @@ namespace Org.BouncyCastle.Math.EC.Custom.Sec
protected readonly SecP224R1Point m_infinity;
public SecP224R1Curve()
- : base(FiniteFields.GetPrimeField(q))
+ : base(q)
{
this.m_infinity = new SecP224R1Point(this, null, null);
@@ -75,27 +74,5 @@ namespace Org.BouncyCastle.Math.EC.Custom.Sec
{
return new SecP224R1Point(this, x, y, zs, withCompression);
}
-
- protected override ECPoint DecompressPoint(int yTilde, BigInteger X1)
- {
- ECFieldElement x = FromBigInteger(X1);
- ECFieldElement alpha = x.Square().Add(A).Multiply(x).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 ArithmeticException("Invalid point compression");
-
- if (beta.TestBitZero() != (yTilde == 1))
- {
- // Use the other root
- beta = beta.Negate();
- }
-
- return new SecP224R1Point(this, x, beta, true);
- }
}
}
diff --git a/crypto/src/math/ec/custom/sec/SecP224R1Point.cs b/crypto/src/math/ec/custom/sec/SecP224R1Point.cs
index 3b339720d..c3f4efb59 100644
--- a/crypto/src/math/ec/custom/sec/SecP224R1Point.cs
+++ b/crypto/src/math/ec/custom/sec/SecP224R1Point.cs
@@ -3,7 +3,7 @@
namespace Org.BouncyCastle.Math.EC.Custom.Sec
{
internal class SecP224R1Point
- : ECPointBase
+ : AbstractFpPoint
{
/**
* Create a point which encodes with point compression.
@@ -54,11 +54,6 @@ namespace Org.BouncyCastle.Math.EC.Custom.Sec
return new SecP224R1Point(null, AffineXCoord, AffineYCoord);
}
- protected internal override bool CompressionYTilde
- {
- get { return this.AffineYCoord.TestBitZero(); }
- }
-
public override ECPoint Add(ECPoint b)
{
if (this.IsInfinity)
@@ -271,14 +266,6 @@ namespace Org.BouncyCastle.Math.EC.Custom.Sec
return Twice().Add(this);
}
- public override ECPoint Subtract(ECPoint b)
- {
- if (b.IsInfinity)
- return this;
-
- return Add(b.Negate());
- }
-
public override ECPoint Negate()
{
if (IsInfinity)
diff --git a/crypto/src/math/ec/custom/sec/SecP256K1Curve.cs b/crypto/src/math/ec/custom/sec/SecP256K1Curve.cs
index 89de61706..59e2cefb2 100644
--- a/crypto/src/math/ec/custom/sec/SecP256K1Curve.cs
+++ b/crypto/src/math/ec/custom/sec/SecP256K1Curve.cs
@@ -1,12 +1,11 @@
using System;
-using Org.BouncyCastle.Math.Field;
using Org.BouncyCastle.Utilities.Encoders;
namespace Org.BouncyCastle.Math.EC.Custom.Sec
{
internal class SecP256K1Curve
- : ECCurve
+ : AbstractFpCurve
{
public static readonly BigInteger q = new BigInteger(1,
Hex.Decode("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F"));
@@ -16,7 +15,7 @@ namespace Org.BouncyCastle.Math.EC.Custom.Sec
protected readonly SecP256K1Point m_infinity;
public SecP256K1Curve()
- : base(FiniteFields.GetPrimeField(q))
+ : base(q)
{
this.m_infinity = new SecP256K1Point(this, null, null);
@@ -72,27 +71,5 @@ namespace Org.BouncyCastle.Math.EC.Custom.Sec
{
return new SecP256K1Point(this, x, y, zs, withCompression);
}
-
- protected override ECPoint DecompressPoint(int yTilde, BigInteger X1)
- {
- ECFieldElement x = FromBigInteger(X1);
- ECFieldElement alpha = x.Square().Multiply(x).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 ArithmeticException("Invalid point compression");
-
- if (beta.TestBitZero() != (yTilde == 1))
- {
- // Use the other root
- beta = beta.Negate();
- }
-
- return new SecP256K1Point(this, x, beta, true);
- }
}
}
diff --git a/crypto/src/math/ec/custom/sec/SecP256K1Point.cs b/crypto/src/math/ec/custom/sec/SecP256K1Point.cs
index b12eadb72..3165682fa 100644
--- a/crypto/src/math/ec/custom/sec/SecP256K1Point.cs
+++ b/crypto/src/math/ec/custom/sec/SecP256K1Point.cs
@@ -3,7 +3,7 @@
namespace Org.BouncyCastle.Math.EC.Custom.Sec
{
internal class SecP256K1Point
- : ECPointBase
+ : AbstractFpPoint
{
/**
* Create a point which encodes with point compression.
@@ -55,11 +55,6 @@ namespace Org.BouncyCastle.Math.EC.Custom.Sec
return new SecP256K1Point(null, AffineXCoord, AffineYCoord);
}
- protected internal override bool CompressionYTilde
- {
- get { return this.AffineYCoord.TestBitZero(); }
- }
-
public override ECPoint Add(ECPoint b)
{
if (this.IsInfinity)
@@ -259,14 +254,6 @@ namespace Org.BouncyCastle.Math.EC.Custom.Sec
return Twice().Add(this);
}
- public override ECPoint Subtract(ECPoint b)
- {
- if (b.IsInfinity)
- return this;
-
- return Add(b.Negate());
- }
-
public override ECPoint Negate()
{
if (IsInfinity)
diff --git a/crypto/src/math/ec/custom/sec/SecP256R1Curve.cs b/crypto/src/math/ec/custom/sec/SecP256R1Curve.cs
index 9a94eb8d1..6b3448f06 100644
--- a/crypto/src/math/ec/custom/sec/SecP256R1Curve.cs
+++ b/crypto/src/math/ec/custom/sec/SecP256R1Curve.cs
@@ -1,12 +1,11 @@
using System;
-using Org.BouncyCastle.Math.Field;
using Org.BouncyCastle.Utilities.Encoders;
namespace Org.BouncyCastle.Math.EC.Custom.Sec
{
internal class SecP256R1Curve
- : ECCurve
+ : AbstractFpCurve
{
public static readonly BigInteger q = new BigInteger(1,
Hex.Decode("FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF"));
@@ -16,7 +15,7 @@ namespace Org.BouncyCastle.Math.EC.Custom.Sec
protected readonly SecP256R1Point m_infinity;
public SecP256R1Curve()
- : base(FiniteFields.GetPrimeField(q))
+ : base(q)
{
this.m_infinity = new SecP256R1Point(this, null, null);
@@ -74,27 +73,5 @@ namespace Org.BouncyCastle.Math.EC.Custom.Sec
{
return new SecP256R1Point(this, x, y, zs, withCompression);
}
-
- protected override ECPoint DecompressPoint(int yTilde, BigInteger X1)
- {
- ECFieldElement x = FromBigInteger(X1);
- ECFieldElement alpha = x.Square().Add(A).Multiply(x).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 ArithmeticException("Invalid point compression");
-
- if (beta.TestBitZero() != (yTilde == 1))
- {
- // Use the other root
- beta = beta.Negate();
- }
-
- return new SecP256R1Point(this, x, beta, true);
- }
}
}
diff --git a/crypto/src/math/ec/custom/sec/SecP256R1Point.cs b/crypto/src/math/ec/custom/sec/SecP256R1Point.cs
index 0e4b95a10..1de4a0b4a 100644
--- a/crypto/src/math/ec/custom/sec/SecP256R1Point.cs
+++ b/crypto/src/math/ec/custom/sec/SecP256R1Point.cs
@@ -3,7 +3,7 @@
namespace Org.BouncyCastle.Math.EC.Custom.Sec
{
internal class SecP256R1Point
- : ECPointBase
+ : AbstractFpPoint
{
/**
* Create a point which encodes with point compression.
@@ -54,11 +54,6 @@ namespace Org.BouncyCastle.Math.EC.Custom.Sec
return new SecP256R1Point(null, AffineXCoord, AffineYCoord);
}
- protected internal override bool CompressionYTilde
- {
- get { return this.AffineYCoord.TestBitZero(); }
- }
-
public override ECPoint Add(ECPoint b)
{
if (this.IsInfinity)
@@ -271,14 +266,6 @@ namespace Org.BouncyCastle.Math.EC.Custom.Sec
return Twice().Add(this);
}
- public override ECPoint Subtract(ECPoint b)
- {
- if (b.IsInfinity)
- return this;
-
- return Add(b.Negate());
- }
-
public override ECPoint Negate()
{
if (IsInfinity)
diff --git a/crypto/src/math/ec/custom/sec/SecP384R1Curve.cs b/crypto/src/math/ec/custom/sec/SecP384R1Curve.cs
index f3dec05c9..7fd58276a 100644
--- a/crypto/src/math/ec/custom/sec/SecP384R1Curve.cs
+++ b/crypto/src/math/ec/custom/sec/SecP384R1Curve.cs
@@ -1,12 +1,11 @@
using System;
-using Org.BouncyCastle.Math.Field;
using Org.BouncyCastle.Utilities.Encoders;
namespace Org.BouncyCastle.Math.EC.Custom.Sec
{
internal class SecP384R1Curve
- : ECCurve
+ : AbstractFpCurve
{
public static readonly BigInteger q = new BigInteger(1,
Hex.Decode("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFF0000000000000000FFFFFFFF"));
@@ -16,7 +15,7 @@ namespace Org.BouncyCastle.Math.EC.Custom.Sec
protected readonly SecP384R1Point m_infinity;
public SecP384R1Curve()
- : base(FiniteFields.GetPrimeField(q))
+ : base(q)
{
this.m_infinity = new SecP384R1Point(this, null, null);
@@ -74,27 +73,5 @@ namespace Org.BouncyCastle.Math.EC.Custom.Sec
{
return new SecP384R1Point(this, x, y, zs, withCompression);
}
-
- protected override ECPoint DecompressPoint(int yTilde, BigInteger X1)
- {
- ECFieldElement x = FromBigInteger(X1);
- ECFieldElement alpha = x.Square().Add(A).Multiply(x).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 ArithmeticException("Invalid point compression");
-
- if (beta.TestBitZero() != (yTilde == 1))
- {
- // Use the other root
- beta = beta.Negate();
- }
-
- return new SecP384R1Point(this, x, beta, true);
- }
}
}
diff --git a/crypto/src/math/ec/custom/sec/SecP384R1Point.cs b/crypto/src/math/ec/custom/sec/SecP384R1Point.cs
index 1ca8489dc..68c601611 100644
--- a/crypto/src/math/ec/custom/sec/SecP384R1Point.cs
+++ b/crypto/src/math/ec/custom/sec/SecP384R1Point.cs
@@ -3,7 +3,7 @@
namespace Org.BouncyCastle.Math.EC.Custom.Sec
{
internal class SecP384R1Point
- : ECPointBase
+ : AbstractFpPoint
{
/**
* Create a point which encodes with point compression.
@@ -54,11 +54,6 @@ namespace Org.BouncyCastle.Math.EC.Custom.Sec
return new SecP384R1Point(null, AffineXCoord, AffineYCoord);
}
- protected internal override bool CompressionYTilde
- {
- get { return this.AffineYCoord.TestBitZero(); }
- }
-
public override ECPoint Add(ECPoint b)
{
if (this.IsInfinity)
@@ -272,14 +267,6 @@ namespace Org.BouncyCastle.Math.EC.Custom.Sec
return Twice().Add(this);
}
- public override ECPoint Subtract(ECPoint b)
- {
- if (b.IsInfinity)
- return this;
-
- return Add(b.Negate());
- }
-
public override ECPoint Negate()
{
if (IsInfinity)
diff --git a/crypto/src/math/ec/custom/sec/SecP521R1Curve.cs b/crypto/src/math/ec/custom/sec/SecP521R1Curve.cs
index cb42304ef..e5083c7f0 100644
--- a/crypto/src/math/ec/custom/sec/SecP521R1Curve.cs
+++ b/crypto/src/math/ec/custom/sec/SecP521R1Curve.cs
@@ -1,12 +1,11 @@
using System;
-using Org.BouncyCastle.Math.Field;
using Org.BouncyCastle.Utilities.Encoders;
namespace Org.BouncyCastle.Math.EC.Custom.Sec
{
internal class SecP521R1Curve
- : ECCurve
+ : AbstractFpCurve
{
public static readonly BigInteger q = new BigInteger(1,
Hex.Decode("01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"));
@@ -16,7 +15,7 @@ namespace Org.BouncyCastle.Math.EC.Custom.Sec
protected readonly SecP521R1Point m_infinity;
public SecP521R1Curve()
- : base(FiniteFields.GetPrimeField(q))
+ : base(q)
{
this.m_infinity = new SecP521R1Point(this, null, null);
@@ -74,27 +73,5 @@ namespace Org.BouncyCastle.Math.EC.Custom.Sec
{
return new SecP521R1Point(this, x, y, zs, withCompression);
}
-
- protected override ECPoint DecompressPoint(int yTilde, BigInteger X1)
- {
- ECFieldElement x = FromBigInteger(X1);
- ECFieldElement alpha = x.Square().Add(A).Multiply(x).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 ArithmeticException("Invalid point compression");
-
- if (beta.TestBitZero() != (yTilde == 1))
- {
- // Use the other root
- beta = beta.Negate();
- }
-
- return new SecP521R1Point(this, x, beta, true);
- }
}
}
diff --git a/crypto/src/math/ec/custom/sec/SecP521R1Point.cs b/crypto/src/math/ec/custom/sec/SecP521R1Point.cs
index 44d590f08..fb1996cfd 100644
--- a/crypto/src/math/ec/custom/sec/SecP521R1Point.cs
+++ b/crypto/src/math/ec/custom/sec/SecP521R1Point.cs
@@ -3,7 +3,7 @@
namespace Org.BouncyCastle.Math.EC.Custom.Sec
{
internal class SecP521R1Point
- : ECPointBase
+ : AbstractFpPoint
{
/**
* Create a point which encodes with point compression.
@@ -54,11 +54,6 @@ namespace Org.BouncyCastle.Math.EC.Custom.Sec
return new SecP521R1Point(null, AffineXCoord, AffineYCoord);
}
- protected internal override bool CompressionYTilde
- {
- get { return this.AffineYCoord.TestBitZero(); }
- }
-
public override ECPoint Add(ECPoint b)
{
if (this.IsInfinity)
@@ -267,14 +262,6 @@ namespace Org.BouncyCastle.Math.EC.Custom.Sec
return Twice().Add(this);
}
- public override ECPoint Subtract(ECPoint b)
- {
- if (b.IsInfinity)
- return this;
-
- return Add(b.Negate());
- }
-
public override ECPoint Negate()
{
if (IsInfinity)
diff --git a/crypto/src/math/ec/multiplier/AbstractECMultiplier.cs b/crypto/src/math/ec/multiplier/AbstractECMultiplier.cs
index fe683726f..517881323 100644
--- a/crypto/src/math/ec/multiplier/AbstractECMultiplier.cs
+++ b/crypto/src/math/ec/multiplier/AbstractECMultiplier.cs
@@ -10,7 +10,13 @@
return p.Curve.Infinity;
ECPoint positive = MultiplyPositive(p, k.Abs());
- return sign > 0 ? positive : positive.Negate();
+ ECPoint result = sign > 0 ? positive : positive.Negate();
+
+ /*
+ * Although the various multipliers ought not to produce invalid output under normal
+ * circumstances, a final check here is advised to guard against fault attacks.
+ */
+ return ECAlgorithms.ValidatePoint(result);
}
protected abstract ECPoint MultiplyPositive(ECPoint p, BigInteger k);
diff --git a/crypto/src/math/ec/multiplier/ReferenceMultiplier.cs b/crypto/src/math/ec/multiplier/ReferenceMultiplier.cs
index 832fd7be4..4848ada39 100644
--- a/crypto/src/math/ec/multiplier/ReferenceMultiplier.cs
+++ b/crypto/src/math/ec/multiplier/ReferenceMultiplier.cs
@@ -3,35 +3,9 @@ namespace Org.BouncyCastle.Math.EC.Multiplier
public class ReferenceMultiplier
: AbstractECMultiplier
{
- /**
- * Simple shift-and-add multiplication. Serves as reference implementation
- * to verify (possibly faster) implementations in
- * {@link org.bouncycastle.math.ec.ECPoint ECPoint}.
- *
- * @param p The point to multiply.
- * @param k The factor by which to multiply.
- * @return The result of the point multiplication <code>k * p</code>.
- */
protected override ECPoint MultiplyPositive(ECPoint p, BigInteger k)
{
- ECPoint q = p.Curve.Infinity;
- int t = k.BitLength;
- if (t > 0)
- {
- if (k.TestBit(0))
- {
- q = p;
- }
- for (int i = 1; i < t; i++)
- {
- p = p.Twice();
- if (k.TestBit(i))
- {
- q = q.Add(p);
- }
- }
- }
- return q;
+ return ECAlgorithms.ReferenceMultiply(p, k);
}
}
}
diff --git a/crypto/test/src/math/ec/test/ECPointTest.cs b/crypto/test/src/math/ec/test/ECPointTest.cs
index 1a23e0bc7..8430f437d 100644
--- a/crypto/test/src/math/ec/test/ECPointTest.cs
+++ b/crypto/test/src/math/ec/test/ECPointTest.cs
@@ -288,35 +288,6 @@ namespace Org.BouncyCastle.Math.EC.Tests
}
/**
- * Simple shift-and-add multiplication. Serves as reference implementation
- * to verify (possibly faster) implementations in
- * {@link org.bouncycastle.math.ec.ECPoint ECPoint}.
- *
- * @param p
- * The point to multiply.
- * @param k
- * The multiplier.
- * @return The result of the point multiplication <code>kP</code>.
- */
- private ECPoint Multiply(ECPoint p, BigInteger k)
- {
- ECPoint q = p.Curve.Infinity;
- int t = k.BitLength;
- for (int i = 0; i < t; i++)
- {
- if (i != 0)
- {
- p = p.Twice();
- }
- if (k.TestBit(i))
- {
- q = q.Add(p);
- }
- }
- return q;
- }
-
- /**
* Checks, if the point multiplication algorithm of the given point yields
* the same result as point multiplication done by the reference
* implementation given in <code>multiply()</code>. This method chooses a
@@ -331,7 +302,7 @@ namespace Org.BouncyCastle.Math.EC.Tests
private void ImplTestMultiply(ECPoint p, int numBits)
{
BigInteger k = new BigInteger(numBits, secRand);
- ECPoint reff = Multiply(p, k);
+ ECPoint reff = ECAlgorithms.ReferenceMultiply(p, k);
ECPoint q = p.Multiply(k);
AssertPointsEqual("ECPoint.Multiply is incorrect", reff, q);
}
@@ -355,7 +326,7 @@ namespace Org.BouncyCastle.Math.EC.Tests
do
{
- ECPoint reff = Multiply(p, k);
+ ECPoint reff = ECAlgorithms.ReferenceMultiply(p, k);
ECPoint q = p.Multiply(k);
AssertPointsEqual("ECPoint.Multiply is incorrect", reff, q);
k = k.Add(BigInteger.One);
|