From c4b07f0925bf0367c40a521e012e7d35ca05f3bd Mon Sep 17 00:00:00 2001 From: Srinath Setty Date: Fri, 10 Feb 2023 12:36:51 -0800 Subject: [PATCH] allow the provider to provide byte representation of a scalar (#140) --- src/provider/pasta.rs | 15 +++++++++++++-- src/traits/mod.rs | 31 ++++++++++++------------------- 2 files changed, 25 insertions(+), 21 deletions(-) diff --git a/src/provider/pasta.rs b/src/provider/pasta.rs index 71ab3a4..9009b99 100644 --- a/src/provider/pasta.rs +++ b/src/provider/pasta.rs @@ -1,13 +1,15 @@ //! This module implements the Nova traits for pallas::Point, pallas::Scalar, vesta::Point, vesta::Scalar. use crate::{ + errors::NovaError, provider::{ keccak::Keccak256Transcript, pedersen::CommitmentEngine, poseidon::{PoseidonRO, PoseidonROCircuit}, }, - traits::{CompressedGroup, Group, PrimeFieldExt}, + traits::{ChallengeTrait, CompressedGroup, Group, PrimeFieldExt, TranscriptEngineTrait}, }; use digest::{ExtendableOutput, Input}; +use ff::PrimeField; use num_bigint::BigInt; use num_traits::Num; use pasta_curves::{ @@ -175,6 +177,10 @@ macro_rules! impl_traits { let bytes_arr: [u8; 64] = bytes.try_into().unwrap(); $name::Scalar::from_bytes_wide(&bytes_arr) } + + fn to_bytes(s: &Self) -> Vec { + s.to_repr().as_ref().to_vec() + } } impl CompressedGroup for $name_compressed { @@ -191,6 +197,12 @@ macro_rules! impl_traits { }; } +impl, F: PrimeField> ChallengeTrait for F { + fn challenge(label: &'static [u8], transcript: &mut G::TE) -> Result { + transcript.squeeze_scalar(label) + } +} + impl_traits!( pallas, PallasCompressedElementWrapper, @@ -210,7 +222,6 @@ impl_traits!( /// Native implementation of fast multiexp for platforms that do not support pasta_msm/semolina /// Adapted from zcash/halo2 fn cpu_multiexp_serial(coeffs: &[C::Scalar], bases: &[C], acc: &mut C::Curve) { - use ff::PrimeField; let coeffs: Vec<_> = coeffs.iter().map(|a| a.to_repr()).collect(); let c = if bases.len() < 4 { diff --git a/src/traits/mod.rs b/src/traits/mod.rs index 9ba9136..d8f5caf 100644 --- a/src/traits/mod.rs +++ b/src/traits/mod.rs @@ -224,35 +224,28 @@ pub trait ChallengeTrait { /// Defines additional methods on PrimeField objects pub trait PrimeFieldExt: PrimeField { - /// Returns a Scalar representing the bytes + /// Returns a scalar representing the bytes fn from_uniform(bytes: &[u8]) -> Self; - /// Returns a byte representation - fn to_bytes(v: &[Self]) -> Vec { - (0..v.len()) - .map(|i| v[i].to_repr().as_ref().to_vec()) - .collect::>>() - .into_iter() - .flatten() - .collect::>() - } -} - -impl, F: PrimeField> ChallengeTrait for F { - fn challenge(label: &'static [u8], transcript: &mut G::TE) -> Result { - transcript.squeeze_scalar(label) - } + /// Returns a vector of bytes representing the scalar + fn to_bytes(s: &Self) -> Vec; } -impl, F: PrimeField> AppendToTranscriptTrait for F { +impl, F: PrimeField + PrimeFieldExt> AppendToTranscriptTrait for F { fn append_to_transcript(&self, label: &'static [u8], transcript: &mut G::TE) { - transcript.absorb_bytes(label, self.to_repr().as_ref()); + transcript.absorb_bytes(label, &::to_bytes(self)); } } impl, F: PrimeField + PrimeFieldExt> AppendToTranscriptTrait for [F] { fn append_to_transcript(&self, label: &'static [u8], transcript: &mut G::TE) { - transcript.absorb_bytes(label, &::to_bytes(self)); + let bytes = (0..self.len()) + .map(|i| ::to_bytes(&self[i])) + .collect::>() + .into_iter() + .flatten() + .collect::>(); + transcript.absorb_bytes(label, &bytes); } }