NAME
Crypt::Sodium::XS::stream - Stream ciphers
SYNOPSIS
use Crypt::Sodium::XS::stream ":default";
DESCRIPTION
These functions are stream ciphers. They do not provide authenticated encryption. They can be used to generate pseudo-random data from a key, or as building blocks for implementing custom constructions, but they are not alternatives to Crypt::Sodium::XS::secretbox.
FUNCTIONS
Nothing is exported by default. A :default
tag imports the functions and constants documented below. A separate :<primitive>
import tag is provided for each of the primitives listed in "PRIMITIVES". These tags import the stream_<primitive>_*
functions and constants for that primitive. A :all
tag imports everything.
stream_keygen
stream_<primitive>_keygen
my $key = stream_keygen($flags);
$flags
is optional. It is the flags used for the $key
Crypt::Sodium::XS::MemVault. See Crypt::Sodium::XS::Protmem.
Returns a Crypt::Sodium::XS::MemVault: a secret key of "stream_KEYBYTES" bytes.
stream_nonce
stream_<primitive>_nonce
my $nonce = stream_nonce($base);
$base
is optional. It must be less than or equal to "stream_NONCEBYTES" bytes. If not provided, the nonce will be random.
Returns a nonce of "stream_NONCEBYTES" bytes.
stream
stream
my $stream_data = stream($size, $nonce, $key);
$out_size
is the desired size, in bytes, of stream data output.
$nonce
is the nonce used to encrypt the stream data. It must be "stream_NONCEBYTES" bytes.
$key
is the secret key used to encrypt the stream data. It must be "stream_KEYBYTES" bytes. It may be a Crypt::Sodium::XS::MemVault.
Returns $out_size
bytes of stream data.
stream_xor
stream_<primitive>_xor
my $ciphertext = stream_xor($plaintext, $nonce, $key, $flags);
$indata
is the data to xor. It may be a Crypt::Sodium::XS::MemVault.
$nonce
is the nonce used to xor the data. It must be "stream_NONCEBYTES" bytes.
$key
is the secret key used to xor the data. It must be "stream_KEYBYTES" bytes. It may be a Crypt::Sodium::XS::MemVault.
$flags
is optional. If provided, the returned data will be a Crypt::Sodium::XS::MemVault, created with the given flags.
Returns the xor result. May be a Crypt::Sodium::XS::MemVault; see $flags
above.
When using this method to decrypt data, $flags
should be passed (even if 0 or undef) to ensure the decrypted data is protected with a Crypt::Sodium::XS::MemVault.
stream_xor_ic
stream_<primitive>_xor_ic
my $ciphertext
= stream_xor_ic($plaintext, $nonce, $internal_counter, $key, $flags);
$indata
is the data to xor. It may be a Crypt::Sodium::XS::MemVault.
$nonce
is the nonce used to xor the data. It must be "stream_NONCEBYTES" bytes.
$internal_counter
is the initial value of the block counter.
$key
is the secret key used to xor the data. It must be "stream_KEYBYTES" bytes. It may be a Crypt::Sodium::XS::MemVault.
$flags
is optional. If provided, the returned data will be a Crypt::Sodium::XS::MemVault, created with the given flags.
Returns the xor result. May be a Crypt::Sodium::XS::MemVault; see $flags
above.
"xor_ic" is similar to "xor" but adds the ability to set the initial value of the block counter ($internal_counter
) to a non-zero value. This permits direct access to any block without having to compute the previous ones.
When using this method to decrypt data, $flags
should be passed (even if 0 or undef) to ensure the decrypted data is protected with a Crypt::Sodium::XS::MemVault.
CONSTANTS
stream_KEYBYTES
stream_<primitive>_KEYBYTES
my $key_size = stream_KEYBYTES();
Returns the size, in bytes, of a secret key.
stream_MESSAGEBYTES_MAX
stream_<primitive>_MESSAGEBYTES_MAX
my $plaintext_max_size = stream_MESSAGEBYTES_MAX();
Returns the size, in bytes, of the maximum size of any message to be encrypted.
stream_NONCEBYTES
stream_<primitive>_NONCEBYTES
my $nonce_size = stream_NONCEBYTES();
Returns the size, in bytes, of a nonce.
PRIMITIVES
Except for salsa2012, which does not provide an xor_ic function, all constants (except _PRIMITIVE) and functions have stream_<primitive>
-prefixed counterparts (e.g., stream_chacha20_ietf_xor_ic, stream_salsa2012_KEYBYTES).
chacha20
chacha20_ietf
ChaCha20 is a stream cipher developed by Daniel J. Bernstein. Its original design expands a 256-bit key into 2^64 randomly accessible streams, each containing 2^64 randomly accessible 64-byte (512 bits) blocks. It is a variant of Salsa20 with better diffusion.
ChaCha20 doesn’t require any lookup tables and avoids the possibility of timing attacks.
Internally, ChaCha20 works like a block cipher used in counter mode. It includes an internal block counter to avoid incrementing the nonce after each block.
Two variants of the ChaCha20 cipher are implemented in libsodium:
* The original ChaCha20 cipher with a 64-bit nonce and a 64-bit counter, allowing a practically unlimited amount of data to be encrypted with the same (key, nonce) pair.
* The IETF variant increases the nonce size to 96 bits, but reduces the counter size down to 32 bits, allowing only up to 256 GB of data to be safely encrypted with a given (key, nonce) pair.
These primitives should only be used to implement protocols that specifically require them. For all other applications, it is recommended to use the XSalsa20 or the ChaCha20-based construction with an extended nonce, XChaCha20.
salsa20
salsa2012
Salsa20 is a stream cipher developed by Daniel J. Bernstein that expands a 256-bit key into 2^64 randomly accessible streams, each containing 2^64 randomly accessible 64-byte (512 bits) blocks.
Salsa20 doesn’t require any lookup tables and avoids the possibility of timing attacks.
Internally, Salsa20 works like a block cipher used in counter mode. It uses a dedicated 64-bit block counter to avoid incrementing the nonce after each block.
The extended-nonce construction XSalsa20 is generally recommended over raw Salsa20, as it makes it easier to safely generate nonces.
The nonce is 64 bits long. In order to prevent nonce reuse, if a key is being reused, it is recommended to increment the previous nonce instead of generating a random nonce every time a new stream is required.
Salsa2012 is a faster, reduced-rounds (reduced from 20 to 12) primitive.
xchacha20
XChaCha20 is a variant of ChaCha20 with an extended nonce, allowing random nonces to be safe.
XChaCha20 doesn’t require any lookup tables and avoids the possibility of timing attacks.
Internally, XChaCha20 works like a block cipher used in counter mode. It uses the HChaCha20 hash function to derive a subkey and a subnonce from the original key and extended nonce, and a dedicated 64-bit block counter to avoid incrementing the nonce after each block.
XChaCha20 is generally recommended over plain ChaCha20 due to its extended nonce size, and its comparable performance. However, XChaCha20 is currently not widely implemented outside the libsodium library, due to the absence of formal specification.
xsalsa20 (default)
XSalsa20 is a stream cipher based upon Salsa20 but with a much longer nonce: 192 bits instead of 64 bits.
XSalsa20 uses a 256-bit key as well as the first 128 bits of the nonce in order to compute a subkey. This subkey, as well as the remaining 64 bits of the nonce, are the parameters of the Salsa20 function used to actually generate the stream.
Like Salsa20, XSalsa20 is immune to timing attacks and provides its own 64-bit block counter to avoid incrementing the nonce after each block.
But with XSalsa20’s longer nonce, it is safe to generate nonces using randombytes_buf() for every message encrypted with the same key without having to worry about a collision.
SEE ALSO
- Crypt::Sodium::XS
- Crypt::Sodium::XS::OO::stream
- https://doc.libsodium.org/advanced/stream_ciphers
- https://doc.libsodium.org/advanced/stream_ciphers/chacha20
- https://doc.libsodium.org/advanced/stream_ciphers/xchacha20
- https://doc.libsodium.org/advanced/stream_ciphers/salsa20
- https://doc.libsodium.org/advanced/stream_ciphers/xsalsa20
FEEDBACK
For reporting bugs, giving feedback, submitting patches, etc. please use the following:
RT queue at https://rt.cpan.org/Dist/Display.html?Name=Crypt-Sodium-XS
IRC channel
#sodium
onirc.perl.org
.Email the author directly.
For any security sensitive reports, please email the author directly or contact privately via IRC.
AUTHOR
Brad Barden <perlmodules@5c30.org>
COPYRIGHT & LICENSE
Copyright (c) 2022 Brad Barden. All rights reserved.
This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.