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
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
use rand::Rng;
use rand_core::{CryptoRng, RngCore};
use secp256k1::{All, Message, PublicKey, Secp256k1, SecretKey, Signature};
use sha2::{
digest::{generic_array::typenum::U32, Digest},
Sha256,
};
use std::{borrow::Cow, marker::PhantomData};
use crate::{Algorithm, AlgorithmSignature};
impl AlgorithmSignature for Signature {
fn try_from_slice(slice: &[u8]) -> anyhow::Result<Self> {
Signature::from_compact(slice).map_err(Into::into)
}
fn as_bytes(&self) -> Cow<[u8]> {
Cow::Owned(self.serialize_compact()[..].to_vec())
}
}
#[derive(Debug, Copy, Clone, Eq, PartialEq)]
pub struct Es256kVerifyingKey(PublicKey);
impl AsRef<PublicKey> for Es256kVerifyingKey {
fn as_ref(&self) -> &PublicKey {
&self.0
}
}
impl Es256kVerifyingKey {
pub fn from_slice(raw: &[u8]) -> anyhow::Result<Es256kVerifyingKey> {
Ok(Es256kVerifyingKey(PublicKey::from_slice(raw)?))
}
}
#[derive(Debug)]
pub struct Es256kSigningKey(SecretKey);
impl AsRef<SecretKey> for Es256kSigningKey {
fn as_ref(&self) -> &SecretKey {
&self.0
}
}
impl Es256kSigningKey {
pub fn from_slice(raw: &[u8]) -> anyhow::Result<Es256kSigningKey> {
Ok(Es256kSigningKey(SecretKey::from_slice(raw)?))
}
pub fn to_verifying_key(&self) -> PublicKey {
PublicKey::from_secret_key(&Secp256k1::new(), &self.0)
}
}
#[derive(Debug)]
pub struct Es256k<D = Sha256> {
context: Secp256k1<All>,
_digest: PhantomData<D>,
}
impl<D> Default for Es256k<D>
where
D: Digest<OutputSize = U32> + Default,
{
fn default() -> Self {
Es256k {
context: Secp256k1::new(),
_digest: PhantomData,
}
}
}
impl<D> Es256k<D>
where
D: Digest<OutputSize = U32> + Default,
{
pub fn new(context: Secp256k1<All>) -> Self {
Es256k {
context,
_digest: PhantomData,
}
}
}
impl<D> Algorithm for Es256k<D>
where
D: Digest<OutputSize = U32> + Default,
{
type SigningKey = Es256kSigningKey;
type VerifyingKey = Es256kVerifyingKey;
type Signature = Signature;
fn name(&self) -> Cow<'static, str> {
Cow::Borrowed("ES256K")
}
fn sign(&self, signing_key: &Self::SigningKey, message: &[u8]) -> Self::Signature {
let mut digest = D::default();
digest.update(message);
let message = Message::from_slice(&digest.finalize())
.expect("failed to convert message to the correct form");
self.context.sign(&message, signing_key.as_ref())
}
fn verify_signature(
&self,
signature: &Self::Signature,
verifying_key: &Self::VerifyingKey,
message: &[u8],
) -> bool {
let mut digest = D::default();
digest.update(message);
let message = Message::from_slice(&digest.finalize())
.expect("failed to convert message to the correct form");
self.context
.verify(&message, signature, verifying_key.as_ref())
.is_ok()
}
}
impl Es256k {
pub fn generate<R: CryptoRng + RngCore>(
&self,
rng: &mut R,
) -> (Es256kSigningKey, Es256kVerifyingKey) {
let signing_key = loop {
let bytes: [u8; secp256k1::constants::SECRET_KEY_SIZE] = rng.gen();
if let Ok(key) = SecretKey::from_slice(&bytes) {
break Es256kSigningKey(key);
}
};
let verifying_key = Es256kVerifyingKey(signing_key.to_verifying_key());
(signing_key, verifying_key)
}
}