NAME
Crypt::Sodium::XS::box - Asymmetric (public/secret key) authenticated encryption
SYNOPSIS
use Crypt::Sodium::XS::box ":default";
use Crypt::Sodium::XS::Util "sodium_increment";
my ($pk, $sk) = box_keypair();
my ($pk2, $sk2) = box_keypair();
my $nonce = box_nonce();
my $ct = box_encrypt("hello", $nonce, $pk2, $sk);
my $pt = box_decrypt($ct, $nonce, $pk, $sk2);
# $pt is now "hello" (MemVault)
$nonce = sodium_increment($nonce);
($ct, my $tag) = box_encrypt_detached("world", $nonce, $pk, $sk2);
$pt = box_decrypt_detached($ct, $tag, $nonce, $pk2, $sk);
# $pt is now "world" (MemVault)
my $precalc1 = box_beforenm($pk2, $sk);
my $precalc2 = box_beforenm($pk, $sk2);
# $precalc and $precalc2 hold identical derived secret keys
$nonce = box_nonce();
$ct = $precalc->encrypt("goodbye", $nonce);
$pt = $precalc2->decrypt($ct, $nonce);
# $pt is now "goodbye" (MemVault)
$ct = box_seal_encrypt("anonymous message", $pk2);
$pt = box_seal_decrypt($ct, $pk, $sk);
DESCRIPTION
Using public-key authenticated encryption, Alice can encrypt a confidential message specifically for Bob, using Bob's public key.
Based on Bob's public key, Alice can compute a shared secret key. Using Alice's public key and his secret key, Bob can compute the exact same shared secret key. That shared secret key can be used to verify that the encrypted message was not tampered with, before eventually decrypting it.
In order to send messages to Bob, Alice only needs Bob's public key. Bob should never ever share his secret key (not even with Alice).
For verification and decryption, Bob only needs Alice's public key, the nonce and the ciphertext. Alice should never ever share her secret key either, even with Bob.
Bob can reply to Alice using the same system, without having to generate a distinct key pair. The nonce doesn't have to be confidential, but it should be used with just one invocation of "box_encrypt" for a particular pair of public and secret keys.
One easy way to generate a nonce is to use "box_nonce", considering the size of the nonces the risk of any random collisions is negligible. For some applications, if you wish to use nonces to detect missing messages or to ignore replayed messages, it is also acceptable to use a simple incrementing counter as a nonce. A better alternative is to use the Crypt::Sodium::XS::secretstream API.
When doing so you must ensure that the same nonce can never be re-used (for example you may have multiple threads or even hosts generating messages using the same key pairs).
As stated above, senders can decrypt their own messages, and compute a valid authentication tag for any messages encrypted with a given shared secret key. This is generally not an issue for online protocols. If this is not acceptable, check out "box_seal_encrypt" and "box_seal_decrypt", as well as the Crypt::Sodium::XS::kx.
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 box_<primitive>_*
functions and constants for that primitive. A :all
tag imports everything.
box_beforenm
box_<primitive>_beforenm
my $precalc = box_beforenm($their_public_key, $my_secret_key, $flags);
$their_public_key
is the public key used by the precalcuation object. It must be "box_PUBLICKEYBYTES" bytes.
$my_secret_key
is the secret key used by the precalculation object. It must be "box_KEYBYTES" bytes. It may be a Crypt::Sodium::XS::MemVault.
$flags
is optional. It is the flags used for the precalculation protected memory object. See Crypt::Sodium::XS::ProtMem.
Returns an opaque protected memory object: a precalculation box object. This is useful if you send or receive many messages using the same public key. See "PRECALCULATION INTERFACE".
box_decrypt
box_<primitive>_decrypt
my $plaintext = box_decrypt(
$ciphertext,
$nonce,
$their_public_key,
$my_secret_key,
$flags
);
Croaks on decryption failure.
$ciphertext
is the ciphertext to decrypt.
$nonce
is the nonce used to encrypt the ciphertext. It must be "box_NONCEBYTES" bytes.
$their_public_key
is the public key used to authenticate the ciphertext. It must be "box_PUBLICKEYBYTES" bytes.
$my_secret_key
is the secret key used to decrypt the ciphertext. It must be "box_SECRETKEYBYTES" bytes. It may be a Crypt::Sodium::XS::MemVault.
$flags
is optional. It is the flags used for the $plaintext
Crypt::Sodium::XS::MemVault. See Crypt::Sodium::XS::Protmem.
Returns a Crypt::Sodium::XS::MemVault: the decrypted plaintext.
NOTE: this is the libsodium function crypto_box_open_easy
. Its name is slightly different for consistency of this API.
box_decrypt_detached
box_<primitive>_decrypt_detached
my $plaintext = box_decrypt_detached(
$ciphertext,
$tag,
$nonce,
$their_public_key,
$my_secret_key,
$flags
);
Croaks on decryption failure.
$ciphertext
is the ciphertext to decrypt.
$tag
is the ciphertext's authentication tag. It must be "box_MACBYTES" bytes.
$nonce
is the nonce used to encrypt the ciphertext. It must be "box_NONCEBYTES" bytes.
$their_public_key
is the public key used to authenticate the ciphertext. It must be "box_PUBLICKEYBYTES" bytes.
$my_secret_key
is the secret key used to decrypt the ciphertext. It must be "box_SECRETKEYBYTES" bytes. It may be a Crypt::Sodium::XS::MemVault.
$flags
is optional. It is the flags used for the $plaintext
Crypt::Sodium::XS::MemVault. See Crypt::Sodium::XS::Protmem.
Returns a Crypt::Sodium::XS::MemVault: the decrypted plaintext.
NOTE: this is the libsodium function crypto_box_open_detached
. Its name is slightly different for consistency of this API.
box_encrypt
box_<primitive>_encrypt
my $ciphertext
= box_encrypt($message, $nonce, $their_public_key, $my_secret_key);
$message
is the message to encrypt. It may be a Crypt::Sodium::XS::MemVault.
$nonce
is the nonce used to encrypt the ciphertext. It must be "box_NONCEBYTES" bytes.
$their_public_key
is the public key used to encrypt the ciphertext. It must be "box_PUBLICKEYBYTES" bytes.
$my_secret_key
is the secret key used to authenticate the ciphertext. It must be "box_SECRETKEYBYTES" bytes. It may be a Crypt::Sodium::XS::MemVault.
Returns the encrypted ciphertext.
NOTE: this is the libsodium function crypto_box
. Its name is slightly different for consistency of this API.
box_encrypt_detached
box_<primitive>_encrypt_detached
my ($ciphertext, $tag)
= box_encrypt_detached($message, $nonce, $their_public_key, $my_secret_key);
$message
is the message to encrypt. It may be a Crypt::Sodium::XS::MemVault.
$nonce
is the nonce used to encrypt the ciphertext. It must be "box_NONCEBYTES" bytes.
$their_public_key
is the public key used to encrypt the ciphertext. It must be "box_PUBLICKEYBYTES" bytes.
$my_secret_key
is the secret key used to authenticate the ciphertext. It must be "box_SECRETKEYBYTES" bytes. It may be a Crypt::Sodium::XS::MemVault.
Returns the encrypted ciphertext and its authentication tag.
NOTE: this is the libsodium function crypto_box_easy_detached
. Its name is slightly different for consistency of this API.
box_keypair
box_<primitive>_keypair
my ($public_key, $secret_key) = box_keypair($seed, $flags);
$seed
is optional. It must be "box_SEEDBYTES" bytes. It may be a Crypt::Sodium::XS::MemVault. Using the same seed will generate the same key pair, so it must be kept confidential. If omitted, a key pair is randomly generated.
$flags
is optional. It is the flags used for the $secret_key
Crypt::Sodium::XS::MemVault. See Crypt::Sodium::XS::ProtMem.
Returns a public key of "box_PUBLICKEYBYTES" bytes and a Crypt::Sodium::XS::MemVault: the secret key of "box_SECRETKEYBYTES" bytes.
box_nonce
box_<primitive>_nonce
my $nonce = box_nonce($base);
$base
is optional. It must be less than or equal to "box_NONCEBYTES" bytes. If not provided, the nonce will be random.
Returns a nonce of "box_NONCEBYTES" bytes.
SEALED BOXES
Sealed boxes are designed to anonymously send messages to a recipient given their public key.
Only the recipient can decrypt these messages using their private key. While the recipient can verify the integrity of the message, they cannot verify the identity of the sender.
A message is encrypted using an ephemeral key pair, with the secret key being erased right after the encryption process.
Without knowing the secret key used for a given message, the sender cannot decrypt the message later. Furthermore, without additional data, a message cannot be correlated with the identity of its sender.
box_seal_decrypt
box_<primitive>_seal_decrypt
my $plaintext = \
box_seal_decrypt($ciphertext, $my_public_key, $my_secret_key, $flags);
Croaks on decryption failure.
$ciphertext
is the ciphertext to decrypt.
$my_public_key
is the public key used to authenticate the ciphertext. It must be "box_PUBLICKEYBYTES" bytes.
$my_secret_key
is the secret key from which the public key is derived. It must be "box_SECRETKEYBYTES" bytes. It may be a Crypt::Sodium::XS::MemVault.
$flags
is optional. It is the flags used for the $plaintext
Crypt::Sodium::XS::MemVault. See Crypt::Sodium::XS::ProtMem.
Returns a Crypt::Sodium::XS::MemVault: the decrypted plaintext.
This function doesn’t require passing the public key of the sender as the ciphertext already includes this information. It requires passing $my_public_key
as the anonymous sender and recipient public keys are used to generate a nonce.
NOTE: this is the libsodium function crypto_box_seal_open
. Its name is slightly different for consistency of this API.
box_seal_encrypt
box_<primitive>_seal_encrypt
my $ciphertext = box_seal_encrypt($message, $their_public_key);
$message
is the message to encrypt. It may be a Crypt::Sodium::XS::MemVault.
$their_public_key
is the public key to which the message is encrypted. It must be "box_PUBLICKEYBYTES" bytes.
Returns the combined ciphertext.
The function creates a new key pair for each message and attaches the public key to the ciphertext. The secret key is overwritten and is not accessible after this function returns.
NOTE: this is the libsodium function crypto_box_seal
. Its name is slightly different for consistency of this API.
PRECALCULATION INTERFACE
Applications that send several messages to the same recipient or receive several messages from the same sender can improve performance by calculating the shared key only once, via the precalculation interface.
A precalculated box object is created by calling the "box_beforenm" function. It is an opaque object which provides the following methods:
- decrypt
-
my $plaintext = $precalc->decrypt($ciphertext, $nonce, $flags);
Croaks on decryption failure.
$ciphertext
is the ciphertext to decrypt.$nonce
is the nonce used to encrypt the ciphertext. It must be "box_NONCEBYTES" bytes.$their_public_key
is the public key derived from the secret key used to encrypt the ciphertext. It must be "box_PUBLICKEYBYTES" bytes.$my_secret_key
is the secret key from which was derived the public key used to encrypt the ciphertext. It must be "box_SECRETKEYBYTES" bytes. It may be a Crypt::Sodium::XS::MemVault.$flags
is optional. It is the flags used for the$plaintext
Crypt::Sodium::XS::MemVault. See Crypt::Sodium::XS::ProtMem.Returns a Crypt::Sodium::XS::MemVault: the decrypted plaintext.
- decrypt_detached
-
my $plaintext = $precalc->decrypt_detached($ciphertext, $tag, $nonce, $flags);
Croaks on decryption failure.
$ciphertext
is the ciphertext to decrypt.$tag
is the ciphertext's authentication tag. It must be "box_MACBYTES" bytes.$nonce
is the nonce used to encrypt the ciphertext. It must be "box_NONCEBYTES" bytes.$their_public_key
is the public key derived from the secret key used to encrypt the ciphertext. It must be "box_PUBLICKEYBYTES" bytes.$my_secret_key
is the secret key from which was derived the public key used to encrypt the ciphertext. It must be "box_SECRETKEYBYTES" bytes. It may be a Crypt::Sodium::XS::MemVault.$flags
is optional. It is the flags used for the$plaintext
Crypt::Sodium::XS::MemVault. See Crypt::Sodium::XS::Protmem.Returns a Crypt::Sodium::XS::MemVault: the decrypted plaintext.
- encrypt
-
my $ciphertext = $precalc->encrypt($message, $nonce);
$message
is the message to encrypt. It may be a Crypt::Sodium::XS::MemVault.$nonce
is the nonce used to encrypt the ciphertext. It must be "box_NONCEBYTES" bytes.Returns the encrypted ciphertext.
- encrypt_detached
-
my ($ciphertext, $tag) = $precalc->encrypt($message, $nonce);
$message
is the message to encrypt. It may be a Crypt::Sodium::XS::MemVault.$nonce
is the nonce used to encrypt the ciphertext. It must be "box_NONCEBYTES" bytes.Returns the encrypted ciphertext and its authentication tag.
CONSTANTS
box_PRIMITIVE
my $default_primitive = box_PRIMITIVE();
Returns the name of the default primitive.
box_BEFORENMBYTES
box_<primitive>_BEFORENMBYTES
my $shared_key_size = box_BEFORENMBYTES();
Returns the size, in bytes, of the pre-calculated state created by "box_beforenm". Not normally needed.
box_MACBYTES
box_<primitive>_MACBYTES
my $tag_size = box_MACBYTES();
Returns the size, in bytes, of a message authentication tag.
The size of a combined (not detached) encrypted ciphertext is message size + "box_MACBYTES".
box_MESSAGEBYTES_MAX
box_<primitive>_MESSAGEBYTES_MAX
my $message_max_size = box_MESSAGEBYTES_MAX();
Returns the size, in bytes, of the maximum size of any message to be encrypted.
box_NONCEBYTES
box_<primitive>_NONCEBYTES
my $nonce_size = box_NONCEBYTES();
Returns the size, in bytes, of a nonce.
box_PUBLICKEYBYTES
Returns the size, in bytes, of a public key.
box_<primitive>_PUBLICKEYBYTES
my $public_key_size = box_PUBLICKEYBYTES();
box_SEALBYTES
box_<primitive>_SEALBYTES
my $seal_size = box_SEALBYTES();
Returns the size, in bytes, of the "seal" attached to a sealed box. The size of a sealed box is the message size + "box_SEALBYTES".
box_SECRETKEYBYTES
box_<primitive>_SECRETKEYBYTES
my $secret_key_size = box_SECRETKEYBYTES();
Returns the size, in bytes, of a private key.
box_SEEDBYTES
box_<primitive>_SEEDBYTES
my $keypair_seed_size = box_SEEDBYTES();
Returns the size, in bytes, of a seed used by "box_keypair".
PRIMITIVES
All constants (except _PRIMITIVE) and functions have box_<primitive>
-prefixed couterparts (e.g., box_curve25519xchacha20poly1305_encrypt, box_curve25519xsalsa20poly1305_SEEDBYTES).
curve25519xchacha20poly1305
curve25519xsalsa20poly1305 (default)
SEE ALSO
- Crypt::Sodium::XS
- Crypt::Sodium::XS::OO::box
- https://doc.libsodium.org/public-key_cryptography/authenticated_encryption
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.
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.