hashes:sha3: Integrate SHA-3 into RIOT API
Add init/update/final interface Add interface functions for direct SHA3 Add unit tests for SHA-3 Document functions and types Reduced var scope in Keccak code Add CCO Copyright notice to Keccak code
This commit is contained in:
parent
a44a313e8f
commit
792137f88d
@ -1,131 +1,197 @@
|
|||||||
/*
|
/*
|
||||||
Implementation by the Keccak, Keyak and Ketje Teams, namely, Guido Bertoni,
|
Implementation by the Keccak, Keyak and Ketje Teams, namely, Guido Bertoni,
|
||||||
Joan Daemen, Michaël Peeters, Gilles Van Assche and Ronny Van Keer, hereby
|
Joan Daemen, Michaël Peeters, Gilles Van Assche and Ronny Van Keer, hereby
|
||||||
denoted as "the implementer".
|
denoted as "the implementer".
|
||||||
|
|
||||||
For more information, feedback or questions, please refer to our websites:
|
For more information, feedback or questions, please refer to our websites:
|
||||||
http://keccak.noekeon.org/
|
http://keccak.noekeon.org/
|
||||||
http://keyak.noekeon.org/
|
http://keyak.noekeon.org/
|
||||||
http://ketje.noekeon.org/
|
http://ketje.noekeon.org/
|
||||||
|
|
||||||
To the extent possible under law, the implementer has waived all copyright
|
To the extent possible under law, the implementer has waived all copyright
|
||||||
and related or neighboring rights to the source code in this file.
|
and related or neighboring rights to the source code in this file.
|
||||||
http://creativecommons.org/publicdomain/zero/1.0/
|
http://creativecommons.org/publicdomain/zero/1.0/
|
||||||
*/
|
|
||||||
|
RIOT OS adaptations by Mathias Tausig
|
||||||
|
|
||||||
|
This software is released under the Creative Commons CC0 1.0 license.
|
||||||
|
To the extent possible under law, the implementer has waived all copyright
|
||||||
|
and related or neighboring rights to the source code in this file.
|
||||||
|
For more information see: http://creativecommons.org/publicdomain/zero/1.0/
|
||||||
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
================================================================
|
================================================================
|
||||||
The purpose of this source file is to demonstrate a readable and compact
|
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,
|
implementation of all the Keccak instances approved in the FIPS 202 standard,
|
||||||
including the hash functions and the extendable-output functions (XOFs).
|
including the hash functions and the extendable-output functions (XOFs).
|
||||||
|
|
||||||
We focused on clarity and on source-code compactness,
|
We focused on clarity and on source-code compactness,
|
||||||
rather than on the performance.
|
rather than on the performance.
|
||||||
|
|
||||||
The advantages of this implementation are:
|
The advantages of this implementation are:
|
||||||
+ The source code is compact, after removing the comments, that is. :-)
|
+ The source code is compact, after removing the comments, that is. :-)
|
||||||
+ There are no tables with arbitrary constants.
|
+ There are no tables with arbitrary constants.
|
||||||
+ For clarity, the comments link the operations to the specifications using
|
+ For clarity, the comments link the operations to the specifications using
|
||||||
the same notation as much as possible.
|
the same notation as much as possible.
|
||||||
+ There is no restriction in cryptographic features. In particular,
|
+ There is no restriction in cryptographic features. In particular,
|
||||||
the SHAKE128 and SHAKE256 XOFs can produce any output length.
|
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 code does not use much RAM, as all operations are done in place.
|
||||||
|
|
||||||
The drawbacks of this implementation are:
|
The drawbacks of this implementation are:
|
||||||
- There is no message queue. The whole message must be ready in a buffer.
|
- There is no message queue. The whole message must be ready in a buffer.
|
||||||
- It is not optimized for peformance.
|
- It is not optimized for peformance.
|
||||||
|
|
||||||
The implementation is even simpler on a little endian platform. Just define the
|
The implementation is even simpler on a little endian platform. Just define the
|
||||||
LITTLE_ENDIAN symbol in that case.
|
LITTLE_ENDIAN symbol in that case.
|
||||||
|
|
||||||
For a more complete set of implementations, please refer to
|
For a more complete set of implementations, please refer to
|
||||||
the Keccak Code Package at https://github.com/gvanas/KeccakCodePackage
|
the Keccak Code Package at https://github.com/gvanas/KeccakCodePackage
|
||||||
|
|
||||||
For more information, please refer to:
|
For more information, please refer to:
|
||||||
* [Keccak Reference] http://keccak.noekeon.org/Keccak-reference-3.0.pdf
|
* [Keccak Reference] http://keccak.noekeon.org/Keccak-reference-3.0.pdf
|
||||||
* [Keccak Specifications Summary] http://keccak.noekeon.org/specs_summary.html
|
* [Keccak Specifications Summary] http://keccak.noekeon.org/specs_summary.html
|
||||||
|
|
||||||
This file uses UTF-8 encoding, as some comments use Greek letters.
|
This file uses UTF-8 encoding, as some comments use Greek letters.
|
||||||
================================================================
|
================================================================
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <hashes/sha3.h>
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Function to compute the Keccak[r, c] sponge function over a given input.
|
* Function to compute the Keccak[r, c] sponge function over a given input.
|
||||||
* @param rate The value of the rate r.
|
* @param rate The value of the rate r.
|
||||||
* @param capacity The value of the capacity c.
|
* @param capacity The value of the capacity c.
|
||||||
* @param input Pointer to the input message.
|
* @param input Pointer to the input message.
|
||||||
* @param inputByteLen The number of input bytes provided in 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
|
* @param delimitedSuffix Bits that will be automatically appended to the end
|
||||||
* of the input message, as in domain separation.
|
* of the input message, as in domain separation.
|
||||||
* This is a byte containing from 0 to 7 bits
|
* This is a byte containing from 0 to 7 bits
|
||||||
* These <i>n</i> bits must be in the least significant bit positions
|
* 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>
|
* 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
|
* (counting from 0=LSB to 7=MSB) and followed by bits 0
|
||||||
* from position <i>n</i>+1 to position 7.
|
* from position <i>n</i>+1 to position 7.
|
||||||
* Some examples:
|
* Some examples:
|
||||||
* - If no bits are to be appended, then @a delimitedSuffix must be 0x01.
|
* - 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 2-bit sequence 0,1 is to be appended (as for SHA3-*),
|
||||||
* - If the 4-bit sequence 1,1,1,1 is to be appended (as for SHAKE*), @a delimitedSuffix must be 0x1F.
|
* @a delimitedSuffix must be 0x06.
|
||||||
* - If the 7-bit sequence 1,1,0,1,0,0,0 is to be absorbed, @a delimitedSuffix must be 0x8B.
|
* - If the 4-bit sequence 1,1,1,1 is to be appended (as for SHAKE*),
|
||||||
* @param output Pointer to the buffer where to store the output.
|
* @a delimitedSuffix must be 0x1F.
|
||||||
* @param outputByteLen The number of output bytes desired.
|
* - If the 7-bit sequence 1,1,0,1,0,0,0 is to be absorbed,
|
||||||
* @pre One must have r+c=1600 and the rate a multiple of 8 bits in this implementation.
|
* @a delimitedSuffix must be 0x8B.
|
||||||
*/
|
* @param output Pointer to the buffer where to store the output.
|
||||||
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);
|
* @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.
|
||||||
|
*/
|
||||||
|
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);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Function to compute SHAKE128 on the input message with any output length.
|
* Function to compute SHAKE128 on the input message with any output length.
|
||||||
*/
|
*/
|
||||||
void FIPS202_SHAKE128(const unsigned char *input, unsigned int inputByteLen, unsigned char *output, int outputByteLen)
|
void FIPS202_SHAKE128(const unsigned char *input, unsigned int inputByteLen, unsigned char *output, int outputByteLen)
|
||||||
{
|
{
|
||||||
Keccak(1344, 256, input, inputByteLen, 0x1F, output, outputByteLen);
|
Keccak(1344, 256, input, inputByteLen, 0x1F, output, outputByteLen);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Function to compute SHAKE256 on the input message with any output length.
|
* Function to compute SHAKE256 on the input message with any output length.
|
||||||
*/
|
*/
|
||||||
void FIPS202_SHAKE256(const unsigned char *input, unsigned int inputByteLen, unsigned char *output, int outputByteLen)
|
void FIPS202_SHAKE256(const unsigned char *input, unsigned int inputByteLen, unsigned char *output, int outputByteLen)
|
||||||
{
|
{
|
||||||
Keccak(1088, 512, input, inputByteLen, 0x1F, output, outputByteLen);
|
Keccak(1088, 512, input, inputByteLen, 0x1F, output, outputByteLen);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Function to compute SHA3-224 on the input message. The output length is fixed to 28 bytes.
|
* Function to compute SHA3-224 on the input message. The output length is fixed to 28 bytes.
|
||||||
*/
|
*/
|
||||||
void FIPS202_SHA3_224(const unsigned char *input, unsigned int inputByteLen, unsigned char *output)
|
void FIPS202_SHA3_224(const unsigned char *input, unsigned int inputByteLen, unsigned char *output)
|
||||||
{
|
{
|
||||||
Keccak(1152, 448, input, inputByteLen, 0x06, output, 28);
|
Keccak(1152, 448, input, inputByteLen, 0x06, output, 28);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Function to compute SHA3-256 on the input message. The output length is fixed to 32 bytes.
|
|
||||||
*/
|
|
||||||
void FIPS202_SHA3_256(const unsigned char *input, unsigned int inputByteLen, unsigned char *output)
|
|
||||||
{
|
|
||||||
Keccak(1088, 512, input, inputByteLen, 0x06, output, 32);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Function to compute SHA3-384 on the input message. The output length is fixed to 48 bytes.
|
* Function to compute SHA3-256 on the input message. The output length is fixed to 32 bytes.
|
||||||
*/
|
*/
|
||||||
void FIPS202_SHA3_384(const unsigned char *input, unsigned int inputByteLen, unsigned char *output)
|
static void FIPS202_SHA3_256(const unsigned char *input, unsigned int inputByteLen, unsigned char *output)
|
||||||
|
{
|
||||||
|
Keccak(1088, 512, input, inputByteLen, 0x06, output, SHA3_256_DIGEST_LENGTH);
|
||||||
|
}
|
||||||
|
|
||||||
|
void sha3_256(void *digest, const void *data, size_t len)
|
||||||
|
{
|
||||||
|
FIPS202_SHA3_256(data, len, digest);
|
||||||
|
}
|
||||||
|
|
||||||
|
void sha3_256_init(keccak_state_t *ctx)
|
||||||
|
{
|
||||||
|
Keccak_init(ctx, 1088, 512, 0x06);
|
||||||
|
}
|
||||||
|
|
||||||
|
void sha3_update(keccak_state_t *ctx, const void *data, size_t len)
|
||||||
|
{
|
||||||
|
Keccak_update(ctx, data, len);
|
||||||
|
}
|
||||||
|
|
||||||
|
void sha3_256_final(keccak_state_t *ctx, void *digest)
|
||||||
|
{
|
||||||
|
Keccak_final(ctx, digest, SHA3_256_DIGEST_LENGTH);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function to compute SHA3-384 on the input message. The output length is fixed to 48 bytes.
|
||||||
|
*/
|
||||||
|
static void FIPS202_SHA3_384(const unsigned char *input, unsigned int inputByteLen, unsigned char *output)
|
||||||
{
|
{
|
||||||
Keccak(832, 768, input, inputByteLen, 0x06, output, 48);
|
Keccak(832, 768, input, inputByteLen, 0x06, output, 48);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void sha3_384(void *digest, const void *data, size_t len)
|
||||||
|
{
|
||||||
|
FIPS202_SHA3_384(data, len, digest);
|
||||||
|
}
|
||||||
|
|
||||||
|
void sha3_384_init(keccak_state_t *ctx)
|
||||||
|
{
|
||||||
|
Keccak_init(ctx, 832, 768, 0x06);
|
||||||
|
}
|
||||||
|
|
||||||
|
void sha3_384_final(keccak_state_t *ctx, void *digest)
|
||||||
|
{
|
||||||
|
Keccak_final(ctx, digest, SHA3_384_DIGEST_LENGTH);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Function to compute SHA3-512 on the input message. The output length is fixed to 64 bytes.
|
* Function to compute SHA3-512 on the input message. The output length is fixed to 64 bytes.
|
||||||
*/
|
*/
|
||||||
void FIPS202_SHA3_512(const unsigned char *input, unsigned int inputByteLen, unsigned char *output)
|
static void FIPS202_SHA3_512(const unsigned char *input, unsigned int inputByteLen, unsigned char *output)
|
||||||
{
|
{
|
||||||
Keccak(576, 1024, input, inputByteLen, 0x06, output, 64);
|
Keccak(576, 1024, input, inputByteLen, 0x06, output, 64);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void sha3_512(void *digest, const void *data, size_t len)
|
||||||
|
{
|
||||||
|
FIPS202_SHA3_512(data, len, digest);
|
||||||
|
}
|
||||||
|
|
||||||
|
void sha3_512_init(keccak_state_t *ctx)
|
||||||
|
{
|
||||||
|
Keccak_init(ctx, 576, 1024, 0x06);
|
||||||
|
}
|
||||||
|
|
||||||
|
void sha3_512_final(keccak_state_t *ctx, void *digest)
|
||||||
|
{
|
||||||
|
Keccak_final(ctx, digest, SHA3_512_DIGEST_LENGTH);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
================================================================
|
================================================================
|
||||||
Technicalities
|
Technicalities
|
||||||
================================================================
|
================================================================
|
||||||
*/
|
*/
|
||||||
|
|
||||||
typedef unsigned char UINT8;
|
typedef unsigned char UINT8;
|
||||||
typedef unsigned long long int UINT64;
|
typedef unsigned long long int UINT64;
|
||||||
@ -133,14 +199,14 @@ typedef UINT64 tKeccakLane;
|
|||||||
|
|
||||||
#ifndef LITTLE_ENDIAN
|
#ifndef LITTLE_ENDIAN
|
||||||
/** Function to load a 64-bit value using the little-endian (LE) convention.
|
/** 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.
|
* On a LE platform, this could be greatly simplified using a cast.
|
||||||
*/
|
*/
|
||||||
static UINT64 load64(const UINT8 *x)
|
static UINT64 load64(const UINT8 *x)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
UINT64 u=0;
|
UINT64 u = 0;
|
||||||
|
|
||||||
for(i=7; i>=0; --i) {
|
for (i = 7; i >= 0; --i) {
|
||||||
u <<= 8;
|
u <<= 8;
|
||||||
u |= x[i];
|
u |= x[i];
|
||||||
}
|
}
|
||||||
@ -148,26 +214,26 @@ static UINT64 load64(const UINT8 *x)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** Function to store a 64-bit value using the little-endian (LE) convention.
|
/** 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.
|
* On a LE platform, this could be greatly simplified using a cast.
|
||||||
*/
|
*/
|
||||||
static void store64(UINT8 *x, UINT64 u)
|
static void store64(UINT8 *x, UINT64 u)
|
||||||
{
|
{
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
|
|
||||||
for(i=0; i<8; ++i) {
|
for (i = 0; i < 8; ++i) {
|
||||||
x[i] = u;
|
x[i] = u;
|
||||||
u >>= 8;
|
u >>= 8;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Function to XOR into a 64-bit value using the little-endian (LE) convention.
|
/** 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.
|
* On a LE platform, this could be greatly simplified using a cast.
|
||||||
*/
|
*/
|
||||||
static void xor64(UINT8 *x, UINT64 u)
|
static void xor64(UINT8 *x, UINT64 u)
|
||||||
{
|
{
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
|
|
||||||
for(i=0; i<8; ++i) {
|
for (i = 0; i < 8; ++i) {
|
||||||
x[i] ^= u;
|
x[i] ^= u;
|
||||||
u >>= 8;
|
u >>= 8;
|
||||||
}
|
}
|
||||||
@ -175,76 +241,80 @@ static void xor64(UINT8 *x, UINT64 u)
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
================================================================
|
================================================================
|
||||||
A readable and compact implementation of the Keccak-f[1600] permutation.
|
A readable and compact implementation of the Keccak-f[1600] permutation.
|
||||||
================================================================
|
================================================================
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define ROL64(a, offset) ((((UINT64)a) << offset) ^ (((UINT64)a) >> (64-offset)))
|
#define ROL64(a, offset) ((((UINT64)a) << offset) ^ (((UINT64)a) >> (64 - offset)))
|
||||||
#define i(x, y) ((x)+5*(y))
|
#define i(x, y) ((x) + 5 * (y))
|
||||||
|
|
||||||
#ifdef LITTLE_ENDIAN
|
#ifdef LITTLE_ENDIAN
|
||||||
#define readLane(x, y) (((tKeccakLane*)state)[i(x, y)])
|
#define readLane(x, y) (((tKeccakLane *)state)[i(x, y)])
|
||||||
#define writeLane(x, y, lane) (((tKeccakLane*)state)[i(x, y)]) = (lane)
|
#define writeLane(x, y, lane) (((tKeccakLane *)state)[i(x, y)]) = (lane)
|
||||||
#define XORLane(x, y, lane) (((tKeccakLane*)state)[i(x, y)]) ^= (lane)
|
#define XORLane(x, y, lane) (((tKeccakLane *)state)[i(x, y)]) ^= (lane)
|
||||||
#else
|
#else
|
||||||
#define readLane(x, y) load64((UINT8*)state+sizeof(tKeccakLane)*i(x, y))
|
#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 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)
|
#define XORLane(x, y, lane) xor64((UINT8 *)state + sizeof(tKeccakLane) * i(x, y), lane)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Function that computes the linear feedback shift register (LFSR) used to
|
* Function that computes the linear feedback shift register (LFSR) used to
|
||||||
* define the round constants (see [Keccak Reference, Section 1.2]).
|
* define the round constants (see [Keccak Reference, Section 1.2]).
|
||||||
*/
|
*/
|
||||||
int LFSR86540(UINT8 *LFSR)
|
static int LFSR86540(UINT8 *LFSR)
|
||||||
{
|
{
|
||||||
int result = ((*LFSR) & 0x01) != 0;
|
int result = ((*LFSR) & 0x01) != 0;
|
||||||
if (((*LFSR) & 0x80) != 0)
|
|
||||||
|
if (((*LFSR) & 0x80) != 0) {
|
||||||
/* Primitive polynomial over GF(2): x^8+x^6+x^5+x^4+1 */
|
/* Primitive polynomial over GF(2): x^8+x^6+x^5+x^4+1 */
|
||||||
(*LFSR) = ((*LFSR) << 1) ^ 0x71;
|
(*LFSR) = ((*LFSR) << 1) ^ 0x71;
|
||||||
else
|
}
|
||||||
|
else {
|
||||||
(*LFSR) <<= 1;
|
(*LFSR) <<= 1;
|
||||||
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Function that computes the Keccak-f[1600] permutation on the given state.
|
* Function that computes the Keccak-f[1600] permutation on the given state.
|
||||||
*/
|
*/
|
||||||
void KeccakF1600_StatePermute(void *state)
|
static void KeccakF1600_StatePermute(void *state)
|
||||||
{
|
{
|
||||||
unsigned int round, x, y, j, t;
|
unsigned int round, x, y, j, t;
|
||||||
UINT8 LFSRstate = 0x01;
|
UINT8 LFSRstate = 0x01;
|
||||||
|
|
||||||
for(round=0; round<24; round++) {
|
for (round = 0; round < 24; round++) {
|
||||||
{ /* === θ step (see [Keccak Reference, Section 2.3.2]) === */
|
{ /* === θ step (see [Keccak Reference, Section 2.3.2]) === */
|
||||||
tKeccakLane C[5], D;
|
tKeccakLane C[5];
|
||||||
|
|
||||||
/* Compute the parity of the columns */
|
/* Compute the parity of the columns */
|
||||||
for(x=0; x<5; x++)
|
for (x = 0; x < 5; x++)
|
||||||
C[x] = readLane(x, 0) ^ readLane(x, 1) ^ readLane(x, 2) ^ readLane(x, 3) ^ readLane(x, 4);
|
C[x] = readLane(x, 0) ^ readLane(x, 1) ^ readLane(x, 2) ^ readLane(x, 3) ^
|
||||||
for(x=0; x<5; x++) {
|
readLane(x, 4);
|
||||||
|
for (x = 0; x < 5; x++) {
|
||||||
/* Compute the θ effect for a given column */
|
/* Compute the θ effect for a given column */
|
||||||
D = C[(x+4)%5] ^ ROL64(C[(x+1)%5], 1);
|
tKeccakLane D = C[(x + 4) % 5] ^ ROL64(C[(x + 1) % 5], 1);
|
||||||
/* Add the θ effect to the whole column */
|
/* Add the θ effect to the whole column */
|
||||||
for (y=0; y<5; y++)
|
for (y = 0; y < 5; y++)
|
||||||
XORLane(x, y, D);
|
XORLane(x, y, D);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
{ /* === ρ and π steps (see [Keccak Reference, Sections 2.3.3 and 2.3.4]) === */
|
{ /* === ρ and π steps (see [Keccak Reference, Sections 2.3.3 and 2.3.4]) === */
|
||||||
tKeccakLane current, temp;
|
tKeccakLane current;
|
||||||
/* Start at coordinates (1 0) */
|
/* Start at coordinates (1 0) */
|
||||||
x = 1; y = 0;
|
x = 1; y = 0;
|
||||||
current = readLane(x, y);
|
current = readLane(x, y);
|
||||||
/* Iterate over ((0 1)(2 3))^t * (1 0) for 0 ≤ t ≤ 23 */
|
/* Iterate over ((0 1)(2 3))^t * (1 0) for 0 ≤ t ≤ 23 */
|
||||||
for(t=0; t<24; t++) {
|
for (t = 0; t < 24; t++) {
|
||||||
/* Compute the rotation constant r = (t+1)(t+2)/2 */
|
/* Compute the rotation constant r = (t+1)(t+2)/2 */
|
||||||
unsigned int r = ((t+1)*(t+2)/2)%64;
|
unsigned int r = ((t + 1) * (t + 2) / 2) % 64;
|
||||||
/* Compute ((0 1)(2 3)) * (x y) */
|
/* Compute ((0 1)(2 3)) * (x y) */
|
||||||
unsigned int Y = (2*x+3*y)%5; x = y; y = Y;
|
unsigned int Y = (2 * x + 3 * y) % 5; x = y; y = Y;
|
||||||
/* Swap current and state(x,y), and rotate */
|
/* Swap current and state(x,y), and rotate */
|
||||||
temp = readLane(x, y);
|
tKeccakLane temp = readLane(x, y);
|
||||||
writeLane(x, y, ROL64(current, r));
|
writeLane(x, y, ROL64(current, r));
|
||||||
current = temp;
|
current = temp;
|
||||||
}
|
}
|
||||||
@ -252,53 +322,58 @@ void KeccakF1600_StatePermute(void *state)
|
|||||||
|
|
||||||
{ /* === χ step (see [Keccak Reference, Section 2.3.1]) === */
|
{ /* === χ step (see [Keccak Reference, Section 2.3.1]) === */
|
||||||
tKeccakLane temp[5];
|
tKeccakLane temp[5];
|
||||||
for(y=0; y<5; y++) {
|
for (y = 0; y < 5; y++) {
|
||||||
/* Take a copy of the plane */
|
/* Take a copy of the plane */
|
||||||
for(x=0; x<5; x++)
|
for (x = 0; x < 5; x++)
|
||||||
temp[x] = readLane(x, y);
|
temp[x] = readLane(x, y);
|
||||||
/* Compute χ on the plane */
|
/* Compute χ on the plane */
|
||||||
for(x=0; x<5; x++)
|
for (x = 0; x < 5; x++)
|
||||||
writeLane(x, y, temp[x] ^((~temp[(x+1)%5]) & temp[(x+2)%5]));
|
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++) {
|
/* === ι step (see [Keccak Reference, Section 2.3.5]) === */
|
||||||
unsigned int bitPosition = (1<<j)-1; /* 2^j-1 */
|
for (j = 0; j < 7; j++) {
|
||||||
if (LFSR86540(&LFSRstate))
|
unsigned int bitPosition = (1 << j) - 1; /* 2^j-1 */
|
||||||
XORLane(0, 0, (tKeccakLane)1<<bitPosition);
|
if (LFSR86540(&LFSRstate)) {
|
||||||
|
XORLane(0, 0, (tKeccakLane)1 << bitPosition);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
================================================================
|
================================================================
|
||||||
A readable and compact implementation of the Keccak sponge functions
|
A readable and compact implementation of the Keccak sponge functions
|
||||||
that use the Keccak-f[1600] permutation.
|
that use the Keccak-f[1600] permutation.
|
||||||
================================================================
|
================================================================
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#define MIN(a, b) ((a) < (b) ? (a) : (b))
|
#define MIN(a, b) ((a) < (b) ? (a) : (b))
|
||||||
|
|
||||||
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)
|
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)
|
||||||
{
|
{
|
||||||
UINT8 state[200];
|
UINT8 state[200];
|
||||||
unsigned int rateInBytes = rate/8;
|
unsigned int rateInBytes = rate / 8;
|
||||||
unsigned int blockSize = 0;
|
unsigned int blockSize = 0;
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
|
|
||||||
if (((rate + capacity) != 1600) || ((rate % 8) != 0))
|
if (((rate + capacity) != 1600) || ((rate % 8) != 0)) {
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
/* === Initialize the state === */
|
/* === Initialize the state === */
|
||||||
memset(state, 0, sizeof(state));
|
memset(state, 0, sizeof(state));
|
||||||
|
|
||||||
/* === Absorb all the input blocks === */
|
/* === Absorb all the input blocks === */
|
||||||
while(inputByteLen > 0) {
|
while (inputByteLen > 0) {
|
||||||
blockSize = MIN(inputByteLen, rateInBytes);
|
blockSize = MIN(inputByteLen, rateInBytes);
|
||||||
for(i=0; i<blockSize; i++)
|
for (i = 0; i < blockSize; i++)
|
||||||
state[i] ^= input[i];
|
state[i] ^= input[i];
|
||||||
input += blockSize;
|
input += blockSize;
|
||||||
inputByteLen -= blockSize;
|
inputByteLen -= blockSize;
|
||||||
@ -310,24 +385,97 @@ void Keccak(unsigned int rate, unsigned int capacity, const unsigned char *input
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* === Do the padding and switch to the squeezing phase === */
|
/* === 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) */
|
/* Absorb the last few bits and add the first bit of padding (which coincides with the
|
||||||
|
delimiter in delimitedSuffix) */
|
||||||
state[blockSize] ^= 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 the first bit of padding is at position rate-1, we need a whole new block for the
|
||||||
if (((delimitedSuffix & 0x80) != 0) && (blockSize == (rateInBytes-1)))
|
second bit of padding */
|
||||||
|
if (((delimitedSuffix & 0x80) != 0) && (blockSize == (rateInBytes - 1))) {
|
||||||
KeccakF1600_StatePermute(state);
|
KeccakF1600_StatePermute(state);
|
||||||
|
}
|
||||||
/* Add the second bit of padding */
|
/* Add the second bit of padding */
|
||||||
state[rateInBytes-1] ^= 0x80;
|
state[rateInBytes - 1] ^= 0x80;
|
||||||
/* Switch to the squeezing phase */
|
/* Switch to the squeezing phase */
|
||||||
KeccakF1600_StatePermute(state);
|
KeccakF1600_StatePermute(state);
|
||||||
|
|
||||||
/* === Squeeze out all the output blocks === */
|
/* === Squeeze out all the output blocks === */
|
||||||
while(outputByteLen > 0) {
|
while (outputByteLen > 0) {
|
||||||
blockSize = MIN(outputByteLen, rateInBytes);
|
blockSize = MIN(outputByteLen, rateInBytes);
|
||||||
memcpy(output, state, blockSize);
|
memcpy(output, state, blockSize);
|
||||||
output += blockSize;
|
output += blockSize;
|
||||||
outputByteLen -= blockSize;
|
outputByteLen -= blockSize;
|
||||||
|
|
||||||
if (outputByteLen > 0)
|
if (outputByteLen > 0) {
|
||||||
KeccakF1600_StatePermute(state);
|
KeccakF1600_StatePermute(state);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Keccak_init(keccak_state_t *ctx, unsigned int rate, unsigned int capacity,
|
||||||
|
unsigned char delimitedSuffix)
|
||||||
|
{
|
||||||
|
ctx->rateInBytes = rate / 8;
|
||||||
|
|
||||||
|
if (((rate + capacity) != 1600) || ((rate % 8) != 0)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* === Initialize the state === */
|
||||||
|
memset(ctx->state, 0, sizeof(ctx->state));
|
||||||
|
ctx->i = 0;
|
||||||
|
|
||||||
|
ctx->rate = rate;
|
||||||
|
ctx->capacity = capacity;
|
||||||
|
ctx->delimitedSuffix = delimitedSuffix;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Keccak_update(keccak_state_t *ctx, const unsigned char *input,
|
||||||
|
unsigned long long int inputByteLen)
|
||||||
|
{
|
||||||
|
/* === Absorb all the input blocks === */
|
||||||
|
while (inputByteLen > 0) {
|
||||||
|
unsigned int blockSize = MIN(inputByteLen + ctx->i, ctx->rateInBytes);
|
||||||
|
while (ctx->i < blockSize) {
|
||||||
|
ctx->state[ctx->i] ^= *input;
|
||||||
|
++(ctx->i);
|
||||||
|
input++;
|
||||||
|
--inputByteLen;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (blockSize == ctx->rateInBytes) {
|
||||||
|
KeccakF1600_StatePermute(ctx->state);
|
||||||
|
blockSize = 0;
|
||||||
|
ctx->i = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Keccak_final(keccak_state_t *ctx, unsigned char *output, unsigned long long int outputByteLen)
|
||||||
|
{
|
||||||
|
|
||||||
|
/* === 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) */
|
||||||
|
ctx->state[ctx->i] ^= ctx->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 (((ctx->delimitedSuffix & 0x80) != 0) && (ctx->i == (ctx->rateInBytes - 1))) {
|
||||||
|
KeccakF1600_StatePermute(ctx->state);
|
||||||
|
}
|
||||||
|
/* Add the second bit of padding */
|
||||||
|
ctx->state[ctx->rateInBytes - 1] ^= 0x80;
|
||||||
|
/* Switch to the squeezing phase */
|
||||||
|
KeccakF1600_StatePermute(ctx->state);
|
||||||
|
|
||||||
|
/* === Squeeze out all the output blocks === */
|
||||||
|
while (outputByteLen > 0) {
|
||||||
|
unsigned int blockSize = MIN(outputByteLen, ctx->rateInBytes);
|
||||||
|
memcpy(output, ctx->state, blockSize);
|
||||||
|
output += blockSize;
|
||||||
|
outputByteLen -= blockSize;
|
||||||
|
|
||||||
|
if (outputByteLen > 0) {
|
||||||
|
KeccakF1600_StatePermute(ctx->state);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
180
sys/include/hashes/sha3.h
Normal file
180
sys/include/hashes/sha3.h
Normal file
@ -0,0 +1,180 @@
|
|||||||
|
/*-
|
||||||
|
* 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".
|
||||||
|
*
|
||||||
|
* RIOT-OS adaptaion by Mathias Tausig
|
||||||
|
*
|
||||||
|
* This software is released under the Creative Commons CC0 1.0 license.
|
||||||
|
* To the extent possible under law, the implementer has waived all copyright
|
||||||
|
* and related or neighboring rights to the source code in this file.
|
||||||
|
* For more information see: http://creativecommons.org/publicdomain/zero/1.0/
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @ingroup sys_hashes
|
||||||
|
* @{
|
||||||
|
*
|
||||||
|
* @file
|
||||||
|
* @brief Header definitions for the SHA-3 hash function
|
||||||
|
*
|
||||||
|
* @author Implementation by the Keccak, Keyak and Ketje Teams (https://keccak.team/)
|
||||||
|
* @author RIOT OS adaptations by Mathias Tausig
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef HASHES_SHA3_H
|
||||||
|
#define HASHES_SHA3_H
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define SHA3_256_DIGEST_LENGTH 32
|
||||||
|
#define SHA3_384_DIGEST_LENGTH 48
|
||||||
|
#define SHA3_512_DIGEST_LENGTH 64
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Context for operations on a sponge with keccak permutation
|
||||||
|
*/
|
||||||
|
typedef struct {
|
||||||
|
/** State of the Keccak sponge */
|
||||||
|
unsigned char state[200];
|
||||||
|
/** Current position within the state */
|
||||||
|
unsigned int i;
|
||||||
|
/** The suffix used for padding */
|
||||||
|
unsigned char delimitedSuffix;
|
||||||
|
/** The bitrate of the sponge */
|
||||||
|
unsigned int rate;
|
||||||
|
/** The capacity in bits of the sponge */
|
||||||
|
unsigned int capacity;
|
||||||
|
/** The rate in bytes of the sponge */
|
||||||
|
unsigned int rateInBytes;
|
||||||
|
} keccak_state_t;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Initialise a sponge based on a keccak-1600 permutation
|
||||||
|
*
|
||||||
|
* @param[out] ctx context handle to initialise
|
||||||
|
* @param[in] rate the desired rate of the sponge
|
||||||
|
* @param[in] capacity the desired capcity of the sponge
|
||||||
|
* @param[in] delimitedSuffix suffix to be appended to the message after the absorbation phase
|
||||||
|
*/
|
||||||
|
void Keccak_init(keccak_state_t *ctx, unsigned int rate, unsigned int capacity,
|
||||||
|
unsigned char delimitedSuffix);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Absorbs data into a sponge. Can be called multiple times
|
||||||
|
*
|
||||||
|
* @param[in,out] ctx context handle of the sponge
|
||||||
|
* @param[in] input pointer to the data to be absorbed
|
||||||
|
* @param[in] inputByteLen length of the input data in bytes
|
||||||
|
*/
|
||||||
|
void Keccak_update(keccak_state_t *ctx, const unsigned char *input,
|
||||||
|
unsigned long long int inputByteLen);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Squeeze data from a sponge
|
||||||
|
*
|
||||||
|
* @param[in,out] ctx context handle of the sponge
|
||||||
|
* @param[out] output the squeezed data
|
||||||
|
* @param[in] outputByteLen size of the data to be squeezed.
|
||||||
|
*/
|
||||||
|
void Keccak_final(keccak_state_t *ctx, unsigned char *output,
|
||||||
|
unsigned long long int outputByteLen);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief SHA-3-256 initialization. Begins a SHA-3-256 operation.
|
||||||
|
*
|
||||||
|
* @param[in] ctx keccak_state_t handle to initialise
|
||||||
|
*/
|
||||||
|
void sha3_256_init(keccak_state_t *ctx);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Add bytes into the hash
|
||||||
|
*
|
||||||
|
* @param[in,out] ctx context handle to use
|
||||||
|
* @param[in] data Input data
|
||||||
|
* @param[in] len Length of @p data
|
||||||
|
*/
|
||||||
|
void sha3_update(keccak_state_t *ctx, const void *data, size_t len);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief SHA-3-256 finalization. Pads the input data and exports the hash value
|
||||||
|
*
|
||||||
|
* @param[in,out] ctx context handle to use
|
||||||
|
* @param[out] digest resulting digest, this is the hash of all the bytes
|
||||||
|
*/
|
||||||
|
void sha3_256_final(keccak_state_t *ctx, void *digest);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief SHA-3-384 initialization. Begins a SHA-3-256 operation.
|
||||||
|
*
|
||||||
|
* @param[in] ctx keccak_state_t handle to initialise
|
||||||
|
*/
|
||||||
|
void sha3_384_init(keccak_state_t *ctx);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief SHA-3-384 finalization. Pads the input data and exports the hash value
|
||||||
|
*
|
||||||
|
* @param[in,out] ctx context handle to use
|
||||||
|
* @param[out] digest resulting digest, this is the hash of all the bytes
|
||||||
|
*/
|
||||||
|
void sha3_384_final(keccak_state_t *ctx, void *digest);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief SHA-3-512 initialization. Begins a SHA-3-256 operation.
|
||||||
|
*
|
||||||
|
* @param[in] ctx keccak_state_t handle to initialise
|
||||||
|
*/
|
||||||
|
void sha3_512_init(keccak_state_t *ctx);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief SHA-3-512 finalization. Pads the input data and exports the hash value
|
||||||
|
*
|
||||||
|
* @param[in,out] ctx context handle to use
|
||||||
|
* @param[out] digest resulting digest, this is the hash of all the bytes
|
||||||
|
*/
|
||||||
|
|
||||||
|
void sha3_512_final(keccak_state_t *ctx, void *digest);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief A wrapper function to simplify the generation of a hash, this is
|
||||||
|
* usefull for generating SHA-3-256 from one buffer
|
||||||
|
*
|
||||||
|
* @param[in] data pointer to the buffer to generate hash from
|
||||||
|
* @param[in] len length of the buffer
|
||||||
|
* @param[out] digest pointer to an array for the result, length must
|
||||||
|
* be SHA3_256_DIGEST_LENGTH
|
||||||
|
*/
|
||||||
|
void sha3_256(void *digest, const void *data, size_t len);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief A wrapper function to simplify the generation of a hash, this is
|
||||||
|
* usefull for generating SHA-3-384 from one buffer
|
||||||
|
*
|
||||||
|
* @param[in] data pointer to the buffer to generate hash from
|
||||||
|
* @param[in] len length of the buffer
|
||||||
|
* @param[out] digest pointer to an array for the result, length must
|
||||||
|
* be SHA3_384_DIGEST_LENGTH
|
||||||
|
*/
|
||||||
|
void sha3_384(void *digest, const void *data, size_t len);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief A wrapper function to simplify the generation of a hash, this is
|
||||||
|
* usefull for generating SHA-3-512 from one buffer
|
||||||
|
*
|
||||||
|
* @param[in] data pointer to the buffer to generate hash from
|
||||||
|
* @param[in] len length of the buffer
|
||||||
|
* @param[out] digest pointer to an array for the result, length must
|
||||||
|
* be SHA3_512_DIGEST_LENGTH
|
||||||
|
*/
|
||||||
|
void sha3_512(void *digest, const void *data, size_t len);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* HASHES_SHA3_H */
|
||||||
|
/** @} */
|
||||||
429
tests/unittests/tests-hashes/tests-hashes-sha3.c
Normal file
429
tests/unittests/tests-hashes/tests-hashes-sha3.c
Normal file
@ -0,0 +1,429 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2017-2018 Mathias Tausig <mathias.tausig@fh-campsuwien.ac.at>
|
||||||
|
*
|
||||||
|
* This file is subject to the terms and conditions of the GNU Lesser
|
||||||
|
* General Public License v2.1. See the file LICENSE in the top level
|
||||||
|
* directory for more details.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @ingroup unittests
|
||||||
|
* @{
|
||||||
|
*
|
||||||
|
* @file
|
||||||
|
* @brief Test cases for the SHA-3 hash implementation
|
||||||
|
*
|
||||||
|
* @author Mathias Tausig <mathias.tausig@fh-campsuwien.ac.at>
|
||||||
|
*
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include "hashes/sha3.h"
|
||||||
|
#include "embUnit/embUnit.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief expected SHA3-256 hash for test 01
|
||||||
|
*
|
||||||
|
* All test values taken from the Keccak code pacakge:
|
||||||
|
* https://github.com/gvanas/KeccakCodePackage
|
||||||
|
* Files: TestVectors/ShortMsgKAT_SHA3-256.txt, TestVectors/ShortMsgKAT_SHA3-384.txt,
|
||||||
|
* TestVectors/ShortMsgKAT_SHA3-512.txt
|
||||||
|
*
|
||||||
|
* * converted using:
|
||||||
|
* s=$(echo '<hash string>' | sed -e 's/../0x&, /g' | sed 's/, $//'); echo {$s}\;
|
||||||
|
*
|
||||||
|
* where <hash string> is the above sequence of characters A7...4A
|
||||||
|
*
|
||||||
|
* msg = ''
|
||||||
|
* md_256 = A7FFC6F8BF1ED76651C14756A061D662F580FF4DE43B49FA82D80A4B80F8434A
|
||||||
|
* md_384 = 0C63A75B845E4F7D01107D852E4C2485C51A50AAAA94FC61995E71BBEE983A2A
|
||||||
|
* C3713831264ADB47FB6BD1E058D5F004
|
||||||
|
* md_512 = A69F73CCA23A9AC5C8B567DC185A756E97C982164FE25859E0D1DCC1475C80A6
|
||||||
|
* 15B2123AF1F5F94C11E3E9402C3AC558F500199D95B6D3E301758586281DCD26
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
static const uint8_t m01[1];
|
||||||
|
size_t m01_len = 0;
|
||||||
|
static const uint8_t m01_1[1];
|
||||||
|
size_t m01_1_len = 0;
|
||||||
|
static const uint8_t m01_2[1];
|
||||||
|
size_t m01_2_len = 0;
|
||||||
|
static const uint8_t h01_256[] = { 0xA7, 0xFF, 0xC6, 0xF8, 0xBF, 0x1E, 0xD7, 0x66,
|
||||||
|
0x51, 0xC1, 0x47, 0x56, 0xA0, 0x61, 0xD6, 0x62,
|
||||||
|
0xF5, 0x80, 0xFF, 0x4D, 0xE4, 0x3B, 0x49, 0xFA,
|
||||||
|
0x82, 0xD8, 0x0A, 0x4B, 0x80, 0xF8, 0x43, 0x4A };
|
||||||
|
static const uint8_t h01_384[] = { 0x0C, 0x63, 0xA7, 0x5B, 0x84, 0x5E, 0x4F, 0x7D,
|
||||||
|
0x01, 0x10, 0x7D, 0x85, 0x2E, 0x4C, 0x24, 0x85,
|
||||||
|
0xC5, 0x1A, 0x50, 0xAA, 0xAA, 0x94, 0xFC, 0x61,
|
||||||
|
0x99, 0x5E, 0x71, 0xBB, 0xEE, 0x98, 0x3A, 0x2A,
|
||||||
|
0xC3, 0x71, 0x38, 0x31, 0x26, 0x4A, 0xDB, 0x47,
|
||||||
|
0xFB, 0x6B, 0xD1, 0xE0, 0x58, 0xD5, 0xF0, 0x04 };
|
||||||
|
static const uint8_t h01_512[] = { 0xA6, 0x9F, 0x73, 0xCC, 0xA2, 0x3A, 0x9A, 0xC5,
|
||||||
|
0xC8, 0xB5, 0x67, 0xDC, 0x18, 0x5A, 0x75, 0x6E,
|
||||||
|
0x97, 0xC9, 0x82, 0x16, 0x4F, 0xE2, 0x58, 0x59,
|
||||||
|
0xE0, 0xD1, 0xDC, 0xC1, 0x47, 0x5C, 0x80, 0xA6,
|
||||||
|
0x15, 0xB2, 0x12, 0x3A, 0xF1, 0xF5, 0xF9, 0x4C,
|
||||||
|
0x11, 0xE3, 0xE9, 0x40, 0x2C, 0x3A, 0xC5, 0x58,
|
||||||
|
0xF5, 0x00, 0x19, 0x9D, 0x95, 0xB6, 0xD3, 0xE3,
|
||||||
|
0x01, 0x75, 0x85, 0x86, 0x28, 0x1D, 0xCD, 0x26 };
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief expected SHA3-256 hash for test 02
|
||||||
|
msg = '4A4F202484512526'
|
||||||
|
md_256 = BA4FB009D57A5CEB85FC64D54E5C55A55854B41CC47AD15294BC41F32165DFBA
|
||||||
|
md_384 = 89DBF4C39B8FB46FDF0A6926CEC0355A4BDBF9C6A446E140B7C8BD08FF6F489F
|
||||||
|
205DAF8EFFE160F437F67491EF897C23
|
||||||
|
md_512 = 150D787D6EB49670C2A4CCD17E6CCE7A04C1FE30FCE03D1EF2501752D92AE04C
|
||||||
|
B345FD42E51038C83B2B4F8FD438D1B4B55CC588C6B913132F1A658FB122CB52
|
||||||
|
*/
|
||||||
|
static const uint8_t m02[] = { 0x4A, 0x4F, 0x20, 0x24, 0x84, 0x51, 0x25, 0x26 };
|
||||||
|
size_t m02_len = sizeof(m02);
|
||||||
|
static const uint8_t m02_1[] = { 0x4A, 0x4F };
|
||||||
|
size_t m02_1_len = sizeof(m02_1);
|
||||||
|
static const uint8_t m02_2[] = { 0x20, 0x24, 0x84, 0x51, 0x25, 0x26 };
|
||||||
|
size_t m02_2_len = sizeof(m02_2);
|
||||||
|
static const uint8_t h02_256[] = { 0xBA, 0x4F, 0xB0, 0x09, 0xD5, 0x7A, 0x5C, 0xEB,
|
||||||
|
0x85, 0xFC, 0x64, 0xD5, 0x4E, 0x5C, 0x55, 0xA5,
|
||||||
|
0x58, 0x54, 0xB4, 0x1C, 0xC4, 0x7A, 0xD1, 0x52,
|
||||||
|
0x94, 0xBC, 0x41, 0xF3, 0x21, 0x65, 0xDF, 0xBA };
|
||||||
|
static const uint8_t h02_384[] = { 0x89, 0xDB, 0xF4, 0xC3, 0x9B, 0x8F, 0xB4, 0x6F,
|
||||||
|
0xDF, 0x0A, 0x69, 0x26, 0xCE, 0xC0, 0x35, 0x5A,
|
||||||
|
0x4B, 0xDB, 0xF9, 0xC6, 0xA4, 0x46, 0xE1, 0x40,
|
||||||
|
0xB7, 0xC8, 0xBD, 0x08, 0xFF, 0x6F, 0x48, 0x9F,
|
||||||
|
0x20, 0x5D, 0xAF, 0x8E, 0xFF, 0xE1, 0x60, 0xF4,
|
||||||
|
0x37, 0xF6, 0x74, 0x91, 0xEF, 0x89, 0x7C, 0x23 };
|
||||||
|
static const uint8_t h02_512[] = { 0x15, 0x0D, 0x78, 0x7D, 0x6E, 0xB4, 0x96, 0x70,
|
||||||
|
0xC2, 0xA4, 0xCC, 0xD1, 0x7E, 0x6C, 0xCE, 0x7A,
|
||||||
|
0x04, 0xC1, 0xFE, 0x30, 0xFC, 0xE0, 0x3D, 0x1E,
|
||||||
|
0xF2, 0x50, 0x17, 0x52, 0xD9, 0x2A, 0xE0, 0x4C,
|
||||||
|
0xB3, 0x45, 0xFD, 0x42, 0xE5, 0x10, 0x38, 0xC8,
|
||||||
|
0x3B, 0x2B, 0x4F, 0x8F, 0xD4, 0x38, 0xD1, 0xB4,
|
||||||
|
0xB5, 0x5C, 0xC5, 0x88, 0xC6, 0xB9, 0x13, 0x13,
|
||||||
|
0x2F, 0x1A, 0x65, 0x8F, 0xB1, 0x22, 0xCB, 0x52 };
|
||||||
|
|
||||||
|
/* @brief expected SHA3-256 hash for test 03
|
||||||
|
msg = '2B6DB7CED8665EBE9DEB080295218426BDAA7C6DA9ADD2088932CDFFBAA1C14129
|
||||||
|
BCCDD70F369EFB149285858D2B1D155D14DE2FDB680A8B027284055182A0CAE275
|
||||||
|
234CC9C92863C1B4AB66F304CF0621CD54565F5BFF461D3B461BD40DF28198E373
|
||||||
|
2501B4860EADD503D26D6E69338F4E0456E9E9BAF3D827AE685FB1D817'
|
||||||
|
md_256 = B7D031AA69B7B4D26A35B896D761314F1D61EB12DCC1E72AAF61B9CD48003AF9
|
||||||
|
md_384 = 8FD01909381EB713803419361D8E82E92476A08EDCC225BB8A135D215CB48D07
|
||||||
|
B074624FCF2E73E666DBA59334719839
|
||||||
|
md_512 = 4FAB45806B4628068458B5D0A2D4BF101B8BFC9276EF86AD5D883765C43F72CE
|
||||||
|
8A5F7B4C5B535A915130BB185E699AB62228014E54DF790C0E93AADBE7E39E19
|
||||||
|
*/
|
||||||
|
static const uint8_t m03[] = { 0x2B, 0x6D, 0xB7, 0xCE, 0xD8, 0x66, 0x5E, 0xBE, 0x9D,
|
||||||
|
0xEB, 0x08, 0x02, 0x95, 0x21, 0x84, 0x26, 0xBD, 0xAA,
|
||||||
|
0x7C, 0x6D, 0xA9, 0xAD, 0xD2, 0x08, 0x89, 0x32, 0xCD,
|
||||||
|
0xFF, 0xBA, 0xA1, 0xC1, 0x41, 0x29, 0xBC, 0xCD, 0xD7,
|
||||||
|
0x0F, 0x36, 0x9E, 0xFB, 0x14, 0x92, 0x85, 0x85, 0x8D,
|
||||||
|
0x2B, 0x1D, 0x15, 0x5D, 0x14, 0xDE, 0x2F, 0xDB, 0x68,
|
||||||
|
0x0A, 0x8B, 0x02, 0x72, 0x84, 0x05, 0x51, 0x82, 0xA0,
|
||||||
|
0xCA, 0xE2, 0x75, 0x23, 0x4C, 0xC9, 0xC9, 0x28, 0x63,
|
||||||
|
0xC1, 0xB4, 0xAB, 0x66, 0xF3, 0x04, 0xCF, 0x06, 0x21,
|
||||||
|
0xCD, 0x54, 0x56, 0x5F, 0x5B, 0xFF, 0x46, 0x1D, 0x3B,
|
||||||
|
0x46, 0x1B, 0xD4, 0x0D, 0xF2, 0x81, 0x98, 0xE3, 0x73,
|
||||||
|
0x25, 0x01, 0xB4, 0x86, 0x0E, 0xAD, 0xD5, 0x03, 0xD2,
|
||||||
|
0x6D, 0x6E, 0x69, 0x33, 0x8F, 0x4E, 0x04, 0x56, 0xE9,
|
||||||
|
0xE9, 0xBA, 0xF3, 0xD8, 0x27, 0xAE, 0x68, 0x5F, 0xB1,
|
||||||
|
0xD8, 0x17 };
|
||||||
|
const size_t m03_len = sizeof(m03);
|
||||||
|
static const uint8_t m03_1[] = { 0x2B, 0x6D, 0xB7, 0xCE, 0xD8, 0x66, 0x5E, 0xBE, 0x9D,
|
||||||
|
0xEB, 0x08, 0x02, 0x95, 0x21, 0x84, 0x26, 0xBD };
|
||||||
|
size_t m03_1_len = sizeof(m03_1);
|
||||||
|
static const uint8_t m03_2[] = { 0xAA, 0x7C, 0x6D, 0xA9, 0xAD, 0xD2, 0x08, 0x89, 0x32,
|
||||||
|
0xCD, 0xFF, 0xBA, 0xA1, 0xC1, 0x41, 0x29, 0xBC, 0xCD,
|
||||||
|
0xD7, 0x0F, 0x36, 0x9E, 0xFB, 0x14, 0x92, 0x85, 0x85,
|
||||||
|
0x8D, 0x2B, 0x1D, 0x15, 0x5D, 0x14, 0xDE, 0x2F, 0xDB,
|
||||||
|
0x68, 0x0A, 0x8B, 0x02, 0x72, 0x84, 0x05, 0x51, 0x82,
|
||||||
|
0xA0, 0xCA, 0xE2, 0x75, 0x23, 0x4C, 0xC9, 0xC9, 0x28,
|
||||||
|
0x63, 0xC1, 0xB4, 0xAB, 0x66, 0xF3, 0x04, 0xCF, 0x06,
|
||||||
|
0x21, 0xCD, 0x54, 0x56, 0x5F, 0x5B, 0xFF, 0x46, 0x1D,
|
||||||
|
0x3B, 0x46, 0x1B, 0xD4, 0x0D, 0xF2, 0x81, 0x98, 0xE3,
|
||||||
|
0x73, 0x25, 0x01, 0xB4, 0x86, 0x0E, 0xAD, 0xD5, 0x03,
|
||||||
|
0xD2, 0x6D, 0x6E, 0x69, 0x33, 0x8F, 0x4E, 0x04, 0x56,
|
||||||
|
0xE9, 0xE9, 0xBA, 0xF3, 0xD8, 0x27, 0xAE, 0x68, 0x5F,
|
||||||
|
0xB1, 0xD8, 0x17 };
|
||||||
|
size_t m03_2_len = sizeof(m03_2);
|
||||||
|
|
||||||
|
|
||||||
|
static const uint8_t h03_256[] = { 0xB7, 0xD0, 0x31, 0xAA, 0x69, 0xB7, 0xB4, 0xD2,
|
||||||
|
0x6A, 0x35, 0xB8, 0x96, 0xD7, 0x61, 0x31, 0x4F,
|
||||||
|
0x1D, 0x61, 0xEB, 0x12, 0xDC, 0xC1, 0xE7, 0x2A,
|
||||||
|
0xAF, 0x61, 0xB9, 0xCD, 0x48, 0x00, 0x3A, 0xF9 };
|
||||||
|
static const uint8_t h03_384[] = { 0x8F, 0xD0, 0x19, 0x09, 0x38, 0x1E, 0xB7, 0x13,
|
||||||
|
0x80, 0x34, 0x19, 0x36, 0x1D, 0x8E, 0x82, 0xE9,
|
||||||
|
0x24, 0x76, 0xA0, 0x8E, 0xDC, 0xC2, 0x25, 0xBB,
|
||||||
|
0x8A, 0x13, 0x5D, 0x21, 0x5C, 0xB4, 0x8D, 0x07,
|
||||||
|
0xB0, 0x74, 0x62, 0x4F, 0xCF, 0x2E, 0x73, 0xE6,
|
||||||
|
0x66, 0xDB, 0xA5, 0x93, 0x34, 0x71, 0x98, 0x39 };
|
||||||
|
static const uint8_t h03_512[] = { 0x4F, 0xAB, 0x45, 0x80, 0x6B, 0x46, 0x28, 0x06,
|
||||||
|
0x84, 0x58, 0xB5, 0xD0, 0xA2, 0xD4, 0xBF, 0x10,
|
||||||
|
0x1B, 0x8B, 0xFC, 0x92, 0x76, 0xEF, 0x86, 0xAD,
|
||||||
|
0x5D, 0x88, 0x37, 0x65, 0xC4, 0x3F, 0x72, 0xCE,
|
||||||
|
0x8A, 0x5F, 0x7B, 0x4C, 0x5B, 0x53, 0x5A, 0x91,
|
||||||
|
0x51, 0x30, 0xBB, 0x18, 0x5E, 0x69, 0x9A, 0xB6,
|
||||||
|
0x22, 0x28, 0x01, 0x4E, 0x54, 0xDF, 0x79, 0x0C,
|
||||||
|
0x0E, 0x93, 0xAA, 0xDB, 0xE7, 0xE3, 0x9E, 0x19 };
|
||||||
|
|
||||||
|
/* @brief expected SHA3-256 hash for test 04
|
||||||
|
msg = '3A3A819C48EFDE2AD914FBF00E18AB6BC4F14513AB27D0C178A188B61431E7F562
|
||||||
|
3CB66B23346775D386B50E982C493ADBBFC54B9A3CD383382336A1A0B2150A1535
|
||||||
|
8F336D03AE18F666C7573D55C4FD181C29E6CCFDE63EA35F0ADF5885CFC0A3D84A
|
||||||
|
2B2E4DD24496DB789E663170CEF74798AA1BBCD4574EA0BBA40489D764B2F83AAD
|
||||||
|
C66B148B4A0CD95246C127D5871C4F11418690A5DDF01246A0C80A43C70088B618
|
||||||
|
3639DCFDA4125BD113A8F49EE23ED306FAAC576C3FB0C1E256671D817FC2534A52
|
||||||
|
F5B439F72E424DE376F4C565CCA82307DD9EF76DA5B7C4EB7E085172E328807C02
|
||||||
|
D011FFBF33785378D79DC266F6A5BE6BB0E4A92ECEEBAEB1'
|
||||||
|
md_256 = C11F3522A8FB7B3532D80B6D40023A92B489ADDAD93BF5D64B23F35E9663521C
|
||||||
|
md_384 = 128DC611762BE9B135B3739484CFAADCA7481D68514F3DFD6F5D78BB1863AE68
|
||||||
|
130835CDC7061A7ED964B32F1DB75EE1
|
||||||
|
md_512 = 6E8B8BD195BDD560689AF2348BDC74AB7CD05ED8B9A57711E9BE71E9726FDA45
|
||||||
|
91FEE12205EDACAF82FFBBAF16DFF9E702A708862080166C2FF6BA379BC7FFC2
|
||||||
|
*/
|
||||||
|
static const uint8_t m04[] = { 0x3A, 0x3A, 0x81, 0x9C, 0x48, 0xEF, 0xDE, 0x2A,
|
||||||
|
0xD9, 0x14, 0xFB, 0xF0, 0x0E, 0x18, 0xAB, 0x6B,
|
||||||
|
0xC4, 0xF1, 0x45, 0x13, 0xAB, 0x27, 0xD0, 0xC1,
|
||||||
|
0x78, 0xA1, 0x88, 0xB6, 0x14, 0x31, 0xE7, 0xF5,
|
||||||
|
0x62, 0x3C, 0xB6, 0x6B, 0x23, 0x34, 0x67, 0x75,
|
||||||
|
0xD3, 0x86, 0xB5, 0x0E, 0x98, 0x2C, 0x49, 0x3A,
|
||||||
|
0xDB, 0xBF, 0xC5, 0x4B, 0x9A, 0x3C, 0xD3, 0x83,
|
||||||
|
0x38, 0x23, 0x36, 0xA1, 0xA0, 0xB2, 0x15, 0x0A,
|
||||||
|
0x15, 0x35, 0x8F, 0x33, 0x6D, 0x03, 0xAE, 0x18,
|
||||||
|
0xF6, 0x66, 0xC7, 0x57, 0x3D, 0x55, 0xC4, 0xFD,
|
||||||
|
0x18, 0x1C, 0x29, 0xE6, 0xCC, 0xFD, 0xE6, 0x3E,
|
||||||
|
0xA3, 0x5F, 0x0A, 0xDF, 0x58, 0x85, 0xCF, 0xC0,
|
||||||
|
0xA3, 0xD8, 0x4A, 0x2B, 0x2E, 0x4D, 0xD2, 0x44,
|
||||||
|
0x96, 0xDB, 0x78, 0x9E, 0x66, 0x31, 0x70, 0xCE,
|
||||||
|
0xF7, 0x47, 0x98, 0xAA, 0x1B, 0xBC, 0xD4, 0x57,
|
||||||
|
0x4E, 0xA0, 0xBB, 0xA4, 0x04, 0x89, 0xD7, 0x64,
|
||||||
|
0xB2, 0xF8, 0x3A, 0xAD, 0xC6, 0x6B, 0x14, 0x8B,
|
||||||
|
0x4A, 0x0C, 0xD9, 0x52, 0x46, 0xC1, 0x27, 0xD5,
|
||||||
|
0x87, 0x1C, 0x4F, 0x11, 0x41, 0x86, 0x90, 0xA5,
|
||||||
|
0xDD, 0xF0, 0x12, 0x46, 0xA0, 0xC8, 0x0A, 0x43,
|
||||||
|
0xC7, 0x00, 0x88, 0xB6, 0x18, 0x36, 0x39, 0xDC,
|
||||||
|
0xFD, 0xA4, 0x12, 0x5B, 0xD1, 0x13, 0xA8, 0xF4,
|
||||||
|
0x9E, 0xE2, 0x3E, 0xD3, 0x06, 0xFA, 0xAC, 0x57,
|
||||||
|
0x6C, 0x3F, 0xB0, 0xC1, 0xE2, 0x56, 0x67, 0x1D,
|
||||||
|
0x81, 0x7F, 0xC2, 0x53, 0x4A, 0x52, 0xF5, 0xB4,
|
||||||
|
0x39, 0xF7, 0x2E, 0x42, 0x4D, 0xE3, 0x76, 0xF4,
|
||||||
|
0xC5, 0x65, 0xCC, 0xA8, 0x23, 0x07, 0xDD, 0x9E,
|
||||||
|
0xF7, 0x6D, 0xA5, 0xB7, 0xC4, 0xEB, 0x7E, 0x08,
|
||||||
|
0x51, 0x72, 0xE3, 0x28, 0x80, 0x7C, 0x02, 0xD0,
|
||||||
|
0x11, 0xFF, 0xBF, 0x33, 0x78, 0x53, 0x78, 0xD7,
|
||||||
|
0x9D, 0xC2, 0x66, 0xF6, 0xA5, 0xBE, 0x6B, 0xB0,
|
||||||
|
0xE4, 0xA9, 0x2E, 0xCE, 0xEB, 0xAE, 0xB1 };
|
||||||
|
size_t m04_len = sizeof(m04);
|
||||||
|
static const uint8_t m04_1[] = { 0x3A, 0x3A, 0x81, 0x9C, 0x48, 0xEF, 0xDE, 0x2A,
|
||||||
|
0xD9, 0x14, 0xFB, 0xF0, 0x0E, 0x18, 0xAB, 0x6B,
|
||||||
|
0xC4, 0xF1, 0x45, 0x13, 0xAB, 0x27, 0xD0, 0xC1,
|
||||||
|
0x78, 0xA1, 0x88, 0xB6, 0x14, 0x31, 0xE7, 0xF5,
|
||||||
|
0x62, 0x3C, 0xB6, 0x6B, 0x23, 0x34, 0x67, 0x75,
|
||||||
|
0xD3, 0x86, 0xB5, 0x0E, 0x98, 0x2C, 0x49, 0x3A,
|
||||||
|
0xDB, 0xBF, 0xC5, 0x4B, 0x9A, 0x3C, 0xD3, 0x83,
|
||||||
|
0x38, 0x23, 0x36, 0xA1, 0xA0, 0xB2, 0x15, 0x0A,
|
||||||
|
0x15, 0x35, 0x8F, 0x33, 0x6D, 0x03, 0xAE, 0x18,
|
||||||
|
0xF6, 0x66, 0xC7, 0x57, 0x3D, 0x55, 0xC4, 0xFD,
|
||||||
|
0x18, 0x1C, 0x29, 0xE6, 0xCC, 0xFD, 0xE6, 0x3E,
|
||||||
|
0xA3, 0x5F, 0x0A, 0xDF, 0x58, 0x85, 0xCF, 0xC0,
|
||||||
|
0xA3, 0xD8, 0x4A, 0x2B, 0x2E, 0x4D, 0xD2, 0x44,
|
||||||
|
0x96, 0xDB, 0x78, 0x9E, 0x66, 0x31, 0x70, 0xCE,
|
||||||
|
0xF7, 0x47, 0x98, 0xAA, 0x1B, 0xBC, 0xD4, 0x57,
|
||||||
|
0x4E, 0xA0, 0xBB, 0xA4, 0x04, 0x89, 0xD7, 0x64,
|
||||||
|
0xB2, 0xF8, 0x3A, 0xAD, 0xC6, 0x6B, 0x14, 0x8B,
|
||||||
|
0x4A, 0x0C, 0xD9, 0x52, 0x46, 0xC1, 0x27, 0xD5,
|
||||||
|
0x87, 0x1C, 0x4F, 0x11, 0x41, 0x86, 0x90, 0xA5,
|
||||||
|
0xDD, 0xF0, 0x12, 0x46, 0xA0, 0xC8, 0x0A, 0x43,
|
||||||
|
0xC7, 0x00, 0x88, 0xB6, 0x18, 0x36, 0x39, 0xDC,
|
||||||
|
0xFD, 0xA4, 0x12, 0x5B, 0xD1, 0x13, 0xA8, 0xF4,
|
||||||
|
0x9E, 0xE2, 0x3E, 0xD3, 0x06, 0xFA, 0xAC, 0x57,
|
||||||
|
0x6C, 0x3F, 0xB0, 0xC1, 0xE2, 0x56, 0x67, 0x1D,
|
||||||
|
0x81, 0x7F, 0xC2, 0x53, 0x4A, 0x52, 0xF5, 0xB4,
|
||||||
|
0x39, 0xF7, 0x2E, 0x42, 0x4D, 0xE3, 0x76, 0xF4,
|
||||||
|
0xC5, 0x65, 0xCC, 0xA8, 0x23, 0x07, 0xDD, 0x9E,
|
||||||
|
0xF7, 0x6D, 0xA5, 0xB7, 0xC4, 0xEB, 0x7E, 0x08,
|
||||||
|
0x51, 0x72, 0xE3, 0x28, 0x80, 0x7C, 0x02, 0xD0,
|
||||||
|
0x11, 0xFF, 0xBF, 0x33, 0x78, 0x53, 0x78, 0xD7,
|
||||||
|
0x9D, 0xC2, 0x66, 0xF6, 0xA5, 0xBE, 0x6B, 0xB0 };
|
||||||
|
|
||||||
|
size_t m04_1_len = sizeof(m04_1);
|
||||||
|
static const uint8_t m04_2[] = { 0xE4, 0xA9, 0x2E, 0xCE, 0xEB, 0xAE, 0xB1 };
|
||||||
|
size_t m04_2_len = sizeof(m04_2);
|
||||||
|
|
||||||
|
static const uint8_t h04_256[] = { 0xC1, 0x1F, 0x35, 0x22, 0xA8, 0xFB, 0x7B, 0x35,
|
||||||
|
0x32, 0xD8, 0x0B, 0x6D, 0x40, 0x02, 0x3A, 0x92,
|
||||||
|
0xB4, 0x89, 0xAD, 0xDA, 0xD9, 0x3B, 0xF5, 0xD6,
|
||||||
|
0x4B, 0x23, 0xF3, 0x5E, 0x96, 0x63, 0x52, 0x1C };
|
||||||
|
static const uint8_t h04_384[] = { 0x12, 0x8D, 0xC6, 0x11, 0x76, 0x2B, 0xE9, 0xB1,
|
||||||
|
0x35, 0xB3, 0x73, 0x94, 0x84, 0xCF, 0xAA, 0xDC,
|
||||||
|
0xA7, 0x48, 0x1D, 0x68, 0x51, 0x4F, 0x3D, 0xFD,
|
||||||
|
0x6F, 0x5D, 0x78, 0xBB, 0x18, 0x63, 0xAE, 0x68,
|
||||||
|
0x13, 0x08, 0x35, 0xCD, 0xC7, 0x06, 0x1A, 0x7E,
|
||||||
|
0xD9, 0x64, 0xB3, 0x2F, 0x1D, 0xB7, 0x5E, 0xE1 };
|
||||||
|
static const uint8_t h04_512[] = { 0x6E, 0x8B, 0x8B, 0xD1, 0x95, 0xBD, 0xD5, 0x60,
|
||||||
|
0x68, 0x9A, 0xF2, 0x34, 0x8B, 0xDC, 0x74, 0xAB,
|
||||||
|
0x7C, 0xD0, 0x5E, 0xD8, 0xB9, 0xA5, 0x77, 0x11,
|
||||||
|
0xE9, 0xBE, 0x71, 0xE9, 0x72, 0x6F, 0xDA, 0x45,
|
||||||
|
0x91, 0xFE, 0xE1, 0x22, 0x05, 0xED, 0xAC, 0xAF,
|
||||||
|
0x82, 0xFF, 0xBB, 0xAF, 0x16, 0xDF, 0xF9, 0xE7,
|
||||||
|
0x02, 0xA7, 0x08, 0x86, 0x20, 0x80, 0x16, 0x6C,
|
||||||
|
0x2F, 0xF6, 0xBA, 0x37, 0x9B, 0xC7, 0xFF, 0xC2 };
|
||||||
|
|
||||||
|
static const uint8_t mfail[] = { 0x4A, 0x4F, 0x20, 0x24, 0x84, 0x51, 0x25, 0x27 };
|
||||||
|
size_t mfail_len = sizeof(mfail);
|
||||||
|
static const uint8_t hfail_256[] = { 0xBA, 0x4F, 0xB0, 0x09, 0xD5, 0x7A, 0x5C, 0xEB,
|
||||||
|
0x85, 0xFC, 0x64, 0xD5, 0x4E, 0x5C, 0x55, 0xA5,
|
||||||
|
0x58, 0x54, 0xB4, 0x1C, 0xC4, 0x7A, 0xD1, 0x52,
|
||||||
|
0x94, 0xBC, 0x41, 0xF3, 0x21, 0x65, 0xDF, 0xBA };
|
||||||
|
static const uint8_t hfail_384[] = { 0x89, 0xDB, 0xF4, 0xC3, 0x9B, 0x8F, 0xB4, 0x6F,
|
||||||
|
0xDF, 0x0A, 0x69, 0x26, 0xCE, 0xC0, 0x35, 0x5A,
|
||||||
|
0x4B, 0xDB, 0xF9, 0xC6, 0xA4, 0x46, 0xE1, 0x40,
|
||||||
|
0xB7, 0xC8, 0xBD, 0x08, 0xFF, 0x6F, 0x48, 0x9F,
|
||||||
|
0x20, 0x5D, 0xAF, 0x8E, 0xFF, 0xE1, 0x60, 0xF4,
|
||||||
|
0x37, 0xF6, 0x74, 0x91, 0xEF, 0x89, 0x7C, 0x23 };
|
||||||
|
static const uint8_t hfail_512[] = { 0x15, 0x0D, 0x78, 0x7D, 0x6E, 0xB4, 0x96, 0x70,
|
||||||
|
0xC2, 0xA4, 0xCC, 0xD1, 0x7E, 0x6C, 0xCE, 0x7A,
|
||||||
|
0x04, 0xC1, 0xFE, 0x30, 0xFC, 0xE0, 0x3D, 0x1E,
|
||||||
|
0xF2, 0x50, 0x17, 0x52, 0xD9, 0x2A, 0xE0, 0x4C,
|
||||||
|
0xB3, 0x45, 0xFD, 0x42, 0xE5, 0x10, 0x38, 0xC8,
|
||||||
|
0x3B, 0x2B, 0x4F, 0x8F, 0xD4, 0x38, 0xD1, 0xB4,
|
||||||
|
0xB5, 0x5C, 0xC5, 0x88, 0xC6, 0xB9, 0x13, 0x13,
|
||||||
|
0x2F, 0x1A, 0x65, 0x8F, 0xB1, 0x22, 0xCB, 0x52 };
|
||||||
|
|
||||||
|
|
||||||
|
static int calc_and_compare_hash_256(const uint8_t *msg, size_t msg_len, const uint8_t *expected)
|
||||||
|
{
|
||||||
|
static unsigned char hash[SHA3_256_DIGEST_LENGTH];
|
||||||
|
|
||||||
|
sha3_256(hash, msg, msg_len);
|
||||||
|
|
||||||
|
return (memcmp(expected, hash, sizeof(hash)) == 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int calc_steps_and_compare_hash_256(const uint8_t *msg1, size_t msg1_len,
|
||||||
|
const uint8_t *msg2, size_t msg2_len, const uint8_t *expected)
|
||||||
|
{
|
||||||
|
static unsigned char hash[SHA3_256_DIGEST_LENGTH];
|
||||||
|
keccak_state_t state;
|
||||||
|
|
||||||
|
sha3_256_init(&state);
|
||||||
|
sha3_update(&state, msg1, msg1_len);
|
||||||
|
sha3_update(&state, msg2, msg2_len);
|
||||||
|
sha3_256_final(&state, hash);
|
||||||
|
|
||||||
|
return (memcmp(expected, hash, sizeof(hash)) == 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int calc_and_compare_hash_384(const uint8_t *msg, size_t msg_len, const uint8_t *expected)
|
||||||
|
{
|
||||||
|
static unsigned char hash[SHA3_384_DIGEST_LENGTH];
|
||||||
|
|
||||||
|
sha3_384(hash, msg, msg_len);
|
||||||
|
|
||||||
|
return (memcmp(expected, hash, sizeof(hash)) == 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int calc_steps_and_compare_hash_384(const uint8_t *msg1, size_t msg1_len,
|
||||||
|
const uint8_t *msg2, size_t msg2_len, const uint8_t *expected)
|
||||||
|
{
|
||||||
|
static unsigned char hash[SHA3_384_DIGEST_LENGTH];
|
||||||
|
keccak_state_t state;
|
||||||
|
|
||||||
|
sha3_384_init(&state);
|
||||||
|
sha3_update(&state, msg1, msg1_len);
|
||||||
|
sha3_update(&state, msg2, msg2_len);
|
||||||
|
sha3_384_final(&state, hash);
|
||||||
|
|
||||||
|
return (memcmp(expected, hash, sizeof(hash)) == 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int calc_and_compare_hash_512(const uint8_t *msg, size_t msg_len, const uint8_t *expected)
|
||||||
|
{
|
||||||
|
static unsigned char hash[SHA3_512_DIGEST_LENGTH];
|
||||||
|
|
||||||
|
sha3_512(hash, msg, msg_len);
|
||||||
|
|
||||||
|
return (memcmp(expected, hash, sizeof(hash)) == 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int calc_steps_and_compare_hash_512(const uint8_t *msg1, size_t msg1_len,
|
||||||
|
const uint8_t *msg2, size_t msg2_len, const uint8_t *expected)
|
||||||
|
{
|
||||||
|
static unsigned char hash[SHA3_512_DIGEST_LENGTH];
|
||||||
|
keccak_state_t state;
|
||||||
|
|
||||||
|
sha3_512_init(&state);
|
||||||
|
sha3_update(&state, msg1, msg1_len);
|
||||||
|
sha3_update(&state, msg2, msg2_len);
|
||||||
|
sha3_512_final(&state, hash);
|
||||||
|
|
||||||
|
return (memcmp(expected, hash, sizeof(hash)) == 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void test_hashes_sha3_hash_sequence_01(void)
|
||||||
|
{
|
||||||
|
TEST_ASSERT(calc_and_compare_hash_256(m01, m01_len, h01_256));
|
||||||
|
TEST_ASSERT(calc_steps_and_compare_hash_256(m01_1, m01_1_len, m01_2, m01_2_len, h01_256));
|
||||||
|
TEST_ASSERT(calc_and_compare_hash_384(m01, m01_len, h01_384));
|
||||||
|
TEST_ASSERT(calc_steps_and_compare_hash_384(m01_1, m01_1_len, m01_2, m01_2_len, h01_384));
|
||||||
|
TEST_ASSERT(calc_and_compare_hash_512(m01, m01_len, h01_512));
|
||||||
|
TEST_ASSERT(calc_steps_and_compare_hash_512(m01_1, m01_1_len, m01_2, m01_2_len, h01_512));
|
||||||
|
}
|
||||||
|
static void test_hashes_sha3_hash_sequence_02(void)
|
||||||
|
{
|
||||||
|
TEST_ASSERT(calc_and_compare_hash_256(m02, m02_len, h02_256));
|
||||||
|
TEST_ASSERT(calc_steps_and_compare_hash_256(m02_1, m02_1_len, m02_2, m02_2_len, h02_256));
|
||||||
|
TEST_ASSERT(calc_and_compare_hash_384(m02, m02_len, h02_384));
|
||||||
|
TEST_ASSERT(calc_steps_and_compare_hash_384(m02_1, m02_1_len, m02_2, m02_2_len, h02_384));
|
||||||
|
TEST_ASSERT(calc_and_compare_hash_512(m02, m02_len, h02_512));
|
||||||
|
TEST_ASSERT(calc_steps_and_compare_hash_512(m02_1, m02_1_len, m02_2, m02_2_len, h02_512));
|
||||||
|
}
|
||||||
|
|
||||||
|
static void test_hashes_sha3_hash_sequence_03(void)
|
||||||
|
{
|
||||||
|
TEST_ASSERT(calc_and_compare_hash_256(m03, m03_len, h03_256));
|
||||||
|
TEST_ASSERT(calc_steps_and_compare_hash_256(m03_1, m03_1_len, m03_2, m03_2_len, h03_256));
|
||||||
|
TEST_ASSERT(calc_and_compare_hash_384(m03, m03_len, h03_384));
|
||||||
|
TEST_ASSERT(calc_steps_and_compare_hash_384(m03_1, m03_1_len, m03_2, m03_2_len, h03_384));
|
||||||
|
TEST_ASSERT(calc_and_compare_hash_512(m03, m03_len, h03_512));
|
||||||
|
TEST_ASSERT(calc_steps_and_compare_hash_512(m03_1, m03_1_len, m03_2, m03_2_len, h03_512));
|
||||||
|
}
|
||||||
|
|
||||||
|
static void test_hashes_sha3_hash_sequence_04(void)
|
||||||
|
{
|
||||||
|
TEST_ASSERT(calc_and_compare_hash_256(m04, m04_len, h04_256));
|
||||||
|
TEST_ASSERT(calc_steps_and_compare_hash_256(m04_1, m04_1_len, m04_2, m04_2_len, h04_256));
|
||||||
|
TEST_ASSERT(calc_and_compare_hash_384(m04, m04_len, h04_384));
|
||||||
|
TEST_ASSERT(calc_steps_and_compare_hash_384(m04_1, m04_1_len, m04_2, m04_2_len, h04_384));
|
||||||
|
TEST_ASSERT(calc_and_compare_hash_512(m04, m04_len, h04_512));
|
||||||
|
TEST_ASSERT(calc_steps_and_compare_hash_512(m04_1, m04_1_len, m04_2, m04_2_len, h04_512));
|
||||||
|
}
|
||||||
|
|
||||||
|
static void test_hashes_sha3_hash_sequence_failing_compare(void)
|
||||||
|
{
|
||||||
|
/* failing compare (message from testcase 02 alterered slightly) */
|
||||||
|
TEST_ASSERT(!calc_and_compare_hash_256(mfail, mfail_len, hfail_256));
|
||||||
|
TEST_ASSERT(!calc_and_compare_hash_384(mfail, mfail_len, hfail_384));
|
||||||
|
TEST_ASSERT(!calc_and_compare_hash_512(mfail, mfail_len, hfail_512));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Test *tests_hashes_sha3_tests(void)
|
||||||
|
{
|
||||||
|
EMB_UNIT_TESTFIXTURES(fixtures) {
|
||||||
|
new_TestFixture(test_hashes_sha3_hash_sequence_01),
|
||||||
|
new_TestFixture(test_hashes_sha3_hash_sequence_02),
|
||||||
|
new_TestFixture(test_hashes_sha3_hash_sequence_03),
|
||||||
|
new_TestFixture(test_hashes_sha3_hash_sequence_04),
|
||||||
|
new_TestFixture(test_hashes_sha3_hash_sequence_failing_compare),
|
||||||
|
};
|
||||||
|
|
||||||
|
EMB_UNIT_TESTCALLER(hashes_sha3_tests, NULL, NULL,
|
||||||
|
fixtures);
|
||||||
|
|
||||||
|
return (Test *)&hashes_sha3_tests;
|
||||||
|
}
|
||||||
@ -28,4 +28,5 @@ void tests_hashes(void)
|
|||||||
TESTS_RUN(tests_hashes_sha256_tests());
|
TESTS_RUN(tests_hashes_sha256_tests());
|
||||||
TESTS_RUN(tests_hashes_sha256_hmac_tests());
|
TESTS_RUN(tests_hashes_sha256_hmac_tests());
|
||||||
TESTS_RUN(tests_hashes_sha256_chain_tests());
|
TESTS_RUN(tests_hashes_sha256_chain_tests());
|
||||||
|
TESTS_RUN(tests_hashes_sha3_tests());
|
||||||
}
|
}
|
||||||
|
|||||||
@ -72,6 +72,13 @@ Test *tests_hashes_sha256_hmac_tests(void);
|
|||||||
*/
|
*/
|
||||||
Test *tests_hashes_sha256_chain_tests(void);
|
Test *tests_hashes_sha256_chain_tests(void);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Generates tests for hashes/sha3.h
|
||||||
|
*
|
||||||
|
* @return embUnit tests if successful, NULL if not.
|
||||||
|
*/
|
||||||
|
Test *tests_hashes_sha3_tests(void);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user