pub mod aead;
pub mod binding;
pub mod commitments;
mod ed25519;
pub mod hashing;
pub mod vss;
#[cfg(feature = "frostristretto255tss")]
mod ristretto255;
pub use ed25519::Ed25519;
pub use purecrypto::ec::edwards25519::hazmat::Scalar;
use purecrypto::rng::RngCore;
#[cfg(feature = "frostristretto255tss")]
pub use ristretto255::Ristretto255;
pub fn random_scalar(rng: &mut impl RngCore) -> Scalar {
let mut b = [0u8; 64];
rng.fill_bytes(&mut b);
Scalar::from_bytes_mod_order(&b)
}
pub trait Ciphersuite {
type Point: Clone + Copy;
const NAME: &'static str;
fn context_string() -> &'static [u8];
fn generator() -> Self::Point;
fn identity() -> Self::Point;
fn add(a: &Self::Point, b: &Self::Point) -> Self::Point;
fn negate(a: &Self::Point) -> Self::Point;
fn scalar_mul(p: &Self::Point, s: &Scalar) -> Self::Point;
fn mul_base(s: &Scalar) -> Self::Point;
fn eq(a: &Self::Point, b: &Self::Point) -> bool;
fn is_identity(p: &Self::Point) -> bool;
fn encode_point(p: &Self::Point) -> [u8; 32];
fn decode_point(b: &[u8; 32]) -> Option<Self::Point>;
fn h1(msg: &[u8]) -> Scalar;
fn h2(msg: &[u8]) -> Scalar;
fn h3(msg: &[u8]) -> Scalar;
fn h4(msg: &[u8]) -> [u8; 64];
fn h5(msg: &[u8]) -> [u8; 64];
}
pub fn encode_scalar(s: &Scalar) -> [u8; 32] {
s.to_bytes()
}
pub fn scalar_to_be(s: &Scalar) -> Vec<u8> {
let be: Vec<u8> = s.to_bytes().iter().rev().copied().collect();
let start = be.iter().position(|&x| x != 0).unwrap_or(be.len());
be[start..].to_vec()
}
pub fn decode_scalar(b: &[u8; 32]) -> Option<Scalar> {
Scalar::from_bytes_canonical(b)
}
pub fn scalar_from_be_mod_l(be: &[u8]) -> Scalar {
let mut le = [0u8; 64];
for (i, &byte) in be.iter().rev().enumerate() {
if i >= 64 {
break;
}
le[i] = byte;
}
Scalar::from_bytes_mod_order(&le)
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn scalar_encode_decode_roundtrip() {
let mut le = [0u8; 32];
le[0] = 42;
let s = decode_scalar(&le).unwrap();
assert_eq!(encode_scalar(&s), le);
}
#[test]
fn identifier_reduction_small() {
let s = scalar_from_be_mod_l(&[5]);
let mut want = [0u8; 32];
want[0] = 5;
assert_eq!(encode_scalar(&s), want);
}
}