Browse Source

completion of Ed25519, X25519 implementations and tests.

Ugochukwu Mmaduekwe 6 years ago
parent
commit
e884597ca7

+ 3 - 1
CryptoLib.Tests/Delphi.Tests/CryptoLib.Tests.TestInsight.dpr

@@ -404,7 +404,9 @@ uses
   CTSTests in '..\src\Crypto\CTSTests.pas',
   CTSTests in '..\src\Crypto\CTSTests.pas',
   PascalCoinECIESTests in '..\src\Math\PascalCoinECIESTests.pas',
   PascalCoinECIESTests in '..\src\Math\PascalCoinECIESTests.pas',
   X25519Tests in '..\src\Math\EC\Rfc7748\X25519Tests.pas',
   X25519Tests in '..\src\Math\EC\Rfc7748\X25519Tests.pas',
-  Ed25519Tests in '..\src\Math\EC\Rfc8032\Ed25519Tests.pas';
+  Ed25519Tests in '..\src\Math\EC\Rfc8032\Ed25519Tests.pas',
+  X25519HigherLevelTests in '..\src\Others\X25519HigherLevelTests.pas',
+  Ed25519HigherLevelTests in '..\src\Others\Ed25519HigherLevelTests.pas';
 
 
 begin
 begin
 
 

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

@@ -407,7 +407,9 @@ uses
   CTSTests in '..\src\Crypto\CTSTests.pas',
   CTSTests in '..\src\Crypto\CTSTests.pas',
   PascalCoinECIESTests in '..\src\Math\PascalCoinECIESTests.pas',
   PascalCoinECIESTests in '..\src\Math\PascalCoinECIESTests.pas',
   X25519Tests in '..\src\Math\EC\Rfc7748\X25519Tests.pas',
   X25519Tests in '..\src\Math\EC\Rfc7748\X25519Tests.pas',
-  Ed25519Tests in '..\src\Math\EC\Rfc8032\Ed25519Tests.pas';
+  Ed25519Tests in '..\src\Math\EC\Rfc8032\Ed25519Tests.pas',
+  X25519HigherLevelTests in '..\src\Others\X25519HigherLevelTests.pas',
+  Ed25519HigherLevelTests in '..\src\Others\Ed25519HigherLevelTests.pas';
 
 
 begin
 begin
 
 

+ 9 - 1
CryptoLib.Tests/FreePascal.Tests/CryptoLib.Tests.lpi

@@ -77,7 +77,7 @@
         <PackageName Value="FCL"/>
         <PackageName Value="FCL"/>
       </Item4>
       </Item4>
     </RequiredPackages>
     </RequiredPackages>
-    <Units Count="59">
+    <Units Count="61">
       <Unit0>
       <Unit0>
         <Filename Value="CryptoLib.lpr"/>
         <Filename Value="CryptoLib.lpr"/>
         <IsPartOfProject Value="True"/>
         <IsPartOfProject Value="True"/>
@@ -315,6 +315,14 @@
         <Filename Value="..\src\Math\EC\Rfc8032\Ed25519Tests.pas"/>
         <Filename Value="..\src\Math\EC\Rfc8032\Ed25519Tests.pas"/>
         <IsPartOfProject Value="True"/>
         <IsPartOfProject Value="True"/>
       </Unit58>
       </Unit58>
+      <Unit59>
+        <Filename Value="..\src\Others\Ed25519HigherLevelTests.pas"/>
+        <IsPartOfProject Value="True"/>
+      </Unit59>
+      <Unit60>
+        <Filename Value="..\src\Others\X25519HigherLevelTests.pas"/>
+        <IsPartOfProject Value="True"/>
+      </Unit60>
     </Units>
     </Units>
   </ProjectOptions>
   </ProjectOptions>
   <CompilerOptions>
   <CompilerOptions>

+ 2 - 0
CryptoLib.Tests/FreePascal.Tests/CryptoLib.lpr

@@ -62,6 +62,8 @@ uses
   CTSTests,
   CTSTests,
   X25519Tests,
   X25519Tests,
   Ed25519Tests,
   Ed25519Tests,
+  X25519HigherLevelTests,
+  Ed25519HigherLevelTests,
   ClpFixedSecureRandom,
   ClpFixedSecureRandom,
   ClpIFixedSecureRandom;
   ClpIFixedSecureRandom;
 
 

+ 9 - 1
CryptoLib.Tests/FreePascal.Tests/CryptoLibConsole.Tests.lpi

@@ -37,7 +37,7 @@
         <PackageName Value="FCL"/>
         <PackageName Value="FCL"/>
       </Item2>
       </Item2>
     </RequiredPackages>
     </RequiredPackages>
