summary refs log tree commit diff
path: root/crypto/src/math/ec/rfc7748
diff options
context:
space:
mode:
authorPeter Dettman <peter.dettman@bouncycastle.org>2022-10-05 20:48:03 +0700
committerPeter Dettman <peter.dettman@bouncycastle.org>2022-10-05 20:48:03 +0700
commit8f7c63588dd18dc3e56e1253ac2779956ac60eb4 (patch)
treefd45fc6050faa2d4965783e5c6137d9e951e2c73 /crypto/src/math/ec/rfc7748
parentSpan-bases variants for Mod methods (diff)
downloadBouncyCastle.NET-ed25519-8f7c63588dd18dc3e56e1253ac2779956ac60eb4.tar.xz
Span-based variants for XDH/EdDSA
Diffstat (limited to 'crypto/src/math/ec/rfc7748')
-rw-r--r--crypto/src/math/ec/rfc7748/X25519.cs4
-rw-r--r--crypto/src/math/ec/rfc7748/X25519Field.cs114
-rw-r--r--crypto/src/math/ec/rfc7748/X448.cs4
-rw-r--r--crypto/src/math/ec/rfc7748/X448Field.cs119
4 files changed, 241 insertions, 0 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<uint> x, Span<int> 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<uint> x, Span<int> 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<int> x, Span<uint> 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<int> x, Span<uint> 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<int> x, Span<int> z)
+        {
+            Span<int> t = stackalloc int[Size];
+            Span<uint> 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<int> x, Span<int> z)
+        {
+            Span<int> t = stackalloc int[Size];
+            Span<uint> 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<int> 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<int> 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<uint> x, Span<uint> 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<uint> x, Span<uint> 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<uint> x, Span<uint> 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<uint> x, Span<uint> 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<uint> x, Span<uint> z)
+        {
+            Span<uint> t = stackalloc uint[Size];
+            Span<uint> 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<uint> x, Span<uint> z)
+        {
+            Span<uint> t = stackalloc uint[Size];
+            Span<uint> 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<uint> 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<uint> 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];