-
Notifications
You must be signed in to change notification settings - Fork 17
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
8 changed files
with
490 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,87 @@ | ||
//! Implementation of bls12381 min-sig public-key cryptogrophy. | ||
#[derive(Clone, Copy, Hash, PartialEq, Eq, PartialOrd, Ord)] | ||
#[cfg_attr( | ||
feature = "serde", | ||
derive(serde_derive::Serialize, serde_derive::Deserialize) | ||
)] | ||
pub struct Bls12381PrivateKey( | ||
#[cfg_attr( | ||
feature = "serde", | ||
serde(with = "::serde_with::As::<::serde_with::IfIsHumanReadable<super::Base64Array32>>") | ||
)] | ||
[u8; Self::LENGTH], | ||
); | ||
|
||
impl Bls12381PrivateKey { | ||
/// The length of an bls12381 private key in bytes. | ||
pub const LENGTH: usize = 32; | ||
} | ||
|
||
#[derive(Clone, Copy, Hash, PartialEq, Eq, PartialOrd, Ord)] | ||
#[cfg_attr( | ||
feature = "serde", | ||
derive(serde_derive::Serialize, serde_derive::Deserialize) | ||
)] | ||
pub struct Bls12381PublicKey( | ||
#[cfg_attr( | ||
feature = "serde", | ||
serde( | ||
with = "::serde_with::As::<::serde_with::IfIsHumanReadable<super::Base64Array96, [::serde_with::Same; 96]>>" | ||
) | ||
)] | ||
[u8; Self::LENGTH], | ||
); | ||
|
||
impl Bls12381PublicKey { | ||
/// The length of an bls12381 public key in bytes. | ||
pub const LENGTH: usize = 96; | ||
} | ||
|
||
impl std::fmt::Display for Bls12381PublicKey { | ||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { | ||
std::fmt::Display::fmt(&super::Base64Display96(&self.0), f) | ||
} | ||
} | ||
|
||
impl std::fmt::Debug for Bls12381PublicKey { | ||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { | ||
f.debug_tuple("Bls12381PublicKey") | ||
.field(&format_args!("\"{}\"", self)) | ||
.finish() | ||
} | ||
} | ||
|
||
#[derive(Clone, Copy, Hash, PartialEq, Eq, PartialOrd, Ord)] | ||
#[cfg_attr( | ||
feature = "serde", | ||
derive(serde_derive::Serialize, serde_derive::Deserialize) | ||
)] | ||
pub struct Bls12381Signature( | ||
#[cfg_attr( | ||
feature = "serde", | ||
serde( | ||
with = "::serde_with::As::<::serde_with::IfIsHumanReadable<super::Base64Array48, [::serde_with::Same; 48]>>" | ||
) | ||
)] | ||
[u8; Self::LENGTH], | ||
); | ||
|
||
impl Bls12381Signature { | ||
/// The length of an bls12381 signature key in bytes. | ||
pub const LENGTH: usize = 48; | ||
} | ||
|
||
impl std::fmt::Display for Bls12381Signature { | ||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { | ||
std::fmt::Display::fmt(&super::Base64Display48(&self.0), f) | ||
} | ||
} | ||
|
||
impl std::fmt::Debug for Bls12381Signature { | ||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { | ||
f.debug_tuple("Bls12381Signature") | ||
.field(&format_args!("\"{}\"", self)) | ||
.finish() | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,85 @@ | ||
//! Implementation of ed25519 public-key cryptogrophy. | ||
#[derive(Clone, Copy, Hash, PartialEq, Eq, PartialOrd, Ord)] | ||
#[cfg_attr( | ||
feature = "serde", | ||
derive(serde_derive::Serialize, serde_derive::Deserialize) | ||
)] | ||
pub struct Ed25519PrivateKey( | ||
#[cfg_attr( | ||
feature = "serde", | ||
serde(with = "::serde_with::As::<::serde_with::IfIsHumanReadable<super::Base64Array32>>") | ||
)] | ||
[u8; Self::LENGTH], | ||
); | ||
|
||
impl Ed25519PrivateKey { | ||
/// The length of an ed25519 private key in bytes. | ||
pub const LENGTH: usize = 32; | ||
} | ||
|
||
#[derive(Clone, Copy, Hash, PartialEq, Eq, PartialOrd, Ord)] | ||
#[cfg_attr( | ||
feature = "serde", | ||
derive(serde_derive::Serialize, serde_derive::Deserialize) | ||
)] | ||
pub struct Ed25519PublicKey( | ||
#[cfg_attr( | ||
feature = "serde", | ||
serde(with = "::serde_with::As::<::serde_with::IfIsHumanReadable<super::Base64Array32>>") | ||
)] | ||
[u8; Self::LENGTH], | ||
); | ||
|
||
impl Ed25519PublicKey { | ||
/// The length of an ed25519 public key in bytes. | ||
pub const LENGTH: usize = 32; | ||
} | ||
|
||
impl std::fmt::Display for Ed25519PublicKey { | ||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { | ||
std::fmt::Display::fmt(&super::Base64Display32(&self.0), f) | ||
} | ||
} | ||
|
||
impl std::fmt::Debug for Ed25519PublicKey { | ||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { | ||
f.debug_tuple("Ed25519PublicKey") | ||
.field(&format_args!("\"{}\"", self)) | ||
.finish() | ||
} | ||
} | ||
|
||
#[derive(Clone, Copy, Hash, PartialEq, Eq, PartialOrd, Ord)] | ||
#[cfg_attr( | ||
feature = "serde", | ||
derive(serde_derive::Serialize, serde_derive::Deserialize) | ||
)] | ||
pub struct Ed25519Signature( | ||
#[cfg_attr( | ||
feature = "serde", | ||
serde( | ||
with = "::serde_with::As::<::serde_with::IfIsHumanReadable<super::Base64Array64, [::serde_with::Same; 64]>>" | ||
) | ||
)] | ||
[u8; Self::LENGTH], | ||
); | ||
|
||
impl Ed25519Signature { | ||
/// The length of an ed25519 signature key in bytes. | ||
pub const LENGTH: usize = 64; | ||
} | ||
|
||
impl std::fmt::Display for Ed25519Signature { | ||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { | ||
std::fmt::Display::fmt(&super::Base64Display64(&self.0), f) | ||
} | ||
} | ||
|
||
impl std::fmt::Debug for Ed25519Signature { | ||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { | ||
f.debug_tuple("Ed25519Signature") | ||
.field(&format_args!("\"{}\"", self)) | ||
.finish() | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,95 @@ | ||
mod bls12381; | ||
mod ed25519; | ||
mod secp256k1; | ||
mod secp256r1; | ||
mod signature; | ||
|
||
pub use bls12381::{Bls12381PrivateKey, Bls12381PublicKey, Bls12381Signature}; | ||
pub use ed25519::{Ed25519PrivateKey, Ed25519PublicKey, Ed25519Signature}; | ||
pub use secp256k1::{Secp256k1PrivateKey, Secp256k1PublicKey, Secp256k1Signature}; | ||
pub use secp256r1::{Secp256r1PrivateKey, Secp256r1PublicKey, Secp256r1Signature}; | ||
pub use signature::{SignatureScheme, SimpleSignature, UserSignature}; | ||
|
||
// | ||
// Implement various base64 fixed-size array helpers | ||
// | ||
|
||
/// Utility for calculating base64 encoding lenghths. | ||
/// | ||
/// In the Base64 encoding each character is used to represent 6 bits (log2(64) = 6). This means | ||
/// that 4 characters are used to represnet 4*6 = 24 bits = 3 bytes. So you need 4*(`n`/3) | ||
/// characters in order to represent `n` bytes, and this needs to be rounded up to a multiple of 4. | ||
/// The number of unused padding characters resulting from the rounding will be 0, 1, 2, or 3. | ||
const fn base64_encoded_length(len: usize) -> usize { | ||
((4 * len / 3) + 3) & !3 | ||
} | ||
|
||
macro_rules! impl_base64_helper { | ||
($base:ident, $display:ident, $fromstr:ident, $array_length:literal) => { | ||
struct $base; | ||
|
||
impl $base { | ||
const LENGTH: usize = $array_length; | ||
const ENCODED_LENGTH: usize = base64_encoded_length(Self::LENGTH); | ||
} | ||
|
||
struct $display<'a>(&'a [u8; $base::LENGTH]); | ||
|
||
impl<'a> std::fmt::Display for $display<'a> { | ||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { | ||
let mut buf = [0; $base::ENCODED_LENGTH]; | ||
let encoded = | ||
<base64ct::Base64 as base64ct::Encoding>::encode(self.0, &mut buf).unwrap(); | ||
f.write_str(encoded) | ||
} | ||
} | ||
|
||
struct $fromstr([u8; $base::LENGTH]); | ||
|
||
impl std::str::FromStr for $fromstr { | ||
type Err = base64ct::Error; | ||
|
||
fn from_str(s: &str) -> Result<Self, Self::Err> { | ||
let mut buf = [0; $base::LENGTH]; | ||
let decoded = <base64ct::Base64 as base64ct::Encoding>::decode(s, &mut buf)?; | ||
assert_eq!(decoded.len(), $base::LENGTH); | ||
Ok(Self(buf)) | ||
} | ||
} | ||
|
||
#[cfg(feature = "serde")] | ||
#[cfg_attr(doc_cfg, doc(cfg(feature = "serde")))] | ||
impl serde_with::SerializeAs<[u8; Self::LENGTH]> for $base { | ||
fn serialize_as<S>( | ||
source: &[u8; Self::LENGTH], | ||
serializer: S, | ||
) -> Result<S::Ok, S::Error> | ||
where | ||
S: serde::Serializer, | ||
{ | ||
let display = $display(source); | ||
serde_with::DisplayFromStr::serialize_as(&display, serializer) | ||
} | ||
} | ||
|
||
#[cfg(feature = "serde")] | ||
#[cfg_attr(doc_cfg, doc(cfg(feature = "serde")))] | ||
impl<'de> serde_with::DeserializeAs<'de, [u8; Self::LENGTH]> for $base { | ||
fn deserialize_as<D>(deserializer: D) -> Result<[u8; Self::LENGTH], D::Error> | ||
where | ||
D: serde::Deserializer<'de>, | ||
{ | ||
let array: $fromstr = serde_with::DisplayFromStr::deserialize_as(deserializer)?; | ||
Ok(array.0) | ||
} | ||
} | ||
|
||
// TODO add tests | ||
}; | ||
} | ||
|
||
impl_base64_helper!(Base64Array32, Base64Display32, Base64FromStr32, 32); | ||
impl_base64_helper!(Base64Array33, Base64Display33, Base64FromStr33, 33); | ||
impl_base64_helper!(Base64Array48, Base64Display48, Base64FromStr48, 48); | ||
impl_base64_helper!(Base64Array64, Base64Display64, Base64FromStr64, 64); | ||
impl_base64_helper!(Base64Array96, Base64Display96, Base64FromStr96, 96); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,87 @@ | ||
//! Implementation of secp256k1 public-key cryptogrophy. | ||
#[derive(Clone, Copy, Hash, PartialEq, Eq, PartialOrd, Ord)] | ||
#[cfg_attr( | ||
feature = "serde", | ||
derive(serde_derive::Serialize, serde_derive::Deserialize) | ||
)] | ||
pub struct Secp256k1PrivateKey( | ||
#[cfg_attr( | ||
feature = "serde", | ||
serde(with = "::serde_with::As::<::serde_with::IfIsHumanReadable<super::Base64Array32>>") | ||
)] | ||
[u8; Self::LENGTH], | ||
); | ||
|
||
impl Secp256k1PrivateKey { | ||
/// The length of an secp256k1 private key in bytes. | ||
pub const LENGTH: usize = 32; | ||
} | ||
|
||
#[derive(Clone, Copy, Hash, PartialEq, Eq, PartialOrd, Ord)] | ||
#[cfg_attr( | ||
feature = "serde", | ||
derive(serde_derive::Serialize, serde_derive::Deserialize) | ||
)] | ||
pub struct Secp256k1PublicKey( | ||
#[cfg_attr( | ||
feature = "serde", | ||
serde( | ||
with = "::serde_with::As::<::serde_with::IfIsHumanReadable<super::Base64Array33, [::serde_with::Same; 33]>>" | ||
) | ||
)] | ||
[u8; Self::LENGTH], | ||
); | ||
|
||
impl Secp256k1PublicKey { | ||
/// The length of an secp256k1 public key in bytes. | ||
pub const LENGTH: usize = 33; | ||
} | ||
|
||
impl std::fmt::Display for Secp256k1PublicKey { | ||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { | ||
std::fmt::Display::fmt(&super::Base64Display33(&self.0), f) | ||
} | ||
} | ||
|
||
impl std::fmt::Debug for Secp256k1PublicKey { | ||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { | ||
f.debug_tuple("Secp256k1PublicKey") | ||
.field(&format_args!("\"{}\"", self)) | ||
.finish() | ||
} | ||
} | ||
|
||
#[derive(Clone, Copy, Hash, PartialEq, Eq, PartialOrd, Ord)] | ||
#[cfg_attr( | ||
feature = "serde", | ||
derive(serde_derive::Serialize, serde_derive::Deserialize) | ||
)] | ||
pub struct Secp256k1Signature( | ||
#[cfg_attr( | ||
feature = "serde", | ||
serde( | ||
with = "::serde_with::As::<::serde_with::IfIsHumanReadable<super::Base64Array64, [::serde_with::Same; 64]>>" | ||
) | ||
)] | ||
[u8; Self::LENGTH], | ||
); | ||
|
||
impl Secp256k1Signature { | ||
/// The length of an secp256k1 signature key in bytes. | ||
pub const LENGTH: usize = 64; | ||
} | ||
|
||
impl std::fmt::Display for Secp256k1Signature { | ||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { | ||
std::fmt::Display::fmt(&super::Base64Display64(&self.0), f) | ||
} | ||
} | ||
|
||
impl std::fmt::Debug for Secp256k1Signature { | ||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { | ||
f.debug_tuple("Secp256k1Signature") | ||
.field(&format_args!("\"{}\"", self)) | ||
.finish() | ||
} | ||
} |
Oops, something went wrong.