-    <Units Count="59">
+    <Units Count="61">
       <Unit0>
       <Unit0>
         <Filename Value="CryptoLibConsole.lpr"/>
         <Filename Value="CryptoLibConsole.lpr"/>
         <IsPartOfProject Value="True"/>
         <IsPartOfProject Value="True"/>
@@ -274,6 +274,14 @@
         <Filename Value="..\src\Math\EC\Rfc8032\Ed25519Tests.pas"/>
         <Filename Value="..\src\Math\EC\Rfc8032\Ed25519Tests.pas"/>
         <IsPartOfProject Value="True"/>
         <IsPartOfProject Value="True"/>
       </Unit58>
       </Unit58>
+      <Unit59>
+        <Filename Value="..\src\Others\Ed25519HigherLevelTests.pas"/>
+        <IsPartOfProject Value="True"/>
+      </Unit59>
+      <Unit60>
+        <Filename Value="..\src\Others\X25519HigherLevelTests.pas"/>
+        <IsPartOfProject Value="True"/>
+      </Unit60>
     </Units>
     </Units>
   </ProjectOptions>
   </ProjectOptions>
   <CompilerOptions>
   <CompilerOptions>

+ 2 - 0
CryptoLib.Tests/FreePascal.Tests/CryptoLibConsole.lpr

@@ -60,6 +60,8 @@ uses
   CTSTests,
   CTSTests,
   X25519Tests,
   X25519Tests,
   Ed25519Tests,
   Ed25519Tests,
+  X25519HigherLevelTests,
+  Ed25519HigherLevelTests,
   ClpFixedSecureRandom,
   ClpFixedSecureRandom,
   ClpIFixedSecureRandom;
   ClpIFixedSecureRandom;
 
 

+ 415 - 0
CryptoLib.Tests/src/Others/Ed25519HigherLevelTests.pas

