summary refs log tree commit diff
path: root/crypto/src/math
diff options
context:
space:
mode:
authorPeter Dettman <peter.dettman@bouncycastle.org>2022-11-20 12:32:26 +0700
committerPeter Dettman <peter.dettman@bouncycastle.org>2022-11-20 12:32:26 +0700
commitc2394e283f20165db6f262aca84fdf973ce7543d (patch)
tree04981cf0a1b79eaca6ded9149fc0d0b3cf395cf3 /crypto/src/math
parentFactor Wnaf out of EdDSA (diff)
downloadBouncyCastle.NET-ed25519-c2394e283f20165db6f262aca84fdf973ce7543d.tar.xz
Factor Codec out of EdDSA
Diffstat (limited to 'crypto/src/math')
-rw-r--r--crypto/src/math/ec/rfc8032/Codec.cs133
-rw-r--r--crypto/src/math/ec/rfc8032/Ed25519.cs236
-rw-r--r--crypto/src/math/ec/rfc8032/Ed448.cs324
3 files changed, 290 insertions, 403 deletions
diff --git a/crypto/src/math/ec/rfc8032/Codec.cs b/crypto/src/math/ec/rfc8032/Codec.cs
new file mode 100644
index 000000000..3aacd12ab
--- /dev/null
+++ b/crypto/src/math/ec/rfc8032/Codec.cs
@@ -0,0 +1,133 @@
+using System;
+#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER
+using System.Buffers.Binary;
+#endif
+
+namespace Org.BouncyCastle.Math.EC.Rfc8032
+{
+    internal static class Codec
+    {
+        internal static uint Decode16(byte[] bs, int off)
+        {
+#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER
+            return BinaryPrimitives.ReadUInt16LittleEndian(bs.AsSpan(off));
+#else
+            uint n = bs[off];
+            n |= (uint)bs[++off] << 8;
+            return n;
+#endif
+        }
+
+#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER
+        internal static uint Decode16(ReadOnlySpan<byte> bs)
+        {
+            return BinaryPrimitives.ReadUInt16LittleEndian(bs);
+        }
+#endif
+
+        internal static uint Decode24(byte[] bs, int off)
+        {
+            uint n = bs[off];
+            n |= (uint)bs[++off] << 8;
+            n |= (uint)bs[++off] << 16;
+            return n;
+        }
+
+#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER
+        internal static uint Decode24(ReadOnlySpan<byte> bs)
+        {
+            uint n = bs[0];
+            n |= (uint)bs[1] << 8;
+            n |= (uint)bs[2] << 16;
+            return n;
+        }
+#endif
+
+        internal static uint Decode32(byte[] bs, int off)
+        {
+#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER
+            return BinaryPrimitives.ReadUInt32LittleEndian(bs.AsSpan(off));
+#else
+            uint n = bs[off];
+            n |= (uint)bs[++off] << 8;
+            n |= (uint)bs[++off] << 16;
+            n |= (uint)bs[++off] << 24;
+            return n;
+#endif
+        }
+
+#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER
+        internal static uint Decode32(ReadOnlySpan<byte> bs)
+        {
+            return BinaryPrimitives.ReadUInt32LittleEndian(bs);
+        }
+#endif
+
+        internal static void Decode32(byte[] bs, int bsOff, uint[] n, int nOff, int nLen)
+        {
+            for (int i = 0; i < nLen; ++i)
+            {
+                n[nOff + i] = Decode32(bs, bsOff + i * 4);
+            }
+        }
+
+#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER
+        internal static void Decode32(ReadOnlySpan<byte> bs, Span<uint> n)
+        {
+            for (int i = 0; i < n.Length; ++i)
+            {
+                n[i] = Decode32(bs[(i * 4)..]);
+            }
+        }
+#endif
+
+        internal static void Encode24(uint n, byte[] bs, int off)
+        {
+            bs[off] = (byte)(n);
+            bs[++off] = (byte)(n >> 8);
+            bs[++off] = (byte)(n >> 16);
+        }
+
+#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER
+        internal static void Encode24(uint n, Span<byte> bs)
+        {
+            bs[0] = (byte)(n);
+            bs[1] = (byte)(n >> 8);
+            bs[2] = (byte)(n >> 16);
+        }
+#endif
+
+        internal static void Encode32(uint n, byte[] bs, int off)
+        {
+#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER
+            BinaryPrimitives.WriteUInt32LittleEndian(bs.AsSpan(off), n);
+#else
+            bs[  off] = (byte)(n      );
+            bs[++off] = (byte)(n >>  8);
+            bs[++off] = (byte)(n >> 16);
+            bs[++off] = (byte)(n >> 24);
+#endif
+        }
+
+#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER
+        internal static void Encode32(uint n, Span<byte> bs)
+        {
+            BinaryPrimitives.WriteUInt32LittleEndian(bs, n);
+        }
+#endif
+
+        internal static void Encode56(ulong n, byte[] bs, int off)
+        {
+            Encode32((uint)n, bs, off);
+            Encode24((uint)(n >> 32), bs, off + 4);
+        }
+
+#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER
+        internal static void Encode56(ulong n, Span<byte> bs)
+        {
+            Encode32((uint)n, bs);
+            Encode24((uint)(n >> 32), bs[4..]);
+        }
+#endif
+    }
+}
diff --git a/crypto/src/math/ec/rfc8032/Ed25519.cs b/crypto/src/math/ec/rfc8032/Ed25519.cs
index 502d5ed9c..696c6e6b7 100644
--- a/crypto/src/math/ec/rfc8032/Ed25519.cs
+++ b/crypto/src/math/ec/rfc8032/Ed25519.cs
@@ -1,7 +1,4 @@
 using System;
-#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER
-using System.Buffers.Binary;
-#endif
 using System.Diagnostics;
 
 using Org.BouncyCastle.Crypto;
@@ -149,7 +146,7 @@ namespace Org.BouncyCastle.Math.EC.Rfc8032
             byte[] result = new byte[ScalarBytes * 2];
             for (int i = 0; i < t.Length; ++i)
             {
-                Encode32(t[i], result, i * 4);
+                Codec.Encode32(t[i], result, i * 4);
             }
             return ReduceScalar(result);
         }
@@ -203,11 +200,11 @@ namespace Org.BouncyCastle.Math.EC.Rfc8032
 #if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER
         private static bool CheckPointVar(ReadOnlySpan<byte> p)
         {
-            if ((Decode32(p[28..]) & 0x7FFFFFFFU) < P[7])
+            if ((Codec.Decode32(p[28..]) & 0x7FFFFFFFU) < P[7])
                 return true;
             for (int i = CoordUints - 2; i >= 0; --i)
             {
-                if (Decode32(p[(i * 4)..]) < P[i])
+                if (Codec.Decode32(p[(i * 4)..]) < P[i])
                     return true;
             }
             return false;
@@ -221,11 +218,11 @@ namespace Org.BouncyCastle.Math.EC.Rfc8032
 #else
         private static bool CheckPointVar(byte[] p)
         {
-            if ((Decode32(p, 28) & 0x7FFFFFFFU) < P[7])
+            if ((Codec.Decode32(p, 28) & 0x7FFFFFFFU) < P[7])
                 return true;
             for (int i = CoordUints - 2; i >= 0; --i)
             {
-                if (Decode32(p, i * 4) < P[i])
+                if (Codec.Decode32(p, i * 4) < P[i])
                     return true;
             }
             return false;
@@ -258,62 +255,6 @@ namespace Org.BouncyCastle.Math.EC.Rfc8032
             return CreateDigest();
         }
 
-        private static uint Decode24(byte[] bs, int off)
-        {
-            uint n = bs[off];
-            n |= (uint)bs[++off] << 8;
-            n |= (uint)bs[++off] << 16;
-            return n;
-        }
-
-#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER
-        private static uint Decode24(ReadOnlySpan<byte> bs)
-        {
-            uint n = bs[0];
-            n |= (uint)bs[1] << 8;
-            n |= (uint)bs[2] << 16;
-            return n;
-        }
-#endif
-
-        private static uint Decode32(byte[] bs, int off)
-        {
-#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER
-            return BinaryPrimitives.ReadUInt32LittleEndian(bs.AsSpan(off));
-#else
-            uint n = bs[off];
-            n |= (uint)bs[++off] << 8;
-            n |= (uint)bs[++off] << 16;
-            n |= (uint)bs[++off] << 24;
-            return n;
-#endif
-        }
-
-#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER
-        private static uint Decode32(ReadOnlySpan<byte> bs)
-        {
-            return BinaryPrimitives.ReadUInt32LittleEndian(bs);
-        }
-#endif
-
-        private static void Decode32(byte[] bs, int bsOff, uint[] n, int nOff, int nLen)
-        {
-            for (int i = 0; i < nLen; ++i)
-            {
-                n[nOff + i] = Decode32(bs, bsOff + i * 4);
-            }
-        }
-
-#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER
-        private static void Decode32(ReadOnlySpan<byte> bs, Span<uint> n)
-        {
-            for (int i = 0; i < n.Length; ++i)
-            {
-                n[i] = Decode32(bs[(i * 4)..]);
-            }
-        }
-#endif
-
         private static bool DecodePointVar(byte[] p, int pOff, bool negate, ref PointAffine r)
         {
             byte[] py = Copy(p, pOff, PointBytes);
@@ -350,13 +291,13 @@ namespace Org.BouncyCastle.Math.EC.Rfc8032
 
         private static void DecodeScalar(byte[] k, int kOff, uint[] n)
         {
-            Decode32(k, kOff, n, 0, ScalarUints);
+            Codec.Decode32(k, kOff, n, 0, ScalarUints);
         }
 
 #if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER
         private static void DecodeScalar(ReadOnlySpan<byte> k, Span<uint> n)
         {
-            Decode32(k, n[..ScalarUints]);
+            Codec.Decode32(k, n[..ScalarUints]);
         }
 #endif
 
@@ -375,55 +316,6 @@ namespace Org.BouncyCastle.Math.EC.Rfc8032
             }
         }
 
