From 8f7c63588dd18dc3e56e1253ac2779956ac60eb4 Mon Sep 17 00:00:00 2001 From: Peter Dettman Date: Wed, 5 Oct 2022 20:48:03 +0700 Subject: Span-based variants for XDH/EdDSA --- crypto/src/math/ec/rfc7748/X25519.cs | 4 + crypto/src/math/ec/rfc7748/X25519Field.cs | 114 ++++++++++++++++++++++++++++ crypto/src/math/ec/rfc7748/X448.cs | 4 + crypto/src/math/ec/rfc7748/X448Field.cs | 119 ++++++++++++++++++++++++++++++ crypto/src/math/ec/rfc8032/Ed25519.cs | 62 +++++++++------- crypto/src/math/ec/rfc8032/Ed448.cs | 40 ++++++---- 6 files changed, 304 insertions(+), 39 deletions(-) diff --git a/crypto/src/math/ec/rfc7748/X25519.cs b/crypto/src/math/ec/rfc7748/X25519.cs index 954b2dd90..ffddd4376 100644 --- a/crypto/src/math/ec/rfc7748/X25519.cs +++ b/crypto/src/math/ec/rfc7748/X25519.cs @@ -266,6 +266,9 @@ namespace Org.BouncyCastle.Math.EC.Rfc7748 public static void ScalarMultBase(byte[] k, int kOff, byte[] r, int rOff) { +#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER + ScalarMultBase(k.AsSpan(kOff), r.AsSpan(rOff)); +#else int[] y = F.Create(); int[] z = F.Create(); @@ -278,6 +281,7 @@ namespace Org.BouncyCastle.Math.EC.Rfc7748 F.Normalize(y); F.Encode(y, r, rOff); +#endif } #if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER diff --git a/crypto/src/math/ec/rfc7748/X25519Field.cs b/crypto/src/math/ec/rfc7748/X25519Field.cs index 8365df03b..c3373c7ea 100644 --- a/crypto/src/math/ec/rfc7748/X25519Field.cs +++ b/crypto/src/math/ec/rfc7748/X25519Field.cs @@ -180,6 +180,16 @@ namespace Org.BouncyCastle.Math.EC.Rfc7748 z[9] &= M24; } +#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER + [CLSCompliant(false)] + public static void Decode(ReadOnlySpan x, Span z) + { + Decode128(x, z); + Decode128(x[4..], z[5..]); + z[9] &= M24; + } +#endif + public static void Decode(byte[] x, int xOff, int[] z) { Decode128(x, xOff, z, 0); @@ -207,6 +217,19 @@ namespace Org.BouncyCastle.Math.EC.Rfc7748 z[zOff + 4] = (int)(t3 >> 7); } +#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER + private static void Decode128(ReadOnlySpan x, Span z) + { + uint t0 = x[0], t1 = x[1], t2 = x[2], t3 = x[3]; + + z[0] = (int)t0 & M26; + z[1] = (int)((t1 << 6) | (t0 >> 26)) & M26; + z[2] = (int)((t2 << 12) | (t1 >> 20)) & M25; + z[3] = (int)((t3 << 19) | (t2 >> 13)) & M26; + z[4] = (int)(t3 >> 7); + } +#endif + private static void Decode128(byte[] bs, int off, int[] z, int zOff) { uint t0 = Decode32(bs, off + 0); @@ -264,6 +287,15 @@ namespace Org.BouncyCastle.Math.EC.Rfc7748 Encode128(x, 5, z, zOff + 4); } +#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER + [CLSCompliant(false)] + public static void Encode(ReadOnlySpan x, Span z) + { + Encode128(x, z); + Encode128(x[5..], z[4..]); + } +#endif + public static void Encode(int[] x, byte[] z, int zOff) { Encode128(x, 0, z, zOff); @@ -289,6 +321,18 @@ namespace Org.BouncyCastle.Math.EC.Rfc7748 z[zOff + 3] = (x3 >> 19) | (x4 << 7); } +#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER + private static void Encode128(ReadOnlySpan x, Span z) + { + uint x0 = (uint)x[0], x1 = (uint)x[1], x2 = (uint)x[2], x3 = (uint)x[3], x4 = (uint)x[4]; + + z[0] = x0 | (x1 << 26); + z[1] = (x1 >> 6) | (x2 << 20); + z[2] = (x2 >> 12) | (x3 << 13); + z[3] = (x3 >> 19) | (x4 << 7); + } +#endif + private static void Encode128(int[] x, int xOff, byte[] bs, int off) { uint x0 = (uint)x[xOff + 0], x1 = (uint)x[xOff + 1], x2 = (uint)x[xOff + 2]; @@ -333,6 +377,9 @@ namespace Org.BouncyCastle.Math.EC.Rfc7748 public static void Inv(int[] x, int[] z) { +#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER + Inv(x.AsSpan(), z.AsSpan()); +#else //int[] x2 = Create(); //int[] t = Create(); //PowPm5d8(x, x2, t); @@ -349,10 +396,30 @@ namespace Org.BouncyCastle.Math.EC.Rfc7748 Mod.ModOddInverse(P32, u, u); Decode(u, 0, z); +#endif + } + +#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER + public static void Inv(ReadOnlySpan x, Span z) + { + Span t = stackalloc int[Size]; + Span u = stackalloc uint[8]; + + Copy(x, t); + Normalize(t); + Encode(t, u); + + Mod.ModOddInverse(P32, u, u); + + Decode(u, z); } +#endif public static void InvVar(int[] x, int[] z) { +#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER + InvVar(x.AsSpan(), z.AsSpan()); +#else int[] t = Create(); uint[] u = new uint[8]; @@ -363,8 +430,25 @@ namespace Org.BouncyCastle.Math.EC.Rfc7748 Mod.ModOddInverseVar(P32, u, u); Decode(u, 0, z); +#endif } +#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER + public static void InvVar(ReadOnlySpan x, Span z) + { + Span t = stackalloc int[Size]; + Span u = stackalloc uint[8]; + + Copy(x, t); + Normalize(t); + Encode(t, u); + + Mod.ModOddInverseVar(P32, u, u); + + Decode(u, z); + } +#endif + public static int IsOne(int[] x) { int d = x[0] ^ 1; @@ -599,6 +683,16 @@ namespace Org.BouncyCastle.Math.EC.Rfc7748 Debug.Assert(z[9] >> 24 == 0); } +#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER + public static void Normalize(Span z) + { + int x = (z[9] >> 23) & 1; + Reduce(z, x); + Reduce(z, -x); + Debug.Assert(z[9] >> 24 == 0); + } +#endif + public static void One(int[] z) { z[0] = 1; @@ -648,6 +742,26 @@ namespace Org.BouncyCastle.Math.EC.Rfc7748 z[9] = z9 + (int)cc; } +#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER + private static void Reduce(Span z, int x) + { + int t = z[9], z9 = t & M24; + t = (t >> 24) + x; + + long cc = t * 19; + cc += z[0]; z[0] = (int)cc & M26; cc >>= 26; + cc += z[1]; z[1] = (int)cc & M26; cc >>= 26; + cc += z[2]; z[2] = (int)cc & M25; cc >>= 25; + cc += z[3]; z[3] = (int)cc & M26; cc >>= 26; + cc += z[4]; z[4] = (int)cc & M25; cc >>= 25; + cc += z[5]; z[5] = (int)cc & M26; cc >>= 26; + cc += z[6]; z[6] = (int)cc & M26; cc >>= 26; + cc += z[7]; z[7] = (int)cc & M25; cc >>= 25; + cc += z[8]; z[8] = (int)cc & M26; cc >>= 26; + z[9] = z9 + (int)cc; + } +#endif + public static void Sqr(int[] x, int[] z) { int x0 = x[0]; diff --git a/crypto/src/math/ec/rfc7748/X448.cs b/crypto/src/math/ec/rfc7748/X448.cs index 2f6016a61..7e078c5c6 100644 --- a/crypto/src/math/ec/rfc7748/X448.cs +++ b/crypto/src/math/ec/rfc7748/X448.cs @@ -279,6 +279,9 @@ namespace Org.BouncyCastle.Math.EC.Rfc7748 public static void ScalarMultBase(byte[] k, int kOff, byte[] r, int rOff) { +#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER + ScalarMultBase(k.AsSpan(kOff), r.AsSpan(rOff)); +#else uint[] x = F.Create(); uint[] y = F.Create(); @@ -290,6 +293,7 @@ namespace Org.BouncyCastle.Math.EC.Rfc7748 F.Normalize(x); F.Encode(x, r, rOff); +#endif } #if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER diff --git a/crypto/src/math/ec/rfc7748/X448Field.cs b/crypto/src/math/ec/rfc7748/X448Field.cs index a1a86b61c..1e1d379fe 100644 --- a/crypto/src/math/ec/rfc7748/X448Field.cs +++ b/crypto/src/math/ec/rfc7748/X448Field.cs @@ -184,6 +184,14 @@ namespace Org.BouncyCastle.Math.EC.Rfc7748 Decode224(x, xOff + 7, z, 8); } +#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER + public static void Decode(ReadOnlySpan x, Span z) + { + Decode224(x, z); + Decode224(x[7..], z[8..]); + } +#endif + public static void Decode(byte[] x, int xOff, uint[] z) { Decode56(x, xOff, z, 0); @@ -225,6 +233,23 @@ namespace Org.BouncyCastle.Math.EC.Rfc7748 z[zOff + 7] = x6 >> 4; } +#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER + private static void Decode224(ReadOnlySpan x, Span z) + { + uint x0 = x[0], x1 = x[1], x2 = x[2], x3 = x[3]; + uint x4 = x[4], x5 = x[5], x6 = x[6]; + + z[0] = x0 & M28; + z[1] = (x0 >> 28 | x1 << 4) & M28; + z[2] = (x1 >> 24 | x2 << 8) & M28; + z[3] = (x2 >> 20 | x3 << 12) & M28; + z[4] = (x3 >> 16 | x4 << 16) & M28; + z[5] = (x4 >> 12 | x5 << 20) & M28; + z[6] = (x5 >> 8 | x6 << 24) & M28; + z[7] = x6 >> 4; + } +#endif + private static uint Decode24(byte[] bs, int off) { uint n = bs[off]; @@ -287,6 +312,14 @@ namespace Org.BouncyCastle.Math.EC.Rfc7748 Encode224(x, 8, z, zOff + 7); } +#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER + public static void Encode(ReadOnlySpan x, Span z) + { + Encode224(x, z); + Encode224(x[8..], z[7..]); + } +#endif + public static void Encode(uint[] x, byte[] z, int zOff) { Encode56(x, 0, z, zOff); @@ -327,6 +360,22 @@ namespace Org.BouncyCastle.Math.EC.Rfc7748 z[zOff + 6] = (x6 >> 24) | (x7 << 4); } +#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER + private static void Encode224(ReadOnlySpan x, Span z) + { + uint x0 = x[0], x1 = x[1], x2 = x[2], x3 = x[3]; + uint x4 = x[4], x5 = x[5], x6 = x[6], x7 = x[7]; + + z[0] = x0 | (x1 << 28); + z[1] = (x1 >> 4) | (x2 << 24); + z[2] = (x2 >> 8) | (x3 << 20); + z[3] = (x3 >> 12) | (x4 << 16); + z[4] = (x4 >> 16) | (x5 << 12); + z[5] = (x5 >> 20) | (x6 << 8); + z[6] = (x6 >> 24) | (x7 << 4); + } +#endif + private static void Encode24(uint n, byte[] bs, int off) { bs[ off] = (byte)(n ); @@ -379,6 +428,9 @@ namespace Org.BouncyCastle.Math.EC.Rfc7748 public static void Inv(uint[] x, uint[] z) { +#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER + Inv(x.AsSpan(), z.AsSpan()); +#else //uint[] t = Create(); //PowPm3d4(x, t); //Sqr(t, 2, t); @@ -394,10 +446,30 @@ namespace Org.BouncyCastle.Math.EC.Rfc7748 Mod.ModOddInverse(P32, u, u); Decode(u, 0, z); +#endif + } + +#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER + public static void Inv(ReadOnlySpan x, Span z) + { + Span t = stackalloc uint[Size]; + Span u = stackalloc uint[14]; + + Copy(x, t); + Normalize(t); + Encode(t, u); + + Mod.ModOddInverse(P32, u, u); + + Decode(u, z); } +#endif public static void InvVar(uint[] x, uint[] z) { +#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER + InvVar(x.AsSpan(), z.AsSpan()); +#else uint[] t = Create(); uint[] u = new uint[14]; @@ -408,7 +480,24 @@ namespace Org.BouncyCastle.Math.EC.Rfc7748 Mod.ModOddInverseVar(P32, u, u); Decode(u, 0, z); +#endif + } + +#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER + public static void InvVar(ReadOnlySpan x, Span z) + { + Span t = stackalloc uint[Size]; + Span u = stackalloc uint[14]; + + Copy(x, t); + Normalize(t); + Encode(t, u); + + Mod.ModOddInverseVar(P32, u, u); + + Decode(u, z); } +#endif public static int IsOne(uint[] x) { @@ -836,6 +925,16 @@ namespace Org.BouncyCastle.Math.EC.Rfc7748 Debug.Assert(z[15] >> 28 == 0U); } +#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER + public static void Normalize(Span z) + { + //int x = (z[15] >> (28 - 1)) & 1; + Reduce(z, 1); + Reduce(z, -1); + Debug.Assert(z[15] >> 28 == 0U); + } +#endif + public static void One(uint[] z) { z[0] = 1U; @@ -885,6 +984,26 @@ namespace Org.BouncyCastle.Math.EC.Rfc7748 z[15] = z15 + (uint)cc; } +#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER + private static void Reduce(Span z, int x) + { + uint u = z[15], z15 = u & M28; + int t = (int)(u >> 28) + x; + + long cc = t; + for (int i = 0; i < 8; ++i) + { + cc += z[i]; z[i] = (uint)cc & M28; cc >>= 28; + } + cc += t; + for (int i = 8; i < 15; ++i) + { + cc += z[i]; z[i] = (uint)cc & M28; cc >>= 28; + } + z[15] = z15 + (uint)cc; + } +#endif + public static void Sqr(uint[] x, uint[] z) { uint x0 = x[0]; diff --git a/crypto/src/math/ec/rfc8032/Ed25519.cs b/crypto/src/math/ec/rfc8032/Ed25519.cs index 128ec4244..d6bf461cf 100644 --- a/crypto/src/math/ec/rfc8032/Ed25519.cs +++ b/crypto/src/math/ec/rfc8032/Ed25519.cs @@ -413,6 +413,9 @@ namespace Org.BouncyCastle.Math.EC.Rfc8032 public static void GeneratePublicKey(byte[] sk, int skOff, byte[] pk, int pkOff) { +#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER + GeneratePublicKey(sk.AsSpan(skOff), pk.AsSpan(pkOff)); +#else IDigest d = CreateDigest(); byte[] h = new byte[d.GetDigestSize()]; @@ -423,6 +426,7 @@ namespace Org.BouncyCastle.Math.EC.Rfc8032 PruneScalar(h, 0, s); ScalarMultBaseEncoded(s, pk, pkOff); +#endif } #if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER @@ -582,7 +586,7 @@ namespace Org.BouncyCastle.Math.EC.Rfc8032 if (!CheckScalarVar(S, nS)) return false; - PointAffine pA; Init(out pA); + Init(out PointAffine pA); if (!DecodePointVar(pk, pkOff, true, ref pA)) return false; @@ -600,7 +604,7 @@ namespace Org.BouncyCastle.Math.EC.Rfc8032 uint[] nA = new uint[ScalarUints]; DecodeScalar(k, 0, nA); - PointAccum pR; Init(out pR); + Init(out PointAccum pR); ScalarMultStrausVar(nS, nA, ref pA, ref pR); byte[] check = new byte[PointBytes]; @@ -963,7 +967,7 @@ namespace Org.BouncyCastle.Math.EC.Rfc8032 Init(out points[0]); PointCopy(ref p, ref points[0]); - PointExtended d; Init(out d); + Init(out PointExtended d); PointAdd(ref points[0], ref points[0], ref d, ref t); for (int i = 1; i < count; ++i) @@ -977,13 +981,13 @@ namespace Org.BouncyCastle.Math.EC.Rfc8032 { Debug.Assert(count > 0); - PointExtended q; Init(out q); + Init(out PointExtended q); PointCopy(ref p, ref q); - PointExtended d; Init(out d); + Init(out PointExtended d); PointAdd(ref q, ref q, ref d, ref t); - PointPrecompZ r; Init(out r); + Init(out PointPrecompZ r); int[] table = F.CreateTable(count * 4); int off = 0; @@ -1010,10 +1014,10 @@ namespace Org.BouncyCastle.Math.EC.Rfc8032 { Debug.Assert(count > 0); - PointExtended q; Init(out q); + Init(out PointExtended q); PointCopy(ref p, ref q); - PointExtended d; Init(out d); + Init(out PointExtended d); PointAdd(ref q, ref q, ref d, ref t); int i = 0; @@ -1051,15 +1055,15 @@ namespace Org.BouncyCastle.Math.EC.Rfc8032 int totalPoints = wnafPoints + combPoints; PointExtended[] points = new PointExtended[totalPoints]; - PointTemp t; Init(out t); + Init(out PointTemp t); - PointAffine b; Init(out b); + Init(out PointAffine b); F.Copy(B_x, 0, b.x, 0); F.Copy(B_y, 0, b.y, 0); PointPrecompute(ref b, points, wnafPoints, ref t); - PointAccum p; Init(out p); + Init(out PointAccum p); F.Copy(B_x, 0, p.x, 0); F.Copy(B_y, 0, p.y, 0); F.One(p.z); @@ -1072,7 +1076,7 @@ namespace Org.BouncyCastle.Math.EC.Rfc8032 { Init(out toothPowers[tooth]); } - PointExtended u; Init(out u); + Init(out PointExtended u); for (int block = 0; block < PrecompBlocks; ++block) { ref PointExtended sum = ref points[pointsIndex++]; @@ -1145,7 +1149,7 @@ namespace Org.BouncyCastle.Math.EC.Rfc8032 } PrecompBaseComb = F.CreateTable(combPoints * 3); - PointPrecomp s; Init(out s); + Init(out PointPrecomp s); int off = 0; for (int i = wnafPoints; i < totalPoints; ++i) { @@ -1344,8 +1348,8 @@ namespace Org.BouncyCastle.Math.EC.Rfc8032 uint c2 = Nat.ShiftDownBit(ScalarUints, n, 1U); Debug.Assert(c2 == (1U << 31)); } - PointPrecompZ q; Init(out q); - PointTemp t; Init(out t); + Init(out PointPrecompZ q); + Init(out PointTemp t); int[] table = PointPrecomputeZ(ref p, 8, ref t); PointSetNeutral(ref r); @@ -1408,7 +1412,7 @@ namespace Org.BouncyCastle.Math.EC.Rfc8032 ScalarMultBase(k.AsSpan(), ref r); #else // Equivalent (but much slower) - //PointAffine p; Init(out p); + //Init(out PointAffine p); //F.Copy(B_x, 0, p.x, 0); //F.Copy(B_y, 0, p.y, 0); //ScalarMult(k, ref p, ref r); @@ -1433,8 +1437,8 @@ namespace Org.BouncyCastle.Math.EC.Rfc8032 } } - PointPrecomp p; Init(out p); - PointTemp t; Init(out t); + Init(out PointPrecomp p); + Init(out PointTemp t); PointSetNeutral(ref r); int resultSign = 0; @@ -1540,10 +1544,14 @@ namespace Org.BouncyCastle.Math.EC.Rfc8032 private static void ScalarMultBaseEncoded(byte[] k, byte[] r, int rOff) { - PointAccum p; Init(out p); +#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER + ScalarMultBaseEncoded(k.AsSpan(), r.AsSpan(rOff)); +#else + Init(out PointAccum p); ScalarMultBase(k, ref p); if (0 == EncodePoint(ref p, r, rOff)) throw new InvalidOperationException(); +#endif } #if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER @@ -1558,10 +1566,13 @@ namespace Org.BouncyCastle.Math.EC.Rfc8032 internal static void ScalarMultBaseYZ(byte[] k, int kOff, int[] y, int[] z) { +#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER + ScalarMultBaseYZ(k.AsSpan(kOff), y.AsSpan(), z.AsSpan()); +#else byte[] n = new byte[ScalarBytes]; PruneScalar(k, kOff, n); - PointAccum p; Init(out p); + Init(out PointAccum p); ScalarMultBase(n, ref p); if (0 == CheckPoint(p.x, p.y, p.z)) @@ -1569,6 +1580,7 @@ namespace Org.BouncyCastle.Math.EC.Rfc8032 F.Copy(p.y, 0, y, 0); F.Copy(p.z, 0, z, 0); +#endif } #if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER @@ -1594,7 +1606,7 @@ namespace Org.BouncyCastle.Math.EC.Rfc8032 int count = 1 << (WnafWidth - 2); PointPrecompZ[] tp = new PointPrecompZ[count]; - PointTemp t; Init(out t); + Init(out PointTemp t); PointPrecomputeZ(ref p, tp, count, ref t); PointSetNeutral(ref r); @@ -1626,7 +1638,7 @@ namespace Org.BouncyCastle.Math.EC.Rfc8032 int count = 1 << (WnafWidth - 2); PointPrecompZ[] tp = new PointPrecompZ[count]; - PointTemp t; Init(out t); + Init(out PointTemp t); PointPrecomputeZ(ref p, tp, count, ref t); PointSetNeutral(ref r); @@ -1726,7 +1738,7 @@ namespace Org.BouncyCastle.Math.EC.Rfc8032 public static bool ValidatePublicKeyFull(byte[] pk, int pkOff) { - PointAffine p; Init(out p); + Init(out PointAffine p); if (!DecodePointVar(pk, pkOff, false, ref p)) return false; @@ -1736,7 +1748,7 @@ namespace Org.BouncyCastle.Math.EC.Rfc8032 if (IsNeutralElementVar(p.x, p.y)) return false; - PointAccum r; Init(out r); + Init(out PointAccum r); ScalarMultOrderVar(ref p, ref r); F.Normalize(r.x); @@ -1748,7 +1760,7 @@ namespace Org.BouncyCastle.Math.EC.Rfc8032 public static bool ValidatePublicKeyPartial(byte[] pk, int pkOff) { - PointAffine p; Init(out p); + Init(out PointAffine p); return DecodePointVar(pk, pkOff, false, ref p); } diff --git a/crypto/src/math/ec/rfc8032/Ed448.cs b/crypto/src/math/ec/rfc8032/Ed448.cs index 8595f2f10..b6bacd179 100644 --- a/crypto/src/math/ec/rfc8032/Ed448.cs +++ b/crypto/src/math/ec/rfc8032/Ed448.cs @@ -397,6 +397,9 @@ namespace Org.BouncyCastle.Math.EC.Rfc8032 public static void GeneratePublicKey(byte[] sk, int skOff, byte[] pk, int pkOff) { +#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER + GeneratePublicKey(sk.AsSpan(skOff), pk.AsSpan(pkOff)); +#else IXof d = CreateXof(); byte[] h = new byte[ScalarBytes * 2]; @@ -407,6 +410,7 @@ namespace Org.BouncyCastle.Math.EC.Rfc8032 PruneScalar(h, 0, s); ScalarMultBaseEncoded(s, pk, pkOff); +#endif } #if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER @@ -566,7 +570,7 @@ namespace Org.BouncyCastle.Math.EC.Rfc8032 if (!CheckScalarVar(S, nS)) return false; - PointProjective pA; Init(out pA); + Init(out PointProjective pA); if (!DecodePointVar(pk, pkOff, true, ref pA)) return false; @@ -584,7 +588,7 @@ namespace Org.BouncyCastle.Math.EC.Rfc8032 uint[] nA = new uint[ScalarUints]; DecodeScalar(k, 0, nA); - PointProjective pR; Init(out pR); + Init(out PointProjective pR); ScalarMultStrausVar(nS, nA, ref pA, ref pR); byte[] check = new byte[PointBytes]; @@ -909,10 +913,10 @@ namespace Org.BouncyCastle.Math.EC.Rfc8032 { Debug.Assert(count > 0); - PointProjective q; Init(out q); + Init(out PointProjective q); PointCopy(ref p, ref q); - PointProjective d; Init(out d); + Init(out PointProjective d); PointCopy(ref q, ref d); PointDouble(ref d); @@ -939,7 +943,7 @@ namespace Org.BouncyCastle.Math.EC.Rfc8032 { Debug.Assert(count > 0); - PointProjective d; Init(out d); + Init(out PointProjective d); PointCopy(ref p, ref d); PointDouble(ref d); @@ -976,7 +980,7 @@ namespace Org.BouncyCastle.Math.EC.Rfc8032 PointProjective[] points = new PointProjective[totalPoints]; - PointProjective p; Init(out p); + Init(out PointProjective p); F.Copy(B_x, 0, p.x, 0); F.Copy(B_y, 0, p.y, 0); F.One(p.z); @@ -1375,7 +1379,7 @@ namespace Org.BouncyCastle.Math.EC.Rfc8032 } uint[] table = PointPrecompute(ref p, 8); - PointProjective q; Init(out q); + Init(out PointProjective q); // Replace first 4 doublings (2^4 * P) with 1 addition (P + 15 * P) PointLookup15(table, ref r); @@ -1442,7 +1446,7 @@ namespace Org.BouncyCastle.Math.EC.Rfc8032 ScalarMultBase(k.AsSpan(), ref r); #else // Equivalent (but much slower) - //PointProjective p; Init(out p); + //Init(out PointProjective p); //F.Copy(B_x, 0, p.x, 0); //F.Copy(B_y, 0, p.y, 0); //F.One(p.z); @@ -1461,7 +1465,7 @@ namespace Org.BouncyCastle.Math.EC.Rfc8032 Debug.Assert(c == (1U << 31)); } - PointAffine p; Init(out p); + Init(out PointAffine p); PointSetNeutral(ref r); @@ -1568,10 +1572,14 @@ namespace Org.BouncyCastle.Math.EC.Rfc8032 private static void ScalarMultBaseEncoded(byte[] k, byte[] r, int rOff) { - PointProjective p; Init(out p); +#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER + ScalarMultBaseEncoded(k.AsSpan(), r.AsSpan(rOff)); +#else + Init(out PointProjective p); ScalarMultBase(k, ref p); if (0 == EncodePoint(ref p, r, rOff)) throw new InvalidOperationException(); +#endif } #if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER @@ -1586,10 +1594,13 @@ namespace Org.BouncyCastle.Math.EC.Rfc8032 internal static void ScalarMultBaseXY(byte[] k, int kOff, uint[] x, uint[] y) { +#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER + ScalarMultBaseXY(k.AsSpan(kOff), x.AsSpan(), y.AsSpan()); +#else byte[] n = new byte[ScalarBytes]; PruneScalar(k, kOff, n); - PointProjective p; Init(out p); + Init(out PointProjective p); ScalarMultBase(n, ref p); if (0 == CheckPoint(p.x, p.y, p.z)) @@ -1597,6 +1608,7 @@ namespace Org.BouncyCastle.Math.EC.Rfc8032 F.Copy(p.x, 0, x, 0); F.Copy(p.y, 0, y, 0); +#endif } #if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER @@ -1736,7 +1748,7 @@ namespace Org.BouncyCastle.Math.EC.Rfc8032 public static bool ValidatePublicKeyFull(byte[] pk, int pkOff) { - PointProjective p; Init(out p); + Init(out PointProjective p); if (!DecodePointVar(pk, pkOff, false, ref p)) return false; @@ -1747,7 +1759,7 @@ namespace Org.BouncyCastle.Math.EC.Rfc8032 if (IsNeutralElementVar(p.x, p.y, p.z)) return false; - PointProjective r; Init(out r); + Init(out PointProjective r); ScalarMultOrderVar(ref p, ref r); F.Normalize(r.x); @@ -1759,7 +1771,7 @@ namespace Org.BouncyCastle.Math.EC.Rfc8032 public static bool ValidatePublicKeyPartial(byte[] pk, int pkOff) { - PointProjective p; Init(out p); + Init(out PointProjective p); return DecodePointVar(pk, pkOff, false, ref p); } -- cgit 1.4.1