diff options
author | Peter Dettman <peter.dettman@bouncycastle.org> | 2014-03-13 22:54:23 +0700 |
---|---|---|
committer | Peter Dettman <peter.dettman@bouncycastle.org> | 2014-03-13 22:54:23 +0700 |
commit | 104b98cc2797c4613151b95dc87218eca7f32c98 (patch) | |
tree | f0e6d13b80c03fbcea305195071b63c85534249f /crypto | |
parent | Fix bug in DoFinal introduced by last change (diff) | |
download | BouncyCastle.NET-ed25519-104b98cc2797c4613151b95dc87218eca7f32c98.tar.xz |
Port GLV implementation from Java
Diffstat (limited to 'crypto')
-rw-r--r-- | crypto/crypto.csproj | 35 | ||||
-rw-r--r-- | crypto/src/asn1/sec/SECNamedCurves.cs | 69 | ||||
-rw-r--r-- | crypto/src/crypto/ec/CustomNamedCurves.cs | 48 | ||||
-rw-r--r-- | crypto/src/math/ec/ECAlgorithms.cs | 48 | ||||
-rw-r--r-- | crypto/src/math/ec/ECCurve.cs | 26 | ||||
-rw-r--r-- | crypto/src/math/ec/ECPointMap.cs | 9 | ||||
-rw-r--r-- | crypto/src/math/ec/ScaleXPointMap.cs | 20 | ||||
-rw-r--r-- | crypto/src/math/ec/ScaleYPointMap.cs | 20 | ||||
-rw-r--r-- | crypto/src/math/ec/endo/ECEndomorphism.cs | 11 | ||||
-rw-r--r-- | crypto/src/math/ec/endo/GlvEndomorphism.cs | 10 | ||||
-rw-r--r-- | crypto/src/math/ec/endo/GlvTypeBEndomorphism.cs | 55 | ||||
-rw-r--r-- | crypto/src/math/ec/endo/GlvTypeBParameters.cs | 60 | ||||
-rw-r--r-- | crypto/src/math/ec/multiplier/WNafUtilities.cs | 46 |
13 files changed, 439 insertions, 18 deletions
diff --git a/crypto/crypto.csproj b/crypto/crypto.csproj index a4d6c7068..195d69a23 100644 --- a/crypto/crypto.csproj +++ b/crypto/crypto.csproj @@ -4649,6 +4649,11 @@ BuildAction = "Compile" /> <File + RelPath = "src\math\ec\ECPointMap.cs" + SubType = "Code" + BuildAction = "Compile" + /> + <File RelPath = "src\math\ec\LongArray.cs" SubType = "Code" BuildAction = "Compile" @@ -4664,6 +4669,16 @@ BuildAction = "Compile" /> <File + RelPath = "src\math\ec\ScaleXPointMap.cs" + SubType = "Code" + BuildAction = "Compile" + /> + <File + RelPath = "src\math\ec\ScaleYPointMap.cs" + SubType = "Code" + BuildAction = "Compile" + /> + <File RelPath = "src\math\ec\abc\SimpleBigDecimal.cs" SubType = "Code" BuildAction = "Compile" @@ -4869,6 +4884,26 @@ BuildAction = "Compile" /> <File + RelPath = "src\math\ec\endo\ECEndomorphism.cs" + SubType = "Code" + BuildAction = "Compile" + /> + <File + RelPath = "src\math\ec\endo\GlvEndomorphism.cs" + SubType = "Code" + BuildAction = "Compile" + /> + <File + RelPath = "src\math\ec\endo\GlvTypeBEndomorphism.cs" + SubType = "Code" + BuildAction = "Compile" + /> + <File + RelPath = "src\math\ec\endo\GlvTypeBParameters.cs" + SubType = "Code" + BuildAction = "Compile" + /> + <File RelPath = "src\math\ec\multiplier\AbstractECMultiplier.cs" SubType = "Code" BuildAction = "Compile" 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; } |