ECAlgorithmsTests.pas 8.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344
  1. { *********************************************************************************** }
  2. { * CryptoLib Library * }
  3. { * Copyright (c) 2018 - 20XX Ugochukwu Mmaduekwe * }
  4. { * Github Repository <https://github.com/Xor-el> * }
  5. { * Distributed under the MIT software license, see the accompanying file LICENSE * }
  6. { * or visit http://www.opensource.org/licenses/mit-license.php. * }
  7. { * Acknowledgements: * }
  8. { * * }
  9. { * Thanks to Sphere 10 Software (http://www.sphere10.com/) for sponsoring * }
  10. { * development of this library * }
  11. { * ******************************************************************************* * }
  12. (* &&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& *)
  13. unit ECAlgorithmsTests;
  14. interface
  15. {$IFDEF FPC}
  16. {$MODE DELPHI}
  17. {$WARNINGS OFF}
  18. {$ENDIF FPC}
  19. uses
  20. Classes,
  21. SysUtils,
  22. {$IFDEF FPC}
  23. fpcunit,
  24. testregistry,
  25. {$ELSE}
  26. TestFramework,
  27. {$ENDIF FPC}
  28. Generics.Collections,
  29. ClpSecureRandom,
  30. ClpISecureRandom,
  31. ClpECCurve,
  32. ClpIECInterface,
  33. ClpBigInteger,
  34. ClpECNamedCurveTable,
  35. ClpECAlgorithms,
  36. ClpX9ECParameters,
  37. ClpIX9ECParameters,
  38. ClpCryptoLibTypes;
  39. type
  40. TCryptoLibTestCase = class abstract(TTestCase)
  41. end;
  42. type
  43. TTestECAlgorithms = class(TCryptoLibTestCase)
  44. private
  45. class var
  46. FRandom: ISecureRandom;
  47. const
  48. Scale = Int32(4);
  49. procedure DoTestSumOfMultiplies(const x9: IX9ECParameters);
  50. procedure DoTestSumOfTwoMultiplies(const x9: IX9ECParameters);
  51. procedure AssertPointsEqual(const msg: String; const a, b: IECPoint);
  52. function CopyPoints(ps: TCryptoLibGenericArray<IECPoint>; len: Int32)
  53. : TCryptoLibGenericArray<IECPoint>;
  54. function CopyScalars(ks: TCryptoLibGenericArray<TBigInteger>; len: Int32)
  55. : TCryptoLibGenericArray<TBigInteger>;
  56. function GetRandomPoint(const x9: IX9ECParameters): IECPoint;
  57. function GetRandomScalar(const x9: IX9ECParameters): TBigInteger;
  58. function GetTestCurves(): TCryptoLibGenericArray<IX9ECParameters>;
  59. procedure AddTestCurves(x9s: TList<IX9ECParameters>;
  60. const x9: IX9ECParameters);
  61. protected
  62. procedure SetUp; override;
  63. procedure TearDown; override;
  64. published
  65. procedure TestSumOfMultiplies;
  66. procedure TestSumOfMultipliesComplete;
  67. procedure TestSumOfTwoMultiplies;
  68. procedure TestSumOfTwoMultipliesComplete;
  69. end;
  70. implementation
  71. { TTestECAlgorithms }
  72. procedure TTestECAlgorithms.AddTestCurves(x9s: TList<IX9ECParameters>;
  73. const x9: IX9ECParameters);
  74. var
  75. curve, c: IECCurve;
  76. point: IECPoint;
  77. params: IX9ECParameters;
  78. coord, i: Int32;
  79. coords: TCryptoLibInt32Array;
  80. begin
  81. curve := x9.curve;
  82. coords := TECCurve.GetAllCoordinateSystems();
  83. for i := 0 to System.Pred(System.Length(coords)) do
  84. begin
  85. coord := coords[i];
  86. if (curve.CoordinateSystem = coord) then
  87. begin
  88. x9s.Add(x9);
  89. end
  90. else if (curve.SupportsCoordinateSystem(coord)) then
  91. begin
  92. c := curve.Configure().SetCoordinateSystem(coord).CreateCurve();
  93. point := c.ImportPoint(x9.G);
  94. params := TX9ECParameters.Create(c, point, x9.N, x9.H);
  95. x9s.Add(params);
  96. end;
  97. end;
  98. end;
  99. procedure TTestECAlgorithms.AssertPointsEqual(const msg: String;
  100. const a, b: IECPoint);
  101. begin
  102. CheckEquals(True, a.Equals(b), msg);
  103. end;
  104. function TTestECAlgorithms.CopyPoints(ps: TCryptoLibGenericArray<IECPoint>;
  105. len: Int32): TCryptoLibGenericArray<IECPoint>;
  106. begin
  107. System.SetLength(Result, len);
  108. Result := System.Copy(ps, 0, len);
  109. end;
  110. function TTestECAlgorithms.CopyScalars(ks: TCryptoLibGenericArray<TBigInteger>;
  111. len: Int32): TCryptoLibGenericArray<TBigInteger>;
  112. begin
  113. System.SetLength(Result, len);
  114. Result := System.Copy(ks, 0, len);
  115. end;
  116. procedure TTestECAlgorithms.DoTestSumOfMultiplies(const x9: IX9ECParameters);
  117. var
  118. points, results: TCryptoLibGenericArray<IECPoint>;
  119. scalars: TCryptoLibGenericArray<TBigInteger>;
  120. i: Int32;
  121. u, v: IECPoint;
  122. begin
  123. System.SetLength(points, Scale);
  124. System.SetLength(scalars, Scale);
  125. for i := 0 to System.Pred(Scale) do
  126. begin
  127. points[i] := GetRandomPoint(x9);
  128. scalars[i] := GetRandomScalar(x9);
  129. end;
  130. u := x9.curve.Infinity;
  131. for i := 0 to System.Pred(Scale) do
  132. begin
  133. u := u.Add(points[i].Multiply(scalars[i]));
  134. v := TECAlgorithms.SumOfMultiplies(CopyPoints(points, i + 1),
  135. CopyScalars(scalars, i + 1));
  136. results := TCryptoLibGenericArray<IECPoint>.Create(u, v);
  137. x9.curve.NormalizeAll(results);
  138. AssertPointsEqual('ECAlgorithms.SumOfMultiplies is incorrect', results[0],
  139. results[1]);
  140. end;
  141. end;
  142. procedure TTestECAlgorithms.DoTestSumOfTwoMultiplies(const x9: IX9ECParameters);
  143. var
  144. i: Int32;
  145. p, q, u, v, w: IECPoint;
  146. a, b: TBigInteger;
  147. results: TCryptoLibGenericArray<IECPoint>;
  148. begin
  149. p := GetRandomPoint(x9);
  150. a := GetRandomScalar(x9);
  151. i := 0;
  152. while i < Scale do
  153. begin
  154. q := GetRandomPoint(x9);
  155. b := GetRandomScalar(x9);
  156. u := p.Multiply(a).Add(q.Multiply(b));
  157. v := TECAlgorithms.ShamirsTrick(p, a, q, b);
  158. w := TECAlgorithms.SumOfTwoMultiplies(p, a, q, b);
  159. results := TCryptoLibGenericArray<IECPoint>.Create(u, v, w);
  160. x9.curve.NormalizeAll(results);
  161. AssertPointsEqual('TECAlgorithms.ShamirsTrick is incorrect', results[0],
  162. results[1]);
  163. AssertPointsEqual('TECAlgorithms.SumOfTwoMultiplies is incorrect',
  164. results[0], results[2]);
  165. p := q;
  166. a := b;
  167. System.Inc(i);
  168. end;
  169. end;
  170. function TTestECAlgorithms.GetRandomPoint(const x9: IX9ECParameters): IECPoint;
  171. begin
  172. Result := x9.G.Multiply(GetRandomScalar(x9));
  173. end;
  174. function TTestECAlgorithms.GetRandomScalar(const x9: IX9ECParameters)
  175. : TBigInteger;
  176. begin
  177. Result := TBigInteger.Create(x9.N.BitLength, FRandom);
  178. end;
  179. function TTestECAlgorithms.GetTestCurves
  180. : TCryptoLibGenericArray<IX9ECParameters>;
  181. var
  182. name: string;
  183. x9s: TList<IX9ECParameters>;
  184. tempList: TList<String>;
  185. tempDict: TDictionary<String, String>;
  186. names: TCryptoLibStringArray;
  187. x9: IX9ECParameters;
  188. s: string;
  189. begin
  190. x9s := TList<IX9ECParameters>.Create();
  191. try
  192. tempList := TList<String>.Create();
  193. try
  194. tempList.AddRange(TECNamedCurveTable.names); // get all collections
  195. // tempList.AddRange(TCustomNamedCurves.Names);
  196. tempDict := TDictionary<String, String>.Create();
  197. try
  198. for s in tempList do
  199. begin
  200. if not tempDict.ContainsKey(s) then // make sure they are unique
  201. begin
  202. tempDict.Add(s, s);
  203. end;
  204. end;
  205. names := tempDict.Values.ToArray; // save unique instances to array
  206. finally
  207. tempDict.Free;
  208. end;
  209. finally
  210. tempList.Free;
  211. end;
  212. for name in names do
  213. begin
  214. x9 := TECNamedCurveTable.GetByName(name);
  215. if (x9 <> Nil) then
  216. begin
  217. AddTestCurves(x9s, x9);
  218. end;
  219. // x9 := TCustomNamedCurves.GetByName(name);
  220. // if (x9 <> Nil) then
  221. // begin
  222. // AddTestCurves(x9s, x9);
  223. // end;
  224. end;
  225. Result := x9s.ToArray;
  226. finally
  227. x9s.Free;
  228. end;
  229. end;
  230. procedure TTestECAlgorithms.SetUp;
  231. begin
  232. FRandom := TSecureRandom.Create();
  233. end;
  234. procedure TTestECAlgorithms.TearDown;
  235. begin
  236. inherited;
  237. end;
  238. procedure TTestECAlgorithms.TestSumOfMultiplies;
  239. var
  240. x9: IX9ECParameters;
  241. begin
  242. // x9 := TCustomNamedCurves.GetByName('secp256r1'); // original
  243. x9 := TECNamedCurveTable.GetByName('secp256k1');
  244. CheckNotNull(x9);
  245. DoTestSumOfMultiplies(x9);
  246. end;
  247. procedure TTestECAlgorithms.TestSumOfMultipliesComplete;
  248. var
  249. x9: IX9ECParameters;
  250. begin
  251. for x9 in GetTestCurves() do
  252. begin
  253. DoTestSumOfMultiplies(x9);
  254. end;
  255. end;
  256. procedure TTestECAlgorithms.TestSumOfTwoMultiplies;
  257. var
  258. x9: IX9ECParameters;
  259. begin
  260. // x9 := TCustomNamedCurves.GetByName('secp256r1'); // original
  261. x9 := TECNamedCurveTable.GetByName('secp256k1');
  262. CheckNotNull(x9);
  263. DoTestSumOfTwoMultiplies(x9);
  264. end;
  265. procedure TTestECAlgorithms.TestSumOfTwoMultipliesComplete;
  266. var
  267. x9: IX9ECParameters;
  268. begin
  269. for x9 in GetTestCurves() do
  270. begin
  271. DoTestSumOfTwoMultiplies(x9);
  272. end;
  273. end;
  274. initialization
  275. // Register any test cases with the test runner
  276. {$IFDEF FPC}
  277. RegisterTest(TTestECAlgorithms);
  278. {$ELSE}
  279. RegisterTest(TTestECAlgorithms.Suite);
  280. {$ENDIF FPC}
  281. end.