summary refs log tree commit diff
diff options
context:
space:
mode:
authorPeter Dettman <peter.dettman@bouncycastle.org>2022-11-29 14:48:28 +0700
committerPeter Dettman <peter.dettman@bouncycastle.org>2022-11-29 14:48:28 +0700
commit71a8cfcb1e7679395b24962d962266a0894702f2 (patch)
tree7475aa35ccfac0732fbcad59e25baac7d4d487e6
parentKoblitz curve perf. opts. (diff)
downloadBouncyCastle.NET-ed25519-71a8cfcb1e7679395b24962d962266a0894702f2.tar.xz
sect233r1 perf. opts.
-rw-r--r--crypto/src/math/ec/custom/sec/SecT233Field.cs21
-rw-r--r--crypto/src/math/ec/custom/sec/SecT233R1Point.cs129
2 files changed, 113 insertions, 37 deletions
diff --git a/crypto/src/math/ec/custom/sec/SecT233Field.cs b/crypto/src/math/ec/custom/sec/SecT233Field.cs
index e4e291154..f2519b369 100644
--- a/crypto/src/math/ec/custom/sec/SecT233Field.cs
+++ b/crypto/src/math/ec/custom/sec/SecT233Field.cs
@@ -22,6 +22,14 @@ namespace Org.BouncyCastle.Math.EC.Custom.Sec
             z[3] = x[3] ^ y[3];
         }
 
+        public static void AddBothTo(ulong[] x, ulong[] y, ulong[] z)
+        {
+            z[0] ^= x[0] ^ y[0];
+            z[1] ^= x[1] ^ y[1];
+            z[2] ^= x[2] ^ y[2];
+            z[3] ^= x[3] ^ y[3];
+        }
+
         public static void AddExt(ulong[] xx, ulong[] yy, ulong[] zz)
         {
             zz[0] = xx[0] ^ yy[0];
@@ -42,7 +50,7 @@ namespace Org.BouncyCastle.Math.EC.Custom.Sec
             z[3] = x[3];
         }
 
-        private static void AddTo(ulong[] x, ulong[] z)
+        public static void AddTo(ulong[] x, ulong[] z)
         {
             z[0] ^= x[0];
             z[1] ^= x[1];
@@ -117,6 +125,12 @@ namespace Org.BouncyCastle.Math.EC.Custom.Sec
             AddExt(zz, tt, zz);
         }
 
+        public static void MultiplyExt(ulong[] x, ulong[] y, ulong[] zz)
+        {
+            Array.Clear(zz, 0, 8);
+            ImplMultiply(x, y, zz);
+        }
+
         public static void Reduce(ulong[] xx, ulong[] z)
         {
             ulong x0 = xx[0], x1 = xx[1], x2 = xx[2], x3 = xx[3];
@@ -196,6 +210,11 @@ namespace Org.BouncyCastle.Math.EC.Custom.Sec
             AddExt(zz, tt, zz);
         }
 
+        public static void SquareExt(ulong[] x, ulong[] zz)
+        {
+            ImplSquare(x, zz);
+        }
+
         public static void SquareN(ulong[] x, int n, ulong[] z)
         {
             Debug.Assert(n > 0);
diff --git a/crypto/src/math/ec/custom/sec/SecT233R1Point.cs b/crypto/src/math/ec/custom/sec/SecT233R1Point.cs
index 59587f0f3..44441b22a 100644
--- a/crypto/src/math/ec/custom/sec/SecT233R1Point.cs
+++ b/crypto/src/math/ec/custom/sec/SecT233R1Point.cs
@@ -1,5 +1,7 @@
 using System;
 
+using Org.BouncyCastle.Math.Raw;
+
 namespace Org.BouncyCastle.Math.EC.Custom.Sec
 {
     internal class SecT233R1Point
@@ -156,7 +158,7 @@ namespace Org.BouncyCastle.Math.EC.Custom.Sec
                 }
             }
 
-            return new SecT233R1Point(curve, X3, L3, new ECFieldElement[] { Z3 });
+            return new SecT233R1Point(curve, X3, L3, new ECFieldElement[]{ Z3 });
         }
 
         public override ECPoint Twice()
@@ -166,31 +168,61 @@ namespace Org.BouncyCastle.Math.EC.Custom.Sec
 
             ECCurve curve = this.Curve;
 
-            ECFieldElement X1 = this.RawXCoord;
+            SecT233FieldElement X1 = (SecT233FieldElement)this.RawXCoord;
             if (X1.IsZero)
             {
                 // A point with X == 0 is its own additive inverse
                 return curve.Infinity;
             }
 
