fe25519.c 8.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338
  1. /* $OpenBSD: fe25519.c,v 1.3 2013/12/09 11:03:45 markus Exp $ */
  2. /*
  3. * Public Domain, Authors: Daniel J. Bernstein, Niels Duif, Tanja Lange,
  4. * Peter Schwabe, Bo-Yin Yang.
  5. * Copied from supercop-20130419/crypto_sign/ed25519/ref/fe25519.c
  6. */
  7. #include "includes.h"
  8. #define WINDOWSIZE 1 /* Should be 1,2, or 4 */
  9. #define WINDOWMASK ((1<<WINDOWSIZE)-1)
  10. #include "fe25519.h"
  11. static crypto_uint32 equal(crypto_uint32 a,crypto_uint32 b) /* 16-bit inputs */
  12. {
  13. crypto_uint32 x = a ^ b; /* 0: yes; 1..65535: no */
  14. x -= 1; /* 4294967295: yes; 0..65534: no */
  15. x >>= 31; /* 1: yes; 0: no */
  16. return x;
  17. }
  18. static crypto_uint32 ge(crypto_uint32 a,crypto_uint32 b) /* 16-bit inputs */
  19. {
  20. unsigned int x = a;
  21. x -= (unsigned int) b; /* 0..65535: yes; 4294901761..4294967295: no */
  22. x >>= 31; /* 0: yes; 1: no */
  23. x ^= 1; /* 1: yes; 0: no */
  24. return x;
  25. }
  26. static crypto_uint32 times19(crypto_uint32 a)
  27. {
  28. return (a << 4) + (a << 1) + a;
  29. }
  30. static crypto_uint32 times38(crypto_uint32 a)
  31. {
  32. return (a << 5) + (a << 2) + (a << 1);
  33. }
  34. static void reduce_add_sub(fe25519 *r)
  35. {
  36. crypto_uint32 t;
  37. int i,rep;
  38. for(rep=0;rep<4;rep++)
  39. {
  40. t = r->v[31] >> 7;
  41. r->v[31] &= 127;
  42. t = times19(t);
  43. r->v[0] += t;
  44. for(i=0;i<31;i++)
  45. {
  46. t = r->v[i] >> 8;
  47. r->v[i+1] += t;
  48. r->v[i] &= 255;
  49. }
  50. }
  51. }
  52. static void reduce_mul(fe25519 *r)
  53. {
  54. crypto_uint32 t;
  55. int i,rep;
  56. for(rep=0;rep<2;rep++)
  57. {
  58. t = r->v[31] >> 7;
  59. r->v[31] &= 127;
  60. t = times19(t);
  61. r->v[0] += t;
  62. for(i=0;i<31;i++)
  63. {
  64. t = r->v[i] >> 8;
  65. r->v[i+1] += t;
  66. r->v[i] &= 255;
  67. }
  68. }
  69. }
  70. /* reduction modulo 2^255-19 */
  71. void fe25519_freeze(fe25519 *r)
  72. {
  73. int i;
  74. crypto_uint32 m = equal(r->v[31],127);
  75. for(i=30;i>0;i--)
  76. m &= equal(r->v[i],255);
  77. m &= ge(r->v[0],237);
  78. m = -m;
  79. r->v[31] -= m&127;
  80. for(i=30;i>0;i--)
  81. r->v[i] -= m&255;
  82. r->v[0] -= m&237;
  83. }
  84. void fe25519_unpack(fe25519 *r, const unsigned char x[32])
  85. {
  86. int i;
  87. for(i=0;i<32;i++) r->v[i] = x[i];
  88. r->v[31] &= 127;
  89. }
  90. /* Assumes input x being reduced below 2^255 */
  91. void fe25519_pack(unsigned char r[32], const fe25519 *x)
  92. {
  93. int i;
  94. fe25519 y = *x;
  95. fe25519_freeze(&y);
  96. for(i=0;i<32;i++)
  97. r[i] = y.v[i];
  98. }
  99. int fe25519_iszero(const fe25519 *x)
  100. {
  101. int i;
  102. int r;
  103. fe25519 t = *x;
  104. fe25519_freeze(&t);
  105. r = equal(t.v[0],0);
  106. for(i=1;i<32;i++)
  107. r &= equal(t.v[i],0);
  108. return r;
  109. }
  110. int fe25519_iseq_vartime(const fe25519 *x, const fe25519 *y)
  111. {
  112. int i;
  113. fe25519 t1 = *x;
  114. fe25519 t2 = *y;
  115. fe25519_freeze(&t1);
  116. fe25519_freeze(&t2);
  117. for(i=0;i<32;i++)
  118. if(t1.v[i] != t2.v[i]) return 0;
  119. return 1;
  120. }
  121. void fe25519_cmov(fe25519 *r, const fe25519 *x, unsigned char b)
  122. {
  123. int i;
  124. crypto_uint32 mask = b;
  125. mask = -mask;
  126. for(i=0;i<32;i++) r->v[i] ^= mask & (x->v[i] ^ r->v[i]);
  127. }
  128. unsigned char fe25519_getparity(const fe25519 *x)
  129. {
  130. fe25519 t = *x;
  131. fe25519_freeze(&t);
  132. return t.v[0] & 1;
  133. }
  134. void fe25519_setone(fe25519 *r)
  135. {
  136. int i;
  137. r->v[0] = 1;
  138. for(i=1;i<32;i++) r->v[i]=0;
  139. }
  140. void fe25519_setzero(fe25519 *r)
  141. {
  142. int i;
  143. for(i=0;i<32;i++) r->v[i]=0;
  144. }
  145. void fe25519_neg(fe25519 *r, const fe25519 *x)
  146. {
  147. fe25519 t;
  148. int i;
  149. for(i=0;i<32;i++) t.v[i]=x->v[i];
  150. fe25519_setzero(r);
  151. fe25519_sub(r, r, &t);
  152. }
  153. void fe25519_add(fe25519 *r, const fe25519 *x, const fe25519 *y)
  154. {
  155. int i;
  156. for(i=0;i<32;i++) r->v[i] = x->v[i] + y->v[i];
  157. reduce_add_sub(r);
  158. }
  159. void fe25519_sub(fe25519 *r, const fe25519 *x, const fe25519 *y)
  160. {
  161. int i;
  162. crypto_uint32 t[32];
  163. t[0] = x->v[0] + 0x1da;
  164. t[31] = x->v[31] + 0xfe;
  165. for(i=1;i<31;i++) t[i] = x->v[i] + 0x1fe;
  166. for(i=0;i<32;i++) r->v[i] = t[i] - y->v[i];
  167. reduce_add_sub(r);
  168. }
  169. void fe25519_mul(fe25519 *r, const fe25519 *x, const fe25519 *y)
  170. {
  171. int i,j;
  172. crypto_uint32 t[63];
  173. for(i=0;i<63;i++)t[i] = 0;
  174. for(i=0;i<32;i++)
  175. for(j=0;j<32;j++)
  176. t[i+j] += x->v[i] * y->v[j];
  177. for(i=32;i<63;i++)
  178. r->v[i-32] = t[i-32] + times38(t[i]);
  179. r->v[31] = t[31]; /* result now in r[0]...r[31] */
  180. reduce_mul(r);
  181. }
  182. void fe25519_square(fe25519 *r, const fe25519 *x)
  183. {
  184. fe25519_mul(r, x, x);
  185. }
  186. void fe25519_invert(fe25519 *r, const fe25519 *x)
  187. {
  188. fe25519 z2;
  189. fe25519 z9;
  190. fe25519 z11;
  191. fe25519 z2_5_0;
  192. fe25519 z2_10_0;
  193. fe25519 z2_20_0;
  194. fe25519 z2_50_0;
  195. fe25519 z2_100_0;
  196. fe25519 t0;
  197. fe25519 t1;
  198. int i;
  199. /* 2 */ fe25519_square(&z2,x);
  200. /* 4 */ fe25519_square(&t1,&z2);
  201. /* 8 */ fe25519_square(&t0,&t1);
  202. /* 9 */ fe25519_mul(&z9,&t0,x);
  203. /* 11 */ fe25519_mul(&z11,&z9,&z2);
  204. /* 22 */ fe25519_square(&t0,&z11);
  205. /* 2^5 - 2^0 = 31 */ fe25519_mul(&z2_5_0,&t0,&z9);
  206. /* 2^6 - 2^1 */ fe25519_square(&t0,&z2_5_0);
  207. /* 2^7 - 2^2 */ fe25519_square(&t1,&t0);
  208. /* 2^8 - 2^3 */ fe25519_square(&t0,&t1);
  209. /* 2^9 - 2^4 */ fe25519_square(&t1,&t0);
  210. /* 2^10 - 2^5 */ fe25519_square(&t0,&t1);
  211. /* 2^10 - 2^0 */ fe25519_mul(&z2_10_0,&t0,&z2_5_0);
  212. /* 2^11 - 2^1 */ fe25519_square(&t0,&z2_10_0);
  213. /* 2^12 - 2^2 */ fe25519_square(&t1,&t0);
  214. /* 2^20 - 2^10 */ for (i = 2;i < 10;i += 2) { fe25519_square(&t0,&t1); fe25519_square(&t1,&t0); }
  215. /* 2^20 - 2^0 */ fe25519_mul(&z2_20_0,&t1,&z2_10_0);
  216. /* 2^21 - 2^1 */ fe25519_square(&t0,&z2_20_0);
  217. /* 2^22 - 2^2 */ fe25519_square(&t1,&t0);
  218. /* 2^40 - 2^20 */ for (i = 2;i < 20;i += 2) { fe25519_square(&t0,&t1); fe25519_square(&t1,&t0); }
  219. /* 2^40 - 2^0 */ fe25519_mul(&t0,&t1,&z2_20_0);
  220. /* 2^41 - 2^1 */ fe25519_square(&t1,&t0);
  221. /* 2^42 - 2^2 */ fe25519_square(&t0,&t1);
  222. /* 2^50 - 2^10 */ for (i = 2;i < 10;i += 2) { fe25519_square(&t1,&t0); fe25519_square(&t0,&t1); }
  223. /* 2^50 - 2^0 */ fe25519_mul(&z2_50_0,&t0,&z2_10_0);
  224. /* 2^51 - 2^1 */ fe25519_square(&t0,&z2_50_0);
  225. /* 2^52 - 2^2 */ fe25519_square(&t1,&t0);
  226. /* 2^100 - 2^50 */ for (i = 2;i < 50;i += 2) { fe25519_square(&t0,&t1); fe25519_square(&t1,&t0); }
  227. /* 2^100 - 2^0 */ fe25519_mul(&z2_100_0,&t1,&z2_50_0);
  228. /* 2^101 - 2^1 */ fe25519_square(&t1,&z2_100_0);
  229. /* 2^102 - 2^2 */ fe25519_square(&t0,&t1);
  230. /* 2^200 - 2^100 */ for (i = 2;i < 100;i += 2) { fe25519_square(&t1,&t0); fe25519_square(&t0,&t1); }
  231. /* 2^200 - 2^0 */ fe25519_mul(&t1,&t0,&z2_100_0);
  232. /* 2^201 - 2^1 */ fe25519_square(&t0,&t1);
  233. /* 2^202 - 2^2 */ fe25519_square(&t1,&t0);
  234. /* 2^250 - 2^50 */ for (i = 2;i < 50;i += 2) { fe25519_square(&t0,&t1); fe25519_square(&t1,&t0); }
  235. /* 2^250 - 2^0 */ fe25519_mul(&t0,&t1,&z2_50_0);
  236. /* 2^251 - 2^1 */ fe25519_square(&t1,&t0);
  237. /* 2^252 - 2^2 */ fe25519_square(&t0,&t1);
  238. /* 2^253 - 2^3 */ fe25519_square(&t1,&t0);
  239. /* 2^254 - 2^4 */ fe25519_square(&t0,&t1);
  240. /* 2^255 - 2^5 */ fe25519_square(&t1,&t0);
  241. /* 2^255 - 21 */ fe25519_mul(r,&t1,&z11);
  242. }
  243. void fe25519_pow2523(fe25519 *r, const fe25519 *x)
  244. {
  245. fe25519 z2;
  246. fe25519 z9;
  247. fe25519 z11;
  248. fe25519 z2_5_0;
  249. fe25519 z2_10_0;
  250. fe25519 z2_20_0;
  251. fe25519 z2_50_0;
  252. fe25519 z2_100_0;
  253. fe25519 t;
  254. int i;
  255. /* 2 */ fe25519_square(&z2,x);
  256. /* 4 */ fe25519_square(&t,&z2);
  257. /* 8 */ fe25519_square(&t,&t);
  258. /* 9 */ fe25519_mul(&z9,&t,x);
  259. /* 11 */ fe25519_mul(&z11,&z9,&z2);
  260. /* 22 */ fe25519_square(&t,&z11);
  261. /* 2^5 - 2^0 = 31 */ fe25519_mul(&z2_5_0,&t,&z9);
  262. /* 2^6 - 2^1 */ fe25519_square(&t,&z2_5_0);
  263. /* 2^10 - 2^5 */ for (i = 1;i < 5;i++) { fe25519_square(&t,&t); }
  264. /* 2^10 - 2^0 */ fe25519_mul(&z2_10_0,&t,&z2_5_0);
  265. /* 2^11 - 2^1 */ fe25519_square(&t,&z2_10_0);
  266. /* 2^20 - 2^10 */ for (i = 1;i < 10;i++) { fe25519_square(&t,&t); }
  267. /* 2^20 - 2^0 */ fe25519_mul(&z2_20_0,&t,&z2_10_0);
  268. /* 2^21 - 2^1 */ fe25519_square(&t,&z2_20_0);
  269. /* 2^40 - 2^20 */ for (i = 1;i < 20;i++) { fe25519_square(&t,&t); }
  270. /* 2^40 - 2^0 */ fe25519_mul(&t,&t,&z2_20_0);
  271. /* 2^41 - 2^1 */ fe25519_square(&t,&t);
  272. /* 2^50 - 2^10 */ for (i = 1;i < 10;i++) { fe25519_square(&t,&t); }
  273. /* 2^50 - 2^0 */ fe25519_mul(&z2_50_0,&t,&z2_10_0);
  274. /* 2^51 - 2^1 */ fe25519_square(&t,&z2_50_0);
  275. /* 2^100 - 2^50 */ for (i = 1;i < 50;i++) { fe25519_square(&t,&t); }
  276. /* 2^100 - 2^0 */ fe25519_mul(&z2_100_0,&t,&z2_50_0);
  277. /* 2^101 - 2^1 */ fe25519_square(&t,&z2_100_0);
  278. /* 2^200 - 2^100 */ for (i = 1;i < 100;i++) { fe25519_square(&t,&t); }
  279. /* 2^200 - 2^0 */ fe25519_mul(&t,&t,&z2_100_0);
  280. /* 2^201 - 2^1 */ fe25519_square(&t,&t);
  281. /* 2^250 - 2^50 */ for (i = 1;i < 50;i++) { fe25519_square(&t,&t); }
  282. /* 2^250 - 2^0 */ fe25519_mul(&t,&t,&z2_50_0);
  283. /* 2^251 - 2^1 */ fe25519_square(&t,&t);
  284. /* 2^252 - 2^2 */ fe25519_square(&t,&t);
  285. /* 2^252 - 3 */ fe25519_mul(r,&t,x);
  286. }