summary refs log tree commit diff
path: root/crypto/src/math/ec/ECAlgorithms.cs
diff options
context:
space:
mode:
Diffstat (limited to 'crypto/src/math/ec/ECAlgorithms.cs')
-rw-r--r--crypto/src/math/ec/ECAlgorithms.cs88
1 files changed, 75 insertions, 13 deletions
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]); } }