Skip to content

Commit

Permalink
wip
Browse files Browse the repository at this point in the history
  • Loading branch information
SWvheerden committed May 24, 2024
1 parent 97c0841 commit 2430ce9
Show file tree
Hide file tree
Showing 10 changed files with 597 additions and 144 deletions.
2 changes: 1 addition & 1 deletion base_layer/chat_ffi/src/contacts_liveness_data.rs
Original file line number Diff line number Diff line change
Expand Up @@ -172,7 +172,7 @@ mod test {
unsafe {
let address_ptr = read_liveness_data_address(liveness_ptr, error_out);

assert_eq!(address.to_bytes(), (*address_ptr).to_bytes());
assert_eq!(address.to_vec(), (*address_ptr).to_bytes());

destroy_contacts_liveness_data(liveness_ptr);
destroy_tari_address(address_ptr);
Expand Down
180 changes: 139 additions & 41 deletions base_layer/common_types/src/tari_address/dual_address.rs
Original file line number Diff line number Diff line change
Expand Up @@ -172,52 +172,153 @@ mod test {
use crate::types::PrivateKey;

#[test]
/// Test valid tari address
/// Test valid dual tari address
fn valid_emoji_id() {
// Generate random public key
let mut rng = rand::thread_rng();
let public_key = PublicKey::from_secret_key(&PrivateKey::random(&mut rng));
let view_key = PublicKey::from_secret_key(&PrivateKey::random(&mut rng));
let spend_key = PublicKey::from_secret_key(&PrivateKey::random(&mut rng));

// Generate an emoji ID from the public key and ensure we recover it
let emoji_id_from_public_key = TariAddress::from_public_key(&public_key, Network::Esmeralda);
assert_eq!(emoji_id_from_public_key.public_key(), &public_key);
let emoji_id_from_public_key = DualAddress::new_with_default_features(view_key.clone(), spend_key.clone(), Network::Esmeralda);
assert_eq!(emoji_id_from_public_key.public_spend_key(), &spend_key);
assert_eq!(emoji_id_from_public_key.public_view_key(), &view_key);

// Check the size of the corresponding emoji string
let emoji_string = emoji_id_from_public_key.to_emoji_string();
assert_eq!(emoji_string.chars().count(), INTERNAL_SIZE);
assert_eq!(emoji_string.chars().count(), INTERNAL_DUAL_SIZE);

let features = emoji_id_from_public_key.features();
assert_eq!(features, TariAddressFeatures::create_interactive_and_one_sided());

// Generate an emoji ID from the emoji string and ensure we recover it
let emoji_id_from_emoji_string = TariAddress::from_emoji_string(&emoji_string).unwrap();
let emoji_id_from_emoji_string = DualAddress::from_emoji_string(&emoji_string).unwrap();
assert_eq!(emoji_id_from_emoji_string.to_emoji_string(), emoji_string);

// Return to the original public key for good measure
assert_eq!(emoji_id_from_emoji_string.public_key(), &public_key);
// Return to the original public keys for good measure
assert_eq!(emoji_id_from_public_key.public_spend_key(), &spend_key);
assert_eq!(emoji_id_from_public_key.public_view_key(), &view_key);


// Generate random public key
let view_key = PublicKey::from_secret_key(&PrivateKey::random(&mut rng));
let spend_key = PublicKey::from_secret_key(&PrivateKey::random(&mut rng));

// Generate an emoji ID from the public key and ensure we recover it
let emoji_id_from_public_key = DualAddress::new(view_key.clone(), spend_key.clone(), Network::Esmeralda, TariAddressFeatures::create_interactive_only());
assert_eq!(emoji_id_from_public_key.public_spend_key(), &spend_key);
assert_eq!(emoji_id_from_public_key.public_view_key(), &view_key);

// Check the size of the corresponding emoji string
let emoji_string = emoji_id_from_public_key.to_emoji_string();
assert_eq!(emoji_string.chars().count(), INTERNAL_DUAL_SIZE);

let features = emoji_id_from_public_key.features();
assert_eq!(features, TariAddressFeatures::create_interactive_only());

// Generate an emoji ID from the emoji string and ensure we recover it
let emoji_id_from_emoji_string = DualAddress::from_emoji_string(&emoji_string).unwrap();
assert_eq!(emoji_id_from_emoji_string.to_emoji_string(), emoji_string);

// Return to the original public keys for good measure
assert_eq!(emoji_id_from_public_key.public_spend_key(), &spend_key);
assert_eq!(emoji_id_from_public_key.public_view_key(), &view_key);


// Generate random public key
let view_key = PublicKey::from_secret_key(&PrivateKey::random(&mut rng));
let spend_key = PublicKey::from_secret_key(&PrivateKey::random(&mut rng));

// Generate an emoji ID from the public key and ensure we recover it
let emoji_id_from_public_key = DualAddress::new(view_key.clone(), spend_key.clone(), Network::Esmeralda, TariAddressFeatures::create_one_sided_only());
assert_eq!(emoji_id_from_public_key.public_spend_key(), &spend_key);
assert_eq!(emoji_id_from_public_key.public_view_key(), &view_key);

// Check the size of the corresponding emoji string
let emoji_string = emoji_id_from_public_key.to_emoji_string();
assert_eq!(emoji_string.chars().count(), INTERNAL_DUAL_SIZE);

let features = emoji_id_from_public_key.features();
assert_eq!(features, TariAddressFeatures::create_one_sided_only());

// Generate an emoji ID from the emoji string and ensure we recover it
let emoji_id_from_emoji_string = DualAddress::from_emoji_string(&emoji_string).unwrap();
assert_eq!(emoji_id_from_emoji_string.to_emoji_string(), emoji_string);

// Return to the original public keys for good measure
assert_eq!(emoji_id_from_public_key.public_spend_key(), &spend_key);
assert_eq!(emoji_id_from_public_key.public_view_key(), &view_key);
}

#[test]
/// Test encoding for tari address
/// Test encoding for dual tari address
fn encoding() {
// Generate random public key
let mut rng = rand::thread_rng();
let public_key = PublicKey::from_secret_key(&PrivateKey::random(&mut rng));
let view_key = PublicKey::from_secret_key(&PrivateKey::random(&mut rng));
let spend_key = PublicKey::from_secret_key(&PrivateKey::random(&mut rng));

// Generate an emoji ID from the public key and ensure we recover it
let address = DualAddress::new_with_default_features(view_key.clone(), spend_key.clone(), Network::Esmeralda);

let buff = address.to_bytes();
let hex = address.to_hex();

let address_buff = DualAddress::from_bytes(&buff).unwrap();
assert_eq!(address_buff.public_spend_key(), address.public_spend_key());
assert_eq!(address_buff.public_view_key(), address.public_view_key());
assert_eq!(address_buff.network(), address.network());
assert_eq!(address_buff.features(), address.features());

let address_hex = DualAddress::from_hex(&hex).unwrap();
assert_eq!(address_hex.public_spend_key(), address.public_spend_key());
assert_eq!(address_hex.public_view_key(), address.public_view_key());
assert_eq!(address_hex.network(), address.network());
assert_eq!(address_hex.features(), address.features());


let view_key = PublicKey::from_secret_key(&PrivateKey::random(&mut rng));
let spend_key = PublicKey::from_secret_key(&PrivateKey::random(&mut rng));

// Generate an emoji ID from the public key and ensure we recover it
let address = TariAddress::from_public_key(&public_key, Network::Esmeralda);
let address = DualAddress::new(view_key.clone(), spend_key.clone(), Network::Esmeralda, TariAddressFeatures::create_interactive_only());

let buff = address.to_bytes();
let hex = address.to_hex();

let address_buff = TariAddress::from_bytes(&buff);
assert_eq!(address_buff, Ok(address.clone()));
let address_buff = DualAddress::from_bytes(&buff).unwrap();
assert_eq!(address_buff.public_spend_key(), address.public_spend_key());
assert_eq!(address_buff.public_view_key(), address.public_view_key());
assert_eq!(address_buff.network(), address.network());
assert_eq!(address_buff.features(), address.features());

let address_hex = DualAddress::from_hex(&hex).unwrap();
assert_eq!(address_hex.public_spend_key(), address.public_spend_key());
assert_eq!(address_hex.public_view_key(), address.public_view_key());
assert_eq!(address_hex.network(), address.network());
assert_eq!(address_hex.features(), address.features());

let address_buff = TariAddress::from_bytes_with_network(&buff, Network::Esmeralda);
assert_eq!(address_buff, Ok(address.clone()));

let address_hex = TariAddress::from_hex(&hex);
assert_eq!(address_hex, Ok(address.clone()));
let view_key = PublicKey::from_secret_key(&PrivateKey::random(&mut rng));
let spend_key = PublicKey::from_secret_key(&PrivateKey::random(&mut rng));

let address_hex = TariAddress::from_hex_with_network(&hex, Network::Esmeralda);
assert_eq!(address_hex, Ok(address));
// Generate an emoji ID from the public key and ensure we recover it
let address = DualAddress::new(view_key.clone(), spend_key.clone(), Network::Esmeralda, TariAddressFeatures::create_one_sided_only());

let buff = address.to_bytes();
let hex = address.to_hex();

let address_buff = DualAddress::from_bytes(&buff).unwrap();
assert_eq!(address_buff.public_spend_key(), address.public_spend_key());
assert_eq!(address_buff.public_view_key(), address.public_view_key());
assert_eq!(address_buff.network(), address.network());
assert_eq!(address_buff.features(), address.features());

let address_hex = DualAddress::from_hex(&hex).unwrap();
assert_eq!(address_hex.public_spend_key(), address.public_spend_key());
assert_eq!(address_hex.public_view_key(), address.public_view_key());
assert_eq!(address_hex.network(), address.network());
assert_eq!(address_hex.features(), address.features());
}

#[test]
Expand All @@ -226,13 +327,13 @@ mod test {
// This emoji string is too short to be a valid emoji ID
let emoji_string = "πŸŒ΄πŸ¦€πŸ”ŒπŸ“ŒπŸš‘πŸŒ°πŸŽ“πŸŒ΄πŸŠπŸŒπŸ”’πŸ’‘πŸœπŸ“œπŸ‘›πŸ΅πŸ‘›πŸ½πŸŽ‚πŸ»πŸ¦‹πŸ“πŸ‘ΆπŸ­πŸΌπŸ€πŸŽͺπŸ’”πŸ’΅πŸ₯‘πŸ”‹πŸŽ’";
assert_eq!(
TariAddress::from_emoji_string(emoji_string),
DualAddress::from_emoji_string(emoji_string),
Err(TariAddressError::InvalidSize)
);
// This emoji string is too long to be a valid emoji ID
let emoji_string = "πŸŒ΄πŸ¦€πŸ”ŒπŸ“ŒπŸš‘πŸŒ°πŸŽ“πŸŒ΄πŸŠπŸŒπŸ”’πŸ’‘πŸœπŸ“œπŸ‘›πŸ΅πŸ‘›πŸ½πŸŽ‚πŸ»πŸ¦‹πŸ“πŸ‘ΆπŸ­πŸΌπŸ€πŸŽͺπŸ’”πŸ’΅πŸ₯‘πŸ”‹πŸŽ’πŸŽ’πŸŽ’πŸŽ’πŸŽ’";
assert_eq!(
TariAddress::from_emoji_string(emoji_string),
DualAddress::from_emoji_string(emoji_string),
Err(TariAddressError::InvalidSize)
);
}
Expand All @@ -243,7 +344,7 @@ mod test {
// This emoji string contains an invalid emoji character
let emoji_string = "πŸŒ΄πŸ¦€πŸ”ŒπŸ“ŒπŸš‘πŸŒ°πŸŽ“πŸŒ΄πŸŠπŸŒπŸ”’πŸ’‘πŸœπŸ“œπŸ‘›πŸ΅πŸ‘›πŸ½πŸŽ‚πŸ»πŸ¦‹πŸ“πŸ‘ΆπŸ­πŸΌπŸ€πŸŽͺπŸ’”πŸ’΅πŸ₯‘πŸ”‹πŸŽ’πŸŽ…";
assert_eq!(
TariAddress::from_emoji_string(emoji_string),
DualAddress::from_emoji_string(emoji_string),
Err(TariAddressError::InvalidEmoji)
);
}
Expand All @@ -254,45 +355,42 @@ mod test {
// This emoji string contains an invalid checksum
let emoji_string = "πŸŒ΄πŸ¦€πŸ”ŒπŸ“ŒπŸš‘πŸŒ°πŸŽ“πŸŒ΄πŸŠπŸŒπŸ”’πŸ’‘πŸœπŸ“œπŸ‘›πŸ΅πŸ‘›πŸ½πŸŽ‚πŸ»πŸ¦‹πŸ“πŸ‘ΆπŸ­πŸΌπŸ€πŸŽͺπŸ’”πŸ’΅πŸ₯‘πŸ”‹πŸŽ’πŸŽ’";
assert_eq!(
TariAddress::from_emoji_string(emoji_string),
Err(TariAddressError::InvalidNetworkOrChecksum)
DualAddress::from_emoji_string(emoji_string),
Err(TariAddressError::InvalidChecksum)
);
}

#[test]
/// Test invalid network
fn invalid_network() {
let mut rng = rand::thread_rng();
let public_key = PublicKey::from_secret_key(&PrivateKey::random(&mut rng));
let view_key = PublicKey::from_secret_key(&PrivateKey::random(&mut rng));
let spend_key = PublicKey::from_secret_key(&PrivateKey::random(&mut rng));

// Generate an address using a valid network and ensure it's not valid on another network
let address = TariAddress::from_public_key(&public_key, Network::Esmeralda);
assert_eq!(
TariAddress::from_bytes_with_network(&address.to_bytes(), Network::Igor),
Err(TariAddressError::InvalidNetworkOrChecksum)
);

// Generate an address using a valid network, mutate it, and ensure it's not valid on the same network
let mut address_bytes = address.to_bytes();
address_bytes[32] ^= 0xFF;
let address = DualAddress::new_with_default_features(view_key, spend_key, Network::Esmeralda);
let mut bytes = address.to_bytes();
// this is an invalid network
bytes[0] = 123;
assert_eq!(
TariAddress::from_bytes_with_network(&address_bytes, Network::Esmeralda),
Err(TariAddressError::InvalidNetworkOrChecksum)
DualAddress::from_bytes(&address.to_bytes()),
Err(TariAddressError::InvalidNetwork)
);
}

#[test]
/// Test invalid public key
fn invalid_public_key() {
let mut bytes = [0; 33].to_vec();
bytes[0] = 1;
let checksum = compute_checksum(&bytes[0..32]);
bytes[32] = Network::Esmeralda.as_byte() ^ checksum;
let mut bytes = [0; 67].to_vec();
bytes[0] = Network::Esmeralda.as_byte();
bytes[1] = TariAddressFeatures::create_interactive_and_one_sided().0;
let checksum = compute_checksum(&bytes[0..66]);
bytes[66] = checksum;
let emoji_string = bytes.iter().map(|b| EMOJI[*b as usize]).collect::<String>();

// This emoji string contains an invalid checksum
assert_eq!(
TariAddress::from_emoji_string(&emoji_string),
DualAddress::from_emoji_string(&emoji_string),
Err(TariAddressError::CannotRecoverPublicKey)
);
}
Expand Down
Loading

0 comments on commit 2430ce9

Please sign in to comment.