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

Copyright (C) 2014 Ricky Elrod BSD2 (see LICENSE file) Ricky Elrod experimental lens None Haskell2010

Crypto.Cipher.Spritz

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.

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

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 :: IntRegister: Always incremented by `w `'mod'` n` whenever changed._j :: IntRegister_k :: IntRegister_z :: IntRegister: Last value produced by `output`_w :: IntRegister: Modified when `whip` is called. Always relatively prime to `n`._a :: IntRegister: Number of nibbles absorbed since start of last `shuffle` of `s`._s :: Vector IntLength `n`. Permutation of Z_n._n :: IntAll values in Spritz are modulo `n`.

Instances

 Eq SpritzState Ord SpritzState Show SpritzState

i :: Lens' SpritzState Int

j :: Lens' SpritzState Int

k :: Lens' SpritzState Int

z :: Lens' SpritzState Int

w :: Lens' SpritzState Int

a :: Lens' SpritzState Int

s :: Lens' SpritzState (Vector Int)

n :: Lens' SpritzState Int

# Spritz basic functions

initializeState

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 ()

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 ()

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 ()

TODO: Write documentation. See §3.2 AbsorbNibble.

absorbStop :: State SpritzState ()

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 ()

`whip`s, `crush`es, `whip`s, `crush`es, and finally `whip`s 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

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 ()

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

update :: State SpritzState ()

# Helper functions

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

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

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

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

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

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

Swap two elements given indices of S.

# Making use of everything

## Encyrption

encrypt

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

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

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

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

Arguments

 :: Vector Int The key. -> Vector Int The message. -> Int r -> SpritzState -> Vector Int

Message authentication code. See §2.4.