Skip to content
This repository has been archived by the owner on Oct 17, 2022. It is now read-only.

crypto: Add Sui + Aggregation support #460

Merged
merged 25 commits into from
Jul 15, 2022
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
feat: isolate PubKeyBytes construction to a generic
  • Loading branch information
huitseeker committed Jul 15, 2022
commit 798120d5b38102c37edf189c565f2f8bb24883ef
50 changes: 5 additions & 45 deletions crypto/src/bls12377/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,10 @@

use std::fmt::{self, Display};

use crate::traits::{AggregateAuthenticator, EncodeDecodeBase64, ToFromBytes, VerifyingKeyBytes};
use crate::{
pubkey_bytes::PublicKeyBytes,
traits::{AggregateAuthenticator, EncodeDecodeBase64, ToFromBytes},
};
use ::ark_serialize::{CanonicalDeserialize, CanonicalSerialize};
use ark_bls12_377::{Fr, G1Affine, G1Projective, G2Affine, G2Projective};
use ark_ec::{AffineCurve, ProjectiveCurve};
Expand All @@ -16,7 +19,6 @@ use celo_bls::{hash_to_curve::try_and_increment, PublicKey};
use once_cell::sync::OnceCell;
use serde::{de, Deserialize, Serialize};
use serde_with::serde_as;
use serde_with::Bytes;
use signature::{Signer, Verifier};

use crate::traits::{Authenticator, KeyPair, SigningKey, VerifyingKey};
Expand All @@ -40,10 +42,7 @@ pub struct BLS12377PublicKey {
pub bytes: OnceCell<[u8; CELO_BLS_PUBLIC_KEY_LENGTH]>,
}

