1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
use k256::{
ecdsa::{signature::RandomizedSigner, signature::Verifier as _, Signature, Signer, Verifier},
elliptic_curve::Generate,
PublicKey, SecretKey,
};
use rand_core::{CryptoRng, RngCore};
use std::borrow::Cow;
use std::convert::TryFrom;
use crate::error::ValidationError;
use crate::{Algorithm, AlgorithmSignature};
impl AlgorithmSignature for Signature {
fn try_from_slice(slice: &[u8]) -> anyhow::Result<Self> {
Signature::try_from(slice).map_err(|e| anyhow::anyhow!(e))
}
fn as_bytes(&self) -> Cow<[u8]> {
Cow::Owned(self.as_ref().to_vec())
}
}
#[derive(Debug, Copy, Clone, Eq, PartialEq)]
pub struct Es256VerifyingKey(PublicKey);
impl AsRef<PublicKey> for Es256VerifyingKey {
fn as_ref(&self) -> &PublicKey {
&self.0
}
}
impl Es256VerifyingKey {
pub fn from_slice(raw: &[u8]) -> anyhow::Result<Es256VerifyingKey> {
Ok(Es256VerifyingKey(
PublicKey::from_bytes(raw).ok_or(ValidationError::InvalidPublicKey)?,
))
}
pub fn as_bytes(&self) -> Cow<[u8]> {
Cow::Owned(self.as_ref().as_bytes().to_vec())
}
}
#[derive(Debug)]
pub struct Es256SigningKey(SecretKey);
impl AsRef<SecretKey> for Es256SigningKey {
fn as_ref(&self) -> &SecretKey {
&self.0
}
}
impl Es256SigningKey {
pub fn from_slice(raw: &[u8]) -> anyhow::Result<Es256SigningKey> {
Ok(Es256SigningKey(SecretKey::from_bytes(raw)?))
}
pub fn to_verifying_key(&self) -> PublicKey {
PublicKey::from_secret_key(&self.0, true).unwrap()
}
}
#[derive(Debug)]
pub struct Es256<R: CryptoRng + RngCore> {
rng: R,
}
impl<R: CryptoRng + RngCore> Es256<R> {
pub fn new(rng: R) -> Self {
Es256 { rng }
}
}
impl<R: CryptoRng + RngCore> Algorithm for Es256<R> {
type SigningKey = Es256SigningKey;
type VerifyingKey = Es256VerifyingKey;
type Signature = Signature;
fn name(&self) -> Cow<'static, str> {
Cow::Borrowed("ES256K")
}
fn sign(&self, signing_key: &Self::SigningKey, message: &[u8]) -> Self::Signature {
let signer = Signer::new(signing_key.as_ref()).unwrap();
signer.sign_with_rng(&mut rand_core::OsRng, message)
}
fn verify_signature(
&self,
signature: &Self::Signature,
verifying_key: &Self::VerifyingKey,
message: &[u8],
) -> bool {
let verifier = match Verifier::new(verifying_key.as_ref()) {
Err(_) => return false,
Ok(verifier) => verifier,
};
verifier.verify(&message, signature).is_ok()
}
}
impl<R: CryptoRng + RngCore> Es256<R> {
pub fn generate(&mut self) -> (Es256SigningKey, Es256VerifyingKey) {
let signing_key = Es256SigningKey(SecretKey::generate(&mut self.rng));
let verifying_key =
Es256VerifyingKey(PublicKey::from_secret_key(signing_key.as_ref(), true).unwrap());
(signing_key, verifying_key)
}
}