changes for wallet key creation
This commit is contained in:
parent
65ac8afa5a
commit
845a70f577
|
|
@ -269,7 +269,7 @@ pub async fn process_handshake_response(
|
||||||
|
|
||||||
let returned_message = encode(returned_message_bin);
|
let returned_message = encode(returned_message_bin);
|
||||||
let returned_signed_message = encode(returned_signed_bin);
|
let returned_signed_message = encode(returned_signed_bin);
|
||||||
if returned_public_key_bin.len() != Wallet::PUBLIC_KEY_LENGTH {
|
if !Wallet::has_valid_public_key_bytes(returned_public_key_bin) {
|
||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
let hash = skein_256_hash_data(&returned_message);
|
let hash = skein_256_hash_data(&returned_message);
|
||||||
|
|
|
||||||
|
|
@ -83,7 +83,7 @@ pub async fn register(
|
||||||
return RpcResponse::Binary(b"0".to_vec());
|
return RpcResponse::Binary(b"0".to_vec());
|
||||||
}
|
}
|
||||||
|
|
||||||
if public_key_bytes.len() != Wallet::PUBLIC_KEY_LENGTH {
|
if !Wallet::has_valid_public_key_bytes(&public_key_bytes) {
|
||||||
return RpcResponse::Binary(b"0".to_vec());
|
return RpcResponse::Binary(b"0".to_vec());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -17,7 +17,7 @@ pub async fn request_registry(db: &Db) -> RpcResponse {
|
||||||
let mut response_bytes = Vec::with_capacity(wallets.len() * WALLET_REGISTRY_RECORD_BYTES);
|
let mut response_bytes = Vec::with_capacity(wallets.len() * WALLET_REGISTRY_RECORD_BYTES);
|
||||||
for (short_address, public_key) in wallets {
|
for (short_address, public_key) in wallets {
|
||||||
if short_address.len() != Wallet::SHORT_ADDRESS_BYTES_LENGTH
|
if short_address.len() != Wallet::SHORT_ADDRESS_BYTES_LENGTH
|
||||||
|| public_key.len() != Wallet::PUBLIC_KEY_LENGTH
|
|| !Wallet::has_valid_public_key_bytes(&public_key)
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -373,7 +373,7 @@ pub async fn handle_handshake(
|
||||||
}
|
}
|
||||||
|
|
||||||
let received_public_key_bytes = match crate::decode(&received_public_key) {
|
let received_public_key_bytes = match crate::decode(&received_public_key) {
|
||||||
Ok(bytes) if bytes.len() == Wallet::PUBLIC_KEY_LENGTH => bytes,
|
Ok(bytes) if Wallet::has_valid_public_key_bytes(&bytes) => bytes,
|
||||||
_ => {
|
_ => {
|
||||||
drop_failed_handshake(&stream).await;
|
drop_failed_handshake(&stream).await;
|
||||||
return;
|
return;
|
||||||
|
|
|
||||||
|
|
@ -185,7 +185,7 @@ async fn perform_handshake(
|
||||||
// Convert the returned binary fields into the formats used by wallet signature verification.
|
// Convert the returned binary fields into the formats used by wallet signature verification.
|
||||||
let returned_message = encode(returned_message_bin);
|
let returned_message = encode(returned_message_bin);
|
||||||
let returned_signed_message = encode(returned_signed_bin);
|
let returned_signed_message = encode(returned_signed_bin);
|
||||||
if returned_public_key_bin.len() != Wallet::PUBLIC_KEY_LENGTH {
|
if !Wallet::has_valid_public_key_bytes(returned_public_key_bin) {
|
||||||
return Err(io::Error::new(
|
return Err(io::Error::new(
|
||||||
io::ErrorKind::InvalidData,
|
io::ErrorKind::InvalidData,
|
||||||
"Handshake returned an invalid public key",
|
"Handshake returned an invalid public key",
|
||||||
|
|
|
||||||
|
|
@ -431,7 +431,7 @@ async fn build_request_bytes(
|
||||||
format!("Invalid wallet registration public key: {err}"),
|
format!("Invalid wallet registration public key: {err}"),
|
||||||
)
|
)
|
||||||
})?;
|
})?;
|
||||||
if public_key_bytes.len() != Wallet::PUBLIC_KEY_LENGTH {
|
if !Wallet::has_valid_public_key_bytes(&public_key_bytes) {
|
||||||
return Err(io::Error::new(
|
return Err(io::Error::new(
|
||||||
io::ErrorKind::InvalidInput,
|
io::ErrorKind::InvalidInput,
|
||||||
"Invalid wallet registration public key",
|
"Invalid wallet registration public key",
|
||||||
|
|
|
||||||
|
|
@ -4,19 +4,24 @@ use crate::{decode, encode};
|
||||||
|
|
||||||
impl Wallet {
|
impl Wallet {
|
||||||
pub fn generate_keypair(_network_byte: u8) -> (Vec<u8>, String) {
|
pub fn generate_keypair(_network_byte: u8) -> (Vec<u8>, String) {
|
||||||
// Generate a new FN-DSA key pair using the wallet security parameter.
|
loop {
|
||||||
let keypair =
|
// Generate a new FN-DSA key pair using the wallet security parameter.
|
||||||
FnDsaKeyPair::generate(Self::FN_DSA_LOGN).expect("Failed to generate FN-DSA key pair");
|
let keypair = FnDsaKeyPair::generate(Self::FN_DSA_LOGN)
|
||||||
|
.expect("Failed to generate FN-DSA key pair");
|
||||||
|
|
||||||
// Keep the private key as raw bytes until it is hex-encoded for storage.
|
let public_key_bytes = keypair.public_key().to_vec();
|
||||||
let secret_key_bytes = keypair.private_key().to_vec();
|
if !Self::has_valid_public_key_bytes(&public_key_bytes) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
let public_key_bytes = keypair.public_key().to_vec();
|
// Keep the private key as raw bytes until it is hex-encoded for storage.
|
||||||
|
let secret_key_bytes = keypair.private_key().to_vec();
|
||||||
|
|
||||||
// Private keys are persisted as hex before wallet-image encryption.
|
// Private keys are persisted as hex before wallet-image encryption.
|
||||||
let private_key_hex = encode(secret_key_bytes);
|
let private_key_hex = encode(secret_key_bytes);
|
||||||
|
|
||||||
(public_key_bytes, private_key_hex)
|
return (public_key_bytes, private_key_hex);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn regenerate_public_key(private_key_hex: &str) -> Result<Vec<u8>, String> {
|
pub fn regenerate_public_key(private_key_hex: &str) -> Result<Vec<u8>, String> {
|
||||||
|
|
@ -43,6 +48,12 @@ impl Wallet {
|
||||||
.map_err(|e| format!("Failed to decode the provided FN-DSA private key: {e}"))?;
|
.map_err(|e| format!("Failed to decode the provided FN-DSA private key: {e}"))?;
|
||||||
|
|
||||||
let _ = network_byte;
|
let _ = network_byte;
|
||||||
Ok(keypair.public_key().to_vec())
|
let public_key_bytes = keypair.public_key().to_vec();
|
||||||
|
if !Self::has_valid_public_key_bytes(&public_key_bytes) {
|
||||||
|
return Err("FN-DSA public key does not satisfy this network's wallet key rule."
|
||||||
|
.to_string());
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(public_key_bytes)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -15,6 +15,8 @@ pub struct Wallet {
|
||||||
}
|
}
|
||||||
impl Wallet {
|
impl Wallet {
|
||||||
pub const FN_DSA_LOGN: u32 = 9;
|
pub const FN_DSA_LOGN: u32 = 9;
|
||||||
|
pub const REQUIRED_PUBLIC_KEY_PREFIX_BYTE: u8 = 239;
|
||||||
|
pub const REQUIRED_PUBLIC_KEY_PREFIX_INDEX: usize = 1;
|
||||||
pub const PUBLIC_KEY_LENGTH: usize = 897;
|
pub const PUBLIC_KEY_LENGTH: usize = 897;
|
||||||
pub const PRIVATE_KEY_LENGTH: usize = 1281;
|
pub const PRIVATE_KEY_LENGTH: usize = 1281;
|
||||||
pub const SIGNATURE_LENGTH: usize = 666;
|
pub const SIGNATURE_LENGTH: usize = 666;
|
||||||
|
|
|
||||||
|
|
@ -35,7 +35,7 @@ impl Wallet {
|
||||||
|
|
||||||
// Decode and length-check the raw public key bytes.
|
// Decode and length-check the raw public key bytes.
|
||||||
let public_key_bytes = match decode(public_key_hex) {
|
let public_key_bytes = match decode(public_key_hex) {
|
||||||
Ok(bytes) if bytes.len() == Self::PUBLIC_KEY_LENGTH => bytes,
|
Ok(bytes) if Self::has_valid_public_key_bytes(&bytes) => bytes,
|
||||||
_ => return false,
|
_ => return false,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -60,7 +60,7 @@ impl Wallet {
|
||||||
_ => return false,
|
_ => return false,
|
||||||
};
|
};
|
||||||
|
|
||||||
if public_key_bytes.len() != Self::PUBLIC_KEY_LENGTH {
|
if !Self::has_valid_public_key_bytes(public_key_bytes) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,15 @@ impl Wallet {
|
||||||
}
|
}
|
||||||
|
|
||||||
// FN-DSA encoded public keys carry the security parameter in the first byte.
|
// FN-DSA encoded public keys carry the security parameter in the first byte.
|
||||||
public_key_bytes[0] == Self::FN_DSA_LOGN as u8
|
if public_key_bytes[0] != Self::FN_DSA_LOGN as u8 {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// The second public-key byte is chain-specific entropy. This restores
|
||||||
|
// the old key-grinding rule so deterministic seed-derived keys cannot
|
||||||
|
// be imported or registered unless they happen to match the network rule.
|
||||||
|
public_key_bytes[Self::REQUIRED_PUBLIC_KEY_PREFIX_INDEX]
|
||||||
|
== Self::REQUIRED_PUBLIC_KEY_PREFIX_BYTE
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn short_address_validation(short_address: &str) -> bool {
|
pub fn short_address_validation(short_address: &str) -> bool {
|
||||||
|
|
|
||||||
|
|
@ -115,7 +115,7 @@ impl Wallet {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn public_key_bytes_to_short_address_bytes(public_key_bytes: &[u8]) -> Option<Vec<u8>> {
|
pub fn public_key_bytes_to_short_address_bytes(public_key_bytes: &[u8]) -> Option<Vec<u8>> {
|
||||||
if public_key_bytes.len() != Self::PUBLIC_KEY_LENGTH {
|
if !Self::has_valid_public_key_bytes(public_key_bytes) {
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -146,11 +146,14 @@ impl Wallet {
|
||||||
|
|
||||||
pub fn normalize_saved_public_key_bytes(public_key_hex: &str) -> Option<Vec<u8>> {
|
pub fn normalize_saved_public_key_bytes(public_key_hex: &str) -> Option<Vec<u8>> {
|
||||||
let bytes = decode(public_key_hex).ok()?;
|
let bytes = decode(public_key_hex).ok()?;
|
||||||
if bytes.len() == Self::PUBLIC_KEY_LENGTH {
|
if Self::has_valid_public_key_bytes(&bytes) {
|
||||||
return Some(bytes);
|
return Some(bytes);
|
||||||
}
|
}
|
||||||
if bytes.len() == Self::ADDRESS_BYTES_LENGTH && bytes[0] == Self::current_network_byte() {
|
if bytes.len() == Self::ADDRESS_BYTES_LENGTH && bytes[0] == Self::current_network_byte() {
|
||||||
return Some(bytes[1..].to_vec());
|
let public_key_bytes = bytes[1..].to_vec();
|
||||||
|
if Self::has_valid_public_key_bytes(&public_key_bytes) {
|
||||||
|
return Some(public_key_bytes);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue