Skip to content

Commit

Permalink
Extendable output functions: SHAKE128 and SHAKE256
Browse files Browse the repository at this point in the history
  • Loading branch information
rweather committed Feb 13, 2016
1 parent 41cc393 commit c624a3e
Show file tree
Hide file tree
Showing 10 changed files with 1,272 additions and 3 deletions.
9 changes: 9 additions & 0 deletions doc/crypto.dox
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
\li Stream ciphers: ChaCha
\li Authenticated encryption with associated data (AEAD): ChaChaPoly, EAX, GCM
\li Hash algorithms: SHA256, SHA512, SHA3_256, SHA3_512, BLAKE2s, BLAKE2b (regular and HMAC modes)
\li Extendable output functions (XOF's): SHAKE128, SHAKE256
\li Message authenticators: Poly1305, GHASH, OMAC
\li Public key algorithms: Curve25519, Ed25519
\li Random number generation: \link RNGClass RNG\endlink, TransistorNoiseSource, RingOscillatorNoiseSource
Expand Down Expand Up @@ -113,6 +114,10 @@ Ardunino Mega 2560 running at 16 MHz are similar:
<tr><td>Poly1305</td><td align="right">26.26us</td><td align="right">489.11us</td><td align="right">17.06us</td><td align="right">53</td></tr>
<tr><td>GHASH</td><td align="right">74.59us</td><td align="right">15.91us</td><td align="right">14.79us</td><td align="right">33</td></tr>
<tr><td colspan="5"> </td></tr>
<tr><td>XOF Algorithm</td><td align="right">Hashing (per byte)</td><td align="right">Extending (per byte)</td><td>Encryption (per byte)</td><td>State Size (bytes)</td></tr>
<tr><td>SHAKE128</td><td align="right">49.43us</td><td align="right">49.02us</td><td align="right">49.59us</td><td align="right">206</td></tr>
<tr><td>SHAKE256</td><td align="right">60.77us</td><td align="right">60.37us</td><td align="right">60.93us</td><td align="right">206</td></tr>
<tr><td colspan="5"> </td></tr>
<tr><td>Public Key Operation</td><td align="right">Time (per operation)</td><td colspan="3">Comment</td></tr>
<tr><td>Curve25519::eval()</td><td align="right">2716ms</td><td colspan="3">Raw curve evaluation</td></tr>
<tr><td>Curve25519::dh1()</td><td align="right">2718ms</td><td colspan="3">First half of Diffie-Hellman key agreement</td></tr>
Expand Down Expand Up @@ -174,6 +179,10 @@ All figures are for the Arduino Due running at 84 MHz:
<tr><td>Poly1305</td><td align="right">0.81us</td><td align="right">19.01us</td><td align="right">2.57us</td><td align="right">60</td></tr>
<tr><td>GHASH</td><td align="right">4.47us</td><td align="right">1.52us</td><td align="right">2.60us</td><td align="right">36</td></tr>
<tr><td colspan="5"> </td></tr>
<tr><td>XOF Algorithm</td><td align="right">Hashing (per byte)</td><td align="right">Extending (per byte)</td><td>Encryption (per byte)</td><td>State Size (bytes)</td></tr>
<tr><td>SHAKE128</td><td align="right">4.60us</td><td align="right">4.45us</td><td align="right">4.59us</td><td align="right">232</td></tr>
<tr><td>SHAKE256</td><td align="right">5.64us</td><td align="right">5.49us</td><td align="right">5.63us</td><td align="right">232</td></tr>
<tr><td colspan="5"> </td></tr>
<tr><td>Public Key Operation</td><td align="right">Time (per operation)</td><td colspan="3">Comment</td></tr>
<tr><td>Curve25519::eval()</td><td align="right">103ms</td><td colspan="3">Raw curve evaluation</td></tr>
<tr><td>Curve25519::dh1()</td><td align="right">103ms</td><td colspan="3">First half of Diffie-Hellman key agreement</td></tr>
Expand Down
1 change: 1 addition & 0 deletions doc/mainpage.dox
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,7 @@ realtime clock and the LCD library to implement an alarm clock.
\li Stream ciphers: ChaCha
\li Authenticated encryption with associated data (AEAD): ChaChaPoly, EAX, GCM
\li Hash algorithms: SHA256, SHA512, SHA3_256, SHA3_512, BLAKE2s, BLAKE2b (regular and HMAC modes)
\li Extendable output functions (XOF's): SHAKE128, SHAKE256
\li Message authenticators: Poly1305, GHASH, OMAC
\li Public key algorithms: Curve25519, Ed25519
\li Random number generation: \link RNGClass RNG\endlink, TransistorNoiseSource, RingOscillatorNoiseSource
Expand Down
56 changes: 53 additions & 3 deletions libraries/Crypto/KeccakCore.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,11 +32,11 @@
* \brief Keccak core sponge function.
*
* KeccakCore provides the core sponge function for different capacities.
* It is used to implement Hash algorithms such as SHA3.
* It is used to implement algorithms such as SHA3 and SHAKE.
*
* References: http://en.wikipedia.org/wiki/SHA-3
*
* \sa SHA3
* \sa SHA3_256, SHAKE256
*/

#if !defined(CRYPTO_LITTLE_ENDIAN)
Expand Down Expand Up @@ -189,7 +189,7 @@ void KeccakCore::pad(uint8_t tag)
* If more than blockSize() bytes are required, the sponge function will
* be invoked to generate additional data.
*
* \sa update(), reset(), extractHash()
* \sa update(), reset(), encrypt()
*/
void KeccakCore::extract(void *data, size_t size)
{
Expand Down Expand Up @@ -219,6 +219,56 @@ void KeccakCore::extract(void *data, size_t size)
}
}

/**
* \brief Extracts data from the Keccak sponge function and uses it to
* encrypt a buffer.
*
* \param output The output buffer to write to, which may be the same
* buffer as \a input. The \a output buffer must have at least as many
* bytes as the \a input buffer.
* \param input The input buffer to read from.
* \param size The number of bytes to encrypt.
*
* This function extracts data from the sponge function and then XOR's
* it with \a input to generate the \a output.
*
* If more than blockSize() bytes are required, the sponge function will
* be invoked to generate additional data.
*
* \sa update(), reset(), extract()
*/
void KeccakCore::encrypt(void *output, const void *input, size_t size)
{
// Stop accepting input while we are generating output.
state.inputSize = 0;

// Copy the output data into the caller's return buffer.
uint8_t *out = (uint8_t *)output;
const uint8_t *in = (const uint8_t *)input;
uint8_t tempSize;
while (size > 0) {
// Generate another output block if the current one has been exhausted.
if (state.outputSize >= _blockSize) {
keccakp();
state.outputSize = 0;
}

// How many bytes can we extract this time around?
tempSize = _blockSize - state.outputSize;
if (tempSize > size)
tempSize = size;

// XOR the partial output data into the caller's return buffer.
const uint8_t *d = ((const uint8_t *)(state.A)) + state.outputSize;
for (uint8_t index = 0; index < tempSize; ++index)
out[index] = in[index] ^ d[index];
state.outputSize += tempSize;
size -= tempSize;
out += tempSize;
in += tempSize;
}
}

/**
* \brief Clears all sensitive data from this object.
*/
Expand Down
1 change: 1 addition & 0 deletions libraries/Crypto/KeccakCore.h
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ class KeccakCore
void pad(uint8_t tag);

void extract(void *data, size_t size);
void encrypt(void *output, const void *input, size_t size);

void clear();

Expand Down
137 changes: 137 additions & 0 deletions libraries/Crypto/SHAKE.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,137 @@
/*
* Copyright (C) 2016 Southern Storm Software, Pty Ltd.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*/

#include "SHAKE.h"

/**
* \class SHAKE SHAKE.h <SHAKE.h>
* \brief Abstract base class for the SHAKE Extendable-Output Functions (XOFs).
*
* Reference: http://en.wikipedia.org/wiki/SHA-3
*
* \sa SHAKE256, SHAKE128, SHA3_256
*/

/**
* \brief Constructs a SHAKE object.
*
* \param capacity The capacity of the Keccak sponge function in bits which
* should be a multiple of 64 and between 64 and 1536.
*/
SHAKE::SHAKE(size_t capacity)
: finalized(false)
{
core.setCapacity(capacity);
}

/**
* \brief Destroys this SHAKE object after clearing all sensitive information.
*/
SHAKE::~SHAKE()
{
}

size_t SHAKE::blockSize() const
{
return core.blockSize();
}

void SHAKE::reset()
{
core.reset();
finalized = false;
}

void SHAKE::update(const void *data, size_t len)
{
if (finalized)
reset();
core.update(data, len);
}

void SHAKE::extend(uint8_t *data, size_t len)
{
if (!finalized) {
core.pad(0x1F);
finalized = true;
}
core.extract(data, len);
}

void SHAKE::encrypt(uint8_t *output, const uint8_t *input, size_t len)
{
if (!finalized) {
core.pad(0x1F);
finalized = true;
}
core.encrypt(output, input, len);
}

void SHAKE::clear()
{
core.clear();
finalized = false;
}

/**
* \class SHAKE128 SHAKE.h <SHAKE.h>
* \brief SHAKE Extendable-Output Function (XOF) with 128-bit security.
*
* Reference: http://en.wikipedia.org/wiki/SHA-3
*
* \sa SHAKE256, SHAKE, SHA3_256
*/

/**
* \fn SHAKE128::SHAKE128()
* \brief Constructs a SHAKE object with 128-bit security.
*/

/**
* \brief Destroys this SHAKE128 object after clearing all sensitive
* information.
*/
SHAKE128::~SHAKE128()
{
}

/**
* \class SHAKE256 SHAKE.h <SHAKE.h>
* \brief SHAKE Extendable-Output Function (XOF) with 256-bit security.
*
* Reference: http://en.wikipedia.org/wiki/SHA-3
*
* \sa SHAKE128, SHAKE, SHA3_256
*/

/**
* \fn SHAKE256::SHAKE256()
* \brief Constructs a SHAKE object with 256-bit security.
*/

/**
* \brief Destroys this SHAKE256 object after clearing all sensitive
* information.
*/
SHAKE256::~SHAKE256()
{
}
66 changes: 66 additions & 0 deletions libraries/Crypto/SHAKE.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
/*
* Copyright (C) 2016 Southern Storm Software, Pty Ltd.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*/

#ifndef CRYPTO_SHAKE_h
#define CRYPTO_SHAKE_h

#include "XOF.h"
#include "KeccakCore.h"

class SHAKE : public XOF
{
public:
virtual ~SHAKE();

size_t blockSize() const;

void reset();
void update(const void *data, size_t len);

void extend(uint8_t *data, size_t len);
void encrypt(uint8_t *output, const uint8_t *input, size_t len);

void clear();

protected:
SHAKE(size_t capacity);

private:
KeccakCore core;
bool finalized;
};

class SHAKE128 : public SHAKE
{
public:
SHAKE128() : SHAKE(256) {}
virtual ~SHAKE128();
};

class SHAKE256 : public SHAKE
{
public:
SHAKE256() : SHAKE(512) {}
virtual ~SHAKE256();
};

#endif
Loading

0 comments on commit c624a3e

Please sign in to comment.