coconut_crypto/setup/keypair/
secret.rs1use alloc::vec::Vec;
2
3use ark_ff::{
4 field_hashers::{DefaultFieldHasher, HashToField},
5 PrimeField,
6};
7use ark_serialize::*;
8use ark_std::rand::RngCore;
9use serde::{Deserialize, Serialize};
10use serde_with::serde_as;
11use utils::{misc::le_bytes_iter, serde_utils::ArkObjectBytes};
12use zeroize::{Zeroize, ZeroizeOnDrop};
13
14#[cfg(feature = "parallel")]
15use rayon::prelude::*;
16
17use crate::helpers::{n_rand, rand, FullDigest};
18use utils::{aliases::SyncIfParallel, concat_slices, join};
19
20#[serde_as]
22#[derive(
23 Clone,
24 Debug,
25 PartialEq,
26 Eq,
27 Serialize,
28 Deserialize,
29 CanonicalSerialize,
30 CanonicalDeserialize,
31 Zeroize,
32 ZeroizeOnDrop,
33)]
34pub struct SecretKey<F: PrimeField> {
35 #[serde_as(as = "ArkObjectBytes")]
36 pub x: F,
37 #[serde_as(as = "Vec<ArkObjectBytes>")]
38 pub y: Vec<F>,
39}
40
41impl<F: PrimeField> SecretKey<F> {
42 pub const X_SALT: &'static [u8] = b"PS-SIG-X-KEYGEN-SALT";
43 pub const Y_SALT: &'static [u8] = b"PS-SIG-Y-KEYGEN-SALT";
44
45 pub fn rand<R: RngCore>(rng: &mut R, message_count: u32) -> Self {
47 let x = rand(rng);
48 let y = n_rand(rng, message_count as usize).collect();
49
50 Self { x, y }
51 }
52
53 pub fn from_seed<D>(seed: &[u8], message_count: u32) -> Self
55 where
56 D: FullDigest + SyncIfParallel,
57 {
58 let new_hasher = <DefaultFieldHasher<D> as HashToField<F>>::new;
59
60 let (x, y) = join!(
61 new_hasher(Self::X_SALT)
62 .hash_to_field(seed, 1)
63 .pop()
64 .unwrap(),
65 {
66 let hasher = new_hasher(Self::Y_SALT);
67
68 le_bytes_iter(message_count)
69 .map(|ctr| concat_slices!(seed, ctr))
70 .map(|seed| hasher.hash_to_field(&seed, 1).pop().unwrap())
71 .collect()
72 }
73 );
74
75 Self { x, y }
76 }
77
78 pub fn supported_message_count(&self) -> usize {
80 self.y.len()
81 }
82}
83
84#[cfg(test)]
85mod tests {
86 use super::*;
87 use ark_bls12_381::Bls12_381;
88 use ark_ec::pairing::Pairing;
89 use blake2::Blake2b512;
90
91 type Fr = <Bls12_381 as Pairing>::ScalarField;
92
93 #[test]
94 fn from_seed() {
95 let seed = b"test-seed";
96 let other_seed = b"other-seed";
97
98 assert_eq!(
99 SecretKey::<Fr>::from_seed::<Blake2b512>(seed, 10),
100 SecretKey::<Fr>::from_seed::<Blake2b512>(seed, 10),
101 );
102
103 assert!(
104 SecretKey::<Fr>::from_seed::<Blake2b512>(seed, 10)
105 != SecretKey::<Fr>::from_seed::<Blake2b512>(other_seed, 10)
106 );
107
108 assert_eq!(
109 SecretKey::<Fr>::from_seed::<Blake2b512>(seed, 10).y[0..9],
110 SecretKey::<Fr>::from_seed::<Blake2b512>(seed, 9).y,
111 );
112 }
113}