NAME

Crypt::Sodium::XS::curve25519 - Low-level functions over Curve25519

SYNOPSIS

# TODO (still)

DESCRIPTION

Crypt::Sodium::XS::curve25519 provides an API to libsodium's low-level core functions over the Curve25519 curve. These functions are not usually needed, and must only be used to implement custom constructions.

CONSTRUCTOR

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

my $curve25519
  = Crypt::Sodium::XS->curve25519(primitive => 'ristretto255');

Returns a new curve25519 object. The primitive attribute is required.

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

ATTRIBUTES

primitive

my $primitive = $curve25519->primitive;
$curve25519->primitive('ristretto255');

Gets or sets the primitive used for all operations by this object. Must be one of the primitives listed in "PRIMITIVES". For this module there is no default primitive, and this attribute is always identical to "PRIMITIVE".

METHODS

ristretto255_available

my $ristretto255_available = $curve25519->ristretto255_available;

Returns true if the version of libsodium this module was built with had the ristretto255 primitive available, false otherwise.

primitives

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

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

Can be called as a class method.

PRIMITIVE

my $primitive = $curve25519->PRIMITIVE;

add

my $r = $curve25519->add($p, $q);

Adds the element represented by $p to the element $q and returns the resulting element.

The function croaks if $p and/or $q are not valid encoded elements.

is_valid_point

my $is_valid = $curve25519->is_valid_point($point);

Checks that $point represents a point on the edwards25519 curve, in canonical form, on the main subgroup, and that the point doesn’t have a small order. Returns true if so, false otherwise.

random

my $point = $curve25519->random;

Returns the representation of a random group element.

from_uniform

from_hash

$curve25519->primitve('ed25519');
my $vector = sodium_random_bytes($curve25519->UNIFORMBYTES);
my $point = $curve25519->from_uniform($vector);
$curve25519->primitive('ristretto255');
my $vector2 = sodium_random_bytes($curve25519->HASHBYTES);
my $point2 = $curve25519->from_hash($vector2);

NOTE: Different methods for primitives ed25519 and ristretto255!

Maps a 32 bytes $vector to a point, and returns its compressed representation.

The point is guaranteed to be on the main subgroup.

This function directly exposes the Elligator 2 map, uses the high bit to set the sign of the X coordinate, and the resulting point is multiplied by the cofactor.

NOTE: Scalar arithmetic over L

