Skip to content

Commit

Permalink
Merge commit 'refs/pull/107/head' of github.com:BitBoxSwiss/bitbox02-…
Browse files Browse the repository at this point in the history
…api-go
  • Loading branch information
benma committed Aug 29, 2024
2 parents a8c8337 + b8e2672 commit a9a0733
Show file tree
Hide file tree
Showing 16 changed files with 566 additions and 379 deletions.
25 changes: 23 additions & 2 deletions api/firmware/eth.go
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,22 @@ func (device *Device) handleSignerNonceCommitment(response *messages.ETHResponse
return signature, nil
}

// ETHIdentifyCase identifies the case of the recipient address given as hexadecimal string.
// This function exists as a convenience to potentially help clients to determine the case of the
// recipient address. The output of the function goes to ETHSign and ETHSignEIP1559 as the
// recipientAddressCase parameter, which is forwarded to BitBox02 device to reconstruct the address
// in the correct case(the one that the user enters).
func ETHIdentifyCase(recipientAddress string) messages.ETHAddressCase {
switch {
case strings.ToUpper(recipientAddress) == recipientAddress:
return messages.ETHAddressCase_ETH_ADDRESS_CASE_UPPER
case strings.ToLower(recipientAddress) == recipientAddress:
return messages.ETHAddressCase_ETH_ADDRESS_CASE_LOWER
default:
return messages.ETHAddressCase_ETH_ADDRESS_CASE_MIXED
}
}

// ETHSign signs an ethereum transaction. It returns a 65 byte signature (R, S, and 1 byte recID).
func (device *Device) ETHSign(
chainID uint64,
Expand All @@ -150,7 +166,8 @@ func (device *Device) ETHSign(
gasLimit uint64,
recipient [20]byte,
value *big.Int,
data []byte) ([]byte, error) {
data []byte,
recipientAddressCase messages.ETHAddressCase) ([]byte, error) {
supportsAntiklepto := device.version.AtLeast(semver.NewSemVer(9, 5, 0))

var hostNonceCommitment *messages.AntiKleptoHostNonceCommitment
Expand All @@ -168,6 +185,7 @@ func (device *Device) ETHSign(
if err != nil {
return nil, err
}

request := &messages.ETHRequest{
Request: &messages.ETHRequest_Sign{
Sign: &messages.ETHSignRequest{
Expand All @@ -181,6 +199,7 @@ func (device *Device) ETHSign(
Value: value.Bytes(),
Data: data,
HostNonceCommitment: hostNonceCommitment,
AddressCase: recipientAddressCase,
},
},
}
Expand Down Expand Up @@ -213,7 +232,8 @@ func (device *Device) ETHSignEIP1559(
gasLimit uint64,
recipient [20]byte,
value *big.Int,
data []byte) ([]byte, error) {
data []byte,
recipientAddressCase messages.ETHAddressCase) ([]byte, error) {

if !device.version.AtLeast(semver.NewSemVer(9, 16, 0)) {
return nil, UnsupportedError("9.16.0")
Expand All @@ -237,6 +257,7 @@ func (device *Device) ETHSignEIP1559(
Value: value.Bytes(),
Data: data,
HostNonceCommitment: hostNonceCommitment,
AddressCase: recipientAddressCase,
},
},
}
Expand Down
73 changes: 73 additions & 0 deletions api/firmware/eth_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
package firmware

import (
"math/big"
"testing"

"github.com/BitBoxSwiss/bitbox02-api-go/api/firmware/messages"
Expand Down Expand Up @@ -378,3 +379,75 @@ func TestSimulatorETHSignTypedMessage(t *testing.T) {
require.Len(t, sig, 65)
})
}

func TestSimulatorETHSign(t *testing.T) {
testInitializedSimulators(t, func(t *testing.T, device *Device) {
t.Helper()
chainID := uint64(1)
keypath := []uint32{
44 + hardenedKeyStart,
60 + hardenedKeyStart,
0 + hardenedKeyStart,
0,
10,
}
nonce := uint64(8156)
gasPrice := new(big.Int).SetUint64(6000000000)
gasLimit := uint64(21000)
recipient := [20]byte{0x04, 0xf2, 0x64, 0xcf, 0x34, 0x44, 0x03, 0x13, 0xb4, 0xa0,
0x19, 0x2a, 0x35, 0x28, 0x14, 0xfb, 0xe9, 0x27, 0xb8, 0x85}
value := new(big.Int).SetUint64(530564000000000000)

sig, err := device.ETHSign(
chainID,
keypath,
nonce,
gasPrice,
gasLimit,
recipient,
value,
nil,
messages.ETHAddressCase_ETH_ADDRESS_CASE_MIXED,
)
require.NoError(t, err)

require.Len(t, sig, 65, "The signature should have exactly 65 bytes")
})
}

func TestSimulatorETHSignEIP1559(t *testing.T) {
testInitializedSimulators(t, func(t *testing.T, device *Device) {
t.Helper()
chainID := uint64(1)
keypath := []uint32{
44 + hardenedKeyStart,
60 + hardenedKeyStart,
0 + hardenedKeyStart,
0,
10,
}
nonce := uint64(8156)
maxPriorityFeePerGas := new(big.Int)
maxFeePerGas := new(big.Int).SetUint64(6000000000)
gasLimit := uint64(21000)
recipient := [20]byte{0x04, 0xf2, 0x64, 0xcf, 0x34, 0x44, 0x03, 0x13, 0xb4, 0xa0,
0x19, 0x2a, 0x35, 0x28, 0x14, 0xfb, 0xe9, 0x27, 0xb8, 0x85}
value := new(big.Int).SetUint64(530564000000000000)

sig, err := device.ETHSignEIP1559(
chainID,
keypath,
nonce,
maxPriorityFeePerGas,
maxFeePerGas,
gasLimit,
recipient,
value,
nil,
messages.ETHAddressCase_ETH_ADDRESS_CASE_MIXED,
)
require.NoError(t, err)

require.Len(t, sig, 65, "The signature should have exactly 65 bytes")
})
}
12 changes: 6 additions & 6 deletions api/firmware/messages/antiklepto.pb.go

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

20 changes: 10 additions & 10 deletions api/firmware/messages/backup_commands.pb.go

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

24 changes: 12 additions & 12 deletions api/firmware/messages/bitbox02_system.pb.go

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

Loading

0 comments on commit a9a0733

Please sign in to comment.