-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathlib.rs
164 lines (131 loc) · 4.87 KB
/
lib.rs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
use ark_ec::{pairing::Pairing, Group};
use ark_ff::{field_hashers::HashToField, One, PrimeField};
use polynomials::univariate_polynomial::UnivariatePolynomial;
mod trusted_setup;
use trusted_setup::TrustedSetUpCeremony;
pub struct KZG<C: Pairing, H: HashToField<C::ScalarField>> {
pub trusted_setup: TrustedSetUpCeremony<C, H>,
}
impl<C: Pairing, H: HashToField<C::ScalarField>> KZG<C, H> {
pub fn instantiate(
hasher_domain: &[u8],
domain_size: usize,
initial_randomness: &[u8],
) -> Self {
let trusted_setup_ceremony = TrustedSetUpCeremony::instantiate(
hasher_domain,
domain_size as u64,
initial_randomness,
);
Self {
trusted_setup: trusted_setup_ceremony,
}
}
pub fn contribute(&mut self, randomness: &[u8]) {
self.trusted_setup.contribute(randomness);
}
pub fn commit_to_poly(&self, poly: &UnivariatePolynomial<C::ScalarField>) -> C::G1 {
assert!(
self.trusted_setup.public_parameters.g1_powers_of_tau.len() >= poly.coefficients.len(),
"Powers of tau not sufficient to evaluate poly"
);
let res = poly.coefficients.iter().enumerate().fold(
C::G1::default(),
|mut acc, (index, coeff)| {
let res = self.trusted_setup.public_parameters.g1_powers_of_tau[index]
.mul_bigint(coeff.into_bigint());
acc = acc + res;
acc
},
);
res
}
// Opens a polynomial (poly) at a point (eval_point) using the commitment to the polynomial
// returns a tuple of the evaluation and proof
pub fn open(
&self,
eval_point: C::ScalarField,
poly: UnivariatePolynomial<C::ScalarField>,
) -> (C::ScalarField, C::G1) {
assert!(
self.trusted_setup.public_parameters.g1_powers_of_tau.len() >= poly.coefficients.len(),
"Powers of tau not sufficient to evaluate poly"
);
let res = poly.evaluate(eval_point);
let (quotient, _) =
poly / UnivariatePolynomial::new(vec![-eval_point, C::ScalarField::one()]);
let proof: C::G1 = quotient.coefficients.iter().enumerate().fold(
C::G1::default(),
|mut acc, (index, coeff)| {
let res = self.trusted_setup.public_parameters.g1_powers_of_tau[index]
.mul_bigint(coeff.into_bigint());
acc = acc + res;
acc
},
);
(res, proof)
}
pub fn verify(
&self,
eval_point: C::ScalarField,
eval: C::ScalarField,
commitment: C::G1,
proof: C::G1,
) -> bool {
let num = commitment - C::G1::generator().mul_bigint(eval.into_bigint());
let denum = self.trusted_setup.public_parameters.g2_power_of_tau[0]
- C::G2::generator().mul_bigint(eval_point.into_bigint());
C::pairing(num, C::G2::generator()) == C::pairing(proof, denum)
}
}
#[cfg(test)]
pub mod test {
use crate::KZG;
use super::TrustedSetUpCeremony;
use ark_bls12_381::{Bls12_381, Fr};
use ark_ec::CurveGroup;
use ark_ff::field_hashers::DefaultFieldHasher;
use polynomials::univariate_polynomial::UnivariatePolynomial;
use sha2::Sha256;
#[test]
pub fn test_instantiate_trusted_setup() {
let mut trusted_setup_instance: TrustedSetUpCeremony<
Bls12_381,
DefaultFieldHasher<Sha256>,
> = TrustedSetUpCeremony::instantiate(
"Hello world".as_bytes(),
8,
"Initialize Ceremony".as_bytes(),
);
trusted_setup_instance.contribute("My contribution".as_bytes());
dbg!(trusted_setup_instance.public_parameters);
}
#[test]
pub fn test_commit_to_poly() {
let poly = UnivariatePolynomial::new(vec![Fr::from(1), Fr::from(3), Fr::from(2)]);
let kzg: KZG<Bls12_381, DefaultFieldHasher<Sha256>> = KZG::instantiate(
"Hello world".as_bytes(),
2,
"Initialize Ceremony".as_bytes(),
);
let commitment = kzg.commit_to_poly(&poly).into_affine().to_string();
dbg!(commitment);
}
#[test]
pub fn test_kzg() {
let poly = UnivariatePolynomial::new(vec![Fr::from(6), Fr::from(5), Fr::from(1)]);
let mut kzg: KZG<Bls12_381, DefaultFieldHasher<Sha256>> = KZG::instantiate(
"Hello world".as_bytes(),
2,
"Instantiate Ceremony".as_bytes(),
);
kzg.contribute("My contribution".as_bytes());
kzg.contribute("Second contribution".as_bytes());
let commitment = kzg.commit_to_poly(&poly);
let (evaluation, proof) = kzg.open(Fr::from(5000), poly);
assert!(
kzg.verify(Fr::from(5000), evaluation, commitment, proof),
"Invalid proof"
);
}
}