Oregami
Repositories/oxedyne/fe2o3

oxedyne/fe2o3/fe2o3_iop_crypto/src/sign.rs

10.3 KiB, 47 runs

created by r1870400018:387, 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 crate::keys::KeyManager;
2
3use oxedyne_fe2o3_core::{
4 prelude::*,
5 alt::{
6 Alt,
7 DefAlt,
8 },
9};
10use oxedyne_fe2o3_namex::id::{
11 LocalId,
12 InNamex,
13 NamexId,
14};
15
16/// One signature to check, in the form a batch wants it.
17///
18/// Each item carries its own public key, because a batch is not a batch of one
19/// signer: a version control history is signed by everyone who has written to
20/// it, and the point of checking many at once is lost if they must first be
21/// sorted by author.
22#[derive(Clone, Copy, Debug)]
23pub struct BatchItem<'a> {
24 /// The public key of whoever signed, as the scheme encodes it.
25 pub public: &'a [u8],
26 /// The bytes that were signed.
27 pub msg: &'a [u8],
28 /// The detached signature over `msg`.
29 pub sig: &'a [u8],
30}
31
32pub trait Signer:
33 KeyManager
34 + Clone
35 + std::fmt::Debug
36 + InNamex
37 + Send
38 + Sync
39{
40 /// Return a detached signature for the given message.
41 fn sign(&self, msg: &[u8]) -> Outcome<Vec<u8>>;
42 /// Verify the validity of the given detached signature for the given message.
43 fn verify(&self, msg: &[u8], sig: &[u8]) -> Outcome<bool>;
44
45 /// Verify many signatures, each against the public key its item carries,
46 /// and report whether every one of them holds.
47 ///
48 /// This is an optimisation and nothing more. A scheme that has a batch
49 /// verification equation may check the whole set for far less than the sum
50 /// of the parts; the default here simply checks them one at a time, so an
51 /// implementation that has nothing better to offer need do nothing.
52 ///
53 /// # What a `false` does and does not tell the caller
54 ///
55 /// It says that the set does not hold. It does not say which member of it
56 /// failed, and a scheme verifying the set as a whole cannot say. A caller
57 /// that must name the culprit -- and one refusing a history should -- falls
58 /// back to [`Signer::verify`] over the items to find it. The same goes for
59 /// an error: a batch that could not be attempted says so without saying
60 /// which item could not be attempted.
61 ///
62 /// # An empty batch
63 ///
64 /// Holds, vacuously. There is nothing in it that does not verify.
65 fn verify_batch(&self, items: &[BatchItem<'_>])
66 -> Outcome<bool>
67 where Self: Sized
68 {
69 verify_each(self, items)
70 }
71}
72
73/// Verifies the items one at a time, stopping at the first that does not hold.
74///
75/// The body of [`Signer::verify_batch`]'s default, exposed so that an
76/// implementation which is faster for some of its schemes and not for others
77/// can hand the rest here rather than writing the loop again.
78pub fn verify_each<S: Signer>(scheme: &S, items: &[BatchItem<'_>])
79 -> Outcome<bool>
80{
81 for item in items {
82 let bound = res!(scheme.clone_with_keys(Some(item.public), None));
83 if !res!(bound.verify(item.msg, item.sig)) {
84 return Ok(false);
85 }
86 }
87 Ok(true)
88}
89
90#[derive(Clone, Debug, Default)]
91pub struct SignerDefAlt<
92 D: Signer,
93 G: Signer,
94>(
95 pub DefAlt<D, G>,
96);
97
98impl<
99 D: Signer,
100 G: Signer,
101>
102 std::ops::Deref for SignerDefAlt<D, G>
103{
104 type Target = DefAlt<D, G>;
105 fn deref(&self) -> &Self::Target { &self.0 }
106}
107
108impl<
109 D: Signer,
110 G: Signer,
111>
112 From<Option<G>> for SignerDefAlt<D, G>
113{
114 fn from(opt: Option<G>) -> Self {
115 Self(
116 DefAlt::from(opt),
117 )
118 }
119}
120
121impl<
122 D: Signer,
123 G: Signer,
124>
125 From<Alt<G>> for SignerDefAlt<D, G>
126{
127 fn from(alt: Alt<G>) -> Self {
128 Self(
129 DefAlt::from(alt),
130 )
131 }
132}
133
134impl<
135 D: Signer,
136 G: Signer,
137>
138 InNamex for SignerDefAlt<D, G>
139{
140 fn name_id(&self) -> Outcome<NamexId> {
141 match &self.0 {
142 DefAlt::Default(inner) => inner.name_id(),
143 DefAlt::Given(inner) => inner.name_id(),
144 DefAlt::None => Err(err!(
145 "No Namex id can be specified for DefAlt::None.";
146 Missing, Bug)),
147 }
148 }
149
150 fn local_id(&self) -> LocalId {
151 match &self.0 {
152 DefAlt::Default(inner) => inner.local_id(),
153 DefAlt::Given(inner) => inner.local_id(),
154 DefAlt::None => LocalId::default(),
155 }
156 }
157
158 fn assoc_names_base64(
159 gname: &'static str,
160 )
161 -> Outcome<Option<Vec<(
162 &'static str,
163 &'static str,
164 )>>>
165 {
166 match res!(D::assoc_names_base64(gname)) {
167 Some(mut vd) => match res!(G::assoc_names_base64(gname)) {
168 Some(vg) => {
169 vd.extend(vg);
170 Ok(Some(vd))
171 },
172 None => Ok(Some(vd)),
173 },
174 None => match res!(G::assoc_names_base64(gname)) {
175 Some(vg) => Ok(Some(vg)),
176 None => Ok(None),
177 },
178 }
179 }
180}
181
182impl<
183 G: Signer,
184 D: Signer,
185>
186 Signer for SignerDefAlt<D, G>
187{
188 fn sign(&self, msg: &[u8]) -> Outcome<Vec<u8>> {
189 match &self.0 {
190 DefAlt::Default(inner) => inner.sign(msg),
191 DefAlt::Given(inner) => inner.sign(msg),
192 DefAlt::None => Err(err!(
193 "Can't sign, signature not specified.";
194 Configuration, Missing)),
195 }
196 }
197
198 fn verify(&self, msg: &[u8], sig: &[u8]) -> Outcome<bool> {
199 match &self.0 {
200 DefAlt::Default(inner) => inner.verify(msg, sig),
201 DefAlt::Given(inner) => inner.verify(msg, sig),
202 DefAlt::None => Err(err!(
203 "Can't verify, signature not specified.";
204 Configuration, Missing)),
205 }
206 }
207
208 /// Hands the batch to whichever scheme is in force, rather than taking the
209 /// default, so that an inner scheme's batch equation is not lost behind the
210 /// wrapper.
211 fn verify_batch(&self, items: &[BatchItem<'_>])
212 -> Outcome<bool>
213 where Self: Sized
214 {
215 match &self.0 {
216 DefAlt::Default(inner) => inner.verify_batch(items),
217 DefAlt::Given(inner) => inner.verify_batch(items),
218 DefAlt::None => Err(err!(
219 "Can't verify, signature not specified.";
220 Configuration, Missing)),
221 }
222 }
223
224}
225
226impl<
227 G: Signer,
228 D: Signer,
229>
230 KeyManager for SignerDefAlt<D, G>
231{
232 fn clone_with_keys(&self, pk: Option<&[u8]>, sk: Option<&[u8]>) -> Outcome<Self> {
233 Ok(match &self.0 {
234 DefAlt::Default(inner) => Self(
235 DefAlt::Default(res!(inner.clone_with_keys(pk, sk))),
236 ),
237 DefAlt::Given(inner) => Self(
238 DefAlt::Given(res!(inner.clone_with_keys(pk, sk))),
239 ),
240 DefAlt::None => Self(
241 DefAlt::None, // TODO should this be an error?
242 ),
243 })
244 }
245
246 fn get_public_key(&self) -> Outcome<Option<&[u8]>> {
247 match &self.0 {
248 DefAlt::Default(inner) => inner.get_public_key(),
249 DefAlt::Given(inner) => inner.get_public_key(),
250 DefAlt::None => Err(err!(
251 "Can't get public key, signature not specified.";
252 Configuration, Missing)),
253 }
254 }
255
256 fn get_secret_key(&self) -> Outcome<Option<&[u8]>> {
257 match &self.0 {
258 DefAlt::Default(inner) => inner.get_secret_key(),
259 DefAlt::Given(inner) => inner.get_secret_key(),
260 DefAlt::None => Err(err!(
261 "Can't get secret key, signature not specified.";
262 Configuration, Missing)),
263 }
264 }
265
266 fn set_public_key(self, pk: Option<&[u8]>) -> Outcome<Self> {
267 match self.0 {
268 DefAlt::Default(inner) => Ok(Self(
269 DefAlt::Default(res!(inner.set_public_key(pk))),
270 )),
271 DefAlt::Given(inner) => Ok(Self(
272 DefAlt::Given(res!(inner.set_public_key(pk))),
273 )),
274 DefAlt::None => Err(err!(
275 "Can't set public key, signature not specified.";
276 Configuration, Missing)),
277 }
278 }
279
280 fn set_secret_key(self, sk: Option<&[u8]>) -> Outcome<Self> {
281 match self.0 {
282 DefAlt::Default(inner) => Ok(Self(
283 DefAlt::Default(res!(inner.set_secret_key(sk))),
284 )),
285 DefAlt::Given(inner) => Ok(Self(
286 DefAlt::Given(res!(inner.set_secret_key(sk))),
287 )),
288 DefAlt::None => Err(err!(
289 "Can't set secret key, signature not specified.";
290 Configuration, Missing)),
291 }
292 }
293}
294
295impl<
296 D: Signer,
297 G: Signer,
298>
299 SignerDefAlt<D, G> {
300
301 /// Use the given `Alt` `Signer` to override the `DefAlt` for encryption, if it is
302 /// specified. If not, use the `DefAlt` `Signer`. This gives the user access to up to
303 /// three different types of `Signer`.
304 pub fn or_sign<OR: Signer>(&self, msg: &[u8], alt: &Alt<OR>) -> Outcome<Vec<u8>> {
305 match alt {
306 Alt::Specific(Some(inner)) => inner.sign(msg), // Type OR Signer
307 Alt::Specific(None) => Err(err!(
308 "Can't sign, signature not specified.";
309 Configuration, Missing)),
310 Alt::Unspecified => match &self.0 {
311 DefAlt::Default(inner) => inner.sign(msg), // Type D Signer
312 DefAlt::Given(inner) => inner.sign(msg), // Type G Signer
313 DefAlt::None => Err(err!(
314 "Can't sign, signature not specified.";
315 Configuration, Missing)),
316 },
317 }
318 }
319
320 /// Use the given `Alt` `Signer` to override the `DefAlt` for decryption, if it is
321 /// specified. If not, use the `DefAlt` `Signer`. This gives the user access to up to
322 /// three different types of `Signer`.
323 pub fn or_verify<OR: Signer>(&self, msg: &[u8], sig: &[u8], alt: &Alt<OR>) -> Outcome<bool> {
324 match alt {
325 Alt::Specific(Some(inner)) => inner.verify(msg, sig), // Type OR Signer
326 Alt::Specific(None) => Err(err!(
327 "Can't verify, signature not specified.";
328 Configuration, Missing)),
329 Alt::Unspecified => match &self.0 {
330 DefAlt::Default(inner) => inner.verify(msg, sig), // Type D Signer
331 DefAlt::Given(inner) => inner.verify(msg, sig), // Type G Signer
332 DefAlt::None => Err(err!(
333 "Can't verify, signature not specified.";
334 Configuration, Missing)),
335 },
336 }
337 }
338}