Skip to content

Commit

Permalink
bip85: restructure api messages to allow for different bip85 apps
Browse files Browse the repository at this point in the history
For now the same app as before is supported - bip39, but explicit.

The empty message now returns InvalidInput - would have been a
breaking change but the BIP85 API endpoint was never
released (disabled by not activating the app-bip85 Rust feature).

Reason: we want to add another dedicated app number for the generation
of deterministic entropy for the Breez SDK Lightning hot wallet in the
BitBoxApp. This will segregate keys so that BIP85-BIP39 mnemonics
which the user already might use (or will use) are not unintentionally
re-used and made hot in the Lightning wallet.
  • Loading branch information
benma committed Feb 19, 2024
1 parent 1bcb6dd commit f642d65
Show file tree
Hide file tree
Showing 8 changed files with 87 additions and 22 deletions.
4 changes: 2 additions & 2 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -88,8 +88,8 @@ endif()
#
# Versions MUST contain three parts and start with lowercase 'v'.
# Example 'v1.0.0'. They MUST not contain a pre-release label such as '-beta'.
set(FIRMWARE_VERSION "v9.16.0")
set(FIRMWARE_BTC_ONLY_VERSION "v9.16.0")
set(FIRMWARE_VERSION "v9.17.0")
set(FIRMWARE_BTC_ONLY_VERSION "v9.17.0")
set(BOOTLOADER_VERSION "v1.0.5")

find_package(PythonInterp 3.6 REQUIRED)
Expand Down
8 changes: 8 additions & 0 deletions messages/keystore.proto
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
syntax = "proto3";
package shiftcrypto.bitbox02;

import "google/protobuf/empty.proto";

message ElectrumEncryptionKeyRequest {
repeated uint32 keypath = 1;
}
Expand All @@ -13,7 +15,13 @@ message ElectrumEncryptionKeyResponse {
}

message BIP85Request {
oneof app {
google.protobuf.Empty bip39 = 1;
}
}

message BIP85Response {
oneof app {
google.protobuf.Empty bip39 = 1;
}
}
13 changes: 9 additions & 4 deletions py/bitbox02/bitbox02/bitbox02/bitbox02.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@
from bitbox02.communication.generated import common_pb2 as common
from bitbox02.communication.generated import keystore_pb2 as keystore
from bitbox02.communication.generated import antiklepto_pb2 as antiklepto
import google.protobuf.empty_pb2

# pylint: disable=unused-import
# We export it in __init__.py
Expand Down Expand Up @@ -678,13 +679,17 @@ def electrum_encryption_key(self, keypath: Sequence[int]) -> str:
)
return self._msg_query(request).electrum_encryption_key.key

def bip85(self) -> None:
"""Invokes the BIP-85 workflow on the device"""
self._require_atleast(semver.VersionInfo(9, 16, 0))
def bip85_39(self) -> None:
"""Invokes the BIP85-BIP39 workflow on the device"""
self._require_atleast(semver.VersionInfo(9, 17, 0))

# pylint: disable=no-member
request = hww.Request()
request.bip85.CopyFrom(keystore.BIP85Request())
request.bip85.CopyFrom(
keystore.BIP85Request(
bip39=google.protobuf.empty_pb2.Empty(),
)
)
self._msg_query(request)

def enable_mnemonic_passphrase(self) -> None:
Expand Down
19 changes: 10 additions & 9 deletions py/bitbox02/bitbox02/communication/generated/keystore_pb2.py

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

