crypto/
state_signature.rs1use objects::object::{ContentHash, StateSignature};
5
6use crate::{Signer, SignerError, verify_state_signature};
7
8#[derive(Debug, thiserror::Error)]
10pub enum StateSignatureError {
11 #[error("unsupported signature algorithm: {0}")]
12 UnsupportedAlgorithm(String),
13 #[error("invalid public key: {0}")]
14 InvalidPublicKey(String),
15 #[error("invalid signature: {0}")]
16 InvalidSignature(String),
17 #[error("hex decode error: {0}")]
18 Hex(#[from] hex::FromHexError),
19 #[error("signer error: {0}")]
20 Signer(#[from] SignerError),
21}
22
23pub fn state_signature_from_signer(
24 hash: &ContentHash,
25 signer: &dyn Signer,
26) -> Result<StateSignature, StateSignatureError> {
27 let signature = signer.sign(hash.as_bytes())?;
28
29 Ok(StateSignature {
30 algorithm: signer.algorithm().to_string(),
31 public_key: hex::encode(signer.public_key()),
32 signature: hex::encode(&signature),
33 })
34}
35
36pub fn verify_state_signature_bytes(
37 signature: &StateSignature,
38 hash: &ContentHash,
39) -> Result<(), StateSignatureError> {
40 let public_key = hex::decode(&signature.public_key)?;
41 let signature_bytes = hex::decode(&signature.signature)?;
42
43 verify_state_signature(hash, &signature.algorithm, &public_key, &signature_bytes)
44 .map_err(StateSignatureError::from)
45}
46
47pub fn public_key_bytes(signature: &StateSignature) -> Result<Vec<u8>, StateSignatureError> {
48 hex::decode(&signature.public_key).map_err(StateSignatureError::from)
49}
50
51pub fn signature_bytes(signature: &StateSignature) -> Result<Vec<u8>, StateSignatureError> {
52 hex::decode(&signature.signature).map_err(StateSignatureError::from)
53}
54
55#[cfg(test)]
56mod tests {
57 use super::*;
58 use crate::Ed25519Signer;
59
60 fn make_test_hash() -> ContentHash {
61 ContentHash::from_bytes([1u8; 32])
62 }
63
64 #[test]
65 fn test_sign_verify_ed25519() {
66 let signer = Ed25519Signer::generate().expect("generate key");
67 let hash = make_test_hash();
68
69 let sig = state_signature_from_signer(&hash, &signer).expect("sign state");
70 assert_eq!(sig.algorithm(), "ed25519");
71
72 verify_state_signature_bytes(&sig, &hash).expect("verify should not error");
73 }
74}