ekzg_multi_open/
commit_key.rs1use bls12_381::{lincomb::g1_lincomb, G1Point, G1Projective, Scalar};
2
3#[derive(Debug, Clone)]
10pub struct CommitKey {
11 pub g1s: Vec<G1Point>,
17}
18
19impl CommitKey {
20 pub fn new(g1s: Vec<G1Point>) -> Self {
29 assert!(
30 !g1s.is_empty(),
31 "cannot initialize `CommitKey` with no g1 points"
32 );
33
34 Self { g1s }
35 }
36
37 pub fn commit_g1(&self, poly_coeff: &[Scalar]) -> G1Projective {
39 g1_lincomb(&self.g1s[0..poly_coeff.len()], poly_coeff)
43 .expect("number of g1 points is equal to the number of coefficients in the polynomial")
44 }
45}
46
47#[cfg(test)]
48mod tests {
49 use bls12_381::{traits::*, G1Projective, Scalar};
50 use rand::{rngs::StdRng, SeedableRng};
51
52 use super::*;
53
54 #[test]
55 fn test_commit_g1_matches_manual_lincomb() {
56 let poly = vec![Scalar::from(1), Scalar::from(2), Scalar::from(3)];
58
59 let g1s: Vec<G1Point> = (0..3).map(|_| G1Projective::generator().into()).collect();
61 let ck = CommitKey::new(g1s);
62
63 let expected = G1Projective::generator() * Scalar::from(6);
65 let actual = ck.commit_g1(&poly);
66
67 assert_eq!(actual, expected);
68 }
69
70 #[test]
71 fn test_commit_g1_with_more_g1s_than_poly_len() {
72 let poly = vec![Scalar::from(1), Scalar::from(2)];
74
75 let g1s: Vec<G1Point> = (0..5).map(|_| G1Projective::generator().into()).collect();
77 let ck = CommitKey::new(g1s);
78
79 let expected = G1Projective::generator() * Scalar::from(3);
81 let actual = ck.commit_g1(&poly);
82
83 assert_eq!(actual, expected);
84 }
85
86 #[test]
87 #[should_panic]
88 fn test_commit_g1_panics_when_poly_longer_than_g1s() {
89 let poly = vec![Scalar::from(1), Scalar::from(2), Scalar::from(3)];
91
92 let g1s: Vec<G1Point> = (0..2).map(|_| G1Projective::generator().into()).collect();
94 let ck = CommitKey::new(g1s);
95
96 let _ = ck.commit_g1(&poly);
98 }
99
100 #[test]
101 #[should_panic]
102 fn test_commit_key_empty_panics() {
103 let _ = CommitKey::new(vec![]);
104 }
105
106 #[test]
107 fn test_commit_g1_identity_when_poly_is_zero() {
108 let poly = vec![Scalar::ZERO, Scalar::ZERO, Scalar::ZERO];
110
111 let g1s: Vec<G1Point> = (0..3).map(|_| G1Projective::generator().into()).collect();
112 let ck = CommitKey::new(g1s);
113
114 let result = ck.commit_g1(&poly);
115 assert_eq!(result, G1Projective::identity());
116 }
117
118 #[test]
119 fn test_commit_key_commit_g1_randomized_consistency() {
120 let mut rng = StdRng::seed_from_u64(42);
121
122 let g1s: Vec<G1Point> = (0..10)
123 .map(|_| G1Projective::random(&mut rng).into())
124 .collect();
125 let poly: Vec<Scalar> = (0..10).map(|_| Scalar::random(&mut rng)).collect();
126
127 let ck = CommitKey::new(g1s.clone());
128
129 let expected: G1Projective = g1s
131 .iter()
132 .zip(&poly)
133 .map(|(g, s)| G1Projective::from(*g) * s)
134 .sum();
135
136 let actual = ck.commit_g1(&poly);
137 assert_eq!(actual, expected);
138 }
139}