From b08280be9e471261302be086a5814ef82cde8bd3 Mon Sep 17 00:00:00 2001 From: morph <82043364+morph-dev@users.noreply.github.com> Date: Tue, 23 Jul 2024 00:04:47 +0300 Subject: [PATCH] feat: add ipa and multiproof tests --- Cargo.lock | 1 + portal-verkle-primitives/Cargo.toml | 1 + portal-verkle-primitives/src/proof/ipa.rs | 37 +++++ .../src/proof/multiproof.rs | 134 ++++++++++++++++++ 4 files changed, 173 insertions(+) diff --git a/Cargo.lock b/Cargo.lock index 0e68869..fc1f90c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1164,6 +1164,7 @@ dependencies = [ "overload", "rstest", "serde", + "serde_json", "sha2", "ssz_types", "thiserror", diff --git a/portal-verkle-primitives/Cargo.toml b/portal-verkle-primitives/Cargo.toml index 51078d8..f3cf623 100644 --- a/portal-verkle-primitives/Cargo.toml +++ b/portal-verkle-primitives/Cargo.toml @@ -27,3 +27,4 @@ thiserror = "1" [dev-dependencies] anyhow = "1" rstest = "0.21" +serde_json = "1" diff --git a/portal-verkle-primitives/src/proof/ipa.rs b/portal-verkle-primitives/src/proof/ipa.rs index dd3283b..cd328a6 100644 --- a/portal-verkle-primitives/src/proof/ipa.rs +++ b/portal-verkle-primitives/src/proof/ipa.rs @@ -184,3 +184,40 @@ impl IpaProof { result.is_zero() } } + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn const_polynomial() { + let x = ScalarField::from(1234u64); + let y = ScalarField::from(42u64); + let poly = LagrangeBasis::new_const(&y); + let c = poly.commit(); + let mut transcript = Transcript::new("test"); + let proof = IpaProof::open_polynomial(Some(c.clone()), poly, x.clone(), &mut transcript); + + let mut transcript = Transcript::new("test"); + assert!(proof.verify_polynomial(c, x, y, &mut transcript)) + } + + #[test] + fn simple_polynomial() { + // poly = (x+1)(x+10)(x-100) + let eval = |x: &ScalarField| { + (x + ScalarField::from(1u64)) + * (x + ScalarField::from(10u64)) + * (x - ScalarField::from(100u64)) + }; + let x = ScalarField::from(1234u64); + let y = eval(&x); + let poly = LagrangeBasis::new(array::from_fn(|i| eval(&ScalarField::from(i)))); + let c = poly.commit(); + let mut transcript = Transcript::new("test"); + let proof = IpaProof::open_polynomial(Some(c.clone()), poly, x.clone(), &mut transcript); + + let mut transcript = Transcript::new("test"); + assert!(proof.verify_polynomial(c, x, y, &mut transcript)) + } +} diff --git a/portal-verkle-primitives/src/proof/multiproof.rs b/portal-verkle-primitives/src/proof/multiproof.rs index 921ec74..7d6cd7e 100644 --- a/portal-verkle-primitives/src/proof/multiproof.rs +++ b/portal-verkle-primitives/src/proof/multiproof.rs @@ -165,3 +165,137 @@ impl MultiPointProof { self.ipa_proof.verify_polynomial(p_comm, t, p_t, transcript) } } + +#[cfg(test)] +mod tests { + + use std::array; + + use alloy_primitives::{hex::FromHex, B256}; + + use crate::{ + constants::{LEAF_MARKER_INDEX, LEAF_STEM_INDEX}, + Stem, + }; + + use super::*; + + type PolynomialFn = Box ScalarField>; + + #[test] + fn simple_multi_opening() { + // p(x) = 42 + let f_const = |_: usize| ScalarField::from(42u64); + // p(x) = (x + 1)(x + 10)(x - 100) + let f_poly = |x: usize| { + let x = ScalarField::from(x); + (&x + ScalarField::from(1u64)) + * (&x + ScalarField::from(10u64)) + * (&x - ScalarField::from(100u64)) + }; + // p(x) = (x + 2) / (x + 1) (on domain) + let f_non_poly = |x: usize| { + let x = ScalarField::from(x); + (&x + ScalarField::from(2u64)) * (&x + ScalarField::from(1u64)).inverse().unwrap() + }; + + let openings: Vec<(PolynomialFn, usize)> = vec![ + (Box::new(f_const), 13), + (Box::new(f_poly), 42), + (Box::new(f_non_poly), 183), + (Box::new(f_non_poly), 42), // same z + ]; + + let mut transcript = Transcript::new("test"); + let queries = openings + .iter() + .map(|(poly_f, z)| { + let poly = LagrangeBasis::new(array::from_fn(poly_f)); + ProverQuery { + c: poly.commit(), + poly, + z: *z, + } + }) + .collect(); + let proof = MultiPointProof::create(queries, &mut transcript); + + let mut transcript = Transcript::new("test"); + let queries = openings + .iter() + .map(|(poly_f, z)| VerifierQuery { + c: LagrangeBasis::new(array::from_fn(poly_f)).commit(), + z: *z, + y: poly_f(*z), + }) + .collect::>(); + assert!(proof.verify(&queries, &mut transcript)); + } + + /// Proof from the kaustinen devnet-6, block 1 + #[test] + fn devnet_6_block_1() -> anyhow::Result<()> { + let ipa_proof = r#"{ + "cl": [ + "0x6e3104792843f10a7236b6648f0d32d9ede087d55a3c8705038ed5358e073904", + "0x5eceadbf8532a2c626366356e9dd870a9e83bc0393ea088a32a8dc7452291cc3", + "0x13bf721c1aa1cdf84ea69161114bbe0eda90f51173ac00dabdfc4e6aeed301a4", + "0x21a7dfe85100ed2e0c6b1f07ff07ad9660711d25ff7ffdd7a7a02b3363089df9", + "0x0abe44837167a603c0ab167071c7d01fab67d0b81b0f8c2c195445f6a0063301", + "0x3f4e616c904c91bc4211dfb14f33528f498fe76c1acc85491ef253afd4ce2cbb", + "0x08631ce02176c4dcf83dbd04c68adf17d70090f2a2d367085b35a733baadf991", + "0x44b4f57ed5ea4fdb1cd97901aab184b9a3d743bc3732e3e9c3b1e29370eb24d8" + ], + "cr": [ + "0x6206979e2aa815bff1c76c521d025229e5867ba2d67422bd54d993a471aebbf8", + "0x11bbacadfad4a06e85a7509ac601693646d1dc6416fb06c14f0745276579d548", + "0x6b34ee89647bf02642546d0c2438fc34f350dae628ba033efbce2d9efe5c714b", + "0x2eaf5b365d0071a04b0bf880df7cc4fefb88bb7e42693fedff0b94f4a4faab18", + "0x3506e34c2e7686856cd0f4485f51f965aa926f235ee2b4c632b2239ffd0c9ff1", + "0x18fbb94e59a02d289cf2d886f365cce91b89416d43e0a44d548cc6fd790b8d06", + "0x31e28a78851612861fede858f62f7bbbfa12d02a302fea0272e03e668f0cb5a9", + "0x48585ea2484b2b902f38297e14491311d8c74002f3eaeca9ac43bf03cfc090b5" + ], + "final_evaluation": "0x08a3079093df751fc850f3805e10cc898314688111df75aa20511c32198a93e3" + }"#; + let proof = MultiPointProof { + ipa_proof: serde_json::from_str::(ipa_proof)?, + g_commitment: Point::from(&B256::from_hex( + "0x5af46ab3e8676b9d4de8ae0be9670c45e9afd43cc11524c7946728268652028a", + )?), + }; + + let root = Point::from(&B256::from_hex( + "0x1fbf85345a3cbba9a6d44f991b721e55620a22397c2a93ee8d5011136ac300ee", + )?); + let other_leaf = Point::from(&B256::from_hex( + "0x26715ff22c071fdd9d9c2c6b5f5bf9bb0d83a2087e1366deabcecdf2a1d3f82e", + )?); + let other_stem = + Stem::from_hex("0x5bdf12f5e17d2911dac2d2b0fc9e64a3ddc1d1ea4fc2568fe7e741ff2daa18")?; + + let queries = vec![ + VerifierQuery { + c: root, + z: 0x5b, + y: other_leaf.map_to_scalar_field(), + }, + VerifierQuery { + c: other_leaf.clone(), + z: LEAF_MARKER_INDEX, + y: ScalarField::one(), + }, + VerifierQuery { + c: other_leaf, + z: LEAF_STEM_INDEX, + y: ScalarField::from(&other_stem), + }, + ]; + let mut transcript = Transcript::new("vt"); + assert!( + proof.verify(&queries, &mut transcript), + "Multiproof should verify" + ); + Ok(()) + } +}