Build fixes, put uint128_t detection in one place.

This commit is contained in:
Adam Ierymenko 2020-02-21 07:25:43 -08:00
parent 5275a34b0b
commit 1d885cf810
No known key found for this signature in database
GPG key ID: C8877CF2D7A5D7F3
4 changed files with 39 additions and 115 deletions

View file

@ -20,13 +20,7 @@ namespace ZeroTier {
namespace { namespace {
#if (defined(__GNUC__) || defined(__clang)) && (defined(__amd64) || defined(__amd64__) || defined(__x86_64) || defined(__x86_64__) || defined(__AMD64) || defined(__AMD64__) || defined(_M_X64) || defined(__aarch64__)) #ifdef ZT_HAVE_UINT128
#if defined(__SIZEOF_INT128__)
typedef unsigned __int128 uint128_t;
#else
typedef unsigned uint128_t __attribute__((mode(TI)));
#endif
ZT_ALWAYS_INLINE void s_bmul64(const uint64_t x,const uint64_t y,uint64_t &r_high,uint64_t &r_low) noexcept ZT_ALWAYS_INLINE void s_bmul64(const uint64_t x,const uint64_t y,uint64_t &r_high,uint64_t &r_low) noexcept
{ {

View file

@ -20,15 +20,10 @@ namespace {
#define NUM_ECC_DIGITS (ECC_BYTES/8) #define NUM_ECC_DIGITS (ECC_BYTES/8)
#define MAX_TRIES 1024 #define MAX_TRIES 1024
#if defined(__SIZEOF_INT128__) || ((__clang_major__ * 100 + __clang_minor__) >= 302) #ifdef ZT_HAVE_UINT128
#define SUPPORTS_INT128 1 #define SUPPORTS_INT128 1
#else #else
#define SUPPORTS_INT128 0 #define SUPPORTS_INT128 0
#endif
#if SUPPORTS_INT128
typedef unsigned __int128 uint128_t;
#else
typedef struct typedef struct
{ {
uint64_t m_low; uint64_t m_low;
@ -215,7 +210,7 @@ ZT_ALWAYS_INLINE uint64_t vli_sub(uint64_t *p_result, const uint64_t *p_left, co
return l_borrow; return l_borrow;
} }
#if SUPPORTS_INT128 #if SUPPORTS_INT128 == 1
/* Computes p_result = p_left * p_right. */ /* Computes p_result = p_left * p_right. */
void vli_mult(uint64_t *p_result, const uint64_t *p_left, const uint64_t *p_right) void vli_mult(uint64_t *p_result, const uint64_t *p_left, const uint64_t *p_right)
@ -309,7 +304,7 @@ ZT_ALWAYS_INLINE uint128_t add_128_128(uint128_t a, uint128_t b)
return l_result; return l_result;
} }
void vli_mult(uint64_t *p_result, uint64_t *p_left, uint64_t *p_right) void vli_mult(uint64_t *p_result, uint64_t *p_left, const uint64_t *p_right)
{ {
uint128_t r01 = {0, 0}; uint128_t r01 = {0, 0};
uint64_t r2 = 0; uint64_t r2 = 0;
@ -1087,10 +1082,6 @@ ZT_ALWAYS_INLINE int ecdsa_verify(const uint8_t p_publicKey[ECC_BYTES+1], const
return (vli_cmp(rx, l_r) == 0); return (vli_cmp(rx, l_r) == 0);
} }
//////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////
} // anonymous namespace } // anonymous namespace
void ECC384GenerateKey(uint8_t pub[ZT_ECC384_PUBLIC_KEY_SIZE],uint8_t priv[ZT_ECC384_PRIVATE_KEY_SIZE]) void ECC384GenerateKey(uint8_t pub[ZT_ECC384_PUBLIC_KEY_SIZE],uint8_t priv[ZT_ECC384_PRIVATE_KEY_SIZE])

View file

@ -32,6 +32,19 @@
#define __GCC__ #define __GCC__
#endif #endif
#endif #endif
#if defined(__GCC__) && !defined(__GNUC__)
#define __GNUC__
#endif
#if (defined(__GCC__) || defined(__GNUC__) || defined(__clang)) && (defined(__SIZEOF_INT128__) || defined(__amd64) || defined(__amd64__) || defined(__x86_64) || defined(__x86_64__) || defined(__AMD64) || defined(__AMD64__) || defined(_M_X64) || defined(__aarch64__))
#if defined(__SIZEOF_INT128__)
#define ZT_HAVE_UINT128
typedef unsigned __int128 uint128_t;
#else
#define ZT_HAVE_UINT128
typedef unsigned uint128_t __attribute__((mode(TI)));
#endif
#endif
#if defined(_WIN32) || defined(_WIN64) #if defined(_WIN32) || defined(_WIN64)
#ifdef _MSC_VER #ifdef _MSC_VER

View file

@ -4,11 +4,11 @@ D. J. Bernstein
Public domain. Public domain.
*/ */
// Small modifications have been made for ZeroTier, but this code remains // Small modifications have been made for ZeroTier, but this code remains in the public domain.
// in the public domain.
#include "Constants.hpp" #include "Constants.hpp"
#include "Poly1305.hpp" #include "Poly1305.hpp"
#include "Utils.hpp"
#include <cstring> #include <cstring>
@ -16,6 +16,11 @@ Public domain.
#pragma warning(disable: 4146) #pragma warning(disable: 4146)
#endif #endif
#define U8TO64(p) Utils::loadBigEndian<uint64_t>(p)
#define U64TO8(p,v) Utils::storeBigEndian<uint64_t>(p,v)
#define U8TO32(p) Utils::loadBigEndian<uint32_t>(p)
#define U32TO8(p,v) Utils::storeBigEndian<uint32_t>(p,v)
namespace ZeroTier { namespace ZeroTier {
namespace { namespace {
@ -25,37 +30,13 @@ typedef struct poly1305_context {
unsigned char opaque[136]; unsigned char opaque[136];
} poly1305_context; } poly1305_context;
#if (defined(_MSC_VER) || defined(__GNUC__) || defined(__clang)) && (defined(__amd64) || defined(__amd64__) || defined(__x86_64) || defined(__x86_64__) || defined(__AMD64) || defined(__AMD64__) || defined(_M_X64)) #ifdef ZT_HAVE_UINT128
////////////////////////////////////////////////////////////////////////////// #define MUL(out, x, y) out = ((uint128_t)x * y)
// 128-bit implementation for MSC and GCC from Poly1305-donna #define ADD(out, in) out += in
#define ADDLO(out, in) out += in
#if defined(_MSC_VER) #define SHR(in, shift) (unsigned long long)(in >> (shift))
#include <intrin.h> #define LO(in) (unsigned long long)(in)
typedef struct uint128_t {
unsigned long long lo;
unsigned long long hi;
} uint128_t;
#define MUL(out, x, y) out.lo = _umul128((x), (y), &out.hi)
#define ADD(out, in) { unsigned long long t = out.lo; out.lo += in.lo; out.hi += (out.lo < t) + in.hi; }
#define ADDLO(out, in) { unsigned long long t = out.lo; out.lo += in; out.hi += (out.lo < t); }
#define SHR(in, shift) (__shiftright128(in.lo, in.hi, (shift)))
#define LO(in) (in.lo)
#elif defined(__GNUC__)
#if defined(__SIZEOF_INT128__)
typedef unsigned __int128 uint128_t;
#else
typedef unsigned uint128_t __attribute__((mode(TI)));
#endif
#define MUL(out, x, y) out = ((uint128_t)x * y)
#define ADD(out, in) out += in
#define ADDLO(out, in) out += in
#define SHR(in, shift) (unsigned long long)(in >> (shift))
#define LO(in) (unsigned long long)(in)
#endif
#define poly1305_block_size 16 #define poly1305_block_size 16
@ -68,40 +49,7 @@ typedef struct poly1305_state_internal_t {
unsigned char final; unsigned char final;
} poly1305_state_internal_t; } poly1305_state_internal_t;
#if defined(ZT_NO_UNALIGNED_ACCESS) || (__BYTE_ORDER != __LITTLE_ENDIAN) ZT_ALWAYS_INLINE void poly1305_init(poly1305_context *ctx, const unsigned char key[32])
static inline unsigned long long U8TO64(const unsigned char *p)
{
return
(((unsigned long long)(p[0]) ) |
((unsigned long long)(p[1]) << 8) |
((unsigned long long)(p[2]) << 16) |
((unsigned long long)(p[3]) << 24) |
((unsigned long long)(p[4]) << 32) |
((unsigned long long)(p[5]) << 40) |
((unsigned long long)(p[6]) << 48) |
((unsigned long long)(p[7]) << 56));
}
#else
#define U8TO64(p) (*reinterpret_cast<const unsigned long long *>(p))
#endif
#if defined(ZT_NO_UNALIGNED_ACCESS) || (__BYTE_ORDER != __LITTLE_ENDIAN)
static inline void U64TO8(unsigned char *p, unsigned long long v)
{
p[0] = (unsigned char)(v );
p[1] = (unsigned char)(v >> 8);
p[2] = (unsigned char)(v >> 16);
p[3] = (unsigned char)(v >> 24);
p[4] = (unsigned char)(v >> 32);
p[5] = (unsigned char)(v >> 40);
p[6] = (unsigned char)(v >> 48);
p[7] = (unsigned char)(v >> 56);
}
#else
#define U64TO8(p,v) ((*reinterpret_cast<unsigned long long *>(p)) = (v))
#endif
static ZT_ALWAYS_INLINE void poly1305_init(poly1305_context *ctx, const unsigned char key[32])
{ {
poly1305_state_internal_t *st = (poly1305_state_internal_t *)ctx; poly1305_state_internal_t *st = (poly1305_state_internal_t *)ctx;
unsigned long long t0,t1; unsigned long long t0,t1;
@ -127,7 +75,7 @@ static ZT_ALWAYS_INLINE void poly1305_init(poly1305_context *ctx, const unsigned
st->final = 0; st->final = 0;
} }
static void poly1305_blocks(poly1305_state_internal_t *st, const unsigned char *m, size_t bytes) void poly1305_blocks(poly1305_state_internal_t *st, const unsigned char *m, size_t bytes)
{ {
const unsigned long long hibit = (st->final) ? 0 : ((unsigned long long)1 << 40); /* 1 << 128 */ const unsigned long long hibit = (st->final) ? 0 : ((unsigned long long)1 << 40); /* 1 << 128 */
unsigned long long r0,r1,r2; unsigned long long r0,r1,r2;
@ -178,7 +126,7 @@ static void poly1305_blocks(poly1305_state_internal_t *st, const unsigned char *
st->h[2] = h2; st->h[2] = h2;
} }
static ZT_ALWAYS_INLINE void poly1305_finish(poly1305_context *ctx, unsigned char mac[16]) ZT_ALWAYS_INLINE void poly1305_finish(poly1305_context *ctx, unsigned char mac[16])
{ {
poly1305_state_internal_t *st = (poly1305_state_internal_t *)ctx; poly1305_state_internal_t *st = (poly1305_state_internal_t *)ctx;
unsigned long long h0,h1,h2,c; unsigned long long h0,h1,h2,c;
@ -249,12 +197,7 @@ static ZT_ALWAYS_INLINE void poly1305_finish(poly1305_context *ctx, unsigned cha
st->pad[1] = 0; st->pad[1] = 0;
} }
////////////////////////////////////////////////////////////////////////////// #else // no uint128_t
#else
//////////////////////////////////////////////////////////////////////////////
// More portable 64-bit implementation
#define poly1305_block_size 16 #define poly1305_block_size 16
@ -267,22 +210,7 @@ typedef struct poly1305_state_internal_t {
unsigned char final; unsigned char final;
} poly1305_state_internal_t; } poly1305_state_internal_t;
static inline unsigned long ZT_ALWAYS_INLINE void poly1305_init(poly1305_context *ctx, const unsigned char key[32])
U8TO32(const unsigned char *p)
{
return (((unsigned long)(p[0])) | ((unsigned long)(p[1]) << 8) | ((unsigned long)(p[2]) << 16) | ((unsigned long)(p[3]) << 24));
}
static inline void
U32TO8(unsigned char *p, unsigned long v)
{
p[0] = (unsigned char)(v );
p[1] = (unsigned char)(v >> 8);
p[2] = (unsigned char)(v >> 16);
p[3] = (unsigned char)(v >> 24);
}
static ZT_ALWAYS_INLINE void poly1305_init(poly1305_context *ctx, const unsigned char key[32])
{ {
poly1305_state_internal_t *st = (poly1305_state_internal_t *)ctx; poly1305_state_internal_t *st = (poly1305_state_internal_t *)ctx;
@ -310,7 +238,7 @@ static ZT_ALWAYS_INLINE void poly1305_init(poly1305_context *ctx, const unsigned
st->final = 0; st->final = 0;
} }
static void poly1305_blocks(poly1305_state_internal_t *st, const unsigned char *m, size_t bytes) void poly1305_blocks(poly1305_state_internal_t *st, const unsigned char *m, size_t bytes)
{ {
const unsigned long hibit = (st->final) ? 0 : (1 << 24); /* 1 << 128 */ const unsigned long hibit = (st->final) ? 0 : (1 << 24); /* 1 << 128 */
unsigned long r0,r1,r2,r3,r4; unsigned long r0,r1,r2,r3,r4;
@ -369,7 +297,7 @@ static void poly1305_blocks(poly1305_state_internal_t *st, const unsigned char *
st->h[4] = h4; st->h[4] = h4;
} }
static ZT_ALWAYS_INLINE void poly1305_finish(poly1305_context *ctx, unsigned char mac[16]) ZT_ALWAYS_INLINE void poly1305_finish(poly1305_context *ctx, unsigned char mac[16])
{ {
poly1305_state_internal_t *st = (poly1305_state_internal_t *)ctx; poly1305_state_internal_t *st = (poly1305_state_internal_t *)ctx;
unsigned long h0,h1,h2,h3,h4,c; unsigned long h0,h1,h2,h3,h4,c;
@ -456,11 +384,9 @@ static ZT_ALWAYS_INLINE void poly1305_finish(poly1305_context *ctx, unsigned cha
st->pad[3] = 0; st->pad[3] = 0;
} }
////////////////////////////////////////////////////////////////////////////// #endif // uint128_t or portable version?
#endif // MSC/GCC or not ZT_ALWAYS_INLINE void poly1305_update(poly1305_context *ctx, const unsigned char *m, size_t bytes) noexcept
static ZT_ALWAYS_INLINE void poly1305_update(poly1305_context *ctx, const unsigned char *m, size_t bytes) noexcept
{ {
poly1305_state_internal_t *st = (poly1305_state_internal_t *)ctx; poly1305_state_internal_t *st = (poly1305_state_internal_t *)ctx;
size_t i; size_t i;