chaincraft_rust/crypto/
ecdsa.rs1use crate::crypto::{KeyType, KeyedCryptoPrimitive, PrivateKey, PublicKey, Signature};
4use crate::error::{ChaincraftError, CryptoError, Result};
5use async_trait::async_trait;
6use base64::{engine::general_purpose, Engine as _};
7use serde::{Deserialize, Serialize};
8
9#[derive(Debug, Clone)]
11pub struct EcdsaSignature {
12 pub key_type: KeyType,
13}
14
15impl EcdsaSignature {
16 pub fn new(key_type: KeyType) -> Self {
17 Self { key_type }
18 }
19
20 pub fn ed25519() -> Self {
21 Self::new(KeyType::Ed25519)
22 }
23
24 pub fn secp256k1() -> Self {
25 Self::new(KeyType::Secp256k1)
26 }
27}
28
29impl Default for EcdsaSignature {
30 fn default() -> Self {
31 Self::ed25519()
32 }
33}
34
35#[async_trait]
36impl KeyedCryptoPrimitive for EcdsaSignature {
37 type PublicKey = PublicKey;
38 type PrivateKey = PrivateKey;
39 type Input = Vec<u8>;
40 type Output = Vec<u8>;
41 type Message = Vec<u8>;
42 type Signature = Signature;
43
44 async fn generate_keypair(&self) -> Result<(Self::PrivateKey, Self::PublicKey)> {
45 crate::crypto::utils::generate_keypair(self.key_type)
46 }
47
48 async fn compute(&self, key: &Self::PrivateKey, input: Self::Input) -> Result<Self::Output> {
49 let signature = self.sign(key, &input).await?;
51 Ok(signature.to_bytes())
52 }
53
54 async fn sign(
55 &self,
56 private_key: &Self::PrivateKey,
57 message: &Self::Message,
58 ) -> Result<Self::Signature> {
59 crate::crypto::utils::sign_message(private_key, message)
60 }
61
62 async fn verify(
63 &self,
64 key: &Self::PublicKey,
65 input: Self::Input,
66 output: &Self::Output,
67 ) -> Result<bool> {
68 match key {
70 PublicKey::Ed25519(pk) => {
71 if output.len() != 64 {
73 return Err(ChaincraftError::Crypto(CryptoError::InvalidSignature));
74 }
75
76 let mut sig_bytes = [0u8; 64];
78 sig_bytes.copy_from_slice(&output[0..64]);
79
80 let signature = ed25519_dalek::Signature::from(sig_bytes);
82
83 use ed25519_dalek::Verifier;
85 match pk.verify(&input, &signature) {
86 Ok(_) => Ok(true),
87 Err(_) => Ok(false), }
89 },
90 PublicKey::Secp256k1(pk) => {
91 let signature = match k256::ecdsa::Signature::from_slice(output.as_slice()) {
93 Ok(s) => s,
94 Err(_) => return Err(ChaincraftError::Crypto(CryptoError::InvalidSignature)),
95 };
96
97 use k256::ecdsa::{signature::Verifier, VerifyingKey};
98 let verifying_key = VerifyingKey::from(pk);
99 Ok(verifying_key.verify(&input, &signature).is_ok())
100 },
101 }
102 }
103}
104
105#[derive(Debug, Clone, Serialize, Deserialize)]
107pub struct ECDSASignature {
108 data: Vec<u8>,
109}
110
111impl ECDSASignature {
112 pub fn new(data: Vec<u8>) -> Self {
113 Self { data }
114 }
115
116 pub fn from_bytes(bytes: &[u8]) -> Result<Self> {
117 Ok(Self {
118 data: bytes.to_vec(),
119 })
120 }
121
122 pub fn to_bytes(&self) -> Vec<u8> {
123 self.data.clone()
124 }
125}
126
127#[derive(Debug)]
129pub struct ECDSASigner {
130 private_key: PrivateKey,
131 public_key: PublicKey,
132 provider: EcdsaSignature,
133}
134
135impl ECDSASigner {
136 pub fn new() -> Result<Self> {
137 let provider = EcdsaSignature::ed25519();
139 let (private_key, public_key) = futures::executor::block_on(provider.generate_keypair())?;
140
141 Ok(Self {
142 private_key,
143 public_key,
144 provider,
145 })
146 }
147
148 pub fn sign(&self, message: &[u8]) -> Result<ECDSASignature> {
149 let signature =
150 futures::executor::block_on(self.provider.sign(&self.private_key, &message.to_vec()))?;
151 Ok(ECDSASignature::new(signature.to_bytes()))
152 }
153
154 pub fn get_public_key_pem(&self) -> Result<String> {
155 match &self.public_key {
156 PublicKey::Ed25519(pk) => {
157 let bytes = pk.to_bytes();
159 let b64 = general_purpose::STANDARD.encode(bytes);
160 Ok(format!("-----BEGIN PUBLIC KEY-----\n{}\n-----END PUBLIC KEY-----", b64))
161 },
162 PublicKey::Secp256k1(pk) => {
163 use k256::elliptic_curve::sec1::ToEncodedPoint;
165 let point = pk.to_encoded_point(true);
166 let b64 = general_purpose::STANDARD.encode(point.as_bytes());
167 Ok(format!("-----BEGIN PUBLIC KEY-----\n{}\n-----END PUBLIC KEY-----", b64))
168 },
169 }
170 }
171}
172
173#[derive(Debug, Clone)]
175pub struct ECDSAVerifier {
176 provider: EcdsaSignature,
177}
178
179impl ECDSAVerifier {
180 pub fn new() -> Self {
181 Self {
182 provider: EcdsaSignature::ed25519(),
183 }
184 }
185
186 pub fn verify(
187 &self,
188 message: &[u8],
189 signature: &ECDSASignature,
190 public_key_pem: &str,
191 ) -> Result<bool> {
192 let public_key = self.parse_public_key_pem(public_key_pem)?;
194
195 futures::executor::block_on(self.provider.verify(
196 &public_key,
197 message.to_vec(),
198 &signature.data,
199 ))
200 }
201
202 fn parse_public_key_pem(&self, pem: &str) -> Result<PublicKey> {
203 let cleaned_pem = pem
205 .replace("-----BEGIN PUBLIC KEY-----", "")
206 .replace("-----END PUBLIC KEY-----", "")
207 .replace(['\n', '\r', ' '], "");
208
209 let key_bytes = general_purpose::STANDARD
211 .decode(cleaned_pem)
212 .map_err(|_| ChaincraftError::Crypto(CryptoError::InvalidSignature))?;
213
214 if key_bytes.len() == 32 {
216 let mut array = [0u8; 32];
217 array.copy_from_slice(&key_bytes);
218
219 match ed25519_dalek::VerifyingKey::from_bytes(&array) {
220 Ok(pk) => Ok(PublicKey::Ed25519(pk)),
221 Err(_) => Err(ChaincraftError::Crypto(CryptoError::InvalidSignature)),
222 }
223 } else if key_bytes.len() == 33 {
224 match k256::PublicKey::from_sec1_bytes(&key_bytes) {
226 Ok(pk) => Ok(PublicKey::Secp256k1(pk)),
227 Err(_) => Err(ChaincraftError::Crypto(CryptoError::InvalidSignature)),
228 }
229 } else {
230 Err(ChaincraftError::Crypto(CryptoError::InvalidSignature))
231 }
232 }
233}
234
235impl Default for ECDSAVerifier {
236 fn default() -> Self {
237 Self::new()
238 }
239}