foundation_urtypes/registry/
seed.rs

1// SPDX-FileCopyrightText: © 2023 Foundation Devices, Inc. <hello@foundationdevices.com>
2// SPDX-License-Identifier: GPL-3.0-or-later
3
4use minicbor::{Decode, Encode};
5
6use crate::cbor::Timestamp;
7
8/// Cryptographic Seed.
9#[doc(alias("seed"))]
10#[derive(Debug, Decode, Encode)]
11pub struct Seed<'a> {
12    /// Seed entropy.
13    #[cbor(n(0), with = "payload")]
14    pub payload: &'a [u8],
15    /// Creation date.
16    #[cbor(n(1))]
17    pub creation_date: Option<Timestamp>,
18    /// Short name for the seed.
19    #[cbor(n(2))]
20    pub name: Option<&'a str>,
21    /// Description of the seed.
22    #[cbor(n(3))]
23    pub note: Option<&'a str>,
24}
25
26/// CBOR decoding and encoding of `crypto-seed-digest`.
27#[doc(alias("crypto-seed-digest"))]
28pub mod digest {
29    use minicbor::data::Tag;
30    use minicbor::encode::Write;
31    use minicbor::{Decoder, Encoder};
32
33    /// Tag representing a `crypto-seed-digest`.
34    pub const TAG: Tag = Tag::new(600);
35
36    /// Encode a `crypto-seed-digest`.
37    #[doc(alias("crypto-seed-digest"))]
38    pub fn encode<C, W: Write>(
39        seed_digest: &[u8; 32],
40        e: &mut Encoder<W>,
41        _ctx: &mut C,
42    ) -> Result<(), minicbor::encode::Error<W::Error>> {
43        e.tag(TAG)?.bytes(seed_digest)?;
44        Ok(())
45    }
46
47    /// Decode a `crypto-seed-digest`.
48    #[doc(alias("crypto-seed-digest"))]
49    pub fn decode<C>(d: &mut Decoder, _ctx: &mut C) -> Result<[u8; 32], minicbor::decode::Error> {
50        if d.tag()? != TAG {
51            return Err(minicbor::decode::Error::message(
52                "invalid crypto-seed-digest tag",
53            ));
54        };
55
56        let seed_digest = d.bytes()?;
57        if seed_digest.len() != 32 {
58            return Err(minicbor::decode::Error::message(
59                "invalid crypto-seed-digest length",
60            ));
61        }
62
63        let mut buf = [0u8; 32];
64        buf.copy_from_slice(seed_digest);
65        Ok(buf)
66    }
67}
68
69mod payload {
70    use minicbor::encode::Write;
71    use minicbor::{Decoder, Encoder};
72
73    pub fn encode<C, W: Write>(
74        payload: &[u8],
75        e: &mut Encoder<W>,
76        _ctx: &mut C,
77    ) -> Result<(), minicbor::encode::Error<W::Error>> {
78        if !(1..=64).contains(&payload.len()) {
79            return Err(minicbor::encode::Error::message("invalid seed payload"));
80        }
81
82        e.bytes(payload)?;
83
84        Ok(())
85    }
86
87    pub fn decode<'b, C>(
88        d: &mut Decoder<'b>,
89        _ctx: &mut C,
90    ) -> Result<&'b [u8], minicbor::decode::Error> {
91        let payload = d.bytes()?;
92
93        if !(1..=64).contains(&payload.len()) {
94            return Err(minicbor::decode::Error::message(
95                "invalid crypto-seed-digest length",
96            ));
97        }
98
99        Ok(payload)
100    }
101}