ssi_verification_methods/methods/w3c/
ed25519_verification_key_2018.rs1use std::{borrow::Cow, hash::Hash, str::FromStr};
2
3use ed25519_dalek::{Signer, Verifier};
4use iref::{Iri, IriBuf, UriBuf};
5use rdf_types::{Interpretation, Vocabulary};
6use serde::{Deserialize, Serialize};
7use ssi_claims_core::{
8 InvalidProof, MessageSignatureError, ProofValidationError, ProofValidity, SignatureError,
9};
10use ssi_jwk::JWK;
11use ssi_jws::JwsString;
12use ssi_verification_methods_core::{JwkVerificationMethod, VerificationMethodSet, VerifyBytes};
13use static_iref::iri;
14
15use crate::{
16 ExpectedType, GenericVerificationMethod, InvalidVerificationMethod, SigningMethod,
17 TypedVerificationMethod, VerificationMethod,
18};
19
20pub const ED25519_VERIFICATION_KEY_2018_TYPE: &str = "Ed25519VerificationKey2018";
22
23#[derive(
27 Debug,
28 Clone,
29 PartialEq,
30 Eq,
31 Hash,
32 Serialize,
33 Deserialize,
34 linked_data::Serialize,
35 linked_data::Deserialize,
36)]
37#[serde(tag = "type", rename = "Ed25519VerificationKey2018")]
38#[ld(prefix("sec" = "https://w3id.org/security#"))]
39#[ld(type = "sec:Ed25519VerificationKey2018")]
40pub struct Ed25519VerificationKey2018 {
41 #[ld(id)]
43 pub id: IriBuf,
44
45 #[ld("sec:controller")]
47 pub controller: UriBuf,
48
49 #[serde(rename = "publicKeyBase58")]
52 #[ld("sec:publicKeyBase58")]
53 pub public_key: PublicKey,
54}
55
56impl Ed25519VerificationKey2018 {
57 pub const NAME: &'static str = ED25519_VERIFICATION_KEY_2018_TYPE;
58 pub const IRI: &'static Iri = iri!("https://w3id.org/security#Ed25519VerificationKey2018");
59
60 pub fn public_key_jwk(&self) -> JWK {
61 self.public_key.to_jwk()
62 }
63
64 pub fn sign(
65 &self,
66 data: &[u8],
67 secret_key: &ed25519_dalek::SigningKey,
68 ) -> Result<JwsString, SignatureError> {
69 let header = ssi_jws::Header::new_unencoded(ssi_jwk::Algorithm::EdDSA, None);
70 let signing_bytes = header.encode_signing_bytes(data);
71 let signature = secret_key.sign(&signing_bytes);
72
73 Ok(ssi_jws::JwsString::from_signing_bytes_and_signature(
74 signing_bytes,
76 signature.to_bytes(),
77 )
78 .unwrap())
79 }
80
81 pub fn verify_bytes(
82 &self,
83 data: &[u8],
84 signature_bytes: &[u8],
85 ) -> Result<ProofValidity, ProofValidationError> {
86 let signature = ed25519_dalek::Signature::try_from(signature_bytes)
87 .map_err(|_| ProofValidationError::InvalidSignature)?;
88 Ok(self.public_key.verify(data, &signature))
89 }
90}
91
92impl VerificationMethod for Ed25519VerificationKey2018 {
93 fn id(&self) -> &Iri {
94 self.id.as_iri()
95 }
96
97 fn controller(&self) -> Option<&Iri> {
98 Some(self.controller.as_iri())
99 }
100}
101
102impl VerificationMethodSet for Ed25519VerificationKey2018 {
103 type TypeSet = &'static str;
104
105 fn type_set() -> Self::TypeSet {
106 Self::NAME
107 }
108}
109
110impl TypedVerificationMethod for Ed25519VerificationKey2018 {
111 fn expected_type() -> Option<ExpectedType> {
112 Some(ED25519_VERIFICATION_KEY_2018_TYPE.to_string().into())
113 }
114
115 fn type_match(ty: &str) -> bool {
116 ty == ED25519_VERIFICATION_KEY_2018_TYPE
117 }
118
119 fn type_(&self) -> &str {
120 ED25519_VERIFICATION_KEY_2018_TYPE
121 }
122}
123
124impl JwkVerificationMethod for Ed25519VerificationKey2018 {
125 fn to_jwk(&self) -> Cow<JWK> {
126 Cow::Owned(self.public_key_jwk())
127 }
128}
129
130impl TryFrom<GenericVerificationMethod> for Ed25519VerificationKey2018 {
131 type Error = InvalidVerificationMethod;
132
133 fn try_from(m: GenericVerificationMethod) -> Result<Self, Self::Error> {
134 Ok(Self {
135 id: m.id,
136 controller: m.controller,
137 public_key: m
138 .properties
139 .get("publicKeyBase58")
140 .ok_or_else(|| InvalidVerificationMethod::missing_property("publicKeyBase58"))?
141 .as_str()
142 .ok_or_else(|| InvalidVerificationMethod::invalid_property("publicKeyBase58"))?
143 .parse()
144 .map_err(|_| InvalidVerificationMethod::invalid_property("publicKeyBase58"))?,
145 })
146 }
147}
148
149impl SigningMethod<JWK, ssi_crypto::algorithm::EdDSA> for Ed25519VerificationKey2018 {
150 fn sign_bytes(
151 &self,
152 secret: &JWK,
153 _algorithm: ssi_crypto::algorithm::EdDSA,
154 bytes: &[u8],
155 ) -> Result<Vec<u8>, MessageSignatureError> {
156 ssi_jws::sign_bytes(ssi_jwk::Algorithm::EdDSA, bytes, secret)
157 .map_err(MessageSignatureError::signature_failed)
158 }
159}
160
161impl VerifyBytes<ssi_crypto::algorithm::EdDSA> for Ed25519VerificationKey2018 {
162 fn verify_bytes(
163 &self,
164 _: ssi_crypto::algorithm::EdDSA,
165 signing_bytes: &[u8],
166 signature: &[u8],
167 ) -> Result<ProofValidity, ProofValidationError> {
168 self.verify_bytes(signing_bytes, signature)
169 }
170}
171
172#[derive(Debug, Clone)]
174pub struct PublicKey {
175 encoded: String,
177
178 decoded: ed25519_dalek::VerifyingKey,
180}
181
182impl PublicKey {
183 pub fn decode(encoded: String) -> Result<Self, InvalidPublicKey> {
184 let pk_bytes = multibase::Base::Base58Btc.decode(&encoded)?;
185 let decoded = ed25519_dalek::VerifyingKey::try_from(pk_bytes.as_slice())?;
186 Ok(Self { encoded, decoded })
187 }
188
189 pub fn encoded(&self) -> &str {
190 &self.encoded
191 }
192
193 pub fn decoded(&self) -> &ed25519_dalek::VerifyingKey {
194 &self.decoded
195 }
196
197 pub fn to_jwk(&self) -> JWK {
198 self.decoded.into()
199 }
200
201 pub fn verify(&self, data: &[u8], signature: &ed25519_dalek::Signature) -> ProofValidity {
202 self.decoded
203 .verify(data, signature)
204 .map_err(|_| InvalidProof::Signature)
205 }
206}
207
208impl Serialize for PublicKey {
209 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
210 where
211 S: serde::Serializer,
212 {
213 self.encoded.serialize(serializer)
214 }
215}
216
217impl<'a> Deserialize<'a> for PublicKey {
218 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
219 where
220 D: serde::Deserializer<'a>,
221 {
222 use serde::de::Error;
223 let encoded = String::deserialize(deserializer)?;
224 Self::decode(encoded).map_err(D::Error::custom)
225 }
226}
227
228impl FromStr for PublicKey {
229 type Err = InvalidPublicKey;
230
231 fn from_str(s: &str) -> Result<Self, Self::Err> {
232 Self::decode(s.to_owned())
233 }
234}
235
236impl PartialEq for PublicKey {
237 fn eq(&self, other: &Self) -> bool {
238 self.decoded.eq(&other.decoded)
239 }
240}
241
242impl Eq for PublicKey {}
243
244impl Hash for PublicKey {
245 fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
246 self.encoded.hash(state)
247 }
248}
249
250impl<I: Interpretation, V: Vocabulary> linked_data::LinkedDataResource<I, V> for PublicKey
251where
252 String: linked_data::LinkedDataResource<I, V>,
253{
254 fn interpretation(
255 &self,
256 vocabulary: &mut V,
257 interpretation: &mut I,
258 ) -> linked_data::ResourceInterpretation<I, V> {
259 self.encoded.interpretation(vocabulary, interpretation)
260 }
261}
262
263impl<I: Interpretation, V: Vocabulary> linked_data::LinkedDataSubject<I, V> for PublicKey
264where
265 String: linked_data::LinkedDataSubject<I, V>,
266{
267 fn visit_subject<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
268 where
269 S: linked_data::SubjectVisitor<I, V>,
270 {
271 self.encoded.visit_subject(serializer)
272 }
273}
274
275impl<I: Interpretation, V: Vocabulary> linked_data::LinkedDataPredicateObjects<I, V> for PublicKey
276where
277 String: linked_data::LinkedDataPredicateObjects<I, V>,
278{
279 fn visit_objects<S>(&self, visitor: S) -> Result<S::Ok, S::Error>
280 where
281 S: linked_data::PredicateObjectsVisitor<I, V>,
282 {
283 self.encoded.visit_objects(visitor)
284 }
285}
286
287#[derive(Debug, thiserror::Error)]
288pub enum InvalidPublicKey {
289 #[error(transparent)]
290 Multibase(#[from] multibase::Error),
291
292 #[error(transparent)]
293 Ed25519(#[from] ed25519_dalek::SignatureError),
294}