cupcake/
serialize.rs

1// Copyright (c) Facebook, Inc. and its affiliates.
2//
3// This source code is licensed under the MIT license found in the
4// LICENSE file in the root directory of this source tree.
5use crate::integer_arith::scalar::Scalar;
6use crate::rqpoly::RqPoly;
7use crate::Serializable;
8use crate::FVCiphertext;
9
10#[cfg(test)]
11use crate::FV;
12#[cfg(test)]
13use crate::integer_arith::ArithUtils;
14#[cfg(test)]
15use crate::traits::*;
16
17use std::convert::TryInto;
18
19impl Serializable for Scalar {
20  fn to_bytes(&self) -> std::vec::Vec<u8> {
21    let bytes = self.rep().to_be_bytes();
22    let mut vec: Vec<u8> = vec![0; 8];
23    vec.copy_from_slice(&bytes);
24    vec
25  }
26  fn from_bytes(bytes: &std::vec::Vec<u8>) -> Self {
27    let a: u64 = u64::from_be_bytes(bytes.as_slice().try_into().unwrap());
28    Scalar::new(a)
29  }
30}
31
32impl<T> Serializable for RqPoly<T>
33where
34  T: Serializable + Clone,
35{
36  fn to_bytes(&self) -> std::vec::Vec<u8> {
37    let mut vec: Vec<u8> = vec![self.is_ntt_form as u8];
38    for coeff in &self.coeffs {
39      let mut bytes = coeff.to_bytes();
40      vec.append(&mut bytes);
41    }
42    vec
43  }
44  fn from_bytes(bytes: &std::vec::Vec<u8>) -> Self {
45    let mut coeffs = Vec::new();
46    let is_ntt_form  = bytes[0] != 0;
47    let mut  i : usize = 1;
48    while i + 8 <= bytes.len() {
49      coeffs.push(T::from_bytes(&bytes[i..i+8].to_vec()));
50      i += 8;
51    }
52    RqPoly::new_without_context(&coeffs, is_ntt_form)
53  }
54}
55
56impl<T> Serializable for FVCiphertext<T>
57where
58  T: Serializable + Clone,
59{
60  fn to_bytes(&self) -> std::vec::Vec<u8> {
61    let mut ct0_bytes = self.0.to_bytes();
62    let mut ct1_bytes = self.1.to_bytes();
63    ct0_bytes.append(&mut ct1_bytes);
64    ct0_bytes
65  }
66  fn from_bytes(bytes: &std::vec::Vec<u8>) -> Self {
67    let twon = bytes.len();
68    let n = twon / 2;
69    (RqPoly::from_bytes(&bytes[0..n].to_vec()),RqPoly::from_bytes(&bytes[n..twon].to_vec()))
70  }
71}
72
73#[cfg(test)]
74mod tests {
75  use super::*;
76  #[test]
77  fn test_scalar_serialization() {
78    let c = Scalar::new(2);
79    let bytes = c.to_bytes();
80    let deserialized_c = Scalar::from_bytes(&bytes);
81    assert_eq!(c, deserialized_c);
82  }
83
84  #[test]
85  fn test_rqpoly_serialization() {
86    let mut coeffs = Vec::<Scalar>::new();
87    for i in 0..4 {
88      coeffs.push(Scalar::from_u64_raw(i));
89    }
90    let testpoly = RqPoly::<Scalar>::new_without_context(&coeffs, false);
91    let bytes = testpoly.to_bytes();
92    let deserialized = RqPoly::<Scalar>::from_bytes(&bytes);
93    assert_eq!(testpoly, deserialized);
94  }
95
96  #[test]
97  fn test_fvciphertext_serialization(){
98    // test ciphertext serialization
99    let fv = FV::<Scalar>::default_2048();
100    let (pk, _) = fv.generate_keypair();
101    let mut v = vec![0; fv.n];
102    for i in 0..fv.n {
103        v[i] = i as u8;
104    }
105    // encrypt v
106    let ct = fv.encrypt(&v, &pk);
107    let bytes = ct.to_bytes();
108    let ct_deserialized = FVCiphertext::from_bytes(&bytes);
109    assert_eq!(ct_deserialized, ct);
110  }
111}