sha3.c revision 211c638d81d382517d196ad47565e0d85012c927
/* -------------------------------------------------------------------------
* Works when compiled for either 32-bit or 64-bit targets, optimized for
* 64 bit.
*
*
* SHA3-256, SHA3-384, SHA-512 are implemented. SHA-224 can easily be added.
*
* Based on code from http://keccak.noekeon.org/ .
*
* I place the code that I wrote into public domain, free to use.
*
* I would appreciate if you give credits to this work if you used it to
* write or test * your code.
*
* Aug 2015. Andrey Jivsov. crypto@brainhub.org
*
* Modified for Dovecot oy use
* Oct 2016. Aki Tuomi <aki.tuomi@dovecot.fi>
* ---------------------------------------------------------------------- */
#include "lib.h"
#include "sha3.h"
#include <stdio.h>
#include <stdint.h>
#include <string.h>
#if defined(_MSC_VER)
#define SHA3_CONST(x) x
#else
#define SHA3_CONST(x) x##L
#endif
/* The following state definition should normally be in a separate
* header file
*/
#ifndef SHA3_ROTL64
#define SHA3_ROTL64(x, y) \
(((x) << (y)) | ((x) >> ((sizeof(uint64_t)*8) - (y))))
#endif
};
static const unsigned keccakf_rotc[24] = {
1, 3, 6, 10, 15, 21, 28, 36, 45, 55, 2, 14, 27, 41, 56, 8, 25, 43, 62,
18, 39, 61, 20, 44
};
static const unsigned keccakf_piln[24] = {
10, 7, 11, 17, 18, 3, 5, 16, 8, 21, 24, 4, 15, 23, 19, 13, 12, 2, 20,
14, 22, 9, 6, 1
};
/* generally called after SHA3_KECCAK_SPONGE_WORDS-ctx->capacityWords words
* are XORed into the state s
*/
static void
{
int i, j, round;
#define KECCAK_ROUNDS 24
/* Theta */
for(i = 0; i < 5; i++)
for(i = 0; i < 5; i++) {
for(j = 0; j < 25; j += 5)
s[j + i] ^= t;
}
/* Rho Pi */
t = s[1];
for(i = 0; i < 24; i++) {
j = keccakf_piln[i];
bc[0] = s[j];
s[j] = SHA3_ROTL64(t, keccakf_rotc[i]);
t = bc[0];
}
/* Chi */
for(j = 0; j < 25; j += 5) {
for(i = 0; i < 5; i++)
bc[i] = s[j + i];
for(i = 0; i < 5; i++)
}
/* Iota */
s[0] ^= keccakf_rndc[round];
}
}
/* *************************** Public Interface ************************ */
void sha3_256_init(void *context)
{
}
void sha3_512_init(void *context)
{
}
{
/* 0...7 -- how much is needed to have a word */
unsigned tail;
size_t i;
* the word yet */
/* endian-independent code follows: */
while (len > 0) {
len--;
}
return;
}
if(old_tail != 0) { /* will have one word to process */
/* endian-independent code follows: */
while (old_tail > 0) {
old_tail--;
}
/* now ready to add saved to the sponge */
ctx->capacityWords)) {
}
}
/* now work in full words directly from input */
#if defined(__x86_64__ ) || defined(__i386__)
#endif
}
}
/* finally, save the partial word */
while (tail > 0) {
tail--;
}
}
/* This is simply the 'update' with the padding block.
* The padding block is 0x01 || 0x00* || 0x80. First 0x01 and last 0x80
* bytes are always present, but they can be the same byte.
*/
static void
{
/* Append 2-bit suffix 01, per SHA-3 spec. Instead of 1 for padding we
* use 1<<2 below. The 0x02 below corresponds to the suffix 01.
* Overall, we feed 0, then 1, and finally 1 to start padding. Without
* M || 01, we would simply use 1 to start padding. */
/* SHA3 version */
SHA3_CONST(0x8000000000000000UL);
#ifdef WORDS_BIGENDIAN
{
unsigned i;
for(i = 0; i < SHA3_KECCAK_SPONGE_WORDS; i++) {
}
}
#endif
}
void sha3_256_result(void *context,
{
}
void sha3_512_result(void *context,
{
}
{
sha3_256_init(&ctx);
}
{
sha3_512_init(&ctx);
}
static void hash_method_init_sha3_256(void *context)
{
}
{
}
{
}
const struct hash_method hash_method_sha3_256 = {
"sha3-256",
sizeof(struct sha3_ctx),
};
static void hash_method_init_sha3_512(void *context)
{
}
{
}
const struct hash_method hash_method_sha3_512 = {
"sha3-512",
sizeof(struct sha3_ctx),
};