Oregami
Repositories/oxedyne/fe2o3

oxedyne/fe2o3/fe2o3_iop_crypto/src/kem.rs

7.0 KiB, 28 runs

created by r1870400018:381, which is this file's identity for as long as the history lasts, whatever it is later renamed to

download · who wrote it · its history

1use oxedyne_fe2o3_core::{
2 prelude::*,
3 alt::{
4 Alt,
5 DefAlt,
6 },
7};
8use oxedyne_fe2o3_namex::{
9 id::{
10 LocalId,
11 InNamex,
12 NamexId,
13 },
14};
15
16/// A Key Exchange Mechanism (KEM) involves the following steps:
17/// 1. Bob generates a public, private key pair.
18/// 2. Bob sends the public key to Alice.
19/// 3. Alice uses `KeyExchanger::encap` to generate a secret session key, and an encrypted version.
20/// 4. Alice sends the encrypted session key to Bob.
21/// 5. Bob uses `KeyExchanger::decap` using his private key to recover the session key.
22/// 6. Alice and Bob can now use the secret session key to encrypt their communications.
23pub trait KeyExchanger:
24 Clone
25 + std::fmt::Debug
26 + InNamex
27 + Send
28 + Sync
29{
30 /// Generate and encapsulate (encrypt) the session key.
31 fn encap<
32 const PK_LEN: usize,
33 const SESSION_KEY_LEN: usize,
34 const CIPHERTEXT_LEN: usize,
35 >(
36 &self,
37 pk: [u8; PK_LEN],
38 )
39 -> Outcome<(
40 [u8; SESSION_KEY_LEN],
41 [u8; CIPHERTEXT_LEN],
42 )>;
43 /// De-encapsulate ("decapsulate" or decrypt) the session key.
44 fn decap<
45 const SESSION_KEY_LEN: usize,
46 const CIPHERTEXT_LEN: usize,
47 >(
48 &self,
49 ciphertext: [u8; CIPHERTEXT_LEN],
50 )
51 -> Outcome<
52 [u8; SESSION_KEY_LEN],
53 >;
54}
55
56#[derive(Clone, Debug, Default)]
57pub struct KeyExchangerDefAlt<
58 D: KeyExchanger,
59 G: KeyExchanger,
60>(
61 pub DefAlt<D, G>,
62);
63
64impl<
65 D: KeyExchanger,
66 G: KeyExchanger,
67>
68 std::ops::Deref for KeyExchangerDefAlt<D, G>
69{
70 type Target = DefAlt<D, G>;
71 fn deref(&self) -> &Self::Target { &self.0 }
72}
73
74impl<
75 D: KeyExchanger,
76 G: KeyExchanger,
77>
78 From<Option<G>> for KeyExchangerDefAlt<D, G>
79{
80 fn from(opt: Option<G>) -> Self {
81 Self(
82 DefAlt::from(opt),
83 )
84 }
85}
86
87impl<
88 D: KeyExchanger,
89 G: KeyExchanger,
90>
91 From<Alt<G>> for KeyExchangerDefAlt<D, G>
92{
93 fn from(alt: Alt<G>) -> Self {
94 Self(
95 DefAlt::from(alt),
96 )
97 }
98}
99
100impl<
101 D: KeyExchanger,
102 G: KeyExchanger,
103>
104 InNamex for KeyExchangerDefAlt<D, G>
105{
106 fn name_id(&self) -> Outcome<NamexId> {
107 match &self.0 {
108 DefAlt::Default(inner) => inner.name_id(),
109 DefAlt::Given(inner) => inner.name_id(),
110 DefAlt::None => Err(err!(
111 "No Namex id can be specified for DefAlt::None.";
112 Missing, Bug)),
113 }
114 }
115
116 fn local_id(&self) -> LocalId {
117 match &self.0 {
118 DefAlt::Default(inner) => inner.local_id(),
119 DefAlt::Given(inner) => inner.local_id(),
120 DefAlt::None => LocalId::default(),
121 }
122 }
123
124 fn assoc_names_base64(
125 gname: &'static str,
126 )
127 -> Outcome<Option<Vec<(
128 &'static str,
129 &'static str,
130 )>>>
131 {
132 match res!(D::assoc_names_base64(gname)) {
133 Some(mut vd) => match res!(G::assoc_names_base64(gname)) {
134 Some(vg) => {
135 vd.extend(vg);
136 Ok(Some(vd))
137 },
138 None => Ok(Some(vd)),
139 },
140 None => match res!(G::assoc_names_base64(gname)) {
141 Some(vg) => Ok(Some(vg)),
142 None => Ok(None),
143 },
144 }
145 }
146}
147
148impl<
149 D: KeyExchanger,
150 G: KeyExchanger,
151>
152 KeyExchanger for KeyExchangerDefAlt<D, G>
153{
154 fn encap<
155 const PK_LEN: usize,
156 const SESSION_KEY_LEN: usize,
157 const CIPHERTEXT_LEN: usize,
158 >(
159 &self,
160 pk: [u8; PK_LEN],
161 )
162 -> Outcome<(
163 [u8; SESSION_KEY_LEN],
164 [u8; CIPHERTEXT_LEN],
165 )>
166 {
167 match &self.0 {
168 DefAlt::Default(inner) => inner.encap(pk),
169 DefAlt::Given(inner) => inner.encap(pk),
170 DefAlt::None => Err(err!(
171 "Can't encapsulate, key exchanger not specified.";
172 Configuration, Missing)),
173 }
174 }
175
176 fn decap<
177 const SESSION_KEY_LEN: usize,
178 const CIPHERTEXT_LEN: usize,
179 >(
180 &self,
181 ciphertext: [u8; CIPHERTEXT_LEN],
182 )
183 -> Outcome<
184 [u8; SESSION_KEY_LEN],
185 >
186 {
187 match &self.0 {
188 DefAlt::Default(inner) => inner.decap(ciphertext),
189 DefAlt::Given(inner) => inner.decap(ciphertext),
190 DefAlt::None => Err(err!(
191 "Can't de-encapsulate, key exchanger not specified.";
192 Configuration, Missing)),
193 }
194 }
195}
196
197impl<
198 D: KeyExchanger,
199 G: KeyExchanger,
200>
201 KeyExchangerDefAlt<D, G>
202{
203 /// Use the given `Alt` `KeyExchanger` to override the `DefAlt` for encryption, if it is
204 /// specified. If not, use the `DefAlt` `KeyExchanger`. This gives the user access to up to
205 /// three different types of `KeyExchanger`.
206 pub fn or_encap<
207 const PK_LEN: usize,
208 const SESSION_KEY_LEN: usize,
209 const CIPHERTEXT_LEN: usize,
210 OR: KeyExchanger,
211 >(
212 &self,
213 pk: [u8; PK_LEN],
214 alt: &Alt<OR>,
215 )
216 -> Outcome<(
217 [u8; SESSION_KEY_LEN],
218 [u8; CIPHERTEXT_LEN],
219 )>
220 {
221 match alt {
222 Alt::Specific(Some(inner)) => inner.encap(pk), // Type OR KeyExchanger
223 Alt::Specific(None) => Err(err!(
224 "Can't encapsulate, key exchanger not specified.";
225 Configuration, Missing)),
226 Alt::Unspecified => match &self.0 {
227 DefAlt::Default(inner) => inner.encap(pk), // Type D KeyExchanger
228 DefAlt::Given(inner) => inner.encap(pk), // Type G KeyExchanger
229 DefAlt::None => Err(err!(
230 "Can't encapsulate, key exchanger not specified.";
231 Configuration, Missing)),
232 },
233 }
234 }
235
236 /// Use the given `Alt` `KeyExchanger` to override the `DefAlt` for decryption, if it is
237 /// specified. If not, use the `DefAlt` `KeyExchanger`. This gives the user access to up to
238 /// three different types of `KeyExchanger`.
239 pub fn or_decap<
240 const SESSION_KEY_LEN: usize,
241 const CIPHERTEXT_LEN: usize,
242 OR: KeyExchanger,
243 >(
244 &self,
245 ciphertext: [u8; CIPHERTEXT_LEN],
246 alt: &Alt<OR>,
247 )
248 -> Outcome<
249 [u8; SESSION_KEY_LEN],
250 >
251 {
252 match alt {
253 Alt::Specific(Some(inner)) => inner.decap(ciphertext), // Type OR KeyExchanger
254 Alt::Specific(None) => Err(err!(
255 "Can't de-encapsulate, key-exchanger not specified.";
256 Configuration, Missing)),
257 Alt::Unspecified => match &self.0 {
258 DefAlt::Default(inner) => inner.decap(ciphertext), // Type D KeyExchanger
259 DefAlt::Given(inner) => inner.decap(ciphertext), // Type G KeyExchanger
260 DefAlt::None => Err(err!(
261 "Can't de-encapsulate, key-exchanger not specified.";
262 Configuration, Missing)),
263 },
264 }
265 }
266}