Skip to content

Commit d604361

Browse files
committed
Merge branch 'sim'
2 parents 546fc04 + c71efc6 commit d604361

18 files changed

+797
-67
lines changed

.github/workflows/ci.yml

+16-10
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,9 @@ jobs:
1111
runs-on: ubuntu-22.04
1212
steps:
1313
- name: Clone the repo
14-
uses: actions/checkout@v3
14+
uses: actions/checkout@v4
1515
- name: Enable caching
16-
uses: actions/cache@v3
16+
uses: actions/cache@v4
1717
with:
1818
# Increment cache number to invalidate.
1919
key: ${{runner.os}}-cache-1
@@ -22,7 +22,7 @@ jobs:
2222
~/.cache/go-build
2323
~/.cache/golangci-lint
2424
- name: Install Go
25-
uses: actions/setup-go@v3
25+
uses: actions/setup-go@v4
2626
with:
2727
go-version: ${{env.GO_VERSION}}
2828
# Keep the linter version and its config in .golangci.yml in sync with the app repo at
@@ -37,31 +37,37 @@ jobs:
3737
runs-on: ubuntu-22.04
3838
steps:
3939
- name: Clone the repo
40-
uses: actions/checkout@v3
40+
uses: actions/checkout@v4
4141
- name: Enable caching
42-
uses: actions/cache@v3
42+
uses: actions/cache@v4
4343
with:
4444
# Increment cache number to invalidate.
4545
key: ${{runner.os}}-cache-1
4646
path: |
4747
~/go/pkg
4848
~/.cache/go-build
4949
~/.cache/golangci-lint
50+
- name: Enable simulators caching
51+
uses: actions/cache@v4
52+
with:
53+
key: ${{runner.os}}-simulators-cache-${{hashFiles('./api/firmware/testdata/simulators.json')}}
54+
path: |
55+
./api/firmware/testdata/simulators
5056
- name: Install Go
51-
uses: actions/setup-go@v3
57+
uses: actions/setup-go@v4
5258
with:
5359
go-version: ${{env.GO_VERSION}}
5460
- name: Test
5561
run: |
5662
go version
57-
go test ./...
63+
go test ./... -v
5864
build:
5965
runs-on: ubuntu-22.04
6066
steps:
6167
- name: Clone the repo
62-
uses: actions/checkout@v3
68+
uses: actions/checkout@v4
6369
- name: Enable caching
64-
uses: actions/cache@v3
70+
uses: actions/cache@v4
6571
with:
6672
# Increment cache number to invalidate.
6773
key: ${{runner.os}}-cache-1
@@ -70,7 +76,7 @@ jobs:
7076
~/.cache/go-build
7177
~/.cache/golangci-lint
7278
- name: Install Go
73-
uses: actions/setup-go@v3
79+
uses: actions/setup-go@v4
7480
with:
7581
go-version: ${{env.GO_VERSION}}
7682
- name: Build

api/bootloader/device_test.go

