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.
 
 
 
 
 

943 lines
26 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 "ec_point.h" // REMOVE!
  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. typedef decaf_word_t gf[DECAF_448_LIMBS] __attribute__((aligned(32)));
  33. static const gf ZERO = {0}, ONE = {1}, TWO = {2};
  34. #define LMASK ((((decaf_word_t)1)<<LBITS)-1)
  35. #if WBITS == 64
  36. static const gf P = { LMASK, LMASK, LMASK, LMASK, LMASK-1, LMASK, LMASK, LMASK };
  37. #else
  38. static const gf P = { LMASK, LMASK, LMASK, LMASK, LMASK, LMASK, LMASK, LMASK,
  39. LMASK-1, LMASK, LMASK, LMASK, LMASK, LMASK, LMASK, LMASK };
  40. #endif
  41. static const int EDWARDS_D = -39081;
  42. const decaf_448_scalar_t decaf_448_scalar_p = {{{
  43. SC_LIMB(0x2378c292ab5844f3),
  44. SC_LIMB(0x216cc2728dc58f55),
  45. SC_LIMB(0xc44edb49aed63690),
  46. SC_LIMB(0xffffffff7cca23e9),
  47. SC_LIMB(0xffffffffffffffff),
  48. SC_LIMB(0xffffffffffffffff),
  49. SC_LIMB(0x3fffffffffffffff)
  50. }}}, decaf_448_scalar_one = {{{1}}}, decaf_448_scalar_zero = {{{0}}};
  51. static const decaf_448_scalar_t decaf_448_scalar_r2 = {{{
  52. SC_LIMB(0xe3539257049b9b60),
  53. SC_LIMB(0x7af32c4bc1b195d9),
  54. SC_LIMB(0x0d66de2388ea1859),
  55. SC_LIMB(0xae17cf725ee4d838),
  56. SC_LIMB(0x1a9cc14ba3c47c44),
  57. SC_LIMB(0x2052bcb7e4d070af),
  58. SC_LIMB(0x3402a939f823b729)
  59. }}};
  60. static const decaf_word_t DECAF_MONTGOMERY_FACTOR = (decaf_word_t)(0x3bd440fae918bc5ull);
  61. /** base = twist of Goldilocks base point (~,19). */
  62. const decaf_448_point_t decaf_448_point_base = {{
  63. { LIMB(0xb39a2d57e08c7b),LIMB(0xb38639c75ff281),
  64. LIMB(0x2ec981082b3288),LIMB(0x99fe8607e5237c),
  65. LIMB(0x0e33fbb1fadd1f),LIMB(0xe714f67055eb4a),
  66. LIMB(0xc9ae06d64067dd),LIMB(0xf7be45054760fa) },
  67. { LIMB(0xbd8715f551617f),LIMB(0x8c17fbeca8f5fc),
  68. LIMB(0xaae0eec209c06f),LIMB(0xce41ad80cbe6b8),
  69. LIMB(0xdf360b5c828c00),LIMB(0xaf25b6bbb40e3b),
  70. LIMB(0x8ed37f0ce4ed31),LIMB(0x72a1c3214557b9) },
  71. { 1 },
  72. { LIMB(0x97ca9c8ed8bde9),LIMB(0xf0b780da83304c),
  73. LIMB(0x0d79c0a7729a69),LIMB(0xc18d3f24aebc1c),
  74. LIMB(0x1fbb5389b3fda5),LIMB(0xbb24f674635948),
  75. LIMB(0x723a55709a3983),LIMB(0xe1c0107a823dd4) }
  76. }};
  77. struct decaf_448_precomputed_s {
  78. decaf_448_point_t p[1];
  79. };
  80. const struct decaf_448_precomputed_s *decaf_448_precomputed_base =
  81. (const struct decaf_448_precomputed_s *)decaf_448_point_base;
  82. const size_t sizeof_decaf_448_precomputed_s = sizeof(struct decaf_448_precomputed_s);
  83. const size_t alignof_decaf_448_precomputed_s = 32;
  84. #if (defined(__OPTIMIZE__) && !defined(__OPTIMIZE_SIZE__)) || defined(DECAF_FORCE_UNROLL)
  85. #if DECAF_448_LIMBS==8
  86. #define FOR_LIMB(i,op) { unsigned int i=0; \
  87. op;i++; op;i++; op;i++; op;i++; op;i++; op;i++; op;i++; op;i++; \
  88. }
  89. #elif DECAF_448_LIMBS==16
  90. #define FOR_LIMB(i,op) { unsigned int i=0; \
  91. op;i++; op;i++; op;i++; op;i++; op;i++; op;i++; op;i++; op;i++; \
  92. op;i++; op;i++; op;i++; op;i++; op;i++; op;i++; op;i++; op;i++; \
  93. }
  94. #else
  95. #define FOR_LIMB(i,op) { unsigned int i=0; for (i=0; i<DECAF_448_LIMBS; i++) { op; }}
  96. #endif
  97. #else
  98. #define FOR_LIMB(i,op) { unsigned int i=0; for (i=0; i<DECAF_448_LIMBS; i++) { op; }}
  99. #endif
  100. /** Copy x = y */
  101. sv gf_cpy(gf x, const gf y) { FOR_LIMB(i, x[i] = y[i]); }
  102. /** Mostly-unoptimized multiply (PERF), but at least it's unrolled. */
  103. static inline void gf_mul (gf c, const gf a, const gf b) {
  104. field_mul((field_t *)c, (const field_t *)a, (const field_t *)b);
  105. }
  106. /** No dedicated square (PERF) */
  107. static inline void gf_sqr (gf c, const gf a) {
  108. field_sqr((field_t *)c, (const field_t *)a);
  109. }
  110. /** Inverse square root using addition chain. */
  111. sv gf_isqrt(gf y, const gf x) {
  112. field_isr((field_t *)y, (const field_t *)x);
  113. }
  114. /** Add mod p. Conservatively always weak-reduce. (PERF) */
  115. static inline void gf_add ( gf c, const gf a, const gf b ) {
  116. field_add((field_t *)c, (const field_t *)a, (const field_t *)b);
  117. }
  118. /** Subtract mod p. Conservatively always weak-reduce. (PERF) */
  119. static inline void gf_sub ( gf c, const gf a, const gf b ) {
  120. field_sub((field_t *)c, (const field_t *)a, (const field_t *)b);
  121. }
  122. /** Add mod p. Conservatively always weak-reduce. (PERF) */
  123. static inline void gf_bias ( gf c, int amt) {
  124. field_bias((field_t *)c, amt);
  125. }
  126. /** Subtract mod p. Bias by 2 and don't reduce */
  127. static inline void gf_sub_nr ( gf c, const gf a, const gf b ) {
  128. ANALYZE_THIS_ROUTINE_CAREFULLY; //TODO
  129. field_sub_nr((field_t *)c, (const field_t *)a, (const field_t *)b);
  130. gf_bias(c, 2);
  131. }
  132. /** Subtract mod p. Bias by amt but don't reduce. */
  133. static inline void gf_sub_nr_x ( gf c, const gf a, const gf b, int amt ) {
  134. ANALYZE_THIS_ROUTINE_CAREFULLY; //TODO
  135. field_sub_nr((field_t *)c, (const field_t *)a, (const field_t *)b);
  136. gf_bias(c, amt);
  137. }
  138. /** Add mod p. Don't reduce. */
  139. static inline void gf_add_nr ( gf c, const gf a, const gf b ) {
  140. ANALYZE_THIS_ROUTINE_CAREFULLY; //TODO
  141. field_add_nr((field_t *)c, (const field_t *)a, (const field_t *)b);
  142. }
  143. /** Constant time, x = is_z ? z : y */
  144. sv cond_sel(gf x, const gf y, const gf z, decaf_bool_t is_z) {
  145. FOR_LIMB(i, x[i] = (y[i] & ~is_z) | (z[i] & is_z) );
  146. }
  147. /** Constant time, if (neg) x=-x; */
  148. sv cond_neg(gf x, decaf_bool_t neg) {
  149. gf y;
  150. gf_sub(y,ZERO,x);
  151. cond_sel(x,x,y,neg);
  152. }
  153. /** Constant time, if (swap) (x,y) = (y,x); */
  154. sv cond_swap(gf x, gf y, decaf_bool_t swap) {
  155. FOR_LIMB(i, {
  156. decaf_word_t s = (x[i] ^ y[i]) & swap;
  157. x[i] ^= s;
  158. y[i] ^= s;
  159. });
  160. }
  161. /**
  162. * Mul by signed int. Not constant-time WRT the sign of that int.
  163. * Just uses a full mul (PERF)
  164. */
  165. static inline void gf_mlw(gf c, const gf a, int w) {
  166. if (w>0) {
  167. field_mulw((field_t *)c, (const field_t *)a, w);
  168. } else {
  169. field_mulw((field_t *)c, (const field_t *)a, -w);
  170. gf_sub(c,ZERO,c);
  171. }
  172. }
  173. /** Canonicalize */
  174. static inline void gf_canon ( gf a ) {
  175. field_strong_reduce((field_t *)a);
  176. }
  177. /** Compare a==b */
  178. static decaf_word_t __attribute__((noinline)) gf_eq(const gf a, const gf b) {
  179. gf c;
  180. gf_sub(c,a,b);
  181. gf_canon(c);
  182. decaf_word_t ret=0;
  183. FOR_LIMB(i, ret |= c[i] );
  184. /* Hope the compiler is too dumb to optimize this, thus noinline */
  185. return ((decaf_dword_t)ret - 1) >> WBITS;
  186. }
  187. /** Return high bit of x = low bit of 2x mod p */
  188. static decaf_word_t hibit(const gf x) {
  189. gf y;
  190. gf_add(y,x,x);
  191. gf_canon(y);
  192. return -(y[0]&1);
  193. }
  194. /* a = use_c ? c : b */
  195. sv decaf_448_cond_sel (
  196. decaf_448_point_t a,
  197. const decaf_448_point_t b,
  198. const decaf_448_point_t c,
  199. decaf_bool_t use_c
  200. ) {
  201. cond_sel(a->x, b->x, c->x, use_c);
  202. cond_sel(a->y, b->y, c->y, use_c);
  203. cond_sel(a->z, b->z, c->z, use_c);
  204. cond_sel(a->t, b->t, c->t, use_c);
  205. }
  206. /** {extra,accum} - sub +? p
  207. * Must have extra <= 1
  208. */
  209. sv decaf_448_subx(
  210. decaf_448_scalar_t out,
  211. const decaf_word_t accum[DECAF_448_SCALAR_LIMBS],
  212. const decaf_448_scalar_t sub,
  213. const decaf_448_scalar_t p,
  214. decaf_word_t extra
  215. ) {
  216. decaf_sdword_t chain = 0;
  217. unsigned int i;
  218. for (i=0; i<DECAF_448_SCALAR_LIMBS; i++) {
  219. chain = (chain + accum[i]) - sub->limb[i];
  220. out->limb[i] = chain;
  221. chain >>= WBITS;
  222. }
  223. decaf_bool_t borrow = chain+extra; /* = 0 or -1 */
  224. chain = 0;
  225. for (i=0; i<DECAF_448_SCALAR_LIMBS; i++) {
  226. chain = (chain + out->limb[i]) + (p->limb[i] & borrow);
  227. out->limb[i] = chain;
  228. chain >>= WBITS;
  229. }
  230. }
  231. sv decaf_448_montmul (
  232. decaf_448_scalar_t out,
  233. const decaf_448_scalar_t a,
  234. const decaf_448_scalar_t b,
  235. const decaf_448_scalar_t p,
  236. decaf_word_t montgomery_factor
  237. ) {
  238. unsigned int i,j;
  239. decaf_word_t accum[DECAF_448_SCALAR_LIMBS+1] = {0};
  240. decaf_word_t hi_carry = 0;
  241. for (i=0; i<DECAF_448_SCALAR_LIMBS; i++) {
  242. decaf_word_t mand = a->limb[i];
  243. const decaf_word_t *mier = b->limb;
  244. decaf_dword_t chain = 0;
  245. for (j=0; j<DECAF_448_SCALAR_LIMBS; j++) {
  246. chain += ((decaf_dword_t)mand)*mier[j] + accum[j];
  247. accum[j] = chain;
  248. chain >>= WBITS;
  249. }
  250. accum[j] = chain;
  251. mand = accum[0] * montgomery_factor;
  252. chain = 0;
  253. mier = p->limb;
  254. for (j=0; j<DECAF_448_SCALAR_LIMBS; j++) {
  255. chain += (decaf_dword_t)mand*mier[j] + accum[j];
  256. if (j) accum[j-1] = chain;
  257. chain >>= WBITS;
  258. }
  259. chain += accum[j];
  260. chain += hi_carry;
  261. accum[j-1] = chain;
  262. hi_carry = chain >> WBITS;
  263. }
  264. decaf_448_subx(out, accum, p, p, hi_carry);
  265. }
  266. void decaf_448_scalar_mul (
  267. decaf_448_scalar_t out,
  268. const decaf_448_scalar_t a,
  269. const decaf_448_scalar_t b
  270. ) {
  271. decaf_448_montmul(out,a,b,decaf_448_scalar_p,DECAF_MONTGOMERY_FACTOR);
  272. decaf_448_montmul(out,out,decaf_448_scalar_r2,decaf_448_scalar_p,DECAF_MONTGOMERY_FACTOR);
  273. }
  274. void decaf_448_scalar_sub (
  275. decaf_448_scalar_t out,
  276. const decaf_448_scalar_t a,
  277. const decaf_448_scalar_t b
  278. ) {
  279. decaf_448_subx(out, a->limb, b, decaf_448_scalar_p, 0);
  280. }
  281. void decaf_448_scalar_add (
  282. decaf_448_scalar_t out,
  283. const decaf_448_scalar_t a,
  284. const decaf_448_scalar_t b
  285. ) {
  286. decaf_dword_t chain = 0;
  287. unsigned int i;
  288. for (i=0; i<DECAF_448_SCALAR_LIMBS; i++) {
  289. chain = (chain + a->limb[i]) + b->limb[i];
  290. out->limb[i] = chain;
  291. chain >>= WBITS;
  292. }
  293. decaf_448_subx(out, out->limb, decaf_448_scalar_p, decaf_448_scalar_p, chain);
  294. }
  295. void decaf_448_scalar_copy (
  296. decaf_448_scalar_t out,
  297. const decaf_448_scalar_t a
  298. ) {
  299. unsigned int i;
  300. for (i=0; i<DECAF_448_SCALAR_LIMBS; i++) {
  301. out->limb[i] = a->limb[i];
  302. }
  303. }
  304. decaf_bool_t decaf_448_scalar_eq (
  305. const decaf_448_scalar_t a,
  306. const decaf_448_scalar_t b
  307. ) {
  308. decaf_word_t diff = 0;
  309. unsigned int i;
  310. for (i=0; i<DECAF_448_SCALAR_LIMBS; i++) {
  311. diff |= a->limb[i] ^ b->limb[i];
  312. }
  313. return (((decaf_dword_t)diff)-1)>>WBITS;
  314. }
  315. /* *** API begins here *** */
  316. /** identity = (0,1) */
  317. const decaf_448_point_t decaf_448_point_identity = {{{0},{1},{1},{0}}};
  318. void decaf_448_point_encode( unsigned char ser[DECAF_448_SER_BYTES], const decaf_448_point_t p ) {
  319. /* Can shave off one mul here; not important but makes consistent with paper */
  320. gf a, b, c, d;
  321. gf_mlw ( a, p->y, 1-EDWARDS_D );
  322. gf_mul ( c, a, p->t );
  323. gf_mul ( a, p->x, p->z );
  324. gf_sub ( d, c, a );
  325. gf_add ( a, p->z, p->y );
  326. gf_sub ( b, p->z, p->y );
  327. gf_mul ( c, b, a );
  328. gf_mlw ( b, c, -EDWARDS_D );
  329. gf_isqrt ( a, b );
  330. gf_mlw ( b, a, -EDWARDS_D );
  331. gf_mul ( c, b, a );
  332. gf_mul ( a, c, d );
  333. gf_add ( d, b, b );
  334. gf_mul ( c, d, p->z );
  335. cond_neg ( b, ~hibit(c) );
  336. gf_mul ( c, b, p->y );
  337. gf_add ( a, a, c );
  338. cond_neg ( a, hibit(a) );
  339. gf_canon(a);
  340. int i, k=0, bits=0;
  341. decaf_dword_t buf=0;
  342. for (i=0; i<DECAF_448_LIMBS; i++) {
  343. buf |= (decaf_dword_t)a[i]<<bits;
  344. for (bits += LBITS; (bits>=8 || i==DECAF_448_LIMBS-1) && k<DECAF_448_SER_BYTES; bits-=8, buf>>=8) {
  345. ser[k++]=buf;
  346. }
  347. }
  348. }
  349. /**
  350. * Deserialize a bool, return TRUE if < p.
  351. */
  352. static decaf_bool_t gf_deser(gf s, const unsigned char ser[DECAF_448_SER_BYTES]) {
  353. unsigned int i, k=0, bits=0;
  354. decaf_dword_t buf=0;
  355. for (i=0; i<DECAF_448_SER_BYTES; i++) {
  356. buf |= (decaf_dword_t)ser[i]<<bits;
  357. for (bits += 8; (bits>=LBITS || i==DECAF_448_SER_BYTES-1) && k<DECAF_448_LIMBS; bits-=LBITS, buf>>=LBITS) {
  358. s[k++] = buf & LMASK;
  359. }
  360. }
  361. decaf_sdword_t accum = 0;
  362. FOR_LIMB(i, accum = (accum + s[i] - P[i]) >> WBITS );
  363. return accum;
  364. }
  365. /* Constant-time add or subtract */
  366. sv decaf_448_point_add_sub (
  367. decaf_448_point_t p,
  368. const decaf_448_point_t q,
  369. const decaf_448_point_t r,
  370. decaf_bool_t do_sub
  371. ) {
  372. /* Twisted Edward formulas, complete when 4-torsion isn't involved */
  373. gf a, b, c, d;
  374. gf_sub_nr ( b, q->y, q->x );
  375. gf_sub_nr ( c, r->y, r->x );
  376. gf_add_nr ( d, r->y, r->x );
  377. cond_swap(c,d,do_sub);
  378. gf_mul ( a, c, b );
  379. gf_add_nr ( b, q->y, q->x );
  380. gf_mul ( p->y, d, b );
  381. gf_mul ( b, r->t, q->t );
  382. gf_mlw ( p->x, b, 2-2*EDWARDS_D );
  383. gf_add_nr ( b, a, p->y );
  384. gf_sub_nr ( c, p->y, a );
  385. gf_mul ( a, q->z, r->z );
  386. gf_add_nr ( a, a, a );
  387. gf_add_nr ( p->y, a, p->x );
  388. gf_sub_nr ( a, a, p->x );
  389. cond_swap(a,p->y,do_sub);
  390. gf_mul ( p->z, a, p->y );
  391. gf_mul ( p->x, p->y, c );
  392. gf_mul ( p->y, a, b );
  393. gf_mul ( p->t, b, c );
  394. }
  395. decaf_bool_t decaf_448_point_decode (
  396. decaf_448_point_t p,
  397. const unsigned char ser[DECAF_448_SER_BYTES],
  398. decaf_bool_t allow_identity
  399. ) {
  400. gf s, a, b, c, d, e;
  401. decaf_bool_t succ = gf_deser(s, ser), zero = gf_eq(s, ZERO);
  402. succ &= allow_identity | ~zero;
  403. succ &= ~hibit(s);
  404. gf_sqr ( a, s );
  405. gf_sub ( p->z, ONE, a );
  406. gf_sqr ( b, p->z );
  407. gf_mlw ( c, a, 4-4*EDWARDS_D );
  408. gf_add ( c, c, b );
  409. gf_mul ( b, c, a );
  410. gf_isqrt ( d, b );
  411. gf_sqr ( e, d );
  412. gf_mul ( a, e, b );
  413. gf_add ( a, a, ONE );
  414. succ &= ~gf_eq ( a, ZERO );
  415. gf_mul ( b, c, d );
  416. cond_neg ( d, hibit(b) );
  417. gf_add ( p->x, s, s );
  418. gf_mul ( c, d, s );
  419. gf_sub ( b, TWO, p->z );
  420. gf_mul ( a, b, c );
  421. gf_mul ( p->y,a,p->z );
  422. gf_mul ( p->t,p->x,a );
  423. p->y[0] -= zero;
  424. /* TODO: do something safe if ~succ? */
  425. return succ;
  426. }
  427. void decaf_448_point_sub (
  428. decaf_448_point_t p,
  429. const decaf_448_point_t q,
  430. const decaf_448_point_t r
  431. ) {
  432. gf a, b, c, d;
  433. gf_sub_nr ( b, q->y, q->x );
  434. gf_sub_nr ( d, r->y, r->x );
  435. gf_add_nr ( c, r->y, r->x );
  436. gf_mul ( a, c, b );
  437. gf_add_nr ( b, q->y, q->x );
  438. gf_mul ( p->y, d, b );
  439. gf_mul ( b, r->t, q->t );
  440. gf_mlw ( p->x, b, 2-2*EDWARDS_D );
  441. gf_add_nr ( b, a, p->y );
  442. gf_sub_nr ( c, p->y, a );
  443. gf_mul ( a, q->z, r->z );
  444. gf_add_nr ( a, a, a );
  445. gf_sub_nr ( p->y, a, p->x );
  446. gf_add_nr ( a, a, p->x );
  447. gf_mul ( p->z, a, p->y );
  448. gf_mul ( p->x, p->y, c );
  449. gf_mul ( p->y, a, b );
  450. gf_mul ( p->t, b, c );
  451. }
  452. void decaf_448_point_add (
  453. decaf_448_point_t p,
  454. const decaf_448_point_t q,
  455. const decaf_448_point_t r
  456. ) {
  457. gf a, b, c, d;
  458. gf_sub_nr ( b, q->y, q->x );
  459. gf_sub_nr ( c, r->y, r->x );
  460. gf_add_nr ( d, r->y, r->x );
  461. gf_mul ( a, c, b );
  462. gf_add_nr ( b, q->y, q->x );
  463. gf_mul ( p->y, d, b );
  464. gf_mul ( b, r->t, q->t );
  465. gf_mlw ( p->x, b, 2-2*EDWARDS_D );
  466. gf_add_nr ( b, a, p->y );
  467. gf_sub_nr ( c, p->y, a );
  468. gf_mul ( a, q->z, r->z );
  469. gf_add_nr ( a, a, a );
  470. gf_add_nr ( p->y, a, p->x );
  471. gf_sub_nr ( a, a, p->x );
  472. gf_mul ( p->z, a, p->y );
  473. gf_mul ( p->x, p->y, c );
  474. gf_mul ( p->y, a, b );
  475. gf_mul ( p->t, b, c );
  476. }
  477. /* No dedicated point double yet (PERF) */
  478. void decaf_448_point_double(decaf_448_point_t p, const decaf_448_point_t q) {
  479. gf a, b, c, d;
  480. gf_sqr ( c, q->x );
  481. gf_sqr ( a, q->y );
  482. gf_add_nr ( d, c, a );
  483. gf_add_nr ( p->t, q->y, q->x );
  484. gf_sqr ( b, p->t );
  485. gf_sub_nr_x ( b, b, d, 3 );
  486. gf_sub_nr ( p->t, a, c );
  487. gf_sqr ( p->x, q->z );
  488. gf_add_nr ( p->z, p->x, p->x );
  489. gf_sub_nr_x ( a, p->z, p->t, 4 );
  490. gf_mul ( p->x, a, b );
  491. gf_mul ( p->z, p->t, a );
  492. gf_mul ( p->y, p->t, d );
  493. gf_mul ( p->t, b, d );
  494. }
  495. void decaf_448_point_copy (
  496. decaf_448_point_t a,
  497. const decaf_448_point_t b
  498. ) {
  499. gf_cpy(a->x, b->x);
  500. gf_cpy(a->y, b->y);
  501. gf_cpy(a->z, b->z);
  502. gf_cpy(a->t, b->t);
  503. }
  504. decaf_bool_t decaf_448_scalar_decode(
  505. decaf_448_scalar_t s,
  506. const unsigned char ser[DECAF_448_SER_BYTES]
  507. ) {
  508. unsigned int i,j,k=0;
  509. for (i=0; i<DECAF_448_SCALAR_LIMBS; i++) {
  510. decaf_word_t out = 0;
  511. for (j=0; j<sizeof(decaf_word_t); j++,k++) {
  512. out |= ((decaf_word_t)ser[k])<<(8*j);
  513. }
  514. s->limb[i] = out;
  515. }
  516. decaf_sdword_t accum = 0;
  517. for (i=0; i<DECAF_448_SCALAR_LIMBS; i++) {
  518. accum = (accum + s->limb[i] - decaf_448_scalar_p->limb[i]) >> WBITS;
  519. }
  520. decaf_448_scalar_mul(s,s,decaf_448_scalar_one); /* ham-handed reduce */
  521. return accum;
  522. }
  523. void decaf_bzero (
  524. void *s,
  525. size_t size
  526. ) {
  527. #ifdef __STDC_LIB_EXT1__
  528. memset_s(s, size, 0, size);
  529. #else
  530. volatile uint8_t *destroy = (volatile uint8_t *)s;
  531. unsigned i;
  532. for (i=0; i<size; i++) {
  533. destroy[i] = 0;
  534. }
  535. #endif
  536. }
  537. void decaf_448_scalar_destroy (
  538. decaf_448_scalar_t scalar
  539. ) {
  540. decaf_bzero(scalar, sizeof(decaf_448_scalar_t));
  541. }
  542. static inline void ignore_result ( decaf_bool_t boo ) {
  543. (void)boo;
  544. }
  545. void decaf_448_scalar_decode_long(
  546. decaf_448_scalar_t s,
  547. const unsigned char *ser,
  548. size_t ser_len
  549. ) {
  550. if (ser_len == 0) {
  551. decaf_448_scalar_copy(s, decaf_448_scalar_zero);
  552. return;
  553. }
  554. size_t i;
  555. unsigned char tmp[DECAF_448_SER_BYTES] = {0};
  556. decaf_448_scalar_t t1, t2;
  557. i = ser_len - (ser_len%DECAF_448_SER_BYTES);
  558. if (i==ser_len) i -= DECAF_448_SER_BYTES;
  559. memcpy(tmp, ser+i, ser_len - i);
  560. ignore_result( decaf_448_scalar_decode(t1, tmp) );
  561. decaf_bzero(tmp, sizeof(tmp));
  562. while (i) {
  563. i -= DECAF_448_SER_BYTES;
  564. decaf_448_montmul(t1,t1,decaf_448_scalar_r2,decaf_448_scalar_p,DECAF_MONTGOMERY_FACTOR);
  565. ignore_result( decaf_448_scalar_decode(t2, ser+i) );
  566. decaf_448_scalar_add(t1, t1, t2);
  567. }
  568. decaf_448_scalar_copy(s, t1);
  569. decaf_448_scalar_destroy(t1);
  570. decaf_448_scalar_destroy(t2);
  571. }
  572. void decaf_448_scalar_encode(
  573. unsigned char ser[DECAF_448_SER_BYTES],
  574. const decaf_448_scalar_t s
  575. ) {
  576. unsigned int i,j,k=0;
  577. for (i=0; i<DECAF_448_SCALAR_LIMBS; i++) {
  578. for (j=0; j<sizeof(decaf_word_t); j++,k++) {
  579. ser[k] = s->limb[i] >> (8*j);
  580. }
  581. }
  582. }
  583. void decaf_448_point_scalarmul (
  584. decaf_448_point_t a,
  585. const decaf_448_point_t b,
  586. const decaf_448_scalar_t scalar
  587. ) {
  588. /* w=2 signed window uses about 1.5 adds per bit.
  589. * I figured a few extra lines was worth the 25% speedup.
  590. */
  591. decaf_448_point_t w,b3,tmp;
  592. decaf_448_point_double(w,b);
  593. /* b3 = b*3 */
  594. decaf_448_point_add(b3,w,b);
  595. int i;
  596. for (i=DECAF_448_SCALAR_BITS &~ 1; i>0; i-=2) {
  597. decaf_word_t bits = scalar->limb[i/WBITS]>>(i%WBITS);
  598. decaf_448_cond_sel(tmp,b,b3,((bits^(bits>>1))&1)-1);
  599. decaf_448_point_double(w,w);
  600. decaf_448_point_add_sub(w,w,tmp,((bits>>1)&1)-1);
  601. decaf_448_point_double(w,w);
  602. }
  603. decaf_448_point_add_sub(w,w,b,((scalar->limb[0]>>1)&1)-1);
  604. /* low bit is special because fo signed window */
  605. decaf_448_cond_sel(tmp,b,decaf_448_point_identity,-(scalar->limb[0]&1));
  606. decaf_448_point_sub(a,w,tmp);
  607. }
  608. void decaf_448_point_double_scalarmul (
  609. decaf_448_point_t a,
  610. const decaf_448_point_t b,
  611. const decaf_448_scalar_t scalarb,
  612. const decaf_448_point_t c,
  613. const decaf_448_scalar_t scalarc
  614. ) {
  615. /* w=2 signed window uses about 1.5 adds per bit.
  616. * I figured a few extra lines was worth the 25% speedup.
  617. * NB: if adapting this function to scalarmul by a
  618. * possibly-odd number of unmasked bits, may need to mask.
  619. */
  620. decaf_448_point_t w,b3,c3,tmp;
  621. decaf_448_point_double(w,b);
  622. decaf_448_point_double(tmp,c);
  623. /* b3 = b*3 */
  624. decaf_448_point_add(b3,w,b);
  625. decaf_448_point_add(c3,tmp,c);
  626. decaf_448_point_add(w,w,tmp);
  627. int i;
  628. for (i=DECAF_448_SCALAR_BITS &~ 1; i>0; i-=2) {
  629. decaf_448_point_double(w,w);
  630. decaf_word_t bits = scalarb->limb[i/WBITS]>>(i%WBITS);
  631. decaf_448_cond_sel(tmp,b,b3,((bits^(bits>>1))&1)-1);
  632. decaf_448_point_add_sub(w,w,tmp,((bits>>1)&1)-1);
  633. bits = scalarc->limb[i/WBITS]>>(i%WBITS);
  634. decaf_448_cond_sel(tmp,c,c3,((bits^(bits>>1))&1)-1);
  635. decaf_448_point_add_sub(w,w,tmp,((bits>>1)&1)-1);
  636. decaf_448_point_double(w,w);
  637. }
  638. decaf_448_point_add_sub(w,w,b,((scalarb->limb[0]>>1)&1)-1);
  639. decaf_448_point_add_sub(w,w,c,((scalarc->limb[0]>>1)&1)-1);
  640. /* low bit is special because of signed window */
  641. decaf_448_cond_sel(tmp,b,decaf_448_point_identity,-(scalarb->limb[0]&1));
  642. decaf_448_point_sub(w,w,tmp);
  643. decaf_448_cond_sel(tmp,c,decaf_448_point_identity,-(scalarc->limb[0]&1));
  644. decaf_448_point_sub(a,w,tmp);
  645. }
  646. decaf_bool_t decaf_448_point_eq ( const decaf_448_point_t p, const decaf_448_point_t q ) {
  647. /* equality mod 2-torsion compares x/y */
  648. gf a, b;
  649. gf_mul ( a, p->y, q->x );
  650. gf_mul ( b, q->y, p->x );
  651. return gf_eq(a,b);
  652. }
  653. void decaf_448_point_from_hash_nonuniform (
  654. decaf_448_point_t p,
  655. const unsigned char ser[DECAF_448_SER_BYTES]
  656. ) {
  657. gf r,urr,a,b,c,dee,e,ur2_d,udr2_1;
  658. (void)gf_deser(r,ser);
  659. gf_canon(r);
  660. gf_sqr(a,r);
  661. gf_mlw(urr,a,QUADRATIC_NONRESIDUE);
  662. gf_mlw(dee,ONE,EDWARDS_D);
  663. gf_add(a,urr,ONE);
  664. gf_sub(ur2_d,dee,urr);
  665. gf_mul(c,a,ur2_d);
  666. gf_mlw(b,urr,-EDWARDS_D);
  667. gf_add(udr2_1,b,ONE);
  668. gf_mul(a,c,udr2_1);
  669. gf_mlw(c,a,EDWARDS_D+1);
  670. gf_isqrt(b,c); /* FIELD: if 5 mod 8, multiply result by u. */
  671. gf_sqr(a,b);
  672. gf_mul(e,a,c);
  673. decaf_bool_t square = gf_eq(e,ONE);
  674. gf_mul(a,b,r);
  675. cond_sel(b,a,b,square);
  676. gf_mlw(a,b,EDWARDS_D+1);
  677. cond_swap(ur2_d,udr2_1,~square);
  678. gf_mul(e,ur2_d,a);
  679. cond_neg(e,hibit(e)^square);
  680. gf_mul(b,udr2_1,a);
  681. gf_sqr(c,b);
  682. gf_sqr(a,e);
  683. gf_sub(a,ONE,a);
  684. gf_add(e,e,e);
  685. gf_add(b,dee,c);
  686. gf_sub(c,dee,c);
  687. gf_mul(p->x,e,c);
  688. gf_mul(p->z,a,c);
  689. gf_mul(p->y,b,a);
  690. gf_mul(p->t,b,e);
  691. }
  692. void decaf_448_point_from_hash_uniform (
  693. decaf_448_point_t pt,
  694. const unsigned char hashed_data[2*DECAF_448_SER_BYTES]
  695. ) {
  696. decaf_448_point_t pt2;
  697. decaf_448_point_from_hash_nonuniform(pt,hashed_data);
  698. decaf_448_point_from_hash_nonuniform(pt2,&hashed_data[DECAF_448_SER_BYTES]);
  699. decaf_448_point_add(pt,pt,pt2);
  700. }
  701. decaf_bool_t decaf_448_point_valid (
  702. const decaf_448_point_t p
  703. ) {
  704. gf a,b,c;
  705. gf_mul(a,p->x,p->y);
  706. gf_mul(b,p->z,p->t);
  707. decaf_bool_t out = gf_eq(a,b);
  708. gf_sqr(a,p->x);
  709. gf_sqr(b,p->y);
  710. gf_sub(a,b,a);
  711. gf_sqr(b,p->t);
  712. gf_mlw(c,b,1-EDWARDS_D);
  713. gf_sqr(b,p->z);
  714. gf_sub(b,b,c);
  715. out &= gf_eq(a,b);
  716. out &= ~gf_eq(p->z,ZERO);
  717. return out;
  718. }
  719. void decaf_448_precompute (
  720. decaf_448_precomputed_s *a,
  721. const decaf_448_point_t b
  722. ) {
  723. decaf_448_point_copy(a->p[0],b);
  724. }
  725. void decaf_448_precomputed_scalarmul (
  726. decaf_448_point_t a,
  727. const decaf_448_precomputed_s *b,
  728. const decaf_448_scalar_t scalar
  729. ) {
  730. decaf_448_point_scalarmul(a,b->p[0],scalar);
  731. }
  732. decaf_bool_t decaf_448_direct_scalarmul (
  733. uint8_t scaled[DECAF_448_SER_BYTES],
  734. const uint8_t base[DECAF_448_SER_BYTES],
  735. const decaf_448_scalar_t scalar,
  736. decaf_bool_t allow_identity,
  737. decaf_bool_t short_circuit
  738. ) {
  739. (void)short_circuit;
  740. gf s0, x0, xa, za, xd, zd, xs, zs;
  741. decaf_bool_t succ = gf_deser ( s0, base );
  742. succ &= allow_identity |~ gf_eq( s0, ZERO);
  743. succ &= ~hibit(s0);
  744. gf_sqr ( xa, s0 );
  745. gf_cpy ( x0, xa );
  746. gf_cpy ( za, ONE );
  747. gf_cpy ( xd, ONE );
  748. gf_cpy ( zd, ZERO );
  749. int i,j;
  750. decaf_bool_t pflip = 0;
  751. for (j=448-1; j>=0; j--) { /* TODO: DECAF_SCALAR_BITS */
  752. decaf_bool_t flip = -((scalar->limb[j/WORD_BITS]>>(j%WORD_BITS))&1);;
  753. cond_swap(xa,xd,flip^pflip);
  754. cond_swap(za,zd,flip^pflip);
  755. gf_add_nr ( xs, xa, za );
  756. gf_sub_nr ( zs, xa, za );
  757. gf_add_nr ( xa, xd, zd );
  758. gf_sub_nr ( za, xd, zd );
  759. gf_mul ( xd, xa, zs );
  760. gf_mul ( zd, xs, za );
  761. gf_add_nr ( xs, xd, zd );
  762. gf_sub_nr ( zd, xd, zd );
  763. gf_mul ( zs, zd, s0 );
  764. gf_sqr ( zd, xa );
  765. gf_sqr ( xa, za );
  766. gf_sub_nr ( za, zd, xa );
  767. gf_mul ( xd, xa, zd );
  768. gf_mlw ( zd, za, 1-EDWARDS_D );
  769. gf_add_nr ( xa, xa, zd );
  770. gf_mul ( zd, xa, za );
  771. gf_sqr ( xa, xs );
  772. gf_sqr ( za, zs );
  773. pflip = flip;
  774. }
  775. cond_swap(xa,xd,pflip);
  776. cond_swap(za,zd,pflip);
  777. /* OK, time to reserialize! */
  778. gf xz_d, xz_a, den, L0, L1, L2, L3, out; /* TODO: simplify */
  779. mask_t zcase, output_zero, sflip, za_zero;
  780. gf_mul(xz_d, xd, zd);
  781. gf_mul(xz_a, xa, za);
  782. output_zero = gf_eq(xz_d, ZERO);
  783. za_zero = gf_eq(za, ZERO);
  784. cond_sel(xz_d, xz_d, ONE, output_zero); /* make xz_d always nonzero */
  785. zcase = output_zero | gf_eq(xz_a, ZERO);
  786. /* Curve test in zcase */
  787. gf_cpy(L0,x0);
  788. gf_add(L0,L0,ONE);
  789. gf_sqr(L1,L0);
  790. gf_mlw(L0,x0,-4*EDWARDS_D);
  791. gf_add(L1,L1,L0);
  792. cond_sel(xz_a,xz_a,L1,zcase);
  793. /* Compute denominator */
  794. gf_mul(L0, x0, xz_d);
  795. gf_mlw(L2, L0, 4);
  796. gf_mul(L1, L2, xz_a);
  797. gf_isqrt(den, L1);
  798. /* Check squareness */
  799. gf_sqr(L2, den);
  800. gf_mul(L0, L1, L2);
  801. gf_add(L0, L0, ONE);
  802. succ &= ~hibit(s0) & ~gf_eq(L0, ZERO);
  803. /* Compute y/x */
  804. gf_mul(L1, x0, xd);
  805. gf_sub(L1, zd, L1);
  806. gf_mul(L0, za, L1); /* L0 = "opq" */
  807. gf_mul(L1, x0, zd);
  808. gf_sub(L1, L1, xd);
  809. gf_mul(L2, xa, L1); /* L2 = "pqr" */
  810. gf_sub(L1, L0, L2);
  811. gf_add(L0, L0, L2);
  812. gf_mul(L2, L1, den); /* L2 = y0 / x0 */
  813. gf_mul(L1, L0, den); /* L1 = yO / xO */
  814. sflip = hibit(L1) ^ hibit(L2) ^ za_zero;
  815. cond_sel(L0, xd, zd, sflip); /* L0 = "times" */
  816. /* OK, done with y-coordinates */
  817. /* OK, now correct for swappage */
  818. gf_add(den,den,den);
  819. gf_mul(L1,den,s0);
  820. gf_sqr(L2,L1);
  821. gf_mul(L3,L2,xz_a);
  822. cond_sel(den,L1,L3,pflip|zcase);
  823. /* compute the output */
  824. gf_mul(L1,L0,den);
  825. cond_sel(L2,zs,s0,zcase); /* zs, but s0 in zcase */
  826. gf_mul(L0,L1,L2);
  827. cond_sel(L3,xd,zd,za_zero);
  828. cond_sel(L2,xs,L3,zcase); /* xs, but zq or qq in zcase */
  829. gf_mul(out,L0,L2);
  830. cond_sel(out,out,ZERO,output_zero);
  831. cond_neg(out,hibit(out));
  832. //
  833. // /* TODO: resubroutineize? */
  834. gf_canon(out);
  835. int k=0, bits=0;
  836. decaf_dword_t buf=0;
  837. for (i=0; i<DECAF_448_LIMBS; i++) {
  838. buf |= (decaf_dword_t)out[i]<<bits;
  839. for (bits += LBITS; (bits>=8 || i==DECAF_448_LIMBS-1) && k<DECAF_448_SER_BYTES; bits-=8, buf>>=8) {
  840. scaled[k++]=buf;
  841. }
  842. }
  843. return succ;
  844. }