1use secp256k1::{
21 ecdsa::{self, RecoverableSignature},
22 Error, Message,
23};
24use tiny_keccak::Hasher;
25
26mod keys;
27pub use keys::*;
28
29pub fn keccak256(input: &[u8]) -> [u8; 32] {
35 let mut buf = [0u8; 32];
36 let mut hasher = tiny_keccak::Keccak::v256();
37 hasher.update(input);
38 hasher.finalize(&mut buf);
39 buf
40}
41
42pub fn keccak512(input: &[u8]) -> [u8; 64] {
48 let mut buf = [0u8; 64];
49 let mut hasher = tiny_keccak::Keccak::v512();
50 hasher.update(input);
51 hasher.finalize(&mut buf);
52 buf
53}
54
55pub type Signature = RecoverableSignature;
56
57pub fn sign(msg: &[u8], secret_key: SecretKey) -> Result<Signature, Error> {
59 let secp = secp256k1::Secp256k1::new();
60 let hash = keccak256(msg);
61 let msg_bytes = Message::from_slice(&hash)?;
62 let sk = secp256k1::SecretKey::from_slice(secret_key.to_slice())?;
63 let sig = secp.sign_ecdsa_recoverable(&msg_bytes, &sk);
64 Ok(sig)
65}
66
67pub fn verify(sig: &Signature, pub_key: &PublicKey, msg: &[u8]) -> Result<bool, Error> {
69 let secp = secp256k1::Secp256k1::new();
70 let hash = keccak256(msg);
71 let msg_bytes = Message::from_slice(&hash)?;
72 let pk = secp256k1::PublicKey::from_slice(pub_key.to_slice())?;
73 let sig = ecdsa::Signature::from_compact(&sig.serialize_compact().1)?;
74
75 let verif = secp.verify_ecdsa(&msg_bytes, &sig, &pk);
76 Ok(verif.is_ok())
77}
78
79pub fn ecrecover(msg: &[u8], sig: &Signature) -> Result<PublicKey, Error> {
81 let secp = secp256k1::Secp256k1::new();
82 let hash = keccak256(msg);
83 let msg_bytes = Message::from_slice(&hash)?;
84 let pk = secp.recover_ecdsa(&msg_bytes, sig)?;
85 let pub_key = PublicKey::from_slice(&pk.serialize_uncompressed());
86
87 match pub_key {
88 Ok(pk) => Ok(pk),
89 Err(_) => Err(Error::InvalidPublicKey),
90 }
91}
92
93#[cfg(test)]
94mod crypto_test {
95 use super::*;
96
97 #[test]
98 fn test_sign_and_verify() {
99 let (sk, pk) = new_key_pair().unwrap();
100 let msg = b"hello world";
101 let sig = sign(msg, sk).unwrap();
102 assert!(verify(&sig, &pk, msg).unwrap());
103 }
104
105 #[test]
106 fn test_ecrecover() {
107 let (sk, pk) = new_key_pair().unwrap();
108 let msg = b"hello world";
109 let sig = sign(msg, sk).unwrap();
110 let pk2 = ecrecover(msg, &sig).unwrap();
111 assert_eq!(pk, pk2);
112 }
113}