duniter_keys/lib.rs
1// Copyright (C) 2018 The Duniter Project Developers.
2//
3// This program is free software: you can redistribute it and/or modify
4// it under the terms of the GNU Affero General Public License as
5// published by the Free Software Foundation, either version 3 of the
6// License, or (at your option) any later version.
7//
8// This program is distributed in the hope that it will be useful,
9// but WITHOUT ANY WARRANTY; without even the implied warranty of
10// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11// GNU Affero General Public License for more details.
12//
13// You should have received a copy of the GNU Affero General Public License
14// along with this program. If not, see <https://www.gnu.org/licenses/>.
15
16//! Provide wrappers around public keys, private keys and signatures.
17//!
18//! - Keys can be converted to/from Base58 string format.
19//! - Signatures can be converted to/from Base64 string format.
20//!
21//! # Usage
22//!
23//! ```
24//! use duniter_keys::{Signature, PublicKey, PrivateKey, KeyPair};
25//! use duniter_keys::ed25519::KeyPairFromSaltedPasswordGenerator;
26//!
27//! let generator = KeyPairFromSaltedPasswordGenerator::with_default_parameters();
28//!
29//! let keypair = generator.generate(
30//! b"password",
31//! b"salt"
32//! );
33//!
34//! let message = "Hello, world!";
35//!
36//! let signature = keypair.sign(&message.as_bytes());
37//!
38//! assert!(keypair.pubkey.verify(&message.as_bytes(), &signature));
39//! ```
40//!
41//! # Format
42//!
43//! - Base58 use the following alphabet :
44//! `123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz`
45//! - Base64 use the following alphabet :
46//! `ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/`
47//! with `=` as padding character.
48
49#![deny(missing_docs, missing_debug_implementations, missing_copy_implementations, trivial_casts,
50 trivial_numeric_casts, unsafe_code, unstable_features, unused_import_braces,
51 unused_qualifications)]
52
53extern crate base58;
54extern crate base64;
55extern crate crypto;
56
57use std::fmt::Display;
58use std::fmt::Debug;
59
60use base58::ToBase58;
61
62pub mod ed25519;
63
64/// Errors enumeration for Base58/64 strings convertion.
65#[derive(Clone, Copy, Debug, PartialEq, Eq)]
66pub enum BaseConvertionError {
67 /// Data have invalid key length (found, expected).
68 InvalidKeyLendth(usize, usize),
69 /// Base58 have an invalid character.
70 InvalidCharacter(char, usize),
71 /// Base58 have invalid lendth
72 InvalidBaseConverterLength(),
73}
74
75/// Store a cryptographic signature.
76///
77/// A signature can be converted from/to Base64 format.
78/// When converted back and forth the value should be the same.
79///
80/// A signature can be made with a [`PrivateKey`]
81/// and a message, and verified with the associated [`PublicKey`].
82///
83/// [`PrivateKey`]: trait.PrivateKey.html
84/// [`PublicKey`]: trait.PublicKey.html
85pub trait Signature: Clone + Display + Debug + PartialEq + Eq {
86 /// Create a `Signature` from a Base64 string.
87 ///
88 /// The Base64 string should contains only valid Base64 characters
89 /// and have a correct length (64 bytes when converted). If it's not the case,
90 /// a [`BaseConvertionError`] is returned with the corresponding variant.
91 ///
92 /// [`BaseConvertionError`]: enum.BaseConvertionError.html
93 fn from_base64(base64_string: &str) -> Result<Self, BaseConvertionError>;
94
95 /// Encode the signature into Base64 string format.
96 fn to_base64(&self) -> String;
97}
98
99/// Store a cryptographic public key.
100///
101/// A `PublicKey` can be converted from/to Base64 format.
102/// When converted back and forth the value should be the same.
103///
104/// A `PublicKey` is used to verify the signature of a message
105/// with the associated [`PrivateKey`].
106///
107/// [`PrivateKey`]: trait.PrivateKey.html
108pub trait PublicKey: Clone + Display + Debug + PartialEq + Eq + ToBase58 {
109 /// Signature type of associated cryptosystem.
110 type Signature: Signature;
111
112 /// Create a PublicKey from a Base58 string.
113 ///
114 /// The Base58 string should contains only valid Base58 characters
115 /// and have a correct length. If it's not the case,
116 /// a [`BaseConvertionError`] is returned with the corresponding variant.
117 ///
118 /// [`BaseConvertionError`]: enum.BaseConvertionError.html
119 fn from_base58(base58_string: &str) -> Result<Self, BaseConvertionError>;
120
121 /// Verify a signature with this public key.
122 fn verify(&self, message: &[u8], signature: &Self::Signature) -> bool;
123}
124
125/// Store a cryptographic private key.
126///
127/// A `PrivateKey` can be converted from/to Base58 format.
128/// When converted back and forth the value should be the same.
129///
130/// A `PrivateKey` is used to sign a message. The corresponding [`PublicKey`]
131/// will then be used to verify that signature.
132///
133/// [`PublicKey`]: trait.PublicKey.html
134pub trait PrivateKey: Clone + Display + Debug + PartialEq + Eq + ToBase58 {
135 /// Signature type of associated cryptosystem.
136 type Signature: Signature;
137
138 /// Create a PrivateKey from a Base58 string.
139 ///
140 /// The Base58 string should contains only valid Base58 characters
141 /// and have a correct length. If it's not the case, a [`BaseConvertionError`]
142 /// is returned with the corresponding variant.
143 ///
144 /// [`BaseConvertionError`]: enum.BaseConvertionError.html
145 fn from_base58(base58_string: &str) -> Result<Self, BaseConvertionError>;
146
147 /// Sign a message with this private key.
148 fn sign(&self, message: &[u8]) -> Self::Signature;
149}
150
151/// Store a cryptographic key pair (`PublicKey` + `PrivateKey`)
152pub trait KeyPair: Clone + Display + Debug + PartialEq + Eq {
153 /// Signature type of associated cryptosystem.
154 type Signature: Signature;
155 /// PublicKey type of associated cryptosystem.
156 type PublicKey: PublicKey;
157 /// PrivateKey type of associated cryptosystem.
158 type PrivateKey: PrivateKey;
159
160 /// Get `PublicKey`
161 fn public_key(&self) -> Self::PublicKey;
162
163 /// Get `PrivateKey`
164 fn private_key(&self) -> Self::PrivateKey;
165
166 /// Sign a message with private key.
167 fn sign(&self, message: &[u8]) -> Self::Signature;
168
169 /// Verify a signature with public key.
170 fn verify(&self, message: &[u8], signature: &Self::Signature) -> bool;
171}