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.
 
 
 
 
 

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