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:

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.