ECAlgorithmsTests.pas 8.5 KB

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