From 435c4ac71ae4e8006979f70152cf980760246ed6 Mon Sep 17 00:00:00 2001 From: Gav Date: Wed, 17 Jan 2018 18:33:20 +0100 Subject: [PATCH] Introduce Ed25519 crypto. --- substrate/Cargo.lock | 85 ++++++++++++++++----- substrate/ed25519.pk8 | Bin 0 -> 85 bytes substrate/pkcs8.key | 28 +++++++ substrate/primitives/Cargo.toml | 2 +- substrate/primitives/src/lib.rs | 127 ++++++++++++++++++++++++-------- 5 files changed, 191 insertions(+), 51 deletions(-) create mode 100644 substrate/ed25519.pk8 create mode 100644 substrate/pkcs8.key diff --git a/substrate/Cargo.lock b/substrate/Cargo.lock index 524ec96570..ce227ffe4b 100644 --- a/substrate/Cargo.lock +++ b/substrate/Cargo.lock @@ -129,6 +129,15 @@ dependencies = [ "yaml-rust 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "coco" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "either 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "scopeguard 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "crunchy" version = "0.1.6" @@ -153,6 +162,11 @@ name = "dtoa" version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "either" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "elastic-array" version = "0.9.0" @@ -706,12 +720,13 @@ dependencies = [ "fixed-hash 0.1.0 (git+https://github.com/paritytech/primitives.git)", "polkadot-serializer 0.1.0", "pretty_assertions 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", - "rust-crypto 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)", + "ring 0.12.1 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-hex 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.19 (registry+https://github.com/rust-lang/crates.io-index)", "serde_derive 1.0.19 (registry+https://github.com/rust-lang/crates.io-index)", "tiny-keccak 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)", "uint 0.1.0 (git+https://github.com/paritytech/primitives.git)", + "untrusted 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -791,6 +806,26 @@ dependencies = [ "libc 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "rayon" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "rayon-core 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "rayon-core" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "coco 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 0.2.9 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)", + "num_cpus 1.7.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rand 0.3.18 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "redox_syscall" version = "0.1.31" @@ -829,6 +864,18 @@ dependencies = [ "futures 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "ring" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "gcc 0.3.54 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 0.2.9 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)", + "rayon 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)", + "untrusted 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "rlp" version = "0.2.1" @@ -852,18 +899,6 @@ dependencies = [ "tiny-keccak 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)", ] -[[package]] -name = "rust-crypto" -version = "0.2.36" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "gcc 0.3.54 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)", - "rand 0.3.18 (registry+https://github.com/rust-lang/crates.io-index)", - "rustc-serialize 0.3.24 (registry+https://github.com/rust-lang/crates.io-index)", - "time 0.1.38 (registry+https://github.com/rust-lang/crates.io-index)", -] - [[package]] name = "rustc-demangle" version = "0.1.5" @@ -874,11 +909,6 @@ name = "rustc-hex" version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -[[package]] -name = "rustc-serialize" -version = "0.3.24" -source = "registry+https://github.com/rust-lang/crates.io-index" - [[package]] name = "rustc_version" version = "0.1.7" @@ -905,6 +935,11 @@ name = "scoped-tls" version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "scopeguard" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "semver" version = "0.1.20" @@ -1150,6 +1185,11 @@ dependencies = [ "void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "untrusted" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "utf8-ranges" version = "1.0.0" @@ -1206,10 +1246,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum cc 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "a9b13a57efd6b30ecd6598ebdb302cca617930b5470647570468a65d12ef9719" "checksum cfg-if 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "d4c819a1287eb618df47cc647173c5c4c66ba19d888a6e50d605672aed3140de" "checksum clap 2.27.1 (registry+https://github.com/rust-lang/crates.io-index)" = "1b8c532887f1a292d17de05ae858a8fe50a301e196f9ef0ddb7ccd0d1d00f180" +"checksum coco 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "c06169f5beb7e31c7c67ebf5540b8b472d23e3eade3b2ec7d1f5b504a85f91bd" "checksum crunchy 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "a2f4a431c5c9f662e1200b7c7f02c34e91361150e382089a8f2dec3ba680cbda" "checksum dbghelp-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "97590ba53bcb8ac28279161ca943a924d1fd4a8fb3fa63302591647c4fc5b850" "checksum difference 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b3304d19798a8e067e48d8e69b2c37f0b5e9b4e462504ad9e27e9f3fce02bba8" "checksum dtoa 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "09c3753c3db574d215cba4ea76018483895d7bff25a31b49ba45db21c48e50ab" +"checksum either 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "740178ddf48b1a9e878e6d6509a1442a2d42fd2928aae8e7a6f8a36fb01981b3" "checksum elastic-array 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "258ff6a9a94f648d0379dbd79110e057edbb53eb85cc237e33eadf8e5a30df85" "checksum env_logger 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)" = "3ddf21e73e016298f5cb37d6ef8e8da8e39f91f9ec8b0df44b7deb16a9f8cd5b" "checksum error-chain 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ff511d5dc435d703f4971bc399647c9bc38e20cb41452e3b9feb4765419ed3f3" @@ -1265,20 +1307,22 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum pretty_assertions 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "94b6bbc8a323d89a019c4cdde21850522fb8405e97add70827177fc2f86c1495" "checksum quote 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)" = "7a6e920b65c65f10b2ae65c831a81a073a89edd28c7cce89475bff467ab4167a" "checksum rand 0.3.18 (registry+https://github.com/rust-lang/crates.io-index)" = "6475140dfd8655aeb72e1fd4b7a1cc1c202be65d71669476e392fe62532b9edd" +"checksum rayon 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)" = "b614fe08b6665cb9a231d07ac1364b0ef3cb3698f1239ee0c4c3a88a524f54c8" +"checksum rayon-core 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e64b609139d83da75902f88fd6c01820046840a18471e4dfcd5ac7c0f46bea53" "checksum redox_syscall 0.1.31 (registry+https://github.com/rust-lang/crates.io-index)" = "8dde11f18c108289bef24469638a04dce49da56084f2d50618b226e47eb04509" "checksum redox_termios 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7e891cfe48e9100a70a3b6eb652fef28920c117d366339687bd5576160db0f76" "checksum regex 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "1731164734096285ec2a5ec7fea5248ae2f5485b3feeb0115af4fda2183b2d1b" "checksum regex-syntax 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "ad890a5eef7953f55427c50575c680c42841653abd2b028b68cd223d157f62db" "checksum relay 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f301bafeb60867c85170031bdb2fcf24c8041f33aee09e7b116a58d4e9f781c5" +"checksum ring 0.12.1 (registry+https://github.com/rust-lang/crates.io-index)" = "6f7d28b30a72c01b458428e0ae988d4149c20d902346902be881e3edc4bb325c" "checksum rlp 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "babe6fce20c0ca9b1582998734c4569082d0ad08e43772a1c6c40aef4f106ef9" -"checksum rust-crypto 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)" = "f76d05d3993fd5f4af9434e8e436db163a12a9d40e1a58a726f27a01dfd12a2a" "checksum rustc-demangle 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "aee45432acc62f7b9a108cc054142dac51f979e69e71ddce7d6fc7adf29e817e" "checksum rustc-hex 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "0ceb8ce7a5e520de349e1fa172baeba4a9e8d5ef06c47471863530bc4972ee1e" -"checksum rustc-serialize 0.3.24 (registry+https://github.com/rust-lang/crates.io-index)" = "dcf128d1287d2ea9d80910b5f1120d0b8eede3fbf1abe91c40d39ea7d51e6fda" "checksum rustc_version 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "c5f5376ea5e30ce23c03eb77cbe4962b988deead10910c372b226388b594c084" "checksum rustc_version 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b9743a7670d88d5d52950408ecdb7c71d8986251ab604d4689dd2ca25c9bca69" "checksum safemem 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e27a8b19b835f7aea908818e871f5cc3a5a186550c30773be987e155e8163d8f" "checksum scoped-tls 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f417c22df063e9450888a7561788e9bd46d3bb3c1466435b4eccb903807f147d" +"checksum scopeguard 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "94258f53601af11e6a49f722422f6e3425c52b06245a5cf9bc09908b174f5e27" "checksum semver 0.1.20 (registry+https://github.com/rust-lang/crates.io-index)" = "d4f410fedcf71af0345d7607d246e7ad15faaadd49d240ee3b24e5dc21a820ac" "checksum semver 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7a3186ec9e65071a2095434b1f5bb24838d4e8e130f584c790f6033c79943537" "checksum semver-parser 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3" @@ -1310,6 +1354,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum unicode-width 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "bf3a113775714a22dcb774d8ea3655c53a32debae63a063acc00a91cc586245f" "checksum unicode-xid 0.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "8c1f860d7d29cf02cb2f3f359fd35991af3d30bac52c57d265a3c461074cb4dc" "checksum unreachable 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "382810877fe448991dfc7f0dd6e3ae5d58088fd0ea5e35189655f84e6814fa56" +"checksum untrusted 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "f392d7819dbe58833e26872f5f6f0d68b7bbbe90fc3667e98731c4a15ad9a7ae" "checksum utf8-ranges 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "662fab6525a98beff2921d7f61a39e7d59e0b425ebc7d0d9e66d316e55124122" "checksum vec_map 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "887b5b631c2ad01628bbbaa7dd4c869f80d3186688f8d0b6f58774fbe324988c" "checksum void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d" diff --git a/substrate/ed25519.pk8 b/substrate/ed25519.pk8 new file mode 100644 index 0000000000000000000000000000000000000000..57a8e9f84df1dc3175d02132f88bf7d03563ed8a GIT binary patch literal 85 zcmV-b0IL5mQvv}2Fa-t!D`jv5A_O2jp9~yh%qqhDL7XlV#y11mAEmT)YK|2S8mY`X rKcB~;BLg7-wIOt@fg3EC6j=CGA>0MTxofFio@CXjjO!~zYbh_!erz9j literal 0 HcmV?d00001 diff --git a/substrate/pkcs8.key b/substrate/pkcs8.key new file mode 100644 index 0000000000..250fbac646 --- /dev/null +++ b/substrate/pkcs8.key @@ -0,0 +1,28 @@ +-----BEGIN PRIVATE KEY----- +MIIEvwIBADANBgkqhkiG9w0BAQEFAASCBKkwggSlAgEAAoIBAQDMpfNjaigc9FKC +8owWoKvAua3O1es2CB7Gq6pFI4Ctv34Wt5XSk83XkSXLOsf2ib1zCpzLUQSVLtH1 +c05uTH6rXLmjbH3lFOUCqD41dIveqo72sekHnYjS23ME2v5JCkg9YFmn32FffHGt +2Uaho+MQZWbpT3SD5tKRdaUUx1f/i16oB4Fnk8zCdQ7NPFru+WUV0cvQnK3rOpOo +KbK59Jo04bHmf/EPeVmxonwt/nmAJRUemuQXPl1cH8sk+t6Bxxp9FLzX6rtmpGDk +mBwrYBNC5auT3L1V2xabI2TKobd/qa+9/Sz41PeHsYLX/cu9Iplvj+LU85gYwv5d +kjvMEI7pAgMBAAECggEBAID7z21HSUUGkMLL0JOqbNYpsWx906PYdl1NcSHmgIIC +AZyb1ShF1CUb7LAsuj+fDPLnK2/R/otwWRDUvggy2ltzM+XWyXqLMtP76kmSzV1o +Lnc6Jt+P4N7VRac3x7GNc36LrbZqylp+er/SA/x46PI6lyRR2eQQpYLcnVF9Wu9K +bbTQ9nH+hxJiRG85GXKjeFkIj7PXBYAiYYcgiPF1RfB3o2R0cXZI24Y5/Ufc3OKg +Jws/VsTIzoxoLd3u6rDKX/N40/VBrGqv76HFqVwgnbxeG+i6HZNIAvZn+6m3a6l5 +APIZp7FfLJ1vZaHP7S7GeNmcz+eJ9Y/FanItohJGfqECgYEA5d17o9Ol3H+6wkQk +a3LU03NfvcdU5TqTOGvzx6yGGASjlByZWb7rMsRMyQ/wP60j+2Hd/G4rXbkF6vee +5uen7geJ6bzhUev1nd1NDcVdZay8x0r3huePUV96k+wU1IrOZrZddlqPyUJMctDy +VbwbDPM0saGx0xIlx/JOC1kEEr0CgYEA4+p/TSEq9DWH5QaMlVxBp48HY4Yrv/gQ +UmNUbCyd7J21Re+7cY3ZGF5IoC2l4K4yPM6ovNipkX9WDZrw8T68sD8yTQzL/tDE +CuXxG+X0b81k5UiZBFIGXiBb8JpoHRKNNGjZTZyBNhOKc902oKoNyTKILX3qI/aL +M2v/SELm5Z0CgYEAx+XZnPn09pF5t3GM/ogpPw3Jh/+t+376AooWwWFuZ7q5Cpfo +YFygq1B8uimLM8T9UqKkat7gBaxe0hyvanyw1FZoAAXLKPP7cGLAnKYzd7VFoka2 +hfIf95MBxVv8LW3c2wPiuYc+HbbzRrIg3KAuIg/qlkNYoobYpk44wrOR0D0CgYB0 +RNeGaGo6ROi7nHixZWwU57FUQ0kkWI8zCHsz6Br0b4vfTqooBr3+YXLZTBA4K4Vz +YdXQ6RKwJ+6laCqMV334x3SIvAOBTc0E5kL3AXuOYZCcK0nsW0/mSsm8V3jPg/xH +BUn9/t4n0RYrf2lz0uzPfBjeZELC7+4ZYHnNyltyPQKBgQCvT40UwZ5yHAt3leWG +stGRTkbupenh2z23hXY0Cio8Zqa7KE5jBWdF4uu27ScK4rhFdS1sgQJFghj6SxRO +VT5PQuRP9ETJIVwNgNQbAxbfeg8DADKGAWX9W5r//WlW1xH0/tSAxX6Pp/IiT9or +cRljrhP8zW6qhj3BKjdivPDgPw== +-----END PRIVATE KEY----- diff --git a/substrate/primitives/Cargo.toml b/substrate/primitives/Cargo.toml index 3e2877e073..045afba827 100644 --- a/substrate/primitives/Cargo.toml +++ b/substrate/primitives/Cargo.toml @@ -11,8 +11,8 @@ serde = "1.0" serde_derive = "1.0" tiny-keccak = "1.3" uint = { git = "https://github.com/paritytech/primitives.git" } -rust-crypto = "0.2.36" ring = "0.12" +untrusted = "0.5" [dev-dependencies] polkadot-serializer = { path = "../serializer", version = "0.1" } diff --git a/substrate/primitives/src/lib.rs b/substrate/primitives/src/lib.rs index ad4c6efd58..cd166f0a54 100644 --- a/substrate/primitives/src/lib.rs +++ b/substrate/primitives/src/lib.rs @@ -21,7 +21,8 @@ extern crate rustc_hex; extern crate serde; extern crate tiny_keccak; -extern crate crypto; +extern crate ring; +extern crate untrusted; #[macro_use] extern crate crunchy; @@ -63,30 +64,85 @@ pub fn hash(data: &[u8]) -> hash::H256 { /// Cool module. pub mod ed25519 { - use crypto; + use untrusted; + use ring::{rand, signature}; use rustc_hex::FromHex; - #[derive(PartialEq, Clone)] - struct Public ([u8; 32]); + struct HexDisplay<'a>(&'a [u8]); + + impl<'a> ::std::fmt::Display for HexDisplay<'a> { + fn fmt(&self, fmtr: &mut ::std::fmt::Formatter) -> Result<(), ::std::fmt::Error> { + for byte in self.0 { + try!( fmtr.write_fmt(format_args!("{:02x}", byte))); + } + Ok(()) + } + } + + /// A public key. + #[derive(PartialEq, Clone, Debug)] + pub struct Public ([u8; 32]); + + /// A key pair. + pub struct Pair(signature::Ed25519KeyPair); + + /// A signature. #[derive(Clone)] - struct Pair ([u8; 64]); - #[derive(Clone)] - struct Signature ([u8; 64]); + pub 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) + /// Generate new secure (random) key pair. + pub fn new() -> Pair { + let rng = rand::SystemRandom::new(); + let pkcs8_bytes = signature::Ed25519KeyPair::generate_pkcs8(&rng).unwrap(); + Pair(signature::Ed25519KeyPair::from_pkcs8(untrusted::Input::from(&pkcs8_bytes)).unwrap()) } + /// Make a new key pair from a seed phrase. + pub fn from_seed(seed: &[u8; 32]) -> Pair { + Pair(signature::Ed25519KeyPair::from_seed_unchecked(untrusted::Input::from(&seed[..])).unwrap()) + } + /// Make a new key pair from the raw secret. + pub fn from_secret(secret: &[u8; 32]) -> Pair { + let mut pkcs8_bytes = FromHex::from_hex("302e020100300506032b657004220420").unwrap(); + pkcs8_bytes.extend_from_slice(&secret[..]); + Pair(signature::Ed25519KeyPair::from_pkcs8_maybe_unchecked(untrusted::Input::from(&pkcs8_bytes)).unwrap()) + } + /// Make a new key pair from the raw secret and public key (it will check to make sure + /// they correspond to each other). + pub fn from_both(secret_public: &[u8; 64]) -> Option { + let mut pkcs8_bytes = FromHex::from_hex("3053020101300506032b657004220420").unwrap(); + pkcs8_bytes.extend_from_slice(&secret_public[0..32]); + pkcs8_bytes.extend_from_slice(&[0xa1u8, 0x23, 0x03, 0x21, 0x00]); + pkcs8_bytes.extend_from_slice(&secret_public[32..64]); + signature::Ed25519KeyPair::from_pkcs8_maybe_unchecked(untrusted::Input::from(&pkcs8_bytes)).ok().map(Pair) + } + /// Sign a message. pub fn sign(&self, message: &[u8]) -> Signature { - Signature(crypto::ed25519::signature(message, &self.0)) + let mut r = [0u8; 64]; + r.copy_from_slice(self.0.sign(message).as_ref()); + Signature(r) } + /// Get the public key. pub fn public(&self) -> Public { let mut r = [0u8; 32]; - r.copy_from_slice(&self.0[32..64]); + let pk = self.0.public_key_bytes(); + r.copy_from_slice(pk); Public(r) } } + impl Signature { + /// Verify a message. + pub fn verify(&self, message: &[u8], public: &Public) -> bool { + let peer_public_key = untrusted::Input::from(&public.0[..]); + let msg = untrusted::Input::from(message); + let sig = untrusted::Input::from(&self.0[..]); + + match signature::verify(&signature::ED25519, peer_public_key, msg, sig) { + Ok(_) => true, + _ => false, + } + } + } impl From<&'static str> for Public { fn from(hex: &'static str) -> Self { let mut r = [0u8; 32]; @@ -96,9 +152,22 @@ pub mod ed25519 { } 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) + let data = FromHex::from_hex(hex).expect("Key pair given is static so hex should be good."); + match data.len() { + 32 => { + let mut r = [0u8; 32]; + r.copy_from_slice(&data[0..32]); + Pair::from_secret(&r) + } + 64 => { + let mut r = [0u8; 64]; + r.copy_from_slice(&data[0..64]); + Pair::from_both(&r).expect("Key pair given is static so should be good.") + } + _ => { + panic!("Key pair given is static so should be correct length."); + } + } } } impl From<&'static str> for Signature { @@ -115,26 +184,15 @@ pub mod ed25519 { } } - 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 pair: Pair = "9d61b19deffd5a60ba844af492ec2cc44449c5697b326919703bac031cae7f60".into(); let public = pair.public(); + assert_eq!(public, "d75a980182b10ab7d54bfed3c964073a0ee172f3daa62325af021a68f707511a".into()); let message = b""; let signature: Signature = "e5564300c360ac729086e2cc806e828a84877f1eb8e5d974d873e065224901555fb8821590a33bacc61e39701cf9b46bd25bf5f0595bbe24655141438e7a100b".into(); assert!(&pair.sign(&message[..]) == &signature); @@ -143,7 +201,16 @@ pub mod ed25519 { #[test] fn generated_pair_should_work() { - let pair = Pair::from_seed(b"test"); + let pair = Pair::new(); + let public = pair.public(); + let message = b"Something important"; + let signature = pair.sign(&message[..]); + assert!(signature.verify(&message[..], &public)); + } + + #[test] + fn seeded_pair_should_work() { + let pair = Pair::from_seed(b"12345678901234567890123456789012"); let public = pair.public(); let message = b"Something important"; let signature = pair.sign(&message[..]);