feat(crypto): add extra types and conversions (#517)

This commit is contained in:
Andrew Westberg 2024-10-04 07:37:36 -04:00 committed by GitHub
parent de88df1986
commit 0ca7c34776
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 63 additions and 19 deletions

View file

@ -4,6 +4,7 @@ use minicbor::{
Decode, Encode,
};
use serde::{Deserialize, Serialize};
use std::str::FromStr;
use std::{collections::HashMap, fmt, hash::Hash as StdHash, ops::Deref};
static TAG_SET: u64 = 258;
@ -1348,6 +1349,14 @@ impl Deref for Bytes {
}
}
impl<const N: usize> TryFrom<&Bytes> for [u8; N] {
type Error = core::array::TryFromSliceError;
fn try_from(value: &Bytes) -> Result<Self, Self::Error> {
value.0.as_slice().try_into()
}
}
impl TryFrom<String> for Bytes {
type Error = hex::FromHexError;
@ -1357,6 +1366,15 @@ impl TryFrom<String> for Bytes {
}
}
impl FromStr for Bytes {
type Err = hex::FromHexError;
fn from_str(s: &str) -> Result<Self, Self::Err> {
let v = hex::decode(s)?;
Ok(Bytes(minicbor::bytes::ByteVec::from(v)))
}
}
impl From<Bytes> for String {
fn from(b: Bytes) -> Self {
hex::encode(b.deref())

View file

@ -19,6 +19,12 @@ pub const VRF_PUBLIC_KEY_SIZE: usize = 32;
pub const VRF_SECRET_KEY_SIZE: usize = 32;
pub const VRF_PROOF_HASH_SIZE: usize = 64;
pub type VrfSeedBytes = [u8; VRF_SEED_SIZE];
pub type VrfProofBytes = [u8; VRF_PROOF_SIZE];
pub type VrfPublicKeyBytes = [u8; VRF_PUBLIC_KEY_SIZE];
pub type VrfSecretKeyBytes = [u8; VRF_SECRET_KEY_SIZE];
pub type VrfProofHashBytes = [u8; VRF_PROOF_HASH_SIZE];
// Wrapper for VRF secret key
pub struct VrfSecretKey {
secret_key_03: SecretKey03,
@ -35,8 +41,8 @@ pub struct VrfProof {
}
// Create a VrfSecretKey from a slice
impl From<&[u8; VRF_SECRET_KEY_SIZE]> for VrfSecretKey {
fn from(slice: &[u8; VRF_SECRET_KEY_SIZE]) -> Self {
impl From<&VrfSecretKeyBytes> for VrfSecretKey {
fn from(slice: &VrfSecretKeyBytes) -> Self {
VrfSecretKey {
secret_key_03: SecretKey03::from_bytes(slice),
}
@ -44,8 +50,8 @@ impl From<&[u8; VRF_SECRET_KEY_SIZE]> for VrfSecretKey {
}
// Create a VrfPublicKey from a slice
impl From<&[u8; VRF_PUBLIC_KEY_SIZE]> for VrfPublicKey {
fn from(slice: &[u8; VRF_PUBLIC_KEY_SIZE]) -> Self {
impl From<&VrfPublicKeyBytes> for VrfPublicKey {
fn from(slice: &VrfPublicKeyBytes) -> Self {
VrfPublicKey {
public_key_03: PublicKey03::from_bytes(slice),
}
@ -53,10 +59,10 @@ impl From<&[u8; VRF_PUBLIC_KEY_SIZE]> for VrfPublicKey {
}
// Create a VrfProof from a slice
impl From<&[u8; VRF_PROOF_SIZE]> for VrfProof {
fn from(slice: &[u8; VRF_PROOF_SIZE]) -> Self {
impl From<&VrfProofBytes> for VrfProof {
fn from(slice: &VrfProofBytes) -> Self {
VrfProof {
proof_03: VrfProof03::from_bytes(slice).unwrap(),
proof_03: VrfProof03::from_bytes(slice).expect("Infallible"),
}
}
}

View file

@ -5,7 +5,7 @@
use serde::{Deserialize, Serialize};
use pallas_codec::minicbor::{Decode, Encode};
use pallas_crypto::hash::Hash;
use pallas_crypto::hash::{Hash, Hasher};
use pallas_codec::utils::{Bytes, CborWrap, KeepRaw, KeyValuePairs, MaybeIndefArray, Nullable};
@ -313,6 +313,34 @@ impl<'a> From<MintedTransactionBody<'a>> for TransactionBody {
}
}
pub enum VrfDerivation {
Leader,
Nonce,
}
pub fn derive_tagged_vrf_output(
block_vrf_output_bytes: &[u8],
derivation: VrfDerivation,
) -> Vec<u8> {
let mut tagged_vrf: Vec<u8> = match derivation {
VrfDerivation::Leader => vec![0x4C_u8], /* "L" */
VrfDerivation::Nonce => vec![0x4E_u8], /* "N" */
};
tagged_vrf.extend(block_vrf_output_bytes);
Hasher::<256>::hash(&tagged_vrf).to_vec()
}
impl HeaderBody {
pub fn leader_vrf_output(&self) -> Vec<u8> {
derive_tagged_vrf_output(&self.vrf_result.0, VrfDerivation::Leader)
}
pub fn nonce_vrf_output(&self) -> Vec<u8> {
derive_tagged_vrf_output(&self.vrf_result.0, VrfDerivation::Nonce)
}
}
#[derive(Debug, PartialEq, Eq, Clone)]
pub enum PseudoTransactionOutput<T> {
Legacy(LegacyTransactionOutput),

View file

@ -2,7 +2,7 @@ use std::borrow::Cow;
use std::ops::Deref;
use pallas_codec::minicbor;
use pallas_crypto::hash::{Hash, Hasher};
use pallas_crypto::hash::Hash;
use pallas_primitives::{alonzo, babbage, byron};
use crate::{wellknown::GenesisValues, Era, Error, MultiEraHeader, OriginalHash};
@ -109,11 +109,7 @@ impl<'b> MultiEraHeader<'b> {
match self {
MultiEraHeader::EpochBoundary(_) => Err(Error::InvalidEra(Era::Byron)),
MultiEraHeader::ShelleyCompatible(x) => Ok(x.header_body.leader_vrf.0.to_vec()),
MultiEraHeader::BabbageCompatible(x) => {
let mut leader_tagged_vrf: Vec<u8> = vec![0x4C_u8]; /* "L" */
leader_tagged_vrf.extend(&*x.header_body.vrf_result.0);
Ok(Hasher::<256>::hash(&leader_tagged_vrf).to_vec())
}
MultiEraHeader::BabbageCompatible(x) => Ok(x.header_body.leader_vrf_output()),
MultiEraHeader::Byron(_) => Err(Error::InvalidEra(Era::Byron)),
}
}
@ -122,11 +118,7 @@ impl<'b> MultiEraHeader<'b> {
match self {
MultiEraHeader::EpochBoundary(_) => Err(Error::InvalidEra(Era::Byron)),
MultiEraHeader::ShelleyCompatible(x) => Ok(x.header_body.nonce_vrf.0.to_vec()),
MultiEraHeader::BabbageCompatible(x) => {
let mut nonce_tagged_vrf: Vec<u8> = vec![0x4E_u8]; /* "N" */
nonce_tagged_vrf.extend(&*x.header_body.vrf_result.0);
Ok(Hasher::<256>::hash(&nonce_tagged_vrf).to_vec())
}
MultiEraHeader::BabbageCompatible(x) => Ok(x.header_body.nonce_vrf_output()),
MultiEraHeader::Byron(_) => Err(Error::InvalidEra(Era::Byron)),
}
}