From 6e306046568f9a4d13639b913f0ff6d5879fa165 Mon Sep 17 00:00:00 2001 From: Peter Dettman Date: Wed, 23 Jul 2014 15:17:12 +0700 Subject: Add automatic EC point validation for decoded points and for multiplier outputs --- crypto/src/math/ec/ECAlgorithms.cs | 54 +++++++++++++++++++++++++++++++++----- 1 file changed, 48 insertions(+), 6 deletions(-) (limited to 'crypto/src/math/ec/ECAlgorithms.cs') 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 kP. + */ + 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; -- cgit 1.5.1