diff --git a/ring/Cargo.toml b/ring/Cargo.toml index 6269f59..7869a0c 100644 --- a/ring/Cargo.toml +++ b/ring/Cargo.toml @@ -18,6 +18,7 @@ merlin.workspace = true rayon = { workspace = true, optional = true } common = { path = "../common", default-features = false } blake2 = { version = "0.10", default-features = false } +arrayvec = { version = "0.7", default-features = false } [dev-dependencies] ark-bls12-381 = { version = "0.4", default-features = false, features = ["curve"] } diff --git a/ring/src/piop/mod.rs b/ring/src/piop/mod.rs index c5a0daf..2916579 100644 --- a/ring/src/piop/mod.rs +++ b/ring/src/piop/mod.rs @@ -22,11 +22,71 @@ mod prover; mod verifier; pub mod params; +// Workaround while waiting for https://github.com/arkworks-rs/algebra/pull/837 +// to be on [crates.io](https://crates.io/crates/ark-serialize) (allegedly ark-serialize 0.4.3 ) +mod ark_serialize_837 { + use ark_serialize::{CanonicalDeserialize, CanonicalSerialize, Compress, Validate, Valid, SerializationError, Read}; + + #[derive(Clone, CanonicalSerialize)] + #[repr(transparent)] + pub struct ArrayWrap(pub [T; N]); + + impl Valid for ArrayWrap + { + fn check(&self) -> Result<(), SerializationError> { + self.0.check() + } + } + + impl CanonicalDeserialize for ArrayWrap { + fn deserialize_with_mode( + mut reader: R, + compress: Compress, + validate: Validate, + ) -> Result { + let mut array = arrayvec::ArrayVec::::new(); + for _ in 0..N { + array.push(T::deserialize_with_mode(&mut reader, compress, Validate::No)?); + } + if let ark_serialize::Validate::Yes = validate { + T::batch_check(array.iter())? + } + Ok(ArrayWrap(array.into_inner().ok().unwrap())) + } + } + + impl core::ops::Deref for ArrayWrap { + type Target = [T; N]; + + fn deref(&self) -> &Self::Target { + &self.0 + } + } + + // This is expected to panic until https://github.com/arkworks-rs/algebra/pull/837 + // doesn't land on crates.io + #[test] + #[should_panic] + fn panics_without_ark_serialize_827() { + let buf = [0u8; 96]; + let res = <[ark_bls12_381::G1Affine; 2]>::deserialize_compressed(&buf[..]); + assert!(res.is_err()); + } + + #[test] + fn workaround_waiting_for_ark_serialize_837() { + let buf = [0u8; 96]; + let res = >::deserialize_compressed(&buf[..]); + assert!(res.is_err()); + } +} +use ark_serialize_837::*; + #[derive(Clone, CanonicalSerialize, CanonicalDeserialize)] pub struct RingCommitments> { pub(crate) bits: C, pub(crate) inn_prod_acc: C, - pub(crate) cond_add_acc: [C; 2], + pub(crate) cond_add_acc: ArrayWrap, pub(crate) phantom: PhantomData, } @@ -43,11 +103,11 @@ impl> ColumnsCommited for RingCommitments< #[derive(Clone, CanonicalSerialize, CanonicalDeserialize)] pub struct RingEvaluations { - pub(crate) points: [F; 2], + pub(crate) points: ArrayWrap, pub(crate) ring_selector: F, pub(crate) bits: F, pub(crate) inn_prod_acc: F, - pub(crate) cond_add_acc: [F; 2], + pub(crate) cond_add_acc: ArrayWrap, } impl ColumnsEvaluated for RingEvaluations { diff --git a/ring/src/piop/prover.rs b/ring/src/piop/prover.rs index 2f94616..e590d09 100644 --- a/ring/src/piop/prover.rs +++ b/ring/src/piop/prover.rs @@ -92,10 +92,10 @@ impl ProverPiop for PiopProver fn committed_columns) -> C>(&self, commit: Fun) -> Self::Commitments { let bits = commit(self.bits.as_poly()); - let cond_add_acc = [ + let cond_add_acc = super::ArrayWrap([ commit(self.cond_add.acc.xs.as_poly()), commit(self.cond_add.acc.ys.as_poly()) - ]; + ]); let inn_prod_acc = commit(self.inner_prod.acc.as_poly()); Self::Commitments { bits, @@ -120,17 +120,17 @@ impl ProverPiop for PiopProver } fn columns_evaluated(&self, zeta: &F) -> Self::Evaluations { - let points = [ + let points = super::ArrayWrap([ self.points.xs.evaluate(zeta), self.points.ys.evaluate(zeta), - ]; + ]); let ring_selector = self.ring_selector.evaluate(zeta); let bits = self.bits.evaluate(zeta); let inn_prod_acc = self.inner_prod.acc.evaluate(zeta); - let cond_add_acc = [ + let cond_add_acc = super::ArrayWrap([ self.cond_add.acc.xs.evaluate(zeta), self.cond_add.acc.ys.evaluate(zeta), - ]; + ]); Self::Evaluations { points, ring_selector,