use std::convert::TryInto; use crate::constants::{self, compute_lagrange_coeffs, H, NUM_WINDOWS, NUM_WINDOWS_SHORT}; use halo2::arithmetic::{CurveAffine, FieldExt}; use std::marker::PhantomData; #[derive(Copy, Clone, Debug, Eq, PartialEq)] pub enum OrchardFixedBasesFull { CommitIvkR(PhantomData), NoteCommitR(PhantomData), NullifierK(PhantomData), ValueCommitR(PhantomData), SpendAuthG(PhantomData), } /// A fixed base to be used in scalar multiplication with a full-width scalar. #[derive(Clone, Debug, Eq, PartialEq)] pub struct OrchardFixedBase { pub generator: C, pub lagrange_coeffs: LagrangeCoeffs, pub z: Z, pub u: U, } impl From> for OrchardFixedBase { fn from(base: OrchardFixedBasesFull) -> Self { let (generator, z, u) = match base { OrchardFixedBasesFull::CommitIvkR(_) => ( super::commit_ivk_r::generator(), super::commit_ivk_r::Z.into(), super::commit_ivk_r::U.into(), ), OrchardFixedBasesFull::NoteCommitR(_) => ( super::note_commit_r::generator(), super::note_commit_r::Z.into(), super::note_commit_r::U.into(), ), OrchardFixedBasesFull::NullifierK(_) => ( super::nullifier_k::generator(), super::nullifier_k::Z.into(), super::nullifier_k::U.into(), ), OrchardFixedBasesFull::ValueCommitR(_) => ( super::value_commit_r::generator(), super::value_commit_r::Z.into(), super::value_commit_r::U.into(), ), OrchardFixedBasesFull::SpendAuthG(_) => ( super::spend_auth_g::generator(), super::spend_auth_g::Z.into(), super::spend_auth_g::U.into(), ), }; Self { generator, lagrange_coeffs: compute_lagrange_coeffs(generator, NUM_WINDOWS).into(), z, u, } } } /// A fixed base to be used in scalar multiplication with a short signed exponent. #[derive(Clone, Debug, Eq, PartialEq)] pub struct ValueCommitV { pub generator: C, pub lagrange_coeffs_short: LagrangeCoeffsShort, pub z_short: ZShort, pub u_short: UShort, } impl ValueCommitV { pub fn get() -> Self { let generator = super::value_commit_v::generator(); Self { generator, lagrange_coeffs_short: compute_lagrange_coeffs(generator, NUM_WINDOWS_SHORT).into(), z_short: super::value_commit_v::Z_SHORT.into(), u_short: super::value_commit_v::U_SHORT.into(), } } } #[derive(Clone, Debug, Eq, PartialEq)] // 8 coefficients per window pub struct WindowLagrangeCoeffs(pub Box<[F; H]>); impl From<&[F; H]> for WindowLagrangeCoeffs { fn from(array: &[F; H]) -> Self { Self(Box::new(*array)) } } #[derive(Clone, Debug, Eq, PartialEq)] // 85 windows per base (with the exception of ValueCommitV) pub struct LagrangeCoeffs(pub Box<[WindowLagrangeCoeffs; constants::NUM_WINDOWS]>); impl From>> for LagrangeCoeffs { fn from(windows: Vec>) -> Self { Self(windows.into_boxed_slice().try_into().unwrap()) } } impl From> for LagrangeCoeffs { fn from(arrays: Vec<[F; H]>) -> Self { let windows: Vec> = arrays.iter().map(|array| array.into()).collect(); windows.into() } } #[derive(Clone, Debug, Eq, PartialEq)] // 22 windows for ValueCommitV pub struct LagrangeCoeffsShort(pub Box<[WindowLagrangeCoeffs; NUM_WINDOWS_SHORT]>); impl From>> for LagrangeCoeffsShort { fn from(windows: Vec>) -> Self { Self(windows.into_boxed_slice().try_into().unwrap()) } } impl From> for LagrangeCoeffsShort { fn from(arrays: Vec<[F; H]>) -> Self { let windows: Vec> = arrays.iter().map(|array| array.into()).collect(); windows.into() } } #[derive(Clone, Debug, Eq, PartialEq)] // 85 Z's per base (with the exception of ValueCommitV) pub struct Z(pub Box<[F; NUM_WINDOWS]>); impl From<[u64; NUM_WINDOWS]> for Z { fn from(zs: [u64; NUM_WINDOWS]) -> Self { Self( zs.iter() .map(|z| F::from_u64(*z)) .collect::>() .into_boxed_slice() .try_into() .unwrap(), ) } } #[derive(Clone, Debug, Eq, PartialEq)] // 22 Z's for ValueCommitV pub struct ZShort(pub Box<[F; NUM_WINDOWS_SHORT]>); impl From<[u64; NUM_WINDOWS_SHORT]> for ZShort { fn from(zs: [u64; NUM_WINDOWS_SHORT]) -> Self { Self( zs.iter() .map(|z| F::from_u64(*z)) .collect::>() .into_boxed_slice() .try_into() .unwrap(), ) } } #[derive(Clone, Debug, Eq, PartialEq)] // 8 u's per window pub struct WindowUs(pub Box<[F; H]>); impl From<&[[u8; 32]; H]> for WindowUs { fn from(window_us: &[[u8; 32]; H]) -> Self { Self( window_us .iter() .map(|u| F::from_bytes(u).unwrap()) .collect::>() .into_boxed_slice() .try_into() .unwrap(), ) } } #[derive(Clone, Debug, Eq, PartialEq)] // 85 windows per base (with the exception of ValueCommitV) pub struct U(pub Box<[WindowUs; NUM_WINDOWS]>); impl From>> for U { fn from(windows: Vec>) -> Self { Self(windows.into_boxed_slice().try_into().unwrap()) } } impl From<[[[u8; 32]; H]; NUM_WINDOWS]> for U { fn from(window_us: [[[u8; 32]; H]; NUM_WINDOWS]) -> Self { let windows: Vec> = window_us.iter().map(|us| us.into()).collect(); windows.into() } } #[derive(Clone, Debug, Eq, PartialEq)] // 22 windows for ValueCommitV pub struct UShort(pub Box<[WindowUs; NUM_WINDOWS_SHORT]>); impl From>> for UShort { fn from(windows: Vec>) -> Self { Self(windows.into_boxed_slice().try_into().unwrap()) } } impl From<[[[u8; 32]; H]; NUM_WINDOWS_SHORT]> for UShort { fn from(window_us: [[[u8; 32]; H]; NUM_WINDOWS_SHORT]) -> Self { let windows: Vec> = window_us.iter().map(|us| us.into()).collect(); windows.into() } }