+4-4
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ import (
1919
"encoding/hex"
2020
"errors"
2121
"fmt"
22-
"io/ioutil"
22+
"os"
2323
"testing"
2424

2525
"github.com/BitBoxSwiss/bitbox02-api-go/api/bootloader"
@@ -184,7 +184,7 @@ func TestGetHashes(t *testing.T) {
184184

185185
// TestSignedFirmwareVersion tests device.SignedFirmwareVersion.
186186
func TestSignedFirmwareVersion(t *testing.T) {
187-
signedFirmware, err := ioutil.ReadFile("testdata/firmware-btc.v4.2.2.signed.bin")
187+
signedFirmware, err := os.ReadFile("testdata/firmware-btc.v4.2.2.signed.bin")
188188
if err != nil {
189189
panic(err)
190190
}
@@ -209,11 +209,11 @@ func TestSignedFirmwareVersion(t *testing.T) {
209209
// TestUpgradeFirmware tests a successful firmware upgrade with a real-world signed firmware
210210
// fixture.
211211
func TestUpgradeFirmware(t *testing.T) {
212-
signedFirmware, err := ioutil.ReadFile("testdata/firmware-btc.v4.2.2.signed.bin")
212+
signedFirmware, err := os.ReadFile("testdata/firmware-btc.v4.2.2.signed.bin")
213213
if err != nil {
214214
panic(err)
215215
}
216-
unsignedFirmware, err := ioutil.ReadFile("testdata/firmware-btc.v4.2.2.bin")
216+
unsignedFirmware, err := os.ReadFile("testdata/firmware-btc.v4.2.2.bin")
217217
if err != nil {
218218
panic(err)
219219
}

api/bootloader/util_test.go

+4-4
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ package bootloader
1616

1717
import (
1818
"encoding/hex"
19-
"io/ioutil"
19+
"os"
2020
"testing"
2121

2222
"github.com/BitBoxSwiss/bitbox02-api-go/api/common"
@@ -27,7 +27,7 @@ func TestHashFirmware(t *testing.T) {
2727
emptyHash := []byte("\xad\x27\x67\x91\x84\x74\xf3\x30\x02\x95\xb2\xef\x94\x9a\xe8\x13\xd7\x87\x0c\xed\x70\x30\x58\x29\xa0\x12\x91\xa4\x8f\x8b\xbc\x78")
2828
require.Equal(t, emptyHash, HashFirmware(5, []byte{}))
2929

30-
unsignedFirmware, err := ioutil.ReadFile("testdata/firmware-btc.v4.2.2.bin")
30+
unsignedFirmware, err := os.ReadFile("testdata/firmware-btc.v4.2.2.bin")
3131
require.NoError(t, err)
3232
require.Equal(t,
3333
[]byte("\x9a\xfc\x65\xa1\x99\x6c\x0d\xfd\xbb\x17\x08\xbf\x51\x8d\x96\x8c\xde\xc7\xe3\xc3\x52\x56\x1e\x2b\x09\x1d\x91\x83\x6c\x06\x8a\xe5"),
@@ -36,10 +36,10 @@ func TestHashFirmware(t *testing.T) {
3636
}
3737

3838
func TestParseSignedFirmmare(t *testing.T) {
39-
unsignedFirmware, err := ioutil.ReadFile("testdata/firmware-btc.v4.2.2.bin")
39+
unsignedFirmware, err := os.ReadFile("testdata/firmware-btc.v4.2.2.bin")
4040
require.NoError(t, err)
4141

42-
signedFirmware, err := ioutil.ReadFile("testdata/firmware-btc.v4.2.2.signed.bin")
42+
signedFirmware, err := os.ReadFile("testdata/firmware-btc.v4.2.2.signed.bin")
4343
require.NoError(t, err)
4444

4545
product, sigData, firmware, err := ParseSignedFirmware(signedFirmware)

api/firmware/backup_test.go

+59
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
// Copyright 2024 Shift Crypto AG
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
package firmware
16+
17+
import (
18+
"testing"
19+
20+
"github.com/stretchr/testify/require"
21+
)
22+
23+
func TestSimulatorBackups(t *testing.T) {
24+
const seedLen = 32
25+
const testName = "test wallet name"
26+
testSimulatorsAfterPairing(t, func(t *testing.T, device *Device) {
27+
t.Helper()
28+
require.NoError(t, device.SetDeviceName(testName))
29+
30+
require.NoError(t, device.SetPassword(seedLen))
31+
require.Equal(t, StatusSeeded, device.Status())
32+
33+
list, err := device.ListBackups()
34+
require.NoError(t, err)
35+
require.Empty(t, list)
36+
37+
_, err = device.CheckBackup(true)
38+
require.Error(t, err)
39+
40+
require.NoError(t, device.CreateBackup())
41+
require.Equal(t, StatusInitialized, device.Status())
42+
43+
list, err = device.ListBackups()
44+
require.NoError(t, err)
45+
require.Len(t, list, 1)
46+
require.Equal(t, testName, list[0].Name)
47+
48+
id, err := device.CheckBackup(true)
49+
require.NoError(t, err)
50+
require.Equal(t, list[0].ID, id)
51+
52+
require.Error(t, device.RestoreBackup(list[0].ID))
53+
require.NoError(t, device.Reset())
54+
require.NoError(t, device.RestoreBackup(list[0].ID))
55+
id, err = device.CheckBackup(true)
56+
require.NoError(t, err)
57+
require.Equal(t, list[0].ID, id)
58+
})
59+
}

api/firmware/bip85_test.go

+38
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
// Copyright 2024 Shift Crypto AG
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
package firmware
16+
17+
import (
18+
"encoding/hex"
19+
"testing"
20+
21+
"github.com/stretchr/testify/require"
22+
)
23+
24+
func TestSimulatorBIP85AppBip39(t *testing.T) {
25+
// Can't test this yet as the simulator panics at trinary_choice (12, 18, 24 word choice).
26+
t.Skip()
27+
}
28+
29+
func TestSimulatorBIP85AppLN(t *testing.T) {
30+
testInitializedSimulators(t, func(t *testing.T, device *Device) {
31+
t.Helper()
32+
entropy, err := device.BIP85AppLN()
33+
require.NoError(t, err)
34+
require.Equal(t,
35+
"d05448562b8b64994b7de7eac43cdc8a",
36+
hex.EncodeToString(entropy))
37+
})
38+
}

api/firmware/btc_test.go

+89-2
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
// Copyright 2018-2019 Shift Cryptosecurity AG
2+
// Copyright 2024 Shift Crypto AG
23
//
34
// Licensed under the Apache License, Version 2.0 (the "License");
45
// you may not use this file except in compliance with the License.
@@ -20,12 +21,26 @@ import (
2021

2122
"github.com/BitBoxSwiss/bitbox02-api-go/api/firmware/messages"
2223
"github.com/BitBoxSwiss/bitbox02-api-go/util/semver"
24+
"github.com/btcsuite/btcd/btcec/v2"
25+
"github.com/btcsuite/btcd/btcec/v2/ecdsa"
26+
"github.com/btcsuite/btcd/btcutil/hdkeychain"
27+
"github.com/btcsuite/btcd/chaincfg/chainhash"
2328
"github.com/stretchr/testify/require"
2429
"google.golang.org/protobuf/proto"
2530
)
2631

2732
const hardenedKeyStart = 0x80000000
2833

34+
func parseECDSASignature(t *testing.T, sig []byte) *ecdsa.Signature {
35+
t.Helper()
36+
require.Len(t, sig, 64)
37+
r := new(btcec.ModNScalar)
38+
r.SetByteSlice(sig[:32])
39+
s := new(btcec.ModNScalar)
40+
s.SetByteSlice(sig[32:])
41+
return ecdsa.NewSignature(r, s)
42+
}
43+
2944
func TestNewXPub(t *testing.T) {
3045
xpub, err := NewXPub(
3146
"xpub6FEZ9Bv73h1vnE4TJG4QFj2RPXJhhsPbnXgFyH3ErLvpcZrDcynY65bhWga8PazWHLSLi23PoBhGcLcYW6JRiJ12zXZ9Aop4LbAqsS3gtcy")
@@ -39,7 +54,79 @@ func TestNewXPub(t *testing.T) {
3954
}, xpub)
4055
}
4156

42-
func TestBTCXPub(t *testing.T) {
57+
func TestBTCXpub(t *testing.T) {
58+
testInitializedSimulators(t, func(t *testing.T, device *Device) {
59+
t.Helper()
60+
xpub, err := device.BTCXPub(messages.BTCCoin_TBTC, []uint32{
61+
49 + hardenedKeyStart,
62+
1 + hardenedKeyStart,
63+
0 + hardenedKeyStart,
64+
}, messages.BTCPubRequest_YPUB, false)
65+
require.NoError(t, err)
66+
require.Equal(t, "ypub6WqXiL3fbDK5QNPe3hN4uSVkEvuE8wXoNCcecgggSuKVpU3Kc4fTvhuLgUhtnbAdaTb9gpz5PQdvzcsKPTLgW2CPkF5ZNRzQeKFT4NSc1xN", xpub)
67+
})
68+
}
69+
70+
func TestBTCAddress(t *testing.T) {
71+
testInitializedSimulators(t, func(t *testing.T, device *Device) {
72+
t.Helper()
73+
address, err := device.BTCAddress(
74+
messages.BTCCoin_TBTC,
75+
[]uint32{
76+
84 + hardenedKeyStart,
77+
1 + hardenedKeyStart,
78+
0 + hardenedKeyStart,
79+
1,
80+
10,
81+
},
82+
NewBTCScriptConfigSimple(messages.BTCScriptConfig_P2WPKH),
83+
false,
84+
)
85+
require.NoError(t, err)
86+
require.Equal(t, "tb1qq064dxjgl9h9wzgsmzy6t6306qew42w9ka02u3", address)
87+
})
88+
}
89+
90+
func parseXPub(t *testing.T, xpubStr string, keypath ...uint32) *hdkeychain.ExtendedKey {
91+
t.Helper()
92+
xpub, err := hdkeychain.NewKeyFromString(xpubStr)
93+
require.NoError(t, err)
94+
95+
for _, child := range keypath {
96+
xpub, err = xpub.Derive(child)
97+
require.NoError(t, err)
98+
}
99+
return xpub
100+
}
101+
102+
func TestSimulatorBTCSignMessage(t *testing.T) {
103+
testInitializedSimulators(t, func(t *testing.T, device *Device) {
104+
t.Helper()
105+
coin := messages.BTCCoin_BTC
106+
accountKeypath := []uint32{49 + hardenedKeyStart, 0 + hardenedKeyStart, 0 + hardenedKeyStart}
107+
108+
xpubStr, err := device.BTCXPub(coin, accountKeypath, messages.BTCPubRequest_XPUB, false)
109+
require.NoError(t, err)
110+
111+
xpub := parseXPub(t, xpubStr, 0, 10)
112+
pubKey, err := xpub.ECPubKey()
113+
require.NoError(t, err)
114+
115+
sig, _, _, err := device.BTCSignMessage(
116+
coin,
117+
&messages.BTCScriptConfigWithKeypath{
118+
ScriptConfig: NewBTCScriptConfigSimple(messages.BTCScriptConfig_P2WPKH_P2SH),
119+
Keypath: append(accountKeypath, 0, 10),
120+
},
121+
[]byte("message"),
122+
)
123+
require.NoError(t, err)
124+
sigHash := chainhash.DoubleHashB([]byte("\x18Bitcoin Signed Message:\n\x07message"))
125+
require.True(t, parseECDSASignature(t, sig).Verify(sigHash, pubKey))
126+
})
127+
}
128+
129+
func TestSimulatorBTCXPub(t *testing.T) {
43130
testConfigurations(t, func(t *testing.T, env *testEnv) {
44131
t.Helper()
45132
expected := "mocked-xpub"
@@ -110,7 +197,7 @@ func TestBTCXPub(t *testing.T) {
110197
})
111198
}
112199

113-
func TestBTCAddress(t *testing.T) {
200+
func TestSimulatorBTCAddress(t *testing.T) {
114201
testConfigurations(t, func(t *testing.T, env *testEnv) {
115202
t.Helper()
116203
expected := "mocked-address"

0 commit comments

Comments
 (0)