-        private static void Encode24(uint n, byte[] bs, int off)
-        {
-            bs[off] = (byte)(n);
-            bs[++off] = (byte)(n >> 8);
-            bs[++off] = (byte)(n >> 16);
-        }
-
-#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER
-        private static void Encode24(uint n, Span<byte> bs)
-        {
-            bs[0] = (byte)(n);
-            bs[1] = (byte)(n >> 8);
-            bs[2] = (byte)(n >> 16);
-        }
-#endif
-
-        private static void Encode32(uint n, byte[] bs, int off)
-        {
-#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER
-            BinaryPrimitives.WriteUInt32LittleEndian(bs.AsSpan(off), n);
-#else
-            bs[  off] = (byte)(n      );
-            bs[++off] = (byte)(n >>  8);
-            bs[++off] = (byte)(n >> 16);
-            bs[++off] = (byte)(n >> 24);
-#endif
-        }
-
-#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER
-        private static void Encode32(uint n, Span<byte> bs)
-        {
-            BinaryPrimitives.WriteUInt32LittleEndian(bs, n);
-        }
-#endif
-
-        private static void Encode56(ulong n, byte[] bs, int off)
-        {
-            Encode32((uint)n, bs, off);
-            Encode24((uint)(n >> 32), bs, off + 4);
-        }
-
-#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER
-        private static void Encode56(ulong n, Span<byte> bs)
-        {
-            Encode32((uint)n, bs);
-            Encode24((uint)(n >> 32), bs[4..]);
-        }
-#endif
-
         private static int EncodePoint(ref PointAccum p, byte[] r, int rOff)
         {
 #if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER
@@ -1299,25 +1191,25 @@ namespace Org.BouncyCastle.Math.EC.Rfc8032
 #if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER
             ReduceScalar(n, r);
 #else
-            long x00 = Decode32(n,  0) & M32L;          // x00:32/--
-            long x01 = (Decode24(n, 4) << 4) & M32L;    // x01:28/--
-            long x02 = Decode32(n,  7) & M32L;          // x02:32/--
-            long x03 = (Decode24(n, 11) << 4) & M32L;   // x03:28/--
-            long x04 = Decode32(n, 14) & M32L;          // x04:32/--
-            long x05 = (Decode24(n, 18) << 4) & M32L;   // x05:28/--
-            long x06 = Decode32(n, 21) & M32L;          // x06:32/--
-            long x07 = (Decode24(n, 25) << 4) & M32L;   // x07:28/--
-            long x08 = Decode32(n, 28) & M32L;          // x08:32/--
-            long x09 = (Decode24(n, 32) << 4) & M32L;   // x09:28/--
-            long x10 = Decode32(n, 35) & M32L;          // x10:32/--
-            long x11 = (Decode24(n, 39) << 4) & M32L;   // x11:28/--
-            long x12 = Decode32(n, 42) & M32L;          // x12:32/--
-            long x13 = (Decode24(n, 46) << 4) & M32L;   // x13:28/--
-            long x14 = Decode32(n, 49) & M32L;          // x14:32/--
-            long x15 = (Decode24(n, 53) << 4) & M32L;   // x15:28/--
-            long x16 = Decode32(n, 56) & M32L;          // x16:32/--
-            long x17 = (Decode24(n, 60) << 4) & M32L;   // x17:28/--
-            long x18 = n[63]                  & M08L;   // x18:08/--
+            long x00 =  Codec.Decode32(n,  0)       & M32L;         // x00:32/--
+            long x01 = (Codec.Decode24(n,  4) << 4) & M32L;         // x01:28/--
+            long x02 =  Codec.Decode32(n,  7)       & M32L;         // x02:32/--
+            long x03 = (Codec.Decode24(n, 11) << 4) & M32L;         // x03:28/--
+            long x04 =  Codec.Decode32(n, 14)       & M32L;         // x04:32/--
+            long x05 = (Codec.Decode24(n, 18) << 4) & M32L;         // x05:28/--
+            long x06 =  Codec.Decode32(n, 21)       & M32L;         // x06:32/--
+            long x07 = (Codec.Decode24(n, 25) << 4) & M32L;         // x07:28/--
+            long x08 =  Codec.Decode32(n, 28)       & M32L;         // x08:32/--
+            long x09 = (Codec.Decode24(n, 32) << 4) & M32L;         // x09:28/--
+            long x10 =  Codec.Decode32(n, 35)       & M32L;         // x10:32/--
+            long x11 = (Codec.Decode24(n, 39) << 4) & M32L;         // x11:28/--
+            long x12 =  Codec.Decode32(n, 42)       & M32L;         // x12:32/--
+            long x13 = (Codec.Decode24(n, 46) << 4) & M32L;         // x13:28/--
+            long x14 =  Codec.Decode32(n, 49)       & M32L;         // x14:32/--
+            long x15 = (Codec.Decode24(n, 53) << 4) & M32L;         // x15:28/--
+            long x16 =  Codec.Decode32(n, 56)       & M32L;         // x16:32/--
+            long x17 = (Codec.Decode24(n, 60) << 4) & M32L;         // x17:28/--
+            long x18 =                 n[63]        & M08L;         // x18:08/--
             long t;
 
             //x18 += (x17 >> 28); x17 &= M28L;
@@ -1424,11 +1316,11 @@ namespace Org.BouncyCastle.Math.EC.Rfc8032
             x07 += (x06 >> 28); x06 &= M28L;
             x08 += (x07 >> 28); x07 &= M28L;
 
-            Encode56((ulong)(x00 | (x01 << 28)), r, 0);
-            Encode56((ulong)(x02 | (x03 << 28)), r, 7);
-            Encode56((ulong)(x04 | (x05 << 28)), r, 14);
-            Encode56((ulong)(x06 | (x07 << 28)), r, 21);
-            Encode32((uint)x08, r, 28);
+            Codec.Encode56((ulong)(x00 | (x01 << 28)), r, 0);
+            Codec.Encode56((ulong)(x02 | (x03 << 28)), r, 7);
+            Codec.Encode56((ulong)(x04 | (x05 << 28)), r, 14);
+            Codec.Encode56((ulong)(x06 | (x07 << 28)), r, 21);
+            Codec.Encode32((uint)x08, r, 28);
 #endif
 
             return r;
@@ -1437,25 +1329,25 @@ namespace Org.BouncyCastle.Math.EC.Rfc8032
 #if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER
         private static void ReduceScalar(ReadOnlySpan<byte> n, Span<byte> r)
         {
-            long x00 = Decode32(n[0..]) & M32L;         // x00:32/--
-            long x01 = (Decode24(n[4..]) << 4) & M32L;  // x01:28/--
-            long x02 = Decode32(n[7..]) & M32L;         // x02:32/--
-            long x03 = (Decode24(n[11..]) << 4) & M32L; // x03:28/--
-            long x04 = Decode32(n[14..]) & M32L;        // x04:32/--
-            long x05 = (Decode24(n[18..]) << 4) & M32L; // x05:28/--
-            long x06 = Decode32(n[21..]) & M32L;        // x06:32/--
-            long x07 = (Decode24(n[25..]) << 4) & M32L; // x07:28/--
-            long x08 = Decode32(n[28..]) & M32L;        // x08:32/--
-            long x09 = (Decode24(n[32..]) << 4) & M32L; // x09:28/--
-            long x10 = Decode32(n[35..]) & M32L;        // x10:32/--
-            long x11 = (Decode24(n[39..]) << 4) & M32L; // x11:28/--
-            long x12 = Decode32(n[42..]) & M32L;        // x12:32/--
-            long x13 = (Decode24(n[46..]) << 4) & M32L; // x13:28/--
-            long x14 = Decode32(n[49..]) & M32L;        // x14:32/--
-            long x15 = (Decode24(n[53..]) << 4) & M32L; // x15:28/--
-            long x16 = Decode32(n[56..]) & M32L;        // x16:32/--
-            long x17 = (Decode24(n[60..]) << 4) & M32L; // x17:28/--
-            long x18 = n[63]                  & M08L;   // x18:08/--
+            long x00 =  Codec.Decode32(n[ 0..])       & M32L;       // x00:32/--
+            long x01 = (Codec.Decode24(n[ 4..]) << 4) & M32L;       // x01:28/--
+            long x02 =  Codec.Decode32(n[ 7..])       & M32L;       // x02:32/--
+            long x03 = (Codec.Decode24(n[11..]) << 4) & M32L;       // x03:28/--
+            long x04 =  Codec.Decode32(n[14..])       & M32L;       // x04:32/--
+            long x05 = (Codec.Decode24(n[18..]) << 4) & M32L;       // x05:28/--
+            long x06 =  Codec.Decode32(n[21..])       & M32L;       // x06:32/--
+            long x07 = (Codec.Decode24(n[25..]) << 4) & M32L;       // x07:28/--
+            long x08 =  Codec.Decode32(n[28..])       & M32L;       // x08:32/--
+            long x09 = (Codec.Decode24(n[32..]) << 4) & M32L;       // x09:28/--
+            long x10 =  Codec.Decode32(n[35..])       & M32L;       // x10:32/--
+            long x11 = (Codec.Decode24(n[39..]) << 4) & M32L;       // x11:28/--
+            long x12 =  Codec.Decode32(n[42..])       & M32L;       // x12:32/--
+            long x13 = (Codec.Decode24(n[46..]) << 4) & M32L;       // x13:28/--
+            long x14 =  Codec.Decode32(n[49..])       & M32L;       // x14:32/--
+            long x15 = (Codec.Decode24(n[53..]) << 4) & M32L;       // x15:28/--
+            long x16 =  Codec.Decode32(n[56..])       & M32L;       // x16:32/--
+            long x17 = (Codec.Decode24(n[60..]) << 4) & M32L;       // x17:28/--
+            long x18 =                 n[63]          & M08L;       // x18:08/--
             long t;
 
             //x18 += (x17 >> 28); x17 &= M28L;
@@ -1562,11 +1454,11 @@ namespace Org.BouncyCastle.Math.EC.Rfc8032
             x07 += (x06 >> 28); x06 &= M28L;
             x08 += (x07 >> 28); x07 &= M28L;
 
-            Encode56((ulong)(x00 | (x01 << 28)), r);
-            Encode56((ulong)(x02 | (x03 << 28)), r[7..]);
-            Encode56((ulong)(x04 | (x05 << 28)), r[14..]);
-            Encode56((ulong)(x06 | (x07 << 28)), r[21..]);
-            Encode32((uint)x08, r[28..]);
+            Codec.Encode56((ulong)(x00 | (x01 << 28)), r);
+            Codec.Encode56((ulong)(x02 | (x03 << 28)), r[7..]);
+            Codec.Encode56((ulong)(x04 | (x05 << 28)), r[14..]);
+            Codec.Encode56((ulong)(x06 | (x07 << 28)), r[21..]);
+            Codec.Encode32((uint)x08, r[28..]);
         }
 #endif
 
@@ -1857,10 +1749,8 @@ namespace Org.BouncyCastle.Math.EC.Rfc8032
                 int wp = ws_p[bit];
                 if (wp != 0)
                 {
-                    int sign = wp >> 31;
-                    int index = (wp >> 1) ^ sign;
-
-                    PointAddVar(sign != 0, ref tp[index], ref r, ref t);
+                    int index = (wp >> 1) ^ (wp >> 31);
+                    PointAddVar(wp < 0, ref tp[index], ref r, ref t);
                 }
 
                 if (--bit < 0)
@@ -1908,19 +1798,15 @@ namespace Org.BouncyCastle.Math.EC.Rfc8032
                 int wb = ws_b[bit];
                 if (wb != 0)
                 {
-                    int sign = wb >> 31;
-                    int index = (wb >> 1) ^ sign;
-
-                    PointAddVar(sign != 0, ref PrecompBaseWnaf[index], ref r, ref t);
+                    int index = (wb >> 1) ^ (wb >> 31);
+                    PointAddVar(wb < 0, ref PrecompBaseWnaf[index], ref r, ref t);
                 }
 
                 int wp = ws_p[bit];
                 if (wp != 0)
                 {
-                    int sign = wp >> 31;
-                    int index = (wp >> 1) ^ sign;
-
-                    PointAddVar(sign != 0, ref tp[index], ref r, ref t);
+                    int index = (wp >> 1) ^ (wp >> 31);
+                    PointAddVar(wp < 0, ref tp[index], ref r, ref t);
                 }
 
                 if (--bit < 0)
diff --git a/crypto/src/math/ec/rfc8032/Ed448.cs b/crypto/src/math/ec/rfc8032/Ed448.cs
index 6d0bc5c7d..7baa221a5 100644
--- a/crypto/src/math/ec/rfc8032/Ed448.cs
+++ b/crypto/src/math/ec/rfc8032/Ed448.cs
@@ -1,7 +1,4 @@
 using System;
-#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER
-using System.Buffers.Binary;
-#endif
 using System.Diagnostics;
 
 using Org.BouncyCastle.Crypto;
@@ -127,7 +124,7 @@ namespace Org.BouncyCastle.Math.EC.Rfc8032
             byte[] result = new byte[ScalarBytes * 2];
             for (int i = 0; i < t.Length; ++i)
             {
-                Encode32(t[i], result, i * 4);
+                Codec.Encode32(t[i], result, i * 4);
             }
             return ReduceScalar(result);
         }
