use k256::ecdsa::{signature::Signer, SigningKey};
use crate::crypto::{
EllipticCurve, KeyEncoding, MessageDigest, Signature, SignatureAlgorithm, SignatureEncoding,
VerifyingKey,
};
use crate::IdentityProvider;
#[derive(Debug, Clone)]
pub struct MockECDSAIdentityProvider {
secret: SigningKey,
}
impl MockECDSAIdentityProvider {
pub fn generate() -> Self {
let mut rng = rand::thread_rng();
Self {
secret: SigningKey::random(&mut rng),
}
}
}
impl IdentityProvider for MockECDSAIdentityProvider {
fn verifying_key(&self) -> VerifyingKey {
VerifyingKey {
key: k256::ecdsa::VerifyingKey::from(&self.secret)
.to_sec1_bytes()
.to_vec(),
algo: SignatureAlgorithm::ECDSA,
curve: EllipticCurve::Secp256k1,
enc: KeyEncoding::SEC1,
}
}
fn sign(&self, msg: &[u8]) -> Signature {
let signature: k256::ecdsa::Signature = self.secret.sign(msg);
Signature {
sig: signature.to_der().as_bytes().to_vec(),
algo: SignatureAlgorithm::ECDSA,
curve: EllipticCurve::Secp256k1,
hash: MessageDigest::SHA256,
enc: SignatureEncoding::DER,
}
}
fn sign_message_share(&self, msg: &[u8]) -> ([u8; 32], [u8; 32]) {
let signature: k256::ecdsa::Signature = self.secret.sign(msg);
let (r, s) = signature.split_bytes();
(r.into(), s.into())
}
}
impl MockECDSAIdentityProvider {
pub fn export(&self) -> Vec<u8> {
self.secret.to_bytes().to_vec()
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::crypto;
#[test]
fn local_identity_provider_works() {
let msg = b"Hello, world!";
let identity_provider = MockECDSAIdentityProvider::generate();
let signature = identity_provider.sign(msg);
assert!(
crypto::verify_signature(&identity_provider.verifying_key(), msg, &signature).is_ok()
);
}
}