diff --git a/Makefile b/Makefile index 4b5d5823a..ccf08a306 100644 --- a/Makefile +++ b/Makefile @@ -54,28 +54,29 @@ objs/%.o: src/%.c links: rm -rf include/oqs mkdir -p include/oqs - $(LN) ../../src/aes/aes.h include/oqs + $(LN) ../../src/crypto/aes/aes.h include/oqs + $(LN) ../../src/crypto/sha3/sha3.h include/oqs $(LN) ../../src/kex/kex.h include/oqs $(LN) ../../src/kex_rlwe_bcns15/kex_rlwe_bcns15.h include/oqs $(LN) ../../src/kex_rlwe_newhope/kex_rlwe_newhope.h include/oqs $(LN) ../../src/kex_rlwe_msrln16/kex_rlwe_msrln16.h include/oqs $(LN) ../../src/kex_lwe_frodo/kex_lwe_frodo.h include/oqs $(LN) ../../src/kex_sidh_cln16/kex_sidh_cln16.h include/oqs - $(LN) ../../src/rand/rand.h include/oqs - $(LN) ../../src/rand_urandom_chacha20/rand_urandom_chacha20.h include/oqs - $(LN) ../../src/rand_urandom_aesctr/rand_urandom_aesctr.h include/oqs + $(LN) ../../src/crypto/rand/rand.h include/oqs + $(LN) ../../src/crypto/rand_urandom_chacha20/rand_urandom_chacha20.h include/oqs + $(LN) ../../src/crypto/rand_urandom_aesctr/rand_urandom_aesctr.h include/oqs $(LN) ../../src/common/common.h include/oqs # RAND_URANDOM_CHACHA -RAND_URANDOM_CHACHA_OBJS := $(addprefix objs/rand_urandom_chacha20/, rand_urandom_chacha20.o) -$(RAND_URANDOM_CHACHA_OBJS): src/rand_urandom_chacha20/rand_urandom_chacha20.h +RAND_URANDOM_CHACHA_OBJS := $(addprefix objs/crypto/rand_urandom_chacha20/, rand_urandom_chacha20.o) +$(RAND_URANDOM_CHACHA_OBJS): src/crypto/rand_urandom_chacha20/rand_urandom_chacha20.h # RAND_URANDOM_AESCTR -RAND_URANDOM_AESCTR_OBJS := $(addprefix objs/rand_urandom_aesctr/, rand_urandom_aesctr.o) -$(RAND_URANDOM_AESCTR_OBJS): src/rand_urandom_aesctr/rand_urandom_aesctr.h +RAND_URANDOM_AESCTR_OBJS := $(addprefix objs/crypto/rand_urandom_aesctr/, rand_urandom_aesctr.o) +$(RAND_URANDOM_AESCTR_OBJS): src/crypto/rand_urandom_aesctr/rand_urandom_aesctr.h # RAND -objs/rand/rand.o: src/rand/rand.h +objs/crypto/rand/rand.o: src/crypto/rand/rand.h # KEX_RLWE_BCNS15 KEX_RLWE_BCNS15_OBJS := $(addprefix objs/kex_rlwe_bcns15/, fft.o kex_rlwe_bcns15.o rlwe.o rlwe_kex.o) @@ -84,7 +85,7 @@ $(KEX_RLWE_BCNS15_OBJS): $(KEX_RLWE_BCNS15_HEADERS) # KEX_NEWHOPE KEX_RLWE_NEWHOPE_OBJS := $(addprefix objs/kex_rlwe_newhope/, kex_rlwe_newhope.o) -KEX_RLWE_NEWHOPE_HEADERS := $(addprefix src/kex_rlwe_newhope/, kex_rlwe_newhope.h fips202.c newhope.c params.h poly.c precomp.c) +KEX_RLWE_NEWHOPE_HEADERS := $(addprefix src/kex_rlwe_newhope/, kex_rlwe_newhope.h newhope.c params.h poly.c precomp.c) $(KEX_RLWE_NEWHOPE_OBJS): $(KEX_RLWE_NEWHOPE_HEADERS) # KEX_RLWE_MSRLN16 @@ -103,8 +104,8 @@ KEX_SIDH_CLN16_HEADERS := $(addprefix src/kex_sidh_cln16/, kex_sidh_cln16.h SIDH $(KEX_SIDH_CLN16_OBJS): $(KEX_SIDH_CLN16_HEADERS) # AES -AES_OBJS := $(addprefix objs/aes/, aes.o aes_c.o aes_ni.o) -AES_HEADERS := $(addprefix src/aes/, aes.h) +AES_OBJS := $(addprefix objs/crypto/aes/, aes.o aes_c.o aes_ni.o) +AES_HEADERS := $(addprefix src/crypto/aes/, aes.h) $(AES_OBJS): $(AES_HEADERS) #COMMON @@ -112,6 +113,10 @@ COMMON_OBJS := $(addprefix objs/common/, common.o) COMMON_HEADERS := $(addprefix src/common/, common.h) $(COMMON_OBJS): $(COMMON_HEADERS) +# SHA3 +SHA3_OBJS := $(addprefix objs/crypto/sha3/, sha3.o) +SHA3_HEADERS := $(addprefix src/crypto/sha3/, sha3.h) +$(SHA3_OBJS): $(SHA3_HEADERS) # KEX objs/kex/kex.o: src/kex/kex.h @@ -119,17 +124,19 @@ objs/kex/kex.o: src/kex/kex.h # LIB -RAND_OBJS := $(RAND_URANDOM_AESCTR_OBJS) $(RAND_URANDOM_CHACHA_OBJS) +RAND_OBJS := $(RAND_URANDOM_AESCTR_OBJS) $(RAND_URANDOM_CHACHA_OBJS) objs/crypto/rand/rand.o -lib: $(RAND_OBJS) $(KEX_RLWE_BCNS15_OBJS) $(KEX_RLWE_NEWHOPE_OBJS) $(KEX_RLWE_MSRLN16_OBJS) $(KEX_LWE_FRODO_OBJS) $(KEX_SIDH_CLN16_OBJS) objs/rand/rand.o objs/kex/kex.o $(AES_OBJS) $(COMMON_OBJS) +KEX_OBJS := $(KEX_RLWE_BCNS15_OBJS) $(KEX_RLWE_NEWHOPE_OBJS) $(KEX_RLWE_MSRLN16_OBJS) $(KEX_LWE_FRODO_OBJS) $(KEX_SIDH_CLN16_OBJS) objs/kex/kex.o + +lib: $(RAND_OBJS) $(KEX_OBJS) $(AES_OBJS) $(COMMON_OBJS) $(SHA3_OBJS) rm -f liboqs.a $(AR) liboqs.a $^ $(RANLIB) liboqs.a -tests: lib src/rand/test_rand.c src/kex/test_kex.c src/aes/test_aes.c src/ds_benchmark.h - $(CC) $(CFLAGS) $(INCLUDES) -L. src/rand/test_rand.c -loqs $(LDFLAGS) -o test_rand +tests: lib src/crypto/rand/test_rand.c src/kex/test_kex.c src/crypto/aes/test_aes.c src/ds_benchmark.h + $(CC) $(CFLAGS) $(INCLUDES) -L. src/crypto/rand/test_rand.c -loqs $(LDFLAGS) -o test_rand $(CC) $(CFLAGS) $(INCLUDES) -L. src/kex/test_kex.c -loqs $(LDFLAGS) -o test_kex - $(CC) $(CFLAGS) $(INCLUDES) -L. src/aes/test_aes.c -loqs $(LDFLAGS) -o test_aes + $(CC) $(CFLAGS) $(INCLUDES) -L. src/crypto/aes/test_aes.c -loqs $(LDFLAGS) -o test_aes docs: links doxygen diff --git a/src/aes/aes.c b/src/crypto/aes/aes.c similarity index 100% rename from src/aes/aes.c rename to src/crypto/aes/aes.c diff --git a/src/aes/aes.h b/src/crypto/aes/aes.h similarity index 100% rename from src/aes/aes.h rename to src/crypto/aes/aes.h diff --git a/src/aes/aes_c.c b/src/crypto/aes/aes_c.c similarity index 100% rename from src/aes/aes_c.c rename to src/crypto/aes/aes_c.c diff --git a/src/aes/aes_local.h b/src/crypto/aes/aes_local.h similarity index 100% rename from src/aes/aes_local.h rename to src/crypto/aes/aes_local.h diff --git a/src/aes/aes_ni.c b/src/crypto/aes/aes_ni.c similarity index 100% rename from src/aes/aes_ni.c rename to src/crypto/aes/aes_ni.c diff --git a/src/aes/test_aes.c b/src/crypto/aes/test_aes.c similarity index 99% rename from src/aes/test_aes.c rename to src/crypto/aes/test_aes.c index a4834df1e..7dc7be99b 100644 --- a/src/aes/test_aes.c +++ b/src/crypto/aes/test_aes.c @@ -6,7 +6,7 @@ #include "aes.h" #include "aes_local.h" -#include "../ds_benchmark.h" +#include "../../ds_benchmark.h" #define BENCH_DURATION 1 diff --git a/src/rand/rand.c b/src/crypto/rand/rand.c similarity index 100% rename from src/rand/rand.c rename to src/crypto/rand/rand.c diff --git a/src/rand/rand.h b/src/crypto/rand/rand.h similarity index 100% rename from src/rand/rand.h rename to src/crypto/rand/rand.h diff --git a/src/rand/test_rand.c b/src/crypto/rand/test_rand.c similarity index 100% rename from src/rand/test_rand.c rename to src/crypto/rand/test_rand.c diff --git a/src/rand_urandom_aesctr/rand_urandom_aesctr.c b/src/crypto/rand_urandom_aesctr/rand_urandom_aesctr.c similarity index 100% rename from src/rand_urandom_aesctr/rand_urandom_aesctr.c rename to src/crypto/rand_urandom_aesctr/rand_urandom_aesctr.c diff --git a/src/rand_urandom_aesctr/rand_urandom_aesctr.h b/src/crypto/rand_urandom_aesctr/rand_urandom_aesctr.h similarity index 100% rename from src/rand_urandom_aesctr/rand_urandom_aesctr.h rename to src/crypto/rand_urandom_aesctr/rand_urandom_aesctr.h diff --git a/src/rand_urandom_chacha20/external/LICENSE.txt b/src/crypto/rand_urandom_chacha20/external/LICENSE.txt similarity index 100% rename from src/rand_urandom_chacha20/external/LICENSE.txt rename to src/crypto/rand_urandom_chacha20/external/LICENSE.txt diff --git a/src/rand_urandom_chacha20/external/chacha20.c b/src/crypto/rand_urandom_chacha20/external/chacha20.c similarity index 100% rename from src/rand_urandom_chacha20/external/chacha20.c rename to src/crypto/rand_urandom_chacha20/external/chacha20.c diff --git a/src/rand_urandom_chacha20/external/ecrypt-config.h b/src/crypto/rand_urandom_chacha20/external/ecrypt-config.h similarity index 100% rename from src/rand_urandom_chacha20/external/ecrypt-config.h rename to src/crypto/rand_urandom_chacha20/external/ecrypt-config.h diff --git a/src/rand_urandom_chacha20/external/ecrypt-portable.h b/src/crypto/rand_urandom_chacha20/external/ecrypt-portable.h similarity index 100% rename from src/rand_urandom_chacha20/external/ecrypt-portable.h rename to src/crypto/rand_urandom_chacha20/external/ecrypt-portable.h diff --git a/src/rand_urandom_chacha20/rand_urandom_chacha20.c b/src/crypto/rand_urandom_chacha20/rand_urandom_chacha20.c similarity index 100% rename from src/rand_urandom_chacha20/rand_urandom_chacha20.c rename to src/crypto/rand_urandom_chacha20/rand_urandom_chacha20.c diff --git a/src/rand_urandom_chacha20/rand_urandom_chacha20.h b/src/crypto/rand_urandom_chacha20/rand_urandom_chacha20.h similarity index 100% rename from src/rand_urandom_chacha20/rand_urandom_chacha20.h rename to src/crypto/rand_urandom_chacha20/rand_urandom_chacha20.h diff --git a/src/kex_rlwe_newhope/fips202.c b/src/crypto/sha3/sha3.c similarity index 90% rename from src/kex_rlwe_newhope/fips202.c rename to src/crypto/sha3/sha3.c index 454888649..690fc8576 100644 --- a/src/kex_rlwe_newhope/fips202.c +++ b/src/crypto/sha3/sha3.c @@ -7,9 +7,10 @@ #include #include +#include -#define SHAKE128_RATE 168 -#define SHA3_256_RATE 136 +#define SHAKE128_RATE OQS_SHA3_SHAKE128_RATE +#define SHA3_256_RATE OQS_SHA3_SHA3_256_RATE #define NROUNDS 24 #define ROL(a, offset) ((a << offset) ^ (a >> (64-offset))) @@ -334,37 +335,32 @@ static void keccak_absorb(uint64_t *s, unsigned long long i; unsigned char t[200]; - for (i = 0; i < 25; ++i) { + for (i = 0; i < 25; ++i) s[i] = 0; - } while (mlen >= r) { - for (i = 0; i < r / 8; ++i) { + for (i = 0; i < r / 8; ++i) s[i] ^= load64(m + 8 * i); - } KeccakF1600_StatePermute(s); mlen -= r; m += r; } - for (i = 0; i < r; ++i) { + for (i = 0; i < r; ++i) t[i] = 0; - } - for (i = 0; i < mlen; ++i) { + for (i = 0; i < mlen; ++i) t[i] = m[i]; - } t[i] = p; t[r - 1] |= 128; - for (i = 0; i < r / 8; ++i) { + for (i = 0; i < r / 8; ++i) s[i] ^= load64(t + 8 * i); - } } -static void keccak_squeezeblocks(unsigned char *h, unsigned long long int nblocks, - uint64_t *s, - unsigned int r) { +void OQS_SHA3_keccak_squeezeblocks(unsigned char *h, unsigned long long int nblocks, + uint64_t *s, + unsigned int r) { unsigned int i; while (nblocks > 0) { KeccakF1600_StatePermute(s); @@ -376,22 +372,21 @@ static void keccak_squeezeblocks(unsigned char *h, unsigned long long int nblock } } -static void shake128_absorb(uint64_t *s, const unsigned char *input, unsigned int inputByteLen) { +void OQS_SHA3_shake128_absorb(uint64_t *s, const unsigned char *input, unsigned int inputByteLen) { keccak_absorb(s, SHAKE128_RATE, input, inputByteLen, 0x1F); } -static void shake128_squeezeblocks(unsigned char *output, unsigned long long nblocks, uint64_t *s) { - keccak_squeezeblocks(output, nblocks, s, SHAKE128_RATE); +void OQS_SHA3_shake128_squeezeblocks(unsigned char *output, unsigned long long nblocks, uint64_t *s) { + OQS_SHA3_keccak_squeezeblocks(output, nblocks, s, SHAKE128_RATE); } -static void sha3256(unsigned char *output, const unsigned char *input, unsigned int inputByteLen) { +void OQS_SHA3_sha3256(unsigned char *output, const unsigned char *input, unsigned int inputByteLen) { uint64_t s[25]; unsigned char t[SHA3_256_RATE]; int i; keccak_absorb(s, SHA3_256_RATE, input, inputByteLen, 0x06); - keccak_squeezeblocks(t, 1, s, SHA3_256_RATE); - for (i = 0; i < 32; i++) { + OQS_SHA3_keccak_squeezeblocks(t, 1, s, SHA3_256_RATE); + for (i = 0; i < 32; i++) output[i] = t[i]; - } } diff --git a/src/crypto/sha3/sha3.h b/src/crypto/sha3/sha3.h new file mode 100644 index 000000000..3bb19449d --- /dev/null +++ b/src/crypto/sha3/sha3.h @@ -0,0 +1,20 @@ +/** + * \file sha3.h + * \brief Header defining the API for OQS SHA3 + */ + +#ifndef __OQS_SHA3_H +#define __OQS_SHA3_H + +#define OQS_SHA3_STATESIZE 25 +#define OQS_SHA3_SHAKE128_RATE 168 +#define OQS_SHA3_SHA3_256_RATE 136 + +void OQS_SHA3_shake128_absorb(uint64_t *s, const unsigned char *input, unsigned int inputByteLen); +void OQS_SHA3_keccak_squeezeblocks(unsigned char *h, unsigned long long int nblocks, uint64_t *s, unsigned int r); +void OQS_SHA3_sha3256(unsigned char *output, const unsigned char *input, unsigned int inputByteLen); +void OQS_SHA3_shake128_squeezeblocks(unsigned char *output, unsigned long long nblocks, uint64_t *s); + +#endif + + diff --git a/src/kex_rlwe_msrln16/LatticeCrypto_kex.c b/src/kex_rlwe_msrln16/LatticeCrypto_kex.c index b05c010ca..d4c1c93a8 100644 --- a/src/kex_rlwe_msrln16/LatticeCrypto_kex.c +++ b/src/kex_rlwe_msrln16/LatticeCrypto_kex.c @@ -17,7 +17,7 @@ #include "LatticeCrypto_priv.h" #include "oqs/rand.h" -#include "external/shake128.h" +#include extern const int32_t psi_rev_ntt1024_12289[1024]; extern const int32_t omegainv_rev_ntt1024_12289[1024]; @@ -25,7 +25,6 @@ extern const int32_t omegainv10N_rev_ntt1024_12289; extern const int32_t Ninv11_ntt1024_12289; // import external code -#include "external/shake128.c" #ifdef RLWE_ASM_AVX2 #include "AMD64/consts.c" #include "AMD64/ntt_x64.c" @@ -296,10 +295,10 @@ CRYPTO_STATUS oqs_rlwe_msrln16_generate_a(uint32_t *a, const unsigned char *seed unsigned int pos = 0, ctr = 0; uint16_t val; unsigned int nblocks = 16; - uint8_t buf[SHAKE128_RATE * 16]; - unsigned char state[SHAKE128_STATE_SIZE] = { 0 }; - FIPS202_SHAKE128_Absorb(seed, OQS_RLWE_MSRLN16_SEED_BYTES, state, sizeof(state)); - FIPS202_SHAKE128_Squeeze(state, (unsigned char *)buf, nblocks * SHAKE128_RATE); + uint8_t buf[OQS_SHA3_SHAKE128_RATE * 16]; + uint64_t state[OQS_SHA3_STATESIZE]; + OQS_SHA3_shake128_absorb(state, seed, OQS_RLWE_MSRLN16_SEED_BYTES); + OQS_SHA3_shake128_squeezeblocks((unsigned char *)buf, nblocks, state); while (ctr < OQS_RLWE_MSRLN16_PARAMETER_N) { val = (buf[pos] | ((uint16_t)buf[pos + 1] << 8)) & 0x3fff; @@ -307,9 +306,9 @@ CRYPTO_STATUS oqs_rlwe_msrln16_generate_a(uint32_t *a, const unsigned char *seed a[ctr++] = val; } pos += 2; - if (pos > SHAKE128_RATE * nblocks - 2) { + if (pos > OQS_SHA3_SHAKE128_RATE * nblocks - 2) { nblocks = 1; - FIPS202_SHAKE128_Squeeze(state, (unsigned char *)buf, nblocks * SHAKE128_RATE); + OQS_SHA3_shake128_squeezeblocks((unsigned char *)buf, nblocks, state); pos = 0; } } diff --git a/src/kex_rlwe_msrln16/external/shake128.c b/src/kex_rlwe_msrln16/external/shake128.c deleted file mode 100644 index 53b9d0e09..000000000 --- a/src/kex_rlwe_msrln16/external/shake128.c +++ /dev/null @@ -1,332 +0,0 @@ -#if defined(WINDOWS) -#define UNUSED -#else -#define UNUSED __attribute__ ((unused)) -#endif - -/* -Original implementation modified to allow spliting the absorb and squeeze -phases of Keccak. -*/ - -/* -Implementation by the Keccak, Keyak and Ketje Teams, namely, Guido Bertoni, -Joan Daemen, Michaël Peeters, Gilles Van Assche and Ronny Van Keer, hereby -denoted as "the implementer". - -For more information, feedback or questions, please refer to our websites: -http://keccak.noekeon.org/ -http://keyak.noekeon.org/ -http://ketje.noekeon.org/ - -To the extent possible under law, the implementer has waived all copyright -and related or neighboring rights to the source code in this file. -http://creativecommons.org/publicdomain/zero/1.0/ -*/ - -/* -================================================================ -The purpose of this source file is to demonstrate a readable and compact -implementation of all the Keccak instances approved in the FIPS 202 standard, -including the hash functions and the extendable-output functions (XOFs). - -We focused on clarity and on source-code compactness, -rather than on the performance. - -The advantages of this implementation are: - + The source code is compact, after removing the comments, that is. :-) - + There are no tables with arbitrary constants. - + For clarity, the comments link the operations to the specifications using - the same notation as much as possible. - + There is no restriction in cryptographic features. In particular, - the SHAKE128 and SHAKE256 XOFs can produce any output length. - + The code does not use much RAM, as all operations are done in place. - -The drawbacks of this implementation are: - - There is no message queue. The whole message must be ready in a buffer. - - It is not optimized for peformance. - -The implementation is even simpler on a little endian platform. Just define the -LITTLE_ENDIAN symbol in that case. - -For a more complete set of implementations, please refer to -the Keccak Code Package at https://github.com/gvanas/KeccakCodePackage - -For more information, please refer to: - * [Keccak Reference] http://keccak.noekeon.org/Keccak-reference-3.0.pdf - * [Keccak Specifications Summary] http://keccak.noekeon.org/specs_summary.html - -This file uses UTF-8 encoding, as some comments use Greek letters. -================================================================ -*/ - -/** - * Function to compute the Keccak[r, c] sponge function over a given input. - * @param rate The value of the rate r. - * @param capacity The value of the capacity c. - * @param input Pointer to the input message. - * @param inputByteLen The number of input bytes provided in the input message. - * @param delimitedSuffix Bits that will be automatically appended to the end - * of the input message, as in domain separation. - * This is a byte containing from 0 to 7 bits - * These n bits must be in the least significant bit positions - * and must be delimited with a bit 1 at position n - * (counting from 0=LSB to 7=MSB) and followed by bits 0 - * from position n+1 to position 7. - * Some examples: - * - If no bits are to be appended, then @a delimitedSuffix must be 0x01. - * - If the 2-bit sequence 0,1 is to be appended (as for SHA3-*), @a delimitedSuffix must be 0x06. - * - If the 4-bit sequence 1,1,1,1 is to be appended (as for SHAKE*), @a delimitedSuffix must be 0x1F. - * - If the 7-bit sequence 1,1,0,1,0,0,0 is to be absorbed, @a delimitedSuffix must be 0x8B. - * @param output Pointer to the buffer where to store the output. - * @param outputByteLen The number of output bytes desired. - * @pre One must have r+c=1600 and the rate a multiple of 8 bits in this implementation. - */ -UNUSED static void Keccak(unsigned int rate, unsigned int capacity, const unsigned char *input, unsigned long long int inputByteLen, unsigned char delimitedSuffix, unsigned char *output, unsigned long long int outputByteLen); - -/* - * Performs the Keccak absorb phase. Same parameters as the Keccak function, but a SHAKE128_STATE_SIZE-byte state must also be provided. - * The Keccak_squeeze function can be called successively to generate output. - */ -static void Keccak_absorb(unsigned int rate, unsigned int capacity, const unsigned char *input, unsigned long long int inputByteLen, unsigned char delimitedSuffix, unsigned char* state, unsigned int stateLen); - -/* - * Performs the Keccak squeeze phase. Same parameters as the Keccak function, but a SHAKE128_STATE_SIZE-byte state must also be provided. - * The Keccak_absorb function must be called first. - */ -static void Keccak_squeeze(unsigned int rate, unsigned int capacity, unsigned char* state, unsigned char *output, unsigned long long int outputByteLen); - -static void FIPS202_SHAKE128_Absorb(const unsigned char *input, unsigned int inputByteLen, unsigned char* state, unsigned int stateLen) -{ - Keccak_absorb(1344, 256, input, inputByteLen, 0x1F, state, stateLen); -} - -static void FIPS202_SHAKE128_Squeeze(unsigned char* state, unsigned char *output, int outputByteLen) -{ - Keccak_squeeze(1344, 256, state, output, outputByteLen); -} - -UNUSED static void FIPS202_SHAKE128(const unsigned char *input, unsigned int inputByteLen, unsigned char *output, int outputByteLen, unsigned int stateLen) -{ - unsigned char state[200] = { 0 }; - FIPS202_SHAKE128_Absorb(input, inputByteLen, state, stateLen); - FIPS202_SHAKE128_Squeeze(state, output, outputByteLen); -} - -/* -================================================================ -Technicalities -================================================================ -*/ - -typedef unsigned char UINT8; -typedef unsigned long long int UINT64; -typedef UINT64 tKeccakLane; - -#ifndef LITTLE_ENDIAN -/** Function to load a 64-bit value using the little-endian (LE) convention. - * On a LE platform, this could be greatly simplified using a cast. - */ -static UINT64 load64(const UINT8 *x) -{ - int i; - UINT64 u=0; - - for(i=7; i>=0; --i) { - u <<= 8; - u |= x[i]; - } - return u; -} - -/** Function to store a 64-bit value using the little-endian (LE) convention. - * On a LE platform, this could be greatly simplified using a cast. - */ -static void store64(UINT8 *x, UINT64 u) -{ - unsigned int i; - - for(i=0; i<8; ++i) { - x[i] = u; - u >>= 8; - } -} - -/** Function to XOR into a 64-bit value using the little-endian (LE) convention. - * On a LE platform, this could be greatly simplified using a cast. - */ -static void xor64(UINT8 *x, UINT64 u) -{ - unsigned int i; - - for(i=0; i<8; ++i) { - x[i] ^= u; - u >>= 8; - } -} -#endif - -/* -================================================================ -A readable and compact implementation of the Keccak-f[1600] permutation. -================================================================ -*/ - -#define ROL64(a, offset) ((((UINT64)a) << offset) ^ (((UINT64)a) >> (64-offset))) -#define i(x, y) ((x)+5*(y)) - -#ifdef LITTLE_ENDIAN - #define readLane(x, y) (((tKeccakLane*)state)[i(x, y)]) - #define writeLane(x, y, lane) (((tKeccakLane*)state)[i(x, y)]) = (lane) - #define XORLane(x, y, lane) (((tKeccakLane*)state)[i(x, y)]) ^= (lane) -#else - #define readLane(x, y) load64((UINT8*)state+sizeof(tKeccakLane)*i(x, y)) - #define writeLane(x, y, lane) store64((UINT8*)state+sizeof(tKeccakLane)*i(x, y), lane) - #define XORLane(x, y, lane) xor64((UINT8*)state+sizeof(tKeccakLane)*i(x, y), lane) -#endif - -/** - * Function that computes the linear feedback shift register (LFSR) used to - * define the round constants (see [Keccak Reference, Section 1.2]). - */ -static int LFSR86540(UINT8 *LFSR) -{ - int result = ((*LFSR) & 0x01) != 0; - if (((*LFSR) & 0x80) != 0) - // Primitive polynomial over GF(2): x^8+x^6+x^5+x^4+1 - (*LFSR) = ((*LFSR) << 1) ^ 0x71; - else - (*LFSR) <<= 1; - return result; -} - -/** - * Function that computes the Keccak-f[1600] permutation on the given state. - */ -static void KeccakF1600_StatePermute(void *state) -{ - unsigned int round, x, y, j, t; - UINT8 LFSRstate = 0x01; - - for(round=0; round<24; round++) { - { // === θ step (see [Keccak Reference, Section 2.3.2]) === - tKeccakLane C[5], D; - - // Compute the parity of the columns - for(x=0; x<5; x++) - C[x] = readLane(x, 0) ^ readLane(x, 1) ^ readLane(x, 2) ^ readLane(x, 3) ^ readLane(x, 4); - for(x=0; x<5; x++) { - // Compute the θ effect for a given column - D = C[(x+4)%5] ^ ROL64(C[(x+1)%5], 1); - // Add the θ effect to the whole column - for (y=0; y<5; y++) - XORLane(x, y, D); - } - } - - { // === ρ and π steps (see [Keccak Reference, Sections 2.3.3 and 2.3.4]) === - tKeccakLane current, temp; - // Start at coordinates (1 0) - x = 1; y = 0; - current = readLane(x, y); - // Iterate over ((0 1)(2 3))^t * (1 0) for 0 ≤ t ≤ 23 - for(t=0; t<24; t++) { - // Compute the rotation constant r = (t+1)(t+2)/2 - unsigned int r = ((t+1)*(t+2)/2)%64; - // Compute ((0 1)(2 3)) * (x y) - unsigned int Y = (2*x+3*y)%5; x = y; y = Y; - // Swap current and state(x,y), and rotate - temp = readLane(x, y); - writeLane(x, y, ROL64(current, r)); - current = temp; - } - } - - { // === χ step (see [Keccak Reference, Section 2.3.1]) === - tKeccakLane temp[5]; - for(y=0; y<5; y++) { - // Take a copy of the plane - for(x=0; x<5; x++) - temp[x] = readLane(x, y); - // Compute χ on the plane - for(x=0; x<5; x++) - writeLane(x, y, temp[x] ^((~temp[(x+1)%5]) & temp[(x+2)%5])); - } - } - - { // === ι step (see [Keccak Reference, Section 2.3.5]) === - for(j=0; j<7; j++) { - unsigned int bitPosition = (1< -#define MIN(a, b) ((a) < (b) ? (a) : (b)) - -void Keccak_absorb(unsigned int rate, unsigned int capacity, const unsigned char *input, unsigned long long int inputByteLen, unsigned char delimitedSuffix, unsigned char* state, unsigned int stateLen) -{ - unsigned int rateInBytes = rate/8; - unsigned int blockSize = 0; - unsigned int i; - - if (((rate + capacity) != 1600) || ((rate % 8) != 0)) - return; - - // === Initialize the state === - memset(state, 0, stateLen); - - // === Absorb all the input blocks === - while(inputByteLen > 0) { - blockSize = MIN(inputByteLen, rateInBytes); - for(i=0; i 0) { - blockSize = MIN(outputByteLen, rateInBytes); - memcpy(output, state, blockSize); - output += blockSize; - outputByteLen -= blockSize; - - if (outputByteLen > 0) - KeccakF1600_StatePermute(state); - } -} diff --git a/src/kex_rlwe_msrln16/external/shake128.h b/src/kex_rlwe_msrln16/external/shake128.h deleted file mode 100644 index 8181e7266..000000000 --- a/src/kex_rlwe_msrln16/external/shake128.h +++ /dev/null @@ -1,24 +0,0 @@ -#ifndef SHAKE128_H -#define SHAKE128_H - -#define SHAKE128_STATE_SIZE 200 -#define SHAKE128_RATE 168 - -/* - * Computes SHAKE128 on the array "input" of length "inputByteLen", resulting in "outputByteLen" bytes stored in "output". - */ -static void FIPS202_SHAKE128(const unsigned char *input, unsigned int inputByteLen, unsigned char *output, int outputByteLen, unsigned int stateLen); - -/* - * Performs the absorb phase of SHAKE128: ingests the "inputByteLen" bytes stored in "input"; storing the internal - * SHAKE128 state of length SHAKE128_STATE_SIZE in "state". - */ -static void FIPS202_SHAKE128_Absorb(const unsigned char *input, unsigned int inputByteLen, unsigned char* state, unsigned int stateLen); - -/* - * Performs the squeeze phase of SHAKE128: generates "outputByteLen" bytes stored in "output" from the "state" of length - * SHAKE128_STATE_SIZE. Must be preceeded by a call to FIPS202_SHAKE128_Absorb. - */ -static void FIPS202_SHAKE128_Squeeze(unsigned char* state, unsigned char *output, int outputByteLen); - -#endif diff --git a/src/kex_rlwe_newhope/newhope.c b/src/kex_rlwe_newhope/newhope.c index 08c8775e9..ff1db103b 100644 --- a/src/kex_rlwe_newhope/newhope.c +++ b/src/kex_rlwe_newhope/newhope.c @@ -1,6 +1,8 @@ #include + +#include + #include "precomp.c" -#include "fips202.c" #include "poly.c" static void encode_a(unsigned char *r, const poly *pk, const unsigned char *seed) { @@ -94,7 +96,7 @@ static void sharedb(unsigned char *sharedkey, unsigned char *send, const unsigne rec(sharedkey, &v, &c); #ifndef STATISTICAL_TEST - sha3256(sharedkey, sharedkey, 32); + OQS_SHA3_sha3256(sharedkey, sharedkey, 32); #endif } @@ -110,6 +112,6 @@ static void shareda(unsigned char *sharedkey, const poly *sk, const unsigned cha rec(sharedkey, &v, &c); #ifndef STATISTICAL_TEST - sha3256(sharedkey, sharedkey, 32); + OQS_SHA3_sha3256(sharedkey, sharedkey, 32); #endif } diff --git a/src/kex_rlwe_newhope/poly.c b/src/kex_rlwe_newhope/poly.c index af80fd5ee..170cdefbb 100644 --- a/src/kex_rlwe_newhope/poly.c +++ b/src/kex_rlwe_newhope/poly.c @@ -142,13 +142,13 @@ static void poly_tobytes(unsigned char *r, const poly *p) { static void poly_uniform(poly *a, const unsigned char *seed) { unsigned int pos = 0, ctr = 0; uint16_t val; - uint64_t state[25]; + uint64_t state[OQS_SHA3_STATESIZE]; unsigned int nblocks = 16; - uint8_t buf[2688]; // SHAKE128_RATE * nblocks + uint8_t buf[OQS_SHA3_SHAKE128_RATE * 16]; - shake128_absorb(state, seed, NEWHOPE_SEEDBYTES); + OQS_SHA3_shake128_absorb(state, seed, NEWHOPE_SEEDBYTES); - shake128_squeezeblocks((unsigned char *) buf, nblocks, state); + OQS_SHA3_shake128_squeezeblocks((unsigned char *) buf, nblocks, state); while (ctr < PARAM_N) { val = (buf[pos] | ((uint16_t) buf[pos + 1] << 8)) & 0x3fff; // Specialized for q = 12889 @@ -156,9 +156,9 @@ static void poly_uniform(poly *a, const unsigned char *seed) { a->coeffs[ctr++] = val; } pos += 2; - if (pos > SHAKE128_RATE * nblocks - 2) { + if (pos > OQS_SHA3_SHAKE128_RATE * nblocks - 2) { nblocks = 1; - shake128_squeezeblocks((unsigned char *) buf, nblocks, state); + OQS_SHA3_shake128_squeezeblocks((unsigned char *) buf, nblocks, state); pos = 0; } }