use std::str::FromStr;
use bip32::PublicKey;
use ecdsa::PrimeCurve;
use ecdsa::signature::Signer;
use ecdsa::signature::RandomizedSigner;
use ecdsa::signature::Keypair;
use k256::ecdsa::{SigningKey, Signature, VerifyingKey};
use k256::Secp256k1;
use k256::ecdsa::signature::Verifier;
use pem::Pem;
use rand::rngs::OsRng;
use serde::{Serialize,Deserialize};
use zeroize::{Zeroize,ZeroizeOnDrop};
use serde_big_array::BigArray;
use slugencode::SlugEncodingUsage;
use slugencode::SlugEncodings;
use slugencode::errors::SlugEncodingError;
use crate::errors::SlugErrorAlgorithms;
use crate::slugcrypt::traits::FromEncoding;
use crate::slugcrypt::traits::IntoEncoding;
use crate::slugcrypt::traits::RecoverablePublicKey;
use crate::slugcrypt::traits::{FromBincode,IntoBincode};
use crate::slugcrypt::traits::{FromStandardPem, IntoStandardPem};
use crate::slugcrypt::traits::{IntoStandardEncoding,FromStandardEncoding};
use crate::errors::SlugErrors;
#[derive(Clone,PartialEq,PartialOrd,Hash,Debug,Serialize,Deserialize,Zeroize,ZeroizeOnDrop)]
pub struct ECDSAPublicKey(#[serde(with = "BigArray")]pub [u8;33]);
#[derive(Clone,PartialEq,PartialOrd,Hash,Debug,Serialize,Deserialize,Zeroize,ZeroizeOnDrop)]
pub struct ECDSASecretKey(pub [u8;32]);
#[derive(Clone,PartialEq,PartialOrd,Hash,Debug,Serialize,Deserialize,Zeroize,ZeroizeOnDrop)]
pub struct ECDSASignature(
#[serde(with = "BigArray")]
pub [u8;64]
);
#[derive(Clone,PartialEq,PartialOrd,Hash,Debug,Serialize,Deserialize,Zeroize,ZeroizeOnDrop)]
pub struct ECDSASignatureRecoveryID(pub u8);
impl RecoverablePublicKey for ECDSAPublicKey {
}
impl RecoverablePublicKey for ECDSASecretKey {
}
impl ECDSASignature {
pub fn verify<T: AsRef<[u8]>>(&self, bytes: T, pk: ECDSAPublicKey) -> Result<bool,SlugErrors> {
return pk.verify(bytes.as_ref(), self.clone())
}
pub fn as_bytes(&self) -> &[u8] {
return self.0.as_slice()
}
pub fn to_bytes(&self) -> Vec<u8> {
return self.0.to_vec()
}
pub fn from_bytes(bytes: [u8;64]) -> Self {
return Self(bytes)
}
pub fn from_slice(bytes: &[u8]) -> Result<Self,SlugErrors> {
let mut output: [u8;64] = [0u8;64];
if bytes.len() == 64 {
output.copy_from_slice(bytes);
Ok(Self(output))
}
else {
return Err(SlugErrors::InvalidLengthFromBytes)
}
}
pub fn into_usable_type(&self) -> Result<Signature,SlugErrors> {
let x = Signature::from_slice(&self.0);
match x {
Ok(v) => Ok(v),
Err(_) => return Err(SlugErrors::InvalidLengthFromBytes)
}
}
pub fn from_base58<T: AsRef<str>>(s: T) -> Result<Self,SlugEncodingError> {
let x = SlugEncodingUsage::new(SlugEncodings::Base58);
let output = x.decode(s.as_ref())?;
let output = Self::from_slice(&output);
match output {
Ok(v) => return Ok(v),
Err(_) => return Err(SlugEncodingError::DecodingError)
}
}
pub fn from_hex<T: AsRef<str>>(s: T) -> Result<Self,SlugEncodingError> {
let x = SlugEncodingUsage::new(SlugEncodings::Hex);
let output = x.decode(s.as_ref())?;
let output = Self::from_slice(&output);
match output {
Ok(v) => return Ok(v),
Err(_) => return Err(SlugEncodingError::DecodingError)
}
}
pub fn from_base32<T: AsRef<str>>(s: T) -> Result<Self,SlugEncodingError> {
let x = SlugEncodingUsage::new(SlugEncodings::Base32);
let output = x.decode(s.as_ref())?;
let output = Self::from_slice(&output);
match output {
Ok(v) => return Ok(v),
Err(_) => return Err(SlugEncodingError::DecodingError)
}
}
pub fn from_base32_unpadded<T: AsRef<str>>(s: T) -> Result<Self,SlugEncodingError> {
let x = SlugEncodingUsage::new(SlugEncodings::Base32unpadded);
let output = x.decode(s.as_ref())?;
let output = Self::from_slice(&output);
match output {
Ok(v) => return Ok(v),
Err(_) => return Err(SlugEncodingError::DecodingError)
}
}
pub fn from_base64<T: AsRef<str>>(s: T) -> Result<Self,SlugEncodingError> {
let x = SlugEncodingUsage::new(SlugEncodings::Base64);
let output = x.decode(s.as_ref())?;
let output = Self::from_slice(&output);
match output {
Ok(v) => return Ok(v),
Err(_) => return Err(SlugEncodingError::DecodingError)
}
}
pub fn from_base64_url_safe<T: AsRef<str>>(s: T) -> Result<Self,SlugEncodingError> {
let x = SlugEncodingUsage::new(SlugEncodings::Base64urlsafe);
let output = x.decode(s.as_ref())?;
let output = Self::from_slice(&output);
match output {
Ok(v) => return Ok(v),
Err(_) => return Err(SlugEncodingError::DecodingError)
}
}
pub fn to_hex(&self) -> Result<String,SlugEncodingError> {
let x = SlugEncodingUsage::new(SlugEncodings::Hex);
let output = x.encode(&self.0);
match output {
Ok(v) => Ok(v),
Err(_) => return Err(SlugEncodingError::EncodingError)
}
}
pub fn to_base32(&self) -> Result<String,SlugEncodingError> {
let x = SlugEncodingUsage::new(SlugEncodings::Base32);
let output = x.encode(&self.0);
match output {
Ok(v) => Ok(v),
Err(_) => return Err(SlugEncodingError::EncodingError)
}
}
pub fn to_base32_unpadded(&self) -> Result<String,SlugEncodingError> {
let x = SlugEncodingUsage::new(SlugEncodings::Base32unpadded);
let output = x.encode(&self.0);
match output {
Ok(v) => Ok(v),
Err(_) => return Err(SlugEncodingError::EncodingError)
}
}
pub fn to_base58(&self) -> Result<String,SlugEncodingError> {
let x = SlugEncodingUsage::new(SlugEncodings::Base58);
let output = x.encode(&self.0);
match output {
Ok(v) => Ok(v),
Err(_) => return Err(SlugEncodingError::EncodingError)
}
}
pub fn to_base64(&self) -> Result<String,SlugEncodingError> {
let x = SlugEncodingUsage::new(SlugEncodings::Base64);
let output = x.encode(&self.0);
match output {
Ok(v) => Ok(v),
Err(_) => return Err(SlugEncodingError::EncodingError)
}
}
pub fn to_base64_url_safe(&self) -> Result<String,SlugEncodingError> {
let x = SlugEncodingUsage::new(SlugEncodings::Base64urlsafe);
let output = x.encode(&self.0);
match output {
Ok(v) => Ok(v),
Err(_) => return Err(SlugEncodingError::EncodingError)
}
}
}
impl ECDSASecretKey {
pub fn generate() -> Self {
let mut bytes: [u8;32] = [0u8;32];
let mut os_rng = OsRng;
let key = k256::ecdsa::SigningKey::random(&mut os_rng);
let output_bytes = key.to_bytes().as_slice().to_vec();
bytes.copy_from_slice(&output_bytes);
ECDSASecretKey(bytes)
}
pub fn sign<T: AsRef<[u8]>>(&self, msg: T) -> Result<(ECDSASignature, ECDSASignatureRecoveryID), SlugErrors> {
let signature = self.to_usable_type();
let signingkey = match signature {
Ok(v) => v,
Err(_) => return Err(SlugErrors::SigningFailure(crate::errors::SlugErrorAlgorithms::SIG_SECP256k1)),
};
let x: Result<(ecdsa::Signature<Secp256k1>, ecdsa::RecoveryId), ecdsa::Error> = signingkey.sign_recoverable(msg.as_ref());
let output = match x {
Ok(v) => v,
Err(_) => return Err(SlugErrors::SigningFailure(crate::errors::SlugErrorAlgorithms::SIG_SECP256k1))
};
let output_bytes = output.0.to_bytes();
let recovery_id = output.1.to_byte();
let sig = ECDSASignature::from_slice(output_bytes.as_slice());
match sig {
Ok(v) => return Ok((v, ECDSASignatureRecoveryID(recovery_id))),
Err(_) => return Err(SlugErrors::SigningFailure(crate::errors::SlugErrorAlgorithms::SIG_SECP256k1)),
}
}
pub fn sign_prehash<T: AsRef<[u8]>>(&self, msg: T) -> Result<(ECDSASignature, ECDSASignatureRecoveryID), SlugErrors> {
let pk = self.to_usable_type();
let x: ecdsa::SigningKey<Secp256k1> = match pk {
Ok(v) => v,
Err(_) => return Err(SlugErrors::SigningFailure(crate::errors::SlugErrorAlgorithms::SIG_SECP256k1))
};
let signature = x.sign_prehash_recoverable(msg.as_ref());
let output = match signature {
Ok(v) => v,
Err(_) => return Err(SlugErrors::SigningFailure(crate::errors::SlugErrorAlgorithms::SIG_SECP256k1))
};
let signature_output = ECDSASignature::from_slice(&output.0.to_bytes())?;
let recovery_id = ECDSASignatureRecoveryID(output.1.to_byte());
return Ok((signature_output,recovery_id))
}
pub fn to_usable_type(&self) -> Result<SigningKey,ecdsa::Error> {
let key: ecdsa::SigningKey<Secp256k1> = SigningKey::from_slice(&self.0)?;
return Ok(key)
}
pub fn to_usable_type_pk(&self) -> Result<VerifyingKey,ecdsa::Error> {
let x = self.to_usable_type();
let key = match x {
Ok(v) => v,
Err(_) => return Err(ecdsa::Error::default()),
};
return Ok(key.verifying_key().to_owned())
}
pub fn public_key(&self) -> Result<ECDSAPublicKey,ecdsa::Error> {
let mut output_bytes: [u8;33] = [0u8;33];
let bytes = self.to_usable_type_pk();
let pk = match bytes {
Ok(v) => v,
Err(_) => return Err(ecdsa::Error::default())
};
let bytes = pk.to_sec1_bytes();
let final_bytes = bytes.to_vec();
if final_bytes.len() == 33 {
output_bytes.copy_from_slice(&final_bytes);
}
Ok(ECDSAPublicKey(output_bytes))
}
pub fn from_slice(bytes: &[u8]) -> Result<Self,SlugErrors> {
let mut output: [u8;32] = [0u8;32];
if bytes.len() == 32 {
output.copy_from_slice(bytes);
Ok(Self(output))
}
else {
return Err(SlugErrors::InvalidLengthFromBytes)
}
}
pub fn from_base58<T: AsRef<str>>(s: T) -> Result<Self,SlugEncodingError> {
let x = SlugEncodingUsage::new(SlugEncodings::Base58);
let output = x.decode(s.as_ref())?;
let output = Self::from_slice(&output);
match output {
Ok(v) => return Ok(v),
Err(_) => return Err(SlugEncodingError::DecodingError)
}
}
pub fn from_hex<T: AsRef<str>>(s: T) -> Result<Self,SlugEncodingError> {
let x = SlugEncodingUsage::new(SlugEncodings::Hex);
let output = x.decode(s.as_ref())?;
let output = Self::from_slice(&output);
match output {
Ok(v) => return Ok(v),
Err(_) => return Err(SlugEncodingError::DecodingError)
}
}
pub fn from_base32<T: AsRef<str>>(s: T) -> Result<Self,SlugEncodingError> {
let x = SlugEncodingUsage::new(SlugEncodings::Base32);
let output = x.decode(s.as_ref())?;
let output = Self::from_slice(&output);
match output {
Ok(v) => return Ok(v),
Err(_) => return Err(SlugEncodingError::DecodingError)
}
}
pub fn from_base32_unpadded<T: AsRef<str>>(s: T) -> Result<Self,SlugEncodingError> {
let x = SlugEncodingUsage::new(SlugEncodings::Base32unpadded);
let output = x.decode(s.as_ref())?;
let output = Self::from_slice(&output);
match output {
Ok(v) => return Ok(v),
Err(_) => return Err(SlugEncodingError::DecodingError)
}
}
pub fn from_base64<T: AsRef<str>>(s: T) -> Result<Self,SlugEncodingError> {
let x = SlugEncodingUsage::new(SlugEncodings::Base64);
let output = x.decode(s.as_ref())?;
let output = Self::from_slice(&output);
match output {
Ok(v) => return Ok(v),
Err(_) => return Err(SlugEncodingError::DecodingError)
}
}
pub fn from_base64_url_safe<T: AsRef<str>>(s: T) -> Result<Self,SlugEncodingError> {
let x = SlugEncodingUsage::new(SlugEncodings::Base64urlsafe);
let output = x.decode(s.as_ref())?;
let output = Self::from_slice(&output);
match output {
Ok(v) => return Ok(v),
Err(_) => return Err(SlugEncodingError::DecodingError)
}
}
pub fn to_hex(&self) -> Result<String,SlugEncodingError> {
let x = SlugEncodingUsage::new(SlugEncodings::Hex);
let output = x.encode(&self.0);
match output {
Ok(v) => Ok(v),
Err(_) => return Err(SlugEncodingError::EncodingError)
}
}
pub fn to_base32(&self) -> Result<String,SlugEncodingError> {
let x = SlugEncodingUsage::new(SlugEncodings::Base32);
let output = x.encode(&self.0);
match output {
Ok(v) => Ok(v),
Err(_) => return Err(SlugEncodingError::EncodingError)
}
}
pub fn to_base32_unpadded(&self) -> Result<String,SlugEncodingError> {
let x = SlugEncodingUsage::new(SlugEncodings::Base32unpadded);
let output = x.encode(&self.0);
match output {
Ok(v) => Ok(v),
Err(_) => return Err(SlugEncodingError::EncodingError)
}
}
pub fn to_base58(&self) -> Result<String,SlugEncodingError> {
let x = SlugEncodingUsage::new(SlugEncodings::Base58);
let output = x.encode(&self.0);
match output {
Ok(v) => Ok(v),
Err(_) => return Err(SlugEncodingError::EncodingError)
}
}
pub fn to_base64(&self) -> Result<String,SlugEncodingError> {
let x = SlugEncodingUsage::new(SlugEncodings::Base64);
let output = x.encode(&self.0);
match output {
Ok(v) => Ok(v),
Err(_) => return Err(SlugEncodingError::EncodingError)
}
}
pub fn to_base64_url_safe(&self) -> Result<String,SlugEncodingError> {
let x = SlugEncodingUsage::new(SlugEncodings::Base64urlsafe);
let output = x.encode(&self.0);
match output {
Ok(v) => Ok(v),
Err(_) => return Err(SlugEncodingError::EncodingError)
}
}
}
impl ECDSAPublicKey {
pub fn verify<T: AsRef<[u8]>>(&self, bytes: T, signature: ECDSASignature) -> Result<bool,SlugErrors> {
let x: Result<ecdsa::VerifyingKey<Secp256k1>, ecdsa::Error> = self.to_usable_type();
let pk: ecdsa::VerifyingKey<Secp256k1> = match x {
Ok(v) => v,
Err(_) => return Err(SlugErrors::VerifyingError(crate::errors::SlugErrorAlgorithms::SIG_SCHNORR))
};
let sig: Result<ecdsa::Signature<Secp256k1>, SlugErrors> = signature.into_usable_type();
let signature_output = match sig {
Ok(v) => v,
Err(_) => return Err(SlugErrors::VerifyingError(crate::errors::SlugErrorAlgorithms::ENC_ECIES_ED25519))
};
let is_valid = pk.verify(bytes.as_ref(), &signature_output);
if is_valid.is_ok() {
return Ok(true)
}
else {
return Ok(false)
}
}
pub fn as_bytes(&self) -> &[u8] {
return &self.0
}
pub fn to_bytes(&self) -> [u8;33] {
return self.0
}
pub fn from_bytes(bytes: [u8;33]) -> Self {
Self(bytes)
}
pub fn from_slice(bytes: &[u8]) -> Result<Self,SlugErrors> {
let mut output: [u8;33] = [0u8;33];
if bytes.len() == 33 {
output.copy_from_slice(bytes);
return Ok(Self(output))
}
else {
return Err(SlugErrors::InvalidLengthFromBytes)
}
}
pub fn to_usable_type(&self) -> Result<VerifyingKey,ecdsa::Error> {
let key: ecdsa::VerifyingKey<Secp256k1> = VerifyingKey::from_sec1_bytes(&self.0)?;
return Ok(key)
}
pub fn from_base58<T: AsRef<str>>(s: T) -> Result<Self,SlugEncodingError> {
let x = SlugEncodingUsage::new(SlugEncodings::Base58);
let output = x.decode(s.as_ref())?;
let output = Self::from_slice(&output);
match output {
Ok(v) => return Ok(v),
Err(_) => return Err(SlugEncodingError::DecodingError)
}
}
pub fn from_hex<T: AsRef<str>>(s: T) -> Result<Self,SlugEncodingError> {
let x = SlugEncodingUsage::new(SlugEncodings::Hex);
let output = x.decode(s.as_ref())?;
let output = Self::from_slice(&output);
match output {
Ok(v) => return Ok(v),
Err(_) => return Err(SlugEncodingError::DecodingError)
}
}
pub fn from_base32<T: AsRef<str>>(s: T) -> Result<Self,SlugEncodingError> {
let x = SlugEncodingUsage::new(SlugEncodings::Base32);
let output = x.decode(s.as_ref())?;
let output = Self::from_slice(&output);
match output {
Ok(v) => return Ok(v),
Err(_) => return Err(SlugEncodingError::DecodingError)
}
}
pub fn from_base32_unpadded<T: AsRef<str>>(s: T) -> Result<Self,SlugEncodingError> {
let x = SlugEncodingUsage::new(SlugEncodings::Base32unpadded);
let output = x.decode(s.as_ref())?;
let output = Self::from_slice(&output);
match output {
Ok(v) => return Ok(v),
Err(_) => return Err(SlugEncodingError::DecodingError)
}
}
pub fn from_base64<T: AsRef<str>>(s: T) -> Result<Self,SlugEncodingError> {
let x = SlugEncodingUsage::new(SlugEncodings::Base64);
let output = x.decode(s.as_ref())?;
let output = Self::from_slice(&output);
match output {
Ok(v) => return Ok(v),
Err(_) => return Err(SlugEncodingError::DecodingError)
}
}
pub fn from_base64_url_safe<T: AsRef<str>>(s: T) -> Result<Self,SlugEncodingError> {
let x = SlugEncodingUsage::new(SlugEncodings::Base64urlsafe);
let output = x.decode(s.as_ref())?;
let output = Self::from_slice(&output);
match output {
Ok(v) => return Ok(v),
Err(_) => return Err(SlugEncodingError::DecodingError)
}
}
pub fn to_hex(&self) -> Result<String,SlugEncodingError> {
let x = SlugEncodingUsage::new(SlugEncodings::Hex);
let output = x.encode(&self.0);
match output {
Ok(v) => Ok(v),
Err(_) => return Err(SlugEncodingError::EncodingError)
}
}
pub fn to_base32(&self) -> Result<String,SlugEncodingError> {
let x = SlugEncodingUsage::new(SlugEncodings::Base32);
let output = x.encode(&self.0);
match output {
Ok(v) => Ok(v),
Err(_) => return Err(SlugEncodingError::EncodingError)
}
}
pub fn to_base32_unpadded(&self) -> Result<String,SlugEncodingError> {
let x = SlugEncodingUsage::new(SlugEncodings::Base32unpadded);
let output = x.encode(&self.0);
match output {
Ok(v) => Ok(v),
Err(_) => return Err(SlugEncodingError::EncodingError)
}
}
pub fn to_base58(&self) -> Result<String,SlugEncodingError> {
let x = SlugEncodingUsage::new(SlugEncodings::Base58);
let output = x.encode(&self.0);
match output {
Ok(v) => Ok(v),
Err(_) => return Err(SlugEncodingError::EncodingError)
}
}
pub fn to_base64(&self) -> Result<String,SlugEncodingError> {
let x = SlugEncodingUsage::new(SlugEncodings::Base64);
let output = x.encode(&self.0);
match output {
Ok(v) => Ok(v),
Err(_) => return Err(SlugEncodingError::EncodingError)
}
}
pub fn to_base64_url_safe(&self) -> Result<String,SlugEncodingError> {
let x = SlugEncodingUsage::new(SlugEncodings::Base64urlsafe);
let output = x.encode(&self.0);
match output {
Ok(v) => Ok(v),
Err(_) => return Err(SlugEncodingError::EncodingError)
}
}
}
impl FromEncoding for ECDSAPublicKey {
fn from_hex<T: AsRef<str>>(s: T) -> Result<Self,SlugErrors> {
let x = SlugEncodingUsage::new(SlugEncodings::Hex);
let output_bytes = x.decode(s.as_ref())?;
let output = Self::from_slice(&output_bytes)?;
return Ok(output)
}
fn from_base32<T: AsRef<str>>(s: T) -> Result<Self,SlugErrors> {
let x = SlugEncodingUsage::new(SlugEncodings::Base32);
let output_bytes = x.decode(s.as_ref())?;
let output = Self::from_slice(&output_bytes)?;
return Ok(output)
}
fn from_base32_unpadded<T: AsRef<str>>(s: T) -> Result<Self,SlugErrors> {
let x = SlugEncodingUsage::new(SlugEncodings::Base32unpadded);
let output_bytes = x.decode(s.as_ref())?;
let output = Self::from_slice(&output_bytes)?;
return Ok(output)
}
fn from_base58<T: AsRef<str>>(s: T) -> Result<Self,SlugErrors> {
let x = SlugEncodingUsage::new(SlugEncodings::Base58);
let output_bytes = x.decode(s.as_ref())?;
let output = Self::from_slice(&output_bytes)?;
return Ok(output)
}
fn from_base64<T: AsRef<str>>(s: T) -> Result<Self,SlugErrors> {
let x = SlugEncodingUsage::new(SlugEncodings::Base64);
let output_bytes = x.decode(s.as_ref())?;
let output = Self::from_slice(&output_bytes)?;
return Ok(output)
}
fn from_base64_url_safe<T: AsRef<str>>(s: T) -> Result<Self,SlugErrors> {
let x = SlugEncodingUsage::new(SlugEncodings::Base64urlsafe);
let output_bytes = x.decode(s.as_ref())?;
let output = Self::from_slice(&output_bytes)?;
return Ok(output)
}
}
impl FromEncoding for ECDSASecretKey {
fn from_base32<T: AsRef<str>>(s: T) -> Result<Self,SlugErrors> {
let x = SlugEncodingUsage::new(SlugEncodings::Base32);
let output_bytes = x.decode(s.as_ref())?;
let output = Self::from_slice(&output_bytes)?;
return Ok(output)
}
fn from_hex<T: AsRef<str>>(s: T) -> Result<Self,SlugErrors> {
let x = SlugEncodingUsage::new(SlugEncodings::Hex);
let output_bytes = x.decode(s.as_ref())?;
let output = Self::from_slice(&output_bytes)?;
return Ok(output)
}
fn from_base32_unpadded<T: AsRef<str>>(s: T) -> Result<Self,SlugErrors> {
let x = SlugEncodingUsage::new(SlugEncodings::Base32unpadded);
let output_bytes = x.decode(s.as_ref())?;
let output = Self::from_slice(&output_bytes)?;
return Ok(output)
}
fn from_base58<T: AsRef<str>>(s: T) -> Result<Self,SlugErrors> {
let x = SlugEncodingUsage::new(SlugEncodings::Base58);
let output_bytes = x.decode(s.as_ref())?;
let output = Self::from_slice(&output_bytes)?;
return Ok(output)
}
fn from_base64<T: AsRef<str>>(s: T) -> Result<Self,SlugErrors> {
let x = SlugEncodingUsage::new(SlugEncodings::Base64);
let output_bytes = x.decode(s.as_ref())?;
let output = Self::from_slice(&output_bytes)?;
return Ok(output)
}
fn from_base64_url_safe<T: AsRef<str>>(s: T) -> Result<Self,SlugErrors> {
let x = SlugEncodingUsage::new(SlugEncodings::Base64urlsafe);
let output_bytes = x.decode(s.as_ref())?;
let output = Self::from_slice(&output_bytes)?;
return Ok(output)
}
}
impl FromEncoding for ECDSASignature {
fn from_base32<T: AsRef<str>>(s: T) -> Result<Self,SlugErrors> {
let x = SlugEncodingUsage::new(SlugEncodings::Base32);
let output_bytes = x.decode(s.as_ref())?;
let output = Self::from_slice(&output_bytes)?;
return Ok(output)
}
fn from_hex<T: AsRef<str>>(s: T) -> Result<Self,SlugErrors> {
let x = SlugEncodingUsage::new(SlugEncodings::Hex);
let output_bytes = x.decode(s.as_ref())?;
let output = Self::from_slice(&output_bytes)?;
return Ok(output)
}
fn from_base32_unpadded<T: AsRef<str>>(s: T) -> Result<Self,SlugErrors> {
let x = SlugEncodingUsage::new(SlugEncodings::Base32unpadded);
let output_bytes = x.decode(s.as_ref())?;
let output = Self::from_slice(&output_bytes)?;
return Ok(output)
}
fn from_base58<T: AsRef<str>>(s: T) -> Result<Self,SlugErrors> {
let x = SlugEncodingUsage::new(SlugEncodings::Base58);
let output_bytes = x.decode(s.as_ref())?;
let output = Self::from_slice(&output_bytes)?;
return Ok(output)
}
fn from_base64<T: AsRef<str>>(s: T) -> Result<Self,SlugErrors> {
let x = SlugEncodingUsage::new(SlugEncodings::Base64);
let output_bytes = x.decode(s.as_ref())?;
let output = Self::from_slice(&output_bytes)?;
return Ok(output)
}
fn from_base64_url_safe<T: AsRef<str>>(s: T) -> Result<Self,SlugErrors> {
let x = SlugEncodingUsage::new(SlugEncodings::Base64urlsafe);
let output_bytes = x.decode(s.as_ref())?;
let output = Self::from_slice(&output_bytes)?;
return Ok(output)
}
}
impl IntoEncoding for ECDSAPublicKey {
fn into_hex(&self) -> Result<String,SlugErrors> {
let x = SlugEncodingUsage::new(SlugEncodings::Hex);
let output = x.encode(self.0)?;
return Ok(output)
}
fn into_base32(&self) -> Result<String,SlugErrors> {
let x = SlugEncodingUsage::new(SlugEncodings::Base32);
let output = x.encode(self.0)?;
return Ok(output)
}
fn into_base32_unpadded(&self) -> Result<String,SlugErrors> {
let x = SlugEncodingUsage::new(SlugEncodings::Base32unpadded);
let output = x.encode(self.0)?;
return Ok(output)
}
fn into_base58(&self) -> Result<String,SlugErrors> {
let x = SlugEncodingUsage::new(SlugEncodings::Base58);
let output = x.encode(self.0)?;
return Ok(output)
}
fn into_base64(&self) -> Result<String,SlugErrors> {
let x = SlugEncodingUsage::new(SlugEncodings::Base64);
let output = x.encode(self.0)?;
return Ok(output)
}
fn into_base64_url_safe(&self) -> Result<String,SlugErrors> {
let x = SlugEncodingUsage::new(SlugEncodings::Base64urlsafe);
let output = x.encode(self.0)?;
return Ok(output)
}
}
impl IntoEncoding for ECDSASecretKey {
fn into_hex(&self) -> Result<String,SlugErrors> {
let x = SlugEncodingUsage::new(SlugEncodings::Hex);
let output = x.encode(self.0)?;
return Ok(output)
}
fn into_base32(&self) -> Result<String,SlugErrors> {
let x = SlugEncodingUsage::new(SlugEncodings::Base32);
let output = x.encode(self.0)?;
return Ok(output)
}
fn into_base32_unpadded(&self) -> Result<String,SlugErrors> {
let x = SlugEncodingUsage::new(SlugEncodings::Base32unpadded);
let output = x.encode(self.0)?;
return Ok(output)
}
fn into_base58(&self) -> Result<String,SlugErrors> {
let x = SlugEncodingUsage::new(SlugEncodings::Base58);
let output = x.encode(self.0)?;
return Ok(output)
}
fn into_base64(&self) -> Result<String,SlugErrors> {
let x = SlugEncodingUsage::new(SlugEncodings::Base64);
let output = x.encode(self.0)?;
return Ok(output)
}
fn into_base64_url_safe(&self) -> Result<String,SlugErrors> {
let x = SlugEncodingUsage::new(SlugEncodings::Base64urlsafe);
let output = x.encode(self.0)?;
return Ok(output)
}
}
impl IntoEncoding for ECDSASignature {
fn into_hex(&self) -> Result<String,SlugErrors> {
let x = SlugEncodingUsage::new(SlugEncodings::Hex);
let output = x.encode(self.0)?;
return Ok(output)
}
fn into_base32(&self) -> Result<String,SlugErrors> {
let x = SlugEncodingUsage::new(SlugEncodings::Base32);
let output = x.encode(self.0)?;
return Ok(output)
}
fn into_base32_unpadded(&self) -> Result<String,SlugErrors> {
let x = SlugEncodingUsage::new(SlugEncodings::Base32unpadded);
let output = x.encode(self.0)?;
return Ok(output)
}
fn into_base58(&self) -> Result<String,SlugErrors> {
let x = SlugEncodingUsage::new(SlugEncodings::Base58);
let output = x.encode(self.0)?;
return Ok(output)
}
fn into_base64(&self) -> Result<String,SlugErrors> {
let x = SlugEncodingUsage::new(SlugEncodings::Base64);
let output = x.encode(self.0)?;
return Ok(output)
}
fn into_base64_url_safe(&self) -> Result<String,SlugErrors> {
let x = SlugEncodingUsage::new(SlugEncodings::Base64urlsafe);
let output = x.encode(self.0)?;
return Ok(output)
}
}
impl IntoBincode for ECDSAPublicKey {
fn into_bincode(&self) -> Result<Vec<u8>, SlugErrors> {
let output = bincode::serialize(self);
match output {
Ok(v) => Ok(v),
Err(_) => return Err(SlugErrors::BincodeError{ alg: SlugErrorAlgorithms::SIG_SECP256k1 })
}
}
}
impl IntoBincode for ECDSASecretKey {
fn into_bincode(&self) -> Result<Vec<u8>, SlugErrors> {
let output = bincode::serialize(self);
match output {
Ok(v) => Ok(v),
Err(_) => return Err(SlugErrors::BincodeError{ alg: SlugErrorAlgorithms::SIG_SECP256k1 })
}
}
}
impl IntoBincode for ECDSASignature {
fn into_bincode(&self) -> Result<Vec<u8>, SlugErrors> {
let output = bincode::serialize(self);
match output {
Ok(v) => Ok(v),
Err(_) => return Err(SlugErrors::BincodeError{ alg: SlugErrorAlgorithms::SIG_SECP256k1 })
}
}
}
impl FromBincode for ECDSAPublicKey {
fn from_bincode<T: AsRef<[u8]>>(bytes: T) -> Result<Self, SlugErrors> {
let output: Result<Self, Box<bincode::ErrorKind>> = bincode::deserialize(bytes.as_ref());
match output {
Ok(v) => Ok(v),
Err(_) => return Err(SlugErrors::BincodeError{ alg: SlugErrorAlgorithms::SIG_SECP256k1 })
}
}
}
impl FromBincode for ECDSASecretKey {
fn from_bincode<T: AsRef<[u8]>>(bytes: T) -> Result<Self, SlugErrors> {
let output: Result<Self, Box<bincode::ErrorKind>> = bincode::deserialize(bytes.as_ref());
match output {
Ok(v) => Ok(v),
Err(_) => return Err(SlugErrors::BincodeError{ alg: SlugErrorAlgorithms::SIG_SECP256k1 })
}
}
}
impl FromBincode for ECDSASignature {
fn from_bincode<T: AsRef<[u8]>>(bytes: T) -> Result<Self, SlugErrors> {
let output: Result<Self, Box<bincode::ErrorKind>> = bincode::deserialize(bytes.as_ref());
match output {
Ok(v) => Ok(v),
Err(_) => return Err(SlugErrors::BincodeError{ alg: SlugErrorAlgorithms::SIG_SECP256k1 })
}
}
}
impl IntoStandardPem for ECDSAPublicKey {
fn into_standard_pem(&self) -> Result<String,SlugErrors> {
let bytes: Vec<u8>= self.into_bincode()?;
let pem: Pem = Pem::new(&Self::label_for_standard_pem(), bytes);
let output = pem.to_string();
return Ok(output)
}
fn label_for_standard_pem() -> String {
String::from("OpenInternetCryptographyProject/ECDSA-SECP256K1-Public-Key")
}
fn label_for_standard_pem_secret() -> String {
String::from("OpenInternetCryptographyProject/ECDSA-SECP256K1-Secret-Key")
}
}
impl IntoStandardPem for ECDSASecretKey {
fn into_standard_pem(&self) -> Result<String,SlugErrors> {
let bytes: Vec<u8>= self.into_bincode()?;
let pem: Pem = Pem::new(&Self::label_for_standard_pem_secret(), bytes);
let output = pem.to_string();
return Ok(output)
}
fn label_for_standard_pem() -> String {
String::from("OpenInternetCryptographyProject/ECDSA-SECP256K1-Secret-Key")
}
fn label_for_standard_pem_secret() -> String {
String::from("OpenInternetCryptographyProject/ECDSA-SECP256K1-Secret-Key")
}
}
impl IntoStandardPem for ECDSASignature {
fn into_standard_pem(&self) -> Result<String,SlugErrors> {
let bytes: Vec<u8>= self.into_bincode()?;
let pem: Pem = Pem::new(&Self::label_for_standard_pem(), bytes);
let output = pem.to_string();
return Ok(output)
}
fn label_for_standard_pem() -> String {
String::from("OpenInternetCryptographyProject/ECDSA-SECP256K1-Signature")
}
fn label_for_standard_pem_secret() -> String {
String::from("OpenInternetCryptographyProject/ECDSA-SECP256K1-Secret-Key")
}
}
impl FromStandardPem for ECDSAPublicKey {
fn from_standard_pem<T: AsRef<str>>(s: T) -> Result<Self, SlugErrors> {
let pem: Pem = Pem::from_str(s.as_ref())?;
if pem.tag() != Self::label_for_standard_pem() {
return Err(SlugErrors::InvalidPemLabel)
}
let output: ECDSAPublicKey = Self::from_bincode(pem.contents())?;
return Ok(output)
}
}
impl FromStandardPem for ECDSASecretKey {
fn from_standard_pem<T: AsRef<str>>(s: T) -> Result<Self, SlugErrors> {
let pem: Pem = Pem::from_str(s.as_ref())?;
if pem.tag() != Self::label_for_standard_pem_secret() {
return Err(SlugErrors::InvalidPemLabel)
}
let output: ECDSASecretKey = Self::from_bincode(pem.contents())?;
return Ok(output)
}
}
impl FromStandardPem for ECDSASignature {
fn from_standard_pem<T: AsRef<str>>(s: T) -> Result<Self, SlugErrors> {
let pem: Pem = Pem::from_str(s.as_ref())?;
if pem.tag() != Self::label_for_standard_pem() {
return Err(SlugErrors::InvalidPemLabel)
}
let output: ECDSASignature = Self::from_bincode(pem.contents())?;
return Ok(output)
}
}
#[test]
fn ECDSA() {
let key = ECDSASecretKey::generate();
let pk = key.public_key().unwrap();
let signature = key.sign("Hello World!".as_bytes()).unwrap();
let is_valid = pk.verify("Hello World!".as_bytes(), signature.0);
println!("{}",is_valid.unwrap())
}