Skip to content

Commit

Permalink
crypto: do not make inner hash public
Browse files Browse the repository at this point in the history
This allows ToBase58Check to no longer return results, since we
know the hashes will _always_ be correctly constructed.
  • Loading branch information
emturner committed Dec 20, 2023
1 parent b7bf966 commit 3272008
Show file tree
Hide file tree
Showing 4 changed files with 28 additions and 42 deletions.
4 changes: 3 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,14 +17,16 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
parameterized by the lifetime of the input byte slice.
- Altered hashes to implement `AsRef<[u8]>` instead of `AsRef<Vec<u8>>`.
- Renamed `hash::Signature` to `hash::UnknownSignature`.
- All hash structs no longer publicly expose the underlying `Hash`. Instead, use `Into<Vec<u8>>` and `AsRef<[u8]>`.
- `ToBase58Check` no longer returns a `Result` type.

### Deprecated

- Nothing.

### Removed

- Nothing.
- Removed `ToBase58CheckError`.

### Fixed

Expand Down
16 changes: 4 additions & 12 deletions crypto/src/base58.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,14 +24,6 @@ pub enum FromBase58CheckError {
IncorrectBase58Prefix,
}

/// Possible errors for ToBase58Check
#[derive(Debug, Error)]
pub enum ToBase58CheckError {
/// Data is too long
#[error("data too long")]
DataTooLong,
}

/// Create double hash of given binary data
fn double_sha256(data: &[u8]) -> [u8; 32] {
let digest = sha256(data);
Expand All @@ -41,7 +33,7 @@ fn double_sha256(data: &[u8]) -> [u8; 32] {
/// A trait for converting a value to base58 encoded string.
pub trait ToBase58Check {
/// Converts a value of `self` to a base58 value, returning the owned string.
fn to_base58check(&self) -> Result<String, ToBase58CheckError>;
fn to_base58check(&self) -> String;
}

/// A trait for converting base58check encoded values.
Expand All @@ -55,14 +47,14 @@ pub trait FromBase58Check {
}

impl ToBase58Check for [u8] {
fn to_base58check(&self) -> Result<String, ToBase58CheckError> {
fn to_base58check(&self) -> String {
// 4 bytes checksum
let mut payload = Vec::with_capacity(self.len() + 4);
payload.extend(self);
let checksum = double_sha256(self);
payload.extend(&checksum[..4]);

Ok(bs58::encode(payload).into_string())
bs58::encode(payload).into_string()
}
}

Expand Down Expand Up @@ -99,7 +91,7 @@ mod tests {

#[test]
fn test_encode() -> Result<(), anyhow::Error> {
let decoded = hex::decode("8eceda2f")?.to_base58check().unwrap();
let decoded = hex::decode("8eceda2f")?.to_base58check();
let expected = "QtRAcc9FSRg";
assert_eq!(expected, &decoded);

Expand Down
10 changes: 3 additions & 7 deletions crypto/src/hash.rs
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ pub enum FromBytesError {
macro_rules! define_hash {
($name:ident) => {
#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct $name(pub Hash);
pub struct $name(pub(crate) Hash);

impl $name {
fn from_bytes(data: &[u8]) -> Result<Self, FromBytesError> {
Expand Down Expand Up @@ -472,12 +472,8 @@ impl HashType {
hash.extend(self.base58check_prefix());
}
hash.extend(data);
hash.to_base58check()
// currently the error is returned if the input lenght exceeds 128 bytes
// that is the limitation of base58 crate, and there are no hash types
// exceeding that limit.
// TODO: remove this when TE-373 is implemented
.map_err(|_| unreachable!("Hash size should not exceed allowed 128 bytes"))

Ok(hash.to_base58check())
}
}

Expand Down
40 changes: 18 additions & 22 deletions crypto/src/signature.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@

use crate::base58::FromBase58CheckError;
use crate::hash::{
BlsSignature, Ed25519Signature, FromBytesError, HashTrait, HashType, P256Signature,
Secp256k1Signature, UnknownSignature,
BlsSignature, Ed25519Signature, FromBytesError, HashTrait, P256Signature, Secp256k1Signature,
UnknownSignature,
};
use serde::{Deserialize, Serialize};

Expand Down Expand Up @@ -57,23 +57,23 @@ impl Signature {
impl AsRef<[u8]> for Signature {
fn as_ref(&self) -> &[u8] {
match self {
Self::Ed25519(s) => s.0.as_ref(),
Self::Secp256k1(s) => s.0.as_ref(),
Self::P256(s) => s.0.as_ref(),
Self::Bls(s) => s.0.as_ref(),
Self::Unknown(s) => s.0.as_ref(),
Self::Ed25519(s) => s.as_ref(),
Self::Secp256k1(s) => s.as_ref(),
Self::P256(s) => s.as_ref(),
Self::Bls(s) => s.as_ref(),
Self::Unknown(s) => s.as_ref(),
}
}
}

impl From<Signature> for Vec<u8> {
fn from(s: Signature) -> Self {
match s {
Signature::Ed25519(s) => s.0,
Signature::Secp256k1(s) => s.0,
Signature::P256(s) => s.0,
Signature::Bls(s) => s.0,
Signature::Unknown(s) => s.0,
Signature::Ed25519(s) => s.into(),
Signature::Secp256k1(s) => s.into(),
Signature::P256(s) => s.into(),
Signature::Bls(s) => s.into(),
Signature::Unknown(s) => s.into(),
}
}
}
Expand All @@ -82,12 +82,10 @@ impl TryFrom<Vec<u8>> for Signature {
type Error = FromBytesError;

fn try_from(hash: Vec<u8>) -> Result<Self, Self::Error> {
if hash.len() == HashType::BlsSignature.size() {
Ok(Signature::Bls(BlsSignature(hash)))
} else if hash.len() == HashType::UnknownSignature.size() {
Ok(Signature::Unknown(UnknownSignature(hash)))
if hash.len() == BlsSignature::hash_size() {
Ok(Signature::Bls(BlsSignature::try_from(hash)?))
} else {
Err(FromBytesError::InvalidSize)
Ok(Signature::Unknown(UnknownSignature::try_from(hash)?))
}
}
}
Expand All @@ -96,12 +94,10 @@ impl TryFrom<&[u8]> for Signature {
type Error = FromBytesError;

fn try_from(hash: &[u8]) -> Result<Self, Self::Error> {
if hash.len() == HashType::BlsSignature.size() {
Ok(Signature::Bls(BlsSignature(hash.to_vec())))
} else if hash.len() == HashType::UnknownSignature.size() {
Ok(Signature::Unknown(UnknownSignature(hash.to_vec())))
if let Ok(s) = BlsSignature::try_from(hash) {
Ok(Signature::Bls(s))
} else {
Err(FromBytesError::InvalidSize)
Ok(Signature::Unknown(UnknownSignature::try_from(hash)?))
}
}
}
Expand Down

0 comments on commit 3272008

Please sign in to comment.