NAME

Crypt::Sodium::XS::sign - Asymmetric (public/secret key) signatures and verification

SYNOPSIS

use Crypt::Sodium::XS;

my $sign = Crypt::Sodium::XS->sign;

my ($pk, $sk) = $sign->keypair;
my $msg = "this is a message";

my $signed_message = $sign->sign($msg, $sk);
die "invalid signature" unless $sign->open($signed_message, $pk);

my $sig = $sign->detached($msg, $sk);
die "invalid signature" unless $sign->verify($msg, $sig, $pk);

my $multipart = $sign->init;
$multipart->update("this is");
$multipart->update(" a", " message");
$sig = $multipart->final_sign($sk);
$multipart = $sign->init;
$multipart->update($msg);
die "invalid signature" unless $multipart->final_verify($sig, $pk);

DESCRIPTION

With Crypt::Sodium::XS::sign, a signer generates a key pair with:

a secret key

Used to append a signature to any number of messages.

a public key

Can be used by anybody to verify that the signature appended to a message was actually issued by the creator of the public key.

Verifiers need to already know and ultimately trust a public key before messages signed using it can be verified.

Warning: this is different from authenticated encryption. Appending a signature does not change the representation of the message itself.

CONSTRUCTOR

The constructor is called with the Crypt::Sodium::XS->sign method.

my $sign = Crypt::Sodium::XS->sign;
my $sign = Crypt::Sodium::XS->sign(primitive => 'ed25519');

Returns a new secretstream object.

Implementation detail: the returned object is blessed into Crypt::Sodium::XS::OO::sign.

ATTRIBUTES

primitive

my $primitive = $sign->primitive;
$sign->primitive('ed25519');

Gets or sets the primitive used for all operations by this object. It must be one of the primitives listed in "PRIMITIVES", including default.

METHODS

primitives

my @primitives = $sign->primitives;
my @primitives = Crypt::Sodium::XS::sign->primitives;

Returns a list of all supported primitive names, including default.

Can be called as a class method.

PRIMITIVE

my $primitive = $sign->PRIMITIVE;

Returns the primitive used for all operations by this object. Note this will never be default but would instead be the primitive it represents.

detached

my $signature = $sign->detached($message, $my_secret_key);

$message is the message to sign.

$my_secret_key is a secret key used to sign the message. It must be "SECRETKEYBYTES" bytes. It may be a Crypt::Sodium::XS::MemVault.

Returns a message signature of "BYTES" bytes.

init

my $multipart = $sign->init($flags);

$flags is optional. It is the flags used for the multipart sign protected memory object. See Crypt::Sodium::XS::ProtMem.

Returns a multipart sign object. See "MULTI-PART INTERFACE".

keypair

my ($public_key, $secret_key) = $sign->keypair($seed, $flags);

$seed is optional. It must be "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 "PUBLICKEYBYTES" bytes and a Crypt::Sodium::XS::MemVault: a secret key of "SECRETKEYBYTES" bytes.

open

my $message = $sign->open($signed_message, $their_public_key);

Croaks on invalid signature.

$signed_message is the combined message and signature from an earlier call to "sign".

$their_public_key is the public key used to authenticate the message signature. It must be "PUBLICKEYBYTES" bytes.

Returns the message content without the signature.

sign

my $signed_message = $sign->sign($message, $my_secret_key);

$message is the message to sign. It may be a Crypt::Sodium::XS::MemVault.

$my_secret_key is a secret key used to sign the message. It must be "KEYBYTES" bytes. It may be a Crypt::Sodium::XS::MemVault.

Returns the combined message and signature.

verify

my $is_valid = $sign->verify($message, $signature, $their_public_key);

$message is the message data to validate against the signature and key.

$signature is the detached message signature from an earlier call to "detached". It must be "BYTES" bytes.

$their_public_key is the public key used to authenticate the message signature. It must be "PUBLICKEYBYTES" bytes.

Returns the true if the signature is valid for the message and public key, false otherwise.

sk_to_pk

my $public_key = $sign->sk_to_pk($secret_key);

