diff --git a/zebra-chain/src/amount.rs b/zebra-chain/src/amount.rs index 60a8c5c5f..8cea75757 100644 --- a/zebra-chain/src/amount.rs +++ b/zebra-chain/src/amount.rs @@ -166,6 +166,17 @@ impl From> for jubjub::Fr { } } +impl From> for halo2::pasta::pallas::Scalar { + fn from(a: Amount) -> halo2::pasta::pallas::Scalar { + // TODO: this isn't constant time -- does that matter? + if a.0 < 0 { + halo2::pasta::pallas::Scalar::from(a.0.abs() as u64).neg() + } else { + halo2::pasta::pallas::Scalar::from(a.0 as u64) + } + } +} + impl TryFrom for Amount where C: Constraint, diff --git a/zebra-chain/src/orchard/commitment.rs b/zebra-chain/src/orchard/commitment.rs index 275d25026..fc3740892 100644 --- a/zebra-chain/src/orchard/commitment.rs +++ b/zebra-chain/src/orchard/commitment.rs @@ -78,7 +78,7 @@ impl TryFrom<[u8; 32]> for NoteCommitment { type Error = &'static str; fn try_from(bytes: [u8; 32]) -> Result { - let possible_point = pallas::Affine::from_bytes(bytes); + let possible_point = pallas::Affine::from_bytes(&bytes); if possible_point.is_some().into() { Ok(Self(possible_point.unwrap())) @@ -135,9 +135,20 @@ impl NoteCommitment { Some(( rcm, - NoteCommitment::from(sinsemilla_commit(rcm.0, "z.cash:Orchard-NoteCommit", &s)), + NoteCommitment::from(sinsemilla_commit(rcm.0, b"z.cash:Orchard-NoteCommit", &s)), )) } + + /// Hash Extractor for Pallas + /// + /// https://zips.z.cash/protocol/protocol.pdf#concreteextractorpallas + pub fn extract_x(&self) -> pallas::Base { + match self.0.get_xy().into { + // If Some, it's not the identity. + Some((x, _)) => x, + _ => pallas::Base::zero(), + } + } } /// A homomorphic Pedersen commitment to the net value of a note, used in Action @@ -159,8 +170,7 @@ impl std::ops::Add for ValueCommitment { type Output = Self; fn add(self, rhs: ValueCommitment) -> Self::Output { - let value = self.0.to_extended() + rhs.0.to_extended(); - ValueCommitment(value.into()) + ValueCommitment((self.0 + rhs.0).into()) } } @@ -212,7 +222,7 @@ impl std::ops::Sub for ValueCommitment { type Output = Self; fn sub(self, rhs: ValueCommitment) -> Self::Output { - ValueCommitment((self.0.to_extended() - rhs.0.to_extended()).into()) + ValueCommitment((self.0 - rhs.0).into()) } } @@ -284,7 +294,7 @@ impl ValueCommitment { /// https://zips.z.cash/protocol/protocol.pdf#concretehomomorphiccommit #[allow(non_snake_case)] pub fn new(rcv: pallas::Scalar, value: Amount) -> Self { - let v = pallas::Scalar::from_bytes(value.to_bytes()); + let v = pallas::Scalar::from(value); // TODO: These generator points can be generated once somewhere else to // avoid having to recompute them on every new commitment. @@ -448,7 +458,7 @@ mod tests { let sum: ValueCommitment = vec![g, other_g].into_iter().sum(); - let doubled_g = ValueCommitment(g_point.to_extended().double().into()); + let doubled_g = ValueCommitment(g_point.into().double().into()); assert_eq!(sum, doubled_g); } diff --git a/zebra-chain/src/primitives/redpallas.rs b/zebra-chain/src/primitives/redpallas.rs index f364adbd0..ef3754e01 100644 --- a/zebra-chain/src/primitives/redpallas.rs +++ b/zebra-chain/src/primitives/redpallas.rs @@ -5,7 +5,7 @@ use halo2::pasta::pallas; // pub mod batch; mod constants; -// mod error; +mod error; // pub mod frost; // mod hash; // mod scalar_mul; @@ -13,6 +13,7 @@ mod constants; mod signing_key; mod verification_key; +pub use error::Error; pub use signing_key::SigningKey; pub use verification_key::{VerificationKey, VerificationKeyBytes};