concordium_base/ps_sig/
secret.rs

1// -*- mode: rust; -*-
2
3//! A secret key
4
5use super::{
6    errors::{InternalError::SecretKeyLengthError, *},
7    known_message::*,
8    signature::*,
9    unknown_message::*,
10};
11use crate::{common::*, curve_arithmetic::*};
12
13use rand::*;
14
15/// A secret key
16#[derive(Debug, Serialize)]
17pub struct SecretKey<C: Pairing> {
18    /// Generator of the first pairing group. Not secret, but needed for various
19    /// operations.
20    pub g:       C::G1,
21    /// Generator of the second pairing group. Not secret, but needed for
22    /// various operations.
23    pub g_tilda: C::G2,
24    #[size_length = 4]
25    pub ys:      Vec<C::ScalarField>,
26    pub x:       C::ScalarField,
27}
28
29impl<C: Pairing> PartialEq for SecretKey<C> {
30    fn eq(&self, other: &Self) -> bool { self.ys == other.ys && self.x == other.x }
31}
32
33impl<C: Pairing> Eq for SecretKey<C> {}
34
35impl<C: Pairing> SecretKey<C> {
36    /// Generate a secret key from a `csprng`. NB: This fixes the generators to
37    /// be those defined by the library.
38    pub fn generate<T>(n: usize, csprng: &mut T) -> SecretKey<C>
39    where
40        T: Rng, {
41        let mut ys: Vec<C::ScalarField> = Vec::with_capacity(n);
42        for _i in 0..n {
43            ys.push(C::generate_scalar(csprng));
44        }
45
46        SecretKey {
47            g: C::G1::one_point(),
48            g_tilda: C::G2::one_point(),
49            ys,
50            x: C::generate_scalar(csprng),
51        }
52    }
53
54    pub fn sign_known_message<T>(
55        &self,
56        message: &KnownMessage<C>,
57        csprng: &mut T,
58    ) -> Result<Signature<C>, SignatureError>
59    where
60        T: Rng, {
61        let ys = &self.ys;
62        let ms = &message.0;
63        if ms.len() > ys.len() {
64            return Err(SignatureError(SecretKeyLengthError));
65        }
66
67        let mut z =
68            ms.iter()
69                .zip(ys.iter())
70                .fold(<C::ScalarField as Field>::zero(), |mut acc, (m, y)| {
71                    let mut r = *m;
72                    r.mul_assign(y);
73                    acc.add_assign(&r);
74                    acc
75                });
76        z.add_assign(&self.x);
77        let h = self.g.mul_by_scalar(&C::generate_scalar(csprng));
78
79        Ok(Signature(h, h.mul_by_scalar(&z)))
80    }
81
82    // FIXME: Should this not require also a AggregateDLog proof that the user knows
83    // the values being commited to?
84    pub fn sign_unknown_message<T>(
85        &self,
86        message: &UnknownMessage<C>,
87        csprng: &mut T,
88    ) -> Signature<C>
89    where
90        T: Rng, {
91        let sk = self.g.mul_by_scalar(&self.x);
92        let r = C::generate_non_zero_scalar(csprng);
93        let a = self.g.mul_by_scalar(&r);
94        let xmr = sk.plus_point(message).mul_by_scalar(&r);
95        Signature(a, xmr)
96    }
97}
98
99#[cfg(test)]
100mod tests {
101    use super::*;
102    type Bls12 = ark_ec::models::bls12::Bls12<ark_bls12_381::Config>;
103
104    macro_rules! macro_test_secret_key_to_byte_conversion {
105        ($function_name:ident, $pairing_type:path) => {
106            #[test]
107            pub fn $function_name() {
108                let mut csprng = thread_rng();
109                for i in 0..20 {
110                    let val = SecretKey::<$pairing_type>::generate(i, &mut csprng);
111                    let res_val2 = serialize_deserialize(&val);
112                    assert!(res_val2.is_ok());
113                    let val2 = res_val2.unwrap();
114                    assert_eq!(val2, val);
115                }
116            }
117        };
118    }
119
120    macro_test_secret_key_to_byte_conversion!(secret_key_to_byte_conversion_bls12_381, Bls12);
121}