- NAME
- VERSION
- SYNOPSIS
- DESCRIPTION
- METHODS
- CONSTANTS
- ALGORITHM DETAILS
- SEE ALSO
- AUTHOR
- COPYRIGHT AND LICENSE

# NAME

Crypt::NaCl::Sodium::box - Public-key authenticated encryption (Curve25519/XSalsa20/Poly1305 MAC)

# VERSION

version 1.0.8.0

# SYNOPSIS

```
use Crypt::NaCl::Sodium qw( :utils );
my $crypto_box = Crypt::NaCl::Sodium->box();
my ($a_skey, $a_pkey, $a_key, $b_skey,
$b_pkey, $b_key,
$a_precal_key, $b_precal_key,
$nonce, $decrypted_msg, $msg, $secret);
## Alice
########
# Alice generates secret keypair
($a_pkey, $a_skey) = $crypto_box->keypair();
# ... and shares the public key with Bob
send_to( Bob => { public_key => $a_pkey } );
## Bob
########
# Bob generates his secret keypair
($b_pkey, $b_skey) = $crypto_box->keypair();
# Bob receives the public key from Alice
$a_key = receive_for( Bob => 'public_key' );
# ... and shares his public key with Alice
send_to( Alice => { public_key => $b_pkey } );
# now Alice and Bob can start communicating
## Alice
########
# Alice receives the public key from Bob
$b_key = receive_for( Alice => 'public_key' );
# Alice generates random nonce
$nonce = $crypto_box->nonce();
send_to( Bob => { nonce => $nonce } );
# Alice's message to Bob
$msg = "Hi Bob!";
# encrypts using combined mode
$secret = $crypto_box->encrypt( $msg, $nonce, $b_key, $a_skey );
# message is ready for Bob
send_to( Bob => { secret => $secret } );
## Bob
########
# Bob receives the random nonce
$nonce = receive_for( Bob => 'nonce' );
# and is now ready to receive first message from Alice
$secret = receive_for( Bob => 'secret' );
# since Bob already has Alice's public key we have all information required to decrypt message
$decrypted_msg = $crypto_box->decrypt( $secret, $nonce, $a_key, $b_skey );
# Bob is going to send a lot of messages to Alice, so we speed up the
# encryption and decryption by pre-calculating the shared key
$b_precal_key = $crypto_box->beforenm( $a_key, $b_skey );
# now it is time to reply
$msg = "Hello Alice!";
# generates new nonce
$nonce = $crypto_box->nonce();
# this time we use detached mode using precalculated key
($mac, $secret) = $crypto_box->encrypt_afternm( $msg, $nonce, $b_precal_key );
# Alice needs all pieces to verify and decrypt Bob's message
send_to( Alice => { nonce => $nonce } );
send_to( Alice => { mac => $mac } );
send_to( Alice => { secret => $secret } );
## Alice
########
# Bob used the detached mode
$nonce = receive_for( Alice => 'nonce' );
$mac = receive_for( Alice => 'mac' );
$secret = receive_for( Alice => 'secret' );
# Alice also pre-calculates the shared key
$a_precal_key = $crypto_box->beforenm( $b_key, $a_skey );
# we have now all information required to decrypt message
$decrypted_msg = $crypto_box->decrypt_detached_afternm( $mac, $secret, $nonce, $a_precal_key );
# NOTE: send_to() and receive_for() and user functions providing transport of
# messages
```

# DESCRIPTION

`crypto_box`

function is designed to meet the standard notions of privacy and third-party unforgeability for a public-key authenticated-encryption scheme using nonces.

The `crypto_box`

function is not meant to provide non-repudiation. On the contrary: the crypto_box function guarantees repudiability. A receiver can freely modify a boxed message, and therefore cannot convince third parties that this particular message came from the sender. The sender and receiver are nevertheless protected against forgeries by other parties. `crypto_box`

uses *public-key authenticators* rather than *public-key signatures*.

Users who want public verifiability (or receiver-assisted public verifiability) should instead use Crypt::NaCl::Sodium::sign.

Using public-key authenticated encryption, parties involved can encrypt a confidential message using their public keys, while keeping their secret keys confidential.

Using the sender's public key, only the receiver can verify that the encrypted message was actually created by the sender and was not tampered with, before eventually decrypting it. This bidirectional guarantee around identity is known as mutual authentication.

The same keypair can be used with multiple other users, without the need of generating a distinct set of keys.

Nonce (number used once) does not have to be protected, but it is crucial that the same nonce has not been ever reused with the same `{sender, receiver}`

set.

# METHODS

## keypair

```
my ($public_key, $secret_key) = $crypto_box->keypair();
# or deterministically derived from a single key seed
my ($public_key, $secret_key) = $crypto_box->keypair( $seed );
```

Helper method to generate a random secret key and corresponding public key to be used by `$crypto_box`

.

See "seed" for more details when generating key pair using given `$seed`

.

The length of the `$public_key`

equals "PUBLICKEYBYTES".

The length of the `$secret_key`

equals "SECRETKEYBYTES".

**NOTE:** keep the secret key confidential.

Returns Data::BytesLocker objects.

## public_key

` my $public_key = $crypto_box->public_key( $secret_key );`

Computes the public key for given secret key.

The length of the `$public_key`

equals "PUBLICKEYBYTES".

Returns Data::BytesLocker objects.

## seed

```
my $seed = $crypto_box->seed();
my ($public_key, $secret_key) = $crypto_box->keypair( $seed );
```

Helper method to generate a random seed, that can be used to deterministically compute the key pair derived from it.

The length of the `$seed`

equals "SEEDBYTES".

Returns Data::BytesLocker objects.

## beforenm

` my $shared_key = $crypto_box->beforenm( $public_key, $secret_key );`

