Skip to content

Commit

Permalink
v0.2,src improv,ChunkByChunk hash & mac
Browse files Browse the repository at this point in the history
  • Loading branch information
abderraouf-adjal committed Nov 27, 2015
1 parent 7091ccf commit 8555215
Show file tree
Hide file tree
Showing 6 changed files with 337 additions and 87 deletions.
65 changes: 47 additions & 18 deletions README.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2,44 +2,73 @@ SpritzCipher
============

Spritz library for Arduino.
A spongy RC4-like stream cipher. This library contains cryptographically secure
pseudo-random bytes generator, Hash & MAC with configurable output length.
A spongy RC4-like stream cipher. This library contains secure random bytes generator,
Flexible cryptographic hash function & message authentication code (MAC).

This library can be used to:
* Encrypt data.
* Generate random numbers.
* Hash & authenticate data.
* Hash data.
* Data encryption.
* Authenticated encryption.
* Generate random numbers from seed.

Home page: <https://github.com/abderraouf-adjal/ArduinoSpritzCipher>
Home page on GitHub: <https://github.com/abderraouf-adjal/ArduinoSpritzCipher>

Spritz paper: <https://people.csail.mit.edu/rivest/pubs/RS14.pdf>


Library content for user
========================

* Types
spritz_ctx - The context/ctx (contain the state), holds indices and S-Box.
See <SpritzCipher.h> for the details.

* Functions
setup(ctx, key, keyLen) - Setup spritz state (spritz_ctx) with a key.
setupIV(ctx, key, keyLen, nonce, nonceLen) - Setup spritz state (spritz_ctx) with a key and nonce (Salt).
wipe_spritz_ctx(ctx) - Wipe spritz context data.
spritz_rand_byte(ctx) - Generates a byte of keystream from spritz state (spritz_ctx).
hash(digest, digestLen, data, dataLen) - Cryptographic hash function.
mac(digest, digestLen, msg, msgLen, key, keyLen) - Message Authentication Code (MAC) function.
* Types:
spritz_ctx
The context/ctx (contain the state), holds indices and S-Box.

* Functions:
wipe_spritz_ctx(spritz_ctx ctx):
Wipe spritz context data.

setup(spritz_ctx ctx, key, keyLen)
Setup spritz state (spritz_ctx) with a key.
setupIV(spritz_ctx ctx, key, keyLen, nonce, nonceLen)
Setup spritz state with a key and nonce (Salt).
spritz_rand_byte(spritz_ctx ctx)
Generates a byte of keystream from spritz state (spritz_ctx).


hash(digest, digestLen, data, dataLen)
Spritz cryptographic hash function.
mac(digest, digestLen, msg, msgLen, key, keyLen)
Spritz Message Authentication Code (MAC) function.

See <SpritzCipher.h> for the details.

hash_setup(spritz_ctx hash_ctx)
Setup spritz hash state.
hash_update(spritz_ctx hash_ctx, data, dataLen)
Add data chunk to hash.
hash_final(spritz_ctx hash_ctx, digest, digestLen)
Output hash digest.

mac_setup(spritz_ctx mac_ctx, key, keyLen)
Setup spritz MAC state.
mac_update(spritz_ctx mac_ctx, msg, msgLen)
Add message/data chunk to MAC.
mac_final(spritz_ctx mac_ctx, digest, digestLen)
Output MAC digest.


Examples
========

* Generate random bytes (Spritz stream test):
./examples/SpritzStreamTest/SpritzStreamTest.ino

* Hash data:
./examples/SpritzHashTest/SpritzHashTest.ino

* Generate random bytes:
./examples/SpritzStreamTest/SpritzStreamTest.ino
* Hash data chunk by chunk:
./examples/SpritzHashChunksTest/SpritzHashChunksTest.ino


Installation Guide
Expand Down
145 changes: 96 additions & 49 deletions SpritzCipher.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,14 @@ SpritzCipher::absorb(spritz_ctx *ctx, const uint8_t octet)
absorbNibble(ctx, octet % 16); /* Low */
absorbNibble(ctx, octet / 16); /* High */
}
void
SpritzCipher::absorbBytes(spritz_ctx *ctx, const uint8_t *buf, unsigned int len)
{
unsigned int i;
for (i = 0; i < len; i++) {
absorb(ctx, buf[i]);
}
}

void
SpritzCipher::absorbStop(spritz_ctx *ctx)
Expand Down Expand Up @@ -169,7 +177,28 @@ SpritzCipher::squeeze(spritz_ctx *ctx, uint8_t *out, uint8_t len)
}


/* ================ User Functions ================ */
/* |====================|| User Functions ||====================| */

/* Wipe spritz context (spritz_ctx) data */
void
SpritzCipher::wipe_spritz_ctx(spritz_ctx *ctx)
{
uint8_t i, d;

start:
ctx->i = ctx->j = ctx->k = ctx->z = ctx->a = ctx->w = 0;
d = ctx->i | ctx->j | ctx->k | ctx->z | ctx->a | ctx->w;
for (i = 0; i < SPRITZ_N_MINUS_1; i++) {
ctx->s[i] = 0;
d |= ctx->s[i];
}
ctx->s[255] = 0;
d |= ctx->s[255];
if (d) {
goto start;
}
}


