efq-test.cc 29 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714
  1. /*############################################################################
  2. # Copyright 2017 Intel Corporation
  3. #
  4. # Licensed under the Apache License, Version 2.0 (the "License");
  5. # you may not use this file except in compliance with the License.
  6. # You may obtain a copy of the License at
  7. #
  8. # http://www.apache.org/licenses/LICENSE-2.0
  9. #
  10. # Unless required by applicable law or agreed to in writing, software
  11. # distributed under the License is distributed on an "AS IS" BASIS,
  12. # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. # See the License for the specific language governing permissions and
  14. # limitations under the License.
  15. ############################################################################*/
  16. /// Unit tests of EFq implementation.
  17. /*! \file */
  18. #include <gtest/gtest.h>
  19. #include <cstring>
  20. #include <random>
  21. #include "epid/member/tiny/math/unittests/cmp-testhelper.h"
  22. #include "epid/member/tiny/math/unittests/onetimepad.h"
  23. extern "C" {
  24. #include "epid/member/tiny/math/efq.h"
  25. #include "epid/member/tiny/math/fq.h"
  26. #include "epid/member/tiny/math/mathtypes.h"
  27. #include "epid/member/tiny/math/vli.h"
  28. }
  29. namespace {
  30. ////////////////////////////////////////////////////////////////////////
  31. // EFqMulSSCM
  32. TEST(TinyEFqTest, EFqMulSSCMWorks) {
  33. const EccPointJacobiFq expected = {
  34. {0xacd848b1, 0xe3d60553, 0x69271cd1, 0x7cf6090e, 0x16c63bcd, 0xdb0c6cf0,
  35. 0x2ab60283, 0x38fc72a8},
  36. {0xf7e0f7d1, 0x6b0cf194, 0x5cf18c77, 0x82a4b960, 0xa6c40a30, 0xf0b3b20f,
  37. 0x5f1a477b, 0x7e2a6668},
  38. {0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
  39. 0x00000000, 0x00000000}};
  40. const EccPointJacobiFq left = {
  41. {0x22cfd6a2, 0x23e82f1e, 0xd50e1450, 0xe853e88c, 0xafa65357, 0x4780716c,
  42. 0xffd94b0f, 0x5e643124},
  43. {0x5e9cb480, 0x6d4aaf9c, 0x99f1f606, 0x222d89b0, 0x30b79eab, 0x88844bd6,
  44. 0xc65e7c30, 0x4830c4ec},
  45. {0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
  46. 0x00000000, 0x00000000}};
  47. const FpElem power = {0x0adf9a12, 0x5cbc9ef4, 0x91762984, 0xa08a22fb,
  48. 0x52a6fddf, 0xf51e743e, 0x7b47b24b, 0x389f865f};
  49. EccPointJacobiFq actual = {0};
  50. EFqMulSSCM(&actual, &left, &power);
  51. EXPECT_EQ(expected, actual);
  52. }
  53. TEST(TinyEFqTest, EFqMulSSCMWorksInPlace) {
  54. const EccPointJacobiFq expected = {
  55. {0xacd848b1, 0xe3d60553, 0x69271cd1, 0x7cf6090e, 0x16c63bcd, 0xdb0c6cf0,
  56. 0x2ab60283, 0x38fc72a8},
  57. {0xf7e0f7d1, 0x6b0cf194, 0x5cf18c77, 0x82a4b960, 0xa6c40a30, 0xf0b3b20f,
  58. 0x5f1a477b, 0x7e2a6668},
  59. {0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
  60. 0x00000000, 0x00000000}};
  61. EccPointJacobiFq left = {{0x22cfd6a2, 0x23e82f1e, 0xd50e1450, 0xe853e88c,
  62. 0xafa65357, 0x4780716c, 0xffd94b0f, 0x5e643124},
  63. {0x5e9cb480, 0x6d4aaf9c, 0x99f1f606, 0x222d89b0,
  64. 0x30b79eab, 0x88844bd6, 0xc65e7c30, 0x4830c4ec},
  65. {0x00000001, 0x00000000, 0x00000000, 0x00000000,
  66. 0x00000000, 0x00000000, 0x00000000, 0x00000000}};
  67. const FpElem power = {0x0adf9a12, 0x5cbc9ef4, 0x91762984, 0xa08a22fb,
  68. 0x52a6fddf, 0xf51e743e, 0x7b47b24b, 0x389f865f};
  69. EFqMulSSCM(&left, &left, &power);
  70. EXPECT_EQ(expected, left);
  71. }
  72. ////////////////////////////////////////////////////////////////////////
  73. // EFqMultiExp
  74. TEST(TinyEFqTest, EFqAffineExpWorks) {
  75. EccPointFq efq_left = {0};
  76. EccPointFq efq_right = {{{0x76abb18a, 0x92c0f7b9, 0x2c1a37e0, 0x7fdf6ca1,
  77. 0xe3401760, 0x66eb7d52, 0x918d50a7, 0x12a65bd6}},
  78. {{0x1f3a8b42, 0xc8d3127f, 0x6d96f7cd, 0xea6fe2f6,
  79. 0x0ac0b46b, 0x557a5f30, 0xaf075250, 0x786528cb}}};
  80. EccPointFq efq_expect = {{{0x79171d4b, 0x0f5ac562, 0x3b911d03, 0x0992a2dc,
  81. 0x3130dd84, 0x16344c80, 0x436ca13c, 0xaf1d9819}},
  82. {{0x742268cd, 0x070b4ac7, 0x7f2b13b7, 0xe167da7f,
  83. 0xd84d16af, 0x9e824ebe, 0x6b5dc0f0, 0x90bd1aa3}}};
  84. FpElem fp_exp = {3};
  85. EFqAffineExp(&efq_left, &efq_right, &fp_exp);
  86. EXPECT_EQ(efq_expect, efq_left);
  87. }
  88. TEST(TinyEFqTest, EFqAffineExpWorksInPlace) {
  89. EccPointFq efq_right = {{{0x76abb18a, 0x92c0f7b9, 0x2c1a37e0, 0x7fdf6ca1,
  90. 0xe3401760, 0x66eb7d52, 0x918d50a7, 0x12a65bd6}},
  91. {{0x1f3a8b42, 0xc8d3127f, 0x6d96f7cd, 0xea6fe2f6,
  92. 0x0ac0b46b, 0x557a5f30, 0xaf075250, 0x786528cb}}};
  93. EccPointFq efq_expect = {{{0x79171d4b, 0x0f5ac562, 0x3b911d03, 0x0992a2dc,
  94. 0x3130dd84, 0x16344c80, 0x436ca13c, 0xaf1d9819}},
  95. {{0x742268cd, 0x070b4ac7, 0x7f2b13b7, 0xe167da7f,
  96. 0xd84d16af, 0x9e824ebe, 0x6b5dc0f0, 0x90bd1aa3}}};
  97. FpElem fp_exp = {3};
  98. EFqAffineExp(&efq_right, &efq_right, &fp_exp);
  99. EXPECT_EQ(efq_expect, efq_right);
  100. }
  101. ////////////////////////////////////////////////////////////////////////
  102. // EFqAffineMultiExp
  103. TEST(TinyEFqTest, EFqAffineMultiExpWorks) {
  104. // eFq2^3*eFq2^3
  105. EccPointFq efq_left = {0};
  106. EccPointFq efq_right = {{{0x76abb18a, 0x92c0f7b9, 0x2c1a37e0, 0x7fdf6ca1,
  107. 0xe3401760, 0x66eb7d52, 0x918d50a7, 0x12a65bd6}},
  108. {{0x1f3a8b42, 0xc8d3127f, 0x6d96f7cd, 0xea6fe2f6,
  109. 0x0ac0b46b, 0x557a5f30, 0xaf075250, 0x786528cb}}};
  110. EccPointFq efq_expect = {{{0x1a178986, 0xeeb06c08, 0x857d79f0, 0x246d0ed6,
  111. 0xed31a3b2, 0x7bf832a0, 0x81a8a27b, 0x3d0cab80}},
  112. {{0xfe2a1509, 0x41cda394, 0x42b33efb, 0x2811fa22,
  113. 0x0ad56486, 0xe52b1a56, 0xf6dc881c, 0x6fee593f}}};
  114. FpElem fp_exp = {3};
  115. EFqAffineMultiExp(&efq_left, &efq_right, &fp_exp, &efq_right, &fp_exp);
  116. EXPECT_EQ(efq_expect, efq_left);
  117. }
  118. ////////////////////////////////////////////////////////////////////////
  119. // EFqMultiExp
  120. TEST(TinyEFqTest, EFqMultiExpWorks) {
  121. EccPointFq efq_left = {0};
  122. EccPointFq efq_right = {{{0x76abb18a, 0x92c0f7b9, 0x2c1a37e0, 0x7fdf6ca1,
  123. 0xe3401760, 0x66eb7d52, 0x918d50a7, 0x12a65bd6}},
  124. {{0x1f3a8b42, 0xc8d3127f, 0x6d96f7cd, 0xea6fe2f6,
  125. 0x0ac0b46b, 0x557a5f30, 0xaf075250, 0x786528cb}}};
  126. EccPointFq efq_expect = {{{0x1a178986, 0xeeb06c08, 0x857d79f0, 0x246d0ed6,
  127. 0xed31a3b2, 0x7bf832a0, 0x81a8a27b, 0x3d0cab80}},
  128. {{0xfe2a1509, 0x41cda394, 0x42b33efb, 0x2811fa22,
  129. 0x0ad56486, 0xe52b1a56, 0xf6dc881c, 0x6fee593f}}};
  130. EccPointJacobiFq efqj_left = {0};
  131. EccPointJacobiFq efqj_right;
  132. FpElem fp_exp = {3};
  133. EFqFromAffine(&efqj_right, &efq_right);
  134. EFqMultiExp(&efqj_left, &efqj_right, &fp_exp, &efqj_right, &fp_exp);
  135. EFqToAffine(&efq_left, &efqj_left);
  136. EXPECT_EQ(efq_expect, efq_left);
  137. }
  138. ////////////////////////////////////////////////////////////////////////
  139. // EFqAffineAdd
  140. TEST(TinyEFqTest, EFqAffineAddWorks) {
  141. EccPointFq efq_left = {{{0x76abb18a, 0x92c0f7b9, 0x2c1a37e0, 0x7fdf6ca1,
  142. 0xe3401760, 0x66eb7d52, 0x918d50a7, 0x12a65bd6}},
  143. {{0x1f3a8b42, 0xc8d3127f, 0x6d96f7cd, 0xea6fe2f6,
  144. 0x0ac0b46b, 0x557a5f30, 0xaf075250, 0x786528cb}}};
  145. EccPointFq const efq_expect = {
  146. {{0x7305f782, 0x84101559, 0xe065da04, 0xfd373fcf, 0x31d2f725, 0x9b420bdc,
  147. 0x622ac9c3, 0xba0ef378}},
  148. {{0x97b2adf0, 0x2935c14b, 0xfc6415b0, 0x48ba036a, 0x61ca7383, 0xcff7f03d,
  149. 0x23a2c3e6, 0x0df0d4a5}}};
  150. EFqAffineAdd(&efq_left, &efq_left, &efq_left);
  151. EXPECT_EQ(efq_expect, efq_left);
  152. }
  153. ////////////////////////////////////////////////////////////////////////
  154. // EFqAffineDbl
  155. TEST(TinyEFqTest, EFqAffineDblWorks) {
  156. EccPointFq efq_left = {{{0x76abb18a, 0x92c0f7b9, 0x2c1a37e0, 0x7fdf6ca1,
  157. 0xe3401760, 0x66eb7d52, 0x918d50a7, 0x12a65bd6}},
  158. {{0x1f3a8b42, 0xc8d3127f, 0x6d96f7cd, 0xea6fe2f6,
  159. 0x0ac0b46b, 0x557a5f30, 0xaf075250, 0x786528cb}}};
  160. EccPointFq const efq_expect = {
  161. {{0x7305f782, 0x84101559, 0xe065da04, 0xfd373fcf, 0x31d2f725, 0x9b420bdc,
  162. 0x622ac9c3, 0xba0ef378}},
  163. {{0x97b2adf0, 0x2935c14b, 0xfc6415b0, 0x48ba036a, 0x61ca7383, 0xcff7f03d,
  164. 0x23a2c3e6, 0x0df0d4a5}}};
  165. EFqAffineDbl(&efq_left, &efq_left);
  166. EXPECT_EQ(efq_expect, efq_left);
  167. }
  168. ////////////////////////////////////////////////////////////////////////
  169. // EFqDbl
  170. TEST(TinyEFqTest, EFqDblWorks) {
  171. EccPointJacobiFq efqj_left = {
  172. {{0x76abb18a, 0x92c0f7b9, 0x2c1a37e0, 0x7fdf6ca1, 0xe3401760, 0x66eb7d52,
  173. 0x918d50a7, 0x12a65bd6}},
  174. {{0x1f3a8b42, 0xc8d3127f, 0x6d96f7cd, 0xea6fe2f6, 0x0ac0b46b, 0x557a5f30,
  175. 0xaf075250, 0x786528cb}},
  176. {{0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
  177. 0x00000000, 0x00000000}}};
  178. EccPointJacobiFq const efqj_expect = {
  179. {{0x7305f782, 0x84101559, 0xe065da04, 0xfd373fcf, 0x31d2f725, 0x9b420bdc,
  180. 0x622ac9c3, 0xba0ef378}},
  181. {{0x97b2adf0, 0x2935c14b, 0xfc6415b0, 0x48ba036a, 0x61ca7383, 0xcff7f03d,
  182. 0x23a2c3e6, 0x0df0d4a5}},
  183. {{0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
  184. 0x00000000, 0x00000000}}};
  185. EFqDbl(&efqj_left, &efqj_left);
  186. EXPECT_EQ(efqj_expect, efqj_left);
  187. }
  188. ////////////////////////////////////////////////////////////////////////
  189. // EFqAdd
  190. TEST(TinyEFqTest, EFqAddWorks) {
  191. EccPointJacobiFq efqj_left = {
  192. {{0x76abb18a, 0x92c0f7b9, 0x2c1a37e0, 0x7fdf6ca1, 0xe3401760, 0x66eb7d52,
  193. 0x918d50a7, 0x12a65bd6}},
  194. {{0x1f3a8b42, 0xc8d3127f, 0x6d96f7cd, 0xea6fe2f6, 0x0ac0b46b, 0x557a5f30,
  195. 0xaf075250, 0x786528cb}},
  196. {{0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
  197. 0x00000000, 0x00000000}}};
  198. EccPointJacobiFq const efqj_expect = {
  199. {{0x7305f782, 0x84101559, 0xe065da04, 0xfd373fcf, 0x31d2f725, 0x9b420bdc,
  200. 0x622ac9c3, 0xba0ef378}},
  201. {{0x97b2adf0, 0x2935c14b, 0xfc6415b0, 0x48ba036a, 0x61ca7383, 0xcff7f03d,
  202. 0x23a2c3e6, 0x0df0d4a5}},
  203. {{0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
  204. 0x00000000, 0x00000000}}};
  205. EFqAdd(&efqj_left, &efqj_left, &efqj_left);
  206. EXPECT_EQ(efqj_expect, efqj_left);
  207. }
  208. ////////////////////////////////////////////////////////////////////////
  209. // EFqRand
  210. // Checks if EFqRand can generate points with Y >= q+1
  211. TEST(TinyEFqTest, EFqRandCanGenerateBigY) {
  212. OneTimePad otp({
  213. 0x25, 0xeb, 0x8c, 0x48, 0xff, 0x89, 0xcb, 0x85, 0x4f, 0xc0, 0x90, 0x81,
  214. 0xcc, 0x47, 0xed, 0xfc, 0x86, 0x19, 0xb2, 0x14, 0xfe, 0x65, 0x92, 0xd4,
  215. 0x8b, 0xfc, 0xea, 0x9c, 0x9d, 0x8e, 0x32, 0x44, 0xd7, 0xd7, 0xe9, 0xf1,
  216. 0xf7, 0xde, 0x60, 0x56, 0x8d, 0xe9, 0x89, 0x07, 0x3f, 0x3d, 0x16, 0x39,
  217. });
  218. // expected.y >= q+1
  219. EccPointFq expected = {{0xd78542d3, 0xf824c127, 0x81eea621, 0x6990833d,
  220. 0x9d843df6, 0x3df36126, 0x435e8eda, 0x2d267586},
  221. {0x1B8DC14B, 0x5967C520, 0x61CECE5D, 0x0290B5BC,
  222. 0x49278859, 0x2C523D9A, 0x6D0AE6DE, 0xAE5590C9}};
  223. EccPointFq actual = {0};
  224. EXPECT_TRUE(EFqRand(&actual, OneTimePad::Generate, &otp));
  225. EXPECT_EQ(expected, actual);
  226. EXPECT_EQ(384u, otp.BitsConsumed());
  227. }
  228. // Checks if EFqRand can generate points with Y <= q-1
  229. TEST(TinyEFqTest, EFqRandCanGenerateSmallY) {
  230. OneTimePad otp({
  231. 0x47, 0xe7, 0xb0, 0x36, 0x0f, 0x85, 0x91, 0xaa, 0x14, 0x76, 0xb0, 0x16,
  232. 0xe5, 0x8d, 0xf1, 0x72, 0x61, 0xb5, 0x54, 0x0a, 0x60, 0xb7, 0x3d, 0x38,
  233. 0xd9, 0x95, 0xe7, 0x60, 0xf9, 0xd3, 0x19, 0xf1, 0x8e, 0x8d, 0xd4, 0x74,
  234. 0x2b, 0x86, 0xcd, 0xb8, 0xbb, 0x8f, 0x18, 0xfb, 0x89, 0xc2, 0xc7, 0x35,
  235. });
  236. // expected.y <= q-1
  237. EccPointFq expected = {{0x5f65199e, 0x59366f56, 0xb1d35d89, 0xf42fdc1f,
  238. 0x07fd66d6, 0x95f32cb3, 0xc4ef7101, 0xeb426988},
  239. {0x834171f5, 0xca1c1f05, 0xdcb4d142, 0xbe060756,
  240. 0x9185652b, 0xb3b9ede1, 0x671f682e, 0x22d0c94c}};
  241. EccPointFq actual = {0};
  242. EXPECT_TRUE(EFqRand(&actual, OneTimePad::Generate, &otp));
  243. EXPECT_EQ(expected, actual);
  244. EXPECT_EQ(384u, otp.BitsConsumed());
  245. }
  246. TEST(TinyEFqTest, EFqRandWorksForFailedSquareRoot) {
  247. // Only last 48 bytes of the given otp will result in x such that
  248. // Fq.sqrt of (x^3 + a*x + b) exists.
  249. OneTimePad otp({
  250. 0x01, 0x80, 0x3c, 0xd1, 0x08, 0xd8, 0x8d, 0x73, 0xaf, 0xea, 0x79, 0xc8,
  251. 0x1e, 0x47, 0x83, 0xc6, 0x95, 0x31, 0x39, 0x03, 0xc4, 0x18, 0xf1, 0x2b,
  252. 0x4c, 0x1a, 0x34, 0x50, 0x6d, 0x73, 0x29, 0xd2, 0x0f, 0x40, 0xc4, 0x19,
  253. 0x6f, 0xe2, 0xd7, 0x87, 0x1a, 0x99, 0x68, 0x16, 0x09, 0xc3, 0xe7, 0x7e,
  254. 0x17, 0x7d, 0x64, 0x9b, 0xa5, 0x39, 0x53, 0xa6, 0x88, 0x20, 0xa2, 0x0a,
  255. 0x17, 0x8f, 0xef, 0x57, 0x19, 0xc7, 0xf3, 0x5c, 0x4a, 0xbe, 0x2e, 0xa0,
  256. 0xd8, 0x97, 0xb7, 0x41, 0x71, 0x4d, 0x03, 0x80, 0xf8, 0xfd, 0xcd, 0x06,
  257. 0x34, 0xd5, 0xc6, 0x02, 0x4c, 0xdb, 0x95, 0xcb, 0x07, 0x4d, 0xc8, 0x4b,
  258. 0x4c, 0x2b, 0x14, 0x1e, 0x24, 0x67, 0x07, 0x2d, 0xc4, 0x39, 0xf0, 0xfc,
  259. 0xd2, 0x60, 0x0d, 0x0a, 0x17, 0x7c, 0x51, 0x87, 0x79, 0x98, 0xca, 0xdc,
  260. 0x94, 0xa0, 0x8c, 0xc1, 0x5e, 0x3c, 0xe9, 0x98, 0x52, 0x73, 0x61, 0x82,
  261. 0xec, 0xdc, 0x67, 0x62, 0x0a, 0xb6, 0x60, 0xe9, 0x52, 0xd6, 0xc6, 0xc2,
  262. 0x47, 0xe7, 0xb0, 0x36, 0x0f, 0x85, 0x91, 0xaa, 0x14, 0x76, 0xb0, 0x16,
  263. 0xe5, 0x8d, 0xf1, 0x72, 0x61, 0xb5, 0x54, 0x0a, 0x60, 0xb7, 0x3d, 0x38,
  264. 0xd9, 0x95, 0xe7, 0x60, 0xf9, 0xd3, 0x19, 0xf1, 0x8e, 0x8d, 0xd4, 0x74,
  265. 0x2b, 0x86, 0xcd, 0xb8, 0xbb, 0x8f, 0x18, 0xfb, 0x89, 0xc2, 0xc7, 0x35,
  266. });
  267. EccPointFq expected = {{0x5f65199e, 0x59366f56, 0xb1d35d89, 0xf42fdc1f,
  268. 0x07fd66d6, 0x95f32cb3, 0xc4ef7101, 0xeb426988},
  269. {0x834171f5, 0xca1c1f05, 0xdcb4d142, 0xbe060756,
  270. 0x9185652b, 0xb3b9ede1, 0x671f682e, 0x22d0c94c}};
  271. EccPointFq actual = {0};
  272. EXPECT_TRUE(EFqRand(&actual, OneTimePad::Generate, &otp));
  273. EXPECT_EQ(expected, actual);
  274. EXPECT_EQ(1536u, otp.BitsConsumed());
  275. }
  276. ////////////////////////////////////////////////////////////////////////
  277. // EFqSet
  278. TEST(TinyEFqTest, EFqSetWorks) {
  279. EccPointJacobiFq efqj_left = {0};
  280. EccPointJacobiFq const efqj_expect = {{{1}}, {{2}}, {{1}}};
  281. FqElem x = {1};
  282. FqElem y = {2};
  283. EFqSet(&efqj_left, &x, &y);
  284. EXPECT_EQ(efqj_expect, efqj_left);
  285. }
  286. ////////////////////////////////////////////////////////////////////////
  287. // EFqIsInf
  288. TEST(TinyEFqTest, EFqIsInfPasses) {
  289. EccPointJacobiFq const efqj_inf = {{{0}}, {{1}}, {{0}}};
  290. EXPECT_TRUE(EFqIsInf(&efqj_inf));
  291. }
  292. TEST(TinyEFqTest, EFqIsInfFails) {
  293. EccPointJacobiFq const efqj_noninf = {{{1}}, {{2}}, {{1}}};
  294. EXPECT_FALSE(EFqIsInf(&efqj_noninf));
  295. }
  296. ////////////////////////////////////////////////////////////////////////
  297. // EFqFromAffine
  298. TEST(TinyEFqTest, FqFromAffineWorks) {
  299. EccPointJacobiFq efqj_left = {0};
  300. EccPointJacobiFq const efqj_expect = {{{1}}, {{2}}, {{1}}};
  301. EccPointFq efq_left = {{{1}}, {{2}}};
  302. EFqFromAffine(&efqj_left, &efq_left);
  303. EXPECT_EQ(efqj_expect, efqj_left);
  304. }
  305. ////////////////////////////////////////////////////////////////////////
  306. // EFqToAffine
  307. TEST(TinyEFqTest, EFqToAffineWorks) {
  308. EccPointFq efq_left = {0};
  309. EccPointFq const efq_expect = {{{1}}, {{2}}};
  310. EccPointJacobiFq efqj_left = {{{1}}, {{2}}, {{1}}};
  311. EFqToAffine(&efq_left, &efqj_left);
  312. EXPECT_EQ(efq_expect, efq_left);
  313. }
  314. ////////////////////////////////////////////////////////////////////////
  315. // EFqNeg
  316. TEST(TinyEFqTest, EFqNegWorks) {
  317. EccPointJacobiFq efqj_left = {0};
  318. EccPointJacobiFq efqj_right = {
  319. {{0x76abb18a, 0x92c0f7b9, 0x2c1a37e0, 0x7fdf6ca1, 0xe3401760, 0x66eb7d52,
  320. 0x918d50a7, 0x12a65bd6}},
  321. {{0x1f3a8b42, 0xc8d3127f, 0x6d96f7cd, 0xea6fe2f6, 0x0ac0b46b, 0x557a5f30,
  322. 0xaf075250, 0x786528cb}},
  323. {{0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
  324. 0x00000000, 0x00000000}}};
  325. EccPointJacobiFq const efqj_expect = {
  326. {{0x76abb18a, 0x92c0f7b9, 0x2c1a37e0, 0x7fdf6ca1, 0xe3401760, 0x66eb7d52,
  327. 0x918d50a7, 0x12a65bd6}},
  328. {{0x8f98a4d1, 0x0a561b5c, 0xa50112b5, 0x226c8304, 0xe3b0f033, 0xf16b932e,
  329. 0x50f59e7c, 0x879ad734}},
  330. {{0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
  331. 0x00000000, 0x00000000}}};
  332. EFqNeg(&efqj_left, &efqj_right);
  333. EXPECT_EQ(efqj_expect, efqj_left);
  334. }
  335. ////////////////////////////////////////////////////////////////////////
  336. // EFqEq
  337. TEST(TinyEFqTest, EFqEqPasses) {
  338. EccPointJacobiFq const efqj_left = {{{1}}, {{2}}, {{1}}};
  339. EccPointJacobiFq const efqj_right = {{{1}}, {{2}}, {{1}}};
  340. EXPECT_TRUE(EFqEq(&efqj_left, &efqj_right));
  341. }
  342. TEST(TinyEFqTest, EFqEqFails) {
  343. EccPointJacobiFq const efqj_left = {{{1}}, {{2}}, {{1}}};
  344. EccPointJacobiFq const efqj_right = {
  345. {{0x76abb18a, 0x92c0f7b9, 0x2c1a37e0, 0x7fdf6ca1, 0xe3401760, 0x66eb7d52,
  346. 0x918d50a7, 0x12a65bd6}},
  347. {{0x1f3a8b42, 0xc8d3127f, 0x6d96f7cd, 0xea6fe2f6, 0x0ac0b46b, 0x557a5f30,
  348. 0xaf075250, 0x786528cb}},
  349. {{0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
  350. 0x00000000, 0x00000000}}};
  351. EXPECT_FALSE(EFqEq(&efqj_left, &efqj_right));
  352. }
  353. ////////////////////////////////////////////////////////////////////////
  354. // EFqHash
  355. TEST(TinyEFqTest, EFqHashWithSha512Works) {
  356. EccPointFq efq_result = {0};
  357. EccPointFq efq_expect = {{{0x992a96e4, 0x42f7b394, 0xf3bada9c, 0xb4033d83,
  358. 0x21979b9b, 0xbc82a6a2, 0x55555586, 0x8c62a02d}},
  359. {{0x406c8f03, 0xe691d8f3, 0xadf2f27b, 0x69540cc6,
  360. 0xe02b87f7, 0x217d5424, 0x17b9fbe5, 0x4c0ea762}}};
  361. unsigned char const msg_buf[] = {'a', 'b', 'c'};
  362. size_t len = sizeof(msg_buf);
  363. HashAlg hashalg = kSha512;
  364. EXPECT_TRUE(EFqHash(&efq_result, msg_buf, len, hashalg));
  365. EXPECT_EQ(efq_expect, efq_result);
  366. }
  367. TEST(TinyEFqTest, EFqHashWithSha256Works) {
  368. EccPointFq efq_result = {0};
  369. EccPointFq efq_expect = {{{0x8008953d, 0xd54a103c, 0x70e6186b, 0x54f5a62a,
  370. 0xadbe836e, 0xf3716581, 0x88ff2562, 0x2ebb504d}},
  371. {{0xdc48f9f7, 0x48aa0d6c, 0x623e2c1f, 0x7ecdf02e,
  372. 0x07f07a32, 0xbd6738b1, 0xb13f3cb4, 0x8a43a104}}};
  373. unsigned char const msg_buf[] = {'a', 'b', 'c'};
  374. size_t len = sizeof(msg_buf);
  375. HashAlg hashalg = kSha256;
  376. EXPECT_TRUE(EFqHash(&efq_result, msg_buf, len, hashalg));
  377. EXPECT_EQ(efq_expect, efq_result);
  378. }
  379. TEST(TinyEFqTest, HashWorksForResultYSmallerThanHalfOfQAndEven) {
  380. std::vector<uint8_t> msg = {'a', 'a', 'd'};
  381. EccPointFq result;
  382. EccPointFq expected = {{0xb315d67e, 0x1924ae56, 0xcf527861, 0xebb789b6,
  383. 0x3f429d2a, 0xb193bf9a, 0x6bd8502f, 0x5e73be39},
  384. {0x0bd51968, 0x0f13472d, 0xc96b5096, 0xa9cd4491,
  385. 0x4ab668cf, 0x2123d56c, 0xf30af180, 0x0db43c33}};
  386. EXPECT_TRUE(EFqHash(&result, msg.data(), msg.size(), kSha512));
  387. EXPECT_EQ(expected, result);
  388. }
  389. TEST(TinyEFqTest, HashWorksForResultYSmallerThanHalfOfQAndOdd) {
  390. std::vector<uint8_t> msg = {'a', 'a', 'c'};
  391. EccPointFq result;
  392. EccPointFq expected = {{0x81D359E2, 0xF438B2AC, 0xAA4342EB, 0x80042B18,
  393. 0x850E1C62, 0x90860717, 0xC79A1AB8, 0xF8F4F2F6},
  394. {0xC1A2BA30, 0x369C0D70, 0x03EAF9DD, 0x4F93FC67,
  395. 0xBB6E5D10, 0x441B22F9, 0xEC70C946, 0xE8D39BD4}};
  396. EXPECT_TRUE(EFqHash(&result, msg.data(), msg.size(), kSha512));
  397. EXPECT_EQ(expected, result);
  398. }
  399. TEST(TinyEFqTest, HashWorksForResultYLargerThanHalfOfQAndOdd) {
  400. std::vector<uint8_t> msg = {'a', 'a', 'b'};
  401. EccPointFq result;
  402. EccPointFq expected = {{0x31F874DA, 0x62DB014E, 0x4A4FC69A, 0xC1DCC122,
  403. 0xC423DAF8, 0x27AB3AAC, 0xF1DE0993, 0x07906282},
  404. {0x8DA507A4, 0x568E1D1E, 0x6D373E90, 0x99A18DA4,
  405. 0xC5717AA2, 0x98C222F5, 0x0A2ADDF2, 0xA1212A44}};
  406. EFqHash(&result, msg.data(), msg.size(), kSha512);
  407. EXPECT_EQ(expected, result);
  408. }
  409. TEST(TinyEFqTest, HashWorksForResultYLargerThanHalfOfQAndEven) {
  410. std::vector<uint8_t> msg = {'a', 'a', 'e'};
  411. EccPointFq result;
  412. EccPointFq expected = {{0xA798F97C, 0xF24EC264, 0xD4C051F4, 0xBA4A5B45,
  413. 0xD2CF5996, 0x121A3F66, 0x222279F0, 0x208E4FD4},
  414. {0x3C816617, 0x6CF621EB, 0x8B8DAFC4, 0x63EB39C7,
  415. 0xE6C8AF5C, 0x32C732D0, 0xC5C46152, 0x114E8AE0}};
  416. EFqHash(&result, msg.data(), msg.size(), kSha512);
  417. EXPECT_EQ(expected, result);
  418. }
  419. ////////////////////////////////////////////////////////////////////////
  420. // EFqCp
  421. TEST(TinyEFqTest, EFqCpWorks) {
  422. const EccPointFq ecfq_point = {
  423. {{0x76ABB18A, 0x92C0F7B9, 0x2C1A37E0, 0x7FDF6CA1, 0xE3401760, 0x66EB7D52,
  424. 0x918D50A7, 0x12A65BD6}},
  425. {{0x1F3A8B42, 0xC8D3127F, 0x6D96F7CD, 0xEA6FE2F6, 0x0AC0B46B, 0x557A5F30,
  426. 0xAF075250, 0x786528CB}}};
  427. EccPointFq result_ecfq_point = {0};
  428. EFqCp(&result_ecfq_point, &ecfq_point);
  429. EXPECT_EQ(ecfq_point, result_ecfq_point);
  430. }
  431. ////////////////////////////////////////////////////////////////////////
  432. // EFqEqAffine
  433. TEST(TinyEFqTest, EFqEqAffinePasses) {
  434. EccPointFq efq_left = {{{1}}, {{2}}};
  435. EccPointFq efq_right = {{{1}}, {{2}}};
  436. EXPECT_TRUE(EFqEqAffine(&efq_left, &efq_right));
  437. }
  438. TEST(TinyEFqTest, EFqEqAffineFails) {
  439. EccPointFq efq_left = {{{1}}, {{2}}};
  440. EccPointFq efq_right = {{{0x76abb18a, 0x92c0f7b9, 0x2c1a37e0, 0x7fdf6ca1,
  441. 0xe3401760, 0x66eb7d52, 0x918d50a7, 0x12a65bd6}},
  442. {{0x8f98a4d1, 0x0a561b5c, 0xa50112b5, 0x226c8304,
  443. 0xe3b0f033, 0xf16b932e, 0x50f59e7c, 0x879ad734}}};
  444. EXPECT_FALSE(EFqEqAffine(&efq_left, &efq_right));
  445. }
  446. ////////////////////////////////////////////////////////////////////////
  447. // EFqCondSet
  448. TEST(TinyEFqTest, EFqCondSetWorksForTrue) {
  449. #define TRUE 1
  450. EccPointJacobiFq efqj_left = {0};
  451. EccPointJacobiFq efqj_right = {
  452. {{0x76abb18a, 0x92c0f7b9, 0x2c1a37e0, 0x7fdf6ca1, 0xe3401760, 0x66eb7d52,
  453. 0x918d50a7, 0x12a65bd6}},
  454. {{0x1f3a8b42, 0xc8d3127f, 0x6d96f7cd, 0xea6fe2f6, 0x0ac0b46b, 0x557a5f30,
  455. 0xaf075250, 0x786528cb}},
  456. {{0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
  457. 0x00000000, 0x00000000}}};
  458. EccPointJacobiFq efqj_expect = {{{1}}, {{2}}, {{1}}};
  459. EFqCondSet(&efqj_left, &efqj_expect, &efqj_right, TRUE);
  460. EXPECT_EQ(efqj_left, efqj_expect);
  461. }
  462. TEST(TinyEFqTest, EFqCondSetWorksForFalse) {
  463. #define FALSE 0
  464. EccPointJacobiFq efqj_left = {0};
  465. EccPointJacobiFq efqj_right = {{{1}}, {{2}}, {{1}}};
  466. EccPointJacobiFq efqj_expect = {
  467. {{0x76abb18a, 0x92c0f7b9, 0x2c1a37e0, 0x7fdf6ca1, 0xe3401760, 0x66eb7d52,
  468. 0x918d50a7, 0x12a65bd6}},
  469. {{0x1f3a8b42, 0xc8d3127f, 0x6d96f7cd, 0xea6fe2f6, 0x0ac0b46b, 0x557a5f30,
  470. 0xaf075250, 0x786528cb}},
  471. {{0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
  472. 0x00000000, 0x00000000}}};
  473. EFqCondSet(&efqj_left, &efqj_right, &efqj_expect, FALSE);
  474. EXPECT_EQ(efqj_left, efqj_expect);
  475. }
  476. ////////////////////////////////////////////////////////////////////////
  477. // EFqJCp
  478. TEST(TinyEFqTest, EFqJCpWorks) {
  479. const EccPointJacobiFq efqj = {{{1}}, {{2}}, {{1}}};
  480. EccPointJacobiFq efqj_result = {0};
  481. EFqJCp(&efqj_result, &efqj);
  482. EXPECT_EQ(efqj, efqj_result);
  483. }
  484. ////////////////////////////////////////////////////////////////////////
  485. // EFqInf
  486. TEST(TinyEFqTest, EFqInfWorks) {
  487. EccPointJacobiFq efqj_left;
  488. EccPointJacobiFq efqj_expect = {{{0}}, {{1}}, {{0}}};
  489. EFqInf(&efqj_left);
  490. EXPECT_EQ(efqj_expect, efqj_left);
  491. }
  492. ////////////////////////////////////////////////////////////////////////
  493. // EFqOnCurve
  494. TEST(TinyEFqTest, EFqOnCurvePasses) {
  495. const EccPointFq ecfq_point = {
  496. {{0x76ABB18A, 0x92C0F7B9, 0x2C1A37E0, 0x7FDF6CA1, 0xE3401760, 0x66EB7D52,
  497. 0x918D50A7, 0x12A65BD6}},
  498. {{0x1F3A8B42, 0xC8D3127F, 0x6D96F7CD, 0xEA6FE2F6, 0x0AC0B46B, 0x557A5F30,
  499. 0xAF075250, 0x786528CB}}};
  500. EXPECT_EQ(1, EFqOnCurve(&ecfq_point));
  501. }
  502. TEST(TinyEFqTest, EFqOnCurveFails) {
  503. EccPointFq bad_ecfq_point = {
  504. {{0x76ABB18A, 0x92C0F7B9, 0x2C1A37E0, 0x7FDF6CA1, 0xE3401760, 0x66EB7D52,
  505. 0x918D50A7, 0x12A65BD6}},
  506. {{0x1F3A8B42, 0xC8D3127F, 0x6D96F7CD, 0xEA6FE2F6, 0x0AC0B46B, 0x557A5F30,
  507. 0xAF075250, 0x786528CB}}};
  508. uint8_t* ecpq_vec = (uint8_t*)bad_ecfq_point.x.limbs.word;
  509. ecpq_vec[31]++;
  510. EXPECT_EQ(0, EFqOnCurve(&bad_ecfq_point));
  511. }
  512. ////////////////////////////////////////////////////////////////////////
  513. // EFqJOnCurve
  514. TEST(TinyEFqTest, EFqJOnCurvePasses) {
  515. EccPointJacobiFq efqj = {{{1}}, {{2}}, {{1}}};
  516. EXPECT_TRUE(EFqJOnCurve(&efqj));
  517. }
  518. TEST(TinyEFqTest, EFqJOnCurveFails) {
  519. EccPointJacobiFq efqj = {{{1}}, {{4}}, {{1}}};
  520. EXPECT_FALSE(EFqJOnCurve(&efqj));
  521. }
  522. TEST(TinyEFqTest, EFqJOnCurveAcceptsPointAtInfinity) {
  523. EccPointJacobiFq infinity = {{{0}}, {{1}}, {{0}}};
  524. EXPECT_TRUE(EFqJOnCurve(&infinity));
  525. }
  526. ////////////////////////////////////////////////////////////////////////
  527. // EFqJRand
  528. // Checks if EFqJRand can generate points with Y >= q+1
  529. TEST(TinyEFqTest, EFqJRandCanGenerateBigY) {
  530. OneTimePad otp({
  531. 0x25, 0xeb, 0x8c, 0x48, 0xff, 0x89, 0xcb, 0x85, 0x4f, 0xc0, 0x90, 0x81,
  532. 0xcc, 0x47, 0xed, 0xfc, 0x86, 0x19, 0xb2, 0x14, 0xfe, 0x65, 0x92, 0xd4,
  533. 0x8b, 0xfc, 0xea, 0x9c, 0x9d, 0x8e, 0x32, 0x44, 0xd7, 0xd7, 0xe9, 0xf1,
  534. 0xf7, 0xde, 0x60, 0x56, 0x8d, 0xe9, 0x89, 0x07, 0x3f, 0x3d, 0x16, 0x39,
  535. });
  536. // expected.y >= q+1
  537. EccPointJacobiFq expected = {
  538. {0xd78542d3, 0xf824c127, 0x81eea621, 0x6990833d, 0x9d843df6, 0x3df36126,
  539. 0x435e8eda, 0x2d267586},
  540. {0x1B8DC14B, 0x5967C520, 0x61CECE5D, 0x0290B5BC, 0x49278859, 0x2C523D9A,
  541. 0x6D0AE6DE, 0xAE5590C9},
  542. {0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
  543. 0x00000000, 0x00000000}};
  544. EccPointJacobiFq actual = {0};
  545. EXPECT_TRUE(EFqJRand(&actual, OneTimePad::Generate, &otp));
  546. EXPECT_EQ(expected, actual);
  547. EXPECT_EQ(384u, otp.BitsConsumed());
  548. }
  549. // Checks if EFqJRand can generate points with Y <= q-1
  550. TEST(TinyEFqTest, EFqJRandCanGenerateSmallY) {
  551. OneTimePad otp({
  552. 0x47, 0xe7, 0xb0, 0x36, 0x0f, 0x85, 0x91, 0xaa, 0x14, 0x76, 0xb0, 0x16,
  553. 0xe5, 0x8d, 0xf1, 0x72, 0x61, 0xb5, 0x54, 0x0a, 0x60, 0xb7, 0x3d, 0x38,
  554. 0xd9, 0x95, 0xe7, 0x60, 0xf9, 0xd3, 0x19, 0xf1, 0x8e, 0x8d, 0xd4, 0x74,
  555. 0x2b, 0x86, 0xcd, 0xb8, 0xbb, 0x8f, 0x18, 0xfb, 0x89, 0xc2, 0xc7, 0x35,
  556. });
  557. // expected.y <= q-1
  558. EccPointJacobiFq expected = {
  559. {0x5f65199e, 0x59366f56, 0xb1d35d89, 0xf42fdc1f, 0x07fd66d6, 0x95f32cb3,
  560. 0xc4ef7101, 0xeb426988},
  561. {0x834171f5, 0xca1c1f05, 0xdcb4d142, 0xbe060756, 0x9185652b, 0xb3b9ede1,
  562. 0x671f682e, 0x22d0c94c},
  563. {0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
  564. 0x00000000, 0x00000000}};
  565. EccPointJacobiFq actual = {0};
  566. EXPECT_TRUE(EFqJRand(&actual, OneTimePad::Generate, &otp));
  567. EXPECT_EQ(expected, actual);
  568. EXPECT_EQ(384u, otp.BitsConsumed());
  569. }
  570. TEST(TinyEFqTest, EFqJRandWorksForFailedSquareRoot) {
  571. // Only last 48 bytes of the given otp will result in x such that
  572. // Fq.sqrt of (x^3 + a*x + b) exists.
  573. OneTimePad otp({
  574. 0x01, 0x80, 0x3c, 0xd1, 0x08, 0xd8, 0x8d, 0x73, 0xaf, 0xea, 0x79, 0xc8,
  575. 0x1e, 0x47, 0x83, 0xc6, 0x95, 0x31, 0x39, 0x03, 0xc4, 0x18, 0xf1, 0x2b,
  576. 0x4c, 0x1a, 0x34, 0x50, 0x6d, 0x73, 0x29, 0xd2, 0x0f, 0x40, 0xc4, 0x19,
  577. 0x6f, 0xe2, 0xd7, 0x87, 0x1a, 0x99, 0x68, 0x16, 0x09, 0xc3, 0xe7, 0x7e,
  578. 0x17, 0x7d, 0x64, 0x9b, 0xa5, 0x39, 0x53, 0xa6, 0x88, 0x20, 0xa2, 0x0a,
  579. 0x17, 0x8f, 0xef, 0x57, 0x19, 0xc7, 0xf3, 0x5c, 0x4a, 0xbe, 0x2e, 0xa0,
  580. 0xd8, 0x97, 0xb7, 0x41, 0x71, 0x4d, 0x03, 0x80, 0xf8, 0xfd, 0xcd, 0x06,
  581. 0x34, 0xd5, 0xc6, 0x02, 0x4c, 0xdb, 0x95, 0xcb, 0x07, 0x4d, 0xc8, 0x4b,
  582. 0x4c, 0x2b, 0x14, 0x1e, 0x24, 0x67, 0x07, 0x2d, 0xc4, 0x39, 0xf0, 0xfc,
  583. 0xd2, 0x60, 0x0d, 0x0a, 0x17, 0x7c, 0x51, 0x87, 0x79, 0x98, 0xca, 0xdc,
  584. 0x94, 0xa0, 0x8c, 0xc1, 0x5e, 0x3c, 0xe9, 0x98, 0x52, 0x73, 0x61, 0x82,
  585. 0xec, 0xdc, 0x67, 0x62, 0x0a, 0xb6, 0x60, 0xe9, 0x52, 0xd6, 0xc6, 0xc2,
  586. 0x47, 0xe7, 0xb0, 0x36, 0x0f, 0x85, 0x91, 0xaa, 0x14, 0x76, 0xb0, 0x16,
  587. 0xe5, 0x8d, 0xf1, 0x72, 0x61, 0xb5, 0x54, 0x0a, 0x60, 0xb7, 0x3d, 0x38,
  588. 0xd9, 0x95, 0xe7, 0x60, 0xf9, 0xd3, 0x19, 0xf1, 0x8e, 0x8d, 0xd4, 0x74,
  589. 0x2b, 0x86, 0xcd, 0xb8, 0xbb, 0x8f, 0x18, 0xfb, 0x89, 0xc2, 0xc7, 0x35,
  590. });
  591. EccPointJacobiFq expected = {
  592. {0x5f65199e, 0x59366f56, 0xb1d35d89, 0xf42fdc1f, 0x07fd66d6, 0x95f32cb3,
  593. 0xc4ef7101, 0xeb426988},
  594. {0x834171f5, 0xca1c1f05, 0xdcb4d142, 0xbe060756, 0x9185652b, 0xb3b9ede1,
  595. 0x671f682e, 0x22d0c94c},
  596. {0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
  597. 0x00000000, 0x00000000}};
  598. EccPointJacobiFq actual = {0};
  599. EXPECT_TRUE(EFqJRand(&actual, OneTimePad::Generate, &otp));
  600. EXPECT_EQ(expected, actual);
  601. EXPECT_EQ(1536u, otp.BitsConsumed());
  602. }
  603. } // namespace