Signing with crypto.

This commit is contained in:
Gav
2018-01-17 15:23:22 +01:00
parent 98faf54ec4
commit 65a466434b
3 changed files with 120 additions and 0 deletions
+92
View File
@@ -21,6 +21,7 @@
extern crate rustc_hex;
extern crate serde;
extern crate tiny_keccak;
extern crate crypto;
#[macro_use]
extern crate crunchy;
@@ -59,3 +60,94 @@ pub use self::uint::{U256, U512};
pub fn hash(data: &[u8]) -> hash::H256 {
tiny_keccak::keccak256(data).into()
}
/// Cool module.
pub mod ed25519 {
use crypto;
use rustc_hex::FromHex;
#[derive(PartialEq, Clone)]
struct Public ([u8; 32]);
#[derive(Clone)]
struct Pair ([u8; 64]);
#[derive(Clone)]
struct Signature ([u8; 64]);
impl Pair {
pub fn from_seed(seed: &[u8]) -> Pair {
let (secret_public, public) = crypto::ed25519::keypair(seed);
assert_eq!(&secret_public[32..64], &public[0..32]);
Pair(secret_public)
}
pub fn sign(&self, message: &[u8]) -> Signature {
Signature(crypto::ed25519::signature(message, &self.0))
}
pub fn public(&self) -> Public {
let mut r = [0u8; 32];
r.copy_from_slice(&self.0[32..64]);
Public(r)
}
}
impl From<&'static str> for Public {
fn from(hex: &'static str) -> Self {
let mut r = [0u8; 32];
r.copy_from_slice(&FromHex::from_hex(hex).unwrap()[0..32]);
Public(r)
}
}
impl From<&'static str> for Pair {
fn from(hex: &'static str) -> Self {
let mut r = [0u8; 64];
r.copy_from_slice(&FromHex::from_hex(hex).unwrap()[0..64]);
Pair(r)
}
}
impl From<&'static str> for Signature {
fn from(hex: &'static str) -> Self {
let mut r = [0u8; 64];
r.copy_from_slice(&FromHex::from_hex(hex).unwrap()[0..64]);
Signature(r)
}
}
impl PartialEq for Signature {
fn eq(&self, other: &Signature) -> bool {
self.0.iter().eq(other.0.iter())
}
}
impl PartialEq for Pair {
fn eq(&self, other: &Pair) -> bool {
self.0.iter().eq(other.0.iter())
}
}
impl Signature {
fn verify(&self, message: &[u8], public: &Public) -> bool {
crypto::ed25519::verify(message, &public.0, &self.0)
}
}
#[cfg(test)]
mod test {
use super::*;
#[test]
fn test_vector_should_work() {
let pair: Pair = "9d61b19deffd5a60ba844af492ec2cc44449c5697b326919703bac031cae7f60d75a980182b10ab7d54bfed3c964073a0ee172f3daa62325af021a68f707511a".into();
let public = pair.public();
let message = b"";
let signature: Signature = "e5564300c360ac729086e2cc806e828a84877f1eb8e5d974d873e065224901555fb8821590a33bacc61e39701cf9b46bd25bf5f0595bbe24655141438e7a100b".into();
assert!(&pair.sign(&message[..]) == &signature);
assert!(signature.verify(&message[..], &public));
}
#[test]
fn generated_pair_should_work() {
let pair = Pair::from_seed(b"test");
let public = pair.public();
let message = b"Something important";
let signature = pair.sign(&message[..]);
assert!(signature.verify(&message[..], &public));
}
}
}