mirror of
https://github.com/open-quantum-safe/liboqs.git
synced 2025-11-22 00:09:23 -05:00
commit
b7c3e86cb9
41
Makefile
41
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
|
||||
|
||||
@ -6,7 +6,7 @@
|
||||
|
||||
#include "aes.h"
|
||||
#include "aes_local.h"
|
||||
#include "../ds_benchmark.h"
|
||||
#include "../../ds_benchmark.h"
|
||||
|
||||
#define BENCH_DURATION 1
|
||||
|
||||
@ -7,9 +7,10 @@
|
||||
|
||||
#include <stdint.h>
|
||||
#include <assert.h>
|
||||
#include <oqs/sha3.h>
|
||||
|
||||
#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];
|
||||
}
|
||||
}
|
||||
20
src/crypto/sha3/sha3.h
Normal file
20
src/crypto/sha3/sha3.h
Normal file
@ -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
|
||||
|
||||
|
||||
@ -17,7 +17,7 @@
|
||||
|
||||
#include "LatticeCrypto_priv.h"
|
||||
#include "oqs/rand.h"
|
||||
#include "external/shake128.h"
|
||||
#include <oqs/sha3.h>
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
332
src/kex_rlwe_msrln16/external/shake128.c
vendored
332
src/kex_rlwe_msrln16/external/shake128.c
vendored
@ -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 <i>n</i> bits must be in the least significant bit positions
|
||||
* and must be delimited with a bit 1 at position <i>n</i>
|
||||
* (counting from 0=LSB to 7=MSB) and followed by bits 0
|
||||
* from position <i>n</i>+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<<j)-1; //2^j-1
|
||||
if (LFSR86540(&LFSRstate))
|
||||
XORLane(0, 0, (tKeccakLane)1<<bitPosition);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
================================================================
|
||||
A readable and compact implementation of the Keccak sponge functions
|
||||
that use the Keccak-f[1600] permutation.
|
||||
================================================================
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
#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<blockSize; i++)
|
||||
state[i] ^= input[i];
|
||||
input += blockSize;
|
||||
inputByteLen -= blockSize;
|
||||
|
||||
if (blockSize == rateInBytes) {
|
||||
KeccakF1600_StatePermute(state);
|
||||
blockSize = 0;
|
||||
}
|
||||
}
|
||||
|
||||
// === Do the padding and switch to the squeezing phase ===
|
||||
// Absorb the last few bits and add the first bit of padding (which coincides with the delimiter in delimitedSuffix)
|
||||
state[blockSize] ^= delimitedSuffix;
|
||||
// If the first bit of padding is at position rate-1, we need a whole new block for the second bit of padding
|
||||
if (((delimitedSuffix & 0x80) != 0) && (blockSize == (rateInBytes-1)))
|
||||
KeccakF1600_StatePermute(state);
|
||||
// Add the second bit of padding
|
||||
state[rateInBytes-1] ^= 0x80;
|
||||
}
|
||||
|
||||
|
||||
void Keccak_squeeze(unsigned int rate, UNUSED unsigned int capacity, unsigned char* state, unsigned char *output, unsigned long long int outputByteLen)
|
||||
{
|
||||
unsigned int blockSize = 0;
|
||||
unsigned int rateInBytes = rate / 8;
|
||||
|
||||
// Switch to the squeezing phase
|
||||
KeccakF1600_StatePermute(state);
|
||||
|
||||
// === Squeeze out all the output blocks ===
|
||||
while (outputByteLen > 0) {
|
||||
blockSize = MIN(outputByteLen, rateInBytes);
|
||||
memcpy(output, state, blockSize);
|
||||
output += blockSize;
|
||||
outputByteLen -= blockSize;
|
||||
|
||||
if (outputByteLen > 0)
|
||||
KeccakF1600_StatePermute(state);
|
||||
}
|
||||
}
|
||||
24
src/kex_rlwe_msrln16/external/shake128.h
vendored
24
src/kex_rlwe_msrln16/external/shake128.h
vendored
@ -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
|
||||
@ -1,6 +1,8 @@
|
||||
#include <stdint.h>
|
||||
|
||||
#include <oqs/sha3.h>
|
||||
|
||||
#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
|
||||
}
|
||||
|
||||
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user