Skip to content

Spritz encryption system portable C library, CSPRNG, cryptographic hash and MAC functions, symmetric-key data encryption, and general-purpose functions. It's also an Arduino library.

License

Notifications You must be signed in to change notification settings

abderraouf-adjal/ArduinoSpritzCipher

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Spritz Library For Arduino

Spritz - a spongy RC4-like stream cipher and hash function.

This library contains a cryptographic pseudo-random number generator, cryptographic hash and message authentication code (MAC) functions, can perform symmetric-key authenticated data encryption, and general-purpose functions for timing-safe comparison and wiping data from memory.

This C Spritz library can be used to:

  • Hash and authenticate data.
  • Perform symmetric-key authenticated data encryption.
  • Generate random numbers and strings from entropy/seed.

This library's GitHub repository.

This library's Bitbucket repository (Backup).

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


Library Content

Read the source code for details.

Types

spritz_ctx - The context/ctx (contains the state). The state consists of byte registers {i, j, k, z, w, a}, And an array {s} containing a permutation of {0, 1, ... , SPRITZ_N-1}.

uint8_t - unsigned integer type with width of 8-bit, MIN=0;MAX=255.

uint16_t - unsigned integer type with width of 16-bit, MIN=0;MAX=65,535.

uint32_t - unsigned integer type with width of 32-bit, MIN=0;MAX=4,294,967,295.

Functions

uint8_t spritz_compare(const uint8_t *data_a, const uint8_t *data_b,
                       uint16_t len)

Timing-safe comparison for data_a and data_b equality. This function can be used to compare the password's hash safely.

Return equality result. Zero (0x00) if data_a equals data_b OR if len is zero, Non-zero value if they are NOT equal.

void spritz_memzero(uint8_t *buf, uint16_t len)

Wipe buf data by replacing it with len zeros (0x00).

void spritz_state_memzero(spritz_ctx *ctx)

Wipe spritz_ctx's data by replacing its data with zeros (0x00).

If SPRITZ_WIPE_TRACES_PARANOID is defined, This function will wipe the sensitive temporary variables in spritz_ctx.

void spritz_setup(spritz_ctx *ctx,
                  const uint8_t *key, uint8_t keyLen)

Setup the spritz state spritz_ctx with a key of length keyLen.

void spritz_setup_withIV(spritz_ctx *ctx,
                         const uint8_t *key, uint8_t keyLen,
                         const uint8_t *nonce, uint8_t nonceLen)

Setup the spritz state spritz_ctx with a key and nonce/Salt/IV.

uint8_t spritz_random8(spritz_ctx *ctx)

Generates a random byte (8-bit) from the spritz state spritz_ctx.

uint32_t spritz_random32(spritz_ctx *ctx)

Generates a random 32-bit (4 bytes) from the spritz state spritz_ctx.

uint32_t spritz_random32_uniform(spritz_ctx *ctx, uint32_t upper_bound)

Calculate an uniformly distributed random number less than upper_bound avoiding modulo bias. Uniformity is achieved by generating new random numbers until the one returned is outside the range [0, 2**32 % upper_bound). This guarantees the selected random number will be inside [2**32 % upper_bound, 2**32) which maps back to [0, upper_bound) after reduction modulo upper_bound.

void spritz_add_entropy(spritz_ctx *ctx,
                        const uint8_t *entropy, uint16_t len)

Add entropy to the spritz state spritz_ctx using the internal function absorb().

void spritz_crypt(spritz_ctx *ctx,
                  const uint8_t *data, uint16_t dataLen,
                  uint8_t *dataOut)

Encrypt or decrypt data chunk by XOR-ing it with the spritz keystream.

void spritz_crypt_inplace(spritz_ctx *ctx,
                          uint8_t *data, uint16_t dataLen)

Encrypt or decrypt data chunk by XOR-ing it with the spritz keystream and put the output in the same buffer data.

void spritz_hash(uint8_t *digest, uint8_t digestLen,
                 const uint8_t *data, uint16_t dataLen)

Spritz cryptographic hash function.

void spritz_mac(uint8_t *digest, uint8_t digestLen,
                const uint8_t *msg, uint16_t msgLen,
                const uint8_t *key, uint16_t keyLen)

Spritz Message Authentication Code (MAC) function.

void spritz_hash_setup(spritz_ctx *hash_ctx)

Setup the spritz hash state.

void spritz_hash_update(spritz_ctx *hash_ctx,
                        const uint8_t *data, uint16_t dataLen)

Add a message/data chunk data to hash.

void spritz_hash_final(spritz_ctx *hash_ctx,
                       uint8_t *digest, uint8_t digestLen)

Output the hash digest.

void spritz_mac_setup(spritz_ctx *mac_ctx,
                      const uint8_t *key, uint16_t keyLen)

Setup the spritz Message Authentication Code (MAC) state.

