use zeroize::Zeroize; use sha2::{Digest, Sha512}; use dalek_ff_group::Scalar; use crate::{curve::Curve, algorithm::Hram}; macro_rules! dalek_curve { ( $Curve: ident, $Hram: ident, $Point: ident, $POINT: ident, $ID: literal, $CONTEXT: literal, $chal: literal, ) => { use dalek_ff_group::{$Point, $POINT}; #[derive(Clone, Copy, PartialEq, Eq, Debug, Zeroize)] pub struct $Curve; impl $Curve { fn hash(dst: &[u8], data: &[u8]) -> Sha512 { Sha512::new().chain_update(&[$CONTEXT.as_ref(), dst, data].concat()) } } impl Curve for $Curve { type F = Scalar; type G = $Point; const ID: &'static [u8] = $ID; fn generator() -> Self::G { $POINT } fn hash_to_vec(dst: &[u8], data: &[u8]) -> Vec { Self::hash(dst, data).finalize().to_vec() } fn hash_to_F(dst: &[u8], data: &[u8]) -> Self::F { Scalar::from_hash(Self::hash(dst, data)) } } #[derive(Copy, Clone)] pub struct $Hram; impl Hram<$Curve> for $Hram { #[allow(non_snake_case)] fn hram(R: &$Point, A: &$Point, m: &[u8]) -> Scalar { let mut hash = Sha512::new(); if $chal.len() != 0 { hash.update(&[$CONTEXT.as_ref(), $chal].concat()); } Scalar::from_hash( hash.chain_update(&[&R.compress().to_bytes(), &A.compress().to_bytes(), m].concat()), ) } } }; } #[cfg(any(test, feature = "ristretto"))] dalek_curve!( Ristretto, IetfRistrettoHram, RistrettoPoint, RISTRETTO_BASEPOINT_POINT, b"ristretto", b"FROST-RISTRETTO255-SHA512-v8", b"chal", ); #[cfg(feature = "ed25519")] dalek_curve!( Ed25519, IetfEd25519Hram, EdwardsPoint, ED25519_BASEPOINT_POINT, b"edwards25519", b"FROST-ED25519-SHA512-v8", b"", );