Applications that send several messages to the same receiver or receive several messages from the same sender can gain speed by calculating the shared key only once, and reusing it in subsequent operations.

The length of the `$shared_key`

equals "BEFORENMBYTES".

Returns Data::BytesLocker objects.

## nonce

` my $nonce = $crypto_box->nonce();`

Helper method to generate a random nonce to be used by `$crypto_box`

.

The length of the nonce equals "NONCEBYTES".

If initial value has been passed as the argument, it will then padded with `null`

bytes.

```
my $counter = 121;
my $nonce = $crypto_box->nonce($counter);
$nonce =~ /^121\0+$/ or die;
```

**NOTE:** nonce does not have to be random nor confidential, but it must never be reused with the same `{sender, receiver}`

set.

If random nonce is being used it needs to be provided to the other party to allow decryption.

If counter is being used store it alongside the recipient's public key to avoid accidental reuse on the next session. In connection-oriented protocols counter-based nonce could help rejecting duplicate messages.

Returns Data::BytesLocker object.

## encrypt

```
# combined mode - MAC and encrypted message stored together
my $secret = $crypto_box->encrypt($msg, $nonce,
$recipient_public_key, $sender_secret_key);
# detached mode - MAC and encrypted message returned separate
my ($mac, $ciphertext) = $crypto_box->encrypt($msg, $nonce,
$recipient_public_key, $sender_secret_key);
```

Encrypts the plaintext message using given `$nonce`

, `$recipient_public_key`

and `$sender_secret_key`

.

In scalar context works in combined mode, where MAC and encrypted message are stored together. The length of the `$secret`

equals the length of `$msg`

+ "MACBYTES".

In list context the `$mac`

and `$ciphertext`

are returned separately. The length of the `$ciphertext`

equals the length of `$msg`

, while length of `$mac`

is "MACBYTES".

Returns Data::BytesLocker object.

### encrypt_afternm

```
# combined mode - MAC and encrypted message stored together
my $secret = $crypto_box->encrypt_afternm($msg, $nonce,
$shared_key);
# detached mode - MAC and encrypted message returned separate
my ($mac, $ciphertext) = $crypto_box->encrypt_afternm($msg, $nonce,
$shared_key);
```

Same as above but encrypts using pre-calculated `$shared_key`

(as returned by "beforenm").

## decrypt

```
my $msg;
eval {
$msg = $crypto_box->decrypt($secret, $nonce,
$sender_public_key, $recipient_secret_key);
};
if ( $@ ) {
warn "Message forged!";
} else {
print "Decrypted message: $msg\n";
}
```

Verify and decrypt the secret message using given `$nonce`

, `$sender_public_key`

and `$recipient_secret_key`

.

Function croaks if the verification fails. Otherwise returns the decrypted message.

The length of the `$msg`

equals the length of `$secret`

- "MACBYTES".

Returns Data::BytesLocker object.

### decrypt_afternm

```
my $msg;
eval {
$msg = $crypto_box->decrypt_afternm($secret, $nonce,
$shared_key);
};
if ( $@ ) {
warn "Message forged!";
} else {
print "Decrypted message: $msg\n";
}
```

Same as above but decrypts using pre-calculated `$shared_key`

(as returned by "beforenm").

## decrypt_detached

```
my $msg;
eval {
$msg = $crypto_box->decrypt_detached($mac, $ciphertext, $nonce,
$sender_public_key, $recipient_secret_key);
};
if ( $@ ) {
warn "Message forged!";
} else {
print "Decrypted message: $msg\n";
}
```

Verify and decrypt the secret message `$ciphertext`

authenticated with `$mac`

using given `$nonce`

, `$sender_public_key`

and `$recipient_secret_key`

.

Function croaks if the verification fails. Otherwise returns the decrypted message.

The length of the `$msg`

equals the length of `$ciphertext`

.

Returns Data::BytesLocker object.

### decrypt_detached_afternm

```
my $msg;
eval {
$msg = $crypto_box->decrypt_detached_afternm($mac, $ciphertext, $nonce,
$shared_key);
};
if ( $@ ) {
warn "Message forged!";
} else {
print "Decrypted message: $msg\n";
}
```

Same as above but decrypts using pre-calculated `$shared_key`

(as returned by "beforenm").

# CONSTANTS

## NONCEBYTES

` my $nonce_length = $crypto_box->NONCEBYTES;`

Returns the length of nonce.

## SECRETKEYBYTES

` my $skey_length = $crypto_box->SECRETKEYBYTES;`

Returns the length of secret key.

## PUBLICKEYBYTES

` my $pkey_length = $crypto_box->PUBLICKEYBYTES;`

Returns the length of public key.

## SEEDBYTES

` my $seed_length = $crypto_box->SEEDBYTES;`

Returns the length of seed key.

## BEFORENMBYTES

` my $shared_key_length = $crypto_box->BEFORENMBYTES;`

Returns the length of pre-calculated shared key.

## MACBYTES

` my $mac_length = $crypto_box->MACBYTES;`

Returns the length of MAC.

# ALGORITHM DETAILS

`crypto_box`

for encryption uses XSalsa20 stream cipher (which is based on Salsa20, but with much longer nonce) and Poly1305 MAC for authentication, for key exchange Curve25519 is used.

# SEE ALSO

Data::BytesLocker - guarded data storage

A state-of-the-art Diffie-Hellman function - Curve25519

Extending the Salsa20 nonce - the paper introducing XSalsa20

# AUTHOR

Alex J. G. Burzyński <ajgb@cpan.org>

# COPYRIGHT AND LICENSE

This software is copyright (c) 2015 by Alex J. G. Burzyński <ajgb@cpan.org>.

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