diff options
author | Peter Dettman <peter.dettman@bouncycastle.org> | 2014-01-25 20:52:28 +0700 |
---|---|---|
committer | Peter Dettman <peter.dettman@bouncycastle.org> | 2014-01-25 20:52:28 +0700 |
commit | 0d360477865400dfe98e1aeade606d57e11def80 (patch) | |
tree | 3593e41ff9dd374c7c315bc90291a67cf262fb7f | |
parent | Change F2m test curve to match Java version more clearly (diff) | |
download | BouncyCastle.NET-ed25519-0d360477865400dfe98e1aeade606d57e11def80.tar.xz |
Port latest Java fixes for lambda-projective and make it the default for F2m
-rw-r--r-- | crypto/src/math/ec/ECCurve.cs | 18 | ||||
-rw-r--r-- | crypto/src/math/ec/ECPoint.cs | 142 |
2 files changed, 92 insertions, 68 deletions
diff --git a/crypto/src/math/ec/ECCurve.cs b/crypto/src/math/ec/ECCurve.cs index 832145e2e..9679fdb89 100644 --- a/crypto/src/math/ec/ECCurve.cs +++ b/crypto/src/math/ec/ECCurve.cs @@ -463,7 +463,7 @@ namespace Org.BouncyCastle.Math.EC */ public class F2mCurve : ECCurve { - private const int F2M_DEFAULT_COORDS = COORD_AFFINE; + private const int F2M_DEFAULT_COORDS = COORD_LAMBDA_PROJECTIVE; private static IFiniteField BuildField(int m, int k1, int k2, int k3) { @@ -827,7 +827,12 @@ namespace Org.BouncyCastle.Math.EC case COORD_LAMBDA_AFFINE: case COORD_LAMBDA_PROJECTIVE: { - if (!X.IsZero) + if (X.IsZero) + { + if (!Y.Square().Equals(B)) + throw new ArgumentException(); + } + else { // Y becomes Lambda (X + Y/X) here Y = Y.Divide(X).Add(X); @@ -847,16 +852,11 @@ namespace Org.BouncyCastle.Math.EC int yTilde, BigInteger X1) { - ECFieldElement xp = FromBigInteger(X1); - ECFieldElement yp = null; + ECFieldElement yp; if (xp.IsZero) { - yp = (F2mFieldElement)m_b; - for (int i = 0; i < m - 1; i++) - { - yp = yp.Square(); - } + yp = m_b.Sqrt(); } else { diff --git a/crypto/src/math/ec/ECPoint.cs b/crypto/src/math/ec/ECPoint.cs index 5dbffda09..67cbebcda 100644 --- a/crypto/src/math/ec/ECPoint.cs +++ b/crypto/src/math/ec/ECPoint.cs @@ -907,7 +907,7 @@ namespace Org.BouncyCastle.Math.EC bool withCompression) : base(curve, x, y, withCompression) { - if ((x != null && y == null) || (x == null && y != null)) + if ((x == null) != (y == null)) { throw new ArgumentException("Exactly one of the field elements is null"); } @@ -1118,7 +1118,12 @@ namespace Org.BouncyCastle.Math.EC case ECCurve.COORD_LAMBDA_PROJECTIVE: { if (X1.IsZero) + { + if (X2.IsZero) + return (F2mPoint)curve.Infinity; + return b.AddSimple(this); + } ECFieldElement L1 = this.RawYCoord, Z1 = this.GetZCoord(0); ECFieldElement L2 = b.RawYCoord, Z2 = b.GetZCoord(0); @@ -1156,13 +1161,21 @@ namespace Org.BouncyCastle.Math.EC if (X2.IsZero) { // TODO This can probably be optimized quite a bit + ECPoint p = this.Normalize(); + X1 = p.RawXCoord; + ECFieldElement Y1 = p.YCoord; - ECFieldElement Y1 = this.RawYCoord, Y2 = L2; + ECFieldElement Y2 = L2; ECFieldElement L = Y1.Add(Y2).Divide(X1); X3 = L.Square().Add(L).Add(X1).Add(curve.A); + if (X3.IsZero) + { + return new F2mPoint(curve, X3, curve.B.Sqrt(), IsCompressed); + } + ECFieldElement Y3 = L.Multiply(X1.Add(X3)).Add(X3).Add(Y1); - L3 = X3.IsZero ? Y3 : Y3.Divide(X3).Add(X3); + L3 = Y3.Divide(X3).Add(X3); Z3 = curve.FromBigInteger(BigInteger.One); } else @@ -1171,13 +1184,19 @@ namespace Org.BouncyCastle.Math.EC ECFieldElement AU1 = A.Multiply(U1); ECFieldElement AU2 = A.Multiply(U2); + + X3 = AU1.Multiply(AU2); + if (X3.IsZero) + { + return new F2mPoint(curve, X3, curve.B.Sqrt(), IsCompressed); + } + ECFieldElement ABZ2 = A.Multiply(B); if (!Z2IsOne) { ABZ2 = ABZ2.Multiply(Z2); } - X3 = AU1.Multiply(AU2); L3 = AU2.Add(B).Square().Add(ABZ2.Multiply(L1.Add(Z1))); Z3 = ABZ2; @@ -1322,6 +1341,11 @@ namespace Org.BouncyCastle.Math.EC ECFieldElement T = L1.Square().Add(L1Z1).Add(aZ1Sq); ECFieldElement X3 = T.Square(); + if (X3.IsZero) + { + return new F2mPoint(curve, X3, curve.B.Sqrt(), IsCompressed); + } + ECFieldElement Z3 = Z1IsOne ? T : T.Multiply(Z1Sq); ECFieldElement b = curve.B; @@ -1366,61 +1390,61 @@ namespace Org.BouncyCastle.Math.EC } } - public override ECPoint TwicePlus(ECPoint b) - { - if (this.IsInfinity) - return b; - if (b.IsInfinity) - return Twice(); - - ECCurve curve = this.Curve; - - ECFieldElement X1 = this.RawXCoord; - if (X1.IsZero) - { - // A point with X == 0 is it's own additive inverse - return b; - } - - int coord = curve.CoordinateSystem; - - switch (coord) - { - case ECCurve.COORD_LAMBDA_PROJECTIVE: - { - // NOTE: twicePlus() only optimized for lambda-affine argument - ECFieldElement X2 = b.RawXCoord, Z2 = b.GetZCoord(0); - if (X2.IsZero || !Z2.IsOne) - { - return Twice().Add(b); - } - - ECFieldElement L1 = this.RawYCoord, Z1 = this.GetZCoord(0); - ECFieldElement L2 = b.RawYCoord; - - ECFieldElement X1Sq = X1.Square(); - ECFieldElement L1Sq = L1.Square(); - ECFieldElement Z1Sq = Z1.Square(); - ECFieldElement L1Z1 = L1.Multiply(Z1); - - ECFieldElement T = curve.A.Multiply(Z1Sq).Add(L1Sq).Add(L1Z1); - ECFieldElement L2plus1 = L2.AddOne(); - ECFieldElement A = curve.A.Add(L2plus1).Multiply(Z1Sq).Add(L1Sq).Multiply(T).Add(X1Sq.Multiply(Z1Sq)); - ECFieldElement X2Z1Sq = X2.Multiply(Z1Sq); - ECFieldElement B = X2Z1Sq.Add(T).Square(); - - ECFieldElement X3 = A.Square().Multiply(X2Z1Sq); - ECFieldElement Z3 = A.Multiply(B).Multiply(Z1Sq); - ECFieldElement L3 = A.Add(B).Square().Multiply(T).Add(L2plus1.Multiply(Z3)); - - return new F2mPoint(curve, X3, L3, new ECFieldElement[] { Z3 }, IsCompressed); - } - default: - { - return Twice().Add(b); - } - } - } + //public override ECPoint TwicePlus(ECPoint b) + //{ + // if (this.IsInfinity) + // return b; + // if (b.IsInfinity) + // return Twice(); + + // ECCurve curve = this.Curve; + + // ECFieldElement X1 = this.RawXCoord; + // if (X1.IsZero) + // { + // // A point with X == 0 is it's own additive inverse + // return b; + // } + + // int coord = curve.CoordinateSystem; + + // switch (coord) + // { + // case ECCurve.COORD_LAMBDA_PROJECTIVE: + // { + // // NOTE: twicePlus() only optimized for lambda-affine argument + // ECFieldElement X2 = b.RawXCoord, Z2 = b.GetZCoord(0); + // if (X2.IsZero || !Z2.IsOne) + // { + // return Twice().Add(b); + // } + + // ECFieldElement L1 = this.RawYCoord, Z1 = this.GetZCoord(0); + // ECFieldElement L2 = b.RawYCoord; + + // ECFieldElement X1Sq = X1.Square(); + // ECFieldElement L1Sq = L1.Square(); + // ECFieldElement Z1Sq = Z1.Square(); + // ECFieldElement L1Z1 = L1.Multiply(Z1); + + // ECFieldElement T = curve.A.Multiply(Z1Sq).Add(L1Sq).Add(L1Z1); + // ECFieldElement L2plus1 = L2.AddOne(); + // ECFieldElement A = curve.A.Add(L2plus1).Multiply(Z1Sq).Add(L1Sq).Multiply(T).Add(X1Sq.Multiply(Z1Sq)); + // ECFieldElement X2Z1Sq = X2.Multiply(Z1Sq); + // ECFieldElement B = X2Z1Sq.Add(T).Square(); + + // ECFieldElement X3 = A.Square().Multiply(X2Z1Sq); + // ECFieldElement Z3 = A.Multiply(B).Multiply(Z1Sq); + // ECFieldElement L3 = A.Add(B).Square().Multiply(T).Add(L2plus1.Multiply(Z3)); + + // return new F2mPoint(curve, X3, L3, new ECFieldElement[] { Z3 }, IsCompressed); + // } + // default: + // { + // return Twice().Add(b); + // } + // } + //} public override ECPoint Negate() { |