summary refs log tree commit diff
path: root/crypto/src/math/ec/endo
diff options
context:
space:
mode:
authorPeter Dettman <peter.dettman@bouncycastle.org>2019-08-03 00:14:03 +0700
committerPeter Dettman <peter.dettman@bouncycastle.org>2019-08-03 00:14:03 +0700
commit11ae28f007e8c932ca11f5351b93e5ebf1a9599a (patch)
treec78afb2b870aaf23b023728ef2a02e50ec06a01e /crypto/src/math/ec/endo
parentUse fixed-point comb when multiplying basepoint (diff)
downloadBouncyCastle.NET-ed25519-11ae28f007e8c932ca11f5351b93e5ebf1a9599a.tar.xz
Improve caching behaviour for algorithms using endomorphisms
Diffstat (limited to 'crypto/src/math/ec/endo')
-rw-r--r--crypto/src/math/ec/endo/EndoPreCompInfo.cs26
-rw-r--r--crypto/src/math/ec/endo/EndoUtilities.cs47
2 files changed, 72 insertions, 1 deletions
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; + } + + } } }