The scalar_* methods operate over scalars in the [0..L[ interval, L being the order of the main subgroup (2^252 + 27742317777372353535851937790883648493).

Non-reduced inputs are expected to be within that interval.

scalar_add

my $r = $curve25519->add($p, $q);

Adds the point $p to the point $q.

The function croaks if $p and/or $q are not valid points.

scalar_complement

my $comp = $curve25519->scalar_complement($s, $flags);

Returns a Crypt::Sodium::XS::MemVault: $comp so that $s + $comp = 1 (mod L).

scalar_mul

my $z = $curve25519->scalar_mul($x, $y, $flags);

Returns a Crypt::Sodium::XS::MemVault: $x * $y (mod L).

scalar_negate

my $neg = $curve25519->scalar_negate($s, $flags);

Returns a Crypt::Sodium::XS::MemVault: $neg so that $s + $neg = 0 (mod L).

scalar_random

my $r = $curve25519->scalar_random($flags);

Returns a Crypt::Sodium::XS::MemVault: a representation of a random scalar in the ]0..L[ interval.

A scalar in the [0..L[ interval can also be obtained by reducing a possibly larger value with "scalar_reduce".

scalar_reduce

my $r = $curve25519->scalar_reduce($s, $flags);

Returns a Crypt::Sodium::XS::MemVault: $s reduced to $s mod L.

Note that $s is much larger than $r (64 bytes vs 32 bytes). Bits of $s can be left to 0, but the interval $s is sampled from should be at least 317 bits to ensure almost uniformity of $r over L.

scalar_sub

my $z = $curve25519->scalar_sub($x, $y, $flags);

Returns a Crypt::Sodium::XS::MemVault: $x - $y (mod L).

sub

my $point = $curve25519->sub($p, $q);

Subtracts the point $q from the point $p.

The function croaks if $p and/or $q are not valid points.

BYTES

my $element_size = $curve25519->bytes;

Returns the size of points, in bytes.

SCALARBYTES

my $scalar_size = $curve25519->SCALARBYTES;

Returns the size of scalars, in bytes.

UNIFORMBYTES

my $uniform_input_size = $curve25519->UNIFORMBYTES;

For ed25519 only; returns the size, in bytes, of input to the "from_uniform" method.

HASHBYTES

my $hash_input_size = $curve25519->HASHBYTES;

For ristretto255 only; returns the size, in bytes, of input to the "from_hash" method.

PRIMITIVES

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 separate :<primitive> import tag is provided for each of the primitives listed in "PRIMITIVES". These tags import the core_<primitive>_* functions and constants for that primitive. A :all tag imports everything.

Note: Crypt::Sodium::XS::curve25519 does provide generic functions for curve25519. Only the primitive-specific functions are available, so there is no :default tag.

Note: Functions are prefixed with core_ (not curve25519_) for consistency with libsodium function names.

ristretto255_available (function)

my $has_ristretto255 = ristretto255_available();
my $ristretto255_available = Crypt::Sodium::XS::curve25519->ristretto255_available;

Same as "ristretto255_available" (method).

Can be called as a class method.

core_<primitive>_add

my $r = core_ed25519_add($p, $q);

Same as "add".

core_<primitive>_is_valid_point

my $is_valid = core_ed25519_is_valid_point($point);

Same as "is_valid_point".

core_<primitive>_random

my $point = core_ed25519_random();

Same as "random".

core_ed25519_from_uniform

core_ristretto255_from_hash

my $point = core_ed25519_from_uniform($vector);
my $point2 = core_ristretto255_from_hash($vector2);

Same as "from_uniform" and "from_hash", respectively.

Note: Different functions for primitives ed25519 and ristretto255!

core_<primitive>_scalar_add

my $r = core_ed25519_add($p, $q);

Same as "scalar_add".

core_<primitive>_scalar_complement

my $comp = core_ed25519_scalar_complement($s, $flags);

Same as "scalar_complement".

core_<primitive>_scalar_mul

my $z = core_ed25519_scalar_mul($x, $y, $flags);

Same as "scalar_mul".

core_<primitive>_scalar_negate

my $neg = core_ed25519_scalar_negate($s, $flags);

Same as "scalar_negate".

core_<primitive>_scalar_random

my $r = core_ed25519_scalar_random($flags);

Same as "scalar_random".

core_<primitive>_scalar_reduce

my $r = core_ed25519_scalar_reduce($s, $flags);

Same as "scalar_reduce".

core_<primitive>_scalar_sub

my $z = core_ed25519_scalar_sub($x, $y, $flags);

Same as "scalar_sub".

core_<primitive>_sub

my $r = core_ed25519_sub($p, $q);

Same as "sub".

CONSTANTS

core_<primitive>_BYTES

my $element_size = core_ed25519_bytes;

Same as "BYTES".

core_<primitive>_SCALARBYTES

my $scalar_size = core_ed25519_SCALARBYTES;

Same as "SCALARBYTES".

core_ed25519_UNIFORMBYTES

my $uniform_input_size = core_ed25519_UNIFORMBYTES;

Same as "UNIFORMBYTES".

core_ristretto255_HASHBYTES

my $hash_input_size = core_ristretto255_HASHBYTES;

Same as "HASHBYTES".

SEE ALSO

Crypt::Sodium::XS
Crypt::Sodium::XS::scalarmult

See this module for point-scalar multiplication with ed25519 and ristretto255.

https://doc.libsodium.org/advanced/scalar_multiplication
https://doc.libsodium.org/advanced/point-arithmetic

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.