Просмотр исходного кода

crypto/constants: Update with latest Orchard constants.

parazyd 4 лет назад
Родитель
Сommit
1df6c3db7f

+ 10 - 1
src/crypto/constants.rs

@@ -2,10 +2,19 @@ pub mod fixed_bases;
 pub mod sinsemilla;
 pub mod sinsemilla;
 pub mod util;
 pub mod util;
 
 
-pub use fixed_bases::OrchardFixedBases;
+pub use fixed_bases::{NullifierK, OrchardFixedBases, OrchardFixedBasesFull, ValueCommitV, H};
 
 
 pub const DRK_SCHNORR_DOMAIN: &[u8] = b"DarkFi_Schnorr";
 pub const DRK_SCHNORR_DOMAIN: &[u8] = b"DarkFi_Schnorr";
 
 
 pub const MERKLE_DEPTH_ORCHARD: usize = 32;
 pub const MERKLE_DEPTH_ORCHARD: usize = 32;
 
 
 pub const L_ORCHARD_MERKLE: usize = 255;
 pub const L_ORCHARD_MERKLE: usize = 255;
+
+/// $\ell^\mathsf{Orchard}_\mathsf{base}$
+pub(crate) const L_ORCHARD_BASE: usize = 255;
+
+/// $\ell^\mathsf{Orchard}_\mathsf{scalar}$
+pub(crate) const L_ORCHARD_SCALAR: usize = 255;
+
+/// $\ell_\mathsf{value}$
+pub(crate) const L_VALUE: usize = 64;

+ 100 - 153
src/crypto/constants/fixed_bases.rs

@@ -1,14 +1,12 @@
-use arrayvec::ArrayVec;
+//! Orchard fixed bases.
+use super::{L_ORCHARD_SCALAR, L_VALUE};
 use halo2_gadgets::ecc::{
 use halo2_gadgets::ecc::{
-    chip::{compute_lagrange_coeffs, NUM_WINDOWS, NUM_WINDOWS_SHORT},
-    FixedPoints, H,
-};
-use pasta_curves::{
-    arithmetic::{CurveAffine, Field, FieldExt},
-    group::Curve,
-    pallas,
+    chip::{BaseFieldElem, FixedPoint, FullScalar, ShortScalar},
+    FixedPoints,
 };
 };
 
 
+use pasta_curves::pallas;
+
 pub mod commit_ivk_r;
 pub mod commit_ivk_r;
 pub mod note_commit_r;
 pub mod note_commit_r;
 pub mod nullifier_k;
 pub mod nullifier_k;
@@ -16,14 +14,18 @@ pub mod spend_auth_g;
 pub mod value_commit_r;
 pub mod value_commit_r;
 pub mod value_commit_v;
 pub mod value_commit_v;
 
 
+/// SWU hash-to-curve personalization for the spending key base point and
+/// the nullifier base point K^Orchard
+pub const ORCHARD_PERSONALIZATION: &str = "z.cash:Orchard";
+
 /// SWU hash-to-curve personalization for the value commitment generator
 /// SWU hash-to-curve personalization for the value commitment generator
 pub const VALUE_COMMITMENT_PERSONALIZATION: &str = "z.cash:Orchard-cv";
 pub const VALUE_COMMITMENT_PERSONALIZATION: &str = "z.cash:Orchard-cv";
 
 
 /// SWU hash-to-curve value for the value commitment generator
 /// SWU hash-to-curve value for the value commitment generator
-pub const VALUE_COMMITMENT_R_BYTES: [u8; 1] = *b"r";
+pub const VALUE_COMMITMENT_V_BYTES: [u8; 1] = *b"v";
 
 
 /// SWU hash-to-curve value for the value commitment generator
 /// SWU hash-to-curve value for the value commitment generator
-pub const VALUE_COMMITMENT_V_BYTES: [u8; 1] = *b"v";
+pub const VALUE_COMMITMENT_R_BYTES: [u8; 1] = *b"r";
 
 
 /// SWU hash-to-curve personalization for the note commitment generator
 /// SWU hash-to-curve personalization for the note commitment generator
 pub const NOTE_COMMITMENT_PERSONALIZATION: &str = "z.cash:Orchard-NoteCommit";
 pub const NOTE_COMMITMENT_PERSONALIZATION: &str = "z.cash:Orchard-NoteCommit";
@@ -31,184 +33,129 @@ pub const NOTE_COMMITMENT_PERSONALIZATION: &str = "z.cash:Orchard-NoteCommit";
 /// SWU hash-to-curve personalization for the IVK commitment generator
 /// SWU hash-to-curve personalization for the IVK commitment generator
 pub const COMMIT_IVK_PERSONALIZATION: &str = "z.cash:Orchard-CommitIvk";
 pub const COMMIT_IVK_PERSONALIZATION: &str = "z.cash:Orchard-CommitIvk";
 
 
-/// SWU hash-to-curve personalization for the spending key base point and
-/// the nullifier base point K^Orchard
-pub const ORCHARD_PERSONALIZATION: &str = "z.cash:Orchard";
-
 /// Window size for fixed-base scalar multiplication
 /// Window size for fixed-base scalar multiplication
 pub const FIXED_BASE_WINDOW_SIZE: usize = 3;
 pub const FIXED_BASE_WINDOW_SIZE: usize = 3;
 
 
+/// $2^{`FIXED_BASE_WINDOW_SIZE`}$
+pub const H: usize = 1 << FIXED_BASE_WINDOW_SIZE;
+
+/// Number of windows for a full-width scalar
+pub const NUM_WINDOWS: usize =
+    (L_ORCHARD_SCALAR + FIXED_BASE_WINDOW_SIZE - 1) / FIXED_BASE_WINDOW_SIZE;
+
+/// Number of windows for a short signed scalar
+pub const NUM_WINDOWS_SHORT: usize =
+    (L_VALUE + FIXED_BASE_WINDOW_SIZE - 1) / FIXED_BASE_WINDOW_SIZE;
+
 #[derive(Copy, Clone, Debug, Eq, PartialEq)]
 #[derive(Copy, Clone, Debug, Eq, PartialEq)]
+// A sum type for both full-width and short bases. This enables us to use the
+// shared functionality of full-width and short fixed-base scalar multiplication.
 pub enum OrchardFixedBases {
 pub enum OrchardFixedBases {
+    Full(OrchardFixedBasesFull),
+    NullifierK,
+    ValueCommitV,
+}
+
+impl From<OrchardFixedBasesFull> for OrchardFixedBases {
+    fn from(full_width_base: OrchardFixedBasesFull) -> Self {
+        Self::Full(full_width_base)
+    }
+}
+
+impl From<ValueCommitV> for OrchardFixedBases {
+    fn from(_value_commit_v: ValueCommitV) -> Self {
+        Self::ValueCommitV
+    }
+}
+
+impl From<NullifierK> for OrchardFixedBases {
+    fn from(_nullifier_k: NullifierK) -> Self {
+        Self::NullifierK
+    }
+}
+
+/// The Orchard fixed bases used in scalar mul with full-width scalars.
+#[derive(Copy, Clone, Debug, Eq, PartialEq)]
+pub enum OrchardFixedBasesFull {
     CommitIvkR,
     CommitIvkR,
     NoteCommitR,
     NoteCommitR,
     ValueCommitR,
     ValueCommitR,
     SpendAuthG,
     SpendAuthG,
-    NullifierK,
-    ValueCommitV,
 }
 }
 
 
+/// NullifierK is used in scalar mul with a base field element.
+#[derive(Copy, Clone, Debug, Eq, PartialEq)]
+pub struct NullifierK;
+
+/// ValueCommitV is used in scalar mul with a short signed scalar.
+#[derive(Copy, Clone, Debug, Eq, PartialEq)]
+pub struct ValueCommitV;
+
 impl FixedPoints<pallas::Affine> for OrchardFixedBases {
 impl FixedPoints<pallas::Affine> for OrchardFixedBases {
+    type FullScalar = OrchardFixedBasesFull;
+    type Base = NullifierK;
+    type ShortScalar = ValueCommitV;
+}
+
+impl FixedPoint<pallas::Affine> for OrchardFixedBasesFull {
+    type ScalarKind = FullScalar;
+
     fn generator(&self) -> pallas::Affine {
     fn generator(&self) -> pallas::Affine {
         match self {
         match self {
-            OrchardFixedBases::CommitIvkR => commit_ivk_r::generator(),
-            OrchardFixedBases::NoteCommitR => note_commit_r::generator(),
-            OrchardFixedBases::ValueCommitR => value_commit_r::generator(),
-            OrchardFixedBases::SpendAuthG => spend_auth_g::generator(),
-            OrchardFixedBases::NullifierK => nullifier_k::generator(),
-            OrchardFixedBases::ValueCommitV => value_commit_v::generator(),
+            Self::CommitIvkR => commit_ivk_r::generator(),
+            Self::NoteCommitR => note_commit_r::generator(),
+            Self::ValueCommitR => value_commit_r::generator(),
+            Self::SpendAuthG => spend_auth_g::generator(),
         }
         }
     }
     }
+
     fn u(&self) -> Vec<[[u8; 32]; H]> {
     fn u(&self) -> Vec<[[u8; 32]; H]> {
         match self {
         match self {
-            OrchardFixedBases::CommitIvkR => commit_ivk_r::U.to_vec(),
-            OrchardFixedBases::NoteCommitR => note_commit_r::U.to_vec(),
-            OrchardFixedBases::ValueCommitR => value_commit_r::U.to_vec(),
-            OrchardFixedBases::SpendAuthG => spend_auth_g::U.to_vec(),
-            OrchardFixedBases::NullifierK => nullifier_k::U.to_vec(),
-            OrchardFixedBases::ValueCommitV => value_commit_v::U_SHORT.to_vec(),
+            Self::CommitIvkR => commit_ivk_r::U.to_vec(),
+            Self::NoteCommitR => note_commit_r::U.to_vec(),
+            Self::ValueCommitR => value_commit_r::U.to_vec(),
+            Self::SpendAuthG => spend_auth_g::U.to_vec(),
         }
         }
     }
     }
 
 
     fn z(&self) -> Vec<u64> {
     fn z(&self) -> Vec<u64> {
         match self {
         match self {
-            OrchardFixedBases::CommitIvkR => commit_ivk_r::Z.to_vec(),
-            OrchardFixedBases::NoteCommitR => note_commit_r::Z.to_vec(),
-            OrchardFixedBases::ValueCommitR => value_commit_r::Z.to_vec(),
-            OrchardFixedBases::SpendAuthG => spend_auth_g::Z.to_vec(),
-            OrchardFixedBases::NullifierK => nullifier_k::Z.to_vec(),
-            OrchardFixedBases::ValueCommitV => value_commit_v::Z_SHORT.to_vec(),
+            Self::CommitIvkR => commit_ivk_r::Z.to_vec(),
+            Self::NoteCommitR => note_commit_r::Z.to_vec(),
+            Self::ValueCommitR => value_commit_r::Z.to_vec(),
+            Self::SpendAuthG => spend_auth_g::Z.to_vec(),
         }
         }
     }
     }
+}
 
 
-    fn lagrange_coeffs(&self) -> Vec<[pallas::Base; H]> {
-        match self {
-            OrchardFixedBases::ValueCommitV => {
-                compute_lagrange_coeffs(self.generator(), NUM_WINDOWS_SHORT)
-            }
-            _ => compute_lagrange_coeffs(self.generator(), NUM_WINDOWS),
-        }
+impl FixedPoint<pallas::Affine> for NullifierK {
+    type ScalarKind = BaseFieldElem;
+
+    fn generator(&self) -> pallas::Affine {
+        nullifier_k::generator()
     }
     }
-}
 
 
-/// For each fixed base, we calculate its scalar multiples in three-bit windows.
-/// Each window will have $2^3 = 8$ points.
-#[allow(dead_code)]
-fn compute_window_table<C: CurveAffine>(base: C, num_windows: usize) -> Vec<[C; H]> {
-    let mut window_table: Vec<[C; H]> = Vec::with_capacity(num_windows);
-
-    // Generate window table entries for all windows but the last.
-    // For these first `num_windows - 1` windows, we compute the multiple [(k+2)*(2^3)^w]B.
-    // Here, w ranges from [0..`num_windows - 1`)
-    for w in 0..(num_windows - 1) {
-        window_table.push(
-            (0..H)
-                .map(|k| {
-                    // scalar = (k+2)*(8^w)
-                    let scalar = C::ScalarExt::from_u64(k as u64 + 2) *
-                        C::ScalarExt::from_u64(H as u64).pow(&[w as u64, 0, 0, 0]);
-                    (base * scalar).to_affine()
-                })
-                .collect::<ArrayVec<C, H>>()
-                .into_inner()
-                .unwrap(),
-        );
+    fn u(&self) -> Vec<[[u8; 32]; H]> {
+        nullifier_k::U.to_vec()
     }
     }
 
 
-    // Generate window table entries for the last window, w = `num_windows - 1`.
-    // For the last window, we compute [k * (2^3)^w - sum]B, where sum is defined
-    // as sum = \sum_{j = 0}^{`num_windows - 2`} 2^{3j+1}
-    let sum = (0..(num_windows - 1)).fold(C::ScalarExt::zero(), |acc, j| {
-        acc + C::ScalarExt::from_u64(2).pow(&[
-            FIXED_BASE_WINDOW_SIZE as u64 * j as u64 + 1,
-            0,
-            0,
-            0,
-        ])
-    });
-    window_table.push(
-        (0..H)
-            .map(|k| {
-                // scalar = k * (2^3)^w - sum, where w = `num_windows - 1`
-                let scalar = C::ScalarExt::from_u64(k as u64) *
-                    C::ScalarExt::from_u64(H as u64).pow(&[(num_windows - 1) as u64, 0, 0, 0]) -
-                    sum;
-                (base * scalar).to_affine()
-            })
-            .collect::<ArrayVec<C, H>>()
-            .into_inner()
-            .unwrap(),
-    );
-
-    window_table
+    fn z(&self) -> Vec<u64> {
+        nullifier_k::Z.to_vec()
+    }
 }
 }
 
 
