Skip to content

Commit

Permalink
feat: add signMessageWithoutRand method for kaspa wasm
Browse files Browse the repository at this point in the history
  • Loading branch information
witter-deland committed Nov 3, 2024
1 parent 3a2bcbb commit 08f7067
Show file tree
Hide file tree
Showing 2 changed files with 58 additions and 13 deletions.
53 changes: 40 additions & 13 deletions wallet/core/src/message.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,17 @@ pub fn sign_message(msg: &PersonalMessage, privkey: &[u8; 32]) -> Result<Vec<u8>
Ok(sig.to_vec())
}

/// Sign a message with the given private key without random
pub fn sign_message_without_rand(msg: &PersonalMessage, privkey: &[u8; 32]) -> Result<Vec<u8>, Error> {
let hash = calc_personal_message_hash(msg);

let msg = secp256k1::Message::from_digest_slice(hash.as_bytes().as_slice())?;
let schnorr_key = secp256k1::Keypair::from_seckey_slice(secp256k1::SECP256K1, privkey)?;
let sig: [u8; 64] = *secp256k1::SECP256K1.sign_schnorr_no_aux_rand(&msg, &schnorr_key).as_ref();

Ok(sig.to_vec())
}

/// Verifies signed message.
///
/// Produces `Ok(())` if the signature matches the given message and [`secp256k1::Error`]
Expand Down Expand Up @@ -72,9 +83,23 @@ mod tests {
0xF9, 0x30, 0x8A, 0x01, 0x92, 0x58, 0xC3, 0x10, 0x49, 0x34, 0x4F, 0x85, 0xF8, 0x9D, 0x52, 0x29, 0xB5, 0x31, 0xC8, 0x45,
0x83, 0x6F, 0x99, 0xB0, 0x86, 0x01, 0xF1, 0x13, 0xBC, 0xE0, 0x36, 0xF9,
])
.unwrap();
.unwrap();

verify_message(&pm, &sign_message(&pm, &privkey).expect("sign_message failed"), &pubkey).expect("verify_message failed");
verify_message(&pm, &sign_message_without_rand(&pm, &privkey).expect("sign_message failed"), &pubkey).expect("verify_message failed");
}

#[test]
fn test_basic_sign_without_rand_twice_should_get_same_signature() {
let pm = PersonalMessage("Hello Kaspa!");
let privkey: [u8; 32] = [
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03,
];

let signature = sign_message_without_rand(&pm, &privkey).expect("sign_message failed");
let signature_twice = sign_message_without_rand(&pm, &privkey).expect("sign_message failed");
assert_eq!(signature, signature_twice);
}

#[test]
Expand All @@ -88,9 +113,10 @@ mod tests {
0xDF, 0xF1, 0xD7, 0x7F, 0x2A, 0x67, 0x1C, 0x5F, 0x36, 0x18, 0x37, 0x26, 0xDB, 0x23, 0x41, 0xBE, 0x58, 0xFE, 0xAE, 0x1D,
0xA2, 0xDE, 0xCE, 0xD8, 0x43, 0x24, 0x0F, 0x7B, 0x50, 0x2B, 0xA6, 0x59,
])
.unwrap();
.unwrap();

verify_message(&pm, &sign_message(&pm, &privkey).expect("sign_message failed"), &pubkey).expect("verify_message failed");
verify_message(&pm, &sign_message_without_rand(&pm, &privkey).expect("sign_message failed"), &pubkey).expect("verify_message failed");
}

#[test]
Expand All @@ -108,9 +134,10 @@ Ut omnis magnam et accusamus earum rem impedit provident eum commodi repellat qu
0xDF, 0xF1, 0xD7, 0x7F, 0x2A, 0x67, 0x1C, 0x5F, 0x36, 0x18, 0x37, 0x26, 0xDB, 0x23, 0x41, 0xBE, 0x58, 0xFE, 0xAE, 0x1D,
0xA2, 0xDE, 0xCE, 0xD8, 0x43, 0x24, 0x0F, 0x7B, 0x50, 0x2B, 0xA6, 0x59,
])
.unwrap();
.unwrap();

verify_message(&pm, &sign_message(&pm, &privkey).expect("sign_message failed"), &pubkey).expect("verify_message failed");
verify_message(&pm, &sign_message_without_rand(&pm, &privkey).expect("sign_message failed"), &pubkey).expect("verify_message failed");
}

