1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
// Copyright (c) Facebook, Inc. and its affiliates.
//
// This source code is licensed under the MIT license found in the
// LICENSE file in the root directory of this source tree.
use crate::integer_arith::scalar::Scalar;
use crate::rqpoly::RqPoly;
use crate::Serializable;
use crate::FVCiphertext;

#[cfg(test)]
use crate::FV;
#[cfg(test)]
use crate::integer_arith::ArithUtils;
#[cfg(test)]
use crate::traits::*;

use std::convert::TryInto;

impl Serializable for Scalar {
  fn to_bytes(&self) -> std::vec::Vec<u8> {
    let bytes = self.rep().to_be_bytes();
    let mut vec: Vec<u8> = vec![0; 8];
    vec.copy_from_slice(&bytes);
    vec
  }
  fn from_bytes(bytes: &std::vec::Vec<u8>) -> Self {
    let a: u64 = u64::from_be_bytes(bytes.as_slice().try_into().unwrap());
    Scalar::new(a)
  }
}

impl<T> Serializable for RqPoly<T>
where
  T: Serializable + Clone,
{
  fn to_bytes(&self) -> std::vec::Vec<u8> {
    let mut vec: Vec<u8> = Vec::new();
    // push in the is ntt form.
    vec.push(self.is_ntt_form as u8);
    for i in 0..self.coeffs.len() {
      let mut bytes = self.coeffs[i].to_bytes();
      vec.append(&mut bytes);
    }
    vec
  }
  fn from_bytes(bytes: &std::vec::Vec<u8>) -> Self {
    let mut coeffs = Vec::new();
    let is_ntt_form  = bytes[0] != 0;
    let mut  i : usize = 1;
    while i + 8 <= bytes.len() {
      coeffs.push(T::from_bytes(&bytes[i..i+8].to_vec()));
      i += 8;
    }
    RqPoly::new(&coeffs, is_ntt_form)
  }
}

impl<T> Serializable for FVCiphertext<T>
where
  T: Serializable + Clone,
{
  fn to_bytes(&self) -> std::vec::Vec<u8> {
    let mut ct0_bytes = self.0.to_bytes();
    let mut ct1_bytes = self.1.to_bytes();
    ct0_bytes.append(&mut ct1_bytes);
    ct0_bytes
  }
  fn from_bytes(bytes: &std::vec::Vec<u8>) -> Self {
    let twon = bytes.len();
    let n = twon / 2;
    (RqPoly::from_bytes(&bytes[0..n].to_vec()),RqPoly::from_bytes(&bytes[n..twon].to_vec()))
  }
}

#[cfg(test)]
mod tests {
  use super::*;
  #[test]
  fn test_scalar_serialization() {
    let c = Scalar::new(2);
    let bytes = c.to_bytes();
    let deserialized_c = Scalar::from_bytes(&bytes);
    assert_eq!(c, deserialized_c);
  }

  #[test]
  fn test_rqpoly_serialization() {
    let mut coeffs = Vec::<Scalar>::new();
    for i in 0..4 {
      coeffs.push(Scalar::from_u64_raw(i));
    }
    let testpoly = RqPoly::<Scalar>::new(&coeffs, false);
    let bytes = testpoly.to_bytes();
    let deserialized = RqPoly::<Scalar>::from_bytes(&bytes);
    assert_eq!(testpoly, deserialized);
  }

  #[test]
  fn test_fvciphertext_serialization(){
    // test ciphertext serialization
    let fv = FV::<Scalar>::default_2048();
    let (pk, _) = fv.generate_keypair();
    let mut v = vec![0; fv.n];
    for i in 0..fv.n {
        v[i] = i as u8;
    }
    // encrypt v
    let ct = fv.encrypt(&v, &pk);
    let bytes = ct.to_bytes();
    let ct_deserialized = FVCiphertext::from_bytes(&bytes);
    assert_eq!(ct_deserialized, ct);
  }
}