bn254/ecdsa.rs
1use bn::{pairing_batch, Group, Gt, G1, G2};
2
3use crate::{
4 error::{Error, Result},
5 hash,
6 PrivateKey,
7 PublicKey,
8 PublicKeyG1,
9 Signature,
10};
11
12/// ECDSA with curve `bn254`.
13pub struct ECDSA;
14
15impl ECDSA {
16 /// Function to sign a message given a private key (as a point in [G1]).
17 ///
18 /// # Arguments
19 ///
20 /// * `message` - The message bytes
21 /// * `private_key` - The private key
22 ///
23 /// # Returns
24 ///
25 /// * If successful, the signature as a [G1] point
26 pub fn sign<T: AsRef<[u8]>>(message: T, private_key: &PrivateKey) -> Result<Signature> {
27 // 1. Hash_to_try_and_increment --> H(m) as point in G1 (only if it exists)
28 let hash_point = hash::hash_to_try_and_increment(message)?;
29
30 // 2. Multiply hash_point times private_key --> Signature in G1
31 let g1_point = hash_point * private_key.into();
32
33 // 3. Return signature
34 Ok(Signature(g1_point))
35 }
36
37 /// Function to verify a signature (point in [G1]) given a public key
38 /// (point in [G2]).
39 ///
40 /// # Arguments
41 ///
42 /// * `message` - The message to be signed
43 /// * `signature` - The signature
44 /// * `public_key` - The public key
45 ///
46 /// # Returns
47 ///
48 /// * If successful, `Ok(())`; otherwise [Error]
49 pub fn verify<T: AsRef<[u8]>>(message: T, signature: &Signature, public_key: &PublicKey) -> Result<()> {
50 // Pairing batch with one negated point
51 let mut vals = Vec::new();
52 // First pairing input: e(H(m), PubKey)
53 let hash_point = hash::hash_to_try_and_increment(message)?;
54 vals.push((hash_point, public_key.into()));
55 // Second pairing input: e(-Signature,G2::one())
56 vals.push((signature.into(), -G2::one()));
57 let mul = pairing_batch(&vals);
58
59 if mul == Gt::one() {
60 Ok(())
61 } else {
62 Err(Error::VerificationFailed)
63 }
64 }
65}
66
67/// Function to check if 2 Public Keys in [G1] and [G2] are valid
68///
69/// # Arguments
70///
71/// * `message` - The message to be signed
72/// * `signature` - The signature
73/// * `public_key` - The public key
74///
75/// # Returns
76///
77/// * If successful, `Ok(())`; otherwise [Error]
78pub fn check_public_keys(public_key_g2: &PublicKey, public_key_g1: &PublicKeyG1) -> Result<()> {
79 // Pairing batch with one negated point
80 let vals = vec![
81 // First pairing input: e(H(m), PubKey)
82 (G1::one(), public_key_g2.into()),
83 // Second pairing input: e(PubKey_G1, G2::one())
84 (public_key_g1.into(), -G2::one()),
85 ];
86 let mul = pairing_batch(&vals);
87
88 if mul == Gt::one() {
89 Ok(())
90 } else {
91 Err(Error::VerificationFailed)
92 }
93}