mirror of
https://github.com/caulk-crypto/caulk.git
synced 2026-01-09 13:27:56 -05:00
opt ready
This commit is contained in:
101
.vscode/launch.json
vendored
Normal file
101
.vscode/launch.json
vendored
Normal file
@@ -0,0 +1,101 @@
|
||||
{
|
||||
// Use IntelliSense to learn about possible attributes.
|
||||
// Hover to view descriptions of existing attributes.
|
||||
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
|
||||
"version": "0.2.0",
|
||||
"configurations": [
|
||||
{
|
||||
"type": "lldb",
|
||||
"request": "launch",
|
||||
"name": "Debug unit tests in library 'caulk'",
|
||||
"cargo": {
|
||||
"args": [
|
||||
"test",
|
||||
"--no-run",
|
||||
"--lib",
|
||||
"--package=caulk"
|
||||
],
|
||||
"filter": {
|
||||
"name": "caulk",
|
||||
"kind": "lib"
|
||||
}
|
||||
},
|
||||
"args": [],
|
||||
"cwd": "${workspaceFolder}"
|
||||
},
|
||||
{
|
||||
"type": "lldb",
|
||||
"request": "launch",
|
||||
"name": "Debug example 'multi_lookup'",
|
||||
"cargo": {
|
||||
"args": [
|
||||
"build",
|
||||
"--example=multi_lookup",
|
||||
"--package=caulk"
|
||||
],
|
||||
"filter": {
|
||||
"name": "multi_lookup",
|
||||
"kind": "example"
|
||||
}
|
||||
},
|
||||
"args": [],
|
||||
"cwd": "${workspaceFolder}"
|
||||
},
|
||||
{
|
||||
"type": "lldb",
|
||||
"request": "launch",
|
||||
"name": "Debug unit tests in example 'multi_lookup'",
|
||||
"cargo": {
|
||||
"args": [
|
||||
"test",
|
||||
"--no-run",
|
||||
"--example=multi_lookup",
|
||||
"--package=caulk"
|
||||
],
|
||||
"filter": {
|
||||
"name": "multi_lookup",
|
||||
"kind": "example"
|
||||
}
|
||||
},
|
||||
"args": [],
|
||||
"cwd": "${workspaceFolder}"
|
||||
},
|
||||
{
|
||||
"type": "lldb",
|
||||
"request": "launch",
|
||||
"name": "Debug example 'single_opening'",
|
||||
"cargo": {
|
||||
"args": [
|
||||
"build",
|
||||
"--example=single_opening",
|
||||
"--package=caulk"
|
||||
],
|
||||
"filter": {
|
||||
"name": "single_opening",
|
||||
"kind": "example"
|
||||
}
|
||||
},
|
||||
"args": [],
|
||||
"cwd": "${workspaceFolder}"
|
||||
},
|
||||
{
|
||||
"type": "lldb",
|
||||
"request": "launch",
|
||||
"name": "Debug unit tests in example 'single_opening'",
|
||||
"cargo": {
|
||||
"args": [
|
||||
"test",
|
||||
"--no-run",
|
||||
"--example=single_opening",
|
||||
"--package=caulk"
|
||||
],
|
||||
"filter": {
|
||||
"name": "single_opening",
|
||||
"kind": "example"
|
||||
}
|
||||
},
|
||||
"args": [],
|
||||
"cwd": "${workspaceFolder}"
|
||||
}
|
||||
]
|
||||
}
|
||||
79
src/dft.rs
79
src/dft.rs
@@ -72,7 +72,7 @@ where
|
||||
// h_i= c_d[x^{d-i-1}]+c_{d-1}[x^{d-i-2}]+c_{d-2}[x^{d-i-3}]+\cdots +
|
||||
// c_{i+2}[x]+c_{i+1}[1]
|
||||
pub fn compute_h_23<F, G>(
|
||||
c_poly: &DensePolynomial<F>, /* c(X) degree up to d<2^p , i.e. c_poly has at most d+1 coeffs
|
||||
c_poly: &DensePolynomial<F>, /* c(X) degree up to d<=2^p , i.e. c_poly has at most d+1 coeffs
|
||||
* non-zero */
|
||||
powers: &[G], // SRS
|
||||
p: usize,
|
||||
@@ -87,36 +87,40 @@ where
|
||||
let fpzero = F::zero();
|
||||
coeffs.resize(dom_size, fpzero);
|
||||
|
||||
// 1. x_ext = [[x^(d-1)], [x^{d-2},...,[x],[1], d+2 [0]'s]
|
||||
// 1. x_ext = [[x^(d-1)], [x^{d-2},...,[x],[1], d [0]'s]
|
||||
let step1_timer = start_timer!(|| "step 1");
|
||||
let mut x_ext: Vec<G> = powers.iter().take(dom_size - 1).rev().copied().collect();
|
||||
x_ext.resize(2 * dom_size, G::zero()); // filling 2d+2 neutral elements
|
||||
x_ext.resize(2 * dom_size, G::zero()); // filling 2d neutral elements
|
||||
let y = group_dft::<F, G>(&x_ext, p + 1);
|
||||
end_timer!(step1_timer);
|
||||
|
||||
// 2. c_ext = [c_d, d zeroes, c_d,c_{0},c_1,...,c_{d-2},c_{d-1}]
|
||||
// 2. c_ext = [ d zeroes, c_{0},c_1,...,c_{d-2},c_{d-1}]
|
||||
let step2_timer = start_timer!(|| "step 2");
|
||||
|
||||
let mut c_ext = vec![coeffs[coeffs.len() - 1]];
|
||||
let mut c_ext = vec![fpzero];
|
||||
c_ext.resize(dom_size, fpzero);
|
||||
c_ext.push(coeffs[coeffs.len() - 1]);
|
||||
for &e in coeffs.iter().take(coeffs.len() - 1) {
|
||||
for &e in coeffs.iter().take(coeffs.len()) {
|
||||
c_ext.push(e);
|
||||
}
|
||||
assert_eq!(c_ext.len(), 2 * dom_size);
|
||||
let v = field_dft::<F>(&c_ext, p + 1);
|
||||
let mut v = field_dft::<F>(&c_ext, p + 1);
|
||||
end_timer!(step2_timer);
|
||||
|
||||
// 3. u = y o v
|
||||
// 3. u = y o v o powers
|
||||
let step3_timer = start_timer!(|| "step 3");
|
||||
let input_domain: GeneralEvaluationDomain<F> = EvaluationDomain::new(2*dom_size).unwrap();
|
||||
for i in 0..2*dom_size{
|
||||
v[i] = v[i].mul(input_domain.element(i));
|
||||
}
|
||||
let u: Vec<_> = y
|
||||
.into_iter()
|
||||
.zip(v.into_iter())
|
||||
.map(|(a, b)| a.mul(b.into_repr()))
|
||||
.collect();
|
||||
|
||||
end_timer!(step3_timer);
|
||||
|
||||
// 4. h_ext = idft_{2d+2}(u)
|
||||
// 4. h_ext = idft_{2d}(u)
|
||||
let step4_timer = start_timer!(|| "step 4");
|
||||
let h_ext = group_inv_dft::<F, G>(&u, p + 1);
|
||||
end_timer!(step4_timer);
|
||||
@@ -125,6 +129,61 @@ where
|
||||
h_ext[0..dom_size].to_vec()
|
||||
}
|
||||
|
||||
// compute all pre-proofs using DFT
|
||||
// h_i= c_d[x^{d-i-1}]+c_{d-1}[x^{d-i-2}]+c_{d-2}[x^{d-i-3}]+\cdots +
|
||||
// c_{i+2}[x]+c_{i+1}[1]
|
||||
pub fn compute_h_evals<F, G>(
|
||||
c_poly: &DensePolynomial<F>, /* c(X) degree up to d<=2^p , i.e. c_poly has at most d+1 coeffs
|
||||
* non-zero */
|
||||
powers: &[G], // SRS
|
||||
p: usize,
|
||||
) -> Vec<G>
|
||||
where
|
||||
F: PrimeField,
|
||||
G: ProjectiveCurve,
|
||||
{
|
||||
let timer = start_timer!(|| "compute h");
|
||||
let mut coeffs = c_poly.coeffs().to_vec();
|
||||
let dom_size = 1 << p;
|
||||
let fpzero = F::zero();
|
||||
coeffs.resize(dom_size, fpzero);
|
||||
|
||||
// 1. x_ext = [[x^(d-1)], [x^{d-2},...,[x],[1], d [0]'s]
|
||||
let step1_timer = start_timer!(|| "step 1");
|
||||
let mut x_ext: Vec<G> = powers.iter().take(dom_size - 1).rev().copied().collect();
|
||||
x_ext.resize(2 * dom_size, G::zero()); // filling 2d neutral elements
|
||||
let y = group_dft::<F, G>(&x_ext, p + 1);
|
||||
end_timer!(step1_timer);
|
||||
|
||||
// 2. c_ext = [ d zeroes, c_{0},c_1,...,c_{d-2},c_{d-1}]
|
||||
let step2_timer = start_timer!(|| "step 2");
|
||||
|
||||
let mut c_ext = vec![fpzero];
|
||||
c_ext.resize(dom_size, fpzero);
|
||||
for &e in coeffs.iter().take(coeffs.len()) {
|
||||
c_ext.push(e);
|
||||
}
|
||||
assert_eq!(c_ext.len(), 2 * dom_size);
|
||||
let mut v = field_dft::<F>(&c_ext, p + 1);
|
||||
end_timer!(step2_timer);
|
||||
|
||||
// 3. u = y o v o powers
|
||||
let step3_timer = start_timer!(|| "step 3");
|
||||
let input_domain: GeneralEvaluationDomain<F> = EvaluationDomain::new(2*dom_size).unwrap();
|
||||
for i in 0..2*dom_size{
|
||||
v[i] = v[i].mul(input_domain.element(i));
|
||||
}
|
||||
let u: Vec<_> = y
|
||||
.into_iter()
|
||||
.zip(v.into_iter())
|
||||
.map(|(a, b)| a.mul(b.into_repr()))
|
||||
.collect();
|
||||
|
||||
end_timer!(step3_timer);
|
||||
|
||||
u
|
||||
}
|
||||
|
||||
// compute DFT of size @dom_size over vector of Fr elements
|
||||
// q_i = h_0 + h_1w^i + h_2w^{2i}+\cdots + h_{dom_size-1}w^{(dom_size-1)i} for
|
||||
// 0<= i< dom_size=2^p
|
||||
|
||||
43
src/kzg.rs
43
src/kzg.rs
@@ -5,7 +5,7 @@
|
||||
// (4) hash_caulk_single is for hashing group and field elements into a field
|
||||
// element (5) random_field is for generating random field elements
|
||||
|
||||
use crate::{compute_h,compute_h_23, group_dft, util::convert_to_bigints};
|
||||
use crate::{compute_h,compute_h_23, compute_h_evals, group_dft, util::convert_to_bigints};
|
||||
use ark_ec::{msm::VariableBaseMSM, AffineCurve, PairingEngine, ProjectiveCurve};
|
||||
use ark_ff::{Field, PrimeField};
|
||||
use ark_poly::{
|
||||
@@ -156,6 +156,45 @@ impl<E: PairingEngine> KZGCommit<E> {
|
||||
res
|
||||
}
|
||||
|
||||
// compute all openings to c_poly using a smart formula
|
||||
// This Code implements an algorithm for calculating n openings of a KZG vector
|
||||
// commitment of size n in n log(n) time. The algorithm is by Feist and
|
||||
// Khovratovich updated in the 2023 paper https://eprint.iacr.org/2023/033.pdf
|
||||
pub fn multiple_open_24<G>(
|
||||
c_poly: &DensePolynomial<E::Fr>, // c(X)
|
||||
powers: &[G], // SRS
|
||||
p: usize,
|
||||
) -> Vec<G>
|
||||
where
|
||||
G: AffineCurve<ScalarField = E::Fr> + Sized,
|
||||
{
|
||||
let timer = start_timer!(|| "multiple open");
|
||||
|
||||
let degree = c_poly.coeffs.len() - 1;
|
||||
let input_domain: GeneralEvaluationDomain<E::Fr> = EvaluationDomain::new(degree).unwrap();
|
||||
|
||||
let h_timer = start_timer!(|| "compute h");
|
||||
let powers: Vec<G::Projective> = powers.iter().map(|x| x.into_projective()).collect();
|
||||
let h2 = compute_h_evals(c_poly, &powers, p);
|
||||
end_timer!(h_timer);
|
||||
|
||||
|
||||
let dom_size = input_domain.size();
|
||||
assert_eq!(1 << p, dom_size);
|
||||
assert_eq!(degree + 1, dom_size);
|
||||
|
||||
let mut q2 = vec![h2[0]];
|
||||
for i in 1..dom_size{
|
||||
q2.push(h2[2*i]);
|
||||
}
|
||||
let normalization_timer = start_timer!(|| "batch normalization");
|
||||
let res = G::Projective::batch_normalization_into_affine(q2.as_ref());
|
||||
end_timer!(normalization_timer);
|
||||
|
||||
end_timer!(timer);
|
||||
res
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////
|
||||
// KZG.Open( srs_KZG, f(X, Y), deg, alpha )
|
||||
// returns ([f(alpha, x)]_1, pi)
|
||||
@@ -686,7 +725,7 @@ pub mod tests {
|
||||
let mut rng = test_rng();
|
||||
|
||||
// current kzg setup should be changed with output from a setup ceremony
|
||||
let p: usize = 4;
|
||||
let p: usize = 8;
|
||||
let max_degree: usize = 1 << p + 1;
|
||||
let actual_degree: usize = (1 << p) - 1;
|
||||
let pp = caulk_single_setup(max_degree, actual_degree, &mut rng);
|
||||
|
||||
Reference in New Issue
Block a user