Home

Awesome

Keccak-f[1600] NIF (SHA3-224, SHA3-256, SHA3-384, SHA3-512, SHAKE128, SHAKE256, SPONGERNG)

Build Status Hex.pm

Keccak-f[1600] NIF with timeslice reductions for Erlang and Elixir.

The timeslice reductions allow the NIF to perform operations on very large inputs without blocking the scheduler or requiring the Erlang VM to support dirty schedulers. See the bitwise project from which the strategy was derived.

Tested against the FIPS 202 test vectors.

Installation

Add keccakf1600 to your project's dependencies in mix.exs

defp deps do
  [
    {:keccakf1600, "~> 3.0.0"}
  ]
end

Add keccakf1600 to your project's dependencies in your Makefile for erlang.mk or the following to your rebar.config

{deps, [
  {keccakf1600, ".*", {git, "git://github.com/potatosalad/erlang-keccakf1600.git", {branch, "master"}}}
]}.

Usage

This library follows usage semantics from Erlang's own crypto library, with the exception of the SHAKE128, SHAKE256, and SPONGERNG algorithms as described below.

SPONGERNG

keccakf1600_spongerng:init_from_buffer/2

This function allows you to specify an initial seed buffer and whether the PRNG will be deterministic or not.

%% Deterministic
keccakf1600_spongerng:init_from_buffer(<<>>, true).
% {spongerng, #Ref<0.0.0.1>}
%% Non-deterministic
keccakf1600_spongerng:init_from_buffer(<<>>, false).
% {spongerng, #Ref<0.0.0.2>}

keccakf1600_spongerng:init_from_file/3

This function allows you specify an initial seed file up to the given length and whether the PRNG will be deterministic or not.

%% Deterministic
keccakf1600_spongerng:init_from_file("seed.txt", 16, true).
% {spongerng, #Ref<0.0.0.3>}
%% Non-deterministic
keccakf1600_spongerng:init_from_file("seed.txt", 16, false).
% {spongerng, #Ref<0.0.0.4>}

keccakf1600_spongerng:init_from_dev_urandom/0

This function reads an initial seed from /dev/urandom and is only allowed to be non-deterministic.

%% Non-deterministic
keccakf1600_spongerng:init_from_dev_urandom().
% {spongerng, #Ref<0.0.0.5>}

keccakf1600_spongerng:next/2

This function returns the next length of bytes from the sponge and returns the new sponge state.

Sponge0 = keccakf1600_spongerng:init_from_buffer(<<>>, true),
{Sponge1, Output} = keccakf1600_spongerng:next(Sponge0, 8).
% {{spongerng, #Ref<0.0.0.6>}, <<99,190,253,62,125,162,80,150>>}

keccakf1600_spongerng:stir/2

This function modifies the sponge state (stirs the pot) with the given input.

Sponge0 = keccakf1600_spongerng:init_from_buffer(<<>>, true),
Sponge1 = keccakf1600_spongerng:stir(Sponge0, <<"test">>),
{Sponge2, Output} = keccakf1600_spongerng:next(Sponge1, 8).
% {{spongerng, #Ref<0.0.0.7>}, <<168,214,5,0,60,110,186,33>>}

SHA-3

keccakf1600_sha3:hash/2

This function can be used for the following algorithms:

keccakf1600_sha3:hash(sha3_224, <<"test">>).
% <<55,151,191,10,251,191,202,74,123,187,167,96,42,43,85,39,70,135,101,23,167,249,183,206,45,176,174,123>>

keccakf1600_sha3:hash(sha3_256, <<"test">>).
% <<54,240,40,88,11,176,44,200,39,42,154,2,15,66,0,227,70,226,118,174,102,78,69,238,128,116,85,116,226,245,171,128>>

keccakf1600_sha3:hash(sha3_384, <<"test">>).
% <<229,22,218,187,35,182,227,0,38,134,53,67,40,39,128,163,174,13,204,240,85,81,207,2,149,23,141,127,240,241,180,30,236,185,219,63,242,25,0,124,78,9,114,96,213,134,33,189>>

keccakf1600_sha3:hash(sha3_512, <<"test">>).
% <<158,206,8,110,155,172,73,31,172,92,29,16,70,202,17,215,55,185,42,43,46,189,147,240,5,215,183,16,17,12,10,103,130,136,22,110,127,190,121,104,131,164,242,233,179,202,159,72,79,82,29,12,228,100,52,92,193,174,201,103,121,20,156,20>>

keccakf1600_sha3:hash/3

This function can be used for the following algorithms:

These algorithms can output arbitrary length digests, so an output length must be specified.

keccakf1600_sha3:hash(shake128, <<"test">>, 16).
% <<211,176,170,156,216,183,37,86,34,206,188,99,30,134,125,64>>

keccakf1600_sha3:hash(shake256, <<"test">>, 16).
% <<181,79,247,37,87,5,167,30,226,146,94,74,62,48,228,26>>

keccakf1600_sha3:init/1

This function can be used for the following algorithms:

SHA3-224 (sha3_224)
Sponge0 = keccakf1600_sha3:init(sha3_224).
% {sha3_224, #Ref<0.0.0.3>}
SHA3-256 (sha3_256)
Sponge0 = keccakf1600_sha3:init(sha3_256).
% {sha3_256, #Ref<0.0.0.4>}
SHA3-384 (sha3_384)
Sponge0 = keccakf1600_sha3:init(sha3_384).
% {sha3_384, #Ref<0.0.0.5>}
SHA3-512 (sha3_512)
Sponge0 = keccakf1600_sha3:init(sha3_512).
% {sha3_512, #Ref<0.0.0.6>}
SHAKE128 (shake128)
Sponge0 = keccakf1600_sha3:init(shake128).
% {shake128, #Ref<0.0.0.7>}
SHAKE256 (shake256)
Sponge0 = keccakf1600_sha3:init(shake256).
% {shake256, #Ref<0.0.0.8>}

keccakf1600_sha3:update/2

This function can be used for the following algorithms:

The examples below use the Sponge0 for each algorithm from the examples above for keccakf1600_sha3:init/1.

SHA3-224 (sha3_224)
Sponge1 = keccakf1600_sha3:update(Sponge0, <<"test">>).
% {sha3_224, #Ref<0.0.0.9>}
SHA3-256 (sha3_256)
Sponge1 = keccakf1600_sha3:update(Sponge0, <<"test">>).
% {sha3_256, #Ref<0.0.0.10>}
SHA3-384 (sha3_384)
Sponge1 = keccakf1600_sha3:update(Sponge0, <<"test">>).
% {sha3_384, #Ref<0.0.0.11>}
SHA3-512 (sha3_512)
Sponge1 = keccakf1600_sha3:update(Sponge0, <<"test">>).
% {sha3_512, #Ref<0.0.0.12>}
SHAKE128 (shake128)
Sponge1 = keccakf1600_sha3:update(Sponge0, <<"test">>).
% {shake128, #Ref<0.0.0.13>}
SHAKE256 (shake256)
Sponge1 = keccakf1600_sha3:update(Sponge0, <<"test">>).
% {shake256, #Ref<0.0.0.14>}

keccakf1600_sha3:final/2

This function can be used for the following algorithms:

The examples below use the Sponge1 for each algorithm from the examples above for keccakf1600_sha3:update/2.

SHA3-224 (sha3_224)
Out = keccakf1600_sha3:final(Sponge1).
% <<55,151,191,10,251,191,202,74,123,187,167,96,42,43,85,39,70,135,101,23,167,249,183,206,45,176,174,123>>
SHA3-256 (sha3_256)
Out = keccakf1600_sha3:final(Sponge1).
% <<54,240,40,88,11,176,44,200,39,42,154,2,15,66,0,227,70,226,118,174,102,78,69,238,128,116,85,116,226,245,171,128>>
SHA3-384 (sha3_384)
Out = keccakf1600_sha3:final(Sponge1).
% <<229,22,218,187,35,182,227,0,38,134,53,67,40,39,128,163,174,13,204,240,85,81,207,2,149,23,141,127,240,241,180,30,236,185,219,63,242,25,0,124,78,9,114,96,213,134,33,189>>
SHA3-512 (sha3_512)
Out = keccakf1600_sha3:final(Sponge1).
% <<158,206,8,110,155,172,73,31,172,92,29,16,70,202,17,215,55,185,42,43,46,189,147,240,5,215,183,16,17,12,10,103,130,136,22,110,127,190,121,104,131,164,242,233,179,202,159,72,79,82,29,12,228,100,52,92,193,174,201,103,121,20,156,20>>

keccakf1600_sha3:final/3

This function can be used for the following algorithms:

These algorithms can output arbitrary length digests, so an output length must be specified.

The examples below use the Sponge1 for each algorithm from the examples above for keccakf1600_sha3:update/2.

SHAKE128 (shake128)
Out = keccakf1600_sha3:final(Sponge1, 16).
% <<211,176,170,156,216,183,37,86,34,206,188,99,30,134,125,64>>
SHAKE256 (shake256)
Out = keccakf1600_sha3:final(Sponge1, 16).
% <<181,79,247,37,87,5,167,30,226,146,94,74,62,48,228,26>>