#[readonly::make]
#[serde_as]
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, Ord, PartialOrd, Copy, Hash)]
pub struct BLS12377PublicKeyBytes(#[serde_as(as = "Bytes")] [u8; CELO_BLS_PUBLIC_KEY_LENGTH]);
pub type BLS12377PublicKeyBytes = PublicKeyBytes<BLS12377PublicKey, { BLS12377PublicKey::LENGTH }>;

#[readonly::make]
#[derive(Debug)]
Expand Down Expand Up @@ -261,7 +260,6 @@ impl<'a> From<&'a BLS12377PrivateKey> for BLS12377PublicKey {
impl VerifyingKey for BLS12377PublicKey {
type PrivKey = BLS12377PrivateKey;
type Sig = BLS12377Signature;
type Bytes = BLS12377PublicKeyBytes;
const LENGTH: usize = CELO_BLS_PUBLIC_KEY_LENGTH;

fn verify_batch(msg: &[u8], pks: &[Self], sigs: &[Self::Sig]) -> Result<(), signature::Error> {
Expand Down Expand Up @@ -395,11 +393,6 @@ impl KeyPair for BLS12377KeyPair {
},
}
}

fn public_key_bytes(&self) -> BLS12377PublicKeyBytes {
BLS12377PublicKeyBytes::from_bytes(self.name.as_ref())
.expect("BLS12-377 serialization invariants violated")
}
}

impl Signer<BLS12377Signature> for BLS12377KeyPair {
Expand Down Expand Up @@ -557,26 +550,6 @@ impl AggregateAuthenticator for BLS12377AggregateSignature {
/// Implement VerifyingKeyBytes
///

impl Default for BLS12377PublicKeyBytes {
fn default() -> Self {
BLS12377PublicKeyBytes([0; CELO_BLS_PUBLIC_KEY_LENGTH])
}
}

impl AsRef<[u8]> for BLS12377PublicKeyBytes {
fn as_ref(&self) -> &[u8] {
self.0.as_ref()
}
}

impl Display for BLS12377PublicKeyBytes {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::result::Result<(), std::fmt::Error> {
let s = hex::encode(&self.0);
write!(f, "k#{}", s)?;
Ok(())
}
}

impl TryInto<BLS12377PublicKey> for BLS12377PublicKeyBytes {
type Error = signature::Error;

Expand All @@ -586,16 +559,3 @@ impl TryInto<BLS12377PublicKey> for BLS12377PublicKeyBytes {
BLS12377PublicKey::from_bytes(self.as_ref()).map_err(|_| Self::Error::new())
}
}

impl ToFromBytes for BLS12377PublicKeyBytes {
fn from_bytes(bytes: &[u8]) -> Result<Self, signature::Error> {
let arr: [u8; CELO_BLS_PUBLIC_KEY_LENGTH] =
bytes.try_into().map_err(|_| signature::Error::new())?;

Ok(BLS12377PublicKeyBytes(arr))
}
}

impl VerifyingKeyBytes for BLS12377PublicKeyBytes {
type PubKey = BLS12377PublicKey;
}
49 changes: 3 additions & 46 deletions crypto/src/bls12381.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,19 +13,18 @@ use blst::min_sig as blst;
use once_cell::sync::OnceCell;
use rand::{rngs::OsRng, RngCore};

use crate::serde_helpers::BlsSignature;
use crate::{pubkey_bytes::PublicKeyBytes, serde_helpers::BlsSignature};
use serde::{
de::{self},
Deserialize, Serialize,
};
use serde_with::serde_as;
use serde_with::Bytes;

use signature::{Signature, Signer, Verifier};

use crate::traits::{
AggregateAuthenticator, Authenticator, EncodeDecodeBase64, KeyPair, SigningKey, ToFromBytes,
VerifyingKey, VerifyingKeyBytes,
VerifyingKey,
};

pub const BLS_PRIVATE_KEY_LENGTH: usize = 32;
Expand All @@ -44,10 +43,7 @@ pub struct BLS12381PublicKey {
pub bytes: OnceCell<[u8; BLS_PUBLIC_KEY_LENGTH]>,
}

#[readonly::make]
#[serde_as]
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, Ord, PartialOrd, Copy, Hash)]
pub struct BLS12381PublicKeyBytes(#[serde_as(as = "Bytes")] [u8; BLS_PUBLIC_KEY_LENGTH]);
pub type BLS12381PublicKeyBytes = PublicKeyBytes<BLS12381PublicKey, { BLS12381PublicKey::LENGTH }>;

#[readonly::make]
#[derive(Default, Debug)]
Expand Down Expand Up @@ -186,7 +182,6 @@ impl<'a> From<&'a BLS12381PrivateKey> for BLS12381PublicKey {
impl VerifyingKey for BLS12381PublicKey {
type PrivKey = BLS12381PrivateKey;
type Sig = BLS12381Signature;
type Bytes = BLS12381PublicKeyBytes;

const LENGTH: usize = BLS_PUBLIC_KEY_LENGTH;

Expand Down Expand Up @@ -411,11 +406,6 @@ impl KeyPair for BLS12381KeyPair {
},
}
}

fn public_key_bytes(&self) -> BLS12381PublicKeyBytes {
let pk_arr: [u8; BLS_PUBLIC_KEY_LENGTH] = self.name.pubkey.to_bytes();
BLS12381PublicKeyBytes(pk_arr)
}
}

impl Signer<BLS12381Signature> for BLS12381KeyPair {
Expand Down Expand Up @@ -574,26 +564,6 @@ impl AggregateAuthenticator for BLS12381AggregateSignature {
/// Implement VerifyingKeyBytes
///

impl Default for BLS12381PublicKeyBytes {
fn default() -> Self {
BLS12381PublicKeyBytes([0; BLS_PUBLIC_KEY_LENGTH])
}
}

impl AsRef<[u8]> for BLS12381PublicKeyBytes {
fn as_ref(&self) -> &[u8] {
self.0.as_ref()
}
}

impl Display for BLS12381PublicKeyBytes {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::result::Result<(), std::fmt::Error> {
let s = hex::encode(&self.0);
write!(f, "k#{}", s)?;
Ok(())
}
}

impl TryInto<BLS12381PublicKey> for BLS12381PublicKeyBytes {
type Error = signature::Error;

Expand All @@ -603,16 +573,3 @@ impl TryInto<BLS12381PublicKey> for BLS12381PublicKeyBytes {
BLS12381PublicKey::from_bytes(self.as_ref()).map_err(|_| Self::Error::new())
}
}

impl ToFromBytes for BLS12381PublicKeyBytes {
fn from_bytes(bytes: &[u8]) -> Result<Self, signature::Error> {
let arr: [u8; BLS_PUBLIC_KEY_LENGTH] =
bytes.try_into().map_err(|_| signature::Error::new())?;

Ok(BLS12381PublicKeyBytes(arr))
}
}

impl VerifyingKeyBytes for BLS12381PublicKeyBytes {
type PubKey = BLS12381PublicKey;
}
46 changes: 3 additions & 43 deletions crypto/src/ed25519.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,10 @@ use signature::{Signature, Signer, Verifier};
use std::fmt::{self, Display};
use std::str::FromStr;

use crate::pubkey_bytes::PublicKeyBytes;
use crate::traits::{
AggregateAuthenticator, Authenticator, EncodeDecodeBase64, KeyPair, SigningKey, ToFromBytes,
VerifyingKey, VerifyingKeyBytes,
VerifyingKey,
};

///
Expand All @@ -20,8 +21,7 @@ use crate::traits::{
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct Ed25519PublicKey(pub ed25519_dalek::PublicKey);

#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq, Ord, PartialOrd, Copy, Hash)]
pub struct Ed25519PublicKeyBytes([u8; ed25519_dalek::PUBLIC_KEY_LENGTH]);
pub type Ed25519PublicKeyBytes = PublicKeyBytes<Ed25519PublicKey, { Ed25519PublicKey::LENGTH }>;

#[derive(Debug)]
pub struct Ed25519PrivateKey(pub ed25519_dalek::SecretKey);
Expand Down Expand Up @@ -59,7 +59,6 @@ impl<'a> From<&'a Ed25519PrivateKey> for Ed25519PublicKey {
impl VerifyingKey for Ed25519PublicKey {
type PrivKey = Ed25519PrivateKey;
type Sig = Ed25519Signature;
type Bytes = Ed25519PublicKeyBytes;
const LENGTH: usize = ed25519_dalek::PUBLIC_KEY_LENGTH;
punwai marked this conversation as resolved.
Show resolved Hide resolved

fn verify_batch(msg: &[u8], pks: &[Self], sigs: &[Self::Sig]) -> Result<(), signature::Error> {
Expand Down Expand Up @@ -346,11 +345,6 @@ impl KeyPair for Ed25519KeyPair {
secret: Ed25519PrivateKey(kp.secret),
}
}

fn public_key_bytes(&self) -> Ed25519PublicKeyBytes {
let pk_arr: [u8; ed25519_dalek::PUBLIC_KEY_LENGTH] = self.name.0.to_bytes();
Ed25519PublicKeyBytes(pk_arr)
}
}

impl FromStr for Ed25519KeyPair {
Expand Down Expand Up @@ -388,27 +382,6 @@ impl Signer<Ed25519Signature> for Ed25519KeyPair {
///
/// Implement VerifyingKeyBytes
///

impl Default for Ed25519PublicKeyBytes {
fn default() -> Self {
Ed25519PublicKeyBytes([0; ed25519_dalek::PUBLIC_KEY_LENGTH])
}
}

impl AsRef<[u8]> for Ed25519PublicKeyBytes {
fn as_ref(&self) -> &[u8] {
self.0.as_ref()
}
}

impl Display for Ed25519PublicKeyBytes {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::result::Result<(), std::fmt::Error> {
let s = hex::encode(&self.0);
write!(f, "k#{}", s)?;
Ok(())
}
}

impl TryInto<Ed25519PublicKey> for Ed25519PublicKeyBytes {
type Error = signature::Error;

Expand All @@ -418,16 +391,3 @@ impl TryInto<Ed25519PublicKey> for Ed25519PublicKeyBytes {
Ed25519PublicKey::from_bytes(self.as_ref()).map_err(|_| Self::Error::new())
}
}

impl ToFromBytes for Ed25519PublicKeyBytes {
fn from_bytes(bytes: &[u8]) -> Result<Self, signature::Error> {
let arr: [u8; ed25519_dalek::PUBLIC_KEY_LENGTH] =
bytes.try_into().map_err(|_| signature::Error::new())?;

Ok(Ed25519PublicKeyBytes(arr))
}
}

impl VerifyingKeyBytes for Ed25519PublicKeyBytes {
type PubKey = Ed25519PublicKey;
}
1 change: 1 addition & 0 deletions crypto/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ pub mod bls12381_tests;
pub mod bls12381;
pub mod ed25519;
pub mod hkdf;
pub mod pubkey_bytes;
pub mod serde_helpers;
pub mod traits;

Expand Down
84 changes: 84 additions & 0 deletions crypto/src/pubkey_bytes.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
// Copyright (c) 2022, Mysten Labs, Inc.
// SPDX-License-Identifier: Apache-2.0

use self::sealed::SealedPublicKeyLength;
use crate::traits::{ToFromBytes, VerifyingKey};
use serde::{Deserialize, Serialize};
use serde_with::{serde_as, Bytes};
use std::{fmt::Display, marker::PhantomData};

/// A generic construction representing bytes who claim to be the instance of a public key.
#[serde_as]
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, Serialize, Deserialize)]
pub struct PublicKeyBytes<T, const N: usize> {
#[serde_as(as = "Bytes")]
bytes: [u8; N],
phantom: PhantomData<T>,
}

impl<T, const N: usize> AsRef<[u8]> for PublicKeyBytes<T, N>
where
T: VerifyingKey,
{
fn as_ref(&self) -> &[u8] {
&self.bytes[..]
}
}

impl<T, const N: usize> Display for PublicKeyBytes<T, N> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::result::Result<(), std::fmt::Error> {
let s = hex::encode(&self.bytes);
write!(f, "k#{}", s)?;
Ok(())
}
}

impl<T: VerifyingKey, const N: usize> ToFromBytes for PublicKeyBytes<T, N> {
fn from_bytes(bytes: &[u8]) -> Result<Self, signature::Error> {
let bytes: [u8; N] = bytes.try_into().map_err(signature::Error::from_source)?;
Ok(PublicKeyBytes {
bytes,
phantom: PhantomData,
})
}
}

impl<T, const N: usize> PublicKeyBytes<T, N> {
/// This ensures it's impossible to construct an instance with other than registered lengths
pub fn new(bytes: [u8; N]) -> PublicKeyBytes<T, N>
where
PublicKeyBytes<T, N>: SealedPublicKeyLength,
{
PublicKeyBytes {
bytes,
phantom: PhantomData,
}
}
}

impl<T, const N: usize> Default for PublicKeyBytes<T, N> {
// this is probably derivable, but we'd rather have it explicitly laid out for instructional purposes,
// see [#34](https://github.com/MystenLabs/narwhal/issues/34)
fn default() -> Self {
Self {
bytes: [0u8; N],
phantom: PhantomData,
}
}
}

// This guarantees the security of the constructor of a `PublicKeyBytes` instance
// TODO: replace this clunky sealed marker trait once feature(associated_const_equality) stabilizes
mod sealed {
#[cfg(feature = "celo")]
use crate::bls12377::BLS12377PublicKey;
use crate::{bls12381::BLS12381PublicKey, ed25519::Ed25519PublicKey, traits::VerifyingKey};

use super::PublicKeyBytes;

pub trait SealedPublicKeyLength {}
impl SealedPublicKeyLength for PublicKeyBytes<Ed25519PublicKey, { Ed25519PublicKey::LENGTH }> {}
impl SealedPublicKeyLength for PublicKeyBytes<BLS12381PublicKey, { BLS12381PublicKey::LENGTH }> {}
#[cfg(feature = "celo")]
impl SealedPublicKeyLength for PublicKeyBytes<BLS12377PublicKey, { BLS12377PublicKey::LENGTH }> {}
}
Loading