oxedyne/fe2o3/fe2o3_crypto/src/keys.rs
7.2 KiB, 9 runs
created by r1870400018:232, 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
| 1 | //! Raw cryptographic key types: [`SecretKey`], [`PublicKey`] and the |
| 2 | //! generic [`Keys`] pair. |
| 3 | //! |
| 4 | //! The multi-admin encrypted keystore (formerly co-located here) lives |
| 5 | //! in the sibling [`crate::keystore`] module. |
| 6 | |
| 7 | use crate::scheme::SchemeTimestamp; |
| 8 | |
| 9 | use oxedyne_fe2o3_core::{ |
| 10 | prelude::*, |
| 11 | mem::Extract, |
| 12 | rand::RanDef, |
| 13 | }; |
| 14 | use oxedyne_fe2o3_jdat::{ |
| 15 | prelude::*, |
| 16 | try_extract_tup2dat, |
| 17 | tup2dat, |
| 18 | }; |
| 19 | use oxedyne_fe2o3_namex::id::LocalId as SchemeLocalId; |
| 20 | |
| 21 | use std::fmt; |
| 22 | |
| 23 | use rand_core::{ |
| 24 | OsRng, |
| 25 | RngCore, |
| 26 | }; |
| 27 | |
| 28 | use secrecy::{ |
| 29 | ExposeSecret, |
| 30 | Secret, |
| 31 | }; |
| 32 | |
| 33 | |
| 34 | // ┌───────────────────────────────────────────────────────────────────────────┐ |
| 35 | // │ SECRET KEY │ |
| 36 | // └───────────────────────────────────────────────────────────────────────────┘ |
| 37 | |
| 38 | /// A private key with `SchemeTimestamp` metadata. A heap `Vec` is used since the key accomodates |
| 39 | /// different schemes, so the length of the key is not known at compile time. |
| 40 | pub struct SecretKey { |
| 41 | pub key: Secret<Vec<u8>>, |
| 42 | pub sts: SchemeTimestamp, |
| 43 | } |
| 44 | |
| 45 | impl Clone for SecretKey { |
| 46 | fn clone(&self) -> Self { |
| 47 | Self { |
| 48 | key: { |
| 49 | let sk = self.key.expose_secret(); |
| 50 | Secret::new(sk.clone()) |
| 51 | }, |
| 52 | sts: self.sts.clone(), |
| 53 | } |
| 54 | } |
| 55 | } |
| 56 | |
| 57 | impl Default for SecretKey { |
| 58 | fn default() -> Self { |
| 59 | Self { |
| 60 | key: Secret::new(Vec::new()), |
| 61 | sts: SchemeTimestamp::default(), |
| 62 | } |
| 63 | } |
| 64 | } |
| 65 | |
| 66 | impl fmt::Debug for SecretKey { |
| 67 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { |
| 68 | let sk = self.key.expose_secret(); |
| 69 | write!(f, "SecretKey{{ key: [{}] bytes, sts: {:?}, k}}", sk.len(), self.sts) |
| 70 | } |
| 71 | } |
| 72 | |
| 73 | impl ToDat for SecretKey { |
| 74 | fn to_dat(&self) -> Outcome<Dat> { |
| 75 | let sk = self.key.expose_secret(); |
| 76 | Ok(tup2dat![ |
| 77 | Dat::bytdat(sk.clone()), |
| 78 | res!(self.sts.to_dat()), |
| 79 | ]) |
| 80 | } |
| 81 | } |
| 82 | |
| 83 | impl FromDat for SecretKey { |
| 84 | fn from_dat(dat: Dat) -> Outcome<Self> { |
| 85 | let mut result = SecretKey::default(); |
| 86 | let mut v = try_extract_tup2dat!(dat); |
| 87 | result.key = Secret::new(try_extract_dat!(v[0].extract(), BU8, BU16, BU32, BU64)); |
| 88 | result.sts = res!(SchemeTimestamp::from_dat(v[1].extract())); |
| 89 | Ok(result) |
| 90 | } |
| 91 | } |
| 92 | |
| 93 | impl SecretKey { |
| 94 | pub fn new( |
| 95 | sts: SchemeTimestamp, |
| 96 | key: Secret<Vec<u8>>, |
| 97 | ) |
| 98 | -> Self |
| 99 | { |
| 100 | Self { |
| 101 | sts, |
| 102 | key, |
| 103 | } |
| 104 | } |
| 105 | |
| 106 | pub fn now( |
| 107 | id: SchemeLocalId, |
| 108 | key: Secret<Vec<u8>>, |
| 109 | ) |
| 110 | -> Outcome<Self> |
| 111 | { |
| 112 | Ok(Self { |
| 113 | sts: res!(SchemeTimestamp::now(id)), |
| 114 | key, |
| 115 | }) |
| 116 | } |
| 117 | } |
| 118 | |
| 119 | |
| 120 | // ┌───────────────────────────────────────────────────────────────────────────┐ |
| 121 | // │ PUBLIC KEY │ |
| 122 | // └───────────────────────────────────────────────────────────────────────────┘ |
| 123 | |
| 124 | /// A public key with `SchemeTimestamp` metadata, stored on the heap. |
| 125 | #[derive(Clone, Eq, Ord, PartialEq, PartialOrd)] |
| 126 | pub struct PublicKey { |
| 127 | pub sts: SchemeTimestamp, // Derived ordering starts with the first field here. |
| 128 | pub key: Vec<u8>, |
| 129 | } |
| 130 | |
| 131 | impl Default for PublicKey { |
| 132 | fn default() -> Self { |
| 133 | Self { |
| 134 | key: Vec::new(), |
| 135 | sts: SchemeTimestamp::default(), |
| 136 | } |
| 137 | } |
| 138 | } |
| 139 | |
| 140 | impl fmt::Debug for PublicKey { |
| 141 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { |
| 142 | write!(f, "PublicKey{{ key: [{}] bytes, sts: {:?}, k}}", self.key.len(), self.sts) |
| 143 | } |
| 144 | } |
| 145 | |
| 146 | impl ToDat for PublicKey { |
| 147 | fn to_dat(&self) -> Outcome<Dat> { |
| 148 | Ok(tup2dat![ |
| 149 | Dat::bytdat(self.key.clone()), |
| 150 | res!(self.sts.to_dat()), |
| 151 | ]) |
| 152 | } |
| 153 | } |
| 154 | |
| 155 | impl FromDat for PublicKey { |
| 156 | fn from_dat(dat: Dat) -> Outcome<Self> { |
| 157 | let mut result = PublicKey::default(); |
| 158 | let mut v = try_extract_tup2dat!(dat); |
| 159 | result.key = try_extract_dat!(v[0].extract(), BU8, BU16, BU32, BU64); |
| 160 | result.sts = res!(SchemeTimestamp::from_dat(v[1].extract())); |
| 161 | Ok(result) |
| 162 | } |
| 163 | } |
| 164 | |
| 165 | impl PublicKey { |
| 166 | pub fn new( |
| 167 | sts: SchemeTimestamp, |
| 168 | key: Vec<u8>, |
| 169 | ) |
| 170 | -> Self |
| 171 | { |
| 172 | Self { |
| 173 | key, |
| 174 | sts, |
| 175 | } |
| 176 | } |
| 177 | |
| 178 | pub fn now( |
| 179 | id: SchemeLocalId, |
| 180 | key: Vec<u8>, |
| 181 | ) |
| 182 | -> Outcome<Self> |
| 183 | { |
| 184 | Ok(Self { |
| 185 | sts: res!(SchemeTimestamp::now(id)), |
| 186 | key, |
| 187 | }) |
| 188 | } |
| 189 | } |
| 190 | |
| 191 | |
| 192 | // ┌───────────────────────────────────────────────────────────────────────────┐ |
| 193 | // │ KEYS PAIR │ |
| 194 | // └───────────────────────────────────────────────────────────────────────────┘ |
| 195 | |
| 196 | /// An optional public and private key pair with no additional metadata. |
| 197 | #[derive(Default)] |
| 198 | pub struct Keys< |
| 199 | const PK_LEN: usize, |
| 200 | const SK_LEN: usize, |
| 201 | > { |
| 202 | pub pk: Option<[u8; PK_LEN]>, |
| 203 | pub sks: Option<Secret<[u8; SK_LEN]>>, |
| 204 | } |
| 205 | |
| 206 | impl< |
| 207 | const PK_LEN: usize, |
| 208 | const SK_LEN: usize, |
| 209 | > |
| 210 | Clone for Keys<PK_LEN, SK_LEN> |
| 211 | { |
| 212 | fn clone(&self) -> Self { |
| 213 | Self { |
| 214 | pk: self.pk.clone(), |
| 215 | sks: match &self.sks { |
| 216 | Some(sks) => { |
| 217 | let sk = sks.expose_secret(); |
| 218 | Some(Secret::new(sk.clone())) |
| 219 | }, |
| 220 | None => None, |
| 221 | }, |
| 222 | } |
| 223 | } |
| 224 | } |
| 225 | |
| 226 | impl< |
| 227 | const PK_LEN: usize, |
| 228 | const SK_LEN: usize, |
| 229 | > |
| 230 | RanDef for Keys<PK_LEN, SK_LEN> |
| 231 | { |
| 232 | fn randef() -> Self { |
| 233 | let mut pk = [0u8; PK_LEN]; |
| 234 | let mut sk = [0u8; SK_LEN]; |
| 235 | OsRng.fill_bytes(&mut pk); |
| 236 | OsRng.fill_bytes(&mut sk); |
| 237 | Self { |
| 238 | pk: Some(pk), |
| 239 | sks: Some(Secret::new(sk)), |
| 240 | } |
| 241 | } |
| 242 | } |
| 243 | |
| 244 | impl< |
| 245 | const PK_LEN: usize, |
| 246 | const SK_LEN: usize, |
| 247 | > |
| 248 | Keys<PK_LEN, SK_LEN> |
| 249 | { |
| 250 | pub fn new( |
| 251 | pk: Option<[u8; PK_LEN]>, |
| 252 | sks: Option<Secret<[u8; SK_LEN]>>, |
| 253 | ) |
| 254 | -> Self |
| 255 | { |
| 256 | Self { |
| 257 | pk, |
| 258 | sks, |
| 259 | } |
| 260 | } |
| 261 | |
| 262 | pub fn randef_sk_only() -> Self { |
| 263 | let mut sk = [0u8; SK_LEN]; |
| 264 | OsRng.fill_bytes(&mut sk); |
| 265 | Self { |
| 266 | pk: None, |
| 267 | sks: Some(Secret::new(sk)), |
| 268 | } |
| 269 | } |
| 270 | |
| 271 | pub fn randef_pk_only() -> Self { |
| 272 | let mut pk = [0u8; PK_LEN]; |
| 273 | OsRng.fill_bytes(&mut pk); |
| 274 | Self { |
| 275 | pk: Some(pk), |
| 276 | sks: None, |
| 277 | } |
| 278 | } |
| 279 | } |