/* Setup spritz state (spritz_ctx) with a key */
void
Expand All @@ -178,9 +207,7 @@ SpritzCipher::setup(spritz_ctx *ctx,
{
uint8_t i;
stateInit(ctx);
for (i = 0; i < keyLen; i++) {
absorb(ctx, key[i]);
}
absorbBytes(ctx, key, keyLen);
}

/* Setup spritz state (spritz_ctx) with a key and nonce (Salt) */
Expand All @@ -192,24 +219,9 @@ SpritzCipher::setupIV(spritz_ctx *ctx,
uint8_t i;
setup(ctx, key, keyLen);
absorbStop(ctx);
for (i = 0; i < nonceLen; i++) {
absorb(ctx, nonce[i]);
}
}

/* Wipe spritz context (spritz_ctx) data */
void
SpritzCipher::wipe_spritz_ctx(spritz_ctx *ctx)
{
uint8_t i;
ctx->i = ctx->j = ctx->k = ctx->z = ctx->a = ctx->w = 0;
for (i = 0; i < SPRITZ_N_MINUS_1; i++) {
ctx->s[i] = 0;
}
ctx->s[255] = 0;
absorbBytes(ctx, nonce, nonceLen);
}


/* Generates a byte of keystream from spritz state (spritz_ctx) */
uint8_t
SpritzCipher::spritz_rand_byte(spritz_ctx *ctx)
Expand All @@ -218,45 +230,80 @@ SpritzCipher::spritz_rand_byte(spritz_ctx *ctx)
}


/* Setup spritz hash state (spritz_ctx) */
void
SpritzCipher::hash_setup(spritz_ctx *hash_ctx)
{
stateInit(hash_ctx);
}

/* Add data chunk to hash */
void
SpritzCipher::hash_update(spritz_ctx *hash_ctx,
const uint8_t *data, unsigned int dataLen)
{
absorbBytes(hash_ctx, data, dataLen);
}

/* Output hash digest */
void
SpritzCipher::hash_final(spritz_ctx *hash_ctx,
uint8_t *digest, uint8_t digestLen)
{
absorbStop(hash_ctx);
absorb(hash_ctx, digestLen);
squeeze(hash_ctx, digest, digestLen);
#ifdef WIPE_AFTER_USAGE
wipe_spritz_ctx(hash_ctx);
#endif
}

/* Cryptographic hash function */
void
SpritzCipher::hash(uint8_t *digest, uint8_t digestLen,
const uint8_t *data, unsigned int dataLen)
{
spritz_ctx ctx;
unsigned int i;
stateInit(&ctx);
for (i = 0; i < dataLen; i++) {
absorb(&ctx, data[i]);
}
absorbStop(&ctx);
absorb(&ctx, digestLen);
squeeze(&ctx, digest, digestLen);
#ifdef WIPE_AFTER_USAGE
wipe_spritz_ctx(&ctx);
#endif
spritz_ctx hash_ctx;
hash_setup(&hash_ctx);
hash_update(&hash_ctx, data, dataLen);
hash_final(&hash_ctx, digest, digestLen);
}


/* Setup spritz MAC state (spritz_ctx) */
void
SpritzCipher::mac_setup(spritz_ctx *mac_ctx,
const uint8_t *key, unsigned int keyLen)
{
stateInit(mac_ctx); /* hash_update() */
absorbBytes(mac_ctx, key, keyLen);
absorbStop(mac_ctx);
}

/* Add message/data chunk to MAC */
void
SpritzCipher::mac_update(spritz_ctx *mac_ctx,
const uint8_t *msg, unsigned int msgLen)
{
absorbBytes(mac_ctx, msg, msgLen); /* hash_update() */
}

/* Output MAC digest */
void
SpritzCipher::mac_final(spritz_ctx *mac_ctx,
uint8_t *digest, uint8_t digestLen)
{
hash_final(mac_ctx, digest, digestLen);
}

/* Message Authentication Code (MAC) function */
void
SpritzCipher::mac(uint8_t *digest, uint8_t digestLen,
const uint8_t *msg, unsigned int msgLen,
const uint8_t *key, uint8_t keyLen)
const uint8_t *key, unsigned int keyLen)
{
spritz_ctx ctx;
unsigned int i;
stateInit(&ctx);
for (i = 0; i < keyLen; i++) {
absorb(&ctx, key[i]);
}
absorbStop(&ctx);
for (i = 0; i < msgLen; i++) {
absorb(&ctx, msg[i]);
}
absorbStop(&ctx);
absorb(&ctx, digestLen);
squeeze(&ctx, digest, digestLen);
#ifdef WIPE_AFTER_USAGE
wipe_spritz_ctx(&ctx);
#endif
spritz_ctx mac_ctx;
mac_setup(&mac_ctx, key, keyLen);
mac_update(&mac_ctx, msg, msgLen);
mac_final(&mac_ctx, digest, digestLen);
}
Loading

0 comments on commit 8555215

Please sign in to comment.