#[test]
Expand All @@ -120,14 +147,14 @@ Ut omnis magnam et accusamus earum rem impedit provident eum commodi repellat qu
0xF9, 0x30, 0x8A, 0x01, 0x92, 0x58, 0xC3, 0x10, 0x49, 0x34, 0x4F, 0x85, 0xF8, 0x9D, 0x52, 0x29, 0xB5, 0x31, 0xC8, 0x45,
0x83, 0x6F, 0x99, 0xB0, 0x86, 0x01, 0xF1, 0x13, 0xBC, 0xE0, 0x36, 0xF9,
])
.unwrap();
.unwrap();
let fake_sig: Vec<u8> = [
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
]
.to_vec();
.to_vec();

let verify_result = verify_message(&pm, &fake_sig, &pubkey);
assert!(verify_result.is_err());
Expand All @@ -148,14 +175,14 @@ Ut omnis magnam et accusamus earum rem impedit provident eum commodi repellat qu
0xF9, 0x30, 0x8A, 0x01, 0x92, 0x58, 0xC3, 0x10, 0x49, 0x34, 0x4F, 0x85, 0xF8, 0x9D, 0x52, 0x29, 0xB5, 0x31, 0xC8, 0x45,
0x83, 0x6F, 0x99, 0xB0, 0x86, 0x01, 0xF1, 0x13, 0xBC, 0xE0, 0x36, 0xF9,
])
.unwrap();
.unwrap();
let expected_sig: Vec<u8> = [
0x40, 0xB9, 0xBB, 0x2B, 0xE0, 0xAE, 0x02, 0x60, 0x72, 0x79, 0xED, 0xA6, 0x40, 0x15, 0xA8, 0xD8, 0x6E, 0x37, 0x63, 0x27,
0x91, 0x70, 0x34, 0x0B, 0x82, 0x43, 0xF7, 0xCE, 0x53, 0x44, 0xD7, 0x7A, 0xFF, 0x11, 0x91, 0x59, 0x8B, 0xAF, 0x2F, 0xD2,
0x61, 0x49, 0xCA, 0xC3, 0xB4, 0xB1, 0x2C, 0x2C, 0x43, 0x32, 0x61, 0xC0, 0x08, 0x34, 0xDB, 0x60, 0x98, 0xCB, 0x17, 0x2A,
0xA4, 0x8E, 0xF5, 0x22,
]
.to_vec();
.to_vec();

let sig_result = sign_message_with_aux_rand(&pm, &privkey, &aux_rand).expect("sign_message failed");
assert_eq!(expected_sig, sig_result);
Expand All @@ -178,14 +205,14 @@ Ut omnis magnam et accusamus earum rem impedit provident eum commodi repellat qu
0xDF, 0xF1, 0xD7, 0x7F, 0x2A, 0x67, 0x1C, 0x5F, 0x36, 0x18, 0x37, 0x26, 0xDB, 0x23, 0x41, 0xBE, 0x58, 0xFE, 0xAE, 0x1D,
0xA2, 0xDE, 0xCE, 0xD8, 0x43, 0x24, 0x0F, 0x7B, 0x50, 0x2B, 0xA6, 0x59,
])
.unwrap();
.unwrap();
let expected_sig: Vec<u8> = [
0xEB, 0x9E, 0x8A, 0x3C, 0x54, 0x7E, 0xB9, 0x1B, 0x6A, 0x75, 0x92, 0x64, 0x4F, 0x32, 0x8F, 0x06, 0x48, 0xBD, 0xD2, 0x1A,
0xBA, 0x3C, 0xD4, 0x47, 0x87, 0xD4, 0x29, 0xD4, 0xD7, 0x90, 0xAA, 0x8B, 0x96, 0x27, 0x45, 0x69, 0x1F, 0x3B, 0x47, 0x2E,
0xD8, 0xD6, 0x5F, 0x3B, 0x77, 0x0E, 0xCB, 0x4F, 0x77, 0x7B, 0xD1, 0x7B, 0x1D, 0x30, 0x91, 0x00, 0x91, 0x9B, 0x53, 0xE0,
0xE2, 0x06, 0xB4, 0xC6,
]
.to_vec();
.to_vec();

