You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 

1623 lines
46 KiB

  1. /* Copyright (c) 2015 Cryptography Research, Inc.
  2. * Released under the MIT License. See LICENSE.txt for license information.
  3. */
  4. /**
  5. * @file decaf.c
  6. * @author Mike Hamburg
  7. * @brief Decaf high-level functions.
  8. */
  9. #define __STDC_WANT_LIB_EXT1__ 1 /* for memset_s */
  10. #include "decaf.h"
  11. #include <string.h>
  12. #include "field.h"
  13. #include "decaf_448_config.h"
  14. #define WBITS DECAF_WORD_BITS
  15. #if WBITS == 64
  16. #define LBITS 56
  17. typedef __uint128_t decaf_dword_t;
  18. typedef __int128_t decaf_sdword_t;
  19. #define LIMB(x) (x##ull)
  20. #define SC_LIMB(x) (x##ull)
  21. #elif WBITS == 32
  22. typedef uint64_t decaf_dword_t;
  23. typedef int64_t decaf_sdword_t;
  24. #define LBITS 28
  25. #define LIMB(x) (x##ull)&((1ull<<LBITS)-1), (x##ull)>>LBITS
  26. #define SC_LIMB(x) (x##ull)&((1ull<<32)-1), (x##ull)>>32
  27. #else
  28. #error "Only supporting 32- and 64-bit platforms right now"
  29. #endif
  30. //static const int QUADRATIC_NONRESIDUE = -1;
  31. #define sv static void
  32. #define snv static void __attribute__((noinline))
  33. #define siv static inline void __attribute__((always_inline))
  34. static const gf ZERO = {{{0}}}, ONE = {{{1}}}, TWO = {{{2}}};
  35. #define LMASK ((((decaf_word_t)1)<<LBITS)-1)
  36. #if WBITS == 64
  37. static const gf P = {{{ LMASK, LMASK, LMASK, LMASK, LMASK-1, LMASK, LMASK, LMASK }}};
  38. #else
  39. static const gf P = {{{ LMASK, LMASK, LMASK, LMASK, LMASK, LMASK, LMASK, LMASK,
  40. LMASK-1, LMASK, LMASK, LMASK, LMASK, LMASK, LMASK, LMASK }}};
  41. #endif
  42. static const int EDWARDS_D = -39081;
  43. const decaf_448_scalar_t decaf_448_scalar_p = {{{
  44. SC_LIMB(0x2378c292ab5844f3),
  45. SC_LIMB(0x216cc2728dc58f55),
  46. SC_LIMB(0xc44edb49aed63690),
  47. SC_LIMB(0xffffffff7cca23e9),
  48. SC_LIMB(0xffffffffffffffff),
  49. SC_LIMB(0xffffffffffffffff),
  50. SC_LIMB(0x3fffffffffffffff)
  51. }}}, decaf_448_scalar_one = {{{1}}}, decaf_448_scalar_zero = {{{0}}};
  52. static const decaf_448_scalar_t decaf_448_scalar_r2 = {{{
  53. SC_LIMB(0xe3539257049b9b60),
  54. SC_LIMB(0x7af32c4bc1b195d9),
  55. SC_LIMB(0x0d66de2388ea1859),
  56. SC_LIMB(0xae17cf725ee4d838),
  57. SC_LIMB(0x1a9cc14ba3c47c44),
  58. SC_LIMB(0x2052bcb7e4d070af),
  59. SC_LIMB(0x3402a939f823b729)
  60. }}};
  61. static const decaf_448_scalar_t decaf_448_scalar_r1 = {{{
  62. SC_LIMB(0x721cf5b5529eec34),
  63. SC_LIMB(0x7a4cf635c8e9c2ab),
  64. SC_LIMB(0xeec492d944a725bf),
  65. SC_LIMB(0x000000020cd77058),
  66. SC_LIMB(0),
  67. SC_LIMB(0),
  68. SC_LIMB(0)
  69. }}};
  70. static const decaf_word_t DECAF_MONTGOMERY_FACTOR = (decaf_word_t)(0x3bd440fae918bc5ull);
  71. /** base = twist of Goldilocks base point (~,19). */
  72. const decaf_448_point_t decaf_448_point_base = {{
  73. {{{ LIMB(0xb39a2d57e08c7b),LIMB(0xb38639c75ff281),
  74. LIMB(0x2ec981082b3288),LIMB(0x99fe8607e5237c),
  75. LIMB(0x0e33fbb1fadd1f),LIMB(0xe714f67055eb4a),
  76. LIMB(0xc9ae06d64067dd),LIMB(0xf7be45054760fa) }}},
  77. {{{ LIMB(0xbd8715f551617f),LIMB(0x8c17fbeca8f5fc),
  78. LIMB(0xaae0eec209c06f),LIMB(0xce41ad80cbe6b8),
  79. LIMB(0xdf360b5c828c00),LIMB(0xaf25b6bbb40e3b),
  80. LIMB(0x8ed37f0ce4ed31),LIMB(0x72a1c3214557b9) }}},
  81. {{{ 1 }}},
  82. {{{ LIMB(0x97ca9c8ed8bde9),LIMB(0xf0b780da83304c),
  83. LIMB(0x0d79c0a7729a69),LIMB(0xc18d3f24aebc1c),
  84. LIMB(0x1fbb5389b3fda5),LIMB(0xbb24f674635948),
  85. LIMB(0x723a55709a3983),LIMB(0xe1c0107a823dd4) }}}
  86. }};
  87. /* Projective Niels coordinates */
  88. typedef struct { gf a, b, c; } niels_s, niels_t[1];
  89. typedef struct { niels_t n; gf z; } pniels_s, pniels_t[1];
  90. /* Precomputed base */
  91. struct decaf_448_precomputed_s { niels_t table [DECAF_COMBS_N<<(DECAF_COMBS_T-1)]; };
  92. extern const decaf_word_t decaf_448_precomputed_base_as_words[];
  93. const decaf_448_precomputed_s *decaf_448_precomputed_base =
  94. (const decaf_448_precomputed_s *) &decaf_448_precomputed_base_as_words;
  95. const size_t sizeof_decaf_448_precomputed_s = sizeof(decaf_448_precomputed_s);
  96. const size_t alignof_decaf_448_precomputed_s = 32;
  97. #ifdef __clang__
  98. #if 100*__clang_major__ + __clang_minor__ > 305
  99. #define VECTORIZE _Pragma("clang loop unroll(disable) vectorize(enable) vectorize_width(8)")
  100. #endif
  101. #endif
  102. #ifndef VECTORIZE
  103. #define VECTORIZE
  104. #endif
  105. #define FOR_LIMB(i,op) { unsigned int i=0; for (i=0; i<DECAF_448_LIMBS; i++) { op; }}
  106. #define FOR_LIMB_V(i,op) { unsigned int i=0; VECTORIZE for (i=0; i<DECAF_448_LIMBS; i++) { op; }}
  107. /** Copy x = y */
  108. siv gf_cpy(gf x, const gf y) { FOR_LIMB_V(i, x->limb[i] = y->limb[i]); }
  109. /** Mostly-unoptimized multiply, but at least it's unrolled. */
  110. siv gf_mul (gf c, const gf a, const gf b) {
  111. field_mul((field_t *)c, (const field_t *)a, (const field_t *)b);
  112. }
  113. /** Dedicated square */
  114. siv gf_sqr (gf c, const gf a) {
  115. field_sqr((field_t *)c, (const field_t *)a);
  116. }
  117. /** Inverse square root using addition chain. */
  118. siv gf_isqrt(gf y, const gf x) {
  119. field_isr((field_t *)y, (const field_t *)x);
  120. }
  121. /** Add mod p. Conservatively always weak-reduce. */
  122. snv gf_add ( gf_s *__restrict__ c, const gf a, const gf b ) {
  123. field_add((field_t *)c, (const field_t *)a, (const field_t *)b);
  124. }
  125. /** Subtract mod p. Conservatively always weak-reduce. */
  126. snv gf_sub ( gf c, const gf a, const gf b ) {
  127. field_sub((field_t *)c, (const field_t *)a, (const field_t *)b);
  128. }
  129. /** Add mod p. Conservatively always weak-reduce.) */
  130. siv gf_bias ( gf c, int amt) {
  131. field_bias((field_t *)c, amt);
  132. }
  133. /** Subtract mod p. Bias by 2 and don't reduce */
  134. siv gf_sub_nr ( gf_s *__restrict__ c, const gf a, const gf b ) {
  135. // FOR_LIMB_V(i, c->limb[i] = a->limb[i] - b->limb[i] + 2*P->limb[i] );
  136. ANALYZE_THIS_ROUTINE_CAREFULLY; //TODO
  137. field_sub_nr((field_t *)c, (const field_t *)a, (const field_t *)b);
  138. gf_bias(c, 2);
  139. }
  140. /** Subtract mod p. Bias by amt but don't reduce. */
  141. siv gf_sub_nr_x ( gf c, const gf a, const gf b, int amt ) {
  142. ANALYZE_THIS_ROUTINE_CAREFULLY; //TODO
  143. field_sub_nr((field_t *)c, (const field_t *)a, (const field_t *)b);
  144. gf_bias(c, amt);
  145. }
  146. /** Add mod p. Don't reduce. */
  147. siv gf_add_nr ( gf c, const gf a, const gf b ) {
  148. // FOR_LIMB_V(i, c->limb[i] = a->limb[i] + b->limb[i]);
  149. ANALYZE_THIS_ROUTINE_CAREFULLY; //TODO
  150. field_add_nr((field_t *)c, (const field_t *)a, (const field_t *)b);
  151. }
  152. /** Constant time, x = is_z ? z : y */
  153. siv cond_sel(gf x, const gf y, const gf z, decaf_bool_t is_z) {
  154. big_register_t br_mask = br_set_to_mask(is_z);
  155. big_register_t *out = (big_register_t *)x;
  156. const big_register_t *y_ = (const big_register_t *)y, *z_ = (const big_register_t *)z;
  157. word_t k;
  158. for (k=0; k<sizeof(gf)/sizeof(big_register_t); k++) {
  159. out[k] = (~br_mask & y_[k]) | (br_mask & z_[k]);
  160. }
  161. /*
  162. constant_time_select(x,z,y,sizeof(gf),is_z);
  163. */
  164. }
  165. /** Constant time, if (neg) x=-x; */
  166. sv cond_neg(gf x, decaf_bool_t neg) {
  167. gf y;
  168. gf_sub(y,ZERO,x);
  169. cond_sel(x,x,y,neg);
  170. }
  171. /** Constant time, if (swap) (x,y) = (y,x); */
  172. siv cond_swap(gf x, gf_s *__restrict__ y, decaf_bool_t swap) {
  173. FOR_LIMB_V(i, {
  174. decaf_word_t s = (x->limb[i] ^ y->limb[i]) & swap;
  175. x->limb[i] ^= s;
  176. y->limb[i] ^= s;
  177. });
  178. }
  179. /**
  180. * Mul by signed int. Not constant-time WRT the sign of that int.
  181. * Just uses a full mul (PERF)
  182. */
  183. siv gf_mlw(gf c, const gf a, int w) {
  184. if (w>0) {
  185. field_mulw((field_t *)c, (const field_t *)a, w);
  186. } else {
  187. field_mulw((field_t *)c, (const field_t *)a, -w);
  188. gf_sub(c,ZERO,c);
  189. }
  190. }
  191. /** Canonicalize */
  192. siv gf_canon ( gf a ) {
  193. field_strong_reduce((field_t *)a);
  194. }
  195. /** Compare a==b */
  196. static decaf_word_t __attribute__((noinline)) gf_eq(const gf a, const gf b) {
  197. gf c;
  198. gf_sub(c,a,b);
  199. gf_canon(c);
  200. decaf_word_t ret=0;
  201. FOR_LIMB(i, ret |= c->limb[i] );
  202. /* Hope the compiler is too dumb to optimize this, thus noinline */
  203. return ((decaf_dword_t)ret - 1) >> WBITS;
  204. }
  205. /** Return high bit of x = low bit of 2x mod p */
  206. static decaf_word_t hibit(const gf x) {
  207. gf y;
  208. gf_add(y,x,x);
  209. gf_canon(y);
  210. return -(y->limb[0]&1);
  211. }
  212. /** {extra,accum} - sub +? p
  213. * Must have extra <= 1
  214. */
  215. snv decaf_448_subx(
  216. decaf_448_scalar_t out,
  217. const decaf_word_t accum[DECAF_448_SCALAR_LIMBS],
  218. const decaf_448_scalar_t sub,
  219. const decaf_448_scalar_t p,
  220. decaf_word_t extra
  221. ) {
  222. decaf_sdword_t chain = 0;
  223. unsigned int i;
  224. for (i=0; i<DECAF_448_SCALAR_LIMBS; i++) {
  225. chain = (chain + accum[i]) - sub->limb[i];
  226. out->limb[i] = chain;
  227. chain >>= WBITS;
  228. }
  229. decaf_bool_t borrow = chain+extra; /* = 0 or -1 */
  230. chain = 0;
  231. for (i=0; i<DECAF_448_SCALAR_LIMBS; i++) {
  232. chain = (chain + out->limb[i]) + (p->limb[i] & borrow);
  233. out->limb[i] = chain;
  234. chain >>= WBITS;
  235. }
  236. }
  237. snv decaf_448_montmul (
  238. decaf_448_scalar_t out,
  239. const decaf_448_scalar_t a,
  240. const decaf_448_scalar_t b
  241. ) {
  242. unsigned int i,j;
  243. decaf_word_t accum[DECAF_448_SCALAR_LIMBS+1] = {0};
  244. decaf_word_t hi_carry = 0;
  245. for (i=0; i<DECAF_448_SCALAR_LIMBS; i++) {
  246. decaf_word_t mand = a->limb[i];
  247. const decaf_word_t *mier = b->limb;
  248. decaf_dword_t chain = 0;
  249. for (j=0; j<DECAF_448_SCALAR_LIMBS; j++) {
  250. chain += ((decaf_dword_t)mand)*mier[j] + accum[j];
  251. accum[j] = chain;
  252. chain >>= WBITS;
  253. }
  254. accum[j] = chain;
  255. mand = accum[0] * DECAF_MONTGOMERY_FACTOR;
  256. chain = 0;
  257. mier = decaf_448_scalar_p->limb;
  258. for (j=0; j<DECAF_448_SCALAR_LIMBS; j++) {
  259. chain += (decaf_dword_t)mand*mier[j] + accum[j];
  260. if (j) accum[j-1] = chain;
  261. chain >>= WBITS;
  262. }
  263. chain += accum[j];
  264. chain += hi_carry;
  265. accum[j-1] = chain;
  266. hi_carry = chain >> WBITS;
  267. }
  268. decaf_448_subx(out, accum, decaf_448_scalar_p, decaf_448_scalar_p, hi_carry);
  269. }
  270. void decaf_448_scalar_mul (
  271. decaf_448_scalar_t out,
  272. const decaf_448_scalar_t a,
  273. const decaf_448_scalar_t b
  274. ) {
  275. decaf_448_montmul(out,a,b);
  276. decaf_448_montmul(out,out,decaf_448_scalar_r2);
  277. }
  278. /* PERF: could implement this */
  279. siv decaf_448_montsqr (
  280. decaf_448_scalar_t out,
  281. const decaf_448_scalar_t a
  282. ) {
  283. decaf_448_montmul(out,a,a);
  284. }
  285. decaf_bool_t decaf_448_scalar_invert (
  286. decaf_448_scalar_t out,
  287. const decaf_448_scalar_t a
  288. ) {
  289. decaf_448_scalar_t chain[7], tmp;
  290. decaf_448_montmul(chain[0],a,decaf_448_scalar_r2);
  291. unsigned int i,j;
  292. /* Addition chain generated by a not-too-clever SAGE script. First part: compute a^(2^222-1) */
  293. const struct { uint8_t widx, sidx, sct, midx; } muls [] = {
  294. {2,0,1,0}, {3,2,1,0}, {4,3,1,0}, {5,4,1,0}, /* 0x3,7,f,1f */
  295. {1,5,1,0}, {1,1,3,3}, {6,1,9,1}, {1,6,1,0}, {6,1,18,6}, /* a^(2^37-1) */
  296. {1,6,37,6}, {1,1,37,6}, {1,1,111,1} /* a^(2^222-1) */
  297. };
  298. /* Second part: sliding window */
  299. const struct { uint8_t sct, midx; } muls1 [] = {
  300. {6, 5}, {4, 2}, {3, 0}, {2, 0}, {4, 0}, {8, 5},
  301. {2, 0}, {5, 3}, {4, 0}, {4, 0}, {5, 3}, {3, 2},
  302. {3, 2}, {3, 2}, {2, 0}, {3, 0}, {4, 2}, {2, 0},
  303. {4, 3}, {3, 2}, {2, 0}, {3, 2}, {5, 2}, {3, 2},
  304. {2, 0}, {3, 0}, {7, 0}, {5, 0}, {3, 2}, {3, 2},
  305. {4, 2}, {5, 0}, {5, 3}, {3, 0}, {2, 0}, {5, 2},
  306. {4, 3}, {4, 0}, {3, 2}, {7, 4}, {2, 0}, {2, 0},
  307. {2, 0}, {2, 0}, {3, 0}, {5, 2}, {5, 4}, {5, 2},
  308. {5, 0}, {2, 0}, {3, 0}, {3, 0}, {2, 0}, {2, 0},
  309. {2, 0}, {3, 2}, {2, 0}, {3, 2}, {5, 0}, {4, 0},
  310. {6, 4}, {4, 0}
  311. };
  312. for (i=0; i<sizeof(muls)/sizeof(muls[0]); i++) {
  313. decaf_448_montsqr(tmp, chain[muls[i].sidx]);
  314. for (j=1; j<muls[i].sct; j++) {
  315. decaf_448_montsqr(tmp, tmp);
  316. }
  317. decaf_448_montmul(chain[muls[i].widx], tmp, chain[muls[i].midx]);
  318. }
  319. for (i=0; i<sizeof(muls1)/sizeof(muls1[0]); i++) {
  320. decaf_448_montsqr(tmp, chain[1]);
  321. for (j=1; j<muls1[i].sct; j++) {
  322. decaf_448_montsqr(tmp, tmp);
  323. }
  324. decaf_448_montmul(chain[1], tmp, chain[muls1[i].midx]);
  325. }
  326. decaf_448_montmul(out,chain[1],decaf_448_scalar_one);
  327. for (i=0; i<sizeof(chain)/sizeof(chain[0]); i++) {
  328. decaf_448_scalar_destroy(chain[i]);
  329. }
  330. return ~decaf_448_scalar_eq(out,decaf_448_scalar_zero);
  331. }
  332. void decaf_448_scalar_sub (
  333. decaf_448_scalar_t out,
  334. const decaf_448_scalar_t a,
  335. const decaf_448_scalar_t b
  336. ) {
  337. decaf_448_subx(out, a->limb, b, decaf_448_scalar_p, 0);
  338. }
  339. void decaf_448_scalar_add (
  340. decaf_448_scalar_t out,
  341. const decaf_448_scalar_t a,
  342. const decaf_448_scalar_t b
  343. ) {
  344. decaf_dword_t chain = 0;
  345. unsigned int i;
  346. for (i=0; i<DECAF_448_SCALAR_LIMBS; i++) {
  347. chain = (chain + a->limb[i]) + b->limb[i];
  348. out->limb[i] = chain;
  349. chain >>= WBITS;
  350. }
  351. decaf_448_subx(out, out->limb, decaf_448_scalar_p, decaf_448_scalar_p, chain);
  352. }
  353. snv decaf_448_halve (
  354. decaf_448_scalar_t out,
  355. const decaf_448_scalar_t a,
  356. const decaf_448_scalar_t p
  357. ) {
  358. decaf_word_t mask = -(a->limb[0] & 1);
  359. decaf_dword_t chain = 0;
  360. unsigned int i;
  361. for (i=0; i<DECAF_448_SCALAR_LIMBS; i++) {
  362. chain = (chain + a->limb[i]) + (p->limb[i] & mask);
  363. out->limb[i] = chain;
  364. chain >>= WBITS;
  365. }
  366. for (i=0; i<DECAF_448_SCALAR_LIMBS-1; i++) {
  367. out->limb[i] = out->limb[i]>>1 | out->limb[i+1]<<(WBITS-1);
  368. }
  369. out->limb[i] = out->limb[i]>>1 | chain<<(WBITS-1);
  370. }
  371. void decaf_448_scalar_copy (
  372. decaf_448_scalar_t out,
  373. const decaf_448_scalar_t a
  374. ) {
  375. unsigned int i;
  376. for (i=0; i<DECAF_448_SCALAR_LIMBS; i++) {
  377. out->limb[i] = a->limb[i];
  378. }
  379. }
  380. void decaf_448_scalar_set (
  381. decaf_448_scalar_t out,
  382. decaf_word_t w
  383. ) {
  384. memset(out,0,sizeof(decaf_448_scalar_t));
  385. out->limb[0] = w;
  386. }
  387. decaf_bool_t decaf_448_scalar_eq (
  388. const decaf_448_scalar_t a,
  389. const decaf_448_scalar_t b
  390. ) {
  391. decaf_word_t diff = 0;
  392. unsigned int i;
  393. for (i=0; i<DECAF_448_SCALAR_LIMBS; i++) {
  394. diff |= a->limb[i] ^ b->limb[i];
  395. }
  396. return (((decaf_dword_t)diff)-1)>>WBITS;
  397. }
  398. /* *** API begins here *** */
  399. /** identity = (0,1) */
  400. const decaf_448_point_t decaf_448_point_identity = {{{{{0}}},{{{1}}},{{{1}}},{{{0}}}}};
  401. static void gf_encode ( unsigned char ser[DECAF_448_SER_BYTES], gf a ) {
  402. gf_canon(a);
  403. int i, k=0, bits=0;
  404. decaf_dword_t buf=0;
  405. for (i=0; i<DECAF_448_LIMBS; i++) {
  406. buf |= (decaf_dword_t)a->limb[i]<<bits;
  407. for (bits += LBITS; (bits>=8 || i==DECAF_448_LIMBS-1) && k<DECAF_448_SER_BYTES; bits-=8, buf>>=8) {
  408. ser[k++]=buf;
  409. }
  410. }
  411. }
  412. void decaf_448_point_encode( unsigned char ser[DECAF_448_SER_BYTES], const decaf_448_point_t p ) {
  413. /* Can shave off one mul here; not important but makes consistent with paper */
  414. gf a, b, c, d;
  415. gf_mlw ( a, p->y, 1-EDWARDS_D );
  416. gf_mul ( c, a, p->t );
  417. gf_mul ( a, p->x, p->z );
  418. gf_sub ( d, c, a );
  419. gf_add ( a, p->z, p->y );
  420. gf_sub ( b, p->z, p->y );
  421. gf_mul ( c, b, a );
  422. gf_mlw ( b, c, -EDWARDS_D );
  423. gf_isqrt ( a, b );
  424. gf_mlw ( b, a, -EDWARDS_D );
  425. gf_mul ( c, b, a );
  426. gf_mul ( a, c, d );
  427. gf_add ( d, b, b );
  428. gf_mul ( c, d, p->z );
  429. cond_neg ( b, ~hibit(c) );
  430. gf_mul ( c, b, p->y );
  431. gf_add ( a, a, c );
  432. cond_neg ( a, hibit(a) );
  433. gf_encode(ser, a);
  434. }
  435. /**
  436. * Deserialize a bool, return TRUE if < p.
  437. */
  438. static decaf_bool_t gf_deser(gf s, const unsigned char ser[DECAF_448_SER_BYTES]) {
  439. unsigned int i, k=0, bits=0;
  440. decaf_dword_t buf=0;
  441. for (i=0; i<DECAF_448_SER_BYTES; i++) {
  442. buf |= (decaf_dword_t)ser[i]<<bits;
  443. for (bits += 8; (bits>=LBITS || i==DECAF_448_SER_BYTES-1) && k<DECAF_448_LIMBS; bits-=LBITS, buf>>=LBITS) {
  444. s->limb[k++] = buf & LMASK;
  445. }
  446. }
  447. decaf_sdword_t accum = 0;
  448. FOR_LIMB(i, accum = (accum + s->limb[i] - P->limb[i]) >> WBITS );
  449. return accum;
  450. }
  451. decaf_bool_t decaf_448_point_decode (
  452. decaf_448_point_t p,
  453. const unsigned char ser[DECAF_448_SER_BYTES],
  454. decaf_bool_t allow_identity
  455. ) {
  456. gf s, a, b, c, d, e;
  457. decaf_bool_t succ = gf_deser(s, ser), zero = gf_eq(s, ZERO);
  458. succ &= allow_identity | ~zero;
  459. succ &= ~hibit(s);
  460. gf_sqr ( a, s );
  461. gf_sub ( p->z, ONE, a );
  462. gf_sqr ( b, p->z );
  463. gf_mlw ( c, a, 4-4*EDWARDS_D );
  464. gf_add ( c, c, b );
  465. gf_mul ( b, c, a );
  466. gf_isqrt ( d, b );
  467. gf_sqr ( e, d );
  468. gf_mul ( a, e, b );
  469. gf_add ( a, a, ONE );
  470. succ &= ~gf_eq ( a, ZERO );
  471. gf_mul ( b, c, d );
  472. cond_neg ( d, hibit(b) );
  473. gf_add ( p->x, s, s );
  474. gf_mul ( c, d, s );
  475. gf_sub ( b, TWO, p->z );
  476. gf_mul ( a, b, c );
  477. gf_mul ( p->y,a,p->z );
  478. gf_mul ( p->t,p->x,a );
  479. p->y->limb[0] -= zero;
  480. /* TODO: do something safe if ~succ? */
  481. return succ;
  482. }
  483. void decaf_448_point_sub (
  484. decaf_448_point_t p,
  485. const decaf_448_point_t q,
  486. const decaf_448_point_t r
  487. ) {
  488. gf a, b, c, d;
  489. gf_sub_nr ( b, q->y, q->x );
  490. gf_sub_nr ( d, r->y, r->x );
  491. gf_add_nr ( c, r->y, r->x );
  492. gf_mul ( a, c, b );
  493. gf_add_nr ( b, q->y, q->x );
  494. gf_mul ( p->y, d, b );
  495. gf_mul ( b, r->t, q->t );
  496. gf_mlw ( p->x, b, 2-2*EDWARDS_D );
  497. gf_add_nr ( b, a, p->y );
  498. gf_sub_nr ( c, p->y, a );
  499. gf_mul ( a, q->z, r->z );
  500. gf_add_nr ( a, a, a );
  501. gf_sub_nr ( p->y, a, p->x );
  502. gf_add_nr ( a, a, p->x );
  503. gf_mul ( p->z, a, p->y );
  504. gf_mul ( p->x, p->y, c );
  505. gf_mul ( p->y, a, b );
  506. gf_mul ( p->t, b, c );
  507. }
  508. void decaf_448_point_add (
  509. decaf_448_point_t p,
  510. const decaf_448_point_t q,
  511. const decaf_448_point_t r
  512. ) {
  513. gf a, b, c, d;
  514. gf_sub_nr ( b, q->y, q->x );
  515. gf_sub_nr ( c, r->y, r->x );
  516. gf_add_nr ( d, r->y, r->x );
  517. gf_mul ( a, c, b );
  518. gf_add_nr ( b, q->y, q->x );
  519. gf_mul ( p->y, d, b );
  520. gf_mul ( b, r->t, q->t );
  521. gf_mlw ( p->x, b, 2-2*EDWARDS_D );
  522. gf_add_nr ( b, a, p->y );
  523. gf_sub_nr ( c, p->y, a );
  524. gf_mul ( a, q->z, r->z );
  525. gf_add_nr ( a, a, a );
  526. gf_add_nr ( p->y, a, p->x );
  527. gf_sub_nr ( a, a, p->x );
  528. gf_mul ( p->z, a, p->y );
  529. gf_mul ( p->x, p->y, c );
  530. gf_mul ( p->y, a, b );
  531. gf_mul ( p->t, b, c );
  532. }
  533. snv decaf_448_point_double_internal (
  534. decaf_448_point_t p,
  535. const decaf_448_point_t q,
  536. decaf_bool_t before_double
  537. ) {
  538. gf a, b, c, d;
  539. gf_sqr ( c, q->x );
  540. gf_sqr ( a, q->y );
  541. gf_add_nr ( d, c, a );
  542. gf_add_nr ( p->t, q->y, q->x );
  543. gf_sqr ( b, p->t );
  544. gf_sub_nr_x ( b, b, d, 3 );
  545. gf_sub_nr ( p->t, a, c );
  546. gf_sqr ( p->x, q->z );
  547. gf_add_nr ( p->z, p->x, p->x );
  548. gf_sub_nr_x ( a, p->z, p->t, 4 );
  549. gf_mul ( p->x, a, b );
  550. gf_mul ( p->z, p->t, a );
  551. gf_mul ( p->y, p->t, d );
  552. if (!before_double) gf_mul ( p->t, b, d );
  553. }
  554. void decaf_448_point_double(decaf_448_point_t p, const decaf_448_point_t q) {
  555. decaf_448_point_double_internal(p,q,0);
  556. }
  557. void decaf_448_point_copy (
  558. decaf_448_point_t a,
  559. const decaf_448_point_t b
  560. ) {
  561. gf_cpy(a->x, b->x);
  562. gf_cpy(a->y, b->y);
  563. gf_cpy(a->z, b->z);
  564. gf_cpy(a->t, b->t);
  565. }
  566. void decaf_448_point_negate (
  567. decaf_448_point_t nega,
  568. const decaf_448_point_t a
  569. ) {
  570. gf_sub(nega->x, ZERO, a->x);
  571. gf_cpy(nega->y, a->y);
  572. gf_cpy(nega->z, a->z);
  573. gf_sub(nega->t, ZERO, a->t);
  574. }
  575. siv decaf_448_scalar_decode_short (
  576. decaf_448_scalar_t s,
  577. const unsigned char ser[DECAF_448_SER_BYTES],
  578. unsigned int nbytes
  579. ) {
  580. unsigned int i,j,k=0;
  581. for (i=0; i<DECAF_448_SCALAR_LIMBS; i++) {
  582. decaf_word_t out = 0;
  583. for (j=0; j<sizeof(decaf_word_t) && k<nbytes; j++,k++) {
  584. out |= ((decaf_word_t)ser[k])<<(8*j);
  585. }
  586. s->limb[i] = out;
  587. }
  588. }
  589. decaf_bool_t decaf_448_scalar_decode(
  590. decaf_448_scalar_t s,
  591. const unsigned char ser[DECAF_448_SER_BYTES]
  592. ) {
  593. unsigned int i;
  594. decaf_448_scalar_decode_short(s, ser, DECAF_448_SER_BYTES);
  595. decaf_sdword_t accum = 0;
  596. for (i=0; i<DECAF_448_SCALAR_LIMBS; i++) {
  597. accum = (accum + s->limb[i] - decaf_448_scalar_p->limb[i]) >> WBITS;
  598. }
  599. decaf_448_montmul(s,s,decaf_448_scalar_r1); /* ham-handed reduce */
  600. return accum;
  601. }
  602. void decaf_bzero (
  603. void *s,
  604. size_t size
  605. ) {
  606. if (s==NULL) return;
  607. #ifdef __STDC_LIB_EXT1__
  608. memset_s(s, size, 0, size);
  609. #else
  610. /* PERF: word at a time? */
  611. volatile uint8_t *destroy = (volatile uint8_t *)s;
  612. unsigned i;
  613. for (i=0; i<size; i++) {
  614. destroy[i] = 0;
  615. }
  616. #endif
  617. }
  618. void decaf_448_scalar_destroy (
  619. decaf_448_scalar_t scalar
  620. ) {
  621. decaf_bzero(scalar, sizeof(decaf_448_scalar_t));
  622. }
  623. static inline void ignore_result ( decaf_bool_t boo ) {
  624. (void)boo;
  625. }
  626. void decaf_448_scalar_decode_long(
  627. decaf_448_scalar_t s,
  628. const unsigned char *ser,
  629. size_t ser_len
  630. ) {
  631. if (ser_len == 0) {
  632. decaf_448_scalar_copy(s, decaf_448_scalar_zero);
  633. return;
  634. }
  635. size_t i;
  636. decaf_448_scalar_t t1, t2;
  637. i = ser_len - (ser_len%DECAF_448_SER_BYTES);
  638. if (i==ser_len) i -= DECAF_448_SER_BYTES;
  639. decaf_448_scalar_decode_short(t1, &ser[i], ser_len-i);
  640. if (ser_len == sizeof(*ser)) {
  641. assert(i==0);
  642. /* ham-handed reduce */
  643. decaf_448_montmul(s,t1,decaf_448_scalar_r1);
  644. decaf_448_scalar_destroy(t1);
  645. return;
  646. }
  647. while (i) {
  648. i -= DECAF_448_SER_BYTES;
  649. decaf_448_montmul(t1,t1,decaf_448_scalar_r2);
  650. ignore_result( decaf_448_scalar_decode(t2, ser+i) );
  651. decaf_448_scalar_add(t1, t1, t2);
  652. }
  653. decaf_448_scalar_copy(s, t1);
  654. decaf_448_scalar_destroy(t1);
  655. decaf_448_scalar_destroy(t2);
  656. }
  657. void decaf_448_scalar_encode(
  658. unsigned char ser[DECAF_448_SER_BYTES],
  659. const decaf_448_scalar_t s
  660. ) {
  661. unsigned int i,j,k=0;
  662. for (i=0; i<DECAF_448_SCALAR_LIMBS; i++) {
  663. for (j=0; j<sizeof(decaf_word_t); j++,k++) {
  664. ser[k] = s->limb[i] >> (8*j);
  665. }
  666. }
  667. }
  668. /* Operations on [p]niels */
  669. siv cond_neg_niels (
  670. niels_t n,
  671. decaf_bool_t neg
  672. ) {
  673. cond_swap(n->a, n->b, neg);
  674. cond_neg(n->c, neg);
  675. }
  676. static void pt_to_pniels (
  677. pniels_t b,
  678. const decaf_448_point_t a
  679. ) {
  680. gf_sub ( b->n->a, a->y, a->x );
  681. gf_add ( b->n->b, a->x, a->y );
  682. gf_mlw ( b->n->c, a->t, 2*EDWARDS_D-2 );
  683. gf_add ( b->z, a->z, a->z );
  684. }
  685. static void pniels_to_pt (
  686. decaf_448_point_t e,
  687. const pniels_t d
  688. ) {
  689. gf eu;
  690. gf_add ( eu, d->n->b, d->n->a );
  691. gf_sub ( e->y, d->n->b, d->n->a );
  692. gf_mul ( e->t, e->y, eu);
  693. gf_mul ( e->x, d->z, e->y );
  694. gf_mul ( e->y, d->z, eu );
  695. gf_sqr ( e->z, d->z );
  696. }
  697. snv niels_to_pt (
  698. decaf_448_point_t e,
  699. const niels_t n
  700. ) {
  701. gf_add ( e->y, n->b, n->a );
  702. gf_sub ( e->x, n->b, n->a );
  703. gf_mul ( e->t, e->y, e->x );
  704. gf_cpy ( e->z, ONE );
  705. }
  706. snv add_niels_to_pt (
  707. decaf_448_point_t d,
  708. const niels_t e,
  709. decaf_bool_t before_double
  710. ) {
  711. gf a, b, c;
  712. gf_sub_nr ( b, d->y, d->x );
  713. gf_mul ( a, e->a, b );
  714. gf_add_nr ( b, d->x, d->y );
  715. gf_mul ( d->y, e->b, b );
  716. gf_mul ( d->x, e->c, d->t );
  717. gf_add_nr ( c, a, d->y );
  718. gf_sub_nr ( b, d->y, a );
  719. gf_sub_nr ( d->y, d->z, d->x );
  720. gf_add_nr ( a, d->x, d->z );
  721. gf_mul ( d->z, a, d->y );
  722. gf_mul ( d->x, d->y, b );
  723. gf_mul ( d->y, a, c );
  724. if (!before_double) gf_mul ( d->t, b, c );
  725. }
  726. snv sub_niels_from_pt (
  727. decaf_448_point_t d,
  728. const niels_t e,
  729. decaf_bool_t before_double
  730. ) {
  731. gf a, b, c;
  732. gf_sub_nr ( b, d->y, d->x );
  733. gf_mul ( a, e->b, b );
  734. gf_add_nr ( b, d->x, d->y );
  735. gf_mul ( d->y, e->a, b );
  736. gf_mul ( d->x, e->c, d->t );
  737. gf_add_nr ( c, a, d->y );
  738. gf_sub_nr ( b, d->y, a );
  739. gf_add_nr ( d->y, d->z, d->x );
  740. gf_sub_nr ( a, d->z, d->x );
  741. gf_mul ( d->z, a, d->y );
  742. gf_mul ( d->x, d->y, b );
  743. gf_mul ( d->y, a, c );
  744. if (!before_double) gf_mul ( d->t, b, c );
  745. }
  746. sv add_pniels_to_pt (
  747. decaf_448_point_t p,
  748. const pniels_t pn,
  749. decaf_bool_t before_double
  750. ) {
  751. gf L0;
  752. gf_mul ( L0, p->z, pn->z );
  753. gf_cpy ( p->z, L0 );
  754. add_niels_to_pt( p, pn->n, before_double );
  755. }
  756. sv sub_pniels_from_pt (
  757. decaf_448_point_t p,
  758. const pniels_t pn,
  759. decaf_bool_t before_double
  760. ) {
  761. gf L0;
  762. gf_mul ( L0, p->z, pn->z );
  763. gf_cpy ( p->z, L0 );
  764. sub_niels_from_pt( p, pn->n, before_double );
  765. }
  766. extern const decaf_448_scalar_t decaf_448_point_scalarmul_adjustment;
  767. /* TODO: get rid of big_register_t dependencies? */
  768. siv constant_time_lookup_xx (
  769. void *__restrict__ out_,
  770. const void *table_,
  771. word_t elem_bytes,
  772. word_t n_table,
  773. word_t idx
  774. ) {
  775. big_register_t big_one = br_set_to_mask(1), big_i = br_set_to_mask(idx);
  776. big_register_t *out = (big_register_t *)out_;
  777. const unsigned char *table = (const unsigned char *)table_;
  778. word_t j,k;
  779. big_register_t br_mask = br_is_zero(big_i);
  780. for (k=0; k<elem_bytes/sizeof(big_register_t); k++)
  781. out[k] = br_mask & *(const big_register_t*)(&table[k*sizeof(big_register_t)]);
  782. big_i-=big_one;
  783. for (j=1; j<n_table; j++, big_i-=big_one) {
  784. br_mask = br_is_zero(big_i);
  785. for (k=0; k<elem_bytes/sizeof(big_register_t); k++) {
  786. out[k] |= br_mask & *(const big_register_t*)(&table[k*sizeof(big_register_t)+j*elem_bytes]);
  787. }
  788. }
  789. }
  790. snv prepare_fixed_window(
  791. pniels_t *multiples,
  792. const decaf_448_point_t b,
  793. int ntable
  794. ) {
  795. decaf_448_point_t tmp;
  796. pniels_t pn;
  797. int i;
  798. decaf_448_point_double(tmp, b);
  799. pt_to_pniels(pn, tmp);
  800. pt_to_pniels(multiples[0], b);
  801. decaf_448_point_copy(tmp, b);
  802. for (i=1; i<ntable; i++) {
  803. add_pniels_to_pt(tmp, pn, 0);
  804. pt_to_pniels(multiples[i], tmp);
  805. }
  806. }
  807. void decaf_448_point_scalarmul (
  808. decaf_448_point_t a,
  809. const decaf_448_point_t b,
  810. const decaf_448_scalar_t scalar
  811. ) {
  812. const int WINDOW = DECAF_WINDOW_BITS,
  813. WINDOW_MASK = (1<<WINDOW)-1,
  814. WINDOW_T_MASK = WINDOW_MASK >> 1,
  815. NTABLE = 1<<(WINDOW-1);
  816. decaf_448_scalar_t scalar1x;
  817. decaf_448_scalar_add(scalar1x, scalar, decaf_448_point_scalarmul_adjustment);
  818. decaf_448_halve(scalar1x,scalar1x,decaf_448_scalar_p);
  819. /* Set up a precomputed table with odd multiples of b. */
  820. pniels_t pn, multiples[NTABLE];
  821. decaf_448_point_t tmp;
  822. prepare_fixed_window(multiples, b, NTABLE);
  823. /* Initialize. */
  824. int i,j,first=1;
  825. i = DECAF_448_SCALAR_BITS - ((DECAF_448_SCALAR_BITS-1) % WINDOW) - 1;
  826. for (; i>=0; i-=WINDOW) {
  827. /* Fetch another block of bits */
  828. decaf_word_t bits = scalar1x->limb[i/WBITS] >> (i%WBITS);
  829. if (i%WBITS >= WBITS-WINDOW && i/WBITS<DECAF_448_SCALAR_LIMBS-1) {
  830. bits ^= scalar1x->limb[i/WBITS+1] << (WBITS - (i%WBITS));
  831. }
  832. bits &= WINDOW_MASK;
  833. decaf_word_t inv = (bits>>(WINDOW-1))-1;
  834. bits ^= inv;
  835. /* Add in from table. Compute t only on last iteration. */
  836. constant_time_lookup_xx(pn, multiples, sizeof(pn), NTABLE, bits & WINDOW_T_MASK);
  837. cond_neg_niels(pn->n, inv);
  838. if (first) {
  839. pniels_to_pt(tmp, pn);
  840. first = 0;
  841. } else {
  842. /* Using Hisil et al's lookahead method instead of extensible here
  843. * for no particular reason. Double WINDOW times, but only compute t on
  844. * the last one.
  845. */
  846. for (j=0; j<WINDOW-1; j++)
  847. decaf_448_point_double_internal(tmp, tmp, -1);
  848. decaf_448_point_double(tmp, tmp);
  849. add_pniels_to_pt(tmp, pn, i ? -1 : 0);
  850. }
  851. }
  852. /* Write out the answer */
  853. decaf_448_point_copy(a,tmp);
  854. }
  855. void decaf_448_point_double_scalarmul (
  856. decaf_448_point_t a,
  857. const decaf_448_point_t b,
  858. const decaf_448_scalar_t scalarb,
  859. const decaf_448_point_t c,
  860. const decaf_448_scalar_t scalarc
  861. ) {
  862. const int WINDOW = DECAF_WINDOW_BITS,
  863. WINDOW_MASK = (1<<WINDOW)-1,
  864. WINDOW_T_MASK = WINDOW_MASK >> 1,
  865. NTABLE = 1<<(WINDOW-1);
  866. decaf_448_scalar_t scalar1x, scalar2x;
  867. decaf_448_scalar_add(scalar1x, scalarb, decaf_448_point_scalarmul_adjustment);
  868. decaf_448_halve(scalar1x,scalar1x,decaf_448_scalar_p);
  869. decaf_448_scalar_add(scalar2x, scalarc, decaf_448_point_scalarmul_adjustment);
  870. decaf_448_halve(scalar2x,scalar2x,decaf_448_scalar_p);
  871. /* Set up a precomputed table with odd multiples of b. */
  872. pniels_t pn, multiples1[NTABLE], multiples2[NTABLE];
  873. decaf_448_point_t tmp;
  874. prepare_fixed_window(multiples1, b, NTABLE);
  875. prepare_fixed_window(multiples2, c, NTABLE);
  876. /* Initialize. */
  877. int i,j,first=1;
  878. i = DECAF_448_SCALAR_BITS - ((DECAF_448_SCALAR_BITS-1) % WINDOW) - 1;
  879. for (; i>=0; i-=WINDOW) {
  880. /* Fetch another block of bits */
  881. decaf_word_t bits1 = scalar1x->limb[i/WBITS] >> (i%WBITS),
  882. bits2 = scalar2x->limb[i/WBITS] >> (i%WBITS);
  883. if (i%WBITS >= WBITS-WINDOW && i/WBITS<DECAF_448_SCALAR_LIMBS-1) {
  884. bits1 ^= scalar1x->limb[i/WBITS+1] << (WBITS - (i%WBITS));
  885. bits2 ^= scalar2x->limb[i/WBITS+1] << (WBITS - (i%WBITS));
  886. }
  887. bits1 &= WINDOW_MASK;
  888. bits2 &= WINDOW_MASK;
  889. decaf_word_t inv1 = (bits1>>(WINDOW-1))-1;
  890. decaf_word_t inv2 = (bits1>>(WINDOW-1))-1;
  891. bits1 ^= inv1;
  892. bits2 ^= inv2;
  893. /* Add in from table. Compute t only on last iteration. */
  894. constant_time_lookup_xx(pn, multiples1, sizeof(pn), NTABLE, bits1 & WINDOW_T_MASK);
  895. cond_neg_niels(pn->n, inv1);
  896. if (first) {
  897. pniels_to_pt(tmp, pn);
  898. first = 0;
  899. } else {
  900. /* Using Hisil et al's lookahead method instead of extensible here
  901. * for no particular reason. Double WINDOW times, but only compute t on
  902. * the last one.
  903. */
  904. for (j=0; j<WINDOW-1; j++)
  905. decaf_448_point_double_internal(tmp, tmp, -1);
  906. decaf_448_point_double(tmp, tmp);
  907. add_pniels_to_pt(tmp, pn, 0);
  908. }
  909. constant_time_lookup_xx(pn, multiples2, sizeof(pn), NTABLE, bits2 & WINDOW_T_MASK);
  910. cond_neg_niels(pn->n, inv2);
  911. add_pniels_to_pt(tmp, pn, i?-1:0);
  912. }
  913. /* Write out the answer */
  914. decaf_448_point_copy(a,tmp);
  915. }
  916. decaf_bool_t decaf_448_point_eq ( const decaf_448_point_t p, const decaf_448_point_t q ) {
  917. /* equality mod 2-torsion compares x/y */
  918. gf a, b;
  919. gf_mul ( a, p->y, q->x );
  920. gf_mul ( b, q->y, p->x );
  921. return gf_eq(a,b);
  922. }
  923. void decaf_448_point_from_hash_nonuniform (
  924. decaf_448_point_t p,
  925. const unsigned char ser[DECAF_448_SER_BYTES]
  926. ) {
  927. gf r,urr,a,b,c,dee,e,ur2_d,udr2_1;
  928. (void)gf_deser(r,ser);
  929. gf_canon(r);
  930. gf_sqr(a,r);
  931. /* gf_mlw(urr,a,QUADRATIC_NONRESIDUE); */
  932. gf_sub(urr,ZERO,a);
  933. gf_mlw(dee,ONE,EDWARDS_D);
  934. gf_add(a,urr,ONE);
  935. gf_sub(ur2_d,dee,urr);
  936. gf_mul(c,a,ur2_d);
  937. gf_mlw(b,urr,-EDWARDS_D);
  938. gf_add(udr2_1,b,ONE);
  939. gf_mul(a,c,udr2_1);
  940. gf_mlw(c,a,EDWARDS_D+1);
  941. gf_isqrt(b,c); /* FIELD: if 5 mod 8, multiply result by u. */
  942. gf_sqr(a,b);
  943. gf_mul(e,a,c);
  944. decaf_bool_t square = gf_eq(e,ONE);
  945. gf_mul(a,b,r);
  946. cond_sel(b,a,b,square);
  947. gf_mlw(a,b,EDWARDS_D+1);
  948. cond_swap(ur2_d,udr2_1,~square);
  949. gf_mul(e,ur2_d,a);
  950. cond_neg(e,hibit(e)^square);
  951. gf_mul(b,udr2_1,a);
  952. gf_sqr(c,b);
  953. gf_sqr(a,e);
  954. gf_sub(a,ONE,a);
  955. gf_add(e,e,e);
  956. gf_add(b,dee,c);
  957. gf_sub(c,dee,c);
  958. gf_mul(p->x,e,c);
  959. gf_mul(p->z,a,c);
  960. gf_mul(p->y,b,a);
  961. gf_mul(p->t,b,e);
  962. }
  963. void decaf_448_point_from_hash_uniform (
  964. decaf_448_point_t pt,
  965. const unsigned char hashed_data[2*DECAF_448_SER_BYTES]
  966. ) {
  967. decaf_448_point_t pt2;
  968. decaf_448_point_from_hash_nonuniform(pt,hashed_data);
  969. decaf_448_point_from_hash_nonuniform(pt2,&hashed_data[DECAF_448_SER_BYTES]);
  970. decaf_448_point_add(pt,pt,pt2);
  971. }
  972. decaf_bool_t decaf_448_point_valid (
  973. const decaf_448_point_t p
  974. ) {
  975. gf a,b,c;
  976. gf_mul(a,p->x,p->y);
  977. gf_mul(b,p->z,p->t);
  978. decaf_bool_t out = gf_eq(a,b);
  979. gf_sqr(a,p->x);
  980. gf_sqr(b,p->y);
  981. gf_sub(a,b,a);
  982. gf_sqr(b,p->t);
  983. gf_mlw(c,b,1-EDWARDS_D);
  984. gf_sqr(b,p->z);
  985. gf_sub(b,b,c);
  986. out &= gf_eq(a,b);
  987. out &= ~gf_eq(p->z,ZERO);
  988. return out;
  989. }
  990. static void gf_batch_invert (
  991. gf *__restrict__ out,
  992. /* const */ gf *in,
  993. unsigned int n
  994. ) {
  995. // if (n==0) {
  996. // return;
  997. // } else if (n==1) {
  998. // field_inverse(out[0],in[0]);
  999. // return;
  1000. // }
  1001. assert(n>1);
  1002. gf_cpy(out[1], in[0]);
  1003. int i;
  1004. for (i=1; i<(int) (n-1); i++) {
  1005. gf_mul(out[i+1], out[i], in[i]);
  1006. }
  1007. gf_mul(out[0], out[n-1], in[n-1]);
  1008. gf t1, t2;
  1009. gf_isqrt(t1, out[0]);
  1010. gf_sqr(t2, t1);
  1011. gf_sqr(t1, t2);
  1012. gf_mul(t2, t1, out[0]);
  1013. gf_cpy(out[0], t2);
  1014. for (i=n-1; i>0; i--) {
  1015. gf_mul(t1, out[i], out[0]);
  1016. gf_cpy(out[i], t1);
  1017. gf_mul(t1, out[0], in[i]);
  1018. gf_cpy(out[0], t1);
  1019. }
  1020. }
  1021. static void batch_normalize_niels (
  1022. niels_t *table,
  1023. gf *zs,
  1024. gf *zis,
  1025. int n
  1026. ) {
  1027. int i;
  1028. gf product;
  1029. gf_batch_invert(zis, zs, n);
  1030. for (i=0; i<n; i++) {
  1031. gf_mul(product, table[i]->a, zis[i]);
  1032. gf_canon(product);
  1033. gf_cpy(table[i]->a, product);
  1034. gf_mul(product, table[i]->b, zis[i]);
  1035. gf_canon(product);
  1036. gf_cpy(table[i]->b, product);
  1037. gf_mul(product, table[i]->c, zis[i]);
  1038. gf_canon(product);
  1039. gf_cpy(table[i]->c, product);
  1040. }
  1041. }
  1042. void
  1043. decaf_448_precompute (
  1044. decaf_448_precomputed_s *table,
  1045. const decaf_448_point_t base
  1046. ) {
  1047. const unsigned int n = DECAF_COMBS_N, t = DECAF_COMBS_T, s = DECAF_COMBS_S;
  1048. assert(n*t*s >= DECAF_448_SCALAR_BITS);
  1049. decaf_448_point_t working, start, doubles[t-1];
  1050. decaf_448_point_copy(working, base);
  1051. pniels_t pn_tmp;
  1052. gf zs[n<<(t-1)], zis[n<<(t-1)];
  1053. unsigned int i,j,k;
  1054. /* Compute n tables */
  1055. for (i=0; i<n; i++) {
  1056. /* Doubling phase */
  1057. for (j=0; j<t; j++) {
  1058. if (j) decaf_448_point_add(start, start, working);
  1059. else decaf_448_point_copy(start, working);
  1060. if (j==t-1 && i==n-1) break;
  1061. decaf_448_point_double(working, working);
  1062. if (j<t-1) decaf_448_point_copy(doubles[j], working);
  1063. for (k=0; k<s-1; k++)
  1064. decaf_448_point_double_internal(working, working, k<s-2);
  1065. }
  1066. /* Gray-code phase */
  1067. for (j=0;; j++) {
  1068. int gray = j ^ (j>>1);
  1069. int idx = (((i+1)<<(t-1))-1) ^ gray;
  1070. pt_to_pniels(pn_tmp, start);
  1071. memcpy(table->table[idx], pn_tmp->n, sizeof(pn_tmp->n));
  1072. gf_cpy(zs[idx], pn_tmp->z);
  1073. if (j >= (1u<<(t-1)) - 1) break;
  1074. int delta = (j+1) ^ ((j+1)>>1) ^ gray;
  1075. for (k=0; delta>1; k++)
  1076. delta >>=1;
  1077. if (gray & (1<<k)) {
  1078. decaf_448_point_add(start, start, doubles[k]);
  1079. } else {
  1080. decaf_448_point_sub(start, start, doubles[k]);
  1081. }
  1082. }
  1083. }
  1084. batch_normalize_niels(table->table,zs,zis,n<<(t-1));
  1085. }
  1086. extern const decaf_448_scalar_t decaf_448_precomputed_scalarmul_adjustment;
  1087. siv constant_time_lookup_niels (
  1088. niels_s *__restrict__ ni,
  1089. const niels_t *table,
  1090. int nelts,
  1091. int idx
  1092. ) {
  1093. constant_time_lookup_xx(ni, table, sizeof(niels_s), nelts, idx);
  1094. }
  1095. void decaf_448_precomputed_scalarmul (
  1096. decaf_448_point_t out,
  1097. const decaf_448_precomputed_s *table,
  1098. const decaf_448_scalar_t scalar
  1099. ) {
  1100. int i;
  1101. unsigned j,k;
  1102. const unsigned int n = DECAF_COMBS_N, t = DECAF_COMBS_T, s = DECAF_COMBS_S;
  1103. decaf_448_scalar_t scalar1x;
  1104. decaf_448_scalar_add(scalar1x, scalar, decaf_448_precomputed_scalarmul_adjustment);
  1105. decaf_448_halve(scalar1x,scalar1x,decaf_448_scalar_p);
  1106. niels_t ni;
  1107. for (i=s-1; i>=0; i--) {
  1108. if (i != (int)s-1) decaf_448_point_double(out,out);
  1109. for (j=0; j<n; j++) {
  1110. int tab = 0;
  1111. for (k=0; k<t; k++) {
  1112. unsigned int bit = i + s*(k + j*t);
  1113. if (bit < SCALAR_WORDS * WBITS) {
  1114. tab |= (scalar1x->limb[bit/WBITS] >> (bit%WBITS) & 1) << k;
  1115. }
  1116. }
  1117. decaf_bool_t invert = (tab>>(t-1))-1;
  1118. tab ^= invert;
  1119. tab &= (1<<(t-1)) - 1;
  1120. constant_time_lookup_niels(ni, &table->table[j<<(t-1)], 1<<(t-1), tab);
  1121. cond_neg_niels(ni, invert);
  1122. if ((i!=s-1)||j) {
  1123. add_niels_to_pt(out, ni, j==n-1 && i);
  1124. } else {
  1125. niels_to_pt(out, ni);
  1126. }
  1127. }
  1128. }
  1129. }
  1130. #if DECAF_USE_MONTGOMERY_LADDER
  1131. /** Return high bit of x/2 = low bit of x mod p */
  1132. static inline decaf_word_t lobit(gf x) {
  1133. gf_canon(x);
  1134. return -(x->limb[0]&1);
  1135. }
  1136. decaf_bool_t decaf_448_direct_scalarmul (
  1137. uint8_t scaled[DECAF_448_SER_BYTES],
  1138. const uint8_t base[DECAF_448_SER_BYTES],
  1139. const decaf_448_scalar_t scalar,
  1140. decaf_bool_t allow_identity,
  1141. decaf_bool_t short_circuit
  1142. ) {
  1143. /* The Montgomery ladder does not short-circuit return on invalid points,
  1144. * since it detects them during recompress.
  1145. */
  1146. (void)short_circuit;
  1147. gf s0, x0, xa, za, xd, zd, xs, zs, L0, L1;
  1148. decaf_bool_t succ = gf_deser ( s0, base );
  1149. succ &= allow_identity |~ gf_eq( s0, ZERO);
  1150. /* Prepare the Montgomery ladder: Q = 1:0, P+Q = P */
  1151. gf_sqr ( xa, s0 );
  1152. gf_cpy ( x0, xa );
  1153. gf_cpy ( za, ONE );
  1154. gf_cpy ( xd, ONE );
  1155. gf_cpy ( zd, ZERO );
  1156. int j;
  1157. decaf_bool_t pflip = 0;
  1158. for (j=DECAF_448_SCALAR_BITS+1; j>=0; j--) {
  1159. /* FIXME: -1, but the test cases use too many bits */
  1160. /* Augmented Montgomery ladder */
  1161. decaf_bool_t flip = -((scalar->limb[j/WBITS]>>(j%WBITS))&1);
  1162. /* Differential add first... */
  1163. gf_add_nr ( xs, xa, za );
  1164. gf_sub_nr ( zs, xa, za );
  1165. gf_add_nr ( xa, xd, zd );
  1166. gf_sub_nr ( za, xd, zd );
  1167. cond_sel(L0,xa,xs,flip^pflip);
  1168. cond_sel(L1,za,zs,flip^pflip);
  1169. gf_mul ( xd, xa, zs );
  1170. gf_mul ( zd, xs, za );
  1171. gf_add_nr ( xs, xd, zd );
  1172. gf_sub_nr ( zd, xd, zd );
  1173. gf_mul ( zs, zd, s0 );
  1174. gf_sqr ( xa, xs );
  1175. gf_sqr ( za, zs );
  1176. /* ... and then double */
  1177. gf_sqr ( zd, L0 );
  1178. gf_sqr ( L0, L1 );
  1179. gf_sub_nr ( L1, zd, L0 );
  1180. gf_mul ( xd, L0, zd );
  1181. gf_mlw ( zd, L1, 1-EDWARDS_D );
  1182. gf_add_nr ( L0, L0, zd );
  1183. gf_mul ( zd, L0, L1 );
  1184. pflip = flip;
  1185. }
  1186. cond_swap(xa,xd,pflip);
  1187. cond_swap(za,zd,pflip);
  1188. /* OK, time to reserialize! Should be easy (heh, but seriously, TODO: simplify) */
  1189. gf xz_d, xz_a, xz_s, den, L2, L3;
  1190. mask_t zcase, output_zero, sflip, za_zero;
  1191. gf_mul(xz_s, xs, zs);
  1192. gf_mul(xz_d, xd, zd);
  1193. gf_mul(xz_a, xa, za);
  1194. output_zero = gf_eq(xz_d, ZERO);
  1195. xz_d->limb[0] -= output_zero; /* make xz_d always nonzero */
  1196. zcase = output_zero | gf_eq(xz_a, ZERO);
  1197. za_zero = gf_eq(za, ZERO);
  1198. /* Curve test in zcase, compute x0^2 + (2d-4)x0 + 1
  1199. * (we know that x0 = s0^2 is square).
  1200. */
  1201. gf_add(L0,x0,ONE);
  1202. gf_sqr(L1,L0);
  1203. gf_mlw(L0,x0,-4*EDWARDS_D);
  1204. gf_add(L1,L1,L0);
  1205. cond_sel(xz_a,xz_a,L1,zcase);
  1206. /* Compute denominator = x0 xa za xd zd */
  1207. gf_mul(L0, x0, xz_a);
  1208. gf_mul(L1, L0, xz_d);
  1209. gf_isqrt(den, L1);
  1210. /* Check that the square root came out OK. */
  1211. gf_sqr(L2, den);
  1212. gf_mul(L3, L0, L2); /* x0 xa za den^2 = 1/xz_d, for later */
  1213. gf_mul(L0, L1, L2);
  1214. gf_add(L0, L0, ONE);
  1215. succ &= ~hibit(s0) & ~gf_eq(L0, ZERO);
  1216. /* Compute y/x for input and output point. */
  1217. gf_mul(L1, x0, xd);
  1218. gf_sub(L1, zd, L1);
  1219. gf_mul(L0, za, L1); /* L0 = "opq" */
  1220. gf_mul(L1, x0, zd);
  1221. gf_sub(L1, L1, xd);
  1222. gf_mul(L2, xa, L1); /* L2 = "pqr" */
  1223. gf_sub(L1, L0, L2);
  1224. gf_add(L0, L0, L2);
  1225. gf_mul(L2, L1, den); /* L2 = y0 / x0 */
  1226. gf_mul(L1, L0, den); /* L1 = yO / xO */
  1227. sflip = (lobit(L1) ^ lobit(L2)) | za_zero;
  1228. /* OK, done with y-coordinates */
  1229. /* If xa==0 or za ==0: return 0
  1230. * Else if za == 0: return s0 * (sflip ? zd : xd)^2 * L3
  1231. * Else if zd == 0: return s0 * (sflip ? zd : xd)^2 * L3
  1232. * Else if pflip: return xs * zs * (sflip ? zd : xd) * L3
  1233. * Else: return s0 * xs * zs * (sflip ? zd : xd) * den
  1234. */
  1235. cond_sel(xd, xd, zd, sflip); /* xd = actual xd we care about */
  1236. cond_sel(den,den,L3,pflip|zcase);
  1237. cond_sel(xz_s,xz_s,xd,zcase);
  1238. cond_sel(s0,s0,ONE,pflip&~zcase);
  1239. cond_sel(s0,s0,ZERO,output_zero);
  1240. gf_mul(L0,xd,den);
  1241. gf_mul(L1,L0,s0);
  1242. gf_mul(L0,L1,xz_s);
  1243. cond_neg(L0,hibit(L0));
  1244. gf_encode(scaled, L0);
  1245. return succ;
  1246. }
  1247. #else /* DECAF_USE_MONTGOMERY_LADDER */
  1248. decaf_bool_t decaf_448_direct_scalarmul (
  1249. uint8_t scaled[DECAF_448_SER_BYTES],
  1250. const uint8_t base[DECAF_448_SER_BYTES],
  1251. const decaf_448_scalar_t scalar,
  1252. decaf_bool_t allow_identity,
  1253. decaf_bool_t short_circuit
  1254. ) {
  1255. decaf_448_point_t basep;
  1256. decaf_bool_t succ = decaf_448_point_decode(basep, base, allow_identity);
  1257. if (short_circuit & ~succ) return succ;
  1258. decaf_448_point_scalarmul(basep, basep, scalar);
  1259. decaf_448_point_encode(scaled, basep);
  1260. return succ;
  1261. }
  1262. #endif /* DECAF_USE_MONTGOMERY_LADDER */
  1263. /**
  1264. * @cond internal
  1265. * Control for variable-time scalar multiply algorithms.
  1266. */
  1267. struct smvt_control {
  1268. int power, addend;
  1269. };
  1270. static int recode_wnaf (
  1271. struct smvt_control *control, /* [nbits/(tableBits+1) + 3] */
  1272. const decaf_448_scalar_t scalar,
  1273. unsigned int tableBits
  1274. ) {
  1275. int current = 0, i, j;
  1276. unsigned int position = 0;
  1277. /* PERF: negate scalar if it's large
  1278. * PERF: this is a pretty simplistic algorithm. I'm sure there's a faster one...
  1279. */
  1280. for (i=DECAF_448_SCALAR_BITS-1; i >= 0; i--) {
  1281. int bit = (scalar->limb[i/WORD_BITS] >> (i%WORD_BITS)) & 1;
  1282. current = 2*current + bit;
  1283. /*
  1284. * Sizing: |current| >= 2^(tableBits+1) -> |current| = 2^0
  1285. * So current loses (tableBits+1) bits every time. It otherwise gains
  1286. * 1 bit per iteration. The number of iterations is
  1287. * (nbits + 2 + tableBits), and an additional control word is added at
  1288. * the end. So the total number of control words is at most
  1289. * ceil((nbits+1) / (tableBits+1)) + 2 = floor((nbits)/(tableBits+1)) + 2.
  1290. * There's also the stopper with power -1, for a total of +3.
  1291. */
  1292. if (current >= (2<<tableBits) || current <= -1 - (2<<tableBits)) {
  1293. int delta = (current + 1) >> 1; /* |delta| < 2^tablebits */
  1294. current = -(current & 1);
  1295. for (j=i; (delta & 1) == 0; j++) {
  1296. delta >>= 1;
  1297. }
  1298. control[position].power = j+1;
  1299. control[position].addend = delta;
  1300. position++;
  1301. assert(position <= DECAF_448_SCALAR_BITS/(tableBits+1) + 2);
  1302. }
  1303. }
  1304. if (current) {
  1305. for (j=0; (current & 1) == 0; j++) {
  1306. current >>= 1;
  1307. }
  1308. control[position].power = j;
  1309. control[position].addend = current;
  1310. position++;
  1311. assert(position <= DECAF_448_SCALAR_BITS/(tableBits+1) + 2);
  1312. }
  1313. control[position].power = -1;
  1314. control[position].addend = 0;
  1315. return position;
  1316. }
  1317. sv prepare_wnaf_table(
  1318. pniels_t *output,
  1319. const decaf_448_point_t working,
  1320. unsigned int tbits
  1321. ) {
  1322. decaf_448_point_t tmp;
  1323. int i;
  1324. pt_to_pniels(output[0], working);
  1325. if (tbits == 0) return;
  1326. decaf_448_point_double(tmp,working);
  1327. pniels_t twop;
  1328. pt_to_pniels(twop, tmp);
  1329. add_pniels_to_pt(tmp, output[0],0);
  1330. pt_to_pniels(output[1], tmp);
  1331. for (i=2; i < 1<<tbits; i++) {
  1332. add_pniels_to_pt(tmp, twop,0);
  1333. pt_to_pniels(output[i], tmp);
  1334. }
  1335. }
  1336. extern const decaf_word_t decaf_448_precomputed_wnaf_as_words[];
  1337. static const niels_t *decaf_448_wnaf_base = (const niels_t *)decaf_448_precomputed_wnaf_as_words;
  1338. const size_t sizeof_decaf_448_precomputed_wnafs __attribute((visibility("hidden")))
  1339. = sizeof(niels_t)<<DECAF_WNAF_FIXED_TABLE_BITS;
  1340. void decaf_448_precompute_wnafs (
  1341. niels_t out[1<<DECAF_WNAF_FIXED_TABLE_BITS],
  1342. const decaf_448_point_t base
  1343. ) __attribute__ ((visibility ("hidden")));
  1344. void decaf_448_precompute_wnafs (
  1345. niels_t out[1<<DECAF_WNAF_FIXED_TABLE_BITS],
  1346. const decaf_448_point_t base
  1347. ) {
  1348. pniels_t tmp[1<<DECAF_WNAF_FIXED_TABLE_BITS];
  1349. gf zs[1<<DECAF_WNAF_FIXED_TABLE_BITS], zis[1<<DECAF_WNAF_FIXED_TABLE_BITS];
  1350. int i;
  1351. prepare_wnaf_table(tmp,base,DECAF_WNAF_FIXED_TABLE_BITS);
  1352. for (i=0; i<1<<DECAF_WNAF_FIXED_TABLE_BITS; i++) {
  1353. memcpy(out[i], tmp[i]->n, sizeof(niels_t));
  1354. gf_cpy(zs[i], tmp[i]->z);
  1355. }
  1356. batch_normalize_niels(out, zs, zis, 1<<DECAF_WNAF_FIXED_TABLE_BITS);
  1357. }
  1358. void decaf_448_base_double_scalarmul_non_secret (
  1359. decaf_448_point_t combo,
  1360. const decaf_448_scalar_t scalar1,
  1361. const decaf_448_point_t base2,
  1362. const decaf_448_scalar_t scalar2
  1363. ) {
  1364. const int table_bits_var = DECAF_WNAF_VAR_TABLE_BITS,
  1365. table_bits_pre = DECAF_WNAF_FIXED_TABLE_BITS;
  1366. struct smvt_control control_var[DECAF_448_SCALAR_BITS/(table_bits_var+1)+3];
  1367. struct smvt_control control_pre[DECAF_448_SCALAR_BITS/(table_bits_pre+1)+3];
  1368. int ncb_pre = recode_wnaf(control_pre, scalar1, table_bits_pre);
  1369. int ncb_var = recode_wnaf(control_var, scalar2, table_bits_var);
  1370. pniels_t precmp_var[1<<table_bits_var];
  1371. prepare_wnaf_table(precmp_var, base2, table_bits_var);
  1372. int contp=0, contv=0, i = control_var[0].power;
  1373. if (i < 0) {
  1374. decaf_448_point_copy(combo, decaf_448_point_identity);
  1375. return;
  1376. } else if (i > control_pre[0].power) {
  1377. pniels_to_pt(combo, precmp_var[control_var[0].addend >> 1]);
  1378. contv++;
  1379. } else if (i == control_pre[0].power && i >=0 ) {
  1380. pniels_to_pt(combo, precmp_var[control_var[0].addend >> 1]);
  1381. add_niels_to_pt(combo, decaf_448_wnaf_base[control_pre[0].addend >> 1], i);
  1382. contv++; contp++;
  1383. } else {
  1384. i = control_pre[0].power;
  1385. niels_to_pt(combo, decaf_448_wnaf_base[control_pre[0].addend >> 1]);
  1386. contp++;
  1387. }
  1388. for (i--; i >= 0; i--) {
  1389. int cv = (i==control_var[contv].power), cp = (i==control_pre[contp].power);
  1390. decaf_448_point_double_internal(combo,combo,i && !(cv||cp));
  1391. if (cv) {
  1392. assert(control_var[contv].addend);
  1393. if (control_var[contv].addend > 0) {
  1394. add_pniels_to_pt(combo, precmp_var[control_var[contv].addend >> 1], i&&!cp);
  1395. } else {
  1396. sub_pniels_from_pt(combo, precmp_var[(-control_var[contv].addend) >> 1], i&&!cp);
  1397. }
  1398. contv++;
  1399. }
  1400. if (cp) {
  1401. assert(control_pre[contp].addend);
  1402. if (control_pre[contp].addend > 0) {
  1403. add_niels_to_pt(combo, decaf_448_wnaf_base[control_pre[contp].addend >> 1], i);
  1404. } else {
  1405. sub_niels_from_pt(combo, decaf_448_wnaf_base[(-control_pre[contp].addend) >> 1], i);
  1406. }
  1407. contp++;
  1408. }
  1409. }
  1410. assert(contv == ncb_var); (void)ncb_var;
  1411. assert(contp == ncb_pre); (void)ncb_pre;
  1412. }
  1413. void decaf_448_point_destroy (
  1414. decaf_448_point_t point
  1415. ) {
  1416. decaf_bzero(point, sizeof(decaf_448_point_t));
  1417. }
  1418. void decaf_448_precomputed_destroy (
  1419. decaf_448_precomputed_s *pre
  1420. ) {
  1421. decaf_bzero(pre, sizeof_decaf_448_precomputed_s);
  1422. }