$secret_key is a secret key. It must be "SECRETKEYBYTES" bytes. It may be a Crypt::Sodium::XS::MemVault.

Returns the public key of "PUBLICKEYBYTES" bytes derived from the secret key.

sk_to_seed

my $seed = $sign->sk_to_seed($secret_key, $flags);

$secret_key is a secret key. It must be "SECRETKEYBYTES" bytes. It may be a Crypt::Sodium::XS::MemVault.

Returns a Crypt::Sodium::XS::MemVault: a seed which can be used to recreate the same secret (and public) key with "keypair".

BYTES

my $signature_size = $sign->BYTES;

Returns the size, in bytes, of a signature.

MESSAGEBYTES_MAX

my $message_max_size = $sign->MESSAGEBYTES_MAX;

Returns the size, in bytes, of the maximum size of any message to be encrypted.

PUBLICKEYBYTES

my $public_key_size = $sign->PUBLICKEYBYTES;

Returns the size, in bytes, of a public key.

SECRETKEYBYTES

my $secret_key_size = $sign->SECRETKEYBYTES;

Returns the size, in bytes, of a secret key.

SEEDBYTES

my $seed_size = $sign->SEEDBYTES;

Returns the size, in bytes, of a seed used by "keypair".

ed25519 to curve25519 METHODS

For the ed25519 primitive only.

Ed25519 keys can be converted to X25519 keys, so that the same key pair can be used both for authenticated encryption (Crypt::Sodium::XS::box) and for signatures (Crypt::Sodium::XS::sign).

If you can afford it, using distinct keys for signing and for encryption is still highly recommended.

The following methods perform these conversions:

pk_to_curve25519

my $curve_public_key = $sign->pk_to_curve25519($public_key);

$public_key is a public key. It must be "PUBLICKEYBYTES" bytes.

Returns the x25519 public key.

sk_to_curve25519

my $curve_secret_key = $sign->pk_to_curve25519($secret_key, $flags);

$secret_key is a secret key. It must be "SECRETKEYBYTES" bytes. It may be a Crypt::Sodium::XS::MemVault.

$flags is optional. It is the flags used for the $curve_secret_key Crypt::Sodium::XS::MemVault. See Crypt::Sodium::XS::ProtMem.

Returns a Crypt::Sodium::XS::MemVault: the x25519 secret key.

to_curve25519

my ($curve_pk, $curve_sk) 
  = $sign->to_curve25519($public_key, $secret_key, $flags);

$public_key is a public key. It must be "PUBLICKEYBYTES" bytes.

$secret_key is a secret key. It must be "SECRETKEYBYTES" bytes. It may be a Crypt::Sodium::XS::MemVault.

$flags is optional. It is the flags used for the $curve_secret_key Crypt::Sodium::XS::MemVault. See Crypt::Sodium::XS::ProtMem.

Returns the x25519 public key and a Crypt::Sodium::XS::MemVault: the x25519 secret key.

MULTI-PART INTERFACE

If the message doesn’t fit in memory, then it can be provided as a sequence of arbitrarily-sized chunks.

This uses the Ed25519ph signature system, which pre-hashes the message. In other words, what gets signed is not the message itself but its image through a hash function.

If the message can fit in memory and be supplied as a single chunk, then the single-part API should be preferred.

Note: Ed25519ph(m) is intentionally not equivalent to Ed25519(SHA512(m)).

Because of this, signatures created with "sign_detached" cannot be verified with the multipart interface, and vice versa.

If, for some reason, you need to pre-hash the message yourself, then use the multi-part "Crypt::Sodium::XS::generichash" APIs and sign the 512-bit output, preferably prefixed by your protocol name (or anything that will make the hash unique for a given use case).

A multipart sign object is created by calling the "init" method. Data to be signed or validated is added by calling the "update" method of that object as many times as desired. An output signature is generated by calling its "final_sign" method with a secret key, or signature verification is performed by calling "final_verify".

The multipart sign object is an opaque object which provides the following methods:

clone

my $multipart_copy = $multipart->clone;

Returns a cloned copy of the multipart sign object, duplicating its internal state.

final_sign

