Skip to content

Commit bee412f

Browse files
committed
keystore: port compressed_to_uncompressed to Rust
Since the inclusion of the miniscript feature and rust-miniscript dep, we depend on rust-bitcoin and rust-secp256k1, so we can make use of it instead of manually wrapping secp256k1. This even saves ~300 bytes of binary space.
1 parent 5f96d5e commit bee412f

File tree

6 files changed

+9
-89
lines changed

6 files changed

+9
-89
lines changed

src/keystore.c

Lines changed: 0 additions & 17 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,

src/keystore.h

Lines changed: 1 addition & 9 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

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

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -121,7 +121,8 @@ impl Xpub {
121121
///
122122
/// (<0x04><64 bytes X><64 bytes Y>).
123123
pub fn pubkey_uncompressed(&self) -> Result<[u8; 65], ()> {
124-
bitbox02::keystore::secp256k1_pubkey_compressed_to_uncompressed(self.public_key())
124+
let pk = bitcoin::secp256k1::PublicKey::from_slice(self.public_key()).map_err(|_| ())?;
125+
Ok(pk.serialize_uncompressed())
125126
}
126127

127128
/// Return the tweaked taproot pubkey.

src/rust/bitbox02-sys/build.rs

Lines changed: 0 additions & 2 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,7 +72,6 @@ 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",
7977
"keystore_secp256k1_schnorr_bip86_pubkey",

src/rust/bitbox02/src/keystore.rs

Lines changed: 0 additions & 16 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 {

test/unit-test/test_keystore_functional.c

Lines changed: 6 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -118,7 +118,7 @@ static bool _encode_xpub(const struct ext_key* xpub, char* out, size_t out_len)
118118
rust_util_bytes(bytes, sizeof(bytes)), rust_util_bytes_mut((uint8_t*)out, out_len));
119119
}
120120

