| @@ -72,7 +72,7 @@ HEADERS= Makefile $(shell find src include test -name "*.h") $(shell find . -nam | |||||
| DECAFCOMPONENTS= build/$(DECAF).o build/shake.o build/decaf_crypto.o \ | DECAFCOMPONENTS= build/$(DECAF).o build/shake.o build/decaf_crypto.o \ | ||||
| build/$(FIELD).o build/f_arithmetic.o # TODO | |||||
| build/$(FIELD).o build/f_arithmetic.o build/utils.o | |||||
| ifeq ($(DECAF),decaf_fast) | ifeq ($(DECAF),decaf_fast) | ||||
| DECAFCOMPONENTS += build/decaf_tables.o | DECAFCOMPONENTS += build/decaf_tables.o | ||||
| endif | endif | ||||
| @@ -104,7 +104,7 @@ else | |||||
| $(LDXX) $(LDFLAGS) -Wl,-rpath,`pwd`/build -o $@ $< -Lbuild -ldecaf | $(LDXX) $(LDFLAGS) -Wl,-rpath,`pwd`/build -o $@ $< -Lbuild -ldecaf | ||||
| endif | endif | ||||
| build/shakesum: build/shakesum.o build/shake.o | |||||
| build/shakesum: build/shakesum.o build/shake.o build/utils.o | |||||
| $(LD) $(LDFLAGS) -o $@ $^ | $(LD) $(LDFLAGS) -o $@ $^ | ||||
| lib: build/libdecaf.so | lib: build/libdecaf.so | ||||
| @@ -127,7 +127,7 @@ build/timestamp: | |||||
| build/%.o: build/%.s | build/%.o: build/%.s | ||||
| $(ASM) $(ASFLAGS) -c -o $@ $< | $(ASM) $(ASFLAGS) -c -o $@ $< | ||||
| build/decaf_gen_tables: build/decaf_gen_tables.o build/$(DECAF).o build/$(FIELD).o build/f_arithmetic.o | |||||
| build/decaf_gen_tables: build/decaf_gen_tables.o build/$(DECAF).o build/$(FIELD).o build/f_arithmetic.o build/utils.o | |||||
| $(LD) $(LDFLAGS) -o $@ $^ | $(LD) $(LDFLAGS) -o $@ $^ | ||||
| build/decaf_tables.c: build/decaf_gen_tables | build/decaf_tables.c: build/decaf_gen_tables | ||||
| @@ -1,66 +1,32 @@ | |||||
| /** | |||||
| * @file decaf.h | |||||
| * @author Mike Hamburg | |||||
| * | |||||
| * @copyright | |||||
| * Copyright (c) 2015 Cryptography Research, Inc. \n | |||||
| * Released under the MIT License. See LICENSE.txt for license information. | |||||
| * | |||||
| * @brief Master header for Decaf library. | |||||
| * | |||||
| * The Decaf library implements cryptographic operations on a elliptic curve | |||||
| * groups of prime order p. It accomplishes this by using a twisted Edwards | |||||
| * curve (isogenous to Ed448-Goldilocks or Ed25519) and wiping out the cofactor. | |||||
| * | |||||
| * The formulas are all complete and have no special cases. However, some | |||||
| * functions can fail. For example, decoding functions can fail because not | |||||
| * every string is the encoding of a valid group element. | |||||
| * | |||||
| * The formulas contain no data-dependent branches, timing or memory accesses, | |||||
| * except for decaf_XXX_base_double_scalarmul_non_secret. | |||||
| */ | |||||
| #ifndef __DECAF_H__ | #ifndef __DECAF_H__ | ||||
| #define __DECAF_H__ 1 | #define __DECAF_H__ 1 | ||||
| #include <stdint.h> | #include <stdint.h> | ||||
| #include <sys/types.h> | #include <sys/types.h> | ||||
| /* Goldilocks' build flags default to hidden and stripping executables. */ | |||||
| /** @cond internal */ | |||||
| #if defined(DOXYGEN) && !defined(__attribute__) | |||||
| #define __attribute__((x)) | |||||
| #endif | |||||
| #define API_VIS __attribute__((visibility("default"))) | |||||
| #define NOINLINE __attribute__((noinline)) | |||||
| #define WARN_UNUSED __attribute__((warn_unused_result)) | |||||
| #define NONNULL1 __attribute__((nonnull(1))) | |||||
| #define NONNULL2 __attribute__((nonnull(1,2))) | |||||
| #define NONNULL3 __attribute__((nonnull(1,2,3))) | |||||
| #define NONNULL4 __attribute__((nonnull(1,2,3,4))) | |||||
| #define NONNULL5 __attribute__((nonnull(1,2,3,4,5))) | |||||
| /** @endcond */ | |||||
| /* Internal word types */ | |||||
| #if (defined(__ILP64__) || defined(__amd64__) || defined(__x86_64__) || (((__UINT_FAST32_MAX__)>>30)>>30)) \ | |||||
| && !defined(DECAF_FORCE_32_BIT) | |||||
| #define DECAF_WORD_BITS 64 | |||||
| typedef uint64_t decaf_word_t, decaf_bool_t; | |||||
| typedef __uint128_t decaf_dword_t; | |||||
| #else | |||||
| #define DECAF_WORD_BITS 32 | |||||
| typedef uint32_t decaf_word_t, decaf_bool_t; | |||||
| typedef uint64_t decaf_dword_t; | |||||
| #endif | |||||
| #ifdef __cplusplus | |||||
| extern "C" { | |||||
| #endif | |||||
| /** DECAF_TRUE = -1 so that DECAF_TRUE & x = x */ | |||||
| static const decaf_bool_t DECAF_TRUE = -(decaf_bool_t)1, DECAF_FALSE = 0; | |||||
| /** NB Success is -1, failure is 0. TODO: see if people would rather the reverse. */ | |||||
| static const decaf_bool_t DECAF_SUCCESS = -(decaf_bool_t)1 /*DECAF_TRUE*/, | |||||
| DECAF_FAILURE = 0 /*DECAF_FALSE*/; | |||||
| #include "decaf_255.h" | |||||
| #include "decaf_448.h" | |||||
| #ifdef __cplusplus | |||||
| } | |||||
| #endif | |||||
| #undef API_VIS | |||||
| #undef WARN_UNUSED | |||||
| #undef NOINLINE | |||||
| #undef NONNULL1 | |||||
| #undef NONNULL2 | |||||
| #undef NONNULL3 | |||||
| #undef NONNULL4 | |||||
| #undef NONNULL5 | |||||
| #include "decaf_255.h" | |||||
| #include "decaf_448.h" | |||||
| #endif /* __DECAF_H__ */ | #endif /* __DECAF_H__ */ | ||||
| @@ -6,27 +6,15 @@ | |||||
| * Copyright (c) 2015 Cryptography Research, Inc. \n | * Copyright (c) 2015 Cryptography Research, Inc. \n | ||||
| * Released under the MIT License. See LICENSE.txt for license information. | * Released under the MIT License. See LICENSE.txt for license information. | ||||
| * | * | ||||
| * @brief A group of prime order p. | |||||
| * | |||||
| * The Decaf library implements cryptographic operations on a an elliptic curve | |||||
| * group of prime order p. It accomplishes this by using a twisted Edwards | |||||
| * curve (isogenous to Ed255-Goldilocks) and wiping out the cofactor. | |||||
| * | |||||
| * The formulas are all complete and have no special cases, except that | |||||
| * decaf_255_decode can fail because not every sequence of bytes is a valid group | |||||
| * element. | |||||
| * | |||||
| * The formulas contain no data-dependent branches, timing or memory accesses, | |||||
| * except for decaf_255_base_double_scalarmul_non_secret. | |||||
| * | |||||
| * This library may support multiple curves eventually. The Ed255-Goldilocks | |||||
| * specific identifiers are prefixed with DECAF_255 or decaf_255. | |||||
| * @brief A group of prime order p, based on Ed25519. | |||||
| */ | */ | ||||
| #ifndef __DECAF_255_H__ | #ifndef __DECAF_255_H__ | ||||
| #define __DECAF_255_H__ 1 | #define __DECAF_255_H__ 1 | ||||
| #ifndef __DECAF_H__ | |||||
| #error "include <decaf.h>, not <decaf_255.h>." | |||||
| #include "decaf_common.h" | |||||
| #ifdef __cplusplus | |||||
| extern "C" { | |||||
| #endif | #endif | ||||
| #define DECAF_255_LIMBS (320/DECAF_WORD_BITS) | #define DECAF_255_LIMBS (320/DECAF_WORD_BITS) | ||||
| @@ -73,11 +61,7 @@ extern const decaf_255_scalar_t decaf_255_scalar_zero API_VIS; | |||||
| /** The identity point on the curve. */ | /** The identity point on the curve. */ | ||||
| extern const decaf_255_point_t decaf_255_point_identity API_VIS; | extern const decaf_255_point_t decaf_255_point_identity API_VIS; | ||||
| /** | |||||
| * An arbitrarily chosen base point on the curve. | |||||
| * Equal to Ed255-Goldilocks base point defined by DJB, except of course that | |||||
| * it's on the twist in this case. TODO: choose a base point with nice encoding? | |||||
| */ | |||||
| /** An arbitrarily chosen base point on the curve. */ | |||||
| extern const decaf_255_point_t decaf_255_point_base API_VIS; | extern const decaf_255_point_t decaf_255_point_base API_VIS; | ||||
| /** Precomputed table for the base point on the curve. */ | /** Precomputed table for the base point on the curve. */ | ||||
| @@ -196,12 +180,11 @@ static inline void NONNULL2 decaf_255_scalar_copy ( | |||||
| } | } | ||||
| /** | /** | ||||
| * @brief Set a scalar to an integer. | |||||
| * @brief Set a scalar to an unsigned integer. | |||||
| * @param [in] a An integer. | * @param [in] a An integer. | ||||
| * @param [out] out Will become equal to a. | * @param [out] out Will become equal to a. | ||||
| * @todo Make inline? | |||||
| */ | */ | ||||
| void decaf_255_scalar_set( | |||||
| void decaf_255_scalar_set_unsigned ( | |||||
| decaf_255_scalar_t out, | decaf_255_scalar_t out, | ||||
| decaf_word_t a | decaf_word_t a | ||||
| ) API_VIS NONNULL1; | ) API_VIS NONNULL1; | ||||
| @@ -381,8 +364,6 @@ void decaf_255_precompute ( | |||||
| * @param [out] scaled The scaled point base*scalar | * @param [out] scaled The scaled point base*scalar | ||||
| * @param [in] base The point to be scaled. | * @param [in] base The point to be scaled. | ||||
| * @param [in] scalar The scalar to multiply by. | * @param [in] scalar The scalar to multiply by. | ||||
| * | |||||
| * @todo precomputed dsmul? const or variable time? | |||||
| */ | */ | ||||
| void decaf_255_precomputed_scalarmul ( | void decaf_255_precomputed_scalarmul ( | ||||
| decaf_255_point_t scaled, | decaf_255_point_t scaled, | ||||
| @@ -518,9 +499,6 @@ decaf_255_point_from_hash_nonuniform ( | |||||
| * @retval DECAF_SUCCESS The inverse succeeded. | * @retval DECAF_SUCCESS The inverse succeeded. | ||||
| * @retval DECAF_FAILURE The pt isn't the image of | * @retval DECAF_FAILURE The pt isn't the image of | ||||
| * decaf_255_point_from_hash_nonuniform with the given hint. | * decaf_255_point_from_hash_nonuniform with the given hint. | ||||
| * | |||||
| * @warning The hinting system is subject to change, especially in corner cases. | |||||
| * @warning FIXME The hinting system doesn't work for certain inputs which have many 0xFF. | |||||
| */ | */ | ||||
| decaf_bool_t | decaf_bool_t | ||||
| decaf_255_invert_elligator_nonuniform ( | decaf_255_invert_elligator_nonuniform ( | ||||
| @@ -564,23 +542,6 @@ void decaf_255_point_from_hash_uniform ( | |||||
| const unsigned char hashed_data[2*DECAF_255_SER_BYTES] | const unsigned char hashed_data[2*DECAF_255_SER_BYTES] | ||||
| ) API_VIS NONNULL2 NOINLINE; | ) API_VIS NONNULL2 NOINLINE; | ||||
| /** | |||||
| * @brief Overwrite data with zeros. Uses memset_s if available. | |||||
| */ | |||||
| void decaf_bzero ( | |||||
| void *data, | |||||
| size_t size | |||||
| ) NONNULL1 API_VIS NOINLINE; | |||||
| /** | |||||
| * @brief Compare two buffers, returning DECAF_TRUE if they are equal. | |||||
| */ | |||||
| decaf_bool_t decaf_memeq ( | |||||
| const void *data1, | |||||
| const void *data2, | |||||
| size_t size | |||||
| ) NONNULL2 WARN_UNUSED API_VIS NOINLINE; | |||||
| /** | /** | ||||
| * @brief Overwrite scalar with zeros. | * @brief Overwrite scalar with zeros. | ||||
| */ | */ | ||||
| @@ -597,11 +558,14 @@ void decaf_255_point_destroy ( | |||||
| ) NONNULL1 API_VIS; | ) NONNULL1 API_VIS; | ||||
| /** | /** | ||||
| * @brief Overwrite point with zeros. | |||||
| * @todo Use this internally. | |||||
| * @brief Overwrite precomputed table with zeros. | |||||
| */ | */ | ||||
| void decaf_255_precomputed_destroy ( | void decaf_255_precomputed_destroy ( | ||||
| decaf_255_precomputed_s *pre | decaf_255_precomputed_s *pre | ||||
| ) NONNULL1 API_VIS; | ) NONNULL1 API_VIS; | ||||
| #ifdef __cplusplus | |||||
| } /* extern "C" */ | |||||
| #endif | |||||
| #endif /* __DECAF_255_H__ */ | #endif /* __DECAF_255_H__ */ | ||||
| @@ -33,7 +33,6 @@ | |||||
| #include <sys/types.h> | #include <sys/types.h> | ||||
| #include <limits.h> | #include <limits.h> | ||||
| /* TODO: This is incomplete */ | |||||
| /* TODO: attribute nonnull */ | /* TODO: attribute nonnull */ | ||||
| /** @cond internal */ | /** @cond internal */ | ||||
| @@ -96,12 +95,12 @@ public: | |||||
| inline Scalar& operator=(const Scalar &x) NOEXCEPT { decaf_255_scalar_copy(s,x.s); return *this; } | inline Scalar& operator=(const Scalar &x) NOEXCEPT { decaf_255_scalar_copy(s,x.s); return *this; } | ||||
| /** @brief Assign from unsigned word. */ | /** @brief Assign from unsigned word. */ | ||||
| inline Scalar& operator=(decaf_word_t w) NOEXCEPT { decaf_255_scalar_set(s,w); return *this; } | |||||
| inline Scalar& operator=(decaf_word_t w) NOEXCEPT { decaf_255_scalar_set_unsigned(s,w); return *this; } | |||||
| /** @brief Assign from signed int. */ | /** @brief Assign from signed int. */ | ||||
| inline Scalar& operator=(int w) NOEXCEPT { | inline Scalar& operator=(int w) NOEXCEPT { | ||||
| Scalar t(-(decaf_word_t)INT_MIN); | Scalar t(-(decaf_word_t)INT_MIN); | ||||
| decaf_255_scalar_set(s,(decaf_word_t)w - (decaf_word_t)INT_MIN); | |||||
| decaf_255_scalar_set_unsigned(s,(decaf_word_t)w - (decaf_word_t)INT_MIN); | |||||
| *this -= t; | *this -= t; | ||||
| return *this; | return *this; | ||||
| } | } | ||||
| @@ -6,27 +6,15 @@ | |||||
| * Copyright (c) 2015 Cryptography Research, Inc. \n | * Copyright (c) 2015 Cryptography Research, Inc. \n | ||||
| * Released under the MIT License. See LICENSE.txt for license information. | * Released under the MIT License. See LICENSE.txt for license information. | ||||
| * | * | ||||
| * @brief A group of prime order p. | |||||
| * | |||||
| * The Decaf library implements cryptographic operations on a an elliptic curve | |||||
| * group of prime order p. It accomplishes this by using a twisted Edwards | |||||
| * curve (isogenous to Ed448-Goldilocks) and wiping out the cofactor. | |||||
| * | |||||
| * The formulas are all complete and have no special cases, except that | |||||
| * decaf_448_decode can fail because not every sequence of bytes is a valid group | |||||
| * element. | |||||
| * | |||||
| * The formulas contain no data-dependent branches, timing or memory accesses, | |||||
| * except for decaf_448_base_double_scalarmul_non_secret. | |||||
| * | |||||
| * This library may support multiple curves eventually. The Ed448-Goldilocks | |||||
| * specific identifiers are prefixed with DECAF_448 or decaf_448. | |||||
| * @brief A group of prime order p, based on Ed448-Goldilocks. | |||||
| */ | */ | ||||
| #ifndef __DECAF_448_H__ | #ifndef __DECAF_448_H__ | ||||
| #define __DECAF_448_H__ 1 | #define __DECAF_448_H__ 1 | ||||
| #ifndef __DECAF_H__ | |||||
| #error "include <decaf.h>, not <decaf_448.h>." | |||||
| #include "decaf_common.h" | |||||
| #ifdef __cplusplus | |||||
| extern "C" { | |||||
| #endif | #endif | ||||
| #define DECAF_448_LIMBS (512/DECAF_WORD_BITS) | #define DECAF_448_LIMBS (512/DECAF_WORD_BITS) | ||||
| @@ -73,11 +61,7 @@ extern const decaf_448_scalar_t decaf_448_scalar_zero API_VIS; | |||||
| /** The identity point on the curve. */ | /** The identity point on the curve. */ | ||||
| extern const decaf_448_point_t decaf_448_point_identity API_VIS; | extern const decaf_448_point_t decaf_448_point_identity API_VIS; | ||||
| /** | |||||
| * An arbitrarily chosen base point on the curve. | |||||
| * Equal to Ed448-Goldilocks base point defined by DJB, except of course that | |||||
| * it's on the twist in this case. TODO: choose a base point with nice encoding? | |||||
| */ | |||||
| /** An arbitrarily chosen base point on the curve. */ | |||||
| extern const decaf_448_point_t decaf_448_point_base API_VIS; | extern const decaf_448_point_t decaf_448_point_base API_VIS; | ||||
| /** Precomputed table for the base point on the curve. */ | /** Precomputed table for the base point on the curve. */ | ||||
| @@ -199,9 +183,8 @@ static inline void NONNULL2 decaf_448_scalar_copy ( | |||||
| * @brief Set a scalar to an integer. | * @brief Set a scalar to an integer. | ||||
| * @param [in] a An integer. | * @param [in] a An integer. | ||||
| * @param [out] out Will become equal to a. | * @param [out] out Will become equal to a. | ||||
| * @todo Make inline? | |||||
| */ | */ | ||||
| void decaf_448_scalar_set( | |||||
| void decaf_448_scalar_set_unsigned ( | |||||
| decaf_448_scalar_t out, | decaf_448_scalar_t out, | ||||
| decaf_word_t a | decaf_word_t a | ||||
| ) API_VIS NONNULL1; | ) API_VIS NONNULL1; | ||||
| @@ -381,8 +364,6 @@ void decaf_448_precompute ( | |||||
| * @param [out] scaled The scaled point base*scalar | * @param [out] scaled The scaled point base*scalar | ||||
| * @param [in] base The point to be scaled. | * @param [in] base The point to be scaled. | ||||
| * @param [in] scalar The scalar to multiply by. | * @param [in] scalar The scalar to multiply by. | ||||
| * | |||||
| * @todo precomputed dsmul? const or variable time? | |||||
| */ | */ | ||||
| void decaf_448_precomputed_scalarmul ( | void decaf_448_precomputed_scalarmul ( | ||||
| decaf_448_point_t scaled, | decaf_448_point_t scaled, | ||||
| @@ -505,9 +486,6 @@ decaf_448_point_from_hash_nonuniform ( | |||||
| * @retval DECAF_SUCCESS The inverse succeeded. | * @retval DECAF_SUCCESS The inverse succeeded. | ||||
| * @retval DECAF_FAILURE The pt isn't the image of | * @retval DECAF_FAILURE The pt isn't the image of | ||||
| * decaf_448_point_from_hash_nonuniform with the given hint. | * decaf_448_point_from_hash_nonuniform with the given hint. | ||||
| * | |||||
| * @warning The hinting system is subject to change, especially in corner cases. | |||||
| * @warning FIXME The hinting system doesn't work for certain inputs which have many 0xFF. | |||||
| */ | */ | ||||
| decaf_bool_t | decaf_bool_t | ||||
| decaf_448_invert_elligator_nonuniform ( | decaf_448_invert_elligator_nonuniform ( | ||||
| @@ -557,23 +535,6 @@ unsigned char decaf_448_point_from_hash_uniform ( | |||||
| const unsigned char hashed_data[2*DECAF_448_SER_BYTES] | const unsigned char hashed_data[2*DECAF_448_SER_BYTES] | ||||
| ) API_VIS NONNULL2 NOINLINE; | ) API_VIS NONNULL2 NOINLINE; | ||||
| /** | |||||
| * @brief Overwrite data with zeros. Uses memset_s if available. | |||||
| */ | |||||
| void decaf_bzero ( | |||||
| void *data, | |||||
| size_t size | |||||
| ) NONNULL1 API_VIS NOINLINE; | |||||
| /** | |||||
| * @brief Compare two buffers, returning DECAF_TRUE if they are equal. | |||||
| */ | |||||
| decaf_bool_t decaf_memeq ( | |||||
| const void *data1, | |||||
| const void *data2, | |||||
| size_t size | |||||
| ) NONNULL2 WARN_UNUSED API_VIS NOINLINE; | |||||
| /** | /** | ||||
| * @brief Overwrite scalar with zeros. | * @brief Overwrite scalar with zeros. | ||||
| */ | */ | ||||
| @@ -590,11 +551,14 @@ void decaf_448_point_destroy ( | |||||
| ) NONNULL1 API_VIS; | ) NONNULL1 API_VIS; | ||||
| /** | /** | ||||
| * @brief Overwrite point with zeros. | |||||
| * @todo Use this internally. | |||||
| * @brief Overwrite precomputed table with zeros. | |||||
| */ | */ | ||||
| void decaf_448_precomputed_destroy ( | void decaf_448_precomputed_destroy ( | ||||
| decaf_448_precomputed_s *pre | decaf_448_precomputed_s *pre | ||||
| ) NONNULL1 API_VIS; | ) NONNULL1 API_VIS; | ||||
| #ifdef __cplusplus | |||||
| } /* extern "C" */ | |||||
| #endif | |||||
| #endif /* __DECAF_448_H__ */ | #endif /* __DECAF_448_H__ */ | ||||
| @@ -277,12 +277,12 @@ public: | |||||
| inline Scalar& operator=(const Scalar &x) NOEXCEPT { decaf_448_scalar_copy(s,x.s); return *this; } | inline Scalar& operator=(const Scalar &x) NOEXCEPT { decaf_448_scalar_copy(s,x.s); return *this; } | ||||
| /** @brief Assign from unsigned word. */ | /** @brief Assign from unsigned word. */ | ||||
| inline Scalar& operator=(decaf_word_t w) NOEXCEPT { decaf_448_scalar_set(s,w); return *this; } | |||||
| inline Scalar& operator=(decaf_word_t w) NOEXCEPT { decaf_448_scalar_set_unsigned(s,w); return *this; } | |||||
| /** @brief Assign from signed int. */ | /** @brief Assign from signed int. */ | ||||
| inline Scalar& operator=(int w) NOEXCEPT { | inline Scalar& operator=(int w) NOEXCEPT { | ||||
| Scalar t(-(decaf_word_t)INT_MIN); | Scalar t(-(decaf_word_t)INT_MIN); | ||||
| decaf_448_scalar_set(s,(decaf_word_t)w - (decaf_word_t)INT_MIN); | |||||
| decaf_448_scalar_set_unsigned(s,(decaf_word_t)w - (decaf_word_t)INT_MIN); | |||||
| *this -= t; | *this -= t; | ||||
| return *this; | return *this; | ||||
| } | } | ||||
| @@ -0,0 +1,78 @@ | |||||
| /** | |||||
| * @file decaf_common.h | |||||
| * @author Mike Hamburg | |||||
| * | |||||
| * @copyright | |||||
| * Copyright (c) 2015 Cryptography Research, Inc. \n | |||||
| * Released under the MIT License. See LICENSE.txt for license information. | |||||
| * | |||||
| * @brief Common utility headers for Decaf library. | |||||
| */ | |||||
| #ifndef __DECAF_COMMON_H__ | |||||
| #define __DECAF_COMMON_H__ 1 | |||||
| #include <stdint.h> | |||||
| #include <sys/types.h> | |||||
| /* Goldilocks' build flags default to hidden and stripping executables. */ | |||||
| /** @cond internal */ | |||||
| #if defined(DOXYGEN) && !defined(__attribute__) | |||||
| #define __attribute__((x)) | |||||
| #endif | |||||
| #define API_VIS __attribute__((visibility("default"))) | |||||
| #define NOINLINE __attribute__((noinline)) | |||||
| #define WARN_UNUSED __attribute__((warn_unused_result)) | |||||
| #define NONNULL1 __attribute__((nonnull(1))) | |||||
| #define NONNULL2 __attribute__((nonnull(1,2))) | |||||
| #define NONNULL3 __attribute__((nonnull(1,2,3))) | |||||
| #define NONNULL13 __attribute__((nonnull(1,3))) | |||||
| #define NONNULL4 __attribute__((nonnull(1,2,3,4))) | |||||
| #define NONNULL5 __attribute__((nonnull(1,2,3,4,5))) | |||||
| /** @endcond */ | |||||
| /* Internal word types */ | |||||
| #if (defined(__ILP64__) || defined(__amd64__) || defined(__x86_64__) || (((__UINT_FAST32_MAX__)>>30)>>30)) \ | |||||
| && !defined(DECAF_FORCE_32_BIT) | |||||
| #define DECAF_WORD_BITS 64 | |||||
| typedef uint64_t decaf_word_t, decaf_bool_t; | |||||
| typedef __uint128_t decaf_dword_t; | |||||
| #else | |||||
| #define DECAF_WORD_BITS 32 | |||||
| typedef uint32_t decaf_word_t, decaf_bool_t; | |||||
| typedef uint64_t decaf_dword_t; | |||||
| #endif | |||||
| #ifdef __cplusplus | |||||
| extern "C" { | |||||
| #endif | |||||
| /** DECAF_TRUE = -1 so that DECAF_TRUE & x = x */ | |||||
| static const decaf_bool_t DECAF_TRUE = -(decaf_bool_t)1, DECAF_FALSE = 0; | |||||
| /** NB Success is -1, failure is 0. */ | |||||
| static const decaf_bool_t DECAF_SUCCESS = -(decaf_bool_t)1 /*DECAF_TRUE*/, | |||||
| DECAF_FAILURE = 0 /*DECAF_FALSE*/; | |||||
| /** | |||||
| * @brief Overwrite data with zeros. Uses memset_s if available. | |||||
| */ | |||||
| void decaf_bzero ( | |||||
| void *data, | |||||
| size_t size | |||||
| ) NONNULL1 API_VIS; | |||||
| /** | |||||
| * @brief Compare two buffers, returning DECAF_TRUE if they are equal. | |||||
| */ | |||||
| decaf_bool_t decaf_memeq ( | |||||
| const void *data1, | |||||
| const void *data2, | |||||
| size_t size | |||||
| ) NONNULL2 WARN_UNUSED API_VIS; | |||||
| #ifdef __cplusplus | |||||
| } /* extern "C" */ | |||||
| #endif | |||||
| #endif /* __DECAF_COMMON_H__ */ | |||||
| @@ -15,9 +15,8 @@ | |||||
| #include <stdint.h> | #include <stdint.h> | ||||
| #include <sys/types.h> | #include <sys/types.h> | ||||
| #include "decaf.h" /* TODO: orly? */ | |||||
| #include "decaf_common.h" | |||||
| /* TODO: unify with other headers (maybe all into one??); add nonnull attributes */ | |||||
| /** @cond internal */ | /** @cond internal */ | ||||
| #define API_VIS __attribute__((visibility("default"))) | #define API_VIS __attribute__((visibility("default"))) | ||||
| #define WARN_UNUSED __attribute__((warn_unused_result)) | #define WARN_UNUSED __attribute__((warn_unused_result)) | ||||
| @@ -115,7 +114,7 @@ void sponge_hash ( | |||||
| const struct kparams_s *params | const struct kparams_s *params | ||||
| ) API_VIS; | ) API_VIS; | ||||
| /* TODO: expand/doxygenate individual SHAKE/SHA3 instances? */ | |||||
| /* FUTURE: expand/doxygenate individual SHAKE/SHA3 instances? */ | |||||
| /** @cond internal */ | /** @cond internal */ | ||||
| #define DECSHAKE(n) \ | #define DECSHAKE(n) \ | ||||
| @@ -438,7 +438,7 @@ snv sc_halve ( | |||||
| out->limb[i] = out->limb[i]>>1 | chain<<(WBITS-1); | out->limb[i] = out->limb[i]>>1 | chain<<(WBITS-1); | ||||
| } | } | ||||
| void API_NS(scalar_set) ( | |||||
| void API_NS(scalar_set_unsigned) ( | |||||
| scalar_t out, | scalar_t out, | ||||
| decaf_word_t w | decaf_word_t w | ||||
| ) { | ) { | ||||
| @@ -702,25 +702,6 @@ decaf_bool_t API_NS(scalar_decode)( | |||||
| return accum; | return accum; | ||||
| } | } | ||||
| void decaf_bzero ( | |||||
| void *s, | |||||
| size_t size | |||||
| ) { | |||||
| #ifdef __STDC_LIB_EXT1__ | |||||
| memset_s(s, size, 0, size); | |||||
| #else | |||||
| const size_t sw = sizeof(decaf_word_t); | |||||
| volatile uint8_t *destroy = (volatile uint8_t *)s; | |||||
| for (; size && ((uintptr_t)destroy)%sw; size--, destroy++) | |||||
| *destroy = 0; | |||||
| for (; size >= sw; size -= sw, destroy += sw) | |||||
| *(volatile decaf_word_t *)destroy = 0; | |||||
| for (; size; size--, destroy++) | |||||
| *destroy = 0; | |||||
| #endif | |||||
| } | |||||
| void API_NS(scalar_destroy) ( | void API_NS(scalar_destroy) ( | ||||
| scalar_t scalar | scalar_t scalar | ||||
| ) { | ) { | ||||
| @@ -1645,20 +1626,6 @@ void API_NS(point_destroy) ( | |||||
| decaf_bzero(point, sizeof(point_t)); | decaf_bzero(point, sizeof(point_t)); | ||||
| } | } | ||||
| decaf_bool_t decaf_memeq ( | |||||
| const void *data1_, | |||||
| const void *data2_, | |||||
| size_t size | |||||
| ) { | |||||
| const unsigned char *data1 = (const unsigned char *)data1_; | |||||
| const unsigned char *data2 = (const unsigned char *)data2_; | |||||
| unsigned char ret = 0; | |||||
| for (; size; size--, data1++, data2++) { | |||||
| ret |= *data1 ^ *data2; | |||||
| } | |||||
| return (((decaf_dword_t)ret) - 1) >> 8; | |||||
| } | |||||
| void API_NS(precomputed_destroy) ( | void API_NS(precomputed_destroy) ( | ||||
| precomputed_s *pre | precomputed_s *pre | ||||
| ) { | ) { | ||||
| @@ -68,7 +68,6 @@ typedef struct keccak_sponge_s { | |||||
| #define INTERNAL_SPONGE_STRUCT 1 | #define INTERNAL_SPONGE_STRUCT 1 | ||||
| #include "shake.h" | #include "shake.h" | ||||
| #include "decaf.h" | |||||
| #define FLAG_ABSORBING 'A' | #define FLAG_ABSORBING 'A' | ||||
| #define FLAG_SQUEEZING 'Z' | #define FLAG_SQUEEZING 'Z' | ||||
| @@ -98,16 +97,16 @@ static inline uint64_t rol(uint64_t x, int s) { | |||||
| return (x << s) | (x >> (64 - s)); | return (x << s) | (x >> (64 - s)); | ||||
| } | } | ||||
| /* Helper macros to unroll the permutation. TODO: opt tradeoffs. */ | |||||
| /* Helper macros to unroll the permutation. */ | |||||
| #define REPEAT5(e) e e e e e | #define REPEAT5(e) e e e e e | ||||
| #define FOR51(v, e) v = 0; REPEAT5(e; v += 1;) | #define FOR51(v, e) v = 0; REPEAT5(e; v += 1;) | ||||
| //#if (defined(__OPTIMIZE__) && !defined(__OPTIMIZE_SIZE__)) | |||||
| #ifndef SHAKE_NO_UNROLL_LOOPS | |||||
| # define FOR55(v, e) v = 0; REPEAT5(e; v += 5;) | # define FOR55(v, e) v = 0; REPEAT5(e; v += 5;) | ||||
| # define REPEAT24(e) e e e e e e e e e e e e e e e e e e e e e e e e | # define REPEAT24(e) e e e e e e e e e e e e e e e e e e e e e e e e | ||||
| // #else | |||||
| // # define FOR55(v, e) for (v=0; v<25; v+= 5) { e; } | |||||
| // # define REPEAT24(e) {int _j=0; for (_j=0; _j<24; _j++) { e }} | |||||
| // #endif | |||||
| #else | |||||
| # define FOR55(v, e) for (v=0; v<25; v+= 5) { e; } | |||||
| # define REPEAT24(e) {int _j=0; for (_j=0; _j<24; _j++) { e }} | |||||
| #endif | |||||
| /*** The Keccak-f[1600] permutation ***/ | /*** The Keccak-f[1600] permutation ***/ | ||||
| static void | static void | ||||
| @@ -213,23 +212,7 @@ void sha3_output ( | |||||
| } | } | ||||
| } | } | ||||
| /** TODO: unify with decaf_bzero? */ | |||||
| static void sponge_bzero(void *s, size_t size) { | |||||
| #ifdef __STDC_LIB_EXT1__ | |||||
| memset_s(s, size, 0, size); | |||||
| #else | |||||
| const size_t sw = sizeof(decaf_word_t); | |||||
| volatile uint8_t *destroy = (volatile uint8_t *)s; | |||||
| for (; size && ((uintptr_t)destroy)%sw; size--, destroy++) | |||||
| *destroy = 0; | |||||
| for (; size >= sw; size -= sw, destroy += sw) | |||||
| *(volatile decaf_word_t *)destroy = 0; | |||||
| for (; size; size--, destroy++) | |||||
| *destroy = 0; | |||||
| #endif | |||||
| } | |||||
| void sponge_destroy (keccak_sponge_t sponge) { sponge_bzero(sponge, sizeof(keccak_sponge_t)); } | |||||
| void sponge_destroy (keccak_sponge_t sponge) { decaf_bzero(sponge, sizeof(keccak_sponge_t)); } | |||||
| void sponge_init ( | void sponge_init ( | ||||
| keccak_sponge_t sponge, | keccak_sponge_t sponge, | ||||
| @@ -509,7 +492,7 @@ static void strobe_forget ( | |||||
| strobe_duplex(sponge,tmp,NULL,len); | strobe_duplex(sponge,tmp,NULL,len); | ||||
| if (sponge->params->position) dokeccak(sponge); | if (sponge->params->position) dokeccak(sponge); | ||||
| strobe_duplex(sponge,tmp,NULL,len); | strobe_duplex(sponge,tmp,NULL,len); | ||||
| sponge_bzero(tmp,len); | |||||
| decaf_bzero(tmp,len); | |||||
| } else { | } else { | ||||
| if (sponge->params->rate < len + sponge->params->position) { | if (sponge->params->rate < len + sponge->params->position) { | ||||
| dokeccak(sponge); | dokeccak(sponge); | ||||
| @@ -0,0 +1,43 @@ | |||||
| /* Copyright (c) 2015 Cryptography Research, Inc. | |||||
| * Released under the MIT License. See LICENSE.txt for license information. | |||||
| */ | |||||
| /** | |||||
| * @file decaf_utils.c | |||||
| * @author Mike Hamburg | |||||
| * @brief Decaf utility functions. | |||||
| */ | |||||
| #include "decaf_common.h" | |||||
| void decaf_bzero ( | |||||
| void *s, | |||||
| size_t size | |||||
| ) { | |||||
| #ifdef __STDC_LIB_EXT1__ | |||||
| memset_s(s, size, 0, size); | |||||
| #else | |||||
| const size_t sw = sizeof(decaf_word_t); | |||||
| volatile uint8_t *destroy = (volatile uint8_t *)s; | |||||
| for (; size && ((uintptr_t)destroy)%sw; size--, destroy++) | |||||
| *destroy = 0; | |||||
| for (; size >= sw; size -= sw, destroy += sw) | |||||
| *(volatile decaf_word_t *)destroy = 0; | |||||
| for (; size; size--, destroy++) | |||||
| *destroy = 0; | |||||
| #endif | |||||
| } | |||||
| decaf_bool_t decaf_memeq ( | |||||
| const void *data1_, | |||||
| const void *data2_, | |||||
| size_t size | |||||
| ) { | |||||
| const unsigned char *data1 = (const unsigned char *)data1_; | |||||
| const unsigned char *data2 = (const unsigned char *)data2_; | |||||
| unsigned char ret = 0; | |||||
| for (; size; size--, data1++, data2++) { | |||||
| ret |= *data1 ^ *data2; | |||||
| } | |||||
| return (((decaf_dword_t)ret) - 1) >> 8; | |||||
| } | |||||