module_lwe/keygen.rs
1use polynomial_ring::Polynomial;
2use std::collections::HashMap;
3use crate::utils::{Parameters, add_vec, mul_mat_vec_simple, gen_small_vector, gen_uniform_matrix,compress};
4
5/// Generate public and secret keys for the ring-LWE cryptosystem
6/// # Arguments
7/// * `params` - Parameters for the ring-LWE cryptosystem
8/// * `seed` - random seed
9/// # Returns
10/// * `((a, t), sk)` - public key (a, t) and secret key (sk)
11/// # Example
12/// ```
13/// let params = module_lwe::utils::Parameters::default();
14/// let (pk, sk) = module_lwe::keygen::keygen(¶ms, None);
15/// ```
16pub fn keygen(
17 params: &Parameters,
18 seed: Option<u64> //random seed
19) -> ((Vec<Vec<Polynomial<i64>>>, Vec<Polynomial<i64>>), Vec<Polynomial<i64>>) {
20 let (n,q,k,f,omega) = (params.n, params.q, params.k, ¶ms.f, params.omega);
21 //Generate a public and secret key
22 let a = gen_uniform_matrix(n, k, q, seed);
23 let sk = gen_small_vector(n, k, seed);
24 let e = gen_small_vector(n, k, seed);
25 let t = add_vec(&mul_mat_vec_simple(&a, &sk, q, &f, omega), &e, q, &f);
26
27 //Return public key (a, t) and secret key (sk) as a 2-tuple
28 ((a, t), sk)
29}
30
31/// Generate public and secret keys for the ring-LWE cryptosystem and return them as a HashMap
32/// They are serialized and base64 encoded
33/// # Arguments
34/// * `params` - Parameters for the ring-LWE cryptosystem
35/// * `seed` - random seed
36/// # Returns
37/// * `keys` - HashMap containing the public and secret keys as base64 encoded strings
38/// # Example
39/// ```
40/// let params = module_lwe::utils::Parameters::default();
41/// let keys = module_lwe::keygen::keygen_string(¶ms, None);
42/// ```
43pub fn keygen_string(params: &Parameters, seed: Option<u64>) -> HashMap<String, String> {
44 // Generate public and secret keys
45 let (pk, sk) = keygen(params, seed);
46
47 // Convert the public key to a flattened list of coefficients
48 let mut pk_coeffs: Vec<i64> = pk.0
49 .iter()
50 .flat_map(|row| {
51 row.iter().flat_map(|poly| {
52 let mut coeffs = poly.coeffs().to_vec();
53 coeffs.resize(params.n, 0); // Resize to include leading zeros up to size `n`
54 coeffs
55 })
56 })
57 .collect();
58
59 pk_coeffs.extend(
60 pk.1.iter()
61 .flat_map(|poly| {
62 let mut coeffs = poly.coeffs().to_vec();
63 coeffs.resize(params.n, 0); // Resize to include leading zeros up to size `n`
64 coeffs
65 })
66 );
67
68 // Convert the secret key to a flattened list of coefficients
69 let sk_coeffs: Vec<i64> = sk
70 .iter()
71 .flat_map(|poly| {
72 let mut coeffs = poly.coeffs().to_vec();
73 coeffs.resize(params.n, 0); // Resize to include leading zeros up to size `n`
74 coeffs
75 })
76 .collect();
77
78 // Store the Base64 encoded keys in a HashMap
79 let mut keys: HashMap<String, String> = HashMap::new();
80 keys.insert(String::from("secret"), compress(&sk_coeffs));
81 keys.insert(String::from("public"), compress(&pk_coeffs));
82
83 keys
84}