@@ -26,7 +26,7 @@ pub enum OpCertError {
26
26
27
27
/// Raw Fields of the operational certificates (without including the cold VK)
28
28
#[ derive( Clone , Debug , Deserialize , PartialEq , Eq , Serialize ) ]
29
- struct RawFields (
29
+ struct RawOpCertWithoutColdVerificationKey (
30
30
#[ serde( with = "serde_bytes" ) ] Vec < u8 > ,
31
31
u64 ,
32
32
u64 ,
@@ -35,16 +35,72 @@ struct RawFields(
35
35
36
36
/// Raw Operational Certificate
37
37
#[ derive( Clone , Debug , Deserialize , PartialEq , Eq , Serialize ) ]
38
- struct RawOpCert ( RawFields , EdVerificationKey ) ;
38
+ struct RawOpCert ( RawOpCertWithoutColdVerificationKey , EdVerificationKey ) ;
39
39
40
- /// Parsed Operational Certificate
40
+ /// Parsed Operational Certificate without cold verification key
41
41
#[ derive( Clone , Debug , PartialEq , Eq ) ]
42
- pub struct OpCert {
42
+ pub struct OpCertWithoutColdVerificationKey {
43
43
pub ( crate ) kes_vk : KesPublicKey ,
44
44
pub ( crate ) issue_number : u64 ,
45
45
/// KES period at which KES key is initalized
46
46
pub start_kes_period : u64 ,
47
47
pub ( crate ) cert_sig : EdSignature ,
48
+ }
49
+
50
+ impl SerDeShelleyFileFormat for OpCertWithoutColdVerificationKey {
51
+ const TYPE : & ' static str = "NodeOperationalCertificateWithoutColdVerificationKey" ;
52
+ const DESCRIPTION : & ' static str = "" ;
53
+ }
54
+
55
+ impl Serialize for OpCertWithoutColdVerificationKey {
56
+ fn serialize < S > ( & self , serializer : S ) -> Result < S :: Ok , S :: Error >
57
+ where
58
+ S : Serializer ,
59
+ {
60
+ let raw_cert = RawOpCertWithoutColdVerificationKey (
61
+ self . kes_vk . as_bytes ( ) . to_vec ( ) ,
62
+ self . issue_number ,
63
+ self . start_kes_period ,
64
+ self . cert_sig . to_bytes ( ) . to_vec ( ) ,
65
+ ) ;
66
+
67
+ raw_cert. serialize ( serializer)
68
+ }
69
+ }
70
+
71
+ impl < ' de > Deserialize < ' de > for OpCertWithoutColdVerificationKey {
72
+ fn deserialize < D > ( deserializer : D ) -> Result < Self , D :: Error >
73
+ where
74
+ D : Deserializer < ' de > ,
75
+ {
76
+ let raw_cert = RawOpCertWithoutColdVerificationKey :: deserialize ( deserializer) ?;
77
+
78
+ Ok ( Self {
79
+ kes_vk : KesPublicKey :: from_bytes ( & raw_cert. 0 )
80
+ . map_err ( |_| Error :: custom ( "KES vk serialisation error" ) ) ?,
81
+ issue_number : raw_cert. 1 ,
82
+ start_kes_period : raw_cert. 2 ,
83
+ cert_sig : EdSignature :: from_slice ( & raw_cert. 3 )
84
+ . map_err ( |_| Error :: custom ( "ed25519 signature serialisation error" ) ) ?,
85
+ } )
86
+ }
87
+ }
88
+
89
+ impl From < & OpCertWithoutColdVerificationKey > for RawOpCertWithoutColdVerificationKey {
90
+ fn from ( opcert : & OpCertWithoutColdVerificationKey ) -> Self {
91
+ RawOpCertWithoutColdVerificationKey (
92
+ opcert. kes_vk . as_bytes ( ) . to_vec ( ) ,
93
+ opcert. issue_number ,
94
+ opcert. start_kes_period ,
95
+ opcert. cert_sig . to_bytes ( ) . to_vec ( ) ,
96
+ )
97
+ }
98
+ }
99
+
100
+ /// Parsed Operational Certificate
101
+ #[ derive( Clone , Debug , PartialEq , Eq ) ]
102
+ pub struct OpCert {
103
+ pub ( crate ) opcert_without_vk : OpCertWithoutColdVerificationKey ,
48
104
pub ( crate ) cold_vk : EdVerificationKey ,
49
105
}
50
106
@@ -69,14 +125,46 @@ impl OpCert {
69
125
) ) ;
70
126
71
127
Self {
72
- kes_vk,
73
- issue_number,
74
- start_kes_period,
75
- cert_sig,
128
+ opcert_without_vk : OpCertWithoutColdVerificationKey {
129
+ kes_vk,
130
+ issue_number,
131
+ start_kes_period,
132
+ cert_sig,
133
+ } ,
76
134
cold_vk,
77
135
}
78
136
}
79
137
138
+ /// Get the KES verification key
139
+ pub fn get_kes_verification_key ( & self ) -> KesPublicKey {
140
+ self . opcert_without_vk . kes_vk
141
+ }
142
+
143
+ /// Get the issue number
144
+ pub fn get_issue_number ( & self ) -> u64 {
145
+ self . opcert_without_vk . issue_number
146
+ }
147
+
148
+ /// Get the start KES period
149
+ pub fn get_start_kes_period ( & self ) -> u64 {
150
+ self . opcert_without_vk . start_kes_period
151
+ }
152
+
153
+ /// Get the certificate signature
154
+ pub fn get_certificate_signature ( & self ) -> EdSignature {
155
+ self . opcert_without_vk . cert_sig
156
+ }
157
+
158
+ /// Get the OpCert without cold verification key
159
+ pub fn get_opcert_without_cold_verification_key ( & self ) -> OpCertWithoutColdVerificationKey {
160
+ self . opcert_without_vk . clone ( )
161
+ }
162
+
163
+ /// Get the cold verification key
164
+ pub fn get_cold_verification_key ( & self ) -> EdVerificationKey {
165
+ self . cold_vk
166
+ }
167
+
80
168
/// Compute message to sign
81
169
pub ( crate ) fn compute_message_to_sign (
82
170
kes_vk : & KesPublicKey ,
@@ -96,11 +184,11 @@ impl OpCert {
96
184
. cold_vk
97
185
. verify (
98
186
& Self :: compute_message_to_sign (
99
- & self . kes_vk ,
100
- self . issue_number ,
101
- self . start_kes_period ,
187
+ & self . opcert_without_vk . kes_vk ,
188
+ self . opcert_without_vk . issue_number ,
189
+ self . opcert_without_vk . start_kes_period ,
102
190
) ,
103
- & self . cert_sig ,
191
+ & self . opcert_without_vk . cert_sig ,
104
192
)
105
193
. is_ok ( )
106
194
{
@@ -129,10 +217,10 @@ impl OpCert {
129
217
/// Compute the hash of an OpCert
130
218
pub fn compute_hash ( & self ) -> String {
131
219
let mut hasher = Sha256 :: new ( ) ;
132
- hasher. update ( self . kes_vk . as_bytes ( ) ) ;
133
- hasher. update ( self . issue_number . to_be_bytes ( ) ) ;
134
- hasher. update ( self . start_kes_period . to_be_bytes ( ) ) ;
135
- hasher. update ( self . cert_sig . to_bytes ( ) ) ;
220
+ hasher. update ( self . opcert_without_vk . kes_vk . as_bytes ( ) ) ;
221
+ hasher. update ( self . opcert_without_vk . issue_number . to_be_bytes ( ) ) ;
222
+ hasher. update ( self . opcert_without_vk . start_kes_period . to_be_bytes ( ) ) ;
223
+ hasher. update ( self . opcert_without_vk . cert_sig . to_bytes ( ) ) ;
136
224
hasher. update ( self . cold_vk . as_bytes ( ) ) ;
137
225
hex:: encode ( hasher. finalize ( ) )
138
226
}
@@ -143,15 +231,9 @@ impl Serialize for OpCert {
143
231
where
144
232
S : Serializer ,
145
233
{
146
- let raw_cert = RawOpCert (
147
- RawFields (
148
- self . kes_vk . as_bytes ( ) . to_vec ( ) ,
149
- self . issue_number ,
150
- self . start_kes_period ,
151
- self . cert_sig . to_bytes ( ) . to_vec ( ) ,
152
- ) ,
153
- self . cold_vk ,
154
- ) ;
234
+ let raw_opcert_without_vk: RawOpCertWithoutColdVerificationKey =
235
+ ( & self . opcert_without_vk ) . into ( ) ;
236
+ let raw_cert = RawOpCert ( raw_opcert_without_vk, self . cold_vk ) ;
155
237
156
238
raw_cert. serialize ( serializer)
157
239
}
@@ -163,18 +245,33 @@ impl<'de> Deserialize<'de> for OpCert {
163
245
D : Deserializer < ' de > ,
164
246
{
165
247
let raw_cert = RawOpCert :: deserialize ( deserializer) ?;
248
+ let raw_opcert_without_vk = & raw_cert. 0 ;
249
+
166
250
Ok ( Self {
167
- kes_vk : KesPublicKey :: from_bytes ( & raw_cert. 0 . 0 )
168
- . map_err ( |_| Error :: custom ( "KES vk serialisation error" ) ) ?,
169
- issue_number : raw_cert. 0 . 1 ,
170
- start_kes_period : raw_cert. 0 . 2 ,
171
- cert_sig : EdSignature :: from_slice ( & raw_cert. 0 . 3 )
172
- . map_err ( |_| Error :: custom ( "ed25519 signature serialisation error" ) ) ?,
251
+ opcert_without_vk : OpCertWithoutColdVerificationKey {
252
+ kes_vk : KesPublicKey :: from_bytes ( & raw_opcert_without_vk. 0 )
253
+ . map_err ( |_| Error :: custom ( "KES vk serialisation error" ) ) ?,
254
+ issue_number : raw_opcert_without_vk. 1 ,
255
+ start_kes_period : raw_opcert_without_vk. 2 ,
256
+ cert_sig : EdSignature :: from_slice ( & raw_opcert_without_vk. 3 )
257
+ . map_err ( |_| Error :: custom ( "ed25519 signature serialisation error" ) ) ?,
258
+ } ,
173
259
cold_vk : raw_cert. 1 ,
174
260
} )
175
261
}
176
262
}
177
263
264
+ impl From < ( OpCertWithoutColdVerificationKey , EdVerificationKey ) > for OpCert {
265
+ fn from (
266
+ ( opcert_without_vk, cold_vk) : ( OpCertWithoutColdVerificationKey , EdVerificationKey ) ,
267
+ ) -> Self {
268
+ Self {
269
+ opcert_without_vk,
270
+ cold_vk,
271
+ }
272
+ }
273
+ }
274
+
178
275
#[ cfg( test) ]
179
276
mod tests {
180
277
use super :: * ;
@@ -220,5 +317,14 @@ mod tests {
220
317
"d9899c574fd7a710732391706b59e878bfd416214c49d2b3841c5c8b" . to_string( ) ,
221
318
party_id_as_hash
222
319
) ;
320
+
321
+ let operational_certificate_bytes_without_cold_vk = operational_certificate
322
+ . get_opcert_without_cold_verification_key ( )
323
+ . to_cbor_bytes ( )
324
+ . expect ( "compute CBOR bytes should not fail" ) ;
325
+ assert_eq ! (
326
+ "845820e650d7531509bb6cffd7998c28c68e4ec8fa621a0952206ea11eb03fcd7dcb2900005840d4abce27da05ff03c1342cc6ab53135072e1babf9cc05492f59f1ff009f70457aaa862c7158b13be0cfb41d7a91a562589bc110eb2cdaf5d2756048abbea5f05" ,
327
+ hex:: encode( operational_certificate_bytes_without_cold_vk)
328
+ ) ;
223
329
}
224
330
}
0 commit comments