Browse Source

Use half-trace when possible (odd m) for decompression/validation

- provide field-specific half-trace methods for custom curves
Ugochukwu Mmaduekwe 6 years ago
parent
commit
00612641a3

+ 1 - 0
CryptoLib/src/Interfaces/ClpIECC.pas

@@ -118,6 +118,7 @@ type
 
 
     function Trace(): Int32;
     function Trace(): Int32;
     function HalfTrace(): IECFieldElement;
     function HalfTrace(): IECFieldElement;
+    function HasFastTrace(): Boolean;
   end;
   end;
 
 
 type
 type

+ 41 - 11
CryptoLib/src/Math/EC/ClpECC.pas

@@ -260,6 +260,7 @@ type
   public
   public
     function Trace(): Int32; virtual;
     function Trace(): Int32; virtual;
     function HalfTrace(): IECFieldElement; virtual;
     function HalfTrace(): IECFieldElement; virtual;
+    function HasFastTrace(): Boolean; virtual;
 
 
   end;
   end;
 
 
@@ -2434,7 +2435,7 @@ end;
 function TAbstractF2mFieldElement.HalfTrace: IECFieldElement;
 function TAbstractF2mFieldElement.HalfTrace: IECFieldElement;
 var
 var
   m, i: Int32;
   m, i: Int32;
-  fe, ht: IECFieldElement;
+  ht: IECFieldElement;
 begin
 begin
   m := FieldSize;
   m := FieldSize;
   if ((m and 1) = 0) then
   if ((m and 1) = 0) then
@@ -2442,33 +2443,35 @@ begin
     raise EArgumentCryptoLibException.CreateRes(@SHalfTraceUndefinedForM);
     raise EArgumentCryptoLibException.CreateRes(@SHalfTraceUndefinedForM);
   end;
   end;
 
 
-  fe := Self as IECFieldElement;
-  ht := fe;
+  ht := Self as IECFieldElement;
   i := 2;
   i := 2;
   while i < m do
   while i < m do
   begin
   begin
-    fe := fe.SquarePow(2);
-    ht := ht.Add(fe);
+    ht := ht.SquarePow(2).Add(Self as IECFieldElement);
     System.Inc(i, 2);
     System.Inc(i, 2);
   end;
   end;
 
 
   result := ht;
   result := ht;
 end;
 end;
 
 
+function TAbstractF2mFieldElement.HasFastTrace: Boolean;
+begin
+  result := false;
+
+end;
+
 function TAbstractF2mFieldElement.Trace: Int32;
 function TAbstractF2mFieldElement.Trace: Int32;
 var
 var
   m, i: Int32;
   m, i: Int32;
-  fe, tr: IECFieldElement;
+  tr: IECFieldElement;
 begin
 begin
   m := FieldSize;
   m := FieldSize;
-  fe := Self as IECFieldElement;
-  tr := fe;
+  tr := Self as IECFieldElement;
 
 
   i := 1;
   i := 1;
   while i < m do
   while i < m do
   begin
   begin
-    fe := fe.Square();
-    tr := tr.Add(fe);
+    tr := tr.Square().Add(Self as IECFieldElement);
     System.Inc(i);
     System.Inc(i);
   end;
   end;
 
 
@@ -3372,9 +3375,36 @@ end;
 function TAbstractF2mCurve.SolveQuadraticEquation(const beta: IECFieldElement)
 function TAbstractF2mCurve.SolveQuadraticEquation(const beta: IECFieldElement)
   : IECFieldElement;
   : IECFieldElement;
 var
 var
-  gamma, z, zeroElement, t, w, w2: IECFieldElement;
+  gamma, z, zeroElement, t, w, w2, r: IECFieldElement;
+  betaF2m: IAbstractF2mFieldElement;
   m, i: Int32;
   m, i: Int32;
+  fastTrace: Boolean;
 begin
 begin
+
+  betaF2m := beta as IAbstractF2mFieldElement;
+
+  fastTrace := betaF2m.HasFastTrace();
+  if ((fastTrace) and (betaF2m.Trace() <> 0)) then
+  begin
+    result := Nil;
+    Exit;
+  end;
+
+  m := FieldSize;
+
+  // For odd m, use the half-trace
+  if ((m and 1) <> 0) then
+  begin
+    r := betaF2m.HalfTrace();
+    if ((fastTrace) or (r.Square().Add(r).Add(beta).IsZero)) then
+    begin
+      result := r;
+      Exit;
+    end;
+    result := Nil;
+    Exit;
+  end;
+
   if (beta.IsZero) then
   if (beta.IsZero) then
   begin
   begin
     result := beta;
     result := beta;

