Commit 1c8cc9e9 authored by Niels Möller's avatar Niels Möller

Implemented sha3.

parent c835888e
2012-11-12 Niels Möller <nisse@lysator.liu.se>
* sha3-permute.c: New file. Permutation function for sha3, aka
Keccak.
* sha3.h: New header file.
* sha3.c: New file, absorption and padding for sha3.
* sha3-256.c: New file.
* sha3-256-meta.c: New file.
* nettle-meta.h (nettle_sha3_256): Declare.
* Makefile.in (nettle_SOURCES): Added sha3 files.
(HEADERS): Added sha3.h.
* testsuite/sha3.awk: New file. Script to extract test vectors.
* testsuite/sha3-256-test.c: New file.
* testsuite/sha3-permute-test.c: New file.
* testsuite/Makefile.in (TS_NETTLE_SOURCES): Added
sha3-permute-test.c and sha3-256-test.c.
(DISTFILES): Added sha3.awk.
* testsuite/.test-rules.make: Added sha3 targets.
* macros.h (LE_WRITE_UINT64): New macro.
* write-le64.c (_nettle_write_le64): New file and function.
* nettle-write.h (_nettle_write_le64): Declare. Also deleted
......
......@@ -88,6 +88,7 @@ nettle_SOURCES = aes-decrypt-internal.c aes-decrypt.c \
sha1.c sha1-compress.c sha1-meta.c \
sha256.c sha256-compress.c sha224-meta.c sha256-meta.c \
sha512.c sha512-compress.c sha384-meta.c sha512-meta.c \
sha3.c sha3-permute.c sha3-256.c sha3-256-meta.c \
serpent-set-key.c serpent-encrypt.c serpent-decrypt.c \
serpent-meta.c \
twofish.c twofish-meta.c \
......@@ -136,7 +137,7 @@ HEADERS = aes.h arcfour.h arctwo.h asn1.h bignum.h blowfish.h \
nettle-meta.h nettle-types.h \
pgp.h pkcs1.h realloc.h ripemd160.h rsa.h rsa-compat.h \
salsa20.h sexp.h \
serpent.h sha.h twofish.h \
serpent.h sha.h sha3.h twofish.h \
yarrow.h
INSTALL_HEADERS = $(HEADERS) nettle-stdint.h
......
......@@ -165,6 +165,7 @@ extern const struct nettle_hash nettle_sha224;
extern const struct nettle_hash nettle_sha256;
extern const struct nettle_hash nettle_sha384;
extern const struct nettle_hash nettle_sha512;
extern const struct nettle_hash nettle_sha3_256;
struct nettle_armor
{
......
/* sha3-256-meta.c */
/* nettle, low-level cryptographics library
*
* Copyright (C) 2012 Niels Möller
*
* The nettle library is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; either version 2.1 of the License, or (at your
* option) any later version.
*
* The nettle library is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
* License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with the nettle library; see the file COPYING.LIB. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
* MA 02111-1301, USA.
*/
#if HAVE_CONFIG_H
# include "config.h"
#endif
#include "nettle-meta.h"
#include "sha3.h"
const struct nettle_hash nettle_sha3_256
= _NETTLE_HASH(sha3_256, SHA3_256);
/* sha3-256.c
*
* The sha3 hash function, 256 bit output.
*/
/* nettle, low-level cryptographics library
*
* Copyright (C) 2012 Niels Möller
*
* The nettle library is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; either version 2.1 of the License, or (at your
* option) any later version.
*
* The nettle library is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
* License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with the nettle library; see the file COPYING.LIB. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
* MA 02111-1301, USA.
*/
#if HAVE_CONFIG_H
# include "config.h"
#endif
#include <stddef.h>
#include <string.h>
#include "sha3.h"
#include "nettle-write.h"
void
sha3_256_init (struct sha3_256_ctx *ctx)
{
memset (&ctx->state, 0, offsetof (struct sha3_256_ctx, block));
}
void
sha3_256_update (struct sha3_256_ctx *ctx,
unsigned length,
const uint8_t *data)
{
ctx->index = _sha3_update (&ctx->state, SHA3_256_DATA_SIZE, ctx->block,
ctx->index, length, data);
}
void
sha3_256_digest(struct sha3_256_ctx *ctx,
unsigned length,
uint8_t *digest)
{
_sha3_pad (&ctx->state, SHA3_256_DATA_SIZE, ctx->block, ctx->index);
_nettle_write_le64 (length, digest, ctx->state.a);
sha3_256_init (ctx);
}
/* sha3-permute.c
*
* The sha3 permutation function (aka Keccak).
*/
/* nettle, low-level cryptographics library
*
* Copyright (C) 2012 Niels Möller
*
* The nettle library is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; either version 2.1 of the License, or (at your
* option) any later version.
*
* The nettle library is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
* License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with the nettle library; see the file COPYING.LIB. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
* MA 02111-1301, USA.
*/
#if HAVE_CONFIG_H
# include "config.h"
#endif
#include "sha3.h"
#include "macros.h"
#define SHA3_ROUNDS 24
/* Based on the pseudocode description at
http://keccak.noekeon.org/specs_summary.html */
void
sha3_permute (struct sha3_state *state)
{
static const unsigned char rot[25] =
{
0, 1, 62, 28, 27,
36, 44, 6, 55, 20,
3, 10, 43, 25, 39,
41, 45, 15, 21, 8,
18, 2, 61, 56, 14,
};
static const uint64_t rc[SHA3_ROUNDS] = {
0x0000000000000001, 0x0000000000008082,
0x800000000000808A, 0x8000000080008000,
0x000000000000808B, 0x0000000080000001,
0x8000000080008081, 0x8000000000008009,
0x000000000000008A, 0x0000000000000088,
0x0000000080008009, 0x000000008000000A,
0x000000008000808B, 0x800000000000008B,
0x8000000000008089, 0x8000000000008003,
0x8000000000008002, 0x8000000000000080,
0x000000000000800A, 0x800000008000000A,
0x8000000080008081, 0x8000000000008080,
0x0000000080000001, 0x8000000080008008,
};
unsigned i;
for (i = 0; i < SHA3_ROUNDS; i++)
{
uint64_t C[5], D[5], B[25];
unsigned x, y;
/* theta step */
for (x = 0; x < 5; x++)
C[x] = state->a[x] ^ state->a[5+x] ^ state->a[10+x]
^ state->a[15+x] ^ state->a[20+x];
for (x = 0; x < 5; x++)
/* Use the simplest indexing expressions in the argument to
the ROTL64 macro */
D[(x+4)%5] = C[(x+3)%5] ^ ROTL64(1, C[x]);
for (x = 0; x < 5; x++)
for (y = 0; y < 5; y++)
state->a[x +5*y] ^= D[x];
/* rho step */
for (x = 0; x < 25; x++)
state->a[x] = ROTL64 (rot[x], state->a[x]);
/* pi step */
for (x = 0; x < 5; x++)
for (y = 0; y < 5; y++)
/* B[y,2*x+3*y] = B[y+5*(2*x + 3*y)]= B[10*x + 16*y] */
B[(10*x+16*y) % 25] = state->a[x+5*y];
/* chi step */
for (x = 0; x < 5; x++)
for (y = 0; y < 5; y++)
state->a[x+5*y] = B[x+5*y] ^ (~B[(x+1)%5 + 5*y] & B[(x+2)%5+5*y]);
/* iota step */
state->a[0] ^= rc[i];
}
}
/* sha3.c
*
* The sha3 hash function.
*/
/* nettle, low-level cryptographics library
*
* Copyright (C) 2012 Niels Möller
*
* The nettle library is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; either version 2.1 of the License, or (at your
* option) any later version.
*
* The nettle library is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
* License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with the nettle library; see the file COPYING.LIB. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
* MA 02111-1301, USA.
*/
#if HAVE_CONFIG_H
# include "config.h"
#endif
#include <assert.h>
#include <string.h>
#include "sha3.h"
#include "memxor.h"
static void
sha3_absorb (struct sha3_state *state, unsigned length, const uint8_t *data)
{
assert ( (length & 7) == 0);
#if WORDS_BIGENDIAN
{
uint64_t *p;
for (p = &state->a[0][0]; length > 0; p++, length -= 8, data += 8)
*p ^= LE_READ_UINT64 (data);
}
#else /* !WORDS_BIGENDIAN */
memxor ((uint8_t *) state->a, data, length);
#endif
sha3_permute (state);
}
unsigned
_sha3_update (struct sha3_state *state,
unsigned block_size, uint8_t *block,
unsigned pos,
unsigned length, const uint8_t *data)
{
if (pos > 0)
{
unsigned left = block_size - pos;
if (length < pos)
{
memcpy (block + pos, data, length);
return pos + length;
}
else
{
memcpy (block + pos, data, left);
data += left;
length -= left;
sha3_absorb (state, block_size, block);
}
}
for (; length >= block_size; length -= block_size, data += block_size)
sha3_absorb (state, block_size, data);
memcpy (block, data, length);
return length;
}
void
_sha3_pad (struct sha3_state *state,
unsigned block_size, uint8_t *block, unsigned pos)
{
assert (pos < block_size);
block[pos++] = 1;
memset (block + pos, 0, block_size - pos);
block[block_size - 1] |= 0x80;
sha3_absorb (state, block_size, block);
}
/* sha3.h
*
* The sha3 hash function (aka Keccak).
*/
/* nettle, low-level cryptographics library
*
* Copyright (C) 2012 Niels Möller
*
* The nettle library is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; either version 2.1 of the License, or (at your
* option) any later version.
*
* The nettle library is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
* License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with the nettle library; see the file COPYING.LIB. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
* MA 02111-1301, USA.
*/
#ifndef NETTLE_SHA3_H_INCLUDED
#define NETTLE_SHA3_H_INCLUDED
#include "nettle-types.h"
#ifdef __cplusplus
extern "C" {
#endif
#define sha3_permute nettle_sha3_permute
#define _sha3_update _nettle_sha3_update
#define _sha3_pad _nettle_sha3_pad
#define sha3_256_init nettle_sha3_256_init
#define sha3_256_update nettle_sha3_256_update
#define sha3_256_digest nettle_sha3_256_digest
/* The sha3 state is a 5x5 matrix of 64-bit words. In the notation of
Keccak description, S[x,y] is element x + 5*y, so if x is
interpreted as the row index and y the column index, it is stored
in column-major order. */
#define SHA3_STATE_LENGTH 25
/* The "width" is 1600 bits or 200 octets */
struct sha3_state
{
uint64_t a[SHA3_STATE_LENGTH];
};
void
sha3_permute (struct sha3_state *state);
unsigned
_sha3_update (struct sha3_state *state,
unsigned block_size, uint8_t *block,
unsigned pos,
unsigned length, const uint8_t *data);
void
_sha3_pad (struct sha3_state *state,
unsigned block_size, uint8_t *block, unsigned pos);
/* The "capacity" is set to 2*(digest size), 512 bits or 64 octets.
The "rate" is the width - capacity, or width - 2 * (digest
size). */
#define SHA3_224_DIGEST_SIZE 28
#define SHA3_224_DATA_SIZE 144
#define SHA3_256_DIGEST_SIZE 32
#define SHA3_256_DATA_SIZE 136
#define SHA3_384_DIGEST_SIZE 48
#define SHA3_384_DATA_SIZE 104
#define SHA3_512_DIGEST_SIZE 64
#define SHA3_512_DATA_SIZE 72
struct sha3_224_ctx
{
struct sha3_state state;
unsigned index;
uint8_t block[SHA3_224_DATA_SIZE];
};
struct sha3_256_ctx
{
struct sha3_state state;
unsigned index;
uint8_t block[SHA3_256_DATA_SIZE];
};
void
sha3_256_init (struct sha3_256_ctx *ctx);
void
sha3_256_update (struct sha3_256_ctx *ctx,
unsigned length,
const uint8_t *data);
void
sha3_256_digest(struct sha3_256_ctx *ctx,
unsigned length,
uint8_t *digest);
struct sha3_384_ctx
{
struct sha3_state state;
unsigned index;
uint8_t block[SHA3_384_DATA_SIZE];
};
struct sha3_512_ctx
{
struct sha3_state state;
unsigned index;
uint8_t block[SHA3_512_DATA_SIZE];
};
#ifdef __cplusplus
}
#endif
#endif /* NETTLE_SHA3_H_INCLUDED */
......@@ -70,6 +70,12 @@ sha384-test$(EXEEXT): sha384-test.$(OBJEXT)
sha512-test$(EXEEXT): sha512-test.$(OBJEXT)
$(LINK) sha512-test.$(OBJEXT) $(TEST_OBJS) -o sha512-test$(EXEEXT)
sha3-permute-test$(EXEEXT): sha3-permute-test.$(OBJEXT)
$(LINK) sha3-permute-test.$(OBJEXT) $(TEST_OBJS) -o sha3-permute-test$(EXEEXT)
sha3-256-test$(EXEEXT): sha3-256-test.$(OBJEXT)
$(LINK) sha3-256-test.$(OBJEXT) $(TEST_OBJS) -o sha3-256-test$(EXEEXT)
serpent-test$(EXEEXT): serpent-test.$(OBJEXT)
$(LINK) serpent-test.$(OBJEXT) $(TEST_OBJS) -o serpent-test$(EXEEXT)
......
......@@ -21,6 +21,7 @@ TS_NETTLE_SOURCES = aes-test.c arcfour-test.c arctwo-test.c \
salsa20-test.c \
sha1-test.c sha224-test.c sha256-test.c \
sha384-test.c sha512-test.c \
sha3-permute-test.c sha3-256-test.c \
serpent-test.c twofish-test.c \
knuth-lfib-test.c \
cbc-test.c ctr-test.c gcm-test.c hmac-test.c \
......@@ -52,7 +53,7 @@ SOURCES = $(TS_SOURCES) $(EXTRA_SOURCES) testutils.c
DISTFILES = $(SOURCES) $(CXX_SOURCES) Makefile.in .test-rules.make \
$(TS_SH) setup-env teardown-env \
gold-bug.txt testutils.h
gold-bug.txt testutils.h sha3.awk
all: $(TARGETS) $(EXTRA_TARGETS)
......
This source diff could not be displayed because it is too large. You can view the blob instead.
#include "testutils.h"
#include "sha3.h"
static void
display (const struct sha3_state *state)
{
unsigned x, y;
for (x = 0; x < 5; x++)
{
for (y = 0; y < 5; y++)
/* Is there a simple and *portable* way to print uint64_t? */
printf ("%8lx%08lx ", (unsigned long) (state->a[x +5*y] >> 32), (unsigned long) (state->a[x+5*y] & 0xffffffff));
printf("\n");
}
}
void
test_main(void)
{
/* From KeccakPermutationIntermediateValues.txt */
static const struct sha3_state s1 =
{ {
0xF1258F7940E1DDE7ULL, 0x84D5CCF933C0478AULL, 0xD598261EA65AA9EEULL, 0xBD1547306F80494DULL, 0x8B284E056253D057ULL,
0xFF97A42D7F8E6FD4ULL, 0x90FEE5A0A44647C4ULL, 0x8C5BDA0CD6192E76ULL, 0xAD30A6F71B19059CULL, 0x30935AB7D08FFC64ULL,
0xEB5AA93F2317D635ULL, 0xA9A6E6260D712103ULL, 0x81A57C16DBCF555FULL, 0x43B831CD0347C826ULL, 0x01F22F1A11A5569FULL,
0x05E5635A21D9AE61ULL, 0x64BEFEF28CC970F2ULL, 0x613670957BC46611ULL, 0xB87C5A554FD00ECBULL, 0x8C3EE88A1CCF32C8ULL,
0x940C7922AE3A2614ULL, 0x1841F924A2C509E4ULL, 0x16F53526E70465C2ULL, 0x75F644E97F30A13BULL, 0xEAF1FF7B5CECA249ULL,
} };
static const struct sha3_state s2 =
{ {
0x2D5C954DF96ECB3CULL, 0x6A332CD07057B56DULL, 0x093D8D1270D76B6CULL, 0x8A20D9B25569D094ULL, 0x4F9C4F99E5E7F156ULL,
0xF957B9A2DA65FB38ULL, 0x85773DAE1275AF0DULL, 0xFAF4F247C3D810F7ULL, 0x1F1B9EE6F79A8759ULL, 0xE4FECC0FEE98B425ULL,
0x68CE61B6B9CE68A1ULL, 0xDEEA66C4BA8F974FULL, 0x33C43D836EAFB1F5ULL, 0xE00654042719DBD9ULL, 0x7CF8A9F009831265ULL,
0xFD5449A6BF174743ULL, 0x97DDAD33D8994B40ULL, 0x48EAD5FC5D0BE774ULL, 0xE3B8C8EE55B7B03CULL, 0x91A0226E649E42E9ULL,
0x900E3129E7BADD7BULL, 0x202A9EC5FAA3CCE8ULL, 0x5B3402464E1C3DB6ULL, 0x609F4E62A44C1059ULL, 0x20D06CD26A8FBF5CULL,
} };
struct sha3_state state;
memset (&state, 0, sizeof(state));
sha3_permute (&state);
if (!MEMEQ (sizeof(state), &state.a, &s1))
{
printf("Got:\n"); display (&state);
printf("Ref:\n"); display (&s1);
FAIL();
}
sha3_permute (&state);
if (!MEMEQ (sizeof(state), &state.a, &s2))
{
printf("Got:\n"); display (&state);
printf("Ref:\n"); display (&s2);
FAIL();
}
}
#! /usr/bin/awk -f
/^Len/ { len = $3 }
/^Msg/ { msg = $3 }
/^MD/ { md = $3;
if (len % 8 == 0)
printf("test_hash(&nettle_sha3_xxx, /* %d octets */\nSHEX(\"%s\"),\nSHEX(\"%s\"));\n",
len / 8, len ? msg : "", md);
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment