Replace `FieldExt::{from, to}_bytes` with `PrimeField::{from, to}_repr`

This commit is contained in:
Jack Grigg 2021-12-07 18:02:03 +00:00
parent 6f0cab5ffd
commit 0378898289
27 changed files with 146 additions and 150 deletions

View File

@ -258,7 +258,7 @@ impl Config {
let base = base.point(); let base = base.point();
let alpha = alpha let alpha = alpha
.value() .value()
.map(|alpha| pallas::Scalar::from_bytes(&alpha.to_bytes()).unwrap()); .map(|alpha| pallas::Scalar::from_repr(alpha.to_repr()).unwrap());
let real_mul = base.zip(alpha).map(|(base, alpha)| base * alpha); let real_mul = base.zip(alpha).map(|(base, alpha)| base * alpha);
let result = result.point(); let result = result.point();
@ -431,7 +431,7 @@ fn decompose_for_scalar_mul(scalar: Option<&pallas::Base>) -> Vec<Option<bool>>
// the scalar field `F_q = 2^254 + t_q`. // the scalar field `F_q = 2^254 + t_q`.
// Note that the addition `scalar + t_q` is not reduced. // Note that the addition `scalar + t_q` is not reduced.
// //
let scalar = U256::from_little_endian(&scalar.to_bytes()); let scalar = U256::from_little_endian(&scalar.to_repr());
let t_q = U256::from_little_endian(&T_Q.to_le_bytes()); let t_q = U256::from_little_endian(&T_Q.to_le_bytes());
let k = scalar + t_q; let k = scalar + t_q;
@ -463,7 +463,7 @@ fn decompose_for_scalar_mul(scalar: Option<&pallas::Base>) -> Vec<Option<bool>>
#[cfg(test)] #[cfg(test)]
pub mod tests { pub mod tests {
use group::Curve; use group::{ff::PrimeField, Curve};
use halo2::{ use halo2::{
circuit::{Chip, Layouter}, circuit::{Chip, Layouter},
plonk::Error, plonk::Error,
@ -497,7 +497,7 @@ pub mod tests {
) -> Result<(), Error> { ) -> Result<(), Error> {
// Move scalar from base field into scalar field (which always fits // Move scalar from base field into scalar field (which always fits
// for Pallas). // for Pallas).
let scalar = pallas::Scalar::from_bytes(&scalar_val.to_bytes()).unwrap(); let scalar = pallas::Scalar::from_repr(scalar_val.to_repr()).unwrap();
let expected = NonIdentityPoint::new( let expected = NonIdentityPoint::new(
chip, chip,
layouter.namespace(|| "expected point"), layouter.namespace(|| "expected point"),

View File

@ -8,7 +8,7 @@ use crate::constants::{
load::{NullifierK, OrchardFixedBase, OrchardFixedBasesFull, ValueCommitV, WindowUs}, load::{NullifierK, OrchardFixedBase, OrchardFixedBasesFull, ValueCommitV, WindowUs},
}; };
use group::Curve; use group::{ff::PrimeField, Curve};
use halo2::{ use halo2::{
circuit::{AssignedCell, Region}, circuit::{AssignedCell, Region},
plonk::{Advice, Column, ConstraintSystem, Error, Expression, Fixed, Selector, VirtualCells}, plonk::{Advice, Column, ConstraintSystem, Error, Expression, Fixed, Selector, VirtualCells},
@ -531,7 +531,7 @@ impl ScalarFixed {
let word = z_cur let word = z_cur
.zip(z_next) .zip(z_next)
.map(|(z_cur, z_next)| z_cur - z_next * *H_BASE); .map(|(z_cur, z_next)| z_cur - z_next * *H_BASE);
word.map(|word| pallas::Scalar::from_bytes(&word.to_bytes()).unwrap()) word.map(|word| pallas::Scalar::from_repr(word.to_repr()).unwrap())
}) })
.collect::<Vec<_>>() .collect::<Vec<_>>()
}; };
@ -543,7 +543,7 @@ impl ScalarFixed {
.iter() .iter()
.map(|bits| { .map(|bits| {
bits.value() bits.value()
.map(|value| pallas::Scalar::from_bytes(&value.to_bytes()).unwrap()) .map(|value| pallas::Scalar::from_repr(value.to_repr()).unwrap())
}) })
.collect::<Vec<_>>(), .collect::<Vec<_>>(),
} }

View File

@ -214,13 +214,13 @@ impl Config {
#[cfg(test)] #[cfg(test)]
// Check that the correct multiple is obtained. // Check that the correct multiple is obtained.
{ {
use group::Curve; use group::{ff::PrimeField, Curve};
let base: super::OrchardFixedBases = base.into(); let base: super::OrchardFixedBases = base.into();
let scalar = &scalar let scalar = &scalar
.base_field_elem() .base_field_elem()
.value() .value()
.map(|scalar| pallas::Scalar::from_bytes(&scalar.to_bytes()).unwrap()); .map(|scalar| pallas::Scalar::from_repr(scalar.to_repr()).unwrap());
let real_mul = scalar.map(|scalar| base.generator() * scalar); let real_mul = scalar.map(|scalar| base.generator() * scalar);
let result = result.point(); let result = result.point();
@ -374,7 +374,7 @@ impl Config {
#[cfg(test)] #[cfg(test)]
pub mod tests { pub mod tests {
use group::Curve; use group::{ff::PrimeField, Curve};
use halo2::{ use halo2::{
circuit::{Chip, Layouter}, circuit::{Chip, Layouter},
plonk::Error, plonk::Error,
@ -421,7 +421,7 @@ pub mod tests {
result: Point<pallas::Affine, EccChip>, result: Point<pallas::Affine, EccChip>,
) -> Result<(), Error> { ) -> Result<(), Error> {
// Move scalar from base field into scalar field (which always fits for Pallas). // Move scalar from base field into scalar field (which always fits for Pallas).
let scalar = pallas::Scalar::from_bytes(&scalar_val.to_bytes()).unwrap(); let scalar = pallas::Scalar::from_repr(scalar_val.to_repr()).unwrap();
let expected = NonIdentityPoint::new( let expected = NonIdentityPoint::new(
chip, chip,
layouter.namespace(|| "expected point"), layouter.namespace(|| "expected point"),

View File

@ -187,8 +187,7 @@ impl Config {
// Invalid values result in constraint failures which are // Invalid values result in constraint failures which are
// tested at the circuit-level. // tested at the circuit-level.
{ {
use group::Curve; use group::{ff::PrimeField, Curve};
use pasta_curves::arithmetic::FieldExt;
if let (Some(magnitude), Some(sign)) = (scalar.magnitude.value(), scalar.sign.value()) { if let (Some(magnitude), Some(sign)) = (scalar.magnitude.value(), scalar.sign.value()) {
let magnitude_is_valid = magnitude <= &pallas::Base::from(0xFFFF_FFFF_FFFF_FFFFu64); let magnitude_is_valid = magnitude <= &pallas::Base::from(0xFFFF_FFFF_FFFF_FFFFu64);
@ -200,8 +199,7 @@ impl Config {
|(magnitude, sign)| { |(magnitude, sign)| {
// Move magnitude from base field into scalar field (which always fits // Move magnitude from base field into scalar field (which always fits
// for Pallas). // for Pallas).
let magnitude = let magnitude = pallas::Scalar::from_repr(magnitude.to_repr()).unwrap();
pallas::Scalar::from_bytes(&magnitude.to_bytes()).unwrap();
let sign = if sign == &pallas::Base::one() { let sign = if sign == &pallas::Base::one() {
pallas::Scalar::one() pallas::Scalar::one()
@ -229,7 +227,7 @@ impl Config {
#[cfg(test)] #[cfg(test)]
pub mod tests { pub mod tests {
use group::Curve; use group::{ff::PrimeField, Curve};
use halo2::{ use halo2::{
arithmetic::CurveAffine, arithmetic::CurveAffine,
circuit::{AssignedCell, Chip, Layouter}, circuit::{AssignedCell, Chip, Layouter},
@ -330,7 +328,7 @@ pub mod tests {
}; };
// Move from base field into scalar field // Move from base field into scalar field
let scalar = { let scalar = {
let magnitude = pallas::Scalar::from_bytes(&magnitude.to_bytes()).unwrap(); let magnitude = pallas::Scalar::from_repr(magnitude.to_repr()).unwrap();
let sign = if *sign == pallas::Base::one() { let sign = if *sign == pallas::Base::one() {
pallas::Scalar::one() pallas::Scalar::one()
} else { } else {

View File

@ -5,8 +5,8 @@ use crate::circuit::gadget::{
}; };
use ff::PrimeField; use ff::PrimeField;
use halo2::{circuit::Layouter, plonk::Error}; use halo2::{circuit::Layouter, plonk::Error};
use pasta_curves::arithmetic::{CurveAffine, FieldExt}; use pasta_curves::arithmetic::CurveAffine;
use std::{convert::TryInto, fmt::Debug}; use std::fmt::Debug;
pub mod chip; pub mod chip;
pub mod commit_ivk; pub mod commit_ivk;
@ -207,7 +207,13 @@ where
.map(|byte| byte.iter().rev().fold(0u8, |acc, bit| acc * 2 + *bit as u8)) .map(|byte| byte.iter().rev().fold(0u8, |acc, bit| acc * 2 + *bit as u8))
.collect() .collect()
}); });
bytes.map(|bytes| C::Base::from_bytes(&bytes.try_into().unwrap()).unwrap()) bytes.map(|bytes| {
let mut repr = <C::Base as PrimeField>::Repr::default();
// The above code assumes the byte representation is 256 bits.
assert_eq!(repr.as_ref().len(), 32);
repr.as_mut().copy_from_slice(&bytes);
C::Base::from_repr(repr).unwrap()
})
}; };
let piece_value = to_base_field(bitstring); let piece_value = to_base_field(bitstring);

View File

@ -12,8 +12,9 @@ use crate::{
}, },
}; };
use group::ff::PrimeField;
use halo2::{ use halo2::{
arithmetic::{CurveAffine, FieldExt}, arithmetic::CurveAffine,
circuit::{AssignedCell, Chip, Layouter}, circuit::{AssignedCell, Chip, Layouter},
plonk::{ plonk::{
Advice, Column, ConstraintSystem, Error, Expression, Fixed, Selector, TableColumn, Advice, Column, ConstraintSystem, Error, Expression, Fixed, Selector, TableColumn,
@ -305,18 +306,18 @@ impl HashDomains<pallas::Affine> for SinsemillaHashDomains {
fn Q(&self) -> pallas::Affine { fn Q(&self) -> pallas::Affine {
match self { match self {
SinsemillaHashDomains::CommitIvk => pallas::Affine::from_xy( SinsemillaHashDomains::CommitIvk => pallas::Affine::from_xy(
pallas::Base::from_bytes(&Q_COMMIT_IVK_M_GENERATOR.0).unwrap(), pallas::Base::from_repr(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.1).unwrap(),
) )
.unwrap(), .unwrap(),
SinsemillaHashDomains::NoteCommit => pallas::Affine::from_xy( SinsemillaHashDomains::NoteCommit => pallas::Affine::from_xy(
pallas::Base::from_bytes(&Q_NOTE_COMMITMENT_M_GENERATOR.0).unwrap(), pallas::Base::from_repr(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.1).unwrap(),
) )
.unwrap(), .unwrap(),
SinsemillaHashDomains::MerkleCrh => pallas::Affine::from_xy( SinsemillaHashDomains::MerkleCrh => pallas::Affine::from_xy(
pallas::Base::from_bytes(&Q_MERKLE_CRH.0).unwrap(), pallas::Base::from_repr(Q_MERKLE_CRH.0).unwrap(),
pallas::Base::from_bytes(&Q_MERKLE_CRH.1).unwrap(), pallas::Base::from_repr(Q_MERKLE_CRH.1).unwrap(),
) )
.unwrap(), .unwrap(),
} }

View File

@ -7,7 +7,7 @@ use halo2::{
plonk::Error, plonk::Error,
}; };
use ff::{Field, PrimeFieldBits}; use group::ff::{Field, PrimeField, PrimeFieldBits};
use pasta_curves::{ use pasta_curves::{
arithmetic::{CurveAffine, FieldExt}, arithmetic::{CurveAffine, FieldExt},
pallas, pallas,
@ -284,7 +284,7 @@ impl SinsemillaChip {
// We end up with z_n = 0. (z_n is not directly encoded as a cell value; // We end up with z_n = 0. (z_n is not directly encoded as a cell value;
// it is implicitly taken as 0 by adjusting the definition of m_{i+1}.) // it is implicitly taken as 0 by adjusting the definition of m_{i+1}.)
let mut z = piece.field_elem(); let mut z = piece.field_elem();
let inv_2_k = pallas::Base::from_bytes(&INV_TWO_POW_K).unwrap(); let inv_2_k = pallas::Base::from_repr(INV_TWO_POW_K).unwrap();
// We do not assign the final z_n as it is constrained to be zero. // We do not assign the final z_n as it is constrained to be zero.
for (idx, word) in words[0..(words.len() - 1)].iter().enumerate() { for (idx, word) in words[0..(words.len() - 1)].iter().enumerate() {

View File

@ -146,6 +146,7 @@ pub mod tests {
tree, tree,
}; };
use group::ff::PrimeField;
use halo2::{ use halo2::{
arithmetic::FieldExt, arithmetic::FieldExt,
circuit::{Layouter, SimpleFloorPlanner}, circuit::{Layouter, SimpleFloorPlanner},
@ -260,8 +261,8 @@ pub mod tests {
// The expected final root // The expected final root
let final_root = { let final_root = {
let path = tree::MerklePath::new(leaf_pos, self.merkle_path.unwrap()); let path = tree::MerklePath::new(leaf_pos, self.merkle_path.unwrap());
let leaf = ExtractedNoteCommitment::from_bytes(&self.leaf.unwrap().to_bytes()) let leaf =
.unwrap(); ExtractedNoteCommitment::from_bytes(&self.leaf.unwrap().to_repr()).unwrap();
path.root(leaf) path.root(leaf)
}; };

View File

@ -323,7 +323,7 @@ impl MerkleInstructions<pallas::Affine, MERKLE_DEPTH_ORCHARD, { sinsemilla::K },
constants::MERKLE_CRH_PERSONALIZATION, primitives::sinsemilla::HashDomain, constants::MERKLE_CRH_PERSONALIZATION, primitives::sinsemilla::HashDomain,
spec::i2lebsp, spec::i2lebsp,
}; };
use ff::PrimeFieldBits; use group::ff::{PrimeField, PrimeFieldBits};
if let (Some(left), Some(right)) = (left.value(), right.value()) { if let (Some(left), Some(right)) = (left.value(), right.value()) {
let l = i2lebsp::<10>(l as u64); let l = i2lebsp::<10>(l as u64);
@ -347,7 +347,7 @@ impl MerkleInstructions<pallas::Affine, MERKLE_DEPTH_ORCHARD, { sinsemilla::K },
let expected = merkle_crh.hash(message.into_iter()).unwrap(); let expected = merkle_crh.hash(message.into_iter()).unwrap();
assert_eq!(expected.to_bytes(), result.value().unwrap().to_bytes()); assert_eq!(expected.to_repr(), result.value().unwrap().to_repr());
} }
} }

View File

@ -6,7 +6,7 @@ use halo2::{
plonk::{Advice, Column, Error, Expression}, plonk::{Advice, Column, Error, Expression},
}; };
use pasta_curves::arithmetic::FieldExt; use pasta_curves::arithmetic::FieldExt;
use std::{array, convert::TryInto, ops::Range}; use std::{array, ops::Range};
pub(crate) mod cond_swap; pub(crate) mod cond_swap;
pub(crate) mod decompose_running_sum; pub(crate) mod decompose_running_sum;
@ -86,7 +86,7 @@ pub fn ternary<F: FieldExt>(a: Expression<F>, b: Expression<F>, c: Expression<F>
/// Takes a specified subsequence of the little-endian bit representation of a field element. /// Takes a specified subsequence of the little-endian bit representation of a field element.
/// The bits are numbered from 0 for the LSB. /// The bits are numbered from 0 for the LSB.
pub fn bitrange_subset<F: FieldExt + PrimeFieldBits>(field_elem: &F, bitrange: Range<usize>) -> F { pub fn bitrange_subset<F: PrimeFieldBits>(field_elem: &F, bitrange: Range<usize>) -> F {
assert!(bitrange.end <= F::NUM_BITS as usize); assert!(bitrange.end <= F::NUM_BITS as usize);
let bits: Vec<bool> = field_elem let bits: Vec<bool> = field_elem
@ -103,7 +103,11 @@ pub fn bitrange_subset<F: FieldExt + PrimeFieldBits>(field_elem: &F, bitrange: R
.map(|byte| byte.iter().rev().fold(0u8, |acc, bit| acc * 2 + *bit as u8)) .map(|byte| byte.iter().rev().fold(0u8, |acc, bit| acc * 2 + *bit as u8))
.collect(); .collect();
F::from_bytes(&bytearray.try_into().unwrap()).unwrap() let mut repr = F::Repr::default();
// The above code assumes the byte representation is 256 bits.
assert_eq!(repr.as_ref().len(), 32);
repr.as_mut().copy_from_slice(&bytearray);
F::from_repr(repr).unwrap()
} }
/// Check that an expression is in the small range [0..range), /// Check that an expression is in the small range [0..range),
@ -261,7 +265,7 @@ mod tests {
.to_little_endian(&mut range_shift); .to_little_endian(&mut range_shift);
range_shift range_shift
}; };
sum += subset * pallas::Base::from_bytes(&range_shift).unwrap(); sum += subset * pallas::Base::from_repr(range_shift).unwrap();
} }
assert_eq!(field_elem, sum); assert_eq!(field_elem, sum);
}; };

View File

@ -431,7 +431,9 @@ mod tests {
.collect::<Vec<_>>() .collect::<Vec<_>>()
}; };
let expected_zs = { let expected_zs = {
let inv_two_pow_k = F::from_bytes(&INV_TWO_POW_K).unwrap(); let mut repr = F::Repr::default();
repr.as_mut().copy_from_slice(&INV_TWO_POW_K);
let inv_two_pow_k = F::from_repr(repr).unwrap();
chunks.iter().fold(vec![element], |mut zs, a_i| { chunks.iter().fold(vec![element], |mut zs, a_i| {
// z_{i + 1} = (z_i - a_i) / 2^{K} // z_{i + 1} = (z_i - a_i) / 2^{K}
let z = (zs[zs.len() - 1] - a_i) * inv_two_pow_k; let z = (zs[zs.len() - 1] - a_i) * inv_two_pow_k;

View File

@ -254,7 +254,9 @@ fn test_zs_and_us<C: CurveAffine>(base: C, z: &[u64], u: &[[[u8; 32]; H]], num_w
for ((u, z), window_points) in u.iter().zip(z.iter()).zip(window_table) { for ((u, z), window_points) in u.iter().zip(z.iter()).zip(window_table) {
for (u, point) in u.iter().zip(window_points.iter()) { for (u, point) in u.iter().zip(window_points.iter()) {
let y = *point.coordinates().unwrap().y(); let y = *point.coordinates().unwrap().y();
let u = C::Base::from_bytes(u).unwrap(); let mut u_repr = <C::Base as PrimeField>::Repr::default();
u_repr.as_mut().copy_from_slice(u);
let u = C::Base::from_repr(u_repr).unwrap();
assert_eq!(C::Base::from(*z) + y, u * u); // allow either square root assert_eq!(C::Base::from(*z) + y, u * u); // allow either square root
assert!(bool::from((C::Base::from(*z) - y).sqrt().is_none())); assert!(bool::from((C::Base::from(*z) - y).sqrt().is_none()));
} }

View File

@ -1,7 +1,5 @@
use pasta_curves::{ use group::ff::PrimeField;
arithmetic::{CurveAffine, FieldExt}, use pasta_curves::{arithmetic::CurveAffine, pallas};
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_repr(GENERATOR.0).unwrap(),
pallas::Base::from_bytes(&GENERATOR.1).unwrap(), pallas::Base::from_repr(GENERATOR.1).unwrap(),
) )
.unwrap() .unwrap()
} }
@ -2936,10 +2934,7 @@ mod tests {
use super::*; use super::*;
use crate::primitives::sinsemilla::CommitDomain; use crate::primitives::sinsemilla::CommitDomain;
use group::Curve; use group::Curve;
use pasta_curves::{ use pasta_curves::{arithmetic::CurveAffine, pallas};
arithmetic::{CurveAffine, FieldExt},
pallas,
};
#[test] #[test]
fn generator() { fn generator() {
@ -2947,8 +2942,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.x(), pallas::Base::from_repr(GENERATOR.0).unwrap());
assert_eq!(*coords.y(), pallas::Base::from_bytes(&GENERATOR.1).unwrap()); assert_eq!(*coords.y(), pallas::Base::from_repr(GENERATOR.1).unwrap());
} }
#[test] #[test]

View File

@ -1,7 +1,8 @@
use std::convert::TryInto; use std::convert::TryInto;
use crate::constants::{self, compute_lagrange_coeffs, H, NUM_WINDOWS, NUM_WINDOWS_SHORT}; use crate::constants::{self, compute_lagrange_coeffs, H, NUM_WINDOWS, NUM_WINDOWS_SHORT};
use pasta_curves::{arithmetic::FieldExt, pallas}; use group::ff::PrimeField;
use pasta_curves::pallas;
#[derive(Copy, Clone, Debug, Eq, PartialEq)] #[derive(Copy, Clone, Debug, Eq, PartialEq)]
pub enum OrchardFixedBasesFull { pub enum OrchardFixedBasesFull {
@ -212,7 +213,7 @@ impl From<&[[u8; 32]; H]> for WindowUs {
Self( Self(
window_us window_us
.iter() .iter()
.map(|u| pallas::Base::from_bytes(u).unwrap()) .map(|u| pallas::Base::from_repr(*u).unwrap())
.collect::<Vec<_>>() .collect::<Vec<_>>()
.into_boxed_slice() .into_boxed_slice()
.try_into() .try_into()

View File

@ -1,7 +1,5 @@
use pasta_curves::{ use group::ff::PrimeField;
arithmetic::{CurveAffine, FieldExt}, use pasta_curves::{arithmetic::CurveAffine, pallas};
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_repr(GENERATOR.0).unwrap(),
pallas::Base::from_bytes(&GENERATOR.1).unwrap(), pallas::Base::from_repr(GENERATOR.1).unwrap(),
) )
.unwrap() .unwrap()
} }
@ -2936,10 +2934,7 @@ mod tests {
use super::*; use super::*;
use crate::primitives::sinsemilla::CommitDomain; use crate::primitives::sinsemilla::CommitDomain;
use group::Curve; use group::Curve;
use pasta_curves::{ use pasta_curves::{arithmetic::CurveAffine, pallas};
arithmetic::{CurveAffine, FieldExt},
pallas,
};
#[test] #[test]
fn generator() { fn generator() {
@ -2947,8 +2942,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.x(), pallas::Base::from_repr(GENERATOR.0).unwrap());
assert_eq!(*coords.y(), pallas::Base::from_bytes(&GENERATOR.1).unwrap()); assert_eq!(*coords.y(), pallas::Base::from_repr(GENERATOR.1).unwrap());
} }
#[test] #[test]

View File

@ -1,7 +1,5 @@
use pasta_curves::{ use group::ff::PrimeField;
arithmetic::{CurveAffine, FieldExt}, use pasta_curves::{arithmetic::CurveAffine, pallas};
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_repr(GENERATOR.0).unwrap(),
pallas::Base::from_bytes(&GENERATOR.1).unwrap(), pallas::Base::from_repr(GENERATOR.1).unwrap(),
) )
.unwrap() .unwrap()
} }
@ -2934,10 +2932,7 @@ mod tests {
}; };
use super::*; use super::*;
use group::Curve; use group::Curve;
use pasta_curves::{ use pasta_curves::{arithmetic::CurveExt, pallas};
arithmetic::{CurveExt, FieldExt},
pallas,
};
#[test] #[test]
fn generator() { fn generator() {
@ -2945,8 +2940,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.x(), pallas::Base::from_repr(GENERATOR.0).unwrap());
assert_eq!(*coords.y(), pallas::Base::from_bytes(&GENERATOR.1).unwrap()); assert_eq!(*coords.y(), pallas::Base::from_repr(GENERATOR.1).unwrap());
} }
#[test] #[test]

View File

@ -1,7 +1,5 @@
use pasta_curves::{ use group::ff::PrimeField;
arithmetic::{CurveAffine, FieldExt}, use pasta_curves::{arithmetic::CurveAffine, pallas};
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_repr(GENERATOR.0).unwrap(),
pallas::Base::from_bytes(&GENERATOR.1).unwrap(), pallas::Base::from_repr(GENERATOR.1).unwrap(),
) )
.unwrap() .unwrap()
} }
@ -2937,7 +2935,7 @@ mod tests {
use super::*; use super::*;
use group::Curve; use group::Curve;
use pasta_curves::{ use pasta_curves::{
arithmetic::{CurveAffine, CurveExt, FieldExt}, arithmetic::{CurveAffine, CurveExt},
pallas, pallas,
}; };
@ -2947,8 +2945,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.x(), pallas::Base::from_repr(GENERATOR.0).unwrap());
assert_eq!(*coords.y(), pallas::Base::from_bytes(&GENERATOR.1).unwrap()); assert_eq!(*coords.y(), pallas::Base::from_repr(GENERATOR.1).unwrap());
} }
#[test] #[test]

View File

@ -102,7 +102,7 @@ mod tests {
let bytes: Vec<u8> = bits.chunks_exact(8).map(|chunk| chunk.iter().rev().fold(0, |acc, b| (acc << 1) + (*b as u8))).collect(); let bytes: Vec<u8> = bits.chunks_exact(8).map(|chunk| chunk.iter().rev().fold(0, |acc, b| (acc << 1) + (*b as u8))).collect();
// Check that original scalar is recovered from decomposition // Check that original scalar is recovered from decomposition
assert_eq!(scalar, pallas::Scalar::from_bytes(&bytes.try_into().unwrap()).unwrap()); assert_eq!(scalar, pallas::Scalar::from_repr(bytes.try_into().unwrap()).unwrap());
} }
} }
} }

View File

@ -1,7 +1,5 @@
use pasta_curves::{ use group::ff::PrimeField;
arithmetic::{CurveAffine, FieldExt}, use pasta_curves::{arithmetic::CurveAffine, pallas};
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_repr(GENERATOR.0).unwrap(),
pallas::Base::from_bytes(&GENERATOR.1).unwrap(), pallas::Base::from_repr(GENERATOR.1).unwrap(),
) )
.unwrap() .unwrap()
} }
@ -2937,7 +2935,7 @@ mod tests {
use super::*; use super::*;
use group::Curve; use group::Curve;
use pasta_curves::{ use pasta_curves::{
arithmetic::{CurveAffine, CurveExt, FieldExt}, arithmetic::{CurveAffine, CurveExt},
pallas, pallas,
}; };
@ -2947,8 +2945,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.x(), pallas::Base::from_repr(GENERATOR.0).unwrap());
assert_eq!(*coords.y(), pallas::Base::from_bytes(&GENERATOR.1).unwrap()); assert_eq!(*coords.y(), pallas::Base::from_repr(GENERATOR.1).unwrap());
} }
#[test] #[test]

View File

@ -1,7 +1,5 @@
use pasta_curves::{ use group::ff::PrimeField;
arithmetic::{CurveAffine, FieldExt}, use pasta_curves::{arithmetic::CurveAffine, pallas};
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_repr(GENERATOR.0).unwrap(),
pallas::Base::from_bytes(&GENERATOR.1).unwrap(), pallas::Base::from_repr(GENERATOR.1).unwrap(),
) )
.unwrap() .unwrap()
} }
@ -790,7 +788,7 @@ mod tests {
use super::*; use super::*;
use group::Curve; use group::Curve;
use pasta_curves::{ use pasta_curves::{
arithmetic::{CurveAffine, CurveExt, FieldExt}, arithmetic::{CurveAffine, CurveExt},
pallas, pallas,
}; };
@ -800,8 +798,8 @@ 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.x(), pallas::Base::from_repr(GENERATOR.0).unwrap());
assert_eq!(*coords.y(), pallas::Base::from_bytes(&GENERATOR.1).unwrap()); assert_eq!(*coords.y(), pallas::Base::from_repr(GENERATOR.1).unwrap());
} }
#[test] #[test]

View File

@ -7,8 +7,11 @@ use std::mem;
use aes::Aes256; use aes::Aes256;
use blake2b_simd::{Hash as Blake2bHash, Params}; use blake2b_simd::{Hash as Blake2bHash, Params};
use fpe::ff1::{BinaryNumeralString, FF1}; use fpe::ff1::{BinaryNumeralString, FF1};
use group::{ff::Field, prime::PrimeCurveAffine, Curve, GroupEncoding}; use group::{
use halo2::arithmetic::FieldExt; ff::{Field, PrimeField},
prime::PrimeCurveAffine,
Curve, GroupEncoding,
};
use pasta_curves::pallas; use pasta_curves::pallas;
use rand::RngCore; use rand::RngCore;
use subtle::{Choice, ConditionallySelectable, ConstantTimeEq, CtOption}; use subtle::{Choice, ConditionallySelectable, ConstantTimeEq, CtOption};
@ -118,10 +121,10 @@ impl From<&SpendingKey> for SpendAuthorizingKey {
// SpendingKey cannot be constructed such that this assertion would fail. // SpendingKey cannot be constructed such that this assertion would fail.
assert!(!bool::from(ask.is_zero())); assert!(!bool::from(ask.is_zero()));
// TODO: Add TryFrom<S::Scalar> for SpendAuthorizingKey. // TODO: Add TryFrom<S::Scalar> for SpendAuthorizingKey.
let ret = SpendAuthorizingKey(ask.to_bytes().try_into().unwrap()); let ret = SpendAuthorizingKey(ask.to_repr().try_into().unwrap());
// If the last bit of repr_P(ak) is 1, negate ask. // If the last bit of repr_P(ak) is 1, negate ask.
if (<[u8; 32]>::from(SpendValidatingKey::from(&ret).0)[31] >> 7) == 1 { if (<[u8; 32]>::from(SpendValidatingKey::from(&ret).0)[31] >> 7) == 1 {
SpendAuthorizingKey((-ask).to_bytes().try_into().unwrap()) SpendAuthorizingKey((-ask).to_repr().try_into().unwrap())
} else { } else {
ret ret
} }
@ -221,7 +224,7 @@ impl NullifierDerivingKey {
pub(crate) fn from_bytes(bytes: &[u8]) -> Option<Self> { pub(crate) fn from_bytes(bytes: &[u8]) -> Option<Self> {
let nk_bytes = <[u8; 32]>::try_from(bytes).ok()?; let nk_bytes = <[u8; 32]>::try_from(bytes).ok()?;
let nk = pallas::Base::from_bytes(&nk_bytes).map(NullifierDerivingKey); let nk = pallas::Base::from_repr(nk_bytes).map(NullifierDerivingKey);
if nk.is_some().into() { if nk.is_some().into() {
Some(nk.unwrap()) Some(nk.unwrap())
} else { } else {
@ -256,7 +259,7 @@ impl CommitIvkRandomness {
pub(crate) fn from_bytes(bytes: &[u8]) -> Option<Self> { pub(crate) fn from_bytes(bytes: &[u8]) -> Option<Self> {
let rivk_bytes = <[u8; 32]>::try_from(bytes).ok()?; let rivk_bytes = <[u8; 32]>::try_from(bytes).ok()?;
let rivk = pallas::Scalar::from_bytes(&rivk_bytes).map(CommitIvkRandomness); let rivk = pallas::Scalar::from_repr(rivk_bytes).map(CommitIvkRandomness);
if rivk.is_some().into() { if rivk.is_some().into() {
Some(rivk.unwrap()) Some(rivk.unwrap())
} else { } else {
@ -315,8 +318,8 @@ impl FullViewingKey {
/// ///
/// [orchardkeycomponents]: https://zips.z.cash/protocol/nu5.pdf#orchardkeycomponents /// [orchardkeycomponents]: https://zips.z.cash/protocol/nu5.pdf#orchardkeycomponents
fn derive_dk_ovk(&self) -> (DiversifierKey, OutgoingViewingKey) { fn derive_dk_ovk(&self) -> (DiversifierKey, OutgoingViewingKey) {
let k = self.rivk.0.to_bytes(); let k = self.rivk.0.to_repr();
let b = [(&self.ak.0).into(), self.nk.0.to_bytes()]; let b = [(&self.ak.0).into(), self.nk.0.to_repr()];
let r = PrfExpand::OrchardDkOvk.with_ad_slices(&k, &[&b[0][..], &b[1][..]]); let r = PrfExpand::OrchardDkOvk.with_ad_slices(&k, &[&b[0][..], &b[1][..]]);
( (
DiversifierKey(r[..32].try_into().unwrap()), DiversifierKey(r[..32].try_into().unwrap()),
@ -346,8 +349,8 @@ impl FullViewingKey {
pub fn write<W: Write>(&self, mut writer: W) -> io::Result<()> { pub fn write<W: Write>(&self, mut writer: W) -> io::Result<()> {
let ak_raw: [u8; 32] = self.ak.0.clone().into(); let ak_raw: [u8; 32] = self.ak.0.clone().into();
writer.write_all(&ak_raw)?; writer.write_all(&ak_raw)?;
writer.write_all(&self.nk.0.to_bytes())?; writer.write_all(&self.nk.0.to_repr())?;
writer.write_all(&self.rivk.0.to_bytes())?; writer.write_all(&self.rivk.0.to_repr())?;
Ok(()) Ok(())
} }
@ -545,7 +548,7 @@ impl IncomingViewingKey {
pub fn to_bytes(&self) -> [u8; 64] { pub fn to_bytes(&self) -> [u8; 64] {
let mut result = [0u8; 64]; let mut result = [0u8; 64];
result[..32].copy_from_slice(self.dk.to_bytes()); result[..32].copy_from_slice(self.dk.to_bytes());
result[32..].copy_from_slice(&self.ivk.0.to_bytes()); result[32..].copy_from_slice(&self.ivk.0.to_repr());
result result
} }

View File

@ -1,8 +1,8 @@
use std::iter; use std::iter;
use bitvec::{array::BitArray, order::Lsb0}; use bitvec::{array::BitArray, order::Lsb0};
use ff::PrimeFieldBits; use group::ff::{PrimeField, PrimeFieldBits};
use pasta_curves::{arithmetic::FieldExt, pallas}; use pasta_curves::pallas;
use subtle::{ConstantTimeEq, CtOption}; use subtle::{ConstantTimeEq, CtOption};
use crate::{ use crate::{
@ -72,12 +72,12 @@ impl ExtractedNoteCommitment {
/// ///
/// [cmxcanon]: https://zips.z.cash/protocol/protocol.pdf#actionencodingandconsensus /// [cmxcanon]: https://zips.z.cash/protocol/protocol.pdf#actionencodingandconsensus
pub fn from_bytes(bytes: &[u8; 32]) -> CtOption<Self> { pub fn from_bytes(bytes: &[u8; 32]) -> CtOption<Self> {
pallas::Base::from_bytes(bytes).map(ExtractedNoteCommitment) pallas::Base::from_repr(*bytes).map(ExtractedNoteCommitment)
} }
/// Serialize the value commitment to its canonical byte representation. /// Serialize the value commitment to its canonical byte representation.
pub fn to_bytes(self) -> [u8; 32] { pub fn to_bytes(self) -> [u8; 32] {
self.0.to_bytes() self.0.to_repr()
} }
} }

View File

@ -1,6 +1,6 @@
use group::Group; use group::{ff::PrimeField, Group};
use halo2::arithmetic::CurveExt; use halo2::arithmetic::CurveExt;
use pasta_curves::{arithmetic::FieldExt, pallas}; use pasta_curves::pallas;
use rand::RngCore; use rand::RngCore;
use subtle::CtOption; use subtle::CtOption;
@ -33,12 +33,12 @@ impl Nullifier {
/// Deserialize the nullifier from a byte array. /// Deserialize the nullifier from a byte array.
pub fn from_bytes(bytes: &[u8; 32]) -> CtOption<Self> { pub fn from_bytes(bytes: &[u8; 32]) -> CtOption<Self> {
pallas::Base::from_bytes(bytes).map(Nullifier) pallas::Base::from_repr(*bytes).map(Nullifier)
} }
/// Serialize the nullifier to its canonical byte representation. /// Serialize the nullifier to its canonical byte representation.
pub fn to_bytes(self) -> [u8; 32] { pub fn to_bytes(self) -> [u8; 32] {
self.0.to_bytes() self.0.to_repr()
} }
/// $DeriveNullifier$. /// $DeriveNullifier$.

View File

@ -3,7 +3,7 @@
use std::{convert::TryInto, fmt}; use std::{convert::TryInto, fmt};
use blake2b_simd::{Hash, Params}; use blake2b_simd::{Hash, Params};
use halo2::arithmetic::FieldExt; use group::ff::PrimeField;
use zcash_note_encryption::{ use zcash_note_encryption::{
BatchDomain, Domain, EphemeralKeyBytes, NotePlaintextBytes, NoteValidity, OutPlaintextBytes, BatchDomain, Domain, EphemeralKeyBytes, NotePlaintextBytes, NoteValidity, OutPlaintextBytes,
OutgoingCipherKey, ShieldedOutput, COMPACT_NOTE_SIZE, NOTE_PLAINTEXT_SIZE, OUT_PLAINTEXT_SIZE, OutgoingCipherKey, ShieldedOutput, COMPACT_NOTE_SIZE, NOTE_PLAINTEXT_SIZE, OUT_PLAINTEXT_SIZE,
@ -170,7 +170,7 @@ impl Domain for OrchardDomain {
) -> OutPlaintextBytes { ) -> OutPlaintextBytes {
let mut op = [0; OUT_PLAINTEXT_SIZE]; let mut op = [0; OUT_PLAINTEXT_SIZE];
op[..32].copy_from_slice(&note.recipient().pk_d().to_bytes()); op[..32].copy_from_slice(&note.recipient().pk_d().to_bytes());
op[32..].copy_from_slice(&esk.0.to_bytes()); op[32..].copy_from_slice(&esk.0.to_repr());
OutPlaintextBytes(op) OutPlaintextBytes(op)
} }

View File

@ -66,8 +66,8 @@ mod tests {
use crate::constants::{ use crate::constants::{
COMMIT_IVK_PERSONALIZATION, MERKLE_CRH_PERSONALIZATION, NOTE_COMMITMENT_PERSONALIZATION, COMMIT_IVK_PERSONALIZATION, MERKLE_CRH_PERSONALIZATION, NOTE_COMMITMENT_PERSONALIZATION,
}; };
use group::Curve; use group::{ff::PrimeField, Curve};
use halo2::arithmetic::{CurveAffine, CurveExt, FieldExt}; use halo2::arithmetic::{CurveAffine, CurveExt};
use halo2::pasta::pallas; use halo2::pasta::pallas;
#[test] #[test]
@ -93,11 +93,11 @@ mod tests {
assert_eq!( assert_eq!(
*coords.x(), *coords.x(),
pallas::Base::from_bytes(&Q_NOTE_COMMITMENT_M_GENERATOR.0).unwrap() pallas::Base::from_repr(Q_NOTE_COMMITMENT_M_GENERATOR.0).unwrap()
); );
assert_eq!( assert_eq!(
*coords.y(), *coords.y(),
pallas::Base::from_bytes(&Q_NOTE_COMMITMENT_M_GENERATOR.1).unwrap() pallas::Base::from_repr(Q_NOTE_COMMITMENT_M_GENERATOR.1).unwrap()
); );
} }
@ -109,11 +109,11 @@ mod tests {
assert_eq!( assert_eq!(
*coords.x(), *coords.x(),
pallas::Base::from_bytes(&Q_COMMIT_IVK_M_GENERATOR.0).unwrap() pallas::Base::from_repr(Q_COMMIT_IVK_M_GENERATOR.0).unwrap()
); );
assert_eq!( assert_eq!(
*coords.y(), *coords.y(),
pallas::Base::from_bytes(&Q_COMMIT_IVK_M_GENERATOR.1).unwrap() pallas::Base::from_repr(Q_COMMIT_IVK_M_GENERATOR.1).unwrap()
); );
} }
@ -125,18 +125,18 @@ mod tests {
assert_eq!( assert_eq!(
*coords.x(), *coords.x(),
pallas::Base::from_bytes(&Q_MERKLE_CRH.0).unwrap() pallas::Base::from_repr(Q_MERKLE_CRH.0).unwrap()
); );
assert_eq!( assert_eq!(
*coords.y(), *coords.y(),
pallas::Base::from_bytes(&Q_MERKLE_CRH.1).unwrap() 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(1u64 << K); let two_pow_k = pallas::Base::from(1u64 << K);
let inv_two_pow_k = pallas::Base::from_bytes(&INV_TWO_POW_K).unwrap(); 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());
} }

View File

@ -70,11 +70,11 @@ impl ConditionallySelectable for NonZeroPallasBase {
impl NonZeroPallasBase { impl NonZeroPallasBase {
pub(crate) fn from_bytes(bytes: &[u8; 32]) -> CtOption<Self> { pub(crate) fn from_bytes(bytes: &[u8; 32]) -> CtOption<Self> {
pallas::Base::from_bytes(bytes).and_then(NonZeroPallasBase::from_base) pallas::Base::from_repr(*bytes).and_then(NonZeroPallasBase::from_base)
} }
pub(crate) fn to_bytes(&self) -> [u8; 32] { pub(crate) fn to_bytes(&self) -> [u8; 32] {
self.0.to_bytes() self.0.to_repr()
} }
pub(crate) fn from_base(b: pallas::Base) -> CtOption<Self> { pub(crate) fn from_base(b: pallas::Base) -> CtOption<Self> {
@ -116,7 +116,7 @@ impl ConditionallySelectable for NonZeroPallasScalar {
impl NonZeroPallasScalar { impl NonZeroPallasScalar {
pub(crate) fn from_bytes(bytes: &[u8; 32]) -> CtOption<Self> { pub(crate) fn from_bytes(bytes: &[u8; 32]) -> CtOption<Self> {
pallas::Scalar::from_bytes(bytes).and_then(NonZeroPallasScalar::from_scalar) pallas::Scalar::from_repr(*bytes).and_then(NonZeroPallasScalar::from_scalar)
} }
pub(crate) fn from_scalar(s: pallas::Scalar) -> CtOption<Self> { pub(crate) fn from_scalar(s: pallas::Scalar) -> CtOption<Self> {

View File

@ -9,7 +9,7 @@ use crate::{
primitives::sinsemilla::{i2lebsp_k, HashDomain}, primitives::sinsemilla::{i2lebsp_k, HashDomain},
}; };
use incrementalmerkletree::{Altitude, Hashable}; use incrementalmerkletree::{Altitude, Hashable};
use pasta_curves::{arithmetic::FieldExt, pallas}; use pasta_curves::pallas;
use ff::{Field, PrimeField, PrimeFieldBits}; use ff::{Field, PrimeField, PrimeFieldBits};
use lazy_static::lazy_static; use lazy_static::lazy_static;
@ -172,7 +172,7 @@ impl MerkleHashOrchard {
/// Convert this digest to its canonical byte representation. /// Convert this digest to its canonical byte representation.
pub fn to_bytes(&self) -> [u8; 32] { pub fn to_bytes(&self) -> [u8; 32] {
self.0.to_bytes() self.0.to_repr()
} }
/// Parses a incremental tree leaf digest from the bytes of /// Parses a incremental tree leaf digest from the bytes of
@ -181,7 +181,7 @@ impl MerkleHashOrchard {
/// Returns the empty `CtOption` if the provided bytes represent /// Returns the empty `CtOption` if the provided bytes represent
/// a non-canonical encoding. /// a non-canonical encoding.
pub fn from_bytes(bytes: &[u8; 32]) -> CtOption<Self> { pub fn from_bytes(bytes: &[u8; 32]) -> CtOption<Self> {
pallas::Base::from_bytes(bytes).map(MerkleHashOrchard) pallas::Base::from_repr(*bytes).map(MerkleHashOrchard)
} }
} }
@ -199,7 +199,7 @@ impl std::cmp::Eq for MerkleHashOrchard {}
impl std::hash::Hash for MerkleHashOrchard { impl std::hash::Hash for MerkleHashOrchard {
fn hash<H: std::hash::Hasher>(&self, state: &mut H) { fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
<Option<pallas::Base>>::from(self.0) <Option<pallas::Base>>::from(self.0)
.map(|b| b.to_bytes()) .map(|b| b.to_repr())
.hash(state) .hash(state)
} }
} }
@ -275,7 +275,9 @@ pub mod testing {
#[cfg(test)] #[cfg(test)]
use crate::tree::{MerkleHashOrchard, EMPTY_ROOTS}; use crate::tree::{MerkleHashOrchard, EMPTY_ROOTS};
#[cfg(test)] #[cfg(test)]
use pasta_curves::{arithmetic::FieldExt, pallas}; use group::ff::PrimeField;
#[cfg(test)]
use pasta_curves::pallas;
#[cfg(test)] #[cfg(test)]
use std::convert::TryInto; use std::convert::TryInto;
@ -296,7 +298,7 @@ pub mod testing {
tree.append(&cmx); tree.append(&cmx);
tree.witness(); tree.witness();
assert_eq!(tree.root().0, pallas::Base::from_bytes(&tv.root).unwrap()); assert_eq!(tree.root().0, pallas::Base::from_repr(tv.root).unwrap());
// Check paths for all leaves up to this point. The test vectors include paths // Check paths for all leaves up to this point. The test vectors include paths
// for not-yet-appended leaves (using UNCOMMITTED_ORCHARD as the leaf value), // for not-yet-appended leaves (using UNCOMMITTED_ORCHARD as the leaf value),
@ -327,7 +329,7 @@ pub mod testing {
assert_eq!( assert_eq!(
MerkleHashOrchard::empty_root(Altitude::from(altitude as u8)) MerkleHashOrchard::empty_root(Altitude::from(altitude as u8))
.0 .0
.to_bytes(), .to_repr(),
*tv_root, *tv_root,
"Empty root mismatch at altitude {}", "Empty root mismatch at altitude {}",
altitude altitude
@ -378,12 +380,9 @@ pub mod testing {
let mut frontier = BridgeFrontier::<MerkleHashOrchard, 32>::empty(); let mut frontier = BridgeFrontier::<MerkleHashOrchard, 32>::empty();
for commitment in commitments.iter() { for commitment in commitments.iter() {
let cmx = MerkleHashOrchard(pallas::Base::from_bytes(commitment).unwrap()); let cmx = MerkleHashOrchard(pallas::Base::from_repr(*commitment).unwrap());
frontier.append(&cmx); frontier.append(&cmx);
} }
assert_eq!( assert_eq!(frontier.root().0, pallas::Base::from_repr(anchor).unwrap());
frontier.root().0,
pallas::Base::from_bytes(&anchor).unwrap()
);
} }
} }