The Perl Toolchain Summit needs more sponsors. If your company depends on Perl, please support this very important event.

NAME

Crypt::Salsa20 - Encrypt data with the Salsa20 cipher

VERSION

This document describes version 0.03 of Crypt::Salsa20, released January 25, 2014.

SYNOPSIS

  use Crypt::Salsa20;

  my $salsa20 = Crypt::Salsa20->new(-key => $key, -iv => $nonce);

  # Use cryptor for the best performance:
  my $cryptor = $salsa20->cryptor;
  my $ciphertext = $cryptor->('plaintext');
  # encryption & decryption are the same operation:
  $salsa20->start;   # reset the block counter (keeping key & iv)
  my $plaintext  = $cryptor->($ciphertext);

  # Or use Crypt::CBC-like API:
  my $ciphertext = $salsa20->encrypt('plaintext');
  my $plaintext  = $salsa20->decrypt($ciphertext);

DESCRIPTION

Crypt::Salsa20 implements D. J. Bernstein's Salsa20 stream cipher (a.k.a. Snuffle 2005) in Perl. For more information on Salsa20, see his page at http://cr.yp.to/snuffle.html.

Salsa20 takes a 256 bit (or 128 bit) key and a 64 bit nonce (a.k.a. an IV or message number) and uses them to generate a stream of up to 2**70 bytes of pseudo-random data. That stream is XORed with your message. Because of that, encryption and decryption are the same operation.

It is critical that you never use the same nonce and key to encrypt two different messages. Because the keystream is completely determined by the key and nonce, reusing them means that you can cancel out the keystream by XORing the two ciphertexts together:

  ciphertext1          ^ ciphertext2
  keystream ^ message1 ^ keystream ^ message2
  message1  ^ message2 ^ keystream ^ keystream
  message1  ^ message2 ^           0
  message1  ^ message2

Crypt::Salsa20 vs. Crypt::CBC

The API is similar to that of the Crypt::CBC module, but there are some differences:

  1. There is no -literal_key option. The key is always interpreted as raw bytes (and must be either 16 or 32 bytes long). If you want to use a pasword hashing function, you have to supply your own.

  2. Crypt::Salsa20 doesn't use any sort of header, trailer, padding, or any other metadata. If you need to transmit the nonce as part of your message, you'll need to do it manually.

  3. Since encryption and decryption are the same operation with Salsa20, the start method does not require a parameter, and it is not necessary to call it at all.

  4. The finish method is available, but unnecessary. In Crypt::Salsa20 it does nothing and always returns the empty string.

ATTRIBUTES

Each attribute has a method of the same name. Calling the method with no parameter returns the current value of the attribute. Calling it with a parameter sets the attribute to that value (and returns the new value).

key

The encryption key is a 16 or 32 byte string (128 or 256 bits), with 32 bytes being the recommended size. It's always interpreted as raw bytes; if you want to use a pasword hashing function, you have to supply your own. Setting the key does not change the IV or reset the block counter.

iv

The nonce (IV) is an 8 byte string (64 bits). The nonce does not need to be kept secret, but you must never encrypt two different messages with the same key and nonce, or you have catastrophically weakened the security of the cipher. You must supply an IV before encrypting or decrypting, but you can omit it from the constructor and call the iv method instead. Setting the IV does not change the key, but it does reset the block counter.

rounds

The number of cipher rounds to use. The default is 20, which is the standard Salsa20 cipher. The standard variants are 8 or 12 rounds (Salsa20/8 or Salsa20/12), but any even integer will work.

METHODS

new

  $salsa20 = Crypt::Salsa20->new(-key => $key, ...);

This constructs a new Crypt::Salsa20 object, with attributes supplied as key => value pairs. For compatibility with Crypt::CBC, attribute names may have a leading hyphen (but unlike Crypt::CBC the hyphen is not required).

The only required attribute at construction time is the key (but you must supply an IV before encrypting or decrypting).

start

  $salsa20->start;

Resets the internal block counter, starting the keystream over at the beginning. You should also change the IV, because using the same key and IV is a security breach.

For compatibility with the Crypt::CBC method of the same name, you can pass a parameter (e.g. 'decrypting' or 'encrypting'), but it is ignored. With Salsa20, encryption and decryption are the same operation, so there's no need to indicate which one you want.

This method is primarily for Crypt::CBC compatibility. Since with Salsa20 you don't need to specify whether you're encrypting or decrypting, and the iv method also does everything start does, you don't really need to call this method.

crypt

  $ciphertext = $salsa20->crypt($plaintext);
  $plaintext  = $salsa20->crypt($ciphertext);

Encrypts or decrypts the provided string.

Because encryption & decryption are the same operation, it is not necessary to call start before calling crypt, but you do need to have set the IV, either by passing it to the constructor or calling the iv method.

finish

  $remaining_ciphertext = $salsa20->finish;

This method exists solely for Crypt::CBC compatibility. It always returns the empty string.

encrypt

  $ciphertext = $salsa20->encrypt($plaintext);

Equivalent to calling start and then crypt.

decrypt

  $plaintext = $salsa20->decrypt($ciphertext);

Equivalent to calling start and then crypt (the same as encrypt).

cryptor

  $cryptor = $salsa20->cryptor;
  $ciphertext = $cryptor->($plaintext); # or if decrypting,
  $plaintext  = $cryptor->($ciphertext);

This method is the most efficient way to use Crypt::Salsa20 if you are encrypting multiple chunks. It returns a coderef that encrypts or decrypts the text you pass it. $cryptor->($text) is equivalent to $salsa20->crypt($text), just faster.

The cryptor remains tied to the original object. Changing the key or IV affects it. But it is not necessary to save a reference to the original object if you don't plan to call any other methods.

CONFIGURATION AND ENVIRONMENT

Crypt::Salsa20 requires no configuration files or environment variables.

INCOMPATIBILITIES

None reported.

BUGS AND LIMITATIONS

No bugs have been reported.

AUTHOR

Christopher J. Madsen <perl AT cjmweb.net>

Please report any bugs or feature requests to <bug-Crypt-Salsa20 AT rt.cpan.org> or through the web interface at http://rt.cpan.org/Public/Bug/Report.html?Queue=Crypt-Salsa20.

You can follow or contribute to Crypt-Salsa20's development at https://github.com/madsen/crypt-salsa20.

COPYRIGHT AND LICENSE

This software is copyright (c) 2014 by Christopher J. Madsen.

This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself.

DISCLAIMER OF WARRANTY

BECAUSE THIS SOFTWARE IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE SOFTWARE, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE SOFTWARE "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE SOFTWARE IS WITH YOU. SHOULD THE SOFTWARE PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR, OR CORRECTION.

IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE SOFTWARE AS PERMITTED BY THE ABOVE LICENSE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE SOFTWARE (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE SOFTWARE TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.