void spritz_mac_update(spritz_ctx *mac_ctx,
                       const uint8_t *msg, uint16_t msgLen)

Add a message/data chunk to Message Authentication Code (MAC).

void spritz_mac_final(spritz_ctx *mac_ctx,
                      uint8_t *digest, uint8_t digestLen)

Output the Message Authentication Code (MAC) digest.

Notes

spritz_random8(), spritz_random32(), spritz_random32_uniform(), spritz_add_entropy(), spritz_crypt(). Are usable only after calling spritz_setup() or spritz_setup_withIV().

Functions spritz_random*() requires spritz_setup() or spritz_setup_withIV() initialized with an entropy (random data), 128-bit of entropy at least. Arduino Uno's ATmega328P and many microcontrollers and microprocessors does NOT have a real/official way to get entropy,

you will/may need getting entropy by using hardware (recommended), or at least a pre-stored random data updated with spritz_random*() output (NOT recommended).

To generate a random number in a range [k, m) use k + spritz_random32_uniform(ctx, m), Not k + (spritz_random8(ctx) % m) or k + (spritz_random32(ctx) % m).

Use spritz_state_memzero() after spritz_hash_final() or spritz_mac_final() if you need to wipe the used spritz_ctx's data.

Constants

Configure library settings in the file SpritzCipher.h.

  • SPRITZ_USE_LIBC

Use C standard library functions such as memset() to zero buffers. It can be useful for performnce if the lib-C functions are optimized in low-level. If the compiler is not GCC or Clang, you will see a security warning about code optimization is not off in some sensitive functions.

SPRITZ_USE_LIBC is NOT defined by default.

  • SPRITZ_TIMING_SAFE_CRUSH

If defined, The equal time crush() will be used.

SPRITZ_TIMING_SAFE_CRUSH is defined by default.

  • SPRITZ_WIPE_TRACES

If defined, Sensitive data like spritz_ctx will be wiped, when they are no longer needed, in the functions: spritz_hash(), spritz_mac().

SPRITZ_WIPE_TRACES is NOT defined by default.

  • SPRITZ_WIPE_TRACES_PARANOID

If defined, The library functions internal variables will be wiped if they contain a bit or more of spritz state, such as temporary variables in a swap function or user data. Variables that contain data length will not be wiped.

If SPRITZ_WIPE_TRACES_PARANOID defined, Then SPRITZ_WIPE_TRACES and SPRITZ_TIMING_SAFE_CRUSH, will be defined automatically.

SPRITZ_WIPE_TRACES_PARANOID is NOT defined by default.

  • SPRITZ_N = 256 - Present the value of N in this spritz implementation, Do NOT change SPRITZ_N value.

  • SPRITZ_LIBRARY_VERSION_STRING = "x.y.z" - Present the version of this spritz library (MAJOR . MINOR . PATCH) using Semantic Versioning.

  • SPRITZ_LIBRARY_VERSION_MAJOR = x - The MAJOR version of the library.

  • SPRITZ_LIBRARY_VERSION_MINOR = y - The MINOR version of the library.

  • SPRITZ_LIBRARY_VERSION_PATCH = z - The PATCH version of the library.


Examples

  • SpritzBestPractice: Hash 32 KB of a Spritz stream (pseudo-random number generator output) then print the result. An embedded entropy/seed for the pseudo-random number generator is used.

  • SpritzBestPracticePassword: Generate a strong Alphanumeric passwords, and then print it. An embedded entropy/seed for the pseudo-random number generator is used.

  • SpritzBestPracticePasswordESP8266: Generate a strong Alphanumeric passwords, and then print it. This example is for ESP8266 SoC, it uses a hardware RNG in ESP8266 as an initialization entropy.

  • SpritzCryptTest: Test the library encryption/decryption function.

  • SpritzCryptInplaceTest: Test the library encryption/decryption function doing encrypt and decrypt in same buffer for less RAM usage.

  • SpritzStreamTest: Generate random bytes (Spritz stream) test.

  • SpritzHashTest: Hash function test.

  • SpritzMACTest: Message authentication code (MAC) function test.


Installation Guide

Arduino IDE - Additional libraries installation guide.

Compiling this library using GCC or Clang will give more security for functions that should be compiled with zero optimization (-O0) like spritz_compare().


Reporting bugs

Create an issue on GitHub.


Copyright and License

Copyright (c) 2015-2020 Abderraouf Adjal

  • The source-code: ISC License.

  • Documentation (e.g. this file content): Public domain.

  • Examples: Public domain.

About

Spritz encryption system portable C library, CSPRNG, cryptographic hash and MAC functions, symmetric-key data encryption, and general-purpose functions. It's also an Arduino library.

Topics

Resources

License

Stars

Watchers

Forks

Contributors 4

  •  
  •  
  •  
  •  

Languages