Browse Source

update CryptoLib to be in Sync with parent version

Ugochukwu Mmaduekwe 6 years ago
parent
commit
94f31c7c56
100 changed files with 7489 additions and 173 deletions
  1. 171 0
      src/libraries/cryptolib4pascal/ClpAgreementUtilities.pas
  2. 269 0
      src/libraries/cryptolib4pascal/ClpArgon2ParametersGenerator.pas
  3. 20 0
      src/libraries/cryptolib4pascal/ClpArrayUtils.pas
  4. 13 0
      src/libraries/cryptolib4pascal/ClpBigInteger.pas
  5. 1 0
      src/libraries/cryptolib4pascal/ClpBlockCipherModes.pas
  6. 1 1
      src/libraries/cryptolib4pascal/ClpBsiObjectIdentifiers.pas
  7. 1 1
      src/libraries/cryptolib4pascal/ClpCipherUtilities.pas
  8. 18 0
      src/libraries/cryptolib4pascal/ClpCryptoLibTypes.pas
  9. 1378 0
      src/libraries/cryptolib4pascal/ClpCurve25519Custom.pas
  10. 66 12
      src/libraries/cryptolib4pascal/ClpCustomNamedCurves.pas
  11. 44 5
      src/libraries/cryptolib4pascal/ClpDigest.pas
  12. 56 36
      src/libraries/cryptolib4pascal/ClpDigestUtilities.pas
  13. 1 1
      src/libraries/cryptolib4pascal/ClpDsaDigestSigner.pas
  14. 1 1
      src/libraries/cryptolib4pascal/ClpDsaKeyGenerationParameters.pas
  15. 1 1
      src/libraries/cryptolib4pascal/ClpDsaParameter.pas
  16. 1 1
      src/libraries/cryptolib4pascal/ClpDsaParameterGenerationParameters.pas
  17. 1 1
      src/libraries/cryptolib4pascal/ClpDsaParameters.pas
  18. 1 1
      src/libraries/cryptolib4pascal/ClpDsaParametersGenerator.pas
  19. 1 1
      src/libraries/cryptolib4pascal/ClpDsaSigner.pas
  20. 1 1
      src/libraries/cryptolib4pascal/ClpDsaValidationParameters.pas
  21. 1 1
      src/libraries/cryptolib4pascal/ClpECDHCBasicAgreement.pas
  22. 1 2
      src/libraries/cryptolib4pascal/ClpECNRSigner.pas
  23. 17 49
      src/libraries/cryptolib4pascal/ClpECNamedCurveTable.pas
  24. 1 1
      src/libraries/cryptolib4pascal/ClpECSchnorrSipaSigner.pas
  25. 1 1
      src/libraries/cryptolib4pascal/ClpEacObjectIdentifiers.pas
  26. 1946 0
      src/libraries/cryptolib4pascal/ClpEd25519.pas
  27. 48 0
      src/libraries/cryptolib4pascal/ClpEd25519Blake2B.pas
  28. 48 0
      src/libraries/cryptolib4pascal/ClpEd25519Blake2BKeyGenerationParameters.pas
  29. 71 0
      src/libraries/cryptolib4pascal/ClpEd25519Blake2BKeyPairGenerator.pas
  30. 212 0
      src/libraries/cryptolib4pascal/ClpEd25519Blake2BPrivateKeyParameters.pas
  31. 119 0
      src/libraries/cryptolib4pascal/ClpEd25519Blake2BPublicKeyParameters.pas
  32. 187 0
      src/libraries/cryptolib4pascal/ClpEd25519Blake2BSigner.pas
  33. 190 0
      src/libraries/cryptolib4pascal/ClpEd25519CtxBlake2BSigner.pas
  34. 189 0
      src/libraries/cryptolib4pascal/ClpEd25519CtxSigner.pas
  35. 47 0
      src/libraries/cryptolib4pascal/ClpEd25519KeyGenerationParameters.pas
  36. 70 0
      src/libraries/cryptolib4pascal/ClpEd25519KeyPairGenerator.pas
  37. 178 0
      src/libraries/cryptolib4pascal/ClpEd25519PhBlake2BSigner.pas
  38. 177 0
      src/libraries/cryptolib4pascal/ClpEd25519PhSigner.pas
  39. 210 0
      src/libraries/cryptolib4pascal/ClpEd25519PrivateKeyParameters.pas
  40. 118 0
      src/libraries/cryptolib4pascal/ClpEd25519PublicKeyParameters.pas
  41. 186 0
      src/libraries/cryptolib4pascal/ClpEd25519Signer.pas
  42. 114 0
      src/libraries/cryptolib4pascal/ClpEdECObjectIdentifiers.pas
  43. 51 9
      src/libraries/cryptolib4pascal/ClpGeneratorUtilities.pas
  44. 1 1
      src/libraries/cryptolib4pascal/ClpHMacDsaKCalculator.pas
  45. 1 1
      src/libraries/cryptolib4pascal/ClpHkdfBytesGenerator.pas
  46. 2 6
      src/libraries/cryptolib4pascal/ClpHkdfParameters.pas
  47. 1 1
      src/libraries/cryptolib4pascal/ClpIAesLightEngine.pas
  48. 118 0
      src/libraries/cryptolib4pascal/ClpIArgon2ParametersGenerator.pas
  49. 0 13
      src/libraries/cryptolib4pascal/ClpIBlockCipherModes.pas
  50. 64 0
      src/libraries/cryptolib4pascal/ClpICurve25519Custom.pas
  51. 6 3
      src/libraries/cryptolib4pascal/ClpIDigest.pas
  52. 1 1
      src/libraries/cryptolib4pascal/ClpIDsaDigestSigner.pas
  53. 1 1
      src/libraries/cryptolib4pascal/ClpIDsaParameter.pas
  54. 1 1
      src/libraries/cryptolib4pascal/ClpIDsaParameterGenerationParameters.pas
  55. 1 1
      src/libraries/cryptolib4pascal/ClpIDsaParametersGenerator.pas
  56. 1 1
      src/libraries/cryptolib4pascal/ClpIDsaSigner.pas
  57. 1 1
      src/libraries/cryptolib4pascal/ClpIECDHCBasicAgreement.pas
  58. 1 1
      src/libraries/cryptolib4pascal/ClpIECNRSigner.pas
  59. 1 1
      src/libraries/cryptolib4pascal/ClpIECSchnorrSipaSigner.pas
  60. 1 1
      src/libraries/cryptolib4pascal/ClpIESEngine.pas
  61. 97 0
      src/libraries/cryptolib4pascal/ClpIEd25519.pas
  62. 35 0
      src/libraries/cryptolib4pascal/ClpIEd25519Blake2B.pas
  63. 35 0
      src/libraries/cryptolib4pascal/ClpIEd25519Blake2BKeyGenerationParameters.pas
  64. 35 0
      src/libraries/cryptolib4pascal/ClpIEd25519Blake2BKeyPairGenerator.pas
  65. 49 0
      src/libraries/cryptolib4pascal/ClpIEd25519Blake2BPrivateKeyParameters.pas
  66. 41 0
      src/libraries/cryptolib4pascal/ClpIEd25519Blake2BPublicKeyParameters.pas
  67. 36 0
      src/libraries/cryptolib4pascal/ClpIEd25519Blake2BSigner.pas
  68. 36 0
      src/libraries/cryptolib4pascal/ClpIEd25519CtxBlake2BSigner.pas
  69. 36 0
      src/libraries/cryptolib4pascal/ClpIEd25519CtxSigner.pas
  70. 35 0
      src/libraries/cryptolib4pascal/ClpIEd25519KeyGenerationParameters.pas
  71. 35 0
      src/libraries/cryptolib4pascal/ClpIEd25519KeyPairGenerator.pas
  72. 36 0
      src/libraries/cryptolib4pascal/ClpIEd25519PhBlake2BSigner.pas
  73. 36 0
      src/libraries/cryptolib4pascal/ClpIEd25519PhSigner.pas
  74. 49 0
      src/libraries/cryptolib4pascal/ClpIEd25519PrivateKeyParameters.pas
  75. 41 0
      src/libraries/cryptolib4pascal/ClpIEd25519PublicKeyParameters.pas
  76. 36 0
      src/libraries/cryptolib4pascal/ClpIEd25519Signer.pas
  77. 1 1
      src/libraries/cryptolib4pascal/ClpIHMacDsaKCalculator.pas
  78. 1 1
      src/libraries/cryptolib4pascal/ClpIHkdfBytesGenerator.pas
  79. 1 1
      src/libraries/cryptolib4pascal/ClpIHkdfParameters.pas
  80. 36 0
      src/libraries/cryptolib4pascal/ClpIKdf1BytesGenerator.pas
  81. 1 1
      src/libraries/cryptolib4pascal/ClpIKdf2BytesGenerator.pas
  82. 1 0
      src/libraries/cryptolib4pascal/ClpIKeyParameter.pas
  83. 1 0
      src/libraries/cryptolib4pascal/ClpIParametersWithIV.pas
  84. 1 1
      src/libraries/cryptolib4pascal/ClpIPbeParametersGenerator.pas
  85. 1 1
      src/libraries/cryptolib4pascal/ClpIPkcs5S2ParametersGenerator.pas
  86. 43 0
      src/libraries/cryptolib4pascal/ClpIRawAgreement.pas
  87. 1 1
      src/libraries/cryptolib4pascal/ClpISchnorr.pas
  88. 1 1
      src/libraries/cryptolib4pascal/ClpISchnorrDigestSigner.pas
  89. 1 1
      src/libraries/cryptolib4pascal/ClpISchnorrExt.pas
  90. 1 1
      src/libraries/cryptolib4pascal/ClpISigner.pas
  91. 36 0
      src/libraries/cryptolib4pascal/ClpISpeckLegacyEngine.pas
  92. 37 0
      src/libraries/cryptolib4pascal/ClpIX25519Agreement.pas
  93. 35 0
      src/libraries/cryptolib4pascal/ClpIX25519KeyGenerationParameters.pas
  94. 35 0
      src/libraries/cryptolib4pascal/ClpIX25519KeyPairGenerator.pas
  95. 45 0
      src/libraries/cryptolib4pascal/ClpIX25519PrivateKeyParameters.pas
  96. 40 0
      src/libraries/cryptolib4pascal/ClpIX25519PublicKeyParameters.pas
  97. 1 1
      src/libraries/cryptolib4pascal/ClpIso18033KdfParameters.pas
  98. 63 0
      src/libraries/cryptolib4pascal/ClpKdf1BytesGenerator.pas
  99. 1 1
      src/libraries/cryptolib4pascal/ClpKdf2BytesGenerator.pas
  100. 7 1
      src/libraries/cryptolib4pascal/ClpKeyParameter.pas

+ 171 - 0
src/libraries/cryptolib4pascal/ClpAgreementUtilities.pas

