sc25519.c 6.9 KB

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