+ 54 - 0
CryptoLib/src/Math/EC/Custom/Sec/ClpSecT283Custom.pas

@@ -63,6 +63,8 @@ type
     class procedure ImplSquare(const x, zz: TCryptoLibUInt64Array);
     class procedure ImplSquare(const x, zz: TCryptoLibUInt64Array);
       static; inline;
       static; inline;
 
 
+    class procedure AddTo(const x, z: TCryptoLibUInt64Array); static; inline;
+
     class procedure Boot(); static;
     class procedure Boot(); static;
     class constructor SecT283Field();
     class constructor SecT283Field();
 
 
@@ -71,6 +73,10 @@ type
     class procedure AddExt(const xx, yy, zz: TCryptoLibUInt64Array);
     class procedure AddExt(const xx, yy, zz: TCryptoLibUInt64Array);
       static; inline;
       static; inline;
     class procedure AddOne(const x, z: TCryptoLibUInt64Array); static; inline;
     class procedure AddOne(const x, z: TCryptoLibUInt64Array); static; inline;
+
+    class procedure HalfTrace(const x, z: TCryptoLibUInt64Array);
+      static; inline;
+
     class function FromBigInteger(const x: TBigInteger): TCryptoLibUInt64Array;
     class function FromBigInteger(const x: TBigInteger): TCryptoLibUInt64Array;
       static; inline;
       static; inline;
 
 
@@ -152,6 +158,10 @@ type
 
 
     function Trace(): Int32; override;
     function Trace(): Int32; override;
 
 
+    function HalfTrace(): IECFieldElement; override;
+
+    function HasFastTrace(): Boolean; override;
+
     function Invert(): IECFieldElement; override;
     function Invert(): IECFieldElement; override;
 
 
     /// <summary>
     /// <summary>
@@ -373,6 +383,15 @@ begin
   z[4] := x[4];
   z[4] := x[4];
 end;
 end;
 
 
+class procedure TSecT283Field.AddTo(const x, z: TCryptoLibUInt64Array);
+begin
+  z[0] := z[0] xor x[0];
+  z[1] := z[1] xor x[1];
+  z[2] := z[2] xor x[2];
+  z[3] := z[3] xor x[3];
+  z[4] := z[4] xor x[4];
+end;
+
 class procedure TSecT283Field.Boot;
 class procedure TSecT283Field.Boot;
 begin
 begin
   FROOT_Z := TCryptoLibUInt64Array.Create(UInt64($0C30C30C30C30808),
   FROOT_Z := TCryptoLibUInt64Array.Create(UInt64($0C30C30C30C30808),
@@ -380,6 +399,27 @@ begin
     UInt64($0820820820820820), UInt64($2082082));
     UInt64($0820820820820820), UInt64($2082082));
 end;
 end;
 
 
+class procedure TSecT283Field.HalfTrace(const x, z: TCryptoLibUInt64Array);
+var
+  tt: TCryptoLibUInt64Array;
+  i: Int32;
+begin
+  tt := TNat.Create64(9);
+
+  TNat320.Copy64(x, z);
+  i := 1;
+
+  while i < 283 do
+  begin
+    ImplSquare(z, tt);
+    Reduce(tt, z);
+    ImplSquare(z, tt);
+    Reduce(tt, z);
+    AddTo(x, z);
+    System.Inc(i, 2);
+  end;
+end;
+
 class function TSecT283Field.FromBigInteger(const x: TBigInteger)
 class function TSecT283Field.FromBigInteger(const x: TBigInteger)
   : TCryptoLibUInt64Array;
   : TCryptoLibUInt64Array;
 var
 var
@@ -909,6 +949,20 @@ begin
   result := Fx;
   result := Fx;
 end;
 end;
 
 
+function TSecT283FieldElement.HalfTrace: IECFieldElement;
+var
+  z: TCryptoLibUInt64Array;
+begin
+  z := TNat320.Create64();
+  TSecT283Field.HalfTrace(x, z);
+  result := TSecT283FieldElement.Create(z) as ISecT283FieldElement;
+end;
+
+function TSecT283FieldElement.HasFastTrace: Boolean;
+begin
+  result := true;
+end;
+
 function TSecT283FieldElement.Invert: IECFieldElement;
 function TSecT283FieldElement.Invert: IECFieldElement;
 var
 var
   z: TCryptoLibUInt64Array;
   z: TCryptoLibUInt64Array;