rusty_saber/
pack_unpack.rs

1use crate::saber_params::*;
2use crate::U16;
3use std::convert::TryFrom;
4use std::error::Error;
5use std::num::Wrapping;
6
7/// Serialize coefficients of polynomial `data` into bytestream `bytes`.
8/// Used in Saber's encryption step.
9pub(crate) fn polt2bs(bytes: &mut [u8; SABER_SCALEBYTES_KEM], data: [U16; SABER_N]) {
10    let (mut offset_byte, mut offsetdata): (usize, usize);
11
12    if cfg!(SABER_L_IS_2) {
13        for j in 0..(SABER_N / 8) as usize {
14            offset_byte = 3 * j;
15            offsetdata = 8 * j;
16            bytes[offset_byte] = ((data[offsetdata] & U16!(0x7))
17                | ((data[offsetdata + 1] & U16!(0x7)) << 3)
18                | ((data[offsetdata + 2] & U16!(0x3)) << 6))
19                .0 as u8;
20            bytes[offset_byte + 1] = (((data[offsetdata + 2] >> 2) & U16!(0x01))
21                | ((data[offsetdata + 3] & U16!(0x7)) << 1)
22                | ((data[offsetdata + 4] & U16!(0x7)) << 4)
23                | (((data[offsetdata + 5]) & U16!(0x01)) << 7))
24                .0 as u8;
25            bytes[offset_byte + 2] = (((data[offsetdata + 5] >> 1) & U16!(0x03))
26                | ((data[offsetdata + 6] & U16!(0x7)) << 2)
27                | ((data[offsetdata + 7] & U16!(0x7)) << 5))
28                .0 as u8;
29        }
30    } else if cfg!(SABER_L_IS_3) {
31        for j in 0..(SABER_N / 2) as usize {
32            offset_byte = j;
33            offsetdata = 2 * j;
34            bytes[offset_byte] = ((data[offsetdata] & U16!(0x0f))
35                | ((data[offsetdata + 1] & U16!(0x0f)) << 4))
36                .0 as u8;
37        }
38    } else if cfg!(SABER_L_IS_4) {
39        for j in 0..(SABER_N / 4) as usize {
40            offset_byte = 3 * j;
41            offsetdata = 4 * j;
42            bytes[offset_byte] = ((data[offsetdata] & U16!(0x3f))
43                | ((data[offsetdata + 1] & U16!(0x03)) << 6))
44                .0 as u8;
45            bytes[offset_byte + 1] = (((data[offsetdata + 1] >> 2) & U16!(0x0f))
46                | ((data[offsetdata + 2] & U16!(0x0f)) << 4))
47                .0 as u8;
48            bytes[offset_byte + 2] = (((data[offsetdata + 2] >> 4) & U16!(0x03))
49                | ((data[offsetdata + 3] & U16!(0x3f)) << 2))
50                .0 as u8;
51        }
52    }
53}
54
55/// Deserialize bytestream `bytes` into polynomial coefficients `data`.
56/// Used during Saber's decryption step.
57pub(crate) fn bs2polt(bytes: [u8; SABER_SCALEBYTES_KEM], data: &mut [U16; SABER_N]) {
58    let (mut offset_byte, mut offsetdata): (usize, usize);
59
60    if cfg!(SABER_L_IS_2) {
61        for j in 0..(SABER_N / 8) as usize {
62            offset_byte = 3 * j;
63            offsetdata = 8 * j;
64            data[offsetdata] = U16!((bytes[offset_byte]) as u16 & 0x07);
65            data[offsetdata + 1] = U16!(((bytes[offset_byte]) as u16 >> 3) & 0x07);
66            data[offsetdata + 2] = U16!(
67                (((bytes[offset_byte]) as u16 >> 6) & 0x03)
68                    | (((bytes[offset_byte + 1]) as u16 & 0x01) << 2)
69            );
70            data[offsetdata + 3] = U16!(((bytes[offset_byte + 1]) as u16 >> 1) & 0x07);
71            data[offsetdata + 4] = U16!(((bytes[offset_byte + 1]) as u16 >> 4) & 0x07);
72            data[offsetdata + 5] = U16!(
73                (((bytes[offset_byte + 1]) as u16 >> 7) & 0x01)
74                    | (((bytes[offset_byte + 2]) as u16 & 0x03) << 1)
75            );
76            data[offsetdata + 6] = U16!((bytes[offset_byte + 2] as u16 >> 2) & 0x07);
77            data[offsetdata + 7] = U16!((bytes[offset_byte + 2] as u16 >> 5) & 0x07);
78        }
79    } else if cfg!(SABER_L_IS_3) {
80        for j in 0..(SABER_N / 2) as usize {
81            offset_byte = j;
82            offsetdata = 2 * j;
83            data[offsetdata] = U16!((bytes[offset_byte] & 0x0f) as u16);
84            data[offsetdata + 1] = U16!(((bytes[offset_byte] >> 4) & 0x0f) as u16);
85        }
86    } else if cfg!(SABER_L_IS_4) {
87        for j in 0..(SABER_N / 4) as usize {
88            offset_byte = 3 * j;
89            offsetdata = 4 * j;
90            data[offsetdata] = U16!((bytes[offset_byte] & 0x3f) as u16);
91            data[offsetdata + 1] = U16!(
92                (((bytes[offset_byte] >> 6) & 0x03) | ((bytes[offset_byte + 1] & 0x0f) << 2))
93                    as u16
94            );
95            data[offsetdata + 2] = U16!(
96                ((bytes[offset_byte + 1] >> 4) | ((bytes[offset_byte + 2] & 0x03) << 4)) as u16
97            );
98            data[offsetdata + 3] = U16!((bytes[offset_byte + 2] >> 2) as u16);
99        }
100    }
101}
102
103/// Serialize coefficients of polynomial `data` into bytestream `bytes`.
104/// Used during Saber's key generation step.
105fn polq2bs(bytes: &mut [u8; SABER_POLYBYTES], data: [U16; SABER_N]) {
106    let (mut offset_byte, mut offsetdata): (usize, usize);
107
108    for j in 0..(SABER_N / 8) as usize {
109        offset_byte = 13 * j;
110        offsetdata = 8 * j;
111        bytes[offset_byte] = (data[offsetdata] & U16!(0xff)).0 as u8;
112        bytes[offset_byte + 1] = (((data[offsetdata] >> 8) & U16!(0x1f))
113            | ((data[offsetdata + 1] & U16!(0x07)) << 5))
114            .0 as u8;
115        bytes[offset_byte + 2] = ((data[offsetdata + 1] >> 3) & U16!(0xff)).0 as u8;
116        bytes[offset_byte + 3] = (((data[offsetdata + 1] >> 11) & U16!(0x03))
117            | ((data[offsetdata + 2] & U16!(0x3f)) << 2))
118            .0 as u8;
119        bytes[offset_byte + 4] = (((data[offsetdata + 2] >> 6) & U16!(0x7f))
120            | ((data[offsetdata + 3] & U16!(0x01)) << 7))
121            .0 as u8;
122        bytes[offset_byte + 5] = ((data[offsetdata + 3] >> 1) & U16!(0xff)).0 as u8;
123        bytes[offset_byte + 6] = (((data[offsetdata + 3] >> 9) & U16!(0x0f))
124            | ((data[offsetdata + 4] & U16!(0x0f)) << 4))
125            .0 as u8;
126        bytes[offset_byte + 7] = ((data[offsetdata + 4] >> 4) & U16!(0xff)).0 as u8;
127        bytes[offset_byte + 8] = (((data[offsetdata + 4] >> 12) & U16!(0x01))
128            | ((data[offsetdata + 5] & U16!(0x7f)) << 1))
129            .0 as u8;
130        bytes[offset_byte + 9] = (((data[offsetdata + 5] >> 7) & U16!(0x3f))
131            | ((data[offsetdata + 6] & U16!(0x03)) << 6))
132            .0 as u8;
133        bytes[offset_byte + 10] = ((data[offsetdata + 6] >> 2) & U16!(0xff)).0 as u8;
134        bytes[offset_byte + 11] = (((data[offsetdata + 6] >> 10) & U16!(0x07))
135            | ((data[offsetdata + 7] & U16!(0x1f)) << 3))
136            .0 as u8;
137        bytes[offset_byte + 12] = ((data[offsetdata + 7] >> 5) & U16!(0xff)).0 as u8;
138    }
139}
140
141/// Deserialize bytestream `bytes` into polynomial coefficients `data`.
142/// Used during Saber's key generation step.
143fn bs2polq(bytes: [u8; SABER_POLYBYTES], data: &mut [U16; SABER_N]) {
144    let (mut offset_byte, mut offsetdata): (usize, usize);
145
146    for j in 0..(SABER_N / 8) as usize {
147        offset_byte = 13 * j;
148        offsetdata = 8 * j;
149        data[offsetdata] = U16!(
150            (bytes[offset_byte] as u16 & (0xff)) | ((bytes[offset_byte + 1] as u16 & 0x1f) << 8)
151        );
152        data[offsetdata + 1] = U16!(
153            (bytes[offset_byte + 1] as u16 >> 5 & (0x07))
154                | ((bytes[offset_byte + 2] as u16 & 0xff) << 3)
155                | ((bytes[offset_byte + 3] as u16 & 0x03) << 11)
156        );
157        data[offsetdata + 2] = U16!(
158            (bytes[offset_byte + 3] as u16 >> 2 & (0x3f))
159                | ((bytes[offset_byte + 4] as u16 & 0x7f) << 6)
160        );
161        data[offsetdata + 3] = U16!(
162            (bytes[offset_byte + 4] as u16 >> 7 & (0x01))
163                | ((bytes[offset_byte + 5] as u16 & 0xff) << 1)
164                | ((bytes[offset_byte + 6] as u16 & 0x0f) << 9)
165        );
166        data[offsetdata + 4] = U16!(
167            (bytes[offset_byte + 6] as u16 >> 4 & (0x0f))
168                | ((bytes[offset_byte + 7] as u16 & 0xff) << 4)
169                | ((bytes[offset_byte + 8] as u16 & 0x01) << 12)
170        );
171        data[offsetdata + 5] = U16!(
172            (bytes[offset_byte + 8] as u16 >> 1 & (0x7f))
173                | ((bytes[offset_byte + 9] as u16 & 0x3f) << 7)
174        );
175        data[offsetdata + 6] = U16!(
176            (bytes[offset_byte + 9] as u16 >> 6 & (0x03))
177                | ((bytes[offset_byte + 10] as u16 & 0xff) << 2)
178                | ((bytes[offset_byte + 11] as u16 & 0x07) << 10)
179        );
180        data[offsetdata + 7] = U16!(
181            (bytes[offset_byte + 11] as u16 >> 3 & (0x1f))
182                | ((bytes[offset_byte + 12] as u16 & 0xff) << 5)
183        );
184    }
185}
186
187/// Serialize coefficients of polynomial `data` into bytestream `bytes`.
188/// Used during Saber's key generation and encryption step.
189fn polp2bs(bytes: &mut [u8; SABER_POLYCOMPRESSEDBYTES], data: [U16; SABER_N]) {
190    let (mut offset_byte, mut offsetdata): (usize, usize);
191
192    for j in 0..(SABER_N / 4) as usize {
193        offset_byte = 5 * j;
194        offsetdata = 4 * j;
195        bytes[offset_byte] = (data[offsetdata] & U16!(0xff)).0 as u8;
196        bytes[offset_byte + 1] = (((data[offsetdata] >> 8) & U16!(0x03))
197            | ((data[offsetdata + 1] & U16!(0x3f)) << 2))
198            .0 as u8;
199        bytes[offset_byte + 2] = (((data[offsetdata + 1] >> 6) & U16!(0x0f))
200            | ((data[offsetdata + 2] & U16!(0x0f)) << 4))
201            .0 as u8;
202        bytes[offset_byte + 3] = (((data[offsetdata + 2] >> 4) & U16!(0x3f))
203            | ((data[offsetdata + 3] & U16!(0x03)) << 6))
204            .0 as u8;
205        bytes[offset_byte + 4] = ((data[offsetdata + 3] >> 2) & U16!(0xff)).0 as u8;
206    }
207}
208
209/// Deserialize bytestream `bytes` into polynomial coefficients `data`.
210/// Used during Saber's decryption step.
211fn bs2polp(bytes: [u8; SABER_POLYCOMPRESSEDBYTES], data: &mut [U16; SABER_N]) {
212    let (mut offset_byte, mut offsetdata): (usize, usize);
213
214    for j in 0..(SABER_N / 4) as usize {
215        offset_byte = 5 * j;
216        offsetdata = 4 * j;
217        data[offsetdata] = U16!(
218            (bytes[offset_byte] as u16 & (0xff)) | ((bytes[offset_byte + 1] as u16 & 0x03) << 8)
219        );
220        data[offsetdata + 1] = U16!(
221            ((bytes[offset_byte + 1] as u16 >> 2) & (0x3f))
222                | ((bytes[offset_byte + 2] as u16 & 0x0f) << 6)
223        );
224        data[offsetdata + 2] = U16!(
225            ((bytes[offset_byte + 2] as u16 >> 4) & (0x0f))
226                | ((bytes[offset_byte + 3] as u16 & 0x3f) << 4)
227        );
228        data[offsetdata + 3] = U16!(
229            ((bytes[offset_byte + 3] as u16 >> 6) & (0x03))
230                | ((bytes[offset_byte + 4] as u16 & 0xff) << 2)
231        );
232    }
233}
234
235/// Applies `polq2bs` to a vector (i.e. module).
236/// Takes a vector of polynomials `data` and returns the serialized `bytes`.
237pub(crate) fn polvecq2bs(
238    bytes: &mut [u8; SABER_POLYVECBYTES],
239    data: [[U16; SABER_N]; SABER_L],
240) -> Result<(), Box<dyn Error>> {
241    for j in 0..SABER_L {
242        let tmp = <&mut [u8; SABER_POLYBYTES]>::try_from(
243            &mut bytes[(j * SABER_POLYBYTES)..((j + 1) * SABER_POLYBYTES)],
244        )?;
245
246        polq2bs(tmp, data[j]);
247    }
248    Ok(())
249}
250
251/// Applies `bs2polq` to a vector (i.e. module).
252/// Takes serialized `bytes` and deserializes them to a vector of polynomials `data`.
253pub(crate) fn bs2polvecq(bytes: [u8; SABER_POLYVECBYTES], data: &mut [[U16; SABER_N]; SABER_L]) {
254    for j in 0..SABER_L {
255        let mut tmp: [u8; SABER_POLYBYTES] = [0; SABER_POLYBYTES];
256        tmp.copy_from_slice(&bytes[(j * SABER_POLYBYTES)..((j + 1) * SABER_POLYBYTES)]);
257        bs2polq(tmp, &mut data[j]);
258    }
259}
260
261/// Applies `polp2bs` to a vector (i.e. module).
262/// Takes a vector of polynomials `data` and returns the serialized `bytes`.
263pub(crate) fn polvecp2bs(
264    bytes: &mut [u8; SABER_POLYVECCOMPRESSEDBYTES],
265    data: [[U16; SABER_N]; SABER_L],
266) -> Result<(), Box<dyn Error>> {
267    for j in 0..SABER_L {
268        let tmp = <&mut [u8; SABER_POLYCOMPRESSEDBYTES]>::try_from(
269            &mut bytes[(j * SABER_POLYCOMPRESSEDBYTES)..((j + 1) * SABER_POLYCOMPRESSEDBYTES)],
270        )?;
271        polp2bs(tmp, data[j]);
272    }
273    Ok(())
274}
275
276/// Applies `bs2polp` to a vector (i.e. module).
277/// Takes serialized `bytes` and deserializes them to a vector of polynomials `data`.
278pub(crate) fn bs2polvecp(
279    bytes: [u8; SABER_POLYVECCOMPRESSEDBYTES],
280    data: &mut [[U16; SABER_N]; SABER_L],
281) {
282    for j in 0..SABER_L {
283        let mut tmp: [u8; SABER_POLYCOMPRESSEDBYTES] = [0; SABER_POLYCOMPRESSEDBYTES];
284        tmp.copy_from_slice(
285            &bytes[(j * SABER_POLYCOMPRESSEDBYTES)..((j + 1) * SABER_POLYCOMPRESSEDBYTES)],
286        );
287        bs2polp(tmp, &mut data[j]);
288    }
289}
290
291/// Serializes the message-to-encrypt `data` to a bytestream `bytes`.
292/// Used in Saber's decryption step.
293pub(crate) fn polmsg2bs(bytes: &mut [u8; SABER_KEYBYTES], data: [U16; SABER_N]) {
294    for b in bytes.iter_mut() {
295        *b = 0;
296    }
297
298    for j in 0..SABER_KEYBYTES {
299        for i in 0..8 {
300            bytes[j] |= ((data[j * 8 + i] & U16!(0x01)) << i).0 as u8;
301        }
302    }
303}
304
305/// Deserializes bytestream `bytes` to the message-to-encrypt `data`.
306/// Used in Saber's encryption step.
307pub(crate) fn bs2polmsg(bytes: [u8; SABER_KEYBYTES], data: &mut [U16; SABER_N]) {
308    for j in 0..SABER_KEYBYTES {
309        for i in 0..8 {
310            data[j * 8 + i] = U16!(((bytes[j] >> i) & 0x01) as u16);
311        }
312    }
313}
314
315#[cfg(test)]
316mod tests {
317    use crate::link_c_reference::{
318        BS2POLVECp, BS2POLVECq, BS2POLmsg, BS2POLp, BS2POLq, POLVECp2BS, POLVECq2BS, POLmsg2BS,
319        POLp2BS, POLq2BS, BS2POLT, POLT2BS,
320    };
321    use crate::pack_unpack::*;
322    use rand::Rng;
323
324    #[test]
325    fn test_polt2bs() {
326        const SIZE_BYTES: usize = SABER_SCALEBYTES_KEM;
327        const SIZE_DATA: usize = SABER_N;
328
329        let mut rng = rand::thread_rng();
330        let mut bytes = [0; SIZE_BYTES];
331
332        let mut data = [U16!(0); SIZE_DATA];
333
334        let mut ind = 0;
335        while ind < data.len() {
336            data[ind] = rng.gen();
337            ind += 1;
338        }
339        ind = 0;
340        while ind < bytes.len() {
341            bytes[ind] = rng.gen();
342            ind += 1;
343        }
344
345        //to check if equal
346        let mut copy_bytes: [u8; SIZE_BYTES] = [0; SIZE_BYTES];
347        copy_bytes.copy_from_slice(&bytes[..]);
348        let mut copy_data: [u16; SIZE_DATA] = [0; SIZE_DATA];
349        wrappedu162u16(&mut copy_data[..], &data[..]);
350
351        unsafe {
352            POLT2BS(&mut copy_bytes, &mut copy_data);
353        };
354
355        polt2bs(&mut bytes, data);
356
357        assert_eq!(copy_bytes, bytes);
358        let mut check = [0u16; SIZE_DATA];
359        wrappedu162u16(&mut check, &data[..]);
360        assert_eq!(copy_data, check);
361    }
362
363    #[test]
364    fn test_bs2polt() {
365        const SIZE_BYTES: usize = SABER_SCALEBYTES_KEM;
366        const SIZE_DATA: usize = SABER_N;
367
368        let mut rng = rand::thread_rng();
369        let mut bytes = [0; SIZE_BYTES];
370
371        let mut data = [U16!(0); SIZE_DATA];
372
373        let mut ind = 0;
374        while ind < data.len() {
375            data[ind] = rng.gen();
376            ind += 1;
377        }
378        ind = 0;
379        while ind < bytes.len() {
380            bytes[ind] = rng.gen();
381            ind += 1;
382        }
383
384        //to check if equal
385        let mut copy_bytes: [u8; SIZE_BYTES] = [0; SIZE_BYTES];
386        copy_bytes.copy_from_slice(&bytes[..]);
387        let mut copy_data: [u16; SIZE_DATA] = [0; SIZE_DATA];
388        wrappedu162u16(&mut copy_data[..], &data[..]);
389        unsafe {
390            BS2POLT(&mut copy_bytes, &mut copy_data);
391        };
392
393        bs2polt(bytes, &mut data);
394
395        assert_eq!(copy_bytes, bytes);
396        let mut check = [0u16; SIZE_DATA];
397        wrappedu162u16(&mut check[..], &data[..]);
398        assert_eq!(copy_data, check);
399    }
400
401    #[test]
402    fn test_polq2bs() {
403        const SIZE_BYTES: usize = SABER_POLYBYTES;
404        const SIZE_DATA: usize = SABER_N;
405
406        let mut rng = rand::thread_rng();
407        let mut bytes = [0; SIZE_BYTES];
408
409        let mut data = [U16!(0); SIZE_DATA];
410
411        let mut ind = 0;
412        while ind < data.len() {
413            data[ind] = rng.gen();
414            ind += 1;
415        }
416        ind = 0;
417        while ind < bytes.len() {
418            bytes[ind] = rng.gen();
419            ind += 1;
420        }
421
422        //to check if equal
423        let mut copy_bytes: [u8; SIZE_BYTES] = [0; SIZE_BYTES];
424        copy_bytes.copy_from_slice(&bytes[..]);
425        let mut copy_data: [u16; SIZE_DATA] = [0; SIZE_DATA];
426        //copy_data.copy_from_slice(&data[..]);
427        wrappedu162u16(&mut copy_data[..], &data[..]);
428        unsafe {
429            POLq2BS(&mut copy_bytes, &mut copy_data);
430        };
431
432        polq2bs(&mut bytes, data);
433        assert_eq!(copy_bytes, bytes);
434        let mut check = [0u16; SIZE_DATA];
435        wrappedu162u16(&mut check[..], &data[..]);
436        assert_eq!(copy_data, check);
437    }
438
439    #[test]
440    fn test_bs2polq() {
441        const SIZE_BYTES: usize = SABER_POLYBYTES;
442        const SIZE_DATA: usize = SABER_N;
443
444        let mut rng = rand::thread_rng();
445        let mut bytes = [0; SIZE_BYTES];
446
447        let mut data = [U16!(0); SIZE_DATA];
448
449        let mut ind = 0;
450        while ind < data.len() {
451            data[ind] = rng.gen();
452            ind += 1;
453        }
454        ind = 0;
455        while ind < bytes.len() {
456            bytes[ind] = rng.gen();
457            ind += 1;
458        }
459
460        //to check if equal
461        let mut copy_bytes: [u8; SIZE_BYTES] = [0; SIZE_BYTES];
462        copy_bytes.copy_from_slice(&bytes[..]);
463        let mut copy_data: [u16; SIZE_DATA] = [0; SIZE_DATA];
464        wrappedu162u16(&mut copy_data[..], &data[..]);
465        unsafe {
466            BS2POLq(&mut copy_bytes, &mut copy_data);
467        };
468
469        bs2polq(bytes, &mut data);
470
471        assert_eq!(copy_bytes, bytes);
472        let mut check = [0u16; SIZE_DATA];
473        wrappedu162u16(&mut check[..], &data[..]);
474        assert_eq!(copy_data, check);
475    }
476
477    #[test]
478    fn test_polp2bs() {
479        const SIZE_BYTES: usize = SABER_POLYCOMPRESSEDBYTES;
480        const SIZE_DATA: usize = SABER_N;
481
482        let mut rng = rand::thread_rng();
483        let mut bytes = [0; SIZE_BYTES];
484
485        let mut data = [U16!(0); SIZE_DATA];
486
487        let mut ind = 0;
488        while ind < data.len() {
489            data[ind] = rng.gen();
490            ind += 1;
491        }
492        ind = 0;
493        while ind < bytes.len() {
494            bytes[ind] = rng.gen();
495            ind += 1;
496        }
497
498        //to check if equal
499        let mut copy_bytes: [u8; SIZE_BYTES] = [0; SIZE_BYTES];
500        copy_bytes.copy_from_slice(&bytes[..]);
501        let mut copy_data: [u16; SIZE_DATA] = [0; SIZE_DATA];
502        wrappedu162u16(&mut copy_data[..], &data[..]);
503        unsafe {
504            POLp2BS(&mut copy_bytes, &mut copy_data);
505        };
506
507        polp2bs(&mut bytes, data);
508
509        assert_eq!(copy_bytes, bytes);
510        let mut check = [0u16; SIZE_DATA];
511        wrappedu162u16(&mut check[..], &data[..]);
512        assert_eq!(copy_data, check);
513    }
514
515    #[test]
516    fn test_bs2polp() {
517        const SIZE_BYTES: usize = SABER_POLYCOMPRESSEDBYTES;
518        const SIZE_DATA: usize = SABER_N;
519
520        let mut rng = rand::thread_rng();
521        let mut bytes = [0; SIZE_BYTES];
522
523        let mut data = [U16!(0); SIZE_DATA];
524
525        let mut ind = 0;
526        while ind < data.len() {
527            data[ind] = rng.gen();
528            ind += 1;
529        }
530        ind = 0;
531        while ind < bytes.len() {
532            bytes[ind] = rng.gen();
533            ind += 1;
534        }
535
536        //to check if equal
537        let mut copy_bytes: [u8; SIZE_BYTES] = [0; SIZE_BYTES];
538        copy_bytes.copy_from_slice(&bytes[..]);
539        let mut copy_data: [u16; SIZE_DATA] = [0; SIZE_DATA];
540        wrappedu162u16(&mut copy_data[..], &data[..]);
541        unsafe {
542            BS2POLp(&mut copy_bytes, &mut copy_data);
543        };
544
545        bs2polp(bytes, &mut data);
546
547        assert_eq!(copy_bytes, bytes);
548        let mut check = [0u16; SIZE_DATA];
549        wrappedu162u16(&mut check[..], &data[..]);
550        assert_eq!(copy_data, check);
551    }
552
553    #[test]
554    fn test_polvecq2bs() {
555        const SIZE_BYTES: usize = SABER_POLYVECBYTES;
556        const SIZE_DATA: usize = SABER_N;
557        const SIZE_DATA2: usize = SABER_L;
558
559        let mut rng = rand::thread_rng();
560        let mut bytes = [0; SIZE_BYTES];
561
562        let mut data = [[U16!(0); SIZE_DATA]; SIZE_DATA2];
563
564        let mut ind = 0;
565        while ind < data.len() {
566            let mut ind2 = 0;
567            while ind2 < data[ind].len() {
568                data[ind][ind2] = rng.gen();
569                ind2 += 1;
570            }
571            ind += 1;
572        }
573        ind = 0;
574        while ind < bytes.len() {
575            bytes[ind] = rng.gen();
576            ind += 1;
577        }
578
579        //to check if equal
580        let mut copy_bytes: [u8; SIZE_BYTES] = [0; SIZE_BYTES];
581        copy_bytes.copy_from_slice(&bytes[..]);
582        let mut copy_data: [[u16; SIZE_DATA]; SIZE_DATA2] = [[0; SIZE_DATA]; SIZE_DATA2];
583        for i in 0..SIZE_DATA2 {
584            wrappedu162u16(&mut copy_data[i][..], &data[i][..]);
585        }
586        unsafe {
587            POLVECq2BS(&mut copy_bytes, &mut copy_data);
588        };
589
590        polvecq2bs(&mut bytes, data).expect("polvecq2bs failed!");
591
592        assert_eq!(copy_bytes, bytes);
593        let mut check = [[0u16; SIZE_DATA]; SIZE_DATA2];
594        for i in 0..SIZE_DATA2 {
595            wrappedu162u16(&mut check[i][..], &data[i][..]);
596        }
597        assert_eq!(copy_data, check);
598    }
599
600    #[test]
601    fn test_bs2polvecq() {
602        const SIZE_BYTES: usize = SABER_POLYVECBYTES;
603        const SIZE_DATA: usize = SABER_N;
604        const SIZE_DATA2: usize = SABER_L;
605
606        let mut rng = rand::thread_rng();
607        let mut bytes = [0; SIZE_BYTES];
608
609        let mut data = [[U16!(0); SIZE_DATA]; SIZE_DATA2];
610
611        let mut ind = 0;
612        while ind < data.len() {
613            let mut ind2 = 0;
614            while ind2 < data[ind].len() {
615                data[ind][ind2] = rng.gen();
616                ind2 += 1;
617            }
618            ind += 1;
619        }
620        ind = 0;
621        while ind < bytes.len() {
622            bytes[ind] = rng.gen();
623            ind += 1;
624        }
625
626        //to check if equal
627        let mut copy_bytes: [u8; SIZE_BYTES] = [0; SIZE_BYTES];
628        copy_bytes.copy_from_slice(&bytes[..]);
629        let mut copy_data: [[u16; SIZE_DATA]; SIZE_DATA2] = [[0; SIZE_DATA]; SIZE_DATA2];
630        for i in 0..SIZE_DATA2 {
631            wrappedu162u16(&mut copy_data[i][..], &data[i][..]);
632        }
633        unsafe {
634            BS2POLVECq(&mut copy_bytes, &mut copy_data);
635        };
636
637        bs2polvecq(bytes, &mut data);
638
639        assert_eq!(copy_bytes, bytes);
640        let mut check = [[0u16; SIZE_DATA]; SIZE_DATA2];
641        for i in 0..SIZE_DATA2 {
642            wrappedu162u16(&mut check[i][..], &data[i][..]);
643        }
644        assert_eq!(copy_data, check);
645    }
646
647    #[test]
648    fn test_polvecp2bs() {
649        const SIZE_BYTES: usize = SABER_POLYVECCOMPRESSEDBYTES;
650        const SIZE_DATA: usize = SABER_N;
651        const SIZE_DATA2: usize = SABER_L;
652
653        let mut rng = rand::thread_rng();
654        let mut bytes = [0; SIZE_BYTES];
655
656        let mut data = [[U16!(0); SIZE_DATA]; SIZE_DATA2];
657
658        let mut ind = 0;
659        while ind < data.len() {
660            let mut ind2 = 0;
661            while ind2 < data[ind].len() {
662                data[ind][ind2] = rng.gen();
663                ind2 += 1;
664            }
665            ind += 1;
666        }
667        ind = 0;
668        while ind < bytes.len() {
669            bytes[ind] = rng.gen();
670            ind += 1;
671        }
672
673        //to check if equal
674        let mut copy_bytes: [u8; SIZE_BYTES] = [0; SIZE_BYTES];
675        copy_bytes.copy_from_slice(&bytes[..]);
676        let mut copy_data: [[u16; SIZE_DATA]; SIZE_DATA2] = [[0; SIZE_DATA]; SIZE_DATA2];
677        for i in 0..SIZE_DATA2 {
678            wrappedu162u16(&mut copy_data[i][..], &data[i][..]);
679        }
680        unsafe {
681            POLVECp2BS(&mut copy_bytes, &mut copy_data);
682        };
683
684        polvecp2bs(&mut bytes, data).expect("polvecp2bs failed!");
685
686        assert_eq!(copy_bytes, bytes);
687        let mut check = [[0u16; SIZE_DATA]; SIZE_DATA2];
688        for i in 0..SIZE_DATA2 {
689            wrappedu162u16(&mut check[i][..], &data[i][..]);
690        }
691        assert_eq!(copy_data, check);
692    }
693
694    #[test]
695    fn test_bs2polvecp() {
696        const SIZE_BYTES: usize = SABER_POLYVECCOMPRESSEDBYTES;
697        const SIZE_DATA: usize = SABER_N;
698        const SIZE_DATA2: usize = SABER_L;
699
700        let mut rng = rand::thread_rng();
701        let mut bytes = [0; SIZE_BYTES];
702
703        let mut data = [[U16!(0); SIZE_DATA]; SIZE_DATA2];
704
705        let mut ind = 0;
706        while ind < data.len() {
707            let mut ind2 = 0;
708            while ind2 < data[ind].len() {
709                data[ind][ind2] = rng.gen();
710                ind2 += 1;
711            }
712            ind += 1;
713        }
714        ind = 0;
715        while ind < bytes.len() {
716            bytes[ind] = rng.gen();
717            ind += 1;
718        }
719
720        //to check if equal
721        let mut copy_bytes: [u8; SIZE_BYTES] = [0; SIZE_BYTES];
722        copy_bytes.copy_from_slice(&bytes[..]);
723        let mut copy_data: [[u16; SIZE_DATA]; SIZE_DATA2] = [[0; SIZE_DATA]; SIZE_DATA2];
724        for i in 0..SIZE_DATA2 {
725            wrappedu162u16(&mut copy_data[i][..], &data[i][..]);
726        }
727        unsafe {
728            BS2POLVECp(&mut copy_bytes, &mut copy_data);
729        };
730
731        bs2polvecp(bytes, &mut data);
732
733        assert_eq!(copy_bytes, bytes);
734        let mut check = [[0u16; SIZE_DATA]; SIZE_DATA2];
735        for i in 0..SIZE_DATA2 {
736            wrappedu162u16(&mut check[i][..], &data[i][..]);
737        }
738        assert_eq!(copy_data, check);
739    }
740
741    #[test]
742    fn test_bs2polmsg() {
743        const SIZE_BYTES: usize = SABER_KEYBYTES;
744        const SIZE_DATA: usize = SABER_N;
745
746        let mut rng = rand::thread_rng();
747        let mut bytes = [0; SIZE_BYTES];
748
749        let mut data = [U16!(0); SIZE_DATA];
750
751        let mut ind = 0;
752        while ind < data.len() {
753            data[ind] = rng.gen();
754            ind += 1;
755        }
756        ind = 0;
757        while ind < bytes.len() {
758            bytes[ind] = rng.gen();
759            ind += 1;
760        }
761
762        //to check if equal
763        let mut copy_bytes: [u8; SIZE_BYTES] = [0; SIZE_BYTES];
764        copy_bytes.copy_from_slice(&bytes[..]);
765        let mut copy_data: [u16; SIZE_DATA] = [0; SIZE_DATA];
766        wrappedu162u16(&mut copy_data[..], &data[..]);
767        unsafe {
768            BS2POLmsg(&mut copy_bytes, &mut copy_data);
769        };
770
771        bs2polmsg(bytes, &mut data);
772
773        assert_eq!(copy_bytes, bytes);
774        let mut check = [0u16; SIZE_DATA];
775        wrappedu162u16(&mut check[..], &data[..]);
776        assert_eq!(copy_data, check);
777    }
778
779    #[test]
780    fn test_polmsg2bs() {
781        const SIZE_BYTES: usize = SABER_KEYBYTES;
782        const SIZE_DATA: usize = SABER_N;
783
784        let mut rng = rand::thread_rng();
785        let mut bytes = [0; SIZE_BYTES];
786
787        let mut data = [U16!(0); SIZE_DATA];
788
789        let mut ind = 0;
790        while ind < data.len() {
791            data[ind] = rng.gen();
792            ind += 1;
793        }
794        ind = 0;
795        while ind < bytes.len() {
796            bytes[ind] = rng.gen();
797            ind += 1;
798        }
799
800        //to check if equal
801        let mut copy_bytes: [u8; SIZE_BYTES] = [0; SIZE_BYTES];
802        copy_bytes.copy_from_slice(&bytes[..]);
803        let mut copy_data: [u16; SIZE_DATA] = [0; SIZE_DATA];
804        wrappedu162u16(&mut copy_data[..], &data[..]);
805        unsafe {
806            POLmsg2BS(&mut copy_bytes, &mut copy_data);
807        };
808
809        polmsg2bs(&mut bytes, data);
810
811        assert_eq!(copy_bytes, bytes);
812        let mut check = [0u16; SIZE_DATA];
813        wrappedu162u16(&mut check[..], &data[..]);
814        assert_eq!(copy_data, check);
815    }
816}