mirror of
https://github.com/open-quantum-safe/liboqs.git
synced 2025-11-27 00:04:24 -05:00
Switch SHA-3 to same implementation as in PQClean
This commit is contained in:
parent
eda92b0b4a
commit
d9747e398e
@ -91,10 +91,8 @@ test: clean-tests check
|
||||
tests/example_sig
|
||||
tests/test_kem
|
||||
tests/test_sig
|
||||
if !ENABLE_SHARED
|
||||
tests/test_aes
|
||||
tests/test_sha3
|
||||
endif
|
||||
|
||||
kat: clean-kats check
|
||||
tests/kat_kem
|
||||
|
||||
@ -106,7 +106,7 @@
|
||||
<ClCompile Include="..\..\src\crypto\aes\aes.c" />
|
||||
<ClCompile Include="..\..\src\crypto\aes\aes_c.c" />
|
||||
<ClCompile Include="..\..\src\crypto\aes\aes_ni.c" />
|
||||
<ClCompile Include="..\..\src\crypto\sha3\sha3.c" />
|
||||
<ClCompile Include="..\..\src\crypto\sha3\sha3_c.c" />
|
||||
<!-- OQS_COPY_FROM_PQCLEAN_FRAGMENT_CLCOMPILE_START -->
|
||||
<ClCompile Include="..\..\src\kem\kyber\kem_kyber_512.c" />
|
||||
<ClCompile Include="..\..\src\kem\kyber\pqclean_kyber512_clean\cbd.c" />
|
||||
|
||||
@ -16,7 +16,7 @@
|
||||
<ClCompile Include="..\..\src\crypto\aes\aes_ni.c">
|
||||
<Filter>crypto</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\src\crypto\sha3\sha3.c">
|
||||
<ClCompile Include="..\..\src\crypto\sha3\sha3_c.c">
|
||||
<Filter>crypto</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\src\sig\sig.c">
|
||||
|
||||
@ -3,46 +3,34 @@
|
||||
|
||||
#include <oqs/sha3.h>
|
||||
|
||||
typedef struct {
|
||||
uint64_t ctx[25];
|
||||
} shake128ctx;
|
||||
|
||||
typedef struct {
|
||||
uint64_t ctx[25];
|
||||
} shake256ctx;
|
||||
|
||||
#define SHAKE128_RATE OQS_SHA3_SHAKE128_RATE
|
||||
#define SHAKE256_RATE OQS_SHA3_SHAKE256_RATE
|
||||
#define SHA3_256_RATE OQS_SHA3_SHA3_256_RATE
|
||||
#define SHA3_512_RATE OQS_SHA3_SHA3_512_RATE
|
||||
|
||||
#define shake128_absorb(state, input, inlen) OQS_SHA3_shake128_absorb((state)->ctx, (input), (inlen))
|
||||
#define shake128_squeezeblocks(output, nblocks, state) OQS_SHA3_shake128_squeezeblocks((output), (nblocks), (state)->ctx)
|
||||
#define shake128 OQS_SHA3_shake128
|
||||
#define shake128ctx OQS_SHA3_shake128_ctx
|
||||
#define shake128_absorb OQS_SHA3_shake128_absorb
|
||||
#define shake128_squeezeblocks OQS_SHA3_shake128_squeezeblocks
|
||||
|
||||
#define shake256_absorb(state, input, inlen) OQS_SHA3_shake256_absorb((state)->ctx, (input), (inlen))
|
||||
#define shake256_squeezeblocks(output, nblocks, state) OQS_SHA3_shake256_squeezeblocks((output), (nblocks), (state)->ctx)
|
||||
#define SHAKE256_RATE OQS_SHA3_SHAKE256_RATE
|
||||
#define shake256 OQS_SHA3_shake256
|
||||
#define shake256ctx OQS_SHA3_shake256_ctx
|
||||
#define shake256_absorb OQS_SHA3_shake256_absorb
|
||||
#define shake256_squeezeblocks OQS_SHA3_shake256_squeezeblocks
|
||||
|
||||
#define sha3_256 OQS_SHA3_sha3256
|
||||
#define sha3_512 OQS_SHA3_sha3512
|
||||
#define SHA3_256_RATE OQS_SHA3_SHA3_256_RATE
|
||||
#define sha3_256 OQS_SHA3_sha3_256
|
||||
|
||||
typedef struct {
|
||||
uint64_t ctx[26];
|
||||
} shake128incctx;
|
||||
#define SHA3_512_RATE OQS_SHA3_SHA3_512_RATE
|
||||
#define sha3_512 OQS_SHA3_sha3_512
|
||||
|
||||
typedef struct {
|
||||
uint64_t ctx[26];
|
||||
} shake256incctx;
|
||||
#define shake128incctx OQS_SHA3_shake128_inc_ctx
|
||||
#define shake128_inc_init OQS_SHA3_shake128_inc_init
|
||||
#define shake128_inc_absorb OQS_SHA3_shake128_inc_absorb
|
||||
#define shake128_inc_finalize OQS_SHA3_shake128_inc_finalize
|
||||
#define shake128_inc_squeeze OQS_SHA3_shake128_inc_squeeze
|
||||
|
||||
#define shake128_inc_init(state) OQS_SHA3_shake128_inc_init((state)->ctx)
|
||||
#define shake128_inc_absorb(state, input, inlen) OQS_SHA3_shake128_inc_absorb((state)->ctx, (input), (inlen))
|
||||
#define shake128_inc_finalize(state) OQS_SHA3_shake128_inc_finalize((state)->ctx)
|
||||
#define shake128_inc_squeeze(output, outlen, state) OQS_SHA3_shake128_inc_squeeze((output), (outlen), (state)->ctx)
|
||||
|
||||
#define shake256_inc_init(state) OQS_SHA3_shake256_inc_init((state)->ctx)
|
||||
#define shake256_inc_absorb(state, input, inlen) OQS_SHA3_shake256_inc_absorb((state)->ctx, (input), (inlen))
|
||||
#define shake256_inc_finalize(state) OQS_SHA3_shake256_inc_finalize((state)->ctx)
|
||||
#define shake256_inc_squeeze(output, outlen, state) OQS_SHA3_shake256_inc_squeeze((output), (outlen), (state)->ctx)
|
||||
#define shake256incctx OQS_SHA3_shake256_inc_ctx
|
||||
#define shake256_inc_init OQS_SHA3_shake256_inc_init
|
||||
#define shake256_inc_absorb OQS_SHA3_shake256_inc_absorb
|
||||
#define shake256_inc_finalize OQS_SHA3_shake256_inc_finalize
|
||||
#define shake256_inc_squeeze OQS_SHA3_shake256_inc_squeeze
|
||||
|
||||
#endif
|
||||
|
||||
@ -1,4 +1,6 @@
|
||||
AUTOMAKE_OPTIONS = foreign
|
||||
noinst_LTLIBRARIES = libsha3.la
|
||||
libsha3_la_SOURCES = sha3.c
|
||||
|
||||
libsha3_la_SOURCES = sha3_c.c
|
||||
|
||||
sha3_c.c: fips202.c sp800-185.c
|
||||
|
||||
803
src/crypto/sha3/fips202.c
Normal file
803
src/crypto/sha3/fips202.c
Normal file
@ -0,0 +1,803 @@
|
||||
/* Based on the public domain implementation in
|
||||
* crypto_hash/keccakc512/simple/ from http://bench.cr.yp.to/supercop.html
|
||||
* by Ronny Van Keer
|
||||
* and the public domain "TweetFips202" implementation
|
||||
* from https://twitter.com/tweetfips202
|
||||
* by Gilles Van Assche, Daniel J. Bernstein, and Peter Schwabe */
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#define NROUNDS 24
|
||||
#define ROL(a, offset) (((a) << (offset)) ^ ((a) >> (64 - (offset))))
|
||||
|
||||
/*************************************************
|
||||
* Name: load64
|
||||
*
|
||||
* Description: Load 8 bytes into uint64_t in little-endian order
|
||||
*
|
||||
* Arguments: - const uint8_t *x: pointer to input byte array
|
||||
*
|
||||
* Returns the loaded 64-bit unsigned integer
|
||||
**************************************************/
|
||||
static uint64_t load64(const uint8_t *x) {
|
||||
uint64_t r = 0;
|
||||
for (size_t i = 0; i < 8; ++i) {
|
||||
r |= (uint64_t)x[i] << 8 * i;
|
||||
}
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
/*************************************************
|
||||
* Name: store64
|
||||
*
|
||||
* Description: Store a 64-bit integer to a byte array in little-endian order
|
||||
*
|
||||
* Arguments: - uint8_t *x: pointer to the output byte array
|
||||
* - uint64_t u: input 64-bit unsigned integer
|
||||
**************************************************/
|
||||
static void store64(uint8_t *x, uint64_t u) {
|
||||
for (size_t i = 0; i < 8; ++i) {
|
||||
x[i] = (uint8_t) (u >> 8 * i);
|
||||
}
|
||||
}
|
||||
|
||||
/* Keccak round constants */
|
||||
static const uint64_t KeccakF_RoundConstants[NROUNDS] = {
|
||||
0x0000000000000001ULL, 0x0000000000008082ULL,
|
||||
0x800000000000808aULL, 0x8000000080008000ULL,
|
||||
0x000000000000808bULL, 0x0000000080000001ULL,
|
||||
0x8000000080008081ULL, 0x8000000000008009ULL,
|
||||
0x000000000000008aULL, 0x0000000000000088ULL,
|
||||
0x0000000080008009ULL, 0x000000008000000aULL,
|
||||
0x000000008000808bULL, 0x800000000000008bULL,
|
||||
0x8000000000008089ULL, 0x8000000000008003ULL,
|
||||
0x8000000000008002ULL, 0x8000000000000080ULL,
|
||||
0x000000000000800aULL, 0x800000008000000aULL,
|
||||
0x8000000080008081ULL, 0x8000000000008080ULL,
|
||||
0x0000000080000001ULL, 0x8000000080008008ULL
|
||||
};
|
||||
|
||||
/*************************************************
|
||||
* Name: KeccakF1600_StatePermute
|
||||
*
|
||||
* Description: The Keccak F1600 Permutation
|
||||
*
|
||||
* Arguments: - uint64_t *state: pointer to input/output Keccak state
|
||||
**************************************************/
|
||||
static void KeccakF1600_StatePermute(uint64_t *state) {
|
||||
int round;
|
||||
|
||||
uint64_t Aba, Abe, Abi, Abo, Abu;
|
||||
uint64_t Aga, Age, Agi, Ago, Agu;
|
||||
uint64_t Aka, Ake, Aki, Ako, Aku;
|
||||
uint64_t Ama, Ame, Ami, Amo, Amu;
|
||||
uint64_t Asa, Ase, Asi, Aso, Asu;
|
||||
uint64_t BCa, BCe, BCi, BCo, BCu;
|
||||
uint64_t Da, De, Di, Do, Du;
|
||||
uint64_t Eba, Ebe, Ebi, Ebo, Ebu;
|
||||
uint64_t Ega, Ege, Egi, Ego, Egu;
|
||||
uint64_t Eka, Eke, Eki, Eko, Eku;
|
||||
uint64_t Ema, Eme, Emi, Emo, Emu;
|
||||
uint64_t Esa, Ese, Esi, Eso, Esu;
|
||||
|
||||
// copyFromState(A, state)
|
||||
Aba = state[0];
|
||||
Abe = state[1];
|
||||
Abi = state[2];
|
||||
Abo = state[3];
|
||||
Abu = state[4];
|
||||
Aga = state[5];
|
||||
Age = state[6];
|
||||
Agi = state[7];
|
||||
Ago = state[8];
|
||||
Agu = state[9];
|
||||
Aka = state[10];
|
||||
Ake = state[11];
|
||||
Aki = state[12];
|
||||
Ako = state[13];
|
||||
Aku = state[14];
|
||||
Ama = state[15];
|
||||
Ame = state[16];
|
||||
Ami = state[17];
|
||||
Amo = state[18];
|
||||
Amu = state[19];
|
||||
Asa = state[20];
|
||||
Ase = state[21];
|
||||
Asi = state[22];
|
||||
Aso = state[23];
|
||||
Asu = state[24];
|
||||
|
||||
for (round = 0; round < NROUNDS; round += 2) {
|
||||
// prepareTheta
|
||||
BCa = Aba ^ Aga ^ Aka ^ Ama ^ Asa;
|
||||
BCe = Abe ^ Age ^ Ake ^ Ame ^ Ase;
|
||||
BCi = Abi ^ Agi ^ Aki ^ Ami ^ Asi;
|
||||
BCo = Abo ^ Ago ^ Ako ^ Amo ^ Aso;
|
||||
BCu = Abu ^ Agu ^ Aku ^ Amu ^ Asu;
|
||||
|
||||
// thetaRhoPiChiIotaPrepareTheta(round , A, E)
|
||||
Da = BCu ^ ROL(BCe, 1);
|
||||
De = BCa ^ ROL(BCi, 1);
|
||||
Di = BCe ^ ROL(BCo, 1);
|
||||
Do = BCi ^ ROL(BCu, 1);
|
||||
Du = BCo ^ ROL(BCa, 1);
|
||||
|
||||
Aba ^= Da;
|
||||
BCa = Aba;
|
||||
Age ^= De;
|
||||
BCe = ROL(Age, 44);
|
||||
Aki ^= Di;
|
||||
BCi = ROL(Aki, 43);
|
||||
Amo ^= Do;
|
||||
BCo = ROL(Amo, 21);
|
||||
Asu ^= Du;
|
||||
BCu = ROL(Asu, 14);
|
||||
Eba = BCa ^ ((~BCe) & BCi);
|
||||
Eba ^= KeccakF_RoundConstants[round];
|
||||
Ebe = BCe ^ ((~BCi) & BCo);
|
||||
Ebi = BCi ^ ((~BCo) & BCu);
|
||||
Ebo = BCo ^ ((~BCu) & BCa);
|
||||
Ebu = BCu ^ ((~BCa) & BCe);
|
||||
|
||||
Abo ^= Do;
|
||||
BCa = ROL(Abo, 28);
|
||||
Agu ^= Du;
|
||||
BCe = ROL(Agu, 20);
|
||||
Aka ^= Da;
|
||||
BCi = ROL(Aka, 3);
|
||||
Ame ^= De;
|
||||
BCo = ROL(Ame, 45);
|
||||
Asi ^= Di;
|
||||
BCu = ROL(Asi, 61);
|
||||
Ega = BCa ^ ((~BCe) & BCi);
|
||||
Ege = BCe ^ ((~BCi) & BCo);
|
||||
Egi = BCi ^ ((~BCo) & BCu);
|
||||
Ego = BCo ^ ((~BCu) & BCa);
|
||||
Egu = BCu ^ ((~BCa) & BCe);
|
||||
|
||||
Abe ^= De;
|
||||
BCa = ROL(Abe, 1);
|
||||
Agi ^= Di;
|
||||
BCe = ROL(Agi, 6);
|
||||
Ako ^= Do;
|
||||
BCi = ROL(Ako, 25);
|
||||
Amu ^= Du;
|
||||
BCo = ROL(Amu, 8);
|
||||
Asa ^= Da;
|
||||
BCu = ROL(Asa, 18);
|
||||
Eka = BCa ^ ((~BCe) & BCi);
|
||||
Eke = BCe ^ ((~BCi) & BCo);
|
||||
Eki = BCi ^ ((~BCo) & BCu);
|
||||
Eko = BCo ^ ((~BCu) & BCa);
|
||||
Eku = BCu ^ ((~BCa) & BCe);
|
||||
|
||||
Abu ^= Du;
|
||||
BCa = ROL(Abu, 27);
|
||||
Aga ^= Da;
|
||||
BCe = ROL(Aga, 36);
|
||||
Ake ^= De;
|
||||
BCi = ROL(Ake, 10);
|
||||
Ami ^= Di;
|
||||
BCo = ROL(Ami, 15);
|
||||
Aso ^= Do;
|
||||
BCu = ROL(Aso, 56);
|
||||
Ema = BCa ^ ((~BCe) & BCi);
|
||||
Eme = BCe ^ ((~BCi) & BCo);
|
||||
Emi = BCi ^ ((~BCo) & BCu);
|
||||
Emo = BCo ^ ((~BCu) & BCa);
|
||||
Emu = BCu ^ ((~BCa) & BCe);
|
||||
|
||||
Abi ^= Di;
|
||||
BCa = ROL(Abi, 62);
|
||||
Ago ^= Do;
|
||||
BCe = ROL(Ago, 55);
|
||||
Aku ^= Du;
|
||||
BCi = ROL(Aku, 39);
|
||||
Ama ^= Da;
|
||||
BCo = ROL(Ama, 41);
|
||||
Ase ^= De;
|
||||
BCu = ROL(Ase, 2);
|
||||
Esa = BCa ^ ((~BCe) & BCi);
|
||||
Ese = BCe ^ ((~BCi) & BCo);
|
||||
Esi = BCi ^ ((~BCo) & BCu);
|
||||
Eso = BCo ^ ((~BCu) & BCa);
|
||||
Esu = BCu ^ ((~BCa) & BCe);
|
||||
|
||||
// prepareTheta
|
||||
BCa = Eba ^ Ega ^ Eka ^ Ema ^ Esa;
|
||||
BCe = Ebe ^ Ege ^ Eke ^ Eme ^ Ese;
|
||||
BCi = Ebi ^ Egi ^ Eki ^ Emi ^ Esi;
|
||||
BCo = Ebo ^ Ego ^ Eko ^ Emo ^ Eso;
|
||||
BCu = Ebu ^ Egu ^ Eku ^ Emu ^ Esu;
|
||||
|
||||
// thetaRhoPiChiIotaPrepareTheta(round+1, E, A)
|
||||
Da = BCu ^ ROL(BCe, 1);
|
||||
De = BCa ^ ROL(BCi, 1);
|
||||
Di = BCe ^ ROL(BCo, 1);
|
||||
Do = BCi ^ ROL(BCu, 1);
|
||||
Du = BCo ^ ROL(BCa, 1);
|
||||
|
||||
Eba ^= Da;
|
||||
BCa = Eba;
|
||||
Ege ^= De;
|
||||
BCe = ROL(Ege, 44);
|
||||
Eki ^= Di;
|
||||
BCi = ROL(Eki, 43);
|
||||
Emo ^= Do;
|
||||
BCo = ROL(Emo, 21);
|
||||
Esu ^= Du;
|
||||
BCu = ROL(Esu, 14);
|
||||
Aba = BCa ^ ((~BCe) & BCi);
|
||||
Aba ^= KeccakF_RoundConstants[round + 1];
|
||||
Abe = BCe ^ ((~BCi) & BCo);
|
||||
Abi = BCi ^ ((~BCo) & BCu);
|
||||
Abo = BCo ^ ((~BCu) & BCa);
|
||||
Abu = BCu ^ ((~BCa) & BCe);
|
||||
|
||||
Ebo ^= Do;
|
||||
BCa = ROL(Ebo, 28);
|
||||
Egu ^= Du;
|
||||
BCe = ROL(Egu, 20);
|
||||
Eka ^= Da;
|
||||
BCi = ROL(Eka, 3);
|
||||
Eme ^= De;
|
||||
BCo = ROL(Eme, 45);
|
||||
Esi ^= Di;
|
||||
BCu = ROL(Esi, 61);
|
||||
Aga = BCa ^ ((~BCe) & BCi);
|
||||
Age = BCe ^ ((~BCi) & BCo);
|
||||
Agi = BCi ^ ((~BCo) & BCu);
|
||||
Ago = BCo ^ ((~BCu) & BCa);
|
||||
Agu = BCu ^ ((~BCa) & BCe);
|
||||
|
||||
Ebe ^= De;
|
||||
BCa = ROL(Ebe, 1);
|
||||
Egi ^= Di;
|
||||
BCe = ROL(Egi, 6);
|
||||
Eko ^= Do;
|
||||
BCi = ROL(Eko, 25);
|
||||
Emu ^= Du;
|
||||
BCo = ROL(Emu, 8);
|
||||
Esa ^= Da;
|
||||
BCu = ROL(Esa, 18);
|
||||
Aka = BCa ^ ((~BCe) & BCi);
|
||||
Ake = BCe ^ ((~BCi) & BCo);
|
||||
Aki = BCi ^ ((~BCo) & BCu);
|
||||
Ako = BCo ^ ((~BCu) & BCa);
|
||||
Aku = BCu ^ ((~BCa) & BCe);
|
||||
|
||||
Ebu ^= Du;
|
||||
BCa = ROL(Ebu, 27);
|
||||
Ega ^= Da;
|
||||
BCe = ROL(Ega, 36);
|
||||
Eke ^= De;
|
||||
BCi = ROL(Eke, 10);
|
||||
Emi ^= Di;
|
||||
BCo = ROL(Emi, 15);
|
||||
Eso ^= Do;
|
||||
BCu = ROL(Eso, 56);
|
||||
Ama = BCa ^ ((~BCe) & BCi);
|
||||
Ame = BCe ^ ((~BCi) & BCo);
|
||||
Ami = BCi ^ ((~BCo) & BCu);
|
||||
Amo = BCo ^ ((~BCu) & BCa);
|
||||
Amu = BCu ^ ((~BCa) & BCe);
|
||||
|
||||
Ebi ^= Di;
|
||||
BCa = ROL(Ebi, 62);
|
||||
Ego ^= Do;
|
||||
BCe = ROL(Ego, 55);
|
||||
Eku ^= Du;
|
||||
BCi = ROL(Eku, 39);
|
||||
Ema ^= Da;
|
||||
BCo = ROL(Ema, 41);
|
||||
Ese ^= De;
|
||||
BCu = ROL(Ese, 2);
|
||||
Asa = BCa ^ ((~BCe) & BCi);
|
||||
Ase = BCe ^ ((~BCi) & BCo);
|
||||
Asi = BCi ^ ((~BCo) & BCu);
|
||||
Aso = BCo ^ ((~BCu) & BCa);
|
||||
Asu = BCu ^ ((~BCa) & BCe);
|
||||
}
|
||||
|
||||
// copyToState(state, A)
|
||||
state[0] = Aba;
|
||||
state[1] = Abe;
|
||||
state[2] = Abi;
|
||||
state[3] = Abo;
|
||||
state[4] = Abu;
|
||||
state[5] = Aga;
|
||||
state[6] = Age;
|
||||
state[7] = Agi;
|
||||
state[8] = Ago;
|
||||
state[9] = Agu;
|
||||
state[10] = Aka;
|
||||
state[11] = Ake;
|
||||
state[12] = Aki;
|
||||
state[13] = Ako;
|
||||
state[14] = Aku;
|
||||
state[15] = Ama;
|
||||
state[16] = Ame;
|
||||
state[17] = Ami;
|
||||
state[18] = Amo;
|
||||
state[19] = Amu;
|
||||
state[20] = Asa;
|
||||
state[21] = Ase;
|
||||
state[22] = Asi;
|
||||
state[23] = Aso;
|
||||
state[24] = Asu;
|
||||
}
|
||||
|
||||
/*************************************************
|
||||
* Name: keccak_absorb
|
||||
*
|
||||
* Description: Absorb step of Keccak;
|
||||
* non-incremental, starts by zeroeing the state.
|
||||
*
|
||||
* Arguments: - uint64_t *s: pointer to (uninitialized) output Keccak state
|
||||
* - uint32_t r: rate in bytes (e.g., 168 for SHAKE128)
|
||||
* - const uint8_t *m: pointer to input to be absorbed into s
|
||||
* - size_t mlen: length of input in bytes
|
||||
* - uint8_t p: domain-separation byte for different
|
||||
* Keccak-derived functions
|
||||
**************************************************/
|
||||
static void keccak_absorb(uint64_t *s, uint32_t r, const uint8_t *m,
|
||||
size_t mlen, uint8_t p) {
|
||||
size_t i;
|
||||
uint8_t t[200];
|
||||
|
||||
/* Zero state */
|
||||
for (i = 0; i < 25; ++i) {
|
||||
s[i] = 0;
|
||||
}
|
||||
|
||||
while (mlen >= r) {
|
||||
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) {
|
||||
t[i] = 0;
|
||||
}
|
||||
for (i = 0; i < mlen; ++i) {
|
||||
t[i] = m[i];
|
||||
}
|
||||
t[i] = p;
|
||||
t[r - 1] |= 128;
|
||||
for (i = 0; i < r / 8; ++i) {
|
||||
s[i] ^= load64(t + 8 * i);
|
||||
}
|
||||
}
|
||||
|
||||
/*************************************************
|
||||
* Name: keccak_squeezeblocks
|
||||
*
|
||||
* Description: Squeeze step of Keccak. Squeezes full blocks of r bytes each.
|
||||
* Modifies the state. Can be called multiple times to keep
|
||||
* squeezing, i.e., is incremental.
|
||||
*
|
||||
* Arguments: - uint8_t *h: pointer to output blocks
|
||||
* - size_t nblocks: number of blocks to be
|
||||
* squeezed (written to h)
|
||||
* - uint64_t *s: pointer to input/output Keccak state
|
||||
* - uint32_t r: rate in bytes (e.g., 168 for SHAKE128)
|
||||
**************************************************/
|
||||
static void keccak_squeezeblocks(uint8_t *h, size_t nblocks,
|
||||
uint64_t *s, uint32_t r) {
|
||||
while (nblocks > 0) {
|
||||
KeccakF1600_StatePermute(s);
|
||||
for (size_t i = 0; i < (r >> 3); i++) {
|
||||
store64(h + 8 * i, s[i]);
|
||||
}
|
||||
h += r;
|
||||
nblocks--;
|
||||
}
|
||||
}
|
||||
|
||||
/*************************************************
|
||||
* Name: keccak_inc_init
|
||||
*
|
||||
* Description: Initializes the incremental Keccak state to zero.
|
||||
*
|
||||
* Arguments: - uint64_t *s_inc: pointer to input/output incremental state
|
||||
* First 25 values represent Keccak state.
|
||||
* 26th value represents either the number of absorbed bytes
|
||||
* that have not been permuted, or not-yet-squeezed bytes.
|
||||
**************************************************/
|
||||
static void keccak_inc_init(uint64_t *s_inc) {
|
||||
size_t i;
|
||||
|
||||
for (i = 0; i < 25; ++i) {
|
||||
s_inc[i] = 0;
|
||||
}
|
||||
s_inc[25] = 0;
|
||||
}
|
||||
|
||||
/*************************************************
|
||||
* Name: keccak_inc_absorb
|
||||
*
|
||||
* Description: Incremental keccak absorb
|
||||
* Preceded by keccak_inc_init, succeeded by keccak_inc_finalize
|
||||
*
|
||||
* Arguments: - uint64_t *s_inc: pointer to input/output incremental state
|
||||
* First 25 values represent Keccak state.
|
||||
* 26th value represents either the number of absorbed bytes
|
||||
* that have not been permuted, or not-yet-squeezed bytes.
|
||||
* - uint32_t r: rate in bytes (e.g., 168 for SHAKE128)
|
||||
* - const uint8_t *m: pointer to input to be absorbed into s
|
||||
* - size_t mlen: length of input in bytes
|
||||
**************************************************/
|
||||
static void keccak_inc_absorb(uint64_t *s_inc, uint32_t r, const uint8_t *m,
|
||||
size_t mlen) {
|
||||
size_t i;
|
||||
|
||||
/* Recall that s_inc[25] is the non-absorbed bytes xored into the state */
|
||||
while (mlen + s_inc[25] >= r) {
|
||||
for (i = 0; i < r - s_inc[25]; i++) {
|
||||
/* Take the i'th byte from message
|
||||
xor with the s_inc[25] + i'th byte of the state; little-endian */
|
||||
s_inc[(s_inc[25] + i) >> 3] ^= (uint64_t)m[i] << (8 * ((s_inc[25] + i) & 0x07));
|
||||
}
|
||||
mlen -= (size_t)(r - s_inc[25]);
|
||||
m += r - s_inc[25];
|
||||
s_inc[25] = 0;
|
||||
|
||||
KeccakF1600_StatePermute(s_inc);
|
||||
}
|
||||
|
||||
for (i = 0; i < mlen; i++) {
|
||||
s_inc[(s_inc[25] + i) >> 3] ^= (uint64_t)m[i] << (8 * ((s_inc[25] + i) & 0x07));
|
||||
}
|
||||
s_inc[25] += mlen;
|
||||
}
|
||||
|
||||
/*************************************************
|
||||
* Name: keccak_inc_finalize
|
||||
*
|
||||
* Description: Finalizes Keccak absorb phase, prepares for squeezing
|
||||
*
|
||||
* Arguments: - uint64_t *s_inc: pointer to input/output incremental state
|
||||
* First 25 values represent Keccak state.
|
||||
* 26th value represents either the number of absorbed bytes
|
||||
* that have not been permuted, or not-yet-squeezed bytes.
|
||||
* - uint32_t r: rate in bytes (e.g., 168 for SHAKE128)
|
||||
* - uint8_t p: domain-separation byte for different
|
||||
* Keccak-derived functions
|
||||
**************************************************/
|
||||
static void keccak_inc_finalize(uint64_t *s_inc, uint32_t r, uint8_t p) {
|
||||
/* After keccak_inc_absorb, we are guaranteed that s_inc[25] < r,
|
||||
so we can always use one more byte for p in the current state. */
|
||||
s_inc[s_inc[25] >> 3] ^= (uint64_t)p << (8 * (s_inc[25] & 0x07));
|
||||
s_inc[(r - 1) >> 3] ^= (uint64_t)128 << (8 * ((r - 1) & 0x07));
|
||||
s_inc[25] = 0;
|
||||
}
|
||||
|
||||
/*************************************************
|
||||
* Name: keccak_inc_squeeze
|
||||
*
|
||||
* Description: Incremental Keccak squeeze; can be called on byte-level
|
||||
*
|
||||
* Arguments: - uint8_t *h: pointer to output bytes
|
||||
* - size_t outlen: number of bytes to be squeezed
|
||||
* - uint64_t *s_inc: pointer to input/output incremental state
|
||||
* First 25 values represent Keccak state.
|
||||
* 26th value represents either the number of absorbed bytes
|
||||
* that have not been permuted, or not-yet-squeezed bytes.
|
||||
* - uint32_t r: rate in bytes (e.g., 168 for SHAKE128)
|
||||
**************************************************/
|
||||
static void keccak_inc_squeeze(uint8_t *h, size_t outlen,
|
||||
uint64_t *s_inc, uint32_t r) {
|
||||
size_t i;
|
||||
|
||||
/* First consume any bytes we still have sitting around */
|
||||
for (i = 0; i < outlen && i < s_inc[25]; i++) {
|
||||
/* There are s_inc[25] bytes left, so r - s_inc[25] is the first
|
||||
available byte. We consume from there, i.e., up to r. */
|
||||
h[i] = (uint8_t)(s_inc[(r - s_inc[25] + i) >> 3] >> (8 * ((r - s_inc[25] + i) & 0x07)));
|
||||
}
|
||||
h += i;
|
||||
outlen -= i;
|
||||
s_inc[25] -= i;
|
||||
|
||||
/* Then squeeze the remaining necessary blocks */
|
||||
while (outlen > 0) {
|
||||
KeccakF1600_StatePermute(s_inc);
|
||||
|
||||
for (i = 0; i < outlen && i < r; i++) {
|
||||
h[i] = (uint8_t)(s_inc[i >> 3] >> (8 * (i & 0x07)));
|
||||
}
|
||||
h += i;
|
||||
outlen -= i;
|
||||
s_inc[25] = r - i;
|
||||
}
|
||||
}
|
||||
|
||||
void shake128_inc_init(shake128incctx *state) {
|
||||
keccak_inc_init(state->ctx);
|
||||
}
|
||||
|
||||
void shake128_inc_absorb(shake128incctx *state, const uint8_t *input, size_t inlen) {
|
||||
keccak_inc_absorb(state->ctx, SHAKE128_RATE, input, inlen);
|
||||
}
|
||||
|
||||
void shake128_inc_finalize(shake128incctx *state) {
|
||||
keccak_inc_finalize(state->ctx, SHAKE128_RATE, 0x1F);
|
||||
}
|
||||
|
||||
void shake128_inc_squeeze(uint8_t *output, size_t outlen, shake128incctx *state) {
|
||||
keccak_inc_squeeze(output, outlen, state->ctx, SHAKE128_RATE);
|
||||
}
|
||||
|
||||
void shake256_inc_init(shake256incctx *state) {
|
||||
keccak_inc_init(state->ctx);
|
||||
}
|
||||
|
||||
void shake256_inc_absorb(shake256incctx *state, const uint8_t *input, size_t inlen) {
|
||||
keccak_inc_absorb(state->ctx, SHAKE256_RATE, input, inlen);
|
||||
}
|
||||
|
||||
void shake256_inc_finalize(shake256incctx *state) {
|
||||
keccak_inc_finalize(state->ctx, SHAKE256_RATE, 0x1F);
|
||||
}
|
||||
|
||||
void shake256_inc_squeeze(uint8_t *output, size_t outlen, shake256incctx *state) {
|
||||
keccak_inc_squeeze(output, outlen, state->ctx, SHAKE256_RATE);
|
||||
}
|
||||
|
||||
|
||||
/*************************************************
|
||||
* Name: shake128_absorb
|
||||
*
|
||||
* Description: Absorb step of the SHAKE128 XOF.
|
||||
* non-incremental, starts by zeroeing the state.
|
||||
*
|
||||
* Arguments: - uint64_t *s: pointer to (uninitialized) output Keccak state
|
||||
* - const uint8_t *input: pointer to input to be absorbed
|
||||
* into s
|
||||
* - size_t inlen: length of input in bytes
|
||||
**************************************************/
|
||||
void shake128_absorb(shake128ctx *state, const uint8_t *input, size_t inlen) {
|
||||
keccak_absorb(state->ctx, SHAKE128_RATE, input, inlen, 0x1F);
|
||||
}
|
||||
|
||||
/*************************************************
|
||||
* Name: shake128_squeezeblocks
|
||||
*
|
||||
* Description: Squeeze step of SHAKE128 XOF. Squeezes full blocks of
|
||||
* SHAKE128_RATE bytes each. Modifies the state. Can be called
|
||||
* multiple times to keep squeezing, i.e., is incremental.
|
||||
*
|
||||
* Arguments: - uint8_t *output: pointer to output blocks
|
||||
* - size_t nblocks: number of blocks to be squeezed
|
||||
* (written to output)
|
||||
* - shake128ctx *state: pointer to input/output Keccak state
|
||||
**************************************************/
|
||||
void shake128_squeezeblocks(uint8_t *output, size_t nblocks, shake128ctx *state) {
|
||||
keccak_squeezeblocks(output, nblocks, state->ctx, SHAKE128_RATE);
|
||||
}
|
||||
|
||||
/*************************************************
|
||||
* Name: shake256_absorb
|
||||
*
|
||||
* Description: Absorb step of the SHAKE256 XOF.
|
||||
* non-incremental, starts by zeroeing the state.
|
||||
*
|
||||
* Arguments: - shake256ctx *state: pointer to (uninitialized) output Keccak state
|
||||
* - const uint8_t *input: pointer to input to be absorbed
|
||||
* into s
|
||||
* - size_t inlen: length of input in bytes
|
||||
**************************************************/
|
||||
void shake256_absorb(shake256ctx *state, const uint8_t *input, size_t inlen) {
|
||||
keccak_absorb(state->ctx, SHAKE256_RATE, input, inlen, 0x1F);
|
||||
}
|
||||
|
||||
/*************************************************
|
||||
* Name: shake256_squeezeblocks
|
||||
*
|
||||
* Description: Squeeze step of SHAKE256 XOF. Squeezes full blocks of
|
||||
* SHAKE256_RATE bytes each. Modifies the state. Can be called
|
||||
* multiple times to keep squeezing, i.e., is incremental.
|
||||
*
|
||||
* Arguments: - uint8_t *output: pointer to output blocks
|
||||
* - size_t nblocks: number of blocks to be squeezed
|
||||
* (written to output)
|
||||
* - shake256ctx *state: pointer to input/output Keccak state
|
||||
**************************************************/
|
||||
void shake256_squeezeblocks(uint8_t *output, size_t nblocks, shake256ctx *state) {
|
||||
keccak_squeezeblocks(output, nblocks, state->ctx, SHAKE256_RATE);
|
||||
}
|
||||
|
||||
/*************************************************
|
||||
* Name: shake128
|
||||
*
|
||||
* Description: SHAKE128 XOF with non-incremental API
|
||||
*
|
||||
* Arguments: - uint8_t *output: pointer to output
|
||||
* - size_t outlen: requested output length in bytes
|
||||
* - const uint8_t *input: pointer to input
|
||||
* - size_t inlen: length of input in bytes
|
||||
**************************************************/
|
||||
void shake128(uint8_t *output, size_t outlen,
|
||||
const uint8_t *input, size_t inlen) {
|
||||
size_t nblocks = outlen / SHAKE128_RATE;
|
||||
uint8_t t[SHAKE128_RATE];
|
||||
shake128ctx s;
|
||||
|
||||
shake128_absorb(&s, input, inlen);
|
||||
shake128_squeezeblocks(output, nblocks, &s);
|
||||
|
||||
output += nblocks * SHAKE128_RATE;
|
||||
outlen -= nblocks * SHAKE128_RATE;
|
||||
|
||||
if (outlen) {
|
||||
shake128_squeezeblocks(t, 1, &s);
|
||||
for (size_t i = 0; i < outlen; ++i) {
|
||||
output[i] = t[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*************************************************
|
||||
* Name: shake256
|
||||
*
|
||||
* Description: SHAKE256 XOF with non-incremental API
|
||||
*
|
||||
* Arguments: - uint8_t *output: pointer to output
|
||||
* - size_t outlen: requested output length in bytes
|
||||
* - const uint8_t *input: pointer to input
|
||||
* - size_t inlen: length of input in bytes
|
||||
**************************************************/
|
||||
void shake256(uint8_t *output, size_t outlen,
|
||||
const uint8_t *input, size_t inlen) {
|
||||
size_t nblocks = outlen / SHAKE256_RATE;
|
||||
uint8_t t[SHAKE256_RATE];
|
||||
shake256ctx s;
|
||||
|
||||
shake256_absorb(&s, input, inlen);
|
||||
shake256_squeezeblocks(output, nblocks, &s);
|
||||
|
||||
output += nblocks * SHAKE256_RATE;
|
||||
outlen -= nblocks * SHAKE256_RATE;
|
||||
|
||||
if (outlen) {
|
||||
shake256_squeezeblocks(t, 1, &s);
|
||||
for (size_t i = 0; i < outlen; ++i) {
|
||||
output[i] = t[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void sha3_256_inc_init(sha3_256incctx *state) {
|
||||
keccak_inc_init(state->ctx);
|
||||
}
|
||||
|
||||
void sha3_256_inc_absorb(sha3_256incctx *state, const uint8_t *input, size_t inlen) {
|
||||
keccak_inc_absorb(state->ctx, SHA3_256_RATE, input, inlen);
|
||||
}
|
||||
|
||||
void sha3_256_inc_finalize(uint8_t *output, sha3_256incctx *state) {
|
||||
uint8_t t[SHA3_256_RATE];
|
||||
keccak_inc_finalize(state->ctx, SHA3_256_RATE, 0x06);
|
||||
|
||||
keccak_squeezeblocks(t, 1, state->ctx, SHA3_256_RATE);
|
||||
|
||||
for (size_t i = 0; i < 32; i++) {
|
||||
output[i] = t[i];
|
||||
}
|
||||
}
|
||||
|
||||
/*************************************************
|
||||
* Name: sha3_256
|
||||
*
|
||||
* Description: SHA3-256 with non-incremental API
|
||||
*
|
||||
* Arguments: - uint8_t *output: pointer to output
|
||||
* - const uint8_t *input: pointer to input
|
||||
* - size_t inlen: length of input in bytes
|
||||
**************************************************/
|
||||
void sha3_256(uint8_t *output, const uint8_t *input, size_t inlen) {
|
||||
uint64_t s[25];
|
||||
uint8_t t[SHA3_256_RATE];
|
||||
|
||||
/* Absorb input */
|
||||
keccak_absorb(s, SHA3_256_RATE, input, inlen, 0x06);
|
||||
|
||||
/* Squeeze output */
|
||||
keccak_squeezeblocks(t, 1, s, SHA3_256_RATE);
|
||||
|
||||
for (size_t i = 0; i < 32; i++) {
|
||||
output[i] = t[i];
|
||||
}
|
||||
}
|
||||
|
||||
void sha3_384_inc_init(sha3_384incctx *state) {
|
||||
keccak_inc_init(state->ctx);
|
||||
}
|
||||
|
||||
void sha3_384_inc_absorb(sha3_384incctx *state, const uint8_t *input, size_t inlen) {
|
||||
keccak_inc_absorb(state->ctx, SHA3_384_RATE, input, inlen);
|
||||
}
|
||||
|
||||
void sha3_384_inc_finalize(uint8_t *output, sha3_384incctx *state) {
|
||||
uint8_t t[SHA3_384_RATE];
|
||||
keccak_inc_finalize(state->ctx, SHA3_384_RATE, 0x06);
|
||||
|
||||
keccak_squeezeblocks(t, 1, state->ctx, SHA3_384_RATE);
|
||||
|
||||
for (size_t i = 0; i < 48; i++) {
|
||||
output[i] = t[i];
|
||||
}
|
||||
}
|
||||
|
||||
/*************************************************
|
||||
* Name: sha3_384
|
||||
*
|
||||
* Description: SHA3-256 with non-incremental API
|
||||
*
|
||||
* Arguments: - uint8_t *output: pointer to output
|
||||
* - const uint8_t *input: pointer to input
|
||||
* - size_t inlen: length of input in bytes
|
||||
**************************************************/
|
||||
void sha3_384(uint8_t *output, const uint8_t *input, size_t inlen) {
|
||||
uint64_t s[25];
|
||||
uint8_t t[SHA3_384_RATE];
|
||||
|
||||
/* Absorb input */
|
||||
keccak_absorb(s, SHA3_384_RATE, input, inlen, 0x06);
|
||||
|
||||
/* Squeeze output */
|
||||
keccak_squeezeblocks(t, 1, s, SHA3_384_RATE);
|
||||
|
||||
for (size_t i = 0; i < 48; i++) {
|
||||
output[i] = t[i];
|
||||
}
|
||||
}
|
||||
|
||||
void sha3_512_inc_init(sha3_512incctx *state) {
|
||||
keccak_inc_init(state->ctx);
|
||||
}
|
||||
|
||||
void sha3_512_inc_absorb(sha3_512incctx *state, const uint8_t *input, size_t inlen) {
|
||||
keccak_inc_absorb(state->ctx, SHA3_512_RATE, input, inlen);
|
||||
}
|
||||
|
||||
void sha3_512_inc_finalize(uint8_t *output, sha3_512incctx *state) {
|
||||
uint8_t t[SHA3_512_RATE];
|
||||
keccak_inc_finalize(state->ctx, SHA3_512_RATE, 0x06);
|
||||
|
||||
keccak_squeezeblocks(t, 1, state->ctx, SHA3_512_RATE);
|
||||
|
||||
for (size_t i = 0; i < 64; i++) {
|
||||
output[i] = t[i];
|
||||
}
|
||||
}
|
||||
|
||||
/*************************************************
|
||||
* Name: sha3_512
|
||||
*
|
||||
* Description: SHA3-512 with non-incremental API
|
||||
*
|
||||
* Arguments: - uint8_t *output: pointer to output
|
||||
* - const uint8_t *input: pointer to input
|
||||
* - size_t inlen: length of input in bytes
|
||||
**************************************************/
|
||||
void sha3_512(uint8_t *output, const uint8_t *input, size_t inlen) {
|
||||
uint64_t s[25];
|
||||
uint8_t t[SHA3_512_RATE];
|
||||
|
||||
/* Absorb input */
|
||||
keccak_absorb(s, SHA3_512_RATE, input, inlen, 0x06);
|
||||
|
||||
/* Squeeze output */
|
||||
keccak_squeezeblocks(t, 1, s, SHA3_512_RATE);
|
||||
|
||||
for (size_t i = 0; i < 64; i++) {
|
||||
output[i] = t[i];
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@ -18,74 +18,10 @@
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*!
|
||||
\def OQS_SHA3_CSHAKE_DOMAIN
|
||||
* The cSHAKE function domain code
|
||||
*/
|
||||
#define OQS_SHA3_CSHAKE_DOMAIN 0x04
|
||||
|
||||
/*!
|
||||
\def OQS_SHA3_CSHAKE128_RATE
|
||||
* The cSHAKE-128 byte absorption rate
|
||||
*/
|
||||
#define OQS_SHA3_CSHAKE128_RATE 168
|
||||
|
||||
/*!
|
||||
\def OQS_SHA3_CSHAKE256_RATE
|
||||
* The cSHAKE-256 byte absorption rate
|
||||
*/
|
||||
#define OQS_SHA3_CSHAKE256_RATE 136
|
||||
|
||||
/*!
|
||||
\def OQS_SHA3_SHA3_DOMAIN
|
||||
* The SHA3 function domain code
|
||||
*/
|
||||
#define OQS_SHA3_SHA3_DOMAIN 0x06
|
||||
|
||||
/*!
|
||||
\def OQS_SHA3_SHA3_256_RATE
|
||||
* The SHA-256 byte absorption rate
|
||||
*/
|
||||
#define OQS_SHA3_SHA3_256_RATE 136
|
||||
|
||||
/*!
|
||||
\def OQS_SHA3_SHA3_512_RATE
|
||||
* The SHA-512 byte absorption rate
|
||||
*/
|
||||
#define OQS_SHA3_SHA3_512_RATE 72
|
||||
|
||||
/*!
|
||||
\def OQS_SHA3_SHAKE_DOMAIN
|
||||
* The function domain code
|
||||
*/
|
||||
#define OQS_SHA3_SHAKE_DOMAIN 0x1F
|
||||
|
||||
/*!
|
||||
\def OQS_SHA3_SHAKE128_RATE
|
||||
* The SHAKE-128 byte absorption rate
|
||||
*/
|
||||
#define OQS_SHA3_SHAKE128_RATE 168
|
||||
|
||||
/*!
|
||||
\def OQS_SHA3_SHAKE256_RATE
|
||||
* The SHAKE-256 byte absorption rate
|
||||
*/
|
||||
#define OQS_SHA3_SHAKE256_RATE 136
|
||||
|
||||
/*!
|
||||
\def OQS_SHA3_STATESIZE
|
||||
* The Keccak SHA3 state array size
|
||||
*/
|
||||
#define OQS_SHA3_STATESIZE 25
|
||||
|
||||
/*!
|
||||
\def OQS_SHA3_INC_STATESIZE
|
||||
* The size of the state for the incremental hashing API
|
||||
*/
|
||||
#define OQS_SHA3_INC_STATESIZE 26
|
||||
|
||||
/* SHA3 */
|
||||
|
||||
#define OQS_SHA3_SHA3_256_RATE 136
|
||||
|
||||
/**
|
||||
* \brief Process a message with SHA3-256 and return the hash code in the output byte array.
|
||||
*
|
||||
@ -95,7 +31,38 @@ extern "C" {
|
||||
* \param input The message input byte array
|
||||
* \param inplen The number of message bytes to process
|
||||
*/
|
||||
void OQS_SHA3_sha3256(uint8_t *output, const uint8_t *input, size_t inplen);
|
||||
void OQS_SHA3_sha3_256(uint8_t *output, const uint8_t *input, size_t inplen);
|
||||
|
||||
typedef struct {
|
||||
uint64_t ctx[26];
|
||||
} OQS_SHA3_sha3_256_inc_ctx;
|
||||
|
||||
void OQS_SHA3_sha3_256_inc_init(OQS_SHA3_sha3_256_inc_ctx *state);
|
||||
void OQS_SHA3_sha3_256_inc_absorb(OQS_SHA3_sha3_256_inc_ctx *state, const uint8_t *input, size_t inlen);
|
||||
void OQS_SHA3_sha3_256_inc_finalize(uint8_t *output, OQS_SHA3_sha3_256_inc_ctx *state);
|
||||
|
||||
#define OQS_SHA3_SHA3_384_RATE 104
|
||||
|
||||
/**
|
||||
* \brief Process a message with SHA3-384 and return the hash code in the output byte array.
|
||||
*
|
||||
* \warning The output array must be at least 32 bytes in length.
|
||||
*
|
||||
* \param output The output byte array
|
||||
* \param input The message input byte array
|
||||
* \param inplen The number of message bytes to process
|
||||
*/
|
||||
void OQS_SHA3_sha3_384(uint8_t *output, const uint8_t *input, size_t inplen);
|
||||
|
||||
typedef struct {
|
||||
uint64_t ctx[26];
|
||||
} OQS_SHA3_sha3_384_inc_ctx;
|
||||
|
||||
void OQS_SHA3_sha3_384_inc_init(OQS_SHA3_sha3_384_inc_ctx *state);
|
||||
void OQS_SHA3_sha3_384_inc_absorb(OQS_SHA3_sha3_384_inc_ctx *state, const uint8_t *input, size_t inlen);
|
||||
void OQS_SHA3_sha3_384_inc_finalize(uint8_t *output, OQS_SHA3_sha3_384_inc_ctx *state);
|
||||
|
||||
#define OQS_SHA3_SHA3_512_RATE 72
|
||||
|
||||
/**
|
||||
* \brief Process a message with SHA3-512 and return the hash code in the output byte array.
|
||||
@ -106,46 +73,20 @@ void OQS_SHA3_sha3256(uint8_t *output, const uint8_t *input, size_t inplen);
|
||||
* \param input The message input byte array
|
||||
* \param inplen The number of message bytes to process
|
||||
*/
|
||||
void OQS_SHA3_sha3512(uint8_t *output, const uint8_t *input, size_t inplen);
|
||||
void OQS_SHA3_sha3_512(uint8_t *output, const uint8_t *input, size_t inplen);
|
||||
|
||||
/**
|
||||
* \brief The Keccak absorb function.
|
||||
* Absorb an input message array directly into the state.
|
||||
*
|
||||
* \warning Finalizes the message state, can not be used in consecutive calls. \n
|
||||
* State must be initialized (and zeroed) by the caller.
|
||||
*
|
||||
* \param state The function state; must be initialized
|
||||
* \param rate The rate of absorption, in bytes
|
||||
* \param input The input message byte array
|
||||
* \param inplen The number of message bytes to process
|
||||
* \param domain The domain seperation code (SHA3=0x06, SHAKE=0x1F, cSHAKE=0x04)
|
||||
*/
|
||||
void OQS_SHA3_keccak_absorb(uint64_t *state, size_t rate, const uint8_t *input, size_t inplen, uint8_t domain);
|
||||
typedef struct {
|
||||
uint64_t ctx[26];
|
||||
} OQS_SHA3_sha3_512_inc_ctx;
|
||||
|
||||
/**
|
||||
* \brief The Keccak permute function.
|
||||
* Permutes the state array, can be used in conjunction with the keccak_absorb function.
|
||||
*
|
||||
* \param state The function state; must be initialized
|
||||
*/
|
||||
void OQS_SHA3_keccak_permute(uint64_t *state);
|
||||
|
||||
/**
|
||||
* \brief The Keccak squeeze function.
|
||||
* Permutes and extracts the state to an output byte array.
|
||||
*
|
||||
* \warning Output array must be initialized to a multiple of the byte rate.
|
||||
*
|
||||
* \param output The output byte array
|
||||
* \param nblocks The number of blocks to extract
|
||||
* \param state The function state; must be pre-initialized
|
||||
* \param rate The rate of absorption, in bytes
|
||||
*/
|
||||
void OQS_SHA3_keccak_squeezeblocks(uint8_t *output, size_t nblocks, uint64_t *state, size_t rate);
|
||||
void OQS_SHA3_sha3_512_inc_init(OQS_SHA3_sha3_512_inc_ctx *state);
|
||||
void OQS_SHA3_sha3_512_inc_absorb(OQS_SHA3_sha3_512_inc_ctx *state, const uint8_t *input, size_t inlen);
|
||||
void OQS_SHA3_sha3_512_inc_finalize(uint8_t *output, OQS_SHA3_sha3_512_inc_ctx *state);
|
||||
|
||||
/* SHAKE */
|
||||
|
||||
#define OQS_SHA3_SHAKE128_RATE 168
|
||||
|
||||
/**
|
||||
* \brief Seed a SHAKE-128 instance, and generate an array of pseudo-random bytes.
|
||||
*
|
||||
@ -158,6 +99,10 @@ void OQS_SHA3_keccak_squeezeblocks(uint8_t *output, size_t nblocks, uint64_t *st
|
||||
*/
|
||||
void OQS_SHA3_shake128(uint8_t *output, size_t outlen, const uint8_t *input, size_t inplen);
|
||||
|
||||
typedef struct {
|
||||
uint64_t ctx[25];
|
||||
} OQS_SHA3_shake128_ctx;
|
||||
|
||||
/**
|
||||
* \brief The SHAKE-128 absorb function.
|
||||
* Absorb and finalize an input seed byte array.
|
||||
@ -170,7 +115,7 @@ void OQS_SHA3_shake128(uint8_t *output, size_t outlen, const uint8_t *input, siz
|
||||
* \param input The input seed byte array
|
||||
* \param inplen The number of seed bytes to process
|
||||
*/
|
||||
void OQS_SHA3_shake128_absorb(uint64_t *state, const uint8_t *input, size_t inplen);
|
||||
void OQS_SHA3_shake128_absorb(OQS_SHA3_shake128_ctx *state, const uint8_t *input, size_t inplen);
|
||||
|
||||
/**
|
||||
* \brief The SHAKE-128 squeeze function.
|
||||
@ -183,12 +128,16 @@ void OQS_SHA3_shake128_absorb(uint64_t *state, const uint8_t *input, size_t inpl
|
||||
* \param nblocks The number of blocks to extract
|
||||
* \param state The function state; must be pre-initialized
|
||||
*/
|
||||
void OQS_SHA3_shake128_squeezeblocks(uint8_t *output, size_t nblocks, uint64_t *state);
|
||||
void OQS_SHA3_shake128_squeezeblocks(uint8_t *output, size_t nblocks, OQS_SHA3_shake128_ctx *state);
|
||||
|
||||
typedef struct {
|
||||
uint64_t ctx[26];
|
||||
} OQS_SHA3_shake128_inc_ctx;
|
||||
|
||||
/**
|
||||
* \brief Initialize the incremental hashing API state
|
||||
*/
|
||||
void OQS_SHA3_shake128_inc_init(uint64_t *s_inc);
|
||||
void OQS_SHA3_shake128_inc_init(OQS_SHA3_shake128_inc_ctx *s_inc);
|
||||
|
||||
/**
|
||||
* \brief Absorb into the state
|
||||
@ -197,13 +146,13 @@ void OQS_SHA3_shake128_inc_init(uint64_t *s_inc);
|
||||
* \param input input buffer
|
||||
* \param inlen length of input buffer
|
||||
*/
|
||||
void OQS_SHA3_shake128_inc_absorb(uint64_t *s_inc, const uint8_t *input, size_t inlen);
|
||||
void OQS_SHA3_shake128_inc_absorb(OQS_SHA3_shake128_inc_ctx *s_inc, const uint8_t *input, size_t inlen);
|
||||
/*
|
||||
* \brief Finalizes output
|
||||
*
|
||||
* \param s_inc Incremental hashing state
|
||||
*/
|
||||
void OQS_SHA3_shake128_inc_finalize(uint64_t *s_inc);
|
||||
void OQS_SHA3_shake128_inc_finalize(OQS_SHA3_shake128_inc_ctx *s_inc);
|
||||
|
||||
/**
|
||||
* \brief Obtains output
|
||||
@ -212,7 +161,9 @@ void OQS_SHA3_shake128_inc_finalize(uint64_t *s_inc);
|
||||
* \param outlen bytes of outbut buffer
|
||||
* \param state
|
||||
*/
|
||||
void OQS_SHA3_shake128_inc_squeeze(uint8_t *output, size_t outlen, uint64_t *s_inc);
|
||||
void OQS_SHA3_shake128_inc_squeeze(uint8_t *output, size_t outlen, OQS_SHA3_shake128_inc_ctx *s_inc);
|
||||
|
||||
#define OQS_SHA3_SHAKE256_RATE 136
|
||||
|
||||
/**
|
||||
* \brief Seed a SHAKE-256 instance, and generate an array of pseudo-random bytes.
|
||||
@ -226,6 +177,10 @@ void OQS_SHA3_shake128_inc_squeeze(uint8_t *output, size_t outlen, uint64_t *s_i
|
||||
*/
|
||||
void OQS_SHA3_shake256(uint8_t *output, size_t outlen, const uint8_t *input, size_t inplen);
|
||||
|
||||
typedef struct {
|
||||
uint64_t ctx[25];
|
||||
} OQS_SHA3_shake256_ctx;
|
||||
|
||||
/**
|
||||
* \brief The SHAKE-256 absorb function.
|
||||
* Absorb and finalize an input seed byte array.
|
||||
@ -238,7 +193,7 @@ void OQS_SHA3_shake256(uint8_t *output, size_t outlen, const uint8_t *input, siz
|
||||
* \param input The input seed byte array
|
||||
* \param inplen The number of seed bytes to process
|
||||
*/
|
||||
void OQS_SHA3_shake256_absorb(uint64_t *state, const uint8_t *input, size_t inplen);
|
||||
void OQS_SHA3_shake256_absorb(OQS_SHA3_shake256_ctx *state, const uint8_t *input, size_t inplen);
|
||||
|
||||
/**
|
||||
* \brief The SHAKE-256 squeeze function.
|
||||
@ -250,12 +205,16 @@ void OQS_SHA3_shake256_absorb(uint64_t *state, const uint8_t *input, size_t inpl
|
||||
* \param nblocks The number of blocks to extract
|
||||
* \param state The function state; must be pre-initialized
|
||||
*/
|
||||
void OQS_SHA3_shake256_squeezeblocks(uint8_t *output, size_t nblocks, uint64_t *state);
|
||||
void OQS_SHA3_shake256_squeezeblocks(uint8_t *output, size_t nblocks, OQS_SHA3_shake256_ctx *state);
|
||||
|
||||
typedef struct {
|
||||
uint64_t ctx[26];
|
||||
} OQS_SHA3_shake256_inc_ctx;
|
||||
|
||||
/**
|
||||
* \brief Initialize the incremental hashing API state
|
||||
*/
|
||||
void OQS_SHA3_shake256_inc_init(uint64_t *s_inc);
|
||||
void OQS_SHA3_shake256_inc_init(OQS_SHA3_shake256_inc_ctx *s_inc);
|
||||
|
||||
/**
|
||||
* \brief Absorb into the state
|
||||
@ -264,13 +223,13 @@ void OQS_SHA3_shake256_inc_init(uint64_t *s_inc);
|
||||
* \param input input buffer
|
||||
* \param inlen length of input buffer
|
||||
*/
|
||||
void OQS_SHA3_shake256_inc_absorb(uint64_t *s_inc, const uint8_t *input, size_t inlen);
|
||||
void OQS_SHA3_shake256_inc_absorb(OQS_SHA3_shake256_inc_ctx *s_inc, const uint8_t *input, size_t inlen);
|
||||
/*
|
||||
* \brief Finalizes output
|
||||
*
|
||||
* \param s_inc Incremental hashing state
|
||||
*/
|
||||
void OQS_SHA3_shake256_inc_finalize(uint64_t *s_inc);
|
||||
void OQS_SHA3_shake256_inc_finalize(OQS_SHA3_shake256_inc_ctx *s_inc);
|
||||
|
||||
/**
|
||||
* \brief Obtains output
|
||||
@ -279,10 +238,24 @@ void OQS_SHA3_shake256_inc_finalize(uint64_t *s_inc);
|
||||
* \param outlen bytes of outbut buffer
|
||||
* \param state
|
||||
*/
|
||||
void OQS_SHA3_shake256_inc_squeeze(uint8_t *output, size_t outlen, uint64_t *s_inc);
|
||||
void OQS_SHA3_shake256_inc_squeeze(uint8_t *output, size_t outlen, OQS_SHA3_shake256_inc_ctx *s_inc);
|
||||
|
||||
/* cSHAKE */
|
||||
|
||||
void OQS_SHA3_cshake128(uint8_t *output, size_t outlen, const uint8_t *name, size_t namelen, const uint8_t *cstm, size_t cstmlen, const uint8_t *input, size_t inlen);
|
||||
|
||||
void OQS_SHA3_cshake128_inc_init(OQS_SHA3_shake128_inc_ctx *state, const uint8_t *name, size_t namelen, const uint8_t *cstm, size_t cstmlen);
|
||||
void OQS_SHA3_cshake128_inc_absorb(OQS_SHA3_shake128_inc_ctx *state, const uint8_t *input, size_t inlen);
|
||||
void OQS_SHA3_cshake128_inc_finalize(OQS_SHA3_shake128_inc_ctx *state);
|
||||
void OQS_SHA3_cshake128_inc_squeeze(uint8_t *output, size_t outlen, OQS_SHA3_shake128_inc_ctx *state);
|
||||
|
||||
void OQS_SHA3_cshake256(uint8_t *output, size_t outlen, const uint8_t *name, size_t namelen, const uint8_t* cstm, size_t cstmlen, const uint8_t *input, size_t inlen);
|
||||
|
||||
void OQS_SHA3_cshake256_inc_init(OQS_SHA3_shake256_inc_ctx *state, const uint8_t *name, size_t namelen, const uint8_t *cstm, size_t cstmlen);
|
||||
void OQS_SHA3_cshake256_inc_absorb(OQS_SHA3_shake256_inc_ctx *state, const uint8_t *input, size_t inlen);
|
||||
void OQS_SHA3_cshake256_inc_finalize(OQS_SHA3_shake256_inc_ctx *state);
|
||||
void OQS_SHA3_cshake256_inc_squeeze(uint8_t *output, size_t outlen, OQS_SHA3_shake256_inc_ctx *state);
|
||||
|
||||
/**
|
||||
* \brief Seed a cSHAKE-128 instance and generate pseudo-random output.
|
||||
* Permutes and extracts the state to an output byte array.
|
||||
@ -295,36 +268,8 @@ void OQS_SHA3_shake256_inc_squeeze(uint8_t *output, size_t outlen, uint64_t *s_i
|
||||
* \param input The input seed byte array
|
||||
* \param inplen The number of seed bytes to process
|
||||
*/
|
||||
|
||||
void OQS_SHA3_cshake128_simple(uint8_t *output, size_t outlen, uint16_t cstm, const uint8_t *input, size_t inplen);
|
||||
|
||||
/**
|
||||
* \brief The cSHAKE-128 simple absorb function.
|
||||
* Absorb and finalize an input seed directly into the state.
|
||||
* Should be used in conjunction with the cshake128_simple_squeezeblocks function.
|
||||
*
|
||||
* \warning Finalizes the seed state, should not be used in consecutive calls. \n
|
||||
* State must be initialized (and zeroed) by the caller.
|
||||
*
|
||||
* \param state The function state; must be pre-initialized
|
||||
* \param cstm The 16bit customization integer
|
||||
* \param input The input seed byte array
|
||||
* \param inplen The number of seed bytes to process
|
||||
*/
|
||||
void OQS_SHA3_cshake128_simple_absorb(uint64_t *state, uint16_t cstm, const uint8_t *input, size_t inplen);
|
||||
|
||||
/**
|
||||
* \brief The cSHAKE-128 simple squeeze function.
|
||||
* Permutes and extracts blocks of state to an output byte array.
|
||||
*
|
||||
* \warning Output array must be initialized to a multiple of the byte rate.
|
||||
*
|
||||
* \param output The output byte array
|
||||
* \param nblocks The number of blocks to extract
|
||||
* \param state The function state; must be pre-initialized
|
||||
*/
|
||||
void OQS_SHA3_cshake128_simple_squeezeblocks(uint8_t *output, size_t nblocks, uint64_t *state);
|
||||
|
||||
/**
|
||||
* \brief Seed a cSHAKE-256 instance and generate pseudo-random output.
|
||||
* Permutes and extracts the state to an output byte array.
|
||||
@ -339,6 +284,7 @@ void OQS_SHA3_cshake128_simple_squeezeblocks(uint8_t *output, size_t nblocks, ui
|
||||
*/
|
||||
void OQS_SHA3_cshake256_simple(uint8_t *output, size_t outlen, uint16_t cstm, const uint8_t *input, size_t inplen);
|
||||
|
||||
#if 0
|
||||
/**
|
||||
* \brief The cSHAKE-256 simple absorb function.
|
||||
* Absorb and finalize an input seed directly into the state.
|
||||
@ -365,6 +311,7 @@ void OQS_SHA3_cshake256_simple_absorb(uint64_t *state, uint16_t cstm, const uint
|
||||
* \param state The function state; must be pre-initialized
|
||||
*/
|
||||
void OQS_SHA3_cshake256_simple_squeezeblocks(uint8_t *output, size_t nblocks, uint64_t *state);
|
||||
#endif
|
||||
|
||||
#if defined(__cplusplus)
|
||||
} // extern "C"
|
||||
|
||||
145
src/crypto/sha3/sha3_c.c
Normal file
145
src/crypto/sha3/sha3_c.c
Normal file
@ -0,0 +1,145 @@
|
||||
#include <oqs/oqs.h>
|
||||
|
||||
#define SHA3_256_RATE OQS_SHA3_SHA3_256_RATE
|
||||
#define sha3_256 OQS_SHA3_sha3_256
|
||||
|
||||
#define sha3_256incctx OQS_SHA3_sha3_256_inc_ctx
|
||||
#define sha3_256_inc_init OQS_SHA3_sha3_256_inc_init
|
||||
#define sha3_256_inc_absorb OQS_SHA3_sha3_256_inc_absorb
|
||||
#define sha3_256_inc_finalize OQS_SHA3_sha3_256_inc_finalize
|
||||
|
||||
#define SHA3_384_RATE OQS_SHA3_SHA3_384_RATE
|
||||
#define sha3_384 OQS_SHA3_sha3_384
|
||||
|
||||
#define sha3_384incctx OQS_SHA3_sha3_384_inc_ctx
|
||||
#define sha3_384_inc_init OQS_SHA3_sha3_384_inc_init
|
||||
#define sha3_384_inc_absorb OQS_SHA3_sha3_384_inc_absorb
|
||||
#define sha3_384_inc_finalize OQS_SHA3_sha3_384_inc_finalize
|
||||
|
||||
#define SHA3_512_RATE OQS_SHA3_SHA3_512_RATE
|
||||
#define sha3_512 OQS_SHA3_sha3_512
|
||||
|
||||
#define sha3_512incctx OQS_SHA3_sha3_512_inc_ctx
|
||||
#define sha3_512_inc_init OQS_SHA3_sha3_512_inc_init
|
||||
#define sha3_512_inc_absorb OQS_SHA3_sha3_512_inc_absorb
|
||||
#define sha3_512_inc_finalize OQS_SHA3_sha3_512_inc_finalize
|
||||
|
||||
#define SHAKE128_RATE OQS_SHA3_SHAKE128_RATE
|
||||
#define shake128 OQS_SHA3_shake128
|
||||
|
||||
#define shake128ctx OQS_SHA3_shake128_ctx
|
||||
#define shake128_absorb OQS_SHA3_shake128_absorb
|
||||
#define shake128_squeezeblocks OQS_SHA3_shake128_squeezeblocks
|
||||
|
||||
#define shake128incctx OQS_SHA3_shake128_inc_ctx
|
||||
#define shake128_inc_init OQS_SHA3_shake128_inc_init
|
||||
#define shake128_inc_absorb OQS_SHA3_shake128_inc_absorb
|
||||
#define shake128_inc_finalize OQS_SHA3_shake128_inc_finalize
|
||||
#define shake128_inc_squeeze OQS_SHA3_shake128_inc_squeeze
|
||||
|
||||
#define SHAKE256_RATE OQS_SHA3_SHAKE256_RATE
|
||||
#define shake256 OQS_SHA3_shake256
|
||||
|
||||
#define shake256ctx OQS_SHA3_shake256_ctx
|
||||
#define shake256_absorb OQS_SHA3_shake256_absorb
|
||||
#define shake256_squeezeblocks OQS_SHA3_shake256_squeezeblocks
|
||||
|
||||
#define shake256incctx OQS_SHA3_shake256_inc_ctx
|
||||
#define shake256_inc_init OQS_SHA3_shake256_inc_init
|
||||
#define shake256_inc_absorb OQS_SHA3_shake256_inc_absorb
|
||||
#define shake256_inc_finalize OQS_SHA3_shake256_inc_finalize
|
||||
#define shake256_inc_squeeze OQS_SHA3_shake256_inc_squeeze
|
||||
|
||||
#include "fips202.c"
|
||||
|
||||
#define cshake128 OQS_SHA3_cshake128
|
||||
|
||||
#define cshake128_inc_init OQS_SHA3_cshake128_inc_init
|
||||
#define cshake128_inc_absorb OQS_SHA3_cshake128_inc_absorb
|
||||
#define cshake128_inc_finalize OQS_SHA3_cshake128_inc_finalize
|
||||
#define cshake128_inc_squeeze OQS_SHA3_cshake128_inc_squeeze
|
||||
|
||||
#define cshake256 OQS_SHA3_cshake256
|
||||
|
||||
#define cshake256_inc_init OQS_SHA3_cshake256_inc_init
|
||||
#define cshake256_inc_absorb OQS_SHA3_cshake256_inc_absorb
|
||||
#define cshake256_inc_finalize OQS_SHA3_cshake256_inc_finalize
|
||||
#define cshake256_inc_squeeze OQS_SHA3_cshake256_inc_squeeze
|
||||
|
||||
#include "sp800-185.c"
|
||||
|
||||
void OQS_SHA3_cshake128_simple(uint8_t *output, size_t outlen, uint16_t cstm, const uint8_t *input, size_t inplen) {
|
||||
|
||||
OQS_SHA3_shake128_inc_ctx state;
|
||||
|
||||
for (size_t i = 0; i < 26; ++i) {
|
||||
state.ctx[i] = 0;
|
||||
}
|
||||
|
||||
/* Note: This function doesn't align exactly to cSHAKE (SP800-185 3.2), which should produce
|
||||
SHAKE output if S and N = zero (sort of a customized custom-SHAKE function).
|
||||
Padding is hard-coded as the first 32 bits, plus 16 bits of fixed S,
|
||||
and 16 bits of counter, equivalant to S=cstm, N=0.
|
||||
The short integer optimizes this function for a digest counter configuration */
|
||||
|
||||
uint8_t sep[8];
|
||||
sep[0] = 0x01; /* bytepad */
|
||||
sep[1] = 0xA8;
|
||||
sep[2] = 0x01;
|
||||
sep[3] = 0x00;
|
||||
sep[4] = 0x01;
|
||||
sep[5] = 0x10; /* bitlen of cstm */
|
||||
sep[6] = cstm & 0xFF;
|
||||
sep[7] = cstm >> 8;
|
||||
|
||||
state.ctx[0] = load64(sep);
|
||||
|
||||
/* transform the domain string */
|
||||
KeccakF1600_StatePermute(state.ctx);
|
||||
|
||||
/* absorb the state */
|
||||
OQS_SHA3_cshake128_inc_absorb(&state, input, inplen);
|
||||
|
||||
/* generate output */
|
||||
OQS_SHA3_cshake128_inc_finalize(&state);
|
||||
OQS_SHA3_cshake128_inc_squeeze(output, outlen, &state);
|
||||
|
||||
}
|
||||
|
||||
void OQS_SHA3_cshake256_simple(uint8_t *output, size_t outlen, uint16_t cstm, const uint8_t *input, size_t inplen) {
|
||||
|
||||
OQS_SHA3_shake256_inc_ctx state;
|
||||
|
||||
for (size_t i = 0; i < 26; ++i) {
|
||||
state.ctx[i] = 0;
|
||||
}
|
||||
|
||||
/* Note: This function doesn't align exactly to cSHAKE (SP800-185 3.2), which should produce
|
||||
SHAKE output if S and N = zero (sort of a customized custom-SHAKE function).
|
||||
Padding is hard-coded as the first 32 bits, plus 16 bits of fixed S,
|
||||
and 16 bits of counter, equivalant to S=cstm, N=0.
|
||||
The short integer optimizes this function for a digest counter configuration */
|
||||
|
||||
uint8_t sep[8];
|
||||
sep[0] = 0x01; /* bytepad */
|
||||
sep[1] = 0x88;
|
||||
sep[2] = 0x01;
|
||||
sep[3] = 0x00;
|
||||
sep[4] = 0x01;
|
||||
sep[5] = 0x10; /* bitlen of cstm */
|
||||
sep[6] = cstm & 0xFF;
|
||||
sep[7] = cstm >> 8;
|
||||
|
||||
state.ctx[0] = load64(sep);
|
||||
|
||||
/* transform the domain string */
|
||||
KeccakF1600_StatePermute(state.ctx);
|
||||
|
||||
/* absorb the state */
|
||||
OQS_SHA3_cshake256_inc_absorb(&state, input, inplen);
|
||||
|
||||
/* generate output */
|
||||
OQS_SHA3_cshake256_inc_finalize(&state);
|
||||
OQS_SHA3_cshake256_inc_squeeze(output, outlen, &state);
|
||||
|
||||
}
|
||||
136
src/crypto/sha3/sp800-185.c
Normal file
136
src/crypto/sha3/sp800-185.c
Normal file
@ -0,0 +1,136 @@
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
static size_t left_encode(uint8_t *encbuf, size_t value) {
|
||||
size_t n, i, v;
|
||||
|
||||
for (v = value, n = 0; v && (n < sizeof(size_t)); n++, v >>= 8) {
|
||||
; /* empty */
|
||||
}
|
||||
if (n == 0) {
|
||||
n = 1;
|
||||
}
|
||||
for (i = 1; i <= n; i++) {
|
||||
encbuf[i] = (uint8_t)(value >> (8 * (n-i)));
|
||||
}
|
||||
encbuf[0] = (uint8_t)n;
|
||||
return n + 1;
|
||||
}
|
||||
|
||||
void cshake128_inc_init(shake128incctx *state, const uint8_t *name, size_t namelen, const uint8_t *cstm, size_t cstmlen) {
|
||||
uint8_t encbuf[sizeof(size_t)+1];
|
||||
|
||||
shake128_inc_init(state);
|
||||
|
||||
shake128_inc_absorb(state, encbuf, left_encode(encbuf, SHAKE128_RATE));
|
||||
|
||||
shake128_inc_absorb(state, encbuf, left_encode(encbuf, namelen * 8));
|
||||
shake128_inc_absorb(state, name, namelen);
|
||||
|
||||
shake128_inc_absorb(state, encbuf, left_encode(encbuf, cstmlen * 8));
|
||||
shake128_inc_absorb(state, cstm, cstmlen);
|
||||
|
||||
if (state->ctx[25] != 0) {
|
||||
state->ctx[25] = SHAKE128_RATE - 1;
|
||||
encbuf[0] = 0;
|
||||
shake128_inc_absorb(state, encbuf, 1);
|
||||
}
|
||||
}
|
||||
|
||||
void cshake128_inc_absorb(shake128incctx *state, const uint8_t *input, size_t inlen) {
|
||||
shake128_inc_absorb(state, input, inlen);
|
||||
}
|
||||
|
||||
void cshake128_inc_finalize(shake128incctx *state) {
|
||||
state->ctx[state->ctx[25] >> 3] ^= (uint64_t)0x04 << (8 * (state->ctx[25] & 0x07));
|
||||
state->ctx[(SHAKE128_RATE - 1) >> 3] ^= (uint64_t)128 << (8 * ((SHAKE128_RATE - 1) & 0x07));
|
||||
state->ctx[25] = 0;
|
||||
}
|
||||
|
||||
void cshake128_inc_squeeze(uint8_t *output, size_t outlen, shake128incctx *state) {
|
||||
shake128_inc_squeeze(output, outlen, state);
|
||||
}
|
||||
|
||||
void cshake256_inc_init(shake256incctx *state, const uint8_t *name, size_t namelen, const uint8_t *cstm, size_t cstmlen) {
|
||||
uint8_t encbuf[sizeof(size_t)+1];
|
||||
|
||||
shake256_inc_init(state);
|
||||
|
||||
shake256_inc_absorb(state, encbuf, left_encode(encbuf, SHAKE256_RATE));
|
||||
|
||||
shake256_inc_absorb(state, encbuf, left_encode(encbuf, namelen * 8));
|
||||
shake256_inc_absorb(state, name, namelen);
|
||||
|
||||
shake256_inc_absorb(state, encbuf, left_encode(encbuf, cstmlen * 8));
|
||||
shake256_inc_absorb(state, cstm, cstmlen);
|
||||
|
||||
if (state->ctx[25] != 0) {
|
||||
state->ctx[25] = SHAKE256_RATE - 1;
|
||||
encbuf[0] = 0;
|
||||
shake256_inc_absorb(state, encbuf, 1);
|
||||
}
|
||||
}
|
||||
|
||||
void cshake256_inc_absorb(shake256incctx *state, const uint8_t *input, size_t inlen) {
|
||||
shake256_inc_absorb(state, input, inlen);
|
||||
}
|
||||
|
||||
void cshake256_inc_finalize(shake256incctx *state) {
|
||||
state->ctx[state->ctx[25] >> 3] ^= (uint64_t)0x04 << (8 * (state->ctx[25] & 0x07));
|
||||
state->ctx[(SHAKE256_RATE - 1) >> 3] ^= (uint64_t)128 << (8 * ((SHAKE256_RATE - 1) & 0x07));
|
||||
state->ctx[25] = 0;
|
||||
}
|
||||
|
||||
void cshake256_inc_squeeze(uint8_t *output, size_t outlen, shake256incctx *state) {
|
||||
shake256_inc_squeeze(output, outlen, state);
|
||||
}
|
||||
|
||||
/*************************************************
|
||||
* Name: cshake128
|
||||
*
|
||||
* Description: cSHAKE128 XOF with non-incremental API
|
||||
*
|
||||
* Arguments: - uint8_t *output: pointer to output
|
||||
* - size_t outlen: requested output length in bytes
|
||||
* - const uint8_t *name: pointer to function-name string
|
||||
* - size_t namelen: length of function-name string in bytes
|
||||
* - const uint8_t *cstm: pointer to non-empty customization string
|
||||
* - size_t cstmlen: length of customization string in bytes
|
||||
* - const uint8_t *input: pointer to input
|
||||
* - size_t inlen: length of input in bytes
|
||||
**************************************************/
|
||||
void cshake128(uint8_t *output, size_t outlen,
|
||||
const uint8_t *name, size_t namelen,
|
||||
const uint8_t *cstm, size_t cstmlen,
|
||||
const uint8_t *input, size_t inlen) {
|
||||
shake128incctx state;
|
||||
cshake128_inc_init(&state, name, namelen, cstm, cstmlen);
|
||||
cshake128_inc_absorb(&state, input, inlen);
|
||||
cshake128_inc_finalize(&state);
|
||||
cshake128_inc_squeeze(output, outlen, &state);
|
||||
}
|
||||
|
||||
/*************************************************
|
||||
* Name: cshake256
|
||||
*
|
||||
* Description: cSHAKE256 XOF with non-incremental API
|
||||
*
|
||||
* Arguments: - uint8_t *output: pointer to output
|
||||
* - size_t outlen: requested output length in bytes
|
||||
* - const uint8_t *name: pointer to function-name string
|
||||
* - size_t namelen: length of function-name string in bytes
|
||||
* - const uint8_t *cstm: pointer to non-empty customization string
|
||||
* - size_t cstmlen: length of customization string in bytes
|
||||
* - const uint8_t *input: pointer to input
|
||||
* - size_t inlen: length of input in bytes
|
||||
**************************************************/
|
||||
void cshake256(uint8_t *output, size_t outlen,
|
||||
const uint8_t *name, size_t namelen,
|
||||
const uint8_t *cstm, size_t cstmlen,
|
||||
const uint8_t *input, size_t inlen) {
|
||||
shake256incctx state;
|
||||
cshake256_inc_init(&state, name, namelen, cstm, cstmlen);
|
||||
cshake256_inc_absorb(&state, input, inlen);
|
||||
cshake256_inc_finalize(&state);
|
||||
cshake256_inc_squeeze(output, outlen, &state);
|
||||
}
|
||||
@ -1,11 +1,8 @@
|
||||
AUTOMAKE_OPTIONS = foreign
|
||||
check_PROGRAMS = example_kem speed_kem test_kem kat_kem \
|
||||
example_sig speed_sig test_sig
|
||||
if !ENABLE_SHARED
|
||||
check_PROGRAMS += test_aes test_sha3
|
||||
endif
|
||||
example_sig speed_sig test_sig test_aes test_sha3
|
||||
|
||||
LIB_FLAGS=../liboqs.la -lm
|
||||
LIB_FLAGS=-L../.libs -loqs -lm
|
||||
if USE_OPENSSL
|
||||
LIB_FLAGS += -L${OPENSSL_DIR}/lib -lcrypto
|
||||
endif
|
||||
@ -24,8 +21,8 @@ example_kem_LDADD = ${LIB_FLAGS}
|
||||
example_sig_LDADD = ${LIB_FLAGS}
|
||||
speed_kem_LDADD = ${LIB_FLAGS}
|
||||
speed_sig_LDADD = ${LIB_FLAGS}
|
||||
test_aes_LDADD = ${LIB_FLAGS}
|
||||
test_aes_LDADD = ${LIB_FLAGS} ../.libs/liboqs.a
|
||||
test_kem_LDADD = ${LIB_FLAGS}
|
||||
test_sha3_LDADD = ${LIB_FLAGS}
|
||||
test_sha3_LDADD = ${LIB_FLAGS} ../.libs/liboqs.a
|
||||
test_sig_LDADD = ${LIB_FLAGS}
|
||||
kat_kem_LDADD = ${LIB_FLAGS}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
Loading…
x
Reference in New Issue
Block a user