123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235 |
- /* This is based on tweetnacl. Some typedefs have been
- * replaced with their stdint equivalents.
- *
- * Original code was public domain. */
- #include <stdint.h>
- #include <stddef.h>
- #include "handy.h"
- typedef int64_t gf[16];
- static const uint8_t _0[16],
- _9[32] = {9};
- static const gf gf0,
- gf1 = {1},
- _121665 = {0xDB41, 1},
- D = {0x78a3, 0x1359, 0x4dca, 0x75eb,
- 0xd8ab, 0x4141, 0x0a4d, 0x0070,
- 0xe898, 0x7779, 0x4079, 0x8cc7,
- 0xfe73, 0x2b6f, 0x6cee, 0x5203},
- D2 = {0xf159, 0x26b2, 0x9b94, 0xebd6,
- 0xb156, 0x8283, 0x149a, 0x00e0,
- 0xd130, 0xeef3, 0x80f2, 0x198e,
- 0xfce7, 0x56df, 0xd9dc, 0x2406},
- X = {0xd51a, 0x8f25, 0x2d60, 0xc956,
- 0xa7b2, 0x9525, 0xc760, 0x692c,
- 0xdc5c, 0xfdd6, 0xe231, 0xc0a4,
- 0x53fe, 0xcd6e, 0x36d3, 0x2169},
- Y = {0x6658, 0x6666, 0x6666, 0x6666,
- 0x6666, 0x6666, 0x6666, 0x6666,
- 0x6666, 0x6666, 0x6666, 0x6666,
- 0x6666, 0x6666, 0x6666, 0x6666},
- I = {0xa0b0, 0x4a0e, 0x1b27, 0xc4ee,
- 0xe478, 0xad2f, 0x1806, 0x2f43,
- 0xd7a7, 0x3dfb, 0x0099, 0x2b4d,
- 0xdf0b, 0x4fc1, 0x2480, 0x2b83};
- static void set25519(gf r, const gf a)
- {
- size_t i;
- for (i = 0; i < 16; i++)
- r[i] = a[i];
- }
- static void car25519(gf o)
- {
- int64_t c;
- size_t i;
- for (i = 0; i < 16; i++)
- {
- o[i] += (1LL << 16);
- c = o[i] >> 16;
- o[(i + 1) * (i < 15)] += c - 1 + 37 * (c - 1) * (i == 15);
- o[i] -= (int64_t)((uint64_t)c << 16);
- }
- }
- static void sel25519(gf p, gf q, int64_t b)
- {
- int64_t tmp, mask = ~(b-1);
- size_t i;
- for (i = 0; i < 16; i++)
- {
- tmp = mask & (p[i] ^ q[i]);
- p[i] ^= tmp;
- q[i] ^= tmp;
- }
- }
- static void pack25519(uint8_t out[32], const gf n)
- {
- size_t i, j;
- int b;
- gf m, t;
- set25519(t, n);
- car25519(t);
- car25519(t);
- car25519(t);
- for(j = 0; j < 2; j++)
- {
- m[0] = t[0] - 0xffed;
- for (i = 1; i < 15; i++)
- {
- m[i] = t[i] - 0xffff - ((m[i - 1] >> 16) & 1);
- m[i - 1] &= 0xffff;
- }
- m[15] = t[15] - 0x7fff - ((m[14] >> 16) & 1);
- b = (m[15] >> 16) & 1;
- m[14] &= 0xffff;
- sel25519(t, m, 1 - b);
- }
- for (i = 0; i < 16; i++)
- {
- out[2 * i] = t[i] & 0xff;
- out[2 * i + 1] = (uint8_t) (t[i] >> 8);
- }
- }
- static void unpack25519(gf o, const uint8_t *n)
- {
- size_t i;
- for (i = 0; i < 16; i++)
- o[i] = n[2 * i] + ((int64_t) n[2 * i + 1] << 8);
- o[15] &= 0x7fff;
- }
- static void add(gf o, const gf a, const gf b)
- {
- size_t i;
- for (i = 0; i < 16; i++)
- o[i] = a[i] + b[i];
- }
- static void sub(gf o, const gf a, const gf b)
- {
- size_t i;
- for (i = 0; i < 16; i++)
- o[i] = a[i] - b[i];
- }
- static void mul(gf o, const gf a, const gf b)
- {
- int64_t t[31];
- size_t i, j;
- for (i = 0; i < 31; i++)
- t[i] = 0;
- for (i = 0; i < 16; i++)
- for (j = 0; j < 16; j++)
- t[i + j] += a[i] * b[j];
- for (i = 0; i < 15; i++)
- t[i] += 38 * t[i + 16];
- for (i = 0; i < 16; i++)
- o[i] = t[i];
- car25519(o);
- car25519(o);
- }
- static void sqr(gf o, const gf a)
- {
- mul(o, a, a);
- }
- static void inv25519(gf o, const gf i)
- {
- gf c;
- int a;
- for (a = 0; a < 16; a++)
- c[a] = i[a];
- for (a = 253; a >= 0; a--)
- {
- sqr(c, c);
- if(a != 2 && a != 4)
- mul(c, c, i);
- }
- for (a = 0; a < 16; a++)
- o[a] = c[a];
- }
- void cf_curve25519_mul(uint8_t *q, const uint8_t *n, const uint8_t *p)
- {
- uint8_t z[32];
- gf x;
- gf a, b, c, d, e, f;
- {
- size_t i;
- for (i = 0; i < 31; i++)
- z[i] = n[i];
- z[31] = (n[31] & 127) | 64;
- z[0] &= 248;
- unpack25519(x, p);
- for(i = 0; i < 16; i++)
- {
- b[i] = x[i];
- d[i] = a[i] = c[i] = 0;
- }
- }
- a[0] = d[0] = 1;
- {int i;
- for (i = 254; i >= 0; i--)
- {
- int64_t r = (z[i >> 3] >> (i & 7)) & 1;
- sel25519(a, b, r);
- sel25519(c, d, r);
- add(e, a, c);
- sub(a, a, c);
- add(c, b, d);
- sub(b, b, d);
- sqr(d, e);
- sqr(f, a);
- mul(a, c, a);
- mul(c, b, e);
- add(e, a, c);
- sub(a, a, c);
- sqr(b, a);
- sub(c, d, f);
- mul(a, c, _121665);
- add(a, a, d);
- mul(c, c, a);
- mul(a, d, f);
- mul(d, b, x);
- sqr(b, e);
- sel25519(a, b, r);
- sel25519(c, d, r);
- }
- }
- inv25519(c, c);
- mul(a, a, c);
- pack25519(q, a);
- }
- void cf_curve25519_mul_base(uint8_t *q, const uint8_t *n)
- {
- cf_curve25519_mul(q, n, _9);
- }
|