oqs/
macros.rs

1//! Defines macros to implement buffers for public/private keys
2
3/// Implements a buffer for cryptographic objects
4#[macro_export]
5macro_rules! newtype_buffer {
6    ($name: ident, $name_ref: ident) => {
7        /// New owned buffer
8        ///
9        /// Construct the reference version of this type through the algorithm API functions.
10        ///
11        /// Optional support for `serde` if that feature is enabled.
12        #[derive(Debug, Clone, PartialEq, Eq)]
13        #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
14        pub struct $name {
15            bytes: Vec<u8>,
16        }
17
18        impl $name {
19            /// Obtain the contained vector
20            pub fn into_vec(self) -> Vec<u8> {
21                self.bytes
22            }
23        }
24
25        /// Reference version of this type.
26        ///
27        /// Allows for copy-less usage
28        /// Construct it through the algorithm API functions
29        #[derive(Debug, Clone, Copy, PartialEq, Eq)]
30        pub struct $name_ref<'a> {
31            bytes: &'a [u8],
32        }
33
34        impl<'a> $name_ref<'a> {
35            /// Construct a new container around this reference version
36            fn new(bytes: &'a [u8]) -> $name_ref<'a> {
37                $name_ref { bytes }
38            }
39
40            /// Clone this into the owned variant
41            pub fn to_owned(self) -> $name {
42                $name {
43                    bytes: self.bytes.to_vec(),
44                }
45            }
46        }
47
48        impl<'a> From<&'a $name> for $name_ref<'a> {
49            fn from(buf: &'a $name) -> $name_ref<'a> {
50                $name_ref::new(&buf.bytes)
51            }
52        }
53
54        impl<'a> From<&'a $name_ref<'a>> for $name_ref<'a> {
55            fn from(buf: &'a $name_ref) -> $name_ref<'a> {
56                *buf
57            }
58        }
59
60        impl<'a> core::ops::Deref for $name_ref<'a> {
61            type Target = [u8];
62            fn deref(&self) -> &Self::Target {
63                &self.bytes
64            }
65        }
66
67        impl AsRef<[u8]> for $name {
68            fn as_ref(&self) -> &[u8] {
69                self.bytes.as_ref()
70            }
71        }
72
73        impl $name {
74            /// Length in bytes
75            #[allow(clippy::len_without_is_empty)]
76            pub fn len(&self) -> usize {
77                self.bytes.len()
78            }
79        }
80    };
81}
82
83#[cfg(test)]
84mod test {
85    use alloc::vec;
86    use alloc::vec::Vec;
87
88    // necessary for newtype_buffer call
89    #[cfg(feature = "serde")]
90    use serde::{Deserialize, Serialize};
91
92    newtype_buffer!(TestBuf, TestBufRef);
93
94    #[test]
95    fn test_get_reference() {
96        let buf = TestBuf {
97            bytes: vec![1, 2, 3],
98        };
99        assert_eq!(buf.bytes.as_ref() as &[u8], buf.as_ref());
100    }
101
102    #[test]
103    fn test_len() {
104        let buf = TestBuf {
105            bytes: vec![1, 2, 3],
106        };
107        assert_eq!(buf.len(), buf.bytes.len());
108    }
109
110    #[test]
111    fn test_into_vec() {
112        let buf = TestBuf {
113            bytes: vec![1, 2, 3],
114        };
115        assert_eq!(buf.into_vec(), vec![1, 2, 3]);
116    }
117
118    #[test]
119    fn test_to_owned() {
120        let bytes = vec![1, 2, 3];
121        let refbuf = TestBufRef::new(bytes.as_ref());
122        let buf = TestBuf {
123            bytes: bytes.clone(),
124        };
125        assert_eq!(refbuf.to_owned(), buf)
126    }
127}