Skip to main content

Module scalar

Module scalar 

Source
Expand description

Arithmetic on scalars (integers mod the group order).

Both the Ristretto group and the Ed25519 basepoint have prime order \( \ell = 2^{252} + 27742317777372353535851937790883648493 \).

This code is intended to be useful with both the Ristretto group (where everything is done modulo \( \ell \)), and the X/Ed25519 setting, which mandates specific bit-twiddles that are not well-defined modulo \( \ell \).

All arithmetic on Scalars is done modulo \( \ell \).

§Constructing a scalar

To create a Scalar from a supposedly canonical encoding, use Scalar::from_canonical_bytes.

This function does input validation, ensuring that the input bytes are the canonical encoding of a Scalar. If they are, we’ll get Some(Scalar) in return:

use curve25519_dalek::scalar::Scalar;

let one_as_bytes: [u8; 32] = Scalar::ONE.to_bytes();
let a: Option<Scalar> = Scalar::from_canonical_bytes(one_as_bytes).into();

assert!(a.is_some());

However, if we give it bytes representing a scalar larger than \( \ell \) (in this case, \( \ell + 2 \)), we’ll get None back:

use curve25519_dalek::scalar::Scalar;

let l_plus_two_bytes: [u8; 32] = [
   0xef, 0xd3, 0xf5, 0x5c, 0x1a, 0x63, 0x12, 0x58,
   0xd6, 0x9c, 0xf7, 0xa2, 0xde, 0xf9, 0xde, 0x14,
   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10,
];
let a: Option<Scalar> = Scalar::from_canonical_bytes(l_plus_two_bytes).into();

assert!(a.is_none());

Another way to create a Scalar is by reducing a \(256\)-bit integer mod \( \ell \), for which one may use the Scalar::from_bytes_mod_order method. In the case of the second example above, this would reduce the resultant scalar \( \mod \ell \), producing \( 2 \):

use curve25519_dalek::scalar::Scalar;

let l_plus_two_bytes: [u8; 32] = [
   0xef, 0xd3, 0xf5, 0x5c, 0x1a, 0x63, 0x12, 0x58,
   0xd6, 0x9c, 0xf7, 0xa2, 0xde, 0xf9, 0xde, 0x14,
   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10,
];
let a: Scalar = Scalar::from_bytes_mod_order(l_plus_two_bytes);

let two: Scalar = Scalar::ONE + Scalar::ONE;

assert!(a == two);

There is also a constructor that reduces a \(512\)-bit integer, Scalar::from_bytes_mod_order_wide.

To construct a Scalar as the hash of some input data, use [Scalar::hash_from_bytes], which takes a buffer, or [Scalar::from_hash], which allows an IUF API.

use sha2::{Digest, Sha512};
use curve25519_dalek::scalar::Scalar;

// Hashing a single byte slice
let a = Scalar::hash_from_bytes::<Sha512>(b"Abolish ICE");

// Streaming data into a hash object
let mut hasher = Sha512::default();
hasher.update(b"Abolish ");
hasher.update(b"ICE");
let a2 = Scalar::from_hash(hasher);

assert_eq!(a, a2);

See also Scalar::hash_from_bytes and Scalar::from_hash that reduces a \(512\)-bit integer, if the optional digest feature has been enabled.

Structs§

Scalar
The Scalar struct holds an element of \(\mathbb Z / \ell\mathbb Z \).

Functions§

clamp_integer
Clamps the given little-endian representation of a 32-byte integer. Clamping the value puts it in the range: