--- Crypt-Spritz/Spritz.pm 2015/01/10 07:48:29 1.6 +++ Crypt-Spritz/Spritz.pm 2015/01/10 09:20:24 1.7 @@ -12,6 +12,10 @@ my $cipher = new Crypt::Spritz::Cipher::XOR $key, $iv; $ciphertext = $cipher->crypt ($cleartext); + my $cipher = new Crypt::Spritz::Cipher $key, $iv; + $ciphertext = $cipher->encrypt ($cleartext); + # $cleartext = $cipher->decrypt ($ciphertext); + my $hasher = new Crypt::Spritz::Hash; $hasher->add ($data); $digest = $hasher->finish; @@ -20,15 +24,22 @@ $hasher->add ($data); $mac = $hasher->finish; + my $prng = new Crypt::Spritz::PRNG $entropy; + $prng->add ($additional_entropy); + $keydata = $prng->get (32); + 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); + my $aead = new Crypt::Spritz::AEAD $key; + $aead->nonce ($counter); + $aead->associated_data ($header); + $ciphertext = $aead->encrypt ($cleartext); + # $cleartext = $aead->decrypt ($ciphertext); + $mac = $aead->mac; =head1 DESCRIPTION @@ -57,11 +68,13 @@ and safer, a number of convenience classes are provided for typical end-user tasks: - encryption - Crypt::Spritz::Cipher::XOR + random number generation - Crypt::Spritz::PRNG hashing - Crypt::Spritz::Hash message authentication - Crypt::Spritz::MAC + encryption - Crypt::Spritz::Cipher::XOR + encryption - Crypt::Spritz::Cipher authenticated encryption - Crypt::Spritz::AEAD::XOR - random number generation - Crypt::Spritz::PRNG + authenticated encryption - Crypt::Spritz::AEAD =cut @@ -167,80 +180,67 @@ =back -=head2 THE Crypt::Spritz::Cipher::XOR CLASS +=head2 THE Crypt::Spritz::PRNG CLASS -This class implements stream encryption/decryption. It doesn't implement -the standard Spritz encryption but the XOR variant (called B -in the paper). +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. -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 usage as a random number generator involves creating a PRNG +object with a seed of your choice, and then fetching randomness via +C: -Typical use for encryption I decryption (code is identical for -decryption, you simply pass the encrypted data to C): + # create a PRNG object, use a seed string of your choice + my $prng = new Crypt::Spritz::PRNG $seed; - # 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. + # 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); + ... - my $cipher = Crypt::Spritz::Cipher::XOR $key, $salt; +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. - # encrypt a message in one or more calls to crypt + # create a PRNG object + my $prng = new Crypt::Spritz::PRNG; - my $encrypted; + # seed some entropy (either via ->add or in the constructor) + $prng->add ($some_secret_highly_entropic_string); - $encrypted .= $cipher->crypt ("This is"); - $encrypted .= $cipher->crypt ("all very"); - $encrypted .= $cipher->crypt ("secret"); + # 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); + ... - # that's all + # 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 $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 can 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 $prng = new Crypt::Spritz::PRNG [$seed] -=item $another_cipher = $cipher->clone +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. -Make an exact copy of the cipher state. This can be useful to cache states -for reuse later, for example, to avoid expensive key setups. +=item $prng->add ($entropy) -While there might be use cases for this feature, it makes a lot more sense -for C and C, as they allow -you to specify the IV/nonce separately. +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. -=item $constant_32 = $cipher->keysize +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. -=item $constant_64 = $cipher->blocksize +For use as PRNG, of course, this matters very little. -These methods are provided for L compatibility and simply -return C<32> and C<64>, respectively. +=item $octets = $prng->get ($length) -Note that it is pointless to use Spritz with L, as Spritz is -not a block cipher and already provides an appropriate mode. +Generates and returns C<$length> random octets as a string. =back @@ -370,6 +370,84 @@ =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 can 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 $another_cipher = $cipher->clone + +Make an exact copy of the cipher state. This can be useful to cache states +for reuse later, for example, to avoid expensive key setups. + +While there might be use cases for this feature, it makes a lot more sense +for C and C, as they allow +you to specify the IV/nonce separately. + +=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. + +=back + + =head2 THE Crypt::Spritz::AEAD::XOR CLASS This is the most complicated class - it combines encryption and @@ -505,71 +583,6 @@ =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. - -=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