From 4bd6196c963c2a1b5cc02ad7fd76f251438fe4db Mon Sep 17 00:00:00 2001 From: Frank Denis Date: Mon, 6 Nov 2017 15:06:21 +0100 Subject: [PATCH] Move functions not worth inlining back to core --- .../msvc/vs2010/libsodium/libsodium.vcxproj | 2 + .../libsodium/libsodium.vcxproj.filters | 6 + .../msvc/vs2012/libsodium/libsodium.vcxproj | 2 + .../libsodium/libsodium.vcxproj.filters | 6 + .../msvc/vs2013/libsodium/libsodium.vcxproj | 2 + .../libsodium/libsodium.vcxproj.filters | 6 + .../msvc/vs2015/libsodium/libsodium.vcxproj | 2 + .../libsodium/libsodium.vcxproj.filters | 6 + .../msvc/vs2017/libsodium/libsodium.vcxproj | 2 + .../libsodium/libsodium.vcxproj.filters | 6 + libsodium.vcxproj | 2 + libsodium.vcxproj.filters | 6 + src/libsodium/Makefile.am | 2 + .../curve25519/ref10/curve25519_ref10.c | 6 + .../crypto_core/curve25519/ref10/fe_25_5/fe.h | 220 +++++++++++++++++ .../crypto_core/curve25519/ref10/fe_51/fe.h | 116 +++++++++ .../include/sodium/private/curve25519_ref10.h | 11 +- .../sodium/private/curve25519_ref10_fe_25_5.h | 222 ------------------ .../sodium/private/curve25519_ref10_fe_51.h | 119 ---------- 19 files changed, 402 insertions(+), 342 deletions(-) create mode 100644 src/libsodium/crypto_core/curve25519/ref10/fe_25_5/fe.h create mode 100644 src/libsodium/crypto_core/curve25519/ref10/fe_51/fe.h diff --git a/builds/msvc/vs2010/libsodium/libsodium.vcxproj b/builds/msvc/vs2010/libsodium/libsodium.vcxproj index f71fafb1..e3b7ec1f 100644 --- a/builds/msvc/vs2010/libsodium/libsodium.vcxproj +++ b/builds/msvc/vs2010/libsodium/libsodium.vcxproj @@ -303,9 +303,11 @@ + + diff --git a/builds/msvc/vs2010/libsodium/libsodium.vcxproj.filters b/builds/msvc/vs2010/libsodium/libsodium.vcxproj.filters index 16d4752f..877dff32 100644 --- a/builds/msvc/vs2010/libsodium/libsodium.vcxproj.filters +++ b/builds/msvc/vs2010/libsodium/libsodium.vcxproj.filters @@ -698,6 +698,9 @@ crypto_core\curve25519\ref10\fe_25_5 + + crypto_core\curve25519\ref10\fe_25_5 + crypto_core\curve25519\ref10\fe_25_5 @@ -707,6 +710,9 @@ crypto_core\curve25519\ref10\fe_51 + + crypto_core\curve25519\ref10\fe_51 + crypto_core\curve25519\ref10\fe_51 diff --git a/builds/msvc/vs2012/libsodium/libsodium.vcxproj b/builds/msvc/vs2012/libsodium/libsodium.vcxproj index 0e44cbcc..868ff0c4 100644 --- a/builds/msvc/vs2012/libsodium/libsodium.vcxproj +++ b/builds/msvc/vs2012/libsodium/libsodium.vcxproj @@ -303,9 +303,11 @@ + + diff --git a/builds/msvc/vs2012/libsodium/libsodium.vcxproj.filters b/builds/msvc/vs2012/libsodium/libsodium.vcxproj.filters index 16d4752f..877dff32 100644 --- a/builds/msvc/vs2012/libsodium/libsodium.vcxproj.filters +++ b/builds/msvc/vs2012/libsodium/libsodium.vcxproj.filters @@ -698,6 +698,9 @@ crypto_core\curve25519\ref10\fe_25_5 + + crypto_core\curve25519\ref10\fe_25_5 + crypto_core\curve25519\ref10\fe_25_5 @@ -707,6 +710,9 @@ crypto_core\curve25519\ref10\fe_51 + + crypto_core\curve25519\ref10\fe_51 + crypto_core\curve25519\ref10\fe_51 diff --git a/builds/msvc/vs2013/libsodium/libsodium.vcxproj b/builds/msvc/vs2013/libsodium/libsodium.vcxproj index f8433bd7..dd16a6c8 100644 --- a/builds/msvc/vs2013/libsodium/libsodium.vcxproj +++ b/builds/msvc/vs2013/libsodium/libsodium.vcxproj @@ -303,9 +303,11 @@ + + diff --git a/builds/msvc/vs2013/libsodium/libsodium.vcxproj.filters b/builds/msvc/vs2013/libsodium/libsodium.vcxproj.filters index 16d4752f..877dff32 100644 --- a/builds/msvc/vs2013/libsodium/libsodium.vcxproj.filters +++ b/builds/msvc/vs2013/libsodium/libsodium.vcxproj.filters @@ -698,6 +698,9 @@ crypto_core\curve25519\ref10\fe_25_5 + + crypto_core\curve25519\ref10\fe_25_5 + crypto_core\curve25519\ref10\fe_25_5 @@ -707,6 +710,9 @@ crypto_core\curve25519\ref10\fe_51 + + crypto_core\curve25519\ref10\fe_51 + crypto_core\curve25519\ref10\fe_51 diff --git a/builds/msvc/vs2015/libsodium/libsodium.vcxproj b/builds/msvc/vs2015/libsodium/libsodium.vcxproj index d44be422..f9239631 100644 --- a/builds/msvc/vs2015/libsodium/libsodium.vcxproj +++ b/builds/msvc/vs2015/libsodium/libsodium.vcxproj @@ -303,9 +303,11 @@ + + diff --git a/builds/msvc/vs2015/libsodium/libsodium.vcxproj.filters b/builds/msvc/vs2015/libsodium/libsodium.vcxproj.filters index 16d4752f..877dff32 100644 --- a/builds/msvc/vs2015/libsodium/libsodium.vcxproj.filters +++ b/builds/msvc/vs2015/libsodium/libsodium.vcxproj.filters @@ -698,6 +698,9 @@ crypto_core\curve25519\ref10\fe_25_5 + + crypto_core\curve25519\ref10\fe_25_5 + crypto_core\curve25519\ref10\fe_25_5 @@ -707,6 +710,9 @@ crypto_core\curve25519\ref10\fe_51 + + crypto_core\curve25519\ref10\fe_51 + crypto_core\curve25519\ref10\fe_51 diff --git a/builds/msvc/vs2017/libsodium/libsodium.vcxproj b/builds/msvc/vs2017/libsodium/libsodium.vcxproj index 78f3ccd3..c36c57ea 100644 --- a/builds/msvc/vs2017/libsodium/libsodium.vcxproj +++ b/builds/msvc/vs2017/libsodium/libsodium.vcxproj @@ -303,9 +303,11 @@ + + diff --git a/builds/msvc/vs2017/libsodium/libsodium.vcxproj.filters b/builds/msvc/vs2017/libsodium/libsodium.vcxproj.filters index 16d4752f..877dff32 100644 --- a/builds/msvc/vs2017/libsodium/libsodium.vcxproj.filters +++ b/builds/msvc/vs2017/libsodium/libsodium.vcxproj.filters @@ -698,6 +698,9 @@ crypto_core\curve25519\ref10\fe_25_5 + + crypto_core\curve25519\ref10\fe_25_5 + crypto_core\curve25519\ref10\fe_25_5 @@ -707,6 +710,9 @@ crypto_core\curve25519\ref10\fe_51 + + crypto_core\curve25519\ref10\fe_51 + crypto_core\curve25519\ref10\fe_51 diff --git a/libsodium.vcxproj b/libsodium.vcxproj index 36675458..3d4a6f91 100644 --- a/libsodium.vcxproj +++ b/libsodium.vcxproj @@ -541,9 +541,11 @@ + + diff --git a/libsodium.vcxproj.filters b/libsodium.vcxproj.filters index 5689ba32..f3e4a239 100644 --- a/libsodium.vcxproj.filters +++ b/libsodium.vcxproj.filters @@ -689,6 +689,9 @@ Header Files + + Header Files + Header Files @@ -698,6 +701,9 @@ Header Files + + Header Files + Header Files diff --git a/src/libsodium/Makefile.am b/src/libsodium/Makefile.am index 36a38bce..b0b78d95 100644 --- a/src/libsodium/Makefile.am +++ b/src/libsodium/Makefile.am @@ -113,12 +113,14 @@ libsodium_la_SOURCES += \ crypto_core/curve25519/ref10/fe_51/base.h \ crypto_core/curve25519/ref10/fe_51/base2.h \ crypto_core/curve25519/ref10/fe_51/constants.h \ + crypto_core/curve25519/ref10/fe_51/fe.h \ include/sodium/private/curve25519_ref10_fe_51.h else libsodium_la_SOURCES += \ crypto_core/curve25519/ref10/fe_25_5/base.h \ crypto_core/curve25519/ref10/fe_25_5/base2.h \ crypto_core/curve25519/ref10/fe_25_5/constants.h \ + crypto_core/curve25519/ref10/fe_25_5/fe.h \ include/sodium/private/curve25519_ref10_fe_25_5.h endif diff --git a/src/libsodium/crypto_core/curve25519/ref10/curve25519_ref10.c b/src/libsodium/crypto_core/curve25519/ref10/curve25519_ref10.c index 28455eaf..60ff2c6e 100644 --- a/src/libsodium/crypto_core/curve25519/ref10/curve25519_ref10.c +++ b/src/libsodium/crypto_core/curve25519/ref10/curve25519_ref10.c @@ -38,6 +38,12 @@ load_4(const unsigned char *in) return result; } +#ifdef HAVE_TI_MODE +# include "fe_51/fe.h" +#else +# include "fe_25_5/fe.h" +#endif + void fe_invert(fe out, const fe z) { diff --git a/src/libsodium/crypto_core/curve25519/ref10/fe_25_5/fe.h b/src/libsodium/crypto_core/curve25519/ref10/fe_25_5/fe.h new file mode 100644 index 00000000..cf06cae7 --- /dev/null +++ b/src/libsodium/crypto_core/curve25519/ref10/fe_25_5/fe.h @@ -0,0 +1,220 @@ +/* + Ignores top bit of h. + */ + +void +fe_frombytes(fe h, const unsigned char *s) +{ + int64_t h0 = load_4(s); + int64_t h1 = load_3(s + 4) << 6; + int64_t h2 = load_3(s + 7) << 5; + int64_t h3 = load_3(s + 10) << 3; + int64_t h4 = load_3(s + 13) << 2; + int64_t h5 = load_4(s + 16); + int64_t h6 = load_3(s + 20) << 7; + int64_t h7 = load_3(s + 23) << 5; + int64_t h8 = load_3(s + 26) << 4; + int64_t h9 = (load_3(s + 29) & 8388607) << 2; + + int64_t carry0; + int64_t carry1; + int64_t carry2; + int64_t carry3; + int64_t carry4; + int64_t carry5; + int64_t carry6; + int64_t carry7; + int64_t carry8; + int64_t carry9; + + carry9 = (h9 + (int64_t)(1L << 24)) >> 25; + h0 += carry9 * 19; + h9 -= carry9 * ((uint64_t) 1L << 25); + carry1 = (h1 + (int64_t)(1L << 24)) >> 25; + h2 += carry1; + h1 -= carry1 * ((uint64_t) 1L << 25); + carry3 = (h3 + (int64_t)(1L << 24)) >> 25; + h4 += carry3; + h3 -= carry3 * ((uint64_t) 1L << 25); + carry5 = (h5 + (int64_t)(1L << 24)) >> 25; + h6 += carry5; + h5 -= carry5 * ((uint64_t) 1L << 25); + carry7 = (h7 + (int64_t)(1L << 24)) >> 25; + h8 += carry7; + h7 -= carry7 * ((uint64_t) 1L << 25); + + carry0 = (h0 + (int64_t)(1L << 25)) >> 26; + h1 += carry0; + h0 -= carry0 * ((uint64_t) 1L << 26); + carry2 = (h2 + (int64_t)(1L << 25)) >> 26; + h3 += carry2; + h2 -= carry2 * ((uint64_t) 1L << 26); + carry4 = (h4 + (int64_t)(1L << 25)) >> 26; + h5 += carry4; + h4 -= carry4 * ((uint64_t) 1L << 26); + carry6 = (h6 + (int64_t)(1L << 25)) >> 26; + h7 += carry6; + h6 -= carry6 * ((uint64_t) 1L << 26); + carry8 = (h8 + (int64_t)(1L << 25)) >> 26; + h9 += carry8; + h8 -= carry8 * ((uint64_t) 1L << 26); + + h[0] = (int32_t) h0; + h[1] = (int32_t) h1; + h[2] = (int32_t) h2; + h[3] = (int32_t) h3; + h[4] = (int32_t) h4; + h[5] = (int32_t) h5; + h[6] = (int32_t) h6; + h[7] = (int32_t) h7; + h[8] = (int32_t) h8; + h[9] = (int32_t) h9; +} + +/* + Preconditions: + |h| bounded by 1.1*2^26,1.1*2^25,1.1*2^26,1.1*2^25,etc. + + Write p=2^255-19; q=floor(h/p). + Basic claim: q = floor(2^(-255)(h + 19 2^(-25)h9 + 2^(-1))). + + Proof: + Have |h|<=p so |q|<=1 so |19^2 2^(-255) q|<1/4. + Also have |h-2^230 h9|<2^231 so |19 2^(-255)(h-2^230 h9)|<1/4. + + Write y=2^(-1)-19^2 2^(-255)q-19 2^(-255)(h-2^230 h9). + Then 0> 25; + q = (h0 + q) >> 26; + q = (h1 + q) >> 25; + q = (h2 + q) >> 26; + q = (h3 + q) >> 25; + q = (h4 + q) >> 26; + q = (h5 + q) >> 25; + q = (h6 + q) >> 26; + q = (h7 + q) >> 25; + q = (h8 + q) >> 26; + q = (h9 + q) >> 25; + + /* Goal: Output h-(2^255-19)q, which is between 0 and 2^255-20. */ + h0 += 19 * q; + /* Goal: Output h-2^255 q, which is between 0 and 2^255-20. */ + + carry0 = h0 >> 26; + h1 += carry0; + h0 -= carry0 * ((uint32_t) 1L << 26); + carry1 = h1 >> 25; + h2 += carry1; + h1 -= carry1 * ((uint32_t) 1L << 25); + carry2 = h2 >> 26; + h3 += carry2; + h2 -= carry2 * ((uint32_t) 1L << 26); + carry3 = h3 >> 25; + h4 += carry3; + h3 -= carry3 * ((uint32_t) 1L << 25); + carry4 = h4 >> 26; + h5 += carry4; + h4 -= carry4 * ((uint32_t) 1L << 26); + carry5 = h5 >> 25; + h6 += carry5; + h5 -= carry5 * ((uint32_t) 1L << 25); + carry6 = h6 >> 26; + h7 += carry6; + h6 -= carry6 * ((uint32_t) 1L << 26); + carry7 = h7 >> 25; + h8 += carry7; + h7 -= carry7 * ((uint32_t) 1L << 25); + carry8 = h8 >> 26; + h9 += carry8; + h8 -= carry8 * ((uint32_t) 1L << 26); + carry9 = h9 >> 25; + h9 -= carry9 * ((uint32_t) 1L << 25); + + h[0] = h0; + h[1] = h1; + h[2] = h2; + h[3] = h3; + h[4] = h4; + h[5] = h5; + h[6] = h6; + h[7] = h7; + h[8] = h8; + h[9] = h9; +} + +/* + Goal: Output h0+...+2^255 h10-2^255 q, which is between 0 and 2^255-20. + Have h0+...+2^230 h9 between 0 and 2^255-1; + evidently 2^255 h10-2^255 q = 0. + + Goal: Output h0+...+2^230 h9. + */ + +void +fe_tobytes(unsigned char *s, const fe h) +{ + fe t; + + fe_reduce(t, h); + s[0] = t[0] >> 0; + s[1] = t[0] >> 8; + s[2] = t[0] >> 16; + s[3] = (t[0] >> 24) | (t[1] * ((uint32_t) 1 << 2)); + s[4] = t[1] >> 6; + s[5] = t[1] >> 14; + s[6] = (t[1] >> 22) | (t[2] * ((uint32_t) 1 << 3)); + s[7] = t[2] >> 5; + s[8] = t[2] >> 13; + s[9] = (t[2] >> 21) | (t[3] * ((uint32_t) 1 << 5)); + s[10] = t[3] >> 3; + s[11] = t[3] >> 11; + s[12] = (t[3] >> 19) | (t[4] * ((uint32_t) 1 << 6)); + s[13] = t[4] >> 2; + s[14] = t[4] >> 10; + s[15] = t[4] >> 18; + s[16] = t[5] >> 0; + s[17] = t[5] >> 8; + s[18] = t[5] >> 16; + s[19] = (t[5] >> 24) | (t[6] * ((uint32_t) 1 << 1)); + s[20] = t[6] >> 7; + s[21] = t[6] >> 15; + s[22] = (t[6] >> 23) | (t[7] * ((uint32_t) 1 << 3)); + s[23] = t[7] >> 5; + s[24] = t[7] >> 13; + s[25] = (t[7] >> 21) | (t[8] * ((uint32_t) 1 << 4)); + s[26] = t[8] >> 4; + s[27] = t[8] >> 12; + s[28] = (t[8] >> 20) | (t[9] * ((uint32_t) 1 << 6)); + s[29] = t[9] >> 2; + s[30] = t[9] >> 10; + s[31] = t[9] >> 18; +} diff --git a/src/libsodium/crypto_core/curve25519/ref10/fe_51/fe.h b/src/libsodium/crypto_core/curve25519/ref10/fe_51/fe.h new file mode 100644 index 00000000..5b0f56d9 --- /dev/null +++ b/src/libsodium/crypto_core/curve25519/ref10/fe_51/fe.h @@ -0,0 +1,116 @@ +/* + Ignores top bit of h. + */ + +void +fe_frombytes(fe 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 +fe_reduce(fe h, const fe 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 +fe_tobytes(unsigned char *s, const fe h) +{ + fe t; + uint64_t t0, t1, t2, t3; + + fe_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); +} diff --git a/src/libsodium/include/sodium/private/curve25519_ref10.h b/src/libsodium/include/sodium/private/curve25519_ref10.h index aa749052..2bbe09f1 100644 --- a/src/libsodium/include/sodium/private/curve25519_ref10.h +++ b/src/libsodium/include/sodium/private/curve25519_ref10.h @@ -11,13 +11,22 @@ #define fe fe25519 +#ifdef HAVE_TI_MODE +typedef uint64_t fe[5]; +#else +typedef int32_t fe[10]; +#endif + +void fe_invert(fe out, const fe z); +void fe_frombytes(fe h, const unsigned char *s); +void fe_tobytes(unsigned char *s, const fe h); + #ifdef HAVE_TI_MODE # include "curve25519_ref10_fe_51.h" #else # include "curve25519_ref10_fe_25_5.h" #endif -void fe_invert(fe out, const fe z); /* ge means group element. diff --git a/src/libsodium/include/sodium/private/curve25519_ref10_fe_25_5.h b/src/libsodium/include/sodium/private/curve25519_ref10_fe_25_5.h index 14ec0710..3707a030 100644 --- a/src/libsodium/include/sodium/private/curve25519_ref10_fe_25_5.h +++ b/src/libsodium/include/sodium/private/curve25519_ref10_fe_25_5.h @@ -3,8 +3,6 @@ #include "private/common.h" #include "utils.h" -typedef int32_t fe[10]; - /* h = 0 */ @@ -298,226 +296,6 @@ fe_copy(fe h, const fe f) h[9] = f9; } -/* - Ignores top bit of h. - */ - -static void -fe_frombytes(fe h, const unsigned char *s) -{ - int64_t h0 = load_4(s); - int64_t h1 = load_3(s + 4) << 6; - int64_t h2 = load_3(s + 7) << 5; - int64_t h3 = load_3(s + 10) << 3; - int64_t h4 = load_3(s + 13) << 2; - int64_t h5 = load_4(s + 16); - int64_t h6 = load_3(s + 20) << 7; - int64_t h7 = load_3(s + 23) << 5; - int64_t h8 = load_3(s + 26) << 4; - int64_t h9 = (load_3(s + 29) & 8388607) << 2; - - int64_t carry0; - int64_t carry1; - int64_t carry2; - int64_t carry3; - int64_t carry4; - int64_t carry5; - int64_t carry6; - int64_t carry7; - int64_t carry8; - int64_t carry9; - - carry9 = (h9 + (int64_t)(1L << 24)) >> 25; - h0 += carry9 * 19; - h9 -= carry9 * ((uint64_t) 1L << 25); - carry1 = (h1 + (int64_t)(1L << 24)) >> 25; - h2 += carry1; - h1 -= carry1 * ((uint64_t) 1L << 25); - carry3 = (h3 + (int64_t)(1L << 24)) >> 25; - h4 += carry3; - h3 -= carry3 * ((uint64_t) 1L << 25); - carry5 = (h5 + (int64_t)(1L << 24)) >> 25; - h6 += carry5; - h5 -= carry5 * ((uint64_t) 1L << 25); - carry7 = (h7 + (int64_t)(1L << 24)) >> 25; - h8 += carry7; - h7 -= carry7 * ((uint64_t) 1L << 25); - - carry0 = (h0 + (int64_t)(1L << 25)) >> 26; - h1 += carry0; - h0 -= carry0 * ((uint64_t) 1L << 26); - carry2 = (h2 + (int64_t)(1L << 25)) >> 26; - h3 += carry2; - h2 -= carry2 * ((uint64_t) 1L << 26); - carry4 = (h4 + (int64_t)(1L << 25)) >> 26; - h5 += carry4; - h4 -= carry4 * ((uint64_t) 1L << 26); - carry6 = (h6 + (int64_t)(1L << 25)) >> 26; - h7 += carry6; - h6 -= carry6 * ((uint64_t) 1L << 26); - carry8 = (h8 + (int64_t)(1L << 25)) >> 26; - h9 += carry8; - h8 -= carry8 * ((uint64_t) 1L << 26); - - h[0] = (int32_t) h0; - h[1] = (int32_t) h1; - h[2] = (int32_t) h2; - h[3] = (int32_t) h3; - h[4] = (int32_t) h4; - h[5] = (int32_t) h5; - h[6] = (int32_t) h6; - h[7] = (int32_t) h7; - h[8] = (int32_t) h8; - h[9] = (int32_t) h9; -} - -/* - Preconditions: - |h| bounded by 1.1*2^26,1.1*2^25,1.1*2^26,1.1*2^25,etc. - - Write p=2^255-19; q=floor(h/p). - Basic claim: q = floor(2^(-255)(h + 19 2^(-25)h9 + 2^(-1))). - - Proof: - Have |h|<=p so |q|<=1 so |19^2 2^(-255) q|<1/4. - Also have |h-2^230 h9|<2^231 so |19 2^(-255)(h-2^230 h9)|<1/4. - - Write y=2^(-1)-19^2 2^(-255)q-19 2^(-255)(h-2^230 h9). - Then 0> 25; - q = (h0 + q) >> 26; - q = (h1 + q) >> 25; - q = (h2 + q) >> 26; - q = (h3 + q) >> 25; - q = (h4 + q) >> 26; - q = (h5 + q) >> 25; - q = (h6 + q) >> 26; - q = (h7 + q) >> 25; - q = (h8 + q) >> 26; - q = (h9 + q) >> 25; - - /* Goal: Output h-(2^255-19)q, which is between 0 and 2^255-20. */ - h0 += 19 * q; - /* Goal: Output h-2^255 q, which is between 0 and 2^255-20. */ - - carry0 = h0 >> 26; - h1 += carry0; - h0 -= carry0 * ((uint32_t) 1L << 26); - carry1 = h1 >> 25; - h2 += carry1; - h1 -= carry1 * ((uint32_t) 1L << 25); - carry2 = h2 >> 26; - h3 += carry2; - h2 -= carry2 * ((uint32_t) 1L << 26); - carry3 = h3 >> 25; - h4 += carry3; - h3 -= carry3 * ((uint32_t) 1L << 25); - carry4 = h4 >> 26; - h5 += carry4; - h4 -= carry4 * ((uint32_t) 1L << 26); - carry5 = h5 >> 25; - h6 += carry5; - h5 -= carry5 * ((uint32_t) 1L << 25); - carry6 = h6 >> 26; - h7 += carry6; - h6 -= carry6 * ((uint32_t) 1L << 26); - carry7 = h7 >> 25; - h8 += carry7; - h7 -= carry7 * ((uint32_t) 1L << 25); - carry8 = h8 >> 26; - h9 += carry8; - h8 -= carry8 * ((uint32_t) 1L << 26); - carry9 = h9 >> 25; - h9 -= carry9 * ((uint32_t) 1L << 25); - - h[0] = h0; - h[1] = h1; - h[2] = h2; - h[3] = h3; - h[4] = h4; - h[5] = h5; - h[6] = h6; - h[7] = h7; - h[8] = h8; - h[9] = h9; -} - -/* - Goal: Output h0+...+2^255 h10-2^255 q, which is between 0 and 2^255-20. - Have h0+...+2^230 h9 between 0 and 2^255-1; - evidently 2^255 h10-2^255 q = 0. - - Goal: Output h0+...+2^230 h9. - */ - -static void -fe_tobytes(unsigned char *s, const fe h) -{ - fe t; - - fe_reduce(t, h); - s[0] = t[0] >> 0; - s[1] = t[0] >> 8; - s[2] = t[0] >> 16; - s[3] = (t[0] >> 24) | (t[1] * ((uint32_t) 1 << 2)); - s[4] = t[1] >> 6; - s[5] = t[1] >> 14; - s[6] = (t[1] >> 22) | (t[2] * ((uint32_t) 1 << 3)); - s[7] = t[2] >> 5; - s[8] = t[2] >> 13; - s[9] = (t[2] >> 21) | (t[3] * ((uint32_t) 1 << 5)); - s[10] = t[3] >> 3; - s[11] = t[3] >> 11; - s[12] = (t[3] >> 19) | (t[4] * ((uint32_t) 1 << 6)); - s[13] = t[4] >> 2; - s[14] = t[4] >> 10; - s[15] = t[4] >> 18; - s[16] = t[5] >> 0; - s[17] = t[5] >> 8; - s[18] = t[5] >> 16; - s[19] = (t[5] >> 24) | (t[6] * ((uint32_t) 1 << 1)); - s[20] = t[6] >> 7; - s[21] = t[6] >> 15; - s[22] = (t[6] >> 23) | (t[7] * ((uint32_t) 1 << 3)); - s[23] = t[7] >> 5; - s[24] = t[7] >> 13; - s[25] = (t[7] >> 21) | (t[8] * ((uint32_t) 1 << 4)); - s[26] = t[8] >> 4; - s[27] = t[8] >> 12; - s[28] = (t[8] >> 20) | (t[9] * ((uint32_t) 1 << 6)); - s[29] = t[9] >> 2; - s[30] = t[9] >> 10; - s[31] = t[9] >> 18; -} - /* return 1 if f is in {1,3,5,...,q-2} return 0 if f is in {0,2,4,...,q-1} diff --git a/src/libsodium/include/sodium/private/curve25519_ref10_fe_51.h b/src/libsodium/include/sodium/private/curve25519_ref10_fe_51.h index 4ebabd7e..f802a1f4 100644 --- a/src/libsodium/include/sodium/private/curve25519_ref10_fe_51.h +++ b/src/libsodium/include/sodium/private/curve25519_ref10_fe_51.h @@ -3,8 +3,6 @@ #include "private/common.h" #include "utils.h" -typedef uint64_t fe[5]; - /* h = 0 */ @@ -206,123 +204,6 @@ fe_copy(fe h, const fe f) h[4] = f4; } -/* - Ignores top bit of h. - */ - -static void -fe_frombytes(fe 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 -fe_reduce(fe h, const fe 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]; -} - -static void -fe_tobytes(unsigned char *s, const fe h) -{ - fe t; - uint64_t t0, t1, t2, t3; - - fe_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); -} - /* return 1 if f is in {1,3,5,...,q-2} return 0 if f is in {0,2,4,...,q-1}