Skip to content

Commit

Permalink
feat!: improve hyperkzg api (#353)
Browse files Browse the repository at this point in the history
* 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
  • Loading branch information
JayWhite2357 authored Jan 23, 2025
1 parent 435665b commit 2a513f5
Show file tree
Hide file tree
Showing 3 changed files with 63 additions and 19 deletions.
63 changes: 53 additions & 10 deletions src/provider/hyperkzg.rs
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,20 @@ where
comm: <E as Engine>::GE,
}

impl<E: Engine> Commitment<E>
where
E::GE: PairingGroup,
{
/// Creates a new commitment from the underlying group element
pub fn new(comm: <E as Engine>::GE) -> Self {
Commitment { comm }
}
/// Returns the commitment as a group element
pub fn into_inner(self) -> <E as Engine>::GE {
self.comm
}
}

impl<E: Engine> CommitmentTrait<E> for Commitment<E>
where
E::GE: PairingGroup,
Expand Down Expand Up @@ -178,18 +192,14 @@ pub struct CommitmentEngine<E: Engine> {
_p: PhantomData<E>,
}

impl<E: Engine> CommitmentEngineTrait<E> for CommitmentEngine<E>
impl<E: Engine> CommitmentKey<E>
where
E::GE: PairingGroup,
{
type Commitment = Commitment<E>;
type CommitmentKey = CommitmentKey<E>;
type DerandKey = DerandKey<E>;

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
Expand All @@ -208,7 +218,22 @@ where

let tau_H = (<<E::GE as PairingGroup>::G2 as DlogGroup>::gen() * tau).affine();

Self::CommitmentKey { ck, h, tau_H }
Self { ck, h, tau_H }
}
}

impl<E: Engine> CommitmentEngineTrait<E> for CommitmentEngine<E>
where
E::GE: PairingGroup,
{
type Commitment = Commitment<E>;
type CommitmentKey = CommitmentKey<E>;
type DerandKey = DerandKey<E>;

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 {
Expand Down Expand Up @@ -270,6 +295,24 @@ where
v: Vec<Vec<E::Scalar>>,
}

impl<E: Engine> EvaluationArgument<E>
where
E::GE: PairingGroup,
{
/// The KZG commitments to intermediate polynomials
pub fn com(&self) -> &[G1Affine<E>] {
&self.com
}
/// The KZG witnesses for batch openings
pub fn w(&self) -> &[G1Affine<E>] {
&self.w
}
/// The evaluations of the polynomials at challenge points
pub fn v(&self) -> &[Vec<E::Scalar>] {
&self.v
}
}

/// Provides an implementation of a polynomial evaluation engine using KZG
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct EvaluationEngine<E: Engine> {
Expand Down
12 changes: 6 additions & 6 deletions src/provider/keccak.rs
Original file line number Diff line number Diff line change
Expand Up @@ -137,18 +137,18 @@ mod tests {
#[test]
fn test_keccak_transcript() {
test_keccak_transcript_with::<PallasEngine>(
"5ddffa8dc091862132788b8976af88b9a2c70594727e611c7217ba4c30c8c70a",
"4d4bf42c065870395749fa1c4fb641df1e0d53f05309b03d5b1db7f0be3aa13d",
"b67339da79ce5f6dc72ad23c8c3b4179f49655cadf92d47e79c3e7788f00f125",
"b7f033d47b3519dd6efe320b995eaad1dc11712cb9b655d2e7006ed5f86bd321",
);

test_keccak_transcript_with::<Bn256EngineKZG>(
"9fb71e3b74bfd0b60d97349849b895595779a240b92a6fae86bd2812692b6b0e",
"bfd4c50b7d6317e9267d5d65c985eb455a3561129c0b3beef79bfc8461a84f18",
"b387ba3a8b9a22b3b7544a3dbbd26a048a1d354d8dc582c64d1513335e66a205",
"73ad65097d947fe45de5241bb340bbd97b198b52cc559a9657f73c361bf8700b",
);

test_keccak_transcript_with::<Secp256k1Engine>(
"9723aafb69ec8f0e9c7de756df0993247d98cf2b2f72fa353e3de654a177e310",
"a6a90fcb6e1b1a2a2f84c950ef1510d369aea8e42085f5c629bfa66d00255f25",
"f15ddd8fa1675a9e273e0ef441711005d77a5fd485f4e6cdee59760ca01493fa",
"3c019f0e557abaecc99790382974cb27132bfe038af9c4d43a33ec9c426e19f5",
);
}

Expand Down
7 changes: 4 additions & 3 deletions src/provider/traits.rs
Original file line number Diff line number Diff line change
Expand Up @@ -197,15 +197,16 @@ macro_rules! impl_traits {

impl<G: Group> TranscriptReprTrait<G> for $name::Scalar {
fn to_transcript_bytes(&self) -> Vec<u8> {
self.to_bytes().to_vec()
self.to_bytes().into_iter().rev().collect()
}
}

impl<G: DlogGroup> TranscriptReprTrait<G> for $name::Affine {
fn to_transcript_bytes(&self) -> Vec<u8> {
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()
}
}
};
Expand Down

0 comments on commit 2a513f5

Please sign in to comment.