17 changes: 17 additions & 0 deletions py/bitbox02/bitbox02/communication/generated/keystore_pb2.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ isort:skip_file
"""
import builtins
import google.protobuf.descriptor
import google.protobuf.empty_pb2
import google.protobuf.internal.containers
import google.protobuf.message
import typing
Expand Down Expand Up @@ -36,12 +37,28 @@ global___ElectrumEncryptionKeyResponse = ElectrumEncryptionKeyResponse

class BIP85Request(google.protobuf.message.Message):
DESCRIPTOR: google.protobuf.descriptor.Descriptor
BIP39_FIELD_NUMBER: builtins.int
@property
def bip39(self) -> google.protobuf.empty_pb2.Empty: ...
def __init__(self,
*,
bip39: typing.Optional[google.protobuf.empty_pb2.Empty] = ...,
) -> None: ...
def HasField(self, field_name: typing_extensions.Literal["app",b"app","bip39",b"bip39"]) -> builtins.bool: ...
def ClearField(self, field_name: typing_extensions.Literal["app",b"app","bip39",b"bip39"]) -> None: ...
def WhichOneof(self, oneof_group: typing_extensions.Literal["app",b"app"]) -> typing.Optional[typing_extensions.Literal["bip39"]]: ...
global___BIP85Request = BIP85Request

class BIP85Response(google.protobuf.message.Message):
DESCRIPTOR: google.protobuf.descriptor.Descriptor
BIP39_FIELD_NUMBER: builtins.int
@property
def bip39(self) -> google.protobuf.empty_pb2.Empty: ...
def __init__(self,
*,
bip39: typing.Optional[google.protobuf.empty_pb2.Empty] = ...,
) -> None: ...
def HasField(self, field_name: typing_extensions.Literal["app",b"app","bip39",b"bip39"]) -> builtins.bool: ...
def ClearField(self, field_name: typing_extensions.Literal["app",b"app","bip39",b"bip39"]) -> None: ...
def WhichOneof(self, oneof_group: typing_extensions.Literal["app",b"app"]) -> typing.Optional[typing_extensions.Literal["bip39"]]: ...
global___BIP85Response = BIP85Response
6 changes: 3 additions & 3 deletions py/send_message.py
Original file line number Diff line number Diff line change
Expand Up @@ -340,8 +340,8 @@ def _get_electrum_encryption_key(self) -> None:
),
)

def _bip85(self) -> None:
self._device.bip85()
def _bip85_39(self) -> None:
self._device.bip85_39()

def _btc_address(self) -> None:
def address(display: bool) -> str:
Expand Down Expand Up @@ -1391,7 +1391,7 @@ def _menu_init(self) -> None:
("Sign Ethereum Typed Message (EIP-712)", self._sign_eth_typed_message),
("Cardano", self._cardano),
("Show Electrum wallet encryption key", self._get_electrum_encryption_key),
("BIP85", self._bip85),
("BIP85 - BIP39", self._bip85_39),
("Reset Device", self._reset_device),
)
choice = ask_user(choices)
Expand Down
14 changes: 12 additions & 2 deletions src/rust/bitbox02-rust/src/hww/api/bip85.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,19 @@ use crate::workflow::{confirm, menu, mnemonic, status, trinary_input_string};

use alloc::vec::Vec;

/// Processes a BIP-85 API call.
pub async fn process(request: &pb::Bip85Request) -> Result<Response, Error> {
match request.app {
None => Err(Error::InvalidInput),
Some(pb::bip85_request::App::Bip39(())) => Ok(Response::Bip85(pb::Bip85Response {
app: Some(pb::bip85_response::App::Bip39(process_bip39().await?)),
})),
}
}

/// Derives and displays a BIP-39 seed according to BIP-85:
/// https://github.com/bitcoin/bips/blob/master/bip-0085.mediawiki#bip39.
pub async fn process(pb::Bip85Request {}: &pb::Bip85Request) -> Result<Response, Error> {
async fn process_bip39() -> Result<(), Error> {
confirm::confirm(&confirm::Params {
title: "BIP-85",
body: "Derive BIP-39\nmnemonic?",
Expand Down Expand Up @@ -104,5 +114,5 @@ pub async fn process(pb::Bip85Request {}: &pb::Bip85Request) -> Result<Response,

status::status("Finished", true).await;

Ok(Response::Bip85(pb::Bip85Response {}))
Ok(())
}
28 changes: 26 additions & 2 deletions src/rust/bitbox02-rust/src/shiftcrypto.bitbox02.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1512,10 +1512,34 @@ pub struct ElectrumEncryptionKeyResponse {
}
#[allow(clippy::derive_partial_eq_without_eq)]
#[derive(Clone, PartialEq, ::prost::Message)]
pub struct Bip85Request {}
pub struct Bip85Request {
#[prost(oneof = "bip85_request::App", tags = "1")]
pub app: ::core::option::Option<bip85_request::App>,
}
/// Nested message and enum types in `BIP85Request`.
pub mod bip85_request {
#[allow(clippy::derive_partial_eq_without_eq)]
#[derive(Clone, PartialEq, ::prost::Oneof)]
pub enum App {
#[prost(message, tag = "1")]
Bip39(()),
}
}
#[allow(clippy::derive_partial_eq_without_eq)]
#[derive(Clone, PartialEq, ::prost::Message)]
pub struct Bip85Response {}
pub struct Bip85Response {
#[prost(oneof = "bip85_response::App", tags = "1")]
pub app: ::core::option::Option<bip85_response::App>,
}
/// Nested message and enum types in `BIP85Response`.
pub mod bip85_response {
#[allow(clippy::derive_partial_eq_without_eq)]
#[derive(Clone, PartialEq, ::prost::Oneof)]
pub enum App {
#[prost(message, tag = "1")]
Bip39(()),
}
}
#[allow(clippy::derive_partial_eq_without_eq)]
#[derive(Clone, PartialEq, ::prost::Message)]
pub struct ShowMnemonicRequest {}
Expand Down

0 comments on commit f642d65

Please sign in to comment.