1use k256::ecdsa;
19use k256::ecdsa::signature::DigestVerifier;
20use k256::ecdsa::{RecoveryId, SigningKey, VerifyingKey};
21use sha3::{Digest, Keccak256};
22
23use crate::error::{Error, Result};
24use crate::{PrivateKey, PublicKey};
25
26#[derive(Debug, Clone, Copy, Eq, PartialEq)]
28pub struct Signature {
29 sig: [u8; 64],
30 id: u8,
31}
32
33impl Signature {
34 pub fn new() -> Self {
36 Self {
37 sig: [0u8; 64],
38 id: 0,
39 }
40 }
41
42 pub fn from_bytes(bytes: [u8; 65]) -> Self {
44 let mut res = Self::new();
45 res.sig.copy_from_slice(&bytes[..64]);
46 res.id = bytes[64];
47 res
48 }
49
50 pub fn from_slice(bytes: &[u8]) -> Result<Self> {
52 if bytes.len() != 64 {
53 return Err(Error::InvalidSignature);
54 }
55 let mut res = Self::new();
56 res.sig.copy_from_slice(bytes);
57 if bytes.len() == 65 {
58 res.id = bytes[64];
59 }
60 Ok(res)
61 }
62
63 pub fn from_hex(hex: &str) -> Result<Self> {
65 let bytes = hex::decode(hex)?;
66 Self::from_slice(&bytes)
67 }
68
69 pub fn as_bytes(&self) -> [u8; 65] {
71 let mut res = [0u8; 65];
72 res[..64].copy_from_slice(&self.sig);
73 res[64] = self.id;
74 res
75 }
76
77 pub fn as_slice(&self) -> &[u8] {
79 let bytes = self.as_bytes();
80 Box::leak(Box::new(bytes))
81 }
82
83 pub fn as_hex(&self) -> String {
85 let bytes = self.as_bytes();
86 hex::encode(bytes)
87 }
88}
89
90impl From<ecdsa::Signature> for Signature {
91 fn from(sig: ecdsa::Signature) -> Self {
92 let mut res = Self::new();
93 res.sig.copy_from_slice(sig.to_bytes().as_slice());
94 res
95 }
96}
97
98impl From<&Signature> for ecdsa::Signature {
99 fn from(value: &Signature) -> Self {
100 Self::from_slice(&value.sig).unwrap()
101 }
102}
103
104impl From<&Signature> for RecoveryId {
105 fn from(value: &Signature) -> Self {
106 Self::from_byte(value.id).unwrap()
107 }
108}
109
110pub trait K256Sign {
113 fn sign(&self, msg: &str) -> Signature;
115}
116
117pub trait K256Verify {
120 fn verify(&self, msg: &str, signature: &Signature) -> bool;
122}
123
124pub trait K256Recover {
127 fn recover(msg: &str, signature: &Signature) -> Result<PublicKey>;
129}
130
131impl From<&PrivateKey> for SigningKey {
132 fn from(value: &PrivateKey) -> Self {
133 Self::from_slice(value.as_slice()).unwrap()
134 }
135}
136
137impl From<SigningKey> for PrivateKey {
138 fn from(value: SigningKey) -> Self {
139 let bytes = value.to_bytes();
140 Self::from_slice(bytes.as_slice()).unwrap()
141 }
142}
143
144impl From<&PublicKey> for VerifyingKey {
145 fn from(value: &PublicKey) -> Self {
146 Self::from_sec1_bytes(value.as_slice()).unwrap()
147 }
148}
149
150impl From<VerifyingKey> for PublicKey {
151 fn from(value: VerifyingKey) -> Self {
152 let bytes = value.to_encoded_point(false);
153 Self::from_slice(bytes.as_bytes()).unwrap()
154 }
155}
156
157impl K256Sign for PrivateKey {
158 fn sign(&self, msg: &str) -> Signature {
159 let digest = Keccak256::new_with_prefix(msg.as_bytes());
160 let key: SigningKey = self.into();
161 let (sig, id) = key.sign_digest_recoverable(digest).unwrap();
162 let mut signature: Signature = sig.into();
163 signature.id = id.to_byte();
164 signature
165 }
166}
167
168impl K256Verify for PublicKey {
169 fn verify(&self, msg: &str, signature: &Signature) -> bool {
170 let digest = Keccak256::new_with_prefix(msg.as_bytes());
171 let key: VerifyingKey = self.into();
172 let sig: ecdsa::Signature = signature.into();
173 key.verify_digest(digest, &sig).is_ok()
174 }
175}
176
177impl K256Recover for PrivateKey {
178 fn recover(msg: &str, signature: &Signature) -> Result<PublicKey> {
179 let digest = Keccak256::new_with_prefix(msg.as_bytes());
180 let sig: ecdsa::Signature = signature.into();
181 let id: RecoveryId = signature.into();
182 let recovered = VerifyingKey::recover_from_digest(digest, &sig, id)
183 .map_err(|e| Error::RecoveryError(e.to_string()))?;
184 let recovered_bytes = recovered.to_encoded_point(false);
185 PublicKey::from_slice(recovered_bytes.as_bytes())
186 }
187}
188
189impl K256Recover for PublicKey {
190 fn recover(msg: &str, signature: &Signature) -> Result<PublicKey> {
191 PrivateKey::recover(msg, signature)
192 }
193}
194
195#[cfg(test)]
196mod tests {
197 use super::*;
198
199 #[test]
200 fn test_k256() {
201 let sk = PrivateKey::new();
202 let pk = sk.public_key();
203 let msg = "hello world";
204 let signature = sk.sign(msg);
205 assert!(pk.verify(msg, &signature));
206 let recovered = PublicKey::recover(msg, &signature).unwrap();
207 assert_eq!(pk, recovered);
208 }
209}