1use rand::Rng;
4
5use crate::modular::mod_q;
6use crate::params::Params;
7
8#[derive(Clone, Debug)]
10pub struct SecretKey {
11 pub s: Vec<u64>,
13 params: Params,
14}
15
16impl SecretKey {
17 pub fn params(&self) -> &Params {
18 &self.params
19 }
20}
21
22#[derive(Clone, Debug)]
25pub struct PublicKey {
26 pub a: Vec<Vec<u64>>,
28 params: Params,
29}
30
31impl PublicKey {
32 pub fn params(&self) -> &Params {
33 &self.params
34 }
35}
36
37fn rand_zq<R: Rng>(rng: &mut R, q: u64) -> u64 {
39 rng.gen_range(0..q)
40}
41
42fn sample_error<R: Rng>(rng: &mut R, bound: i64) -> i64 {
44 if bound <= 0 {
45 return 0;
46 }
47 rng.gen_range(-bound..=bound)
48}
49
50pub fn keygen<R: Rng>(rng: &mut R, params: &Params) -> (SecretKey, PublicKey) {
52 let n = params.n;
53 let m = params.m;
54 let q = params.q;
55 let bound = params.error_bound;
56
57 let t: Vec<u64> = (0..n).map(|_| rand_zq(rng, q)).collect();
59
60 let mut s = vec![1u64];
62 for &ti in &t {
63 s.push(mod_q(-(ti as i64), q));
64 }
65
66 let b_mat: Vec<Vec<u64>> = (0..m)
68 .map(|_| (0..n).map(|_| rand_zq(rng, q)).collect())
69 .collect();
70
71 let e: Vec<i64> = (0..m).map(|_| sample_error(rng, bound)).collect();
72
73 let mut b = vec![0u64; m];
74 for i in 0..m {
75 let mut dot: i64 = 0;
76 for j in 0..n {
77 dot += b_mat[i][j] as i64 * t[j] as i64;
78 }
79 b[i] = mod_q(dot + e[i], q);
80 }
81
82 let mut a = vec![vec![0u64; n + 1]; m];
83 for i in 0..m {
84 a[i][0] = b[i];
85 for j in 0..n {
86 a[i][j + 1] = b_mat[i][j];
87 }
88 }
89
90 (
91 SecretKey {
92 s: s.clone(),
93 params: params.clone(),
94 },
95 PublicKey {
96 a,
97 params: params.clone(),
98 },
99 )
100}