my $signature = $multipart->final_sign($my_secret_key);

$my_secret_key is a secret key used to sign the data. It must be "SECRETKEYBYTES" bytes. It may be a Crypt::Sodium::XS::MemVault.

Returns the detached signature of "BYTES" bytes.

final_verify

my $is_valid = $multipart->final_verify($signature, $their_public_key);

$signature is the detached signature to validate against signed data and the public key. It must be "BYTES" bytes.

$their_public_key is the public key used to authenticate the signature. It must be "PUBLICKEYBYTES" bytes.

update

$multipart->update(@messages);

Adds all given arguments (stringified) to signed data. Any argument may be a Crypt::Sodium::XS::MemVault.

NOTE: The multi-part interface uses a deterministic pre-hashing algorithm with ed25519, which is not the same as simply sign_ed25519(hash_sha512($message)). This module (unlike libsodium) exposes it with the consistent sign_ed25519_init name (no "ph").

PRIMITIVES

  • ed25519 (default)

FUNCTIONS

The object API above is the recommended way to use this module. The functions and constants documented below can be imported instead or in addition.

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 sign_<primitive>_* functions and constants for that primitive. A :all tag imports everything.

sign (function)

sign_<primitive>

my $signed_message = sign($message, $my_secret_key);

Same as "sign" (method).

sign_detached

sign_<primitive>_detached

my $signature = sign_detached($message, $my_secret_key);

Same as "detached".

sign_init

sign_<primitive>_init

my $multipart = sign_init($flags);

Same as "init".

sign_keypair

sign_<primitive>_keypair

my ($public_key, $secret_key) = sign_keypair($seed, $flags);

Same as "keypair".

sign_open

sign_<primitive>_open

my $message = sign_open($signed_message, $their_public_key);

Same as "open".

sign_verify

sign_<primitive>_verify

my $is_valid = sign_verify($message, $signature, $their_public_key);

Same as "verify".

sign_sk_to_pk

sign_<primitive>_sk_to_pk

my $public_key = sign_sk_to_pk($secret_key);

Same as "sk_to_pk".

sign_sk_to_seed

sign_<primitive>_sk_to_seed

my $seed = sign_sk_to_seed($secret_key);

Same as "sk_to_seed".

sign_ed25519_pk_to_curve25519

my $curve_public_key = sign_ed25519_pk_to_curve25519($public_key);

Same as "pk_to_curve25519".

sign_ed25519_sk_to_curve25519

my $curve_secret_key = sign_ed25519_pk_to_curve25519($secret_key);

Same as "sk_to_curve25519".

sign_ed25519_to_curve25519

my ($curve_pk, $curve_sk) sign_to_curve25519($public_key, $secret_key);

Same as "to_curve25519".

CONSTANTS

sign_PRIMITIVE

my $default_primitive = sign_PRIMITIVE();

Returns the name of the default primitive.

sign_BYTES

sign_<primitive>_BYTES

my $signature_size = sign_BYTES();

Same as "BYTES".

sign_MESSAGEBYTES_MAX

sign_<primitive>_MESSAGEBYTES_MAX

my $message_max_size = sign_MESSAGEBYTES_MAX();

Same as "MESSAGEBYTES_MAX".

sign_PUBLICKEYBYTES

sign_<primitive>_PUBLICKEYBYTES

my $public_key_size = sign_PUBLICKEYBYTES();

Same as "PUBLICKEYBYTES".

sign_SECRETKEYBYTES

sign_<primitive>_SECRETKEYBYTES

my $secret_key_size = sign_SECRETKEYBYTES();

Same as "SECRETKEYBYTES".

sign_SEEDBYTES

sign_<primitive>_SEEDBYTES

my $seed_size = sign_SEEDBYTES();

Same as "SEEDBYTES".

Returns the size, in bytes, of a seed used by "keypair".

SEE ALSO

Crypt::Sodium::XS
https://doc.libsodium.org/public-key_cryptography/public-key_signatures
https://doc.libsodium.org/advanced/ed25519-curve25519

FEEDBACK

For reporting bugs, giving feedback, submitting patches, etc. please use the following:

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.