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;
+ }
+
+ }
}
}
|