Skip to content

Commit

Permalink
Crypto module refactor (#3)
Browse files Browse the repository at this point in the history
  • Loading branch information
MissingNO57 authored Apr 11, 2024
1 parent b246b7a commit 65be5d3
Show file tree
Hide file tree
Showing 13 changed files with 523 additions and 99 deletions.
18 changes: 18 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 4 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -12,4 +12,7 @@ cw-storage-plus = "1.0.1"
bech32 = "0.9.1"
sha2 = "0.10.6"
ripemd = "0.1.3"
serde = { version = "1.0.145", default-features = false, features = ["derive"] }
serde = { version = "1.0.145", default-features = false, features = ["derive"] }
tiny-keccak = { version = "2.0.2", features = ["keccak"] }
hex = "0.4.3"
base64 = "0.21.7"
45 changes: 45 additions & 0 deletions src/crypto/cosmos.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
use cosmwasm_std::Addr;

use crate::crypto::encoding::encode_bech32;
use crate::crypto::hashing::{ripemd160, sha256};

pub type RawCosmosAddress = [u8; 20];

pub fn cosmos_raw_address(pubkey: &[u8]) -> RawCosmosAddress {
let hash = ripemd160(&sha256(pubkey));

let mut addr = [0u8; 20];
addr.copy_from_slice(&hash[..]);

addr
}

pub fn cosmos_address(raw_address: &RawCosmosAddress, prefix: &str) -> Addr {
Addr::unchecked(encode_bech32(prefix, raw_address).unwrap())
}

pub fn cosmos_address_from_pubkey(pubkey: &[u8], prefix: &str) -> Addr {
cosmos_address(&cosmos_raw_address(pubkey), prefix)
}

#[cfg(test)]
mod tests {
use super::*;
use crate::crypto::encoding::parse_bech32;

#[test]
fn test_pubkey_to_address() {
// Test if encoded pubkey can be decoded and converted to address

let pubkey_str =
"pub1qv6wrktsr7hng9rmmjqa2yfqj0cg7w43n0qkq3xuqmgxu6ewnyyjykzgyam".to_string();
let address = Addr::unchecked("fetch1967p3vkp0yngdfturv4ypq2p4g760ml705wcxy".to_string());

// Get pubkey in bytes
let pubkey_bytes = parse_bech32(&pubkey_str, "pub").unwrap();
// Convert pubkey bytes to address
let recovered_addr = cosmos_address_from_pubkey(&pubkey_bytes, "fetch");

assert_eq!(recovered_addr, address);
}
}
87 changes: 0 additions & 87 deletions src/crypto/crypto_impl.rs

This file was deleted.

39 changes: 39 additions & 0 deletions src/crypto/encoding.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
use bech32::{FromBase32, ToBase32};
use cosmwasm_std::StdError;

pub fn parse_bech32(data: &str, expected_prefix: &str) -> Result<Vec<u8>, StdError> {
let (prefix, parsed_data, _variant) = match bech32::decode(data) {
Ok(parsed_data) => Ok(parsed_data),
Err(err) => Err(base32_parsing_error(&err)),
}?;

if prefix != expected_prefix {
return Err(prefix_error(expected_prefix, &prefix));
}

match Vec::<u8>::from_base32(&parsed_data) {
Ok(res) => Ok(res),
Err(err) => Err(base32_parsing_error(&err)),
}
}

pub fn encode_bech32(prefix: &str, data: &[u8]) -> Result<String, StdError> {
let encoded = match bech32::encode(prefix, data.to_base32(), bech32::Variant::Bech32) {
Ok(encoded) => Ok(encoded),
Err(err) => Err(base32_parsing_error(&err)),
}?;

Ok(encoded)
}

// Errors
pub fn prefix_error(expected: &str, actual: &str) -> StdError {
StdError::generic_err(format!(
"Wrong prefix. Expected {}, got {}.",
expected, actual
))
}

pub fn base32_parsing_error<T: std::fmt::Display>(err: &T) -> StdError {
StdError::generic_err(format!("Base32 parsing failed: {}", err))
}
Loading

0 comments on commit 65be5d3

Please sign in to comment.