-            ECFieldElement L1 = this.RawYCoord, Z1 = this.RawZCoords[0];
+            SecT233FieldElement L1 = (SecT233FieldElement)this.RawYCoord, Z1 = (SecT233FieldElement)this.RawZCoords[0];
+
+            ulong[] tt0 = Nat256.CreateExt64();
+            ulong[] _X3 = Nat256.Create64();
+            ulong[] _L3 = Nat256.Create64();
+            ulong[] _Z3 = Nat256.Create64();
 
             bool Z1IsOne = Z1.IsOne;
-            ECFieldElement L1Z1 = Z1IsOne ? L1 : L1.Multiply(Z1);
-            ECFieldElement Z1Sq = Z1IsOne ? Z1 : Z1.Square();
-            ECFieldElement T = L1.Square().Add(L1Z1).Add(Z1Sq);
-            if (T.IsZero)
+            if (Z1IsOne)
             {
-                return new SecT233R1Point(curve, T, curve.B.Sqrt());
+                SecT233Field.Square(L1.x, _Z3);
+                SecT233Field.AddBothTo(L1.x, Z1.x, _Z3);
+
+                if (Nat256.IsZero64(_Z3))
+                    return new SecT233R1Point(curve, new SecT233FieldElement(_Z3), curve.B.Sqrt());
+
+                SecT233Field.Square(_Z3, _X3);
+
+                SecT233Field.SquareExt(X1.x, tt0);
+                SecT233Field.MultiplyAddToExt(_Z3, L1.x, tt0);
             }
+            else
+            {
+                ulong[] t1 = Nat256.Create64();
+                ulong[] t2 = Nat256.Create64();
+
+                SecT233Field.Multiply(L1.x, Z1.x, t1);      // L1Z1
+                SecT233Field.Square(Z1.x, tt0);             // Z1Sq
 
-            ECFieldElement X3 = T.Square();
-            ECFieldElement Z3 = Z1IsOne ? T : T.Multiply(Z1Sq);
+                SecT233Field.Square(L1.x, t2);
+                SecT233Field.AddBothTo(t1, tt0, t2);        // T
 
-            ECFieldElement X1Z1 = Z1IsOne ? X1 : X1.Multiply(Z1);
-            ECFieldElement L3 = X1Z1.SquarePlusProduct(T, L1Z1).Add(X3).Add(Z3);
+                if (Nat256.IsZero64(t2))
+                    return new SecT233R1Point(curve, new SecT233FieldElement(t2), curve.B.Sqrt());
+
+                SecT233Field.Square(t2, _X3);
+                SecT233Field.Multiply(t2, tt0, _Z3);
+                SecT233Field.Multiply(X1.x, Z1.x, tt0);     // X1Z1
+
+                SecT233Field.SquareExt(tt0, tt0);
+                SecT233Field.MultiplyAddToExt(t2, t1, tt0);
+            }
 
-            return new SecT233R1Point(curve, X3, L3, new ECFieldElement[] { Z3 });
+            SecT233Field.Reduce(tt0, _L3);
+            SecT233Field.AddBothTo(_X3, _Z3, _L3);
+
+            return new SecT233R1Point(curve, new SecT233FieldElement(_X3), new SecT233FieldElement(_L3),
+                new ECFieldElement[]{ new SecT233FieldElement(_Z3) });
         }
 
         public override ECPoint TwicePlus(ECPoint b)
@@ -202,50 +234,75 @@ namespace Org.BouncyCastle.Math.EC.Custom.Sec
 
             ECCurve curve = this.Curve;
 
-            ECFieldElement X1 = this.RawXCoord;
+            SecT233FieldElement X1 = (SecT233FieldElement)this.RawXCoord;
             if (X1.IsZero)
             {
                 // A point with X == 0 is its own additive inverse
                 return b;
             }
 
-            ECFieldElement X2 = b.RawXCoord, Z2 = b.RawZCoords[0];
+            SecT233FieldElement X2 = (SecT233FieldElement)b.RawXCoord, Z2 = (SecT233FieldElement)b.RawZCoords[0];
             if (X2.IsZero || !Z2.IsOne)
             {
                 return Twice().Add(b);
             }
 
-            ECFieldElement L1 = this.RawYCoord, Z1 = this.RawZCoords[0];
-            ECFieldElement L2 = b.RawYCoord;
+            SecT233FieldElement L1 = (SecT233FieldElement)this.RawYCoord, Z1 = (SecT233FieldElement)this.RawZCoords[0];
+            SecT233FieldElement L2 = (SecT233FieldElement)b.RawYCoord;
 
