sc25519.c 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307
  1. /* $OpenBSD: sc25519.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/sc25519.c
  6. */
  7. #include <libwebsockets.h>
  8. #include "sc25519.h"
  9. /*Arithmetic modulo the group order m = 2^252 + 27742317777372353535851937790883648493 = 7237005577332262213973186563042994240857116359379907606001950938285454250989 */
  10. static const uint32_t m[32] = {0xED, 0xD3, 0xF5, 0x5C, 0x1A, 0x63, 0x12, 0x58, 0xD6, 0x9C, 0xF7, 0xA2, 0xDE, 0xF9, 0xDE, 0x14,
  11. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10};
  12. static const uint32_t mu[33] = {0x1B, 0x13, 0x2C, 0x0A, 0xA3, 0xE5, 0x9C, 0xED, 0xA7, 0x29, 0x63, 0x08, 0x5D, 0x21, 0x06, 0x21,
  13. 0xEB, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x0F};
  14. static uint32_t lt(uint32_t a,uint32_t b) /* 16-bit inputs */
  15. {
  16. unsigned int x = a;
  17. x -= (unsigned int) b; /* 0..65535: no; 4294901761..4294967295: yes */
  18. x >>= 31; /* 0: no; 1: yes */
  19. return x;
  20. }
  21. /* Reduce coefficients of r before calling sc_reduce_add_sub */
  22. static void sc_reduce_add_sub(sc25519 *r)
  23. {
  24. uint32_t pb = 0;
  25. uint32_t b;
  26. uint32_t mask;
  27. int i;
  28. unsigned char t[32];
  29. for(i=0;i<32;i++)
  30. {
  31. pb += m[i];
  32. b = lt(r->v[i],pb);
  33. t[i] = r->v[i]-pb+(b<<8);
  34. pb = b;
  35. }
  36. mask = b - 1;
  37. for(i=0;i<32;i++)
  38. r->v[i] ^= mask & (r->v[i] ^ t[i]);
  39. }
  40. /* Reduce coefficients of x before calling barrett_reduce */
  41. static void barrett_reduce(sc25519 *r, const uint32_t x[64])
  42. {
  43. /* See HAC, Alg. 14.42 */
  44. int i,j;
  45. uint32_t q2[66];
  46. uint32_t *q3 = q2 + 33;
  47. uint32_t r1[33];
  48. uint32_t r2[33];
  49. uint32_t carry;
  50. uint32_t pb = 0;
  51. uint32_t b;
  52. for (i = 0;i < 66;++i) q2[i] = 0;
  53. for (i = 0;i < 33;++i) r2[i] = 0;
  54. for(i=0;i<33;i++)
  55. for(j=0;j<33;j++)
  56. if(i+j >= 31) q2[i+j] += mu[i]*x[j+31];
  57. carry = q2[31] >> 8;
  58. q2[32] += carry;
  59. //carry = q2[32] >> 8;
  60. //q2[33] += carry;
  61. for(i=0;i<33;i++)r1[i] = x[i];
  62. for(i=0;i<32;i++)
  63. for(j=0;j<33;j++)
  64. if(i+j < 33) r2[i+j] += m[i]*q3[j];
  65. for(i=0;i<32;i++)
  66. {
  67. carry = r2[i] >> 8;
  68. r2[i+1] += carry;
  69. r2[i] &= 0xff;
  70. }
  71. for(i=0;i<32;i++)
  72. {
  73. pb += r2[i];
  74. b = lt(r1[i],pb);
  75. r->v[i] = r1[i]-pb+(b<<8);
  76. pb = b;
  77. }
  78. /* XXX: Can it really happen that r<0?, See HAC, Alg 14.42, Step 3
  79. * If so: Handle it here!
  80. */
  81. sc_reduce_add_sub(r);
  82. sc_reduce_add_sub(r);
  83. }
  84. void sc25519_from32bytes(sc25519 *r, const unsigned char x[32])
  85. {
  86. int i;
  87. uint32_t t[64];
  88. for(i=0;i<32;i++) t[i] = x[i];
  89. for(i=32;i<64;++i) t[i] = 0;
  90. barrett_reduce(r, t);
  91. }
  92. void shortsc25519_from16bytes(shortsc25519 *r, const unsigned char x[16])
  93. {
  94. int i;
  95. for(i=0;i<16;i++) r->v[i] = x[i];
  96. }
  97. void sc25519_from64bytes(sc25519 *r, const unsigned char x[64])
  98. {
  99. int i;
  100. uint32_t t[64];
  101. for(i=0;i<64;i++) t[i] = x[i];
  102. barrett_reduce(r, t);
  103. }
  104. void sc25519_from_shortsc(sc25519 *r, const shortsc25519 *x)
  105. {
  106. int i;
  107. for(i=0;i<16;i++)
  108. r->v[i] = x->v[i];
  109. for(i=0;i<16;i++)
  110. r->v[16+i] = 0;
  111. }
  112. void sc25519_to32bytes(unsigned char r[32], const sc25519 *x)
  113. {
  114. int i;
  115. for(i=0;i<32;i++) r[i] = x->v[i];
  116. }
  117. int sc25519_iszero_vartime(const sc25519 *x)
  118. {
  119. int i;
  120. for(i=0;i<32;i++)
  121. if(x->v[i] != 0) return 0;
  122. return 1;
  123. }
  124. int sc25519_isshort_vartime(const sc25519 *x)
  125. {
  126. int i;
  127. for(i=31;i>15;i--)
  128. if(x->v[i] != 0) return 0;
  129. return 1;
  130. }
  131. int sc25519_lt_vartime(const sc25519 *x, const sc25519 *y)
  132. {
  133. int i;
  134. for(i=31;i>=0;i--)
  135. {
  136. if(x->v[i] < y->v[i]) return 1;
  137. if(x->v[i] > y->v[i]) return 0;
  138. }
  139. return 0;
  140. }
  141. void sc25519_add(sc25519 *r, const sc25519 *x, const sc25519 *y)
  142. {
  143. int i, carry;
  144. for(i=0;i<32;i++) r->v[i] = x->v[i] + y->v[i];
  145. for(i=0;i<31;i++)
  146. {
  147. carry = r->v[i] >> 8;
  148. r->v[i+1] += carry;
  149. r->v[i] &= 0xff;
  150. }
  151. sc_reduce_add_sub(r);
  152. }
  153. void sc25519_sub_nored(sc25519 *r, const sc25519 *x, const sc25519 *y)
  154. {
  155. uint32_t b = 0;
  156. int i;
  157. for(i=0;i<32;i++)
  158. {
  159. uint32_t t = x->v[i] - y->v[i] - b;
  160. r->v[i] = t & 255;
  161. b = (t >> 8) & 1;
  162. }
  163. }
  164. void sc25519_mul(sc25519 *r, const sc25519 *x, const sc25519 *y)
  165. {
  166. int i,j,carry;
  167. uint32_t t[64];
  168. for(i=0;i<64;i++)t[i] = 0;
  169. for(i=0;i<32;i++)
  170. for(j=0;j<32;j++)
  171. t[i+j] += x->v[i] * y->v[j];
  172. /* Reduce coefficients */
  173. for(i=0;i<63;i++)
  174. {
  175. carry = t[i] >> 8;
  176. t[i+1] += carry;
  177. t[i] &= 0xff;
  178. }
  179. barrett_reduce(r, t);
  180. }
  181. void sc25519_mul_shortsc(sc25519 *r, const sc25519 *x, const shortsc25519 *y)
  182. {
  183. sc25519 t;
  184. sc25519_from_shortsc(&t, y);
  185. sc25519_mul(r, x, &t);
  186. }
  187. void sc25519_window3(signed char r[85], const sc25519 *s)
  188. {
  189. char carry;
  190. int i;
  191. for(i=0;i<10;i++)
  192. {
  193. r[8*i+0] = s->v[3*i+0] & 7;
  194. r[8*i+1] = (s->v[3*i+0] >> 3) & 7;
  195. r[8*i+2] = (s->v[3*i+0] >> 6) & 7;
  196. r[8*i+2] ^= (s->v[3*i+1] << 2) & 7;
  197. r[8*i+3] = (s->v[3*i+1] >> 1) & 7;
  198. r[8*i+4] = (s->v[3*i+1] >> 4) & 7;
  199. r[8*i+5] = (s->v[3*i+1] >> 7) & 7;
  200. r[8*i+5] ^= (s->v[3*i+2] << 1) & 7;
  201. r[8*i+6] = (s->v[3*i+2] >> 2) & 7;
  202. r[8*i+7] = (s->v[3*i+2] >> 5) & 7;
  203. }
  204. r[8*i+0] = s->v[3*i+0] & 7;
  205. r[8*i+1] = (s->v[3*i+0] >> 3) & 7;
  206. r[8*i+2] = (s->v[3*i+0] >> 6) & 7;
  207. r[8*i+2] ^= (s->v[3*i+1] << 2) & 7;
  208. r[8*i+3] = (s->v[3*i+1] >> 1) & 7;
  209. r[8*i+4] = (s->v[3*i+1] >> 4) & 7;
  210. /* Making it signed */
  211. carry = 0;
  212. for(i=0;i<84;i++)
  213. {
  214. r[i] += carry;
  215. r[i+1] += r[i] >> 3;
  216. r[i] &= 7;
  217. carry = r[i] >> 2;
  218. r[i] -= carry<<3;
  219. }
  220. r[84] += carry;
  221. }
  222. void sc25519_window5(signed char r[51], const sc25519 *s)
  223. {
  224. char carry;
  225. int i;
  226. for(i=0;i<6;i++)
  227. {
  228. r[8*i+0] = s->v[5*i+0] & 31;
  229. r[8*i+1] = (s->v[5*i+0] >> 5) & 31;
  230. r[8*i+1] ^= (s->v[5*i+1] << 3) & 31;
  231. r[8*i+2] = (s->v[5*i+1] >> 2) & 31;
  232. r[8*i+3] = (s->v[5*i+1] >> 7) & 31;
  233. r[8*i+3] ^= (s->v[5*i+2] << 1) & 31;
  234. r[8*i+4] = (s->v[5*i+2] >> 4) & 31;
  235. r[8*i+4] ^= (s->v[5*i+3] << 4) & 31;
  236. r[8*i+5] = (s->v[5*i+3] >> 1) & 31;
  237. r[8*i+6] = (s->v[5*i+3] >> 6) & 31;
  238. r[8*i+6] ^= (s->v[5*i+4] << 2) & 31;
  239. r[8*i+7] = (s->v[5*i+4] >> 3) & 31;
  240. }
  241. r[8*i+0] = s->v[5*i+0] & 31;
  242. r[8*i+1] = (s->v[5*i+0] >> 5) & 31;
  243. r[8*i+1] ^= (s->v[5*i+1] << 3) & 31;
  244. r[8*i+2] = (s->v[5*i+1] >> 2) & 31;
  245. /* Making it signed */
  246. carry = 0;
  247. for(i=0;i<50;i++)
  248. {
  249. r[i] += carry;
  250. r[i+1] += r[i] >> 5;
  251. r[i] &= 31;
  252. carry = r[i] >> 4;
  253. r[i] -= carry<<5;
  254. }
  255. r[50] += carry;
  256. }
  257. void sc25519_2interleave2(unsigned char r[127], const sc25519 *s1, const sc25519 *s2)
  258. {
  259. int i;
  260. for(i=0;i<31;i++)
  261. {
  262. r[4*i] = ( s1->v[i] & 3) ^ (( s2->v[i] & 3) << 2);
  263. r[4*i+1] = ((s1->v[i] >> 2) & 3) ^ (((s2->v[i] >> 2) & 3) << 2);
  264. r[4*i+2] = ((s1->v[i] >> 4) & 3) ^ (((s2->v[i] >> 4) & 3) << 2);
  265. r[4*i+3] = ((s1->v[i] >> 6) & 3) ^ (((s2->v[i] >> 6) & 3) << 2);
  266. }
  267. r[124] = ( s1->v[31] & 3) ^ (( s2->v[31] & 3) << 2);
  268. r[125] = ((s1->v[31] >> 2) & 3) ^ (((s2->v[31] >> 2) & 3) << 2);
  269. r[126] = ((s1->v[31] >> 4) & 3) ^ (((s2->v[31] >> 4) & 3) << 2);
  270. }