let sig_result = sign_message_with_aux_rand(&pm, &privkey, &aux_rand).expect("sign_message failed");
assert_eq!(expected_sig, sig_result);
Expand All @@ -208,14 +235,14 @@ Ut omnis magnam et accusamus earum rem impedit provident eum commodi repellat qu
0xDF, 0xF1, 0xD7, 0x7F, 0x2A, 0x67, 0x1C, 0x5F, 0x36, 0x18, 0x37, 0x26, 0xDB, 0x23, 0x41, 0xBE, 0x58, 0xFE, 0xAE, 0x1D,
0xA2, 0xDE, 0xCE, 0xD8, 0x43, 0x24, 0x0F, 0x7B, 0x50, 0x2B, 0xA6, 0x59,
])
.unwrap();
.unwrap();
let expected_sig: Vec<u8> = [
0x81, 0x06, 0x53, 0xD5, 0xF8, 0x02, 0x06, 0xDB, 0x51, 0x96, 0x72, 0x36, 0x2A, 0xDD, 0x6C, 0x98, 0xDA, 0xD3, 0x78, 0x84,
0x4E, 0x5B, 0xA4, 0xD8, 0x9A, 0x22, 0xC9, 0xF0, 0xC7, 0x09, 0x2E, 0x8C, 0xEC, 0xBA, 0x73, 0x4F, 0xFF, 0x79, 0x22, 0xB6,
0x56, 0xB4, 0xBE, 0x3F, 0x4B, 0x1F, 0x09, 0x88, 0x99, 0xC9, 0x5C, 0xB5, 0xC1, 0x02, 0x3D, 0xCE, 0x35, 0x19, 0x20, 0x8A,
0xFA, 0xFB, 0x59, 0xBC,
]
.to_vec();
.to_vec();

let sig_result = sign_message_with_aux_rand(&pm, &privkey, &aux_rand).expect("sign_message failed");
assert_eq!(expected_sig, sig_result);
Expand All @@ -242,14 +269,14 @@ Ut omnis magnam et accusamus earum rem impedit provident eum commodi repellat qu
0xDF, 0xF1, 0xD7, 0x7F, 0x2A, 0x67, 0x1C, 0x5F, 0x36, 0x18, 0x37, 0x26, 0xDB, 0x23, 0x41, 0xBE, 0x58, 0xFE, 0xAE, 0x1D,
0xA2, 0xDE, 0xCE, 0xD8, 0x43, 0x24, 0x0F, 0x7B, 0x50, 0x2B, 0xA6, 0x59,
])
.unwrap();
.unwrap();
let expected_sig: Vec<u8> = [
0x40, 0xCB, 0xBD, 0x39, 0x38, 0x86, 0x7B, 0x10, 0x07, 0x6B, 0xB1, 0x48, 0x35, 0x55, 0x7C, 0x06, 0x2F, 0x5B, 0xF6, 0xA4,
0x68, 0x29, 0x95, 0xFC, 0x8B, 0x0A, 0x1C, 0xD2, 0xED, 0x98, 0x6E, 0xED, 0xAA, 0xA0, 0x0C, 0xFE, 0x04, 0xF6, 0xC9, 0xE5,
0xA9, 0x54, 0x6B, 0x86, 0x07, 0x32, 0xE5, 0xB9, 0x03, 0xCC, 0x82, 0x78, 0x02, 0x28, 0x64, 0x7D, 0x53, 0x75, 0xBE, 0xC3,
0xD2, 0xA4, 0x98, 0x3A,
]
.to_vec();
.to_vec();

let sig_result = sign_message_with_aux_rand(&pm, &privkey, &aux_rand).expect("sign_message failed");
assert_eq!(expected_sig, sig_result);
Expand Down
18 changes: 18 additions & 0 deletions wallet/core/src/wasm/message.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,24 @@ pub fn js_sign_message(value: ISignMessage) -> Result<HexString, Error> {
}
}

/// Signs a message with the given private key without rand
/// @category Message Signing
#[wasm_bindgen(js_name = signMessageWithoutRand)]
pub fn js_sign_message_without_rand(value: ISignMessage) -> Result<HexString, Error> {
if let Some(object) = Object::try_from(&value) {
let private_key = object.cast_into::<PrivateKey>("privateKey")?;
let raw_msg = object.get_string("message")?;
let mut privkey_bytes = [0u8; 32];
privkey_bytes.copy_from_slice(&private_key.secret_bytes());
let pm = PersonalMessage(&raw_msg);
let sig_vec = sign_message_without_rand(&pm, &privkey_bytes)?;
privkey_bytes.zeroize();
Ok(faster_hex::hex_string(sig_vec.as_slice()).into())
} else {
Err(Error::custom("Failed to parse input"))
}
}

#[wasm_bindgen(typescript_custom_section)]
const TS_MESSAGE_TYPES: &'static str = r#"
/**
Expand Down

0 comments on commit 08f7067

Please sign in to comment.