From 69308cbf990ef015a93da9956c77130b26a8fb1d Mon Sep 17 00:00:00 2001 From: mrolinek Date: Mon, 12 Feb 2018 18:01:20 +0100 Subject: [PATCH] windows_compatibility windows_testing windows_testing windows_testing windows_testing windows_testing windows_testing windows_testing windows_testing windows_testing windows_testing windows_testing windows_testing windows_testing windows_testing windows_testing windows_testing windows_testing windows_testing windows testing windows testing windows testing windows testing windows testing windows testing windows testing windows testing windows testing windows testing windows testing windows testing windows testing windows testing windows testing windows testing windows testing windows testing windows testing windows testing windows testing Revert "windows testing" This reverts commit 4b1047d433142d039951605a33a1f426197b7ead. Revert "windows testing" This reverts commit 4deaad7796e426f7eaf582c14ad8db5937faf981. Revert "windows testing" This reverts commit ce1af72cd1c70eb5ff5aec6eff41d6d5801042a6. windows testing --- src/include/arch_32/arch_intrinsics.h | 5 + src/include/keccak_internal.h | 7 + src/include/portable_endian.h | 6 +- src/include/word.h | 5 + src/per_curve/decaf.tmpl.c | 48 +++-- src/per_curve/eddsa.tmpl.h | 47 ++--- src/per_curve/point.tmpl.h | 196 ++++++++++++--------- src/per_curve/scalar.tmpl.c | 2 +- src/public_include/decaf/common.h | 34 +++- src/public_include/decaf/secure_buffer.hxx | 4 + src/public_include/decaf/sha512.h | 6 +- src/public_include/decaf/shake.h | 103 ++++++++--- src/public_include/decaf/shake.hxx | 13 ++ src/public_include/decaf/spongerng.h | 20 +-- src/spongerng.c | 8 +- test/bench_decaf.cxx | 19 +- test/shakesum.c | 6 + 17 files changed, 365 insertions(+), 164 deletions(-) diff --git a/src/include/arch_32/arch_intrinsics.h b/src/include/arch_32/arch_intrinsics.h index f3908a2..46be539 100644 --- a/src/include/arch_32/arch_intrinsics.h +++ b/src/include/arch_32/arch_intrinsics.h @@ -7,6 +7,11 @@ #define ARCH_WORD_BITS 32 +#if defined _MSC_VER +#define __attribute(x) +#define __inline__ __inline +#endif // MSVC + static __inline__ __attribute((always_inline,unused)) uint32_t word_is_zero(uint32_t a) { /* let's hope the compiler isn't clever enough to optimize this. */ diff --git a/src/include/keccak_internal.h b/src/include/keccak_internal.h index 15d1be4..62d199f 100644 --- a/src/include/keccak_internal.h +++ b/src/include/keccak_internal.h @@ -12,6 +12,13 @@ #include +/* Aliasing MSVC preprocessing to GNU preprocessing */ +#if defined _MSC_VER +#define __attribute__(x) // Turn off attribute code +#define __attribute(x) +#define __restrict__ __restrict // Use MSVC restrict code +#endif // MSVC + /* The internal, non-opaque definition of the decaf_sponge struct. */ typedef union { uint64_t w[25]; uint8_t b[25*8]; diff --git a/src/include/portable_endian.h b/src/include/portable_endian.h index 5cbfca7..100674e 100644 --- a/src/include/portable_endian.h +++ b/src/include/portable_endian.h @@ -21,8 +21,12 @@ # define htole64(x) LE_64(x) # define le64toh(x) LE_64(x) #elif defined(_WIN16) || defined(_WIN32) || defined(_WIN64) || defined(__WINDOWS__) +# if defined(_MSC_VER) +# define __builtin_bswap64(x) _byteswap_uint64((x)) +# else +# include +# endif # include -# include # if BYTE_ORDER == LITTLE_ENDIAN # define htole64(x) (x) # define le64toh(x) (x) diff --git a/src/include/word.h b/src/include/word.h index 7c7644a..de22693 100644 --- a/src/include/word.h +++ b/src/include/word.h @@ -13,6 +13,11 @@ extern int posix_memalign(void **, size_t, size_t); #endif +// MSVC has no posix_memalign +#if defined(_MSC_VER) +#define posix_memalign(p, a, s) (((*(p)) = _aligned_malloc((s), (a))), *(p) ?0 :errno) +#endif + #include #include #include "arch_intrinsics.h" diff --git a/src/per_curve/decaf.tmpl.c b/src/per_curve/decaf.tmpl.c index 9bfe4c0..833f301 100644 --- a/src/per_curve/decaf.tmpl.c +++ b/src/per_curve/decaf.tmpl.c @@ -7,6 +7,23 @@ #include #include +/* MSVC has no builtint ctz, this is a fix as in +https://stackoverflow.com/questions/355967/how-to-use-msvc-intrinsics-to-get-the-equivalent-of-this-gcc-code/5468852#5468852 +*/ +#ifdef _MSC_VER +#include + +uint32_t __inline ctz(uint32_t value) +{ + DWORD trailing_zero = 0; + if ( _BitScanForward( &trailing_zero, value ) ) + return trailing_zero; + else + return 32; // This is undefined, I better choose 32 than 0 +} +#define __builtin_ctz(x) ctz(x) +#endif + /* Template stuff */ #define API_NS(_id) $(c_ns)_##_id #define SCALAR_BITS $(C_NS)_SCALAR_BITS @@ -514,6 +531,7 @@ void API_NS(point_scalarmul) ( const point_t b, const scalar_t scalar ) { + const int WINDOW = DECAF_WINDOW_BITS, WINDOW_MASK = (1<> 1, @@ -524,7 +542,7 @@ void API_NS(point_scalarmul) ( API_NS(scalar_halve)(scalar1x,scalar1x); /* Set up a precomputed table with odd multiples of b. */ - pniels_t pn, multiples[NTABLE]; + pniels_t pn, multiples[1<<((int)(DECAF_WINDOW_BITS)-1)]; // == NTABLE (MSVC compatibility issue) point_t tmp; prepare_fixed_window(multiples, b, NTABLE); @@ -575,12 +593,13 @@ void API_NS(point_double_scalarmul) ( const scalar_t scalarb, const point_t c, const scalar_t scalarc -) { +) { + const int WINDOW = DECAF_WINDOW_BITS, WINDOW_MASK = (1<> 1, NTABLE = 1<<(WINDOW-1); - + scalar_t scalar1x, scalar2x; API_NS(scalar_add)(scalar1x, scalarb, point_scalarmul_adjustment); API_NS(scalar_halve)(scalar1x,scalar1x); @@ -588,9 +607,10 @@ void API_NS(point_double_scalarmul) ( API_NS(scalar_halve)(scalar2x,scalar2x); /* Set up a precomputed table with odd multiples of b. */ - pniels_t pn, multiples1[NTABLE], multiples2[NTABLE]; + pniels_t pn, multiples1[1<<((int)(DECAF_WINDOW_BITS)-1)], multiples2[1<<((int)(DECAF_WINDOW_BITS)-1)]; + // Array size above equal NTABLE (MSVC compatibility issue) point_t tmp; - prepare_fixed_window(multiples1, b, NTABLE); + prepare_fixed_window(multiples1, b, NTABLE); prepare_fixed_window(multiples2, c, NTABLE); /* Initialize. */ @@ -652,11 +672,13 @@ void API_NS(point_dual_scalarmul) ( const scalar_t scalar1, const scalar_t scalar2 ) { + const int WINDOW = DECAF_WINDOW_BITS, WINDOW_MASK = (1<> 1, NTABLE = 1<<(WINDOW-1); - + + scalar_t scalar1x, scalar2x; API_NS(scalar_add)(scalar1x, scalar1, point_scalarmul_adjustment); API_NS(scalar_halve)(scalar1x,scalar1x); @@ -664,7 +686,9 @@ void API_NS(point_dual_scalarmul) ( API_NS(scalar_halve)(scalar2x,scalar2x); /* Set up a precomputed table with odd multiples of b. */ - point_t multiples1[NTABLE], multiples2[NTABLE], working, tmp; + point_t multiples1[1<<((int)(DECAF_WINDOW_BITS)-1)], multiples2[1<<((int)(DECAF_WINDOW_BITS)-1)], working, tmp; + // Array sizes above equal NTABLE (MSVC compatibility issue) + pniels_t pn; API_NS(point_copy)(working, b); @@ -887,11 +911,11 @@ void API_NS(precompute) ( const unsigned int n = COMBS_N, t = COMBS_T, s = COMBS_S; assert(n*t*s >= SCALAR_BITS); - point_t working, start, doubles[t-1]; + point_t working, start, doubles[COMBS_T-1]; API_NS(point_copy)(working, base); pniels_t pn_tmp; - gf zs[n<<(t-1)], zis[n<<(t-1)]; + gf zs[(unsigned int)(COMBS_N)<<(unsigned int)(COMBS_T-1)], zis[(unsigned int)(COMBS_N)<<(unsigned int)(COMBS_T-1)]; unsigned int i,j,k; @@ -1511,13 +1535,13 @@ void API_NS(base_double_scalarmul_non_secret) ( ) { const int table_bits_var = DECAF_WNAF_VAR_TABLE_BITS, table_bits_pre = DECAF_WNAF_FIXED_TABLE_BITS; - struct smvt_control control_var[SCALAR_BITS/(table_bits_var+1)+3]; - struct smvt_control control_pre[SCALAR_BITS/(table_bits_pre+1)+3]; + struct smvt_control control_var[SCALAR_BITS/((int)(DECAF_WNAF_VAR_TABLE_BITS)+1)+3]; + struct smvt_control control_pre[SCALAR_BITS/((int)(DECAF_WNAF_FIXED_TABLE_BITS)+1)+3]; int ncb_pre = recode_wnaf(control_pre, scalar1, table_bits_pre); int ncb_var = recode_wnaf(control_var, scalar2, table_bits_var); - pniels_t precmp_var[1< +#if defined (__GNUC__) // File only exists for GNU compilers #include +#endif #ifdef __cplusplus extern "C" { @@ -25,11 +27,31 @@ extern "C" { #define __attribute__(x) #define NOINLINE #endif + +/* Aliasing MSVC preprocessing to GNU preprocessing */ +#if defined _MSC_VER +# define __attribute__(x) // Turn off attribute code +# define __attribute(x) +# define __restrict__ __restrict // Use MSVC restrict code +# if defined _DLL +# define DECAF_API_VIS __declspec(dllexport) // MSVC for visibility +# else +# define DECAF_API_VIS __declspec(dllimport) +# endif + +//# define DECAF_NOINLINE __declspec(noinline) // MSVC for noinline +//# define DECAF_INLINE __forceinline // MSVC for always inline +//# define DECAF_WARN_UNUSED _Check_return_ +#else // MSVC #define DECAF_API_VIS __attribute__((visibility("default"))) +#define DECAF_API_IMPORT +#endif + +// The following are disabled for MSVC #define DECAF_NOINLINE __attribute__((noinline)) -#define DECAF_WARN_UNUSED __attribute__((warn_unused_result)) -#define DECAF_NONNULL __attribute__((nonnull)) #define DECAF_INLINE inline __attribute__((always_inline,unused)) +#define DECAF_WARN_UNUSED __attribute__((warn_unused_result)) +#define DECAF_NONNULL __attribute__((nonnull)) // Cribbed from libnotmuch #if defined (__clang_major__) && __clang_major__ >= 3 \ || defined (__GNUC__) && __GNUC__ >= 5 \ @@ -98,17 +120,17 @@ decaf_successful(decaf_error_t e) { } /** Overwrite data with zeros. Uses memset_s if available. */ -void decaf_bzero ( +void DECAF_API_VIS decaf_bzero ( void *data, size_t size -) DECAF_NONNULL DECAF_API_VIS; +) DECAF_NONNULL; /** Compare two buffers, returning DECAF_TRUE if they are equal. */ -decaf_bool_t decaf_memeq ( +decaf_bool_t DECAF_API_VIS decaf_memeq ( const void *data1, const void *data2, size_t size -) DECAF_NONNULL DECAF_WARN_UNUSED DECAF_API_VIS; +) DECAF_NONNULL DECAF_WARN_UNUSED; #ifdef __cplusplus } /* extern "C" */ diff --git a/src/public_include/decaf/secure_buffer.hxx b/src/public_include/decaf/secure_buffer.hxx index 073a377..79aaff1 100644 --- a/src/public_include/decaf/secure_buffer.hxx +++ b/src/public_include/decaf/secure_buffer.hxx @@ -19,6 +19,10 @@ #include #include +#if defined(_MSC_VER) // MSVC does not have built in posix_memalign +#define posix_memalign(p, a, s) (((*(p)) = _aligned_malloc((s), (a))), *(p) ?0 :errno) +#endif + /** @cond internal */ #if __cplusplus >= 201103L #define DECAF_NOEXCEPT noexcept diff --git a/src/public_include/decaf/sha512.h b/src/public_include/decaf/sha512.h index ab810b4..dfe5808 100644 --- a/src/public_include/decaf/sha512.h +++ b/src/public_include/decaf/sha512.h @@ -28,17 +28,17 @@ typedef struct decaf_sha512_ctx_s { } decaf_sha512_ctx_s, decaf_sha512_ctx_t[1]; /** Initialize a SHA-512 context. */ -void decaf_sha512_init(decaf_sha512_ctx_t ctx) DECAF_NONNULL DECAF_API_VIS; +void DECAF_API_VIS decaf_sha512_init(decaf_sha512_ctx_t ctx) DECAF_NONNULL; /** Update context by hashing part of a message. */ -void decaf_sha512_update(decaf_sha512_ctx_t ctx, const uint8_t *message, size_t message_len) DECAF_NONNULL DECAF_API_VIS; +void DECAF_API_VIS decaf_sha512_update(decaf_sha512_ctx_t ctx, const uint8_t *message, size_t message_len) DECAF_NONNULL; /** Finalize context and write out hash. * @param [inout] ctx The context. Will be destroyed and re-initialized on return. * @param [out] output Place to store the output hash. * @param [in] output_len Length in bytes of the output hash. Must between 0 and 64, inclusive. */ -void decaf_sha512_final(decaf_sha512_ctx_t ctx, uint8_t *output, size_t output_len) DECAF_NONNULL DECAF_API_VIS; +void DECAF_API_VIS decaf_sha512_final(decaf_sha512_ctx_t ctx, uint8_t *output, size_t output_len) DECAF_NONNULL; /** Securely destroy a SHA512 context. */ static inline void decaf_sha512_destroy(decaf_sha512_ctx_t ctx) { diff --git a/src/public_include/decaf/shake.h b/src/public_include/decaf/shake.h index ae125b9..9e847d1 100644 --- a/src/public_include/decaf/shake.h +++ b/src/public_include/decaf/shake.h @@ -43,10 +43,10 @@ extern "C" { * @param [out] sponge The object to initialize. * @param [in] params The sponge's parameter description. */ -void decaf_sha3_init ( +void DECAF_API_VIS decaf_sha3_init ( decaf_keccak_sponge_t sponge, const struct decaf_kparams_s *params -) DECAF_API_VIS; +); /** * @brief Absorb data into a DECAF_SHA3 or DECAF_SHAKE hash context. @@ -56,11 +56,11 @@ void decaf_sha3_init ( * @return DECAF_FAILURE if the sponge has already been used for output. * @return DECAF_SUCCESS otherwise. */ -decaf_error_t decaf_sha3_update ( +decaf_error_t DECAF_API_VIS decaf_sha3_update ( struct decaf_keccak_sponge_s * __restrict__ sponge, const uint8_t *in, size_t len -) DECAF_API_VIS; +); /** * @brief Squeeze output data from a DECAF_SHA3 or DECAF_SHAKE hash context. @@ -73,11 +73,11 @@ decaf_error_t decaf_sha3_update ( * @return DECAF_FAILURE if the sponge has exhausted its output capacity. * @return DECAF_SUCCESS otherwise. */ -decaf_error_t decaf_sha3_output ( +decaf_error_t DECAF_API_VIS decaf_sha3_output ( decaf_keccak_sponge_t sponge, uint8_t * __restrict__ out, size_t len -) DECAF_API_VIS; +); /** * @brief Squeeze output data from a DECAF_SHA3 or DECAF_SHAKE hash context. @@ -87,20 +87,20 @@ decaf_error_t decaf_sha3_output ( * @param [out] out The output data. * @param [in] len The requested output data length in bytes. */ -decaf_error_t decaf_sha3_final ( +decaf_error_t DECAF_API_VIS decaf_sha3_final ( decaf_keccak_sponge_t sponge, uint8_t * __restrict__ out, size_t len -) DECAF_API_VIS; +); /** * @brief Reset the sponge to the empty string. * * @param [inout] sponge The context. */ -void decaf_sha3_reset ( +void DECAF_API_VIS decaf_sha3_reset ( decaf_keccak_sponge_t sponge -) DECAF_API_VIS; +); /** * @brief Return the default output length of the sponge construction, @@ -108,9 +108,9 @@ void decaf_sha3_reset ( * * Returns n/8 for DECAF_SHA3-n and 2n/8 for DECAF_SHAKE-n. */ -size_t decaf_sha3_default_output_bytes ( +size_t DECAF_API_VIS decaf_sha3_default_output_bytes ( const decaf_keccak_sponge_t sponge /**< [inout] The context. */ -) DECAF_API_VIS; +); /** * @brief Return the default output length of the sponge construction, @@ -118,17 +118,17 @@ size_t decaf_sha3_default_output_bytes ( * * Returns n/8 for DECAF_SHA3-n and SIZE_MAX for DECAF_SHAKE-n. */ -size_t decaf_sha3_max_output_bytes ( +size_t DECAF_API_VIS decaf_sha3_max_output_bytes ( const decaf_keccak_sponge_t sponge /**< [inout] The context. */ -) DECAF_API_VIS; +); /** * @brief Destroy a DECAF_SHA3 or DECAF_SHAKE sponge context by overwriting it with 0. * @param [out] sponge The context. */ -void decaf_sha3_destroy ( +void DECAF_API_VIS decaf_sha3_destroy ( decaf_keccak_sponge_t sponge -) DECAF_API_VIS; +); /** * @brief Hash (in) to (out) @@ -138,19 +138,78 @@ void decaf_sha3_destroy ( * @param [in] outlen The length of the output data. * @param [in] params The parameters of the sponge hash. */ -decaf_error_t decaf_sha3_hash ( +decaf_error_t DECAF_API_VIS decaf_sha3_hash ( uint8_t *out, size_t outlen, const uint8_t *in, size_t inlen, const struct decaf_kparams_s *params -) DECAF_API_VIS; +); /* FUTURE: expand/doxygenate individual DECAF_SHAKE/DECAF_SHA3 instances? */ +#if defined _MSC_VER + +/** @cond internal */ +#define DECAF_DEC_SHAKE(n) \ + extern const struct DECAF_API_VIS decaf_kparams_s DECAF_SHAKE##n##_params_s; \ + typedef struct decaf_shake##n##_ctx_s { decaf_keccak_sponge_t s; } decaf_shake##n##_ctx_t[1]; \ + static inline void DECAF_NONNULL decaf_shake##n##_init(decaf_shake##n##_ctx_t sponge) { \ + decaf_sha3_init(sponge->s, &DECAF_SHAKE##n##_params_s); \ + } \ + static inline void DECAF_NONNULL decaf_shake##n##_gen_init(decaf_keccak_sponge_t sponge) { \ + decaf_sha3_init(sponge, &DECAF_SHAKE##n##_params_s); \ + } \ + static inline decaf_error_t DECAF_NONNULL decaf_shake##n##_update(decaf_shake##n##_ctx_t sponge, const uint8_t *in, size_t inlen ) { \ + return decaf_sha3_update(sponge->s, in, inlen); \ + } \ + static inline void DECAF_NONNULL decaf_shake##n##_final(decaf_shake##n##_ctx_t sponge, uint8_t *out, size_t outlen ) { \ + decaf_sha3_output(sponge->s, out, outlen); \ + decaf_sha3_init(sponge->s, &DECAF_SHAKE##n##_params_s); \ + } \ + static inline void DECAF_NONNULL decaf_shake##n##_output(decaf_shake##n##_ctx_t sponge, uint8_t *out, size_t outlen ) { \ + decaf_sha3_output(sponge->s, out, outlen); \ + } \ + static inline void DECAF_NONNULL decaf_shake##n##_hash(uint8_t *out, size_t outlen, const uint8_t *in, size_t inlen) { \ + decaf_sha3_hash(out,outlen,in,inlen,&DECAF_SHAKE##n##_params_s); \ + } \ + static inline void DECAF_NONNULL decaf_shake##n##_destroy( decaf_shake##n##_ctx_t sponge ) { \ + decaf_sha3_destroy(sponge->s); \ + } + +#define DECAF_DEC_SHA3(n) \ + extern const struct DECAF_API_VIS decaf_kparams_s DECAF_SHA3_##n##_params_s; \ + typedef struct decaf_sha3_##n##_ctx_s { decaf_keccak_sponge_t s; } decaf_sha3_##n##_ctx_t[1]; \ + static inline void DECAF_NONNULL decaf_sha3_##n##_init(decaf_sha3_##n##_ctx_t sponge) { \ + decaf_sha3_init(sponge->s, &DECAF_SHA3_##n##_params_s); \ + } \ + static inline void DECAF_NONNULL decaf_sha3_##n##_gen_init(decaf_keccak_sponge_t sponge) { \ + decaf_sha3_init(sponge, &DECAF_SHA3_##n##_params_s); \ + } \ + static inline decaf_error_t DECAF_NONNULL decaf_sha3_##n##_update(decaf_sha3_##n##_ctx_t sponge, const uint8_t *in, size_t inlen ) { \ + return decaf_sha3_update(sponge->s, in, inlen); \ + } \ + static inline decaf_error_t DECAF_NONNULL decaf_sha3_##n##_final(decaf_sha3_##n##_ctx_t sponge, uint8_t *out, size_t outlen ) { \ + decaf_error_t ret = decaf_sha3_output(sponge->s, out, outlen); \ + decaf_sha3_init(sponge->s, &DECAF_SHA3_##n##_params_s); \ + return ret; \ + } \ + static inline decaf_error_t DECAF_NONNULL decaf_sha3_##n##_output(decaf_sha3_##n##_ctx_t sponge, uint8_t *out, size_t outlen ) { \ + return decaf_sha3_output(sponge->s, out, outlen); \ + } \ + static inline decaf_error_t DECAF_NONNULL decaf_sha3_##n##_hash(uint8_t *out, size_t outlen, const uint8_t *in, size_t inlen) { \ + return decaf_sha3_hash(out,outlen,in,inlen,&DECAF_SHA3_##n##_params_s); \ + } \ + static inline void DECAF_NONNULL decaf_sha3_##n##_destroy(decaf_sha3_##n##_ctx_t sponge) { \ + decaf_sha3_destroy(sponge->s); \ + } +/** @endcond */ + +#else // _MSC_VER + /** @cond internal */ #define DECAF_DEC_SHAKE(n) \ - extern const struct decaf_kparams_s DECAF_SHAKE##n##_params_s DECAF_API_VIS; \ + DECAF_API_VIS extern const struct decaf_kparams_s DECAF_SHAKE##n##_params_s; \ typedef struct decaf_shake##n##_ctx_s { decaf_keccak_sponge_t s; } decaf_shake##n##_ctx_t[1]; \ static inline void DECAF_NONNULL decaf_shake##n##_init(decaf_shake##n##_ctx_t sponge) { \ decaf_sha3_init(sponge->s, &DECAF_SHAKE##n##_params_s); \ @@ -176,7 +235,7 @@ decaf_error_t decaf_sha3_hash ( } #define DECAF_DEC_SHA3(n) \ - extern const struct decaf_kparams_s DECAF_SHA3_##n##_params_s DECAF_API_VIS; \ + DECAF_API_VIS extern const struct decaf_kparams_s DECAF_SHA3_##n##_params_s; \ typedef struct decaf_sha3_##n##_ctx_s { decaf_keccak_sponge_t s; } decaf_sha3_##n##_ctx_t[1]; \ static inline void DECAF_NONNULL decaf_sha3_##n##_init(decaf_sha3_##n##_ctx_t sponge) { \ decaf_sha3_init(sponge->s, &DECAF_SHA3_##n##_params_s); \ @@ -202,6 +261,10 @@ decaf_error_t decaf_sha3_hash ( decaf_sha3_destroy(sponge->s); \ } /** @endcond */ + +#endif // _MSC_VER + + DECAF_DEC_SHAKE(128) DECAF_DEC_SHAKE(256) diff --git a/src/public_include/decaf/shake.hxx b/src/public_include/decaf/shake.hxx index 58e360b..7eda93c 100644 --- a/src/public_include/decaf/shake.hxx +++ b/src/public_include/decaf/shake.hxx @@ -173,6 +173,17 @@ public: } }; + +#if defined _MSC_VER // MSVC does not want tempalte<> syntax, gcc cannot live without it +/** @cond internal */ +inline const struct decaf_kparams_s *SHAKE<128>::get_params() { return &DECAF_SHAKE128_params_s; } +inline const struct decaf_kparams_s *SHAKE<256>::get_params() { return &DECAF_SHAKE256_params_s; } +inline const struct decaf_kparams_s *SHA3<224>::get_params() { return &DECAF_SHA3_224_params_s; } +inline const struct decaf_kparams_s *SHA3<256>::get_params() { return &DECAF_SHA3_256_params_s; } +inline const struct decaf_kparams_s *SHA3<384>::get_params() { return &DECAF_SHA3_384_params_s; } +inline const struct decaf_kparams_s *SHA3<512>::get_params() { return &DECAF_SHA3_512_params_s; } +/** @endcond */ +#else /** @cond internal */ template<> inline const struct decaf_kparams_s *SHAKE<128>::get_params() { return &DECAF_SHAKE128_params_s; } template<> inline const struct decaf_kparams_s *SHAKE<256>::get_params() { return &DECAF_SHAKE256_params_s; } @@ -181,6 +192,8 @@ template<> inline const struct decaf_kparams_s *SHA3<256>::get_params() { return template<> inline const struct decaf_kparams_s *SHA3<384>::get_params() { return &DECAF_SHA3_384_params_s; } template<> inline const struct decaf_kparams_s *SHA3<512>::get_params() { return &DECAF_SHA3_512_params_s; } /** @endcond */ +#endif + } /* namespace decaf */ diff --git a/src/public_include/decaf/spongerng.h b/src/public_include/decaf/spongerng.h index eaad167..7b0836a 100644 --- a/src/public_include/decaf/spongerng.h +++ b/src/public_include/decaf/spongerng.h @@ -27,12 +27,12 @@ typedef struct { typedef decaf_keccak_prng_s decaf_keccak_prng_t[1]; /** Initialize a sponge-based CSPRNG from a buffer. */ -void decaf_spongerng_init_from_buffer ( +void DECAF_API_VIS decaf_spongerng_init_from_buffer ( decaf_keccak_prng_t prng, /**< [out] The PRNG object. */ const uint8_t *__restrict__ in, /**< [in] The initialization data. */ size_t len, /**< [in] The length of the initialization data. */ int deterministic /**< [in] If zero, allow RNG to stir in nondeterministic data from RDRAND or RDTSC.*/ -) DECAF_NONNULL DECAF_API_VIS; +) DECAF_NONNULL; /** * @brief Initialize a sponge-based CSPRNG from a file. @@ -40,12 +40,12 @@ void decaf_spongerng_init_from_buffer ( * @retval DECAF_FAILURE failure. * @note On failure, errno can be used to determine the cause. */ -decaf_error_t decaf_spongerng_init_from_file ( +decaf_error_t DECAF_API_VIS decaf_spongerng_init_from_file ( decaf_keccak_prng_t prng, /**< [out] The PRNG object. */ const char *file, /**< [in] A name of a file containing initial data. */ size_t len, /**< [in] The length of the initial data. Must be positive. */ int deterministic /**< [in] If zero, allow RNG to stir in nondeterministic data from RDRAND or RDTSC. */ -) DECAF_NONNULL DECAF_API_VIS DECAF_WARN_UNUSED; +) DECAF_NONNULL DECAF_WARN_UNUSED; /** * @brief Initialize a nondeterministic sponge-based CSPRNG from /dev/urandom. @@ -53,23 +53,23 @@ decaf_error_t decaf_spongerng_init_from_file ( * @retval DECAF_FAILURE failure. * @note On failure, errno can be used to determine the cause. */ -decaf_error_t decaf_spongerng_init_from_dev_urandom ( +decaf_error_t DECAF_API_VIS decaf_spongerng_init_from_dev_urandom ( decaf_keccak_prng_t prng /**< [out] sponge The sponge object. */ -) DECAF_API_VIS DECAF_WARN_UNUSED; +) DECAF_WARN_UNUSED; /** Output bytes from a sponge-based CSPRNG. */ -void decaf_spongerng_next ( +void DECAF_API_VIS decaf_spongerng_next ( decaf_keccak_prng_t prng, /**< [inout] The PRNG object. */ uint8_t * __restrict__ out, /**< [out] Output buffer. */ size_t len /**< [in] Number of bytes to output. */ -) DECAF_API_VIS; +); /** Stir entropy data into a sponge-based CSPRNG from a buffer. */ -void decaf_spongerng_stir ( +void DECAF_API_VIS decaf_spongerng_stir ( decaf_keccak_prng_t prng, /**< [out] The PRNG object. */ const uint8_t * __restrict__ in, /**< [in] The entropy data. */ size_t len /**< [in] The length of the initial data. */ -) DECAF_NONNULL DECAF_API_VIS; +) DECAF_NONNULL; /** Securely destroy a sponge RNG object by overwriting it. */ static DECAF_INLINE void diff --git a/src/spongerng.c b/src/spongerng.c index 52630b5..fea7702 100644 --- a/src/spongerng.c +++ b/src/spongerng.c @@ -22,7 +22,13 @@ #include #include #include -#include +#if defined(_MSC_VER) +# include +#include +typedef SSIZE_T ssize_t; +#else +# include +#endif /** Get entropy from a CPU, preferably in the form of RDRAND, but possibly instead from RDTSC. */ static void get_cpu_entropy(uint8_t *entropy, size_t len) { diff --git a/test/bench_decaf.cxx b/test/bench_decaf.cxx index ed77640..88a26c8 100644 --- a/test/bench_decaf.cxx +++ b/test/bench_decaf.cxx @@ -15,7 +15,6 @@ #include #include #include -#include #include #include #include @@ -23,13 +22,31 @@ using namespace decaf; +#if defined _MSC_VER // Turn off attribute code and rename inline +#define __attribute__(x) // Turn off attribute code +#define __attribute(x) +#define __inline__ __inline // Use MSVC inline +#endif // MSVC static __inline__ void __attribute__((unused)) ignore_result ( int result ) { (void)result; } +#if defined _MSC_VER // MSVC does not have gettimeoftheday +#include +static double now(void) { + static const auto beg = std::chrono::high_resolution_clock::now(); + auto end_time = std::chrono::high_resolution_clock::now(); + auto time = end_time - beg; + double duration = 0.000001 * std::chrono::duration_cast(time).count(); + return duration; +} +#else +#include static double now(void) { struct timeval tv; gettimeofday(&tv, NULL); return tv.tv_sec + tv.tv_usec/1000000.0; } +#endif + // RDTSC from the chacha code #ifndef __has_builtin diff --git a/test/shakesum.c b/test/shakesum.c index e627797..7d9019a 100644 --- a/test/shakesum.c +++ b/test/shakesum.c @@ -9,7 +9,13 @@ */ #include +#if defined _MSC_VER // MSVC has not unistd.h +#include +#include +typedef SSIZE_T ssize_t; +#else #include +#endif #include #include #include