ziglet_okamoto/bls12_381_plain/
mod.rs1use bls12_381::{G1Affine, G1Projective, G2Affine, G2Projective, Scalar};
46use ff::Field;
47use rand_core::RngCore;
48
49pub type SecretKey = Scalar;
50
51#[derive(Copy, Clone, Debug, PartialEq, Default)]
54pub struct PublicKey {
55 pub g1: G1Affine,
56 pub h1: G1Affine,
57 pub u1: G1Affine,
58 pub v1: G1Affine,
59 pub g2: G2Affine,
60 pub h2: G2Affine,
61 pub u2: G2Affine,
62 pub v2: G2Affine,
63 pub w2: G2Affine,
65}
66
67pub struct KeyPair {
69 pub public_key: PublicKey,
70 secret_key: SecretKey,
72}
73
74impl KeyPair {
75 pub fn generate(mut rng: impl RngCore) -> KeyPair {
76 let secret_key: SecretKey = Scalar::random(&mut rng);
77
78 let mut public_key = PublicKey::default();
79
80 let mut g1_r: Scalar;
81 let mut h1_r: Scalar;
82 let mut u1_r: Scalar;
83 let mut v1_r: Scalar;
84
85 loop {
86 g1_r = Scalar::random(&mut rng);
87 if g1_r.is_zero().into() {
88 continue;
89 }
90 public_key.g1 = G1Affine::from(G1Affine::generator() * g1_r);
91 if public_key.g1 == G1Affine::generator() {
92 continue;
93 }
94 break;
95 }
96
97 loop {
98 h1_r = Scalar::random(&mut rng);
99 if h1_r.is_zero().into() {
100 continue;
101 }
102 public_key.h1 = G1Affine::from(G1Affine::generator() * h1_r);
103 if public_key.h1 == G1Affine::generator() {
104 continue;
105 }
106 if public_key.h1 != public_key.g1 {
107 break;
108 }
109 }
110
111 loop {
112 u1_r = Scalar::random(&mut rng);
113 if u1_r.is_zero().into() {
114 continue;
115 }
116 public_key.u1 = G1Affine::from(G1Affine::generator() * u1_r);
117 if public_key.u1 == G1Affine::generator() {
118 continue;
119 }
120 if public_key.u1 != public_key.g1 && public_key.u1 != public_key.h1 {
121 break;
122 }
123 }
124
125 loop {
126 v1_r = Scalar::random(&mut rng);
127 if v1_r.is_zero().into() {
128 continue;
129 }
130 public_key.v1 = G1Affine::from(G1Affine::generator() * v1_r);
131 if public_key.v1 == G1Affine::generator() {
132 continue;
133 }
134 if public_key.v1 != public_key.g1 && public_key.v1 != public_key.h1 && public_key.v1 != public_key.u1 {
135 break;
136 }
137 }
138
139 public_key.g2 = G2Affine::from(G2Projective::generator() * g1_r);
140 public_key.h2 = G2Affine::from(G2Projective::generator() * h1_r);
141 public_key.u2 = G2Affine::from(G2Projective::generator() * u1_r);
142 public_key.v2 = G2Affine::from(G2Projective::generator() * v1_r);
143 public_key.w2 = G2Affine::from(public_key.g2 * secret_key);
144
145 let key_pair = KeyPair { secret_key, public_key };
146
147 key_pair
148 }
149}
150
151#[derive(Debug)]
152pub enum Error {
153 InvalidState,
155 InvalidSignature,
157 PointNotOnCurve,
159 InvalidWitness,
161 ScalarIsZero,
163}
164
165pub enum SignerState {
166 ReadyToSetMessage,
168 ReadyToCommit,
170 ReadyToVerifyWitness,
172 ReadyToSign,
174 Signed,
176 Aborted,
178}
179
180#[allow(non_snake_case)]
186#[allow(dead_code)]
187pub struct Signer<'a, R: RngCore> {
188 key_pair: &'a KeyPair,
189 rng: R,
190 state: SignerState,
191 m0: Scalar,
192 W: G1Projective,
193 X: G1Projective,
194 #[cfg(test)]
195 l: Scalar,
196 #[cfg(test)]
197 r: Scalar,
198 eta: Scalar,
199 #[cfg(test)]
200 b1: Scalar,
201 #[cfg(test)]
202 b2: Scalar,
203 #[cfg(test)]
204 b3: Scalar,
205}
206
207impl<'a, R: RngCore> Signer<'a, R> {
208 pub fn new(key_pair: &'a KeyPair, rng: R) -> Self {
210 Self {
211 key_pair,
212 rng,
213 state: SignerState::ReadyToSetMessage,
214 m0: Scalar::zero(),
215 W: Default::default(),
216 X: Default::default(),
217 #[cfg(test)]
218 l: Default::default(),
219 #[cfg(test)]
220 r: Default::default(),
221 eta: Default::default(),
222 #[cfg(test)]
223 b1: Default::default(),
224 #[cfg(test)]
225 b2: Default::default(),
226 #[cfg(test)]
227 b3: Default::default(),
228 }
229 }
230
231 pub fn get_state(&self) -> &SignerState {
233 &self.state
234 }
235
236 pub fn set_message(&mut self, m0: Scalar) -> Result<(), Error> {
245 match self.state {
246 SignerState::ReadyToSetMessage => {}
247 _ => return Err(Error::InvalidState),
248 }
249
250 self.m0 = m0;
251 self.state = SignerState::ReadyToCommit;
252
253 Ok(())
254 }
255
256 #[allow(non_snake_case)]
268 pub fn commit(&mut self, W: G1Affine, X: G1Affine) -> Result<&Scalar, Error> {
269 match self.state {
270 SignerState::ReadyToCommit => {}
271 _ => return Err(Error::InvalidState),
272 }
273
274 if !bool::from(W.is_on_curve()) || !bool::from(X.is_on_curve()) {
275 self.state = SignerState::Aborted;
276 return Err(Error::PointNotOnCurve);
277 }
278
279 self.eta = Scalar::random(&mut self.rng);
280 self.W = G1Projective::from(W);
281 self.X = G1Projective::from(X);
282 self.state = SignerState::ReadyToVerifyWitness;
283
284 Ok(&self.eta)
285 }
286
287 pub fn verify_witness(&mut self, b1: Scalar, b2: Scalar, b3: Scalar) -> Result<(), Error> {
291 match self.state {
292 SignerState::ReadyToVerifyWitness => {}
293 _ => return Err(Error::InvalidState),
294 }
295
296 let pk = &self.key_pair.public_key;
297
298 let rhs = self.W + self.X * self.eta;
299 let lhs = pk.h1 * (self.m0 * b2) + pk.g1 * b1 + pk.u1 * b2 + pk.v1 * b3;
300
301 if rhs != lhs {
302 self.state = SignerState::Aborted;
303 return Err(Error::InvalidWitness);
304 }
305
306 self.state = SignerState::ReadyToSign;
307
308 Ok(())
309 }
310
311 pub fn sign(&mut self) -> Result<(G1Affine, G2Affine, Scalar), Error> {
322 match self.state {
323 SignerState::ReadyToSign => {}
324 _ => return Err(Error::InvalidState),
325 }
326
327 let pk = &self.key_pair.public_key;
328
329 let l = Scalar::random(&mut self.rng);
330 let r = Scalar::random(&mut self.rng);
331 #[allow(non_snake_case)]
332 let R = pk.g2 * r;
333 #[allow(non_snake_case)]
334 let Y = (self.X + (pk.v1 * l)) * (self.key_pair.secret_key + r).invert().unwrap();
335
336 #[cfg(test)]
337 {
338 self.l = l;
339 self.r = r;
340 }
341
342 self.state = SignerState::Signed;
343
344 Ok((G1Affine::from(Y), G2Affine::from(R), l))
345 }
346
347 pub fn abort(&mut self) {
349 self.state = SignerState::Aborted
350 }
351}
352
353pub enum UserState {
354 ReadyToSetMessage,
355 ReadyToCommit,
356 ReadyToComputeWitness,
357 ReadyToSign,
358 Signed,
359 Aborted,
360}
361
362#[allow(non_snake_case)]
367pub struct User<'a, R: RngCore> {
368 public_key: &'a PublicKey,
369 state: UserState,
370 rng: R,
371 m0: Scalar,
372 m1: Scalar,
373 a1: Scalar,
374 a2: Scalar,
375 a3: Scalar,
376 #[cfg(test)]
377 f: Scalar,
378 s: Scalar,
379 t: Scalar,
380 #[cfg(test)]
381 W: G1Projective,
382 #[cfg(test)]
383 X: G1Projective,
384}
385
386impl<'a, R: RngCore> User<'a, R> {
388 pub fn new(public_key: &'a PublicKey, rng: R) -> Self {
389 Self {
390 public_key,
391 state: UserState::ReadyToSetMessage,
392 rng,
393 m0: Default::default(),
394 m1: Default::default(),
395 a1: Default::default(),
396 a2: Default::default(),
397 a3: Default::default(),
398 #[cfg(test)]
399 f: Default::default(),
400 s: Default::default(),
401 t: Default::default(),
402 #[cfg(test)]
403 X: Default::default(),
404 #[cfg(test)]
405 W: Default::default(),
406 }
407 }
408
409 pub fn get_state(&self) -> &UserState {
410 &self.state
411 }
412
413 pub fn set_message(&mut self, m0: Scalar, m1: Scalar) -> Result<(), Error> {
415 match self.state {
416 UserState::ReadyToSetMessage => {}
417 _ => return Err(Error::InvalidState),
418 }
419
420 if m0.is_zero().into() || m1.is_zero().into() {
421 return Err(Error::ScalarIsZero);
422 }
423
424 self.m0 = m0;
425 self.m1 = m1;
426 self.state = UserState::ReadyToCommit;
427
428 Ok(())
429 }
430
431 pub fn commit(&mut self) -> Result<(G1Affine, G1Affine), Error> {
442 match self.state {
443 UserState::ReadyToCommit => {}
444 _ => return Err(Error::InvalidState),
445 }
446
447 let a1 = Scalar::random(&mut self.rng);
448 let a2 = Scalar::random(&mut self.rng);
449 let a3 = Scalar::random(&mut self.rng);
450 let s = Scalar::random(&mut self.rng);
451 let t = Scalar::random(&mut self.rng);
452 let pk = &self.public_key;
453 #[allow(non_snake_case)]
454 let X = pk.h1 * (self.m0 * t) + pk.g1 * (self.m1 * t) + pk.u1 * t + pk.v1 * (s * t);
455 #[allow(non_snake_case)]
456 let W = pk.h1 * (self.m0 * a2) + pk.g1 * a1 + pk.u1 * a2 + pk.v1 * a3;
457
458 #[cfg(test)]
459 {
460 self.X = X.clone();
461 self.W = W.clone();
462 }
463
464 self.a1 = a1;
465 self.a2 = a2;
466 self.a3 = a3;
467 self.t = t;
468 self.s = s;
469
470 self.state = UserState::ReadyToComputeWitness;
471
472 Ok((G1Affine::from(W), G1Affine::from(X)))
473 }
474
475 pub fn compute_witness(&mut self, eta: &Scalar) -> Result<(Scalar, Scalar, Scalar), Error> {
489 match self.state {
490 UserState::ReadyToComputeWitness => {}
491 _ => return Err(Error::InvalidState),
492 }
493
494 let b1 = self.a1 + eta * self.m1 * self.t;
495 let b2 = self.a2 + eta * self.t;
496 let b3 = self.a3 + eta * self.s * self.t;
497
498 self.state = UserState::ReadyToSign;
499
500 Ok((b1, b2, b3))
501 }
502
503 #[allow(non_snake_case)]
508 pub fn sign(&mut self, Y: &G1Affine, R: &G2Affine, l: &Scalar) -> Result<(G1Affine, G2Affine, Scalar), Error> {
509 match self.state {
510 UserState::ReadyToSign => {}
511 _ => return Err(Error::InvalidState),
512 }
513
514 let pk = &self.public_key;
515 let f = Scalar::random(&mut self.rng);
516 let tau = (f * self.t).invert().unwrap();
517 let sigma = Y * tau;
518 let alpha = pk.w2 * (f - Scalar::one()) + (R * f);
519 let beta = self.s + l * self.t.invert().unwrap();
520
521 #[cfg(test)]
522 {
523 self.f = f;
524 }
525
526 self.state = UserState::Signed;
527
528 Ok((G1Affine::from(sigma), G2Affine::from(alpha), beta))
529 }
530
531 pub fn abort(&mut self) {
533 self.state = UserState::Aborted;
534 }
535}
536
537pub fn verify_signature(
552 public_key: &PublicKey,
553 m0: &Scalar,
554 m1: &Scalar,
555 sigma: &G1Affine,
556 alpha: &G2Affine,
557 beta: &Scalar,
558) -> Result<(), Error> {
559 let lhs2 = G2Affine::from(G2Projective::from(public_key.w2) + alpha);
560 let rhs2 = G2Affine::from(public_key.h2 * m0 + public_key.g2 * m1 + public_key.u2 + public_key.v2 * beta);
561 let lhs = bls12_381::pairing(&sigma, &lhs2);
562 let rhs = bls12_381::pairing(&public_key.g1, &rhs2);
563
564 if sigma == &G1Affine::identity() {
565 return Err(Error::InvalidSignature);
566 }
567
568 if !bool::from(sigma.is_on_curve()) {
569 return Err(Error::InvalidSignature);
570 }
571
572 if !bool::from(alpha.is_on_curve()) {
573 return Err(Error::InvalidSignature);
574 }
575
576 if lhs != rhs {
577 return Err(Error::InvalidSignature);
578 }
579
580 Ok(())
581}
582
583#[cfg(test)]
584mod tests;