use std::sync::OnceLock;
use curve25519_dalek::ristretto::{CompressedRistretto, RistrettoBasepointTable, RistrettoPoint};
const NUMBER_NUMS_POINTS: usize = 10;
pub const RISTRETTO_NUMS_POINTS_COMPRESSED: [CompressedRistretto; NUMBER_NUMS_POINTS] = [
CompressedRistretto([
206, 56, 152, 65, 192, 200, 105, 138, 185, 91, 112, 36, 42, 238, 166, 72, 64, 177, 234, 197, 246, 68, 183, 208,
8, 172, 5, 135, 207, 71, 29, 112,
]),
CompressedRistretto([
54, 179, 59, 85, 148, 85, 113, 114, 237, 39, 200, 19, 236, 249, 193, 45, 13, 194, 254, 236, 39, 225, 9, 66,
123, 41, 222, 21, 125, 254, 102, 77,
]),
CompressedRistretto([
152, 202, 159, 30, 58, 170, 77, 68, 126, 51, 86, 197, 114, 69, 19, 227, 202, 190, 145, 71, 127, 19, 101, 207,
17, 221, 227, 175, 5, 88, 90, 85,
]),
CompressedRistretto([
242, 2, 148, 178, 187, 151, 148, 185, 122, 161, 129, 17, 83, 85, 124, 125, 30, 139, 225, 50, 69, 73, 206, 68,
114, 177, 81, 20, 255, 56, 82, 71,
]),
CompressedRistretto([
196, 93, 153, 124, 195, 94, 29, 16, 123, 234, 15, 2, 184, 227, 67, 128, 103, 87, 113, 86, 69, 132, 187, 122,
11, 194, 246, 23, 111, 190, 164, 28,
]),
CompressedRistretto([
70, 122, 19, 104, 23, 41, 249, 95, 206, 125, 54, 95, 126, 136, 57, 94, 54, 200, 73, 141, 40, 206, 124, 156,
224, 237, 133, 95, 3, 225, 220, 102,
]),
CompressedRistretto([
212, 243, 209, 88, 16, 127, 237, 87, 22, 162, 111, 122, 214, 165, 70, 23, 71, 139, 35, 16, 187, 144, 228, 5,
182, 51, 244, 148, 184, 63, 222, 26,
]),
CompressedRistretto([
106, 114, 88, 57, 144, 221, 187, 75, 248, 13, 1, 136, 214, 61, 106, 235, 221, 175, 66, 184, 107, 31, 113, 2,
142, 36, 210, 62, 91, 35, 45, 25,
]),
CompressedRistretto([
206, 164, 160, 199, 62, 109, 174, 203, 69, 222, 211, 23, 80, 44, 161, 143, 118, 138, 145, 140, 51, 145, 84,
208, 173, 74, 97, 128, 193, 239, 30, 30,
]),
CompressedRistretto([
218, 174, 170, 84, 178, 150, 240, 77, 72, 189, 188, 156, 46, 84, 202, 209, 80, 14, 212, 160, 195, 106, 149, 59,
173, 24, 184, 4, 233, 38, 232, 44,
]),
];
pub fn ristretto_nums_points() -> &'static [RistrettoPoint; NUMBER_NUMS_POINTS] {
static INSTANCE: OnceLock<[RistrettoPoint; NUMBER_NUMS_POINTS]> = OnceLock::new();
INSTANCE.get_or_init(|| {
let mut arr = [RistrettoPoint::default(); NUMBER_NUMS_POINTS];
for i in 0..NUMBER_NUMS_POINTS {
arr[i] = RISTRETTO_NUMS_POINTS_COMPRESSED[i].decompress().unwrap();
}
arr
})
}
pub fn ristretto_nums_table_0() -> &'static RistrettoBasepointTable {
static INSTANCE: OnceLock<RistrettoBasepointTable> = OnceLock::new();
INSTANCE.get_or_init(|| RistrettoBasepointTable::create(&ristretto_nums_points()[0]))
}
#[cfg(test)]
mod test {
use alloc::vec::Vec;
use curve25519_dalek::{
constants::{RISTRETTO_BASEPOINT_COMPRESSED, RISTRETTO_BASEPOINT_POINT},
ristretto::{CompressedRistretto, RistrettoPoint},
scalar::Scalar,
traits::Identity,
};
use sha2::{Digest, Sha512};
use crate::ristretto::constants::{
RISTRETTO_NUMS_POINTS_COMPRESSED,
ristretto_nums_points,
ristretto_nums_table_0,
};
fn nums_ristretto(n: usize) -> (Vec<RistrettoPoint>, Vec<CompressedRistretto>) {
let mut points = Vec::with_capacity(n);
let mut compressed_points = Vec::with_capacity(n);
let mut a: [u8; 64] = [0; 64];
for i in 0..n {
let mut data = b"TARI CRYPTO NUMS BASEPOINT LABEL - ".to_vec(); data.append(&mut (i as u64).to_le_bytes().to_vec()); let hashed_v = Sha512::digest(&data);
a.copy_from_slice(&hashed_v);
let next_val = RistrettoPoint::from_uniform_bytes(&a);
points.push(next_val);
compressed_points.push(next_val.compress());
}
(points, compressed_points)
}
#[test]
pub fn check_nums_points() {
let n = RISTRETTO_NUMS_POINTS_COMPRESSED.len();
let calculated_nums_points = nums_ristretto(n);
#[allow(clippy::needless_range_loop)]
for i in 0..n {
assert_eq!(calculated_nums_points.0[i], ristretto_nums_points()[i]);
assert_eq!(calculated_nums_points.1[i], RISTRETTO_NUMS_POINTS_COMPRESSED[i]);
assert_ne!(RistrettoPoint::default(), ristretto_nums_points()[i]);
assert_ne!(CompressedRistretto::default(), RISTRETTO_NUMS_POINTS_COMPRESSED[i]);
assert_ne!(RISTRETTO_BASEPOINT_POINT, ristretto_nums_points()[i]);
assert_ne!(RISTRETTO_BASEPOINT_COMPRESSED, RISTRETTO_NUMS_POINTS_COMPRESSED[i]);
#[allow(clippy::needless_range_loop)]
for j in i + 1..n {
assert_ne!(ristretto_nums_points()[i], ristretto_nums_points()[j]);
assert_ne!(RISTRETTO_NUMS_POINTS_COMPRESSED[i], RISTRETTO_NUMS_POINTS_COMPRESSED[j]);
}
}
}
#[test]
pub fn check_tables() {
assert_eq!(ristretto_nums_table_0() * &Scalar::ZERO, RistrettoPoint::identity());
for j in 0..15u8 {
assert_eq!(
ristretto_nums_table_0() * &Scalar::from(j),
ristretto_nums_points()[0] * Scalar::from(j)
);
}
}
}