diff --git a/crypto/src/math/ec/ECAlgorithms.cs b/crypto/src/math/ec/ECAlgorithms.cs
index 6519e81c6..5d60de40f 100644
--- a/crypto/src/math/ec/ECAlgorithms.cs
+++ b/crypto/src/math/ec/ECAlgorithms.cs
@@ -10,14 +10,23 @@ namespace Org.BouncyCastle.Math.EC
{
public static bool IsF2mCurve(ECCurve c)
{
- IFiniteField field = c.Field;
+ return IsF2mField(c.Field);
+ }
+
+ public static bool IsF2mField(IFiniteField field)
+ {
return field.Dimension > 1 && field.Characteristic.Equals(BigInteger.Two)
&& field is IPolynomialExtensionField;
}
public static bool IsFpCurve(ECCurve c)
{
- return c.Field.Dimension == 1;
+ return IsFpField(c.Field);
+ }
+
+ public static bool IsFpField(IFiniteField field)
+ {
+ return field.Dimension == 1;
}
public static ECPoint SumOfMultiplies(ECPoint[] ps, BigInteger[] ks)
@@ -49,10 +58,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)
@@ -61,22 +70,22 @@ namespace Org.BouncyCastle.Math.EC
Q = ImportPoint(cp, Q);
// Point multiplication for Koblitz curves (using WTNAF) beats Shamir's trick
- if (cp is F2mCurve)
{
- F2mCurve f2mCurve = (F2mCurve) cp;
- if (f2mCurve.IsKoblitz)
+ AbstractF2mCurve f2mCurve = cp as AbstractF2mCurve;
+ if (f2mCurve != null && 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 +111,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)
@@ -116,6 +125,11 @@ namespace Org.BouncyCastle.Math.EC
public static void MontgomeryTrick(ECFieldElement[] zs, int off, int len)
{
+ MontgomeryTrick(zs, off, len, null);
+ }
+
+ public static void MontgomeryTrick(ECFieldElement[] zs, int off, int len, ECFieldElement scale)
+ {
/*
* Uses the "Montgomery Trick" to invert many field elements, with only a single actual
* field inversion. See e.g. the paper:
@@ -132,7 +146,14 @@ namespace Org.BouncyCastle.Math.EC
c[i] = c[i - 1].Multiply(zs[off + i]);
}
- ECFieldElement u = c[--i].Invert();
+ --i;
+
+ if (scale != null)
+ {
+ c[i] = c[i].Multiply(scale);
+ }
+
+ ECFieldElement u = c[i].Invert();
while (i > 0)
{
@@ -145,6 +166,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;
@@ -386,7 +448,7 @@ namespace Org.BouncyCastle.Math.EC
{
int n = System.Math.Abs(wi);
WNafPreCompInfo info = infos[j];
- ECPoint[] table = (wi < 0 == negs[j]) ? info.PreCompNeg : info.PreComp;
+ ECPoint[] table = (wi < 0 == negs[j]) ? info.PreComp : info.PreCompNeg;
r = r.Add(table[n >> 1]);
}
}
|