@@ -182,13 +179,13 @@ namespace Org.BouncyCastle.Math.EC.Rfc8032
         {
             if ((p[PointBytes - 1] & 0x7F) != 0x00)
                 return false;
-            if (Decode32(p[52..]) < P[13])
+            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 (Decode32(p[(i * 4)..]) < P[i])
+                if (Codec.Decode32(p[(i * 4)..]) < P[i])
                     return true;
             }
             return false;
@@ -207,13 +204,13 @@ namespace Org.BouncyCastle.Math.EC.Rfc8032
         {
             if ((p[PointBytes - 1] & 0x7F) != 0x00)
                 return false;
-            if (Decode32(p, 52) < P[13])
+            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 (Decode32(p, i * 4) < P[i])
+                if (Codec.Decode32(p, i * 4) < P[i])
                     return true;
             }
             return false;
@@ -246,80 +243,6 @@ namespace Org.BouncyCastle.Math.EC.Rfc8032
             return new ShakeDigest(256);
         }
 
-        private static uint Decode16(byte[] bs, int off)
-        {
-#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER
-            return BinaryPrimitives.ReadUInt16LittleEndian(bs.AsSpan(off));
-#else
-            uint n = bs[off];
-            n |= (uint)bs[++off] << 8;
-            return n;
-#endif
-        }
-
-#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER
-        private static uint Decode16(ReadOnlySpan<byte> bs)
-        {
-            return BinaryPrimitives.ReadUInt16LittleEndian(bs);
-        }
-#endif
-
-        private static uint Decode24(byte[] bs, int off)
-        {
-            uint n = bs[off];
-            n |= (uint)bs[++off] << 8;
-            n |= (uint)bs[++off] << 16;
-            return n;
-        }
-
-#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER
-        private static uint Decode24(ReadOnlySpan<byte> bs)
-        {
-            uint n = bs[0];
-            n |= (uint)bs[1] << 8;
-            n |= (uint)bs[2] << 16;
-            return n;
-        }
-#endif
-
-        private static uint Decode32(byte[] bs, int off)
-        {
-#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER
-            return BinaryPrimitives.ReadUInt32LittleEndian(bs.AsSpan(off));
-#else
-            uint n = bs[off];
-            n |= (uint)bs[++off] << 8;
-            n |= (uint)bs[++off] << 16;
-            n |= (uint)bs[++off] << 24;
-            return n;
-#endif
-        }
-
-#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER
-        private static uint Decode32(ReadOnlySpan<byte> bs)
-        {
-            return BinaryPrimitives.ReadUInt32LittleEndian(bs);
-        }
-#endif
-
-        private static void Decode32(byte[] bs, int bsOff, uint[] n, int nOff, int nLen)
-        {
-            for (int i = 0; i < nLen; ++i)
-            {
-                n[nOff + i] = Decode32(bs, bsOff + i * 4);
-            }
-        }
-
-#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER
-        private static void Decode32(ReadOnlySpan<byte> bs, Span<uint> n)
-        {
-            for (int i = 0; i < n.Length; ++i)
-            {
-                n[i] = Decode32(bs[(i * 4)..]);
-            }
-        }
-#endif
-
         private static bool DecodePointVar(byte[] p, int pOff, bool negate, ref PointProjective r)
         {
             byte[] py = Copy(p, pOff, PointBytes);
@@ -360,7 +283,7 @@ namespace Org.BouncyCastle.Math.EC.Rfc8032
         {
             Debug.Assert(k[kOff + ScalarBytes - 1] == 0x00);
 
-            Decode32(k, kOff, n, 0, ScalarUints);
+            Codec.Decode32(k, kOff, n, 0, ScalarUints);
         }
 
 #if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER
@@ -368,7 +291,7 @@ namespace Org.BouncyCastle.Math.EC.Rfc8032
         {
             Debug.Assert(k[ScalarBytes - 1] == 0x00);
 
-            Decode32(k, n[..ScalarUints]);
+            Codec.Decode32(k, n[..ScalarUints]);
         }
 #endif
 
@@ -384,55 +307,6 @@ namespace Org.BouncyCastle.Math.EC.Rfc8032
             d.BlockUpdate(t, 0, t.Length);
         }
 