-            ECFieldElement X1Sq = X1.Square();
-            ECFieldElement L1Sq = L1.Square();
-            ECFieldElement Z1Sq = Z1.Square();
-            ECFieldElement L1Z1 = L1.Multiply(Z1);
+            ulong[] tt0 = Nat256.CreateExt64();
+            ulong[] t1 = Nat256.Create64();
+            ulong[] t2 = Nat256.Create64();
+            ulong[] t3 = Nat256.Create64();
+            ulong[] t4 = Nat256.Create64();
+            ulong[] t5 = Nat256.Create64();
 
-            ECFieldElement T = Z1Sq.Add(L1Sq).Add(L1Z1);
-            ECFieldElement A = L2.Multiply(Z1Sq).Add(L1Sq).MultiplyPlusProduct(T, X1Sq, Z1Sq);
-            ECFieldElement X2Z1Sq = X2.Multiply(Z1Sq);
-            ECFieldElement B = X2Z1Sq.Add(T).Square();
+            SecT233Field.Square(X1.x, t1);              // X1Sq
+            SecT233Field.Square(L1.x, t2);              // L1Sq
+            SecT233Field.Square(Z1.x, t3);              // Z1Sq
+            SecT233Field.Multiply(L1.x, Z1.x, t4);      // L1Z1
 
-            if (B.IsZero)
+            SecT233Field.AddBothTo(t2, t3, t4);         // T
+
+            SecT233Field.MultiplyExt(t1, t3, tt0);
+            SecT233Field.Multiply(L2.x, t3, t1);
+            SecT233Field.AddTo(t2, t1);
+            SecT233Field.MultiplyAddToExt(t4, t1, tt0);
+            SecT233Field.Reduce(tt0, t1);               // A
+
+            SecT233Field.Multiply(X2.x, t3, t2);        // X2Z1Sq
+            SecT233Field.Add(t4, t2, t5);
+            SecT233Field.Square(t5, t5);                // B
+
+            if (Nat256.IsZero64(t5))
             {
-                if (A.IsZero)
+                if (Nat256.IsZero64(t1))
                     return b.Twice();
 
                 return curve.Infinity;
             }
 
-            if (A.IsZero)
-            {
-                return new SecT233R1Point(curve, A, curve.B.Sqrt());
-            }
+            if (Nat256.IsZero64(t1))
+                return new SecT233R1Point(curve, new SecT233FieldElement(t1), curve.B.Sqrt());
+
+            ulong[] _X3 = t2;
+            SecT233Field.Square(t1, tt0);
+            SecT233Field.Multiply(_X3, tt0, _X3);
+
+            ulong[] _Z3 = t3;
+            SecT233Field.Multiply(_Z3, t1, _Z3);
+            SecT233Field.Multiply(_Z3, t5, _Z3);
 
-            ECFieldElement X3 = A.Square().Multiply(X2Z1Sq);
-            ECFieldElement Z3 = A.Multiply(B).Multiply(Z1Sq);
-            ECFieldElement L3 = A.Add(B).Square().MultiplyPlusProduct(T, L2.AddOne(), Z3);
+            ulong[] _L3 = t1;
+            SecT233Field.AddTo(t5, _L3);
+            SecT233Field.Square(_L3, _L3);
+            SecT233Field.MultiplyExt(_L3, t4, tt0);
+            SecT233Field.MultiplyAddToExt(L2.x, _Z3, tt0);
+            SecT233Field.Reduce(tt0, _L3);
+            SecT233Field.AddTo(_Z3, _L3);
 
-            return new SecT233R1Point(curve, X3, L3, new ECFieldElement[] { Z3 });
+            return new SecT233R1Point(curve, new SecT233FieldElement(_X3), new SecT233FieldElement(_L3),
+                new ECFieldElement[]{ new SecT233FieldElement(_Z3) });
         }
 
         public override ECPoint Negate()
@@ -259,7 +316,7 @@ namespace Org.BouncyCastle.Math.EC.Custom.Sec
 
             // L is actually Lambda (X + Y/X) here
             ECFieldElement L = this.RawYCoord, Z = this.RawZCoords[0];
-            return new SecT233R1Point(Curve, X, L.Add(Z), new ECFieldElement[] { Z });
+            return new SecT233R1Point(Curve, X, L.Add(Z), new ECFieldElement[]{ Z });
         }
     }
 }