Skip to content

Commit

Permalink
Merge pull request #23 from airgap-it/feat/publickey-to-address
Browse files Browse the repository at this point in the history
feat: convert public key to address
  • Loading branch information
RomarQ authored Apr 4, 2023
2 parents 907ed67 + c1f0f29 commit dba4aeb
Show file tree
Hide file tree
Showing 3 changed files with 79 additions and 13 deletions.
6 changes: 6 additions & 0 deletions tezos-core/src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,12 @@ pub enum Error {
TryFromBigUInt {
source: num_bigint::TryFromBigIntError<num_bigint::BigUint>,
},
Blake2InvalidOutputSize {
source: blake2::digest::InvalidOutputSize,
},
Blake2InvalidBufferSize {
source: blake2::digest::InvalidBufferSize,
},
InvalidSecretKeyBytes,
InvalidPublicKeyBytes,
InvalidSignatureBytes,
Expand Down
24 changes: 14 additions & 10 deletions tezos-core/src/internal/crypto.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,16 +21,7 @@ impl Crypto {
}

pub fn blake2b(&self, message: &[u8], size: usize) -> Result<Vec<u8>> {
use blake2::{
digest::{Update, VariableOutput},
Blake2bVar,
};
let mut hasher = Blake2bVar::new(size).unwrap();
hasher.update(message);
let mut buf = Vec::<u8>::new();
buf.resize(size, 0);
hasher.finalize_variable(&mut buf).unwrap();
Ok(buf)
blake2b(message, size)
}

pub fn sign_ed25519(&self, message: &[u8], secret: &[u8]) -> Result<Vec<u8>> {
Expand Down Expand Up @@ -85,3 +76,16 @@ impl Crypto {
.verify(message, signature, public_key)
}
}

pub fn blake2b(message: &[u8], size: usize) -> Result<Vec<u8>> {
use blake2::{
digest::{Update, VariableOutput},
Blake2bVar,
};
let mut hasher = Blake2bVar::new(size)?;
hasher.update(message);
let mut buf = Vec::<u8>::new();
buf.resize(size, 0);
hasher.finalize_variable(&mut buf)?;
Ok(buf)
}
62 changes: 59 additions & 3 deletions tezos-core/src/types/encoded/key.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,14 @@
use serde::{Deserialize, Serialize};

use crate::{
internal::coder::{EncodedBytesCoder, PublicKeyBytesCoder},
internal::{
coder::{EncodedBytesCoder, PublicKeyBytesCoder},
crypto::blake2b,
},
types::encoded::{
Ed25519PublicKey, Ed25519SecretKey, Encoded, MetaEncoded, P256PublicKey, P256SecretKey,
Secp256K1PublicKey, Secp256K1SecretKey,
Ed25519PublicKey, Ed25519PublicKeyHash, Ed25519SecretKey, Encoded, ImplicitAddress,
MetaEncoded, P256PublicKey, P256PublicKeyHash, P256SecretKey, Secp256K1PublicKey,
Secp256K1PublicKeyHash, Secp256K1SecretKey,
},
Error, Result,
};
Expand Down Expand Up @@ -280,6 +284,31 @@ impl PublicKey {
|| Secp256K1PublicKey::is_valid_bytes(value)
|| P256PublicKey::is_valid_bytes(value)
}

/// Base58 encoded address
pub fn bs58_address(&self) -> Result<String> {
self.address().map(|address| address.into_string())
}

fn address(&self) -> Result<ImplicitAddress> {
fn address_of<T: Encoded>(v: &[u8]) -> Result<T> {
blake2b(v, 20).map(|hash| T::from_bytes(hash.as_slice()))?
}

let address = match self {
Self::Ed25519(value) => {
ImplicitAddress::from(address_of::<Ed25519PublicKeyHash>(&value.to_bytes()?)?)
}
Self::Secp256K1(value) => {
ImplicitAddress::from(address_of::<Secp256K1PublicKeyHash>(&value.to_bytes()?)?)
}
Self::P256(value) => {
ImplicitAddress::from(address_of::<P256PublicKeyHash>(&value.to_bytes()?)?)
}
};

Ok(address)
}
}

impl Encoded for PublicKey {
Expand Down Expand Up @@ -418,6 +447,15 @@ mod test {
Err(Error::InvalidConversion)
}

#[test]
fn test_edpk_to_tz1() {
let key: PublicKey = "edpkuF5y5V7NNH5xKMCKHHqVDzq6YuUXiPT3FFjA9CGnht6xCgziTe"
.try_into()
.unwrap();
let address = key.bs58_address().unwrap();
assert_eq!(address, "tz1VZFmv9dJj7QFs8nv5JTjJiYJxVQXqmDMv".to_string())
}

#[test]
fn test_edpk_secret_key() -> Result<()> {
let key: SecretKey = "edskRhKTQkgxb7CNTr31rzy3xdkyKaYX9hySAnZYJTPmUzPB7WU4NL7C8pmtQDgRqQ4jDw4Ugh6Y1UW5nvo7UYrRbyhVYK1YuR".try_into()?;
Expand Down Expand Up @@ -471,6 +509,15 @@ mod test {
Err(Error::InvalidConversion)
}

#[test]
fn test_sppk_to_tz2() {
let key: PublicKey = "sppkDN74FpFyXiHUe7MZS7rwDzzwb2esc21355LEcSExN67KdNnAfqA"
.try_into()
.unwrap();
let address = key.bs58_address().unwrap();
assert_eq!(address, "tz2WHHyhmspQDmKzAZmDmUyqkhcS3BA5EiuU".to_string())
}

#[test]
fn test_secp_256_k1_secret_key() -> Result<()> {
let key: SecretKey = "spsk2WUw2TFXQq2CsrNhB7EfFzdhMyNvGoYgD4uGQ6e17MgoRDv1co".try_into()?;
Expand Down Expand Up @@ -524,6 +571,15 @@ mod test {
Err(Error::InvalidConversion)
}

#[test]
fn test_p2pk_to_tz2() {
let key: PublicKey = "p2pkDkL6thzTwyPjpmMotSqeKy1MAftLrseqTALwBhHwUtXRmFV983f"
.try_into()
.unwrap();
let address = key.bs58_address().unwrap();
assert_eq!(address, "tz3c6Z7Vaz3jDfpKLof6PSJsHsUDYjBbQpbn".to_string())
}

#[test]
fn test_p256_secret_key() -> Result<()> {
let key: SecretKey = "p2sk2Xoduh8dx6B3smV81NMV25cYpZJj7yYWMRARedzyJae8SB9auw".try_into()?;
Expand Down

0 comments on commit dba4aeb

Please sign in to comment.