hcrypto: Add X25519

The X25519 implementation comes from libsodium. Explicit copyright
notices have been added to each file as well as some portability changes
(e.g. align.h).
This commit is contained in:
Luke Howard
2019-12-30 21:07:04 +11:00
committed by Nicolas Williams
parent 20f9b2be48
commit beda11a079
20 changed files with 8184 additions and 5 deletions
File diff suppressed because it is too large Load Diff
+40
View File
@@ -0,0 +1,40 @@
{
{ 1288382639258501, 245678601348599, 269427782077623, 1462984067271730, 137412439391563 },
{ 62697248952638, 204681361388450, 631292143396476, 338455783676468, 1213667448819585 },
{ 301289933810280, 1259582250014073, 1422107436869536, 796239922652654, 1953934009299142 }
},
{
{ 1601611775252272, 1720807796594148, 1132070835939856, 1260455018889551, 2147779492816911 },
{ 316559037616741, 2177824224946892, 1459442586438991, 1461528397712656, 751590696113597 },
{ 1850748884277385, 1200145853858453, 1068094770532492, 672251375690438, 1586055907191707 }
},
{
{ 769950342298419, 132954430919746, 844085933195555, 974092374476333, 726076285546016 },
{ 425251763115706, 608463272472562, 442562545713235, 837766094556764, 374555092627893 },
{ 1086255230780037, 274979815921559, 1960002765731872, 929474102396301, 1190409889297339 }
},
{
{ 665000864555967, 2065379846933859, 370231110385876, 350988370788628, 1233371373142985 },
{ 2019367628972465, 676711900706637, 110710997811333, 1108646842542025, 517791959672113 },
{ 965130719900578, 247011430587952, 526356006571389, 91986625355052, 2157223321444601 }
},
{
{ 1802695059465007, 1664899123557221, 593559490740857, 2160434469266659, 927570450755031 },
{ 1725674970513508, 1933645953859181, 1542344539275782, 1767788773573747, 1297447965928905 },
{ 1381809363726107, 1430341051343062, 2061843536018959, 1551778050872521, 2036394857967624 }
},
{
{ 1970894096313054, 528066325833207, 1619374932191227, 2207306624415883, 1169170329061080 },
{ 2070390218572616, 1458919061857835, 624171843017421, 1055332792707765, 433987520732508 },
{ 893653801273833, 1168026499324677, 1242553501121234, 1306366254304474, 1086752658510815 }
},
{
{ 213454002618221, 939771523987438, 1159882208056014, 317388369627517, 621213314200687 },
{ 1971678598905747, 338026507889165, 762398079972271, 655096486107477, 42299032696322 },
{ 177130678690680, 1754759263300204, 1864311296286618, 1180675631479880, 1292726903152791 }
},
{
{ 1913163449625248, 460779200291993, 2193883288642314, 1008900146920800, 1721983679009502 },
{ 1070401523076875, 1272492007800961, 1910153608563310, 2075579521696771, 1191169788841221 },
{ 692896803108118, 500174642072499, 2068223309439677, 1162190621851337, 1426986007309901 }
}
+41
View File
@@ -0,0 +1,41 @@
/* 37095705934669439343138083508754565189542113879843219016388785533085940283555 */
static const fe25519 d = {
929955233495203, 466365720129213, 1662059464998953, 2033849074728123, 1442794654840575
};
/* 2 * d =
* 16295367250680780974490674513165176452449235426866156013048779062215315747161
*/
static const fe25519 d2 = {
1859910466990425, 932731440258426, 1072319116312658, 1815898335770999, 633789495995903
};
/* sqrt(-1) */
static const fe25519 sqrtm1 = {
1718705420411056, 234908883556509, 2233514472574048, 2117202627021982, 765476049583133
};
/* A = 486662 */
static const fe25519 curve25519_A = {
486662, 0, 0, 0, 0
};
/* sqrt(ad - 1) with a = -1 (mod p) */
static const fe25519 sqrtadm1 = {
2241493124984347, 425987919032274, 2207028919301688, 1220490630685848, 974799131293748
};
/* 1 / sqrt(a - d) */
static const fe25519 invsqrtamd = {
278908739862762, 821645201101625, 8113234426968, 1777959178193151, 2118520810568447
};
/* 1 - d ^ 2 */
static const fe25519 onemsqd = {
1136626929484150, 1998550399581263, 496427632559748, 118527312129759, 45110755273534
};
/* (d - 1) ^ 2 */
static const fe25519 sqdmone = {
1507062230895904, 1572317787530805, 683053064812840, 317374165784489, 1572899562415810
};
+116
View File
@@ -0,0 +1,116 @@
/*
Ignores top bit of h.
*/
void
fe25519_frombytes(fe25519 h, const unsigned char *s)
{
const uint64_t mask = 0x7ffffffffffffULL;
uint64_t h0, h1, h2, h3, h4;
h0 = (LOAD64_LE(s ) ) & mask;
h1 = (LOAD64_LE(s + 6) >> 3) & mask;
h2 = (LOAD64_LE(s + 12) >> 6) & mask;
h3 = (LOAD64_LE(s + 19) >> 1) & mask;
h4 = (LOAD64_LE(s + 24) >> 12) & mask;
h[0] = h0;
h[1] = h1;
h[2] = h2;
h[3] = h3;
h[4] = h4;
}
static void
fe25519_reduce(fe25519 h, const fe25519 f)
{
const uint64_t mask = 0x7ffffffffffffULL;
uint128_t t[5];
t[0] = f[0];
t[1] = f[1];
t[2] = f[2];
t[3] = f[3];
t[4] = f[4];
t[1] += t[0] >> 51;
t[0] &= mask;
t[2] += t[1] >> 51;
t[1] &= mask;
t[3] += t[2] >> 51;
t[2] &= mask;
t[4] += t[3] >> 51;
t[3] &= mask;
t[0] += 19 * (t[4] >> 51);
t[4] &= mask;
t[1] += t[0] >> 51;
t[0] &= mask;
t[2] += t[1] >> 51;
t[1] &= mask;
t[3] += t[2] >> 51;
t[2] &= mask;
t[4] += t[3] >> 51;
t[3] &= mask;
t[0] += 19 * (t[4] >> 51);
t[4] &= mask;
/* now t is between 0 and 2^255-1, properly carried. */
/* case 1: between 0 and 2^255-20. case 2: between 2^255-19 and 2^255-1. */
t[0] += 19ULL;
t[1] += t[0] >> 51;
t[0] &= mask;
t[2] += t[1] >> 51;
t[1] &= mask;
t[3] += t[2] >> 51;
t[2] &= mask;
t[4] += t[3] >> 51;
t[3] &= mask;
t[0] += 19ULL * (t[4] >> 51);
t[4] &= mask;
/* now between 19 and 2^255-1 in both cases, and offset by 19. */
t[0] += 0x8000000000000 - 19ULL;
t[1] += 0x8000000000000 - 1ULL;
t[2] += 0x8000000000000 - 1ULL;
t[3] += 0x8000000000000 - 1ULL;
t[4] += 0x8000000000000 - 1ULL;
/* now between 2^255 and 2^256-20, and offset by 2^255. */
t[1] += t[0] >> 51;
t[0] &= mask;
t[2] += t[1] >> 51;
t[1] &= mask;
t[3] += t[2] >> 51;
t[2] &= mask;
t[4] += t[3] >> 51;
t[3] &= mask;
t[4] &= mask;
h[0] = t[0];
h[1] = t[1];
h[2] = t[2];
h[3] = t[3];
h[4] = t[4];
}
void
fe25519_tobytes(unsigned char *s, const fe25519 h)
{
fe25519 t;
uint64_t t0, t1, t2, t3;
fe25519_reduce(t, h);
t0 = t[0] | (t[1] << 51);
t1 = (t[1] >> 13) | (t[2] << 38);
t2 = (t[2] >> 26) | (t[3] << 25);
t3 = (t[3] >> 39) | (t[4] << 12);
STORE64_LE(s + 0, t0);
STORE64_LE(s + 8, t1);
STORE64_LE(s + 16, t2);
STORE64_LE(s + 24, t3);
}