ekzg_multi_open/
verification_key.rs1use bls12_381::{
2 lincomb::{g1_lincomb, g2_lincomb},
3 G1Point, G1Projective, G2Point, G2Projective, Scalar,
4};
5
6#[derive(Clone, Debug)]
8pub struct VerificationKey {
9 pub g1s: Vec<G1Point>,
13 pub g2s: Vec<G2Point>,
17 pub g2_gen: G2Point,
19 pub coset_size: usize,
28 pub num_coefficients_in_polynomial: usize,
33}
34
35impl VerificationKey {
36 pub fn new(
37 g1s: Vec<G1Point>,
38 g2s: Vec<G2Point>,
39 coset_size: usize,
40 num_coefficients_in_polynomial: usize,
41 ) -> Self {
42 let g2_gen = g2s[0];
46
47 assert!(coset_size < g2s.len(), "The coset size must be less than the amount of g2 elements as the verifier needs to do a g2 msm of size `coset_size`");
48
49 Self {
50 g1s,
51 g2s,
52 g2_gen,
53 coset_size,
54 num_coefficients_in_polynomial,
55 }
56 }
57
58 pub fn commit_g2(&self, polynomial: &[Scalar]) -> G2Projective {
60 assert!(self.g2s.len() >= polynomial.len());
61 g2_lincomb(&self.g2s[..polynomial.len()], polynomial)
62 .expect("number of g2 points is equal to the number of coefficients in the polynomial")
63 }
64
65 pub fn commit_g1(&self, polynomial: &[Scalar]) -> G1Projective {
67 assert!(self.g1s.len() >= polynomial.len());
68 g1_lincomb(&self.g1s[..polynomial.len()], polynomial)
69 .expect("number of g1 points is equal to the number of coefficients in the polynomial")
70 }
71}
72
73#[cfg(test)]
74mod tests {
75 use bls12_381::{traits::*, G1Projective, Scalar};
76
77 use super::*;
78
79 #[test]
80 fn test_commit_g1_matches_lincomb() {
81 let poly = vec![Scalar::from(1u64), Scalar::from(2u64), Scalar::from(3u64)];
83
84 let g1s: Vec<G1Point> = (0..3).map(|_| G1Projective::generator().into()).collect();
86
87 let g2s: Vec<_> = (0..4).map(|_| G2Projective::generator().into()).collect();
89
90 let vk = VerificationKey::new(g1s, g2s, 2, 3);
91
92 let g = G1Projective::generator();
94 let expected = g * Scalar::from(6u64);
95
96 let actual = vk.commit_g1(&poly);
97
98 assert_eq!(actual, expected);
99 }
100
101 #[test]
102 fn test_commit_g2_matches_lincomb() {
103 let poly = vec![Scalar::from(5u64), Scalar::from(7u64), Scalar::from(11u64)];
105
106 let g2s: Vec<G2Point> = (0..3).map(|_| G2Projective::generator().into()).collect();
108
109 let g1s: Vec<_> = (0..4).map(|_| G1Projective::generator().into()).collect();
111
112 let vk = VerificationKey::new(g1s, g2s, 2, 3);
113
114 let g = G2Projective::generator();
116 let expected = g * Scalar::from(23u64);
117
118 let actual = vk.commit_g2(&poly);
119
120 assert_eq!(actual, expected);
121 }
122
123 #[test]
124 #[should_panic]
125 fn test_coset_size_check_panics() {
126 let g1s = vec![G1Projective::generator().into(); 2];
127 let g2s = vec![G2Projective::generator().into(); 2];
128 let _vk = VerificationKey::new(g1s, g2s, 2, 2); }
130
131 #[test]
132 fn test_g2_gen_is_first_element() {
133 let g2s: Vec<_> = (0..4).map(|_| G2Projective::generator().into()).collect();
134 let g1s: Vec<_> = (0..4).map(|_| G1Projective::generator().into()).collect();
135
136 let vk = VerificationKey::new(g1s, g2s.clone(), 1, 3);
137 assert_eq!(vk.g2_gen, g2s[0]);
138 }
139
140 #[test]
141 #[should_panic]
142 fn test_commit_g1_panics_when_poly_longer_than_g1s() {
143 let g1s: Vec<G1Point> = (0..2).map(|_| G1Projective::generator().into()).collect();
145 let g2s: Vec<G2Point> = (0..3).map(|_| G2Projective::generator().into()).collect();
146
147 let poly = vec![Scalar::from(1), Scalar::from(2), Scalar::from(3)];
149
150 let vk = VerificationKey::new(g1s, g2s, 1, 3);
151
152 let _ = vk.commit_g1(&poly);
154 }
155
156 #[test]
157 #[should_panic]
158 fn test_commit_g2_panics_when_poly_longer_than_g2s() {
159 let g2s: Vec<G2Point> = (0..2).map(|_| G2Projective::generator().into()).collect();
161 let g1s: Vec<G1Point> = (0..3).map(|_| G1Projective::generator().into()).collect();
162
163 let poly = vec![Scalar::from(5), Scalar::from(7), Scalar::from(11)];
165
166 let vk = VerificationKey::new(g1s, g2s, 1, 3);
167
168 let _ = vk.commit_g2(&poly);
170 }
171
172 #[test]
173 fn test_commit_g1_with_more_g1s_than_poly_len() {
174 let g1s: Vec<G1Point> = (0..5).map(|_| G1Projective::generator().into()).collect();
176 let g2s: Vec<G2Point> = (0..5).map(|_| G2Projective::generator().into()).collect();
177
178 let poly = vec![Scalar::from(1), Scalar::from(2), Scalar::from(3)];
180
181 let vk = VerificationKey::new(g1s, g2s, 1, 5);
182
183 let g = G1Projective::generator();
185 let expected = g * Scalar::from(6u64);
186
187 let actual = vk.commit_g1(&poly);
188 assert_eq!(actual, expected);
189 }
190
191 #[test]
192 fn test_commit_g2_with_more_g2s_than_poly_len() {
193 let g2s: Vec<G2Point> = (0..5).map(|_| G2Projective::generator().into()).collect();
195 let g1s: Vec<G1Point> = (0..5).map(|_| G1Projective::generator().into()).collect();
196
197 let poly = vec![Scalar::from(2), Scalar::from(4), Scalar::from(6)];
199
200 let vk = VerificationKey::new(g1s, g2s, 1, 5);
201
202 let g = G2Projective::generator();
204 let expected = g * Scalar::from(12u64);
205
206 let actual = vk.commit_g2(&poly);
207 assert_eq!(actual, expected);
208 }
209}