From 3643d5f3bd6f3357e89138b8417c3e1caedc5631 Mon Sep 17 00:00:00 2001
From: Nanocryk <nanocryk@gmail.com>
Date: Tue, 9 Jan 2018 14:35:38 +0100
Subject: [PATCH] added associated constraint + doc + fmt + removed useless
comments
Changed public API => increased numver 0.2.0
---
Cargo.lock | 2 +-
keys/Cargo.toml | 2 +-
keys/ed25519.rs | 799 +++++++++++++++++++++++-------------------------
keys/lib.rs | 42 +--
4 files changed, 395 insertions(+), 450 deletions(-)
diff --git a/Cargo.lock b/Cargo.lock
index 2c6ec61a..e35bda0d 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -33,7 +33,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "duniter-keys"
-version = "0.1.0"
+version = "0.2.0"
dependencies = [
"base58 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"base64 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
diff --git a/keys/Cargo.toml b/keys/Cargo.toml
index 6459b81c..3d6199a2 100644
--- a/keys/Cargo.toml
+++ b/keys/Cargo.toml
@@ -1,6 +1,6 @@
[package]
name = "duniter-keys"
-version = "0.1.0"
+version = "0.2.0"
authors = ["nanocryk <nanocryk@duniter.org>"]
description = "Manage cryptographic keys for the Duniter project."
repository = "https://git.duniter.org/nodes/rust/duniter-rs"
diff --git a/keys/ed25519.rs b/keys/ed25519.rs
index bab6cb14..8bb13a91 100644
--- a/keys/ed25519.rs
+++ b/keys/ed25519.rs
@@ -1,426 +1,397 @@
-// Copyright (C) 2017 The Duniter Project Developers.
-//
-// This program is free software: you can redistribute it and/or modify
-// it under the terms of the GNU Affero General Public License as
-// published by the Free Software Foundation, either version 3 of the
-// License, or (at your option) any later version.
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU Affero General Public License for more details.
-//
-// You should have received a copy of the GNU Affero General Public License
-// along with this program. If not, see <https://www.gnu.org/licenses/>.
-
-//! Provide wrappers around ed25519 keys and signatures
-//!
-//! Key pairs can be generated with [`KeyPairGenerator`].
-//!
-//! [`KeyPairGenerator`]: struct.KeyPairGenerator.html
-
-use std::fmt::Display;
-use std::fmt::Error;
-use std::fmt::Formatter;
-use std::fmt::Debug;
-
-use base58::{ToBase58, FromBase58, FromBase58Error};
-use base64;
-use base64::DecodeError;
-use crypto;
-
-use super::BaseConvertionError;
-
-
-
-// ---------------------------- //
-// ----- struct Signature ----- //
-// ---------------------------- //
-
-/// Store a ed25519 signature.
-#[derive(Clone, Copy)]
-pub struct Signature(pub [u8; 64]);
-
-impl super::Signature for Signature {
- fn from_base64(base64_data: &str) -> Result<Signature, BaseConvertionError> {
- match base64::decode(base64_data) {
- Ok(result) => {
- if result.len() == 64 {
- let mut u8_array = [0; 64];
-
- u8_array[..64].clone_from_slice(&result[..64]);
-
- Ok(Signature(u8_array))
- } else {
- Err(BaseConvertionError::InvalidKeyLendth(result.len(), 64))
- }
- }
- Err(DecodeError::InvalidByte(pos, byte)) => {
- Err(BaseConvertionError::InvalidCharacter(byte as char, pos))
- }
- Err(DecodeError::InvalidLength) => Err(
- BaseConvertionError::InvalidBaseConverterLength(),
- ),
- }
- }
-
- fn to_base64(&self) -> String {
- base64::encode(&self.0[..]) // need to take a slice for required trait `AsRef<[u8]>`
- }
-}
-
-impl Display for Signature {
- fn fmt(&self, f: &mut Formatter) -> Result<(), Error> {
- use super::Signature;
-
- write!(f, "{}", self.to_base64())
- }
-}
-
-impl Debug for Signature {
- // Signature { 1eubHHb... }
- fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
- write!(f, "Signature {{ {} }}", self)
- }
-}
-
-impl PartialEq<Signature> for Signature {
- fn eq(&self, other: &Signature) -> bool {
- // No PartialEq for [u8;64], need to use 2 [u8;32]
- self.0[0..32] == other.0[0..32] && self.0[32..64] == other.0[32..64]
- }
-}
-
-impl Eq for Signature {}
-
-
-
-// ---------------------------- //
-// ----- struct PublicKey ----- //
-// ---------------------------- //
-
-/// Store a Ed25519 public key.
-///
-/// Can be generated with [`KeyPairGenerator`].
-///
-/// [`KeyPairGenerator`]: struct.KeyPairGenerator.html
-#[derive(Copy, Clone, PartialEq, Eq)]
-pub struct PublicKey(pub [u8; 32]);
-
-impl ToBase58 for PublicKey {
- fn to_base58(&self) -> String {
- self.0.to_base58()
- }
-}
-
-impl Display for PublicKey {
- fn fmt(&self, f: &mut Formatter) -> Result<(), Error> {
- write!(f, "{}", self.to_base58())
- }
-}
-
-impl Debug for PublicKey {
- // PublicKey { DNann1L... }
- fn fmt(&self, f: &mut Formatter) -> Result<(), Error> {
- write!(f, "PublicKey {{ {} }}", self)
- }
-}
-
-impl super::PublicKey for PublicKey {
- type Signature = Signature;
-
- fn from_base58(base58_data: &str) -> Result<Self, BaseConvertionError> {
- match base58_data.from_base58() {
- Ok(result) => {
- if result.len() == 32 {
- let mut u8_array = [0; 32];
-
- u8_array[..32].clone_from_slice(&result[..32]);
-
- Ok(PublicKey(u8_array))
- } else {
- Err(BaseConvertionError::InvalidKeyLendth(result.len(), 32))
- }
- }
- Err(FromBase58Error::InvalidBase58Character(character, pos)) => Err(
- BaseConvertionError::InvalidCharacter(character, pos),
- ),
- Err(FromBase58Error::InvalidBase58Length) => Err(
- BaseConvertionError::InvalidBaseConverterLength(),
- ),
- }
- }
-
- fn verify(&self, message: &[u8], signature: &Self::Signature) -> bool {
- crypto::ed25519::verify(message, &self.0, &signature.0)
- }
-}
-
-
-
-// ----------------------------- //
-// ----- struct PrivateKey ----- //
-// ----------------------------- //
-
-/// Store a Ed25519 private key.
-///
-/// Can be generated with [`KeyPairGenerator`].
-///
-/// [`KeyPairGenerator`]: struct.KeyPairGenerator.html
-#[derive(Copy, Clone)]
-pub struct PrivateKey(pub [u8; 64]);
-
-impl ToBase58 for PrivateKey {
- fn to_base58(&self) -> String {
- self.0.to_base58()
- }
-}
-
-impl Display for PrivateKey {
- fn fmt(&self, f: &mut Formatter) -> Result<(), Error> {
- write!(f, "{}", self.to_base58())
- }
-}
-
-impl Debug for PrivateKey {
- // PrivateKey { 468Q1XtT... }
- fn fmt(&self, f: &mut Formatter) -> Result<(), Error> {
- write!(f, "PrivateKey {{ {} }}", self)
- }
-}
-
-impl PartialEq<PrivateKey> for PrivateKey {
- fn eq(&self, other: &PrivateKey) -> bool {
- // No PartialEq for [u8;64], need to use 2 [u8;32]
- self.0[0..32] == other.0[0..32] && self.0[32..64] == other.0[32..64]
- }
-}
-
-impl Eq for PrivateKey {}
-
-impl super::PrivateKey for PrivateKey {
- type Signature = Signature;
-
- fn from_base58(base58_data: &str) -> Result<Self, BaseConvertionError> {
- match base58_data.from_base58() {
- Ok(result) => {
- if result.len() == 64 {
- let mut u8_array = [0; 64];
-
- u8_array[..64].clone_from_slice(&result[..64]);
-
- Ok(PrivateKey(u8_array))
- } else {
- Err(BaseConvertionError::InvalidKeyLendth(result.len(), 64))
- }
- }
- Err(FromBase58Error::InvalidBase58Character(character, pos)) => Err(
- BaseConvertionError::InvalidCharacter(character, pos),
- ),
- Err(FromBase58Error::InvalidBase58Length) => Err(
- BaseConvertionError::InvalidBaseConverterLength(),
- ),
- }
- }
-
- /// Sign a message with this private key.
- fn sign(&self, message: &[u8]) -> Self::Signature {
- Signature(crypto::ed25519::signature(message, &self.0))
- }
-}
-
-
-
-
-// ----------------------------------- //
-// ----- struct KeyPairGenerator ----- //
-// ----------------------------------- //
-
-/// Keypair generator with given parameters for `scrypt` keypair function.
-#[derive(Debug, Copy, Clone)]
-pub struct KeyPairGenerator {
- /// The log2 of the Scrypt parameter `N`.
- log_n: u8,
- /// The Scrypt parameter `r`
- r: u32,
- /// The Scrypt parameter `p`
- p: u32,
-}
-
-impl KeyPairGenerator {
- /// Create a `KeyPairGenerator` with default arguments `(log_n: 12, r: 16, p: 1)`
- pub fn with_default_parameters() -> KeyPairGenerator {
- KeyPairGenerator {
- log_n: 12,
- r: 16,
- p: 1,
- }
- }
-
- /// Create a `KeyPairGenerator` with given arguments.
- ///
- /// # Arguments
- ///
- /// - log_n - The log2 of the Scrypt parameter N
- /// - r - The Scrypt parameter r
- /// - p - The Scrypt parameter p
- pub fn with_parameters(log_n: u8, r: u32, p: u32) -> KeyPairGenerator {
- KeyPairGenerator { log_n, r, p }
- }
-
- /// Create a keypair based on a given password and salt.
- ///
- /// The [`PublicKey`](struct.PublicKey.html) will be able to verify messaged signed with
- /// the [`PrivateKey`](struct.PrivateKey.html).
- pub fn generate(&self, password: &[u8], salt: &[u8]) -> (PrivateKey, PublicKey) {
- let mut seed = [0u8; 32];
- crypto::scrypt::scrypt(
- password,
- salt,
- &crypto::scrypt::ScryptParams::new(self.log_n, self.r, self.p),
- &mut seed,
- );
-
- let (private, public) = crypto::ed25519::keypair(&seed);
- (PrivateKey(private), PublicKey(public))
- }
-}
-
-
-
-// ---------------------- //
-// ----- UNIT TESTS ----- //
-// ---------------------- //
-
-#[cfg(test)]
-mod tests {
- use super::*;
- use {Signature, PublicKey, PrivateKey};
-
- #[test]
- fn base58_private_key() {
- let private58 = "468Q1XtTq7h84NorZdWBZFJrGkB18CbmbHr9tkp9snt5GiERP7ySs3wM8myLccbAAGejgMRC9r\
- qnXuW3iAfZACm7";
- let private_key = super::PrivateKey::from_base58(private58).unwrap();
- let private_raw = private58.from_base58().unwrap();
-
- for (key, raw) in private_key.0.iter().zip(private_raw.iter()) {
- assert_eq!(key, raw);
- }
-
- assert_eq!(private_key.to_base58(), private58);
- assert_eq!(
- private_key,
- super::PrivateKey::from_base58(private58).unwrap()
- );
-
+// Copyright (C) 2017 The Duniter Project Developers.
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero General Public License as
+// published by the Free Software Foundation, either version 3 of the
+// License, or (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU Affero General Public License for more details.
+//
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see <https://www.gnu.org/licenses/>.
+
+//! Provide wrappers around ed25519 keys and signatures
+//!
+//! Key pairs can be generated with [`KeyPairGenerator`].
+//!
+//! [`KeyPairGenerator`]: struct.KeyPairGenerator.html
+
+use std::fmt::Display;
+use std::fmt::Error;
+use std::fmt::Formatter;
+use std::fmt::Debug;
+
+use base58::{FromBase58, FromBase58Error, ToBase58};
+use base64;
+use base64::DecodeError;
+use crypto;
+
+use super::BaseConvertionError;
+
+/// Store a ed25519 signature.
+#[derive(Clone, Copy)]
+pub struct Signature(pub [u8; 64]);
+
+impl super::Signature for Signature {
+ fn from_base64(base64_data: &str) -> Result<Signature, BaseConvertionError> {
+ match base64::decode(base64_data) {
+ Ok(result) => {
+ if result.len() == 64 {
+ let mut u8_array = [0; 64];
+
+ u8_array[..64].clone_from_slice(&result[..64]);
+
+ Ok(Signature(u8_array))
+ } else {
+ Err(BaseConvertionError::InvalidKeyLendth(result.len(), 64))
+ }
+ }
+ Err(DecodeError::InvalidByte(pos, byte)) => {
+ Err(BaseConvertionError::InvalidCharacter(byte as char, pos))
+ }
+ Err(DecodeError::InvalidLength) => {
+ Err(BaseConvertionError::InvalidBaseConverterLength())
+ }
+ }
+ }
+
+ fn to_base64(&self) -> String {
+ base64::encode(&self.0[..]) // need to take a slice for required trait `AsRef<[u8]>`
+ }
+}
+
+impl Display for Signature {
+ fn fmt(&self, f: &mut Formatter) -> Result<(), Error> {
+ use super::Signature;
+
+ write!(f, "{}", self.to_base64())
+ }
+}
+
+impl Debug for Signature {
+ // Signature { 1eubHHb... }
+ fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
+ write!(f, "Signature {{ {} }}", self)
+ }
+}
+
+impl PartialEq<Signature> for Signature {
+ fn eq(&self, other: &Signature) -> bool {
+ // No PartialEq for [u8;64], need to use 2 [u8;32]
+ self.0[0..32] == other.0[0..32] && self.0[32..64] == other.0[32..64]
+ }
+}
+
+impl Eq for Signature {}
+
+/// Store a Ed25519 public key.
+///
+/// Can be generated with [`KeyPairGenerator`].
+///
+/// [`KeyPairGenerator`]: struct.KeyPairGenerator.html
+#[derive(Copy, Clone, PartialEq, Eq)]
+pub struct PublicKey(pub [u8; 32]);
+
+impl ToBase58 for PublicKey {
+ fn to_base58(&self) -> String {
+ self.0.to_base58()
+ }
+}
+
+impl Display for PublicKey {
+ fn fmt(&self, f: &mut Formatter) -> Result<(), Error> {
+ write!(f, "{}", self.to_base58())
+ }
+}
+
+impl Debug for PublicKey {
+ // PublicKey { DNann1L... }
+ fn fmt(&self, f: &mut Formatter) -> Result<(), Error> {
+ write!(f, "PublicKey {{ {} }}", self)
+ }
+}
+
+impl super::PublicKey for PublicKey {
+ type Signature = Signature;
+
+ fn from_base58(base58_data: &str) -> Result<Self, BaseConvertionError> {
+ match base58_data.from_base58() {
+ Ok(result) => {
+ if result.len() == 32 {
+ let mut u8_array = [0; 32];
+
+ u8_array[..32].clone_from_slice(&result[..32]);
+
+ Ok(PublicKey(u8_array))
+ } else {
+ Err(BaseConvertionError::InvalidKeyLendth(result.len(), 32))
+ }
+ }
+ Err(FromBase58Error::InvalidBase58Character(character, pos)) => {
+ Err(BaseConvertionError::InvalidCharacter(character, pos))
+ }
+ Err(FromBase58Error::InvalidBase58Length) => {
+ Err(BaseConvertionError::InvalidBaseConverterLength())
+ }
+ }
+ }
+
+ fn verify(&self, message: &[u8], signature: &Self::Signature) -> bool {
+ crypto::ed25519::verify(message, &self.0, &signature.0)
+ }
+}
+
+/// Store a Ed25519 private key.
+///
+/// Can be generated with [`KeyPairGenerator`].
+///
+/// [`KeyPairGenerator`]: struct.KeyPairGenerator.html
+#[derive(Copy, Clone)]
+pub struct PrivateKey(pub [u8; 64]);
+
+impl ToBase58 for PrivateKey {
+ fn to_base58(&self) -> String {
+ self.0.to_base58()
+ }
+}
+
+impl Display for PrivateKey {
+ fn fmt(&self, f: &mut Formatter) -> Result<(), Error> {
+ write!(f, "{}", self.to_base58())
+ }
+}
+
+impl Debug for PrivateKey {
+ // PrivateKey { 468Q1XtT... }
+ fn fmt(&self, f: &mut Formatter) -> Result<(), Error> {
+ write!(f, "PrivateKey {{ {} }}", self)
+ }
+}
+
+impl PartialEq<PrivateKey> for PrivateKey {
+ fn eq(&self, other: &PrivateKey) -> bool {
+ // No PartialEq for [u8;64], need to use 2 [u8;32]
+ self.0[0..32] == other.0[0..32] && self.0[32..64] == other.0[32..64]
+ }
+}
+
+impl Eq for PrivateKey {}
+
+impl super::PrivateKey for PrivateKey {
+ type Signature = Signature;
+
+ fn from_base58(base58_data: &str) -> Result<Self, BaseConvertionError> {
+ match base58_data.from_base58() {
+ Ok(result) => {
+ if result.len() == 64 {
+ let mut u8_array = [0; 64];
+
+ u8_array[..64].clone_from_slice(&result[..64]);
+
+ Ok(PrivateKey(u8_array))
+ } else {
+ Err(BaseConvertionError::InvalidKeyLendth(result.len(), 64))
+ }
+ }
+ Err(FromBase58Error::InvalidBase58Character(character, pos)) => {
+ Err(BaseConvertionError::InvalidCharacter(character, pos))
+ }
+ Err(FromBase58Error::InvalidBase58Length) => {
+ Err(BaseConvertionError::InvalidBaseConverterLength())
+ }
+ }
+ }
+
+ /// Sign a message with this private key.
+ fn sign(&self, message: &[u8]) -> Self::Signature {
+ Signature(crypto::ed25519::signature(message, &self.0))
+ }
+}
+
+/// Keypair generator with given parameters for `scrypt` keypair function.
+#[derive(Debug, Copy, Clone)]
+pub struct KeyPairGenerator {
+ /// The log2 of the Scrypt parameter `N`.
+ log_n: u8,
+ /// The Scrypt parameter `r`
+ r: u32,
+ /// The Scrypt parameter `p`
+ p: u32,
+}
+
+impl KeyPairGenerator {
+ /// Create a `KeyPairGenerator` with default arguments `(log_n: 12, r: 16, p: 1)`
+ pub fn with_default_parameters() -> KeyPairGenerator {
+ KeyPairGenerator {
+ log_n: 12,
+ r: 16,
+ p: 1,
+ }
+ }
+
+ /// Create a `KeyPairGenerator` with given arguments.
+ ///
+ /// # Arguments
+ ///
+ /// - log_n - The log2 of the Scrypt parameter N
+ /// - r - The Scrypt parameter r
+ /// - p - The Scrypt parameter p
+ pub fn with_parameters(log_n: u8, r: u32, p: u32) -> KeyPairGenerator {
+ KeyPairGenerator { log_n, r, p }
+ }
+
+ /// Create a keypair based on a given password and salt.
+ ///
+ /// The [`PublicKey`](struct.PublicKey.html) will be able to verify messaged signed with
+ /// the [`PrivateKey`](struct.PrivateKey.html).
+ pub fn generate(&self, password: &[u8], salt: &[u8]) -> (PrivateKey, PublicKey) {
+ let mut seed = [0u8; 32];
+ crypto::scrypt::scrypt(
+ password,
+ salt,
+ &crypto::scrypt::ScryptParams::new(self.log_n, self.r, self.p),
+ &mut seed,
+ );
+
+ let (private, public) = crypto::ed25519::keypair(&seed);
+ (PrivateKey(private), PublicKey(public))
+ }
+}
+
+#[cfg(test)]
+mod tests {
+ use super::*;
+ use {PrivateKey, PublicKey, Signature};
+
+ #[test]
+ fn base58_private_key() {
+ let private58 =
+ "468Q1XtTq7h84NorZdWBZFJrGkB18CbmbHr9tkp9snt5GiERP7ySs3wM8myLccbAAGejgMRC9r\
+ qnXuW3iAfZACm7";
+ let private_key = super::PrivateKey::from_base58(private58).unwrap();
+ let private_raw = private58.from_base58().unwrap();
+
+ for (key, raw) in private_key.0.iter().zip(private_raw.iter()) {
+ assert_eq!(key, raw);
+ }
+
+ assert_eq!(private_key.to_base58(), private58);
+ assert_eq!(
+ private_key,
+ super::PrivateKey::from_base58(private58).unwrap()
+ );
+
assert_eq!(
super::PrivateKey::from_base58(
"468Q1XtTq7h84NorZdWBZFJrGkB18CbmbHr9tkp9snt5GiERP7ySs3wM8myLccbAAGejgMRC9rqnXuW3iA\
fZACm7djh",
).unwrap_err(),
BaseConvertionError::InvalidKeyLendth(67, 64)
- );
- assert_eq!(
- super::PrivateKey::from_base58(
- "468Q1XtTq7h84NorZdWBZFJrGkB18CbmbHr9tkp9snt5GiERP7ySs3wM8myLccbAAGejgMRC9",
- ).unwrap_err(),
- BaseConvertionError::InvalidKeyLendth(53, 64)
- );
- assert_eq!(
- super::PrivateKey::from_base58(
- "468Q1XtTq7h84NorZdWBZFJrGkB18CbmbHr9tkp9snt5GiERP7ySs3wM8myLccbAAGejgMRC9<<",
- ).unwrap_err(),
- BaseConvertionError::InvalidCharacter('<', 73)
- );
- }
-
- #[test]
- fn base58_public_key() {
- let public58 = "DNann1Lh55eZMEDXeYt59bzHbA3NJR46DeQYCS2qQdLV";
- let public_key = super::PublicKey::from_base58(public58).unwrap();
- let public_raw = public58.from_base58().unwrap();
-
- for (key, raw) in public_key.0.iter().zip(public_raw.iter()) {
- assert_eq!(key, raw);
- }
-
- assert_eq!(public_key.to_base58(), public58);
- assert_eq!(public_key, super::PublicKey::from_base58(public58).unwrap());
-
- assert_eq!(
- super::PublicKey::from_base58("DNann1Lh55eZMEDXeYt59bzHbA3NJR46DeQYCS2qQdLVdjq")
- .unwrap_err(),
- BaseConvertionError::InvalidKeyLendth(35, 32)
- );
- assert_eq!(
- super::PublicKey::from_base58("DNann1Lh55eZMEDXeYt59bzHbA3NJR46DeQYCS2qQd").unwrap_err(),
- BaseConvertionError::InvalidKeyLendth(31, 32)
- );
- assert_eq!(
- super::PublicKey::from_base58("DNann1Lh55eZMEDXeYt59bzHbA3NJR46DeQYCS2qQd<<")
- .unwrap_err(),
- BaseConvertionError::InvalidCharacter('<', 42)
- );
- }
-
- #[test]
- fn base64_signature() {
- let signature64 = "1eubHHbuNfilHMM0G2bI30iZzebQ2cQ1PC7uPAw08FG\
- MMmQCRerlF/3pc4sAcsnexsxBseA/3lY03KlONqJBAg==";
- let signature = super::Signature::from_base64(signature64).unwrap();
- let signature_raw = base64::decode(signature64).unwrap();
-
- for (sig, raw) in signature.0.iter().zip(signature_raw.iter()) {
- assert_eq!(sig, raw);
- }
-
- assert_eq!(
- super::Signature::from_base64("YmhlaW9iaHNlcGlvaGVvaXNlcGl2ZXBvdm5pc2U=").unwrap_err(),
- BaseConvertionError::InvalidKeyLendth(29, 64)
- );
- assert_eq!(
- super::Signature::from_base64(
- "YmhlaW9iaHNlcGlvaGVvaXNlcGl2ZXBvdm5pc2V2c2JlaW9idmVpb3Zqc\
- 2V2Z3BpaHNlamVwZ25qZXNqb2dwZWpnaW9zZXNkdnNic3JicmJyZGJyZGI=",
- ).unwrap_err(),
- BaseConvertionError::InvalidKeyLendth(86, 64)
- );
- assert_eq!(
- super::Signature::from_base64(
- "1eubHHbuNfilHMM0G2bI30iZzebQ2cQ1PC7uPAw08FGMM\
- mQCRerlF/3pc4sAcsnexsxBseA/3lY03KlONqJBAgdha<<",
- ).unwrap_err(),
- BaseConvertionError::InvalidCharacter('<', 89)
- );
- }
-
- #[test]
- fn message_sign_verify() {
- let pubkey = super::PublicKey::from_base58("DNann1Lh55eZMEDXeYt59bzHbA3NJR46DeQYCS2qQdLV")
- .unwrap();
-
- let prikey = super::PrivateKey::from_base58(
- "468Q1XtTq7h84NorZdWBZFJrGkB18CbmbHr9tkp9snt\
- 5GiERP7ySs3wM8myLccbAAGejgMRC9rqnXuW3iAfZACm7",
- ).unwrap();
-
- let expected_signature = super::Signature::from_base64(
- "1eubHHbuNfilHMM0G2bI30iZzebQ2cQ1PC7uPAw08FG\
- MMmQCRerlF/3pc4sAcsnexsxBseA/3lY03KlONqJBAg==",
- ).unwrap();
-
+ );
+ assert_eq!(
+ super::PrivateKey::from_base58(
+ "468Q1XtTq7h84NorZdWBZFJrGkB18CbmbHr9tkp9snt5GiERP7ySs3wM8myLccbAAGejgMRC9",
+ ).unwrap_err(),
+ BaseConvertionError::InvalidKeyLendth(53, 64)
+ );
+ assert_eq!(
+ super::PrivateKey::from_base58(
+ "468Q1XtTq7h84NorZdWBZFJrGkB18CbmbHr9tkp9snt5GiERP7ySs3wM8myLccbAAGejgMRC9<<",
+ ).unwrap_err(),
+ BaseConvertionError::InvalidCharacter('<', 73)
+ );
+ }
+
+ #[test]
+ fn base58_public_key() {
+ let public58 = "DNann1Lh55eZMEDXeYt59bzHbA3NJR46DeQYCS2qQdLV";
+ let public_key = super::PublicKey::from_base58(public58).unwrap();
+ let public_raw = public58.from_base58().unwrap();
+
+ for (key, raw) in public_key.0.iter().zip(public_raw.iter()) {
+ assert_eq!(key, raw);
+ }
+
+ assert_eq!(public_key.to_base58(), public58);
+ assert_eq!(public_key, super::PublicKey::from_base58(public58).unwrap());
+
+ assert_eq!(
+ super::PublicKey::from_base58("DNann1Lh55eZMEDXeYt59bzHbA3NJR46DeQYCS2qQdLVdjq")
+ .unwrap_err(),
+ BaseConvertionError::InvalidKeyLendth(35, 32)
+ );
+ assert_eq!(
+ super::PublicKey::from_base58("DNann1Lh55eZMEDXeYt59bzHbA3NJR46DeQYCS2qQd")
+ .unwrap_err(),
+ BaseConvertionError::InvalidKeyLendth(31, 32)
+ );
+ assert_eq!(
+ super::PublicKey::from_base58("DNann1Lh55eZMEDXeYt59bzHbA3NJR46DeQYCS2qQd<<")
+ .unwrap_err(),
+ BaseConvertionError::InvalidCharacter('<', 42)
+ );
+ }
+
+ #[test]
+ fn base64_signature() {
+ let signature64 = "1eubHHbuNfilHMM0G2bI30iZzebQ2cQ1PC7uPAw08FG\
+ MMmQCRerlF/3pc4sAcsnexsxBseA/3lY03KlONqJBAg==";
+ let signature = super::Signature::from_base64(signature64).unwrap();
+ let signature_raw = base64::decode(signature64).unwrap();
+
+ for (sig, raw) in signature.0.iter().zip(signature_raw.iter()) {
+ assert_eq!(sig, raw);
+ }
+
+ assert_eq!(
+ super::Signature::from_base64("YmhlaW9iaHNlcGlvaGVvaXNlcGl2ZXBvdm5pc2U=").unwrap_err(),
+ BaseConvertionError::InvalidKeyLendth(29, 64)
+ );
+ assert_eq!(
+ super::Signature::from_base64(
+ "YmhlaW9iaHNlcGlvaGVvaXNlcGl2ZXBvdm5pc2V2c2JlaW9idmVpb3Zqc\
+ 2V2Z3BpaHNlamVwZ25qZXNqb2dwZWpnaW9zZXNkdnNic3JicmJyZGJyZGI=",
+ ).unwrap_err(),
+ BaseConvertionError::InvalidKeyLendth(86, 64)
+ );
+ assert_eq!(
+ super::Signature::from_base64(
+ "1eubHHbuNfilHMM0G2bI30iZzebQ2cQ1PC7uPAw08FGMM\
+ mQCRerlF/3pc4sAcsnexsxBseA/3lY03KlONqJBAgdha<<",
+ ).unwrap_err(),
+ BaseConvertionError::InvalidCharacter('<', 89)
+ );
+ }
+
+ #[test]
+ fn message_sign_verify() {
+ let pubkey =
+ super::PublicKey::from_base58("DNann1Lh55eZMEDXeYt59bzHbA3NJR46DeQYCS2qQdLV").unwrap();
+
+ let prikey = super::PrivateKey::from_base58(
+ "468Q1XtTq7h84NorZdWBZFJrGkB18CbmbHr9tkp9snt\
+ 5GiERP7ySs3wM8myLccbAAGejgMRC9rqnXuW3iAfZACm7",
+ ).unwrap();
+
+ let expected_signature = super::Signature::from_base64(
+ "1eubHHbuNfilHMM0G2bI30iZzebQ2cQ1PC7uPAw08FG\
+ MMmQCRerlF/3pc4sAcsnexsxBseA/3lY03KlONqJBAg==",
+ ).unwrap();
+
let message = "Version: 10
Type: Identity
Currency: duniter_unit_test_currency
Issuer: DNann1Lh55eZMEDXeYt59bzHbA3NJR46DeQYCS2qQdLV
UniqueID: tic
Timestamp: 0-E3B0C44298FC1C149AFBF4C8996FB92427AE41E4649B934CA495991B7852B855
-";
-
- let sig = prikey.sign(message.as_bytes());
-
- assert_eq!(sig, expected_signature);
- assert!(pubkey.verify(message.as_bytes(), &sig));
- }
-}
+";
+
+ let sig = prikey.sign(message.as_bytes());
+
+ assert_eq!(sig, expected_signature);
+ assert!(pubkey.verify(message.as_bytes(), &sig));
+ }
+}
diff --git a/keys/lib.rs b/keys/lib.rs
index 5f807abe..49842a68 100644
--- a/keys/lib.rs
+++ b/keys/lib.rs
@@ -1,4 +1,4 @@
-// Copyright (C) 2017 The Duniter Project Developers.
+// Copyright (C) 2018 The Duniter Project Developers.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as
@@ -46,12 +46,9 @@
//! `ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/`
//! with `=` as padding character.
-#![deny(missing_docs,
- missing_debug_implementations, missing_copy_implementations,
- trivial_casts, trivial_numeric_casts,
- unsafe_code,
- unstable_features,
- unused_import_braces, unused_qualifications)]
+#![deny(missing_docs, missing_debug_implementations, missing_copy_implementations, trivial_casts,
+ trivial_numeric_casts, unsafe_code, unstable_features, unused_import_braces,
+ unused_qualifications)]
extern crate base58;
extern crate base64;
@@ -64,10 +61,6 @@ use base58::ToBase58;
pub mod ed25519;
-// ------------------------------------ //
-// ----- enum BaseConvertionError ----- //
-// ------------------------------------ //
-
/// Errors enumeration for Base58/64 strings convertion.
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum BaseConvertionError {
@@ -79,11 +72,6 @@ pub enum BaseConvertionError {
InvalidBaseConverterLength(),
}
-
-// --------------------------- //
-// ----- trait Signature ----- //
-// --------------------------- //
-
/// Store a cryptographic signature.
///
/// A signature can be converted from/to Base64 format.
@@ -108,11 +96,6 @@ pub trait Signature: Clone + Display + Debug + PartialEq + Eq {
fn to_base64(&self) -> String;
}
-
-// ---------------------------- //
-// ----- struct PublicKey ----- //
-// ---------------------------- //
-
/// Store a cryptographic public key.
///
/// A `PublicKey` can be converted from/to Base64 format.
@@ -123,10 +106,8 @@ pub trait Signature: Clone + Display + Debug + PartialEq + Eq {
///
/// [`PrivateKey`]: trait.PrivateKey.html
pub trait PublicKey: Clone + Display + Debug + PartialEq + Eq + ToBase58 {
- /// [`Signature`] type of associated cryptosystem.
- ///
- /// [`Signature`]: trait.Signature.html
- type Signature;
+ /// Signature type of associated cryptosystem.
+ type Signature: Signature;
/// Create a PublicKey from a Base58 string.
///
@@ -141,11 +122,6 @@ pub trait PublicKey: Clone + Display + Debug + PartialEq + Eq + ToBase58 {
fn verify(&self, message: &[u8], signature: &Self::Signature) -> bool;
}
-
-// ----------------------------- //
-// ----- struct PrivateKey ----- //
-// ----------------------------- //
-
/// Store a cryptographic private key.
///
/// A `PrivateKey` can be converted from/to Base58 format.
@@ -156,10 +132,8 @@ pub trait PublicKey: Clone + Display + Debug + PartialEq + Eq + ToBase58 {
///
/// [`PublicKey`]: trait.PublicKey.html
pub trait PrivateKey: Clone + Display + Debug + PartialEq + Eq + ToBase58 {
- /// [`Signature`] type of associated cryptosystem.
- ///
- /// [`Signature`]: trait.Signature.html
- type Signature;
+ /// Signature type of associated cryptosystem.
+ type Signature: Signature;
/// Create a PrivateKey from a Base58 string.
///
--
GitLab