commit
336ea60a36
165
common/fips202.c
165
common/fips202.c
@ -5,10 +5,11 @@
|
|||||||
* from https://twitter.com/tweetfips202
|
* from https://twitter.com/tweetfips202
|
||||||
* by Gilles Van Assche, Daniel J. Bernstein, and Peter Schwabe */
|
* by Gilles Van Assche, Daniel J. Bernstein, and Peter Schwabe */
|
||||||
|
|
||||||
#include "fips202.h"
|
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#include "fips202.h"
|
||||||
|
|
||||||
#define NROUNDS 24
|
#define NROUNDS 24
|
||||||
#define ROL(a, offset) (((a) << (offset)) ^ ((a) >> (64 - (offset))))
|
#define ROL(a, offset) (((a) << (offset)) ^ ((a) >> (64 - (offset))))
|
||||||
|
|
||||||
@ -17,15 +18,13 @@
|
|||||||
*
|
*
|
||||||
* Description: Load 8 bytes into uint64_t in little-endian order
|
* Description: Load 8 bytes into uint64_t in little-endian order
|
||||||
*
|
*
|
||||||
* Arguments: - const unsigned char *x: pointer to input byte array
|
* Arguments: - const uint8_t *x: pointer to input byte array
|
||||||
*
|
*
|
||||||
* Returns the loaded 64-bit unsigned integer
|
* Returns the loaded 64-bit unsigned integer
|
||||||
**************************************************/
|
**************************************************/
|
||||||
static uint64_t load64(const unsigned char *x) {
|
static uint64_t load64(const uint8_t *x) {
|
||||||
unsigned int i;
|
|
||||||
uint64_t r = 0;
|
uint64_t r = 0;
|
||||||
|
for (size_t i = 0; i < 8; ++i) {
|
||||||
for (i = 0; i < 8; ++i) {
|
|
||||||
r |= (uint64_t)x[i] << 8 * i;
|
r |= (uint64_t)x[i] << 8 * i;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -41,27 +40,25 @@ static uint64_t load64(const unsigned char *x) {
|
|||||||
* - uint64_t u: input 64-bit unsigned integer
|
* - uint64_t u: input 64-bit unsigned integer
|
||||||
**************************************************/
|
**************************************************/
|
||||||
static void store64(uint8_t *x, uint64_t u) {
|
static void store64(uint8_t *x, uint64_t u) {
|
||||||
unsigned int i;
|
for (size_t i = 0; i < 8; ++i) {
|
||||||
|
|
||||||
for (i = 0; i < 8; ++i) {
|
|
||||||
x[i] = u >> 8 * i;
|
x[i] = u >> 8 * i;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Keccak round constants */
|
/* Keccak round constants */
|
||||||
static const uint64_t KeccakF_RoundConstants[NROUNDS] = {
|
static const uint64_t KeccakF_RoundConstants[NROUNDS] = {
|
||||||
(uint64_t)0x0000000000000001ULL, (uint64_t)0x0000000000008082ULL,
|
0x0000000000000001ULL, 0x0000000000008082ULL,
|
||||||
(uint64_t)0x800000000000808aULL, (uint64_t)0x8000000080008000ULL,
|
0x800000000000808aULL, 0x8000000080008000ULL,
|
||||||
(uint64_t)0x000000000000808bULL, (uint64_t)0x0000000080000001ULL,
|
0x000000000000808bULL, 0x0000000080000001ULL,
|
||||||
(uint64_t)0x8000000080008081ULL, (uint64_t)0x8000000000008009ULL,
|
0x8000000080008081ULL, 0x8000000000008009ULL,
|
||||||
(uint64_t)0x000000000000008aULL, (uint64_t)0x0000000000000088ULL,
|
0x000000000000008aULL, 0x0000000000000088ULL,
|
||||||
(uint64_t)0x0000000080008009ULL, (uint64_t)0x000000008000000aULL,
|
0x0000000080008009ULL, 0x000000008000000aULL,
|
||||||
(uint64_t)0x000000008000808bULL, (uint64_t)0x800000000000008bULL,
|
0x000000008000808bULL, 0x800000000000008bULL,
|
||||||
(uint64_t)0x8000000000008089ULL, (uint64_t)0x8000000000008003ULL,
|
0x8000000000008089ULL, 0x8000000000008003ULL,
|
||||||
(uint64_t)0x8000000000008002ULL, (uint64_t)0x8000000000000080ULL,
|
0x8000000000008002ULL, 0x8000000000000080ULL,
|
||||||
(uint64_t)0x000000000000800aULL, (uint64_t)0x800000008000000aULL,
|
0x000000000000800aULL, 0x800000008000000aULL,
|
||||||
(uint64_t)0x8000000080008081ULL, (uint64_t)0x8000000000008080ULL,
|
0x8000000080008081ULL, 0x8000000000008080ULL,
|
||||||
(uint64_t)0x0000000080000001ULL, (uint64_t)0x8000000080008008ULL
|
0x0000000080000001ULL, 0x8000000080008008ULL
|
||||||
};
|
};
|
||||||
|
|
||||||
/*************************************************
|
/*************************************************
|
||||||
@ -341,16 +338,16 @@ static void KeccakF1600_StatePermute(uint64_t *state) {
|
|||||||
* non-incremental, starts by zeroeing the state.
|
* non-incremental, starts by zeroeing the state.
|
||||||
*
|
*
|
||||||
* Arguments: - uint64_t *s: pointer to (uninitialized) output Keccak state
|
* Arguments: - uint64_t *s: pointer to (uninitialized) output Keccak state
|
||||||
* - unsigned int r: rate in bytes (e.g., 168 for SHAKE128)
|
* - uint32_t r: rate in bytes (e.g., 168 for SHAKE128)
|
||||||
* - const unsigned char *m: pointer to input to be absorbed into s
|
* - const uint8_t *m: pointer to input to be absorbed into s
|
||||||
* - unsigned long long mlen: length of input in bytes
|
* - size_t mlen: length of input in bytes
|
||||||
* - unsigned char p: domain-separation byte for different
|
* - uint8_t p: domain-separation byte for different
|
||||||
* Keccak-derived functions
|
* Keccak-derived functions
|
||||||
**************************************************/
|
**************************************************/
|
||||||
static void keccak_absorb(uint64_t *s, unsigned int r, const unsigned char *m,
|
static void keccak_absorb(uint64_t *s, uint32_t r, const uint8_t *m,
|
||||||
unsigned long long mlen, unsigned char p) {
|
size_t mlen, uint8_t p) {
|
||||||
unsigned int i;
|
size_t i;
|
||||||
unsigned char t[200];
|
uint8_t t[200];
|
||||||
|
|
||||||
/* Zero state */
|
/* Zero state */
|
||||||
for (i = 0; i < 25; ++i) {
|
for (i = 0; i < 25; ++i) {
|
||||||
@ -387,19 +384,17 @@ static void keccak_absorb(uint64_t *s, unsigned int r, const unsigned char *m,
|
|||||||
* Modifies the state. Can be called multiple times to keep
|
* Modifies the state. Can be called multiple times to keep
|
||||||
* squeezing, i.e., is incremental.
|
* squeezing, i.e., is incremental.
|
||||||
*
|
*
|
||||||
* Arguments: - unsigned char *h: pointer to output blocks
|
* Arguments: - uint8_t *h: pointer to output blocks
|
||||||
* - unsigned long long int nblocks: number of blocks to be
|
* - size_t nblocks: number of blocks to be
|
||||||
* squeezed (written to h)
|
* squeezed (written to h)
|
||||||
* - uint64_t *s: pointer to input/output Keccak state
|
* - uint64_t *s: pointer to input/output Keccak state
|
||||||
* - unsigned int r: rate in bytes (e.g., 168 for SHAKE128)
|
* - uint32_t r: rate in bytes (e.g., 168 for SHAKE128)
|
||||||
**************************************************/
|
**************************************************/
|
||||||
static void keccak_squeezeblocks(unsigned char *h, unsigned long nblocks,
|
static void keccak_squeezeblocks(uint8_t *h, size_t nblocks,
|
||||||
uint64_t *s, unsigned int r) {
|
uint64_t *s, uint32_t r) {
|
||||||
unsigned int i;
|
|
||||||
|
|
||||||
while (nblocks > 0) {
|
while (nblocks > 0) {
|
||||||
KeccakF1600_StatePermute(s);
|
KeccakF1600_StatePermute(s);
|
||||||
for (i = 0; i < (r >> 3); i++) {
|
for (size_t i = 0; i < (r >> 3); i++) {
|
||||||
store64(h + 8 * i, s[i]);
|
store64(h + 8 * i, s[i]);
|
||||||
}
|
}
|
||||||
h += r;
|
h += r;
|
||||||
@ -414,12 +409,11 @@ static void keccak_squeezeblocks(unsigned char *h, unsigned long nblocks,
|
|||||||
* non-incremental, starts by zeroeing the state.
|
* non-incremental, starts by zeroeing the state.
|
||||||
*
|
*
|
||||||
* Arguments: - uint64_t *s: pointer to (uninitialized) output Keccak state
|
* Arguments: - uint64_t *s: pointer to (uninitialized) output Keccak state
|
||||||
* - const unsigned char *input: pointer to input to be absorbed
|
* - const uint8_t *input: pointer to input to be absorbed
|
||||||
* into s
|
* into s
|
||||||
* - unsigned long long inlen: length of input in bytes
|
* - size_t inlen: length of input in bytes
|
||||||
**************************************************/
|
**************************************************/
|
||||||
void shake128_absorb(uint64_t *s, const unsigned char *input,
|
void shake128_absorb(uint64_t *s, const uint8_t *input, size_t inlen) {
|
||||||
unsigned long long inlen) {
|
|
||||||
keccak_absorb(s, SHAKE128_RATE, input, inlen, 0x1F);
|
keccak_absorb(s, SHAKE128_RATE, input, inlen, 0x1F);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -430,13 +424,12 @@ void shake128_absorb(uint64_t *s, const unsigned char *input,
|
|||||||
* SHAKE128_RATE bytes each. Modifies the state. Can be called
|
* SHAKE128_RATE bytes each. Modifies the state. Can be called
|
||||||
* multiple times to keep squeezing, i.e., is incremental.
|
* multiple times to keep squeezing, i.e., is incremental.
|
||||||
*
|
*
|
||||||
* Arguments: - unsigned char *output: pointer to output blocks
|
* Arguments: - uint8_t *output: pointer to output blocks
|
||||||
* - unsigned long long nblocks: number of blocks to be squeezed
|
* - size_t nblocks: number of blocks to be squeezed
|
||||||
* (written to output)
|
* (written to output)
|
||||||
* - uint64_t *s: pointer to input/output Keccak state
|
* - uint64_t *s: pointer to input/output Keccak state
|
||||||
**************************************************/
|
**************************************************/
|
||||||
void shake128_squeezeblocks(unsigned char *output, unsigned long nblocks,
|
void shake128_squeezeblocks(uint8_t *output, size_t nblocks, uint64_t *s) {
|
||||||
uint64_t *s) {
|
|
||||||
keccak_squeezeblocks(output, nblocks, s, SHAKE128_RATE);
|
keccak_squeezeblocks(output, nblocks, s, SHAKE128_RATE);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -447,12 +440,11 @@ void shake128_squeezeblocks(unsigned char *output, unsigned long nblocks,
|
|||||||
* non-incremental, starts by zeroeing the state.
|
* non-incremental, starts by zeroeing the state.
|
||||||
*
|
*
|
||||||
* Arguments: - uint64_t *s: pointer to (uninitialized) output Keccak state
|
* Arguments: - uint64_t *s: pointer to (uninitialized) output Keccak state
|
||||||
* - const unsigned char *input: pointer to input to be absorbed
|
* - const uint8_t *input: pointer to input to be absorbed
|
||||||
* into s
|
* into s
|
||||||
* - unsigned long long inlen: length of input in bytes
|
* - size_t inlen: length of input in bytes
|
||||||
**************************************************/
|
**************************************************/
|
||||||
void shake256_absorb(uint64_t *s, const unsigned char *input,
|
void shake256_absorb(uint64_t *s, const uint8_t *input, size_t inlen) {
|
||||||
unsigned long long inlen) {
|
|
||||||
keccak_absorb(s, SHAKE256_RATE, input, inlen, 0x1F);
|
keccak_absorb(s, SHAKE256_RATE, input, inlen, 0x1F);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -463,13 +455,12 @@ void shake256_absorb(uint64_t *s, const unsigned char *input,
|
|||||||
* SHAKE256_RATE bytes each. Modifies the state. Can be called
|
* SHAKE256_RATE bytes each. Modifies the state. Can be called
|
||||||
* multiple times to keep squeezing, i.e., is incremental.
|
* multiple times to keep squeezing, i.e., is incremental.
|
||||||
*
|
*
|
||||||
* Arguments: - unsigned char *output: pointer to output blocks
|
* Arguments: - uint8_t *output: pointer to output blocks
|
||||||
* - unsigned long long nblocks: number of blocks to be squeezed
|
* - size_t nblocks: number of blocks to be squeezed
|
||||||
* (written to output)
|
* (written to output)
|
||||||
* - uint64_t *s: pointer to input/output Keccak state
|
* - uint64_t *s: pointer to input/output Keccak state
|
||||||
**************************************************/
|
**************************************************/
|
||||||
void shake256_squeezeblocks(unsigned char *output, unsigned long nblocks,
|
void shake256_squeezeblocks(uint8_t *output, size_t nblocks, uint64_t *s) {
|
||||||
uint64_t *s) {
|
|
||||||
keccak_squeezeblocks(output, nblocks, s, SHAKE256_RATE);
|
keccak_squeezeblocks(output, nblocks, s, SHAKE256_RATE);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -478,16 +469,15 @@ void shake256_squeezeblocks(unsigned char *output, unsigned long nblocks,
|
|||||||
*
|
*
|
||||||
* Description: SHAKE128 XOF with non-incremental API
|
* Description: SHAKE128 XOF with non-incremental API
|
||||||
*
|
*
|
||||||
* Arguments: - unsigned char *output: pointer to output
|
* Arguments: - uint8_t *output: pointer to output
|
||||||
* - unsigned long long outlen: requested output length in bytes
|
* - size_t outlen: requested output length in bytes
|
||||||
* - const unsigned char *input: pointer to input
|
* - const uint8_t *input: pointer to input
|
||||||
* - unsigned long long inlen: length of input in bytes
|
* - size_t inlen: length of input in bytes
|
||||||
**************************************************/
|
**************************************************/
|
||||||
void shake128(unsigned char *output, unsigned long long outlen,
|
void shake128(uint8_t *output, size_t outlen,
|
||||||
const unsigned char *input, unsigned long long inlen) {
|
const uint8_t *input, size_t inlen) {
|
||||||
unsigned int i;
|
size_t nblocks = outlen / SHAKE128_RATE;
|
||||||
unsigned long nblocks = outlen / SHAKE128_RATE;
|
uint8_t t[SHAKE128_RATE];
|
||||||
unsigned char t[SHAKE128_RATE];
|
|
||||||
uint64_t s[25];
|
uint64_t s[25];
|
||||||
|
|
||||||
shake128_absorb(s, input, inlen);
|
shake128_absorb(s, input, inlen);
|
||||||
@ -498,7 +488,7 @@ void shake128(unsigned char *output, unsigned long long outlen,
|
|||||||
|
|
||||||
if (outlen) {
|
if (outlen) {
|
||||||
shake128_squeezeblocks(t, 1, s);
|
shake128_squeezeblocks(t, 1, s);
|
||||||
for (i = 0; i < outlen; ++i) {
|
for (size_t i = 0; i < outlen; ++i) {
|
||||||
output[i] = t[i];
|
output[i] = t[i];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -509,16 +499,15 @@ void shake128(unsigned char *output, unsigned long long outlen,
|
|||||||
*
|
*
|
||||||
* Description: SHAKE256 XOF with non-incremental API
|
* Description: SHAKE256 XOF with non-incremental API
|
||||||
*
|
*
|
||||||
* Arguments: - unsigned char *output: pointer to output
|
* Arguments: - uint8_t *output: pointer to output
|
||||||
* - unsigned long long outlen: requested output length in bytes
|
* - size_t outlen: requested output length in bytes
|
||||||
* - const unsigned char *input: pointer to input
|
* - const uint8_t *input: pointer to input
|
||||||
* - unsigned long long inlen: length of input in bytes
|
* - size_t inlen: length of input in bytes
|
||||||
**************************************************/
|
**************************************************/
|
||||||
void shake256(unsigned char *output, unsigned long long outlen,
|
void shake256(uint8_t *output, size_t outlen,
|
||||||
const unsigned char *input, unsigned long long inlen) {
|
const uint8_t *input, size_t inlen) {
|
||||||
unsigned int i;
|
size_t nblocks = outlen / SHAKE256_RATE;
|
||||||
unsigned long nblocks = outlen / SHAKE256_RATE;
|
uint8_t t[SHAKE256_RATE];
|
||||||
unsigned char t[SHAKE256_RATE];
|
|
||||||
uint64_t s[25];
|
uint64_t s[25];
|
||||||
|
|
||||||
shake256_absorb(s, input, inlen);
|
shake256_absorb(s, input, inlen);
|
||||||
@ -529,7 +518,7 @@ void shake256(unsigned char *output, unsigned long long outlen,
|
|||||||
|
|
||||||
if (outlen) {
|
if (outlen) {
|
||||||
shake256_squeezeblocks(t, 1, s);
|
shake256_squeezeblocks(t, 1, s);
|
||||||
for (i = 0; i < outlen; ++i) {
|
for (size_t i = 0; i < outlen; ++i) {
|
||||||
output[i] = t[i];
|
output[i] = t[i];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -540,15 +529,13 @@ void shake256(unsigned char *output, unsigned long long outlen,
|
|||||||
*
|
*
|
||||||
* Description: SHA3-256 with non-incremental API
|
* Description: SHA3-256 with non-incremental API
|
||||||
*
|
*
|
||||||
* Arguments: - unsigned char *output: pointer to output
|
* Arguments: - uint8_t *output: pointer to output
|
||||||
* - const unsigned char *input: pointer to input
|
* - const uint8_t *input: pointer to input
|
||||||
* - unsigned long long inlen: length of input in bytes
|
* - size_t inlen: length of input in bytes
|
||||||
**************************************************/
|
**************************************************/
|
||||||
void sha3_256(unsigned char *output, const unsigned char *input,
|
void sha3_256(uint8_t *output, const uint8_t *input, size_t inlen) {
|
||||||
unsigned long long inlen) {
|
|
||||||
uint64_t s[25];
|
uint64_t s[25];
|
||||||
unsigned char t[SHA3_256_RATE];
|
uint8_t t[SHA3_256_RATE];
|
||||||
size_t i;
|
|
||||||
|
|
||||||
/* Absorb input */
|
/* Absorb input */
|
||||||
keccak_absorb(s, SHA3_256_RATE, input, inlen, 0x06);
|
keccak_absorb(s, SHA3_256_RATE, input, inlen, 0x06);
|
||||||
@ -556,7 +543,7 @@ void sha3_256(unsigned char *output, const unsigned char *input,
|
|||||||
/* Squeeze output */
|
/* Squeeze output */
|
||||||
keccak_squeezeblocks(t, 1, s, SHA3_256_RATE);
|
keccak_squeezeblocks(t, 1, s, SHA3_256_RATE);
|
||||||
|
|
||||||
for (i = 0; i < 32; i++) {
|
for (size_t i = 0; i < 32; i++) {
|
||||||
output[i] = t[i];
|
output[i] = t[i];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -566,15 +553,13 @@ void sha3_256(unsigned char *output, const unsigned char *input,
|
|||||||
*
|
*
|
||||||
* Description: SHA3-512 with non-incremental API
|
* Description: SHA3-512 with non-incremental API
|
||||||
*
|
*
|
||||||
* Arguments: - unsigned char *output: pointer to output
|
* Arguments: - uint8_t *output: pointer to output
|
||||||
* - const unsigned char *input: pointer to input
|
* - const uint8_t *input: pointer to input
|
||||||
* - unsigned long long inlen: length of input in bytes
|
* - size_t inlen: length of input in bytes
|
||||||
**************************************************/
|
**************************************************/
|
||||||
void sha3_512(unsigned char *output, const unsigned char *input,
|
void sha3_512(uint8_t *output, const uint8_t *input, size_t inlen) {
|
||||||
unsigned long long inlen) {
|
|
||||||
uint64_t s[25];
|
uint64_t s[25];
|
||||||
unsigned char t[SHA3_512_RATE];
|
uint8_t t[SHA3_512_RATE];
|
||||||
size_t i;
|
|
||||||
|
|
||||||
/* Absorb input */
|
/* Absorb input */
|
||||||
keccak_absorb(s, SHA3_512_RATE, input, inlen, 0x06);
|
keccak_absorb(s, SHA3_512_RATE, input, inlen, 0x06);
|
||||||
@ -582,7 +567,7 @@ void sha3_512(unsigned char *output, const unsigned char *input,
|
|||||||
/* Squeeze output */
|
/* Squeeze output */
|
||||||
keccak_squeezeblocks(t, 1, s, SHA3_512_RATE);
|
keccak_squeezeblocks(t, 1, s, SHA3_512_RATE);
|
||||||
|
|
||||||
for (i = 0; i < 64; i++) {
|
for (size_t i = 0; i < 64; i++) {
|
||||||
output[i] = t[i];
|
output[i] = t[i];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
#ifndef FIPS202_H
|
#ifndef FIPS202_H
|
||||||
#define FIPS202_H
|
#define FIPS202_H
|
||||||
|
|
||||||
|
#include <stddef.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
#define SHAKE128_RATE 168
|
#define SHAKE128_RATE 168
|
||||||
@ -8,27 +9,21 @@
|
|||||||
#define SHA3_256_RATE 136
|
#define SHA3_256_RATE 136
|
||||||
#define SHA3_512_RATE 72
|
#define SHA3_512_RATE 72
|
||||||
|
|
||||||
void shake128_absorb(uint64_t *s, const unsigned char *input,
|
void shake128_absorb(uint64_t *s, const uint8_t *input, size_t inlen);
|
||||||
unsigned long long inlen);
|
|
||||||
|
|
||||||
void shake128_squeezeblocks(unsigned char *output, unsigned long nblocks,
|
void shake128_squeezeblocks(uint8_t *output, size_t nblocks, uint64_t *s);
|
||||||
uint64_t *s);
|
|
||||||
|
|
||||||
void shake256_absorb(uint64_t *s, const unsigned char *input,
|
void shake256_absorb(uint64_t *s, const uint8_t *input, size_t inlen);
|
||||||
unsigned long long inlen);
|
|
||||||
|
|
||||||
void shake256_squeezeblocks(unsigned char *output, unsigned long nblocks,
|
void shake256_squeezeblocks(uint8_t *output, size_t nblocks, uint64_t *s);
|
||||||
uint64_t *s);
|
|
||||||
|
|
||||||
void shake128(unsigned char *output, unsigned long long outlen,
|
void shake128(uint8_t *output, size_t outlen,
|
||||||
const unsigned char *input, unsigned long long inlen);
|
const uint8_t *input, size_t inlen);
|
||||||
|
|
||||||
void shake256(unsigned char *output, unsigned long long outlen,
|
void shake256(uint8_t *output, size_t outlen,
|
||||||
const unsigned char *input, unsigned long long inlen);
|
const uint8_t *input, size_t inlen);
|
||||||
|
|
||||||
void sha3_256(unsigned char *output, const unsigned char *input,
|
void sha3_256(uint8_t *output, const uint8_t *input, size_t inlen);
|
||||||
unsigned long long inlen);
|
void sha3_512(uint8_t *output, const uint8_t *input, size_t inlen);
|
||||||
void sha3_512(unsigned char *output, const unsigned char *input,
|
|
||||||
unsigned long long inlen);
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
121
common/sha2.c
121
common/sha2.c
@ -2,18 +2,19 @@
|
|||||||
* crypto_hash/sha512/ref/ from http://bench.cr.yp.to/supercop.html
|
* crypto_hash/sha512/ref/ from http://bench.cr.yp.to/supercop.html
|
||||||
* by D. J. Bernstein */
|
* by D. J. Bernstein */
|
||||||
|
|
||||||
|
#include <stddef.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
#include "sha2.h"
|
#include "sha2.h"
|
||||||
|
|
||||||
typedef unsigned long long uint64;
|
static uint64_t load_bigendian(const unsigned char *x) {
|
||||||
|
return (uint64_t)(x[7]) | (((uint64_t)(x[6])) << 8) | (((uint64_t)(x[5])) << 16) |
|
||||||
static uint64 load_bigendian(const unsigned char *x) {
|
(((uint64_t)(x[4])) << 24) | (((uint64_t)(x[3])) << 32) |
|
||||||
return (uint64)(x[7]) | (((uint64)(x[6])) << 8) | (((uint64)(x[5])) << 16) |
|
(((uint64_t)(x[2])) << 40) | (((uint64_t)(x[1])) << 48) |
|
||||||
(((uint64)(x[4])) << 24) | (((uint64)(x[3])) << 32) |
|
(((uint64_t)(x[0])) << 56);
|
||||||
(((uint64)(x[2])) << 40) | (((uint64)(x[1])) << 48) |
|
|
||||||
(((uint64)(x[0])) << 56);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void store_bigendian(unsigned char *x, uint64 u) {
|
static void store_bigendian(uint8_t *x, uint64_t u) {
|
||||||
x[7] = u;
|
x[7] = u;
|
||||||
u >>= 8;
|
u >>= 8;
|
||||||
x[6] = u;
|
x[6] = u;
|
||||||
@ -73,20 +74,20 @@ static void store_bigendian(unsigned char *x, uint64 u) {
|
|||||||
b = a; \
|
b = a; \
|
||||||
a = T1 + T2;
|
a = T1 + T2;
|
||||||
|
|
||||||
static int crypto_hashblocks_sha512(unsigned char *statebytes,
|
static int crypto_hashblocks_sha512(uint8_t *statebytes,
|
||||||
const unsigned char *in,
|
const uint8_t *in,
|
||||||
unsigned long long inlen) {
|
size_t inlen) {
|
||||||
uint64 state[8];
|
uint64_t state[8];
|
||||||
uint64 a;
|
uint64_t a;
|
||||||
uint64 b;
|
uint64_t b;
|
||||||
uint64 c;
|
uint64_t c;
|
||||||
uint64 d;
|
uint64_t d;
|
||||||
uint64 e;
|
uint64_t e;
|
||||||
uint64 f;
|
uint64_t f;
|
||||||
uint64 g;
|
uint64_t g;
|
||||||
uint64 h;
|
uint64_t h;
|
||||||
uint64 T1;
|
uint64_t T1;
|
||||||
uint64 T2;
|
uint64_t T2;
|
||||||
|
|
||||||
a = load_bigendian(statebytes + 0);
|
a = load_bigendian(statebytes + 0);
|
||||||
state[0] = a;
|
state[0] = a;
|
||||||
@ -106,22 +107,22 @@ static int crypto_hashblocks_sha512(unsigned char *statebytes,
|
|||||||
state[7] = h;
|
state[7] = h;
|
||||||
|
|
||||||
while (inlen >= 128) {
|
while (inlen >= 128) {
|
||||||
uint64 w0 = load_bigendian(in + 0);
|
uint64_t w0 = load_bigendian(in + 0);
|
||||||
uint64 w1 = load_bigendian(in + 8);
|
uint64_t w1 = load_bigendian(in + 8);
|
||||||
uint64 w2 = load_bigendian(in + 16);
|
uint64_t w2 = load_bigendian(in + 16);
|
||||||
uint64 w3 = load_bigendian(in + 24);
|
uint64_t w3 = load_bigendian(in + 24);
|
||||||
uint64 w4 = load_bigendian(in + 32);
|
uint64_t w4 = load_bigendian(in + 32);
|
||||||
uint64 w5 = load_bigendian(in + 40);
|
uint64_t w5 = load_bigendian(in + 40);
|
||||||
uint64 w6 = load_bigendian(in + 48);
|
uint64_t w6 = load_bigendian(in + 48);
|
||||||
uint64 w7 = load_bigendian(in + 56);
|
uint64_t w7 = load_bigendian(in + 56);
|
||||||
uint64 w8 = load_bigendian(in + 64);
|
uint64_t w8 = load_bigendian(in + 64);
|
||||||
uint64 w9 = load_bigendian(in + 72);
|
uint64_t w9 = load_bigendian(in + 72);
|
||||||
uint64 w10 = load_bigendian(in + 80);
|
uint64_t w10 = load_bigendian(in + 80);
|
||||||
uint64 w11 = load_bigendian(in + 88);
|
uint64_t w11 = load_bigendian(in + 88);
|
||||||
uint64 w12 = load_bigendian(in + 96);
|
uint64_t w12 = load_bigendian(in + 96);
|
||||||
uint64 w13 = load_bigendian(in + 104);
|
uint64_t w13 = load_bigendian(in + 104);
|
||||||
uint64 w14 = load_bigendian(in + 112);
|
uint64_t w14 = load_bigendian(in + 112);
|
||||||
uint64 w15 = load_bigendian(in + 120);
|
uint64_t w15 = load_bigendian(in + 120);
|
||||||
|
|
||||||
F(w0, 0x428a2f98d728ae22ULL)
|
F(w0, 0x428a2f98d728ae22ULL)
|
||||||
F(w1, 0x7137449123ef65cdULL)
|
F(w1, 0x7137449123ef65cdULL)
|
||||||
@ -252,7 +253,7 @@ static int crypto_hashblocks_sha512(unsigned char *statebytes,
|
|||||||
|
|
||||||
#define blocks crypto_hashblocks_sha512
|
#define blocks crypto_hashblocks_sha512
|
||||||
|
|
||||||
static const unsigned char iv_384[64] = {
|
static const uint8_t iv_384[64] = {
|
||||||
0xcb, 0xbb, 0x9d, 0x5d, 0xc1, 0x05, 0x9e, 0xd8, 0x62, 0x9a, 0x29,
|
0xcb, 0xbb, 0x9d, 0x5d, 0xc1, 0x05, 0x9e, 0xd8, 0x62, 0x9a, 0x29,
|
||||||
0x2a, 0x36, 0x7c, 0xd5, 0x07, 0x91, 0x59, 0x01, 0x5a, 0x30, 0x70,
|
0x2a, 0x36, 0x7c, 0xd5, 0x07, 0x91, 0x59, 0x01, 0x5a, 0x30, 0x70,
|
||||||
0xdd, 0x17, 0x15, 0x2f, 0xec, 0xd8, 0xf7, 0x0e, 0x59, 0x39, 0x67,
|
0xdd, 0x17, 0x15, 0x2f, 0xec, 0xd8, 0xf7, 0x0e, 0x59, 0x39, 0x67,
|
||||||
@ -261,7 +262,7 @@ static const unsigned char iv_384[64] = {
|
|||||||
0xa7, 0x47, 0xb5, 0x48, 0x1d, 0xbe, 0xfa, 0x4f, 0xa4
|
0xa7, 0x47, 0xb5, 0x48, 0x1d, 0xbe, 0xfa, 0x4f, 0xa4
|
||||||
};
|
};
|
||||||
|
|
||||||
static const unsigned char iv_512[64] = {
|
static const uint8_t iv_512[64] = {
|
||||||
0x6a, 0x09, 0xe6, 0x67, 0xf3, 0xbc, 0xc9, 0x08, 0xbb, 0x67, 0xae,
|
0x6a, 0x09, 0xe6, 0x67, 0xf3, 0xbc, 0xc9, 0x08, 0xbb, 0x67, 0xae,
|
||||||
0x85, 0x84, 0xca, 0xa7, 0x3b, 0x3c, 0x6e, 0xf3, 0x72, 0xfe, 0x94,
|
0x85, 0x84, 0xca, 0xa7, 0x3b, 0x3c, 0x6e, 0xf3, 0x72, 0xfe, 0x94,
|
||||||
0xf8, 0x2b, 0xa5, 0x4f, 0xf5, 0x3a, 0x5f, 0x1d, 0x36, 0xf1, 0x51,
|
0xf8, 0x2b, 0xa5, 0x4f, 0xf5, 0x3a, 0x5f, 0x1d, 0x36, 0xf1, 0x51,
|
||||||
@ -270,14 +271,12 @@ static const unsigned char iv_512[64] = {
|
|||||||
0x6b, 0x5b, 0xe0, 0xcd, 0x19, 0x13, 0x7e, 0x21, 0x79
|
0x6b, 0x5b, 0xe0, 0xcd, 0x19, 0x13, 0x7e, 0x21, 0x79
|
||||||
};
|
};
|
||||||
|
|
||||||
int sha384(unsigned char *out, const unsigned char *in,
|
int sha384(uint8_t *out, const uint8_t *in, size_t inlen) {
|
||||||
unsigned long long inlen) {
|
uint8_t h[64];
|
||||||
unsigned char h[64];
|
uint8_t padded[256];
|
||||||
unsigned char padded[256];
|
uint64_t bytes = inlen;
|
||||||
unsigned int i;
|
|
||||||
unsigned long long bytes = inlen;
|
|
||||||
|
|
||||||
for (i = 0; i < 64; ++i) {
|
for (size_t i = 0; i < 64; ++i) {
|
||||||
h[i] = iv_384[i];
|
h[i] = iv_384[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -286,13 +285,13 @@ int sha384(unsigned char *out, const unsigned char *in,
|
|||||||
inlen &= 127;
|
inlen &= 127;
|
||||||
in -= inlen;
|
in -= inlen;
|
||||||
|
|
||||||
for (i = 0; i < inlen; ++i) {
|
for (size_t i = 0; i < inlen; ++i) {
|
||||||
padded[i] = in[i];
|
padded[i] = in[i];
|
||||||
}
|
}
|
||||||
padded[inlen] = 0x80;
|
padded[inlen] = 0x80;
|
||||||
|
|
||||||
if (inlen < 112) {
|
if (inlen < 112) {
|
||||||
for (i = inlen + 1; i < 119; ++i) {
|
for (size_t i = inlen + 1; i < 119; ++i) {
|
||||||
padded[i] = 0;
|
padded[i] = 0;
|
||||||
}
|
}
|
||||||
padded[119] = bytes >> 61;
|
padded[119] = bytes >> 61;
|
||||||
@ -306,7 +305,7 @@ int sha384(unsigned char *out, const unsigned char *in,
|
|||||||
padded[127] = bytes << 3;
|
padded[127] = bytes << 3;
|
||||||
blocks(h, padded, 128);
|
blocks(h, padded, 128);
|
||||||
} else {
|
} else {
|
||||||
for (i = inlen + 1; i < 247; ++i) {
|
for (size_t i = inlen + 1; i < 247; ++i) {
|
||||||
padded[i] = 0;
|
padded[i] = 0;
|
||||||
}
|
}
|
||||||
padded[247] = bytes >> 61;
|
padded[247] = bytes >> 61;
|
||||||
@ -321,21 +320,19 @@ int sha384(unsigned char *out, const unsigned char *in,
|
|||||||
blocks(h, padded, 256);
|
blocks(h, padded, 256);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i = 0; i < 48; ++i) {
|
for (size_t i = 0; i < 48; ++i) {
|
||||||
out[i] = h[i];
|
out[i] = h[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int sha512(unsigned char *out, const unsigned char *in,
|
int sha512(uint8_t *out, const uint8_t *in, size_t inlen) {
|
||||||
unsigned long long inlen) {
|
uint8_t h[64];
|
||||||
unsigned char h[64];
|
uint8_t padded[256];
|
||||||
unsigned char padded[256];
|
uint64_t bytes = inlen;
|
||||||
unsigned int i;
|
|
||||||
unsigned long long bytes = inlen;
|
|
||||||
|
|
||||||
for (i = 0; i < 64; ++i) {
|
for (size_t i = 0; i < 64; ++i) {
|
||||||
h[i] = iv_512[i];
|
h[i] = iv_512[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -344,13 +341,13 @@ int sha512(unsigned char *out, const unsigned char *in,
|
|||||||
inlen &= 127;
|
inlen &= 127;
|
||||||
in -= inlen;
|
in -= inlen;
|
||||||
|
|
||||||
for (i = 0; i < inlen; ++i) {
|
for (size_t i = 0; i < inlen; ++i) {
|
||||||
padded[i] = in[i];
|
padded[i] = in[i];
|
||||||
}
|
}
|
||||||
padded[inlen] = 0x80;
|
padded[inlen] = 0x80;
|
||||||
|
|
||||||
if (inlen < 112) {
|
if (inlen < 112) {
|
||||||
for (i = inlen + 1; i < 119; ++i) {
|
for (size_t i = inlen + 1; i < 119; ++i) {
|
||||||
padded[i] = 0;
|
padded[i] = 0;
|
||||||
}
|
}
|
||||||
padded[119] = bytes >> 61;
|
padded[119] = bytes >> 61;
|
||||||
@ -364,7 +361,7 @@ int sha512(unsigned char *out, const unsigned char *in,
|
|||||||
padded[127] = bytes << 3;
|
padded[127] = bytes << 3;
|
||||||
blocks(h, padded, 128);
|
blocks(h, padded, 128);
|
||||||
} else {
|
} else {
|
||||||
for (i = inlen + 1; i < 247; ++i) {
|
for (size_t i = inlen + 1; i < 247; ++i) {
|
||||||
padded[i] = 0;
|
padded[i] = 0;
|
||||||
}
|
}
|
||||||
padded[247] = bytes >> 61;
|
padded[247] = bytes >> 61;
|
||||||
@ -379,7 +376,7 @@ int sha512(unsigned char *out, const unsigned char *in,
|
|||||||
blocks(h, padded, 256);
|
blocks(h, padded, 256);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i = 0; i < 64; ++i) {
|
for (size_t i = 0; i < 64; ++i) {
|
||||||
out[i] = h[i];
|
out[i] = h[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,9 +1,7 @@
|
|||||||
#ifndef SHA2_H
|
#ifndef SHA2_H
|
||||||
#define SHA2_H
|
#define SHA2_H
|
||||||
|
|
||||||
int sha384(unsigned char *out, const unsigned char *in,
|
int sha384(uint8_t *out, const uint8_t *in, size_t inlen);
|
||||||
unsigned long long inlen);
|
int sha512(uint8_t *out, const uint8_t *in, size_t inlen);
|
||||||
int sha512(unsigned char *out, const unsigned char *in,
|
|
||||||
unsigned long long inlen);
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
Loading…
Reference in New Issue
Block a user