-        private static void Encode24(uint n, byte[] bs, int off)
-        {
-            bs[off] = (byte)(n);
-            bs[++off] = (byte)(n >> 8);
-            bs[++off] = (byte)(n >> 16);
-        }
-
-#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER
-        private static void Encode24(uint n, Span<byte> bs)
-        {
-            bs[0] = (byte)(n);
-            bs[1] = (byte)(n >> 8);
-            bs[2] = (byte)(n >> 16);
-        }
-#endif
-
-        private static void Encode32(uint n, byte[] bs, int off)
-        {
-#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER
-            BinaryPrimitives.WriteUInt32LittleEndian(bs.AsSpan(off), n);
-#else
-            bs[  off] = (byte)(n      );
-            bs[++off] = (byte)(n >>  8);
-            bs[++off] = (byte)(n >> 16);
-            bs[++off] = (byte)(n >> 24);
-#endif
-        }
-
-#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER
-        private static void Encode32(uint n, Span<byte> bs)
-        {
-            BinaryPrimitives.WriteUInt32LittleEndian(bs, n);
-        }
-#endif
-
-        private static void Encode56(ulong n, byte[] bs, int off)
-        {
-            Encode32((uint)n, bs, off);
-            Encode24((uint)(n >> 32), bs, off + 4);
-        }
-
-#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER
-        private static void Encode56(ulong n, Span<byte> bs)
-        {
-            Encode32((uint)n, bs);
-            Encode24((uint)(n >> 32), bs[4..]);
-        }
-#endif
-
         private static int EncodePoint(ref PointProjective p, byte[] r, int rOff)
         {
             uint[] x = F.Create();
@@ -1196,39 +1070,39 @@ namespace Org.BouncyCastle.Math.EC.Rfc8032
 #if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER
             ReduceScalar(n, r);
 #else
-            ulong x00 =  Decode32(n,   0);              // x00:32/--
-            ulong x01 = (Decode24(n,   4) << 4);        // x01:28/--
-            ulong x02 =  Decode32(n,   7);              // x02:32/--
-            ulong x03 = (Decode24(n,  11) << 4);        // x03:28/--
-            ulong x04 =  Decode32(n,  14);              // x04:32/--
-            ulong x05 = (Decode24(n,  18) << 4);        // x05:28/--
-            ulong x06 =  Decode32(n,  21);              // x06:32/--
-            ulong x07 = (Decode24(n,  25) << 4);        // x07:28/--
-            ulong x08 =  Decode32(n,  28);              // x08:32/--
-            ulong x09 = (Decode24(n,  32) << 4);        // x09:28/--
-            ulong x10 =  Decode32(n,  35);              // x10:32/--
-            ulong x11 = (Decode24(n,  39) << 4);        // x11:28/--
-            ulong x12 =  Decode32(n,  42);              // x12:32/--
-            ulong x13 = (Decode24(n,  46) << 4);        // x13:28/--
-            ulong x14 =  Decode32(n,  49);              // x14:32/--
-            ulong x15 = (Decode24(n,  53) << 4);        // x15:28/--
-            ulong x16 =  Decode32(n,  56);              // x16:32/--
-            ulong x17 = (Decode24(n,  60) << 4);        // x17:28/--
-            ulong x18 =  Decode32(n,  63);              // x18:32/--
-            ulong x19 = (Decode24(n,  67) << 4);        // x19:28/--
-            ulong x20 =  Decode32(n,  70);              // x20:32/--
-            ulong x21 = (Decode24(n,  74) << 4);        // x21:28/--
-            ulong x22 =  Decode32(n,  77);              // x22:32/--
-            ulong x23 = (Decode24(n,  81) << 4);        // x23:28/--
-            ulong x24 =  Decode32(n,  84);              // x24:32/--
-            ulong x25 = (Decode24(n,  88) << 4);        // x25:28/--
-            ulong x26 =  Decode32(n,  91);              // x26:32/--
-            ulong x27 = (Decode24(n,  95) << 4);        // x27:28/--
-            ulong x28 =  Decode32(n,  98);              // x28:32/--
-            ulong x29 = (Decode24(n, 102) << 4);        // x29:28/--
-            ulong x30 =  Decode32(n, 105);              // x30:32/--
-            ulong x31 = (Decode24(n, 109) << 4);        // x31:28/--
-            ulong x32 =  Decode16(n, 112);              // x32:16/--
+            ulong x00 =  Codec.Decode32(n,   0);                // x00:32/--
+            ulong x01 = (Codec.Decode24(n,   4) << 4);          // x01:28/--
+            ulong x02 =  Codec.Decode32(n,   7);                // x02:32/--
+            ulong x03 = (Codec.Decode24(n,  11) << 4);          // x03:28/--
+            ulong x04 =  Codec.Decode32(n,  14);                // x04:32/--
+            ulong x05 = (Codec.Decode24(n,  18) << 4);          // x05:28/--
+            ulong x06 =  Codec.Decode32(n,  21);                // x06:32/--
+            ulong x07 = (Codec.Decode24(n,  25) << 4);          // x07:28/--
+            ulong x08 =  Codec.Decode32(n,  28);                // x08:32/--
+            ulong x09 = (Codec.Decode24(n,  32) << 4);          // x09:28/--
+            ulong x10 =  Codec.Decode32(n,  35);                // x10:32/--
+            ulong x11 = (Codec.Decode24(n,  39) << 4);          // x11:28/--
+            ulong x12 =  Codec.Decode32(n,  42);                // x12:32/--
+            ulong x13 = (Codec.Decode24(n,  46) << 4);          // x13:28/--
+            ulong x14 =  Codec.Decode32(n,  49);                // x14:32/--
+            ulong x15 = (Codec.Decode24(n,  53) << 4);          // x15:28/--
+            ulong x16 =  Codec.Decode32(n,  56);                // x16:32/--
+            ulong x17 = (Codec.Decode24(n,  60) << 4);          // x17:28/--
+            ulong x18 =  Codec.Decode32(n,  63);                // x18:32/--
+            ulong x19 = (Codec.Decode24(n,  67) << 4);          // x19:28/--
+            ulong x20 =  Codec.Decode32(n,  70);                // x20:32/--
+            ulong x21 = (Codec.Decode24(n,  74) << 4);          // x21:28/--
+            ulong x22 =  Codec.Decode32(n,  77);                // x22:32/--
+            ulong x23 = (Codec.Decode24(n,  81) << 4);          // x23:28/--
+            ulong x24 =  Codec.Decode32(n,  84);                // x24:32/--
+            ulong x25 = (Codec.Decode24(n,  88) << 4);          // x25:28/--
+            ulong x26 =  Codec.Decode32(n,  91);                // x26:32/--
+            ulong x27 = (Codec.Decode24(n,  95) << 4);          // x27:28/--
+            ulong x28 =  Codec.Decode32(n,  98);                // x28:32/--
+            ulong x29 = (Codec.Decode24(n, 102) << 4);          // x29:28/--
+            ulong x30 =  Codec.Decode32(n, 105);                // x30:32/--
+            ulong x31 = (Codec.Decode24(n, 109) << 4);          // x31:28/--
+            ulong x32 =  Codec.Decode16(n, 112);                // x32:16/--
 
             //x32 += (x31 >> 28); x31 &= M28UL;
             x16 += x32 * L4_0;                          // x16:42/--
@@ -1458,14 +1332,14 @@ namespace Org.BouncyCastle.Math.EC.Rfc8032
 
             Debug.Assert(x15 >> 26 == 0UL);
 
-            Encode56(x00 | (x01 << 28), r,  0);
-            Encode56(x02 | (x03 << 28), r,  7);
-            Encode56(x04 | (x05 << 28), r, 14);
-            Encode56(x06 | (x07 << 28), r, 21);
-            Encode56(x08 | (x09 << 28), r, 28);
-            Encode56(x10 | (x11 << 28), r, 35);
-            Encode56(x12 | (x13 << 28), r, 42);
-            Encode56(x14 | (x15 << 28), r, 49);
+            Codec.Encode56(x00 | (x01 << 28), r,  0);
+            Codec.Encode56(x02 | (x03 << 28), r,  7);
+            Codec.Encode56(x04 | (x05 << 28), r, 14);
+            Codec.Encode56(x06 | (x07 << 28), r, 21);
+            Codec.Encode56(x08 | (x09 << 28), r, 28);
+            Codec.Encode56(x10 | (x11 << 28), r, 35);
+            Codec.Encode56(x12 | (x13 << 28), r, 42);
+            Codec.Encode56(x14 | (x15 << 28), r, 49);
             //r[ScalarBytes - 1] = 0;
 #endif
 
@@ -1475,39 +1349,39 @@ namespace Org.BouncyCastle.Math.EC.Rfc8032
 #if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER
         private static void ReduceScalar(ReadOnlySpan<byte> n, Span<byte> r)
         {
-            ulong x00 =  Decode32(n[ 0..]);             // x00:32/--
-            ulong x01 = (Decode24(n[ 4..]) << 4);       // x01:28/--
-            ulong x02 =  Decode32(n[ 7..]);             // x02:32/--
-            ulong x03 = (Decode24(n[11..]) << 4);       // x03:28/--
-            ulong x04 =  Decode32(n[14..]);             // x04:32/--
-            ulong x05 = (Decode24(n[18..]) << 4);       // x05:28/--
-            ulong x06 =  Decode32(n[21..]);             // x06:32/--
-            ulong x07 = (Decode24(n[25..]) << 4);       // x07:28/--
-            ulong x08 =  Decode32(n[28..]);             // x08:32/--
-            ulong x09 = (Decode24(n[32..]) << 4);       // x09:28/--
-            ulong x10 =  Decode32(n[35..]);             // x10:32/--
-            ulong x11 = (Decode24(n[39..]) << 4);       // x11:28/--
-            ulong x12 =  Decode32(n[42..]);             // x12:32/--
-            ulong x13 = (Decode24(n[46..]) << 4);       // x13:28/--
-            ulong x14 =  Decode32(n[49..]);             // x14:32/--
-            ulong x15 = (Decode24(n[53..]) << 4);       // x15:28/--
-            ulong x16 =  Decode32(n[56..]);             // x16:32/--
-            ulong x17 = (Decode24(n[60..]) << 4);       // x17:28/--
-            ulong x18 =  Decode32(n[63..]);             // x18:32/--
-            ulong x19 = (Decode24(n[67..]) << 4);       // x19:28/--
-            ulong x20 =  Decode32(n[70..]);             // x20:32/--
-            ulong x21 = (Decode24(n[74..]) << 4);       // x21:28/--
-            ulong x22 =  Decode32(n[77..]);             // x22:32/--
-            ulong x23 = (Decode24(n[81..]) << 4);       // x23:28/--
-            ulong x24 =  Decode32(n[84..]);             // x24:32/--
-            ulong x25 = (Decode24(n[88..]) << 4);       // x25:28/--
-            ulong x26 =  Decode32(n[91..]);             // x26:32/--
-            ulong x27 = (Decode24(n[95..]) << 4);       // x27:28/--
-            ulong x28 =  Decode32(n[98..]);             // x28:32/--
-            ulong x29 = (Decode24(n[102..]) << 4);      // x29:28/--
-            ulong x30 =  Decode32(n[105..]);            // x30:32/--
-            ulong x31 = (Decode24(n[109..]) << 4);      // x31:28/--
-            ulong x32 =  Decode16(n[112..]);            // x32:16/--
+            ulong x00 =  Codec.Decode32(n[  0..]);              // x00:32/--
+            ulong x01 = (Codec.Decode24(n[  4..]) << 4);        // x01:28/--
+            ulong x02 =  Codec.Decode32(n[  7..]);              // x02:32/--
+            ulong x03 = (Codec.Decode24(n[ 11..]) << 4);        // x03:28/--
+            ulong x04 =  Codec.Decode32(n[ 14..]);              // x04:32/--
+            ulong x05 = (Codec.Decode24(n[ 18..]) << 4);        // x05:28/--
+            ulong x06 =  Codec.Decode32(n[ 21..]);              // x06:32/--
+            ulong x07 = (Codec.Decode24(n[ 25..]) << 4);        // x07:28/--
+            ulong x08 =  Codec.Decode32(n[ 28..]);              // x08:32/--
+            ulong x09 = (Codec.Decode24(n[ 32..]) << 4);        // x09:28/--
+            ulong x10 =  Codec.Decode32(n[ 35..]);              // x10:32/--
+            ulong x11 = (Codec.Decode24(n[ 39..]) << 4);        // x11:28/--
+            ulong x12 =  Codec.Decode32(n[ 42..]);              // x12:32/--
+            ulong x13 = (Codec.Decode24(n[ 46..]) << 4);        // x13:28/--
+            ulong x14 =  Codec.Decode32(n[ 49..]);              // x14:32/--
+            ulong x15 = (Codec.Decode24(n[ 53..]) << 4);        // x15:28/--
+            ulong x16 =  Codec.Decode32(n[ 56..]);              // x16:32/--
+            ulong x17 = (Codec.Decode24(n[ 60..]) << 4);        // x17:28/--
+            ulong x18 =  Codec.Decode32(n[ 63..]);              // x18:32/--
+            ulong x19 = (Codec.Decode24(n[ 67..]) << 4);        // x19:28/--
+            ulong x20 =  Codec.Decode32(n[ 70..]);              // x20:32/--
+            ulong x21 = (Codec.Decode24(n[ 74..]) << 4);        // x21:28/--
+            ulong x22 =  Codec.Decode32(n[ 77..]);              // x22:32/--
+            ulong x23 = (Codec.Decode24(n[ 81..]) << 4);        // x23:28/--
+            ulong x24 =  Codec.Decode32(n[ 84..]);              // x24:32/--
+            ulong x25 = (Codec.Decode24(n[ 88..]) << 4);        // x25:28/--
+            ulong x26 =  Codec.Decode32(n[ 91..]);              // x26:32/--
+            ulong x27 = (Codec.Decode24(n[ 95..]) << 4);        // x27:28/--
+            ulong x28 =  Codec.Decode32(n[ 98..]);              // x28:32/--
+            ulong x29 = (Codec.Decode24(n[102..]) << 4);        // x29:28/--
+            ulong x30 =  Codec.Decode32(n[105..]);              // x30:32/--
+            ulong x31 = (Codec.Decode24(n[109..]) << 4);        // x31:28/--
+            ulong x32 =  Codec.Decode16(n[112..]);              // x32:16/--
 
             //x32 += (x31 >> 28); x31 &= M28UL;
             x16 += x32 * L4_0;                          // x16:42/--
@@ -1737,15 +1611,15 @@ namespace Org.BouncyCastle.Math.EC.Rfc8032
 
             Debug.Assert(x15 >> 26 == 0UL);
 
-            Encode56(x00 | (x01 << 28), r);
-            Encode56(x02 | (x03 << 28), r[7..]);
-            Encode56(x04 | (x05 << 28), r[14..]);
-            Encode56(x06 | (x07 << 28), r[21..]);
-            Encode56(x08 | (x09 << 28), r[28..]);
-            Encode56(x10 | (x11 << 28), r[35..]);
-            Encode56(x12 | (x13 << 28), r[42..]);
-            Encode56(x14 | (x15 << 28), r[49..]);
-            //r[ScalarBytes - 1] = 0;
+            Codec.Encode56(x00 | (x01 << 28), r);
+            Codec.Encode56(x02 | (x03 << 28), r[7..]);
+            Codec.Encode56(x04 | (x05 << 28), r[14..]);
+            Codec.Encode56(x06 | (x07 << 28), r[21..]);
+            Codec.Encode56(x08 | (x09 << 28), r[28..]);
+            Codec.Encode56(x10 | (x11 << 28), r[35..]);
+            Codec.Encode56(x12 | (x13 << 28), r[42..]);
+            Codec.Encode56(x14 | (x15 << 28), r[49..]);
+            r[ScalarBytes - 1] = 0;
         }
 #endif
 
@@ -2035,10 +1909,8 @@ namespace Org.BouncyCastle.Math.EC.Rfc8032
                 int wp = ws_p[bit];
                 if (wp != 0)
                 {
-                    int sign = wp >> 31;
-                    int index = (wp >> 1) ^ sign;
-
-                    PointAddVar(sign != 0, ref tp[index], ref r);
+                    int index = (wp >> 1) ^ (wp >> 31);
+                    PointAddVar(wp < 0, ref tp[index], ref r);
                 }
 
                 if (--bit < 0)
@@ -2085,19 +1957,15 @@ namespace Org.BouncyCastle.Math.EC.Rfc8032
                 int wb = ws_b[bit];
                 if (wb != 0)
                 {
-                    int sign = wb >> 31;
-                    int index = (wb >> 1) ^ sign;
-
-                    PointAddVar(sign != 0, ref PrecompBaseWnaf[index], ref r);
+                    int index = (wb >> 1) ^ (wb >> 31);
+                    PointAddVar(wb < 0, ref PrecompBaseWnaf[index], ref r);
                 }
 
                 int wp = ws_p[bit];
                 if (wp != 0)
                 {
-                    int sign = wp >> 31;
-                    int index = (wp >> 1) ^ sign;
-
-                    PointAddVar(sign != 0, ref tp[index], ref r);
+                    int index = (wp >> 1) ^ (wp >> 31);
+                    PointAddVar(wp < 0, ref tp[index], ref r);
                 }
 
                 if (--bit < 0)