diff --git a/crypto/src/asn1/sec/SECNamedCurves.cs b/crypto/src/asn1/sec/SECNamedCurves.cs
index 52e8ed36d..7e2afbe6e 100644
--- a/crypto/src/asn1/sec/SECNamedCurves.cs
+++ b/crypto/src/asn1/sec/SECNamedCurves.cs
@@ -5,6 +5,7 @@ using Org.BouncyCastle.Asn1;
using Org.BouncyCastle.Asn1.X9;
using Org.BouncyCastle.Math;
using Org.BouncyCastle.Math.EC;
+using Org.BouncyCastle.Math.EC.Endo;
using Org.BouncyCastle.Utilities;
using Org.BouncyCastle.Utilities.Collections;
using Org.BouncyCastle.Utilities.Encoders;
@@ -22,8 +23,12 @@ namespace Org.BouncyCastle.Asn1.Sec
return curve;
}
- private static BigInteger FromHex(
- string hex)
+ private static ECCurve ConfigureCurveGlv(ECCurve c, GlvTypeBParameters p)
+ {
+ return c.Configure().SetEndomorphism(new GlvTypeBEndomorphism(c, p)).Create();
+ }
+
+ private static BigInteger FromHex(string hex)
{
return new BigInteger(1, Hex.Decode(hex));
}
@@ -172,7 +177,20 @@ namespace Org.BouncyCastle.Asn1.Sec
BigInteger n = FromHex("0100000000000000000001B8FA16DFAB9ACA16B6B3");
BigInteger h = BigInteger.One;
- ECCurve curve = ConfigureCurve(new FpCurve(p, a, b, n, h));
+ GlvTypeBParameters glv = new GlvTypeBParameters(
+ new BigInteger("9ba48cba5ebcb9b6bd33b92830b2a2e0e192f10a", 16),
+ new BigInteger("c39c6c3b3a36d7701b9c71a1f5804ae5d0003f4", 16),
+ new BigInteger[]{
+ new BigInteger("9162fbe73984472a0a9e", 16),
+ new BigInteger("-96341f1138933bc2f505", 16) },
+ new BigInteger[]{
+ new BigInteger("127971af8721782ecffa3", 16),
+ new BigInteger("9162fbe73984472a0a9e", 16) },
+ new BigInteger("48b17df39cc22395054e8", 16),
+ new BigInteger("4b1a0f889c499de17a820", 16),
+ 163);
+
+ ECCurve curve = ConfigureCurveGlv(new FpCurve(p, a, b, n, h), glv);
//ECPoint G = curve.DecodePoint(Hex.Decode("02"
//+ "3B4C382CE37AA192A4019E763036F4F5DD4D7EBB"));
ECPoint G = curve.DecodePoint(Hex.Decode("04"
@@ -265,7 +283,20 @@ namespace Org.BouncyCastle.Asn1.Sec
BigInteger n = FromHex("FFFFFFFFFFFFFFFFFFFFFFFE26F2FC170F69466A74DEFD8D");
BigInteger h = BigInteger.One;
- ECCurve curve = ConfigureCurve(new FpCurve(p, a, b, n, h));
+ GlvTypeBParameters glv = new GlvTypeBParameters(
+ new BigInteger("bb85691939b869c1d087f601554b96b80cb4f55b35f433c2", 16),
+ new BigInteger("3d84f26c12238d7b4f3d516613c1759033b1a5800175d0b1", 16),
+ new BigInteger[]{
+ new BigInteger("71169be7330b3038edb025f1", 16),
+ new BigInteger("-b3fb3400dec5c4adceb8655c", 16) },
+ new BigInteger[]{
+ new BigInteger("12511cfe811d0f4e6bc688b4d", 16),
+ new BigInteger("71169be7330b3038edb025f1", 16) },
+ new BigInteger("1c45a6f9ccc2cc0e3b6c097c7", 16),
+ new BigInteger("2cfecd0037b1712b73ae19575", 16),
+ 194);
+
+ ECCurve curve = ConfigureCurveGlv(new FpCurve(p, a, b, n, h), glv);
//ECPoint G = curve.DecodePoint(Hex.Decode("03"
//+ "DB4FF10EC057E9AE26B07D0280B7F4341DA5D1B1EAE06C7D"));
ECPoint G = curve.DecodePoint(Hex.Decode("04"
@@ -327,7 +358,20 @@ namespace Org.BouncyCastle.Asn1.Sec
BigInteger n = FromHex("010000000000000000000000000001DCE8D2EC6184CAF0A971769FB1F7");
BigInteger h = BigInteger.One;
- ECCurve curve = ConfigureCurve(new FpCurve(p, a, b, n, h));
+ GlvTypeBParameters glv = new GlvTypeBParameters(
+ new BigInteger("fe0e87005b4e83761908c5131d552a850b3f58b749c37cf5b84d6768", 16),
+ new BigInteger("60dcd2104c4cbc0be6eeefc2bdd610739ec34e317f9b33046c9e4788", 16),
+ new BigInteger[]{
+ new BigInteger("6b8cf07d4ca75c88957d9d670591", 16),
+ new BigInteger("-b8adf1378a6eb73409fa6c9c637d", 16) },
+ new BigInteger[]{
+ new BigInteger("1243ae1b4d71613bc9f780a03690e", 16),
+ new BigInteger("6b8cf07d4ca75c88957d9d670591", 16) },
+ new BigInteger("35c6783ea653ae444abeceb382c82", 16),
+ new BigInteger("5c56f89bc5375b9a04fd364e31bdd", 16),
+ 227);
+
+ ECCurve curve = ConfigureCurveGlv(new FpCurve(p, a, b, n, h), glv);
//ECPoint G = curve.DecodePoint(Hex.Decode("03"
//+ "A1455B334DF099DF30FC28A169A467E9E47075A90F7E650EB6B7A45C"));
ECPoint G = curve.DecodePoint(Hex.Decode("04"
@@ -389,7 +433,20 @@ namespace Org.BouncyCastle.Asn1.Sec
BigInteger n = FromHex("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141");
BigInteger h = BigInteger.One;
- ECCurve curve = ConfigureCurve(new FpCurve(p, a, b, n, h));
+ GlvTypeBParameters glv = new GlvTypeBParameters(
+ new BigInteger("7ae96a2b657c07106e64479eac3434e99cf0497512f58995c1396c28719501ee", 16),
+ new BigInteger("5363ad4cc05c30e0a5261c028812645a122e22ea20816678df02967c1b23bd72", 16),
+ new BigInteger[]{
+ new BigInteger("3086d221a7d46bcde86c90e49284eb15", 16),
+ new BigInteger("-e4437ed6010e88286f547fa90abfe4c3", 16) },
+ new BigInteger[]{
+ new BigInteger("114ca50f7a8e2f3f657c1108d9d44cfd8", 16),
+ new BigInteger("3086d221a7d46bcde86c90e49284eb15", 16) },
+ new BigInteger("c21b48869f51af37a1b243924a13ac55", 16),
+ new BigInteger("3910dfb58043a20a1bd51fea42aff9311", 16),
+ 258);
+
+ ECCurve curve = ConfigureCurveGlv(new FpCurve(p, a, b, n, h), glv);
//ECPoint G = curve.DecodePoint(Hex.Decode("02"
//+ "79BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798"));
ECPoint G = curve.DecodePoint(Hex.Decode("04"
diff --git a/crypto/src/crypto/ec/CustomNamedCurves.cs b/crypto/src/crypto/ec/CustomNamedCurves.cs
index a4b21ab3d..e58f83d25 100644
--- a/crypto/src/crypto/ec/CustomNamedCurves.cs
+++ b/crypto/src/crypto/ec/CustomNamedCurves.cs
@@ -7,6 +7,7 @@ using Org.BouncyCastle.Asn1.X9;
using Org.BouncyCastle.Math;
using Org.BouncyCastle.Math.EC;
using Org.BouncyCastle.Math.EC.Custom.Sec;
+using Org.BouncyCastle.Math.EC.Endo;
using Org.BouncyCastle.Utilities;
using Org.BouncyCastle.Utilities.Collections;
using Org.BouncyCastle.Utilities.Encoders;
@@ -29,6 +30,11 @@ namespace Org.BouncyCastle.Crypto.EC
return curve;
}
+ private static ECCurve ConfigureCurveGlv(ECCurve c, GlvTypeBParameters p)
+ {
+ return c.Configure().SetEndomorphism(new GlvTypeBEndomorphism(c, p)).Create();
+ }
+
/*
* secp192k1
*/
@@ -42,7 +48,19 @@ namespace Org.BouncyCastle.Crypto.EC
protected override X9ECParameters CreateParameters()
{
byte[] S = null;
- ECCurve curve = ConfigureCurve(new SecP192K1Curve());
+ GlvTypeBParameters glv = new GlvTypeBParameters(
+ new BigInteger("bb85691939b869c1d087f601554b96b80cb4f55b35f433c2", 16),
+ new BigInteger("3d84f26c12238d7b4f3d516613c1759033b1a5800175d0b1", 16),
+ new BigInteger[]{
+ new BigInteger("71169be7330b3038edb025f1", 16),
+ new BigInteger("-b3fb3400dec5c4adceb8655c", 16) },
+ new BigInteger[]{
+ new BigInteger("12511cfe811d0f4e6bc688b4d", 16),
+ new BigInteger("71169be7330b3038edb025f1", 16) },
+ new BigInteger("1c45a6f9ccc2cc0e3b6c097c7", 16),
+ new BigInteger("2cfecd0037b1712b73ae19575", 16),
+ 194);
+ ECCurve curve = ConfigureCurveGlv(new SecP192K1Curve(), glv);
ECPoint G = curve.DecodePoint(Hex.Decode("04"
+ "DB4FF10EC057E9AE26B07D0280B7F4341DA5D1B1EAE06C7D"
+ "9B2F2F6D9C5628A7844163D015BE86344082AA88D95E2F9D"));
@@ -84,7 +102,19 @@ namespace Org.BouncyCastle.Crypto.EC
protected override X9ECParameters CreateParameters()
{
byte[] S = null;
- ECCurve curve = ConfigureCurve(new SecP224K1Curve());
+ GlvTypeBParameters glv = new GlvTypeBParameters(
+ new BigInteger("fe0e87005b4e83761908c5131d552a850b3f58b749c37cf5b84d6768", 16),
+ new BigInteger("60dcd2104c4cbc0be6eeefc2bdd610739ec34e317f9b33046c9e4788", 16),
+ new BigInteger[]{
+ new BigInteger("6b8cf07d4ca75c88957d9d670591", 16),
+ new BigInteger("-b8adf1378a6eb73409fa6c9c637d", 16) },
+ new BigInteger[]{
+ new BigInteger("1243ae1b4d71613bc9f780a03690e", 16),
+ new BigInteger("6b8cf07d4ca75c88957d9d670591", 16) },
+ new BigInteger("35c6783ea653ae444abeceb382c82", 16),
+ new BigInteger("5c56f89bc5375b9a04fd364e31bdd", 16),
+ 227);
+ ECCurve curve = ConfigureCurveGlv(new SecP224K1Curve(), glv);
ECPoint G = curve.DecodePoint(Hex.Decode("04"
+ "A1455B334DF099DF30FC28A169A467E9E47075A90F7E650EB6B7A45C"
+ "7E089FED7FBA344282CAFBD6F7E319F7C0B0BD59E2CA4BDB556D61A5"));
@@ -126,7 +156,19 @@ namespace Org.BouncyCastle.Crypto.EC
protected override X9ECParameters CreateParameters()
{
byte[] S = null;
- ECCurve curve = ConfigureCurve(new SecP256K1Curve());
+ GlvTypeBParameters glv = new GlvTypeBParameters(
+ new BigInteger("7ae96a2b657c07106e64479eac3434e99cf0497512f58995c1396c28719501ee", 16),
+ new BigInteger("5363ad4cc05c30e0a5261c028812645a122e22ea20816678df02967c1b23bd72", 16),
+ new BigInteger[]{
+ new BigInteger("3086d221a7d46bcde86c90e49284eb15", 16),
+ new BigInteger("-e4437ed6010e88286f547fa90abfe4c3", 16) },
+ new BigInteger[]{
+ new BigInteger("114ca50f7a8e2f3f657c1108d9d44cfd8", 16),
+ new BigInteger("3086d221a7d46bcde86c90e49284eb15", 16) },
+ new BigInteger("c21b48869f51af37a1b243924a13ac55", 16),
+ new BigInteger("3910dfb58043a20a1bd51fea42aff9311", 16),
+ 258);
+ ECCurve curve = ConfigureCurveGlv(new SecP256K1Curve(), glv);
ECPoint G = curve.DecodePoint(Hex.Decode("04"
+ "79BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798"
+ "483ADA7726A3C4655DA4FBFC0E1108A8FD17B448A68554199C47D08FFB10D4B8"));
diff --git a/crypto/src/math/ec/ECAlgorithms.cs b/crypto/src/math/ec/ECAlgorithms.cs
index 0b8836b6b..628680e24 100644
--- a/crypto/src/math/ec/ECAlgorithms.cs
+++ b/crypto/src/math/ec/ECAlgorithms.cs
@@ -168,25 +168,61 @@ namespace Org.BouncyCastle.Math.EC
return R;
}
- internal static ECPoint ImplShamirsTrickWNaf(ECPoint P, BigInteger k, ECPoint Q, BigInteger l)
+ internal static ECPoint ImplShamirsTrickWNaf(ECPoint P, BigInteger k,
+ ECPoint Q, BigInteger l)
{
+ bool negK = k.SignValue < 0, negL = l.SignValue < 0;
+
+ k = k.Abs();
+ l = l.Abs();
+
int widthP = System.Math.Max(2, System.Math.Min(16, WNafUtilities.GetWindowSize(k.BitLength)));
int widthQ = System.Math.Max(2, System.Math.Min(16, WNafUtilities.GetWindowSize(l.BitLength)));
WNafPreCompInfo infoP = WNafUtilities.Precompute(P, widthP, true);
WNafPreCompInfo infoQ = WNafUtilities.Precompute(Q, widthQ, true);
- ECPoint[] preCompP = infoP.PreComp;
- ECPoint[] preCompQ = infoQ.PreComp;
- ECPoint[] preCompNegP = infoP.PreCompNeg;
- ECPoint[] preCompNegQ = infoQ.PreCompNeg;
+ ECPoint[] preCompP = negK ? infoP.PreCompNeg : infoP.PreComp;
+ ECPoint[] preCompQ = negL ? infoQ.PreCompNeg : infoQ.PreComp;
+ ECPoint[] preCompNegP = negK ? infoP.PreComp : infoP.PreCompNeg;
+ ECPoint[] preCompNegQ = negL ? infoQ.PreComp : infoQ.PreCompNeg;
byte[] wnafP = WNafUtilities.GenerateWindowNaf(widthP, k);
byte[] wnafQ = WNafUtilities.GenerateWindowNaf(widthQ, l);
+ return ImplShamirsTrickWNaf(preCompP, preCompNegP, wnafP, preCompQ, preCompNegQ, wnafQ);
+ }
+
+ internal static ECPoint ImplShamirsTrickWNaf(ECPoint P, BigInteger k, ECPointMap pointMapQ, BigInteger l)
+ {
+ bool negK = k.SignValue < 0, negL = l.SignValue < 0;
+
+ k = k.Abs();
+ l = l.Abs();
+
+ int width = System.Math.Max(2, System.Math.Min(16, WNafUtilities.GetWindowSize(System.Math.Max(k.BitLength, l.BitLength))));
+
+ ECPoint Q = WNafUtilities.MapPointWithPrecomp(P, width, true, pointMapQ);
+ WNafPreCompInfo infoP = WNafUtilities.GetWNafPreCompInfo(P);
+ WNafPreCompInfo infoQ = WNafUtilities.GetWNafPreCompInfo(Q);
+
+ ECPoint[] preCompP = negK ? infoP.PreCompNeg : infoP.PreComp;
+ ECPoint[] preCompQ = negL ? infoQ.PreCompNeg : infoQ.PreComp;
+ ECPoint[] preCompNegP = negK ? infoP.PreComp : infoP.PreCompNeg;
+ ECPoint[] preCompNegQ = negL ? infoQ.PreComp : infoQ.PreCompNeg;
+
+ byte[] wnafP = WNafUtilities.GenerateWindowNaf(width, k);
+ byte[] wnafQ = WNafUtilities.GenerateWindowNaf(width, l);
+
+ return ImplShamirsTrickWNaf(preCompP, preCompNegP, wnafP, preCompQ, preCompNegQ, wnafQ);
+ }
+
+ private static ECPoint ImplShamirsTrickWNaf(ECPoint[] preCompP, ECPoint[] preCompNegP, byte[] wnafP,
+ ECPoint[] preCompQ, ECPoint[] preCompNegQ, byte[] wnafQ)
+ {
int len = System.Math.Max(wnafP.Length, wnafQ.Length);
- ECCurve curve = P.Curve;
+ ECCurve curve = preCompP[0].Curve;
ECPoint infinity = curve.Infinity;
ECPoint R = infinity;
diff --git a/crypto/src/math/ec/ECCurve.cs b/crypto/src/math/ec/ECCurve.cs
index a84863ce6..50ff88e82 100644
--- a/crypto/src/math/ec/ECCurve.cs
+++ b/crypto/src/math/ec/ECCurve.cs
@@ -2,6 +2,7 @@ using System;
using System.Collections;
using Org.BouncyCastle.Math.EC.Abc;
+using Org.BouncyCastle.Math.EC.Endo;
using Org.BouncyCastle.Math.EC.Multiplier;
using Org.BouncyCastle.Math.Field;
using Org.BouncyCastle.Utilities;
@@ -30,12 +31,14 @@ namespace Org.BouncyCastle.Math.EC
{
protected ECCurve outer;
protected int coord;
+ protected ECEndomorphism endomorphism;
protected ECMultiplier multiplier;
- internal Config(ECCurve outer, int coord, ECMultiplier multiplier)
+ internal Config(ECCurve outer, int coord, ECEndomorphism endomorphism, ECMultiplier multiplier)
{
this.outer = outer;
this.coord = coord;
+ this.endomorphism = endomorphism;
this.multiplier = multiplier;
}
@@ -45,6 +48,12 @@ namespace Org.BouncyCastle.Math.EC
return this;
}
+ public Config SetEndomorphism(ECEndomorphism endomorphism)
+ {
+ this.endomorphism = endomorphism;
+ return this;
+ }
+
public Config SetMultiplier(ECMultiplier multiplier)
{
this.multiplier = multiplier;
@@ -65,6 +74,7 @@ namespace Org.BouncyCastle.Math.EC
}
c.m_coord = coord;
+ c.m_endomorphism = endomorphism;
c.m_multiplier = multiplier;
return c;
@@ -76,6 +86,7 @@ namespace Org.BouncyCastle.Math.EC
protected BigInteger m_order, m_cofactor;
protected int m_coord = COORD_AFFINE;
+ protected ECEndomorphism m_endomorphism = null;
protected ECMultiplier m_multiplier = null;
protected ECCurve(IFiniteField field)
@@ -88,7 +99,7 @@ namespace Org.BouncyCastle.Math.EC
public virtual Config Configure()
{
- return new Config(this, this.m_coord, this.m_multiplier);
+ return new Config(this, this.m_coord, this.m_endomorphism, this.m_multiplier);
}
public virtual ECPoint CreatePoint(BigInteger x, BigInteger y)
@@ -110,6 +121,12 @@ namespace Org.BouncyCastle.Math.EC
protected virtual ECMultiplier CreateDefaultMultiplier()
{
+ GlvEndomorphism glvEndomorphism = m_endomorphism as GlvEndomorphism;
+ if (glvEndomorphism != null)
+ {
+ return new GlvMultiplier(this, glvEndomorphism);
+ }
+
return new WNafL2RMultiplier();
}
@@ -296,6 +313,11 @@ namespace Org.BouncyCastle.Math.EC
protected abstract ECPoint DecompressPoint(int yTilde, BigInteger X1);
+ public virtual ECEndomorphism GetEndomorphism()
+ {
+ return m_endomorphism;
+ }
+
/**
* Sets the default <code>ECMultiplier</code>, unless already set.
*/
diff --git a/crypto/src/math/ec/ECPointMap.cs b/crypto/src/math/ec/ECPointMap.cs
new file mode 100644
index 000000000..e78c80065
--- /dev/null
+++ b/crypto/src/math/ec/ECPointMap.cs
@@ -0,0 +1,9 @@
+using System;
+
+namespace Org.BouncyCastle.Math.EC
+{
+ public interface ECPointMap
+ {
+ ECPoint Map(ECPoint p);
+ }
+}
diff --git a/crypto/src/math/ec/ScaleXPointMap.cs b/crypto/src/math/ec/ScaleXPointMap.cs
new file mode 100644
index 000000000..f8a363b24
--- /dev/null
+++ b/crypto/src/math/ec/ScaleXPointMap.cs
@@ -0,0 +1,20 @@
+using System;
+
+namespace Org.BouncyCastle.Math.EC
+{
+ public class ScaleXPointMap
+ : ECPointMap
+ {
+ protected readonly ECFieldElement scale;
+
+ public ScaleXPointMap(ECFieldElement scale)
+ {
+ this.scale = scale;
+ }
+
+ public virtual ECPoint Map(ECPoint p)
+ {
+ return p.ScaleX(scale);
+ }
+ }
+}
diff --git a/crypto/src/math/ec/ScaleYPointMap.cs b/crypto/src/math/ec/ScaleYPointMap.cs
new file mode 100644
index 000000000..1c4795b70
--- /dev/null
+++ b/crypto/src/math/ec/ScaleYPointMap.cs
@@ -0,0 +1,20 @@
+using System;
+
+namespace Org.BouncyCastle.Math.EC
+{
+ public class ScaleYPointMap
+ : ECPointMap
+ {
+ protected readonly ECFieldElement scale;
+
+ public ScaleYPointMap(ECFieldElement scale)
+ {
+ this.scale = scale;
+ }
+
+ public virtual ECPoint Map(ECPoint p)
+ {
+ return p.ScaleY(scale);
+ }
+ }
+}
diff --git a/crypto/src/math/ec/endo/ECEndomorphism.cs b/crypto/src/math/ec/endo/ECEndomorphism.cs
new file mode 100644
index 000000000..dfb321368
--- /dev/null
+++ b/crypto/src/math/ec/endo/ECEndomorphism.cs
@@ -0,0 +1,11 @@
+using System;
+
+namespace Org.BouncyCastle.Math.EC.Endo
+{
+ public interface ECEndomorphism
+ {
+ ECPointMap PointMap { get; }
+
+ bool HasEfficientPointMap { get; }
+ }
+}
diff --git a/crypto/src/math/ec/endo/GlvEndomorphism.cs b/crypto/src/math/ec/endo/GlvEndomorphism.cs
new file mode 100644
index 000000000..f65bdd613
--- /dev/null
+++ b/crypto/src/math/ec/endo/GlvEndomorphism.cs
@@ -0,0 +1,10 @@
+using System;
+
+namespace Org.BouncyCastle.Math.EC.Endo
+{
+ public interface GlvEndomorphism
+ : ECEndomorphism
+ {
+ BigInteger[] DecomposeScalar(BigInteger k);
+ }
+}
diff --git a/crypto/src/math/ec/endo/GlvTypeBEndomorphism.cs b/crypto/src/math/ec/endo/GlvTypeBEndomorphism.cs
new file mode 100644
index 000000000..d234d88bf
--- /dev/null
+++ b/crypto/src/math/ec/endo/GlvTypeBEndomorphism.cs
@@ -0,0 +1,55 @@
+using System;
+
+namespace Org.BouncyCastle.Math.EC.Endo
+{
+ public class GlvTypeBEndomorphism
+ : GlvEndomorphism
+ {
+ protected readonly ECCurve m_curve;
+ protected readonly GlvTypeBParameters m_parameters;
+ protected readonly ECPointMap m_pointMap;
+
+ public GlvTypeBEndomorphism(ECCurve curve, GlvTypeBParameters parameters)
+ {
+ this.m_curve = curve;
+ this.m_parameters = parameters;
+ this.m_pointMap = new ScaleXPointMap(curve.FromBigInteger(parameters.Beta));
+ }
+
+ public virtual BigInteger[] DecomposeScalar(BigInteger k)
+ {
+ int bits = m_parameters.Bits;
+ BigInteger b1 = CalculateB(k, m_parameters.G1, bits);
+ BigInteger b2 = CalculateB(k, m_parameters.G2, bits);
+
+ BigInteger[] v1 = m_parameters.V1, v2 = m_parameters.V2;
+ BigInteger a = k.Subtract((b1.Multiply(v1[0])).Add(b2.Multiply(v2[0])));
+ BigInteger b = (b1.Multiply(v1[1])).Add(b2.Multiply(v2[1])).Negate();
+
+ return new BigInteger[]{ a, b };
+ }
+
+ public virtual ECPointMap PointMap
+ {
+ get { return m_pointMap; }
+ }
+
+ public virtual bool HasEfficientPointMap
+ {
+ get { return true; }
+ }
+
+ protected virtual BigInteger CalculateB(BigInteger k, BigInteger g, int t)
+ {
+ bool negative = (g.SignValue < 0);
+ BigInteger b = k.Multiply(g.Abs());
+ bool extra = b.TestBit(t - 1);
+ b = b.ShiftRight(t);
+ if (extra)
+ {
+ b = b.Add(BigInteger.One);
+ }
+ return negative ? b.Negate() : b;
+ }
+ }
+}
diff --git a/crypto/src/math/ec/endo/GlvTypeBParameters.cs b/crypto/src/math/ec/endo/GlvTypeBParameters.cs
new file mode 100644
index 000000000..f93dfaf2b
--- /dev/null
+++ b/crypto/src/math/ec/endo/GlvTypeBParameters.cs
@@ -0,0 +1,60 @@
+using System;
+
+namespace Org.BouncyCastle.Math.EC.Endo
+{
+ public class GlvTypeBParameters
+ {
+ protected readonly BigInteger m_beta;
+ protected readonly BigInteger m_lambda;
+ protected readonly BigInteger[] m_v1, m_v2;
+ protected readonly BigInteger m_g1, m_g2;
+ protected readonly int m_bits;
+
+ public GlvTypeBParameters(BigInteger beta, BigInteger lambda, BigInteger[] v1, BigInteger[] v2,
+ BigInteger g1, BigInteger g2, int bits)
+ {
+ this.m_beta = beta;
+ this.m_lambda = lambda;
+ this.m_v1 = v1;
+ this.m_v2 = v2;
+ this.m_g1 = g1;
+ this.m_g2 = g2;
+ this.m_bits = bits;
+ }
+
+ public virtual BigInteger Beta
+ {
+ get { return m_beta; }
+ }
+
+ public virtual BigInteger Lambda
+ {
+ get { return m_lambda; }
+ }
+
+ public virtual BigInteger[] V1
+ {
+ get { return m_v1; }
+ }
+
+ public virtual BigInteger[] V2
+ {
+ get { return m_v2; }
+ }
+
+ public virtual BigInteger G1
+ {
+ get { return m_g1; }
+ }
+
+ public virtual BigInteger G2
+ {
+ get { return m_g2; }
+ }
+
+ public virtual int Bits
+ {
+ get { return m_bits; }
+ }
+ }
+}
diff --git a/crypto/src/math/ec/multiplier/WNafUtilities.cs b/crypto/src/math/ec/multiplier/WNafUtilities.cs
index 179d6d6eb..98e4f545f 100644
--- a/crypto/src/math/ec/multiplier/WNafUtilities.cs
+++ b/crypto/src/math/ec/multiplier/WNafUtilities.cs
@@ -268,6 +268,11 @@ namespace Org.BouncyCastle.Math.EC.Multiplier
return wnaf;
}
+ public static WNafPreCompInfo GetWNafPreCompInfo(ECPoint p)
+ {
+ return GetWNafPreCompInfo(p.Curve.GetPreCompInfo(p, PRECOMP_NAME));
+ }
+
public static WNafPreCompInfo GetWNafPreCompInfo(PreCompInfo preCompInfo)
{
if ((preCompInfo != null) && (preCompInfo is WNafPreCompInfo))
@@ -309,6 +314,45 @@ namespace Org.BouncyCastle.Math.EC.Multiplier
return w + 2;
}
+ public static ECPoint MapPointWithPrecomp(ECPoint p, int width, bool includeNegated,
+ ECPointMap pointMap)
+ {
+ ECCurve c = p.Curve;
+ WNafPreCompInfo wnafPreCompP = Precompute(p, width, includeNegated);
+
+ ECPoint q = pointMap.Map(p);
+ WNafPreCompInfo wnafPreCompQ = GetWNafPreCompInfo(c.GetPreCompInfo(q, PRECOMP_NAME));
+
+ ECPoint twiceP = wnafPreCompP.Twice;
+ if (twiceP != null)
+ {
+ ECPoint twiceQ = pointMap.Map(twiceP);
+ wnafPreCompQ.Twice = twiceQ;
+ }
+
+ ECPoint[] preCompP = wnafPreCompP.PreComp;
+ ECPoint[] preCompQ = new ECPoint[preCompP.Length];
+ for (int i = 0; i < preCompP.Length; ++i)
+ {
+ preCompQ[i] = pointMap.Map(preCompP[i]);
+ }
+ wnafPreCompQ.PreComp = preCompQ;
+
+ if (includeNegated)
+ {
+ ECPoint[] preCompNegQ = new ECPoint[preCompQ.Length];
+ for (int i = 0; i < preCompNegQ.Length; ++i)
+ {
+ preCompNegQ[i] = preCompQ[i].Negate();
+ }
+ wnafPreCompQ.PreCompNeg = preCompNegQ;
+ }
+
+ c.SetPreCompInfo(q, PRECOMP_NAME, wnafPreCompQ);
+
+ return q;
+ }
+
public static WNafPreCompInfo Precompute(ECPoint p, int width, bool includeNegated)
{
ECCurve c = p.Curve;
@@ -335,7 +379,7 @@ namespace Org.BouncyCastle.Math.EC.Multiplier
ECPoint twiceP = wnafPreCompInfo.Twice;
if (twiceP == null)
{
- twiceP = preComp[0].Twice().Normalize();
+ twiceP = preComp[0].Twice();
wnafPreCompInfo.Twice = twiceP;
}
|