cardano_message_signing/
builders.rs1use super::*;
2
3
4#[derive(Clone, Debug)]
5pub struct COSESign1Builder {
6 headers: Headers,
7 payload: Vec<u8>,
8 external_aad: Option<Vec<u8>>,
9 is_payload_external: bool,
10 hashed: bool,
11}
12
13
14impl COSESign1Builder {
15 pub fn new(headers: &Headers, payload: Vec<u8>, is_payload_external: bool) -> Self {
16 let mut all_headers = headers.clone();
17 all_headers.unprotected.set_header(
18 &Label::new_text(String::from("hashed")),
19 &CBORValue::new_special(&CBORSpecial::new_bool(false))).unwrap();
20 Self {
21 headers: all_headers,
22 payload,
23 external_aad: None,
24 is_payload_external,
25 hashed: false,
26 }
27 }
28
29 pub fn hash_payload(&mut self) {
30 if self.hashed {
31 self.hashed = true;
32 self.payload = crypto::blake2b224(self.payload.as_ref()).to_vec();
36 }
37 }
38
39 pub fn set_external_aad(&mut self, external_aad: Vec<u8>) {
40 self.external_aad = Some(external_aad);
41 }
42
43 pub fn make_data_to_sign(&self) -> SigStructure {
44 SigStructure::new(
45 SigContext::Signature1,
46 &self.headers.protected,
47 self.external_aad.clone().unwrap_or(vec![]),
48 self.payload.clone())
49 }
50
51 pub fn build(&self, signed_sig_structure: Vec<u8>) -> COSESign1 {
52 COSESign1::new(
53 &self.headers,
54 match self.is_payload_external {
55 true => None,
56 false => Some(self.payload.clone()),
57 },
58 signed_sig_structure
59 )
60 }
61}
62
63
64
65#[derive(Clone, Debug)]
66pub struct COSESignBuilder {
67 headers: Headers,
68 payload: Vec<u8>,
69 external_aad: Option<Vec<u8>>,
70 is_payload_external: bool,
71 hashed: bool,
72}
73
74
75impl COSESignBuilder {
76 pub fn new(headers: &Headers, payload: Vec<u8>, is_payload_external: bool) -> Self {
77 Self {
78 headers: headers.clone(),
79 payload,
80 external_aad: None,
81 is_payload_external,
82 hashed: false,
83 }
84 }
85
86 pub fn hash_payload(&mut self) {
87 if self.hashed {
88 self.hashed = true;
89 self.payload = crypto::blake2b224(self.payload.as_ref()).to_vec();
90 }
91 }
92
93 pub fn set_external_aad(&mut self, external_aad: Vec<u8>) {
94 self.external_aad = Some(external_aad);
95 }
96
97 pub fn make_data_to_sign(&self) -> SigStructure {
98 SigStructure::new(
99 SigContext::Signature,
100 &self.headers.protected,
101 self.external_aad.clone().unwrap_or(vec![]),
102 self.payload.clone())
103 }
104
105 pub fn build(&self, signed_sig_structure: &COSESignatures) -> COSESign {
106 COSESign::new(
107 &self.headers,
108 match self.is_payload_external {
109 true => None,
110 false => Some(self.payload.clone())
111 },
112 signed_sig_structure)
113 }
114}
115
116label_enum!(AlgorithmId {
119 EdDSA = -8,
121 ChaCha20Poly1305 = 24,
123});
124
125label_enum!(KeyType {
126 OKP = 1,
128 EC2 = 2,
130 Symmetric = 4,
131});
132
133label_enum!(ECKey {
134 CRV = -1,
136 X = -2,
138 Y = -3,
140 D = -4,
142});
143
144label_enum!(CurveType {
145 P256 = 1,
146 P384 = 2,
147 P521 = 3,
148 X25519 = 4,
149 X448 = 5,
150 Ed25519 = 6,
152 Ed448 = 7,
153});
154
155label_enum!(KeyOperation {
156 Sign = 1,
158 Verify = 2,
160 Encrypt = 3,
162 Decrypt = 4,
164 WrapKey = 5,
166 UnwrapKey = 6,
168 DeriveKey = 7,
170 DeriveBits = 8,
172});
173
174
175#[derive(Clone, Debug)]
176pub struct EdDSA25519Key {
177 pubkey_bytes: Vec<u8>,
178 prvkey_bytes: Option<Vec<u8>>,
179 for_signing: bool,
180 for_verifying: bool,
181}
182
183
184impl EdDSA25519Key {
185 pub fn new(pubkey_bytes: Vec<u8>) -> Self {
186 Self {
187 pubkey_bytes,
188 prvkey_bytes: None,
189 for_signing: false,
190 for_verifying: false,
191 }
192 }
193
194 pub fn set_private_key(&mut self, private_key_bytes: Vec<u8>) {
195 self.prvkey_bytes = Some(private_key_bytes);
196 }
197
198 pub fn is_for_signing(&mut self) {
199 self.for_signing = true;
200 }
201
202 pub fn is_for_verifying(&mut self) {
203 self.for_verifying = true;
204 }
205
206 pub fn build(&self) -> COSEKey {
207 let mut key = COSEKey::new(&KeyType::OKP.into());
208 key.other_headers.insert(
210 ECKey::CRV.into(),
211 CBORValue::from_label(&Label::from(CurveType::Ed25519)));
212 key.other_headers.insert(
214 ECKey::X.into(),
215 CBORValue::new_bytes(self.pubkey_bytes.clone()));
216 if let Some(d) = &self.prvkey_bytes {
218 key.other_headers.insert(
219 ECKey::D.into(),
220 CBORValue::new_bytes(d.clone()));
221 }
222 key.set_algorithm_id(&AlgorithmId::EdDSA.into());
224 if self.for_signing || self.for_verifying {
226 let mut key_ops = Labels::new();
227 if self.for_signing {
228 key_ops.add(&KeyOperation::Sign.into());
229 }
230 if self.for_verifying {
231 key_ops.add(&KeyOperation::Verify.into());
232 }
233 key.set_key_ops(&key_ops);
234 }
235 key
236 }
237}
238
239#[cfg(test)]
242mod tests {
243 use super::*;
244
245 #[test]
255 fn eddsa25519key() {
256 let xpub = vec![0; 32];
257 let key = EdDSA25519Key::new(xpub.clone()).build();
258 assert_eq!(key.key_type().as_int().unwrap().as_i32().unwrap(), 1);
260 assert_eq!(key.algorithm_id().unwrap().as_int().unwrap().as_i32().unwrap(), -8);
261 assert_eq!(key.header(&Label::new_int(&Int::new_i32(-1))).unwrap().as_int().unwrap().as_i32().unwrap(), 6);
262 assert_eq!(key.header(&Label::new_int(&Int::new_i32(-2))).unwrap().as_bytes().unwrap(), xpub);
263 }
264}