@@ -0,0 +1,171 @@
+{ *********************************************************************************** }
+{ *                              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 ClpAgreementUtilities;
+
+{$I CryptoLib.inc}
+
+interface
+
+uses
+  SysUtils,
+  Generics.Collections,
+  ClpIBasicAgreement,
+  ClpECDHBasicAgreement,
+  ClpIECDHBasicAgreement,
+  ClpECDHCBasicAgreement,
+  ClpIECDHCBasicAgreement,
+  ClpX25519Agreement,
+  ClpIX25519Agreement,
+  ClpIRawAgreement,
+  ClpEdECObjectIdentifiers,
+  ClpIAsn1Objects,
+  ClpCryptoLibTypes;
+
+resourcestring
+  SUnRecognizedRawAgreementAlgorithm =
+    'Raw Agreement Algorithm "%s" Not Recognised.';
+  SUnRecognizedBasicAgreementAlgorithm =
+    'Basic Agreement Algorithm "%s" Not Recognised.';
+
+type
+
+  /// <summary>
+  /// Utility class for creating IBasicAgreement objects from their
+  /// names/Oids
+  /// </summary>
+  TAgreementUtilities = class sealed(TObject)
+
+  strict private
+    class var
+
+      Falgorithms: TDictionary<String, String>;
+
+    class function GetMechanism(const algorithm: String): String;
+      static; inline;
+
+    class procedure Boot(); static;
+    class constructor CreateAgreementUtilities();
+    class destructor DestroyAgreementUtilities();
+
+  public
+    class function GetBasicAgreement(const algorithm: String)
+      : IBasicAgreement; static;
+
+    class function GetRawAgreement(const oid: IDerObjectIdentifier)
+      : IRawAgreement; overload; static; inline;
+
+    class function GetRawAgreement(const algorithm: String): IRawAgreement;
+      overload; static;
+
+    class function GetAlgorithmName(const oid: IDerObjectIdentifier): String;
+      static; inline;
+
+  end;
+
+implementation
+
+{ TAgreementUtilities }
+
+class procedure TAgreementUtilities.Boot;
+begin
+  Falgorithms := TDictionary<string, string>.Create();
+  Falgorithms.Add(TEdECObjectIdentifiers.id_X25519.Id, 'X25519');
+end;
+
+class constructor TAgreementUtilities.CreateAgreementUtilities;
+begin
+  TAgreementUtilities.Boot;
+end;
+
+class destructor TAgreementUtilities.DestroyAgreementUtilities;
+begin
+  Falgorithms.Free;
+end;
+
+class function TAgreementUtilities.GetMechanism(const algorithm
+  : String): String;
+var
+  upper, mechanism: String;
+begin
+  upper := UpperCase(algorithm);
+  if Falgorithms.TryGetValue(upper, mechanism) then
+  begin
+    result := mechanism
+  end
+  else
+  begin
+    result := upper;
+  end;
+end;
+
+class function TAgreementUtilities.GetAlgorithmName
+  (const oid: IDerObjectIdentifier): String;
+begin
+  if not(Falgorithms.TryGetValue(oid.Id, result)) then
+  begin
+    result := '';
+  end;
+end;
+
+class function TAgreementUtilities.GetBasicAgreement(const algorithm: String)
+  : IBasicAgreement;
+var
+  mechanism: String;
+begin
+  mechanism := GetMechanism(algorithm);
+
+  if (mechanism = 'ECDH') then
+  begin
+    result := TECDHBasicAgreement.Create() as IECDHBasicAgreement;
+    Exit;
+  end;
+
+  if ((mechanism = 'ECDHC') or (mechanism = 'ECCDH')) then
+  begin
+    result := TECDHCBasicAgreement.Create() as IECDHCBasicAgreement;
+    Exit;
+  end;
+
+  raise ESecurityUtilityCryptoLibException.CreateResFmt
+    (@SUnRecognizedBasicAgreementAlgorithm, [algorithm]);
+end;
+
+class function TAgreementUtilities.GetRawAgreement(const algorithm: String)
+  : IRawAgreement;
+var
+  mechanism: String;
+begin
+  mechanism := GetMechanism(algorithm);
+
+  if (mechanism = 'X25519') then
+  begin
+    result := TX25519Agreement.Create() as IX25519Agreement;
+    Exit;
+  end;
+
+  raise ESecurityUtilityCryptoLibException.CreateResFmt
+    (@SUnRecognizedRawAgreementAlgorithm, [algorithm]);
+end;
+
+class function TAgreementUtilities.GetRawAgreement
+  (const oid: IDerObjectIdentifier): IRawAgreement;
+begin
+  result := GetRawAgreement(oid.Id);
+end;
+
+end.

+ 269 - 0
src/libraries/cryptolib4pascal/ClpArgon2ParametersGenerator.pas

@@ -0,0 +1,269 @@
+{ *********************************************************************************** }
+{ *                              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 ClpArgon2ParametersGenerator;
+
+{$I CryptoLib.inc}
+
+interface
+
+uses
+
+  HlpIHashInfo,
+  HlpHashFactory,
+  HlpPBKDF_Argon2NotBuildInAdapter,
+  ClpICipherParameters,
+  ClpIArgon2ParametersGenerator,
+  ClpKeyParameter,
+  ClpIKeyParameter,
+  ClpParametersWithIV,
+  ClpParameterUtilities,
+  ClpCryptoLibTypes;
+
+resourcestring
+  SArgon2TypeInvalid = 'Selected Argon2Type is Invalid';
+  SArgon2MemoryCostTypeInvalid = 'Selected Argon2MemoryCostType is Invalid';
+
+type
+
+  /// <summary>
+  /// <see href="https://github.com/P-H-C/phc-winner-argon2/blob/master/argon2-specs.pdf">
+  /// Argon2 Specification</see>, <see href="https://tools.ietf.org/html/draft-irtf-cfrg-argon2-04">
+  /// ietf specs</see>
+  /// </summary>
+  TArgon2ParametersGenerator = class sealed(TInterfacedObject,
+    IArgon2ParametersGenerator)
+
+  strict private
+  var
+    FPassword: TCryptoLibByteArray;
+    FPBKDF_Argon2: IPBKDF_Argon2;
+    FArgon2ParametersBuilder: HlpIHashInfo.IArgon2ParametersBuilder;
+
+    /// <returns>
+    /// the password byte array.
+    /// </returns>
+    function GetPassword: TCryptoLibByteArray; inline;
+
+    /// <returns>
+    /// the Argon2 Parameter Builder Instance
+    /// </returns>
+    function GetArgon2ParametersBuilder
+      : HlpIHashInfo.IArgon2ParametersBuilder; inline;
+
+    function GenerateDerivedKey(dkLen: Int32): TCryptoLibByteArray; inline;
+
+  public
+
+    /// <summary>
+    /// construct an Argon2 Parameters generator.
+    /// </summary>
+    /// <param name="digest">
+    /// digest to use for constructing hmac
+    /// </param>
+    constructor Create();
+
+    procedure Init(argon2Type: TArgon2Type; argon2Version: TArgon2Version;
+      const password, salt, secret, additional: TCryptoLibByteArray;
+      iterations, memory, parallelism: Int32;
+      memoryCostType: TArgon2MemoryCostType);
+
+    /// <summary>
+    /// Generate a key parameter derived from the password, salt, and
+    /// iteration count we are currently initialised with.
+    /// </summary>
+    /// <param name="algorithm">
+    /// a parameters object representing a key.
+    /// </param>
+    /// <param name="keySize">
+    /// the length, in bits, of the key required.
+    /// </param>
+    /// <returns>
+    /// a parameters object representing a key.
+    /// </returns>
+    function GenerateDerivedParameters(const algorithm: String; keySize: Int32)
+      : ICipherParameters; overload;
+
+    /// <summary>
+    /// Generate a key with initialisation vector parameter derived from <br />
+    /// the password, salt, and iteration count we are currently initialised
+    /// with.
+    /// </summary>
+    /// <param name="algorithm">
+    /// a parameters object representing a key.
+    /// </param>
+    /// <param name="keySize">
+    /// the length, in bits, of the key required.
+    /// </param>
+    /// <param name="ivSize">
+    /// the length, in bits, of the iv required.
+    /// </param>
+    /// <returns>
+    /// a parameters object representing a key and an iv.
+    /// </returns>
+    function GenerateDerivedParameters(const algorithm: String;
+      keySize, ivSize: Int32): ICipherParameters; overload;
+
+    /// <summary>
+    /// Generate a key parameter for use with a MAC derived from the
+    /// password, salt, and iteration count we are currently initialised
+    /// with.
+    /// </summary>
+    /// <param name="keySize">
+    /// the length, in bits, of the key required.
+    /// </param>
+    /// <returns>
+    /// a parameters object representing a key.
+    /// </returns>
+    function GenerateDerivedMacParameters(keySize: Int32)
+      : ICipherParameters; overload;
+
+    /// <value>
+    /// the password byte array.
+    /// </value>
+    property password: TCryptoLibByteArray read GetPassword;
+
+    /// <returns>
+    /// the Argon2 Parameter Builder Instance
+    /// </returns>
+    property Argon2ParametersBuilder: HlpIHashInfo.IArgon2ParametersBuilder
+      read GetArgon2ParametersBuilder;
+
+  end;
+
+implementation
+
+{ TArgon2ParametersGenerator }
+
+function TArgon2ParametersGenerator.GetPassword: TCryptoLibByteArray;
+begin
+  result := System.Copy(FPassword);
+end;
+
+function TArgon2ParametersGenerator.GetArgon2ParametersBuilder
+  : HlpIHashInfo.IArgon2ParametersBuilder;
+begin
+  result := FArgon2ParametersBuilder;
+end;
+
+constructor TArgon2ParametersGenerator.Create();
+begin
+  Inherited Create();
+end;
+
+function TArgon2ParametersGenerator.GenerateDerivedKey(dkLen: Int32)
+  : TCryptoLibByteArray;
+begin
+  result := FPBKDF_Argon2.GetBytes(dkLen);
+end;
+
+function TArgon2ParametersGenerator.GenerateDerivedMacParameters(keySize: Int32)
+  : ICipherParameters;
+var
+  dKey: TCryptoLibByteArray;
+begin
+  keySize := keySize div 8;
+
+  dKey := GenerateDerivedKey(keySize);
+
+  result := TKeyParameter.Create(dKey, 0, keySize);
+end;
+
+function TArgon2ParametersGenerator.GenerateDerivedParameters(const algorithm
+  : String; keySize: Int32): ICipherParameters;
+var
+  dKey: TCryptoLibByteArray;
+begin
+  keySize := keySize div 8;
+
+  dKey := GenerateDerivedKey(keySize);
+
+  result := TParameterUtilities.CreateKeyParameter(algorithm, dKey, 0, keySize);
+end;
+
+function TArgon2ParametersGenerator.GenerateDerivedParameters(const algorithm
+  : String; keySize, ivSize: Int32): ICipherParameters;
+var
+  dKey: TCryptoLibByteArray;
+  key: IKeyParameter;
+begin
+  keySize := keySize div 8;
+  ivSize := ivSize div 8;
+
+  dKey := GenerateDerivedKey(keySize + ivSize);
+  key := TParameterUtilities.CreateKeyParameter(algorithm, dKey, 0, keySize);
+
+  result := TParametersWithIV.Create(key, dKey, keySize, ivSize);
+end;
+
+procedure TArgon2ParametersGenerator.Init(argon2Type: TArgon2Type;
+  argon2Version: TArgon2Version; const password, salt, secret,
+  additional: TCryptoLibByteArray; iterations, memory, parallelism: Int32;
+  memoryCostType: TArgon2MemoryCostType);
+var
+  LArgon2ParametersBuilder: IArgon2ParametersBuilder;
+begin
+  FPassword := password;
+
+  case argon2Type of
+    TArgon2Type.a2tARGON2_d:
+      begin
+        LArgon2ParametersBuilder := TArgon2dParametersBuilder.Builder();
+      end;
+
+    TArgon2Type.a2tARGON2_i:
+      begin
+        LArgon2ParametersBuilder := TArgon2iParametersBuilder.Builder();
+      end;
+    TArgon2Type.a2tARGON2_id:
+      begin
+        LArgon2ParametersBuilder := TArgon2idParametersBuilder.Builder();
+      end
+  else
+    begin
+      raise EArgumentCryptoLibException.CreateRes(@SArgon2TypeInvalid);
+    end;
+  end;
+
+  case memoryCostType of
+    TArgon2MemoryCostType.a2mctMemoryAsKB:
+      begin
+        LArgon2ParametersBuilder.WithVersion(argon2Version).WithSalt(salt)
+          .WithSecret(secret).WithAdditional(additional)
+          .WithIterations(iterations).WithMemoryAsKB(memory)
+          .WithParallelism(parallelism);
+      end;
+
+    TArgon2MemoryCostType.a2mctMemoryPowOfTwo:
+      begin
+        LArgon2ParametersBuilder.WithVersion(argon2Version).WithSalt(salt)
+          .WithSecret(secret).WithAdditional(additional)
+          .WithIterations(iterations).WithMemoryPowOfTwo(memory)
+          .WithParallelism(parallelism);
+      end
+  else
+    begin
+      raise EArgumentCryptoLibException.CreateRes
+        (@SArgon2MemoryCostTypeInvalid);
+    end;
+  end;
+
+  FPBKDF_Argon2 := TKDF.TPBKDF_Argon2.CreatePBKDF_Argon2(FPassword,
+    LArgon2ParametersBuilder.Build());
+end;
+
+end.

+ 20 - 0
src/libraries/cryptolib4pascal/ClpArrayUtils.pas

@@ -74,6 +74,9 @@ type
     class function Prepend(const A: TCryptoLibByteArray; B: Byte)
     class function Prepend(const A: TCryptoLibByteArray; B: Byte)
       : TCryptoLibByteArray; static;
       : TCryptoLibByteArray; static;
 
 
+    class function Append(const A: TCryptoLibByteArray; B: Byte)
+      : TCryptoLibByteArray; static;
+
     class function CopyOf(const data: TCryptoLibByteArray; newLength: Int32)
     class function CopyOf(const data: TCryptoLibByteArray; newLength: Int32)
       : TCryptoLibByteArray; static;
       : TCryptoLibByteArray; static;
 
 
@@ -420,4 +423,21 @@ begin
   Result[0] := B;
   Result[0] := B;
 end;
 end;
 
 
+class function TArrayUtils.Append(const A: TCryptoLibByteArray; B: Byte)
+  : TCryptoLibByteArray;
+var
+  &length: Int32;
+begin
+  if (A = Nil) then
+  begin
+    Result := TCryptoLibByteArray.Create(B);
+    Exit;
+  end;
+
+  Length := System.Length(A);
+  System.SetLength(Result, Length + 1);
+  System.Move(A[0], Result[0], Length * System.SizeOf(Byte));
+  Result[Length] := B;
+end;
+
 end.
 end.

+ 13 - 0
src/libraries/cryptolib4pascal/ClpBigInteger.pas

@@ -434,6 +434,8 @@ type
     function GetHashCode(): {$IFDEF DELPHI}Int32; {$ELSE}PtrInt;
     function GetHashCode(): {$IFDEF DELPHI}Int32; {$ELSE}PtrInt;
     inline;
     inline;
 {$ENDIF DELPHI}
 {$ENDIF DELPHI}
+    function Clone(): TBigInteger; inline;
+
     class function BitCnt(i: Int32): Int32; static;
     class function BitCnt(i: Int32): Int32; static;
 
 
     /// <summary>
     /// <summary>
@@ -2040,6 +2042,17 @@ begin
 
 
 end;
 end;
 
 
+function TBigInteger.Clone(): TBigInteger;
+begin
+  Result := Default (TBigInteger);
+  Result.Fmagnitude := System.Copy(Fmagnitude);
+  Result.Fsign := Fsign;
+  Result.FnBits := FnBits;
+  Result.FnBitLength := FnBitLength;
+  Result.FmQuote := FmQuote;
+  Result.FIsInitialized := FIsInitialized;
+end;
+
 function TBigInteger.GetLowestSetBit: Int32;
 function TBigInteger.GetLowestSetBit: Int32;
 begin
 begin
   if (Fsign = 0) then
   if (Fsign = 0) then

+ 1 - 0
src/libraries/cryptolib4pascal/ClpBlockCipherModes.pas

@@ -627,6 +627,7 @@ type
   TCtsBlockCipher = class sealed(TBufferedBlockCipher, ICtsBlockCipher)
   TCtsBlockCipher = class sealed(TBufferedBlockCipher, ICtsBlockCipher)
 
 
   strict private
   strict private
+  var
     FblockSize: Int32;
     FblockSize: Int32;
 
 
   public
   public

+ 1 - 1
src/libraries/cryptolib4pascal/ClpBsiObjectIdentifiers.pas

@@ -17,7 +17,7 @@
 
 
 unit ClpBsiObjectIdentifiers;
 unit ClpBsiObjectIdentifiers;
 
 
-{$I ..\..\Include\CryptoLib.inc}
+{$I CryptoLib.inc}
 
 
 interface
 interface
 
 

+ 1 - 1
src/libraries/cryptolib4pascal/ClpCipherUtilities.pas

@@ -55,7 +55,7 @@ uses
 resourcestring
 resourcestring
   SMechanismNil = 'Mechanism Cannot be Nil';
   SMechanismNil = 'Mechanism Cannot be Nil';
   SAlgorithmNil = 'Algorithm Cannot be Nil';
   SAlgorithmNil = 'Algorithm Cannot be Nil';
-  SUnRecognizedCipher = '"Cipher " %s Not Recognised.';
+  SUnRecognizedCipher = 'Cipher "%s" Not Recognised.';
   SSICModeWarning =
   SSICModeWarning =
     'Warning: SIC-Mode Can Become a TwoTime-Pad if the Blocksize of the Cipher is Too Small. Use a Cipher With a Block Size of at Least 128 bits (e.g. AES)';
     'Warning: SIC-Mode Can Become a TwoTime-Pad if the Blocksize of the Cipher is Too Small. Use a Cipher With a Block Size of at Least 128 bits (e.g. AES)';
   SModeAndPaddingNotNeededStreamCipher =
   SModeAndPaddingNotNeededStreamCipher =

+ 18 - 0
src/libraries/cryptolib4pascal/ClpCryptoLibTypes.pas

@@ -207,6 +207,24 @@ type
   TCryptoLibMatrixUInt64Array = array of TCryptoLibUInt64Array;
   TCryptoLibMatrixUInt64Array = array of TCryptoLibUInt64Array;
 {$ENDIF DELPHIXE_UP}
 {$ENDIF DELPHIXE_UP}
 
 
+  TCryptoLibCustomArrayBuffer<T> = record
+  private
+    FData: TCryptoLibGenericArray<T>;
+    FLength: Int32;
+    FIsNil: Boolean;
+
+  public
+    property Data: TCryptoLibGenericArray<T> read FData write FData;
+    property Length: Int32 read FLength write FLength;
+    property IsNil: Boolean read FIsNil write FIsNil;
+  end;
+
+  TCryptoLibCustomByteArrayBuffer = TCryptoLibCustomArrayBuffer<Byte>;
+
+const
+  EmptyBytesNil: TCryptoLibCustomByteArrayBuffer = (FData: Nil; FLength: 0;
+    FIsNil: True);
+
 implementation
 implementation
 
 
 {$IFDEF FPC}
 {$IFDEF FPC}

+ 1378 - 0
src/libraries/cryptolib4pascal/ClpCurve25519Custom.pas

@@ -0,0 +1,1378 @@
+{ *********************************************************************************** }
+{ *                              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 ClpCurve25519Custom;
+
+{$I CryptoLib.inc}
+
+interface
+
+uses
+  ClpECC,
+  ClpIECC,
+  ClpNat,
+  ClpMod,
+  ClpNat256,
+  ClpBigInteger,
+  ClpICurve25519Custom,
+  ClpECCurveConstants,
+  ClpBits,
+  ClpEncoders,
+  ClpArrayUtils,
+  ClpCryptoLibTypes;
+
+resourcestring
+  SInvalidValueForCurve25519FieldElement =
+    'Value Invalid for Curve25519FieldElement "%s"';
+  SOneOfECFieldElementIsNil = 'Exactly One of the Field Elements is Nil';
+
+type
+  // 2^255 - 2^4 - 2^1 - 1
+  TCurve25519Field = class sealed(TObject)
+
+  strict private
+  const
+    P7 = UInt32($7FFFFFFF);
+    PInv = UInt32($13);
+
+    class var
+
+      FP, FPExt: TCryptoLibUInt32Array;
+
+    class function AddPTo(const z: TCryptoLibUInt32Array): UInt32;
+      static; inline;
+
+    class function AddPExtTo(const zz: TCryptoLibUInt32Array): UInt32;
+      static; inline;
+
+    class function SubPFrom(const z: TCryptoLibUInt32Array): Int32;
+      static; inline;
+
+    class function SubPExtFrom(const zz: TCryptoLibUInt32Array): Int32;
+      static; inline;
+
+    class function GetP: TCryptoLibUInt32Array; static; inline;
+
+    class procedure Boot(); static;
+    class constructor Curve25519Field();
+
+  public
+    class procedure Add(const x, y, z: TCryptoLibUInt32Array); static; inline;
+    class procedure AddExt(const xx, yy, zz: TCryptoLibUInt32Array);
+      static; inline;
+    class procedure AddOne(const x, z: TCryptoLibUInt32Array); static; inline;
+    class function FromBigInteger(const x: TBigInteger): TCryptoLibUInt32Array;
+      static; inline;
+    class procedure Half(const x, z: TCryptoLibUInt32Array); static; inline;
+    class procedure Multiply(const x, y, z: TCryptoLibUInt32Array);
+      static; inline;
+    class procedure MultiplyAddToExt(const x, y, zz: TCryptoLibUInt32Array);
+      static; inline;
+    class procedure Negate(const x, z: TCryptoLibUInt32Array); static; inline;
+    class procedure Reduce(const xx, z: TCryptoLibUInt32Array); static; inline;
+    class procedure Reduce27(x: UInt32; const z: TCryptoLibUInt32Array);
+      static; inline;
+    class procedure Square(const x, z: TCryptoLibUInt32Array); static; inline;
+    class procedure SquareN(const x: TCryptoLibUInt32Array; n: Int32;
+      const z: TCryptoLibUInt32Array); static; inline;
+    class procedure Subtract(const x, y, z: TCryptoLibUInt32Array);
+      static; inline;
+    class procedure SubtractExt(const xx, yy, zz: TCryptoLibUInt32Array);
+      static; inline;
+    class procedure Twice(const x, z: TCryptoLibUInt32Array); static; inline;
+
+    class property P: TCryptoLibUInt32Array read GetP;
+
+  end;
+
+type
+  TCurve25519FieldElement = class(TAbstractFpFieldElement,
+    ICurve25519FieldElement)
+
+  strict private
+    class var
+
+      FPRECOMP_POW2: TCryptoLibUInt32Array;
+
+    function Equals(const other: ICurve25519FieldElement): Boolean;
+      reintroduce; overload;
+
+    class function GetQ: TBigInteger; static; inline;
+
+    class procedure Boot(); static;
+    class constructor Curve25519FieldElement();
+
+  strict protected
+  var
+    Fx: TCryptoLibUInt32Array;
+
+    function GetFieldName: string; override;
+    function GetFieldSize: Int32; override;
+    function GetIsOne: Boolean; override;
+    function GetIsZero: Boolean; override;
+
+    function GetX: TCryptoLibUInt32Array; inline;
+    property x: TCryptoLibUInt32Array read GetX;
+
+  public
+    constructor Create(); overload;
+    constructor Create(const x: TBigInteger); overload;
+    constructor Create(const x: TCryptoLibUInt32Array); overload;
+
+    function TestBitZero: Boolean; override;
+    function ToBigInteger(): TBigInteger; override;
+
+    function Add(const b: IECFieldElement): IECFieldElement; override;
+    function AddOne(): IECFieldElement; override;
+    function Subtract(const b: IECFieldElement): IECFieldElement; override;
+
+    function Multiply(const b: IECFieldElement): IECFieldElement; override;
+    function Divide(const b: IECFieldElement): IECFieldElement; override;
+    function Negate(): IECFieldElement; override;
+    function Square(): IECFieldElement; override;
+
+    function Invert(): IECFieldElement; override;
+
+    /// <summary>
+    /// return a sqrt root - the routine verifies that the calculation
+    /// returns the right value - if <br />none exists it returns null.
+    /// </summary>
+    function Sqrt(): IECFieldElement; override;
+
+    function Equals(const other: IECFieldElement): Boolean; overload; override;
+
+    function GetHashCode(): {$IFDEF DELPHI}Int32; {$ELSE}PtrInt;
+{$ENDIF DELPHI}override;
+
+    property IsZero: Boolean read GetIsZero;
+    property IsOne: Boolean read GetIsOne;
+    property FieldName: string read GetFieldName;
+    property FieldSize: Int32 read GetFieldSize;
+
+    class property Q: TBigInteger read GetQ;
+
+  end;
+
+type
+  TCurve25519Point = class sealed(TAbstractFpPoint, ICurve25519Point)
+
+  strict protected
+    function Detach(): IECPoint; override;
+    function CalculateJacobianModifiedW(const z: ICurve25519FieldElement;
+      const ZSquared: TCryptoLibUInt32Array): ICurve25519FieldElement; virtual;
+    function GetJacobianModifiedW(): ICurve25519FieldElement; virtual;
+    function TwiceJacobianModified(calculateW: Boolean)
+      : ICurve25519Point; virtual;
+
+  public
+
+    /// <summary>
+    /// Create a point which encodes without point compression.
+    /// </summary>
+    /// <param name="curve">
+    /// the curve to use
+    /// </param>
+    /// <param name="x">
+    /// affine x co-ordinate
+    /// </param>
+    /// <param name="y">
+    /// affine y co-ordinate
+    /// </param>
+    constructor Create(const curve: IECCurve; const x, y: IECFieldElement);
+      overload; deprecated 'Use ECCurve.createPoint to construct points';
+
+    /// <summary>
+    /// Create a point that encodes with or without point compresion.
+    /// </summary>
+    /// <param name="curve">
+    /// the curve to use
+    /// </param>
+    /// <param name="x">
+    /// affine x co-ordinate
+    /// </param>
+    /// <param name="y">
+    /// affine y co-ordinate
+    /// </param>
+    /// <param name="withCompression">
+    /// if true encode with point compression
+    /// </param>
+    constructor Create(const curve: IECCurve; const x, y: IECFieldElement;
+      withCompression: Boolean); overload;
+      deprecated
+      'Per-point compression property will be removed, see GetEncoded(boolean)';
+
+    constructor Create(const curve: IECCurve; const x, y: IECFieldElement;
+      const zs: TCryptoLibGenericArray<IECFieldElement>;
+      withCompression: Boolean); overload;
+
+    function Add(const b: IECPoint): IECPoint; override;
+    function Negate(): IECPoint; override;
+
+    function Twice(): IECPoint; override;
+    function TwicePlus(const b: IECPoint): IECPoint; override;
+
+    function ThreeTimes(): IECPoint; override;
+
+    function GetZCoord(index: Int32): IECFieldElement; override;
+
+  end;
+
+type
+  TCurve25519 = class sealed(TAbstractFpCurve, ICurve25519)
+
+  strict private
+
+  type
+    TCurve25519LookupTable = class sealed(TInterfacedObject,
+      ICurve25519LookupTable, IECLookupTable)
+
+    strict private
+    var
+      Fm_outer: ICurve25519;
+      Fm_table: TCryptoLibUInt32Array;
+      Fm_size: Int32;
+
+      function GetSize: Int32; virtual;
+
+    public
+
+      constructor Create(const outer: ICurve25519;
+        const table: TCryptoLibUInt32Array; size: Int32);
+
+      function Lookup(index: Int32): IECPoint; virtual;
+
+      property size: Int32 read GetSize;
+
+    end;
+
+  const
+    Curve25519_DEFAULT_COORDS = Int32
+      (TECCurveConstants.COORD_JACOBIAN_MODIFIED);
+    CURVE25519_FE_INTS = Int32(8);
+
+  var
+    Fq: TBigInteger;
+
+    class function GetCurve25519_Q: TBigInteger; static; inline;
+
+  strict protected
+  var
+    Fm_infinity: ICurve25519Point;
+
+    function GetQ: TBigInteger; virtual;
+    function GetFieldSize: Int32; override;
+    function GetInfinity: IECPoint; override;
+
+    function CloneCurve(): IECCurve; override;
+
+    function CreateRawPoint(const x, y: IECFieldElement;
+      withCompression: Boolean): IECPoint; overload; override;
+
+    function CreateRawPoint(const x, y: IECFieldElement;
+      const zs: TCryptoLibGenericArray<IECFieldElement>;
+      withCompression: Boolean): IECPoint; overload; override;
+
+  public
+    constructor Create();
+    function FromBigInteger(const x: TBigInteger): IECFieldElement; override;
+
+    function SupportsCoordinateSystem(coord: Int32): Boolean; override;
+
+    function CreateCacheSafeLookupTable(const points
+      : TCryptoLibGenericArray<IECPoint>; off, len: Int32)
+      : IECLookupTable; override;
+
+    property Q: TBigInteger read GetQ;
+    property Infinity: IECPoint read GetInfinity;
+    property FieldSize: Int32 read GetFieldSize;
+
+    class property Curve25519_Q: TBigInteger read GetCurve25519_Q;
+
+  end;
+
+implementation
+
+{ TCurve25519Field }
+
+class function TCurve25519Field.AddPTo(const z: TCryptoLibUInt32Array): UInt32;
+var
+  c: Int64;
+begin
+  c := Int64(z[0]) - PInv;
+  z[0] := UInt32(c);
+  c := c shr 32;
+  if (c <> 0) then
+  begin
+    c := TNat.DecAt(7, z, 1);
+  end;
+  c := c + (Int64(z[7]) + (P7 + 1));
+  z[7] := UInt32(c);
+  c := c shr 32;
+  result := UInt32(c);
+end;
+
+class function TCurve25519Field.AddPExtTo
+  (const zz: TCryptoLibUInt32Array): UInt32;
+var
+  c: Int64;
+begin
+  c := Int64(zz[0]) + FPExt[0];
+  zz[0] := UInt32(c);
+  c := c shr 32;
+  if (c <> 0) then
+  begin
+    c := TNat.IncAt(8, zz, 1);
+  end;
+  c := c + (Int64(zz[8]) - PInv);
+  zz[8] := UInt32(c);
+  c := c shr 32;
+  if (c <> 0) then
+  begin
+    c := TNat.DecAt(15, zz, 9);
+  end;
+  c := c + (Int64(zz[15]) + (FPExt[15] + 1));
+  zz[15] := UInt32(c);
+  c := c shr 32;
+  result := UInt32(c);
+end;
+
+class function TCurve25519Field.SubPFrom(const z: TCryptoLibUInt32Array): Int32;
+var
+  c: Int64;
+begin
+  c := Int64(z[0]) + PInv;
+  z[0] := UInt32(c);
+  c := c shr 32;
+  if (c <> 0) then
+  begin
+    c := TNat.IncAt(7, z, 1);
+  end;
+  c := c + (Int64(z[7]) - (P7 + 1));
+  z[7] := UInt32(c);
+  c := c shr 32;
+  result := Int32(c);
+end;
+
+class function TCurve25519Field.SubPExtFrom
+  (const zz: TCryptoLibUInt32Array): Int32;
+var
+  c: Int64;
+begin
+  c := Int64(zz[0]) - FPExt[0];
+  zz[0] := UInt32(c);
+  c := c shr 32;
+  if (c <> 0) then
+  begin
+    c := TNat.DecAt(8, zz, 1);
+  end;
+  c := c + (Int64(zz[8]) + PInv);
+  zz[8] := UInt32(c);
+  c := c shr 32;
+  if (c <> 0) then
+  begin
+    c := TNat.IncAt(15, zz, 9);
+  end;
+  c := c + (Int64(zz[15]) - (FPExt[15] + 1));
+  zz[15] := UInt32(c);
+  c := c shr 32;
+  result := Int32(c);
+end;
+
+class constructor TCurve25519Field.Curve25519Field;
+begin
+  TCurve25519Field.Boot;
+end;
+
+class function TCurve25519Field.GetP: TCryptoLibUInt32Array;
+begin
+  result := FP;
+end;
+
+class procedure TCurve25519Field.Add(const x, y, z: TCryptoLibUInt32Array);
+begin
+  TNat256.Add(x, y, z);
+  if (TNat256.Gte(z, P)) then
+  begin
+    SubPFrom(z);
+  end;
+end;
+
+class procedure TCurve25519Field.AddExt(const xx, yy,
+  zz: TCryptoLibUInt32Array);
+begin
+  TNat.Add(16, xx, yy, zz);
+  if (TNat.Gte(16, zz, FPExt)) then
+  begin
+    SubPExtFrom(zz);
+  end;
+end;
+
+class procedure TCurve25519Field.AddOne(const x, z: TCryptoLibUInt32Array);
+begin
+  TNat.Inc(8, x, z);
+  if (TNat256.Gte(z, P)) then
+  begin
+    SubPFrom(z);
+  end;
+end;
+
+class procedure TCurve25519Field.Boot;
+begin
+  FP := TCryptoLibUInt32Array.Create($FFFFFFED, $FFFFFFFF, $FFFFFFFF, $FFFFFFFF,
+    $FFFFFFFF, $FFFFFFFF, $FFFFFFFF, $7FFFFFFF);
+  FPExt := TCryptoLibUInt32Array.Create($00000169, $00000000, $00000000,
+    $00000000, $00000000, $00000000, $00000000, $00000000, $FFFFFFED, $FFFFFFFF,
+    $FFFFFFFF, $FFFFFFFF, $FFFFFFFF, $FFFFFFFF, $FFFFFFFF, $3FFFFFFF);
+end;
+
+class function TCurve25519Field.FromBigInteger(const x: TBigInteger)
+  : TCryptoLibUInt32Array;
+var
+  z: TCryptoLibUInt32Array;
+begin
+  z := TNat256.FromBigInteger(x);
+  while (TNat256.Gte(z, P)) do
+  begin
+    TNat256.SubFrom(P, z);
+  end;
+  result := z;
+end;
+
+class procedure TCurve25519Field.Half(const x, z: TCryptoLibUInt32Array);
+begin
+  if ((x[0] and 1) = 0) then
+  begin
+    TNat.ShiftDownBit(8, x, 0, z);
+  end
+  else
+  begin
+    TNat256.Add(x, P, z);
+    TNat.ShiftDownBit(8, z, 0);
+  end;
+end;
+
+class procedure TCurve25519Field.Reduce(const xx, z: TCryptoLibUInt32Array);
+var
+  xx07, c, z7: UInt32;
+begin
+{$IFDEF DEBUG}
+  System.Assert((xx[15] shr 30) = 0);
+{$ENDIF DEBUG}
+  xx07 := xx[7];
+  TNat.ShiftUpBit(8, xx, 8, xx07, z, 0);
+  c := TNat256.MulByWordAddTo(PInv, xx, z) shl 1;
+  z7 := z[7];
+  c := c + ((z7 shr 31) - (xx07 shr 31));
+  z7 := z7 and P7;
+  z7 := z7 + (TNat.AddWordTo(7, c * PInv, z));
+  z[7] := z7;
+  if ((z7 >= P7) and (TNat256.Gte(z, P))) then
+  begin
+    SubPFrom(z);
+  end;
+end;
+
+class procedure TCurve25519Field.Multiply(const x, y, z: TCryptoLibUInt32Array);
+var
+  tt: TCryptoLibUInt32Array;
+begin
+  tt := TNat256.CreateExt();
+  TNat256.Mul(x, y, tt);
+  Reduce(tt, z);
+end;
+
+class procedure TCurve25519Field.MultiplyAddToExt(const x, y,
+  zz: TCryptoLibUInt32Array);
+begin
+  TNat256.MulAddTo(x, y, zz);
+  if (TNat.Gte(16, zz, FPExt)) then
+  begin
+    SubPExtFrom(zz);
+  end;
+end;
+
+class procedure TCurve25519Field.Negate(const x, z: TCryptoLibUInt32Array);
+begin
+  if (TNat256.IsZero(x)) then
+  begin
+    TNat256.Zero(z);
+  end
+  else
+  begin
+    TNat256.Sub(P, x, z);
+  end;
+end;
+
+class procedure TCurve25519Field.Reduce27(x: UInt32;
+  const z: TCryptoLibUInt32Array);
+var
+  z7, c: UInt32;
+begin
+{$IFDEF DEBUG}
+  System.Assert(((x shr 26) = 0));
+{$ENDIF DEBUG}
+  z7 := z[7];
+  c := ((x shl 1) or (z7 shr 31));
+  z7 := z7 and P7;
+  z7 := z7 + (TNat.AddWordTo(7, c * PInv, z));
+  z[7] := z7;
+  if ((z7 >= P7) and (TNat256.Gte(z, P))) then
+  begin
+    SubPFrom(z);
+  end;
+end;
+
+class procedure TCurve25519Field.Square(const x, z: TCryptoLibUInt32Array);
+var
+  tt: TCryptoLibUInt32Array;
+begin
+  tt := TNat256.CreateExt();
+  TNat256.Square(x, tt);
+  Reduce(tt, z);
+end;
+
+class procedure TCurve25519Field.SquareN(const x: TCryptoLibUInt32Array;
+  n: Int32; const z: TCryptoLibUInt32Array);
+var
+  tt: TCryptoLibUInt32Array;
+begin
+{$IFDEF DEBUG}
+  System.Assert(n > 0);
+{$ENDIF DEBUG}
+  tt := TNat256.CreateExt();
+  TNat256.Square(x, tt);
+  Reduce(tt, z);
+  System.Dec(n);
+  while (n > 0) do
+  begin
+    TNat256.Square(z, tt);
+    Reduce(tt, z);
+    System.Dec(n);
+  end;
+end;
+
+class procedure TCurve25519Field.Subtract(const x, y, z: TCryptoLibUInt32Array);
+var
+  c: Int32;
+begin
+  c := TNat256.Sub(x, y, z);
+  if (c <> 0) then
+  begin
+    AddPTo(z);
+  end;
+end;
+
+class procedure TCurve25519Field.SubtractExt(const xx, yy,
+  zz: TCryptoLibUInt32Array);
+var
+  c: Int32;
+begin
+  c := TNat.Sub(16, xx, yy, zz);
+  if (c <> 0) then
+  begin
+    AddPExtTo(zz);
+  end;
+end;
+
+class procedure TCurve25519Field.Twice(const x, z: TCryptoLibUInt32Array);
+begin
+  TNat.ShiftUpBit(8, x, 0, z);
+  if (TNat256.Gte(z, P)) then
+  begin
+    SubPFrom(z);
+  end;
+end;
+
+{ TCurve25519FieldElement }
+
+class function TCurve25519FieldElement.GetQ: TBigInteger;
+begin
+  result := TCurve25519.Curve25519_Q;
+end;
+
+class procedure TCurve25519FieldElement.Boot;
+begin
+  // Calculated as TBigInteger.ValueOf(2).modPow(Q.shiftRight(2), Q)
+  FPRECOMP_POW2 := TCryptoLibUInt32Array.Create($4A0EA0B0, $C4EE1B27, $AD2FE478,
+    $2F431806, $3DFBD7A7, $2B4D0099, $4FC1DF0B, $2B832480);
+end;
+
+class constructor TCurve25519FieldElement.Curve25519FieldElement;
+begin
+  TCurve25519FieldElement.Boot();
+end;
+
+function TCurve25519FieldElement.GetX: TCryptoLibUInt32Array;
+begin
+  result := Fx;
+end;
+
+constructor TCurve25519FieldElement.Create;
+begin
+  Inherited Create();
+  Fx := TNat256.Create();
+end;
+
+constructor TCurve25519FieldElement.Create(const x: TBigInteger);
+begin
+  if ((not(x.IsInitialized)) or (x.SignValue < 0) or (x.CompareTo(Q) >= 0)) then
+  begin
+    raise EArgumentCryptoLibException.CreateResFmt
+      (@SInvalidValueForCurve25519FieldElement, ['x']);
+  end;
+  Inherited Create();
+  Fx := TCurve25519Field.FromBigInteger(x);
+end;
+
+constructor TCurve25519FieldElement.Create(const x: TCryptoLibUInt32Array);
+begin
+  Inherited Create();
+  Fx := x;
+end;
+
+function TCurve25519FieldElement.GetFieldName: string;
+begin
+  result := 'Curve25519Field';
+end;
+
+function TCurve25519FieldElement.GetFieldSize: Int32;
+begin
+  result := Q.BitLength;
+end;
+
+function TCurve25519FieldElement.GetHashCode: {$IFDEF DELPHI}Int32; {$ELSE}PtrInt;
+{$ENDIF DELPHI}
+begin
+  result := Q.GetHashCode() xor TArrayUtils.GetArrayHashCode(Fx, 0, 8);
+end;
+
+function TCurve25519FieldElement.GetIsOne: Boolean;
+begin
+  result := TNat256.IsOne(Fx);
+end;
+
+function TCurve25519FieldElement.GetIsZero: Boolean;
+begin
+  result := TNat256.IsZero(Fx);
+end;
+
+function TCurve25519FieldElement.Invert: IECFieldElement;
+var
+  z: TCryptoLibUInt32Array;
+begin
+  z := TNat256.Create();
+  TMod.Invert(TCurve25519Field.P, Fx, z);
+  result := TCurve25519FieldElement.Create(z);
+end;
+
+function TCurve25519FieldElement.Multiply(const b: IECFieldElement)
+  : IECFieldElement;
+var
+  z: TCryptoLibUInt32Array;
+begin
+  z := TNat256.Create();
+  TCurve25519Field.Multiply(Fx, (b as ICurve25519FieldElement).x, z);
+  result := TCurve25519FieldElement.Create(z);
+end;
+
+function TCurve25519FieldElement.Negate: IECFieldElement;
+var
+  z: TCryptoLibUInt32Array;
+begin
+  z := TNat256.Create();
+  TCurve25519Field.Negate(Fx, z);
+  result := TCurve25519FieldElement.Create(z);
+end;
+
+function TCurve25519FieldElement.Sqrt: IECFieldElement;
+var
+  x1, x2, x3, x4, x7, x11, x15, x30, x60, x120, x131, x251, t1,
+    t2: TCryptoLibUInt32Array;
+begin
+
+  (*
+    * Q == 8m + 5, so we use Pocklington's method for this case.
+    *
+    * First, raise this element to the exponent 2^252 - 2^1 (i.e. m + 1)
+    * 
+    * Breaking up the exponent's binary representation into "repunits", we get:
+    * { 251 1s } { 1 0s }
+    * 
+    * Therefore we need an addition chain containing 251 (the lengths of the repunits)
+    * We use: 1, 2, 3, 4, 7, 11, 15, 30, 60, 120, 131, [251]
+  *)
+
+  x1 := Fx;
+  if ((TNat256.IsZero(x1)) or (TNat256.IsOne(x1))) then
+  begin
+    result := Self as IECFieldElement;
+    Exit;
+  end;
+
+  x2 := TNat256.Create();
+  TCurve25519Field.Square(x1, x2);
+  TCurve25519Field.Multiply(x2, x1, x2);
+  x3 := x2;
+  TCurve25519Field.Square(x2, x3);
+  TCurve25519Field.Multiply(x3, x1, x3);
+  x4 := TNat256.Create();
+  TCurve25519Field.Square(x3, x4);
+  TCurve25519Field.Multiply(x4, x1, x4);
+  x7 := TNat256.Create();
+  TCurve25519Field.SquareN(x4, 3, x7);
+  TCurve25519Field.Multiply(x7, x3, x7);
+  x11 := x3;
+  TCurve25519Field.SquareN(x7, 4, x11);
+  TCurve25519Field.Multiply(x11, x4, x11);
+  x15 := x7;
+  TCurve25519Field.SquareN(x11, 4, x15);
+  TCurve25519Field.Multiply(x15, x4, x15);
+  x30 := x4;
+  TCurve25519Field.SquareN(x15, 15, x30);
+  TCurve25519Field.Multiply(x30, x15, x30);
+  x60 := x15;
+  TCurve25519Field.SquareN(x30, 30, x60);
+  TCurve25519Field.Multiply(x60, x30, x60);
+  x120 := x30;
+  TCurve25519Field.SquareN(x60, 60, x120);
+  TCurve25519Field.Multiply(x120, x60, x120);
+  x131 := x60;
+  TCurve25519Field.SquareN(x120, 11, x131);
+  TCurve25519Field.Multiply(x131, x11, x131);
+  x251 := x11;
+  TCurve25519Field.SquareN(x131, 120, x251);
+  TCurve25519Field.Multiply(x251, x120, x251);
+
+  t1 := x251;
+  TCurve25519Field.Square(t1, t1);
+
+  t2 := x120;
+  TCurve25519Field.Square(t1, t2);
+
+  if (TNat256.Eq(x1, t2)) then
+  begin
+    result := TCurve25519FieldElement.Create(t1);
+    Exit;
+  end;
+
+  (*
+    * If the first guess is incorrect, we multiply by a precomputed power of 2 to get the second guess,
+    * which is ((4x)^(m + 1))/2 mod Q
+  *)
+  TCurve25519Field.Multiply(t1, FPRECOMP_POW2, t1);
+
+  TCurve25519Field.Square(t1, t2);
+
+  if (TNat256.Eq(x1, t2)) then
+  begin
+    result := TCurve25519FieldElement.Create(t1);
+    Exit;
+  end;
+
+  result := Nil;
+
+end;
+
+function TCurve25519FieldElement.Square: IECFieldElement;
+var
+  z: TCryptoLibUInt32Array;
+begin
+  z := TNat256.Create();
+  TCurve25519Field.Square(Fx, z);
+  result := TCurve25519FieldElement.Create(z);
+end;
+
+function TCurve25519FieldElement.Subtract(const b: IECFieldElement)
+  : IECFieldElement;
+var
+  z: TCryptoLibUInt32Array;
+begin
+  z := TNat256.Create();
+  TCurve25519Field.Subtract(Fx, (b as ICurve25519FieldElement).x, z);
+  result := TCurve25519FieldElement.Create(z);
+end;
+
+function TCurve25519FieldElement.TestBitZero: Boolean;
+begin
+  result := TNat256.GetBit(Fx, 0) = 1;
+end;
+
+function TCurve25519FieldElement.ToBigInteger: TBigInteger;
+begin
+  result := TNat256.ToBigInteger(Fx);
+end;
+
+function TCurve25519FieldElement.Add(const b: IECFieldElement): IECFieldElement;
+var
+  z: TCryptoLibUInt32Array;
+begin
+  z := TNat256.Create();
+  TCurve25519Field.Add(x, (b as ICurve25519FieldElement).x, z);
+  result := TCurve25519FieldElement.Create(z);
+end;
+
+function TCurve25519FieldElement.AddOne: IECFieldElement;
+var
+  z: TCryptoLibUInt32Array;
+begin
+  z := TNat256.Create();
+  TCurve25519Field.AddOne(Fx, z);
+  result := TCurve25519FieldElement.Create(z);
+end;
+
+function TCurve25519FieldElement.Divide(const b: IECFieldElement)
+  : IECFieldElement;
+var
+  z: TCryptoLibUInt32Array;
+begin
+  z := TNat256.Create();
+  TMod.Invert(TCurve25519Field.P, (b as ICurve25519FieldElement).x, z);
+  TCurve25519Field.Multiply(z, Fx, z);
+  result := TCurve25519FieldElement.Create(z);
+end;
+
+function TCurve25519FieldElement.Equals(const other
+  : ICurve25519FieldElement): Boolean;
+begin
+  if ((Self as ICurve25519FieldElement) = other) then
+  begin
+    result := true;
+    Exit;
+  end;
+  if (other = Nil) then
+  begin
+    result := false;
+    Exit;
+  end;
+  result := TNat256.Eq(Fx, other.x);
+end;
+
+function TCurve25519FieldElement.Equals(const other: IECFieldElement): Boolean;
+begin
+  result := Equals(other as ICurve25519FieldElement);
+end;
+
+{ TCurve25519Point }
+
+function TCurve25519Point.Detach: IECPoint;
+begin
+  result := TCurve25519Point.Create(Nil, AffineXCoord, AffineYCoord);
+end;
+
+function TCurve25519Point.CalculateJacobianModifiedW
+  (const z: ICurve25519FieldElement; const ZSquared: TCryptoLibUInt32Array)
+  : ICurve25519FieldElement;
+var
+  a4, W: ICurve25519FieldElement;
+  LZSquared: TCryptoLibUInt32Array;
+begin
+  a4 := curve.A as ICurve25519FieldElement;
+  if (z.IsOne) then
+  begin
+    result := a4;
+    Exit;
+  end;
+
+  W := TCurve25519FieldElement.Create();
+  LZSquared := ZSquared;
+  if (LZSquared = Nil) then
+  begin
+    LZSquared := W.x;
+    TCurve25519Field.Square(z.x, LZSquared);
+  end;
+  TCurve25519Field.Square(LZSquared, W.x);
+  TCurve25519Field.Multiply(W.x, a4.x, W.x);
+  result := W;
+end;
+
+function TCurve25519Point.GetJacobianModifiedW: ICurve25519FieldElement;
+var
+  zz: TCryptoLibGenericArray<IECFieldElement>;
+  W: ICurve25519FieldElement;
+begin
+  zz := RawZCoords;
+  W := zz[1] as ICurve25519FieldElement;
+  if (W = Nil) then
+  begin
+    // NOTE: Rarely, TwicePlus will result in the need for a lazy W1 calculation here
+    W := CalculateJacobianModifiedW(zz[0] as ICurve25519FieldElement, Nil);
+    zz[1] := W;
+  end;
+  result := W;
+end;
+
+function TCurve25519Point.TwiceJacobianModified(calculateW: Boolean)
+  : ICurve25519Point;
+var
+  x1, Y1, Z1, W1, x3, Y3, Z3, W3: ICurve25519FieldElement;
+  c: UInt32;
+  M, _2Y1, _2Y1Squared, S, _8T: TCryptoLibUInt32Array;
+begin
+  x1 := RawXCoord as ICurve25519FieldElement;
+  Y1 := RawYCoord as ICurve25519FieldElement;
+  Z1 := RawZCoords[0] as ICurve25519FieldElement;
+  W1 := GetJacobianModifiedW();
+
+  M := TNat256.Create();
+  TCurve25519Field.Square(x1.x, M);
+  c := TNat256.AddBothTo(M, M, M);
+  c := c + TNat256.AddTo(W1.x, M);
+  TCurve25519Field.Reduce27(c, M);
+
+  _2Y1 := TNat256.Create();
+  TCurve25519Field.Twice(Y1.x, _2Y1);
+
+  _2Y1Squared := TNat256.Create();
+  TCurve25519Field.Multiply(_2Y1, Y1.x, _2Y1Squared);
+
+  S := TNat256.Create();
+  TCurve25519Field.Multiply(_2Y1Squared, x1.x, S);
+  TCurve25519Field.Twice(S, S);
+
+  _8T := TNat256.Create();
+  TCurve25519Field.Square(_2Y1Squared, _8T);
+  TCurve25519Field.Twice(_8T, _8T);
+
+  x3 := TCurve25519FieldElement.Create(_2Y1Squared);
+  TCurve25519Field.Square(M, x3.x);
+  TCurve25519Field.Subtract(x3.x, S, x3.x);
+  TCurve25519Field.Subtract(x3.x, S, x3.x);
+
+  Y3 := TCurve25519FieldElement.Create(S);
+  TCurve25519Field.Subtract(S, x3.x, Y3.x);
+  TCurve25519Field.Multiply(Y3.x, M, Y3.x);
+  TCurve25519Field.Subtract(Y3.x, _8T, Y3.x);
+
+  Z3 := TCurve25519FieldElement.Create(_2Y1);
+  if (not(TNat256.IsOne(Z1.x))) then
+  begin
+    TCurve25519Field.Multiply(Z3.x, Z1.x, Z3.x);
+  end;
+
+  W3 := Nil;
+  if (calculateW) then
+  begin
+    W3 := TCurve25519FieldElement.Create(_8T);
+    TCurve25519Field.Multiply(W3.x, W1.x, W3.x);
+    TCurve25519Field.Twice(W3.x, W3.x);
+  end;
+
+  result := TCurve25519Point.Create(curve, x3, Y3,
+    TCryptoLibGenericArray<IECFieldElement>.Create(Z3, W3), IsCompressed);
+end;
+
+function TCurve25519Point.GetZCoord(index: Int32): IECFieldElement;
+begin
+  if (index = 1) then
+  begin
+    result := GetJacobianModifiedW();
+    Exit;
+  end;
+
+  result := Inherited GetZCoord(index);
+end;
+
+function TCurve25519Point.Add(const b: IECPoint): IECPoint;
+var
+  LCurve: IECCurve;
+  x1, Y1, Z1, x2, Y2, Z2, x3, Y3, Z3, W3: ICurve25519FieldElement;
+  c: UInt32;
+  tt1, t2, t3, t4, U2, S2, U1, S1, H, R, G, V, HSquared,
+    Z3Squared: TCryptoLibUInt32Array;
+  zs: TCryptoLibGenericArray<IECFieldElement>;
+  Z1IsOne, Z2IsOne: Boolean;
+begin
+  if (IsInfinity) then
+  begin
+    result := b;
+    Exit;
+  end;
+  if (b.IsInfinity) then
+  begin
+    result := Self;
+    Exit;
+  end;
+  if ((Self as IECPoint) = b) then
+  begin
+    result := Twice();
+    Exit;
+  end;
+
+  LCurve := curve;
+
+  x1 := RawXCoord as ICurve25519FieldElement;
+  Y1 := RawYCoord as ICurve25519FieldElement;
+  Z1 := RawZCoords[0] as ICurve25519FieldElement;
+  x2 := b.RawXCoord as ICurve25519FieldElement;
+  Y2 := b.RawYCoord as ICurve25519FieldElement;
+  Z2 := b.RawZCoords[0] as ICurve25519FieldElement;
+
+  tt1 := TNat256.CreateExt();
+  t2 := TNat256.Create();
+  t3 := TNat256.Create();
+  t4 := TNat256.Create();
+
+  Z1IsOne := Z1.IsOne;
+  if (Z1IsOne) then
+  begin
+    U2 := x2.x;
+    S2 := Y2.x;
+  end
+  else
+  begin
+    S2 := t3;
+    TCurve25519Field.Square(Z1.x, S2);
+
+    U2 := t2;
+    TCurve25519Field.Multiply(S2, x2.x, U2);
+
+    TCurve25519Field.Multiply(S2, Z1.x, S2);
+    TCurve25519Field.Multiply(S2, Y2.x, S2);
+  end;
+
+  Z2IsOne := Z2.IsOne;
+
+  if (Z2IsOne) then
+  begin
+    U1 := x1.x;
+    S1 := Y1.x;
+  end
+  else
+  begin
+    S1 := t4;
+    TCurve25519Field.Square(Z2.x, S1);
+
+    U1 := tt1;
+    TCurve25519Field.Multiply(S1, x1.x, U1);
+
+    TCurve25519Field.Multiply(S1, Z2.x, S1);
+    TCurve25519Field.Multiply(S1, Y1.x, S1);
+  end;
+
+  H := TNat256.Create();
+  TCurve25519Field.Subtract(U1, U2, H);
+
+  R := t2;
+  TCurve25519Field.Subtract(S1, S2, R);
+
+  // Check if b = Self or b = -Self
+  if (TNat256.IsZero(H)) then
+  begin
+    if (TNat256.IsZero(R)) then
+    begin
+      // this == b, i.e. this must be doubled
+      result := Twice();
+      Exit;
+    end;
+
+    // Self = -b, i.e. the result is the point at infinity
+    result := LCurve.Infinity;
+    Exit;
+  end;
+
+  HSquared := TNat256.Create();
+  TCurve25519Field.Square(H, HSquared);
+
+  G := TNat256.Create();
+  TCurve25519Field.Multiply(HSquared, H, G);
+
+  V := t3;
+  TCurve25519Field.Multiply(HSquared, U1, V);
+
+  TCurve25519Field.Negate(G, G);
+  TNat256.Mul(S1, G, tt1);
+
+  c := TNat256.AddBothTo(V, V, G);
+  TCurve25519Field.Reduce27(c, G);
+
+  x3 := TCurve25519FieldElement.Create(t4);
+  TCurve25519Field.Square(R, x3.x);
+  TCurve25519Field.Subtract(x3.x, G, x3.x);
+
+  Y3 := TCurve25519FieldElement.Create(G);
+  TCurve25519Field.Subtract(V, x3.x, Y3.x);
+  TCurve25519Field.MultiplyAddToExt(Y3.x, R, tt1);
+  TCurve25519Field.Reduce(tt1, Y3.x);
+
+  Z3 := TCurve25519FieldElement.Create(H);
+  if (not(Z1IsOne)) then
+  begin
+    TCurve25519Field.Multiply(Z3.x, Z1.x, Z3.x);
+  end;
+  if (not(Z2IsOne)) then
+  begin
+    TCurve25519Field.Multiply(Z3.x, Z2.x, Z3.x);
+  end;
+
+  if ((Z1IsOne) and (Z2IsOne)) then
+  begin
+    Z3Squared := HSquared;
+  end
+  else
+  begin
+    Z3Squared := Nil;
+  end;
+
+  // TODO If the result will only be used in a subsequent addition, we don't need W3
+  W3 := CalculateJacobianModifiedW(Z3, Z3Squared);
+
+  zs := TCryptoLibGenericArray<IECFieldElement>.Create(Z3, W3);
+
+  result := TCurve25519Point.Create(LCurve, x3, Y3, zs, IsCompressed);
+end;
+
+constructor TCurve25519Point.Create(const curve: IECCurve;
+  const x, y: IECFieldElement;
+  const zs: TCryptoLibGenericArray<IECFieldElement>; withCompression: Boolean);
+begin
+  Inherited Create(curve, x, y, zs, withCompression);
+end;
+
+constructor TCurve25519Point.Create(const curve: IECCurve;
+  const x, y: IECFieldElement; withCompression: Boolean);
+begin
+  Inherited Create(curve, x, y, withCompression);
+  if ((x = Nil) <> (y = Nil)) then
+  begin
+    raise EArgumentCryptoLibException.CreateRes(@SOneOfECFieldElementIsNil);
+  end;
+end;
+
+constructor TCurve25519Point.Create(const curve: IECCurve;
+  const x, y: IECFieldElement);
+begin
+  Create(curve, x, y, false);
+end;
+
+function TCurve25519Point.Negate: IECPoint;
+begin
+  if (IsInfinity) then
+  begin
+    result := Self;
+    Exit;
+  end;
+
+  result := TCurve25519Point.Create(curve, RawXCoord, RawYCoord.Negate(),
+    RawZCoords, IsCompressed);
+end;
+
+function TCurve25519Point.ThreeTimes: IECPoint;
+begin
+  if ((IsInfinity) or (RawYCoord.IsZero)) then
+  begin
+    result := Self;
+    Exit;
+  end;
+
+  result := TwiceJacobianModified(false).Add(Self as ICurve25519Point);
+end;
+
+function TCurve25519Point.Twice: IECPoint;
+var
+  LCurve: IECCurve;
+  Y1: IECFieldElement;
+begin
+  if (IsInfinity) then
+  begin
+    result := Self;
+    Exit;
+  end;
+
+  LCurve := curve;
+
+  Y1 := RawYCoord;
+  if (Y1.IsZero) then
+  begin
+    result := LCurve.Infinity;
+    Exit;
+  end;
+
+  result := TwiceJacobianModified(true);
+end;
+
+function TCurve25519Point.TwicePlus(const b: IECPoint): IECPoint;
+var
+  Y1: IECFieldElement;
+begin
+  if ((Self as IECPoint) = b) then
+  begin
+    result := ThreeTimes();
+    Exit;
+  end;
+  if (IsInfinity) then
+  begin
+    result := b;
+    Exit;
+  end;
+  if (b.IsInfinity) then
+  begin
+    result := Twice();
+    Exit;
+  end;
+
+  Y1 := RawYCoord;
+  if (Y1.IsZero) then
+  begin
+    result := b;
+    Exit;
+  end;
+
+  result := TwiceJacobianModified(false).Add(b);
+end;
+
+{ TCurve25519 }
+
+class function TCurve25519.GetCurve25519_Q: TBigInteger;
+begin
+  result := TNat256.ToBigInteger(TCurve25519Field.P);
+end;
+
+constructor TCurve25519.Create;
+begin
+  Fq := Curve25519_Q;
+  Inherited Create(Fq);
+  Fm_infinity := TCurve25519Point.Create(Self as IECCurve, Nil, Nil);
+
+  Fm_a := FromBigInteger(TBigInteger.Create(1,
+    THex.Decode
+    ('2AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA984914A144')));
+  Fm_b := FromBigInteger(TBigInteger.Create(1,
+    THex.Decode
+    ('7B425ED097B425ED097B425ED097B425ED097B425ED097B4260B5E9C7710C864')));
+  Fm_order := TBigInteger.Create(1,
+    THex.Decode
+    ('1000000000000000000000000000000014DEF9DEA2F79CD65812631A5CF5D3ED'));
+  Fm_cofactor := TBigInteger.ValueOf(8);
+  Fm_coord := Curve25519_DEFAULT_COORDS;
+end;
+
+function TCurve25519.CloneCurve: IECCurve;
+begin
+  result := TCurve25519.Create();
+end;
+
+function TCurve25519.CreateCacheSafeLookupTable(const points
+  : TCryptoLibGenericArray<IECPoint>; off, len: Int32): IECLookupTable;
+var
+  table: TCryptoLibUInt32Array;
+  pos, i: Int32;
+  P: IECPoint;
+begin
+  System.SetLength(table, len * CURVE25519_FE_INTS * 2);
+
+  pos := 0;
+  for i := 0 to System.Pred(len) do
+  begin
+    P := points[off + i];
+    TNat256.Copy((P.RawXCoord as ICurve25519FieldElement).x, 0, table, pos);
+    pos := pos + CURVE25519_FE_INTS;
+    TNat256.Copy((P.RawYCoord as ICurve25519FieldElement).x, 0, table, pos);
+    pos := pos + CURVE25519_FE_INTS;
+  end;
+
+  result := TCurve25519LookupTable.Create(Self as ICurve25519, table, len);
+end;
+
+function TCurve25519.CreateRawPoint(const x, y: IECFieldElement;
+  withCompression: Boolean): IECPoint;
+begin
+  result := TCurve25519Point.Create(Self as IECCurve, x, y, withCompression);
+end;
+
+function TCurve25519.CreateRawPoint(const x, y: IECFieldElement;
+  const zs: TCryptoLibGenericArray<IECFieldElement>; withCompression: Boolean)
+  : IECPoint;
+begin
+  result := TCurve25519Point.Create(Self as IECCurve, x, y, zs,
+    withCompression);
+end;
+
+function TCurve25519.FromBigInteger(const x: TBigInteger): IECFieldElement;
+begin
+  result := TCurve25519FieldElement.Create(x);
+end;
+
+function TCurve25519.GetFieldSize: Int32;
+begin
+  result := Fq.BitLength;
+end;
+
+function TCurve25519.GetInfinity: IECPoint;
+begin
+  result := Fm_infinity;
+end;
+
+function TCurve25519.GetQ: TBigInteger;
+begin
+  result := Fq;
+end;
+
+function TCurve25519.SupportsCoordinateSystem(coord: Int32): Boolean;
+begin
+  case coord of
+    TECCurveConstants.COORD_JACOBIAN_MODIFIED:
+      result := true
+  else
+    result := false;
+  end;
+end;
+
+{ TCurve25519.TCurve25519LookupTable }
+
+constructor TCurve25519.TCurve25519LookupTable.Create(const outer: ICurve25519;
+  const table: TCryptoLibUInt32Array; size: Int32);
+begin
+  Inherited Create();
+  Fm_outer := outer;
+  Fm_table := table;
+  Fm_size := size;
+end;
+
+function TCurve25519.TCurve25519LookupTable.GetSize: Int32;
+begin
+  result := Fm_size;
+end;
+
+function TCurve25519.TCurve25519LookupTable.Lookup(index: Int32): IECPoint;
+var
+  x, y: TCryptoLibUInt32Array;
+  pos, i, J: Int32;
+  MASK: UInt32;
+begin
+  x := TNat256.Create();
+  y := TNat256.Create();
+  pos := 0;
+
+  for i := 0 to System.Pred(Fm_size) do
+  begin
+    MASK := UInt32(TBits.Asr32((i xor index) - 1, 31));
+
+    for J := 0 to System.Pred(CURVE25519_FE_INTS) do
+    begin
+      x[J] := x[J] xor (Fm_table[pos + J] and MASK);
+      y[J] := y[J] xor (Fm_table[pos + CURVE25519_FE_INTS + J] and MASK);
+    end;
+
+    pos := pos + (CURVE25519_FE_INTS * 2);
+  end;
+
+  result := Fm_outer.CreateRawPoint(TCurve25519FieldElement.Create(x)
+    as ICurve25519FieldElement, TCurve25519FieldElement.Create(y)
+    as ICurve25519FieldElement, false);
+end;
+
+end.

+ 66 - 12
src/libraries/cryptolib4pascal/ClpCustomNamedCurves.pas

@@ -41,6 +41,8 @@ uses
   ClpISecP521R1Custom,
   ClpISecP521R1Custom,
   ClpSecT283Custom,
   ClpSecT283Custom,
   ClpISecT283Custom,
   ClpISecT283Custom,
+  ClpCurve25519Custom,
+  ClpICurve25519Custom,
   ClpIECC,
   ClpIECC,
   ClpX9ECC,
   ClpX9ECC,
   ClpIX9ECC,
   ClpIX9ECC,
@@ -67,8 +69,8 @@ type
 
 
     class function GetNames: TCryptoLibStringArray; static; inline;
     class function GetNames: TCryptoLibStringArray; static; inline;
 
 
-    // class procedure DefineCurve(const name: String;
-    // const holder: IX9ECParametersHolder); static; inline;
+    class procedure DefineCurve(const name: String;
+      const holder: IX9ECParametersHolder); static; inline;
 
 
     class procedure DefineCurveWithOid(const name: String;
     class procedure DefineCurveWithOid(const name: String;
       const oid: IDerObjectIdentifier; const holder: IX9ECParametersHolder);
       const oid: IDerObjectIdentifier; const holder: IX9ECParametersHolder);
@@ -116,6 +118,22 @@ type
     // */
     // */
     class property Names: TCryptoLibStringArray read GetNames;
     class property Names: TCryptoLibStringArray read GetNames;
 
 
+  type
+
+    /// <summary>
+    /// curve25519
+    /// </summary>
+    TCurve25519Holder = class sealed(TX9ECParametersHolder,
+      IX9ECParametersHolder)
+
+    strict protected
+      function CreateParameters(): IX9ECParameters; override;
+
+    public
+      class function Instance(): IX9ECParametersHolder; static;
+
+    end;
+
   type
   type
 
 
     /// <summary>
     /// <summary>
@@ -202,16 +220,16 @@ implementation
 
 
 { TCustomNamedCurves }
 { TCustomNamedCurves }
 
 
-// class procedure TCustomNamedCurves.DefineCurve(const name: String;
-// const holder: IX9ECParametersHolder);
-// var
-// LName: string;
-// begin
-// LName := name;
-// Fnames.Add(LName);
-// LName := UpperCase(LName);
-// FnameToCurve.Add(LName, holder);
-// end;
+class procedure TCustomNamedCurves.DefineCurve(const name: String;
+  const holder: IX9ECParametersHolder);
+var
+  LName: string;
+begin
+  LName := name;
+  Fnames.Add(LName);
+  LName := UpperCase(LName);
+  FnameToCurve.Add(LName, holder);
+end;
 
 
 class procedure TCustomNamedCurves.DefineCurveWithOid(const name: String;
 class procedure TCustomNamedCurves.DefineCurveWithOid(const name: String;
   const oid: IDerObjectIdentifier; const holder: IX9ECParametersHolder);
   const oid: IDerObjectIdentifier; const holder: IX9ECParametersHolder);
@@ -335,6 +353,8 @@ begin
 
 
   Fnames := TList<String>.Create();
   Fnames := TList<String>.Create();
 
 
+  DefineCurve('curve25519', TCurve25519Holder.Instance);
+
   DefineCurveWithOid('secp256k1', TSecObjectIdentifiers.SecP256k1,
   DefineCurveWithOid('secp256k1', TSecObjectIdentifiers.SecP256k1,
     TSecP256K1Holder.Instance);
     TSecP256K1Holder.Instance);
 
 
@@ -357,6 +377,40 @@ begin
   DefineCurveAlias('P-521', TSecObjectIdentifiers.SecP521r1);
   DefineCurveAlias('P-521', TSecObjectIdentifiers.SecP521r1);
 end;
 end;
 
 
+{ TCustomNamedCurves.TCurve25519Holder }
+
+function TCustomNamedCurves.TCurve25519Holder.CreateParameters: IX9ECParameters;
+var
+  curve: IECCurve;
+  G: IX9ECPoint;
+  S: TCryptoLibByteArray;
+begin
+  S := Nil;
+  curve := ConfigureCurve(TCurve25519.Create() as ICurve25519);
+
+  { *
+    * NOTE: Curve25519 was specified in Montgomery form. Rewriting in Weierstrass form
+    * involves substitution of variables, so the base-point x coordinate is 9 + (486662 / 3).
+    *
+    * The Curve25519 paper doesn't say which of the two possible y values the base
+    * point has. The choice here is guided by language in the Ed25519 paper.
+    *
+    * (The other possible y value is 5F51E65E475F794B1FE122D388B72EB36DC2B28192839E4DD6163A5D81312C14)
+    * }
+  G := TX9ECPoint.Create(curve,
+    THex.Decode('04' +
+    '2AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD245A' +
+    '20AE19A1B8A086B4E01EDD2C7748D14C923D4D7E6D7C61B229E9C5A27ECED3D9'));
+
+  result := TX9ECParameters.Create(curve, G, curve.Order, curve.Cofactor, S);
+end;
+
+class function TCustomNamedCurves.TCurve25519Holder.Instance
+  : IX9ECParametersHolder;
+begin
+  result := TCurve25519Holder.Create();
+end;
+
 { TCustomNamedCurves.TSecP256K1Holder }
 { TCustomNamedCurves.TSecP256K1Holder }
 
 
 function TCustomNamedCurves.TSecP256K1Holder.CreateParameters: IX9ECParameters;
 function TCustomNamedCurves.TSecP256K1Holder.CreateParameters: IX9ECParameters;

+ 44 - 5
src/libraries/cryptolib4pascal/ClpDigest.pas

@@ -21,7 +21,9 @@ unit ClpDigest;
 interface
 interface
 
 
 uses
 uses
+  SysUtils,
   HlpIHash,
   HlpIHash,
+  HlpIHashInfo,
   ClpIDigest,
   ClpIDigest,
   ClpCryptoLibTypes;
   ClpCryptoLibTypes;
 
 
@@ -44,7 +46,7 @@ type
     function DoFinal: TCryptoLibByteArray; overload;
     function DoFinal: TCryptoLibByteArray; overload;
 
 
   public
   public
-    constructor Create(const hash: IHash);
+    constructor Create(const hash: IHash; doInitialize: Boolean = True);
 
 
     /// <summary>
     /// <summary>
     /// Gets the Underlying <b>IHash</b> Instance
     /// Gets the Underlying <b>IHash</b> Instance
@@ -98,6 +100,11 @@ type
     /// </summary>
     /// </summary>
     procedure Reset();
     procedure Reset();
 
 
+    /// <summary>
+    /// Clone the digest instance
+    /// </summary>
+    function Clone(): IDigest;
+
     /// <summary>
     /// <summary>
     /// the algorithm name
     /// the algorithm name
     /// </summary>
     /// </summary>
@@ -110,8 +117,19 @@ implementation
 { TDigest }
 { TDigest }
 
 
 function TDigest.GetAlgorithmName: string;
 function TDigest.GetAlgorithmName: string;
+var
+  LName: String;
+  LowPoint, HighPoint: Int32;
 begin
 begin
-  result := FHash.Name;
+  LName := FHash.Name;
+{$IFDEF DELPHIXE3_UP}
+  LowPoint := System.Low(LName);
+  HighPoint := System.High(LName);
+{$ELSE}
+  LowPoint := 1;
+  HighPoint := System.Length(LName);
+{$ENDIF DELPHIXE3_UP}
+  result := Copy(LName, LowPoint + 1, HighPoint - 1);
 end;
 end;
 
 
 function TDigest.GetByteLength: Int32;
 function TDigest.GetByteLength: Int32;
@@ -140,20 +158,35 @@ begin
   FHash.TransformBytes(input, inOff, len);
   FHash.TransformBytes(input, inOff, len);
 end;
 end;
 
 
-constructor TDigest.Create(const hash: IHash);
+constructor TDigest.Create(const hash: IHash; doInitialize: Boolean);
 begin
 begin
   Inherited Create();
   Inherited Create();
   FHash := hash;
   FHash := hash;
-  FHash.Initialize;
+  if doInitialize then
+  begin
+    FHash.Initialize;
+  end;
 end;
 end;
 
 
 function TDigest.DoFinal(const output: TCryptoLibByteArray;
 function TDigest.DoFinal(const output: TCryptoLibByteArray;
   outOff: Int32): Int32;
   outOff: Int32): Int32;
 var
 var
   buf: TCryptoLibByteArray;
   buf: TCryptoLibByteArray;
+  Limit, LXOFSizeInBits: Int32;
 begin
 begin
 
 
-  if (System.Length(output) - outOff) < GetDigestSize then
+  if Supports(FHash, IXOF) then
+  begin
+    LXOFSizeInBits := (System.Length(output) - outOff) * 8;
+    (FHash as IXOF).XOFSizeInBits := LXOFSizeInBits;
+    Limit := LXOFSizeInBits shr 3;
+  end
+  else
+  begin
+    Limit := GetDigestSize;
+  end;
+
+  if (System.Length(output) - outOff) < Limit then
   begin
   begin
     raise EDataLengthCryptoLibException.CreateRes(@SOutputBufferTooShort);
     raise EDataLengthCryptoLibException.CreateRes(@SOutputBufferTooShort);
   end
   end
@@ -163,6 +196,7 @@ begin
     System.Move(buf[0], output[outOff], System.Length(buf) *
     System.Move(buf[0], output[outOff], System.Length(buf) *
       System.SizeOf(Byte));
       System.SizeOf(Byte));
   end;
   end;
+
   result := System.Length(buf);
   result := System.Length(buf);
 end;
 end;
 
 
@@ -176,4 +210,9 @@ begin
   FHash.TransformUntyped(input, System.SizeOf(Byte));
   FHash.TransformUntyped(input, System.SizeOf(Byte));
 end;
 end;
 
 
+function TDigest.Clone(): IDigest;
+begin
+  result := TDigest.Create(FHash.Clone(), False);
+end;
+
 end.
 end.

+ 56 - 36
src/libraries/cryptolib4pascal/ClpDigestUtilities.pas

@@ -40,7 +40,7 @@ uses
 
 
 resourcestring
 resourcestring
   SMechanismNil = 'Mechanism Cannot be Nil';
   SMechanismNil = 'Mechanism Cannot be Nil';
-  SUnRecognizedDigest = '"Digest " %s not recognised.';
+  SUnRecognizedDigest = 'Digest "%s" not recognised.';
 
 
 type
 type
   TDigestUtilities = class sealed(TObject)
   TDigestUtilities = class sealed(TObject)
@@ -55,10 +55,11 @@ type
 {$SCOPEDENUMS ON}
 {$SCOPEDENUMS ON}
     TDigestAlgorithm = (BLAKE2B_160, BLAKE2B_256, BLAKE2B_384, BLAKE2B_512,
     TDigestAlgorithm = (BLAKE2B_160, BLAKE2B_256, BLAKE2B_384, BLAKE2B_512,
       BLAKE2S_128, BLAKE2S_160, BLAKE2S_224, BLAKE2S_256, GOST3411,
       BLAKE2S_128, BLAKE2S_160, BLAKE2S_224, BLAKE2S_256, GOST3411,
-      GOST3411_2012_256, GOST3411_2012_512, MD2, MD4, MD5, NONE, RIPEMD128,
-      RIPEMD160, RIPEMD256, RIPEMD320, SHA_1, SHA_224, SHA_256, SHA_384,
-      SHA_512, SHA_512_224, SHA_512_256, SHA3_224, SHA3_256, SHA3_384, SHA3_512,
-      TIGER, WHIRLPOOL);
+      GOST3411_2012_256, GOST3411_2012_512, KECCAK_224, KECCAK_256, KECCAK_288,
+      KECCAK_384, KECCAK_512, MD2, MD4, MD5, NONE, RIPEMD128, RIPEMD160,
+      RIPEMD256, RIPEMD320, SHA_1, SHA_224, SHA_256, SHA_384, SHA_512,
+      SHA_512_224, SHA_512_256, SHA3_224, SHA3_256, SHA3_384, SHA3_512,
+      SHAKE128, SHAKE256, TIGER, WHIRLPOOL);
 {$SCOPEDENUMS OFF}
 {$SCOPEDENUMS OFF}
   class procedure Boot(); static;
   class procedure Boot(); static;
   class constructor CreateDigestUtilities();
   class constructor CreateDigestUtilities();
@@ -132,63 +133,54 @@ begin
     TDigestAlgorithm.BLAKE2B_160:
     TDigestAlgorithm.BLAKE2B_160:
       begin
       begin
         result := TDigest.Create(THashFactory.TCrypto.CreateBlake2B_160);
         result := TDigest.Create(THashFactory.TCrypto.CreateBlake2B_160);
-
         Exit;
         Exit;
       end;
       end;
 
 
     TDigestAlgorithm.BLAKE2B_256:
     TDigestAlgorithm.BLAKE2B_256:
       begin
       begin
         result := TDigest.Create(THashFactory.TCrypto.CreateBlake2B_256);
         result := TDigest.Create(THashFactory.TCrypto.CreateBlake2B_256);
-
         Exit;
         Exit;
       end;
       end;
 
 
     TDigestAlgorithm.BLAKE2B_384:
     TDigestAlgorithm.BLAKE2B_384:
       begin
       begin
         result := TDigest.Create(THashFactory.TCrypto.CreateBlake2B_384);
         result := TDigest.Create(THashFactory.TCrypto.CreateBlake2B_384);
-
         Exit;
         Exit;
       end;
       end;
 
 
     TDigestAlgorithm.BLAKE2B_512:
     TDigestAlgorithm.BLAKE2B_512:
       begin
       begin
         result := TDigest.Create(THashFactory.TCrypto.CreateBlake2B_512);
         result := TDigest.Create(THashFactory.TCrypto.CreateBlake2B_512);
-
         Exit;
         Exit;
       end;
       end;
 
 
     TDigestAlgorithm.BLAKE2S_128:
     TDigestAlgorithm.BLAKE2S_128:
       begin
       begin
         result := TDigest.Create(THashFactory.TCrypto.CreateBlake2S_128);
         result := TDigest.Create(THashFactory.TCrypto.CreateBlake2S_128);
-
         Exit;
         Exit;
       end;
       end;
 
 
     TDigestAlgorithm.BLAKE2S_160:
     TDigestAlgorithm.BLAKE2S_160:
       begin
       begin
         result := TDigest.Create(THashFactory.TCrypto.CreateBlake2S_160);
         result := TDigest.Create(THashFactory.TCrypto.CreateBlake2S_160);
-
         Exit;
         Exit;
       end;
       end;
 
 
     TDigestAlgorithm.BLAKE2S_224:
     TDigestAlgorithm.BLAKE2S_224:
       begin
       begin
         result := TDigest.Create(THashFactory.TCrypto.CreateBlake2S_224);
         result := TDigest.Create(THashFactory.TCrypto.CreateBlake2S_224);
-
         Exit;
         Exit;
       end;
       end;
 
 
     TDigestAlgorithm.BLAKE2S_256:
     TDigestAlgorithm.BLAKE2S_256:
       begin
       begin
         result := TDigest.Create(THashFactory.TCrypto.CreateBlake2S_256);
         result := TDigest.Create(THashFactory.TCrypto.CreateBlake2S_256);
-
         Exit;
         Exit;
       end;
       end;
 
 
     TDigestAlgorithm.GOST3411:
     TDigestAlgorithm.GOST3411:
       begin
       begin
         result := TDigest.Create(THashFactory.TCrypto.CreateGost());
         result := TDigest.Create(THashFactory.TCrypto.CreateGost());
-
         Exit;
         Exit;
       end;
       end;
 
 
@@ -196,7 +188,6 @@ begin
       begin
       begin
         result := TDigest.Create
         result := TDigest.Create
           (THashFactory.TCrypto.CreateGOST3411_2012_256());
           (THashFactory.TCrypto.CreateGOST3411_2012_256());
-
         Exit;
         Exit;
       end;
       end;
 
 
@@ -204,28 +195,54 @@ begin
       begin
       begin
         result := TDigest.Create
         result := TDigest.Create
           (THashFactory.TCrypto.CreateGOST3411_2012_512());
           (THashFactory.TCrypto.CreateGOST3411_2012_512());
+        Exit;
+      end;
 
 
+    TDigestAlgorithm.KECCAK_224:
+      begin
+        result := TDigest.Create(THashFactory.TCrypto.CreateKeccak_224());
+        Exit;
+      end;
+
+    TDigestAlgorithm.KECCAK_256:
+      begin
+        result := TDigest.Create(THashFactory.TCrypto.CreateKeccak_256());
+        Exit;
+      end;
+
+    TDigestAlgorithm.KECCAK_288:
+      begin
+        result := TDigest.Create(THashFactory.TCrypto.CreateKeccak_288());
+        Exit;
+      end;
+
+    TDigestAlgorithm.KECCAK_384:
+      begin
+        result := TDigest.Create(THashFactory.TCrypto.CreateKeccak_384());
+        Exit;
+      end;
+
+    TDigestAlgorithm.KECCAK_512:
+      begin
+        result := TDigest.Create(THashFactory.TCrypto.CreateKeccak_512());
         Exit;
         Exit;
       end;
       end;
 
 
     TDigestAlgorithm.MD2:
     TDigestAlgorithm.MD2:
       begin
       begin
         result := TDigest.Create(THashFactory.TCrypto.CreateMD2());
         result := TDigest.Create(THashFactory.TCrypto.CreateMD2());
-
         Exit;
         Exit;
       end;
       end;
 
 
     TDigestAlgorithm.MD4:
     TDigestAlgorithm.MD4:
       begin
       begin
         result := TDigest.Create(THashFactory.TCrypto.CreateMD4());
         result := TDigest.Create(THashFactory.TCrypto.CreateMD4());
-
         Exit;
         Exit;
       end;
       end;
 
 
     TDigestAlgorithm.MD5:
     TDigestAlgorithm.MD5:
       begin
       begin
         result := TDigest.Create(THashFactory.TCrypto.CreateMD5());
         result := TDigest.Create(THashFactory.TCrypto.CreateMD5());
-
         Exit;
         Exit;
       end;
       end;
 
 
@@ -233,127 +250,120 @@ begin
       begin
       begin
         result := TDigest.Create
         result := TDigest.Create
           (THashFactory.TNullDigestFactory.CreateNullDigest());
           (THashFactory.TNullDigestFactory.CreateNullDigest());
-
         Exit;
         Exit;
       end;
       end;
 
 
     TDigestAlgorithm.RIPEMD128:
     TDigestAlgorithm.RIPEMD128:
       begin
       begin
         result := TDigest.Create(THashFactory.TCrypto.CreateRIPEMD128());
         result := TDigest.Create(THashFactory.TCrypto.CreateRIPEMD128());
-
         Exit;
         Exit;
       end;
       end;
 
 
     TDigestAlgorithm.RIPEMD160:
     TDigestAlgorithm.RIPEMD160:
       begin
       begin
         result := TDigest.Create(THashFactory.TCrypto.CreateRIPEMD160());
         result := TDigest.Create(THashFactory.TCrypto.CreateRIPEMD160());
-
         Exit;
         Exit;
       end;
       end;
 
 
     TDigestAlgorithm.RIPEMD256:
     TDigestAlgorithm.RIPEMD256:
       begin
       begin
         result := TDigest.Create(THashFactory.TCrypto.CreateRIPEMD256());
         result := TDigest.Create(THashFactory.TCrypto.CreateRIPEMD256());
-
         Exit;
         Exit;
       end;
       end;
 
 
     TDigestAlgorithm.RIPEMD320:
     TDigestAlgorithm.RIPEMD320:
       begin
       begin
         result := TDigest.Create(THashFactory.TCrypto.CreateRIPEMD320());
         result := TDigest.Create(THashFactory.TCrypto.CreateRIPEMD320());
-
         Exit;
         Exit;
       end;
       end;
 
 
     TDigestAlgorithm.SHA_1:
     TDigestAlgorithm.SHA_1:
       begin
       begin
         result := TDigest.Create(THashFactory.TCrypto.CreateSHA1());
         result := TDigest.Create(THashFactory.TCrypto.CreateSHA1());
-
         Exit;
         Exit;
       end;
       end;
 
 
     TDigestAlgorithm.SHA_224:
     TDigestAlgorithm.SHA_224:
       begin
       begin
         result := TDigest.Create(THashFactory.TCrypto.CreateSHA2_224());
         result := TDigest.Create(THashFactory.TCrypto.CreateSHA2_224());
-
         Exit;
         Exit;
       end;
       end;
 
 
     TDigestAlgorithm.SHA_256:
     TDigestAlgorithm.SHA_256:
       begin
       begin
         result := TDigest.Create(THashFactory.TCrypto.CreateSHA2_256());
         result := TDigest.Create(THashFactory.TCrypto.CreateSHA2_256());
-
         Exit;
         Exit;
       end;
       end;
 
 
     TDigestAlgorithm.SHA_384:
     TDigestAlgorithm.SHA_384:
       begin
       begin
         result := TDigest.Create(THashFactory.TCrypto.CreateSHA2_384());
         result := TDigest.Create(THashFactory.TCrypto.CreateSHA2_384());
-
         Exit;
         Exit;
       end;
       end;
 
 
     TDigestAlgorithm.SHA_512:
     TDigestAlgorithm.SHA_512:
       begin
       begin
-
         result := TDigest.Create(THashFactory.TCrypto.CreateSHA2_512());
         result := TDigest.Create(THashFactory.TCrypto.CreateSHA2_512());
-
         Exit;
         Exit;
       end;
       end;
 
 
     TDigestAlgorithm.SHA_512_224:
     TDigestAlgorithm.SHA_512_224:
       begin
       begin
         result := TDigest.Create(THashFactory.TCrypto.CreateSHA2_512_224());
         result := TDigest.Create(THashFactory.TCrypto.CreateSHA2_512_224());
-
         Exit;
         Exit;
       end;
       end;
 
 
     TDigestAlgorithm.SHA_512_256:
     TDigestAlgorithm.SHA_512_256:
       begin
       begin
         result := TDigest.Create(THashFactory.TCrypto.CreateSHA2_512_256());
         result := TDigest.Create(THashFactory.TCrypto.CreateSHA2_512_256());
-
         Exit;
         Exit;
       end;
       end;
 
 
     TDigestAlgorithm.SHA3_224:
     TDigestAlgorithm.SHA3_224:
       begin
       begin
         result := TDigest.Create(THashFactory.TCrypto.CreateSHA3_224());
         result := TDigest.Create(THashFactory.TCrypto.CreateSHA3_224());
-
         Exit;
         Exit;
       end;
       end;
 
 
     TDigestAlgorithm.SHA3_256:
     TDigestAlgorithm.SHA3_256:
       begin
       begin
         result := TDigest.Create(THashFactory.TCrypto.CreateSHA3_256());
         result := TDigest.Create(THashFactory.TCrypto.CreateSHA3_256());
-
         Exit;
         Exit;
       end;
       end;
 
 
     TDigestAlgorithm.SHA3_384:
     TDigestAlgorithm.SHA3_384:
       begin
       begin
         result := TDigest.Create(THashFactory.TCrypto.CreateSHA3_384());
         result := TDigest.Create(THashFactory.TCrypto.CreateSHA3_384());
-
         Exit;
         Exit;
       end;
       end;
 
 
     TDigestAlgorithm.SHA3_512:
     TDigestAlgorithm.SHA3_512:
       begin
       begin
         result := TDigest.Create(THashFactory.TCrypto.CreateSHA3_512());
         result := TDigest.Create(THashFactory.TCrypto.CreateSHA3_512());
+        Exit;
+      end;
+
+    TDigestAlgorithm.SHAKE128:
+      begin
+        result := TDigest.Create(THashFactory.TXOF.CreateShake_128(128));
+        Exit;
+      end;
 
 
+    TDigestAlgorithm.SHAKE256:
+      begin
+        result := TDigest.Create(THashFactory.TXOF.CreateShake_256(256));
         Exit;
         Exit;
       end;
       end;
 
 
     TDigestAlgorithm.TIGER:
     TDigestAlgorithm.TIGER:
       begin
       begin
         result := TDigest.Create(THashFactory.TCrypto.CreateTiger_3_192);
         result := TDigest.Create(THashFactory.TCrypto.CreateTiger_3_192);
-
         Exit;
         Exit;
       end;
       end;
 
 
     TDigestAlgorithm.WHIRLPOOL:
     TDigestAlgorithm.WHIRLPOOL:
       begin
       begin
         result := TDigest.Create(THashFactory.TCrypto.CreateWhirlPool);
         result := TDigest.Create(THashFactory.TCrypto.CreateWhirlPool);
-
         Exit;
         Exit;
       end
       end
   else
   else
@@ -416,10 +426,18 @@ begin
 
 
     Falgorithms.Add(TCryptoProObjectIdentifiers.GostR3411.id, 'GOST3411');
     Falgorithms.Add(TCryptoProObjectIdentifiers.GostR3411.id, 'GOST3411');
 
 
+    Falgorithms.Add('KECCAK224', 'KECCAK-224');
+    Falgorithms.Add('KECCAK256', 'KECCAK-256');
+    Falgorithms.Add('KECCAK288', 'KECCAK-288');
+    Falgorithms.Add('KECCAK384', 'KECCAK-384');
+    Falgorithms.Add('KECCAK512', 'KECCAK-512');
+
     Falgorithms.Add(TNistObjectIdentifiers.IdSha3_224.id, 'SHA3-224');
     Falgorithms.Add(TNistObjectIdentifiers.IdSha3_224.id, 'SHA3-224');
     Falgorithms.Add(TNistObjectIdentifiers.IdSha3_256.id, 'SHA3-256');
     Falgorithms.Add(TNistObjectIdentifiers.IdSha3_256.id, 'SHA3-256');
     Falgorithms.Add(TNistObjectIdentifiers.IdSha3_384.id, 'SHA3-384');
     Falgorithms.Add(TNistObjectIdentifiers.IdSha3_384.id, 'SHA3-384');
     Falgorithms.Add(TNistObjectIdentifiers.IdSha3_512.id, 'SHA3-512');
     Falgorithms.Add(TNistObjectIdentifiers.IdSha3_512.id, 'SHA3-512');
+    Falgorithms.Add(TNistObjectIdentifiers.IdShake128.id, 'SHAKE128');
+    Falgorithms.Add(TNistObjectIdentifiers.IdShake256.id, 'SHAKE256');
 
 
     TMiscObjectIdentifiers.Boot;
     TMiscObjectIdentifiers.Boot;
 
 
@@ -453,6 +471,8 @@ begin
     Foids.Add('SHA3-256', TNistObjectIdentifiers.IdSha3_256);
     Foids.Add('SHA3-256', TNistObjectIdentifiers.IdSha3_256);
     Foids.Add('SHA3-384', TNistObjectIdentifiers.IdSha3_384);
     Foids.Add('SHA3-384', TNistObjectIdentifiers.IdSha3_384);
     Foids.Add('SHA3-512', TNistObjectIdentifiers.IdSha3_512);
     Foids.Add('SHA3-512', TNistObjectIdentifiers.IdSha3_512);
+    Foids.Add('SHAKE128', TNistObjectIdentifiers.IdShake128);
+    Foids.Add('SHAKE256', TNistObjectIdentifiers.IdShake256);
     Foids.Add('RIPEMD128', TTeleTrusTObjectIdentifiers.RIPEMD128);
     Foids.Add('RIPEMD128', TTeleTrusTObjectIdentifiers.RIPEMD128);
     Foids.Add('RIPEMD160', TTeleTrusTObjectIdentifiers.RIPEMD160);
     Foids.Add('RIPEMD160', TTeleTrusTObjectIdentifiers.RIPEMD160);
     Foids.Add('RIPEMD256', TTeleTrusTObjectIdentifiers.RIPEMD256);
     Foids.Add('RIPEMD256', TTeleTrusTObjectIdentifiers.RIPEMD256);

+ 1 - 1
src/libraries/cryptolib4pascal/ClpDsaDigestSigner.pas

@@ -17,7 +17,7 @@
 
 
 unit ClpDsaDigestSigner;
 unit ClpDsaDigestSigner;
 
 
-{$I ..\..\Include\CryptoLib.inc}
+{$I CryptoLib.inc}
 
 
 interface
 interface
 
 

+ 1 - 1
src/libraries/cryptolib4pascal/ClpDsaKeyGenerationParameters.pas

@@ -17,7 +17,7 @@
 
 
 unit ClpDsaKeyGenerationParameters;
 unit ClpDsaKeyGenerationParameters;
 
 
-{$I ..\..\Include\CryptoLib.inc}
+{$I CryptoLib.inc}
 
 
 interface
 interface
 
 

+ 1 - 1
src/libraries/cryptolib4pascal/ClpDsaParameter.pas

@@ -17,7 +17,7 @@
 
 
 unit ClpDsaParameter;
 unit ClpDsaParameter;
 
 
-{$I ..\..\Include\CryptoLib.inc}
+{$I CryptoLib.inc}
 
 
 interface
 interface
 
 

+ 1 - 1
src/libraries/cryptolib4pascal/ClpDsaParameterGenerationParameters.pas

@@ -17,7 +17,7 @@
 
 
 unit ClpDsaParameterGenerationParameters;
 unit ClpDsaParameterGenerationParameters;
 
 
-{$I ..\..\Include\CryptoLib.inc}
+{$I CryptoLib.inc}
 
 
 interface
 interface
 
 

+ 1 - 1
src/libraries/cryptolib4pascal/ClpDsaParameters.pas

@@ -17,7 +17,7 @@
 
 
 unit ClpDsaParameters;
 unit ClpDsaParameters;
 
 
-{$I ..\..\Include\CryptoLib.inc}
+{$I CryptoLib.inc}
 
 
 interface
 interface
 
 

+ 1 - 1
src/libraries/cryptolib4pascal/ClpDsaParametersGenerator.pas

@@ -17,7 +17,7 @@
 
 
 unit ClpDsaParametersGenerator;
 unit ClpDsaParametersGenerator;
 
 
-{$I ..\..\Include\CryptoLib.inc}
+{$I CryptoLib.inc}
 
 
 interface
 interface
 
 

+ 1 - 1
src/libraries/cryptolib4pascal/ClpDsaSigner.pas

@@ -17,7 +17,7 @@
 
 
 unit ClpDsaSigner;
 unit ClpDsaSigner;
 
 
-{$I ..\..\Include\CryptoLib.inc}
+{$I CryptoLib.inc}
 
 
 interface
 interface
 
 

+ 1 - 1
src/libraries/cryptolib4pascal/ClpDsaValidationParameters.pas

@@ -17,7 +17,7 @@
 
 
 unit ClpDsaValidationParameters;
 unit ClpDsaValidationParameters;
 
 
-{$I ..\..\Include\CryptoLib.inc}
+{$I CryptoLib.inc}
 
 
 interface
 interface
 
 

+ 1 - 1
src/libraries/cryptolib4pascal/ClpECDHCBasicAgreement.pas

@@ -17,7 +17,7 @@
 
 
 unit ClpECDHCBasicAgreement;
 unit ClpECDHCBasicAgreement;
 
 
-{$I ..\..\Include\CryptoLib.inc}
+{$I CryptoLib.inc}
 
 
 interface
 interface
 
 

+ 1 - 2
src/libraries/cryptolib4pascal/ClpECNRSigner.pas

@@ -17,7 +17,7 @@
 
 
 unit ClpECNRSigner;
 unit ClpECNRSigner;
 
 
-{$I ..\..\Include\CryptoLib.inc}
+{$I CryptoLib.inc}
 
 
 interface
 interface
 
 
@@ -167,7 +167,6 @@ begin
 
 
     tempPair := keyGen.GenerateKeyPair();
     tempPair := keyGen.GenerateKeyPair();
 
 
-    // BigInteger Vx := tempPair.getPublic().getW().getAffineX();
     V := tempPair.Public as IECPublicKeyParameters; // get temp's public key
     V := tempPair.Public as IECPublicKeyParameters; // get temp's public key
     Vx := V.Q.AffineXCoord.ToBigInteger(); // get the point's x coordinate
     Vx := V.Q.AffineXCoord.ToBigInteger(); // get the point's x coordinate
 
 

+ 17 - 49
src/libraries/cryptolib4pascal/ClpECNamedCurveTable.pas

@@ -24,12 +24,9 @@ interface
 uses
 uses
   Generics.Collections,
   Generics.Collections,
   ClpCryptoLibTypes,
   ClpCryptoLibTypes,
-  // ClpX962NamedCurves,
-  // ClpECGost3410NamedCurves,
-  // ClpX9ECParameters,
   ClpSecNamedCurves,
   ClpSecNamedCurves,
   ClpNistNamedCurves,
   ClpNistNamedCurves,
-  // ClpIECDomainParameters,
+  ClpTeleTrusTNamedCurves,
   ClpIAsn1Objects,
   ClpIAsn1Objects,
   ClpIX9ECParameters;
   ClpIX9ECParameters;
 
 
@@ -42,8 +39,6 @@ type
   strict private
   strict private
 
 
     class function GetNames: TCryptoLibStringArray; static;
     class function GetNames: TCryptoLibStringArray; static;
-    // class function FromDomainParameters(const dp: IECDomainParameters)
-    // : IX9ECParameters; static; inline;
 
 
   public
   public
     // /**
     // /**
@@ -55,7 +50,6 @@ type
     // */
     // */
     class function GetByName(const name: String): IX9ECParameters; static;
     class function GetByName(const name: String): IX9ECParameters; static;
 
 
-    class function GetName(const oid: IDerObjectIdentifier): String; static;
     // /**
     // /**
     // * return the object identifier signified by the passed in name. Null
     // * return the object identifier signified by the passed in name. Null
     // * if there is no object identifier associated with name.
     // * if there is no object identifier associated with name.
@@ -88,36 +82,23 @@ implementation
 
 
 { TECNamedCurveTable }
 { TECNamedCurveTable }
 
 
-// class function TECNamedCurveTable.FromDomainParameters
-// (const dp: IECDomainParameters): IX9ECParameters;
-// begin
-// if dp = Nil then
-// begin
-// result := Nil;
-// end
-// else
-// begin
-// result := TX9ECParameters.Create(dp.Curve, dp.G, dp.N, dp.H, dp.GetSeed())
-// end;
-//
-// end;
-
 class function TECNamedCurveTable.GetByName(const name: String)
 class function TECNamedCurveTable.GetByName(const name: String)
   : IX9ECParameters;
   : IX9ECParameters;
 var
 var
   ecP: IX9ECParameters;
   ecP: IX9ECParameters;
 begin
 begin
-  // ecP := TX962NamedCurves.GetByName(name);
-  // if (ecP = Nil) then
-  // begin
   ecP := TSecNamedCurves.GetByName(name);
   ecP := TSecNamedCurves.GetByName(name);
-  // end;
 
 
   if (ecP = Nil) then
   if (ecP = Nil) then
   begin
   begin
     ecP := TNistNamedCurves.GetByName(name);
     ecP := TNistNamedCurves.GetByName(name);
   end;
   end;
 
 
+  if (ecP = Nil) then
+  begin
+    ecP := TTeleTrusTNamedCurves.GetByName(name);
+  end;
+
   result := ecP;
   result := ecP;
 end;
 end;
 
 
@@ -126,31 +107,15 @@ class function TECNamedCurveTable.GetByOid(const oid: IDerObjectIdentifier)
 var
 var
   ecP: IX9ECParameters;
   ecP: IX9ECParameters;
 begin
 begin
-  // ecP := TX962NamedCurves.GetByOid(oid);
-  // if (ecP = Nil) then
-  // begin
   ecP := TSecNamedCurves.GetByOid(oid);
   ecP := TSecNamedCurves.GetByOid(oid);
-  // end;
   // NOTE: All the NIST curves are currently from SEC, so no point in redundant OID lookup
   // NOTE: All the NIST curves are currently from SEC, so no point in redundant OID lookup
-  result := ecP;
-end;
-
-class function TECNamedCurveTable.GetName
-  (const oid: IDerObjectIdentifier): String;
-var
-  name: String;
-begin
-  // name := TX962NamedCurves.GetName(oid);
-  // if (name = '') then
-  // begin
-  name := TSecNamedCurves.GetName(oid);
-  // end;
 
 
-  if (name = '') then
+  if (ecP = Nil) then
   begin
   begin
-    name := TNistNamedCurves.GetName(oid);
+    ecP := TTeleTrusTNamedCurves.GetByOid(oid);
   end;
   end;
-  result := name;
+
+  result := ecP;
 end;
 end;
 
 
 class function TECNamedCurveTable.GetOid(const name: String)
 class function TECNamedCurveTable.GetOid(const name: String)
@@ -158,17 +123,19 @@ class function TECNamedCurveTable.GetOid(const name: String)
 var
 var
   oid: IDerObjectIdentifier;
   oid: IDerObjectIdentifier;
 begin
 begin
-  // oid := TX962NamedCurves.GetOid(name);
-  // if (oid = Nil) then
-  // begin
+
   oid := TSecNamedCurves.GetOid(name);
   oid := TSecNamedCurves.GetOid(name);
-  // end;
 
 
   if (oid = Nil) then
   if (oid = Nil) then
   begin
   begin
     oid := TNistNamedCurves.GetOid(name);
     oid := TNistNamedCurves.GetOid(name);
   end;
   end;
 
 
+  if (oid = Nil) then
+  begin
+    oid := TTeleTrusTNamedCurves.GetOid(name);
+  end;
+
   result := oid;
   result := oid;
 end;
 end;
 
 
@@ -180,6 +147,7 @@ begin
   try
   try
     temp.AddRange(TSecNamedCurves.Names);
     temp.AddRange(TSecNamedCurves.Names);
     temp.AddRange(TNistNamedCurves.Names);
     temp.AddRange(TNistNamedCurves.Names);
+    temp.AddRange(TTeleTrusTNamedCurves.Names);
     result := temp.ToArray;
     result := temp.ToArray;
   finally
   finally
     temp.Free;
     temp.Free;

+ 1 - 1
src/libraries/cryptolib4pascal/ClpECSchnorrSipaSigner.pas

@@ -17,7 +17,7 @@
 
 
 unit ClpECSchnorrSipaSigner;
 unit ClpECSchnorrSipaSigner;
 
 
-{$I ..\..\Include\CryptoLib.inc}
+{$I CryptoLib.inc}
 
 
 interface
 interface
 
 

+ 1 - 1
src/libraries/cryptolib4pascal/ClpEacObjectIdentifiers.pas

@@ -17,7 +17,7 @@
 
 
 unit ClpEacObjectIdentifiers;
 unit ClpEacObjectIdentifiers;
 
 
-{$I ..\..\Include\CryptoLib.inc}
+{$I CryptoLib.inc}
 
 
 interface
 interface
 
 

+ 1946 - 0
src/libraries/cryptolib4pascal/ClpEd25519.pas

@@ -0,0 +1,1946 @@
+{ *********************************************************************************** }
+{ *                              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 ClpEd25519;
+
+{$I CryptoLib.inc}
+
+interface
+
+uses
+  SyncObjs,
+  ClpNat,
+  ClpBits,
+  ClpNat256,
+  ClpInterleave,
+  ClpDigestUtilities,
+  ClpISecureRandom,
+  ClpIDigest,
+  ClpIEd25519,
+  ClpX25519Field,
+  ClpConverters,
+  ClpArrayUtils,
+  ClpCryptoLibTypes;
+
+resourcestring
+  SInvalidCtx = 'ctx';
+  SDigestError = 'Digest Produced Insufficient Data';
+
+type
+  TEd25519 = class(TInterfacedObject, IEd25519)
+
+  strict private
+
+  type
+    IPointAccum = interface(IInterface)
+      ['{8A257C67-674F-4F62-B937-4E83B46CAF36}']
+      function GetX: TCryptoLibInt32Array;
+      procedure SetX(const value: TCryptoLibInt32Array);
+      property X: TCryptoLibInt32Array read GetX write SetX;
+
+      function GetY: TCryptoLibInt32Array;
+      procedure SetY(const value: TCryptoLibInt32Array);
+      property Y: TCryptoLibInt32Array read GetY write SetY;
+
+      function GetZ: TCryptoLibInt32Array;
+      procedure SetZ(const value: TCryptoLibInt32Array);
+      property Z: TCryptoLibInt32Array read GetZ write SetZ;
+
+      function GetU: TCryptoLibInt32Array;
+      procedure SetU(const value: TCryptoLibInt32Array);
+      property U: TCryptoLibInt32Array read GetU write SetU;
+
+      function GetV: TCryptoLibInt32Array;
+      procedure SetV(const value: TCryptoLibInt32Array);
+      property V: TCryptoLibInt32Array read GetV write SetV;
+
+    end;
+
+  type
+    TPointAccum = class sealed(TInterfacedObject, IPointAccum)
+    private
+      Fx, Fy, Fz, Fu, Fv: TCryptoLibInt32Array;
+
+      function GetX: TCryptoLibInt32Array; inline;
+      procedure SetX(const value: TCryptoLibInt32Array); inline;
+      function GetY: TCryptoLibInt32Array; inline;
+      procedure SetY(const value: TCryptoLibInt32Array); inline;
+      function GetZ: TCryptoLibInt32Array; inline;
+      procedure SetZ(const value: TCryptoLibInt32Array); inline;
+      function GetU: TCryptoLibInt32Array; inline;
+      procedure SetU(const value: TCryptoLibInt32Array); inline;
+      function GetV: TCryptoLibInt32Array; inline;
+      procedure SetV(const value: TCryptoLibInt32Array); inline;
+
+    public
+      property X: TCryptoLibInt32Array read GetX write SetX;
+      property Y: TCryptoLibInt32Array read GetY write SetY;
+      property Z: TCryptoLibInt32Array read GetZ write SetZ;
+      property U: TCryptoLibInt32Array read GetU write SetU;
+      property V: TCryptoLibInt32Array read GetV write SetV;
+
+      constructor Create();
+    end;
+
+  type
+    IPointExt = interface(IInterface)
+      ['{20C8CC66-D9E6-4626-B09D-BC500223F103}']
+      function GetX: TCryptoLibInt32Array;
+      procedure SetX(const value: TCryptoLibInt32Array);
+      property X: TCryptoLibInt32Array read GetX write SetX;
+
+      function GetY: TCryptoLibInt32Array;
+      procedure SetY(const value: TCryptoLibInt32Array);
+      property Y: TCryptoLibInt32Array read GetY write SetY;
+
+      function GetZ: TCryptoLibInt32Array;
+      procedure SetZ(const value: TCryptoLibInt32Array);
+      property Z: TCryptoLibInt32Array read GetZ write SetZ;
+
+      function GetT: TCryptoLibInt32Array;
+      procedure SetT(const value: TCryptoLibInt32Array);
+      property T: TCryptoLibInt32Array read GetT write SetT;
+
+    end;
+
+  type
+    TPointExt = class sealed(TInterfacedObject, IPointExt)
+    private
+      Fx, Fy, Fz, Ft: TCryptoLibInt32Array;
+
+      function GetX: TCryptoLibInt32Array; inline;
+      procedure SetX(const value: TCryptoLibInt32Array); inline;
+      function GetY: TCryptoLibInt32Array; inline;
+      procedure SetY(const value: TCryptoLibInt32Array); inline;
+      function GetZ: TCryptoLibInt32Array; inline;
+      procedure SetZ(const value: TCryptoLibInt32Array); inline;
+      function GetT: TCryptoLibInt32Array; inline;
+      procedure SetT(const value: TCryptoLibInt32Array); inline;
+
+    public
+      property X: TCryptoLibInt32Array read GetX write SetX;
+      property Y: TCryptoLibInt32Array read GetY write SetY;
+      property Z: TCryptoLibInt32Array read GetZ write SetZ;
+      property T: TCryptoLibInt32Array read GetT write SetT;
+
+      constructor Create();
+    end;
+
+  type
+    IPointPrecomp = interface(IInterface)
+      ['{9EADAD66-FE44-4A1E-8458-3AE7D2AF14C2}']
+      function GetYpx_h: TCryptoLibInt32Array;
+      procedure SetYpx_h(const value: TCryptoLibInt32Array);
+      property Ypx_h: TCryptoLibInt32Array read GetYpx_h write SetYpx_h;
+      function GetYmx_h: TCryptoLibInt32Array;
+      procedure SetYmx_h(const value: TCryptoLibInt32Array);
+      property Ymx_h: TCryptoLibInt32Array read GetYmx_h write SetYmx_h;
+      function GetXyd: TCryptoLibInt32Array;
+      procedure SetXyd(const value: TCryptoLibInt32Array);
+      property Xyd: TCryptoLibInt32Array read GetXyd write SetXyd;
+
+    end;
+
+  type
+    TPointPrecomp = class sealed(TInterfacedObject, IPointPrecomp)
+    private
+      Fypx_h, Fymx_h, Fxyd: TCryptoLibInt32Array;
+
+      function GetYpx_h: TCryptoLibInt32Array; inline;
+      procedure SetYpx_h(const value: TCryptoLibInt32Array); inline;
+      function GetYmx_h: TCryptoLibInt32Array; inline;
+      procedure SetYmx_h(const value: TCryptoLibInt32Array); inline;
+      function GetXyd: TCryptoLibInt32Array; inline;
+      procedure SetXyd(const value: TCryptoLibInt32Array); inline;
+
+    public
+      property Ypx_h: TCryptoLibInt32Array read GetYpx_h write SetYpx_h;
+      property Ymx_h: TCryptoLibInt32Array read GetYmx_h write SetYmx_h;
+      property Xyd: TCryptoLibInt32Array read GetXyd write SetXyd;
+
+      constructor Create();
+    end;
+
+  const
+    M28L = Int64($0FFFFFFF);
+    M32L = Int64($FFFFFFFF);
+
+    PointBytes = Int32(32);
+    ScalarUints = Int32(8);
+    ScalarBytes = Int32(ScalarUints * 4);
+
+    L0 = Int32($FCF5D3ED); // L0:26/--
+    L1 = Int32($012631A6); // L1:24/22
+    L2 = Int32($079CD658); // L2:27/--
+    L3 = Int32($FF9DEA2F); // L3:23/--
+    L4 = Int32($000014DF); // L4:12/11
+
+    WnafWidthBase = Int32(7);
+
+    PrecompBlocks = Int32(8);
+    PrecompTeeth = Int32(4);
+    PrecompSpacing = Int32(8);
+    PrecompPoints = Int32(1 shl (PrecompTeeth - 1));
+    PrecompMask = Int32(PrecompPoints - 1);
+
+  class var
+
+    FDom2Prefix: TCryptoLibByteArray;
+    FP, FL: TCryptoLibUInt32Array;
+    FB_x, FB_y, FC_d, FC_d2, FC_d4: TCryptoLibInt32Array;
+    FPrecompLock: TCriticalSection;
+    // TODO[ed25519] Convert to PointPrecomp
+    FPrecompBaseTable: TCryptoLibGenericArray<IPointExt>;
+    FPrecompBase: TCryptoLibInt32Array;
+
+    class function CalculateS(const r, k, s: TCryptoLibByteArray)
+      : TCryptoLibByteArray; static;
+
+    class function CheckContextVar(const ctx: TCryptoLibCustomByteArrayBuffer;
+      phflag: Byte): Boolean; static; inline;
+
+    class function CheckPointVar(const p: TCryptoLibByteArray): Boolean;
+      static; inline;
+
+    class function CheckScalarVar(const s: TCryptoLibByteArray): Boolean;
+      static; inline;
+
+    class function Decode24(const bs: TCryptoLibByteArray; off: Int32): UInt32;
+      static; inline;
+
+    class function Decode32(const bs: TCryptoLibByteArray; off: Int32): UInt32;
+      overload; static; inline;
+
+    class procedure Decode32(const bs: TCryptoLibByteArray; bsOff: Int32;
+      const n: TCryptoLibUInt32Array; nOff, nLen: Int32); overload;
+      static; inline;
+
+    class function DecodePointVar(const p: TCryptoLibByteArray; pOff: Int32;
+      ANegate: Boolean; const r: IPointExt): Boolean; static;
+
+    class procedure DecodeScalar(const k: TCryptoLibByteArray; kOff: Int32;
+      const n: TCryptoLibUInt32Array); static; inline;
+
+    class procedure Dom2(const d: IDigest; phflag: Byte;
+      const ctx: TCryptoLibCustomByteArrayBuffer); static; inline;
+
+    class procedure Encode24(n: UInt32; const bs: TCryptoLibByteArray;
+      off: Int32); static; inline;
+
+    class procedure Encode32(n: UInt32; const bs: TCryptoLibByteArray;
+      off: Int32); static; inline;
+
+    class procedure Encode56(n: UInt64; const bs: TCryptoLibByteArray;
+      off: Int32); static; inline;
+
+    class procedure EncodePoint(const p: IPointAccum;
+      const r: TCryptoLibByteArray; rOff: Int32); static;
+
+    class function GetWnaf(const n: TCryptoLibUInt32Array; width: Int32)
+      : TCryptoLibShortIntArray; static;
+
+    class procedure ImplSign(const d: IDigest;
+      const h, s, pk: TCryptoLibByteArray; pkOff: Int32;
+      const ctx: TCryptoLibCustomByteArrayBuffer; phflag: Byte;
+      const m: TCryptoLibByteArray; mOff, mLen: Int32;
+      const sig: TCryptoLibByteArray; sigOff: Int32); overload; static;
+
+    procedure ImplSign(const sk: TCryptoLibByteArray; skOff: Int32;
+      const ctx: TCryptoLibCustomByteArrayBuffer; phflag: Byte;
+      const m: TCryptoLibByteArray; mOff: Int32; mLen: Int32;
+      const sig: TCryptoLibByteArray; sigOff: Int32); overload;
+
+    procedure ImplSign(const sk: TCryptoLibByteArray; skOff: Int32;
+      const pk: TCryptoLibByteArray; pkOff: Int32;
+      const ctx: TCryptoLibCustomByteArrayBuffer; phflag: Byte;
+      const m: TCryptoLibByteArray; mOff: Int32; mLen: Int32;
+      const sig: TCryptoLibByteArray; sigOff: Int32); overload;
+
+    function ImplVerify(const sig: TCryptoLibByteArray; sigOff: Int32;
+      const pk: TCryptoLibByteArray; pkOff: Int32;
+      const ctx: TCryptoLibCustomByteArrayBuffer; phflag: Byte;
+      const m: TCryptoLibByteArray; mOff, mLen: Int32): Boolean;
+
+    class procedure PointAddVar(negate: Boolean; const p: IPointExt;
+      const r: IPointAccum); overload; static;
+
+    class procedure PointAddVar(negate: Boolean; const p, q, r: IPointExt);
+      overload; static;
+
+    class procedure PointAddPrecomp(const p: IPointPrecomp;
+      const r: IPointAccum); overload; static;
+
+    class function PointCopy(const p: IPointAccum): IPointExt; overload;
+      static; inline;
+
+    class function PointCopy(const p: IPointExt): IPointExt; overload;
+      static; inline;
+
+    class procedure PointDouble(const r: IPointAccum); static;
+
+    class procedure PointExtendXY(const p: IPointAccum); overload;
+      static; inline;
+
+    class procedure PointExtendXY(const p: IPointExt); overload; static; inline;
+
+    class procedure PointLookup(block, index: Int32;
+      const p: IPointPrecomp); static;
+
+    class function PointPrecompVar(const p: IPointExt; count: Int32)
+      : TCryptoLibGenericArray<IPointExt>; static;
+
+    class procedure PointSetNeutral(const p: IPointAccum); overload;
+      static; inline;
+
+    class procedure PointSetNeutral(const p: IPointExt); overload;
+      static; inline;
+
+    class procedure PruneScalar(const n: TCryptoLibByteArray; nOff: Int32;
+      const r: TCryptoLibByteArray); static; inline;
+
+    class function ReduceScalar(const n: TCryptoLibByteArray)
+      : TCryptoLibByteArray; static;
+
+    class procedure ScalarMultBase(const k: TCryptoLibByteArray;
+      const r: IPointAccum); static;
+
+    class procedure ScalarMultBaseEncoded(const k, r: TCryptoLibByteArray;
+      rOff: Int32); static; inline;
+
+    class procedure ScalarMultStraussVar(const nb, np: TCryptoLibUInt32Array;
+      const p: IPointExt; const r: IPointAccum); static;
+
+    class function ValidateDigestOutputSize(const ADigest: IDigest)
+      : TCryptoLibByteArray; static; inline;
+
+    class function ConstructCustomByteArrayBufferContext
+      (const AData: TCryptoLibByteArray; AIsNil: Boolean; ALength: Int32)
+      : TCryptoLibCustomByteArrayBuffer; static; inline;
+
+    class procedure Boot(); static;
+    class constructor CreateEd25519();
+    class destructor DestroyEd25519();
+
+  strict protected
+
+    function CreateDigest(): IDigest; virtual;
+
+  public
+
+    const
+    PreHashSize = Int32(64);
+    PublicKeySize = Int32(PointBytes);
+    SecretKeySize = Int32(32);
+    SignatureSize = Int32(PointBytes + ScalarBytes);
+
+  type
+{$SCOPEDENUMS ON}
+    TEd25519Algorithm = (Ed25519 = 0, Ed25519ctx = 1, Ed25519ph = 2);
+{$SCOPEDENUMS OFF}
+  constructor Create();
+
+  function CreatePreHash(): IDigest; inline;
+
+  procedure GeneratePrivateKey(const random: ISecureRandom;
+    const k: TCryptoLibByteArray); inline;
+
+  procedure GeneratePublicKey(const sk: TCryptoLibByteArray; skOff: Int32;
+    pk: TCryptoLibByteArray; pkOff: Int32);
+
+  class procedure Precompute(); static;
+
+  class procedure ScalarMultBaseYZ(const k: TCryptoLibByteArray; kOff: Int32;
+    const Y, Z: TCryptoLibInt32Array); static; inline;
+
+  procedure Sign(const sk: TCryptoLibByteArray; skOff: Int32;
+    const m: TCryptoLibByteArray; mOff, mLen: Int32;
+    const sig: TCryptoLibByteArray; sigOff: Int32); overload;
+
+  procedure Sign(const sk: TCryptoLibByteArray; skOff: Int32;
+    const pk: TCryptoLibByteArray; pkOff: Int32; const m: TCryptoLibByteArray;
+    mOff, mLen: Int32; const sig: TCryptoLibByteArray; sigOff: Int32); overload;
+
+  procedure Sign(const sk: TCryptoLibByteArray; skOff: Int32;
+    const ctx, m: TCryptoLibByteArray; mOff, mLen: Int32;
+    const sig: TCryptoLibByteArray; sigOff: Int32); overload;
+
+  procedure Sign(const sk: TCryptoLibByteArray; skOff: Int32;
+    const pk: TCryptoLibByteArray; pkOff: Int32;
+    const ctx, m: TCryptoLibByteArray; mOff, mLen: Int32;
+    const sig: TCryptoLibByteArray; sigOff: Int32); overload;
+
+  procedure SignPreHash(const sk: TCryptoLibByteArray; skOff: Int32;
+    const ctx, ph: TCryptoLibByteArray; phOff: Int32;
+    const sig: TCryptoLibByteArray; sigOff: Int32); overload;
+
+  procedure SignPreHash(const sk: TCryptoLibByteArray; skOff: Int32;
+    const pk: TCryptoLibByteArray; pkOff: Int32;
+    const ctx, ph: TCryptoLibByteArray; phOff: Int32;
+    const sig: TCryptoLibByteArray; sigOff: Int32); overload;
+
+  procedure SignPreHash(const sk: TCryptoLibByteArray; skOff: Int32;
+    const ctx: TCryptoLibByteArray; const ph: IDigest;
+    const sig: TCryptoLibByteArray; sigOff: Int32); overload;
+
+  procedure SignPreHash(const sk: TCryptoLibByteArray; skOff: Int32;
+    const pk: TCryptoLibByteArray; pkOff: Int32; const ctx: TCryptoLibByteArray;
+    const ph: IDigest; const sig: TCryptoLibByteArray; sigOff: Int32); overload;
+
+  function Verify(const sig: TCryptoLibByteArray; sigOff: Int32;
+    const pk: TCryptoLibByteArray; pkOff: Int32; const m: TCryptoLibByteArray;
+    mOff, mLen: Int32): Boolean; overload;
+
+  function Verify(const sig: TCryptoLibByteArray; sigOff: Int32;
+    const pk: TCryptoLibByteArray; pkOff: Int32;
+    const ctx, m: TCryptoLibByteArray; mOff, mLen: Int32): Boolean; overload;
+
+  function VerifyPreHash(const sig: TCryptoLibByteArray; sigOff: Int32;
+    const pk: TCryptoLibByteArray; pkOff: Int32;
+    const ctx, ph: TCryptoLibByteArray; phOff: Int32): Boolean; overload;
+
+  function VerifyPreHash(const sig: TCryptoLibByteArray; sigOff: Int32;
+    const pk: TCryptoLibByteArray; pkOff: Int32; const ctx: TCryptoLibByteArray;
+    const ph: IDigest): Boolean; overload;
+
+  end;
+
+implementation
+
+{ TEd25519.TPointExt }
+
+constructor TEd25519.TPointExt.Create;
+begin
+  Inherited Create();
+  Fx := TX25519Field.Create();
+  Fy := TX25519Field.Create();
+  Fz := TX25519Field.Create();
+  Ft := TX25519Field.Create();
+end;
+
+function TEd25519.TPointExt.GetT: TCryptoLibInt32Array;
+begin
+  result := Ft;
+end;
+
+function TEd25519.TPointExt.GetX: TCryptoLibInt32Array;
+begin
+  result := Fx;
+end;
+
+function TEd25519.TPointExt.GetY: TCryptoLibInt32Array;
+begin
+  result := Fy;
+end;
+
+function TEd25519.TPointExt.GetZ: TCryptoLibInt32Array;
+begin
+  result := Fz;
+end;
+
+procedure TEd25519.TPointExt.SetT(const value: TCryptoLibInt32Array);
+begin
+  Ft := value;
+end;
+
+procedure TEd25519.TPointExt.SetX(const value: TCryptoLibInt32Array);
+begin
+  Fx := value;
+end;
+
+procedure TEd25519.TPointExt.SetY(const value: TCryptoLibInt32Array);
+begin
+  Fy := value;
+end;
+
+procedure TEd25519.TPointExt.SetZ(const value: TCryptoLibInt32Array);
+begin
+  Fz := value;
+end;
+
+{ TEd25519.TPointAccum }
+
+constructor TEd25519.TPointAccum.Create;
+begin
+  Inherited Create();
+  Fx := TX25519Field.Create();
+  Fy := TX25519Field.Create();
+  Fz := TX25519Field.Create();
+  Fu := TX25519Field.Create();
+  Fv := TX25519Field.Create();
+end;
+
+function TEd25519.TPointAccum.GetU: TCryptoLibInt32Array;
+begin
+  result := Fu;
+end;
+
+function TEd25519.TPointAccum.GetV: TCryptoLibInt32Array;
+begin
+  result := Fv;
+end;
+
+function TEd25519.TPointAccum.GetX: TCryptoLibInt32Array;
+begin
+  result := Fx;
+end;
+
+function TEd25519.TPointAccum.GetY: TCryptoLibInt32Array;
+begin
+  result := Fy;
+end;
+
+function TEd25519.TPointAccum.GetZ: TCryptoLibInt32Array;
+begin
+  result := Fz;
+end;
+
+procedure TEd25519.TPointAccum.SetU(const value: TCryptoLibInt32Array);
+begin
+  Fu := value;
+end;
+
+procedure TEd25519.TPointAccum.SetV(const value: TCryptoLibInt32Array);
+begin
+  Fv := value;
+end;
+
+procedure TEd25519.TPointAccum.SetX(const value: TCryptoLibInt32Array);
+begin
+  Fx := value;
+end;
+
+procedure TEd25519.TPointAccum.SetY(const value: TCryptoLibInt32Array);
+begin
+  Fy := value;
+end;
+
+procedure TEd25519.TPointAccum.SetZ(const value: TCryptoLibInt32Array);
+begin
+  Fz := value;
+end;
+
+{ TEd25519.TPointPrecomp }
+
+constructor TEd25519.TPointPrecomp.Create;
+begin
+  Inherited Create();
+  Fypx_h := TX25519Field.Create();
+  Fymx_h := TX25519Field.Create();
+  Fxyd := TX25519Field.Create();
+end;
+
+function TEd25519.TPointPrecomp.GetXyd: TCryptoLibInt32Array;
+begin
+  result := Fxyd;
+end;
+
+function TEd25519.TPointPrecomp.GetYmx_h: TCryptoLibInt32Array;
+begin
+  result := Fymx_h;
+end;
+
+function TEd25519.TPointPrecomp.GetYpx_h: TCryptoLibInt32Array;
+begin
+  result := Fypx_h;
+end;
+
+procedure TEd25519.TPointPrecomp.SetXyd(const value: TCryptoLibInt32Array);
+begin
+  Fxyd := value;
+end;
+
+procedure TEd25519.TPointPrecomp.SetYmx_h(const value: TCryptoLibInt32Array);
+begin
+  Fymx_h := value;
+end;
+
+procedure TEd25519.TPointPrecomp.SetYpx_h(const value: TCryptoLibInt32Array);
+begin
+  Fypx_h := value;
+end;
+
+{ TEd25519 }
+
+class procedure TEd25519.Boot;
+begin
+  // 'SigEd25519 no Ed25519 collisions' as ByteArray using ASCII Encoding
+  FDom2Prefix := TCryptoLibByteArray.Create(83, 105, 103, 69, 100, 50, 53, 53,
+    49, 57, 32, 110, 111, 32, 69, 100, 50, 53, 53, 49, 57, 32, 99, 111, 108,
+    108, 105, 115, 105, 111, 110, 115);
+
+  FP := TCryptoLibUInt32Array.Create($FFFFFFED, $FFFFFFFF, $FFFFFFFF, $FFFFFFFF,
+    $FFFFFFFF, $FFFFFFFF, $FFFFFFFF, $7FFFFFFF);
+  FL := TCryptoLibUInt32Array.Create($5CF5D3ED, $5812631A, $A2F79CD6, $14DEF9DE,
+    $00000000, $00000000, $00000000, $10000000);
+
+  FB_x := TCryptoLibInt32Array.Create($0325D51A, $018B5823, $007B2C95,
+    $0304A92D, $00D2598E, $01D6DC5C, $01388C7F, $013FEC0A, $029E6B72,
+    $0042D26D);
+  FB_y := TCryptoLibInt32Array.Create($02666658, $01999999, $00666666,
+    $03333333, $00CCCCCC, $02666666, $01999999, $00666666, $03333333,
+    $00CCCCCC);
+  FC_d := TCryptoLibInt32Array.Create($035978A3, $02D37284, $018AB75E,
+    $026A0A0E, $0000E014, $0379E898, $01D01E5D, $01E738CC, $03715B7F,
+    $00A406D9);
+  FC_d2 := TCryptoLibInt32Array.Create($02B2F159, $01A6E509, $01156EBD,
+    $00D4141D, $0001C029, $02F3D130, $03A03CBB, $01CE7198, $02E2B6FF,
+    $00480DB3);
+  FC_d4 := TCryptoLibInt32Array.Create($0165E2B2, $034DCA13, $002ADD7A,
+    $01A8283B, $00038052, $01E7A260, $03407977, $019CE331, $01C56DFF,
+    $00901B67);
+
+  if FPrecompLock = Nil then
+  begin
+    FPrecompLock := TCriticalSection.Create;
+  end;
+end;
+
+class function TEd25519.Decode32(const bs: TCryptoLibByteArray;
+  off: Int32): UInt32;
+begin
+  // UInt32 n := bs[off];
+  // System.Inc(off);
+  // n := n or (UInt32(bs[off]) shl 8);
+  // System.Inc(off);
+  // n := n or (UInt32(bs[off]) shl 16);
+  // System.Inc(off);
+  // n := n or (UInt32(bs[off]) shl 24);
+  // result := n;
+  result := TConverters.ReadBytesAsUInt32LE(PByte(bs), off);
+end;
+
+class procedure TEd25519.Decode32(const bs: TCryptoLibByteArray; bsOff: Int32;
+  const n: TCryptoLibUInt32Array; nOff, nLen: Int32);
+begin
+  // int32 i;
+  // for i := 0 to System.Pred(nLen) do
+  // begin
+  // n[nOff + i] := Decode32(bs, bsOff + (i * 4));
+  // end;
+  TConverters.le32_copy(PByte(bs), bsOff * System.SizeOf(Byte), PCardinal(n),
+    nOff * System.SizeOf(UInt32), nLen * System.SizeOf(UInt32));
+end;
+
+class procedure TEd25519.DecodeScalar(const k: TCryptoLibByteArray; kOff: Int32;
+  const n: TCryptoLibUInt32Array);
+begin
+  Decode32(k, kOff, n, 0, ScalarUints);
+end;
+
+class procedure TEd25519.Encode24(n: UInt32; const bs: TCryptoLibByteArray;
+  off: Int32);
+begin
+  bs[off] := Byte(n);
+  System.Inc(off);
+  bs[off] := Byte(n shr 8);
+  System.Inc(off);
+  bs[off] := Byte(n shr 16);
+end;
+
+class procedure TEd25519.Encode32(n: UInt32; const bs: TCryptoLibByteArray;
+  off: Int32);
+begin
+  // bs[  off] := Byte(n      );
+  // System.Inc(off);
+  // bs[off] := Byte(n shr  8);
+  // System.Inc(off);
+  // bs[off] := Byte(n shr  16);
+  // System.Inc(off);
+  // bs[off] := Byte(n shr  24);
+  TConverters.ReadUInt32AsBytesLE(n, bs, off);
+end;
+
+class procedure TEd25519.Encode56(n: UInt64; const bs: TCryptoLibByteArray;
+  off: Int32);
+begin
+  Encode32(UInt32(n), bs, off);
+  Encode24(UInt32(n shr 32), bs, off + 4);
+end;
+
+class function TEd25519.CalculateS(const r, k, s: TCryptoLibByteArray)
+  : TCryptoLibByteArray;
+var
+  T, U, V: TCryptoLibUInt32Array;
+  i: Int32;
+begin
+  System.SetLength(T, ScalarUints * 2);
+  DecodeScalar(r, 0, T);
+  System.SetLength(U, ScalarUints);
+  DecodeScalar(k, 0, U);
+  System.SetLength(V, ScalarUints);
+  DecodeScalar(s, 0, V);
+
+  TNat256.MulAddTo(U, V, T);
+
+  System.SetLength(result, ScalarBytes * 2);
+
+  for i := 0 to System.Pred(System.Length(T)) do
+  begin
+    Encode32(T[i], result, i * 4);
+  end;
+  result := ReduceScalar(result);
+end;
+
+class function TEd25519.CheckContextVar(const ctx
+  : TCryptoLibCustomByteArrayBuffer; phflag: Byte): Boolean;
+begin
+  result := ((ctx.IsNil) and (phflag = $00)) or
+    ((not ctx.IsNil) and (ctx.Length < 256));
+end;
+
+class function TEd25519.CheckPointVar(const p: TCryptoLibByteArray): Boolean;
+var
+  T: TCryptoLibUInt32Array;
+begin
+  System.SetLength(T, 8);
+  Decode32(p, 0, T, 0, 8);
+  T[7] := T[7] and $7FFFFFFF;
+  result := not(TNat256.Gte(T, FP));
+end;
+
+class function TEd25519.CheckScalarVar(const s: TCryptoLibByteArray): Boolean;
+var
+  n: TCryptoLibUInt32Array;
+begin
+  System.SetLength(n, ScalarUints);
+  DecodeScalar(s, 0, n);
+  result := not(TNat256.Gte(n, FL));
+end;
+
+constructor TEd25519.Create;
+begin
+  Inherited Create();
+end;
+
+function TEd25519.CreateDigest: IDigest;
+begin
+  result := TDigestUtilities.GetDigest('SHA-512');
+end;
+
+class constructor TEd25519.CreateEd25519;
+begin
+  TEd25519.Boot();
+end;
+
+function TEd25519.CreatePreHash: IDigest;
+begin
+  result := CreateDigest();
+end;
+
+class function TEd25519.Decode24(const bs: TCryptoLibByteArray;
+  off: Int32): UInt32;
+var
+  n: UInt32;
+begin
+  n := bs[off];
+  System.Inc(off);
+  n := n or (UInt32(bs[off]) shl 8);
+  System.Inc(off);
+  n := n or (UInt32(bs[off]) shl 16);
+  result := n;
+end;
+
+class procedure TEd25519.PointExtendXY(const p: IPointAccum);
+begin
+  TX25519Field.One(p.Z);
+  TX25519Field.Copy(p.X, 0, p.U, 0);
+  TX25519Field.Copy(p.Y, 0, p.V, 0);
+end;
+
+class procedure TEd25519.PointExtendXY(const p: IPointExt);
+begin
+  TX25519Field.One(p.Z);
+  TX25519Field.Mul(p.X, p.Y, p.T);
+end;
+
+class function TEd25519.DecodePointVar(const p: TCryptoLibByteArray;
+  pOff: Int32; ANegate: Boolean; const r: IPointExt): Boolean;
+var
+  py: TCryptoLibByteArray;
+  U, V: TCryptoLibInt32Array;
+  x_0: Int32;
+begin
+  py := TArrayUtils.CopyOfRange(p, pOff, pOff + PointBytes);
+  if (not CheckPointVar(py)) then
+  begin
+    result := false;
+    Exit;
+  end;
+
+  x_0 := (py[PointBytes - 1] and $80) shr 7;
+  py[PointBytes - 1] := py[PointBytes - 1] and $7F;
+
+  TX25519Field.Decode(py, 0, r.Y);
+
+  U := TX25519Field.Create();
+  V := TX25519Field.Create();
+
+  TX25519Field.Sqr(r.Y, U);
+  TX25519Field.Mul(FC_d, U, V);
+  TX25519Field.SubOne(U);
+  TX25519Field.AddOne(V);
+
+  if (not(TX25519Field.SqrtRatioVar(U, V, r.X))) then
+  begin
+    result := false;
+    Exit;
+  end;
+
+  TX25519Field.Normalize(r.X);
+  if ((x_0 = 1) and (TX25519Field.IsZeroVar(r.X))) then
+  begin
+    result := false;
+    Exit;
+  end;
+
+  if (ANegate xor (x_0 <> (r.X[0] and 1))) then
+  begin
+    TX25519Field.negate(r.X, r.X);
+  end;
+
+  PointExtendXY(r);
+  result := true;
+end;
+
+class destructor TEd25519.DestroyEd25519;
+begin
+  FPrecompLock.Free;
+end;
+
+class procedure TEd25519.Dom2(const d: IDigest; phflag: Byte;
+  const ctx: TCryptoLibCustomByteArrayBuffer);
+begin
+  if (not(ctx.IsNil)) then
+  begin
+    d.BlockUpdate(FDom2Prefix, 0, System.Length(FDom2Prefix));
+    d.Update(phflag);
+    d.Update(Byte(ctx.Length));
+    if ctx.Data <> Nil then
+    begin
+      d.BlockUpdate(ctx.Data, 0, ctx.Length);
+    end;
+  end;
+end;
+
+class procedure TEd25519.EncodePoint(const p: IPointAccum;
+  const r: TCryptoLibByteArray; rOff: Int32);
+var
+  X, Y: TCryptoLibInt32Array;
+begin
+  X := TX25519Field.Create();
+  Y := TX25519Field.Create();
+
+  TX25519Field.Inv(p.Z, Y);
+  TX25519Field.Mul(p.X, Y, X);
+  TX25519Field.Mul(p.Y, Y, Y);
+  TX25519Field.Normalize(X);
+  TX25519Field.Normalize(Y);
+
+  TX25519Field.Encode(Y, r, rOff);
+  r[rOff + PointBytes - 1] := r[rOff + PointBytes - 1] or
+    Byte((X[0] and 1) shl 7);
+end;
+
+procedure TEd25519.GeneratePrivateKey(const random: ISecureRandom;
+  const k: TCryptoLibByteArray);
+begin
+  random.NextBytes(k);
+end;
+
+class procedure TEd25519.PruneScalar(const n: TCryptoLibByteArray; nOff: Int32;
+  const r: TCryptoLibByteArray);
+begin
+  System.Move(n[nOff], r[0], ScalarBytes * System.SizeOf(Byte));
+
+  r[0] := r[0] and $F8;
+  r[ScalarBytes - 1] := r[ScalarBytes - 1] and $7F;
+  r[ScalarBytes - 1] := r[ScalarBytes - 1] or $40;
+end;
+
+class procedure TEd25519.ScalarMultBaseEncoded(const k, r: TCryptoLibByteArray;
+  rOff: Int32);
+var
+  p: IPointAccum;
+begin
+  p := TPointAccum.Create();
+  ScalarMultBase(k, p);
+  EncodePoint(p, r, rOff);
+end;
+
+procedure TEd25519.GeneratePublicKey(const sk: TCryptoLibByteArray;
+  skOff: Int32; pk: TCryptoLibByteArray; pkOff: Int32);
+var
+  d: IDigest;
+  h, s: TCryptoLibByteArray;
+begin
+  d := CreateDigest();
+  System.SetLength(h, d.GetDigestSize());
+
+  d.BlockUpdate(sk, skOff, SecretKeySize);
+  d.DoFinal(h, 0);
+
+  System.SetLength(s, ScalarBytes);
+
+  PruneScalar(h, 0, s);
+
+  ScalarMultBaseEncoded(s, pk, pkOff);
+end;
+
+class function TEd25519.GetWnaf(const n: TCryptoLibUInt32Array; width: Int32)
+  : TCryptoLibShortIntArray;
+var
+  T: TCryptoLibUInt32Array;
+  ws: TCryptoLibShortIntArray;
+  i, tPos, j: Int32;
+  c, next, pow2, mask, LSign, carry, word, word16, bit, digit: UInt32;
+begin
+{$IFDEF DEBUG}
+  System.Assert((n[ScalarUints - 1] shr 31) = 0);
+{$ENDIF DEBUG}
+  System.SetLength(T, ScalarUints * 2);
+
+  c := 0;
+  tPos := System.Length(T);
+  i := ScalarUints;
+  System.Dec(i);
+  while (i >= 0) do
+  begin
+    next := n[i];
+    System.Dec(tPos);
+    T[tPos] := (next shr 16) or (c shl 16);
+    System.Dec(tPos);
+    c := next;
+    T[tPos] := c;
+    System.Dec(i);
+  end;
+
+  System.SetLength(ws, 256);
+
+  pow2 := UInt32(1) shl width;
+  mask := pow2 - UInt32(1);
+  LSign := pow2 shr 1;
+
+  carry := UInt32(0);
+  j := 0;
+
+  for i := 0 to System.Pred(System.Length(T)) do
+  begin
+    word := T[i];
+    while (j < 16) do
+    begin
+      word16 := word shr j;
+      bit := word16 and UInt32(1);
+
+      if (bit = carry) then
+      begin
+        System.Inc(j);
+        continue;
+      end;
+
+      digit := (word16 and mask) + carry;
+      carry := digit and LSign;
+      digit := digit - (carry shl 1);
+      carry := carry shr (width - 1);
+
+      ws[(i shl 4) + j] := ShortInt(digit);
+
+      j := j + width;
+    end;
+    System.Dec(j, 16);
+  end;
+
+{$IFDEF DEBUG}
+  System.Assert(carry = 0);
+{$ENDIF DEBUG}
+  result := ws;
+end;
+
+procedure TEd25519.ImplSign(const sk: TCryptoLibByteArray; skOff: Int32;
+  const pk: TCryptoLibByteArray; pkOff: Int32;
+  const ctx: TCryptoLibCustomByteArrayBuffer; phflag: Byte;
+  const m: TCryptoLibByteArray; mOff, mLen: Int32;
+  const sig: TCryptoLibByteArray; sigOff: Int32);
+var
+  d: IDigest;
+  h, s: TCryptoLibByteArray;
+begin
+  if (not CheckContextVar(ctx, phflag)) then
+  begin
+    raise EArgumentCryptoLibException.CreateRes(@SInvalidCtx);
+  end;
+
+  d := CreateDigest();
+  System.SetLength(h, d.GetDigestSize());
+
+  d.BlockUpdate(sk, skOff, SecretKeySize);
+  d.DoFinal(h, 0);
+
+  System.SetLength(s, ScalarBytes);
+  PruneScalar(h, 0, s);
+
+  ImplSign(d, h, s, pk, pkOff, ctx, phflag, m, mOff, mLen, sig, sigOff);
+
+end;
+
+procedure TEd25519.ImplSign(const sk: TCryptoLibByteArray; skOff: Int32;
+  const ctx: TCryptoLibCustomByteArrayBuffer; phflag: Byte;
+  const m: TCryptoLibByteArray; mOff, mLen: Int32;
+  const sig: TCryptoLibByteArray; sigOff: Int32);
+var
+  d: IDigest;
+  h, s, pk: TCryptoLibByteArray;
+begin
+  if (not CheckContextVar(ctx, phflag)) then
+  begin
+    raise EArgumentCryptoLibException.CreateRes(@SInvalidCtx);
+  end;
+
+  d := CreateDigest();
+  System.SetLength(h, d.GetDigestSize());
+
+  d.BlockUpdate(sk, skOff, SecretKeySize);
+  d.DoFinal(h, 0);
+
+  System.SetLength(s, ScalarBytes);
+  PruneScalar(h, 0, s);
+
+  System.SetLength(pk, PointBytes);
+  ScalarMultBaseEncoded(s, pk, 0);
+
+  ImplSign(d, h, s, pk, 0, ctx, phflag, m, mOff, mLen, sig, sigOff);
+end;
+
+class procedure TEd25519.ImplSign(const d: IDigest;
+  const h, s, pk: TCryptoLibByteArray; pkOff: Int32;
+  const ctx: TCryptoLibCustomByteArrayBuffer; phflag: Byte;
+  const m: TCryptoLibByteArray; mOff, mLen: Int32;
+  const sig: TCryptoLibByteArray; sigOff: Int32);
+var
+  r, bigR, k, bigS: TCryptoLibByteArray;
+begin
+  Dom2(d, phflag, ctx);
+  d.BlockUpdate(h, ScalarBytes, ScalarBytes);
+  d.BlockUpdate(m, mOff, mLen);
+  d.DoFinal(h, 0);
+
+  r := ReduceScalar(h);
+  System.SetLength(bigR, PointBytes);
+  ScalarMultBaseEncoded(r, bigR, 0);
+
+  Dom2(d, phflag, ctx);
+  d.BlockUpdate(bigR, 0, PointBytes);
+  d.BlockUpdate(pk, pkOff, PointBytes);
+  d.BlockUpdate(m, mOff, mLen);
+  d.DoFinal(h, 0);
+
+  k := ReduceScalar(h);
+  bigS := CalculateS(r, k, s);
+
+  System.Move(bigR[0], sig[sigOff], PointBytes * System.SizeOf(Byte));
+  System.Move(bigS[0], sig[sigOff + PointBytes],
+    ScalarBytes * System.SizeOf(Byte));
+end;
+
+function TEd25519.ImplVerify(const sig: TCryptoLibByteArray; sigOff: Int32;
+  const pk: TCryptoLibByteArray; pkOff: Int32;
+  const ctx: TCryptoLibCustomByteArrayBuffer; phflag: Byte;
+  const m: TCryptoLibByteArray; mOff, mLen: Int32): Boolean;
+var
+  r, s, h, k, check: TCryptoLibByteArray;
+  nS, nA: TCryptoLibUInt32Array;
+  pA: IPointExt;
+  pR: IPointAccum;
+  d: IDigest;
+begin
+  if (not CheckContextVar(ctx, phflag)) then
+  begin
+    raise EArgumentCryptoLibException.CreateRes(@SInvalidCtx);
+  end;
+
+  r := TArrayUtils.CopyOfRange(sig, sigOff, sigOff + PointBytes);
+  s := TArrayUtils.CopyOfRange(sig, sigOff + PointBytes,
+    sigOff + SignatureSize);
+
+  if (not CheckPointVar(r)) then
+  begin
+    result := false;
+    Exit;
+  end;
+
+  if (not CheckScalarVar(s)) then
+  begin
+    result := false;
+    Exit;
+  end;
+
+  pA := TPointExt.Create();
+  if (not DecodePointVar(pk, pkOff, true, pA)) then
+  begin
+    result := false;
+    Exit;
+  end;
+
+  d := CreateDigest();
+  System.SetLength(h, d.GetDigestSize());
+
+  Dom2(d, phflag, ctx);
+  d.BlockUpdate(r, 0, PointBytes);
+  d.BlockUpdate(pk, pkOff, PointBytes);
+  d.BlockUpdate(m, mOff, mLen);
+  d.DoFinal(h, 0);
+
+  k := ReduceScalar(h);
+
+  System.SetLength(nS, ScalarUints);
+  DecodeScalar(s, 0, nS);
+
+  System.SetLength(nA, ScalarUints);
+
+  DecodeScalar(k, 0, nA);
+
+  pR := TPointAccum.Create();
+  ScalarMultStraussVar(nS, nA, pA, pR);
+
+  System.SetLength(check, PointBytes);
+
+  EncodePoint(pR, check, 0);
+
+  result := TArrayUtils.ConstantTimeAreEqual(check, r);
+end;
+
+class procedure TEd25519.PointAddPrecomp(const p: IPointPrecomp;
+  const r: IPointAccum);
+var
+  bigA, bigB, bigC, bigD, bigE, bigF, bigG: TCryptoLibInt32Array;
+begin
+  bigA := TX25519Field.Create();
+  bigB := TX25519Field.Create();
+  bigC := TX25519Field.Create();
+  bigD := r.U;
+  bigE := TX25519Field.Create();
+  bigF := TX25519Field.Create();
+  bigG := r.V;
+
+  TX25519Field.Apm(r.Y, r.X, bigB, bigA);
+  TX25519Field.Mul(bigA, p.Ymx_h, bigA);
+  TX25519Field.Mul(bigB, p.Ypx_h, bigB);
+  TX25519Field.Mul(r.U, r.V, bigC);
+  TX25519Field.Mul(bigC, p.Xyd, bigC);
+  TX25519Field.Apm(bigB, bigA, bigG, bigD);
+  TX25519Field.Apm(r.Z, bigC, bigF, bigE);
+  TX25519Field.carry(bigF);
+  TX25519Field.Mul(bigD, bigE, r.X);
+  TX25519Field.Mul(bigF, bigG, r.Y);
+  TX25519Field.Mul(bigE, bigF, r.Z);
+end;
+
+class procedure TEd25519.PointAddVar(negate: Boolean; const p, q, r: IPointExt);
+var
+  bigA, bigB, bigC, bigD, bigE, bigF, bigG, bigH, c, d, f,
+    g: TCryptoLibInt32Array;
+begin
+  bigA := TX25519Field.Create();
+  bigB := TX25519Field.Create();
+  bigC := TX25519Field.Create();
+  bigD := TX25519Field.Create();
+  bigE := TX25519Field.Create();
+  bigF := TX25519Field.Create();
+  bigG := TX25519Field.Create();
+  bigH := TX25519Field.Create();
+
+  if (negate) then
+  begin
+    c := bigD;
+    d := bigC;
+    f := bigG;
+    g := bigF;
+  end
+  else
+  begin
+    c := bigC;
+    d := bigD;
+    f := bigF;
+    g := bigG;
+  end;
+
+  TX25519Field.Apm(p.Y, p.X, bigB, bigA);
+  TX25519Field.Apm(q.Y, q.X, d, c);
+  TX25519Field.Mul(bigA, bigC, bigA);
+  TX25519Field.Mul(bigB, bigD, bigB);
+  TX25519Field.Mul(p.T, q.T, bigC);
+  TX25519Field.Mul(bigC, FC_d2, bigC);
+  TX25519Field.Mul(p.Z, q.Z, bigD);
+  TX25519Field.Add(bigD, bigD, bigD);
+  TX25519Field.Apm(bigB, bigA, bigH, bigE);
+  TX25519Field.Apm(bigD, bigC, g, f);
+  TX25519Field.carry(g);
+  TX25519Field.Mul(bigE, bigF, r.X);
+  TX25519Field.Mul(bigG, bigH, r.Y);
+  TX25519Field.Mul(bigF, bigG, r.Z);
+  TX25519Field.Mul(bigE, bigH, r.T);
+end;
+
+class procedure TEd25519.PointAddVar(negate: Boolean; const p: IPointExt;
+  const r: IPointAccum);
+var
+  bigA, bigB, bigC, bigD, bigE, bigF, bigG, bigH, c, d, f,
+    g: TCryptoLibInt32Array;
+begin
+  bigA := TX25519Field.Create();
+  bigB := TX25519Field.Create();
+  bigC := TX25519Field.Create();
+  bigD := TX25519Field.Create();
+  bigE := r.U;
+  bigF := TX25519Field.Create();
+  bigG := TX25519Field.Create();
+  bigH := r.V;
+
+  if (negate) then
+  begin
+    c := bigD;
+    d := bigC;
+    f := bigG;
+    g := bigF;
+  end
+  else
+  begin
+    c := bigC;
+    d := bigD;
+    f := bigF;
+    g := bigG;
+  end;
+
+  TX25519Field.Apm(r.Y, r.X, bigB, bigA);
+  TX25519Field.Apm(p.Y, p.X, d, c);
+  TX25519Field.Mul(bigA, bigC, bigA);
+  TX25519Field.Mul(bigB, bigD, bigB);
+  TX25519Field.Mul(r.U, r.V, bigC);
+  TX25519Field.Mul(bigC, p.T, bigC);
+  TX25519Field.Mul(bigC, FC_d2, bigC);
+  TX25519Field.Mul(r.Z, p.Z, bigD);
+  TX25519Field.Add(bigD, bigD, bigD);
+  TX25519Field.Apm(bigB, bigA, bigH, bigE);
+  TX25519Field.Apm(bigD, bigC, g, f);
+  TX25519Field.carry(g);
+  TX25519Field.Mul(bigE, bigF, r.X);
+  TX25519Field.Mul(bigG, bigH, r.Y);
+  TX25519Field.Mul(bigF, bigG, r.Z);
+end;
+
+class function TEd25519.PointCopy(const p: IPointAccum): IPointExt;
+var
+  r: IPointExt;
+begin
+  r := TPointExt.Create();
+  TX25519Field.Copy(p.X, 0, r.X, 0);
+  TX25519Field.Copy(p.Y, 0, r.Y, 0);
+  TX25519Field.Copy(p.Z, 0, r.Z, 0);
+  TX25519Field.Mul(p.U, p.V, r.T);
+  result := r;
+end;
+
+class function TEd25519.PointCopy(const p: IPointExt): IPointExt;
+var
+  r: IPointExt;
+begin
+  r := TPointExt.Create();
+  TX25519Field.Copy(p.X, 0, r.X, 0);
+  TX25519Field.Copy(p.Y, 0, r.Y, 0);
+  TX25519Field.Copy(p.Z, 0, r.Z, 0);
+  TX25519Field.Copy(p.T, 0, r.T, 0);
+  result := r;
+end;
+
+class procedure TEd25519.PointDouble(const r: IPointAccum);
+var
+  bigA, bigB, bigC, bigD, bigE, bigF, bigG: TCryptoLibInt32Array;
+begin
+  bigA := TX25519Field.Create();
+  bigB := TX25519Field.Create();
+  bigC := TX25519Field.Create();
+  bigD := r.U;
+  bigE := TX25519Field.Create();
+  bigF := TX25519Field.Create();
+  bigG := r.V;
+
+  TX25519Field.Sqr(r.X, bigA);
+  TX25519Field.Sqr(r.Y, bigB);
+  TX25519Field.Sqr(r.Z, bigC);
+  TX25519Field.Add(bigC, bigC, bigC);
+  TX25519Field.Apm(bigA, bigB, bigG, bigF);
+  TX25519Field.Add(r.X, r.Y, bigD);
+  TX25519Field.Sqr(bigD, bigD);
+  TX25519Field.Sub(bigG, bigD, bigD);
+  TX25519Field.Add(bigC, bigF, bigE);
+  TX25519Field.carry(bigE);
+  TX25519Field.Mul(bigD, bigE, r.X);
+  TX25519Field.Mul(bigF, bigG, r.Y);
+  TX25519Field.Mul(bigE, bigF, r.Z);
+end;
+
+class procedure TEd25519.PointLookup(block, index: Int32;
+  const p: IPointPrecomp);
+var
+  off, i, mask: Int32;
+begin
+{$IFDEF DEBUG}
+  System.Assert((0 <= block) and (block < PrecompBlocks));
+  System.Assert((0 <= index) and (index < PrecompPoints));
+{$ENDIF DEBUG}
+  off := block * PrecompPoints * 3 * TX25519Field.Size;
+
+  for i := 0 to System.Pred(PrecompPoints) do
+  begin
+    mask := TBits.Asr32(((i xor index) - 1), 31);
+    TNat.CMov(TX25519Field.Size, mask, FPrecompBase, off, p.Ypx_h, 0);
+    off := off + TX25519Field.Size;
+    TNat.CMov(TX25519Field.Size, mask, FPrecompBase, off, p.Ymx_h, 0);
+    off := off + TX25519Field.Size;
+    TNat.CMov(TX25519Field.Size, mask, FPrecompBase, off, p.Xyd, 0);
+    off := off + TX25519Field.Size;
+  end;
+end;
+
+class function TEd25519.PointPrecompVar(const p: IPointExt; count: Int32)
+  : TCryptoLibGenericArray<IPointExt>;
+var
+  d: IPointExt;
+  table: TCryptoLibGenericArray<IPointExt>;
+  i: Int32;
+begin
+{$IFDEF DEBUG}
+  System.Assert(count > 0);
+{$ENDIF DEBUG}
+  d := TPointExt.Create();
+  PointAddVar(false, p, p, d);
+
+  System.SetLength(table, count);
+
+  table[0] := PointCopy(p);
+  for i := 1 to System.Pred(count) do
+  begin
+    table[i] := TPointExt.Create() as IPointExt;
+    PointAddVar(false, table[i - 1], d, table[i]);
+  end;
+  result := table;
+end;
+
+class procedure TEd25519.PointSetNeutral(const p: IPointAccum);
+begin
+  TX25519Field.Zero(p.X);
+  TX25519Field.One(p.Y);
+  TX25519Field.One(p.Z);
+  TX25519Field.Zero(p.U);
+  TX25519Field.One(p.V);
+end;
+
+class procedure TEd25519.PointSetNeutral(const p: IPointExt);
+begin
+  TX25519Field.Zero(p.X);
+  TX25519Field.One(p.Y);
+  TX25519Field.One(p.Z);
+  TX25519Field.Zero(p.T);
+end;
+
+class procedure TEd25519.Precompute;
+var
+  bigB: IPointExt;
+  p: IPointAccum;
+  X, Y: TCryptoLibInt32Array;
+  off, b, T, s, k, Size, j, i: Int32;
+  // ds, points: TCryptoLibGenericArray<IPointExt>;
+  ds: array [0 .. (PrecompTeeth - 1)] of IPointExt;
+  points: array [0 .. (PrecompPoints - 1)] of IPointExt;
+  sum, q: IPointExt;
+  r: IPointPrecomp;
+begin
+  FPrecompLock.Acquire;
+  try
+
+    if (FPrecompBase <> Nil) then
+    begin
+      Exit;
+    end;
+
+    // Precomputed table for the base point in verification ladder
+    bigB := TPointExt.Create();
+    TX25519Field.Copy(FB_x, 0, bigB.X, 0);
+    TX25519Field.Copy(FB_y, 0, bigB.Y, 0);
+    PointExtendXY(bigB);
+
+    FPrecompBaseTable := PointPrecompVar(bigB, 1 shl (WnafWidthBase - 2));
+
+    p := TPointAccum.Create();
+    TX25519Field.Copy(FB_x, 0, p.X, 0);
+    TX25519Field.Copy(FB_y, 0, p.Y, 0);
+    PointExtendXY(p);
+
+    System.SetLength(FPrecompBase, PrecompBlocks * PrecompPoints * 3 *
+      TX25519Field.Size);
+
+    off := 0;
+    for b := 0 to System.Pred(PrecompBlocks) do
+    begin
+      // System.SetLength(ds, PrecompTeeth); // **
+
+      sum := TPointExt.Create() as IPointExt;
+      PointSetNeutral(sum);
+
+      for T := 0 to System.Pred(PrecompTeeth) do
+      begin
+        q := PointCopy(p);
+        PointAddVar(true, sum, q, sum);
+        PointDouble(p);
+
+        ds[T] := PointCopy(p);
+
+        if ((b + T) <> (PrecompBlocks + PrecompTeeth - 2)) then
+        begin
+          s := 1;
+          while s < PrecompSpacing do
+          begin
+            PointDouble(p);
+            System.Inc(s);
+          end;
+        end;
+      end;
+
+      // System.SetLength(points, PrecompPoints); // **
+
+      k := 0;
+      points[k] := sum;
+      System.Inc(k);
+
+      for T := 0 to System.Pred(PrecompTeeth - 1) do
+      begin
+        Size := 1 shl T;
+        j := 0;
+        while j < Size do
+        begin
+          points[k] := TPointExt.Create() as IPointExt;
+          PointAddVar(false, points[k - Size], ds[T], points[k]);
+          System.Inc(k);
+          System.Inc(j);
+        end;
+
+      end;
+{$IFDEF DEBUG}
+      System.Assert(k = PrecompPoints);
+{$ENDIF DEBUG}
+      for i := 0 to System.Pred(PrecompPoints) do
+      begin
+        q := points[i];
+
+        X := TX25519Field.Create();
+        Y := TX25519Field.Create();
+
+        TX25519Field.Add(q.Z, q.Z, X);
+        // TODO[ed25519] Batch inversion
+        TX25519Field.Inv(X, Y);
+        TX25519Field.Mul(q.X, Y, X);
+        TX25519Field.Mul(q.Y, Y, Y);
+
+        r := TPointPrecomp.Create();
+        TX25519Field.Apm(Y, X, r.Ypx_h, r.Ymx_h);
+        TX25519Field.Mul(X, Y, r.Xyd);
+        TX25519Field.Mul(r.Xyd, FC_d4, r.Xyd);
+
+        TX25519Field.Normalize(r.Ypx_h);
+        TX25519Field.Normalize(r.Ymx_h);
+        // TX25519Field.Normalize(r.xyd);
+
+        TX25519Field.Copy(r.Ypx_h, 0, FPrecompBase, off);
+        off := off + TX25519Field.Size;
+        TX25519Field.Copy(r.Ymx_h, 0, FPrecompBase, off);
+        off := off + TX25519Field.Size;
+        TX25519Field.Copy(r.Xyd, 0, FPrecompBase, off);
+        off := off + TX25519Field.Size;
+      end;
+    end;
+
+{$IFDEF DEBUG}
+    System.Assert(off = System.Length(FPrecompBase));
+{$ENDIF DEBUG}
+  finally
+    FPrecompLock.Release;
+  end;
+end;
+
+class function TEd25519.ReduceScalar(const n: TCryptoLibByteArray)
+  : TCryptoLibByteArray;
+var
+  x00, x01, x02, x03, x04, x05, x06, x07, x08, x09, x10, x11, x12, x13, x14,
+    x15, x16, x17, x18, T: Int64;
+begin
+  x00 := Decode32(n, 0) and Int64(M32L); // x00:32/--
+  x01 := (Decode24(n, 4) shl 4) and Int64(M32L); // x01:28/--
+  x02 := Decode32(n, 7) and Int64(M32L); // x02:32/--
+  x03 := (Decode24(n, 11) shl 4) and Int64(M32L); // x03:28/--
+  x04 := Decode32(n, 14) and Int64(M32L); // x04:32/--
+  x05 := (Decode24(n, 18) shl 4) and Int64(M32L); // x05:28/--
+  x06 := Decode32(n, 21) and Int64(M32L); // x06:32/--
+  x07 := (Decode24(n, 25) shl 4) and Int64(M32L); // x07:28/--
+  x08 := Decode32(n, 28) and Int64(M32L); // x08:32/--
+  x09 := (Decode24(n, 32) shl 4) and Int64(M32L); // x09:28/--
+  x10 := Decode32(n, 35) and Int64(M32L); // x10:32/--
+  x11 := (Decode24(n, 39) shl 4) and Int64(M32L); // x11:28/--
+  x12 := Decode32(n, 42) and Int64(M32L); // x12:32/--
+  x13 := (Decode24(n, 46) shl 4) and Int64(M32L); // x13:28/--
+  x14 := Decode32(n, 49) and Int64(M32L); // x14:32/--
+  x15 := (Decode24(n, 53) shl 4) and Int64(M32L); // x15:28/--
+  x16 := Decode32(n, 56) and Int64(M32L); // x16:32/--
+  x17 := (Decode24(n, 60) shl 4) and Int64(M32L); // x17:28/--
+  x18 := n[63] and Int64($FF); // x18:08/--
+
+  // x18 := x18 + (x17 shr  28); x17 := x17 and Int64(M28L);
+  x09 := x09 - (x18 * L0); // x09:34/28
+  x10 := x10 - (x18 * L1); // x10:33/30
+  x11 := x11 - (x18 * L2); // x11:35/28
+  x12 := x12 - (x18 * L3); // x12:32/31
+  x13 := x13 - (x18 * L4); // x13:28/21
+
+  x17 := x17 + TBits.Asr64(x16, 28); // x17:28/--
+  x16 := x16 and Int64(M28L); // x16:28/--
+  x08 := x08 - (x17 * L0); // x08:54/32
+  x09 := x09 - (x17 * L1); // x09:52/51
+  x10 := x10 - (x17 * L2); // x10:55/34
+  x11 := x11 - (x17 * L3); // x11:51/36
+  x12 := x12 - (x17 * L4); // x12:41/--
+
+  // x16 := x16 + (x15 shr  28); x15 := x15 and Int64(M28L);
+  x07 := x07 - (x16 * L0); // x07:54/28
+  x08 := x08 - (x16 * L1); // x08:54/53
+  x09 := x09 - (x16 * L2); // x09:55/53
+  x10 := x10 - (x16 * L3); // x10:55/52
+  x11 := x11 - (x16 * L4); // x11:51/41
+
+  x15 := x15 + TBits.Asr64(x14, 28); // x15:28/--
+  x14 := x14 and Int64(M28L); // x14:28/--
+  x06 := x06 - (x15 * L0); // x06:54/32
+  x07 := x07 - (x15 * L1); // x07:54/53
+  x08 := x08 - (x15 * L2); // x08:56/--
+  x09 := x09 - (x15 * L3); // x09:55/54
+  x10 := x10 - (x15 * L4); // x10:55/53
+
+  // x14 := x14 + (x13 shr  28); x13 := x13 and Int64(M28L);
+  x05 := x05 - (x14 * L0); // x05:54/28
+  x06 := x06 - (x14 * L1); // x06:54/53
+  x07 := x07 - (x14 * L2); // x07:56/--
+  x08 := x08 - (x14 * L3); // x08:56/51
+  x09 := x09 - (x14 * L4); // x09:56/--
+
+  x13 := x13 + TBits.Asr64(x12, 28); // x13:28/22
+  x12 := x12 and Int64(M28L); // x12:28/--
+  x04 := x04 - (x13 * L0); // x04:54/49
+  x05 := x05 - (x13 * L1); // x05:54/53
+  x06 := x06 - (x13 * L2); // x06:56/--
+  x07 := x07 - (x13 * L3); // x07:56/52
+  x08 := x08 - (x13 * L4); // x08:56/52
+
+  x12 := x12 + TBits.Asr64(x11, 28); // x12:28/24
+  x11 := x11 and Int64(M28L); // x11:28/--
+  x03 := x03 - (x12 * L0); // x03:54/49
+  x04 := x04 - (x12 * L1); // x04:54/51
+  x05 := x05 - (x12 * L2); // x05:56/--
+  x06 := x06 - (x12 * L3); // x06:56/52
+  x07 := x07 - (x12 * L4); // x07:56/53
+
+  x11 := x11 + TBits.Asr64(x10, 28); // x11:29/--
+  x10 := x10 and Int64(M28L); // x10:28/--
+  x02 := x02 - (x11 * L0); // x02:55/32
+  x03 := x03 - (x11 * L1); // x03:55/--
+  x04 := x04 - (x11 * L2); // x04:56/55
+  x05 := x05 - (x11 * L3); // x05:56/52
+  x06 := x06 - (x11 * L4); // x06:56/53
+
+  x10 := x10 + TBits.Asr64(x09, 28); // x10:29/--
+  x09 := x09 and Int64(M28L); // x09:28/--
+  x01 := x01 - (x10 * L0); // x01:55/28
+  x02 := x02 - (x10 * L1); // x02:55/54
+  x03 := x03 - (x10 * L2); // x03:56/55
+  x04 := x04 - (x10 * L3); // x04:57/--
+  x05 := x05 - (x10 * L4); // x05:56/53
+
+  x08 := x08 + TBits.Asr64(x07, 28); // x08:56/53
+  x07 := x07 and Int64(M28L); // x07:28/--
+  x09 := x09 + TBits.Asr64(x08, 28); // x09:29/25
+  x08 := x08 and Int64(M28L); // x08:28/--
+
+  T := TBits.Asr64(x08, 27) and Int64(1);
+  x09 := x09 + T; // x09:29/26
+
+  x00 := x00 - (x09 * L0); // x00:55/53
+  x01 := x01 - (x09 * L1); // x01:55/54
+  x02 := x02 - (x09 * L2); // x02:57/--
+  x03 := x03 - (x09 * L3); // x03:57/--
+  x04 := x04 - (x09 * L4); // x04:57/42
+
+  x01 := x01 + TBits.Asr64(x00, 28);
+  x00 := x00 and Int64(M28L);
+  x02 := x02 + TBits.Asr64(x01, 28);
+  x01 := x01 and Int64(M28L);
+  x03 := x03 + TBits.Asr64(x02, 28);
+  x02 := x02 and Int64(M28L);
+  x04 := x04 + TBits.Asr64(x03, 28);
+  x03 := x03 and Int64(M28L);
+  x05 := x05 + TBits.Asr64(x04, 28);
+  x04 := x04 and Int64(M28L);
+  x06 := x06 + TBits.Asr64(x05, 28);
+  x05 := x05 and Int64(M28L);
+  x07 := x07 + TBits.Asr64(x06, 28);
+  x06 := x06 and Int64(M28L);
+  x08 := x08 + TBits.Asr64(x07, 28);
+  x07 := x07 and Int64(M28L);
+  x09 := TBits.Asr64(x08, 28);
+  x08 := x08 and Int64(M28L);
+
+  x09 := x09 - T;
+
+{$IFDEF DEBUG}
+  System.Assert((x09 = Int64(0)) or (x09 = -Int64(1)));
+{$ENDIF DEBUG}
+  x00 := x00 + (x09 and L0);
+  x01 := x01 + (x09 and L1);
+  x02 := x02 + (x09 and L2);
+  x03 := x03 + (x09 and L3);
+  x04 := x04 + (x09 and L4);
+
+  x01 := x01 + TBits.Asr64(x00, 28);
+  x00 := x00 and Int64(M28L);
+  x02 := x02 + TBits.Asr64(x01, 28);
+  x01 := x01 and Int64(M28L);
+  x03 := x03 + TBits.Asr64(x02, 28);
+  x02 := x02 and Int64(M28L);
+  x04 := x04 + TBits.Asr64(x03, 28);
+  x03 := x03 and Int64(M28L);
+  x05 := x05 + TBits.Asr64(x04, 28);
+  x04 := x04 and Int64(M28L);
+  x06 := x06 + TBits.Asr64(x05, 28);
+  x05 := x05 and Int64(M28L);
+  x07 := x07 + TBits.Asr64(x06, 28);
+  x06 := x06 and Int64(M28L);
+  x08 := x08 + TBits.Asr64(x07, 28);
+  x07 := x07 and Int64(M28L);
+
+  System.SetLength(result, ScalarBytes);
+  Encode56(UInt64(x00 or (x01 shl 28)), result, 0);
+  Encode56(UInt64(x02 or (x03 shl 28)), result, 7);
+  Encode56(UInt64(x04 or (x05 shl 28)), result, 14);
+  Encode56(UInt64(x06 or (x07 shl 28)), result, 21);
+  Encode32(UInt32(x08), result, 28);
+end;
+
+class procedure TEd25519.ScalarMultBase(const k: TCryptoLibByteArray;
+  const r: IPointAccum);
+var
+  n: TCryptoLibUInt32Array;
+  w, c1, c2: UInt32;
+  i, cOff, b, LSign, abs: Int32;
+  p: IPointPrecomp;
+begin
+  Precompute();
+
+  PointSetNeutral(r);
+  System.SetLength(n, ScalarUints);
+  DecodeScalar(k, 0, n);
+
+  // Recode the scalar into signed-digit form, then group comb bits in each block
+
+  c1 := TNat.CAdd(ScalarUints, not(Int32(n[0])) and 1, n, FL, n);
+  System.Assert(c1 = 0);
+  c2 := TNat.ShiftDownBit(ScalarUints, n, UInt32(1));
+  System.Assert(c2 = (UInt32(1) shl 31));
+  for i := 0 to System.Pred(ScalarUints) do
+  begin
+    n[i] := TInterleave.Shuffle2(n[i]);
+  end;
+
+  p := TPointPrecomp.Create();
+
+  cOff := (PrecompSpacing - 1) * PrecompTeeth;
+  while true do
+
+  begin
+    for b := 0 to System.Pred(PrecompBlocks) do
+    begin
+      w := n[b] shr cOff;
+      LSign := Int32(w shr (PrecompTeeth - 1)) and 1;
+      abs := (Int32(w) xor -LSign) and PrecompMask;
+
+{$IFDEF DEBUG}
+      System.Assert((LSign = 0) or (LSign = 1));
+      System.Assert((0 <= abs) and (abs < PrecompPoints));
+{$ENDIF DEBUG}
+      PointLookup(b, abs, p);
+
+      TX25519Field.CSwap(LSign, p.Ypx_h, p.Ymx_h);
+      TX25519Field.CNegate(LSign, p.Xyd);
+
+      PointAddPrecomp(p, r);
+    end;
+    cOff := (cOff - PrecompTeeth);
+    if (cOff < 0) then
+    begin
+      break;
+    end;
+
+    PointDouble(r);
+  end;
+end;
+
+class procedure TEd25519.ScalarMultBaseYZ(const k: TCryptoLibByteArray;
+  kOff: Int32; const Y, Z: TCryptoLibInt32Array);
+var
+  n: TCryptoLibByteArray;
+  p: IPointAccum;
+begin
+  System.SetLength(n, ScalarBytes);
+  PruneScalar(k, kOff, n);
+
+  p := TPointAccum.Create();
+  ScalarMultBase(n, p);
+  TX25519Field.Copy(p.Y, 0, Y, 0);
+  TX25519Field.Copy(p.Z, 0, Z, 0);
+end;
+
+class procedure TEd25519.ScalarMultStraussVar(const nb,
+  np: TCryptoLibUInt32Array; const p: IPointExt; const r: IPointAccum);
+var
+  width, bit, wb, wp, LSign, index: Int32;
+  ws_b, ws_p: TCryptoLibShortIntArray;
+  tp: TCryptoLibGenericArray<IPointExt>;
+begin
+  Precompute();
+
+  width := 5;
+
+  ws_b := GetWnaf(nb, WnafWidthBase);
+  ws_p := GetWnaf(np, width);
+
+  tp := PointPrecompVar(p, 1 shl (width - 2));
+
+  PointSetNeutral(r);
+
+  bit := 255;
+  while ((bit > 0) and ((Byte(ws_b[bit]) or Byte(ws_p[bit])) = 0)) do
+  begin
+    System.Dec(bit);
+  end;
+
+  while true do
+  begin
+    wb := ws_b[bit];
+    if (wb <> 0) then
+    begin
+      LSign := TBits.Asr32(wb, 31);
+      index := TBits.Asr32((wb xor LSign), 1);
+
+      PointAddVar((LSign <> 0), FPrecompBaseTable[index], r);
+    end;
+
+    wp := ws_p[bit];
+    if (wp <> 0) then
+    begin
+      LSign := TBits.Asr32(wp, 31);
+      index := TBits.Asr32((wp xor LSign), 1);
+
+      PointAddVar((LSign <> 0), tp[index], r);
+    end;
+
+    System.Dec(bit);
+    if (bit < 0) then
+    begin
+      break;
+    end;
+
+    PointDouble(r);
+  end;
+end;
+
+class function TEd25519.ValidateDigestOutputSize(const ADigest: IDigest)
+  : TCryptoLibByteArray;
+begin
+  System.SetLength(result, PreHashSize);
+  if (PreHashSize <> ADigest.DoFinal(result, 0)) then
+  begin
+    raise EArgumentCryptoLibException.CreateRes(@SDigestError);
+  end;
+end;
+
+class function TEd25519.ConstructCustomByteArrayBufferContext
+  (const AData: TCryptoLibByteArray; AIsNil: Boolean; ALength: Int32)
+  : TCryptoLibCustomByteArrayBuffer;
+begin
+  result := Default (TCryptoLibCustomByteArrayBuffer);
+  result.Data := AData;
+  result.IsNil := AIsNil;
+  result.Length := ALength;
+end;
+
+procedure TEd25519.Sign(const sk: TCryptoLibByteArray; skOff: Int32;
+  const m: TCryptoLibByteArray; mOff, mLen: Int32;
+  const sig: TCryptoLibByteArray; sigOff: Int32);
+var
+  phflag: Byte;
+begin
+  phflag := $00;
+  ImplSign(sk, skOff, EmptyBytesNil, phflag, m, mOff, mLen, sig, sigOff);
+end;
+
+procedure TEd25519.Sign(const sk: TCryptoLibByteArray; skOff: Int32;
+  const pk: TCryptoLibByteArray; pkOff: Int32; const m: TCryptoLibByteArray;
+  mOff, mLen: Int32; const sig: TCryptoLibByteArray; sigOff: Int32);
+var
+  phflag: Byte;
+begin
+  phflag := $00;
+  ImplSign(sk, skOff, pk, pkOff, EmptyBytesNil, phflag, m, mOff, mLen,
+    sig, sigOff);
+end;
+
+procedure TEd25519.Sign(const sk: TCryptoLibByteArray; skOff: Int32;
+  const ctx, m: TCryptoLibByteArray; mOff, mLen: Int32;
+  const sig: TCryptoLibByteArray; sigOff: Int32);
+var
+  phflag: Byte;
+  LCtx: TCryptoLibCustomByteArrayBuffer;
+begin
+  phflag := $00;
+  LCtx := ConstructCustomByteArrayBufferContext(ctx, false, System.Length(ctx));
+  ImplSign(sk, skOff, LCtx, phflag, m, mOff, mLen, sig, sigOff);
+end;
+
+procedure TEd25519.Sign(const sk: TCryptoLibByteArray; skOff: Int32;
+  const pk: TCryptoLibByteArray; pkOff: Int32;
+  const ctx, m: TCryptoLibByteArray; mOff, mLen: Int32;
+  const sig: TCryptoLibByteArray; sigOff: Int32);
+var
+  phflag: Byte;
+  LCtx: TCryptoLibCustomByteArrayBuffer;
+begin
+  phflag := $00;
+  LCtx := ConstructCustomByteArrayBufferContext(ctx, false, System.Length(ctx));
+  ImplSign(sk, skOff, pk, pkOff, LCtx, phflag, m, mOff, mLen, sig, sigOff);
+end;
+
+procedure TEd25519.SignPreHash(const sk: TCryptoLibByteArray; skOff: Int32;
+  const ctx, ph: TCryptoLibByteArray; phOff: Int32;
+  const sig: TCryptoLibByteArray; sigOff: Int32);
+var
+  phflag: Byte;
+  LCtx: TCryptoLibCustomByteArrayBuffer;
+begin
+  phflag := $01;
+  LCtx := ConstructCustomByteArrayBufferContext(ctx, false, System.Length(ctx));
+  ImplSign(sk, skOff, LCtx, phflag, ph, phOff, PreHashSize, sig, sigOff);
+end;
+
+procedure TEd25519.SignPreHash(const sk: TCryptoLibByteArray; skOff: Int32;
+  const pk: TCryptoLibByteArray; pkOff: Int32;
+  const ctx, ph: TCryptoLibByteArray; phOff: Int32;
+  const sig: TCryptoLibByteArray; sigOff: Int32);
+var
+  phflag: Byte;
+  LCtx: TCryptoLibCustomByteArrayBuffer;
+begin
+  phflag := $01;
+  LCtx := ConstructCustomByteArrayBufferContext(ctx, false, System.Length(ctx));
+  ImplSign(sk, skOff, pk, pkOff, LCtx, phflag, ph, phOff, PreHashSize,
+    sig, sigOff);
+end;
+
+procedure TEd25519.SignPreHash(const sk: TCryptoLibByteArray; skOff: Int32;
+  const ctx: TCryptoLibByteArray; const ph: IDigest;
+  const sig: TCryptoLibByteArray; sigOff: Int32);
+var
+  phflag: Byte;
+  m: TCryptoLibByteArray;
+  LCtx: TCryptoLibCustomByteArrayBuffer;
+begin
+  phflag := $01;
+  m := ValidateDigestOutputSize(ph);
+  LCtx := ConstructCustomByteArrayBufferContext(ctx, false, System.Length(ctx));
+  ImplSign(sk, skOff, LCtx, phflag, m, 0, System.Length(m), sig, sigOff);
+end;
+
+procedure TEd25519.SignPreHash(const sk: TCryptoLibByteArray; skOff: Int32;
+  const pk: TCryptoLibByteArray; pkOff: Int32; const ctx: TCryptoLibByteArray;
+  const ph: IDigest; const sig: TCryptoLibByteArray; sigOff: Int32);
+var
+  phflag: Byte;
+  m: TCryptoLibByteArray;
+  LCtx: TCryptoLibCustomByteArrayBuffer;
+begin
+  phflag := $01;
+  m := ValidateDigestOutputSize(ph);
+  LCtx := ConstructCustomByteArrayBufferContext(ctx, false, System.Length(ctx));
+  ImplSign(sk, skOff, pk, pkOff, LCtx, phflag, m, 0, System.Length(m),
+    sig, sigOff);
+end;
+
+function TEd25519.Verify(const sig: TCryptoLibByteArray; sigOff: Int32;
+  const pk: TCryptoLibByteArray; pkOff: Int32; const m: TCryptoLibByteArray;
+  mOff, mLen: Int32): Boolean;
+var
+  phflag: Byte;
+begin
+  phflag := $00;
+  result := ImplVerify(sig, sigOff, pk, pkOff, EmptyBytesNil, phflag, m,
+    mOff, mLen);
+end;
+
+function TEd25519.Verify(const sig: TCryptoLibByteArray; sigOff: Int32;
+  const pk: TCryptoLibByteArray; pkOff: Int32;
+  const ctx, m: TCryptoLibByteArray; mOff, mLen: Int32): Boolean;
+var
+  phflag: Byte;
+  LCtx: TCryptoLibCustomByteArrayBuffer;
+begin
+  phflag := $00;
+  LCtx := ConstructCustomByteArrayBufferContext(ctx, false, System.Length(ctx));
+  result := ImplVerify(sig, sigOff, pk, pkOff, LCtx, phflag, m, mOff, mLen);
+end;
+
+function TEd25519.VerifyPreHash(const sig: TCryptoLibByteArray; sigOff: Int32;
+  const pk: TCryptoLibByteArray; pkOff: Int32;
+  const ctx, ph: TCryptoLibByteArray; phOff: Int32): Boolean;
+var
+  phflag: Byte;
+  LCtx: TCryptoLibCustomByteArrayBuffer;
+begin
+  phflag := $01;
+  LCtx := ConstructCustomByteArrayBufferContext(ctx, false, System.Length(ctx));
+  result := ImplVerify(sig, sigOff, pk, pkOff, LCtx, phflag, ph, phOff,
+    PreHashSize);
+end;
+
+function TEd25519.VerifyPreHash(const sig: TCryptoLibByteArray; sigOff: Int32;
+  const pk: TCryptoLibByteArray; pkOff: Int32; const ctx: TCryptoLibByteArray;
+  const ph: IDigest): Boolean;
+var
+  phflag: Byte;
+  m: TCryptoLibByteArray;
+  LCtx: TCryptoLibCustomByteArrayBuffer;
+begin
+  phflag := $01;
+  m := ValidateDigestOutputSize(ph);
+  LCtx := ConstructCustomByteArrayBufferContext(ctx, false, System.Length(ctx));
+  result := ImplVerify(sig, sigOff, pk, pkOff, LCtx, phflag, m, 0,
+    System.Length(m));
+end;
+
+end.

+ 48 - 0
src/libraries/cryptolib4pascal/ClpEd25519Blake2B.pas

@@ -0,0 +1,48 @@
+{ *********************************************************************************** }
+{ *                              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 ClpEd25519Blake2B;
+
+{$I CryptoLib.inc}
+
+interface
+
+uses
+  ClpIDigest,
+  ClpEd25519,
+  ClpDigestUtilities,
+  ClpIEd25519Blake2B;
+
+type
+  TEd25519Blake2B = class sealed(TEd25519, IEd25519Blake2B)
+
+  strict protected
+
+    function CreateDigest(): IDigest; override;
+
+  end;
+
+implementation
+
+{ TEd25519Blake2B }
+
+function TEd25519Blake2B.CreateDigest: IDigest;
+begin
+  result := TDigestUtilities.GetDigest('BLAKE2B-512');
+end;
+
+end.

+ 48 - 0
src/libraries/cryptolib4pascal/ClpEd25519Blake2BKeyGenerationParameters.pas

@@ -0,0 +1,48 @@
+{ *********************************************************************************** }
+{ *                              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 ClpEd25519Blake2BKeyGenerationParameters;
+
+{$I CryptoLib.inc}
+
+interface
+
+uses
+  ClpISecureRandom,
+  ClpIEd25519Blake2BKeyGenerationParameters,
+  ClpKeyGenerationParameters;
+
+type
+  TEd25519Blake2BKeyGenerationParameters = class sealed
+    (TKeyGenerationParameters, IEd25519Blake2BKeyGenerationParameters)
+
+  public
+    constructor Create(const random: ISecureRandom);
+
+  end;
+
+implementation
+
+{ TEd25519Blake2BKeyGenerationParameters }
+
+constructor TEd25519Blake2BKeyGenerationParameters.Create
+  (const random: ISecureRandom);
+begin
+  Inherited Create(random, 256);
+end;
+
+end.

+ 71 - 0
src/libraries/cryptolib4pascal/ClpEd25519Blake2BKeyPairGenerator.pas

@@ -0,0 +1,71 @@
+{ *********************************************************************************** }
+{ *                              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 ClpEd25519Blake2BKeyPairGenerator;
+
+{$I CryptoLib.inc}
+
+interface
+
+uses
+  ClpAsymmetricCipherKeyPair,
+  ClpIEd25519Blake2BKeyPairGenerator,
+  ClpIEd25519Blake2BPrivateKeyParameters,
+  ClpEd25519Blake2BPrivateKeyParameters,
+  ClpIEd25519Blake2BPublicKeyParameters,
+  ClpISecureRandom,
+  ClpIKeyGenerationParameters,
+  ClpIAsymmetricCipherKeyPair,
+  ClpIAsymmetricCipherKeyPairGenerator;
+
+type
+  TEd25519Blake2BKeyPairGenerator = class(TInterfacedObject,
+    IEd25519Blake2BKeyPairGenerator, IAsymmetricCipherKeyPairGenerator)
+
+  strict private
+  var
+    FRandom: ISecureRandom;
+
+  public
+    procedure Init(const parameters: IKeyGenerationParameters);
+
+    function GenerateKeyPair(): IAsymmetricCipherKeyPair;
+
+  end;
+
+implementation
+
+{ TEd25519Blake2BKeyPairGenerator }
+
+function TEd25519Blake2BKeyPairGenerator.GenerateKeyPair
+  : IAsymmetricCipherKeyPair;
+var
+  privateKey: IEd25519Blake2BPrivateKeyParameters;
+  publicKey: IEd25519Blake2BPublicKeyParameters;
+begin
+  privateKey := TEd25519Blake2BPrivateKeyParameters.Create(FRandom);
+  publicKey := privateKey.GeneratePublicKey();
+  result := TAsymmetricCipherKeyPair.Create(publicKey, privateKey);
+end;
+
+procedure TEd25519Blake2BKeyPairGenerator.Init(const parameters
+  : IKeyGenerationParameters);
+begin
+  FRandom := parameters.random;
+end;
+
+end.

+ 212 - 0
src/libraries/cryptolib4pascal/ClpEd25519Blake2BPrivateKeyParameters.pas

@@ -0,0 +1,212 @@
+{ *********************************************************************************** }
+{ *                              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 ClpEd25519Blake2BPrivateKeyParameters;
+
+{$I CryptoLib.inc}
+
+interface
+
+uses
+  Classes,
+  ClpEd25519Blake2B,
+  ClpIEd25519Blake2B,
+  ClpISecureRandom,
+  ClpAsymmetricKeyParameter,
+  ClpIEd25519Blake2BPrivateKeyParameters,
+  ClpIEd25519Blake2BPublicKeyParameters,
+  ClpEd25519Blake2BPublicKeyParameters,
+  ClpArrayUtils,
+  ClpAsn1Objects,
+  ClpCryptoLibTypes;
+
+resourcestring
+  SEOFInPrivateKey = 'EOF encountered in middle of Ed25519Blake2B private key';
+  SUnsupportedAlgorithm = 'Unsupported Algorithm';
+  SCtxNotNil = 'Ctx must be Nil for Ed25519 Algorithm';
+  SMsgLen = 'MsgLen must be Equal to "PreHashSize" for Ed25519ph Algorithm';
+
+type
+  TEd25519Blake2BPrivateKeyParameters = class sealed(TAsymmetricKeyParameter,
+    IEd25519Blake2BPrivateKeyParameters)
+
+  strict private
+  var
+    FData: TCryptoLibByteArray;
+    FEd25519Blake2BInstance: IEd25519Blake2B;
+
+  public
+
+    const
+    KeySize = Int32(TEd25519Blake2B.SecretKeySize);
+    SignatureSize = Int32(TEd25519Blake2B.SignatureSize);
+
+    constructor Create(const random: ISecureRandom); overload;
+    constructor Create(const buf: TCryptoLibByteArray; off: Int32); overload;
+    constructor Create(input: TStream); overload;
+
+    procedure Encode(const buf: TCryptoLibByteArray; off: Int32); inline;
+    function GetEncoded(): TCryptoLibByteArray; inline;
+    function GeneratePublicKey(): IEd25519Blake2BPublicKeyParameters; inline;
+
+    procedure Sign(algorithm: TEd25519Blake2B.TEd25519Algorithm;
+      const publicKey: IEd25519Blake2BPublicKeyParameters;
+      const ctx, msg: TCryptoLibByteArray; msgOff, msgLen: Int32;
+      const sig: TCryptoLibByteArray; sigOff: Int32);
+
+    function Equals(const other: IEd25519Blake2BPrivateKeyParameters): Boolean;
+      reintroduce; overload;
+    function GetHashCode(): {$IFDEF DELPHI}Int32; {$ELSE}PtrInt;
+{$ENDIF DELPHI}override;
+
+  end;
+
+implementation
+
+{ TEd25519Blake2BPrivateKeyParameters }
+
+function TEd25519Blake2BPrivateKeyParameters.GeneratePublicKey
+  : IEd25519Blake2BPublicKeyParameters;
+var
+  publicKey: TCryptoLibByteArray;
+begin
+  System.SetLength(publicKey, TEd25519Blake2B.PublicKeySize);
+  FEd25519Blake2BInstance.GeneratePublicKey(FData, 0, publicKey, 0);
+  result := TEd25519Blake2BPublicKeyParameters.Create(publicKey, 0);
+end;
+
+function TEd25519Blake2BPrivateKeyParameters.GetEncoded: TCryptoLibByteArray;
+begin
+  result := System.Copy(FData);
+end;
+
+constructor TEd25519Blake2BPrivateKeyParameters.Create
+  (const random: ISecureRandom);
+begin
+  Inherited Create(true);
+  System.SetLength(FData, KeySize);
+  FEd25519Blake2BInstance := TEd25519Blake2B.Create();
+  FEd25519Blake2BInstance.GeneratePrivateKey(random, FData);
+end;
+
+constructor TEd25519Blake2BPrivateKeyParameters.Create
+  (const buf: TCryptoLibByteArray; off: Int32);
+begin
+  Inherited Create(true);
+  System.SetLength(FData, KeySize);
+  FEd25519Blake2BInstance := TEd25519Blake2B.Create();
+  System.Move(buf[off], FData[0], KeySize * System.SizeOf(Byte));
+end;
+
+constructor TEd25519Blake2BPrivateKeyParameters.Create(input: TStream);
+begin
+  Inherited Create(true);
+  System.SetLength(FData, KeySize);
+  FEd25519Blake2BInstance := TEd25519Blake2B.Create();
+  if (KeySize <> TStreamUtils.ReadFully(input, FData)) then
+  begin
+    raise EEndOfStreamCryptoLibException.CreateRes(@SEOFInPrivateKey);
+  end;
+end;
+
+procedure TEd25519Blake2BPrivateKeyParameters.Encode
+  (const buf: TCryptoLibByteArray; off: Int32);
+begin
+  System.Move(FData[0], buf[off], KeySize * System.SizeOf(Byte));
+end;
+
+function TEd25519Blake2BPrivateKeyParameters.Equals
+  (const other: IEd25519Blake2BPrivateKeyParameters): Boolean;
+begin
+  if (other = Self as IEd25519Blake2BPrivateKeyParameters) then
+  begin
+    result := true;
+    Exit;
+  end;
+
+  if (other = Nil) then
+  begin
+    result := false;
+    Exit;
+  end;
+  result := TArrayUtils.ConstantTimeAreEqual(FData, other.GetEncoded())
+end;
+
+function TEd25519Blake2BPrivateKeyParameters.GetHashCode: {$IFDEF DELPHI}Int32;
+{$ELSE}PtrInt;
+{$ENDIF DELPHI}
+begin
+  result := TArrayUtils.GetArrayHashCode(FData);
+end;
+
+procedure TEd25519Blake2BPrivateKeyParameters.Sign
+  (algorithm: TEd25519Blake2B.TEd25519Algorithm;
+  const publicKey: IEd25519Blake2BPublicKeyParameters;
+  const ctx, msg: TCryptoLibByteArray; msgOff, msgLen: Int32;
+  const sig: TCryptoLibByteArray; sigOff: Int32);
+var
+  pk: TCryptoLibByteArray;
+begin
+  System.SetLength(pk, TEd25519Blake2B.PublicKeySize);
+
+  if (publicKey = Nil) then
+  begin
+    FEd25519Blake2BInstance.GeneratePublicKey(FData, 0, pk, 0);
+  end
+  else
+  begin
+    publicKey.Encode(pk, 0);
+  end;
+
+  case algorithm of
+    TEd25519Blake2B.TEd25519Algorithm.Ed25519:
+      begin
+        if (ctx <> Nil) then
+        begin
+          raise EArgumentCryptoLibException.CreateRes(@SCtxNotNil);
+        end;
+
+        FEd25519Blake2BInstance.Sign(FData, 0, pk, 0, msg, msgOff, msgLen,
+          sig, sigOff);
+      end;
+
+    TEd25519Blake2B.TEd25519Algorithm.Ed25519ctx:
+      begin
+        FEd25519Blake2BInstance.Sign(FData, 0, pk, 0, ctx, msg, msgOff, msgLen,
+          sig, sigOff);
+      end;
+
+    TEd25519Blake2B.TEd25519Algorithm.Ed25519ph:
+      begin
+        if (TEd25519Blake2B.PreHashSize <> msgLen) then
+        begin
+          raise EArgumentCryptoLibException.CreateRes(@SMsgLen);
+        end;
+
+        FEd25519Blake2BInstance.SignPrehash(FData, 0, pk, 0, ctx, msg, msgOff,
+          sig, sigOff);
+      end
+  else
+    begin
+      raise EInvalidOperationCryptoLibException.CreateRes
+        (@SUnsupportedAlgorithm);
+    end;
+
+  end;
+end;
+
+end.

+ 119 - 0
src/libraries/cryptolib4pascal/ClpEd25519Blake2BPublicKeyParameters.pas

@@ -0,0 +1,119 @@
+{ *********************************************************************************** }
+{ *                              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 ClpEd25519Blake2BPublicKeyParameters;
+
+{$I CryptoLib.inc}
+
+interface
+
+uses
+  Classes,
+  ClpEd25519Blake2B,
+  ClpAsymmetricKeyParameter,
+  ClpIEd25519Blake2BPublicKeyParameters,
+  ClpArrayUtils,
+  ClpAsn1Objects,
+  ClpCryptoLibTypes;
+
+resourcestring
+  SEOFInPublicKey = 'EOF encountered in middle of Ed25519Blake2B public key';
+
+type
+  TEd25519Blake2BPublicKeyParameters = class sealed(TAsymmetricKeyParameter,
+    IEd25519Blake2BPublicKeyParameters)
+
+  strict private
+  var
+    FData: TCryptoLibByteArray;
+
+  public
+
+    const
+    KeySize = Int32(TEd25519Blake2B.PublicKeySize);
+
+    constructor Create(const buf: TCryptoLibByteArray; off: Int32); overload;
+    constructor Create(input: TStream); overload;
+
+    procedure Encode(const buf: TCryptoLibByteArray; off: Int32); inline;
+    function GetEncoded(): TCryptoLibByteArray; inline;
+
+    function Equals(const other: IEd25519Blake2BPublicKeyParameters): Boolean;
+      reintroduce; overload;
+    function GetHashCode(): {$IFDEF DELPHI}Int32; {$ELSE}PtrInt;
+{$ENDIF DELPHI}override;
+
+  end;
+
+implementation
+
+{ TEd25519Blake2BPublicKeyParameters }
+
+function TEd25519Blake2BPublicKeyParameters.GetEncoded: TCryptoLibByteArray;
+begin
+  result := System.Copy(FData);
+end;
+
+constructor TEd25519Blake2BPublicKeyParameters.Create
+  (const buf: TCryptoLibByteArray; off: Int32);
+begin
+  Inherited Create(false);
+  System.SetLength(FData, KeySize);
+  System.Move(buf[off], FData[0], KeySize * System.SizeOf(Byte));
+end;
+
+constructor TEd25519Blake2BPublicKeyParameters.Create(input: TStream);
+begin
+  Inherited Create(false);
+  System.SetLength(FData, KeySize);
+  if (KeySize <> TStreamUtils.ReadFully(input, FData)) then
+  begin
+    raise EEndOfStreamCryptoLibException.CreateRes(@SEOFInPublicKey);
+  end;
+end;
+
+procedure TEd25519Blake2BPublicKeyParameters.Encode
+  (const buf: TCryptoLibByteArray; off: Int32);
+begin
+  System.Move(FData[0], buf[off], KeySize * System.SizeOf(Byte));
+end;
+
+function TEd25519Blake2BPublicKeyParameters.Equals
+  (const other: IEd25519Blake2BPublicKeyParameters): Boolean;
+begin
+  if (other = Self as IEd25519Blake2BPublicKeyParameters) then
+  begin
+    result := true;
+    Exit;
+  end;
+
+  if (other = Nil) then
+  begin
+    result := false;
+    Exit;
+  end;
+  result := TArrayUtils.ConstantTimeAreEqual(FData, other.GetEncoded())
+end;
+
+function TEd25519Blake2BPublicKeyParameters.GetHashCode: {$IFDEF DELPHI}Int32;
+{$ELSE}PtrInt;
+{$ENDIF DELPHI}
+begin
+  result := TArrayUtils.GetArrayHashCode(FData);
+end;
+
+end.

+ 187 - 0
src/libraries/cryptolib4pascal/ClpEd25519Blake2BSigner.pas

@@ -0,0 +1,187 @@
+{ *********************************************************************************** }
+{ *                              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 ClpEd25519Blake2BSigner;
+
+{$I CryptoLib.inc}
+
+interface
+
+uses
+  Classes,
+  ClpIEd25519Blake2B,
+  ClpEd25519Blake2B,
+  ClpICipherParameters,
+  ClpIEd25519Blake2BSigner,
+  ClpIEd25519Blake2BPrivateKeyParameters,
+  ClpIEd25519Blake2BPublicKeyParameters,
+  ClpEd25519Blake2BPrivateKeyParameters,
+  ClpCryptoLibTypes;
+
+resourcestring
+  SNotInitializedForSigning =
+    'Ed25519Blake2BSigner not Initialised for Signature Generation.';
+  SNotInitializedForVerifying =
+    'Ed25519Blake2BSigner not Initialised for Verification';
+
+type
+  TEd25519Blake2BSigner = class(TInterfacedObject, IEd25519Blake2BSigner)
+
+  strict private
+  var
+    FBuffer: TMemoryStream;
+    FforSigning: Boolean;
+    FEd25519Blake2BInstance: IEd25519Blake2B;
+    FPrivateKey: IEd25519Blake2BPrivateKeyParameters;
+    FPublicKey: IEd25519Blake2BPublicKeyParameters;
+
+    function Aggregate: TCryptoLibByteArray; inline;
+
+  strict protected
+    function GetAlgorithmName: String; virtual;
+
+  public
+    constructor Create();
+    destructor Destroy(); override;
+
+    procedure Init(forSigning: Boolean;
+      const parameters: ICipherParameters); virtual;
+    procedure Update(b: Byte); virtual;
+    procedure BlockUpdate(const buf: TCryptoLibByteArray;
+      off, len: Int32); virtual;
+    function GenerateSignature(): TCryptoLibByteArray; virtual;
+    function VerifySignature(const signature: TCryptoLibByteArray)
+      : Boolean; virtual;
+    procedure Reset(); virtual;
+
+    property AlgorithmName: String read GetAlgorithmName;
+
+  end;
+
+implementation
+
+{ TEd25519Blake2BSigner }
+
+function TEd25519Blake2BSigner.Aggregate: TCryptoLibByteArray;
+begin
+  FBuffer.Position := 0;
+  System.SetLength(Result, FBuffer.Size);
+  FBuffer.Read(Result[0], FBuffer.Size);
+end;
+
+procedure TEd25519Blake2BSigner.BlockUpdate(const buf: TCryptoLibByteArray;
+  off, len: Int32);
+begin
+  FBuffer.Write(buf[off], len);
+end;
+
+constructor TEd25519Blake2BSigner.Create;
+begin
+  Inherited Create();
+  FBuffer := TMemoryStream.Create();
+  FEd25519Blake2BInstance := TEd25519Blake2B.Create();
+end;
+
+destructor TEd25519Blake2BSigner.Destroy;
+begin
+  FBuffer.Free;
+  inherited Destroy;
+end;
+
+function TEd25519Blake2BSigner.GetAlgorithmName: String;
+begin
+  Result := 'Ed25519Blake2B';
+end;
+
+procedure TEd25519Blake2BSigner.Init(forSigning: Boolean;
+  const parameters: ICipherParameters);
+begin
+  FforSigning := forSigning;
+
+  if (forSigning) then
+  begin
+    // TODO Allow IAsymmetricCipherKeyPair to be an ICipherParameters?
+
+    FPrivateKey := parameters as IEd25519Blake2BPrivateKeyParameters;
+    FPublicKey := FPrivateKey.GeneratePublicKey();
+  end
+  else
+  begin
+    FPrivateKey := Nil;
+    FPublicKey := parameters as IEd25519Blake2BPublicKeyParameters;
+  end;
+
+  Reset();
+end;
+
+procedure TEd25519Blake2BSigner.Reset;
+begin
+  FBuffer.Clear;
+  FBuffer.SetSize(Int64(0));
+end;
+
+procedure TEd25519Blake2BSigner.Update(b: Byte);
+begin
+  FBuffer.Write(TCryptoLibByteArray.Create(b)[0], 1);
+end;
+
+function TEd25519Blake2BSigner.GenerateSignature: TCryptoLibByteArray;
+var
+  signature, buf: TCryptoLibByteArray;
+  count: Int32;
+begin
+  if ((not FforSigning) or (FPrivateKey = Nil)) then
+  begin
+    raise EInvalidOperationCryptoLibException.CreateRes
+      (@SNotInitializedForSigning);
+  end;
+
+  System.SetLength(signature,
+    TEd25519Blake2BPrivateKeyParameters.SignatureSize);
+  buf := Aggregate();
+  count := System.Length(buf);
+
+  FPrivateKey.Sign(TEd25519Blake2B.TEd25519Algorithm.Ed25519, FPublicKey, Nil,
+    buf, 0, count, signature, 0);
+  Reset();
+  Result := signature;
+end;
+
+function TEd25519Blake2BSigner.VerifySignature(const signature
+  : TCryptoLibByteArray): Boolean;
+var
+  buf, pk: TCryptoLibByteArray;
+  count: Int32;
+begin
+  if ((FforSigning) or (FPublicKey = Nil)) then
+  begin
+    raise EInvalidOperationCryptoLibException.CreateRes
+      (@SNotInitializedForVerifying);
+  end;
+  if (TEd25519Blake2B.SignatureSize <> System.Length(signature)) then
+  begin
+    Result := false;
+    Exit;
+  end;
+  pk := FPublicKey.GetEncoded();
+  buf := Aggregate();
+  count := System.Length(buf);
+  Result := FEd25519Blake2BInstance.Verify(signature, 0, pk, 0, buf, 0, count);
+  Reset();
+end;
+
+end.

+ 190 - 0
src/libraries/cryptolib4pascal/ClpEd25519CtxBlake2BSigner.pas

@@ -0,0 +1,190 @@
+{ *********************************************************************************** }
+{ *                              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 ClpEd25519CtxBlake2BSigner;
+
+{$I CryptoLib.inc}
+
+interface
+
+uses
+  Classes,
+  ClpIEd25519Blake2B,
+  ClpEd25519Blake2B,
+  ClpICipherParameters,
+  ClpIEd25519CtxBlake2BSigner,
+  ClpIEd25519Blake2BPrivateKeyParameters,
+  ClpIEd25519Blake2BPublicKeyParameters,
+  ClpEd25519Blake2BPrivateKeyParameters,
+  ClpCryptoLibTypes;
+
+resourcestring
+  SNotInitializedForSigning =
+    'Ed25519CtxBlake2BSigner not Initialised for Signature Generation.';
+  SNotInitializedForVerifying =
+    'Ed25519CtxBlake2BSigner not Initialised for Verification';
+
+type
+  TEd25519CtxBlake2BSigner = class(TInterfacedObject, IEd25519CtxBlake2BSigner)
+
+  strict private
+  var
+    FContext: TCryptoLibByteArray;
+    FBuffer: TMemoryStream;
+    FforSigning: Boolean;
+    FEd25519Blake2BInstance: IEd25519Blake2B;
+    FPrivateKey: IEd25519Blake2BPrivateKeyParameters;
+    FPublicKey: IEd25519Blake2BPublicKeyParameters;
+
+    function Aggregate: TCryptoLibByteArray; inline;
+
+  strict protected
+    function GetAlgorithmName: String; virtual;
+
+  public
+    constructor Create(const context: TCryptoLibByteArray);
+    destructor Destroy(); override;
+
+    procedure Init(forSigning: Boolean;
+      const parameters: ICipherParameters); virtual;
+    procedure Update(b: Byte); virtual;
+    procedure BlockUpdate(const buf: TCryptoLibByteArray;
+      off, len: Int32); virtual;
+    function GenerateSignature(): TCryptoLibByteArray; virtual;
+    function VerifySignature(const signature: TCryptoLibByteArray)
+      : Boolean; virtual;
+    procedure Reset(); virtual;
+
+    property AlgorithmName: String read GetAlgorithmName;
+
+  end;
+
+implementation
+
+{ TEd25519CtxBlake2BSigner }
+
+function TEd25519CtxBlake2BSigner.Aggregate: TCryptoLibByteArray;
+begin
+  FBuffer.Position := 0;
+  System.SetLength(Result, FBuffer.Size);
+  FBuffer.Read(Result[0], FBuffer.Size);
+end;
+
+procedure TEd25519CtxBlake2BSigner.BlockUpdate(const buf: TCryptoLibByteArray;
+  off, len: Int32);
+begin
+  FBuffer.Write(buf[off], len);
+end;
+
+constructor TEd25519CtxBlake2BSigner.Create(const context: TCryptoLibByteArray);
+begin
+  Inherited Create();
+  FBuffer := TMemoryStream.Create();
+  FContext := System.Copy(context);
+  FEd25519Blake2BInstance := TEd25519Blake2B.Create();
+end;
+
+destructor TEd25519CtxBlake2BSigner.Destroy;
+begin
+  FBuffer.Free;
+  inherited Destroy;
+end;
+
+function TEd25519CtxBlake2BSigner.GetAlgorithmName: String;
+begin
+  Result := 'Ed25519CtxBlake2B';
+end;
+
+procedure TEd25519CtxBlake2BSigner.Init(forSigning: Boolean;
+  const parameters: ICipherParameters);
+begin
+  FforSigning := forSigning;
+
+  if (forSigning) then
+  begin
+    // TODO Allow IAsymmetricCipherKeyPair to be an ICipherParameters?
+
+    FPrivateKey := parameters as IEd25519Blake2BPrivateKeyParameters;
+    FPublicKey := FPrivateKey.GeneratePublicKey();
+  end
+  else
+  begin
+    FPrivateKey := Nil;
+    FPublicKey := parameters as IEd25519Blake2BPublicKeyParameters;
+  end;
+
+  Reset();
+end;
+
+procedure TEd25519CtxBlake2BSigner.Reset;
+begin
+  FBuffer.Clear;
+  FBuffer.SetSize(Int64(0));
+end;
+
+procedure TEd25519CtxBlake2BSigner.Update(b: Byte);
+begin
+  FBuffer.Write(TCryptoLibByteArray.Create(b)[0], 1);
+end;
+
+function TEd25519CtxBlake2BSigner.GenerateSignature: TCryptoLibByteArray;
+var
+  signature, buf: TCryptoLibByteArray;
+  count: Int32;
+begin
+  if ((not FforSigning) or (FPrivateKey = Nil)) then
+  begin
+    raise EInvalidOperationCryptoLibException.CreateRes
+      (@SNotInitializedForSigning);
+  end;
+
+  System.SetLength(signature,
+    TEd25519Blake2BPrivateKeyParameters.SignatureSize);
+  buf := Aggregate();
+  count := System.Length(buf);
+
+  FPrivateKey.Sign(TEd25519Blake2B.TEd25519Algorithm.Ed25519Ctx, FPublicKey,
+    FContext, buf, 0, count, signature, 0);
+  Reset();
+  Result := signature;
+end;
+
+function TEd25519CtxBlake2BSigner.VerifySignature(const signature
+  : TCryptoLibByteArray): Boolean;
+var
+  buf, pk: TCryptoLibByteArray;
+  count: Int32;
+begin
+  if ((FforSigning) or (FPublicKey = Nil)) then
+  begin
+    raise EInvalidOperationCryptoLibException.CreateRes
+      (@SNotInitializedForVerifying);
+  end;
+  if (TEd25519Blake2B.SignatureSize <> System.Length(signature)) then
+  begin
+    Result := false;
+    Exit;
+  end;
+  pk := FPublicKey.GetEncoded();
+  buf := Aggregate();
+  count := System.Length(buf);
+  Result := FEd25519Blake2BInstance.Verify(signature, 0, pk, 0, FContext, buf,
+    0, count);
+  Reset();
+end;
+
+end.

+ 189 - 0
src/libraries/cryptolib4pascal/ClpEd25519CtxSigner.pas

@@ -0,0 +1,189 @@
+{ *********************************************************************************** }
+{ *                              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 ClpEd25519CtxSigner;
+
+{$I CryptoLib.inc}
+
+interface
+
+uses
+  Classes,
+  ClpIEd25519,
+  ClpEd25519,
+  ClpICipherParameters,
+  ClpIEd25519CtxSigner,
+  ClpIEd25519PrivateKeyParameters,
+  ClpIEd25519PublicKeyParameters,
+  ClpEd25519PrivateKeyParameters,
+  ClpCryptoLibTypes;
+
+resourcestring
+  SNotInitializedForSigning =
+    'Ed25519CtxSigner not Initialised for Signature Generation.';
+  SNotInitializedForVerifying =
+    'Ed25519CtxSigner not Initialised for Verification';
+
+type
+  TEd25519CtxSigner = class(TInterfacedObject, IEd25519CtxSigner)
+
+  strict private
+  var
+    FContext: TCryptoLibByteArray;
+    FBuffer: TMemoryStream;
+    FforSigning: Boolean;
+    FEd25519Instance: IEd25519;
+    FPrivateKey: IEd25519PrivateKeyParameters;
+    FPublicKey: IEd25519PublicKeyParameters;
+
+    function Aggregate: TCryptoLibByteArray; inline;
+
+  strict protected
+    function GetAlgorithmName: String; virtual;
+
+  public
+    constructor Create(const context: TCryptoLibByteArray);
+    destructor Destroy(); override;
+
+    procedure Init(forSigning: Boolean;
+      const parameters: ICipherParameters); virtual;
+    procedure Update(b: Byte); virtual;
+    procedure BlockUpdate(const buf: TCryptoLibByteArray;
+      off, len: Int32); virtual;
+    function GenerateSignature(): TCryptoLibByteArray; virtual;
+    function VerifySignature(const signature: TCryptoLibByteArray)
+      : Boolean; virtual;
+    procedure Reset(); virtual;
+
+    property AlgorithmName: String read GetAlgorithmName;
+
+  end;
+
+implementation
+
+{ TEd25519CtxSigner }
+
+function TEd25519CtxSigner.Aggregate: TCryptoLibByteArray;
+begin
+  FBuffer.Position := 0;
+  System.SetLength(Result, FBuffer.Size);
+  FBuffer.Read(Result[0], FBuffer.Size);
+end;
+
+procedure TEd25519CtxSigner.BlockUpdate(const buf: TCryptoLibByteArray;
+  off, len: Int32);
+begin
+  FBuffer.Write(buf[off], len);
+end;
+
+constructor TEd25519CtxSigner.Create(const context: TCryptoLibByteArray);
+begin
+  Inherited Create();
+  FBuffer := TMemoryStream.Create();
+  FContext := System.Copy(context);
+  FEd25519Instance := TEd25519.Create();
+end;
+
+destructor TEd25519CtxSigner.Destroy;
+begin
+  FBuffer.Free;
+  inherited Destroy;
+end;
+
+function TEd25519CtxSigner.GetAlgorithmName: String;
+begin
+  Result := 'Ed25519ctx';
+end;
+
+procedure TEd25519CtxSigner.Init(forSigning: Boolean;
+  const parameters: ICipherParameters);
+begin
+  FforSigning := forSigning;
+
+  if (forSigning) then
+  begin
+    // TODO Allow IAsymmetricCipherKeyPair to be an ICipherParameters?
+
+    FPrivateKey := parameters as IEd25519PrivateKeyParameters;
+    FPublicKey := FPrivateKey.GeneratePublicKey();
+  end
+  else
+  begin
+    FPrivateKey := Nil;
+    FPublicKey := parameters as IEd25519PublicKeyParameters;
+  end;
+
+  Reset();
+end;
+
+procedure TEd25519CtxSigner.Reset;
+begin
+  FBuffer.Clear;
+  FBuffer.SetSize(Int64(0));
+end;
+
+procedure TEd25519CtxSigner.Update(b: Byte);
+begin
+  FBuffer.Write(TCryptoLibByteArray.Create(b)[0], 1);
+end;
+
+function TEd25519CtxSigner.GenerateSignature: TCryptoLibByteArray;
+var
+  signature, buf: TCryptoLibByteArray;
+  count: Int32;
+begin
+  if ((not FforSigning) or (FPrivateKey = Nil)) then
+  begin
+    raise EInvalidOperationCryptoLibException.CreateRes
+      (@SNotInitializedForSigning);
+  end;
+
+  System.SetLength(signature, TEd25519PrivateKeyParameters.SignatureSize);
+  buf := Aggregate();
+  count := System.Length(buf);
+
+  FPrivateKey.Sign(TEd25519.TEd25519Algorithm.Ed25519ctx, FPublicKey, FContext,
+    buf, 0, count, signature, 0);
+  Reset();
+  Result := signature;
+end;
+
+function TEd25519CtxSigner.VerifySignature(const signature
+  : TCryptoLibByteArray): Boolean;
+var
+  buf, pk: TCryptoLibByteArray;
+  count: Int32;
+begin
+  if ((FforSigning) or (FPublicKey = Nil)) then
+  begin
+    raise EInvalidOperationCryptoLibException.CreateRes
+      (@SNotInitializedForVerifying);
+  end;
+  if (TEd25519.SignatureSize <> System.Length(signature)) then
+  begin
+    Result := false;
+    Exit;
+  end;
+  pk := FPublicKey.GetEncoded();
+  buf := Aggregate();
+  count := System.Length(buf);
+  Result := FEd25519Instance.Verify(signature, 0, pk, 0, FContext, buf,
+    0, count);
+  Reset();
+end;
+
+end.

+ 47 - 0
src/libraries/cryptolib4pascal/ClpEd25519KeyGenerationParameters.pas

@@ -0,0 +1,47 @@
+{ *********************************************************************************** }
+{ *                              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 ClpEd25519KeyGenerationParameters;
+
+{$I CryptoLib.inc}
+
+interface
+
+uses
+  ClpISecureRandom,
+  ClpIEd25519KeyGenerationParameters,
+  ClpKeyGenerationParameters;
+
+type
+  TEd25519KeyGenerationParameters = class sealed(TKeyGenerationParameters,
+    IEd25519KeyGenerationParameters)
+
+  public
+    constructor Create(const random: ISecureRandom);
+
+  end;
+
+implementation
+
+{ TEd25519KeyGenerationParameters }
+
+constructor TEd25519KeyGenerationParameters.Create(const random: ISecureRandom);
+begin
+  Inherited Create(random, 256);
+end;
+
+end.

+ 70 - 0
src/libraries/cryptolib4pascal/ClpEd25519KeyPairGenerator.pas

@@ -0,0 +1,70 @@
+{ *********************************************************************************** }
+{ *                              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 ClpEd25519KeyPairGenerator;
+
+{$I CryptoLib.inc}
+
+interface
+
+uses
+  ClpAsymmetricCipherKeyPair,
+  ClpIEd25519KeyPairGenerator,
+  ClpIEd25519PrivateKeyParameters,
+  ClpEd25519PrivateKeyParameters,
+  ClpIEd25519PublicKeyParameters,
+  ClpISecureRandom,
+  ClpIKeyGenerationParameters,
+  ClpIAsymmetricCipherKeyPair,
+  ClpIAsymmetricCipherKeyPairGenerator;
+
+type
+  TEd25519KeyPairGenerator = class(TInterfacedObject, IEd25519KeyPairGenerator,
+    IAsymmetricCipherKeyPairGenerator)
+
+  strict private
+  var
+    FRandom: ISecureRandom;
+
+  public
+    procedure Init(const parameters: IKeyGenerationParameters);
+
+    function GenerateKeyPair(): IAsymmetricCipherKeyPair;
+
+  end;
+
+implementation
+
+{ TEd25519KeyPairGenerator }
+
+function TEd25519KeyPairGenerator.GenerateKeyPair: IAsymmetricCipherKeyPair;
+var
+  privateKey: IEd25519PrivateKeyParameters;
+  publicKey: IEd25519PublicKeyParameters;
+begin
+  privateKey := TEd25519PrivateKeyParameters.Create(FRandom);
+  publicKey := privateKey.GeneratePublicKey();
+  result := TAsymmetricCipherKeyPair.Create(publicKey, privateKey);
+end;
+
+procedure TEd25519KeyPairGenerator.Init(const parameters
+  : IKeyGenerationParameters);
+begin
+  FRandom := parameters.random;
+end;
+
+end.

+ 178 - 0
src/libraries/cryptolib4pascal/ClpEd25519PhBlake2BSigner.pas

@@ -0,0 +1,178 @@
+{ *********************************************************************************** }
+{ *                              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 ClpEd25519PhBlake2BSigner;
+
+{$I CryptoLib.inc}
+
+interface
+
+uses
+  ClpIDigest,
+  ClpIEd25519Blake2B,
+  ClpEd25519Blake2B,
+  ClpICipherParameters,
+  ClpIEd25519PhBlake2BSigner,
+  ClpIEd25519Blake2BPrivateKeyParameters,
+  ClpIEd25519Blake2BPublicKeyParameters,
+  ClpEd25519Blake2BPrivateKeyParameters,
+  ClpCryptoLibTypes;
+
+resourcestring
+  SNotInitializedForSigning =
+    'Ed25519PhBlake2BSigner not Initialised for Signature Generation.';
+  SNotInitializedForVerifying =
+    'Ed25519PhBlake2BSigner not Initialised for Verification';
+  SPreHashDigestFailed = 'PreHash Digest Failed';
+
+type
+  TEd25519PhBlake2BSigner = class(TInterfacedObject, IEd25519PhBlake2BSigner)
+
+  strict private
+  var
+    FPreHash: IDigest;
+    FContext: TCryptoLibByteArray;
+    FforSigning: Boolean;
+    FEd25519Blake2BInstance: IEd25519Blake2B;
+    FPrivateKey: IEd25519Blake2BPrivateKeyParameters;
+    FPublicKey: IEd25519Blake2BPublicKeyParameters;
+
+  strict protected
+    function GetAlgorithmName: String; virtual;
+
+  public
+    constructor Create(const context: TCryptoLibByteArray);
+    destructor Destroy(); override;
+
+    procedure Init(forSigning: Boolean;
+      const parameters: ICipherParameters); virtual;
+    procedure Update(b: Byte); virtual;
+    procedure BlockUpdate(const buf: TCryptoLibByteArray;
+      off, len: Int32); virtual;
+    function GenerateSignature(): TCryptoLibByteArray; virtual;
+    function VerifySignature(const signature: TCryptoLibByteArray)
+      : Boolean; virtual;
+    procedure Reset(); virtual;
+
+    property AlgorithmName: String read GetAlgorithmName;
+
+  end;
+
+implementation
+
+{ TEd25519PhBlake2BSigner }
+
+procedure TEd25519PhBlake2BSigner.BlockUpdate(const buf: TCryptoLibByteArray;
+  off, len: Int32);
+begin
+  FPreHash.BlockUpdate(buf, off, len);
+end;
+
+constructor TEd25519PhBlake2BSigner.Create(const context: TCryptoLibByteArray);
+begin
+  Inherited Create();
+  FContext := System.Copy(context);
+  FEd25519Blake2BInstance := TEd25519Blake2B.Create();
+  FPreHash := FEd25519Blake2BInstance.CreatePreHash();
+end;
+
+destructor TEd25519PhBlake2BSigner.Destroy;
+begin
+  inherited Destroy;
+end;
+
+function TEd25519PhBlake2BSigner.GetAlgorithmName: String;
+begin
+  Result := 'Ed25519PhBlake2B';
+end;
+
+procedure TEd25519PhBlake2BSigner.Init(forSigning: Boolean;
+  const parameters: ICipherParameters);
+begin
+  FforSigning := forSigning;
+
+  if (forSigning) then
+  begin
+    // TODO Allow IAsymmetricCipherKeyPair to be an ICipherParameters?
+
+    FPrivateKey := parameters as IEd25519Blake2BPrivateKeyParameters;
+    FPublicKey := FPrivateKey.GeneratePublicKey();
+  end
+  else
+  begin
+    FPrivateKey := Nil;
+    FPublicKey := parameters as IEd25519Blake2BPublicKeyParameters;
+  end;
+
+  Reset();
+end;
+
+procedure TEd25519PhBlake2BSigner.Reset;
+begin
+  FPreHash.Reset();
+end;
+
+procedure TEd25519PhBlake2BSigner.Update(b: Byte);
+begin
+  FPreHash.Update(b);
+end;
+
+function TEd25519PhBlake2BSigner.GenerateSignature: TCryptoLibByteArray;
+var
+  signature, msg: TCryptoLibByteArray;
+begin
+  if ((not FforSigning) or (FPrivateKey = Nil)) then
+  begin
+    raise EInvalidOperationCryptoLibException.CreateRes
+      (@SNotInitializedForSigning);
+  end;
+  System.SetLength(msg, TEd25519Blake2B.PreHashSize);
+
+  if ((TEd25519Blake2B.PreHashSize) <> (FPreHash.DoFinal(msg, 0))) then
+  begin
+    raise EInvalidOperationCryptoLibException.CreateRes(@SPreHashDigestFailed);
+  end;
+
+  System.SetLength(signature,
+    TEd25519Blake2BPrivateKeyParameters.SignatureSize);
+
+  FPrivateKey.Sign(TEd25519Blake2B.TEd25519Algorithm.Ed25519Ph, FPublicKey,
+    FContext, msg, 0, TEd25519Blake2B.PreHashSize, signature, 0);
+  Result := signature;
+end;
+
+function TEd25519PhBlake2BSigner.VerifySignature(const signature
+  : TCryptoLibByteArray): Boolean;
+var
+  pk: TCryptoLibByteArray;
+begin
+  if ((FforSigning) or (FPublicKey = Nil)) then
+  begin
+    raise EInvalidOperationCryptoLibException.CreateRes
+      (@SNotInitializedForVerifying);
+  end;
+  if (TEd25519Blake2B.SignatureSize <> System.Length(signature)) then
+  begin
+    Result := false;
+    Exit;
+  end;
+  pk := FPublicKey.GetEncoded();
+  Result := FEd25519Blake2BInstance.VerifyPrehash(signature, 0, pk, 0, FContext,
+    FPreHash);
+end;
+
+end.

+ 177 - 0
src/libraries/cryptolib4pascal/ClpEd25519PhSigner.pas

@@ -0,0 +1,177 @@
+{ *********************************************************************************** }
+{ *                              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 ClpEd25519PhSigner;
+
+{$I CryptoLib.inc}
+
+interface
+
+uses
+  ClpIDigest,
+  ClpIEd25519,
+  ClpEd25519,
+  ClpICipherParameters,
+  ClpIEd25519PhSigner,
+  ClpIEd25519PrivateKeyParameters,
+  ClpIEd25519PublicKeyParameters,
+  ClpEd25519PrivateKeyParameters,
+  ClpCryptoLibTypes;
+
+resourcestring
+  SNotInitializedForSigning =
+    'Ed25519PhSigner not Initialised for Signature Generation.';
+  SNotInitializedForVerifying =
+    'Ed25519PhSigner not Initialised for Verification';
+  SPreHashDigestFailed = 'PreHash Digest Failed';
+
+type
+  TEd25519PhSigner = class(TInterfacedObject, IEd25519PhSigner)
+
+  strict private
+  var
+    FPreHash: IDigest;
+    FContext: TCryptoLibByteArray;
+    FforSigning: Boolean;
+    FEd25519Instance: IEd25519;
+    FPrivateKey: IEd25519PrivateKeyParameters;
+    FPublicKey: IEd25519PublicKeyParameters;
+
+  strict protected
+    function GetAlgorithmName: String; virtual;
+
+  public
+    constructor Create(const context: TCryptoLibByteArray);
+    destructor Destroy(); override;
+
+    procedure Init(forSigning: Boolean;
+      const parameters: ICipherParameters); virtual;
+    procedure Update(b: Byte); virtual;
+    procedure BlockUpdate(const buf: TCryptoLibByteArray;
+      off, len: Int32); virtual;
+    function GenerateSignature(): TCryptoLibByteArray; virtual;
+    function VerifySignature(const signature: TCryptoLibByteArray)
+      : Boolean; virtual;
+    procedure Reset(); virtual;
+
+    property AlgorithmName: String read GetAlgorithmName;
+
+  end;
+
+implementation
+
+{ TEd25519PhSigner }
+
+procedure TEd25519PhSigner.BlockUpdate(const buf: TCryptoLibByteArray;
+  off, len: Int32);
+begin
+  FPreHash.BlockUpdate(buf, off, len);
+end;
+
+constructor TEd25519PhSigner.Create(const context: TCryptoLibByteArray);
+begin
+  Inherited Create();
+  FContext := System.Copy(context);
+  FEd25519Instance := TEd25519.Create();
+  FPreHash := FEd25519Instance.CreatePreHash();
+end;
+
+destructor TEd25519PhSigner.Destroy;
+begin
+  inherited Destroy;
+end;
+
+function TEd25519PhSigner.GetAlgorithmName: String;
+begin
+  Result := 'Ed25519Ph';
+end;
+
+procedure TEd25519PhSigner.Init(forSigning: Boolean;
+  const parameters: ICipherParameters);
+begin
+  FforSigning := forSigning;
+
+  if (forSigning) then
+  begin
+    // TODO Allow IAsymmetricCipherKeyPair to be an ICipherParameters?
+
+    FPrivateKey := parameters as IEd25519PrivateKeyParameters;
+    FPublicKey := FPrivateKey.GeneratePublicKey();
+  end
+  else
+  begin
+    FPrivateKey := Nil;
+    FPublicKey := parameters as IEd25519PublicKeyParameters;
+  end;
+
+  Reset();
+end;
+
+procedure TEd25519PhSigner.Reset;
+begin
+  FPreHash.Reset();
+end;
+
+procedure TEd25519PhSigner.Update(b: Byte);
+begin
+  FPreHash.Update(b);
+end;
+
+function TEd25519PhSigner.GenerateSignature: TCryptoLibByteArray;
+var
+  signature, msg: TCryptoLibByteArray;
+begin
+  if ((not FforSigning) or (FPrivateKey = Nil)) then
+  begin
+    raise EInvalidOperationCryptoLibException.CreateRes
+      (@SNotInitializedForSigning);
+  end;
+  System.SetLength(msg, TEd25519.PreHashSize);
+
+  if ((TEd25519.PreHashSize) <> (FPreHash.DoFinal(msg, 0))) then
+  begin
+    raise EInvalidOperationCryptoLibException.CreateRes(@SPreHashDigestFailed);
+  end;
+
+  System.SetLength(signature, TEd25519PrivateKeyParameters.SignatureSize);
+
+  FPrivateKey.Sign(TEd25519.TEd25519Algorithm.Ed25519Ph, FPublicKey, FContext,
+    msg, 0, TEd25519.PreHashSize, signature, 0);
+  Result := signature;
+end;
+
+function TEd25519PhSigner.VerifySignature(const signature
+  : TCryptoLibByteArray): Boolean;
+var
+  pk: TCryptoLibByteArray;
+begin
+  if ((FforSigning) or (FPublicKey = Nil)) then
+  begin
+    raise EInvalidOperationCryptoLibException.CreateRes
+      (@SNotInitializedForVerifying);
+  end;
+  if (TEd25519.SignatureSize <> System.Length(signature)) then
+  begin
+    Result := false;
+    Exit;
+  end;
+  pk := FPublicKey.GetEncoded();
+  Result := FEd25519Instance.VerifyPrehash(signature, 0, pk, 0, FContext,
+    FPreHash);
+end;
+
+end.

+ 210 - 0
src/libraries/cryptolib4pascal/ClpEd25519PrivateKeyParameters.pas

@@ -0,0 +1,210 @@
+{ *********************************************************************************** }
+{ *                              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 ClpEd25519PrivateKeyParameters;
+
+{$I CryptoLib.inc}
+
+interface
+
+uses
+  Classes,
+  ClpEd25519,
+  ClpIEd25519,
+  ClpISecureRandom,
+  ClpAsymmetricKeyParameter,
+  ClpIEd25519PrivateKeyParameters,
+  ClpIEd25519PublicKeyParameters,
+  ClpEd25519PublicKeyParameters,
+  ClpArrayUtils,
+  ClpAsn1Objects,
+  ClpCryptoLibTypes;
+
+resourcestring
+  SEOFInPrivateKey = 'EOF encountered in middle of Ed25519 private key';
+  SUnsupportedAlgorithm = 'Unsupported Algorithm';
+  SCtxNotNil = 'Ctx must be Nil for Ed25519 Algorithm';
+  SMsgLen = 'MsgLen must be Equal to "PreHashSize" for Ed25519ph Algorithm';
+
+type
+  TEd25519PrivateKeyParameters = class sealed(TAsymmetricKeyParameter,
+    IEd25519PrivateKeyParameters)
+
+  strict private
+  var
+    FData: TCryptoLibByteArray;
+    FEd25519Instance: IEd25519;
+
+  public
+
+    const
+    KeySize = Int32(TEd25519.SecretKeySize);
+    SignatureSize = Int32(TEd25519.SignatureSize);
+
+    constructor Create(const random: ISecureRandom); overload;
+    constructor Create(const buf: TCryptoLibByteArray; off: Int32); overload;
+    constructor Create(input: TStream); overload;
+
+    procedure Encode(const buf: TCryptoLibByteArray; off: Int32); inline;
+    function GetEncoded(): TCryptoLibByteArray; inline;
+    function GeneratePublicKey(): IEd25519PublicKeyParameters; inline;
+
+    procedure Sign(algorithm: TEd25519.TEd25519Algorithm;
+      const publicKey: IEd25519PublicKeyParameters;
+      const ctx, msg: TCryptoLibByteArray; msgOff, msgLen: Int32;
+      const sig: TCryptoLibByteArray; sigOff: Int32);
+
+    function Equals(const other: IEd25519PrivateKeyParameters): Boolean;
+      reintroduce; overload;
+    function GetHashCode(): {$IFDEF DELPHI}Int32; {$ELSE}PtrInt;
+{$ENDIF DELPHI}override;
+
+  end;
+
+implementation
+
+{ TEd25519PrivateKeyParameters }
+
+function TEd25519PrivateKeyParameters.GeneratePublicKey
+  : IEd25519PublicKeyParameters;
+var
+  publicKey: TCryptoLibByteArray;
+begin
+  System.SetLength(publicKey, TEd25519.PublicKeySize);
+  FEd25519Instance.GeneratePublicKey(FData, 0, publicKey, 0);
+  result := TEd25519PublicKeyParameters.Create(publicKey, 0);
+end;
+
+function TEd25519PrivateKeyParameters.GetEncoded: TCryptoLibByteArray;
+begin
+  result := System.Copy(FData);
+end;
+
+constructor TEd25519PrivateKeyParameters.Create(const random: ISecureRandom);
+begin
+  Inherited Create(true);
+  System.SetLength(FData, KeySize);
+  FEd25519Instance := TEd25519.Create();
+  FEd25519Instance.GeneratePrivateKey(random, FData);
+end;
+
+constructor TEd25519PrivateKeyParameters.Create(const buf: TCryptoLibByteArray;
+  off: Int32);
+begin
+  Inherited Create(true);
+  System.SetLength(FData, KeySize);
+  FEd25519Instance := TEd25519.Create();
+  System.Move(buf[off], FData[0], KeySize * System.SizeOf(Byte));
+end;
+
+constructor TEd25519PrivateKeyParameters.Create(input: TStream);
+begin
+  Inherited Create(true);
+  System.SetLength(FData, KeySize);
+  FEd25519Instance := TEd25519.Create();
+  if (KeySize <> TStreamUtils.ReadFully(input, FData)) then
+  begin
+    raise EEndOfStreamCryptoLibException.CreateRes(@SEOFInPrivateKey);
+  end;
+end;
+
+procedure TEd25519PrivateKeyParameters.Encode(const buf: TCryptoLibByteArray;
+  off: Int32);
+begin
+  System.Move(FData[0], buf[off], KeySize * System.SizeOf(Byte));
+end;
+
+function TEd25519PrivateKeyParameters.Equals(const other
+  : IEd25519PrivateKeyParameters): Boolean;
+begin
+  if (other = Self as IEd25519PrivateKeyParameters) then
+  begin
+    result := true;
+    Exit;
+  end;
+
+  if (other = Nil) then
+  begin
+    result := false;
+    Exit;
+  end;
+  result := TArrayUtils.ConstantTimeAreEqual(FData, other.GetEncoded())
+end;
+
+function TEd25519PrivateKeyParameters.GetHashCode: {$IFDEF DELPHI}Int32; {$ELSE}PtrInt;
+{$ENDIF DELPHI}
+begin
+  result := TArrayUtils.GetArrayHashCode(FData);
+end;
+
+procedure TEd25519PrivateKeyParameters.Sign
+  (algorithm: TEd25519.TEd25519Algorithm;
+  const publicKey: IEd25519PublicKeyParameters;
+  const ctx, msg: TCryptoLibByteArray; msgOff, msgLen: Int32;
+  const sig: TCryptoLibByteArray; sigOff: Int32);
+var
+  pk: TCryptoLibByteArray;
+begin
+  System.SetLength(pk, TEd25519.PublicKeySize);
+
+  if (publicKey = Nil) then
+  begin
+    FEd25519Instance.GeneratePublicKey(FData, 0, pk, 0);
+  end
+  else
+  begin
+    publicKey.Encode(pk, 0);
+  end;
+
+  case algorithm of
+    TEd25519.TEd25519Algorithm.Ed25519:
+      begin
+        if (ctx <> Nil) then
+        begin
+          raise EArgumentCryptoLibException.CreateRes(@SCtxNotNil);
+        end;
+
+        FEd25519Instance.Sign(FData, 0, pk, 0, msg, msgOff, msgLen,
+          sig, sigOff);
+      end;
+
+    TEd25519.TEd25519Algorithm.Ed25519ctx:
+      begin
+        FEd25519Instance.Sign(FData, 0, pk, 0, ctx, msg, msgOff, msgLen,
+          sig, sigOff);
+      end;
+
+    TEd25519.TEd25519Algorithm.Ed25519ph:
+      begin
+        if (TEd25519.PreHashSize <> msgLen) then
+        begin
+          raise EArgumentCryptoLibException.CreateRes(@SMsgLen);
+        end;
+
+        FEd25519Instance.SignPrehash(FData, 0, pk, 0, ctx, msg, msgOff,
+          sig, sigOff);
+      end
+  else
+    begin
+      raise EInvalidOperationCryptoLibException.CreateRes
+        (@SUnsupportedAlgorithm);
+    end;
+
+  end;
+end;
+
+end.

+ 118 - 0
src/libraries/cryptolib4pascal/ClpEd25519PublicKeyParameters.pas

@@ -0,0 +1,118 @@
+{ *********************************************************************************** }
+{ *                              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 ClpEd25519PublicKeyParameters;
+
+{$I CryptoLib.inc}
+
+interface
+
+uses
+  Classes,
+  ClpEd25519,
+  ClpAsymmetricKeyParameter,
+  ClpIEd25519PublicKeyParameters,
+  ClpArrayUtils,
+  ClpAsn1Objects,
+  ClpCryptoLibTypes;
+
+resourcestring
+  SEOFInPublicKey = 'EOF encountered in middle of Ed25519 public key';
+
+type
+  TEd25519PublicKeyParameters = class sealed(TAsymmetricKeyParameter,
+    IEd25519PublicKeyParameters)
+
+  strict private
+  var
+    FData: TCryptoLibByteArray;
+
+  public
+
+    const
+    KeySize = Int32(TEd25519.PublicKeySize);
+
+    constructor Create(const buf: TCryptoLibByteArray; off: Int32); overload;
+    constructor Create(input: TStream); overload;
+
+    procedure Encode(const buf: TCryptoLibByteArray; off: Int32); inline;
+    function GetEncoded(): TCryptoLibByteArray; inline;
+
+    function Equals(const other: IEd25519PublicKeyParameters): Boolean;
+      reintroduce; overload;
+    function GetHashCode(): {$IFDEF DELPHI}Int32; {$ELSE}PtrInt;
+{$ENDIF DELPHI}override;
+
+  end;
+
+implementation
+
+{ TEd25519PublicKeyParameters }
+
+function TEd25519PublicKeyParameters.GetEncoded: TCryptoLibByteArray;
+begin
+  result := System.Copy(FData);
+end;
+
+constructor TEd25519PublicKeyParameters.Create(const buf: TCryptoLibByteArray;
+  off: Int32);
+begin
+  Inherited Create(false);
+  System.SetLength(FData, KeySize);
+  System.Move(buf[off], FData[0], KeySize * System.SizeOf(Byte));
+end;
+
+constructor TEd25519PublicKeyParameters.Create(input: TStream);
+begin
+  Inherited Create(false);
+  System.SetLength(FData, KeySize);
+  if (KeySize <> TStreamUtils.ReadFully(input, FData)) then
+  begin
+    raise EEndOfStreamCryptoLibException.CreateRes(@SEOFInPublicKey);
+  end;
+end;
+
+procedure TEd25519PublicKeyParameters.Encode(const buf: TCryptoLibByteArray;
+  off: Int32);
+begin
+  System.Move(FData[0], buf[off], KeySize * System.SizeOf(Byte));
+end;
+
+function TEd25519PublicKeyParameters.Equals(const other
+  : IEd25519PublicKeyParameters): Boolean;
+begin
+  if (other = Self as IEd25519PublicKeyParameters) then
+  begin
+    result := true;
+    Exit;
+  end;
+
+  if (other = Nil) then
+  begin
+    result := false;
+    Exit;
+  end;
+  result := TArrayUtils.ConstantTimeAreEqual(FData, other.GetEncoded())
+end;
+
+function TEd25519PublicKeyParameters.GetHashCode: {$IFDEF DELPHI}Int32; {$ELSE}PtrInt;
+{$ENDIF DELPHI}
+begin
+  result := TArrayUtils.GetArrayHashCode(FData);
+end;
+
+end.

+ 186 - 0
src/libraries/cryptolib4pascal/ClpEd25519Signer.pas

@@ -0,0 +1,186 @@
+{ *********************************************************************************** }
+{ *                              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 ClpEd25519Signer;
+
+{$I CryptoLib.inc}
+
+interface
+
+uses
+  Classes,
+  ClpIEd25519,
+  ClpEd25519,
+  ClpICipherParameters,
+  ClpIEd25519Signer,
+  ClpIEd25519PrivateKeyParameters,
+  ClpIEd25519PublicKeyParameters,
+  ClpEd25519PrivateKeyParameters,
+  ClpCryptoLibTypes;
+
+resourcestring
+  SNotInitializedForSigning =
+    'Ed25519Signer not Initialised for Signature Generation.';
+  SNotInitializedForVerifying =
+    'Ed25519Signer not Initialised for Verification';
+
+type
+  TEd25519Signer = class(TInterfacedObject, IEd25519Signer)
+
+  strict private
+  var
+    FBuffer: TMemoryStream;
+    FforSigning: Boolean;
+    FEd25519Instance: IEd25519;
+    FPrivateKey: IEd25519PrivateKeyParameters;
+    FPublicKey: IEd25519PublicKeyParameters;
+
+    function Aggregate: TCryptoLibByteArray; inline;
+
+  strict protected
+    function GetAlgorithmName: String; virtual;
+
+  public
+    constructor Create();
+    destructor Destroy(); override;
+
+    procedure Init(forSigning: Boolean;
+      const parameters: ICipherParameters); virtual;
+    procedure Update(b: Byte); virtual;
+    procedure BlockUpdate(const buf: TCryptoLibByteArray;
+      off, len: Int32); virtual;
+    function GenerateSignature(): TCryptoLibByteArray; virtual;
+    function VerifySignature(const signature: TCryptoLibByteArray)
+      : Boolean; virtual;
+    procedure Reset(); virtual;
+
+    property AlgorithmName: String read GetAlgorithmName;
+
+  end;
+
+implementation
+
+{ TEd25519Signer }
+
+function TEd25519Signer.Aggregate: TCryptoLibByteArray;
+begin
+  FBuffer.Position := 0;
+  System.SetLength(Result, FBuffer.Size);
+  FBuffer.Read(Result[0], FBuffer.Size);
+end;
+
+procedure TEd25519Signer.BlockUpdate(const buf: TCryptoLibByteArray;
+  off, len: Int32);
+begin
+  FBuffer.Write(buf[off], len);
+end;
+
+constructor TEd25519Signer.Create;
+begin
+  Inherited Create();
+  FBuffer := TMemoryStream.Create();
+  FEd25519Instance := TEd25519.Create();
+end;
+
+destructor TEd25519Signer.Destroy;
+begin
+  FBuffer.Free;
+  inherited Destroy;
+end;
+
+function TEd25519Signer.GetAlgorithmName: String;
+begin
+  Result := 'Ed25519';
+end;
+
+procedure TEd25519Signer.Init(forSigning: Boolean;
+  const parameters: ICipherParameters);
+begin
+  FforSigning := forSigning;
+
+  if (forSigning) then
+  begin
+    // TODO Allow IAsymmetricCipherKeyPair to be an ICipherParameters?
+
+    FPrivateKey := parameters as IEd25519PrivateKeyParameters;
+    FPublicKey := FPrivateKey.GeneratePublicKey();
+  end
+  else
+  begin
+    FPrivateKey := Nil;
+    FPublicKey := parameters as IEd25519PublicKeyParameters;
+  end;
+
+  Reset();
+end;
+
+procedure TEd25519Signer.Reset;
+begin
+  FBuffer.Clear;
+  FBuffer.SetSize(Int64(0));
+end;
+
+procedure TEd25519Signer.Update(b: Byte);
+begin
+  FBuffer.Write(TCryptoLibByteArray.Create(b)[0], 1);
+end;
+
+function TEd25519Signer.GenerateSignature: TCryptoLibByteArray;
+var
+  signature, buf: TCryptoLibByteArray;
+  count: Int32;
+begin
+  if ((not FforSigning) or (FPrivateKey = Nil)) then
+  begin
+    raise EInvalidOperationCryptoLibException.CreateRes
+      (@SNotInitializedForSigning);
+  end;
+
+  System.SetLength(signature, TEd25519PrivateKeyParameters.SignatureSize);
+  buf := Aggregate();
+  count := System.Length(buf);
+
+  FPrivateKey.Sign(TEd25519.TEd25519Algorithm.Ed25519, FPublicKey, Nil, buf, 0,
+    count, signature, 0);
+  Reset();
+  Result := signature;
+end;
+
+function TEd25519Signer.VerifySignature(const signature
+  : TCryptoLibByteArray): Boolean;
+var
+  buf, pk: TCryptoLibByteArray;
+  count: Int32;
+begin
+  if ((FforSigning) or (FPublicKey = Nil)) then
+  begin
+    raise EInvalidOperationCryptoLibException.CreateRes
+      (@SNotInitializedForVerifying);
+  end;
+  if (TEd25519.SignatureSize <> System.Length(signature)) then
+  begin
+    Result := false;
+    Exit;
+  end;
+  pk := FPublicKey.GetEncoded();
+  buf := Aggregate();
+  count := System.Length(buf);
+  Result := FEd25519Instance.Verify(signature, 0, pk, 0, buf, 0, count);
+  Reset();
+end;
+
+end.

+ 114 - 0
src/libraries/cryptolib4pascal/ClpEdECObjectIdentifiers.pas

@@ -0,0 +1,114 @@
+{ *********************************************************************************** }
+{ *                              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 ClpEdECObjectIdentifiers;
+
+{$I CryptoLib.inc}
+
+interface
+
+uses
+  ClpAsn1Objects,
+  ClpIAsn1Objects;
+
+type
+
+  /// <summary>
+  /// Edwards Elliptic Curve Object Identifiers (RFC 8410)
+  /// </summary>
+  TEdECObjectIdentifiers = class abstract(TObject)
+
+  strict private
+
+  class var
+
+    FIsBooted: Boolean;
+    Fid_edwards_curve_algs, Fid_X25519, Fid_X448, Fid_Ed25519,
+      Fid_Ed448: IDerObjectIdentifier;
+
+    class constructor EdECObjectIdentifiers();
+  private
+    class function Getid_Ed25519: IDerObjectIdentifier; static; inline;
+    class function Getid_Ed448: IDerObjectIdentifier; static; inline;
+    class function Getid_edwards_curve_algs: IDerObjectIdentifier;
+      static; inline;
+    class function Getid_X25519: IDerObjectIdentifier; static; inline;
+    class function Getid_X448: IDerObjectIdentifier; static; inline;
+
+  public
+
+    class property id_edwards_curve_algs: IDerObjectIdentifier
+      read Getid_edwards_curve_algs;
+    class property id_X25519: IDerObjectIdentifier read Getid_X25519;
+    class property id_X448: IDerObjectIdentifier read Getid_X448;
+    class property id_Ed25519: IDerObjectIdentifier read Getid_Ed25519;
+    class property id_Ed448: IDerObjectIdentifier read Getid_Ed448;
+
+    class procedure Boot(); static;
+  end;
+
+implementation
+
+{ TEdECObjectIdentifiers }
+
+class procedure TEdECObjectIdentifiers.Boot;
+begin
+  if not FIsBooted then
+  begin
+    Fid_edwards_curve_algs := TDerObjectIdentifier.Create('1.3.101');
+
+    Fid_X25519 := id_edwards_curve_algs.Branch('110');
+    Fid_X448 := id_edwards_curve_algs.Branch('111');
+    Fid_Ed25519 := id_edwards_curve_algs.Branch('112');
+    Fid_Ed448 := id_edwards_curve_algs.Branch('113');
+
+    FIsBooted := True;
+  end;
+end;
+
+class constructor TEdECObjectIdentifiers.EdECObjectIdentifiers;
+begin
+  TEdECObjectIdentifiers.Boot();
+end;
+
+class function TEdECObjectIdentifiers.Getid_Ed25519: IDerObjectIdentifier;
+begin
+  result := Fid_Ed25519;
+end;
+
+class function TEdECObjectIdentifiers.Getid_Ed448: IDerObjectIdentifier;
+begin
+  result := Fid_Ed448;
+end;
+
+class function TEdECObjectIdentifiers.Getid_edwards_curve_algs
+  : IDerObjectIdentifier;
+begin
+  result := Fid_edwards_curve_algs;
+end;
+
+class function TEdECObjectIdentifiers.Getid_X25519: IDerObjectIdentifier;
+begin
+  result := Fid_X25519;
+end;
+
+class function TEdECObjectIdentifiers.Getid_X448: IDerObjectIdentifier;
+begin
+  result := Fid_X448;
+end;
+
+end.

+ 51 - 9
src/libraries/cryptolib4pascal/ClpGeneratorUtilities.pas

@@ -31,11 +31,18 @@ uses
   ClpIAsn1Objects,
   ClpIAsn1Objects,
   ClpDsaKeyPairGenerator,
   ClpDsaKeyPairGenerator,
   ClpIDsaKeyPairGenerator,
   ClpIDsaKeyPairGenerator,
+  ClpEd25519KeyPairGenerator,
+  ClpIEd25519KeyPairGenerator,
+  ClpEd25519Blake2BKeyPairGenerator,
+  ClpIEd25519Blake2BKeyPairGenerator,
+  ClpX25519KeyPairGenerator,
+  ClpIX25519KeyPairGenerator,
   ClpIAsymmetricCipherKeyPairGenerator,
   ClpIAsymmetricCipherKeyPairGenerator,
   ClpNistObjectIdentifiers,
   ClpNistObjectIdentifiers,
   ClpIanaObjectIdentifiers,
   ClpIanaObjectIdentifiers,
   ClpPkcsObjectIdentifiers,
   ClpPkcsObjectIdentifiers,
   ClpRosstandartObjectIdentifiers,
   ClpRosstandartObjectIdentifiers,
+  ClpEdECObjectIdentifiers,
   ClpStringUtils,
   ClpStringUtils,
   ClpCryptoLibTypes;
   ClpCryptoLibTypes;
 
 
@@ -125,10 +132,10 @@ class procedure TGeneratorUtilities.AddKgAlgorithm(const canonicalName: String;
 var
 var
   alias: string;
   alias: string;
 begin
 begin
-  FkgAlgorithms.Add(canonicalName, canonicalName);
+  FkgAlgorithms.Add(UpperCase(canonicalName), canonicalName);
   for alias in aliases do
   for alias in aliases do
   begin
   begin
-    FkgAlgorithms.Add(alias, canonicalName);
+    FkgAlgorithms.Add(UpperCase(alias), canonicalName);
   end;
   end;
 
 
 end;
 end;
@@ -138,10 +145,10 @@ class procedure TGeneratorUtilities.AddKpgAlgorithm(const canonicalName: String;
 var
 var
   alias: string;
   alias: string;
 begin
 begin
-  FkpgAlgorithms.Add(canonicalName, canonicalName);
+  FkpgAlgorithms.Add(UpperCase(canonicalName), canonicalName);
   for alias in aliases do
   for alias in aliases do
   begin
   begin
-    FkpgAlgorithms.Add(alias, canonicalName);
+    FkpgAlgorithms.Add(UpperCase(alias), canonicalName);
   end;
   end;
 
 
 end;
 end;
@@ -159,7 +166,7 @@ begin
 
 
   for alias in aliases do
   for alias in aliases do
   begin
   begin
-    FkgAlgorithms.Add(alias, mainName);
+    FkgAlgorithms.Add(UpperCase(alias), mainName);
   end;
   end;
 
 
 end;
 end;
@@ -218,6 +225,12 @@ begin
   AddHMacKeyGenerator('SHA512/224', []);
   AddHMacKeyGenerator('SHA512/224', []);
   AddHMacKeyGenerator('SHA512/256', []);
   AddHMacKeyGenerator('SHA512/256', []);
 
 
+  AddHMacKeyGenerator('KECCAK224', []);
+  AddHMacKeyGenerator('KECCAK256', []);
+  AddHMacKeyGenerator('KECCAK288', []);
+  AddHMacKeyGenerator('KECCAK384', []);
+  AddHMacKeyGenerator('KECCAK512', []);
+
   AddHMacKeyGenerator('SHA3-224',
   AddHMacKeyGenerator('SHA3-224',
     [TNistObjectIdentifiers.IdHMacWithSha3_224.ID]);
     [TNistObjectIdentifiers.IdHMacWithSha3_224.ID]);
   AddHMacKeyGenerator('SHA3-256',
   AddHMacKeyGenerator('SHA3-256',
@@ -243,19 +256,29 @@ begin
 
 
   AddKpgAlgorithm('DSA', []);
   AddKpgAlgorithm('DSA', []);
   AddKpgAlgorithm('ECDH', ['ECIES']);
   AddKpgAlgorithm('ECDH', ['ECIES']);
+  AddKpgAlgorithm('ECDHC', []);
   AddKpgAlgorithm('ECDSA', []);
   AddKpgAlgorithm('ECDSA', []);
 
 
+  TEdECObjectIdentifiers.Boot;
+
+  AddKpgAlgorithm('Ed25519', ['Ed25519ctx', 'Ed25519ph',
+    TEdECObjectIdentifiers.id_Ed25519.ID]);
+  AddKpgAlgorithm('Ed25519Blake2B', ['Ed25519Blake2Bctx', 'Ed25519Blake2Bph']);
+  AddKpgAlgorithm('X25519', [TEdECObjectIdentifiers.id_X25519.ID]);
+
   AddDefaultKeySizeEntries(128, ['AES128', 'BLOWFISH', 'HMACMD2', 'HMACMD4',
   AddDefaultKeySizeEntries(128, ['AES128', 'BLOWFISH', 'HMACMD2', 'HMACMD4',
     'HMACMD5', 'HMACRIPEMD128', 'SALSA20']);
     'HMACMD5', 'HMACRIPEMD128', 'SALSA20']);
   AddDefaultKeySizeEntries(160, ['HMACRIPEMD160', 'HMACSHA1']);
   AddDefaultKeySizeEntries(160, ['HMACRIPEMD160', 'HMACSHA1']);
   AddDefaultKeySizeEntries(192, ['AES', 'AES192', 'HMACTIGER']);
   AddDefaultKeySizeEntries(192, ['AES', 'AES192', 'HMACTIGER']);
-  AddDefaultKeySizeEntries(224, ['HMACSHA3-224', 'HMACSHA224',
+  AddDefaultKeySizeEntries(224, ['HMACSHA3-224', 'HMACKECCAK224', 'HMACSHA224',
     'HMACSHA512/224']);
     'HMACSHA512/224']);
   AddDefaultKeySizeEntries(256, ['AES256', 'HMACGOST3411-2012-256',
   AddDefaultKeySizeEntries(256, ['AES256', 'HMACGOST3411-2012-256',
-    'HMACSHA3-256', 'HMACSHA256', 'HMACSHA512/256']);
-  AddDefaultKeySizeEntries(384, ['HMACSHA3-384', 'HMACSHA384']);
+    'HMACSHA3-256', 'HMACKECCAK256', 'HMACSHA256', 'HMACSHA512/256']);
+  AddDefaultKeySizeEntries(288, ['HMACKECCAK288']);
+  AddDefaultKeySizeEntries(384, ['HMACSHA3-384', 'HMACKECCAK384',
+    'HMACSHA384']);
   AddDefaultKeySizeEntries(512, ['HMACGOST3411-2012-512', 'HMACSHA3-512',
   AddDefaultKeySizeEntries(512, ['HMACGOST3411-2012-512', 'HMACSHA3-512',
-    'HMACSHA512']);
+    'HMACKECCAK512', 'HMACSHA512']);
 end;
 end;
 
 
 class constructor TGeneratorUtilities.CreateGeneratorUtilities;
 class constructor TGeneratorUtilities.CreateGeneratorUtilities;
@@ -375,6 +398,25 @@ begin
     Exit;
     Exit;
   end;
   end;
 
 
+  if (canonicalName = 'Ed25519') then
+  begin
+    result := TEd25519KeyPairGenerator.Create() as IEd25519KeyPairGenerator;
+    Exit;
+  end;
+
+  if (canonicalName = 'Ed25519Blake2B') then
+  begin
+    result := TEd25519Blake2BKeyPairGenerator.Create()
+      as IEd25519Blake2BKeyPairGenerator;
+    Exit;
+  end;
+
+  if (canonicalName = 'X25519') then
+  begin
+    result := TX25519KeyPairGenerator.Create() as IX25519KeyPairGenerator;
+    Exit;
+  end;
+
   raise ESecurityUtilityCryptoLibException.CreateResFmt
   raise ESecurityUtilityCryptoLibException.CreateResFmt
     (@SKeyPairGeneratorAlgorithmNotSupported, [algorithm, canonicalName]);
     (@SKeyPairGeneratorAlgorithmNotSupported, [algorithm, canonicalName]);
 
 

+ 1 - 1
src/libraries/cryptolib4pascal/ClpHMacDsaKCalculator.pas

@@ -17,7 +17,7 @@
 
 
 unit ClpHMacDsaKCalculator;
 unit ClpHMacDsaKCalculator;
 
 
-{$I ..\..\Include\CryptoLib.inc}
+{$I CryptoLib.inc}
 
 
 interface
 interface
 
 

+ 1 - 1
src/libraries/cryptolib4pascal/ClpHkdfBytesGenerator.pas

@@ -17,7 +17,7 @@
 
 
 unit ClpHkdfBytesGenerator;
 unit ClpHkdfBytesGenerator;
 
 
-{$I ..\..\Include\CryptoLib.inc}
+{$I CryptoLib.inc}
 
 
 interface
 interface
 
 

+ 2 - 6
src/libraries/cryptolib4pascal/ClpHkdfParameters.pas

@@ -17,7 +17,7 @@
 
 
 unit ClpHkdfParameters;
 unit ClpHkdfParameters;
 
 
-{$I ..\..\Include\CryptoLib.inc}
+{$I CryptoLib.inc}
 
 
 interface
 interface
 
 
@@ -153,11 +153,7 @@ begin
     Fsalt := System.Copy(salt);
     Fsalt := System.Copy(salt);
   end;
   end;
 
 
-  if (info = Nil) then
-  begin
-    System.SetLength(Finfo, 0);
-  end
-  else
+  if info <> Nil then
   begin
   begin
     Finfo := System.Copy(info);
     Finfo := System.Copy(info);
   end;
   end;

+ 1 - 1
src/libraries/cryptolib4pascal/ClpIAesLightEngine.pas

@@ -17,7 +17,7 @@
 
 
 unit ClpIAesLightEngine;
 unit ClpIAesLightEngine;
 
 
-{$I ..\Include\CryptoLib.inc}
+{$I CryptoLib.inc}
 
 
 interface
 interface
 
 

+ 118 - 0
src/libraries/cryptolib4pascal/ClpIArgon2ParametersGenerator.pas

@@ -0,0 +1,118 @@
+{ *********************************************************************************** }
+{ *                              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 ClpIArgon2ParametersGenerator;
+
+{$I CryptoLib.inc}
+
+interface
+
+uses
+  HlpIHashInfo,
+  HlpArgon2TypeAndVersion,
+  ClpICipherParameters,
+  ClpCryptoLibTypes;
+
+type
+{$SCOPEDENUMS ON}
+  TArgon2Type = HlpArgon2TypeAndVersion.TArgon2Type;
+  TArgon2Version = HlpArgon2TypeAndVersion.TArgon2Version;
+  TArgon2MemoryCostType = (a2mctMemoryAsKB, a2mctMemoryPowOfTwo);
+{$SCOPEDENUMS OFF}
+
+type
+  IArgon2ParametersGenerator = interface(IInterface)
+
+    ['{0AC3D3A8-9422-405F-B0EE-6B7AE0F64F74}']
+
+    procedure Init(argon2Type: TArgon2Type; argon2Version: TArgon2Version;
+      const password, salt, secret, additional: TCryptoLibByteArray;
+      iterations, memory, parallelism: Int32;
+      memoryCostType: TArgon2MemoryCostType);
+
+    /// <returns>
+    /// the password byte array.
+    /// </returns>
+    function GetPassword: TCryptoLibByteArray;
+
+    /// <value>
+    /// the password byte array.
+    /// </value>
+    property password: TCryptoLibByteArray read GetPassword;
+
+    /// <returns>
+    /// the Argon2 Parameter Builder Instance
+    /// </returns>
+    function GetArgon2ParametersBuilder: HlpIHashInfo.IArgon2ParametersBuilder;
+
+    /// <returns>
+    /// the Argon2 Parameter Builder Instance
+    /// </returns>
+    property Argon2ParametersBuilder: HlpIHashInfo.IArgon2ParametersBuilder
+      read GetArgon2ParametersBuilder;
+
+    /// <summary>
+    /// Generate derived parameters for a key of length keySize.
+    /// </summary>
+    /// <param name="algorithm">
+    /// a parameters object representing a key.
+    /// </param>
+    /// <param name="keySize">
+    /// the length, in bits, of the key required.
+    /// </param>
+    /// <returns>
+    /// a parameters object representing a key.
+    /// </returns>
+    function GenerateDerivedParameters(const algorithm: String; keySize: Int32)
+      : ICipherParameters; overload;
+
+    /// <summary>
+    /// Generate derived parameters for a key of length keySize and iv
+    /// of length ivSize.
+    /// </summary>
+    /// <param name="algorithm">
+    /// a parameters object representing a key.
+    /// </param>
+    /// <param name="keySize">
+    /// the length, in bits, of the key required.
+    /// </param>
+    /// <param name="ivSize">
+    /// the length, in bits, of the iv required.
+    /// </param>
+    /// <returns>
+    /// a parameters object representing a key and an iv.
+    /// </returns>
+    function GenerateDerivedParameters(const algorithm: String;
+      keySize, ivSize: Int32): ICipherParameters; overload;
+
+    /// <summary>
+    /// Generate derived parameters for a key of length keySize,
+    /// specifically <br />for use with a MAC.
+    /// </summary>
+    /// <param name="keySize">
+    /// the length, in bits, of the key required.
+    /// </param>
+    /// <returns>
+    /// a parameters object representing a key.
+    /// </returns>
+    function GenerateDerivedMacParameters(keySize: Int32): ICipherParameters;
+
+  end;
+
+implementation
+
+end.

+ 0 - 13
src/libraries/cryptolib4pascal/ClpIBlockCipherModes.pas

@@ -91,19 +91,6 @@ type
 
 
     ['{4D02FD0B-47D6-4914-B31F-5869FF364558}']
     ['{4D02FD0B-47D6-4914-B31F-5869FF364558}']
 
 
-    function GetOutputSize(inputLen: Int32): Int32;
-
-    function GetUpdateOutputSize(inputLen: Int32): Int32;
-
-    function ProcessByte(input: Byte; const output: TCryptoLibByteArray;
-      outOff: Int32): Int32;
-
-    function ProcessBytes(const input: TCryptoLibByteArray;
-      inOff, Length: Int32; const output: TCryptoLibByteArray;
-      outOff: Int32): Int32;
-
-    function DoFinal(const output: TCryptoLibByteArray; outOff: Int32): Int32;
-
   end;
   end;
 
 
 implementation
 implementation

+ 64 - 0
src/libraries/cryptolib4pascal/ClpICurve25519Custom.pas

@@ -0,0 +1,64 @@
+{ *********************************************************************************** }
+{ *                              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 ClpICurve25519Custom;
+
+{$I CryptoLib.inc}
+
+interface
+
+uses
+  ClpBigInteger,
+  ClpIECC,
+  ClpCryptoLibTypes;
+
+type
+  ICurve25519FieldElement = Interface(IAbstractFpFieldElement)
+    ['{50046C65-BACE-4E68-9AEF-09AAD33DFD62}']
+
+    function GetX: TCryptoLibUInt32Array;
+    property X: TCryptoLibUInt32Array read GetX;
+  end;
+
+type
+  ICurve25519Point = Interface(IAbstractFpPoint)
+    ['{49280930-32AC-4F84-BBCE-C9A9DF18E71E}']
+
+    function CalculateJacobianModifiedW(const z: ICurve25519FieldElement;
+      const ZSquared: TCryptoLibUInt32Array): ICurve25519FieldElement;
+    function GetJacobianModifiedW(): ICurve25519FieldElement;
+    function TwiceJacobianModified(calculateW: Boolean): ICurve25519Point;
+
+  end;
+
+type
+  ICurve25519 = Interface(IAbstractFpCurve)
+    ['{56BB2C20-454C-4C42-A603-AD7429362D82}']
+
+    function GetQ: TBigInteger;
+    property Q: TBigInteger read GetQ;
+
+  end;
+
+type
+  ICurve25519LookupTable = Interface(IECLookupTable)
+    ['{79FE1276-3D22-4A20-A4F1-58F0C0532BAC}']
+  end;
+
+implementation
+
+end.

+ 6 - 3
src/libraries/cryptolib4pascal/ClpIDigest.pas

@@ -81,15 +81,18 @@ type
     /// <param name="outOff">
     /// <param name="outOff">
     /// the offset into the out array the digest is to start at.
     /// the offset into the out array the digest is to start at.
     /// </param>
     /// </param>
-    function DoFinal(const output: TCryptoLibByteArray; outOff: Int32)
-      : Int32; overload;
-    function DoFinal: TCryptoLibByteArray; overload;
+    function DoFinal(const output: TCryptoLibByteArray; outOff: Int32): Int32;
 
 
     /// <summary>
     /// <summary>
     /// Resets the digest back to it's initial state.
     /// Resets the digest back to it's initial state.
     /// </summary>
     /// </summary>
     procedure Reset();
     procedure Reset();
 
 
+    /// <summary>
+    /// Clone the digest instance
+    /// </summary>
+    function Clone(): IDigest;
+
   end;
   end;
 
 
 implementation
 implementation

+ 1 - 1
src/libraries/cryptolib4pascal/ClpIDsaDigestSigner.pas

@@ -17,7 +17,7 @@
 
 
 unit ClpIDsaDigestSigner;
 unit ClpIDsaDigestSigner;
 
 
-{$I ..\Include\CryptoLib.inc}
+{$I CryptoLib.inc}
 
 
 interface
 interface
 
 

+ 1 - 1
src/libraries/cryptolib4pascal/ClpIDsaParameter.pas

@@ -17,7 +17,7 @@
 
 
 unit ClpIDsaParameter;
 unit ClpIDsaParameter;
 
 
-{$I ..\Include\CryptoLib.inc}
+{$I CryptoLib.inc}
 
 
 interface
 interface
 
 

+ 1 - 1
src/libraries/cryptolib4pascal/ClpIDsaParameterGenerationParameters.pas

@@ -17,7 +17,7 @@
 
 
 unit ClpIDsaParameterGenerationParameters;
 unit ClpIDsaParameterGenerationParameters;
 
 
-{$I ..\Include\CryptoLib.inc}
+{$I CryptoLib.inc}
 
 
 interface
 interface
 
 

+ 1 - 1
src/libraries/cryptolib4pascal/ClpIDsaParametersGenerator.pas

@@ -17,7 +17,7 @@
 
 
 unit ClpIDsaParametersGenerator;
 unit ClpIDsaParametersGenerator;
 
 
-{$I ..\Include\CryptoLib.inc}
+{$I CryptoLib.inc}
 
 
 interface
 interface
 
 

+ 1 - 1
src/libraries/cryptolib4pascal/ClpIDsaSigner.pas

@@ -17,7 +17,7 @@
 
 
 unit ClpIDsaSigner;
 unit ClpIDsaSigner;
 
 
-{$I ..\Include\CryptoLib.inc}
+{$I CryptoLib.inc}
 
 
 interface
 interface
 
 

+ 1 - 1
src/libraries/cryptolib4pascal/ClpIECDHCBasicAgreement.pas

@@ -17,7 +17,7 @@
 
 
 unit ClpIECDHCBasicAgreement;
 unit ClpIECDHCBasicAgreement;
 
 
-{$I ..\Include\CryptoLib.inc}
+{$I CryptoLib.inc}
 
 
 interface
 interface
 
 

+ 1 - 1
src/libraries/cryptolib4pascal/ClpIECNRSigner.pas

@@ -17,7 +17,7 @@
 
 
 unit ClpIECNRSigner;
 unit ClpIECNRSigner;
 
 
-{$I ..\Include\CryptoLib.inc}
+{$I CryptoLib.inc}
 
 
 interface
 interface
 
 

+ 1 - 1
src/libraries/cryptolib4pascal/ClpIECSchnorrSipaSigner.pas

@@ -17,7 +17,7 @@
 
 
 unit ClpIECSchnorrSipaSigner;
 unit ClpIECSchnorrSipaSigner;
 
 
-{$I ..\Include\CryptoLib.inc}
+{$I CryptoLib.inc}
 
 
 interface
 interface
 
 

+ 1 - 1
src/libraries/cryptolib4pascal/ClpIESEngine.pas

@@ -442,7 +442,7 @@ begin
     if (FIV <> Nil) then
     if (FIV <> Nil) then
     begin
     begin
       Fcipher.Init(true, TParametersWithIV.Create(TKeyParameter.Create(K1)
       Fcipher.Init(true, TParametersWithIV.Create(TKeyParameter.Create(K1)
-        as IKeyParameter, FIV));
+        as IKeyParameter, FIV) as IParametersWithIV);
     end
     end
     else
     else
     begin
     begin

+ 97 - 0
src/libraries/cryptolib4pascal/ClpIEd25519.pas

@@ -0,0 +1,97 @@
+{ *********************************************************************************** }
+{ *                              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 ClpIEd25519;
+
+{$I CryptoLib.inc}
+
+interface
+
+uses
+  ClpIDigest,
+  ClpISecureRandom,
+  ClpCryptoLibTypes;
+
+type
+  IEd25519 = interface(IInterface)
+    ['{2C6CD9DD-8809-44E6-979D-1EBE465CE9E2}']
+
+    function CreatePreHash(): IDigest;
+
+    procedure GeneratePrivateKey(const random: ISecureRandom;
+      const k: TCryptoLibByteArray);
+
+    procedure GeneratePublicKey(const sk: TCryptoLibByteArray; skOff: Int32;
+      pk: TCryptoLibByteArray; pkOff: Int32);
+
+    procedure Sign(const sk: TCryptoLibByteArray; skOff: Int32;
+      const m: TCryptoLibByteArray; mOff, mLen: Int32;
+      const sig: TCryptoLibByteArray; sigOff: Int32); overload;
+
+    procedure Sign(const sk: TCryptoLibByteArray; skOff: Int32;
+      const pk: TCryptoLibByteArray; pkOff: Int32; const m: TCryptoLibByteArray;
+      mOff, mLen: Int32; const sig: TCryptoLibByteArray;
+      sigOff: Int32); overload;
+
+    procedure Sign(const sk: TCryptoLibByteArray; skOff: Int32;
+      const ctx, m: TCryptoLibByteArray; mOff, mLen: Int32;
+      const sig: TCryptoLibByteArray; sigOff: Int32); overload;
+
+    procedure Sign(const sk: TCryptoLibByteArray; skOff: Int32;
+      const pk: TCryptoLibByteArray; pkOff: Int32;
+      const ctx, m: TCryptoLibByteArray; mOff, mLen: Int32;
+      const sig: TCryptoLibByteArray; sigOff: Int32); overload;
+
+    procedure SignPreHash(const sk: TCryptoLibByteArray; skOff: Int32;
+      const ctx, ph: TCryptoLibByteArray; phOff: Int32;
+      const sig: TCryptoLibByteArray; sigOff: Int32); overload;
+
+    procedure SignPreHash(const sk: TCryptoLibByteArray; skOff: Int32;
+      const pk: TCryptoLibByteArray; pkOff: Int32;
+      const ctx, ph: TCryptoLibByteArray; phOff: Int32;
+      const sig: TCryptoLibByteArray; sigOff: Int32); overload;
+
+    procedure SignPreHash(const sk: TCryptoLibByteArray; skOff: Int32;
+      const ctx: TCryptoLibByteArray; const ph: IDigest;
+      const sig: TCryptoLibByteArray; sigOff: Int32); overload;
+
+    procedure SignPreHash(const sk: TCryptoLibByteArray; skOff: Int32;
+      const pk: TCryptoLibByteArray; pkOff: Int32;
+      const ctx: TCryptoLibByteArray; const ph: IDigest;
+      const sig: TCryptoLibByteArray; sigOff: Int32); overload;
+
+    function Verify(const sig: TCryptoLibByteArray; sigOff: Int32;
+      const pk: TCryptoLibByteArray; pkOff: Int32; const m: TCryptoLibByteArray;
+      mOff, mLen: Int32): Boolean; overload;
+
+    function Verify(const sig: TCryptoLibByteArray; sigOff: Int32;
+      const pk: TCryptoLibByteArray; pkOff: Int32;
+      const ctx, m: TCryptoLibByteArray; mOff, mLen: Int32): Boolean; overload;
+
+    function VerifyPreHash(const sig: TCryptoLibByteArray; sigOff: Int32;
+      const pk: TCryptoLibByteArray; pkOff: Int32;
+      const ctx, ph: TCryptoLibByteArray; phOff: Int32): Boolean; overload;
+
+    function VerifyPreHash(const sig: TCryptoLibByteArray; sigOff: Int32;
+      const pk: TCryptoLibByteArray; pkOff: Int32;
+      const ctx: TCryptoLibByteArray; const ph: IDigest): Boolean; overload;
+
+  end;
+
+implementation
+
+end.

+ 35 - 0
src/libraries/cryptolib4pascal/ClpIEd25519Blake2B.pas

@@ -0,0 +1,35 @@
+{ *********************************************************************************** }
+{ *                              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 ClpIEd25519Blake2B;
+
+{$I CryptoLib.inc}
+
+interface
+
+uses
+  ClpIEd25519;
+
+type
+  IEd25519Blake2B = interface(IEd25519)
+    ['{4EF6C436-D49D-4442-A014-848E08D81BE6}']
+
+  end;
+
+implementation
+
+end.

+ 35 - 0
src/libraries/cryptolib4pascal/ClpIEd25519Blake2BKeyGenerationParameters.pas

@@ -0,0 +1,35 @@
+{ *********************************************************************************** }
+{ *                              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 ClpIEd25519Blake2BKeyGenerationParameters;
+
+{$I CryptoLib.inc}
+
+interface
+
+uses
+  ClpIKeyGenerationParameters;
+
+type
+  IEd25519Blake2BKeyGenerationParameters = interface(IKeyGenerationParameters)
+    ['{83EED7AC-2214-444D-8411-CD5CDFC32972}']
+
+  end;
+
+implementation
+
+end.

+ 35 - 0
src/libraries/cryptolib4pascal/ClpIEd25519Blake2BKeyPairGenerator.pas

@@ -0,0 +1,35 @@
+{ *********************************************************************************** }
+{ *                              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 ClpIEd25519Blake2BKeyPairGenerator;
+
+{$I CryptoLib.inc}
+
+interface
+
+uses
+  ClpIEd25519KeyPairGenerator;
+
+type
+  IEd25519Blake2BKeyPairGenerator = interface(IEd25519KeyPairGenerator)
+    ['{1923A01B-2246-4F5B-8BD5-3C78C181029E}']
+
+  end;
+
+implementation
+
+end.

+ 49 - 0
src/libraries/cryptolib4pascal/ClpIEd25519Blake2BPrivateKeyParameters.pas

@@ -0,0 +1,49 @@
+{ *********************************************************************************** }
+{ *                              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 ClpIEd25519Blake2BPrivateKeyParameters;
+
+{$I CryptoLib.inc}
+
+interface
+
+uses
+  ClpEd25519,
+  ClpIEd25519Blake2BPublicKeyParameters,
+  ClpIAsymmetricKeyParameter,
+  ClpCryptoLibTypes;
+
+type
+  IEd25519Blake2BPrivateKeyParameters = interface(IAsymmetricKeyParameter)
+    ['{AA0786F9-11D8-4B36-B9AE-A108FE678774}']
+
+    procedure Encode(const buf: TCryptoLibByteArray; off: Int32);
+    function GetEncoded(): TCryptoLibByteArray;
+    function GeneratePublicKey(): IEd25519Blake2BPublicKeyParameters;
+
+    procedure Sign(algorithm: TEd25519.TEd25519Algorithm;
+      const publicKey: IEd25519Blake2BPublicKeyParameters;
+      const ctx, msg: TCryptoLibByteArray; msgOff, msgLen: Int32;
+      const sig: TCryptoLibByteArray; sigOff: Int32);
+
+    function Equals(const other: IEd25519Blake2BPrivateKeyParameters)
+      : Boolean; overload;
+  end;
+
+implementation
+
+end.

+ 41 - 0
src/libraries/cryptolib4pascal/ClpIEd25519Blake2BPublicKeyParameters.pas

@@ -0,0 +1,41 @@
+{ *********************************************************************************** }
+{ *                              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 ClpIEd25519Blake2BPublicKeyParameters;
+
+{$I CryptoLib.inc}
+
+interface
+
+uses
+  ClpIAsymmetricKeyParameter,
+  ClpCryptoLibTypes;
+
+type
+  IEd25519Blake2BPublicKeyParameters = interface(IAsymmetricKeyParameter)
+    ['{54BC984B-F087-463C-AB06-BCB8C61D9770}']
+
+    procedure Encode(const buf: TCryptoLibByteArray; off: Int32);
+    function GetEncoded(): TCryptoLibByteArray;
+
+    function Equals(const other: IEd25519Blake2BPublicKeyParameters)
+      : Boolean; overload;
+  end;
+
+implementation
+
+end.

+ 36 - 0
src/libraries/cryptolib4pascal/ClpIEd25519Blake2BSigner.pas

@@ -0,0 +1,36 @@
+{ *********************************************************************************** }
+{ *                              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 ClpIEd25519Blake2BSigner;
+
+{$I CryptoLib.inc}
+
+interface
+
+uses
+  ClpISigner;
+
+type
+  IEd25519Blake2BSigner = interface(ISigner)
+
+    ['{3BF234D8-550D-4505-9C55-2C93733DCE30}']
+
+  end;
+
+implementation
+
+end.

+ 36 - 0
src/libraries/cryptolib4pascal/ClpIEd25519CtxBlake2BSigner.pas

@@ -0,0 +1,36 @@
+{ *********************************************************************************** }
+{ *                              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 ClpIEd25519CtxBlake2BSigner;
+
+{$I CryptoLib.inc}
+
+interface
+
+uses
+  ClpISigner;
+
+type
+  IEd25519CtxBlake2BSigner = interface(ISigner)
+
+    ['{E3138C67-743D-4772-BF30-63D398AE4D2D}']
+
+  end;
+
+implementation
+
+end.

+ 36 - 0
src/libraries/cryptolib4pascal/ClpIEd25519CtxSigner.pas

@@ -0,0 +1,36 @@
+{ *********************************************************************************** }
+{ *                              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 ClpIEd25519CtxSigner;
+
+{$I CryptoLib.inc}
+
+interface
+
+uses
+  ClpISigner;
+
+type
+  IEd25519CtxSigner = interface(ISigner)
+
+    ['{EF0302AE-A4FE-46B8-8839-8B7450EE977B}']
+
+  end;
+
+implementation
+
+end.

+ 35 - 0
src/libraries/cryptolib4pascal/ClpIEd25519KeyGenerationParameters.pas

@@ -0,0 +1,35 @@
+{ *********************************************************************************** }
+{ *                              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 ClpIEd25519KeyGenerationParameters;
+
+{$I CryptoLib.inc}
+
+interface
+
+uses
+  ClpIKeyGenerationParameters;
+
+type
+  IEd25519KeyGenerationParameters = interface(IKeyGenerationParameters)
+    ['{65D7E76D-588F-4499-BE57-ADA4273C68B9}']
+
+  end;
+
+implementation
+
+end.

+ 35 - 0
src/libraries/cryptolib4pascal/ClpIEd25519KeyPairGenerator.pas

@@ -0,0 +1,35 @@
+{ *********************************************************************************** }
+{ *                              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 ClpIEd25519KeyPairGenerator;
+
+{$I CryptoLib.inc}
+
+interface
+
+uses
+  ClpIAsymmetricCipherKeyPairGenerator;
+
+type
+  IEd25519KeyPairGenerator = interface(IAsymmetricCipherKeyPairGenerator)
+    ['{7A9A2591-E1F0-4D41-8DB3-8D56822B5AF0}']
+
+  end;
+
+implementation
+
+end.

+ 36 - 0
src/libraries/cryptolib4pascal/ClpIEd25519PhBlake2BSigner.pas

@@ -0,0 +1,36 @@
+{ *********************************************************************************** }
+{ *                              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 ClpIEd25519PhBlake2BSigner;
+
+{$I CryptoLib.inc}
+
+interface
+
+uses
+  ClpISigner;
+
+type
+  IEd25519PhBlake2BSigner = interface(ISigner)
+
+    ['{C51DD3EF-C78A-4C0A-993E-F1B4BA414875}']
+
+  end;
+
+implementation
+
+end.

+ 36 - 0
src/libraries/cryptolib4pascal/ClpIEd25519PhSigner.pas

@@ -0,0 +1,36 @@
+{ *********************************************************************************** }
+{ *                              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 ClpIEd25519PhSigner;
+
+{$I CryptoLib.inc}
+
+interface
+
+uses
+  ClpISigner;
+
+type
+  IEd25519PhSigner = interface(ISigner)
+
+    ['{7E2EBA92-1D10-474D-8342-2ED64D0DACE5}']
+
+  end;
+
+implementation
+
+end.

+ 49 - 0
src/libraries/cryptolib4pascal/ClpIEd25519PrivateKeyParameters.pas

@@ -0,0 +1,49 @@
+{ *********************************************************************************** }
+{ *                              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 ClpIEd25519PrivateKeyParameters;
+
+{$I CryptoLib.inc}
+
+interface
+
+uses
+  ClpEd25519,
+  ClpIEd25519PublicKeyParameters,
+  ClpIAsymmetricKeyParameter,
+  ClpCryptoLibTypes;
+
+type
+  IEd25519PrivateKeyParameters = interface(IAsymmetricKeyParameter)
+    ['{03CF8E9D-F462-4C77-B954-2519E31E625F}']
+
+    procedure Encode(const buf: TCryptoLibByteArray; off: Int32);
+    function GetEncoded(): TCryptoLibByteArray;
+    function GeneratePublicKey(): IEd25519PublicKeyParameters;
+
+    procedure Sign(algorithm: TEd25519.TEd25519Algorithm;
+      const publicKey: IEd25519PublicKeyParameters;
+      const ctx, msg: TCryptoLibByteArray; msgOff, msgLen: Int32;
+      const sig: TCryptoLibByteArray; sigOff: Int32);
+
+    function Equals(const other: IEd25519PrivateKeyParameters)
+      : Boolean; overload;
+  end;
+
+implementation
+
+end.

+ 41 - 0
src/libraries/cryptolib4pascal/ClpIEd25519PublicKeyParameters.pas

@@ -0,0 +1,41 @@
+{ *********************************************************************************** }
+{ *                              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 ClpIEd25519PublicKeyParameters;
+
+{$I CryptoLib.inc}
+
+interface
+
+uses
+  ClpIAsymmetricKeyParameter,
+  ClpCryptoLibTypes;
+
+type
+  IEd25519PublicKeyParameters = interface(IAsymmetricKeyParameter)
+    ['{84C0E096-F4BA-438D-9E20-3ECFAE341E63}']
+
+    procedure Encode(const buf: TCryptoLibByteArray; off: Int32);
+    function GetEncoded(): TCryptoLibByteArray;
+
+    function Equals(const other: IEd25519PublicKeyParameters): Boolean;
+      overload;
+  end;
+
+implementation
+
+end.

+ 36 - 0
src/libraries/cryptolib4pascal/ClpIEd25519Signer.pas

@@ -0,0 +1,36 @@
+{ *********************************************************************************** }
+{ *                              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 ClpIEd25519Signer;
+
+{$I CryptoLib.inc}
+
+interface
+
+uses
+  ClpISigner;
+
+type
+  IEd25519Signer = interface(ISigner)
+
+    ['{A7DC401C-ABF9-4615-AEB0-705B278DBEB9}']
+
+  end;
+
+implementation
+
+end.

+ 1 - 1
src/libraries/cryptolib4pascal/ClpIHMacDsaKCalculator.pas

@@ -17,7 +17,7 @@
 
 
 unit ClpIHMacDsaKCalculator;
 unit ClpIHMacDsaKCalculator;
 
 
-{$I ..\Include\CryptoLib.inc}
+{$I CryptoLib.inc}
 
 
 interface
 interface
 
 

+ 1 - 1
src/libraries/cryptolib4pascal/ClpIHkdfBytesGenerator.pas

@@ -17,7 +17,7 @@
 
 
 unit ClpIHkdfBytesGenerator;
 unit ClpIHkdfBytesGenerator;
 
 
-{$I ..\Include\CryptoLib.inc}
+{$I CryptoLib.inc}
 
 
 interface
 interface
 
 

+ 1 - 1
src/libraries/cryptolib4pascal/ClpIHkdfParameters.pas

@@ -17,7 +17,7 @@
 
 
 unit ClpIHkdfParameters;
 unit ClpIHkdfParameters;
 
 
-{$I ..\Include\CryptoLib.inc}
+{$I CryptoLib.inc}
 
 
 interface
 interface
 
 

+ 36 - 0
src/libraries/cryptolib4pascal/ClpIKdf1BytesGenerator.pas

@@ -0,0 +1,36 @@
+{ *********************************************************************************** }
+{ *                              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 ClpIKdf1BytesGenerator;
+
+{$I CryptoLib.inc}
+
+interface
+
+uses
+  ClpIBaseKdfBytesGenerator;
+
+type
+
+  IKdf1BytesGenerator = interface(IBaseKdfBytesGenerator)
+    ['{FD2AF455-8C5D-4860-A1D5-B70E5D417841}']
+
+  end;
+
+implementation
+
+end.

+ 1 - 1
src/libraries/cryptolib4pascal/ClpIKdf2BytesGenerator.pas

@@ -17,7 +17,7 @@
 
 
 unit ClpIKdf2BytesGenerator;
 unit ClpIKdf2BytesGenerator;
 
 
-{$I ..\Include\CryptoLib.inc}
+{$I CryptoLib.inc}
 
 
 interface
 interface
 
 

+ 1 - 0
src/libraries/cryptolib4pascal/ClpIKeyParameter.pas

@@ -31,6 +31,7 @@ type
     ['{92E7D4F7-40E5-4DC1-8058-23BE60848CC3}']
     ['{92E7D4F7-40E5-4DC1-8058-23BE60848CC3}']
 
 
     function GetKey(): TCryptoLibByteArray;
     function GetKey(): TCryptoLibByteArray;
+    procedure Clear();
 
 
   end;
   end;
 
 

+ 1 - 0
src/libraries/cryptolib4pascal/ClpIParametersWithIV.pas

@@ -32,6 +32,7 @@ type
     function GetIV(): TCryptoLibByteArray;
     function GetIV(): TCryptoLibByteArray;
     function GetParameters: ICipherParameters;
     function GetParameters: ICipherParameters;
     property Parameters: ICipherParameters read GetParameters;
     property Parameters: ICipherParameters read GetParameters;
+    procedure Clear();
 
 
   end;
   end;
 
 

+ 1 - 1
src/libraries/cryptolib4pascal/ClpIPbeParametersGenerator.pas

@@ -17,7 +17,7 @@
 
 
 unit ClpIPbeParametersGenerator;
 unit ClpIPbeParametersGenerator;
 
 
-{$I ..\Include\CryptoLib.inc}
+{$I CryptoLib.inc}
 
 
 interface
 interface
 
 

+ 1 - 1
src/libraries/cryptolib4pascal/ClpIPkcs5S2ParametersGenerator.pas

@@ -17,7 +17,7 @@
 
 
 unit ClpIPkcs5S2ParametersGenerator;
 unit ClpIPkcs5S2ParametersGenerator;
 
 
-{$I ..\Include\CryptoLib.inc}
+{$I CryptoLib.inc}
 
 
 interface
 interface
 
 

+ 43 - 0
src/libraries/cryptolib4pascal/ClpIRawAgreement.pas

@@ -0,0 +1,43 @@
+{ *********************************************************************************** }
+{ *                              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 ClpIRawAgreement;
+
+{$I CryptoLib.inc}
+
+interface
+
+uses
+  ClpICipherParameters,
+  ClpCryptoLibTypes;
+
+type
+  IRawAgreement = interface(IInterface)
+    ['{B3C55CE5-1F35-4C77-8CDB-757C07DBF4AA}']
+
+    procedure Init(const parameters: ICipherParameters);
+
+    function GetAgreementSize(): Int32;
+    property AgreementSize: Int32 read GetAgreementSize;
+
+    procedure CalculateAgreement(const publicKey: ICipherParameters;
+      const buf: TCryptoLibByteArray; off: Int32);
+  end;
+
+implementation
+
+end.

+ 1 - 1
src/libraries/cryptolib4pascal/ClpISchnorr.pas

@@ -17,7 +17,7 @@
 
 
 unit ClpISchnorr;
 unit ClpISchnorr;
 
 
-{$I ..\Include\CryptoLib.inc}
+{$I CryptoLib.inc}
 
 
 interface
 interface
 
 

+ 1 - 1
src/libraries/cryptolib4pascal/ClpISchnorrDigestSigner.pas

@@ -17,7 +17,7 @@
 
 
 unit ClpISchnorrDigestSigner;
 unit ClpISchnorrDigestSigner;
 
 
-{$I ..\Include\CryptoLib.inc}
+{$I CryptoLib.inc}
 
 
 interface
 interface
 
 

+ 1 - 1
src/libraries/cryptolib4pascal/ClpISchnorrExt.pas

@@ -17,7 +17,7 @@
 
 
 unit ClpISchnorrExt;
 unit ClpISchnorrExt;
 
 
-{$I ..\Include\CryptoLib.inc}
+{$I CryptoLib.inc}
 
 
 interface
 interface
 
 

+ 1 - 1
src/libraries/cryptolib4pascal/ClpISigner.pas

@@ -17,7 +17,7 @@
 
 
 unit ClpISigner;
 unit ClpISigner;
 
 
-{$I ..\Include\CryptoLib.inc}
+{$I CryptoLib.inc}
 
 
 interface
 interface
 
 

+ 36 - 0
src/libraries/cryptolib4pascal/ClpISpeckLegacyEngine.pas

@@ -0,0 +1,36 @@
+{ *********************************************************************************** }
+{ *                              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 ClpISpeckLegacyEngine;
+
+{$I CryptoLib.inc}
+
+interface
+
+uses
+  ClpIBlockCipher;
+
+type
+
+  ISpeckLegacyEngine = interface(IBlockCipher)
+   ['{8BD403C6-B761-4C24-9907-B7ABEA0FEF1B}']
+
+  end;
+
+implementation
+
+end.

+ 37 - 0
src/libraries/cryptolib4pascal/ClpIX25519Agreement.pas

@@ -0,0 +1,37 @@
+{ *********************************************************************************** }
+{ *                              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 ClpIX25519Agreement;
+
+{$I CryptoLib.inc}
+
+interface
+
+uses
+  ClpIRawAgreement;
+
+type
+
+  IX25519Agreement = interface(IRawAgreement)
+
+    ['{5561516C-4BC6-4D97-BF1A-FBC35A3B7A03}']
+
+  end;
+
+implementation
+
+end.

+ 35 - 0
src/libraries/cryptolib4pascal/ClpIX25519KeyGenerationParameters.pas

@@ -0,0 +1,35 @@
+{ *********************************************************************************** }
+{ *                              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 ClpIX25519KeyGenerationParameters;
+
+{$I CryptoLib.inc}
+
+interface
+
+uses
+  ClpIKeyGenerationParameters;
+
+type
+  IX25519KeyGenerationParameters = interface(IKeyGenerationParameters)
+    ['{BDDAF238-C842-4449-A7B8-3A537E405A62}']
+
+  end;
+
+implementation
+
+end.

+ 35 - 0
src/libraries/cryptolib4pascal/ClpIX25519KeyPairGenerator.pas

@@ -0,0 +1,35 @@
+{ *********************************************************************************** }
+{ *                              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 ClpIX25519KeyPairGenerator;
+
+{$I CryptoLib.inc}
+
+interface
+
+uses
+  ClpIAsymmetricCipherKeyPairGenerator;
+
+type
+  IX25519KeyPairGenerator = interface(IAsymmetricCipherKeyPairGenerator)
+    ['{EC906E22-1587-4E06-85D0-697368365F97}']
+
+  end;
+
+implementation
+
+end.

+ 45 - 0
src/libraries/cryptolib4pascal/ClpIX25519PrivateKeyParameters.pas

@@ -0,0 +1,45 @@
+{ *********************************************************************************** }
+{ *                              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 ClpIX25519PrivateKeyParameters;
+
+{$I CryptoLib.inc}
+
+interface
+
+uses
+  ClpIX25519PublicKeyParameters,
+  ClpIAsymmetricKeyParameter,
+  ClpCryptoLibTypes;
+
+type
+  IX25519PrivateKeyParameters = interface(IAsymmetricKeyParameter)
+    ['{6C7D2CD5-33A1-4153-A84C-70455CA69729}']
+
+    procedure Encode(const buf: TCryptoLibByteArray; off: Int32);
+    function GetEncoded(): TCryptoLibByteArray;
+    function GeneratePublicKey(): IX25519PublicKeyParameters;
+    procedure GenerateSecret(const publicKey: IX25519PublicKeyParameters;
+      const buf: TCryptoLibByteArray; off: Int32);
+
+    function Equals(const other: IX25519PrivateKeyParameters): Boolean;
+      overload;
+  end;
+
+implementation
+
+end.

+ 40 - 0
src/libraries/cryptolib4pascal/ClpIX25519PublicKeyParameters.pas

@@ -0,0 +1,40 @@
+{ *********************************************************************************** }
+{ *                              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 ClpIX25519PublicKeyParameters;
+
+{$I CryptoLib.inc}
+
+interface
+
+uses
+  ClpIAsymmetricKeyParameter,
+  ClpCryptoLibTypes;
+
+type
+  IX25519PublicKeyParameters = interface(IAsymmetricKeyParameter)
+    ['{52D136C4-4DD1-4AF1-9AB8-0783136EF04A}']
+
+    procedure Encode(const buf: TCryptoLibByteArray; off: Int32);
+    function GetEncoded(): TCryptoLibByteArray;
+
+    function Equals(const other: IX25519PublicKeyParameters): Boolean; overload;
+  end;
+
+implementation
+
+end.

+ 1 - 1
src/libraries/cryptolib4pascal/ClpIso18033KdfParameters.pas

@@ -17,7 +17,7 @@
 
 
 unit ClpIso18033KdfParameters;
 unit ClpIso18033KdfParameters;
 
 
-{$I ..\..\Include\CryptoLib.inc}
+{$I CryptoLib.inc}
 
 
 interface
 interface
 
 

+ 63 - 0
src/libraries/cryptolib4pascal/ClpKdf1BytesGenerator.pas

@@ -0,0 +1,63 @@
+{ *********************************************************************************** }
+{ *                              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 ClpKdf1BytesGenerator;
+
+{$I CryptoLib.inc}
+
+interface
+
+uses
+  ClpIDigest,
+  ClpBaseKdfBytesGenerator,
+  ClpIKdf1BytesGenerator;
+
+type
+
+  /// <summary>
+  /// <para>
+  /// KDF1 generator for derived keys and ivs as defined by IEEE
+  /// P1363a/ISO 18033
+  /// </para>
+  /// <para>
+  /// This implementation is based on IEEE P1363/ISO 18033.
+  /// </para>
+  /// </summary>
+  TKdf1BytesGenerator = class(TBaseKdfBytesGenerator, IKdf1BytesGenerator)
+
+  public
+
+    /// <summary>
+    /// Construct a KDF1 bytes generator.
+    /// </summary>
+    /// <param name="digest">
+    /// the digest to be used as the source of derived keys.
+    /// </param>
+    constructor Create(const digest: IDigest);
+
+  end;
+
+implementation
+
+{ TKdf1BytesGenerator }
+
+constructor TKdf1BytesGenerator.Create(const digest: IDigest);
+begin
+  Inherited Create(0, digest);
+end;
+
+end.

+ 1 - 1
src/libraries/cryptolib4pascal/ClpKdf2BytesGenerator.pas

@@ -17,7 +17,7 @@
 
 
 unit ClpKdf2BytesGenerator;
 unit ClpKdf2BytesGenerator;
 
 
-{$I ..\..\Include\CryptoLib.inc}
+{$I CryptoLib.inc}
 
 
 interface
 interface
 
 

+ 7 - 1
src/libraries/cryptolib4pascal/ClpKeyParameter.pas

@@ -46,6 +46,7 @@ type
       keyOff, keyLen: Int32); overload;
       keyOff, keyLen: Int32); overload;
     destructor Destroy; override;
     destructor Destroy; override;
     function GetKey(): TCryptoLibByteArray; inline;
     function GetKey(): TCryptoLibByteArray; inline;
+    procedure Clear(); inline;
 
 
   end;
   end;
 
 
@@ -64,6 +65,11 @@ begin
   Fkey := System.Copy(key);
   Fkey := System.Copy(key);
 end;
 end;
 
 
+procedure TKeyParameter.Clear;
+begin
+  TArrayUtils.Fill(Fkey, 0, System.Length(Fkey), Byte(0));
+end;
+
 constructor TKeyParameter.Create(const key: TCryptoLibByteArray;
 constructor TKeyParameter.Create(const key: TCryptoLibByteArray;
   keyOff, keyLen: Int32);
   keyOff, keyLen: Int32);
 begin
 begin
@@ -91,7 +97,7 @@ end;
 
 
 destructor TKeyParameter.Destroy;
 destructor TKeyParameter.Destroy;
 begin
 begin
-  TArrayUtils.Fill(Fkey, 0, System.Length(Fkey), Byte(0));
+  Clear();
   inherited Destroy;
   inherited Destroy;
 end;
 end;
 
 

Some files were not shown because too many files changed in this diff