spritz-0.1.0.0: An implementation of the Spritz RC4-like stream cipher in Haskell

Copyright(C) 2014 Ricky Elrod
LicenseBSD2 (see LICENSE file)
MaintainerRicky Elrod <ricky@elrod.me>
Stabilityexperimental
Portabilitylens
Safe HaskellNone
LanguageHaskell2010

Crypto.Cipher.Spritz

Contents

Description

The original paper for the Spritz cipher can be found here:

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

This package provides a Haskell implementation of the pseudocode in the paper listed above. It intends to be a direct implementation of the cipher, so we rely heavily on use of the State monad. We also make heavy use of the lens library's combinators, internally, to ease our use of State.

Please report any and all bugs to https://github.com/relrod/spritz.

Lastly, I must give a shout-out to spritzjs for the bitmasking parts and for existing so that I had something to test against when I was done.

Synopsis

State/Lenses

data SpritzState Source

Register values and s. As a difference to the paper, we also include n in the state, for easy access to it within the various functions.

See §3.1 State.

Constructors

SpritzState 

Fields

_i :: Int

Register: Always incremented by w `'mod'` n whenever changed.

_j :: Int

Register

_k :: Int

Register

_z :: Int

Register: Last value produced by output

_w :: Int

Register: Modified when whip is called. Always relatively prime to n.

_a :: Int

Register: Number of nibbles absorbed since start of last shuffle of s.

_s :: Vector Int

Length n. Permutation of Z_n.

_n :: Int

All values in Spritz are modulo n.

s :: Lens' SpritzState (Vector Int) Source

Spritz basic functions

initializeState Source

Arguments

:: Int

The n value to use throughout.

-> SpritzState

The initial state.

Returns the standard initial state. See §3.2 InitializeState.

absorb :: Vector Int -> State SpritzState () Source

Takes a variable-lenght input and updates the state based on it. Spritz absorbs input in blocks of floor (n / 2) nibbles each (low-order nibble of each byte first). After each block is absorbed, we call shuffle.

Satisfies the following law:

absorb x1 >> absorb x2 = 'absorb (x1 ++ x2)'

See §3.2 Absorb.

absorbByte :: Int -> State SpritzState () Source

Splits the given input byte into two nibbles and updates state based on each nibble, low-order nibble first. See §3.2 AbsorbByte.

absorbNibble :: Int -> State SpritzState () Source

Tests whether Spritz is full of absorbed data (i.e. a = floor (n / 2). If it is, calls shuffle to mix in the absorbed data and reset a to 0. Then updates the state based on the value of the supplied nibble. See §3.2 AbsorbNibble.

absorbStop :: State SpritzState () Source

Equivalent to absorbing a special "stop" symbol outside of the oridnary input alphabet. The intent is to provide a clean way to separate different inputs being absorbed. See §2.1.

shuffle :: State SpritzState () Source

whips, crushes, whips, crushes, and finally whips again. According to the paper, each whip randomizes the state. Calling crush between each whip causes the effects of crush to be not easily determined by manipulating the input. See §3.2 Shuffle.

whip Source

Arguments

:: Int

r. The number of times to call update.

-> State SpritzState () 

Calls update r times. Also updates w to the next largest value that is relatively prime to n.

crush :: State SpritzState () Source

Provides a non-invertable transformation from states to states. Intentionally loses information about the current state by mapping 2^(n2) states to 1 state, since each of @n2@ pairs of compared values in s are sorted into increasing order. See §3.2 "crush".

squeeze :: Int -> State SpritzState (Vector Int) Source

Main output function for Spritz. The Int parameter states how many bytes to produce. Calls shuffle if a > 0, which shuffles any unabsorbed input and puts Spritz into "squeeze mode" (a > 0). See §3.2 "squeeze".

drip :: State SpritzState Int Source

Basic pseudorandom output routine. Calls shuffle when a > 0, updates state using update, and produces one output byte using output. See §3.2 "drip".

update :: State SpritzState () Source

Advances the system to the next state by adding w to i, giving j and k their next values, and swapping s'_'i with s'_'j. w being relatively prime to n means that the value of i cycles modulo n as repeated updates are performed. See §3.2 "update".

output :: State SpritzState Int Source

Computes a single byte (n-value) to output, saves it in register z and returns it.

Helper functions

low :: (Bits a, Num a, Show a) => a -> a Source

See §3.1 Nibbles.

high :: (Bits a, Num a, Show a) => a -> a Source

See §3.1 Nibbles.

plusmod :: Integral a => a -> a -> a -> a Source

A utility function that adds the first parameter to the second then returns that modulo the third parameter (n). This is used throughout Spritz in place of a more traditional xor approach so that n can be any value and is not limited to being a power of 2.

submod :: Integral a => a -> a -> a -> a Source

See plusmod. This is very similar except it subtracts the first two arguments instead of adding them.

swap :: Int -> Int -> State SpritzState () Source

Swap two elements given indices of S.

Making use of everything

Encyrption

encrypt Source

Arguments

:: Vector Int

The key.

-> Vector Int

The decrypted message.

-> SpritzState

Starting state.

-> Vector Int 

Adds-modulo-N (plusmod) each byte of the message with the corresponding byte of the output of squeeze yielding an ecrypted ciphertext. See §2.2.

decrypt Source

Arguments

:: Vector Int

The key.

-> Vector Int

The encrypted message.

-> SpritzState

Starting state.

-> Vector Int 

Decrypts a message encrypted with encrypt. Identical to encrypt except uses submod instead. See §2.2.

keySetup Source

Arguments

:: Int

Our N value. 256 in the paper.

-> Vector Int

The key.

-> State SpritzState () 

Used in the paper at the top of encrypt* and decrypt, but not used by default in this library. Still, we provide it in case it's needed.

keySetup n' k' = put (initializeState n') >> absorb k'

Hashing

hash Source

Arguments

:: Vector Int

The message.

-> Int

r (number of bytes).

-> SpritzState

Initial state.

-> Vector Int 

Produces an r-byte hash of the input message.

hash absorbs the input message, calls absorbStop to signal the end of the input message, then absorbs the desired hash length (r).

The given r is absorbed for functional separation.

See §2.3.

Message Authentication Code (MAC)

mac Source

Arguments

:: Vector Int

The key.

-> Vector Int

The message.

-> Int

r

-> SpritzState 
-> Vector Int 

Message authentication code. See §2.4.