qfall_math/integer_mod_q/mat_zq/sample/
uniform.rs1use crate::{
12 integer::Z,
13 integer_mod_q::MatZq,
14 traits::{MatrixDimensions, MatrixSetEntry},
15 utils::sample::uniform::UniformIntegerSampler,
16};
17use std::fmt::Display;
18
19impl MatZq {
20 pub fn sample_uniform(
47 num_rows: impl TryInto<i64> + Display,
48 num_cols: impl TryInto<i64> + Display,
49 modulus: impl Into<Z>,
50 ) -> Self {
51 let modulus: Z = modulus.into();
52 let mut uis = UniformIntegerSampler::init(&modulus).unwrap();
53 let mut matrix = MatZq::new(num_rows, num_cols, modulus);
54
55 for row in 0..matrix.get_num_rows() {
56 for col in 0..matrix.get_num_columns() {
57 let sample = uis.sample();
58 unsafe { matrix.set_entry_unchecked(row, col, sample) };
59 }
60 }
61
62 matrix
63 }
64}
65
66#[cfg(test)]
67mod test_sample_uniform {
68 use crate::traits::{MatrixDimensions, MatrixGetEntry};
69 use crate::{
70 integer::Z,
71 integer_mod_q::{MatZq, Modulus},
72 };
73
74 #[test]
76 fn boundaries_kept_small() {
77 for _ in 0..32 {
78 let matrix = MatZq::sample_uniform(1, 1, 17);
79 let sample: Z = matrix.get_entry(0, 0).unwrap();
80 assert!(Z::ZERO <= sample);
81 assert!(sample < 17);
82 }
83 }
84
85 #[test]
87 fn boundaries_kept_large() {
88 let modulus = Z::from(u64::MAX);
89 for _ in 0..256 {
90 let matrix = MatZq::sample_uniform(1, 1, &modulus);
91 let sample: Z = matrix.get_entry(0, 0).unwrap();
92 assert!(Z::ZERO <= sample);
93 assert!(sample < modulus);
94 }
95 }
96
97 #[should_panic]
100 #[test]
101 fn false_size() {
102 let modulus = Z::from(15);
103
104 let _ = MatZq::sample_uniform(0, 3, &modulus);
105 }
106
107 #[should_panic]
109 #[test]
110 fn invalid_modulus() {
111 let _ = MatZq::sample_uniform(4, 1, 1);
112 }
113
114 #[test]
117 fn availability() {
118 let modulus = Modulus::from(7);
119 let z = Z::from(7);
120
121 let _ = MatZq::sample_uniform(1, 1, 7u8);
122 let _ = MatZq::sample_uniform(1, 1, 7u16);
123 let _ = MatZq::sample_uniform(1, 1, 7u32);
124 let _ = MatZq::sample_uniform(1, 1, 7u64);
125 let _ = MatZq::sample_uniform(1, 1, 7i8);
126 let _ = MatZq::sample_uniform(1, 1, 7i16);
127 let _ = MatZq::sample_uniform(1, 1, 7i32);
128 let _ = MatZq::sample_uniform(1, 1, 7i64);
129 let _ = MatZq::sample_uniform(1, 1, &modulus);
130 let _ = MatZq::sample_uniform(1, 1, &z);
131 }
132
133 #[test]
136 fn matrix_size() {
137 let modulus = Z::from(15);
138
139 let mat_0 = MatZq::sample_uniform(3, 3, &modulus);
140 let mat_1 = MatZq::sample_uniform(4, 1, &modulus);
141 let mat_2 = MatZq::sample_uniform(1, 5, &modulus);
142 let mat_3 = MatZq::sample_uniform(15, 20, &modulus);
143
144 assert_eq!(3, mat_0.get_num_rows());
145 assert_eq!(3, mat_0.get_num_columns());
146 assert_eq!(4, mat_1.get_num_rows());
147 assert_eq!(1, mat_1.get_num_columns());
148 assert_eq!(1, mat_2.get_num_rows());
149 assert_eq!(5, mat_2.get_num_columns());
150 assert_eq!(15, mat_3.get_num_rows());
151 assert_eq!(20, mat_3.get_num_columns());
152 }
153}