瀏覽代碼

added NistNamedCurves (aliases)

-fixed bug in "TFpFieldElement.Sqrt" that affected secp224r1 curve.
Ugochukwu Mmaduekwe 7 年之前
父節點
當前提交
4ba82bf956

+ 2 - 1
CryptoLib.Samples/Delphi.Samples/UsageSamples.dpr

@@ -410,7 +410,8 @@ uses
   ClpIDsaParametersGenerator in '..\..\CryptoLib\src\Interfaces\ClpIDsaParametersGenerator.pas',
   ClpDsaParameter in '..\..\CryptoLib\src\Asn1\X509\ClpDsaParameter.pas',
   ClpIDsaParameter in '..\..\CryptoLib\src\Interfaces\ClpIDsaParameter.pas',
-  ClpIPreCompCallBack in '..\..\CryptoLib\src\Interfaces\ClpIPreCompCallBack.pas';
+  ClpIPreCompCallBack in '..\..\CryptoLib\src\Interfaces\ClpIPreCompCallBack.pas',
+  ClpNistNamedCurves in '..\..\CryptoLib\src\Asn1\Nist\ClpNistNamedCurves.pas';
 
 begin
   try

+ 2 - 1
CryptoLib.Tests/Delphi.Tests/CryptoLib.Tests.dpr

@@ -454,7 +454,8 @@ uses
   ClpDsaParameter in '..\..\CryptoLib\src\Asn1\X509\ClpDsaParameter.pas',
   ClpIDsaParameter in '..\..\CryptoLib\src\Interfaces\ClpIDsaParameter.pas',
   ClpIPreCompCallBack in '..\..\CryptoLib\src\Interfaces\ClpIPreCompCallBack.pas',
-  DeterministicDsaTests in '..\src\Crypto\DeterministicDsaTests.pas';
+  DeterministicDsaTests in '..\src\Crypto\DeterministicDsaTests.pas',
+  ClpNistNamedCurves in '..\..\CryptoLib\src\Asn1\Nist\ClpNistNamedCurves.pas';
 
 begin
 

+ 175 - 0
CryptoLib/src/Asn1/Nist/ClpNistNamedCurves.pas

