use core::ops::Add;
use subtle::Choice;
pub(crate) mod chain;
mod expand_msg;
pub use self::expand_msg::{ExpandMessage, ExpandMsgXmd, ExpandMsgXof, Message};
mod map_g1;
mod map_g2;
mod map_scalar;
use crate::generic_array::{
ArrayLength, GenericArray,
typenum::{IsLess, U256, Unsigned},
};
pub trait HashToField: Sized {
type InputLength: ArrayLength<u8>;
type XofOutputLength: ArrayLength<u8> + IsLess<U256>;
fn from_okm(okm: &GenericArray<u8, Self::InputLength>) -> Self;
fn hash_to_field<X, M>(message: M, dst: &[u8], output: &mut [Self])
where
X: ExpandMessage,
M: Message,
{
let len_per_elm = Self::InputLength::to_usize();
let len_in_bytes = output.len() * len_per_elm;
let mut expander = X::init_expand::<M, Self::XofOutputLength>(message, dst, len_in_bytes);
let mut buf = GenericArray::<u8, Self::InputLength>::default();
output.iter_mut().for_each(|item| {
expander.read_into(&mut buf[..]);
*item = Self::from_okm(&buf);
});
}
}
pub trait MapToCurve: Sized {
type Field: Copy + Default + HashToField;
fn map_to_curve(elt: &Self::Field) -> Self;
fn clear_h(&self) -> Self;
}
pub trait HashToCurve<X: ExpandMessage>: MapToCurve + for<'a> Add<&'a Self, Output = Self> {
fn hash_to_curve<M: Message>(message: M, dst: &[u8]) -> Self {
let mut u = [Self::Field::default(); 2];
Self::Field::hash_to_field::<X, M>(message, dst, &mut u);
let p1 = Self::map_to_curve(&u[0]);
let p2 = Self::map_to_curve(&u[1]);
(p1 + &p2).clear_h()
}
fn encode_to_curve<M: Message>(message: M, dst: &[u8]) -> Self {
let mut u = [Self::Field::default(); 1];
Self::Field::hash_to_field::<X, M>(message, dst, &mut u);
let p = Self::map_to_curve(&u[0]);
p.clear_h()
}
}
impl<G, X> HashToCurve<X> for G
where
G: MapToCurve + for<'a> Add<&'a Self, Output = Self>,
X: ExpandMessage,
{
}
pub(crate) trait Sgn0 {
fn sgn0(&self) -> Choice;
}