Skip to main content

rootchain_crypto/
signing.rs

1use crate::error::CryptoError;
2use crate::hashing::{hash_block_header, hash_transaction};
3pub use ed25519_dalek::SigningKey;
4use ed25519_dalek::{Signer, Verifier, VerifyingKey};
5use rand_core::OsRng;
6use rootchain_core::types::{Address, BlockHeader, Signature, Transaction};
7
8pub fn generate_keypair() -> (SigningKey, Address) {
9    let mut csprng = OsRng;
10    let sk = SigningKey::generate(&mut csprng);
11    let pk = sk.verifying_key();
12    (sk, Address::from_bytes(pk.to_bytes()))
13}
14
15pub fn sign(data: &[u8], key: &SigningKey) -> Result<Signature, CryptoError> {
16    let sig = key.sign(data);
17    Ok(Signature(sig.to_bytes()))
18}
19
20pub fn verify(data: &[u8], sig: &Signature, addr: &Address) -> Result<bool, CryptoError> {
21    let vk = VerifyingKey::from_bytes(&addr.0).map_err(CryptoError::Signature)?;
22    let ed_sig = ed25519_dalek::Signature::from_bytes(&sig.0);
23    match vk.verify(data, &ed_sig) {
24        Ok(_) => Ok(true),
25        Err(_) => Ok(false),
26    }
27}
28
29pub fn sign_transaction(tx: &mut Transaction, key: &SigningKey) -> Result<(), CryptoError> {
30    // Ensure the 'from' address matches the signing key
31    tx.from = Address::from_bytes(key.verifying_key().to_bytes());
32
33    let hash = hash_transaction(tx);
34    tx.signature = sign(&hash.0, key)?;
35    Ok(())
36}
37
38pub fn verify_transaction(tx: &Transaction) -> Result<bool, CryptoError> {
39    let hash = hash_transaction(tx);
40    verify(&hash.0, &tx.signature, &tx.from)
41}
42
43pub fn sign_block_header(header: &mut BlockHeader, key: &SigningKey) -> Result<(), CryptoError> {
44    let hash = hash_block_header(header);
45    header.signature = sign(&hash.0, key)?;
46    Ok(())
47}
48
49pub fn verify_block_header(header: &BlockHeader) -> Result<bool, CryptoError> {
50    let hash = hash_block_header(header);
51    verify(&hash.0, &header.signature, &header.proposer)
52}