Skip to main content

ziglet_okamoto/bls12_381_plain/
mod.rs

1//! Okamoto Partially Blind Signatures implemented over the BLS12-381 Elliptic Curve
2//!
3//! # Example
4//! ```rust
5//! #![allow(non_snake_case)]
6//! use bls12_381::Scalar;
7//! use ff::Field;
8//! use ziglet_okamoto::bls12_381_plain::{Error, KeyPair, Signer, User};
9//!
10//! fn happy_path() -> Result<(), Error> {
11//!     // Setup
12//!     let mut rng = rand_core::OsRng;
13//!     let key_pair = KeyPair::generate(rng.clone());
14//!     let mut user = User::new(&key_pair.public_key, rng.clone());
15//!     let mut signer = Signer::new(&key_pair, rng.clone());
16//!
17//!     // Step 0: out-of-band, the [User] and the [Signer] perform application logic necessary to agree on $m_0$
18//!     let m0 = Scalar::random(&mut rng);
19//!     let m1 = Scalar::random(&mut rng);
20//!
21//!
22//!     // Step 1: User and Signer both commit to messages
23//!     user.set_message(m0, m1)?;
24//!     signer.set_message(m0)?;
25//!
26//!     // Step 2: User generates a proof of commitment that is verified by Signer
27//!     let (W,X) = user.commit()?;
28//!     let eta = signer.commit(W,X)?;
29//!
30//!     // Step 3: User generates proof of knowledge of variables $s,t \in \mathbb{Z}_p^{*}$.
31//!     // Signer verifies the proof.
32//!     let (b1, b2, b3) = user.compute_witness(&eta)?;
33//!     signer.verify_witness(b1,b2,b3)?;
34//!
35//!     // Step 4: Signer send a partial signature to the User. User generates a completed signature.
36//!     let (Y,R,l) = signer.sign()?;
37//!     let (sigma, alpha, beta) = user.sign(&Y,&R,&l)?;
38//!
39//!     Ok(())
40//! }
41//!
42//! happy_path().expect("successful completion");
43//! ```
44
45use bls12_381::{G1Affine, G1Projective, G2Affine, G2Projective, Scalar};
46use ff::Field;
47use rand_core::RngCore;
48
49pub type SecretKey = Scalar;
50
51/// The public key for this signing protocol consists of several generators in $\mathbb{G_1}$ and
52/// matching generators for the pairing operation in $\mathbb{G_2}$.
53#[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    /// ${g_2}^{x}$
64    pub w2: G2Affine,
65}
66
67/// A pair of secret and public keys for the signing protocol
68pub struct KeyPair {
69    pub public_key: PublicKey,
70    /// The exponent $x \in $\mathbb{Z}_p^{*}$ in ${g_2}^{x}$
71    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    /// A method was called in the incorrect state
154    InvalidState,
155    /// A provided signature could not be validated given the [PublicKey]
156    InvalidSignature,
157    /// Given point is not on the curve
158    PointNotOnCurve,
159    /// The given witness was invalid
160    InvalidWitness,
161    /// A given [Scalar] value was zero
162    ScalarIsZero,
163}
164
165pub enum SignerState {
166    /// Step 1, ready to call [Signer::set_message]
167    ReadyToSetMessage,
168    /// Step 2, ready to call [Signer::commit]
169    ReadyToCommit,
170    /// Step 3, ready to call [Signer::verify_witness]
171    ReadyToVerifyWitness,
172    /// Step 4, ready to call [Signer::sign]
173    ReadyToSign,
174    /// End, the message has been signed
175    Signed,
176    /// An error occurred during the signing process
177    Aborted,
178}
179
180/// Signer is a single, stateful interaction with a [User] to sign a shared message $m_0$ (aka info)
181/// and a blinded message $m_1$ (aka message).
182///
183/// A Signer can be used for any number of [Signer::verify_signature] operations but can only be used for a single
184/// signing flow.
185#[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    /// Create a fresh [Signer] in the starting state given a [KeyPair]
209    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    /// Get the current [SignerState]
232    pub fn get_state(&self) -> &SignerState {
233        &self.state
234    }
235
236    /// Step 1. In the first stage of the negotiation, Signer and User agree on $m_0$ (aka `info`).
237    /// The rules for agreement are up to the application.
238    ///
239    /// $m_0 \in \mathbb{Z}_p^{*}$.
240    ///
241    /// It is up to the application to hash the byte array of the message to the finite field:
242    ///
243    /// $H: {0..1}^* \rightarrow \mathbb{Z}_p^{*}$
244    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    /// Step 2. The [User] commits to the messages and random values for the generators and presents
257    /// a witness that will be used in the next step to prove the witness.
258    ///
259    /// * Verify that $W \in \mathbb{G1}$
260    /// * Verify that $X \in \mathbb{G1}$
261    /// * Verify that $a1, a2, a3 \in \mathbb{Z}_p^{*}$
262    /// * Store $W$ and $X$
263    ///
264    /// # Returns
265    /// $\eta$ a value used in the next step to prove to the [Signer] that she
266    /// knows $s,t \in \mathbb{Z}_p^{*}$
267    #[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    /// Step 3. Verify that the [User] has knowledge of $s,t \in \mathbb{Z}_p^{*}$
288    ///
289    /// Verify that $({h_1}^{m_0})^{b_2}{g_1}^{b_1}{u_1}^{b_2}{v_1}^{b_3} = WX^{\eta}$
290    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    /// Step 4. (counter) sign and return the wrapped signature.
312    ///
313    /// $Y \leftarrow (Xv_1^l)^{1/{(x+r)}}$
314    ///
315    /// $R \leftarrow g_2^r$
316    ///
317    /// $l \leftarrow \mathbb{Z}_p^{*}$
318    ///
319    /// # Returns
320    /// $(Y, R, l)$
321    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    /// Abort the protocol preventing further use of the values
348    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/// User is a single stateful interaction with a [Signer] to sign a shared message $m_0$ (aka `info`)
363/// and a blinded message $m_1$ (aka `message`).
364///
365/// User can be used to verify any number of signatures but can be used to sign at most on message.
366#[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
386/// User is a stateful single instance of the User side of the (partially) blind signing protocol.
387impl<'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    /// Step 1. Commit to the values of $m_0$ and $m_1$
414    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    /// Step 2. Generate a commitment that can be sent to [Signer] to commit the [User] to
432    /// $m_0,m_1 \in \mathbb{G_1}$ and $s,t \in {Z}_p^{*}$.
433    ///
434    /// $W \leftarrow ({h_1}^{m_0})^{a_2}{g_1}^{a_1}{u_1}^{a_2}{v_1}^{a_3}$
435    ///
436    /// $X \leftarrow {h_1}^{m_0t}{g_1}^{m_1t}{u_1}^{t}{v_1}^{st}$
437    ///
438    ///
439    /// # Returns
440    /// ($W$,$X$)
441    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    /// Step 3. Compute a witness that proves that the [User] knows values $s,t \in \mathbb{Z}_p^{*}$ that
476    /// were mixed into the values of $W,X$.
477    ///
478    /// $b_1, b_2, b_3 \in \mathbb{Z}_p^{*}$
479    ///
480    /// $b_1 \leftarrow a_1 + \eta{m}_1t \mod p$
481    ///
482    /// $b_2 \leftarrow a_2 + \eta{t} \mod p$
483    ///
484    /// $b_3 \leftarrow a_  + \eta{s}t \mod p$
485    ///
486    /// # Returns
487    /// $b_1, b_2, b_3 \in \mathbb{Z}_p^{*}$
488    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    /// Step 4 (final). Compute the final signature $(\sigma, \alpha, \beta)$
504    ///
505    /// # Returns
506    /// $(\sigma, \alpha, \beta)$
507    #[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    /// Abort the instance of the protocol preventing further use of the values
532    pub fn abort(&mut self) {
533        self.state = UserState::Aborted;
534    }
535}
536
537/// Verify that a signature is valid
538///
539/// # Checks
540/// * $m_0 \in \mathbb{Z}_p^{*}$
541///
542/// * $m_1 \in \mathbb{Z}_p^{*}$
543///
544/// * $\sigma \in \mathbb{G}_1$
545///
546/// * $\alpha \in \mathbb{G}_2$
547///
548/// * $\beta \in \mathbb{Z}_p$
549///
550/// * $e(\sigma,w_2\alpha) = e(g_1,{h_2}^{m_0}{g_2}^{m_1}{u_2}{v_2}^{\beta})$
551pub 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;