diff options
author | Peter Dettman <peter.dettman@bouncycastle.org> | 2019-08-02 18:41:24 +0700 |
---|---|---|
committer | Peter Dettman <peter.dettman@bouncycastle.org> | 2019-08-02 18:41:24 +0700 |
commit | d5b186492a09c1aee253998670fc843e6087fe6e (patch) | |
tree | 011ee300b06ce58772a6fe46879c35a0a372d198 | |
parent | Provide a constant-time zero test (diff) | |
download | BouncyCastle.NET-ed25519-d5b186492a09c1aee253998670fc843e6087fe6e.tar.xz |
Add experimental support for GLV Type A endomorphisms
-rw-r--r-- | crypto/BouncyCastle.Android.csproj | 6 | ||||
-rw-r--r-- | crypto/BouncyCastle.csproj | 6 | ||||
-rw-r--r-- | crypto/BouncyCastle.iOS.csproj | 6 | ||||
-rw-r--r-- | crypto/crypto.csproj | 30 | ||||
-rw-r--r-- | crypto/src/asn1/sec/SECNamedCurves.cs | 76 | ||||
-rw-r--r-- | crypto/src/crypto/ec/CustomNamedCurves.cs | 76 | ||||
-rw-r--r-- | crypto/src/math/ec/ECPoint.cs | 24 | ||||
-rw-r--r-- | crypto/src/math/ec/ScaleXNegateYPointMap.cs | 20 | ||||
-rw-r--r-- | crypto/src/math/ec/ScaleYNegateXPointMap.cs | 20 | ||||
-rw-r--r-- | crypto/src/math/ec/endo/EndoUtilities.cs | 34 | ||||
-rw-r--r-- | crypto/src/math/ec/endo/GlvTypeAEndomorphism.cs | 38 | ||||
-rw-r--r-- | crypto/src/math/ec/endo/GlvTypeAParameters.cs | 32 | ||||
-rw-r--r-- | crypto/src/math/ec/endo/GlvTypeBEndomorphism.cs | 31 | ||||
-rw-r--r-- | crypto/src/math/ec/endo/GlvTypeBParameters.cs | 41 | ||||
-rw-r--r-- | crypto/src/math/ec/endo/ScalarSplitParameters.cs | 69 |
15 files changed, 398 insertions, 111 deletions
diff --git a/crypto/BouncyCastle.Android.csproj b/crypto/BouncyCastle.Android.csproj index 41ad0c236..2c2c44f86 100644 --- a/crypto/BouncyCastle.Android.csproj +++ b/crypto/BouncyCastle.Android.csproj @@ -1225,7 +1225,9 @@ <Compile Include="src\math\ec\ECPoint.cs" /> <Compile Include="src\math\ec\ECPointMap.cs" /> <Compile Include="src\math\ec\LongArray.cs" /> + <Compile Include="src\math\ec\ScaleXNegateYPointMap.cs" /> <Compile Include="src\math\ec\ScaleXPointMap.cs" /> + <Compile Include="src\math\ec\ScaleYNegateXPointMap.cs" /> <Compile Include="src\math\ec\ScaleYPointMap.cs" /> <Compile Include="src\math\ec\SimpleLookupTable.cs" /> <Compile Include="src\math\ec\abc\SimpleBigDecimal.cs" /> @@ -1340,9 +1342,13 @@ <Compile Include="src\math\ec\custom\sec\SecT571R1Curve.cs" /> <Compile Include="src\math\ec\custom\sec\SecT571R1Point.cs" /> <Compile Include="src\math\ec\endo\ECEndomorphism.cs" /> + <Compile Include="src\math\ec\endo\EndoUtilities.cs" /> <Compile Include="src\math\ec\endo\GlvEndomorphism.cs" /> + <Compile Include="src\math\ec\endo\GlvTypeAEndomorphism.cs" /> + <Compile Include="src\math\ec\endo\GlvTypeAParameters.cs" /> <Compile Include="src\math\ec\endo\GlvTypeBEndomorphism.cs" /> <Compile Include="src\math\ec\endo\GlvTypeBParameters.cs" /> + <Compile Include="src\math\ec\endo\ScalarSplitParameters.cs" /> <Compile Include="src\math\ec\multiplier\AbstractECMultiplier.cs" /> <Compile Include="src\math\ec\multiplier\DoubleAddMultiplier.cs" /> <Compile Include="src\math\ec\multiplier\ECMultiplier.cs" /> diff --git a/crypto/BouncyCastle.csproj b/crypto/BouncyCastle.csproj index 8c7f342d2..6a5e58829 100644 --- a/crypto/BouncyCastle.csproj +++ b/crypto/BouncyCastle.csproj @@ -1219,7 +1219,9 @@ <Compile Include="src\math\ec\ECPoint.cs" /> <Compile Include="src\math\ec\ECPointMap.cs" /> <Compile Include="src\math\ec\LongArray.cs" /> + <Compile Include="src\math\ec\ScaleXNegateYPointMap.cs" /> <Compile Include="src\math\ec\ScaleXPointMap.cs" /> + <Compile Include="src\math\ec\ScaleYNegateXPointMap.cs" /> <Compile Include="src\math\ec\ScaleYPointMap.cs" /> <Compile Include="src\math\ec\SimpleLookupTable.cs" /> <Compile Include="src\math\ec\abc\SimpleBigDecimal.cs" /> @@ -1334,9 +1336,13 @@ <Compile Include="src\math\ec\custom\sec\SecT571R1Curve.cs" /> <Compile Include="src\math\ec\custom\sec\SecT571R1Point.cs" /> <Compile Include="src\math\ec\endo\ECEndomorphism.cs" /> + <Compile Include="src\math\ec\endo\EndoUtilities.cs" /> <Compile Include="src\math\ec\endo\GlvEndomorphism.cs" /> + <Compile Include="src\math\ec\endo\GlvTypeAEndomorphism.cs" /> + <Compile Include="src\math\ec\endo\GlvTypeAParameters.cs" /> <Compile Include="src\math\ec\endo\GlvTypeBEndomorphism.cs" /> <Compile Include="src\math\ec\endo\GlvTypeBParameters.cs" /> + <Compile Include="src\math\ec\endo\ScalarSplitParameters.cs" /> <Compile Include="src\math\ec\multiplier\AbstractECMultiplier.cs" /> <Compile Include="src\math\ec\multiplier\DoubleAddMultiplier.cs" /> <Compile Include="src\math\ec\multiplier\ECMultiplier.cs" /> diff --git a/crypto/BouncyCastle.iOS.csproj b/crypto/BouncyCastle.iOS.csproj index f3ffb3b66..8194180f5 100644 --- a/crypto/BouncyCastle.iOS.csproj +++ b/crypto/BouncyCastle.iOS.csproj @@ -1220,7 +1220,9 @@ <Compile Include="src\math\ec\ECPoint.cs" /> <Compile Include="src\math\ec\ECPointMap.cs" /> <Compile Include="src\math\ec\LongArray.cs" /> + <Compile Include="src\math\ec\ScaleXNegateYPointMap.cs" /> <Compile Include="src\math\ec\ScaleXPointMap.cs" /> + <Compile Include="src\math\ec\ScaleYNegateXPointMap.cs" /> <Compile Include="src\math\ec\ScaleYPointMap.cs" /> <Compile Include="src\math\ec\SimpleLookupTable.cs" /> <Compile Include="src\math\ec\abc\SimpleBigDecimal.cs" /> @@ -1335,9 +1337,13 @@ <Compile Include="src\math\ec\custom\sec\SecT571R1Curve.cs" /> <Compile Include="src\math\ec\custom\sec\SecT571R1Point.cs" /> <Compile Include="src\math\ec\endo\ECEndomorphism.cs" /> + <Compile Include="src\math\ec\endo\EndoUtilities.cs" /> <Compile Include="src\math\ec\endo\GlvEndomorphism.cs" /> + <Compile Include="src\math\ec\endo\GlvTypeAEndomorphism.cs" /> + <Compile Include="src\math\ec\endo\GlvTypeAParameters.cs" /> <Compile Include="src\math\ec\endo\GlvTypeBEndomorphism.cs" /> <Compile Include="src\math\ec\endo\GlvTypeBParameters.cs" /> + <Compile Include="src\math\ec\endo\ScalarSplitParameters.cs" /> <Compile Include="src\math\ec\multiplier\AbstractECMultiplier.cs" /> <Compile Include="src\math\ec\multiplier\DoubleAddMultiplier.cs" /> <Compile Include="src\math\ec\multiplier\ECMultiplier.cs" /> diff --git a/crypto/crypto.csproj b/crypto/crypto.csproj index 1b4cccd52..4e6330818 100644 --- a/crypto/crypto.csproj +++ b/crypto/crypto.csproj @@ -5984,11 +5984,21 @@ BuildAction = "Compile" /> <File + RelPath = "src\math\ec\ScaleXNegateYPointMap.cs" + SubType = "Code" + BuildAction = "Compile" + /> + <File RelPath = "src\math\ec\ScaleXPointMap.cs" SubType = "Code" BuildAction = "Compile" /> <File + RelPath = "src\math\ec\ScaleYNegateXPointMap.cs" + SubType = "Code" + BuildAction = "Compile" + /> + <File RelPath = "src\math\ec\ScaleYPointMap.cs" SubType = "Code" BuildAction = "Compile" @@ -6559,11 +6569,26 @@ BuildAction = "Compile" /> <File + RelPath = "src\math\ec\endo\EndoUtilities.cs" + SubType = "Code" + BuildAction = "Compile" + /> + <File RelPath = "src\math\ec\endo\GlvEndomorphism.cs" SubType = "Code" BuildAction = "Compile" /> <File + RelPath = "src\math\ec\endo\GlvTypeAEndomorphism.cs" + SubType = "Code" + BuildAction = "Compile" + /> + <File + RelPath = "src\math\ec\endo\GlvTypeAParameters.cs" + SubType = "Code" + BuildAction = "Compile" + /> + <File RelPath = "src\math\ec\endo\GlvTypeBEndomorphism.cs" SubType = "Code" BuildAction = "Compile" @@ -6574,6 +6599,11 @@ BuildAction = "Compile" /> <File + RelPath = "src\math\ec\endo\ScalarSplitParameters.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 b753ac5d1..7d755cc11 100644 --- a/crypto/src/asn1/sec/SECNamedCurves.cs +++ b/crypto/src/asn1/sec/SECNamedCurves.cs @@ -172,15 +172,16 @@ namespace Org.BouncyCastle.Asn1.Sec 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("9162fbe73984472a0a9d0590", 16), - new BigInteger("96341f1138933bc2f503fd44", 16), - 176); + new ScalarSplitParameters( + new BigInteger[]{ + new BigInteger("9162fbe73984472a0a9e", 16), + new BigInteger("-96341f1138933bc2f505", 16) }, + new BigInteger[]{ + new BigInteger("127971af8721782ecffa3", 16), + new BigInteger("9162fbe73984472a0a9e", 16) }, + new BigInteger("9162fbe73984472a0a9d0590", 16), + new BigInteger("96341f1138933bc2f503fd44", 16), + 176)); ECCurve curve = ConfigureCurveGlv(new FpCurve(p, a, b, n, h), glv); X9ECPoint G = new X9ECPoint(curve, Hex.Decode("04" @@ -272,15 +273,16 @@ namespace Org.BouncyCastle.Asn1.Sec 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("71169be7330b3038edb025f1d0f9", 16), - new BigInteger("b3fb3400dec5c4adceb8655d4c94", 16), - 208); + new ScalarSplitParameters( + new BigInteger[]{ + new BigInteger("71169be7330b3038edb025f1", 16), + new BigInteger("-b3fb3400dec5c4adceb8655c", 16) }, + new BigInteger[]{ + new BigInteger("12511cfe811d0f4e6bc688b4d", 16), + new BigInteger("71169be7330b3038edb025f1", 16) }, + new BigInteger("71169be7330b3038edb025f1d0f9", 16), + new BigInteger("b3fb3400dec5c4adceb8655d4c94", 16), + 208)); ECCurve curve = ConfigureCurveGlv(new FpCurve(p, a, b, n, h), glv); X9ECPoint G = new X9ECPoint(curve, Hex.Decode("04" @@ -343,15 +345,16 @@ namespace Org.BouncyCastle.Asn1.Sec 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("6b8cf07d4ca75c88957d9d67059037a4", 16), - new BigInteger("b8adf1378a6eb73409fa6c9c637ba7f5", 16), - 240); + new ScalarSplitParameters( + new BigInteger[]{ + new BigInteger("6b8cf07d4ca75c88957d9d670591", 16), + new BigInteger("-b8adf1378a6eb73409fa6c9c637d", 16) }, + new BigInteger[]{ + new BigInteger("1243ae1b4d71613bc9f780a03690e", 16), + new BigInteger("6b8cf07d4ca75c88957d9d670591", 16) }, + new BigInteger("6b8cf07d4ca75c88957d9d67059037a4", 16), + new BigInteger("b8adf1378a6eb73409fa6c9c637ba7f5", 16), + 240)); ECCurve curve = ConfigureCurveGlv(new FpCurve(p, a, b, n, h), glv); X9ECPoint G = new X9ECPoint(curve, Hex.Decode("04" @@ -414,15 +417,16 @@ namespace Org.BouncyCastle.Asn1.Sec 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("3086d221a7d46bcde86c90e49284eb153dab", 16), - new BigInteger("e4437ed6010e88286f547fa90abfe4c42212", 16), - 272); + new ScalarSplitParameters( + new BigInteger[]{ + new BigInteger("3086d221a7d46bcde86c90e49284eb15", 16), + new BigInteger("-e4437ed6010e88286f547fa90abfe4c3", 16) }, + new BigInteger[]{ + new BigInteger("114ca50f7a8e2f3f657c1108d9d44cfd8", 16), + new BigInteger("3086d221a7d46bcde86c90e49284eb15", 16) }, + new BigInteger("3086d221a7d46bcde86c90e49284eb153dab", 16), + new BigInteger("e4437ed6010e88286f547fa90abfe4c42212", 16), + 272)); ECCurve curve = ConfigureCurveGlv(new FpCurve(p, a, b, n, h), glv); X9ECPoint G = new X9ECPoint(curve, Hex.Decode("04" diff --git a/crypto/src/crypto/ec/CustomNamedCurves.cs b/crypto/src/crypto/ec/CustomNamedCurves.cs index 4b7600e09..1f6b361a2 100644 --- a/crypto/src/crypto/ec/CustomNamedCurves.cs +++ b/crypto/src/crypto/ec/CustomNamedCurves.cs @@ -107,15 +107,16 @@ namespace Org.BouncyCastle.Crypto.EC 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("9162fbe73984472a0a9d0590", 16), - new BigInteger("96341f1138933bc2f503fd44", 16), - 176); + new ScalarSplitParameters( + new BigInteger[]{ + new BigInteger("9162fbe73984472a0a9e", 16), + new BigInteger("-96341f1138933bc2f505", 16) }, + new BigInteger[]{ + new BigInteger("127971af8721782ecffa3", 16), + new BigInteger("9162fbe73984472a0a9e", 16) }, + new BigInteger("9162fbe73984472a0a9d0590", 16), + new BigInteger("96341f1138933bc2f503fd44", 16), + 176)); ECCurve curve = ConfigureCurveGlv(new SecP160K1Curve(), glv); X9ECPoint G = new X9ECPoint(curve, Hex.Decode("04" + "3B4C382CE37AA192A4019E763036F4F5DD4D7EBB" @@ -182,15 +183,16 @@ namespace Org.BouncyCastle.Crypto.EC 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("71169be7330b3038edb025f1d0f9", 16), - new BigInteger("b3fb3400dec5c4adceb8655d4c94", 16), - 208); + new ScalarSplitParameters( + new BigInteger[]{ + new BigInteger("71169be7330b3038edb025f1", 16), + new BigInteger("-b3fb3400dec5c4adceb8655c", 16) }, + new BigInteger[]{ + new BigInteger("12511cfe811d0f4e6bc688b4d", 16), + new BigInteger("71169be7330b3038edb025f1", 16) }, + new BigInteger("71169be7330b3038edb025f1d0f9", 16), + new BigInteger("b3fb3400dec5c4adceb8655d4c94", 16), + 208)); ECCurve curve = ConfigureCurveGlv(new SecP192K1Curve(), glv); X9ECPoint G = new X9ECPoint(curve, Hex.Decode("04" + "DB4FF10EC057E9AE26B07D0280B7F4341DA5D1B1EAE06C7D" @@ -236,15 +238,16 @@ namespace Org.BouncyCastle.Crypto.EC 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("6b8cf07d4ca75c88957d9d67059037a4", 16), - new BigInteger("b8adf1378a6eb73409fa6c9c637ba7f5", 16), - 240); + new ScalarSplitParameters( + new BigInteger[]{ + new BigInteger("6b8cf07d4ca75c88957d9d670591", 16), + new BigInteger("-b8adf1378a6eb73409fa6c9c637d", 16) }, + new BigInteger[]{ + new BigInteger("1243ae1b4d71613bc9f780a03690e", 16), + new BigInteger("6b8cf07d4ca75c88957d9d670591", 16) }, + new BigInteger("6b8cf07d4ca75c88957d9d67059037a4", 16), + new BigInteger("b8adf1378a6eb73409fa6c9c637ba7f5", 16), + 240)); ECCurve curve = ConfigureCurveGlv(new SecP224K1Curve(), glv); X9ECPoint G = new X9ECPoint(curve, Hex.Decode("04" + "A1455B334DF099DF30FC28A169A467E9E47075A90F7E650EB6B7A45C" @@ -290,15 +293,16 @@ namespace Org.BouncyCastle.Crypto.EC 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("3086d221a7d46bcde86c90e49284eb153dab", 16), - new BigInteger("e4437ed6010e88286f547fa90abfe4c42212", 16), - 272); + new ScalarSplitParameters( + new BigInteger[]{ + new BigInteger("3086d221a7d46bcde86c90e49284eb15", 16), + new BigInteger("-e4437ed6010e88286f547fa90abfe4c3", 16) }, + new BigInteger[]{ + new BigInteger("114ca50f7a8e2f3f657c1108d9d44cfd8", 16), + new BigInteger("3086d221a7d46bcde86c90e49284eb15", 16) }, + new BigInteger("3086d221a7d46bcde86c90e49284eb153dab", 16), + new BigInteger("e4437ed6010e88286f547fa90abfe4c42212", 16), + 272)); ECCurve curve = ConfigureCurveGlv(new SecP256K1Curve(), glv); X9ECPoint G = new X9ECPoint(curve, Hex.Decode("04" + "79BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798" diff --git a/crypto/src/math/ec/ECPoint.cs b/crypto/src/math/ec/ECPoint.cs index 425424e32..6a7c3ecf0 100644 --- a/crypto/src/math/ec/ECPoint.cs +++ b/crypto/src/math/ec/ECPoint.cs @@ -306,6 +306,13 @@ namespace Org.BouncyCastle.Math.EC : Curve.CreateRawPoint(RawXCoord.Multiply(scale), RawYCoord, RawZCoords, IsCompressed); } + public virtual ECPoint ScaleXNegateY(ECFieldElement scale) + { + return IsInfinity + ? this + : Curve.CreateRawPoint(RawXCoord.Multiply(scale), RawYCoord.Negate(), RawZCoords, IsCompressed); + } + public virtual ECPoint ScaleY(ECFieldElement scale) { return IsInfinity @@ -313,6 +320,13 @@ namespace Org.BouncyCastle.Math.EC : Curve.CreateRawPoint(RawXCoord, RawYCoord.Multiply(scale), RawZCoords, IsCompressed); } + public virtual ECPoint ScaleYNegateX(ECFieldElement scale) + { + return IsInfinity + ? this + : Curve.CreateRawPoint(RawXCoord.Negate(), RawYCoord.Multiply(scale), RawZCoords, IsCompressed); + } + public override bool Equals(object obj) { return Equals(obj as ECPoint); @@ -1500,6 +1514,11 @@ namespace Org.BouncyCastle.Math.EC } } + public override ECPoint ScaleXNegateY(ECFieldElement scale) + { + return ScaleX(scale); + } + public override ECPoint ScaleY(ECFieldElement scale) { if (this.IsInfinity) @@ -1524,6 +1543,11 @@ namespace Org.BouncyCastle.Math.EC } } + public override ECPoint ScaleYNegateX(ECFieldElement scale) + { + return ScaleY(scale); + } + public override ECPoint Subtract(ECPoint b) { if (b.IsInfinity) diff --git a/crypto/src/math/ec/ScaleXNegateYPointMap.cs b/crypto/src/math/ec/ScaleXNegateYPointMap.cs new file mode 100644 index 000000000..b0466a633 --- /dev/null +++ b/crypto/src/math/ec/ScaleXNegateYPointMap.cs @@ -0,0 +1,20 @@ +using System; + +namespace Org.BouncyCastle.Math.EC +{ + public class ScaleXNegateYPointMap + : ECPointMap + { + protected readonly ECFieldElement scale; + + public ScaleXNegateYPointMap(ECFieldElement scale) + { + this.scale = scale; + } + + public virtual ECPoint Map(ECPoint p) + { + return p.ScaleXNegateY(scale); + } + } +} diff --git a/crypto/src/math/ec/ScaleYNegateXPointMap.cs b/crypto/src/math/ec/ScaleYNegateXPointMap.cs new file mode 100644 index 000000000..6a7fed12e --- /dev/null +++ b/crypto/src/math/ec/ScaleYNegateXPointMap.cs @@ -0,0 +1,20 @@ +using System; + +namespace Org.BouncyCastle.Math.EC +{ + public class ScaleYNegateXPointMap + : ECPointMap + { + protected readonly ECFieldElement scale; + + public ScaleYNegateXPointMap(ECFieldElement scale) + { + this.scale = scale; + } + + public virtual ECPoint Map(ECPoint p) + { + return p.ScaleYNegateX(scale); + } + } +} diff --git a/crypto/src/math/ec/endo/EndoUtilities.cs b/crypto/src/math/ec/endo/EndoUtilities.cs new file mode 100644 index 000000000..16916e632 --- /dev/null +++ b/crypto/src/math/ec/endo/EndoUtilities.cs @@ -0,0 +1,34 @@ +using System; + +using Org.BouncyCastle.Math; + +namespace Org.BouncyCastle.Math.EC.Endo +{ + public abstract class EndoUtilities + { + public static BigInteger[] DecomposeScalar(ScalarSplitParameters p, BigInteger k) + { + int bits = p.Bits; + BigInteger b1 = CalculateB(k, p.G1, bits); + BigInteger b2 = CalculateB(k, p.G2, bits); + + BigInteger a = k.Subtract((b1.Multiply(p.V1A)).Add(b2.Multiply(p.V2A))); + BigInteger b = (b1.Multiply(p.V1B)).Add(b2.Multiply(p.V2B)).Negate(); + + return new BigInteger[]{ a, b }; + } + + private static 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/GlvTypeAEndomorphism.cs b/crypto/src/math/ec/endo/GlvTypeAEndomorphism.cs new file mode 100644 index 000000000..fda8f154c --- /dev/null +++ b/crypto/src/math/ec/endo/GlvTypeAEndomorphism.cs @@ -0,0 +1,38 @@ +using System; + +namespace Org.BouncyCastle.Math.EC.Endo +{ + public class GlvTypeAEndomorphism + : GlvEndomorphism + { + protected readonly GlvTypeAParameters m_parameters; + protected readonly ECPointMap m_pointMap; + + public GlvTypeAEndomorphism(ECCurve curve, GlvTypeAParameters parameters) + { + /* + * NOTE: 'curve' MUST only be used to create a suitable ECFieldElement. Due to the way + * ECCurve configuration works, 'curve' will not be the actual instance of ECCurve that the + * endomorphism is being used with. + */ + + this.m_parameters = parameters; + this.m_pointMap = new ScaleYNegateXPointMap(curve.FromBigInteger(parameters.I)); + } + + public virtual BigInteger[] DecomposeScalar(BigInteger k) + { + return EndoUtilities.DecomposeScalar(m_parameters.SplitParams, k); + } + + public virtual ECPointMap PointMap + { + get { return m_pointMap; } + } + + public virtual bool HasEfficientPointMap + { + get { return true; } + } + } +} diff --git a/crypto/src/math/ec/endo/GlvTypeAParameters.cs b/crypto/src/math/ec/endo/GlvTypeAParameters.cs new file mode 100644 index 000000000..68464c530 --- /dev/null +++ b/crypto/src/math/ec/endo/GlvTypeAParameters.cs @@ -0,0 +1,32 @@ +using System; + +namespace Org.BouncyCastle.Math.EC.Endo +{ + public class GlvTypeAParameters + { + protected readonly BigInteger m_i, m_lambda; + protected readonly ScalarSplitParameters m_splitParams; + + public GlvTypeAParameters(BigInteger i, BigInteger lambda, ScalarSplitParameters splitParams) + { + this.m_i = i; + this.m_lambda = lambda; + this.m_splitParams = splitParams; + } + + public virtual BigInteger I + { + get { return m_i; } + } + + public virtual BigInteger Lambda + { + get { return m_lambda; } + } + + public virtual ScalarSplitParameters SplitParams + { + get { return m_splitParams; } + } + } +} diff --git a/crypto/src/math/ec/endo/GlvTypeBEndomorphism.cs b/crypto/src/math/ec/endo/GlvTypeBEndomorphism.cs index d234d88bf..e4f12fed9 100644 --- a/crypto/src/math/ec/endo/GlvTypeBEndomorphism.cs +++ b/crypto/src/math/ec/endo/GlvTypeBEndomorphism.cs @@ -5,28 +5,24 @@ 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; + /* + * NOTE: 'curve' MUST only be used to create a suitable ECFieldElement. Due to the way + * ECCurve configuration works, 'curve' will not be the actual instance of ECCurve that the + * endomorphism is being used with. + */ + 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 }; + return EndoUtilities.DecomposeScalar(m_parameters.SplitParams, k); } public virtual ECPointMap PointMap @@ -38,18 +34,5 @@ namespace Org.BouncyCastle.Math.EC.Endo { 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 index f93dfaf2b..5e2937be8 100644 --- a/crypto/src/math/ec/endo/GlvTypeBParameters.cs +++ b/crypto/src/math/ec/endo/GlvTypeBParameters.cs @@ -4,22 +4,23 @@ 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; + protected readonly BigInteger m_beta, m_lambda; + protected readonly ScalarSplitParameters m_splitParams; + [Obsolete("Use constructor taking a ScalarSplitParameters instead")] 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; + this.m_splitParams = new ScalarSplitParameters(v1, v2, g1, g2, bits); + } + + public GlvTypeBParameters(BigInteger beta, BigInteger lambda, ScalarSplitParameters splitParams) + { + this.m_beta = beta; + this.m_lambda = lambda; + this.m_splitParams = splitParams; } public virtual BigInteger Beta @@ -32,29 +33,39 @@ namespace Org.BouncyCastle.Math.EC.Endo get { return m_lambda; } } + public virtual ScalarSplitParameters SplitParams + { + get { return m_splitParams; } + } + + [Obsolete("Access via SplitParams instead")] public virtual BigInteger[] V1 { - get { return m_v1; } + get { return new BigInteger[] { m_splitParams.V1A, m_splitParams.V1B }; } } + [Obsolete("Access via SplitParams instead")] public virtual BigInteger[] V2 { - get { return m_v2; } + get { return new BigInteger[] { m_splitParams.V2A, m_splitParams.V2B }; } } + [Obsolete("Access via SplitParams instead")] public virtual BigInteger G1 { - get { return m_g1; } + get { return m_splitParams.G1; } } + [Obsolete("Access via SplitParams instead")] public virtual BigInteger G2 { - get { return m_g2; } + get { return m_splitParams.G2; } } + [Obsolete("Access via SplitParams instead")] public virtual int Bits { - get { return m_bits; } + get { return m_splitParams.Bits; } } } } diff --git a/crypto/src/math/ec/endo/ScalarSplitParameters.cs b/crypto/src/math/ec/endo/ScalarSplitParameters.cs new file mode 100644 index 000000000..18d0bdb9e --- /dev/null +++ b/crypto/src/math/ec/endo/ScalarSplitParameters.cs @@ -0,0 +1,69 @@ +using System; + +using Org.BouncyCastle.Math; + +namespace Org.BouncyCastle.Math.EC.Endo +{ + public class ScalarSplitParameters + { + private static void CheckVector(BigInteger[] v, string name) + { + if (v == null || v.Length != 2 || v[0] == null || v[1] == null) + throw new ArgumentException("Must consist of exactly 2 (non-null) values", name); + } + + protected readonly BigInteger m_v1A, m_v1B, m_v2A, m_v2B; + protected readonly BigInteger m_g1, m_g2; + protected readonly int m_bits; + + public ScalarSplitParameters(BigInteger[] v1, BigInteger[] v2, BigInteger g1, + BigInteger g2, int bits) + { + CheckVector(v1, "v1"); + CheckVector(v2, "v2"); + + this.m_v1A = v1[0]; + this.m_v1B = v1[1]; + this.m_v2A = v2[0]; + this.m_v2B = v2[1]; + this.m_g1 = g1; + this.m_g2 = g2; + this.m_bits = bits; + } + + public virtual BigInteger V1A + { + get { return m_v1A; } + } + + public virtual BigInteger V1B + { + get { return m_v1B; } + } + + public virtual BigInteger V2A + { + get { return m_v2A; } + } + + public virtual BigInteger V2B + { + get { return m_v2B; } + } + + public virtual BigInteger G1 + { + get { return m_g1; } + } + + public virtual BigInteger G2 + { + get { return m_g2; } + } + + public virtual int Bits + { + get { return m_bits; } + } + } +} |