Skip to content

Commit 95a3b48

Browse files
committed
Merge branch 'rust-pk'
2 parents 7d3aaf6 + cbb837b commit 95a3b48

File tree

9 files changed

+31
-241
lines changed

9 files changed

+31
-241
lines changed

src/keystore.c

Lines changed: 0 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -614,23 +614,6 @@ bool keystore_get_bip39_word(uint16_t idx, char** word_out)
614614
return bip39_get_word(NULL, idx, word_out) == WALLY_OK;
615615
}
616616

617-
bool keystore_secp256k1_compressed_to_uncompressed(
618-
const uint8_t* pubkey_bytes,
619-
uint8_t* uncompressed_out)
620-
{
621-
const secp256k1_context* ctx = wally_get_secp_context();
622-
secp256k1_pubkey pubkey;
623-
if (!secp256k1_ec_pubkey_parse(ctx, &pubkey, pubkey_bytes, 33)) {
624-
return false;
625-
}
626-
size_t len = 65;
627-
if (!secp256k1_ec_pubkey_serialize(
628-
ctx, uncompressed_out, &len, &pubkey, SECP256K1_EC_UNCOMPRESSED)) {
629-
return false;
630-
}
631-
return true;
632-
}
633-
634617
bool keystore_secp256k1_nonce_commit(
635618
const uint32_t* keypath,
636619
size_t keypath_len,
@@ -843,46 +826,6 @@ USE_RESULT bool keystore_encode_xpub_at_keypath(
843826
WALLY_OK;
844827
}
845828

846-
static void _tagged_hash(const char* tag, const uint8_t* msg, size_t msg_len, uint8_t* hash_out)
847-
{
848-
uint8_t tag_hash[32] = {0};
849-
rust_sha256(tag, strlen(tag), tag_hash);
850-
void* hash_ctx = rust_sha256_new();
851-
rust_sha256_update(hash_ctx, tag_hash, sizeof(tag_hash));
852-
rust_sha256_update(hash_ctx, tag_hash, sizeof(tag_hash));
853-
rust_sha256_update(hash_ctx, msg, msg_len);
854-
rust_sha256_finish(&hash_ctx, hash_out);
855-
}
856-
857-
bool keystore_secp256k1_schnorr_bip86_pubkey(const uint8_t* pubkey33, uint8_t* pubkey_out)
858-
{
859-
const secp256k1_context* ctx = wally_get_secp_context();
860-
861-
secp256k1_pubkey pubkey = {0};
862-
if (!secp256k1_ec_pubkey_parse(ctx, &pubkey, pubkey33, 33)) {
863-
return false;
864-
}
865-
secp256k1_xonly_pubkey xonly_pubkey = {0};
866-
if (!secp256k1_xonly_pubkey_from_pubkey(ctx, &xonly_pubkey, NULL, &pubkey)) {
867-
return false;
868-
}
869-
uint8_t xonly_pubkey_serialized[32] = {0};
870-
if (!secp256k1_xonly_pubkey_serialize(ctx, xonly_pubkey_serialized, &xonly_pubkey)) {
871-
return false;
872-
}
873-
uint8_t hash[32] = {0};
874-
secp256k1_pubkey tweaked_pubkey = {0};
875-
_tagged_hash("TapTweak", xonly_pubkey_serialized, sizeof(xonly_pubkey_serialized), hash);
876-
if (!secp256k1_xonly_pubkey_tweak_add(ctx, &tweaked_pubkey, &xonly_pubkey, hash)) {
877-
return false;
878-
}
879-
secp256k1_xonly_pubkey tweaked_xonly_pubkey = {0};
880-
if (!secp256k1_xonly_pubkey_from_pubkey(ctx, &tweaked_xonly_pubkey, NULL, &tweaked_pubkey)) {
881-
return false;
882-
}
883-
return secp256k1_xonly_pubkey_serialize(ctx, pubkey_out, &tweaked_xonly_pubkey) == 1;
884-
}
885-
886829
static bool _schnorr_keypair(
887830
const uint32_t* keypath,
888831
size_t keypath_len,

src/keystore.h

Lines changed: 2 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@
2424
#include <secp256k1.h>
2525
#include <wally_bip32.h>
2626
#include <wally_bip39.h> // for BIP39_WORDLIST_LEN
27-
#include <wally_crypto.h> // for EC_PUBLIC_KEY_UNCOMPRESSED_LEN and EC_PUBLIC_KEY_LEN
27+
#include <wally_crypto.h> // for EC_PUBLIC_KEY_LEN
2828

2929
#define KEYSTORE_MAX_SEED_LENGTH (32)
3030
#define KEYSTORE_U2F_SEED_LENGTH SHA256_LEN
@@ -160,14 +160,6 @@ void keystore_zero_xkey(struct ext_key* xkey);
160160
*/
161161
USE_RESULT bool keystore_get_bip39_word(uint16_t idx, char** word_out);
162162

163-
// Reformats pubkey from compressed 33 bytes to uncompressed 65 bytes (<0x04><64 bytes X><64 bytes
164-
// Y>),
165-
// pubkey must be 33 bytes
166-
// uncompressed_out must be 65 bytes.
167-
USE_RESULT bool keystore_secp256k1_compressed_to_uncompressed(
168-
const uint8_t* pubkey_bytes,
169-
uint8_t* uncompressed_out);
170-
171163
/**
172164
* Get a commitment to the original nonce before tweaking it with the host nonce. This is part of
173165
* the ECDSA Anti-Klepto Protocol. For more details, check the docs of
@@ -274,23 +266,7 @@ USE_RESULT bool keystore_encode_xpub_at_keypath(
274266
uint8_t* out);
275267

276268
/**
277-
* Return the tweaked taproot pubkey.
278-
*
279-
* Instead of returning the original pubkey directly, it is tweaked with the hash of the pubkey.
280-
*
281-
* See
282-
* https://github.com/bitcoin/bips/blob/edffe529056f6dfd33d8f716fb871467c3c09263/bip-0086.mediawiki#address-derivation
283-
*
284-
* @param[in] pubkey33 33 byte compressed pubkey.
285-
* @param[out] pubkey_out 32 byte x-only pubkey (see BIP-340 for details).
286-
*/
287-
USE_RESULT bool keystore_secp256k1_schnorr_bip86_pubkey(
288-
const uint8_t* pubkey33,
289-
uint8_t* pubkey_out);
290-
291-
/**
292-
* Sign a message that verifies against the pubkey returned by
293-
* `keystore_secp256k1_schnorr_bip86_pubkey()`.
269+
* Sign a message that verifies against the pubkey tweaked using BIP-86.
294270
*
295271
* @param[in] keypath derivation keypath
296272
* @param[in] keypath_len number of elements in keypath

src/rust/bitbox02-rust/src/bip32.rs

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@ use alloc::vec::Vec;
1818

1919
pub use pb::btc_pub_request::XPubType;
2020

21+
use bitcoin::hashes::Hash;
22+
2123
#[derive(Clone)]
2224
pub struct Xpub {
2325
xpub: pb::XPub,
@@ -114,14 +116,17 @@ impl Xpub {
114116

115117
/// Return the hash160 of the secp256k1 public key.
116118
pub fn pubkey_hash160(&self) -> Vec<u8> {
117-
bitbox02::hash160(self.public_key()).to_vec()
119+
bitcoin::hashes::hash160::Hash::hash(self.public_key())
120+
.to_byte_array()
121+
.to_vec()
118122
}
119123

120124
/// Return the 65 byte secp256k1 compressed pubkey:
121125
///
122126
/// (<0x04><64 bytes X><64 bytes Y>).
123127
pub fn pubkey_uncompressed(&self) -> Result<[u8; 65], ()> {
124-
bitbox02::keystore::secp256k1_pubkey_compressed_to_uncompressed(self.public_key())
128+
let pk = bitcoin::secp256k1::PublicKey::from_slice(self.public_key()).map_err(|_| ())?;
129+
Ok(pk.serialize_uncompressed())
125130
}
126131

127132
/// Return the tweaked taproot pubkey.
@@ -132,7 +137,14 @@ impl Xpub {
132137
/// See
133138
/// https://github.com/bitcoin/bips/blob/edffe529056f6dfd33d8f716fb871467c3c09263/bip-0086.mediawiki#address-derivation
134139
pub fn schnorr_bip86_pubkey(&self) -> Result<[u8; 32], ()> {
135-
bitbox02::keystore::secp256k1_schnorr_bip86_pubkey(self.public_key())
140+
use bitcoin::key::TapTweak;
141+
let untweaked_pubkey: bitcoin::key::UntweakedPublicKey =
142+
bitcoin::key::PublicKey::from_slice(self.public_key())
143+
.map_err(|_| ())?
144+
.into();
145+
let secp = bitcoin::secp256k1::Secp256k1::new();
146+
let (tweaked, _) = untweaked_pubkey.tap_tweak(&secp, None);
147+
Ok(tweaked.serialize())
136148
}
137149
}
138150

src/rust/bitbox02-rust/src/hww/api/bitcoin/common.rs

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,8 @@ use super::{multisig, params::Params, script};
2929

3030
use sha2::{Digest, Sha256};
3131

32+
use bitcoin::hashes::Hash;
33+
3234
const HASH160_LEN: usize = 20;
3335
const SHA256_LEN: usize = 32;
3436

@@ -92,7 +94,9 @@ impl Payload {
9294
Payload::from_simple(xpub_cache, params, SimpleType::P2wpkh, keypath)?;
9395
let pkscript_p2wpkh = payload_p2wpkh.pk_script(params)?;
9496
Ok(Payload {
95-
data: bitbox02::hash160(&pkscript_p2wpkh).to_vec(),
97+
data: bitcoin::hashes::hash160::Hash::hash(&pkscript_p2wpkh)
98+
.to_byte_array()
99+
.to_vec(),
96100
output_type: BtcOutputType::P2sh,
97101
})
98102
}
@@ -140,7 +144,9 @@ impl Payload {
140144
pb::btc_script_config::multisig::ScriptType::P2wshP2sh => {
141145
let pkscript_p2wsh = payload_p2wsh.pk_script(params)?;
142146
Ok(Payload {
143-
data: bitbox02::hash160(&pkscript_p2wsh).to_vec(),
147+
data: bitcoin::hashes::hash160::Hash::hash(&pkscript_p2wsh)
148+
.to_byte_array()
149+
.to_vec(),
144150
output_type: BtcOutputType::P2sh,
145151
})
146152
}

src/rust/bitbox02-sys/build.rs

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,6 @@ const ALLOWLIST_VARS: &[&str] = &[
2222
"BIP32_SERIALIZED_LEN",
2323
"BIP39_WORDLIST_LEN",
2424
"EC_PUBLIC_KEY_LEN",
25-
"EC_PUBLIC_KEY_UNCOMPRESSED_LEN",
2625
"INPUT_STRING_MAX_SIZE",
2726
"KEYSTORE_MAX_SEED_LENGTH",
2827
"MAX_LABEL_SIZE",
@@ -73,10 +72,8 @@ const ALLOWLIST_FNS: &[&str] = &[
7372
"keystore_is_locked",
7473
"keystore_lock",
7574
"keystore_mock_unlocked",
76-
"keystore_secp256k1_compressed_to_uncompressed",
7775
"keystore_secp256k1_get_private_key",
7876
"keystore_secp256k1_nonce_commit",
79-
"keystore_secp256k1_schnorr_bip86_pubkey",
8077
"keystore_secp256k1_schnorr_sign",
8178
"keystore_secp256k1_sign",
8279
"keystore_unlock",
@@ -141,7 +138,6 @@ const ALLOWLIST_FNS: &[&str] = &[
141138
"util_format_datetime",
142139
"wally_free_string",
143140
"wally_get_secp_context",
144-
"wally_hash160",
145141
"wally_sha512",
146142
];
147143

src/rust/bitbox02/src/keystore.rs

Lines changed: 0 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,6 @@ use core::convert::TryInto;
2222
use bitbox02_sys::keystore_error_t;
2323

2424
pub const BIP39_WORDLIST_LEN: u16 = bitbox02_sys::BIP39_WORDLIST_LEN as u16;
25-
pub const EC_PUBLIC_KEY_UNCOMPRESSED_LEN: usize = bitbox02_sys::EC_PUBLIC_KEY_UNCOMPRESSED_LEN as _;
2625
pub const EC_PUBLIC_KEY_LEN: usize = bitbox02_sys::EC_PUBLIC_KEY_LEN as _;
2726
pub const MAX_SEED_LENGTH: usize = bitbox02_sys::KEYSTORE_MAX_SEED_LENGTH as usize;
2827

@@ -200,21 +199,6 @@ pub fn get_bip39_wordlist(indices: Option<&[u16]>) -> Bip39Wordlist {
200199
)
201200
}
202201

203-
pub fn secp256k1_pubkey_compressed_to_uncompressed(
204-
compressed_pubkey: &[u8],
205-
) -> Result<[u8; EC_PUBLIC_KEY_UNCOMPRESSED_LEN], ()> {
206-
let mut pubkey = [0u8; EC_PUBLIC_KEY_UNCOMPRESSED_LEN];
207-
match unsafe {
208-
bitbox02_sys::keystore_secp256k1_compressed_to_uncompressed(
209-
compressed_pubkey.as_ptr(),
210-
pubkey.as_mut_ptr(),
211-
)
212-
} {
213-
true => Ok(pubkey),
214-
false => Err(()),
215-
}
216-
}
217-
218202
pub fn encode_xpub_at_keypath(keypath: &[u32]) -> Result<Vec<u8>, ()> {
219203
let mut xpub = vec![0u8; bitbox02_sys::BIP32_SERIALIZED_LEN as _];
220204
match unsafe {
@@ -376,19 +360,6 @@ pub fn secp256k1_schnorr_sign(
376360
}
377361
}
378362

379-
pub fn secp256k1_schnorr_bip86_pubkey(pubkey33: &[u8]) -> Result<[u8; 32], ()> {
380-
let mut pubkey = [0u8; 32];
381-
match unsafe {
382-
bitbox02_sys::keystore_secp256k1_schnorr_bip86_pubkey(
383-
pubkey33.as_ptr(),
384-
pubkey.as_mut_ptr(),
385-
)
386-
} {
387-
true => Ok(pubkey),
388-
false => Err(()),
389-
}
390-
}
391-
392363
#[cfg(test)]
393364
mod tests {
394365
use super::*;

src/rust/bitbox02/src/lib.rs

Lines changed: 0 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -217,19 +217,6 @@ pub fn reboot() -> ! {
217217
loop {}
218218
}
219219

220-
pub fn hash160(data: &[u8]) -> [u8; 20] {
221-
let mut out = [0u8; 20];
222-
unsafe {
223-
bitbox02_sys::wally_hash160(
224-
data.as_ptr(),
225-
data.len() as _,
226-
out.as_mut_ptr(),
227-
out.len() as _,
228-
);
229-
}
230-
out
231-
}
232-
233220
#[cfg(feature = "testing")]
234221
pub fn reboot() -> ! {
235222
panic!("reboot called")

test/unit-test/test_keystore.c

Lines changed: 0 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -638,68 +638,6 @@ static void _test_secp256k1_schnorr_sign(void** state)
638638
}
639639
}
640640

641-
static void _test_keystore_secp256k1_schnorr_bip86_pubkey(void** state)
642-
{
643-
// Test vectors from:
644-
// https://github.com/bitcoin/bips/blob/edffe529056f6dfd33d8f716fb871467c3c09263/bip-0086.mediawiki#test-vectors
645-
// Here we only test the creation of the tweaked pubkkey.
646-
_mock_with_mnemonic(
647-
"abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon "
648-
"about",
649-
"");
650-
{
651-
const uint32_t keypath[] = {
652-
86 + BIP32_INITIAL_HARDENED_CHILD,
653-
0 + BIP32_INITIAL_HARDENED_CHILD,
654-
0 + BIP32_INITIAL_HARDENED_CHILD,
655-
0,
656-
0,
657-
};
658-
struct ext_key xpub = {0};
659-
assert_true(keystore_get_xpub(keypath, 5, &xpub));
660-
uint8_t pubkey[32] = {0};
661-
assert_true(keystore_secp256k1_schnorr_bip86_pubkey(xpub.pub_key, pubkey));
662-
const uint8_t expected_pubkey[32] =
663-
"\xa6\x08\x69\xf0\xdb\xcf\x1d\xc6\x59\xc9\xce\xcb\xaf\x80\x50\x13\x5e\xa9\xe8\xcd\xc4"
664-
"\x87\x05\x3f\x1d\xc6\x88\x09\x49\xdc\x68\x4c";
665-
assert_memory_equal(pubkey, expected_pubkey, sizeof(pubkey));
666-
}
667-
{
668-
const uint32_t keypath[] = {
669-
86 + BIP32_INITIAL_HARDENED_CHILD,
670-
0 + BIP32_INITIAL_HARDENED_CHILD,
671-
0 + BIP32_INITIAL_HARDENED_CHILD,
672-
0,
673-
1,
674-
};
675-
struct ext_key xpub = {0};
676-
assert_true(keystore_get_xpub(keypath, 5, &xpub));
677-
uint8_t pubkey[32] = {0};
678-
assert_true(keystore_secp256k1_schnorr_bip86_pubkey(xpub.pub_key, pubkey));
679-
const uint8_t expected_pubkey[32] =
680-
"\xa8\x2f\x29\x94\x4d\x65\xb8\x6a\xe6\xb5\xe5\xcc\x75\xe2\x94\xea\xd6\xc5\x93\x91\xa1"
681-
"\xed\xc5\xe0\x16\xe3\x49\x8c\x67\xfc\x7b\xbb";
682-
assert_memory_equal(pubkey, expected_pubkey, sizeof(pubkey));
683-
}
684-
{
685-
const uint32_t keypath[] = {
686-
86 + BIP32_INITIAL_HARDENED_CHILD,
687-
0 + BIP32_INITIAL_HARDENED_CHILD,
688-
0 + BIP32_INITIAL_HARDENED_CHILD,
689-
1,
690-
0,
691-
};
692-
struct ext_key xpub = {0};
693-
assert_true(keystore_get_xpub(keypath, 5, &xpub));
694-
uint8_t pubkey[32] = {0};
695-
assert_true(keystore_secp256k1_schnorr_bip86_pubkey(xpub.pub_key, pubkey));
696-
const uint8_t expected_pubkey[32] =
697-
"\x88\x2d\x74\xe5\xd0\x57\x2d\x5a\x81\x6c\xef\x00\x41\xa9\x6b\x6c\x1d\xe8\x32\xf6\xf9"
698-
"\x67\x6d\x96\x05\xc4\x4d\x5e\x9a\x97\xd3\xdc";
699-
assert_memory_equal(pubkey, expected_pubkey, sizeof(pubkey));
700-
}
701-
}
702-
703641
static void _test_keystore_secp256k1_schnorr_sign(void** state)
704642
{
705643
_mock_with_mnemonic(
@@ -762,7 +700,6 @@ int main(void)
762700
cmocka_unit_test(_test_keystore_create_and_store_seed),
763701
cmocka_unit_test(_test_keystore_get_ed25519_seed),
764702
cmocka_unit_test(_test_secp256k1_schnorr_sign),
765-
cmocka_unit_test(_test_keystore_secp256k1_schnorr_bip86_pubkey),
766703
cmocka_unit_test(_test_keystore_secp256k1_schnorr_sign),
767704
};
768705
return cmocka_run_group_tests(tests, NULL, NULL);

0 commit comments

Comments
 (0)