--- Crypt-Spritz/README 2015/01/10 03:15:59 1.1 +++ Crypt-Spritz/README 2015/01/10 07:48:29 1.2 @@ -0,0 +1,411 @@ +NAME + Crypt::Spritz - Spritz stream cipher/hash/MAC/AEAD/CSPRNG module + +SYNOPSIS + use Crypt::Spritz; + + # see the commented examples in their respective classes, + # but basically + + my $cipher = new Crypt::Spritz::Cipher::XOR $key, $iv; + $ciphertext = $cipher->crypt ($cleartext); + + my $hasher = new Crypt::Spritz::Hash; + $hasher->add ($data); + $digest = $hasher->finish; + + my $hasher = new Crypt::Spritz::MAC $key; + $hasher->add ($data); + $mac = $hasher->finish; + + my $aead = new Crypt::Spritz::AEAD::XOR $key; + $aead->nonce ($counter); + $aead->associated_data ($header); + $ciphertext = $aead->crypt ($cleartext); + $mac = $aead->mac; + + my $prng = new Crypt::Spritz::PRNG $entropy; + $prng->add ($additional_entropy); + $keydata = $prng->get (32); + +DESCRIPTION + This module implements the Spritz spongelike function (with N=256), the + spiritual successor of RC4 developed by Ron Rivest and Jacob Schuldt. + + Its strength is extreme versatility (you get a stream cipher, a hash, a + MAC, a DRBG/CSPRNG, an authenticated encryption block/stream cipher and + more) and extremely simple and small code (encryption and authentication + can be had in 1KB of compiled code on amd64, which isn't an issue for + most uses in Perl, but is useful in embedded situations, or e.g. when + doing crypto using javascript in a browser and communicating with Perl). + + Its weakness is its relatively slow speed (encryption is a few times + slower than RC4 or AES, hashing many times slower than SHA-3, although + this might be reversed on an 8-bit-cpu) and the fact that it is totally + unproven in the field (as of this writing, the cipher was just a few + months old), so it can't be called production-ready. + + All the usual caveats regarding stream ciphers apply - never repeat your + key, never repeat your nonce and so on - you should have some basic + understanding of cryptography before using this cipher in your own + designs. + + The Spritz base class is not meant for end users. To make usage simpler + and safer, a number of convenience classes are provided for typical + end-user tasks: + + encryption - Crypt::Spritz::Cipher::XOR + hashing - Crypt::Spritz::Hash + message authentication - Crypt::Spritz::MAC + authenticated encryption - Crypt::Spritz::AEAD::XOR + random number generation - Crypt::Spritz::PRNG + + THE Crypt::Spritz CLASS + This class implements most of the Spritz primitives. To use it + effectively you should understand them, for example, by reading the + "http://people.csail.mit.edu/rivest/pubs/RS14.pdf" in Spritz paper, + especially pp. 5-6. + + The Spritz primitive corresponding to the Perl method is given as + comment. + + $spritz = new Crypt::Spritz # InitializeState + Creates and returns a new, initialised Spritz state. + + $spritz->init # InitializeState + Initialises the Spritz state again, throwing away the previous + state. + + $spritz->update # Update + $spritz->whip ($r) # Whip + $spritz->crush # Crush + $spritz->shuffle # Shuffle + $spritz->output # Output + Calls the Spritz primitive ovf the same name - these are not + normally called manually. + + $spritz->absorb ($I) # Absorb + Absorbs the given data into the state (usually used for key + material, nonces, IVs messages to be hashed and so on). + + $spritz->absorb_stop # AbsorbStop + Absorbs a special stop symbol - this is usually used as delimiter + between multiple strings to be absorbed, to thwart extension + attacks. + + $spritz->absorb_and_stop ($I) + This is a convenience function that simply calls "absorb" followed + by "absorb_stop". + + $octet = $spritz->drip # Drip + Squeezes out a single byte from the state. + + $octets = $spritz->squeeze ($len) # Squeeze + Squeezes out the requested number of bytes from the state - this is + usually + + THE Crypt::Spritz::Cipher::XOR CLASS + This class implements stream encryption/decryption. It doesn't implement + the standard Spritz encryption but the XOR variant (called spritz-xor in + the paper). + + The XOR variant should be as secure as the standard variant, but doesn't + have separate encryption and decryaption functions, which saves + codesize. IT is not compatible with standard Spritz encryption, however + - drop me a note if you want that implemented as well. + + Typical use for encryption *and* decryption (code is identical for + decryption, you simply pass the encrypted data to "crypt"): + + # create a cipher - $salt can be a random string you send + # with your message, in clear, a counter (best), or empty if + # you only want to encrypt one message with the given key. + # 16 or 32 octets are typical sizes for the key, for the salt, + # use whatever you need to give a unique salt for every + # message you encrypt with the same key. + + my $cipher = Crypt::Spritz::Cipher::XOR $key, $salt; + + # encrypt a message in one or more calls to crypt + + my $encrypted; + + $encrypted .= $cipher->crypt ("This is"); + $encrypted .= $cipher->crypt ("all very"); + $encrypted .= $cipher->crypt ("secret"); + + # that's all + + $cipher = new Crypt::Spritz::Cipher::XOR $key[, $iv] + Creates a new cipher object usable for encryption and decryption. + The $key must be provided, the initial vector $IV is optional. + + Both $key and $IV can be of any length. Typical lengths for the $key + are 16 (128 bit) or 32 (256 bit), while the $IV simply needs to be + long enough to distinguish repeated uses of tghe same key. + + $encrypted = $cipher->crypt ($cleartext) + $cleartext = $cipher->crypt ($encrypted) + Encrypt or decrypt a piece of a message. This cna be called as many + times as you want, and the message can be split into as few or many + pieces as required without affecting the results. + + $cipher->crypt_inplace ($cleartext_or_ciphertext) + Same as "crypt", except it *modifies the argument in-place*. + + $constant_32 = $cipher->keysize + $constant_64 = $cipher->blocksize + These methods are provided for Crypt::CBC compatibility and simply + return 32 and 64, respectively. + + Note that it is pointless to use Spritz with Crypt::CBC, as Spritz + is not a block cipher and already provides an appropriate mode. + + THE Crypt::Spritz::Hash CLASS + This implements the Spritz digest/hash algorithm. It works very similar + to other digest modules on CPAN, such as Digest::SHA3. + + Typical use for hashing: + + # create hasher object + my $hasher = new Crypt::Spritz::Hash; + + # now feed data to be hashed into $hasher + # in as few or many calls as required + $hasher->add ("Some data"); + $hasher->add ("Some more"); + + # extract the hash - the object is not usable afterwards + my $digest = $hasher->finish (32); + + $hasher = new Crypt::Spritz::Hash + Creates a new hasher object. + + $hasher->add ($data) + Adds data to be hashed into the hasher state. It doesn't matter + whether you pass your data in in one go or split it up, the hash + will be the same. + + $digest = $hasher->finish ($length) + Calculates a hash digest of the given length and return it. The + object cannot sensibly be used for further hashing afterwards. + + Typical digest lengths are 16 and 32, corresponding to 128 and 256 + bit digests, respectively. + + THE Crypt::Spritz::MAC CLASS + This implements the Spritz Message Authentication Code algorithm. It + works very similar to other digest modules on CPAN, such as + Digest::SHA3, but implements an authenticated digest (like + Digest::HMAC). + + *Authenticated* means that, unlike Crypt::Spritz::Hash, where everybody + can verify and recreate the hash value for some data, with a MAC, + knowledge of the (hopefully) secret key is required both to create and + to verify the digest. + + Typical use for hashing is almost the same as with Crypt::Spritz::MAC, + except a key (typically 16 or 32 octets) is provided to the constructor: + + # create hasher object + my $hasher = new Crypt::Spritz::Mac $key; + + # now feed data to be hashed into $hasher + # in as few or many calls as required + $hasher->add ("Some data"); + $hasher->add ("Some more"); + + # extract the mac - the object is not usable afterwards + my $mac = $hasher->finish (32); + + $hasher = new Crypt::Spritz::MAC $key + Creates a new hasher object. The $key can be of any length, but 16 + and 32 (128 and 256 bit) are customary. + + $hasher->add ($data) + Adds data to be hashed into the hasher state. It doesn't matter + whether you pass your data in in one go or split it up, the hash + will be the same. + + $mac = $hasher->finish ($length) + Calculates a message code of the given length and return it. The + object cannot sensibly be used for further hashing afterwards. + + Typical digest lengths are 16 and 32, corresponding to 128 and 256 + bit digests, respectively. + + THE Crypt::Spritz::AEAD::XOR CLASS + This is the most complicated class - it combines encryption and message + authentication into a single "authenticated encryption mode". It is + similar to using both Crypt::Spritz::Cipher::XOR and Crypt::Spritz::MAC, + but makes it harder to make mistakes in combining them. + + You can additionally provide cleartext data that will not be encrypted + or decrypted, but that is nevertheless authenticated using the MAC, + which is why this mode is called *AEAD*, *Authenticated Encryption with + Associated Data*. Associated data is usually used to any header data + that is in cleartext, but should nevertheless be authenticated. + + This implementation implements the XOR variant. Just as with + Crypt::Spritz::Cipher::XOR, this means it is not compatible with the + standard mode, but uses less code and doesn't distinguish between + encryption and decryption. + + Typical usage is as follows: + + # create a new aead object + # you use one object per message + # key length customarily is 16 or 32 + my $aead = new Crypt::Spritz::AEAD::XOR $key; + + # now you must feed the nonce. if you do not need a nonce, + # you can provide the empty string, but you have to call it + # after creating the object, before calling associated_data. + # the nonce must be different for each usage of the $key. + # a counter of some kind is good enough. + # reusing a nonce with the same key completely + # destroys security! + $aead->nonce ($counter); + + # then you must feed any associated data you have. if you + # do not have associated cleartext data, you can provide the empty + # string, but you have to call it after nonce and before crypt. + $aead->associated_data ($header); + + # next, you call crypt one or more times with your data + # to be encrypted (opr decrypted). + # all except the last call must use a length that is a + # multiple of 64. + # the last block can have any length. + my $encrypted; + + $encrypted .= $aead->crypt ("1" x 64); + $encrypted .= $aead->crypt ("2" x 64); + $encrypted .= $aead->crypt ("3456"); + + # finally you can calculate the MAC for all of the above + my $mac = $aead->finish; + + $aead = new Crypt::Spritz::AEAD::XOR $key + Creates a new cipher object usable for encryption and decryption. + + The $key can be of any length. Typical lengths for the $key are 16 + (128 bit) or 32 (256 bit). + + After creation, you have to call "nonce" next. + + $aead->nonce ($nonce) + Provide the nonce value (nonce means "value used once"), a value the + is unique between all uses with the same key. This method *must* be + called *after* "new" and *before* "associated_data". + + If you only ever use a given key once, you can provide an empty + nonce - but you still have to call the method. + + Common strategies to provide a nonce are to implement a persistent + counter or to generate a random string of sufficient length to + guarantee that it differs each time. + + The problem with counters is that you might get confused and forget + increments, and thus reuse the same sequence number. The problem + with random strings i that your random number generator might be + hosed and generate the same randomness multiple times (randomness + can be very hard to get especially on embedded devices). + + $aead->associated_data ($data)( + Provide the associated data (cleartext data to be authenticated but + not encrypted). This method *must* be called *after* "nonce" and + *before* "crypt". + + If you don't have any associated data, you can provide an empty + string - but you still have to call the method. + + Associated data is typically header data - data anybody is allowed + to see in cleartext, but that should nevertheless be protected with + an authentication code. Typically such data is used to identify + where to forward a message to, how to find the key to decrypt the + message or in general how to interpret the encrypted part of a + message. + + $encrypted = $cipher->crypt ($cleartext) + $cleartext = $cipher->crypt ($encrypted) + Encrypt or decrypt a piece of a message. This cna be called as many + times as you want, and the message can be split into as few or many + pieces as required without affecting the results, with one + exception: All except the last call to "crypt" needs to pass in a + multiple of 64 octets. The last call to "crypt" does not have this + limitation. + + $cipher->crypt_inplace ($cleartext_or_ciphertext) + Same as "crypt", except it *modifies the argument in-place*. + + THE Crypt::Spritz::PRNG CLASS + This class implements a Pseudorandom Number Generatore (PRNG), sometimes + also called a Deterministic Random Bit Generator (DRBG). In fact, it is + even cryptographically secure, making it a CSPRNG. + + Typical usage as a random number generator involves creating a PRNG + object with a seed of your choice, and then fetching randomness via + "get": + + # create a PRNG object, use a seed string of your choice + my $prng = new Crypt::Spritz::PRNG $seed; + + # now call get as many times as you wish to get binary randomness + my $some_randomness = $prng->get (17); + my moree_randomness = $prng->get (5000); + ... + + Typical usage as a cryptographically secure random number generator is + to feed in some secret entropy (32 octets/256 bits are commonly + considered enough), for example from "/dev/random" or "/dev/urandom", + and then generate some key material. + + # create a PRNG object + my $prng = new Crypt::Spritz::PRNG; + + # seed some entropy (either via ->add or in the constructor) + $prng->add ($some_secret_highly_entropic_string); + + # now call get as many times as you wish to get + # hard to guess binary randomness + my $key1 = $prng->get (32); + my $key2 = $prng->get (16); + ... + + # for long running programs, it is advisable to + # reseed the PRNG from time to time with new entropy + $prng->add ($some_more_entropy); + + $prng = new Crypt::Spritz::PRNG [$seed] + Creates a new random number generator object. If $seed is given, + then the $seed is added to the internal state as if by a call to + "add". + + $prng->add ($entropy) + Adds entropy to the internal state, thereby hopefully making it + harder to guess. Good sources for entropy are irregular hardware + events, or randomness provided by "/dev/urandom" or "/dev/random". + + The design of the Spritz PRNG should make it strong against attacks + where the attacker controls all the entropy, so it should be safe to + add entropy from untrusted sources - more is better than less if you + need a CSPRNG. + + For use as PRNG, of course, this matters very little. + + $octets = $prng->get ($length) + Generates and returns $length random octets as a string. + +SEE ALSO + . + +SECURITY CONSIDERATIONS + I also cannot give any guarantees for security, Spritz is a very new + cryptographic algorithm, and when this module was written, almost + completely unproven. + +AUTHOR + Marc Lehmann + http://software.schmorp.de/pkg/Crypt-Spritz +