1#![doc = include_str!("../README.md")]
2#![cfg_attr(not(feature = "std"), no_std)]
3
4#[cfg(feature = "std")]
5use std::fmt;
6
7#[cfg(feature = "pure-rust")]
8mod pure_rust;
9#[cfg(feature = "pure-rust")]
10pub use pure_rust::*;
11
12#[cfg(not(feature = "pure-rust"))]
13mod c;
14#[cfg(not(feature = "pure-rust"))]
15pub use c::*;
16
17#[derive(Debug, Clone, Copy, Eq, PartialEq)]
18pub enum Error {
19 InvalidTag,
20}
21
22#[cfg(feature = "std")]
23impl fmt::Display for Error {
24 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
25 match self {
26 Error::InvalidTag => write!(f, "Invalid tag"),
27 }
28 }
29}
30
31#[cfg(feature = "std")]
32impl std::error::Error for Error {}
33
34pub mod compat;
35
36#[cfg(test)]
37mod tests;
38
39#[cfg(test)]
40mod basic_tests {
41
42 #[test]
43 #[cfg(feature = "std")]
44 fn test_aegis() {
45 use crate::aegis128l::Aegis128L;
46
47 let m = b"Ladies and Gentlemen of the class of '99: If I could offer you only one tip for the future, sunscreen would be it.";
48 let ad = b"Comment numero un";
49 let key = b"YELLOW SUBMARINE";
50 let nonce = [0u8; 16];
51
52 let (c, tag) = Aegis128L::<16>::new(key, &nonce).encrypt(m, ad);
53 let expected_c = [
54 137, 147, 98, 134, 30, 108, 100, 90, 185, 139, 110, 255, 169, 201, 98, 232, 138, 159,
55 166, 71, 169, 80, 96, 205, 2, 109, 22, 101, 71, 138, 231, 79, 130, 148, 159, 175, 131,
56 148, 166, 200, 180, 159, 139, 138, 80, 104, 188, 50, 89, 53, 204, 111, 12, 212, 196,
57 143, 98, 25, 129, 118, 132, 115, 95, 13, 232, 167, 13, 59, 19, 143, 58, 59, 42, 206,
58 238, 139, 2, 251, 194, 222, 185, 59, 143, 116, 231, 175, 233, 67, 229, 11, 219, 127,
59 160, 215, 89, 217, 109, 89, 76, 225, 102, 118, 69, 94, 252, 2, 69, 205, 251, 65, 159,
60 177, 3, 101,
61 ];
62 let expected_tag = [
63 16, 244, 133, 167, 76, 40, 56, 136, 6, 235, 61, 139, 252, 7, 57, 150,
64 ];
65 assert_eq!(c, expected_c);
66 assert_eq!(tag, expected_tag);
67
68 let m2 = Aegis128L::<16>::new(key, &nonce)
69 .decrypt(&c, &tag, ad)
70 .unwrap();
71 assert_eq!(m2, m);
72 }
73
74 #[test]
75 #[cfg(feature = "std")]
76 fn test_aegis_in_place() {
77 use crate::aegis128l::Aegis128L;
78
79 let m = b"Ladies and Gentlemen of the class of '99: If I could offer you only one tip for the future, sunscreen would be it.";
80 let ad = b"Comment numero un";
81 let key = b"YELLOW SUBMARINE";
82 let nonce = [0u8; 16];
83
84 let mut mc = m.to_vec();
85 let tag = Aegis128L::<16>::new(key, &nonce).encrypt_in_place(&mut mc, ad);
86 let expected_mc = [
87 137, 147, 98, 134, 30, 108, 100, 90, 185, 139, 110, 255, 169, 201, 98, 232, 138, 159,
88 166, 71, 169, 80, 96, 205, 2, 109, 22, 101, 71, 138, 231, 79, 130, 148, 159, 175, 131,
89 148, 166, 200, 180, 159, 139, 138, 80, 104, 188, 50, 89, 53, 204, 111, 12, 212, 196,
90 143, 98, 25, 129, 118, 132, 115, 95, 13, 232, 167, 13, 59, 19, 143, 58, 59, 42, 206,
91 238, 139, 2, 251, 194, 222, 185, 59, 143, 116, 231, 175, 233, 67, 229, 11, 219, 127,
92 160, 215, 89, 217, 109, 89, 76, 225, 102, 118, 69, 94, 252, 2, 69, 205, 251, 65, 159,
93 177, 3, 101,
94 ];
95 let expected_tag = [
96 16, 244, 133, 167, 76, 40, 56, 136, 6, 235, 61, 139, 252, 7, 57, 150,
97 ];
98 assert_eq!(mc, expected_mc);
99 assert_eq!(tag, expected_tag);
100
101 Aegis128L::<16>::new(key, &nonce)
102 .decrypt_in_place(&mut mc, &tag, ad)
103 .unwrap();
104 assert_eq!(mc, m);
105 }
106
107 #[cfg(feature = "std")]
108 #[test]
109 fn test_aegis_tag256() {
110 use crate::aegis128l::Aegis128L;
111
112 let m = b"Ladies and Gentlemen of the class of '99: If I could offer you only one tip for the future, sunscreen would be it.";
113 let ad = b"Comment numero un";
114 let key = b"YELLOW SUBMARINE";
115 let nonce = [0u8; 16];
116
117 let (c, tag) = Aegis128L::<32>::new(key, &nonce).encrypt(m, ad);
118 let m2 = Aegis128L::<32>::new(key, &nonce)
119 .decrypt(&c, &tag, ad)
120 .unwrap();
121 assert_eq!(m2, m);
122 }
123
124 #[cfg(feature = "std")]
125 #[test]
126 fn test_aegis256() {
127 use crate::aegis256::Aegis256;
128
129 let m = b"Ladies and Gentlemen of the class of '99: If I could offer you only one tip for the future, sunscreen would be it.";
130 let ad = b"Comment numero un";
131 let key = b"YELLOW SUBMARINEyellow submarine";
132 let nonce = [0u8; 32];
133
134 let (c, tag) = Aegis256::<16>::new(key, &nonce).encrypt(m, ad);
135 let expected_c = [
136 62, 90, 21, 90, 245, 182, 17, 214, 55, 102, 124, 12, 140, 5, 78, 233, 79, 134, 10, 29,
137 103, 105, 233, 197, 238, 49, 221, 109, 44, 245, 42, 101, 43, 204, 250, 251, 9, 111, 4,
138 6, 190, 106, 238, 190, 80, 100, 12, 203, 168, 27, 250, 240, 222, 50, 155, 250, 247, 76,
139 26, 233, 228, 18, 17, 187, 52, 229, 159, 66, 12, 62, 120, 255, 42, 90, 14, 50, 243,
140 148, 197, 107, 194, 159, 186, 95, 69, 120, 85, 99, 212, 193, 142, 67, 74, 194, 34, 196,
141 9, 135, 148, 118, 215, 39, 44, 71, 146, 241, 247, 72, 50, 60, 16, 52, 156, 226,
142 ];
143 let expected_tag = [
144 89, 198, 229, 213, 31, 223, 43, 199, 193, 71, 4, 63, 201, 114, 129, 176,
145 ];
146 assert_eq!(c, expected_c);
147 assert_eq!(tag, expected_tag);
148
149 let m2 = Aegis256::<16>::new(key, &nonce)
150 .decrypt(&c, &tag, ad)
151 .unwrap();
152 assert_eq!(m2, m);
153 }
154
155 #[cfg(feature = "std")]
156 #[test]
157 fn test_aegis128l_mac() {
158 use crate::aegis128l::Aegis128LMac;
159
160 let key = b"YELLOW SUBMARINE";
161 let mut st: Aegis128LMac<16> = Aegis128LMac::new(key);
162 let mut st2 = st.clone();
163 let expected_mac: [u8; 16] = [
164 123, 30, 49, 201, 62, 248, 169, 183, 13, 58, 122, 174, 41, 128, 214, 160,
165 ];
166 st.update(b"a");
167 st.verify(&expected_mac).unwrap();
168 st2.update(b"a");
169 st2.verify(&expected_mac).unwrap();
170 }
171}