Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: implement extractable witness encryption #3

Merged
merged 4 commits into from
Sep 4, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 14 additions & 14 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
[package]
name = "we-kzg"
name = "keaki"
version = "0.1.0"
edition = "2021"

Expand Down
11 changes: 5 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# WE-KZG (wip)
# ケヤキ 🌳

[![License][mit-badge]][mit-url]
[![Build][actions-badge]][actions-url]
Expand All @@ -11,13 +11,12 @@
[codecov-badge]: https://codecov.io/github/brech1/we-kzg/graph/badge.svg
[codecov-url]: https://app.codecov.io/github/brech1/we-kzg/

This crate is a Rust implementation of an **Extractable Witness Encryption for KZG Commitments** scheme.
**Keaki** is a Rust implementation of an Extractable Witness Encryption for KZG Commitments scheme.

Based on the following paper:

- [Extractable Witness Encryption for KZG Commitments
and Efficient Laconic OT](https://eprint.iacr.org/2024/264.pdf).
- [Extractable Witness Encryption for KZG Commitments and Efficient Laconic OT](https://eprint.iacr.org/2024/264.pdf)

A great set of notes on this paper is available here:
A great post on it can be found here:

- [Notes on Extractable Witness Encryption for KZG Commitments and Efficient Laconic OT](https://hackmd.io/@letargicus/Hk3rpPnK0)
- [Notes on Extractable Witness Encryption for KZG Commitments and Efficient Laconic OT](https://www.leku.blog/kzg-we/)
33 changes: 21 additions & 12 deletions src/kem.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
//! KEM Module
//! # Key Encapsulation Module
//!
//! This module contains the implementation of an Extractable Witness Key Encapsulation Mechanism (KEM).
//! This module contains the implementation of an Extractable Witness Key Encapsulation Mechanism.

use crate::kzg::KZG;
use ark_ec::pairing::Pairing;
Expand All @@ -11,34 +11,36 @@ use rand::thread_rng;
use std::ops::Mul;
use thiserror::Error;

/// Key Encapsulation Mechanism struct.
/// Extractable Witness Key Encapsulation Mechanism struct.
pub struct KEM<E: Pairing> {
kzg: KZG<E>,
}

impl<E: Pairing> KEM<E> {
/// Creates a new KEM instance.
/// Creates a new instance.
pub fn new(kzg: KZG<E>) -> Self {
Self { kzg }
}

/// Encapsulation method.
/// Returns the ciphertext and the key.
/// Generates a key for a commitment and a point-value pair.
pub fn encapsulate(
&self,
commitment: E::G1,
point: E::ScalarField,
value: E::ScalarField,
) -> Result<(E::G2, OutputReader), KEMError> {
let mut rng = thread_rng();
let r = E::ScalarField::rand(&mut rng);

// [beta]_1
let value_in_g1: E::G1 = self.kzg.g1_gen().mul(value);

// (com - [beta]_1)
let com_beta = commitment - value_in_g1;

// Generate a random value
// This allows the generated secret not to be tied to the inputs.
let mut rng = thread_rng();
let r = E::ScalarField::rand(&mut rng);

// Calculate secret
// s = e(r * (com - [beta]_1), g2)
let secret = E::pairing(com_beta.mul(r), self.kzg.g2_gen());
Expand All @@ -47,12 +49,13 @@ impl<E: Pairing> KEM<E> {
.serialize_uncompressed(&mut secret_bytes)
.map_err(KEMError::SerializationError)?;

// Calculate ciphertext
// Calculate a ciphertext to share the randomness used in the encapsulation.
// ct = r([tau]_2 - [alpha]_2)
let tau_alpha: E::G2 = self.kzg.tau_g2() - self.kzg.g2_gen().mul(point);
let ciphertext: E::G2 = tau_alpha.mul(r);

// Get the key
// Generate the key
// Hash the secret to make the key indistinguishable from random.
// k = H(s)
let mut key_hasher = blake3::Hasher::new();
key_hasher.update(&secret_bytes);
Expand All @@ -63,7 +66,8 @@ impl<E: Pairing> KEM<E> {
}

/// Decapsulation method.
/// Returns the key.
/// Generates a key for an opening and a ciphertext.
/// The generated key will be the same as the one generated during encapsulation for a valid opening.
pub fn decapsulate(&self, proof: E::G1, ciphertext: E::G2) -> Result<OutputReader, KEMError> {
// Calculate secret
// s = e(proof, ct)
Expand Down Expand Up @@ -121,6 +125,11 @@ impl<E: Pairing> KEM<E> {
.map(|(&proof, &ciphertext)| self.decapsulate(proof, ciphertext))
.collect()
}

/// Returns KZG scheme
pub fn kzg(&self) -> &KZG<E> {
&self.kzg
}
}

#[derive(Error, Debug)]
Expand All @@ -136,7 +145,7 @@ pub enum KEMError {
#[cfg(test)]
mod tests {
use super::*;
use crate::operations::evaluate_polynomial;
use crate::pol_op::evaluate_polynomial;
use ark_bls12_381::{Bls12_381, Fr, G1Projective, G2Projective};
use ark_std::test_rng;
use ark_std::UniformRand;
Expand Down
4 changes: 2 additions & 2 deletions src/kzg.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
//! KZG Module
//! # KZG Module
//!
//! This module contains the implementation of the KZG polynomial commitment scheme.

use crate::operations::*;
use crate::pol_op::*;
use ark_ec::pairing::Pairing;
use ark_ff::{Field, Zero};
use std::ops::Mul;
Expand Down
7 changes: 5 additions & 2 deletions src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
//! WE-KZG
//! # Keaki
//!
//! Implementation of an Extractable Witness Encryption for KZG Commitments scheme.

pub mod kem;
pub mod kzg;
pub mod operations;
pub mod pol_op;
pub mod we;
16 changes: 7 additions & 9 deletions src/operations.rs → src/pol_op.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
//! Operations Module
//! # Polynomial Operations Module
//!
//! This module contains polynomial operations.
//! This module contains functions to perform operations on polynomials.

use ark_ec::pairing::Pairing;
use ark_ff::{Field, One, Zero};
Expand All @@ -12,26 +12,24 @@
p: &[E::ScalarField],
q: &[E::ScalarField],
) -> Vec<E::ScalarField> {
let max_len = p.len().max(q.len());
let mut result = Vec::with_capacity(max_len);

let min_len = p.len().min(q.len());
let mut res = Vec::with_capacity(p.len().max(q.len()));

// Subtract the overlapping parts
for i in 0..min_len {
result.push(p[i] - q[i]);
res.push(p[i] - q[i]);
}

// Handle remaining terms in the longer polynomial
if p.len() > min_len {
result.extend_from_slice(&p[min_len..]);
res.extend_from_slice(&p[min_len..]);
} else {
for &coeff in &q[min_len..] {
result.push(-coeff);
res.push(-coeff);

Check warning on line 28 in src/pol_op.rs

View check run for this annotation

Codecov / codecov/patch

src/pol_op.rs#L28

Added line #L28 was not covered by tests
}
}

result
res
}

/// Multiplies two polynomials.
Expand Down
Loading
Loading