arkecosystem_crypto/utils/
message.rs1use hex;
2use secp256k1;
3use secp256k1::{Secp256k1, Signature};
4use serde_json;
5use serde_json::Value;
6use sha2::{Digest, Sha256};
7
8use super::super::identities::{private_key, public_key};
9
10#[derive(Clone, Debug, Deserialize, Serialize)]
11pub struct Message {
12 #[serde(rename = "publickey")]
13 pub public_key: String,
14 pub signature: String,
15 pub message: String,
16}
17
18impl Message {
19 pub fn new(public_key: &str, signature: &str, message: &str) -> Message {
20 Message {
21 public_key: public_key.to_owned(),
22 signature: signature.to_owned(),
23 message: message.to_owned(),
24 }
25 }
26
27 pub fn sign(message: &str, passphrase: &str) -> Message {
28 let key = private_key::from_passphrase(passphrase).unwrap();
29 let public_key = public_key::from_private_key(&key);
30
31 Message {
32 public_key: hex::encode(&public_key.serialize()[..]),
33 signature: private_key::sign(message.as_bytes(), passphrase),
34 message: message.to_owned(),
35 }
36 }
37
38 pub fn verify(&self) -> bool {
40 let hash = Sha256::digest_str(&self.message);
41
42 let message = secp256k1::Message::from_slice(&hash);
43 if message.is_err() {
44 return false;
45 }
46
47 let decoded = hex::decode(&self.signature);
48 if decoded.is_err() {
49 return false;
50 }
51
52 let secp = Secp256k1::new();
53 let signature = Signature::from_der(&secp, &decoded.unwrap());
54 if signature.is_err() {
55 return false;
56 }
57
58 let pk = public_key::from_hex(&self.public_key).unwrap();
59 secp.verify(&message.unwrap(), &signature.unwrap(), &pk)
60 .is_ok()
61 }
62
63 pub fn to_json(&self) -> Result<String, serde_json::Error> {
64 serde_json::to_string(&self)
65 }
66
67 pub fn to_map(&self) -> Result<Value, serde_json::Error> {
68 serde_json::to_value(&self)
69 }
70}
71
72#[cfg(test)]
73mod tests {
74 use super::*;
75
76 #[test]
77 fn test_verify() {
78 let m = Message::new(
79 "034151a3ec46b5670a682b0a63394f863587d1bc97483b1b6c70eb58e7f0aed192",
80 "304402200fb4adddd1f1d652b544ea6ab62828a0a65b712ed447e2538db0caebfa68929e02205ecb2e1c63b29879c2ecf1255db506d671c8b3fa6017f67cfd1bf07e6edd1cc8",
81 "Hello World"
82 );
83
84 assert!(m.verify());
85 }
86
87 #[test]
88 fn test_sign() {
89 let sig = Message::sign("Hello World", "this is a top secret passphrase");
90 assert_eq!(sig.signature, "304402200fb4adddd1f1d652b544ea6ab62828a0a65b712ed447e2538db0caebfa68929e02205ecb2e1c63b29879c2ecf1255db506d671c8b3fa6017f67cfd1bf07e6edd1cc8");
91 }
92
93}