NAC_Blockchain/charter-std/utils/crypto.ch

381 lines
10 KiB
Plaintext
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

///! # 加密函数库
///!
///! Cryptographic Utilities
///! 提供加密哈希和签名验证函数
///!
///! **版本**: v1.0
///! **模块**: charter-std/utils/crypto.ch
// ============================================================================
// 哈希函数NAC使用SHA3-384不是SHA256/Keccak256
// ============================================================================
/// SHA3-384哈希NAC标准
///
/// # 参数
/// - `data`: 待哈希数据
///
/// # 返回
/// - `Hash`: SHA3-384哈希值48字节
pub fn sha3_384_hash(data: Bytes) -> Hash {
return Hash::sha3_384(data);
}
/// SHA3-384哈希字符串
///
/// # 参数
/// - `data`: 待哈希字符串
///
/// # 返回
/// - `Hash`: SHA3-384哈希值
pub fn sha3_384_hash_string(data: String) -> Hash {
return Hash::sha3_384(data.as_bytes());
}
/// SHA3-384哈希多个数据
///
/// # 参数
/// - `data_list`: 数据列表
///
/// # 返回
/// - `Hash`: SHA3-384哈希值
pub fn sha3_384_hash_multiple(data_list: Vec<Bytes>) -> Hash {
let mut combined = Bytes::new();
for data in data_list {
combined.extend(data);
}
return Hash::sha3_384(combined);
}
// ============================================================================
// 地址相关
// ============================================================================
/// 从公钥派生地址
///
/// # 参数
/// - `public_key`: 公钥33字节压缩格式或65字节未压缩格式
///
/// # 返回
/// - `Address`: 地址
pub fn address_from_public_key(public_key: Bytes) -> Address {
require(
public_key.len() == 33 || public_key.len() == 65,
"Invalid public key length"
);
// SHA3-384哈希公钥取前20字节作为地址
let hash = sha3_384_hash(public_key);
return Address::from_hash(hash);
}
/// 验证地址格式
///
/// # 参数
/// - `address`: 地址
///
/// # 返回
/// - `bool`: 是否有效
pub fn is_valid_address(address: Address) -> bool {
return !address.is_zero();
}
// ============================================================================
// 签名验证
// ============================================================================
/// 验证Ed25519签名
///
/// # 参数
/// - `message`: 消息
/// - `signature`: 签名64字节
/// - `public_key`: 公钥48字节
///
/// # 返回
/// - `bool`: 签名是否有效
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);
}
/// 验证ECDSA签名secp256k1
///
/// # 参数
/// - `message_hash`: 消息哈希
/// - `signature`: 签名64字节 + 1字节recovery id
/// - `public_key`: 公钥33字节压缩格式或65字节未压缩格式
///
/// # 返回
/// - `bool`: 签名是否有效
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);
}
/// 从ECDSA签名恢复公钥
///
/// # 参数
/// - `message_hash`: 消息哈希
/// - `signature`: 签名64字节 + 1字节recovery id
///
/// # 返回
/// - `Bytes`: 恢复的公钥65字节未压缩格式
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);
}
// ============================================================================
// 消息签名和验证
// ============================================================================
/// 创建消息哈希(用于签名)
///
/// # 参数
/// - `message`: 消息
///
/// # 返回
/// - `Hash`: 消息哈希
pub fn create_message_hash(message: String) -> Hash {
// NAC消息签名格式"\x19NAC Signed Message:\n" + len(message) + message
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);
}
/// 验证签名消息
///
/// # 参数
/// - `message`: 原始消息
/// - `signature`: 签名
/// - `signer`: 签名者地址
///
/// # 返回
/// - `bool`: 签名是否有效
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;
}
// ============================================================================
// Merkle树
// ============================================================================
/// 计算Merkle根
///
/// # 参数
/// - `leaves`: 叶子节点哈希列表
///
/// # 返回
/// - `Hash`: Merkle根
pub fn compute_merkle_root(leaves: Vec<Hash>) -> 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];
}
/// 验证Merkle证明
///
/// # 参数
/// - `leaf`: 叶子节点哈希
/// - `proof`: Merkle证明哈希列表
/// - `root`: Merkle根
/// - `index`: 叶子节点索引
///
/// # 返回
/// - `bool`: 证明是否有效
pub fn verify_merkle_proof(
leaf: Hash,
proof: Vec<Hash>,
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;
}
// ============================================================================
// 随机数生成(伪随机)
// ============================================================================
/// 生成伪随机数
///
/// # 参数
/// - `seed`: 种子
///
/// # 返回
/// - `u256`: 伪随机数
///
/// # 警告
/// 这不是密码学安全的随机数生成器!
/// 仅用于非安全关键场景
pub fn pseudo_random(seed: Bytes) -> u256 {
let hash = sha3_384_hash(seed);
return u256::from_bytes(hash.as_bytes());
}
/// 生成伪随机数(使用区块信息)
///
/// # 返回
/// - `u256`: 伪随机数
///
/// # 警告
/// 这不是密码学安全的随机数生成器!
/// 可被矿工操纵,仅用于非安全关键场景
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);
}
// ============================================================================
// Base58编码/解码(用于地址显示)
// ============================================================================
/// Base58编码
///
/// # 参数
/// - `data`: 待编码数据
///
/// # 返回
/// - `String`: Base58编码字符串
pub fn base58_encode(data: Bytes) -> String {
const ALPHABET: &str = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz";
// 实现Base58编码逻辑
// (简化版本,实际实现需要更复杂的逻辑)
return crypto::base58_encode(data);
}
/// Base58解码
///
/// # 参数
/// - `encoded`: Base58编码字符串
///
/// # 返回
/// - `Bytes`: 解码后的数据
pub fn base58_decode(encoded: String) -> Bytes {
return crypto::base58_decode(encoded);
}
// ============================================================================
// 十六进制编码/解码
// ============================================================================
/// 十六进制编码
///
/// # 参数
/// - `data`: 待编码数据
///
/// # 返回
/// - `String`: 十六进制字符串带0x前缀
pub fn hex_encode(data: Bytes) -> String {
return "0x" + data.to_hex();
}
/// 十六进制解码
///
/// # 参数
/// - `hex_string`: 十六进制字符串可带或不带0x前缀
///
/// # 返回
/// - `Bytes`: 解码后的数据
pub fn hex_decode(hex_string: String) -> Bytes {
let hex = hex_string.trim_start_matches("0x");
return Bytes::from_hex(hex);
}