ed25519.c 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318
  1. /*
  2. Public domain by Andrew M. <liquidsun@gmail.com>
  3. Ed25519 reference implementation using Ed25519-donna
  4. */
  5. /* define ED25519_SUFFIX to have it appended to the end of each public function */
  6. #ifdef ED25519_SUFFIX
  7. #define ED25519_FN3(fn,suffix) fn##suffix
  8. #define ED25519_FN2(fn,suffix) ED25519_FN3(fn,suffix)
  9. #define ED25519_FN(fn) ED25519_FN2(fn,ED25519_SUFFIX)
  10. #else
  11. #define ED25519_FN(fn) fn
  12. #endif
  13. #include "ed25519-donna.h"
  14. #include "ed25519.h"
  15. #include "ed25519-hash-custom.h"
  16. #include "../rand.h"
  17. #include "../memzero.h"
  18. /*
  19. Generates a (extsk[0..31]) and aExt (extsk[32..63])
  20. */
  21. DONNA_INLINE static void
  22. ed25519_extsk(hash_512bits extsk, const ed25519_secret_key sk) {
  23. ed25519_hash(extsk, sk, 32);
  24. extsk[0] &= 248;
  25. extsk[31] &= 127;
  26. extsk[31] |= 64;
  27. }
  28. static void
  29. ed25519_hram(hash_512bits hram, const ed25519_public_key R, const ed25519_public_key pk, const unsigned char *m, size_t mlen) {
  30. ed25519_hash_context ctx;
  31. ed25519_hash_init(&ctx);
  32. ed25519_hash_update(&ctx, R, 32);
  33. ed25519_hash_update(&ctx, pk, 32);
  34. ed25519_hash_update(&ctx, m, mlen);
  35. ed25519_hash_final(&ctx, hram);
  36. }
  37. void
  38. ED25519_FN(ed25519_publickey) (const ed25519_secret_key sk, ed25519_public_key pk) {
  39. hash_512bits extsk = {0};
  40. ed25519_extsk(extsk, sk);
  41. ed25519_publickey_ext(extsk, pk);
  42. memzero(&extsk, sizeof(extsk));
  43. }
  44. void
  45. ED25519_FN(ed25519_cosi_commit) (ed25519_secret_key nonce, ed25519_public_key commitment) {
  46. bignum256modm r = {0};
  47. ge25519 ALIGN(16) R;
  48. unsigned char extnonce[64] = {0};
  49. /* r = random512 mod L */
  50. random_buffer(extnonce, sizeof(extnonce));
  51. expand256_modm(r, extnonce, sizeof(extnonce));
  52. memzero(&extnonce, sizeof(extnonce));
  53. contract256_modm(nonce, r);
  54. /* R = rB */
  55. ge25519_scalarmult_base_niels(&R, ge25519_niels_base_multiples, r);
  56. memzero(&r, sizeof(r));
  57. ge25519_pack(commitment, &R);
  58. }
  59. int
  60. ED25519_FN(ed25519_cosi_sign) (const unsigned char *m, size_t mlen, const ed25519_secret_key sk, const ed25519_secret_key nonce, const ed25519_public_key R, const ed25519_public_key pk, ed25519_cosi_signature sig) {
  61. bignum256modm r = {0}, S = {0}, a = {0};
  62. hash_512bits extsk = {0}, hram = {0};
  63. ed25519_extsk(extsk, sk);
  64. /* r */
  65. expand_raw256_modm(r, nonce);
  66. if (!is_reduced256_modm(r))
  67. return -1;
  68. /* S = H(R,A,m).. */
  69. ed25519_hram(hram, R, pk, m, mlen);
  70. expand256_modm(S, hram, 64);
  71. /* S = H(R,A,m)a */
  72. expand256_modm(a, extsk, 32);
  73. memzero(&extsk, sizeof(extsk));
  74. mul256_modm(S, S, a);
  75. memzero(&a, sizeof(a));
  76. /* S = (r + H(R,A,m)a) */
  77. add256_modm(S, S, r);
  78. memzero(&r, sizeof(r));
  79. /* S = (r + H(R,A,m)a) mod L */
  80. contract256_modm(sig, S);
  81. return 0;
  82. }
  83. void
  84. ED25519_FN(ed25519_sign_ext) (const unsigned char *m, size_t mlen, const ed25519_secret_key sk, const ed25519_secret_key skext, ed25519_signature RS) {
  85. ed25519_hash_context ctx;
  86. bignum256modm r = {0}, S = {0}, a = {0};
  87. ge25519 ALIGN(16) R = {0};
  88. ge25519 ALIGN(16) A = {0};
  89. ed25519_public_key pk = {0};
  90. hash_512bits extsk = {0}, hashr = {0}, hram = {0};
  91. /* we don't stretch the key through hashing first since its already 64 bytes */
  92. memcpy(extsk, sk, 32);
  93. memcpy(extsk+32, skext, 32);
  94. /* r = H(aExt[32..64], m) */
  95. ed25519_hash_init(&ctx);
  96. ed25519_hash_update(&ctx, extsk + 32, 32);
  97. ed25519_hash_update(&ctx, m, mlen);
  98. ed25519_hash_final(&ctx, hashr);
  99. expand256_modm(r, hashr, 64);
  100. memzero(&hashr, sizeof(hashr));
  101. /* R = rB */
  102. ge25519_scalarmult_base_niels(&R, ge25519_niels_base_multiples, r);
  103. ge25519_pack(RS, &R);
  104. /* a = aExt[0..31] */
  105. expand256_modm(a, extsk, 32);
  106. memzero(&extsk, sizeof(extsk));
  107. /* A = aB */
  108. ge25519_scalarmult_base_niels(&A, ge25519_niels_base_multiples, a);
  109. ge25519_pack(pk, &A);
  110. /* S = H(R,A,m).. */
  111. ed25519_hram(hram, RS, pk, m, mlen);
  112. expand256_modm(S, hram, 64);
  113. /* S = H(R,A,m)a */
  114. mul256_modm(S, S, a);
  115. memzero(&a, sizeof(a));
  116. /* S = (r + H(R,A,m)a) */
  117. add256_modm(S, S, r);
  118. memzero(&r, sizeof(r));
  119. /* S = (r + H(R,A,m)a) mod L */
  120. contract256_modm(RS + 32, S);
  121. }
  122. void
  123. ED25519_FN(ed25519_sign) (const unsigned char *m, size_t mlen, const ed25519_secret_key sk, ed25519_signature RS) {
  124. hash_512bits extsk = {0};
  125. ed25519_extsk(extsk, sk);
  126. ED25519_FN(ed25519_sign_ext)(m, mlen, extsk, extsk + 32, RS);
  127. memzero(&extsk, sizeof(extsk));
  128. }
  129. int
  130. ED25519_FN(ed25519_sign_open) (const unsigned char *m, size_t mlen, const ed25519_public_key pk, const ed25519_signature RS) {
  131. ge25519 ALIGN(16) R = {0}, A = {0};
  132. hash_512bits hash = {0};
  133. bignum256modm hram = {0}, S = {0};
  134. unsigned char checkR[32] = {0};
  135. if ((RS[63] & 224) || !ge25519_unpack_negative_vartime(&A, pk))
  136. return -1;
  137. /* hram = H(R,A,m) */
  138. ed25519_hram(hash, RS, pk, m, mlen);
  139. expand256_modm(hram, hash, 64);
  140. /* S */
  141. expand_raw256_modm(S, RS + 32);
  142. if (!is_reduced256_modm(S))
  143. return -1;
  144. /* SB - H(R,A,m)A */
  145. ge25519_double_scalarmult_vartime(&R, &A, hram, S);
  146. ge25519_pack(checkR, &R);
  147. /* check that R = SB - H(R,A,m)A */
  148. return ed25519_verify(RS, checkR, 32) ? 0 : -1;
  149. }
  150. int
  151. ED25519_FN(ed25519_scalarmult) (ed25519_public_key res, const ed25519_secret_key sk, const ed25519_public_key pk) {
  152. bignum256modm a = {0};
  153. ge25519 ALIGN(16) A = {0}, P = {0};
  154. hash_512bits extsk = {0};
  155. ed25519_extsk(extsk, sk);
  156. expand256_modm(a, extsk, 32);
  157. memzero(&extsk, sizeof(extsk));
  158. if (!ge25519_unpack_negative_vartime(&P, pk)) {
  159. return -1;
  160. }
  161. ge25519_scalarmult(&A, &P, a);
  162. memzero(&a, sizeof(a));
  163. curve25519_neg(A.x, A.x);
  164. ge25519_pack(res, &A);
  165. return 0;
  166. }
  167. #ifndef ED25519_SUFFIX
  168. #include "curve25519-donna-scalarmult-base.h"
  169. void
  170. ed25519_publickey_ext(const ed25519_secret_key extsk, ed25519_public_key pk) {
  171. bignum256modm a = {0};
  172. ge25519 ALIGN(16) A = {0};
  173. expand256_modm(a, extsk, 32);
  174. /* A = aB */
  175. ge25519_scalarmult_base_niels(&A, ge25519_niels_base_multiples, a);
  176. memzero(&a, sizeof(a));
  177. ge25519_pack(pk, &A);
  178. }
  179. int
  180. ed25519_cosi_combine_publickeys(ed25519_public_key res, CONST ed25519_public_key *pks, size_t n) {
  181. size_t i = 0;
  182. ge25519 P = {0};
  183. ge25519_pniels sump = {0};
  184. ge25519_p1p1 sump1 = {0};
  185. if (n == 1) {
  186. memcpy(res, pks, sizeof(ed25519_public_key));
  187. return 0;
  188. }
  189. if (!ge25519_unpack_negative_vartime(&P, pks[i++])) {
  190. return -1;
  191. }
  192. ge25519_full_to_pniels(&sump, &P);
  193. while (i < n - 1) {
  194. if (!ge25519_unpack_negative_vartime(&P, pks[i++])) {
  195. return -1;
  196. }
  197. ge25519_pnielsadd(&sump, &P, &sump);
  198. }
  199. if (!ge25519_unpack_negative_vartime(&P, pks[i++])) {
  200. return -1;
  201. }
  202. ge25519_pnielsadd_p1p1(&sump1, &P, &sump, 0);
  203. ge25519_p1p1_to_partial(&P, &sump1);
  204. curve25519_neg(P.x, P.x);
  205. ge25519_pack(res, &P);
  206. return 0;
  207. }
  208. void
  209. ed25519_cosi_combine_signatures(ed25519_signature res, const ed25519_public_key R, CONST ed25519_cosi_signature *sigs, size_t n) {
  210. bignum256modm s = {0}, t = {0};
  211. size_t i = 0;
  212. expand256_modm(s, sigs[i++], 32);
  213. while (i < n) {
  214. expand256_modm(t, sigs[i++], 32);
  215. add256_modm(s, s, t);
  216. }
  217. memcpy(res, R, 32);
  218. contract256_modm(res + 32, s);
  219. }
  220. /*
  221. Fast Curve25519 basepoint scalar multiplication
  222. */
  223. void
  224. curve25519_scalarmult_basepoint(curve25519_key pk, const curve25519_key e) {
  225. curve25519_key ec = {0};
  226. bignum256modm s = {0};
  227. bignum25519 ALIGN(16) yplusz = {0}, zminusy = {0};
  228. ge25519 ALIGN(16) p = {0};
  229. size_t i = 0;
  230. /* clamp */
  231. for (i = 0; i < 32; i++) ec[i] = e[i];
  232. ec[0] &= 248;
  233. ec[31] &= 127;
  234. ec[31] |= 64;
  235. expand_raw256_modm(s, ec);
  236. memzero(&ec, sizeof(ec));
  237. /* scalar * basepoint */
  238. ge25519_scalarmult_base_niels(&p, ge25519_niels_base_multiples, s);
  239. memzero(&s, sizeof(s));
  240. /* u = (y + z) / (z - y) */
  241. curve25519_add(yplusz, p.y, p.z);
  242. curve25519_sub(zminusy, p.z, p.y);
  243. curve25519_recip(zminusy, zminusy);
  244. curve25519_mul(yplusz, yplusz, zminusy);
  245. curve25519_contract(pk, yplusz);
  246. }
  247. void
  248. curve25519_scalarmult(curve25519_key mypublic, const curve25519_key secret, const curve25519_key basepoint) {
  249. curve25519_key e = {0};
  250. size_t i = 0;
  251. for (i = 0;i < 32;++i) e[i] = secret[i];
  252. e[0] &= 0xf8;
  253. e[31] &= 0x7f;
  254. e[31] |= 0x40;
  255. curve25519_scalarmult_donna(mypublic, e, basepoint);
  256. memzero(&e, sizeof(e));
  257. }
  258. #endif // ED25519_SUFFIX