-#[cfg(test)]
-// Test that Lagrange interpolation coefficients reproduce the correct x-coordinate
-// for each fixed-base multiple in each window.
-fn test_lagrange_coeffs<C: CurveAffine>(base: C, num_windows: usize) {
-    let lagrange_coeffs = compute_lagrange_coeffs(base, num_windows);
-
-    // Check first 84 windows, i.e. `k_0, k_1, ..., k_83`
-    for (idx, coeffs) in lagrange_coeffs[0..(num_windows - 1)].iter().enumerate() {
-        // Test each three-bit chunk in this window.
-        for bits in 0..(1 << FIXED_BASE_WINDOW_SIZE) {
-            {
-                // Interpolate the x-coordinate using this window's coefficients
-                let interpolated_x = super::util::evaluate::<C>(bits, coeffs);
-
-                // Compute the actual x-coordinate of the multiple [(k+2)*(8^w)]B.
-                let point = base *
-                    C::Scalar::from_u64(bits as u64 + 2) *
-                    C::Scalar::from_u64(H as u64).pow(&[idx as u64, 0, 0, 0]);
-                let x = *point.to_affine().coordinates().unwrap().x();
-
-                // Check that the interpolated x-coordinate matches the actual one.
-                assert_eq!(x, interpolated_x);
-            }
-        }
+impl FixedPoint<pallas::Affine> for ValueCommitV {
+    type ScalarKind = ShortScalar;
+
+    fn generator(&self) -> pallas::Affine {
+        value_commit_v::generator()
     }
     }
 
 
-    // Check last window.
-    for bits in 0..(1 << FIXED_BASE_WINDOW_SIZE) {
-        // Interpolate the x-coordinate using the last window's coefficients
-        let interpolated_x = super::util::evaluate::<C>(bits, &lagrange_coeffs[num_windows - 1]);
-
-        // Compute the actual x-coordinate of the multiple [k * (8^84) - offset]B,
-        // where offset = \sum_{j = 0}^{83} 2^{3j+1}
-        let offset = (0..(num_windows - 1)).fold(C::Scalar::zero(), |acc, w| {
-            acc + C::Scalar::from_u64(2).pow(&[
-                FIXED_BASE_WINDOW_SIZE as u64 * w as u64 + 1,
-                0,
-                0,
-                0,
-            ])
-        });
-        let scalar = C::Scalar::from_u64(bits as u64) *
-            C::Scalar::from_u64(H as u64).pow(&[(num_windows - 1) as u64, 0, 0, 0]) -
-            offset;
-        let point = base * scalar;
-        let x = *point.to_affine().coordinates().unwrap().x();
-
-        // Check that the interpolated x-coordinate matches the actual one.
-        assert_eq!(x, interpolated_x);
+    fn u(&self) -> Vec<[[u8; 32]; H]> {
+        value_commit_v::U_SHORT.to_vec()
     }
     }
-}
 
 
-#[cfg(test)]
-// Test that the z-values and u-values satisfy the conditions:
-//      1. z + y = u^2,
-//      2. z - y is not a square
-// for the y-coordinate of each fixed-base multiple in each window.
-fn test_zs_and_us<C: CurveAffine>(base: C, z: &[u64], u: &[[[u8; 32]; H]], num_windows: usize) {
-    let window_table = compute_window_table(base, num_windows);
-
-    for ((u, z), window_points) in u.iter().zip(z.iter()).zip(window_table) {
-        for (u, point) in u.iter().zip(window_points.iter()) {
-            let y = *point.coordinates().unwrap().y();
-            let u = C::Base::from_bytes(u).unwrap();
-            assert_eq!(C::Base::from_u64(*z) + y, u * u); // allow either square root
-            assert!(bool::from((C::Base::from_u64(*z) - y).sqrt().is_none()));
-        }
+    fn z(&self) -> Vec<u64> {
+        value_commit_v::Z_SHORT.to_vec()
     }
     }
 }
 }

+ 11 - 13
src/crypto/constants/fixed_bases/commit_ivk_r.rs