@@ -0,0 +1,415 @@
+{ *********************************************************************************** }
+{ *                              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 Ed25519HigherLevelTests;
+
+interface
+
+{$IFDEF FPC}
+{$MODE DELPHI}
+{$ENDIF FPC}
+
+uses
+  SysUtils,
+{$IFDEF FPC}
+  fpcunit,
+  testregistry,
+{$ELSE}
+  TestFramework,
+{$ENDIF FPC}
+  TypInfo,
+  ClpSecureRandom,
+  ClpISecureRandom,
+  ClpISigner,
+  ClpEd25519,
+  ClpEd25519Signer,
+  ClpIEd25519Signer,
+  ClpEd25519CtxSigner,
+  ClpIEd25519CtxSigner,
+  ClpEd25519PhSigner,
+  ClpIEd25519PhSigner,
+  ClpIEd25519PrivateKeyParameters,
+  ClpIEd25519PublicKeyParameters,
+  ClpIEd25519Blake2BPrivateKeyParameters,
+  ClpIEd25519Blake2BPublicKeyParameters,
+  ClpEd25519PrivateKeyParameters,
+  ClpEd25519PublicKeyParameters,
+  ClpEd25519Blake2BPrivateKeyParameters,
+  ClpEd25519Blake2BPublicKeyParameters,
+  ClpIAsymmetricCipherKeyPair,
+  ClpAsymmetricCipherKeyPair,
+  ClpEd25519KeyPairGenerator,
+  ClpIEd25519KeyPairGenerator,
+  ClpEd25519KeyGenerationParameters,
+  ClpIEd25519KeyGenerationParameters,
+  ClpSignerUtilities,
+  ClpArrayUtils,
+  ClpEncoders,
+  ClpCryptoLibTypes;
+
+type
+
+  TCryptoLibTestCase = class abstract(TTestCase)
+
+  end;
+
+type
+
+  /// <summary>
+  /// test vectors gotten from <see href="https://github.com/warner/python-ed25519" />
+  /// and <see href="https://github.com/Matoking/python-ed25519-blake2b" />
+  /// </summary>
+  TTestEd25519HigherLevel = class(TCryptoLibTestCase)
+  private
+  var
+    FRandom: ISecureRandom;
+
+  type
+{$SCOPEDENUMS ON}
+    TEd25519SignerAlgorithm = (Ed25519, Ed25519Blake2B);
+{$SCOPEDENUMS OFF}
+  function CreateSigner(algorithm: TEd25519.TEd25519Algorithm;
+    const context: TCryptoLibByteArray): ISigner;
+
+  function CreateCustomSigner(const algorithm: TEd25519SignerAlgorithm)
+    : ISigner;
+
+  function ReconstructEd25519KeyPair(algorithm: TEd25519SignerAlgorithm;
+    const sk, pk: TCryptoLibByteArray): IAsymmetricCipherKeyPair;
+
+  function RandomContext(length: Int32): TCryptoLibByteArray;
+
+  procedure DoTestConsistency(algorithm: TEd25519.TEd25519Algorithm;
+    const context: TCryptoLibByteArray);
+
+  procedure DoEd25519Test(id: Int32; algorithm: TEd25519SignerAlgorithm;
+    const sk, pk, msg, sig: String);
+  protected
+    procedure SetUp; override;
+    procedure TearDown; override;
+  published
+    procedure TestConsistency();
+    procedure TestEd25519();
+
+  end;
+
+implementation
+
+{ TTestEd25519HigherLevel }
+
+function TTestEd25519HigherLevel.CreateCustomSigner(const algorithm
+  : TEd25519SignerAlgorithm): ISigner;
+var
+  algorithmName: String;
+begin
+  algorithmName := GetEnumName(TypeInfo(TEd25519SignerAlgorithm),
+    Ord(algorithm));
+  Result := TSignerUtilities.GetSigner(algorithmName);
+end;
+
+function TTestEd25519HigherLevel.CreateSigner
+  (algorithm: TEd25519.TEd25519Algorithm;
+  const context: TCryptoLibByteArray): ISigner;
+begin
+  case algorithm of
+    TEd25519.TEd25519Algorithm.Ed25519:
+      Result := TEd25519Signer.Create() as IEd25519Signer;
+    TEd25519.TEd25519Algorithm.Ed25519ctx:
+      Result := TEd25519CtxSigner.Create(context) as IEd25519CtxSigner;
+    TEd25519.TEd25519Algorithm.Ed25519ph:
+      Result := TEd25519PhSigner.Create(context) as IEd25519PhSigner;
+  else
+    begin
+      raise EArgumentCryptoLibException.Create('algorithm');
+    end;
+  end;
+end;
+
+procedure TTestEd25519HigherLevel.DoEd25519Test(id: Int32;
+  algorithm: TEd25519SignerAlgorithm; const sk, pk, msg, sig: String);
+var
+  LSk, LPk, LMsg, LSig, LResultSig, LKey: TCryptoLibByteArray;
+  LKeyPair: IAsymmetricCipherKeyPair;
+  LIsVerified: Boolean;
+  LSigner: ISigner;
+begin
+  LSk := THex.Decode(sk);
+  LPk := THex.Decode(pk);
+  LMsg := THex.Decode(msg);
+  LSig := THex.Decode(sig);
+  LKeyPair := ReconstructEd25519KeyPair(algorithm, LSk, LPk);
+  LSigner := CreateCustomSigner(algorithm);
+
+  case algorithm of
+    TTestEd25519HigherLevel.TEd25519SignerAlgorithm.Ed25519:
+      begin
+        LKey := (LKeyPair.Private as IEd25519PrivateKeyParameters).GetEncoded();
+        if not TArrayUtils.AreEqual(LKey, System.Copy(LSk, 0, 32)) then
+        begin
+          Fail(Format
+            ('Test with Id %d Failed on PrivateKey Reconstruction Comparison, Expected "%s" but got "%s"',
+            [id, THex.Encode(LSk), THex.Encode(LKey)]));
+        end;
+
+        LKey := (LKeyPair.Public as IEd25519PublicKeyParameters).GetEncoded();
+        if not TArrayUtils.AreEqual(LKey, System.Copy(LPk, 0, 64)) then
+        begin
+          Fail(Format
+            ('Test with Id %d Failed on PublicKey Reconstruction Comparison, Expected "%s" but got "%s"',
+            [id, THex.Encode(LPk), THex.Encode(LKey)]));
+        end;
+      end;
+    TTestEd25519HigherLevel.TEd25519SignerAlgorithm.Ed25519Blake2B:
+      begin
+        LKey := (LKeyPair.Private as IEd25519Blake2BPrivateKeyParameters)
+          .GetEncoded();
+        if not TArrayUtils.AreEqual(LKey, System.Copy(LSk, 0, 32)) then
+        begin
+          Fail(Format
+            ('Test with Id %d Failed on PrivateKey Reconstruction Comparison, Expected "%s" but got "%s"',
+            [id, THex.Encode(LSk), THex.Encode(LKey)]));
+        end;
+
+        LKey := (LKeyPair.Public as IEd25519Blake2BPublicKeyParameters)
+          .GetEncoded();
+        if not TArrayUtils.AreEqual(LKey, System.Copy(LPk, 0, 64)) then
+        begin
+          Fail(Format
+            ('Test with Id %d Failed on PublicKey Reconstruction Comparison, Expected "%s" but got "%s"',
+            [id, THex.Encode(LPk), THex.Encode(LKey)]));
+        end;
+      end
+  else
+    begin
+      raise EArgumentCryptoLibException.Create('algorithm');
+    end;
+
+  end;
+
+  LSigner.Init(True, LKeyPair.Private);
+  LSigner.BlockUpdate(LMsg, 0, System.length(LMsg));
+  LResultSig := LSigner.GenerateSignature();
+
+  if not TArrayUtils.AreEqual(LResultSig, System.Copy(LSig, 0, 64)) then
+  begin
+    Fail(Format
+      ('Test with Id %d Failed on Signature Comparison, Expected "%s" but got "%s"',
+      [id, THex.Encode(LSig), THex.Encode(LResultSig)]));
+  end;
+
+  LSigner.Init(False, LKeyPair.Public);
+  LSigner.BlockUpdate(LMsg, 0, System.length(LMsg));
+  LIsVerified := LSigner.VerifySignature(LResultSig);
+
+  if not LIsVerified then
+  begin
+    Fail(Format('Test with Id %d Failed on Verifying "%s" Signature',
+      [id, THex.Encode(LResultSig)]));
+  end;
+end;
+
+procedure TTestEd25519HigherLevel.DoTestConsistency
+  (algorithm: TEd25519.TEd25519Algorithm; const context: TCryptoLibByteArray);
+var
+  kpg: IEd25519KeyPairGenerator;
+  kp: IAsymmetricCipherKeyPair;
+  privateKey: IEd25519PrivateKeyParameters;
+  publicKey: IEd25519PublicKeyParameters;
+  msg, signature: TCryptoLibByteArray;
+  Signer, verifier: ISigner;
+  shouldVerify, shouldNotVerify: Boolean;
+  algorithmName: String;
+begin
+  kpg := TEd25519KeyPairGenerator.Create();
+  kpg.Init(TEd25519KeyGenerationParameters.Create(FRandom)
+    as IEd25519KeyGenerationParameters);
+
+  kp := kpg.GenerateKeyPair();
+  privateKey := kp.Private as IEd25519PrivateKeyParameters;
+  publicKey := kp.Public as IEd25519PublicKeyParameters;
+
+  System.SetLength(msg, FRandom.NextInt32 and 255);
+  FRandom.NextBytes(msg);
+
+  Signer := CreateSigner(algorithm, context);
+  Signer.Init(True, privateKey);
+  Signer.BlockUpdate(msg, 0, System.length(msg));
+  signature := Signer.GenerateSignature();
+
+  verifier := CreateSigner(algorithm, context);
+  verifier.Init(False, publicKey);
+  verifier.BlockUpdate(msg, 0, System.length(msg));
+  shouldVerify := verifier.VerifySignature(signature);
+
+  algorithmName := GetEnumName(TypeInfo(TEd25519.TEd25519Algorithm),
+    Ord(algorithm));
+
+  if (not shouldVerify) then
+  begin
+    Fail(Format('Ed25519 (%s) signature failed to verify', [algorithmName]));
+  end;
+
+  signature[FRandom.Next() mod System.length(signature)] :=
+    signature[FRandom.Next() mod System.length(signature)
+    ] xor Byte(1 shl (FRandom.NextInt32 and 7));
+
+  verifier.Init(False, publicKey);
+  verifier.BlockUpdate(msg, 0, System.length(msg));
+  shouldNotVerify := verifier.VerifySignature(signature);
+
+  if (shouldNotVerify) then
+  begin
+    Fail(Format('Ed25519 (%s) bad signature incorrectly verified',
+      [algorithmName]));
+  end;
+end;
+
+function TTestEd25519HigherLevel.RandomContext(length: Int32)
+  : TCryptoLibByteArray;
+begin
+  System.SetLength(Result, length);
+  FRandom.NextBytes(Result);
+end;
+
+function TTestEd25519HigherLevel.ReconstructEd25519KeyPair
+  (algorithm: TEd25519SignerAlgorithm; const sk, pk: TCryptoLibByteArray)
+  : IAsymmetricCipherKeyPair;
+begin
+  case algorithm of
+    TTestEd25519HigherLevel.TEd25519SignerAlgorithm.Ed25519:
+      begin
+        Result := TAsymmetricCipherKeyPair.Create
+          (TEd25519PublicKeyParameters.Create(pk, 0)
+          as IEd25519PublicKeyParameters,
+          TEd25519PrivateKeyParameters.Create(sk, 0)
+          as IEd25519PrivateKeyParameters);
+      end;
+    TTestEd25519HigherLevel.TEd25519SignerAlgorithm.Ed25519Blake2B:
+      begin
+        Result := TAsymmetricCipherKeyPair.Create
+          (TEd25519Blake2BPublicKeyParameters.Create(pk, 0)
+          as IEd25519Blake2BPublicKeyParameters,
+          TEd25519Blake2BPrivateKeyParameters.Create(sk, 0)
+          as IEd25519Blake2BPrivateKeyParameters);
+      end
+  else
+    begin
+      raise EArgumentCryptoLibException.Create('algorithm');
+    end;
+  end;
+end;
+
+procedure TTestEd25519HigherLevel.SetUp;
+begin
+  inherited;
+  FRandom := TSecureRandom.Create();
+end;
+
+procedure TTestEd25519HigherLevel.TearDown;
+begin
+  inherited;
+
+end;
+
+procedure TTestEd25519HigherLevel.TestConsistency;
+var
+  i: Int32;
+  context: TCryptoLibByteArray;
+begin
+  i := 0;
+  while i < 10 do
+  begin
+    DoTestConsistency(TEd25519.TEd25519Algorithm.Ed25519, Nil);
+
+    context := RandomContext(FRandom.NextInt32 and 255);
+    DoTestConsistency(TEd25519.TEd25519Algorithm.Ed25519ctx, context);
+    DoTestConsistency(TEd25519.TEd25519Algorithm.Ed25519ph, context);
+    System.Inc(i);
+  end;
+end;
+
+procedure TTestEd25519HigherLevel.TestEd25519;
+begin
+
+  // TEd25519SignerAlgorithm.Ed25519
+
+  DoEd25519Test(1, TEd25519SignerAlgorithm.Ed25519,
+    '9d61b19deffd5a60ba844af492ec2cc44449c5697b326919703bac031cae7f60d75a980182b10ab7d54bfed3c964073a0ee172f3daa62325af021a68f707511a',
+    'd75a980182b10ab7d54bfed3c964073a0ee172f3daa62325af021a68f707511a', '',
+    'e5564300c360ac729086e2cc806e828a84877f1eb8e5d974d873e065224901555fb8821590a33bacc61e39701cf9b46bd25bf5f0595bbe24655141438e7a100b');
+
+  DoEd25519Test(2, TEd25519SignerAlgorithm.Ed25519,
+    '4ccd089b28ff96da9db6c346ec114e0f5b8a319f35aba624da8cf6ed4fb8a6fb3d4017c3e843895a92b70aa74d1b7ebc9c982ccf2ec4968cc0cd55f12af4660c',
+    '3d4017c3e843895a92b70aa74d1b7ebc9c982ccf2ec4968cc0cd55f12af4660c', '72',
+    '92a009a9f0d4cab8720e820b5f642540a2b27b5416503f8fb3762223ebdb69da085ac1e43e15996e458f3613d0f11d8c387b2eaeb4302aeeb00d291612bb0c0072');
+
+  DoEd25519Test(3, TEd25519SignerAlgorithm.Ed25519,
+    'c5aa8df43f9f837bedb7442f31dcb7b166d38535076f094b85ce3a2e0b4458f7fc51cd8e6218a1a38da47ed00230f0580816ed13ba3303ac5deb911548908025',
+    'fc51cd8e6218a1a38da47ed00230f0580816ed13ba3303ac5deb911548908025', 'af82',
+    '6291d657deec24024827e69c3abe01a30ce548a284743a445e3680d7db5ac3ac18ff9b538d16f290ae67f760984dc6594a7c15e9716ed28dc027beceea1ec40aaf82');
+
+  DoEd25519Test(4, TEd25519SignerAlgorithm.Ed25519,
+    '0d4a05b07352a5436e180356da0ae6efa0345ff7fb1572575772e8005ed978e9e61a185bcef2613a6c7cb79763ce945d3b245d76114dd440bcf5f2dc1aa57057',
+    'e61a185bcef2613a6c7cb79763ce945d3b245d76114dd440bcf5f2dc1aa57057',
+    'cbc77b', 'd9868d52c2bebce5f3fa5a79891970f309cb6591e3e1702a70276fa97c24b3a8e58606c38c9758529da50ee31b8219cba45271c689afa60b0ea26c99db19b00ccbc77b');
+
+  DoEd25519Test(5, TEd25519SignerAlgorithm.Ed25519,
+    '6df9340c138cc188b5fe4464ebaa3f7fc206a2d55c3434707e74c9fc04e20ebbc0dac102c4533186e25dc43128472353eaabdb878b152aeb8e001f92d90233a7',
+    'c0dac102c4533186e25dc43128472353eaabdb878b152aeb8e001f92d90233a7',
+    '5f4c8989',
+    '124f6fc6b0d100842769e71bd530664d888df8507df6c56dedfdb509aeb93416e26b918d38aa06305df3095697c18b2aa832eaa52edc0ae49fbae5a85e150c075f4c8989');
+
+  // TEd25519SignerAlgorithm.Ed25519Blake2B
+
+  DoEd25519Test(6, TEd25519SignerAlgorithm.Ed25519Blake2B,
+    '9d61b19deffd5a60ba844af492ec2cc44449c5697b326919703bac031cae7f60',
+    '78e65bf30f893d32fc57ef051c341bdede242544fc2a2112f0fa2c7afdebc02f', '',
+    '99a523bd4616c8161144d6a99d3c32400cb4a326f4d79e307340f6afa11750a0085d7d84626bc9e4b153fc0e396d15ce44c39bae4533804db1fe5b52f2b1b805');
+
+  DoEd25519Test(7, TEd25519SignerAlgorithm.Ed25519Blake2B,
+    '4ccd089b28ff96da9db6c346ec114e0f5b8a319f35aba624da8cf6ed4fb8a6fb',
+    '5e71392d91e6a58fedeb0850364f56cd158a60447557d7890389c9b3d4576d4d', '72',
+    '6da75e15b5707f4de5a153c48a5d839fb85074c38aeb6285977f03a13977597f976069fdb903f183474aaa5ed0cfe878ba8ef868c5e47ca3f96ccfb3a89b2a0672');
+
+  DoEd25519Test(8, TEd25519SignerAlgorithm.Ed25519Blake2B,
+    'c5aa8df43f9f837bedb7442f31dcb7b166d38535076f094b85ce3a2e0b4458f7',
+    '8d53ca70f0eab23b9178345785fcdb69ed6723f8148f7e339e88653700b718da', 'af82',
+    '7cc3c13852bd12abf3ce4ca8ca2836cbf86da96c4634c50df3fb80dc809e29db0e109c361353407c1236a904f636868aa33977a99d3f844598db1538b4295203af82');
+
+  DoEd25519Test(9, TEd25519SignerAlgorithm.Ed25519Blake2B,
+    '0d4a05b07352a5436e180356da0ae6efa0345ff7fb1572575772e8005ed978e9',
+    '0c6989f1abebe219db9d1e2cb8b0c602b191828ef7238f8e6dbff8a506802c09',
+    'cbc77b', '7fb2c11db736d16ebd07a653463dc8739d3315f89f61a66715e41528cb32b7689393f5af8a66c9c7336e209e6b187259fe266f7941a435fecb8cd7a7fc759400cbc77b');
+
+  DoEd25519Test(10, TEd25519SignerAlgorithm.Ed25519Blake2B,
+    '6df9340c138cc188b5fe4464ebaa3f7fc206a2d55c3434707e74c9fc04e20ebb',
+    'ce99a0d41b2c1bdf593cfe41b0bf38f40ab77a804a71138188cc879b59869d90',
+    '5f4c8989',
+    'e09625735d184975409020659f3c0b07f036a19a7e7aa2100964cef577806e26125d1437577d2d3286c29df871797cac3fc0cdecbbeca616030cfcc6711db6065f4c8989');
+end;
+
+initialization
+
+// Register any test cases with the test runner
+
+{$IFDEF FPC}
+// RegisterTest(TTestEd25519HigherLevel);
+{$ELSE}
+  RegisterTest(TTestEd25519HigherLevel.Suite);
+{$ENDIF FPC}
+
+end.

+ 136 - 0
CryptoLib.Tests/src/Others/X25519HigherLevelTests.pas

@@ -0,0 +1,136 @@
+{ *********************************************************************************** }
+{ *                              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 X25519HigherLevelTests;
+
+interface
+
+{$IFDEF FPC}
+{$MODE DELPHI}
+{$ENDIF FPC}
+
+uses
+{$IFDEF FPC}
+  fpcunit,
+  testregistry,
+{$ELSE}
+  TestFramework,
+{$ENDIF FPC}
+  ClpSecureRandom,
+  ClpISecureRandom,
+  ClpArrayUtils,
+  ClpX25519Agreement,
+  ClpIX25519Agreement,
+  ClpIAsymmetricCipherKeyPair,
+  ClpX25519KeyPairGenerator,
+  ClpIX25519KeyPairGenerator,
+  ClpX25519KeyGenerationParameters,
+  ClpIX25519KeyGenerationParameters,
+  ClpIAsymmetricCipherKeyPairGenerator,
+  ClpCryptoLibTypes;
+
+type
+
+  TCryptoLibTestCase = class abstract(TTestCase)
+
+  end;
+
+type
+
+  TTestX25519HigherLevel = class(TCryptoLibTestCase)
+  private
+  var
+    FRandom: ISecureRandom;
+
+    procedure DoTestAgreement();
+  protected
+    procedure SetUp; override;
+    procedure TearDown; override;
+  published
+    procedure TestAgreement();
+
+  end;
+
+implementation
+
+{ TTestX25519HigherLevel }
+
+procedure TTestX25519HigherLevel.DoTestAgreement;
+var
+  kpGen: IAsymmetricCipherKeyPairGenerator;
+  kpA, kpB: IAsymmetricCipherKeyPair;
+  agreeA, agreeB: IX25519Agreement;
+  secretA, secretB: TCryptoLibByteArray;
+begin
+  kpGen := TX25519KeyPairGenerator.Create() as IX25519KeyPairGenerator;
+  kpGen.Init(TX25519KeyGenerationParameters.Create(FRandom)
+    as IX25519KeyGenerationParameters);
+
+  kpA := kpGen.GenerateKeyPair();
+  kpB := kpGen.GenerateKeyPair();
+
+  agreeA := TX25519Agreement.Create();
+  agreeA.Init(kpA.Private);
+  System.SetLength(secretA, agreeA.AgreementSize);
+  agreeA.CalculateAgreement(kpB.Public, secretA, 0);
+
+  agreeB := TX25519Agreement.Create();
+  agreeB.Init(kpB.Private);
+  System.SetLength(secretB, agreeB.AgreementSize);
+  agreeB.CalculateAgreement(kpA.Public, secretB, 0);
+
+  if (not TArrayUtils.AreEqual(secretA, secretB)) then
+  begin
+    Fail('X25519 agreement failed');
+  end;
+end;
+
+procedure TTestX25519HigherLevel.SetUp;
+begin
+  inherited;
+  FRandom := TSecureRandom.Create();
+end;
+
+procedure TTestX25519HigherLevel.TearDown;
+begin
+  inherited;
+
+end;
+
+procedure TTestX25519HigherLevel.TestAgreement;
+var
+  i: Int32;
+begin
+  i := 0;
+  while i < 10 do
+  begin
+    DoTestAgreement();
+    System.Inc(i);
+  end;
+end;
+
+initialization
+
+// Register any test cases with the test runner
+
+{$IFDEF FPC}
+// RegisterTest(TTestX25519HigherLevel);
+{$ELSE}
+  RegisterTest(TTestX25519HigherLevel.Suite);
+{$ENDIF FPC}
+
+end.

+ 69 - 0
CryptoLib/src/Security/ClpSignerUtilities.pas

@@ -36,12 +36,25 @@ uses
   ClpOiwObjectIdentifiers,
   ClpOiwObjectIdentifiers,
   ClpNistObjectIdentifiers,
   ClpNistObjectIdentifiers,
   ClpCryptoProObjectIdentifiers,
   ClpCryptoProObjectIdentifiers,
+  ClpEdECObjectIdentifiers,
   ClpParameterUtilities,
   ClpParameterUtilities,
   ClpIAsymmetricKeyParameter,
   ClpIAsymmetricKeyParameter,
   ClpDsaSigner,
   ClpDsaSigner,
   ClpIDsaSigner,
   ClpIDsaSigner,
   ClpECDsaSigner,
   ClpECDsaSigner,
   ClpIECDsaSigner,
   ClpIECDsaSigner,
+  ClpEd25519Signer,
+  ClpIEd25519Signer,
+  ClpEd25519CtxSigner,
+  ClpIEd25519CtxSigner,
+  ClpEd25519PhSigner,
+  ClpIEd25519PhSigner,
+  ClpEd25519Blake2BSigner,
+  ClpIEd25519Blake2BSigner,
+  ClpEd25519CtxBlake2BSigner,
+  ClpIEd25519CtxBlake2BSigner,
+  ClpEd25519PhBlake2BSigner,
+  ClpIEd25519PhBlake2BSigner,
   ClpISigner,
   ClpISigner,
   ClpISecureRandom,
   ClpISecureRandom,
   ClpIAsn1Objects,
   ClpIAsn1Objects,
@@ -126,6 +139,7 @@ begin
   TCryptoProObjectIdentifiers.Boot;
   TCryptoProObjectIdentifiers.Boot;
   TEacObjectIdentifiers.Boot;
   TEacObjectIdentifiers.Boot;
   TBsiObjectIdentifiers.Boot;
   TBsiObjectIdentifiers.Boot;
+  TEdECObjectIdentifiers.Boot;
 
 
   Falgorithms.Add('NONEWITHDSA', 'NONEwithDSA');
   Falgorithms.Add('NONEWITHDSA', 'NONEwithDSA');
   Falgorithms.Add('DSAWITHNONE', 'NONEwithDSA');
   Falgorithms.Add('DSAWITHNONE', 'NONEwithDSA');
@@ -340,6 +354,17 @@ begin
   // Falgorithms.Add(TCryptoProObjectIdentifiers.GostR3411x94WithGostR3410x2001.id,
   // Falgorithms.Add(TCryptoProObjectIdentifiers.GostR3411x94WithGostR3410x2001.id,
   // 'ECGOST3410');
   // 'ECGOST3410');
 
 
+  // ED25519
+  Falgorithms.Add('ED25519', 'Ed25519');
+  Falgorithms.Add(TEdECObjectIdentifiers.id_Ed25519.id, 'Ed25519');
+  Falgorithms.Add('ED25519CTX', 'Ed25519ctx');
+  Falgorithms.Add('ED25519PH', 'Ed25519ph');
+
+  // ED25519Blake2B
+  Falgorithms.Add('ED25519BLAKE2B', 'Ed25519Blake2B');
+  Falgorithms.Add('ED25519BLAKE2BCTX', 'Ed25519Blake2Bctx');
+  Falgorithms.Add('ED25519BLAKE2BPH', 'Ed25519Blake2Bph');
+
   // ECSCHNORR SIPA
   // ECSCHNORR SIPA
 
 
   Falgorithms.Add('SHA1/ECSCHNORR/SIPA', 'SHA-1withECSCHNORRSIPA');
   Falgorithms.Add('SHA1/ECSCHNORR/SIPA', 'SHA-1withECSCHNORRSIPA');
@@ -409,6 +434,8 @@ begin
   //
   //
   // Foids.Add('ECGOST3410',
   // Foids.Add('ECGOST3410',
   // TCryptoProObjectIdentifiers.GostR3411x94WithGostR3410x2001);
   // TCryptoProObjectIdentifiers.GostR3411x94WithGostR3410x2001);
+
+  Foids.Add('Ed25519', TEdECObjectIdentifiers.id_Ed25519);
 end;
 end;
 
 
 class constructor TSignerUtilities.CreateSignerUtilities;
 class constructor TSignerUtilities.CreateSignerUtilities;
@@ -475,6 +502,48 @@ begin
     mechanism := algorithm;
     mechanism := algorithm;
   end;
   end;
 
 
+  if (TStringUtils.BeginsWith(mechanism, 'Ed25519', True)) then
+  begin
+    if TStringUtils.EndsWith(mechanism, 'Blake2B', True) then
+    begin
+      if (mechanism = 'Ed25519Blake2B') then
+      begin
+        Result := TEd25519Blake2BSigner.Create() as IEd25519Blake2BSigner;
+        Exit;
+      end;
+      if (mechanism = 'Ed25519ctxBlake2B') then
+      begin
+        Result := TEd25519ctxBlake2BSigner.Create(Nil)
+          as IEd25519ctxBlake2BSigner;
+        Exit;
+      end;
+      if (mechanism = 'Ed25519phBlake2B') then
+      begin
+        Result := TEd25519phBlake2BSigner.Create(Nil)
+          as IEd25519phBlake2BSigner;
+        Exit;
+      end;
+    end
+    else
+    begin
+      if (mechanism = 'Ed25519') then
+      begin
+        Result := TEd25519Signer.Create() as IEd25519Signer;
+        Exit;
+      end;
+      if (mechanism = 'Ed25519ctx') then
+      begin
+        Result := TEd25519ctxSigner.Create(Nil) as IEd25519ctxSigner;
+        Exit;
+      end;
+      if (mechanism = 'Ed25519ph') then
+      begin
+        Result := TEd25519phSigner.Create(Nil) as IEd25519phSigner;
+        Exit;
+      end;
+    end;
+  end;
+
   if TStringUtils.EndsWith(mechanism, 'withDSA', True) then
   if TStringUtils.EndsWith(mechanism, 'withDSA', True) then
   begin
   begin
     DigestName := System.Copy(mechanism, 1, TStringUtils.LastIndexOf(mechanism,
     DigestName := System.Copy(mechanism, 1, TStringUtils.LastIndexOf(mechanism,

+ 0 - 2
CryptoLib/src/Utils/ClpCryptoLibTypes.pas

@@ -222,8 +222,6 @@ type
   TCryptoLibCustomByteArrayBuffer = TCryptoLibCustomArrayBuffer<Byte>;
   TCryptoLibCustomByteArrayBuffer = TCryptoLibCustomArrayBuffer<Byte>;
 
 
 const
 const
-  EmptyBytesNotNil: TCryptoLibCustomByteArrayBuffer = (FData: Nil; FLength: 0;
-    FIsNil: False);
   EmptyBytesNil: TCryptoLibCustomByteArrayBuffer = (FData: Nil; FLength: 0;
   EmptyBytesNil: TCryptoLibCustomByteArrayBuffer = (FData: Nil; FLength: 0;
     FIsNil: True);
     FIsNil: True);