Ed25519.cpp 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601
  1. #include <openssl/sha.h>
  2. #include "Log.h"
  3. #include "Crypto.h"
  4. #include "Ed25519.h"
  5. namespace i2p
  6. {
  7. namespace crypto
  8. {
  9. Ed25519::Ed25519 ()
  10. {
  11. BN_CTX * ctx = BN_CTX_new ();
  12. BIGNUM * tmp = BN_new ();
  13. q = BN_new ();
  14. // 2^255-19
  15. BN_set_bit (q, 255); // 2^255
  16. BN_sub_word (q, 19);
  17. l = BN_new ();
  18. // 2^252 + 27742317777372353535851937790883648493
  19. BN_set_bit (l, 252);
  20. two_252_2 = BN_dup (l);
  21. BN_dec2bn (&tmp, "27742317777372353535851937790883648493");
  22. BN_add (l, l, tmp);
  23. BN_sub_word (two_252_2, 2); // 2^252 - 2
  24. // -121665*inv(121666)
  25. d = BN_new ();
  26. BN_set_word (tmp, 121666);
  27. BN_mod_inverse (tmp, tmp, q, ctx);
  28. BN_set_word (d, 121665);
  29. BN_set_negative (d, 1);
  30. BN_mul (d, d, tmp, ctx);
  31. // 2^((q-1)/4)
  32. I = BN_new ();
  33. BN_free (tmp);
  34. tmp = BN_dup (q);
  35. BN_sub_word (tmp, 1);
  36. BN_div_word (tmp, 4);
  37. BN_set_word (I, 2);
  38. BN_mod_exp (I, I, tmp, q, ctx);
  39. BN_free (tmp);
  40. // 4*inv(5)
  41. BIGNUM * By = BN_new ();
  42. BN_set_word (By, 5);
  43. BN_mod_inverse (By, By, q, ctx);
  44. BN_mul_word (By, 4);
  45. BIGNUM * Bx = RecoverX (By, ctx);
  46. BN_mod (Bx, Bx, q, ctx); // % q
  47. BN_mod (By, By, q, ctx); // % q
  48. // precalculate Bi256 table
  49. Bi256Carry = { Bx, By }; // B
  50. for (int i = 0; i < 32; i++)
  51. {
  52. Bi256[i][0] = Bi256Carry; // first point
  53. for (int j = 1; j < 128; j++)
  54. Bi256[i][j] = Sum (Bi256[i][j-1], Bi256[i][0], ctx); // (256+j+1)^i*B
  55. Bi256Carry = Bi256[i][127];
  56. for (int j = 0; j < 128; j++) // add first point 128 more times
  57. Bi256Carry = Sum (Bi256Carry, Bi256[i][0], ctx);
  58. }
  59. BN_CTX_free (ctx);
  60. }
  61. Ed25519::Ed25519 (const Ed25519& other): q (BN_dup (other.q)), l (BN_dup (other.l)),
  62. d (BN_dup (other.d)), I (BN_dup (other.I)), two_252_2 (BN_dup (other.two_252_2)),
  63. Bi256Carry (other.Bi256Carry)
  64. {
  65. for (int i = 0; i < 32; i++)
  66. for (int j = 0; j < 128; j++)
  67. Bi256[i][j] = other.Bi256[i][j];
  68. }
  69. Ed25519::~Ed25519 ()
  70. {
  71. BN_free (q);
  72. BN_free (l);
  73. BN_free (d);
  74. BN_free (I);
  75. BN_free (two_252_2);
  76. }
  77. EDDSAPoint Ed25519::GeneratePublicKey (const uint8_t * expandedPrivateKey, BN_CTX * ctx) const
  78. {
  79. return MulB (expandedPrivateKey, ctx); // left half of expanded key, considered as Little Endian
  80. }
  81. EDDSAPoint Ed25519::DecodePublicKey (const uint8_t * buf, BN_CTX * ctx) const
  82. {
  83. return DecodePoint (buf, ctx);
  84. }
  85. void Ed25519::EncodePublicKey (const EDDSAPoint& publicKey, uint8_t * buf, BN_CTX * ctx) const
  86. {
  87. EncodePoint (Normalize (publicKey, ctx), buf);
  88. }
  89. bool Ed25519::Verify (const EDDSAPoint& publicKey, const uint8_t * digest, const uint8_t * signature) const
  90. {
  91. BN_CTX * ctx = BN_CTX_new ();
  92. BIGNUM * h = DecodeBN<64> (digest);
  93. // signature 0..31 - R, 32..63 - S
  94. // B*S = R + PK*h => R = B*S - PK*h
  95. // we don't decode R, but encode (B*S - PK*h)
  96. auto Bs = MulB (signature + EDDSA25519_SIGNATURE_LENGTH/2, ctx); // B*S;
  97. BN_mod (h, h, l, ctx); // public key is multiple of B, but B%l = 0
  98. auto PKh = Mul (publicKey, h, ctx); // PK*h
  99. uint8_t diff[32];
  100. EncodePoint (Normalize (Sum (Bs, -PKh, ctx), ctx), diff); // Bs - PKh encoded
  101. bool passed = !memcmp (signature, diff, 32); // R
  102. BN_free (h);
  103. BN_CTX_free (ctx);
  104. if (!passed)
  105. LogPrint (eLogError, "25519 signature verification failed");
  106. return passed;
  107. }
  108. void Ed25519::Sign (const uint8_t * expandedPrivateKey, const uint8_t * publicKeyEncoded,
  109. const uint8_t * buf, size_t len, uint8_t * signature) const
  110. {
  111. BN_CTX * bnCtx = BN_CTX_new ();
  112. // calculate r
  113. SHA512_CTX ctx;
  114. SHA512_Init (&ctx);
  115. SHA512_Update (&ctx, expandedPrivateKey + EDDSA25519_PRIVATE_KEY_LENGTH, EDDSA25519_PRIVATE_KEY_LENGTH); // right half of expanded key
  116. SHA512_Update (&ctx, buf, len); // data
  117. uint8_t digest[64];
  118. SHA512_Final (digest, &ctx);
  119. BIGNUM * r = DecodeBN<32> (digest); // DecodeBN<64> (digest); // for test vectors
  120. // calculate R
  121. uint8_t R[EDDSA25519_SIGNATURE_LENGTH/2]; // we must use separate buffer because signature might be inside buf
  122. EncodePoint (Normalize (MulB (digest, bnCtx), bnCtx), R); // EncodePoint (Mul (B, r, bnCtx), R); // for test vectors
  123. // calculate S
  124. SHA512_Init (&ctx);
  125. SHA512_Update (&ctx, R, EDDSA25519_SIGNATURE_LENGTH/2); // R
  126. SHA512_Update (&ctx, publicKeyEncoded, EDDSA25519_PUBLIC_KEY_LENGTH); // public key
  127. SHA512_Update (&ctx, buf, len); // data
  128. SHA512_Final (digest, &ctx);
  129. BIGNUM * h = DecodeBN<64> (digest);
  130. // S = (r + h*a) % l
  131. BIGNUM * a = DecodeBN<EDDSA25519_PRIVATE_KEY_LENGTH> (expandedPrivateKey); // left half of expanded key
  132. BN_mod_mul (h, h, a, l, bnCtx); // %l
  133. BN_mod_add (h, h, r, l, bnCtx); // %l
  134. memcpy (signature, R, EDDSA25519_SIGNATURE_LENGTH/2);
  135. EncodeBN (h, signature + EDDSA25519_SIGNATURE_LENGTH/2, EDDSA25519_SIGNATURE_LENGTH/2); // S
  136. BN_free (r); BN_free (h); BN_free (a);
  137. BN_CTX_free (bnCtx);
  138. }
  139. void Ed25519::SignRedDSA (const uint8_t * privateKey, const uint8_t * publicKeyEncoded,
  140. const uint8_t * buf, size_t len, uint8_t * signature) const
  141. {
  142. BN_CTX * bnCtx = BN_CTX_new ();
  143. // T = 80 random bytes
  144. uint8_t T[80];
  145. RAND_bytes (T, 80);
  146. // calculate r = H*(T || publickey || data)
  147. SHA512_CTX ctx;
  148. SHA512_Init (&ctx);
  149. SHA512_Update (&ctx, T, 80);
  150. SHA512_Update (&ctx, publicKeyEncoded, 32);
  151. SHA512_Update (&ctx, buf, len); // data
  152. uint8_t digest[64];
  153. SHA512_Final (digest, &ctx);
  154. BIGNUM * r = DecodeBN<64> (digest);
  155. BN_mod (r, r, l, bnCtx); // % l
  156. EncodeBN (r, digest, 32);
  157. // calculate R
  158. uint8_t R[EDDSA25519_SIGNATURE_LENGTH/2]; // we must use separate buffer because signature might be inside buf
  159. EncodePoint (Normalize (MulB (digest, bnCtx), bnCtx), R);
  160. // calculate S
  161. SHA512_Init (&ctx);
  162. SHA512_Update (&ctx, R, EDDSA25519_SIGNATURE_LENGTH/2); // R
  163. SHA512_Update (&ctx, publicKeyEncoded, EDDSA25519_PUBLIC_KEY_LENGTH); // public key
  164. SHA512_Update (&ctx, buf, len); // data
  165. SHA512_Final (digest, &ctx);
  166. BIGNUM * h = DecodeBN<64> (digest);
  167. // S = (r + h*a) % l
  168. BIGNUM * a = DecodeBN<EDDSA25519_PRIVATE_KEY_LENGTH> (privateKey);
  169. BN_mod_mul (h, h, a, l, bnCtx); // %l
  170. BN_mod_add (h, h, r, l, bnCtx); // %l
  171. memcpy (signature, R, EDDSA25519_SIGNATURE_LENGTH/2);
  172. EncodeBN (h, signature + EDDSA25519_SIGNATURE_LENGTH/2, EDDSA25519_SIGNATURE_LENGTH/2); // S
  173. BN_free (r); BN_free (h); BN_free (a);
  174. BN_CTX_free (bnCtx);
  175. }
  176. EDDSAPoint Ed25519::Sum (const EDDSAPoint& p1, const EDDSAPoint& p2, BN_CTX * ctx) const
  177. {
  178. // x3 = (x1*y2+y1*x2)*(z1*z2-d*t1*t2)
  179. // y3 = (y1*y2+x1*x2)*(z1*z2+d*t1*t2)
  180. // z3 = (z1*z2-d*t1*t2)*(z1*z2+d*t1*t2)
  181. // t3 = (y1*y2+x1*x2)*(x1*y2+y1*x2)
  182. BIGNUM * x3 = BN_new (), * y3 = BN_new (), * z3 = BN_new (), * t3 = BN_new ();
  183. BN_mul (x3, p1.x, p2.x, ctx); // A = x1*x2
  184. BN_mul (y3, p1.y, p2.y, ctx); // B = y1*y2
  185. BN_CTX_start (ctx);
  186. BIGNUM * t1 = p1.t, * t2 = p2.t;
  187. if (!t1) { t1 = BN_CTX_get (ctx); BN_mul (t1, p1.x, p1.y, ctx); }
  188. if (!t2) { t2 = BN_CTX_get (ctx); BN_mul (t2, p2.x, p2.y, ctx); }
  189. BN_mul (t3, t1, t2, ctx);
  190. BN_mul (t3, t3, d, ctx); // C = d*t1*t2
  191. if (p1.z)
  192. {
  193. if (p2.z)
  194. BN_mul (z3, p1.z, p2.z, ctx); // D = z1*z2
  195. else
  196. BN_copy (z3, p1.z); // D = z1
  197. }
  198. else
  199. {
  200. if (p2.z)
  201. BN_copy (z3, p2.z); // D = z2
  202. else
  203. BN_one (z3); // D = 1
  204. }
  205. BIGNUM * E = BN_CTX_get (ctx), * F = BN_CTX_get (ctx), * G = BN_CTX_get (ctx), * H = BN_CTX_get (ctx);
  206. BN_add (E, p1.x, p1.y);
  207. BN_add (F, p2.x, p2.y);
  208. BN_mul (E, E, F, ctx); // (x1 + y1)*(x2 + y2)
  209. BN_sub (E, E, x3);
  210. BN_sub (E, E, y3); // E = (x1 + y1)*(x2 + y2) - A - B
  211. BN_sub (F, z3, t3); // F = D - C
  212. BN_add (G, z3, t3); // G = D + C
  213. BN_add (H, y3, x3); // H = B + A
  214. BN_mod_mul (x3, E, F, q, ctx); // x3 = E*F
  215. BN_mod_mul (y3, G, H, q, ctx); // y3 = G*H
  216. BN_mod_mul (z3, F, G, q, ctx); // z3 = F*G
  217. BN_mod_mul (t3, E, H, q, ctx); // t3 = E*H
  218. BN_CTX_end (ctx);
  219. return EDDSAPoint {x3, y3, z3, t3};
  220. }
  221. void Ed25519::Double (EDDSAPoint& p, BN_CTX * ctx) const
  222. {
  223. BN_CTX_start (ctx);
  224. BIGNUM * x2 = BN_CTX_get (ctx), * y2 = BN_CTX_get (ctx), * z2 = BN_CTX_get (ctx), * t2 = BN_CTX_get (ctx);
  225. BN_sqr (x2, p.x, ctx); // x2 = A = x^2
  226. BN_sqr (y2, p.y, ctx); // y2 = B = y^2
  227. if (p.t)
  228. BN_sqr (t2, p.t, ctx); // t2 = t^2
  229. else
  230. {
  231. BN_mul (t2, p.x, p.y, ctx); // t = x*y
  232. BN_sqr (t2, t2, ctx); // t2 = t^2
  233. }
  234. BN_mul (t2, t2, d, ctx); // t2 = C = d*t^2
  235. if (p.z)
  236. BN_sqr (z2, p.z, ctx); // z2 = D = z^2
  237. else
  238. BN_one (z2); // z2 = 1
  239. BIGNUM * E = BN_CTX_get (ctx), * F = BN_CTX_get (ctx), * G = BN_CTX_get (ctx), * H = BN_CTX_get (ctx);
  240. // E = (x+y)*(x+y)-A-B = x^2+y^2+2xy-A-B = 2xy
  241. BN_mul (E, p.x, p.y, ctx);
  242. BN_lshift1 (E, E); // E =2*x*y
  243. BN_sub (F, z2, t2); // F = D - C
  244. BN_add (G, z2, t2); // G = D + C
  245. BN_add (H, y2, x2); // H = B + A
  246. BN_mod_mul (p.x, E, F, q, ctx); // x2 = E*F
  247. BN_mod_mul (p.y, G, H, q, ctx); // y2 = G*H
  248. if (!p.z) p.z = BN_new ();
  249. BN_mod_mul (p.z, F, G, q, ctx); // z2 = F*G
  250. if (!p.t) p.t = BN_new ();
  251. BN_mod_mul (p.t, E, H, q, ctx); // t2 = E*H
  252. BN_CTX_end (ctx);
  253. }
  254. EDDSAPoint Ed25519::Mul (const EDDSAPoint& p, const BIGNUM * e, BN_CTX * ctx) const
  255. {
  256. BIGNUM * zero = BN_new (), * one = BN_new ();
  257. BN_zero (zero); BN_one (one);
  258. EDDSAPoint res {zero, one};
  259. if (!BN_is_zero (e))
  260. {
  261. int bitCount = BN_num_bits (e);
  262. for (int i = bitCount - 1; i >= 0; i--)
  263. {
  264. Double (res, ctx);
  265. if (BN_is_bit_set (e, i)) res = Sum (res, p, ctx);
  266. }
  267. }
  268. return res;
  269. }
  270. EDDSAPoint Ed25519::MulB (const uint8_t * e, BN_CTX * ctx) const // B*e, e is 32 bytes Little Endian
  271. {
  272. BIGNUM * zero = BN_new (), * one = BN_new ();
  273. BN_zero (zero); BN_one (one);
  274. EDDSAPoint res {zero, one};
  275. bool carry = false;
  276. for (int i = 0; i < 32; i++)
  277. {
  278. uint8_t x = e[i];
  279. if (carry)
  280. {
  281. if (x < 255)
  282. {
  283. x++;
  284. carry = false;
  285. }
  286. else
  287. x = 0;
  288. }
  289. if (x > 0)
  290. {
  291. if (x <= 128)
  292. res = Sum (res, Bi256[i][x-1], ctx);
  293. else
  294. {
  295. res = Sum (res, -Bi256[i][255-x], ctx); // -Bi[256-x]
  296. carry = true;
  297. }
  298. }
  299. }
  300. if (carry) res = Sum (res, Bi256Carry, ctx);
  301. return res;
  302. }
  303. EDDSAPoint Ed25519::Normalize (const EDDSAPoint& p, BN_CTX * ctx) const
  304. {
  305. if (p.z)
  306. {
  307. BIGNUM * x = BN_new (), * y = BN_new ();
  308. BN_mod_inverse (y, p.z, q, ctx);
  309. BN_mod_mul (x, p.x, y, q, ctx); // x = x/z
  310. BN_mod_mul (y, p.y, y, q, ctx); // y = y/z
  311. return EDDSAPoint{x, y};
  312. }
  313. else
  314. return EDDSAPoint{BN_dup (p.x), BN_dup (p.y)};
  315. }
  316. bool Ed25519::IsOnCurve (const EDDSAPoint& p, BN_CTX * ctx) const
  317. {
  318. BN_CTX_start (ctx);
  319. BIGNUM * x2 = BN_CTX_get (ctx), * y2 = BN_CTX_get (ctx), * tmp = BN_CTX_get (ctx);
  320. BN_sqr (x2, p.x, ctx); // x^2
  321. BN_sqr (y2, p.y, ctx); // y^2
  322. // y^2 - x^2 - 1 - d*x^2*y^2
  323. BN_mul (tmp, d, x2, ctx);
  324. BN_mul (tmp, tmp, y2, ctx);
  325. BN_sub (tmp, y2, tmp);
  326. BN_sub (tmp, tmp, x2);
  327. BN_sub_word (tmp, 1);
  328. BN_mod (tmp, tmp, q, ctx); // % q
  329. bool ret = BN_is_zero (tmp);
  330. BN_CTX_end (ctx);
  331. return ret;
  332. }
  333. BIGNUM * Ed25519::RecoverX (const BIGNUM * y, BN_CTX * ctx) const
  334. {
  335. BN_CTX_start (ctx);
  336. BIGNUM * y2 = BN_CTX_get (ctx), * xx = BN_CTX_get (ctx);
  337. BN_sqr (y2, y, ctx); // y^2
  338. // xx = (y^2 -1)*inv(d*y^2 +1)
  339. BN_mul (xx, d, y2, ctx);
  340. BN_add_word (xx, 1);
  341. BN_mod_inverse (xx, xx, q, ctx);
  342. BN_sub_word (y2, 1);
  343. BN_mul (xx, y2, xx, ctx);
  344. // x = srqt(xx) = xx^(2^252-2)
  345. BIGNUM * x = BN_new ();
  346. BN_mod_exp (x, xx, two_252_2, q, ctx);
  347. // check (x^2 -xx) % q
  348. BN_sqr (y2, x, ctx);
  349. BN_mod_sub (y2, y2, xx, q, ctx);
  350. if (!BN_is_zero (y2))
  351. BN_mod_mul (x, x, I, q, ctx);
  352. if (BN_is_odd (x))
  353. BN_sub (x, q, x);
  354. BN_CTX_end (ctx);
  355. return x;
  356. }
  357. EDDSAPoint Ed25519::DecodePoint (const uint8_t * buf, BN_CTX * ctx) const
  358. {
  359. // buf is 32 bytes Little Endian, convert it to Big Endian
  360. uint8_t buf1[EDDSA25519_PUBLIC_KEY_LENGTH];
  361. for (size_t i = 0; i < EDDSA25519_PUBLIC_KEY_LENGTH/2; i++) // invert bytes
  362. {
  363. buf1[i] = buf[EDDSA25519_PUBLIC_KEY_LENGTH -1 - i];
  364. buf1[EDDSA25519_PUBLIC_KEY_LENGTH -1 - i] = buf[i];
  365. }
  366. bool isHighestBitSet = buf1[0] & 0x80;
  367. if (isHighestBitSet)
  368. buf1[0] &= 0x7f; // clear highest bit
  369. BIGNUM * y = BN_new ();
  370. BN_bin2bn (buf1, EDDSA25519_PUBLIC_KEY_LENGTH, y);
  371. BIGNUM * x = RecoverX (y, ctx);
  372. if (BN_is_bit_set (x, 0) != isHighestBitSet)
  373. BN_sub (x, q, x); // x = q - x
  374. BIGNUM * z = BN_new (), * t = BN_new ();
  375. BN_one (z); BN_mod_mul (t, x, y, q, ctx); // pre-calculate t
  376. EDDSAPoint p {x, y, z, t};
  377. if (!IsOnCurve (p, ctx))
  378. LogPrint (eLogError, "Decoded point is not on 25519");
  379. return p;
  380. }
  381. void Ed25519::EncodePoint (const EDDSAPoint& p, uint8_t * buf) const
  382. {
  383. EncodeBN (p.y, buf,EDDSA25519_PUBLIC_KEY_LENGTH);
  384. if (BN_is_bit_set (p.x, 0)) // highest bit
  385. buf[EDDSA25519_PUBLIC_KEY_LENGTH - 1] |= 0x80; // set highest bit
  386. }
  387. template<int len>
  388. BIGNUM * Ed25519::DecodeBN (const uint8_t * buf) const
  389. {
  390. // buf is Little Endian convert it to Big Endian
  391. uint8_t buf1[len];
  392. for (size_t i = 0; i < len/2; i++) // invert bytes
  393. {
  394. buf1[i] = buf[len -1 - i];
  395. buf1[len -1 - i] = buf[i];
  396. }
  397. BIGNUM * res = BN_new ();
  398. BN_bin2bn (buf1, len, res);
  399. return res;
  400. }
  401. void Ed25519::EncodeBN (const BIGNUM * bn, uint8_t * buf, size_t len) const
  402. {
  403. bn2buf (bn, buf, len);
  404. // To Little Endian
  405. for (size_t i = 0; i < len/2; i++) // invert bytes
  406. {
  407. uint8_t tmp = buf[i];
  408. buf[i] = buf[len -1 - i];
  409. buf[len -1 - i] = tmp;
  410. }
  411. }
  412. #if !OPENSSL_X25519
  413. BIGNUM * Ed25519::ScalarMul (const BIGNUM * u, const BIGNUM * k, BN_CTX * ctx) const
  414. {
  415. BN_CTX_start (ctx);
  416. auto x1 = BN_CTX_get (ctx); BN_copy (x1, u);
  417. auto x2 = BN_CTX_get (ctx); BN_one (x2);
  418. auto z2 = BN_CTX_get (ctx); BN_zero (z2);
  419. auto x3 = BN_CTX_get (ctx); BN_copy (x3, u);
  420. auto z3 = BN_CTX_get (ctx); BN_one (z3);
  421. auto c121666 = BN_CTX_get (ctx); BN_set_word (c121666, 121666);
  422. auto tmp0 = BN_CTX_get (ctx); auto tmp1 = BN_CTX_get (ctx);
  423. unsigned int swap = 0;
  424. auto bits = BN_num_bits (k);
  425. while(bits)
  426. {
  427. --bits;
  428. auto k_t = BN_is_bit_set(k, bits) ? 1 : 0;
  429. swap ^= k_t;
  430. if (swap)
  431. {
  432. std::swap (x2, x3);
  433. std::swap (z2, z3);
  434. }
  435. swap = k_t;
  436. BN_mod_sub(tmp0, x3, z3, q, ctx);
  437. BN_mod_sub(tmp1, x2, z2, q, ctx);
  438. BN_mod_add(x2, x2, z2, q, ctx);
  439. BN_mod_add(z2, x3, z3, q, ctx);
  440. BN_mod_mul(z3, tmp0, x2, q, ctx);
  441. BN_mod_mul(z2, z2, tmp1, q, ctx);
  442. BN_mod_sqr(tmp0, tmp1, q, ctx);
  443. BN_mod_sqr(tmp1, x2, q, ctx);
  444. BN_mod_add(x3, z3, z2, q, ctx);
  445. BN_mod_sub(z2, z3, z2, q, ctx);
  446. BN_mod_mul(x2, tmp1, tmp0, q, ctx);
  447. BN_mod_sub(tmp1, tmp1, tmp0, q, ctx);
  448. BN_mod_sqr(z2, z2, q, ctx);
  449. BN_mod_mul(z3, tmp1, c121666, q, ctx);
  450. BN_mod_sqr(x3, x3, q, ctx);
  451. BN_mod_add(tmp0, tmp0, z3, q, ctx);
  452. BN_mod_mul(z3, x1, z2, q, ctx);
  453. BN_mod_mul(z2, tmp1, tmp0, q, ctx);
  454. }
  455. if (swap)
  456. {
  457. std::swap (x2, x3);
  458. std::swap (z2, z3);
  459. }
  460. BN_mod_inverse (z2, z2, q, ctx);
  461. BIGNUM * res = BN_new (); // not from ctx
  462. BN_mod_mul(res, x2, z2, q, ctx);
  463. BN_CTX_end (ctx);
  464. return res;
  465. }
  466. void Ed25519::ScalarMul (const uint8_t * p, const uint8_t * e, uint8_t * buf, BN_CTX * ctx) const
  467. {
  468. BIGNUM * p1 = DecodeBN<32> (p);
  469. uint8_t k[32];
  470. memcpy (k, e, 32);
  471. k[0] &= 248; k[31] &= 127; k[31] |= 64;
  472. BIGNUM * n = DecodeBN<32> (k);
  473. BIGNUM * q1 = ScalarMul (p1, n, ctx);
  474. EncodeBN (q1, buf, 32);
  475. BN_free (p1); BN_free (n); BN_free (q1);
  476. }
  477. void Ed25519::ScalarMulB (const uint8_t * e, uint8_t * buf, BN_CTX * ctx) const
  478. {
  479. BIGNUM *p1 = BN_new (); BN_set_word (p1, 9);
  480. uint8_t k[32];
  481. memcpy (k, e, 32);
  482. k[0] &= 248; k[31] &= 127; k[31] |= 64;
  483. BIGNUM * n = DecodeBN<32> (k);
  484. BIGNUM * q1 = ScalarMul (p1, n, ctx);
  485. EncodeBN (q1, buf, 32);
  486. BN_free (p1); BN_free (n); BN_free (q1);
  487. }
  488. #endif
  489. void Ed25519::BlindPublicKey (const uint8_t * pub, const uint8_t * seed, uint8_t * blinded)
  490. {
  491. BN_CTX * ctx = BN_CTX_new ();
  492. // calculate alpha = seed mod l
  493. BIGNUM * alpha = DecodeBN<64> (seed); // seed is in Little Endian
  494. BN_mod (alpha, alpha, l, ctx); // % l
  495. uint8_t priv[32];
  496. EncodeBN (alpha, priv, 32); // back to Little Endian
  497. BN_free (alpha);
  498. // A' = BLIND_PUBKEY(A, alpha) = A + DERIVE_PUBLIC(alpha)
  499. auto A1 = Sum (DecodePublicKey (pub, ctx), MulB (priv, ctx), ctx); // pub + B*alpha
  500. EncodePublicKey (A1, blinded, ctx);
  501. BN_CTX_free (ctx);
  502. }
  503. void Ed25519::BlindPrivateKey (const uint8_t * priv, const uint8_t * seed, uint8_t * blindedPriv, uint8_t * blindedPub)
  504. {
  505. BN_CTX * ctx = BN_CTX_new ();
  506. // calculate alpha = seed mod l
  507. BIGNUM * alpha = DecodeBN<64> (seed); // seed is in Little Endian
  508. BN_mod (alpha, alpha, l, ctx); // % l
  509. BIGNUM * p = DecodeBN<32> (priv); // priv is in Little Endian
  510. BN_add (alpha, alpha, p); // alpha = alpha + priv
  511. // a' = BLIND_PRIVKEY(a, alpha) = (a + alpha) mod L
  512. BN_mod (alpha, alpha, l, ctx); // % l
  513. EncodeBN (alpha, blindedPriv, 32);
  514. // A' = DERIVE_PUBLIC(a')
  515. auto A1 = MulB (blindedPriv, ctx);
  516. EncodePublicKey (A1, blindedPub, ctx);
  517. BN_free (alpha); BN_free (p);
  518. BN_CTX_free (ctx);
  519. }
  520. void Ed25519::ExpandPrivateKey (const uint8_t * key, uint8_t * expandedKey)
  521. {
  522. SHA512 (key, EDDSA25519_PRIVATE_KEY_LENGTH, expandedKey);
  523. expandedKey[0] &= 0xF8; // drop last 3 bits
  524. expandedKey[EDDSA25519_PRIVATE_KEY_LENGTH - 1] &= 0x3F; // drop first 2 bits
  525. expandedKey[EDDSA25519_PRIVATE_KEY_LENGTH - 1] |= 0x40; // set second bit
  526. }
  527. void Ed25519::CreateRedDSAPrivateKey (uint8_t * priv)
  528. {
  529. uint8_t seed[32];
  530. RAND_bytes (seed, 32);
  531. BIGNUM * p = DecodeBN<32> (seed);
  532. BN_CTX * ctx = BN_CTX_new ();
  533. BN_mod (p, p, l, ctx); // % l
  534. EncodeBN (p, priv, 32);
  535. BN_CTX_free (ctx);
  536. BN_free (p);
  537. }
  538. static std::unique_ptr<Ed25519> g_Ed25519;
  539. std::unique_ptr<Ed25519>& GetEd25519 ()
  540. {
  541. if (!g_Ed25519)
  542. {
  543. auto c = new Ed25519();
  544. if (!g_Ed25519) // make sure it was not created already
  545. g_Ed25519.reset (c);
  546. else
  547. delete c;
  548. }
  549. return g_Ed25519;
  550. }
  551. }
  552. }