use crate::bases::BaseConvertionError;
use base58::ToBase58;
use bincode;
use std::fmt::Debug;
use std::fmt::Display;
use std::fmt::Error;
use std::fmt::Formatter;
use std::hash::Hash;
pub mod bin_signable;
pub mod ed25519;
pub mod text_signable;
#[derive(Clone, Copy, Debug, PartialEq, Eq, Serialize, Deserialize, Hash)]
pub enum KeysAlgo {
Ed25519 = 0,
Schnorr = 1,
}
pub trait GetKeysAlgo: Clone + Debug + PartialEq + Eq {
fn algo(&self) -> KeysAlgo;
}
#[derive(Debug)]
pub enum SigError {
NotSameAlgo(),
InvalidSig(),
NotSig(),
DeserError(bincode::Error),
}
impl From<bincode::Error> for SigError {
fn from(e: bincode::Error) -> Self {
SigError::DeserError(e)
}
}
#[derive(Debug, Copy, Clone)]
pub enum SignError {
WrongAlgo(),
WrongPrivkey(),
AlreadySign(),
}
pub trait Signature: Clone + Display + Debug + PartialEq + Eq + Hash {
fn from_base64(base64_string: &str) -> Result<Self, BaseConvertionError>;
fn to_bytes_vector(&self) -> Vec<u8>;
fn to_base64(&self) -> String;
}
#[derive(Clone, Copy, Debug, Deserialize, Eq, Hash, PartialEq, Serialize)]
pub enum Sig {
Ed25519(ed25519::Signature),
Schnorr(),
}
impl Sig {
pub fn size_in_bytes(&self) -> usize {
match *self {
Sig::Ed25519(_) => *ed25519::SIG_SIZE_IN_BYTES + 2,
Sig::Schnorr() => panic!("Schnorr algo not yet supported !"),
}
}
}
impl Display for Sig {
fn fmt(&self, f: &mut Formatter) -> Result<(), Error> {
write!(f, "{}", self.to_base64())
}
}
impl GetKeysAlgo for Sig {
fn algo(&self) -> KeysAlgo {
match *self {
Sig::Ed25519(_) => KeysAlgo::Ed25519,
Sig::Schnorr() => KeysAlgo::Schnorr,
}
}
}
impl Signature for Sig {
fn from_base64(_base64_string: &str) -> Result<Self, BaseConvertionError> {
unimplemented!()
}
fn to_bytes_vector(&self) -> Vec<u8> {
match *self {
Sig::Ed25519(ed25519_sig) => ed25519_sig.to_bytes_vector(),
Sig::Schnorr() => panic!("Schnorr algo not yet supported !"),
}
}
fn to_base64(&self) -> String {
match *self {
Sig::Ed25519(ed25519_sig) => ed25519_sig.to_base64(),
Sig::Schnorr() => panic!("Schnorr algo not yet supported !"),
}
}
}
pub trait PublicKey: Clone + Display + Debug + PartialEq + Eq + Hash + ToBase58 {
type Signature: Signature;
fn from_base58(base58_string: &str) -> Result<Self, BaseConvertionError>;
fn to_bytes_vector(&self) -> Vec<u8>;
fn verify(&self, message: &[u8], signature: &Self::Signature) -> bool;
}
#[derive(Clone, Copy, Debug, Deserialize, Eq, Hash, PartialEq, Serialize)]
pub enum PubKey {
Ed25519(ed25519::PublicKey),
Schnorr(),
}
impl PubKey {
pub fn size_in_bytes(&self) -> usize {
match *self {
PubKey::Ed25519(_) => ed25519::PUBKEY_SIZE_IN_BYTES + 3,
PubKey::Schnorr() => panic!("Schnorr algo not yet supported !"),
}
}
}
impl Default for PubKey {
fn default() -> Self {
PubKey::Schnorr()
}
}
impl GetKeysAlgo for PubKey {
fn algo(&self) -> KeysAlgo {
match *self {
PubKey::Ed25519(_) => KeysAlgo::Ed25519,
PubKey::Schnorr() => KeysAlgo::Schnorr,
}
}
}
impl ToBase58 for PubKey {
fn to_base58(&self) -> String {
match *self {
PubKey::Ed25519(ed25519_pub) => ed25519_pub.to_base58(),
PubKey::Schnorr() => panic!("Schnorr algo not yet supported !"),
}
}
}
impl Display for PubKey {
fn fmt(&self, f: &mut Formatter) -> Result<(), Error> {
write!(f, "{}", self.to_base58())
}
}
impl PublicKey for PubKey {
type Signature = Sig;
fn from_base58(_base58_string: &str) -> Result<Self, BaseConvertionError> {
unimplemented!()
}
fn to_bytes_vector(&self) -> Vec<u8> {
match *self {
PubKey::Ed25519(ed25519_pubkey) => ed25519_pubkey.to_bytes_vector(),
PubKey::Schnorr() => panic!("Schnorr algo not yet supported !"),
}
}
fn verify(&self, message: &[u8], signature: &Self::Signature) -> bool {
match *self {
PubKey::Ed25519(ed25519_pubkey) => {
if let Sig::Ed25519(ed25519_sig) = signature {
ed25519_pubkey.verify(message, ed25519_sig)
} else {
panic!("Try to verify a signature with public key of a different algorithm !\nSignature={:?}\nPublickey={:?}", signature, self)
}
}
PubKey::Schnorr() => panic!("Schnorr algo not yet supported !"),
}
}
}
pub trait PrivateKey: Clone + Display + Debug + PartialEq + Eq + ToBase58 {
type Signature: Signature;
fn from_base58(base58_string: &str) -> Result<Self, BaseConvertionError>;
fn sign(&self, message: &[u8]) -> Self::Signature;
}
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub enum PrivKey {
Ed25519(ed25519::PrivateKey),
Schnorr(),
}
impl GetKeysAlgo for PrivKey {
fn algo(&self) -> KeysAlgo {
match *self {
PrivKey::Ed25519(_) => KeysAlgo::Ed25519,
PrivKey::Schnorr() => KeysAlgo::Schnorr,
}
}
}
impl ToBase58 for PrivKey {
fn to_base58(&self) -> String {
match *self {
PrivKey::Ed25519(ed25519_privkey) => ed25519_privkey.to_base58(),
PrivKey::Schnorr() => panic!("Schnorr algo not yet supported !"),
}
}
}
impl Display for PrivKey {
fn fmt(&self, f: &mut Formatter) -> Result<(), Error> {
write!(f, "{}", self.to_base58())
}
}
impl PrivateKey for PrivKey {
type Signature = Sig;
fn from_base58(_base58_string: &str) -> Result<Self, BaseConvertionError> {
unimplemented!()
}
fn sign(&self, message: &[u8]) -> Self::Signature {
match *self {
PrivKey::Ed25519(ed25519_privkey) => Sig::Ed25519(ed25519_privkey.sign(message)),
PrivKey::Schnorr() => panic!("Schnorr algo not yet supported !"),
}
}
}
pub trait KeyPair: Clone + Display + Debug + PartialEq + Eq {
type Signature: Signature;
type PublicKey: PublicKey;
type PrivateKey: PrivateKey;
fn public_key(&self) -> Self::PublicKey;
fn private_key(&self) -> Self::PrivateKey;
fn sign(&self, message: &[u8]) -> Self::Signature;
fn verify(&self, message: &[u8], signature: &Self::Signature) -> bool;
}
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub enum KeyPairEnum {
Ed25519(ed25519::KeyPair),
Schnorr(),
}
impl GetKeysAlgo for KeyPairEnum {
fn algo(&self) -> KeysAlgo {
match *self {
KeyPairEnum::Ed25519(_) => KeysAlgo::Ed25519,
KeyPairEnum::Schnorr() => KeysAlgo::Schnorr,
}
}
}
impl Display for KeyPairEnum {
fn fmt(&self, f: &mut Formatter) -> Result<(), Error> {
match *self {
KeyPairEnum::Ed25519(ed25519_keypair) => {
write!(f, "({}, hidden)", ed25519_keypair.pubkey.to_base58())
}
KeyPairEnum::Schnorr() => panic!("Schnorr algo not yet supported !"),
}
}
}
impl KeyPair for KeyPairEnum {
type Signature = Sig;
type PublicKey = PubKey;
type PrivateKey = PrivKey;
fn public_key(&self) -> Self::PublicKey {
match *self {
KeyPairEnum::Ed25519(ed25519_keypair) => PubKey::Ed25519(ed25519_keypair.public_key()),
KeyPairEnum::Schnorr() => panic!("Schnorr algo not yet supported !"),
}
}
fn private_key(&self) -> Self::PrivateKey {
match *self {
KeyPairEnum::Ed25519(ed25519_keypair) => {
PrivKey::Ed25519(ed25519_keypair.private_key())
}
KeyPairEnum::Schnorr() => panic!("Schnorr algo not yet supported !"),
}
}
fn verify(&self, message: &[u8], signature: &Sig) -> bool {
match *self {
KeyPairEnum::Ed25519(ed25519_keypair) => {
if let Sig::Ed25519(ed25519_sig) = signature {
ed25519_keypair.verify(message, ed25519_sig)
} else {
panic!("Try to verify a signature with key pair of a different algorithm !\nSignature={:?}\nKeyPair={:?}", signature, self)
}
}
KeyPairEnum::Schnorr() => panic!("Schnorr algo not yet supported !"),
}
}
fn sign(&self, message: &[u8]) -> Sig {
match *self {
KeyPairEnum::Ed25519(ed25519_keypair) => Sig::Ed25519(ed25519_keypair.sign(message)),
KeyPairEnum::Schnorr() => panic!("Schnorr algo not yet supported !"),
}
}
}