diff options
author | Peter Dettman <peter.dettman@bouncycastle.org> | 2022-11-27 20:48:58 +0700 |
---|---|---|
committer | Peter Dettman <peter.dettman@bouncycastle.org> | 2022-11-27 20:48:58 +0700 |
commit | 24a0aa84a2dfe82f7cabe89d3ab98437e8d027ef (patch) | |
tree | 2d720ef01e744e6ead9c3848eab8ec4755db9993 | |
parent | Update comments (diff) | |
download | BouncyCastle.NET-ed25519-24a0aa84a2dfe82f7cabe89d3ab98437e8d027ef.tar.xz |
Refactoring in Math.EC.Rfc8032
-rw-r--r-- | crypto/src/math/ec/rfc7748/X25519Field.cs | 7 | ||||
-rw-r--r-- | crypto/src/math/ec/rfc7748/X448Field.cs | 12 | ||||
-rw-r--r-- | crypto/src/math/ec/rfc8032/Ed25519.cs | 115 | ||||
-rw-r--r-- | crypto/src/math/ec/rfc8032/Ed448.cs | 118 | ||||
-rw-r--r-- | crypto/src/math/ec/rfc8032/Scalar448.cs | 2 | ||||
-rw-r--r-- | crypto/src/math/ec/rfc8032/ScalarUtilities.cs | 7 | ||||
-rw-r--r-- | crypto/src/math/raw/Nat448.cs | 2 |
7 files changed, 140 insertions, 123 deletions
diff --git a/crypto/src/math/ec/rfc7748/X25519Field.cs b/crypto/src/math/ec/rfc7748/X25519Field.cs index 1c0b928f7..079e673a8 100644 --- a/crypto/src/math/ec/rfc7748/X25519Field.cs +++ b/crypto/src/math/ec/rfc7748/X25519Field.cs @@ -333,6 +333,13 @@ namespace Org.BouncyCastle.Math.EC.Rfc7748 z[9] &= M24; } + public static void Decode(byte[] x, int xOff, int[] z, int zOff) + { + Decode128(x, xOff, z, zOff); + Decode128(x, xOff + 16, z, zOff + 5); + z[zOff + 9] &= M24; + } + #if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER public static void Decode(ReadOnlySpan<byte> x, Span<int> z) { diff --git a/crypto/src/math/ec/rfc7748/X448Field.cs b/crypto/src/math/ec/rfc7748/X448Field.cs index d812172bb..f3fe71114 100644 --- a/crypto/src/math/ec/rfc7748/X448Field.cs +++ b/crypto/src/math/ec/rfc7748/X448Field.cs @@ -265,6 +265,18 @@ namespace Org.BouncyCastle.Math.EC.Rfc7748 Decode56(x, xOff + 49, z, 14); } + public static void Decode(byte[] x, int xOff, uint[] z, int zOff) + { + Decode56(x, xOff, z, zOff); + Decode56(x, xOff + 7, z, zOff + 2); + Decode56(x, xOff + 14, z, zOff + 4); + Decode56(x, xOff + 21, z, zOff + 6); + Decode56(x, xOff + 28, z, zOff + 8); + Decode56(x, xOff + 35, z, zOff + 10); + Decode56(x, xOff + 42, z, zOff + 12); + Decode56(x, xOff + 49, z, zOff + 14); + } + #if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER public static void Decode(ReadOnlySpan<byte> x, Span<uint> z) { diff --git a/crypto/src/math/ec/rfc8032/Ed25519.cs b/crypto/src/math/ec/rfc8032/Ed25519.cs index baacc75fa..cde61b621 100644 --- a/crypto/src/math/ec/rfc8032/Ed25519.cs +++ b/crypto/src/math/ec/rfc8032/Ed25519.cs @@ -62,10 +62,10 @@ namespace Org.BouncyCastle.Math.EC.Rfc8032 private static readonly uint[] P = { 0xFFFFFFEDU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0xFFFFFFFFU, 0x7FFFFFFFU }; - private static readonly uint[] Order8_y1 = { 0x706A17C7, 0x4FD84D3D, 0x760B3CBA, 0x0F67100D, 0xFA53202A, - 0xC6CC392C, 0x77FDC74E, 0x7A03AC92 }; - private static readonly uint[] Order8_y2 = { 0x8F95E826, 0xB027B2C2, 0x89F4C345, 0xF098EFF2, 0x05ACDFD5, - 0x3933C6D3, 0x880238B1, 0x05FC536D }; + private static readonly uint[] Order8_y1 = { 0x706A17C7U, 0x4FD84D3DU, 0x760B3CBAU, 0x0F67100DU, 0xFA53202AU, + 0xC6CC392CU, 0x77FDC74EU, 0x7A03AC92U }; + private static readonly uint[] Order8_y2 = { 0x8F95E826U, 0xB027B2C2U, 0x89F4C345U, 0xF098EFF2U, 0x05ACDFD5U, + 0x3933C6D3U, 0x880238B1U, 0x05FC536DU }; private static readonly int[] B_x = { 0x0325D51A, 0x018B5823, 0x007B2C95, 0x0304A92D, 0x00D2598E, 0x01D6DC5C, 0x01388C7F, 0x013FEC0A, 0x029E6B72, 0x0042D26D }; @@ -148,10 +148,7 @@ namespace Org.BouncyCastle.Math.EC.Rfc8032 Nat256.MulAddTo(u, v, t); byte[] result = new byte[ScalarBytes * 2]; - for (int i = 0; i < t.Length; ++i) - { - Codec.Encode32(t[i], result, i * 4); - } + Codec.Encode32(t, 0, t.Length, result, 0); return Scalar25519.Reduce(result); } @@ -179,16 +176,16 @@ namespace Org.BouncyCastle.Math.EC.Rfc8032 return F.IsZero(t); } - private static int CheckPoint(int[] x, int[] y, int[] z) + private static int CheckPoint(PointAccum p) { int[] t = F.Create(); int[] u = F.Create(); int[] v = F.Create(); int[] w = F.Create(); - F.Sqr(x, u); - F.Sqr(y, v); - F.Sqr(z, w); + F.Sqr(p.x, u); + F.Sqr(p.y, v); + F.Sqr(p.z, w); F.Mul(u, v, t); F.Sub(v, u, v); F.Mul(v, w, v); @@ -201,39 +198,6 @@ namespace Org.BouncyCastle.Math.EC.Rfc8032 return F.IsZero(t); } - private static bool CheckPointOrderVar(ref PointAffine p) - { - Init(out PointAccum r); - ScalarMultOrderVar(ref p, ref r); - return NormalizeToNeutralElementVar(ref r); - } - -#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER - private static bool CheckPointVar(ReadOnlySpan<byte> p) - { - if ((Codec.Decode32(p[28..]) & 0x7FFFFFFFU) < P[7]) - return true; - for (int i = CoordUints - 2; i >= 0; --i) - { - if (Codec.Decode32(p[(i * 4)..]) < P[i]) - return true; - } - return false; - } -#else - private static bool CheckPointVar(byte[] p) - { - if ((Codec.Decode32(p, 28) & 0x7FFFFFFFU) < P[7]) - return true; - for (int i = CoordUints - 2; i >= 0; --i) - { - if (Codec.Decode32(p, i * 4) < P[i]) - return true; - } - return false; - } -#endif - #if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER private static bool CheckPointFullVar(ReadOnlySpan<byte> p) { @@ -308,6 +272,39 @@ namespace Org.BouncyCastle.Math.EC.Rfc8032 } #endif + private static bool CheckPointOrderVar(ref PointAffine p) + { + Init(out PointAccum r); + ScalarMultOrderVar(ref p, ref r); + return NormalizeToNeutralElementVar(ref r); + } + +#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER + private static bool CheckPointVar(ReadOnlySpan<byte> p) + { + if ((Codec.Decode32(p[28..]) & 0x7FFFFFFFU) < P[7]) + return true; + for (int i = CoordUints - 2; i >= 0; --i) + { + if (Codec.Decode32(p[(i * 4)..]) < P[i]) + return true; + } + return false; + } +#else + private static bool CheckPointVar(byte[] p) + { + if ((Codec.Decode32(p, 28) & 0x7FFFFFFFU) < P[7]) + return true; + for (int i = CoordUints - 2; i >= 0; --i) + { + if (Codec.Decode32(p, i * 4) < P[i]) + return true; + } + return false; + } +#endif + private static byte[] Copy(byte[] buf, int off, int len) { byte[] result = new byte[len]; @@ -938,10 +935,10 @@ namespace Org.BouncyCastle.Math.EC.Rfc8032 F.Copy(u, 0, points[0].z, 0); } - private static bool IsNeutralElementVar(int[] x, int[] y) - { - return F.IsZeroVar(x) && F.IsOneVar(y); - } + //private static bool IsNeutralElementVar(int[] x, int[] y) + //{ + // return F.IsZeroVar(x) && F.IsOneVar(y); + //} private static bool IsNeutralElementVar(int[] x, int[] y, int[] z) { @@ -1325,17 +1322,17 @@ namespace Org.BouncyCastle.Math.EC.Rfc8032 PointExtended[] points = new PointExtended[totalPoints]; Init(out PointTemp t); - Init(out PointAffine b); - F.Copy(B_x, 0, b.x, 0); - F.Copy(B_y, 0, b.y, 0); + Init(out PointAffine B); + F.Copy(B_x, 0, B.x, 0); + F.Copy(B_y, 0, B.y, 0); - PointPrecompute(ref b, points, 0, wnafPoints, ref t); + PointPrecompute(ref B, points, 0, wnafPoints, ref t); - Init(out PointAffine b128); - F.Copy(B128_x, 0, b128.x, 0); - F.Copy(B128_y, 0, b128.y, 0); + Init(out PointAffine B128); + F.Copy(B128_x, 0, B128.x, 0); + F.Copy(B128_y, 0, B128.y, 0); - PointPrecompute(ref b128, points, wnafPoints, wnafPoints, ref t); + PointPrecompute(ref B128, points, wnafPoints, wnafPoints, ref t); Init(out PointAccum p); F.Copy(B_x, 0, p.x, 0); @@ -1627,7 +1624,7 @@ namespace Org.BouncyCastle.Math.EC.Rfc8032 Init(out PointAccum p); ScalarMultBase(n, ref p); - if (0 == CheckPoint(p.x, p.y, p.z)) + if (0 == CheckPoint(p)) throw new InvalidOperationException(); F.Copy(p.y, 0, y, 0); @@ -1644,7 +1641,7 @@ namespace Org.BouncyCastle.Math.EC.Rfc8032 Init(out PointAccum p); ScalarMultBase(n, ref p); - if (0 == CheckPoint(p.x, p.y, p.z)) + if (0 == CheckPoint(p)) throw new InvalidOperationException(); F.Copy(p.y, y); diff --git a/crypto/src/math/ec/rfc8032/Ed448.cs b/crypto/src/math/ec/rfc8032/Ed448.cs index d3a9caf4d..c592fcdcc 100644 --- a/crypto/src/math/ec/rfc8032/Ed448.cs +++ b/crypto/src/math/ec/rfc8032/Ed448.cs @@ -66,12 +66,12 @@ namespace Org.BouncyCastle.Math.EC.Rfc8032 0x02488762U, 0x016EB6BCU, 0x0693F467U }; // 2^225 * B - private static readonly uint[] B225_x = { 0x06909ee2U, 0x01d7605cU, 0x0995ec8aU, 0x0fc4d970U, 0x0cf2b361U, - 0x02d82e9dU, 0x01225f55U, 0x007f0ef6U, 0x0aee9c55U, 0x0a240c13U, 0x05627b54U, 0x0d449d1eU, 0x03a44575U, - 0x007164a7U, 0x0bd4bd71U, 0x061a15fdU }; - private static readonly uint[] B225_y = { 0x0d3a9fe4U, 0x030696b9U, 0x07e7e326U, 0x068308c7U, 0x0ce0b8c8U, - 0x03ac222bU, 0x0304db8eU, 0x083ee319U, 0x05e5db0bU, 0x0eca503bU, 0x0b1c6539U, 0x078a8dceU, 0x02d256bcU, - 0x04a8b05eU, 0x0bd9fd57U, 0x0a1c3cb8U }; + private static readonly uint[] B225_x = { 0x06909EE2U, 0x01D7605CU, 0x0995EC8AU, 0x0FC4D970U, 0x0CF2B361U, + 0x02D82E9DU, 0x01225F55U, 0x007F0EF6U, 0x0AEE9C55U, 0x0A240C13U, 0x05627B54U, 0x0D449D1EU, 0x03A44575U, + 0x007164A7U, 0x0BD4BD71U, 0x061A15FDU }; + private static readonly uint[] B225_y = { 0x0D3A9FE4U, 0x030696B9U, 0x07E7E326U, 0x068308C7U, 0x0CE0B8C8U, + 0x03AC222BU, 0x0304DB8EU, 0x083EE319U, 0x05E5DB0BU, 0x0ECA503BU, 0x0B1C6539U, 0x078A8DCEU, 0x02D256BCU, + 0x04A8B05EU, 0x0BD9FD57U, 0x0A1C3CB8U }; private const int C_d = -39081; @@ -117,10 +117,7 @@ namespace Org.BouncyCastle.Math.EC.Rfc8032 Nat.MulAddTo(ScalarUints, u, v, t); byte[] result = new byte[ScalarBytes * 2]; - for (int i = 0; i < t.Length; ++i) - { - Codec.Encode32(t[i], result, i * 4); - } + Codec.Encode32(t, 0, t.Length, result, 0); return Scalar448.Reduce(result); } @@ -147,16 +144,16 @@ namespace Org.BouncyCastle.Math.EC.Rfc8032 return F.IsZero(t); } - private static int CheckPoint(uint[] x, uint[] y, uint[] z) + private static int CheckPoint(PointProjective p) { uint[] t = F.Create(); uint[] u = F.Create(); uint[] v = F.Create(); uint[] w = F.Create(); - F.Sqr(x, u); - F.Sqr(y, v); - F.Sqr(z, w); + F.Sqr(p.x, u); + F.Sqr(p.y, v); + F.Sqr(p.z, w); F.Mul(u, v, t); F.Add(u, v, u); F.Mul(u, w, u); @@ -169,47 +166,6 @@ namespace Org.BouncyCastle.Math.EC.Rfc8032 return F.IsZero(t); } - private static bool CheckPointOrderVar(ref PointAffine p) - { - Init(out PointProjective r); - ScalarMultOrderVar(ref p, ref r); - return NormalizeToNeutralElementVar(ref r); - } - -#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER - private static bool CheckPointVar(ReadOnlySpan<byte> p) - { - if ((p[PointBytes - 1] & 0x7F) != 0x00) - return false; - if (Codec.Decode32(p[52..]) < P[13]) - return true; - - int last = p[28] == 0xFF ? 7 : 0; - for (int i = CoordUints - 2; i >= last; --i) - { - if (Codec.Decode32(p[(i * 4)..]) < P[i]) - return true; - } - return false; - } -#else - private static bool CheckPointVar(byte[] p) - { - if ((p[PointBytes - 1] & 0x7F) != 0x00) - return false; - if (Codec.Decode32(p, 52) < P[13]) - return true; - - int last = p[28] == 0xFF ? 7 : 0; - for (int i = CoordUints - 2; i >= last; --i) - { - if (Codec.Decode32(p, i * 4) < P[i]) - return true; - } - return false; - } -#endif - #if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER private static bool CheckPointFullVar(ReadOnlySpan<byte> p) { @@ -282,6 +238,47 @@ namespace Org.BouncyCastle.Math.EC.Rfc8032 } #endif + private static bool CheckPointOrderVar(ref PointAffine p) + { + Init(out PointProjective r); + ScalarMultOrderVar(ref p, ref r); + return NormalizeToNeutralElementVar(ref r); + } + +#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER + private static bool CheckPointVar(ReadOnlySpan<byte> p) + { + if ((p[PointBytes - 1] & 0x7F) != 0x00) + return false; + if (Codec.Decode32(p[52..]) < P[13]) + return true; + + int last = p[28] == 0xFF ? 7 : 0; + for (int i = CoordUints - 2; i >= last; --i) + { + if (Codec.Decode32(p[(i * 4)..]) < P[i]) + return true; + } + return false; + } +#else + private static bool CheckPointVar(byte[] p) + { + if ((p[PointBytes - 1] & 0x7F) != 0x00) + return false; + if (Codec.Decode32(p, 52) < P[13]) + return true; + + int last = p[28] == 0xFF ? 7 : 0; + for (int i = CoordUints - 2; i >= last; --i) + { + if (Codec.Decode32(p, i * 4) < P[i]) + return true; + } + return false; + } +#endif + private static byte[] Copy(byte[] buf, int off, int len) { byte[] result = new byte[len]; @@ -336,6 +333,8 @@ namespace Org.BouncyCastle.Math.EC.Rfc8032 private static void Dom4(IXof d, byte phflag, byte[] ctx) { + Debug.Assert(ctx != null); + int n = Dom4Prefix.Length; #if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER @@ -854,6 +853,11 @@ namespace Org.BouncyCastle.Math.EC.Rfc8032 F.Copy(u, 0, points[0].z, 0); } + //private static bool IsNeutralElementVar(uint[] x, uint[] y) + //{ + // return F.IsZeroVar(x) && F.IsOneVar(y); + //} + private static bool IsNeutralElementVar(uint[] x, uint[] y, uint[] z) { return F.IsZeroVar(x) && F.AreEqualVar(y, z); @@ -1486,7 +1490,7 @@ namespace Org.BouncyCastle.Math.EC.Rfc8032 Init(out PointProjective p); ScalarMultBase(n, ref p); - if (0 == CheckPoint(p.x, p.y, p.z)) + if (0 == CheckPoint(p)) throw new InvalidOperationException(); F.Copy(p.x, 0, x, 0); @@ -1503,7 +1507,7 @@ namespace Org.BouncyCastle.Math.EC.Rfc8032 Init(out PointProjective p); ScalarMultBase(n, ref p); - if (0 == CheckPoint(p.x, p.y, p.z)) + if (0 == CheckPoint(p)) throw new InvalidOperationException(); F.Copy(p.x, x); diff --git a/crypto/src/math/ec/rfc8032/Scalar448.cs b/crypto/src/math/ec/rfc8032/Scalar448.cs index 5840b05ec..4afe1d2d6 100644 --- a/crypto/src/math/ec/rfc8032/Scalar448.cs +++ b/crypto/src/math/ec/rfc8032/Scalar448.cs @@ -14,7 +14,7 @@ namespace Org.BouncyCastle.Math.EC.Rfc8032 { internal const int Size = 14; - internal const int ScalarBytes = Size * 4 + 1; + private const int ScalarBytes = Size * 4 + 1; private const ulong M26UL = 0x03FFFFFFUL; private const ulong M28UL = 0x0FFFFFFFUL; diff --git a/crypto/src/math/ec/rfc8032/ScalarUtilities.cs b/crypto/src/math/ec/rfc8032/ScalarUtilities.cs index 3407c65c7..c70a4f2e8 100644 --- a/crypto/src/math/ec/rfc8032/ScalarUtilities.cs +++ b/crypto/src/math/ec/rfc8032/ScalarUtilities.cs @@ -158,17 +158,14 @@ namespace Org.BouncyCastle.Math.EC.Rfc8032 #endif { int i = last; - if ((int)x[i] < (int)y[i]) - return true; - if ((int)x[i] > (int)y[i]) - return false; - while (--i >= 0) + do { if (x[i] < y[i]) return true; if (x[i] > y[i]) return false; } + while (--i >= 0); return false; } diff --git a/crypto/src/math/raw/Nat448.cs b/crypto/src/math/raw/Nat448.cs index 5189d8936..688f327a4 100644 --- a/crypto/src/math/raw/Nat448.cs +++ b/crypto/src/math/raw/Nat448.cs @@ -85,7 +85,7 @@ namespace Org.BouncyCastle.Math.Raw Nat224.Mul(x, 7, y, 7, zz, 14); uint c21 = Nat224.AddToEachOther(zz, 7, zz, 14); - uint c14 = c21 + Nat224.AddTo(zz, 0, zz, 7, 0); + uint c14 = c21 + Nat224.AddTo(zz, 0, zz, 7, 0U); c21 += Nat224.AddTo(zz, 21, zz, 14, c14); uint[] dx = Nat224.Create(), dy = Nat224.Create(); |