pub fn sha3_384_hash(data: Bytes) -> Hash { return Hash::sha3_384(data); } pub fn sha3_384_hash_string(data: String) -> Hash { return Hash::sha3_384(data.as_bytes()); } pub fn sha3_384_hash_multiple(data_list: Vec) -> Hash { let mut combined = Bytes::new(); for data in data_list { combined.extend(data); } return Hash::sha3_384(combined); } pub fn address_from_public_key(public_key: Bytes) -> Address { require(public_key.len() == 33 || public_key.len() == 65, "Invalid public key length"); let hash = sha3_384_hash(public_key); return Address::from_hash(hash); } pub fn is_valid_address(address: Address) -> bool { return !address.is_zero(); } pub fn verify_ed25519_signature(message: Bytes, signature: Bytes, public_key: Bytes) -> bool { require(signature.len() == 64, "Invalid signature length"); require(public_key.len() == 32, "Invalid public key length"); return crypto::ed25519_verify(message, signature, public_key); } pub fn verify_ecdsa_signature(message_hash: Hash, signature: Bytes, public_key: Bytes) -> bool { require(signature.len() == 65, "Invalid signature length"); require(public_key.len() == 33 || public_key.len() == 65, "Invalid public key length"); return crypto::ecdsa_verify(message_hash.as_bytes(), signature, public_key); } pub fn recover_ecdsa_public_key(message_hash: Hash, signature: Bytes) -> Bytes { require(signature.len() == 65, "Invalid signature length"); return crypto::ecdsa_recover(message_hash.as_bytes(), signature); } pub fn create_message_hash(message: String) -> Hash { let prefix = "\x19NAC Signed Message:\n"; let len_str = message.len().to_string(); let mut full_message = Bytes::from(prefix); full_message.extend(Bytes::from(len_str)); full_message.extend(Bytes::from(message)); return sha3_384_hash(full_message); } pub fn verify_signed_message(message: String, signature: Bytes, signer: Address) -> bool { require(signature.len() == 65, "Invalid signature length"); let message_hash = create_message_hash(message); let recovered_pubkey = recover_ecdsa_public_key(message_hash, signature); let recovered_address = address_from_public_key(recovered_pubkey); return recovered_address == signer; } pub fn compute_merkle_root(leaves: Vec) -> Hash { require(leaves.len() > 0, "Leaves cannot be empty"); if leaves.len() == 1 { return leaves[0]; } let mut current_level = leaves; while current_level.len() > 1 { let mut next_level = Vec::new(); let mut i = 0; while i < current_level.len() { if i + 1 < current_level.len() { let combined = Bytes::new(); combined.extend(current_level[i].as_bytes()); combined.extend(current_level[i + 1].as_bytes()); next_level.push(sha3_384_hash(combined)); i += 2; } else { let combined = Bytes::new(); combined.extend(current_level[i].as_bytes()); combined.extend(current_level[i].as_bytes()); next_level.push(sha3_384_hash(combined)); i += 1; } } current_level = next_level; } return current_level[0]; } pub fn verify_merkle_proof(leaf: Hash, proof: Vec, root: Hash, index: u256) -> bool { let mut computed_hash = leaf; let mut current_index = index; for proof_element in proof { let combined = Bytes::new(); if current_index % 2 == 0 { combined.extend(computed_hash.as_bytes()); combined.extend(proof_element.as_bytes()); } else { combined.extend(proof_element.as_bytes()); combined.extend(computed_hash.as_bytes()); } computed_hash = sha3_384_hash(combined); current_index = current_index / 2; } return computed_hash == root; } pub fn pseudo_random(seed: Bytes) -> u256 { let hash = sha3_384_hash(seed); return u256::from_bytes(hash.as_bytes()); } pub fn pseudo_random_from_block() -> u256 { let mut seed = Bytes::new(); seed.extend(block.hash.as_bytes()); seed.extend(block.timestamp.to_bytes()); seed.extend(tx.hash.as_bytes()); return pseudo_random(seed); } pub fn base58_encode(data: Bytes) -> String { const ALPHABET: &str = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz"; return crypto::base58_encode(data); } pub fn base58_decode(encoded: String) -> Bytes { return crypto::base58_decode(encoded); } pub fn hex_encode(data: Bytes) -> String { return "0x" + data.to_hex(); } pub fn hex_decode(hex_string: String) -> Bytes { let hex = hex_string.trim_start_matches("0x"); return Bytes::from_hex(hex); }