From 2a513f509b97e616983525b3d3b607f080176636 Mon Sep 17 00:00:00 2001 From: Jay White Date: Thu, 23 Jan 2025 18:31:42 -0500 Subject: [PATCH] feat!: improve hyperkzg api (#353) * feat!: make field elements serialize into transcript in big-endian form This makes the transcript more compatible with the EVM, which is big-endian * feat: expose hyperkzg underlying group This is accomplished via `new` and `into_inner` methods * feat: expose hyperkzg argument underlying elements This is accomplished via `com`, `w`, and `v` accessors. * feat: add `setup_from_rng` for hyperkzg::CommitmentKey This can be used instead of `CommitmentEngineTrait::setup` to generate a reproducible commitment key --- src/provider/hyperkzg.rs | 63 +++++++++++++++++++++++++++++++++------- src/provider/keccak.rs | 12 ++++---- src/provider/traits.rs | 7 +++-- 3 files changed, 63 insertions(+), 19 deletions(-) diff --git a/src/provider/hyperkzg.rs b/src/provider/hyperkzg.rs index 4ee1f956..99bb7a3e 100644 --- a/src/provider/hyperkzg.rs +++ b/src/provider/hyperkzg.rs @@ -71,6 +71,20 @@ where comm: ::GE, } +impl Commitment +where + E::GE: PairingGroup, +{ + /// Creates a new commitment from the underlying group element + pub fn new(comm: ::GE) -> Self { + Commitment { comm } + } + /// Returns the commitment as a group element + pub fn into_inner(self) -> ::GE { + self.comm + } +} + impl CommitmentTrait for Commitment where E::GE: PairingGroup, @@ -178,18 +192,14 @@ pub struct CommitmentEngine { _p: PhantomData, } -impl CommitmentEngineTrait for CommitmentEngine +impl CommitmentKey where E::GE: PairingGroup, { - type Commitment = Commitment; - type CommitmentKey = CommitmentKey; - type DerandKey = DerandKey; - - fn setup(label: &'static [u8], n: usize) -> Self::CommitmentKey { - // NOTE: this is for testing purposes and should not be used in production - // TODO: we need to decide how to generate load/store parameters - let tau = E::Scalar::random(OsRng); + /// NOTE: this is for testing purposes and should not be used in production + /// This can be used instead of `setup` to generate a reproducible commitment key + pub fn setup_from_rng(label: &'static [u8], n: usize, rng: impl rand_core::RngCore) -> Self { + let tau = E::Scalar::random(rng); let num_gens = n.next_power_of_two(); // Compute powers of tau in E::Scalar, then scalar muls in parallel @@ -208,7 +218,22 @@ where let tau_H = (<::G2 as DlogGroup>::gen() * tau).affine(); - Self::CommitmentKey { ck, h, tau_H } + Self { ck, h, tau_H } + } +} + +impl CommitmentEngineTrait for CommitmentEngine +where + E::GE: PairingGroup, +{ + type Commitment = Commitment; + type CommitmentKey = CommitmentKey; + type DerandKey = DerandKey; + + fn setup(label: &'static [u8], n: usize) -> Self::CommitmentKey { + // NOTE: this is for testing purposes and should not be used in production + // TODO: we need to decide how to generate load/store parameters + Self::CommitmentKey::setup_from_rng(label, n, OsRng) } fn derand_key(ck: &Self::CommitmentKey) -> Self::DerandKey { @@ -270,6 +295,24 @@ where v: Vec>, } +impl EvaluationArgument +where + E::GE: PairingGroup, +{ + /// The KZG commitments to intermediate polynomials + pub fn com(&self) -> &[G1Affine] { + &self.com + } + /// The KZG witnesses for batch openings + pub fn w(&self) -> &[G1Affine] { + &self.w + } + /// The evaluations of the polynomials at challenge points + pub fn v(&self) -> &[Vec] { + &self.v + } +} + /// Provides an implementation of a polynomial evaluation engine using KZG #[derive(Clone, Debug, Serialize, Deserialize)] pub struct EvaluationEngine { diff --git a/src/provider/keccak.rs b/src/provider/keccak.rs index 82bf37d6..48cf50fb 100644 --- a/src/provider/keccak.rs +++ b/src/provider/keccak.rs @@ -137,18 +137,18 @@ mod tests { #[test] fn test_keccak_transcript() { test_keccak_transcript_with::( - "5ddffa8dc091862132788b8976af88b9a2c70594727e611c7217ba4c30c8c70a", - "4d4bf42c065870395749fa1c4fb641df1e0d53f05309b03d5b1db7f0be3aa13d", + "b67339da79ce5f6dc72ad23c8c3b4179f49655cadf92d47e79c3e7788f00f125", + "b7f033d47b3519dd6efe320b995eaad1dc11712cb9b655d2e7006ed5f86bd321", ); test_keccak_transcript_with::( - "9fb71e3b74bfd0b60d97349849b895595779a240b92a6fae86bd2812692b6b0e", - "bfd4c50b7d6317e9267d5d65c985eb455a3561129c0b3beef79bfc8461a84f18", + "b387ba3a8b9a22b3b7544a3dbbd26a048a1d354d8dc582c64d1513335e66a205", + "73ad65097d947fe45de5241bb340bbd97b198b52cc559a9657f73c361bf8700b", ); test_keccak_transcript_with::( - "9723aafb69ec8f0e9c7de756df0993247d98cf2b2f72fa353e3de654a177e310", - "a6a90fcb6e1b1a2a2f84c950ef1510d369aea8e42085f5c629bfa66d00255f25", + "f15ddd8fa1675a9e273e0ef441711005d77a5fd485f4e6cdee59760ca01493fa", + "3c019f0e557abaecc99790382974cb27132bfe038af9c4d43a33ec9c426e19f5", ); } diff --git a/src/provider/traits.rs b/src/provider/traits.rs index a790fd45..36f41546 100644 --- a/src/provider/traits.rs +++ b/src/provider/traits.rs @@ -197,15 +197,16 @@ macro_rules! impl_traits { impl TranscriptReprTrait for $name::Scalar { fn to_transcript_bytes(&self) -> Vec { - self.to_bytes().to_vec() + self.to_bytes().into_iter().rev().collect() } } impl TranscriptReprTrait for $name::Affine { fn to_transcript_bytes(&self) -> Vec { let coords = self.coordinates().unwrap(); - - [coords.x().to_bytes(), coords.y().to_bytes()].concat() + let x_bytes = coords.x().to_bytes().into_iter(); + let y_bytes = coords.y().to_bytes().into_iter(); + x_bytes.rev().chain(y_bytes.rev()).collect() } } };