@@ -1,7 +1,5 @@
-use pasta_curves::{
-    arithmetic::{CurveAffine, FieldExt},
-    pallas,
-};
+use group::ff::PrimeField;
+use pasta_curves::{arithmetic::CurveAffine, pallas};
 
 
 /// Generator used in SinsemillaCommit randomness for IVK commitment
 /// Generator used in SinsemillaCommit randomness for IVK commitment
 pub const GENERATOR: ([u8; 32], [u8; 32]) = (
 pub const GENERATOR: ([u8; 32], [u8; 32]) = (
@@ -2922,8 +2920,8 @@ pub const U: [[[u8; 32]; super::H]; super::NUM_WINDOWS] = [
 
 
 pub fn generator() -> pallas::Affine {
 pub fn generator() -> pallas::Affine {
     pallas::Affine::from_xy(
     pallas::Affine::from_xy(
-        pallas::Base::from_bytes(&GENERATOR.0).unwrap(),
-        pallas::Base::from_bytes(&GENERATOR.1).unwrap(),
+        pallas::Base::from_repr(GENERATOR.0).unwrap(),
+        pallas::Base::from_repr(GENERATOR.1).unwrap(),
     )
     )
     .unwrap()
     .unwrap()
 }
 }
@@ -2931,15 +2929,15 @@ pub fn generator() -> pallas::Affine {
 #[cfg(test)]
 #[cfg(test)]
 mod tests {
 mod tests {
     use super::{
     use super::{
-        super::{test_lagrange_coeffs, test_zs_and_us, COMMIT_IVK_PERSONALIZATION, NUM_WINDOWS},
+        super::{COMMIT_IVK_PERSONALIZATION, NUM_WINDOWS},
         *,
         *,
     };
     };
     use group::Curve;
     use group::Curve;
-    use halo2_gadgets::primitives::sinsemilla::CommitDomain;
-    use pasta_curves::{
-        arithmetic::{CurveAffine, FieldExt},
-        pallas,
+    use halo2_gadgets::{
+        ecc::chip::constants::{test_lagrange_coeffs, test_zs_and_us},
+        primitives::sinsemilla::CommitDomain,
     };
     };
+    use pasta_curves::{arithmetic::CurveAffine, pallas};
 
 
     #[test]
     #[test]
     fn generator() {
     fn generator() {
@@ -2947,8 +2945,8 @@ mod tests {
         let point = domain.R();
         let point = domain.R();
         let coords = point.to_affine().coordinates().unwrap();
         let coords = point.to_affine().coordinates().unwrap();
 
 
-        assert_eq!(*coords.x(), pallas::Base::from_bytes(&GENERATOR.0).unwrap());
-        assert_eq!(*coords.y(), pallas::Base::from_bytes(&GENERATOR.1).unwrap());
+        assert_eq!(*coords.x(), pallas::Base::from_repr(GENERATOR.0).unwrap());
+        assert_eq!(*coords.y(), pallas::Base::from_repr(GENERATOR.1).unwrap());
     }
     }
 
 
     #[test]
     #[test]

+ 13 - 16
src/crypto/constants/fixed_bases/note_commit_r.rs

@@ -1,7 +1,5 @@
-use pasta_curves::{
-    arithmetic::{CurveAffine, FieldExt},
-    pallas,
-};
+use group::ff::PrimeField;
+use pasta_curves::{arithmetic::CurveAffine, pallas};
 
 
 /// Generator used in SinsemillaCommit randomness for note commitment
 /// Generator used in SinsemillaCommit randomness for note commitment
 pub const GENERATOR: ([u8; 32], [u8; 32]) = (
 pub const GENERATOR: ([u8; 32], [u8; 32]) = (
@@ -2922,8 +2920,8 @@ pub const U: [[[u8; 32]; super::H]; super::NUM_WINDOWS] = [
 
 
 pub fn generator() -> pallas::Affine {
 pub fn generator() -> pallas::Affine {
     pallas::Affine::from_xy(
     pallas::Affine::from_xy(
-        pallas::Base::from_bytes(&GENERATOR.0).unwrap(),
-        pallas::Base::from_bytes(&GENERATOR.1).unwrap(),
+        pallas::Base::from_repr(GENERATOR.0).unwrap(),
+        pallas::Base::from_repr(GENERATOR.1).unwrap(),
     )
     )
     .unwrap()
     .unwrap()
 }
 }
@@ -2931,26 +2929,25 @@ pub fn generator() -> pallas::Affine {
 #[cfg(test)]
 #[cfg(test)]
 mod tests {
 mod tests {
     use super::{
     use super::{
-        super::{
-            test_lagrange_coeffs, test_zs_and_us, NOTE_COMMITMENT_PERSONALIZATION, NUM_WINDOWS,
-        },
+        super::{NOTE_COMMITMENT_PERSONALIZATION, NUM_WINDOWS},
         *,
         *,
     };
     };
-    use group::Curve;
-    use halo2_gadgets::primitives::sinsemilla::CommitDomain;
-    use pasta_curves::{
-        arithmetic::{CurveAffine, FieldExt},
-        pallas,
+    use halo2_gadgets::{
+        ecc::chip::constants::{test_lagrange_coeffs, test_zs_and_us},
+        primitives::sinsemilla::CommitDomain,
     };
     };
 
 
+    use group::Curve;
+    use pasta_curves::{arithmetic::CurveAffine, pallas};
+
     #[test]
     #[test]
     fn generator() {
     fn generator() {
         let domain = CommitDomain::new(NOTE_COMMITMENT_PERSONALIZATION);
         let domain = CommitDomain::new(NOTE_COMMITMENT_PERSONALIZATION);
         let point = domain.R();
         let point = domain.R();
         let coords = point.to_affine().coordinates().unwrap();
         let coords = point.to_affine().coordinates().unwrap();
 
 
-        assert_eq!(*coords.x(), pallas::Base::from_bytes(&GENERATOR.0).unwrap());
-        assert_eq!(*coords.y(), pallas::Base::from_bytes(&GENERATOR.1).unwrap());
+        assert_eq!(*coords.x(), pallas::Base::from_repr(GENERATOR.0).unwrap());
+        assert_eq!(*coords.y(), pallas::Base::from_repr(GENERATOR.1).unwrap());
     }
     }
 
 
     #[test]
     #[test]

+ 9 - 13
src/crypto/constants/fixed_bases/nullifier_k.rs

@@ -1,7 +1,5 @@
-use pasta_curves::{
-    arithmetic::{CurveAffine, FieldExt},
-    pallas,
-};
+use group::ff::PrimeField;
+use pasta_curves::{arithmetic::CurveAffine, pallas};
 
 
 pub const GENERATOR: ([u8; 32], [u8; 32]) = (
 pub const GENERATOR: ([u8; 32], [u8; 32]) = (
     [
     [
@@ -2921,8 +2919,8 @@ pub const U: [[[u8; 32]; super::H]; super::NUM_WINDOWS] = [
 
 
 pub fn generator() -> pallas::Affine {
 pub fn generator() -> pallas::Affine {
     pallas::Affine::from_xy(
     pallas::Affine::from_xy(
-        pallas::Base::from_bytes(&GENERATOR.0).unwrap(),
-        pallas::Base::from_bytes(&GENERATOR.1).unwrap(),
+        pallas::Base::from_repr(GENERATOR.0).unwrap(),
+        pallas::Base::from_repr(GENERATOR.1).unwrap(),
     )
     )
     .unwrap()
     .unwrap()
 }
 }
@@ -2930,14 +2928,12 @@ pub fn generator() -> pallas::Affine {
 #[cfg(test)]
 #[cfg(test)]
 mod tests {
 mod tests {
     use super::{
     use super::{
-        super::{test_lagrange_coeffs, test_zs_and_us, NUM_WINDOWS, ORCHARD_PERSONALIZATION},
+        super::{NUM_WINDOWS, ORCHARD_PERSONALIZATION},
         *,
         *,
     };
     };
     use group::Curve;
     use group::Curve;
-    use pasta_curves::{
-        arithmetic::{CurveExt, FieldExt},
-        pallas,
-    };
+    use halo2_gadgets::ecc::chip::constants::{test_lagrange_coeffs, test_zs_and_us};
+    use pasta_curves::{arithmetic::CurveExt, pallas};
 
 
     #[test]
     #[test]
     fn generator() {
     fn generator() {
@@ -2945,8 +2941,8 @@ mod tests {
         let point = hasher(b"K");
         let point = hasher(b"K");
         let coords = point.to_affine().coordinates().unwrap();
         let coords = point.to_affine().coordinates().unwrap();
 
 
-        assert_eq!(*coords.x(), pallas::Base::from_bytes(&GENERATOR.0).unwrap());
-        assert_eq!(*coords.y(), pallas::Base::from_bytes(&GENERATOR.1).unwrap());
+        assert_eq!(*coords.x(), pallas::Base::from_repr(GENERATOR.0).unwrap());
+        assert_eq!(*coords.y(), pallas::Base::from_repr(GENERATOR.1).unwrap());
     }
     }
 
 
     #[test]
     #[test]

+ 9 - 10
src/crypto/constants/fixed_bases/spend_auth_g.rs

@@ -1,7 +1,5 @@
-use pasta_curves::{
-    arithmetic::{CurveAffine, FieldExt},
-    pallas,
-};
+use group::ff::PrimeField;
+use pasta_curves::{arithmetic::CurveAffine, pallas};
 
 
 /// The value commitment is used to check balance between inputs and outputs. The value is
 /// The value commitment is used to check balance between inputs and outputs. The value is
 /// placed over this generator.
 /// placed over this generator.
@@ -2923,8 +2921,8 @@ pub const U: [[[u8; 32]; super::H]; super::NUM_WINDOWS] = [
 
 
 pub fn generator() -> pallas::Affine {
 pub fn generator() -> pallas::Affine {
     pallas::Affine::from_xy(
     pallas::Affine::from_xy(
-        pallas::Base::from_bytes(&GENERATOR.0).unwrap(),
-        pallas::Base::from_bytes(&GENERATOR.1).unwrap(),
+        pallas::Base::from_repr(GENERATOR.0).unwrap(),
+        pallas::Base::from_repr(GENERATOR.1).unwrap(),
     )
     )
     .unwrap()
     .unwrap()
 }
 }
@@ -2932,12 +2930,13 @@ pub fn generator() -> pallas::Affine {
 #[cfg(test)]
 #[cfg(test)]
 mod tests {
 mod tests {
     use super::{
     use super::{
-        super::{test_lagrange_coeffs, test_zs_and_us, NUM_WINDOWS, ORCHARD_PERSONALIZATION},
+        super::{NUM_WINDOWS, ORCHARD_PERSONALIZATION},
         *,
         *,
     };
     };
     use group::Curve;
     use group::Curve;
+    use halo2_gadgets::ecc::chip::constants::{test_lagrange_coeffs, test_zs_and_us};
     use pasta_curves::{
     use pasta_curves::{
-        arithmetic::{CurveAffine, CurveExt, FieldExt},
+        arithmetic::{CurveAffine, CurveExt},
         pallas,
         pallas,
     };
     };
 
 
@@ -2947,8 +2946,8 @@ mod tests {
         let point = hasher(b"G");
         let point = hasher(b"G");
         let coords = point.to_affine().coordinates().unwrap();
         let coords = point.to_affine().coordinates().unwrap();
 
 
-        assert_eq!(*coords.x(), pallas::Base::from_bytes(&GENERATOR.0).unwrap());
-        assert_eq!(*coords.y(), pallas::Base::from_bytes(&GENERATOR.1).unwrap());
+        assert_eq!(*coords.x(), pallas::Base::from_repr(GENERATOR.0).unwrap());
+        assert_eq!(*coords.y(), pallas::Base::from_repr(GENERATOR.1).unwrap());
     }
     }
 
 
     #[test]
     #[test]

+ 9 - 12
src/crypto/constants/fixed_bases/value_commit_r.rs

@@ -1,7 +1,5 @@
-use pasta_curves::{
-    arithmetic::{CurveAffine, FieldExt},
-    pallas,
-};
+use group::ff::PrimeField;
+use pasta_curves::{arithmetic::CurveAffine, pallas};
 
 
 /// The value commitment is used to check balance between inputs and outputs. The value is
 /// The value commitment is used to check balance between inputs and outputs. The value is
 /// placed over this generator.
 /// placed over this generator.
@@ -2923,8 +2921,8 @@ pub const U: [[[u8; 32]; super::H]; super::NUM_WINDOWS] = [
 
 
 pub fn generator() -> pallas::Affine {
 pub fn generator() -> pallas::Affine {
     pallas::Affine::from_xy(
     pallas::Affine::from_xy(
-        pallas::Base::from_bytes(&GENERATOR.0).unwrap(),
-        pallas::Base::from_bytes(&GENERATOR.1).unwrap(),
+        pallas::Base::from_repr(GENERATOR.0).unwrap(),
+        pallas::Base::from_repr(GENERATOR.1).unwrap(),
     )
     )
     .unwrap()
     .unwrap()
 }
 }
@@ -2932,14 +2930,13 @@ pub fn generator() -> pallas::Affine {
 #[cfg(test)]
 #[cfg(test)]
 mod tests {
 mod tests {
     use super::{
     use super::{
-        super::{
-            test_lagrange_coeffs, test_zs_and_us, NUM_WINDOWS, VALUE_COMMITMENT_PERSONALIZATION,
-        },
+        super::{NUM_WINDOWS, VALUE_COMMITMENT_PERSONALIZATION},
         *,
         *,
     };
     };
     use group::Curve;
     use group::Curve;
+    use halo2_gadgets::ecc::chip::constants::{test_lagrange_coeffs, test_zs_and_us};
     use pasta_curves::{
     use pasta_curves::{
-        arithmetic::{CurveAffine, CurveExt, FieldExt},
+        arithmetic::{CurveAffine, CurveExt},
         pallas,
         pallas,
     };
     };
 
 
@@ -2949,8 +2946,8 @@ mod tests {
         let point = hasher(b"r");
         let point = hasher(b"r");
         let coords = point.to_affine().coordinates().unwrap();
         let coords = point.to_affine().coordinates().unwrap();
 
 
-        assert_eq!(*coords.x(), pallas::Base::from_bytes(&GENERATOR.0).unwrap());
-        assert_eq!(*coords.y(), pallas::Base::from_bytes(&GENERATOR.1).unwrap());
+        assert_eq!(*coords.x(), pallas::Base::from_repr(GENERATOR.0).unwrap());
+        assert_eq!(*coords.y(), pallas::Base::from_repr(GENERATOR.1).unwrap());
     }
     }
 
 
     #[test]
     #[test]

+ 11 - 15
src/crypto/constants/fixed_bases/value_commit_v.rs

@@ -1,7 +1,5 @@
-use pasta_curves::{
-    arithmetic::{CurveAffine, FieldExt},
-    pallas,
-};
+use group::ff::PrimeField;
+use pasta_curves::{arithmetic::CurveAffine, pallas};
 
 
 /// The value commitment is used to check balance between inputs and outputs. The value is
 /// The value commitment is used to check balance between inputs and outputs. The value is
 /// placed over this generator.
 /// placed over this generator.
@@ -776,8 +774,8 @@ pub const U_SHORT: [[[u8; 32]; super::H]; super::NUM_WINDOWS_SHORT] = [
 
 
 pub fn generator() -> pallas::Affine {
 pub fn generator() -> pallas::Affine {
     pallas::Affine::from_xy(
     pallas::Affine::from_xy(
-        pallas::Base::from_bytes(&GENERATOR.0).unwrap(),
-        pallas::Base::from_bytes(&GENERATOR.1).unwrap(),
+        pallas::Base::from_repr(GENERATOR.0).unwrap(),
+        pallas::Base::from_repr(GENERATOR.1).unwrap(),
     )
     )
     .unwrap()
     .unwrap()
 }
 }
@@ -785,15 +783,13 @@ pub fn generator() -> pallas::Affine {
 #[cfg(test)]
 #[cfg(test)]
 mod tests {
 mod tests {
     use super::{
     use super::{
-        super::{
-            test_lagrange_coeffs, test_zs_and_us, NUM_WINDOWS_SHORT,
-            VALUE_COMMITMENT_PERSONALIZATION,
-        },
+        super::{NUM_WINDOWS_SHORT, VALUE_COMMITMENT_PERSONALIZATION},
         *,
         *,
     };
     };
     use group::Curve;
     use group::Curve;
+    use halo2_gadgets::ecc::chip::constants::{test_lagrange_coeffs, test_zs_and_us};
     use pasta_curves::{
     use pasta_curves::{
-        arithmetic::{CurveAffine, CurveExt, FieldExt},
+        arithmetic::{CurveAffine, CurveExt},
         pallas,
         pallas,
     };
     };
 
 
@@ -803,18 +799,18 @@ mod tests {
         let point = hasher(b"v");
         let point = hasher(b"v");
         let coords = point.to_affine().coordinates().unwrap();
         let coords = point.to_affine().coordinates().unwrap();
 
 
-        assert_eq!(*coords.x(), pallas::Base::from_bytes(&GENERATOR.0).unwrap());
-        assert_eq!(*coords.y(), pallas::Base::from_bytes(&GENERATOR.1).unwrap());
+        assert_eq!(*coords.x(), pallas::Base::from_repr(GENERATOR.0).unwrap());
+        assert_eq!(*coords.y(), pallas::Base::from_repr(GENERATOR.1).unwrap());
     }
     }
 
 
     #[test]
     #[test]
-    fn lagrange_coeffs_short() {
+    fn lagrange_coeffs() {
         let base = super::generator();
         let base = super::generator();
         test_lagrange_coeffs(base, NUM_WINDOWS_SHORT);
         test_lagrange_coeffs(base, NUM_WINDOWS_SHORT);
     }
     }
 
 
     #[test]
     #[test]
-    fn z_short() {
+    fn z() {
         let base = super::generator();
         let base = super::generator();
         test_zs_and_us(base, &Z_SHORT, &U_SHORT, NUM_WINDOWS_SHORT);
         test_zs_and_us(base, &Z_SHORT, &U_SHORT, NUM_WINDOWS_SHORT);
     }
     }

+ 257 - 0
src/crypto/constants/load.rs

@@ -0,0 +1,257 @@
+use std::convert::TryInto;
+
+use crate::constants::{self, compute_lagrange_coeffs, H, NUM_WINDOWS, NUM_WINDOWS_SHORT};
+use group::ff::PrimeField;
+use pasta_curves::pallas;
+
+#[derive(Copy, Clone, Debug, Eq, PartialEq)]
+pub enum OrchardFixedBasesFull {
+    CommitIvkR,
+    NoteCommitR,
+    ValueCommitR,
+    SpendAuthG,
+}
+
+impl OrchardFixedBasesFull {
+    pub fn generator(&self) -> pallas::Affine {
+        match self {
+            OrchardFixedBasesFull::CommitIvkR => super::commit_ivk_r::generator(),
+            OrchardFixedBasesFull::NoteCommitR => super::note_commit_r::generator(),
+            OrchardFixedBasesFull::ValueCommitR => super::value_commit_r::generator(),
+            OrchardFixedBasesFull::SpendAuthG => super::spend_auth_g::generator(),
+        }
+    }
+
+    pub fn u(&self) -> U {
+        match self {
+            OrchardFixedBasesFull::CommitIvkR => super::commit_ivk_r::U.into(),
+            OrchardFixedBasesFull::NoteCommitR => super::note_commit_r::U.into(),
+            OrchardFixedBasesFull::ValueCommitR => super::value_commit_r::U.into(),
+            OrchardFixedBasesFull::SpendAuthG => super::spend_auth_g::U.into(),
+        }
+    }
+}
+
+/// A fixed base to be used in scalar multiplication with a full-width scalar.
+#[derive(Clone, Debug, Eq, PartialEq)]
+pub struct OrchardFixedBase {
+    pub generator: pallas::Affine,
+    pub lagrange_coeffs: LagrangeCoeffs,
+    pub z: Z,
+    pub u: U,
+}
+
+impl From<OrchardFixedBasesFull> 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::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 base field element.
+#[derive(Clone, Debug, Eq, PartialEq)]
+pub struct ValueCommitV {
+    pub generator: pallas::Affine,
+    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(),
+        }
+    }
+}
+
+/// A fixed base to be used in scalar multiplication with a short signed exponent.
+#[derive(Copy, Clone, Debug, Eq, PartialEq)]
+pub struct NullifierK;
+
+impl From<NullifierK> for OrchardFixedBase {
+    fn from(_nullifier_k: NullifierK) -> Self {
+        let (generator, z, u) = (
+            super::nullifier_k::generator(),
+            super::nullifier_k::Z.into(),
+            super::nullifier_k::U.into(),
+        );
+        Self {
+            generator,
+            lagrange_coeffs: compute_lagrange_coeffs(generator, NUM_WINDOWS).into(),
+            z,
+            u,
+        }
+    }
+}
+
+impl NullifierK {
+    pub fn generator(&self) -> pallas::Affine {
+        super::nullifier_k::generator()
+    }
+
+    pub fn u(&self) -> U {
+        super::nullifier_k::U.into()
+    }
+}
+
+#[derive(Clone, Debug, Eq, PartialEq)]
+// 8 coefficients per window
+pub struct WindowLagrangeCoeffs(pub Box<[pallas::Base; H]>);
+
+impl From<&[pallas::Base; H]> for WindowLagrangeCoeffs {
+    fn from(array: &[pallas::Base; 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<Vec<WindowLagrangeCoeffs>> for LagrangeCoeffs {
+    fn from(windows: Vec<WindowLagrangeCoeffs>) -> Self {
+        Self(windows.into_boxed_slice().try_into().unwrap())
+    }
+}
+
+impl From<Vec<[pallas::Base; H]>> for LagrangeCoeffs {
+    fn from(arrays: Vec<[pallas::Base; H]>) -> Self {
+        let windows: Vec<WindowLagrangeCoeffs> = 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<Vec<WindowLagrangeCoeffs>> for LagrangeCoeffsShort {
+    fn from(windows: Vec<WindowLagrangeCoeffs>) -> Self {
+        Self(windows.into_boxed_slice().try_into().unwrap())
+    }
+}
+
+impl From<Vec<[pallas::Base; H]>> for LagrangeCoeffsShort {
+    fn from(arrays: Vec<[pallas::Base; H]>) -> Self {
+        let windows: Vec<WindowLagrangeCoeffs> = 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<[pallas::Base; NUM_WINDOWS]>);
+
+impl From<[u64; NUM_WINDOWS]> for Z {
+    fn from(zs: [u64; NUM_WINDOWS]) -> Self {
+        Self(
+            zs.iter()
+                .map(|z| pallas::Base::from(*z))
+                .collect::<Vec<_>>()
+                .into_boxed_slice()
+                .try_into()
+                .unwrap(),
+        )
+    }
+}
+
+#[derive(Clone, Debug, Eq, PartialEq)]
+// 22 Z's for ValueCommitV
+pub struct ZShort(pub Box<[pallas::Base; NUM_WINDOWS_SHORT]>);
+
+impl From<[u64; NUM_WINDOWS_SHORT]> for ZShort {
+    fn from(zs: [u64; NUM_WINDOWS_SHORT]) -> Self {
+        Self(
+            zs.iter()
+                .map(|z| pallas::Base::from(*z))
+                .collect::<Vec<_>>()
+                .into_boxed_slice()
+                .try_into()
+                .unwrap(),
+        )
+    }
+}
+
+#[derive(Clone, Debug, Eq, PartialEq)]
+// 8 u's per window
+pub struct WindowUs(pub Box<[pallas::Base; H]>);
+
+impl From<&[[u8; 32]; H]> for WindowUs {
+    fn from(window_us: &[[u8; 32]; H]) -> Self {
+        Self(
+            window_us
+                .iter()
+                .map(|u| pallas::Base::from_repr(*u).unwrap())
+                .collect::<Vec<_>>()
+                .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<Vec<WindowUs>> for U {
+    fn from(windows: Vec<WindowUs>) -> 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<WindowUs> = 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<Vec<WindowUs>> for UShort {
+    fn from(windows: Vec<WindowUs>) -> 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<WindowUs> = window_us.iter().map(|us| us.into()).collect();
+        windows.into()
+    }
+}

+ 31 - 56
src/crypto/constants/sinsemilla.rs

@@ -1,12 +1,10 @@
 //! Sinsemilla generators
 //! Sinsemilla generators
-use super::OrchardFixedBases;
-//use crate::spec::i2lebsp;
-
+use super::{OrchardFixedBases, OrchardFixedBasesFull};
+use crate::crypto::util::i2lebsp;
 use halo2_gadgets::sinsemilla::{CommitDomains, HashDomains};
 use halo2_gadgets::sinsemilla::{CommitDomains, HashDomains};
-use pasta_curves::{
-    arithmetic::{CurveAffine, FieldExt},
-    pallas,
-};
+
+use group::ff::PrimeField;
+use pasta_curves::{arithmetic::CurveAffine, pallas};
 
 
 /// Number of bits of each message piece in $\mathsf{SinsemillaHashToPoint}$
 /// Number of bits of each message piece in $\mathsf{SinsemillaHashToPoint}$
 pub const K: usize = 10;
 pub const K: usize = 10;
@@ -21,19 +19,12 @@ pub const INV_TWO_POW_K: [u8; 32] = [
 /// of Pallas.
 /// of Pallas.
 pub const C: usize = 253;
 pub const C: usize = 253;
 
 
+/// $\ell^\mathsf{Orchard}_\mathsf{Merkle}$
+pub(crate) const L_ORCHARD_MERKLE: usize = 255;
+
 /// SWU hash-to-curve personalization for the Merkle CRH generator
 /// SWU hash-to-curve personalization for the Merkle CRH generator
 pub const MERKLE_CRH_PERSONALIZATION: &str = "z.cash:Orchard-MerkleCRH";
 pub const MERKLE_CRH_PERSONALIZATION: &str = "z.cash:Orchard-MerkleCRH";
 
 
-// Sinsemilla Q generators
-
-/// SWU hash-to-curve personalization for Sinsemilla $Q$ generators.
-pub const Q_PERSONALIZATION: &str = "z.cash:SinsemillaQ";
-
-// Sinsemilla S generators
-
-/// SWU hash-to-curve personalization for Sinsemilla $S$ generators.
-pub const S_PERSONALIZATION: &str = "z.cash:SinsemillaS";
-
 /// Generator used in SinsemillaHashToPoint for note commitment
 /// Generator used in SinsemillaHashToPoint for note commitment
 pub const Q_NOTE_COMMITMENT_M_GENERATOR: ([u8; 32], [u8; 32]) = (
 pub const Q_NOTE_COMMITMENT_M_GENERATOR: ([u8; 32], [u8; 32]) = (
     [
     [
@@ -70,20 +61,14 @@ pub const Q_MERKLE_CRH: ([u8; 32], [u8; 32]) = (
     ],
     ],
 );
 );
 
 
-pub fn i2lebsp<const NUM_BITS: usize>(int: u64) -> [bool; NUM_BITS] {
-    assert!(NUM_BITS <= 64);
-    super::util::gen_const_array(|mask: usize| (int & (1 << mask)) != 0)
-}
-
-#[allow(dead_code)]
-fn lebs2ip_k(bits: &[bool]) -> u32 {
+pub(crate) fn lebs2ip_k(bits: &[bool]) -> u32 {
     assert!(bits.len() == K);
     assert!(bits.len() == K);
     bits.iter().enumerate().fold(0u32, |acc, (i, b)| acc + if *b { 1 << i } else { 0 })
     bits.iter().enumerate().fold(0u32, |acc, (i, b)| acc + if *b { 1 << i } else { 0 })
 }
 }
 
 
 /// The sequence of K bits in little-endian order representing an integer
 /// The sequence of K bits in little-endian order representing an integer
 /// up to `2^K` - 1.
 /// up to `2^K` - 1.
-pub fn i2lebsp_k(int: usize) -> [bool; K] {
+pub(crate) fn i2lebsp_k(int: usize) -> [bool; K] {
     assert!(int < (1 << K));
     assert!(int < (1 << K));
     i2lebsp(int as u64)
     i2lebsp(int as u64)
 }
 }
@@ -100,18 +85,18 @@ impl HashDomains<pallas::Affine> for OrchardHashDomains {
     fn Q(&self) -> pallas::Affine {
     fn Q(&self) -> pallas::Affine {
         match self {
         match self {
             OrchardHashDomains::CommitIvk => pallas::Affine::from_xy(
             OrchardHashDomains::CommitIvk => pallas::Affine::from_xy(
-                pallas::Base::from_bytes(&Q_COMMIT_IVK_M_GENERATOR.0).unwrap(),
-                pallas::Base::from_bytes(&Q_COMMIT_IVK_M_GENERATOR.1).unwrap(),
+                pallas::Base::from_repr(Q_COMMIT_IVK_M_GENERATOR.0).unwrap(),
+                pallas::Base::from_repr(Q_COMMIT_IVK_M_GENERATOR.1).unwrap(),
             )
             )
             .unwrap(),
             .unwrap(),
             OrchardHashDomains::NoteCommit => pallas::Affine::from_xy(
             OrchardHashDomains::NoteCommit => pallas::Affine::from_xy(
-                pallas::Base::from_bytes(&Q_NOTE_COMMITMENT_M_GENERATOR.0).unwrap(),
-                pallas::Base::from_bytes(&Q_NOTE_COMMITMENT_M_GENERATOR.1).unwrap(),
+                pallas::Base::from_repr(Q_NOTE_COMMITMENT_M_GENERATOR.0).unwrap(),
+                pallas::Base::from_repr(Q_NOTE_COMMITMENT_M_GENERATOR.1).unwrap(),
             )
             )
             .unwrap(),
             .unwrap(),
             OrchardHashDomains::MerkleCrh => pallas::Affine::from_xy(
             OrchardHashDomains::MerkleCrh => pallas::Affine::from_xy(
-                pallas::Base::from_bytes(&Q_MERKLE_CRH.0).unwrap(),
-                pallas::Base::from_bytes(&Q_MERKLE_CRH.1).unwrap(),
+                pallas::Base::from_repr(Q_MERKLE_CRH.0).unwrap(),
+                pallas::Base::from_repr(Q_MERKLE_CRH.1).unwrap(),
             )
             )
             .unwrap(),
             .unwrap(),
         }
         }
@@ -125,10 +110,10 @@ pub enum OrchardCommitDomains {
 }
 }
 
 
 impl CommitDomains<pallas::Affine, OrchardFixedBases, OrchardHashDomains> for OrchardCommitDomains {
 impl CommitDomains<pallas::Affine, OrchardFixedBases, OrchardHashDomains> for OrchardCommitDomains {
-    fn r(&self) -> OrchardFixedBases {
+    fn r(&self) -> OrchardFixedBasesFull {
         match self {
         match self {
-            Self::NoteCommit => OrchardFixedBases::NoteCommitR,
-            Self::CommitIvk => OrchardFixedBases::CommitIvkR,
+            Self::NoteCommit => OrchardFixedBasesFull::NoteCommitR,
+            Self::CommitIvk => OrchardFixedBasesFull::CommitIvkR,
         }
         }
     }
     }
 
 
@@ -143,23 +128,19 @@ impl CommitDomains<pallas::Affine, OrchardFixedBases, OrchardHashDomains> for Or
 #[cfg(test)]
 #[cfg(test)]
 mod tests {
 mod tests {
     use super::*;
     use super::*;
-    use crate::crypto::constants::{
+    use crate::constants::{
         fixed_bases::{COMMIT_IVK_PERSONALIZATION, NOTE_COMMITMENT_PERSONALIZATION},
         fixed_bases::{COMMIT_IVK_PERSONALIZATION, NOTE_COMMITMENT_PERSONALIZATION},
         sinsemilla::MERKLE_CRH_PERSONALIZATION,
         sinsemilla::MERKLE_CRH_PERSONALIZATION,
     };
     };
+    use group::{ff::PrimeField, Curve};
     use halo2_gadgets::primitives::sinsemilla::{CommitDomain, HashDomain};
     use halo2_gadgets::primitives::sinsemilla::{CommitDomain, HashDomain};
-
-    use pasta_curves::{
-        arithmetic::{CurveAffine, FieldExt},
-        group::{ff::PrimeField, Curve},
-        pallas,
-    };
+    use halo2_proofs::{arithmetic::CurveAffine, pasta::pallas};
     use rand::{self, rngs::OsRng, Rng};
     use rand::{self, rngs::OsRng, Rng};
 
 
     #[test]
     #[test]
     // Nodes in the Merkle tree are Pallas base field elements.
     // Nodes in the Merkle tree are Pallas base field elements.
     fn l_orchard_merkle() {
     fn l_orchard_merkle() {
-        assert_eq!(255, pallas::Base::NUM_BITS as usize);
+        assert_eq!(super::L_ORCHARD_MERKLE, pallas::Base::NUM_BITS as usize);
     }
     }
 
 
     #[test]
     #[test]
@@ -198,14 +179,8 @@ mod tests {
         let point = domain.Q();
         let point = domain.Q();
         let coords = point.to_affine().coordinates().unwrap();
         let coords = point.to_affine().coordinates().unwrap();
 
 
-        assert_eq!(
-            *coords.x(),
-            pallas::Base::from_bytes(&Q_NOTE_COMMITMENT_M_GENERATOR.0).unwrap()
-        );
-        assert_eq!(
-            *coords.y(),
-            pallas::Base::from_bytes(&Q_NOTE_COMMITMENT_M_GENERATOR.1).unwrap()
-        );
+        assert_eq!(*coords.x(), pallas::Base::from_repr(Q_NOTE_COMMITMENT_M_GENERATOR.0).unwrap());
+        assert_eq!(*coords.y(), pallas::Base::from_repr(Q_NOTE_COMMITMENT_M_GENERATOR.1).unwrap());
     }
     }
 
 
     #[test]
     #[test]
@@ -214,8 +189,8 @@ mod tests {
         let point = domain.Q();
         let point = domain.Q();
         let coords = point.to_affine().coordinates().unwrap();
         let coords = point.to_affine().coordinates().unwrap();
 
 
-        assert_eq!(*coords.x(), pallas::Base::from_bytes(&Q_COMMIT_IVK_M_GENERATOR.0).unwrap());
-        assert_eq!(*coords.y(), pallas::Base::from_bytes(&Q_COMMIT_IVK_M_GENERATOR.1).unwrap());
+        assert_eq!(*coords.x(), pallas::Base::from_repr(Q_COMMIT_IVK_M_GENERATOR.0).unwrap());
+        assert_eq!(*coords.y(), pallas::Base::from_repr(Q_COMMIT_IVK_M_GENERATOR.1).unwrap());
     }
     }
 
 
     #[test]
     #[test]
@@ -224,14 +199,14 @@ mod tests {
         let point = domain.Q();
         let point = domain.Q();
         let coords = point.to_affine().coordinates().unwrap();
         let coords = point.to_affine().coordinates().unwrap();
 
 
-        assert_eq!(*coords.x(), pallas::Base::from_bytes(&Q_MERKLE_CRH.0).unwrap());
-        assert_eq!(*coords.y(), pallas::Base::from_bytes(&Q_MERKLE_CRH.1).unwrap());
+        assert_eq!(*coords.x(), pallas::Base::from_repr(Q_MERKLE_CRH.0).unwrap());
+        assert_eq!(*coords.y(), pallas::Base::from_repr(Q_MERKLE_CRH.1).unwrap());
     }
     }
 
 
     #[test]
     #[test]
     fn inv_two_pow_k() {
     fn inv_two_pow_k() {
-        let two_pow_k = pallas::Base::from_u64(1u64 << K);
-        let inv_two_pow_k = pallas::Base::from_bytes(&INV_TWO_POW_K).unwrap();
+        let two_pow_k = pallas::Base::from(1u64 << K);
+        let inv_two_pow_k = pallas::Base::from_repr(INV_TWO_POW_K).unwrap();
 
 
         assert_eq!(two_pow_k * inv_two_pow_k, pallas::Base::one());
         assert_eq!(two_pow_k * inv_two_pow_k, pallas::Base::one());
     }
     }

+ 2 - 10
src/crypto/constants/util.rs

@@ -1,11 +1,3 @@
-use pasta_curves::arithmetic::{CurveAffine, Field, FieldExt};
-
-/// Evaluate y = f(x) given the coefficients of f(x)
-pub fn evaluate<C: CurveAffine>(x: u8, coeffs: &[C::Base]) -> C::Base {
-    let x = C::Base::from_u64(x as u64);
-    coeffs.iter().rev().cloned().reduce(|acc, coeff| acc * x + coeff).unwrap_or_else(C::Base::zero)
-}
-
 /// Takes in an FnMut closure and returns a constant-length array with elements of
 /// Takes in an FnMut closure and returns a constant-length array with elements of
 /// type `Output`.
 /// type `Output`.
 pub fn gen_const_array<Output: Copy + Default, const LEN: usize>(
 pub fn gen_const_array<Output: Copy + Default, const LEN: usize>(
@@ -16,10 +8,10 @@ pub fn gen_const_array<Output: Copy + Default, const LEN: usize>(
 
 
 pub(crate) fn gen_const_array_with_default<Output: Copy, const LEN: usize>(
 pub(crate) fn gen_const_array_with_default<Output: Copy, const LEN: usize>(
     default_value: Output,
     default_value: Output,
-    closure: impl FnMut(usize) -> Output,
+    mut closure: impl FnMut(usize) -> Output,
 ) -> [Output; LEN] {
 ) -> [Output; LEN] {
     let mut ret: [Output; LEN] = [default_value; LEN];
     let mut ret: [Output; LEN] = [default_value; LEN];
-    for (bit, val) in ret.iter_mut().zip((0..LEN).map(closure)) {
+    for (bit, val) in ret.iter_mut().zip((0..LEN).map(|idx| closure(idx))) {
         *bit = val;
         *bit = val;
     }
     }
     ret
     ret