@@ -0,0 +1,175 @@
+{ *********************************************************************************** }
+{ *                              CryptoLib Library                                  * }
+{ *                Copyright (c) 2018 - 20XX Ugochukwu Mmaduekwe                    * }
+{ *                 Github Repository <https://github.com/Xor-el>                   * }
+
+{ *  Distributed under the MIT software license, see the accompanying file LICENSE  * }
+{ *          or visit http://www.opensource.org/licenses/mit-license.php.           * }
+
+{ *                              Acknowledgements:                                  * }
+{ *                                                                                 * }
+{ *      Thanks to Sphere 10 Software (http://www.sphere10.com/) for sponsoring     * }
+{ *                           development of this library                           * }
+
+{ * ******************************************************************************* * }
+
+(* &&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& *)
+
+unit ClpNistNamedCurves;
+
+{$I ..\..\Include\CryptoLib.inc}
+
+interface
+
+uses
+  SysUtils,
+  Generics.Collections,
+  ClpIX9ECParameters,
+  ClpSecNamedCurves,
+  ClpCryptoLibTypes,
+  ClpIDerObjectIdentifier,
+  ClpSecObjectIdentifiers;
+
+type
+
+  /// <summary>
+  /// Utility class for fetching curves using their NIST names as published
+  /// in FIPS-PUB 186-3
+  /// </summary>
+  TNistNamedCurves = class sealed(TObject)
+
+  strict private
+
+  class var
+    FobjIds: TDictionary<String, IDerObjectIdentifier>;
+    Fnames: TDictionary<IDerObjectIdentifier, String>;
+
+    class function GetNames: TCryptoLibStringArray; static; inline;
+
+    class procedure DefineCurveAlias(const name: String;
+      const oid: IDerObjectIdentifier); static; inline;
+
+    class constructor CreateNistNamedCurves();
+    class destructor DestroyNistNamedCurves();
+
+  public
+
+    class function GetByName(const name: String): IX9ECParameters;
+      static; inline;
+    // /**
+    // * return the X9ECParameters object for the named curve represented by
+    // * the passed in object identifier. Null if the curve isn't present.
+    // *
+    // * @param oid an object identifier representing a named curve, if present.
+    // */
+    class function GetByOid(const oid: IDerObjectIdentifier): IX9ECParameters;
+      static; inline;
+    // /**
+    // * return the object identifier signified by the passed in name. Null
+    // * if there is no object identifier associated with name.
+    // *
+    // * @return the object identifier associated with name, if present.
+    // */
+    class function GetOid(const name: String): IDerObjectIdentifier;
+      static; inline;
+    // /**
+    // * return the named curve name represented by the given object identifier.
+    // */
+    class function GetName(const oid: IDerObjectIdentifier): String;
+      static; inline;
+    // /**
+    // * returns an enumeration containing the name strings for curves
+    // * contained in this structure.
+    // */
+    class property Names: TCryptoLibStringArray read GetNames;
+
+  end;
+
+implementation
+
+{ TNistNamedCurves }
+
+class procedure TNistNamedCurves.DefineCurveAlias(const name: String;
+  const oid: IDerObjectIdentifier);
+begin
+  FobjIds.Add(UpperCase(name), oid);
+  Fnames.Add(oid, name);
+end;
+
+class function TNistNamedCurves.GetByOid(const oid: IDerObjectIdentifier)
+  : IX9ECParameters;
+begin
+  result := TSecNamedCurves.GetByOid(oid);
+end;
+
+class function TNistNamedCurves.GetOid(const name: String)
+  : IDerObjectIdentifier;
+begin
+  if not(FobjIds.TryGetValue(UpperCase(name), result)) then
+  begin
+    result := Nil;
+  end;
+end;
+
+class function TNistNamedCurves.GetByName(const name: String): IX9ECParameters;
+var
+  oid: IDerObjectIdentifier;
+begin
+  oid := GetOid(name);
+  if oid = Nil then
+  begin
+    result := Nil;
+  end
+  else
+  begin
+    result := GetByOid(oid);
+  end;
+
+end;
+
+class function TNistNamedCurves.GetName(const oid
+  : IDerObjectIdentifier): String;
+begin
+  if not(Fnames.TryGetValue(oid, result)) then
+  begin
+    result := '';
+  end;
+end;
+
+class function TNistNamedCurves.GetNames: TCryptoLibStringArray;
+begin
+  result := Fnames.Values.ToArray();
+end;
+
+class constructor TNistNamedCurves.CreateNistNamedCurves;
+begin
+  FobjIds := TDictionary<String, IDerObjectIdentifier>.Create();
+  Fnames := TDictionary<IDerObjectIdentifier, String>.Create();
+
+  DefineCurveAlias('B-163', TSecObjectIdentifiers.SecT163r2);
+  DefineCurveAlias('B-233', TSecObjectIdentifiers.SecT233r1);
+  DefineCurveAlias('B-283', TSecObjectIdentifiers.SecT283r1);
+  DefineCurveAlias('B-409', TSecObjectIdentifiers.SecT409r1);
+  DefineCurveAlias('B-571', TSecObjectIdentifiers.SecT571r1);
+
+  DefineCurveAlias('K-163', TSecObjectIdentifiers.SecT163k1);
+  DefineCurveAlias('K-233', TSecObjectIdentifiers.SecT233k1);
+  DefineCurveAlias('K-283', TSecObjectIdentifiers.SecT283k1);
+  DefineCurveAlias('K-409', TSecObjectIdentifiers.SecT409k1);
+  DefineCurveAlias('K-571', TSecObjectIdentifiers.SecT571k1);
+
+  DefineCurveAlias('P-192', TSecObjectIdentifiers.SecP192r1);
+  DefineCurveAlias('P-224', TSecObjectIdentifiers.SecP224r1);
+  DefineCurveAlias('P-256', TSecObjectIdentifiers.SecP256r1);
+  DefineCurveAlias('P-384', TSecObjectIdentifiers.SecP384r1);
+  DefineCurveAlias('P-521', TSecObjectIdentifiers.SecP521r1);
+
+end;
+
+class destructor TNistNamedCurves.DestroyNistNamedCurves;
+begin
+  FobjIds.Free;
+  Fnames.Free;
+end;
+
+end.

+ 89 - 87
CryptoLib/src/Asn1/Sec/ClpSecNamedCurves.pas

@@ -63,23 +63,28 @@ type
       const p: IGlvTypeBParameters): IECCurve; static; inline;
     class function FromHex(const Hex: String): TBigInteger; static; inline;
 
+    class constructor CreateSecNamedCurves();
+    class destructor DestroySecNamedCurves();
+
   public
-    class function GetByName(const name: String): IX9ECParameters; static;
+    class function GetByName(const name: String): IX9ECParameters;
+      static; inline;
     // /**
     // * return the X9ECParameters object for the named curve represented by
     // * the passed in object identifier. Null if the curve isn't present.
     // *
     // * @param oid an object identifier representing a named curve, if present.
     // */
-    class function GetByOid(const oid: IDerObjectIdentifier)
-      : IX9ECParameters; static;
+    class function GetByOid(const oid: IDerObjectIdentifier): IX9ECParameters;
+      static; inline;
     // /**
     // * return the object identifier signified by the passed in name. Null
     // * if there is no object identifier associated with name.
     // *
     // * @return the object identifier associated with name, if present.
     // */
-    class function GetOid(const name: String): IDerObjectIdentifier; static;
+    class function GetOid(const name: String): IDerObjectIdentifier;
+      static; inline;
     // /**
     // * return the named curve name represented by the given object identifier.
     // */
@@ -727,22 +732,98 @@ type
 
     end;
 
-  class constructor CreateSecNamedCurves();
-  class destructor DestroySecNamedCurves();
-
   end;
 
 implementation
 
 { TSecNamedCurves }
 
+class procedure TSecNamedCurves.DefineCurve(const name: String;
+  const oid: IDerObjectIdentifier; const holder: IX9ECParametersHolder);
+begin
+  FobjIds.Add(UpperCase(name), oid);
+  Fnames.Add(oid, name);
+  Fcurves.Add(oid, holder);
+end;
+
+class function TSecNamedCurves.ConfigureCurve(const curve: IECCurve): IECCurve;
+begin
+  result := curve;
+end;
+
+class function TSecNamedCurves.ConfigureCurveGlv(const c: IECCurve;
+  const p: IGlvTypeBParameters): IECCurve;
+var
+  glv: IGlvTypeBEndomorphism;
+begin
+  glv := TGlvTypeBEndomorphism.Create(c, p);
+  result := c.Configure().SetEndomorphism(glv).CreateCurve();
+end;
+
+class function TSecNamedCurves.FromHex(const Hex: String): TBigInteger;
+begin
+  result := TBigInteger.Create(1, THex.Decode(Hex));
+end;
+
+class function TSecNamedCurves.GetByOid(const oid: IDerObjectIdentifier)
+  : IX9ECParameters;
+var
+  holder: IX9ECParametersHolder;
+begin
+  if Fcurves.TryGetValue(oid, holder) then
+  begin
+    result := holder.Parameters
+  end
+  else
+  begin
+    result := Nil;
+  end;
+end;
+
+class function TSecNamedCurves.GetOid(const name: String): IDerObjectIdentifier;
+begin
+  if not(FobjIds.TryGetValue(UpperCase(name), result)) then
+  begin
+    result := Nil;
+  end;
+end;
+
+class function TSecNamedCurves.GetByName(const name: String): IX9ECParameters;
+var
+  oid: IDerObjectIdentifier;
+begin
+  oid := GetOid(name);
+  if oid = Nil then
+  begin
+    result := Nil;
+  end
+  else
+  begin
+    result := GetByOid(oid);
+  end;
+
+end;
+
+class function TSecNamedCurves.GetName(const oid: IDerObjectIdentifier): String;
+begin
+  if not(Fnames.TryGetValue(oid, result)) then
+  begin
+    result := '';
+  end;
+end;
+
+class function TSecNamedCurves.GetNames: TCryptoLibStringArray;
+begin
+  result := Fnames.Values.ToArray();
+end;
+
 class constructor TSecNamedCurves.CreateSecNamedCurves;
 begin
   FobjIds := TDictionary<String, IDerObjectIdentifier>.Create();
   Fnames := TDictionary<IDerObjectIdentifier, String>.Create();
   Fcurves := TDictionary<IDerObjectIdentifier, IX9ECParametersHolder>.Create();
 
-  TSecObjectIdentifiers.Boot;
+  // TSecObjectIdentifiers.Boot;
 
   DefineCurve('secp112r1', TSecObjectIdentifiers.SecP112r1,
     TSecp112r1Holder.Instance);
@@ -820,85 +901,6 @@ begin
   Fcurves.Free;
 end;
 
-class procedure TSecNamedCurves.DefineCurve(const name: String;
-  const oid: IDerObjectIdentifier; const holder: IX9ECParametersHolder);
-begin
-  FobjIds.Add(UpperCase(name), oid);
-  Fnames.Add(oid, name);
-  Fcurves.Add(oid, holder);
-end;
-
-class function TSecNamedCurves.ConfigureCurve(const curve: IECCurve): IECCurve;
-begin
-  result := curve;
-end;
-
-class function TSecNamedCurves.ConfigureCurveGlv(const c: IECCurve;
-  const p: IGlvTypeBParameters): IECCurve;
-var
-  glv: IGlvTypeBEndomorphism;
-begin
-  glv := TGlvTypeBEndomorphism.Create(c, p);
-  result := c.Configure().SetEndomorphism(glv).CreateCurve();
-end;
-
-class function TSecNamedCurves.FromHex(const Hex: String): TBigInteger;
-begin
-  result := TBigInteger.Create(1, THex.Decode(Hex));
-end;
-
-class function TSecNamedCurves.GetByOid(const oid: IDerObjectIdentifier)
-  : IX9ECParameters;
-var
-  holder: IX9ECParametersHolder;
-begin
-  if Fcurves.TryGetValue(oid, holder) then
-  begin
-    result := holder.Parameters
-  end
-  else
-  begin
-    result := Nil;
-  end;
-end;
-
-class function TSecNamedCurves.GetOid(const name: String): IDerObjectIdentifier;
-begin
-  if not(FobjIds.TryGetValue(UpperCase(name), result)) then
-  begin
-    result := Nil;
-  end;
-end;
-
-class function TSecNamedCurves.GetByName(const name: String): IX9ECParameters;
-var
-  oid: IDerObjectIdentifier;
-begin
-  oid := GetOid(name);
-  if oid = Nil then
-  begin
-    result := Nil;
-  end
-  else
-  begin
-    result := GetByOid(oid);
-  end;
-
-end;
-
-class function TSecNamedCurves.GetName(const oid: IDerObjectIdentifier): String;
-begin
-  if not(Fnames.TryGetValue(oid, result)) then
-  begin
-    result := '';
-  end;
-end;
-
-class function TSecNamedCurves.GetNames: TCryptoLibStringArray;
-begin
-  result := Fnames.Values.ToArray();
-end;
-
 { TSecNamedCurves.TSecp112r1Holder }
 
 function TSecNamedCurves.TSecp112r1Holder.CreateParameters: IX9ECParameters;

+ 32 - 15
CryptoLib/src/Asn1/X9/ClpECNamedCurveTable.pas

@@ -28,6 +28,7 @@ uses
   // ClpECGost3410NamedCurves,
   // ClpX9ECParameters,
   ClpSecNamedCurves,
+  ClpNistNamedCurves,
   // ClpIECDomainParameters,
   ClpIDerObjectIdentifier,
   ClpIX9ECParameters;
@@ -112,6 +113,11 @@ begin
   ecP := TSecNamedCurves.GetByName(name);
   // end;
 
+  if (ecP = Nil) then
+  begin
+    ecP := TNistNamedCurves.GetByName(name);
+  end;
+
   result := ecP;
 end;
 
@@ -125,6 +131,7 @@ begin
   // begin
   ecP := TSecNamedCurves.GetByOid(oid);
   // end;
+  // NOTE: All the NIST curves are currently from SEC, so no point in redundant OID lookup
   result := ecP;
 end;
 
@@ -134,26 +141,16 @@ var
   name: String;
 begin
   // name := TX962NamedCurves.GetName(oid);
-  // if (name = Nil) then
+  // if (name = '') then
   // begin
   name := TSecNamedCurves.GetName(oid);
   // end;
-  result := name;
-end;
 
-class function TECNamedCurveTable.GetNames: TCryptoLibStringArray;
-var
-  temp: TList<String>;
-begin
-  temp := TList<String>.Create();
-  try
-    temp.AddRange(TSecNamedCurves.Names);
-    // temp.AddRange(TECGost3410NamedCurves.Names);
-    result := temp.ToArray;
-  finally
-    temp.Free;
+  if (name = '') then
+  begin
+    name := TNistNamedCurves.GetName(oid);
   end;
-
+  result := name;
 end;
 
 class function TECNamedCurveTable.GetOid(const name: String)
@@ -167,7 +164,27 @@ begin
   oid := TSecNamedCurves.GetOid(name);
   // end;
 
+  if (oid = Nil) then
+  begin
+    oid := TNistNamedCurves.GetOid(name);
+  end;
+
   result := oid;
 end;
 
+class function TECNamedCurveTable.GetNames: TCryptoLibStringArray;
+var
+  temp: TList<String>;
+begin
+  temp := TList<String>.Create();
+  try
+    temp.AddRange(TSecNamedCurves.Names);
+    temp.AddRange(TNistNamedCurves.Names);
+    result := temp.ToArray;
+  finally
+    temp.Free;
+  end;
+
+end;
+
 end.

+ 9 - 3
CryptoLib/src/Math/EC/ClpECFieldElement.pas

@@ -1017,7 +1017,8 @@ begin
     begin
       Qh := Ql;
       Uh := ModReduce(Uh.Multiply(Vl).Subtract(Ql));
-      Vh := ModReduce(Vl.Multiply(Vl).Subtract(Ql.ShiftLeft(1)));
+      Vh := ModReduce(Vh.Multiply(Vl).Subtract(P.Multiply(Ql)));
+      Vl := ModReduce(Vl.Multiply(Vl).Subtract(Ql.ShiftLeft(1)));
     end;
     System.Dec(j);
   end;
@@ -1233,6 +1234,7 @@ var
   u, v, K, e, t1, t2, t3, t4, y, legendreExponent, x, fourX, qMinusOne,
     P: TBigInteger;
   tempRes: TCryptoLibGenericArray<TBigInteger>;
+  CompareRes, ModReduceRes: Boolean;
 begin
   if (IsZero or IsOne) then
   begin
@@ -1294,8 +1296,12 @@ begin
 
     repeat
       P := TBigInteger.Arbitrary(Fq.BitLength);
-    until ((not P.CompareTo(Q) >= 0) or (ModReduce(P.Multiply(P).Subtract(fourX)
-      ).ModPow(legendreExponent, Q).Equals(qMinusOne)));
+
+      CompareRes := P.CompareTo(Q) >= 0;
+      ModReduceRes := (not ModReduce(P.Multiply(P).Subtract(fourX))
+        .ModPow(legendreExponent, Q).Equals(qMinusOne));
+
+    until ((not CompareRes) and (not ModReduceRes));
 
     tempRes := LucasSequence(P, x, K);
     u := tempRes[0];

+ 5 - 1
CryptoLib/src/Packages/FPC/CryptoLib4PascalPackage.lpk

@@ -25,7 +25,7 @@
  Acknowledgements: 
 Thanks to Sphere 10 Software (http://www.sphere10.com/) for sponsoring the development of this library "/>
     <Version Major="2" Minor="3"/>
-    <Files Count="408">
+    <Files Count="409">
       <Item1>
         <Filename Value="..\..\Asn1\ClpAsn1Encodable.pas"/>
         <UnitName Value="ClpAsn1Encodable"/>
@@ -1660,6 +1660,10 @@ Thanks to Sphere 10 Software (http://www.sphere10.com/) for sponsoring the devel
         <AddToUsesPkgSection Value="False"/>
         <UnitName Value="ClpValidityPrecompInfo"/>
       </Item408>
+      <Item409>
+        <Filename Value="..\..\Asn1\Nist\ClpNistNamedCurves.pas"/>
+        <UnitName Value="ClpNistNamedCurves"/>
+      </Item409>
     </Files>
     <RequiredPkgs Count="3">
       <Item1>

+ 1 - 1
CryptoLib/src/Packages/FPC/CryptoLib4PascalPackage.pas

@@ -135,7 +135,7 @@ uses
   ClpIDsaParameterGenerationParameters, ClpValidityPrecompInfo, 
   ClpIValidityPrecompInfo, ClpDsaParametersGenerator, ClpDsaParameter, 
   ClpIDsaParameter, ClpIKeyEncoder, ClpIDsaParametersGenerator, 
-  ClpIPreCompCallBack;
+  ClpIPreCompCallBack, ClpNistNamedCurves;
 
 implementation
 

+ 1 - 0
CryptoLib/src/Security/ClpSecureRandom.pas

@@ -68,6 +68,7 @@ type
     class destructor DestroySecureRandom();
 
   strict protected
+  var
     Fgenerator: IRandomGenerator;
 
   public