Skip to content

Commit 08f7067

Browse files
committed
feat: add signMessageWithoutRand method for kaspa wasm
1 parent 3a2bcbb commit 08f7067

File tree

2 files changed

+58
-13
lines changed

2 files changed

+58
-13
lines changed

wallet/core/src/message.rs

+40-13
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,17 @@ pub fn sign_message(msg: &PersonalMessage, privkey: &[u8; 32]) -> Result<Vec<u8>
2626
Ok(sig.to_vec())
2727
}
2828

29+
/// Sign a message with the given private key without random
30+
pub fn sign_message_without_rand(msg: &PersonalMessage, privkey: &[u8; 32]) -> Result<Vec<u8>, Error> {
31+
let hash = calc_personal_message_hash(msg);
32+
33+
let msg = secp256k1::Message::from_digest_slice(hash.as_bytes().as_slice())?;
34+
let schnorr_key = secp256k1::Keypair::from_seckey_slice(secp256k1::SECP256K1, privkey)?;
35+
let sig: [u8; 64] = *secp256k1::SECP256K1.sign_schnorr_no_aux_rand(&msg, &schnorr_key).as_ref();
36+
37+
Ok(sig.to_vec())
38+
}
39+
2940
/// Verifies signed message.
3041
///
3142
/// Produces `Ok(())` if the signature matches the given message and [`secp256k1::Error`]
@@ -72,9 +83,23 @@ mod tests {
7283
0xF9, 0x30, 0x8A, 0x01, 0x92, 0x58, 0xC3, 0x10, 0x49, 0x34, 0x4F, 0x85, 0xF8, 0x9D, 0x52, 0x29, 0xB5, 0x31, 0xC8, 0x45,
7384
0x83, 0x6F, 0x99, 0xB0, 0x86, 0x01, 0xF1, 0x13, 0xBC, 0xE0, 0x36, 0xF9,
7485
])
75-
.unwrap();
86+
.unwrap();
7687

7788
verify_message(&pm, &sign_message(&pm, &privkey).expect("sign_message failed"), &pubkey).expect("verify_message failed");
89+
verify_message(&pm, &sign_message_without_rand(&pm, &privkey).expect("sign_message failed"), &pubkey).expect("verify_message failed");
90+
}
91+
92+
#[test]
93+
fn test_basic_sign_without_rand_twice_should_get_same_signature() {
94+
let pm = PersonalMessage("Hello Kaspa!");
95+
let privkey: [u8; 32] = [
96+
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
97+
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03,
98+
];
99+
100+
let signature = sign_message_without_rand(&pm, &privkey).expect("sign_message failed");
101+
let signature_twice = sign_message_without_rand(&pm, &privkey).expect("sign_message failed");
102+
assert_eq!(signature, signature_twice);
78103
}
79104

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

93118
verify_message(&pm, &sign_message(&pm, &privkey).expect("sign_message failed"), &pubkey).expect("verify_message failed");
119+
verify_message(&pm, &sign_message_without_rand(&pm, &privkey).expect("sign_message failed"), &pubkey).expect("verify_message failed");
94120
}
95121

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

113139
verify_message(&pm, &sign_message(&pm, &privkey).expect("sign_message failed"), &pubkey).expect("verify_message failed");
140+
verify_message(&pm, &sign_message_without_rand(&pm, &privkey).expect("sign_message failed"), &pubkey).expect("verify_message failed");
114141
}
115142

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

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

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

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

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

254281
let sig_result = sign_message_with_aux_rand(&pm, &privkey, &aux_rand).expect("sign_message failed");
255282
assert_eq!(expected_sig, sig_result);

wallet/core/src/wasm/message.rs

+18
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,24 @@ pub fn js_sign_message(value: ISignMessage) -> Result<HexString, Error> {
4141
}
4242
}
4343

44+
/// Signs a message with the given private key without rand
45+
/// @category Message Signing
46+
#[wasm_bindgen(js_name = signMessageWithoutRand)]
47+
pub fn js_sign_message_without_rand(value: ISignMessage) -> Result<HexString, Error> {
48+
if let Some(object) = Object::try_from(&value) {
49+
let private_key = object.cast_into::<PrivateKey>("privateKey")?;
50+
let raw_msg = object.get_string("message")?;
51+
let mut privkey_bytes = [0u8; 32];
52+
privkey_bytes.copy_from_slice(&private_key.secret_bytes());
53+
let pm = PersonalMessage(&raw_msg);
54+
let sig_vec = sign_message_without_rand(&pm, &privkey_bytes)?;
55+
privkey_bytes.zeroize();
56+
Ok(faster_hex::hex_string(sig_vec.as_slice()).into())
57+
} else {
58+
Err(Error::custom("Failed to parse input"))
59+
}
60+
}
61+
4462
#[wasm_bindgen(typescript_custom_section)]
4563
const TS_MESSAGE_TYPES: &'static str = r#"
4664
/**

0 commit comments

Comments
 (0)