From 11ae28f007e8c932ca11f5351b93e5ebf1a9599a Mon Sep 17 00:00:00 2001 From: Peter Dettman Date: Sat, 3 Aug 2019 00:14:03 +0700 Subject: Improve caching behaviour for algorithms using endomorphisms --- crypto/src/math/ec/endo/EndoPreCompInfo.cs | 26 +++++++++++++++++ crypto/src/math/ec/endo/EndoUtilities.cs | 47 +++++++++++++++++++++++++++++- 2 files changed, 72 insertions(+), 1 deletion(-) create mode 100644 crypto/src/math/ec/endo/EndoPreCompInfo.cs (limited to 'crypto/src/math/ec/endo') diff --git a/crypto/src/math/ec/endo/EndoPreCompInfo.cs b/crypto/src/math/ec/endo/EndoPreCompInfo.cs new file mode 100644 index 000000000..cb926fc98 --- /dev/null +++ b/crypto/src/math/ec/endo/EndoPreCompInfo.cs @@ -0,0 +1,26 @@ +using System; + +using Org.BouncyCastle.Math.EC.Multiplier; + +namespace Org.BouncyCastle.Math.EC.Endo +{ + public class EndoPreCompInfo + : PreCompInfo + { + protected ECEndomorphism m_endomorphism; + + protected ECPoint m_mappedPoint; + + public virtual ECEndomorphism Endomorphism + { + get { return m_endomorphism; } + set { this.m_endomorphism = value; } + } + + public virtual ECPoint MappedPoint + { + get { return m_mappedPoint; } + set { this.m_mappedPoint = value; } + } + } +} diff --git a/crypto/src/math/ec/endo/EndoUtilities.cs b/crypto/src/math/ec/endo/EndoUtilities.cs index 16916e632..843103bca 100644 --- a/crypto/src/math/ec/endo/EndoUtilities.cs +++ b/crypto/src/math/ec/endo/EndoUtilities.cs @@ -1,11 +1,13 @@ using System; -using Org.BouncyCastle.Math; +using Org.BouncyCastle.Math.EC.Multiplier; namespace Org.BouncyCastle.Math.EC.Endo { public abstract class EndoUtilities { + public static readonly string PRECOMP_NAME = "bc_endo"; + public static BigInteger[] DecomposeScalar(ScalarSplitParameters p, BigInteger k) { int bits = p.Bits; @@ -18,6 +20,13 @@ namespace Org.BouncyCastle.Math.EC.Endo return new BigInteger[]{ a, b }; } + public static ECPoint MapPoint(ECEndomorphism endomorphism, ECPoint p) + { + EndoPreCompInfo precomp = (EndoPreCompInfo)p.Curve.Precompute(p, PRECOMP_NAME, + new MapPointCallback(endomorphism, p)); + return precomp.MappedPoint; + } + private static BigInteger CalculateB(BigInteger k, BigInteger g, int t) { bool negative = (g.SignValue < 0); @@ -30,5 +39,41 @@ namespace Org.BouncyCastle.Math.EC.Endo } return negative ? b.Negate() : b; } + + private class MapPointCallback + : IPreCompCallback + { + private readonly ECEndomorphism m_endomorphism; + private readonly ECPoint m_point; + + internal MapPointCallback(ECEndomorphism endomorphism, ECPoint point) + { + this.m_endomorphism = endomorphism; + this.m_point = point; + } + + public PreCompInfo Precompute(PreCompInfo existing) + { + EndoPreCompInfo existingEndo = existing as EndoPreCompInfo; + + if (CheckExisting(existingEndo, m_endomorphism)) + return existingEndo; + + ECPoint mappedPoint = m_endomorphism.PointMap.Map(m_point); + + EndoPreCompInfo result = new EndoPreCompInfo(); + result.Endomorphism = m_endomorphism; + result.MappedPoint = mappedPoint; + return result; + } + + private bool CheckExisting(EndoPreCompInfo existingEndo, ECEndomorphism endomorphism) + { + return null != existingEndo + && existingEndo.Endomorphism == endomorphism + && existingEndo.MappedPoint != null; + } + + } } } -- cgit 1.5.1