--- Crypt-Spritz/Spritz.pm 2015/01/10 04:56:38 1.3 +++ Crypt-Spritz/Spritz.pm 2015/01/10 07:10:46 1.4 @@ -17,13 +17,36 @@ =head1 DESCRIPTION -This module implements the spritz spongelike function. +This module implements the Spritz spongelike function (with N=256), the +spiritual successor of RC4 developed by Ron Rivest and Jacob Schuldt. -Although it is C compliant you usually gain nothing by using -that module (except generality, which is often a good thing), since -C can work in either ECB or CBC mode itself. - -=over 4 +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 etc. - 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 =cut @@ -35,99 +58,447 @@ XSLoader::load __PACKAGE__, $VERSION; -@Crypt::Spritz::CipherBase::ISA = +@Crypt::Spritz::ISA = Crypt::Spritz::Base::; + @Crypt::Spritz::Hash::ISA = -@Crypt::Spritz::PRNG::ISA = Crypt::Spritz::; +@Crypt::Spritz::PRNG::ISA = +@Crypt::Spritz::Cipher::ISA = +@Crypt::Spritz::AEAD::ISA = Crypt::Spritz::Base::; @Crypt::Spritz::MAC::ISA = Crypt::Spritz::Hash::; -@Crypt::Spritz::Cipher::XOR::ISA = -@Crypt::Spritz::Cipher::ISA = -@Crypt::Spritz::AEAD::ISA = -@Crypt::Spritz::AEAD::XOR::ISA = Crypt::Spritz::CipherBase::; +@Crypt::Spritz::Cipher::XOR::ISA = Crypt::Spritz::Cipher::; +@Crypt::Spritz::AEAD::XOR::ISA = Crypt::Spritz::AEAD::; + +sub Crypt::Spritz::Cipher::keysize () { 32 } +sub Crypt::Spritz::Cipher::blocksize () { 64 } -sub Crypt::Spritz::CipherBase::keysize () { 32 } -sub Crypt::Spritz::CipherBase::blocksize () { 64 } +*Crypt::Spritz::Hash::new = \&Crypt::Spritz::new; *Crypt::Spritz::Hash::add = *Crypt::Spritz::PRNG::add = \&Crypt::Spritz::absorb; *Crypt::Spritz::PRNG::get = \&Crypt::Spritz::squeeze; -*Crypt::Spritz::AEAD::XOR::new = -*Crypt::Spritz::AEAD::new = \&Crypt::Spritz::MAC::new; +*Crypt::Spritz::AEAD::new = \&Crypt::Spritz::MAC::new; +*Crypt::Spritz::AEAD::finish = \&Crypt::Spritz::Hash::finish; + +*Crypt::Spritz::AEAD::associated_data = +*Crypt::Spritz::AEAD::nonce = \&Crypt::Spritz::absorb_and_stop; + + +=head2 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 L, especially +pp. 5-6. + +The Spritz primitive corresponding to the Perl method is given as +comment. + +=over 4 + +=item $spritz = new Crypt::Spritz # InitializeState + +Creates and returns a new, initialised Spritz state. + +=item $spritz->init # InitializeState + +Initialises the Spritz state again, throwing away the previous state. + +=item $spritz->update # Update + +=item $spritz->whip ($r) # Whip + +=item $spritz->crush # Crush + +=item $spritz->shuffle # Shuffle + +=item $spritz->output # Output + +Calls the Spritz primitive ovf the same name - these are not normally +called manually. + +=item $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). + +=item $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. + +=item $spritz->absorb_and_stop ($I) + +This is a convenience function that simply calls C followed by +C. + +=item $octet = $spritz->drip # Drip + +Squeezes out a single byte from the state. + +=item $octets = $spritz->squeeze ($len) # Squeeze + +Squeezes out the requested number of bytes from the state - this is usually + +=back + + +=head2 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 B +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 I decryption (code is identical for +decryption, you simply pass the encrypted data to C): + + # 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 + +=over 4 + +=item $cipher = new Crypt::Spritz::Cipher::XOR $key[, $iv] + +Creates a new cipher object usable for encryption and decryption. The +C<$key> must be provided, the initial vector C<$IV> is optional. + +Both C<$key> and C<$IV> can be of any length. Typical lengths for the +C<$key> are 16 (128 bit) or 32 (256 bit), while the C<$IV> simply needs to +be long enough to distinguish repeated uses of tghe same key. + +=item $encrypted = $cipher->crypt ($cleartext) + +=item $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. + +=item $cipher->crypt_inplace ($cleartext_or_ciphertext) + +Same as C, except it I. + +=item $constant_32 = $cipher->keysize + +=item $constant_64 = $cipher->blocksize + +These methods are provided for L compatibility and simply +return C<32> and C<64>, respectively. + +Note that it is pointless to use Spritz with L, as Spritz is +not a block cipher and already provides an appropriate mode. -*Crypt::Spritz::AEAD::XOR::finish = -*Crypt::Spritz::AEAD::finish = \&Crypt::Spritz::Hash::finish; +=back + + +=head2 THE Crypt::Spritz::Hash CLASS + +This implements the Spritz digest/hash algorithm. It works very similar to +other digest modules on CPAN, such as L. + +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); + +=over 4 + +=item $hasher = new Crypt::Spritz::Hash + +Creates a new hasher object. + +=item $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. + +=item $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. + +=back + + +=head2 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 L, but +implements an authenticated digest (like L). + +I means that, unlike L, 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 L, +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); + +=over 4 + +=item $hasher = new Crypt::Spritz::MAC $key + +Creates a new hasher object. The C<$key> can be of any length, but 16 and +32 (128 and 256 bit) are customary. + +=item $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. + +=item $mac = $hasher->finish ($length) -*Crypt::Spritz::AEAD::XOR::associated_data = -*Crypt::Spritz::AEAD::associated_data = -*Crypt::Spritz::AEAD::XOR::nonce = -*Crypt::Spritz::AEAD::nonce = \&Crypt::Spritz::absborb_and_stop; +Calculates a message code of the given length and return it. The object +cannot sensibly be used for further hashing afterwards. -=item keysize +Typical digest lengths are 16 and 32, corresponding to 128 and 256 bit +digests, respectively. -Returns the keysize, which is 32 (bytes). The Twofish2 cipher actually -supports keylengths of 16, 24 or 32 bytes, but there is no way to -communicate this to C. +=back + + +=head2 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 L and +L, 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 I, I. 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 +L, 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; + +=over 4 + +=item $aead = new Crypt::Spritz::AEAD::XOR $key + +Creates a new cipher object usable for encryption and decryption. + +The C<$key> can be of any length. Typical lengths for the C<$key> are 16 +(128 bit) or 32 (256 bit). + +After creation, you have to call C next. + +=item $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 I be called +I C and I C. + +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. -=item blocksize +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). -The blocksize for Twofish2 is 16 bytes (128 bits), which is somewhat -unique. It is also the reason I need this module myself ;) +=item $aead->associated_data ($data)( -=item $cipher = new $key [, $mode] +Provide the associated data (cleartext data to be authenticated but not +encrypted). This method I be called I C and I +C. -Create a new C cipher object with the given key (which -must be 128, 192 or 256 bits long). The additional C<$mode> argument is -the encryption mode, either C (electronic cookbook mode, the -default), C (cipher block chaining, the same that C -does) or C (1-bit cipher feedback mode). +If you don't have any associated data, you can provide an empty string - +but you still have to call the method. -ECB mode is very insecure (read a book on cryptography if you don't know -why!), so you should probably use CBC mode. CFB1 mode is not tested and is -most probably broken, so do not try to use it. +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. -In ECB mode you can use the same cipher object to encrypt and decrypt -data. However, every change of "direction" causes an internal reordering -of key data, which is quite slow, so if you want ECB mode and -encryption/decryption at the same time you should create two seperate -C objects with the same key. +=item $encrypted = $cipher->crypt ($cleartext) -In CBC mode you have to use seperate objects for encryption/decryption in -any case. +=item $cleartext = $cipher->crypt ($encrypted) -The C-constants are not exported by this module, so you must -specify them as C etc. (sorry for that). +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 C needs to pass in a multiple of C<64> octets. The +last call to C does not have this limitation. -=item $cipher->encrypt($data) +=item $cipher->crypt_inplace ($cleartext_or_ciphertext) -Encrypt data. The size of C<$data> must be a multiple of C (16 -bytes), otherwise this function will croak. Apart from that, it can be of -(almost) any length. +Same as C, except it I. -=item $cipher->decrypt($data) +=back + + +=head2 THE Crypt::Spritz::PRNG CLASS + +This class implements a Pseudorandom Number Generatore (B), +sometimes also called a Deterministic Random Bit Generator (B). In +fact, it is even cryptographically secure, making it a B. + +Typical usage as a random number generator involves creating a PRNG +object with a seed of your choice, and then fetching randomness via +C: + + # 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 C or C, 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); + +=over 4 + +=item $prng = new Crypt::Spritz::PRNG [$seed] + +Creates a new random number generator object. If C<$seed> is given, then +the C<$seed> is added to the internal state as if by a call to C. -The pendant to C in that it Icrypts data again. +=item $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 C or C. + +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. + +=item $octets = $prng->get ($length) + +Generates and returns C<$length> random octets as a string. =back + =head1 SEE ALSO -L, L, L. +L. =head1 SECURITY CONSIDERATIONS -I also cannot guarantee for security. +I also cannot give any guarantees for security, Spritz is a very new +cryptographic algorithm, and when this module was written, almost +completely unproven. =head1 AUTHOR Marc Lehmann http://home.schmorp.de/ - The actual twofish encryption is written in horribly microsoft'ish looking - almost ansi-c by Doug Whiting. - =cut 1;