Skip to content

Commit f9ec107

Browse files
use base64 encoding for sk, pk, ct
use base64 encoding (binary serialization of vectors of integers followed by encoding) for secret key, public key, and ciphertext
1 parent 0c082c6 commit f9ec107

File tree

5 files changed

+72
-54
lines changed

5 files changed

+72
-54
lines changed

Cargo.toml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@ rand = "0.8.5"
1515
rand_distr = "0.4.3"
1616
ntt = "0.1.9"
1717
ring-lwe = "0.1.6"
18+
base64 = "0.21"
19+
bincode = "1.3"
1820

1921
[dev-dependencies]
2022
criterion = "0.5.1"

src/decrypt.rs

Lines changed: 29 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
use polynomial_ring::Polynomial;
22
use ring_lwe::utils::{polysub,nearest_int};
33
use crate::utils::{Parameters,mul_vec_simple};
4+
use base64::{engine::general_purpose, Engine as _};
5+
use bincode;
46

57
/// Decrypt a ciphertext
68
/// # Arguments
@@ -46,55 +48,59 @@ pub fn decrypt(
4648
/// * `params` - Parameters for the ring-LWE cryptosystem
4749
/// # Returns
4850
/// * `message_string` - decrypted message string
49-
pub fn decrypt_string(sk_string: &String, ciphertext_string: &String, params: &Parameters) -> String {
50-
51-
//get parameters
51+
pub fn decrypt_string(sk_string: &String, ciphertext_base64: &String, params: &Parameters) -> String {
52+
// Get parameters
5253
let (n, k) = (params.n, params.k);
53-
54-
// Convert the secret key string into a Vec<Polynomial<i64>>
55-
let sk_array: Vec<i64> = sk_string.split(',')
56-
.filter_map(|s| s.parse().ok())
57-
.collect();
54+
55+
// Base64 decode the secret key string
56+
let sk_bytes = general_purpose::STANDARD.decode(sk_string).expect("Failed to decode base64 secret key");
57+
58+
// Deserialize the secret key from bytes (it was serialized with bincode)
59+
let sk_array: Vec<i64> = bincode::deserialize(&sk_bytes).expect("Failed to deserialize secret key");
60+
61+
// Convert the secret key into a Vec<Polynomial<i64>>
5862
let sk: Vec<Polynomial<i64>> = sk_array.chunks(n)
5963
.map(|chunk| Polynomial::new(chunk.to_vec()))
6064
.collect();
61-
62-
// Parse ciphertext into u and v
63-
let ciphertext_list: Vec<i64> = ciphertext_string.split(',')
64-
.filter_map(|s| s.parse().ok())
65-
.collect();
65+
66+
// Base64 decode the ciphertext string
67+
let ciphertext_bytes = general_purpose::STANDARD.decode(ciphertext_base64).expect("Failed to decode ciphertext");
68+
69+
// Deserialize the ciphertext list from the decoded bytes
70+
let ciphertext_list: Vec<i64> = bincode::deserialize(&ciphertext_bytes).expect("Failed to deserialize ciphertext");
71+
6672
let block_size = (k + 1) * n;
6773
let num_blocks = ciphertext_list.len() / block_size;
6874

6975
let mut message_binary = vec![];
70-
76+
7177
for i in 0..num_blocks {
7278
// Get u and v for this block
7379
let u_array = &ciphertext_list[i * block_size..i * block_size + k * n];
7480
let v_array = &ciphertext_list[i * block_size + k * n..(i + 1) * block_size];
75-
81+
7682
let u: Vec<Polynomial<i64>> = u_array.chunks(n)
7783
.map(|chunk| Polynomial::new(chunk.to_vec()))
7884
.collect();
7985
let v = Polynomial::new(v_array.to_vec());
80-
86+
8187
// Decrypt the ciphertext
8288
let mut m_b = decrypt(&sk, &u, &v, &params);
83-
m_b.resize(n,0);
84-
89+
m_b.resize(n, 0);
90+
8591
message_binary.extend(m_b);
8692
}
87-
93+
8894
// Group the bits back into bytes (8 bits each)
8995
let byte_chunks: Vec<String> = message_binary.chunks(8)
9096
.map(|chunk| chunk.iter().map(|bit| bit.to_string()).collect())
9197
.collect();
92-
98+
9399
// Convert each binary string back into a character
94100
let message_string: String = byte_chunks.iter()
95101
.map(|byte| char::from_u32(i64::from_str_radix(byte, 2).unwrap() as u32).unwrap())
96102
.collect();
97-
98-
//trim the null characters \0 = '00000000' from the end
103+
104+
// Trim the null characters \0 = '00000000' from the end
99105
message_string.trim_end_matches('\0').to_string()
100-
}
106+
}

src/encrypt.rs

Lines changed: 19 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
use polynomial_ring::Polynomial;
22
use ring_lwe::utils::{polyadd,polysub,nearest_int};
33
use crate::utils::{Parameters, add_vec, mul_mat_vec_simple, transpose, mul_vec_simple, gen_small_vector};
4+
use base64::{engine::general_purpose, Engine as _};
5+
use bincode;
46

57
/// Encrypt a message using the ring-LWE cryptosystem
68
/// # Arguments
@@ -43,6 +45,8 @@ pub fn encrypt(
4345
// Compute u = a^T * r + e_1 mod q
4446
let u = add_vec(&mul_mat_vec_simple(&transpose(a), &r, q, f, omega), &e1, q, f);
4547

48+
println!("t: {:?}", t);
49+
4650
// Compute v = t * r + e_2 - m mod q
4751
let v = polysub(&polyadd(&mul_vec_simple(t, &r, q, &f, omega), &e2, q, f), &m, q, f);
4852

@@ -51,12 +55,12 @@ pub fn encrypt(
5155

5256
/// function to encrypt a message given a public_key string
5357
/// # Arguments
54-
/// * `pk_string` - public key string
55-
/// * `message_string` - message string
58+
/// * `pk_string` - public key string in base64 encoding
59+
/// * `message_string` - message string in base64 encoding
5660
/// * `params` - Parameters for the ring-LWE cryptosystem
5761
/// * `seed` - random seed
5862
/// # Returns
59-
/// * `ciphertext_str` - ciphertext string
63+
/// * `ciphertext_str` - ciphertext string, base64 encoded
6064
/// # Example
6165
/// ```
6266
/// let params = module_lwe::utils::Parameters::default();
@@ -67,14 +71,16 @@ pub fn encrypt(
6771
/// let ciphertext_string = module_lwe::encrypt::encrypt_string(&pk_string, &message_string, &params, None);
6872
/// ```
6973
pub fn encrypt_string(pk_string: &String, message_string: &String, params: &Parameters, seed: Option<u64>) -> String {
70-
71-
//get parameters
74+
// Get parameters
7275
let (n, k) = (params.n, params.k);
7376

74-
// Parse public key
77+
// Decode the base64-encoded public key string
78+
let pk_bytes = general_purpose::STANDARD.decode(pk_string).expect("Failed to decode base64 public key");
7579

76-
let pk_list: Vec<i64> = pk_string.split(',').map(|x| x.parse::<i64>().unwrap()).collect();
80+
// Deserialize the public key from bytes (it was serialized with bincode)
81+
let pk_list: Vec<i64> = bincode::deserialize(&pk_bytes).expect("Failed to deserialize public key");
7782

83+
// Parse the public key
7884
let a: Vec<Vec<Polynomial<i64>>> = pk_list[..k * k * n]
7985
.chunks(k * n)
8086
.map(|chunk| {
@@ -93,7 +99,7 @@ pub fn encrypt_string(pk_string: &String, message_string: &String, params: &Para
9399
.flat_map(|byte| (0..8).rev().map(move |i| ((byte >> i) & 1) as i64))
94100
.collect();
95101

96-
// Break message into blocks, including the last partial block if necessary
102+
// Break message into blocks
97103
let message_blocks: Vec<Vec<i64>> = message_binary
98104
.chunks(n) // Divide the binary message into chunks of size `n`
99105
.map(|chunk| chunk.to_vec()) // Convert each chunk into a vector
@@ -111,12 +117,14 @@ pub fn encrypt_string(pk_string: &String, message_string: &String, params: &Para
111117
})
112118
.collect();
113119
let mut v_flattened: Vec<i64> = v.coeffs().to_vec();
114-
v_flattened.resize(n,0);
120+
v_flattened.resize(n, 0);
115121
ciphertext_list.extend(u_flattened);
116122
ciphertext_list.extend(v_flattened);
117123
}
118124

119-
let ciphertext_str = ciphertext_list.iter().map(|x| x.to_string()).collect::<Vec<String>>().join(",");
125+
// Serialize and Base64 encode the ciphertext
126+
let ciphertext_bytes = bincode::serialize(&ciphertext_list).expect("Failed to serialize ciphertext");
127+
let ciphertext_base64 = general_purpose::STANDARD.encode(ciphertext_bytes);
120128

121-
ciphertext_str
129+
ciphertext_base64
122130
}

src/keygen.rs

Lines changed: 20 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
use polynomial_ring::Polynomial;
22
use std::collections::HashMap;
33
use crate::utils::{Parameters, add_vec, mul_mat_vec_simple, gen_small_vector, gen_uniform_matrix};
4+
use base64::{engine::general_purpose, Engine as _};
5+
use bincode;
46

57
/// Generate public and secret keys for the ring-LWE cryptosystem
68
/// # Arguments
@@ -29,22 +31,22 @@ pub fn keygen(
2931
}
3032

3133
/// Generate public and secret keys for the ring-LWE cryptosystem and return them as a HashMap
34+
/// They are serialized and base64 encoded
3235
/// # Arguments
3336
/// * `params` - Parameters for the ring-LWE cryptosystem
3437
/// * `seed` - random seed
3538
/// # Returns
36-
/// * `keys` - HashMap containing the public and secret keys
39+
/// * `keys` - HashMap containing the public and secret keys as base64 encoded strings
3740
/// # Example
3841
/// ```
3942
/// let params = module_lwe::utils::Parameters::default();
4043
/// let keys = module_lwe::keygen::keygen_string(&params, None);
4144
/// ```
4245
pub fn keygen_string(params: &Parameters, seed: Option<u64>) -> HashMap<String, String> {
46+
// Generate public and secret keys
47+
let (pk, sk) = keygen(params, seed);
4348

44-
//generate public, secret keys
45-
let (pk,sk) = keygen(params,seed);
46-
47-
// Convert public key to a flattened list of coefficients
49+
// Convert the public key to a flattened list of coefficients
4850
let mut pk_coeffs: Vec<i64> = pk.0
4951
.iter()
5052
.flat_map(|row| {
@@ -64,7 +66,7 @@ pub fn keygen_string(params: &Parameters, seed: Option<u64>) -> HashMap<String,
6466
})
6567
);
6668

67-
// Convert secret key to a flattened list of coefficients
69+
// Convert the secret key to a flattened list of coefficients
6870
let sk_coeffs: Vec<i64> = sk
6971
.iter()
7072
.flat_map(|poly| {
@@ -74,20 +76,18 @@ pub fn keygen_string(params: &Parameters, seed: Option<u64>) -> HashMap<String,
7476
})
7577
.collect();
7678

77-
// Convert the public/secret key coefficients to a comma-separated string
78-
let pk_coeffs_str = pk_coeffs.iter()
79-
.map(|coef| coef.to_string())
80-
.collect::<Vec<String>>()
81-
.join(",");
82-
let sk_coeffs_str = sk_coeffs.iter()
83-
.map(|coef| coef.to_string())
84-
.collect::<Vec<String>>()
85-
.join(",");
86-
87-
//store the secret/public key in a HashMap
79+
// Serialize the public and secret key coefficients
80+
let pk_bytes = bincode::serialize(&pk_coeffs).expect("Failed to serialize public key coefficients");
81+
let sk_bytes = bincode::serialize(&sk_coeffs).expect("Failed to serialize secret key coefficients");
82+
83+
// Base64 encode the serialized keys
84+
let pk_base64 = general_purpose::STANDARD.encode(pk_bytes);
85+
let sk_base64 = general_purpose::STANDARD.encode(sk_bytes);
86+
87+
// Store the Base64 encoded keys in a HashMap
8888
let mut keys: HashMap<String, String> = HashMap::new();
89-
keys.insert(String::from("secret"), sk_coeffs_str);
90-
keys.insert(String::from("public"), pk_coeffs_str);
91-
89+
keys.insert(String::from("secret"), sk_base64);
90+
keys.insert(String::from("public"), pk_base64);
91+
9292
keys
9393
}

src/utils.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,8 @@ pub fn add_vec(v0: &Vec<Polynomial<i64>>, v1: &Vec<Polynomial<i64>>, modulus: i6
6262
/// # Returns
6363
/// * `result` - polynomial
6464
pub fn mul_vec_simple(v0: &Vec<Polynomial<i64>>, v1: &Vec<Polynomial<i64>>, modulus: i64, poly_mod: &Polynomial<i64>, omega: i64) -> Polynomial<i64> {
65+
println!("v0: {:?}", v0);
66+
println!("v1: {:?}", v1);
6567
assert!(v0.len() == v1.len());
6668
let mut result = Polynomial::new(vec![]);
6769
for i in 0..v0.len() {

0 commit comments

Comments
 (0)