qfall_math/integer_mod_q/mat_zq/
serialize.rs

1// Copyright © 2023 Marvin Beckmann
2//
3// This file is part of qFALL-math.
4//
5// qFALL-math is free software: you can redistribute it and/or modify it under
6// the terms of the Mozilla Public License Version 2.0 as published by the
7// Mozilla Foundation. See <https://mozilla.org/en-US/MPL/2.0/>.
8
9//! This module contains implementations of functions
10//! important for serialization such as the [`Serialize`] and [`Deserialize`] trait.
11//!
12//! The explicit functions contain the documentation.
13
14use super::MatZq;
15use crate::macros::serialize::{deserialize, serialize};
16use core::fmt;
17use serde::{
18    Deserialize, Serialize,
19    de::{Error, MapAccess, Unexpected, Visitor},
20    ser::SerializeStruct,
21};
22use std::str::FromStr;
23
24serialize!("matrix", MatZq);
25deserialize!("matrix", Matrix, MatZq);
26
27#[cfg(test)]
28mod test_serialize {
29    use crate::integer_mod_q::MatZq;
30    use std::str::FromStr;
31
32    /// Tests whether the serialization of a positive [`MatZq`] works.
33    #[test]
34    fn serialize_output_positive() {
35        let mat_poly_str = "[[17, 42],[1, 17]] mod 57";
36        let mat_poly_z = MatZq::from_str(mat_poly_str).unwrap();
37        let cmp_str = format!("{{\"matrix\":\"{mat_poly_str}\"}}");
38
39        assert_eq!(cmp_str, serde_json::to_string(&mat_poly_z).unwrap());
40    }
41
42    /// Tests whether the serialization of a negative [`MatZq`] works.
43    #[test]
44    fn serialize_output_negative() {
45        let mat_poly_str = "[[-17, -42, 1],[-13, -5, -42]] mod 57";
46        let mat_poly_z = MatZq::from_str(mat_poly_str).unwrap();
47        let cmp_str = "{\"matrix\":\"[[40, 15, 1],[44, 52, 15]] mod 57\"}";
48
49        assert_eq!(cmp_str, serde_json::to_string(&mat_poly_z).unwrap());
50    }
51
52    /// Tests whether the serialization of a positive large [`MatZq`] works.
53    #[test]
54    fn serialize_output_positive_large() {
55        let mat_poly_str = format!("[[3, 17, {}, 1, 2, 13, 5]] mod {}", u64::MAX - 1, u64::MAX);
56        let mat_poly_z = MatZq::from_str(&mat_poly_str).unwrap();
57        let cmp_str = format!("{{\"matrix\":\"{mat_poly_str}\"}}");
58
59        assert_eq!(cmp_str, serde_json::to_string(&mat_poly_z).unwrap());
60    }
61
62    /// Tests whether the serialization of a negative large [`MatZq`] works.
63    #[test]
64    fn serialize_output_negative_large() {
65        let mat_poly_str = format!(
66            "[[3, -{}, -{}, 1, 2, 13, 5]] mod {}",
67            u64::MAX - 58,
68            u64::MAX - 1,
69            u64::MAX
70        );
71        let mat_poly_z = MatZq::from_str(&mat_poly_str).unwrap();
72        let cmp_str = format!(
73            "{{\"matrix\":\"[[3, 58, 1, 1, 2, 13, 5]] mod {}\"}}",
74            u64::MAX
75        );
76
77        assert_eq!(cmp_str, serde_json::to_string(&mat_poly_z).unwrap());
78    }
79}
80
81#[cfg(test)]
82mod test_deserialize {
83    use crate::integer_mod_q::MatZq;
84    use std::str::FromStr;
85
86    /// Tests whether the deserialization of a positive [`MatZq`] works.
87    #[test]
88    fn deserialize_positive() {
89        let mat_poly_str = "[[17, 42],[1, 17]] mod 57";
90        let cmp_str = format!("{{\"matrix\":\"{mat_poly_str}\"}}");
91
92        let mat_poly_z = MatZq::from_str(mat_poly_str).unwrap();
93        assert_eq!(mat_poly_z, serde_json::from_str(&cmp_str).unwrap());
94    }
95
96    /// Tests whether the deserialization of a negative [`MatZq`] works.
97    #[test]
98    fn deserialize_negative() {
99        let mat_poly_str = "[[-17, -42, 1],[-13, -5, -42]] mod 57";
100        let cmp_str = format!("{{\"matrix\":\"{mat_poly_str}\"}}");
101
102        let mat_poly_z = MatZq::from_str(mat_poly_str).unwrap();
103        assert_eq!(mat_poly_z, serde_json::from_str(&cmp_str).unwrap());
104    }
105
106    /// Tests whether the deserialization of a positive large [`MatZq`] works.
107    #[test]
108    fn deserialize_positive_large() {
109        let mat_poly_str = format!(
110            "[[3, -17, {}, 1, 2, -13, 5]] mod {}",
111            u64::MAX - 1,
112            u64::MAX
113        );
114        let cmp_str = format!("{{\"matrix\":\"{mat_poly_str}\"}}");
115
116        let mat_poly_z = MatZq::from_str(&mat_poly_str).unwrap();
117        assert_eq!(mat_poly_z, serde_json::from_str(&cmp_str).unwrap());
118    }
119
120    /// Tests whether the deserialization of a negative large [`MatZq`] works.
121    #[test]
122    fn deserialize_negative_large() {
123        let mat_poly_str = format!(
124            "[[3, -17, -{}, 1, 2, -13, 5]] mod {}",
125            u64::MAX - 1,
126            u64::MAX
127        );
128        let cmp_str = format!("{{\"matrix\":\"{mat_poly_str}\"}}");
129
130        let mat_poly_z = MatZq::from_str(&mat_poly_str).unwrap();
131        assert_eq!(mat_poly_z, serde_json::from_str(&cmp_str).unwrap());
132    }
133
134    /// Tests whether no fields `matrix` provided yield an error
135    #[test]
136    fn no_field_matrix() {
137        let a: Result<MatZq, serde_json::Error> =
138            serde_json::from_str("{{\"tree\":\"{[[2, 17, 42]] mod 57}\"}}");
139        assert!(a.is_err());
140
141        let b: Result<MatZq, serde_json::Error> = serde_json::from_str("{{}}");
142        assert!(b.is_err());
143    }
144
145    /// Tests whether too many fields yield an error
146    #[test]
147    fn too_many_fields() {
148        let a: Result<MatZq, serde_json::Error> = serde_json::from_str(
149            "{{\"tree\":\"{[[[2, 17, 42]] mod 57}\", \"matrix\":\"{[[2, 17, 42]] mod 57}\"}}",
150        );
151        assert!(a.is_err());
152
153        let b: Result<MatZq, serde_json::Error> = serde_json::from_str(
154            "{{\"matrix\":\"{[[1, 1]] mod 3}\", \"matrix\":\"{[[2, 17, 42]] mod 57}\"}}",
155        );
156        assert!(b.is_err());
157    }
158
159    /// Tests whether a negative modulus yields an error
160    #[test]
161    fn negative_modulus() {
162        let a: Result<MatZq, serde_json::Error> =
163            serde_json::from_str("{{\"matrix\":\"{[[2, 17, 42]] mod -57}\"}}");
164        assert!(a.is_err());
165    }
166
167    /// Tests whether a missing modulus yields an error
168    #[test]
169    fn missing_modulus() {
170        let a: Result<MatZq, serde_json::Error> =
171            serde_json::from_str("{{\"matrix\":\"{[[2, 17, 42]]}\"}}");
172        assert!(a.is_err());
173    }
174}