121-
static void _check_pubs(const char* expected_xpub, const char* expected_pubkey_uncompressed_hex)
121+
static void _check_pubs(const char* expected_xpub)
122122
{
123123
struct ext_key __attribute__((__cleanup__(keystore_zero_xkey))) xpub_3;
124124
struct ext_key __attribute__((__cleanup__(keystore_zero_xkey))) xpub_5;
@@ -135,19 +135,13 @@ static void _check_pubs(const char* expected_xpub, const char* expected_pubkey_u
135135
char xpub_serialized[120];
136136
assert_true(_encode_xpub(&xpub_3, xpub_serialized, sizeof(xpub_serialized)));
137137
assert_string_equal(xpub_serialized, expected_xpub);
138-
139-
uint8_t pubkey_uncompressed[EC_PUBLIC_KEY_UNCOMPRESSED_LEN];
140-
assert_true(keystore_secp256k1_compressed_to_uncompressed(xpub_5.pub_key, pubkey_uncompressed));
141-
_assert_equal_memory_hex(
142-
pubkey_uncompressed, sizeof(pubkey_uncompressed), expected_pubkey_uncompressed_hex);
143138
}
144139

145140
static void _test_combination(
146141
const char* mnemonic_passphrase,
147142
uint32_t seed_len,
148143
const char* expected_mnemonic,
149144
const char* expected_xpub,
150-
const char* expected_pubkey_uncompressed_hex,
151145
const char* expected_u2f_seed_hex)
152146
{
153147
assert_false(keystore_unlock_bip39(mnemonic_passphrase));
@@ -163,7 +157,7 @@ static void _test_combination(
163157
assert_true(keystore_unlock_bip39(mnemonic_passphrase));
164158
assert_false(keystore_is_locked());
165159
_check_mnemonic(expected_mnemonic);
166-
_check_pubs(expected_xpub, expected_pubkey_uncompressed_hex);
160+
_check_pubs(expected_xpub);
167161

168162
uint8_t u2f_seed[32];
169163
assert_true(keystore_get_u2f_seed(u2f_seed));
@@ -182,18 +176,10 @@ static void _test_fixtures(void** state)
182176
const char* expected_xpub =
183177
"xpub6Cj6NNCGj2CRPHvkuEG1rbW3nrNCAnLjaoTg1P67FCGoahSsbg9WQ7YaMEEP83QDxt2kZ3hTPAPpGdyEZc"
184178
"fAC1C75HfR66UbjpAb39f4PnG";
185-
const char* expected_pubkey_uncompressed_hex =
186-
"0477a44aa9e8c8fb5105ef5ee2394e8aed89ad73fc74361425f06347ecfe326131e1339367ee3cbe877192"
187-
"85a07f774b17eb933ecf0b9b82acebc195226d634244";
188179
const char* expected_u2f_seed_hex =
189180
"4f464a6667ad88eebcd0f02982761e474ee0dd16253160320f49d1d6681745e9";
190181
_test_combination(
191-
mnemonic_passphrase,
192-
seed_len,
193-
expected_mnemonic,
194-
expected_xpub,
195-
expected_pubkey_uncompressed_hex,
196-
expected_u2f_seed_hex);
182+
mnemonic_passphrase, seed_len, expected_mnemonic, expected_xpub, expected_u2f_seed_hex);
197183
}
198184
{
199185
const char* mnemonic_passphrase = "abc";
@@ -204,18 +190,10 @@ static void _test_fixtures(void** state)
204190
const char* expected_xpub =
205191
"xpub6DXBP3HhFdhUTafatEULxfTXUUxDVuCxfa9RAiBU5r6aRgKiABbeBDyqwWWjmKPP1BZvpvVNMbVR5LeHzh"
206192
"QphtLcPZ8jk3MdLBgc2sACJwR";
207-
const char* expected_pubkey_uncompressed_hex =
208-
"044fb66eeefd352b441c86a6200a1e871928a367f5ab5f46566645d01d0534791ae39ff64a7d14d2427297"
209-
"61ebd3829e8536b389dba543cbc48b1d86c01559d27b";
210193
const char* expected_u2f_seed_hex =
211194
"d599da991ad83baaf449c789e2dff1539dd66983b47a1dec1c00ff3f352cccbc";
212195
_test_combination(
213-
mnemonic_passphrase,
214-
seed_len,
215-
expected_mnemonic,
216-
expected_xpub,
217-
expected_pubkey_uncompressed_hex,
218-
expected_u2f_seed_hex);
196+
mnemonic_passphrase, seed_len, expected_mnemonic, expected_xpub, expected_u2f_seed_hex);
219197
}
220198
{
221199
const char* mnemonic_passphrase = "";
@@ -226,18 +204,10 @@ static void _test_fixtures(void** state)
226204
const char* expected_xpub =
227205
"xpub6C7fKxGtTzEVxCC22U2VHx4GpaVy77DzU6KdZ1CLuHgoUGviBMWDc62uoQVxqcRa5RQbMPnffjpwxve18B"
228206
"G81VJhJDXnSpRe5NGKwVpXiAb";
229-
const char* expected_pubkey_uncompressed_hex =
230-
"043113631363e62a07d6a0becafc8063bb311fd1e9e71a6930d995857837642648aba5c743374e19428565"
231-
"80f565c6b929737af5439f65f5333baf1d63c1f986bf";
232207
const char* expected_u2f_seed_hex =
233208
"fb9dc3fb0a17390776df5c3d8f9261bc5fd5df9f00414cee1393e37e0efda7ef";
234209
_test_combination(
235-
mnemonic_passphrase,
236-
seed_len,
237-
expected_mnemonic,
238-
expected_xpub,
239-
expected_pubkey_uncompressed_hex,
240-
expected_u2f_seed_hex);
210+
mnemonic_passphrase, seed_len, expected_mnemonic, expected_xpub, expected_u2f_seed_hex);
241211
}
242212
{
243213
const char* mnemonic_passphrase = "";
@@ -247,18 +217,10 @@ static void _test_fixtures(void** state)
247217
const char* expected_xpub =
248218
"xpub6DLvpzjKpJ8k4xYrWYPmZQkUe9dkG1eRig2v6Jz4iYgo8hcpHWx87gGoCGDaB2cHFZ3ExUfe1jDiMu7Ch6"
249219
"gA4ULCBhvwZj29mHCPYSux3YV";
250-
const char* expected_pubkey_uncompressed_hex =
251-
"04588110a40455d74a3fd439fa2f4c0994cd0dc64644f9e5bc03cc99e7fcfe32eea56cb72d31cb997663b1"
252-
"f62ad12e9c3a24b717064e8db4cc8ca70ac8a98a46a5";
253220
const char* expected_u2f_seed_hex =
254221
"20d68b206aff9667b623a460ce61fc94762de67561d6855ca9a6df7b409b2a54";
255222
_test_combination(
256-
mnemonic_passphrase,
257-
seed_len,
258-
expected_mnemonic,
259-
expected_xpub,
260-
expected_pubkey_uncompressed_hex,
261-
expected_u2f_seed_hex);
223+
mnemonic_passphrase, seed_len, expected_mnemonic, expected_xpub, expected_u2f_seed_hex);
262224
}
263225
}
264226

0 commit comments

Comments
 (0)