mirror of
https://github.com/trezor/trezor-firmware.git
synced 2024-11-12 18:49:07 +00:00
add more checks for improbable cases; rework gui testing app
This commit is contained in:
parent
b9ed9a9cd4
commit
8820ae9873
1
.gitignore
vendored
1
.gitignore
vendored
@ -3,3 +3,4 @@
|
||||
*~
|
||||
test-openssl
|
||||
tests
|
||||
build-*/
|
||||
|
46
bip32.c
46
bip32.c
@ -31,27 +31,38 @@
|
||||
#include "ripemd160.h"
|
||||
#include "base58.h"
|
||||
|
||||
void hdnode_from_xpub(uint32_t depth, uint32_t fingerprint, uint32_t child_num, uint8_t *chain_code, uint8_t *public_key, HDNode *out)
|
||||
int hdnode_from_xpub(uint32_t depth, uint32_t fingerprint, uint32_t child_num, uint8_t *chain_code, uint8_t *public_key, HDNode *out)
|
||||
{
|
||||
curve_point c;
|
||||
if (!ecdsa_read_pubkey(public_key, &c)) { // invalid pubkey
|
||||
return 0;
|
||||
}
|
||||
out->depth = depth;
|
||||
out->fingerprint = fingerprint;
|
||||
out->child_num = child_num;
|
||||
memcpy(out->chain_code, chain_code, 32);
|
||||
memset(out->private_key, 0, 32);
|
||||
memcpy(out->public_key, public_key, 33);
|
||||
return 1;
|
||||
}
|
||||
|
||||
void hdnode_from_xprv(uint32_t depth, uint32_t fingerprint, uint32_t child_num, uint8_t *chain_code, uint8_t *private_key, HDNode *out)
|
||||
int hdnode_from_xprv(uint32_t depth, uint32_t fingerprint, uint32_t child_num, uint8_t *chain_code, uint8_t *private_key, HDNode *out)
|
||||
{
|
||||
bignum256 a;
|
||||
bn_read_be(private_key, &a);
|
||||
if (bn_is_zero(&a) || !bn_is_less(&a, &order256k1)) { // == 0 or >= order
|
||||
return 0;
|
||||
}
|
||||
out->depth = depth;
|
||||
out->fingerprint = fingerprint;
|
||||
out->child_num = child_num;
|
||||
memcpy(out->chain_code, chain_code, 32);
|
||||
memcpy(out->private_key, private_key, 32);
|
||||
hdnode_fill_public_key(out);
|
||||
return 1;
|
||||
}
|
||||
|
||||
void hdnode_from_seed(uint8_t *seed, int seed_len, HDNode *out)
|
||||
int hdnode_from_seed(uint8_t *seed, int seed_len, HDNode *out)
|
||||
{
|
||||
uint8_t I[32 + 32];
|
||||
memset(out, 0, sizeof(HDNode));
|
||||
@ -59,9 +70,15 @@ void hdnode_from_seed(uint8_t *seed, int seed_len, HDNode *out)
|
||||
out->fingerprint = 0x00000000;
|
||||
out->child_num = 0;
|
||||
hmac_sha512((uint8_t *)"Bitcoin seed", 12, seed, seed_len, I);
|
||||
memcpy(out->chain_code, I + 32, 32);
|
||||
memcpy(out->private_key, I, 32);
|
||||
bignum256 a;
|
||||
bn_read_be(out->private_key, &a);
|
||||
if (bn_is_zero(&a) || !bn_is_less(&a, &order256k1)) { // == 0 or >= order
|
||||
return 0;
|
||||
}
|
||||
memcpy(out->chain_code, I + 32, 32);
|
||||
hdnode_fill_public_key(out);
|
||||
return 1;
|
||||
}
|
||||
|
||||
int hdnode_private_ckd(HDNode *inout, uint32_t i)
|
||||
@ -90,8 +107,17 @@ int hdnode_private_ckd(HDNode *inout, uint32_t i)
|
||||
memcpy(inout->private_key, I, 32);
|
||||
|
||||
bn_read_be(inout->private_key, &b);
|
||||
|
||||
if (!bn_is_less(&b, &order256k1)) { // >= order
|
||||
return 0;
|
||||
}
|
||||
|
||||
bn_addmod(&a, &b, &order256k1);
|
||||
|
||||
if (bn_is_zero(&a)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
inout->depth++;
|
||||
inout->child_num = i;
|
||||
bn_write_be(&a, inout->private_key);
|
||||
@ -128,8 +154,20 @@ int hdnode_public_ckd(HDNode *inout, uint32_t i)
|
||||
hmac_sha512(inout->chain_code, 32, data, sizeof(data), I);
|
||||
memcpy(inout->chain_code, I + 32, 32);
|
||||
bn_read_be(I, &c);
|
||||
|
||||
if (!bn_is_less(&c, &order256k1)) { // >= order
|
||||
return 0;
|
||||
}
|
||||
|
||||
scalar_multiply(&c, &b); // b = c * G
|
||||
point_add(&a, &b); // b = a + b
|
||||
|
||||
#if USE_PUBKEY_VALIDATE
|
||||
if (!ecdsa_validate_pubkey(&b)) {
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
inout->public_key[0] = 0x02 | (b.y.val[0] & 0x01);
|
||||
bn_write_be(&b.x, inout->public_key + 1);
|
||||
|
||||
|
6
bip32.h
6
bip32.h
@ -35,11 +35,11 @@ typedef struct {
|
||||
uint8_t public_key[33];
|
||||
} HDNode;
|
||||
|
||||
void hdnode_from_xpub(uint32_t depth, uint32_t fingerprint, uint32_t child_num, uint8_t *chain_code, uint8_t *public_key, HDNode *out);
|
||||
int hdnode_from_xpub(uint32_t depth, uint32_t fingerprint, uint32_t child_num, uint8_t *chain_code, uint8_t *public_key, HDNode *out);
|
||||
|
||||
void hdnode_from_xprv(uint32_t depth, uint32_t fingerprint, uint32_t child_num, uint8_t *chain_code, uint8_t *private_key, HDNode *out);
|
||||
int hdnode_from_xprv(uint32_t depth, uint32_t fingerprint, uint32_t child_num, uint8_t *chain_code, uint8_t *private_key, HDNode *out);
|
||||
|
||||
void hdnode_from_seed(uint8_t *seed, int seed_len, HDNode *out);
|
||||
int hdnode_from_seed(uint8_t *seed, int seed_len, HDNode *out);
|
||||
|
||||
#define hdnode_private_ckd_prime(X, I) hdnode_private_ckd((X), ((I) | 0x80000000))
|
||||
|
||||
|
@ -7,6 +7,7 @@ extern "C" {
|
||||
#include "../ecdsa.h"
|
||||
}
|
||||
|
||||
bool root_set = false;
|
||||
HDNode root;
|
||||
|
||||
MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWindow)
|
||||
@ -28,7 +29,6 @@ MainWindow::~MainWindow()
|
||||
|
||||
void MainWindow::on_buttonLoad_clicked()
|
||||
{
|
||||
ui->listAccount->clear();
|
||||
if (!mnemonic_check(ui->editMnemonic->text().toLocal8Bit().data())) {
|
||||
QMessageBox::critical(this, "Error", "Text is not a valid BIP39 mnemonic.", QMessageBox::Ok);
|
||||
return;
|
||||
@ -36,22 +36,26 @@ void MainWindow::on_buttonLoad_clicked()
|
||||
uint8_t seed[64];
|
||||
mnemonic_to_seed(ui->editMnemonic->text().toLocal8Bit().data(), ui->editPassphrase->text().toLocal8Bit().data(), seed, 0);
|
||||
hdnode_from_seed(seed, 64, &root);
|
||||
for (int i = 1; i <= 10; i++) {
|
||||
ui->listAccount->addItem(QString("Account #") + QString::number(i));
|
||||
}
|
||||
root_set = true;
|
||||
ui->spinAccount->setValue(1);
|
||||
on_spinAccount_valueChanged(1);
|
||||
}
|
||||
|
||||
void MainWindow::on_listAccount_clicked(const QModelIndex &index)
|
||||
void MainWindow::on_spinAccount_valueChanged(int arg1)
|
||||
{
|
||||
if (!root_set) return;
|
||||
const char addr_version = 0x00, wif_version = 0x80;
|
||||
char buf[64];
|
||||
char buf[128];
|
||||
HDNode node;
|
||||
// external chain
|
||||
for (int chain = 0; chain < 2; chain++) {
|
||||
QTableWidget *list = chain == 0 ? ui->listAddress : ui->listChange;
|
||||
node = root;
|
||||
hdnode_private_ckd(&node, 44 | 0x80000000);
|
||||
hdnode_private_ckd(&node, index.row() | 0x80000000);
|
||||
hdnode_private_ckd(&node, 0 | 0x80000000); // bitcoin
|
||||
hdnode_private_ckd(&node, (arg1 - 1) | 0x80000000);
|
||||
hdnode_serialize_private(&node, buf); QString xprv = QString(buf); ui->lineXprv->setText(xprv);
|
||||
hdnode_serialize_public(&node, buf); QString xpub = QString(buf); ui->lineXpub->setText(xpub);
|
||||
hdnode_private_ckd(&node, chain); // external / internal
|
||||
for (int i = 0; i < 100; i++) {
|
||||
HDNode node2 = node;
|
||||
|
@ -18,7 +18,7 @@ public:
|
||||
|
||||
private slots:
|
||||
void on_buttonLoad_clicked();
|
||||
void on_listAccount_clicked(const QModelIndex &index);
|
||||
void on_spinAccount_valueChanged(int arg1);
|
||||
|
||||
private:
|
||||
Ui::MainWindow *ui;
|
||||
|
@ -6,13 +6,14 @@
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>800</width>
|
||||
<width>1000</width>
|
||||
<height>600</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="font">
|
||||
<font>
|
||||
<family>DejaVu Sans Mono</family>
|
||||
<pointsize>8</pointsize>
|
||||
</font>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
@ -20,10 +21,10 @@
|
||||
</property>
|
||||
<widget class="QWidget" name="centralWidget">
|
||||
<layout class="QGridLayout" name="gridLayout">
|
||||
<item row="0" column="0" colspan="2">
|
||||
<widget class="QLineEdit" name="editMnemonic"/>
|
||||
<item row="4" column="1" colspan="3">
|
||||
<widget class="QLineEdit" name="lineXpub"/>
|
||||
</item>
|
||||
<item row="0" column="2">
|
||||
<item row="1" column="2">
|
||||
<widget class="QLineEdit" name="editPassphrase">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
|
||||
@ -33,7 +34,7 @@
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="3">
|
||||
<item row="1" column="3">
|
||||
<widget class="QPushButton" name="buttonLoad">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
|
||||
@ -52,23 +53,7 @@
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0" rowspan="2">
|
||||
<widget class="QListWidget" name="listAccount">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Fixed" vsizetype="Expanding">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>140</width>
|
||||
<height>16777215</height>
|
||||
</size>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1" colspan="3">
|
||||
<item row="7" column="0" colspan="4">
|
||||
<widget class="QTableWidget" name="listAddress">
|
||||
<column>
|
||||
<property name="text">
|
||||
@ -87,7 +72,7 @@
|
||||
</column>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1" colspan="3">
|
||||
<item row="9" column="0" colspan="4">
|
||||
<widget class="QTableWidget" name="listChange">
|
||||
<column>
|
||||
<property name="text">
|
||||
@ -106,15 +91,70 @@
|
||||
</column>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="labelMnemonic">
|
||||
<property name="text">
|
||||
<string>Mnemonic:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="2">
|
||||
<widget class="QLabel" name="labelPassphrase">
|
||||
<property name="text">
|
||||
<string>Passphrase:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="5" column="0">
|
||||
<widget class="QLabel" name="labelExternal">
|
||||
<property name="text">
|
||||
<string>External Chain:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="8" column="0">
|
||||
<widget class="QLabel" name="labelInternal">
|
||||
<property name="text">
|
||||
<string>Internal Chain:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<widget class="QSpinBox" name="spinAccount">
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>130</width>
|
||||
<height>16777215</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="prefix">
|
||||
<string>Account #</string>
|
||||
</property>
|
||||
<property name="minimum">
|
||||
<number>1</number>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<number>2147483647</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0" colspan="2">
|
||||
<widget class="QLineEdit" name="editMnemonic"/>
|
||||
</item>
|
||||
<item row="2" column="1" colspan="3">
|
||||
<widget class="QLineEdit" name="lineXprv"/>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</widget>
|
||||
<layoutdefault spacing="6" margin="11"/>
|
||||
<tabstops>
|
||||
<tabstop>editMnemonic</tabstop>
|
||||
<tabstop>editPassphrase</tabstop>
|
||||
<tabstop>buttonLoad</tabstop>
|
||||
<tabstop>listAccount</tabstop>
|
||||
<tabstop>spinAccount</tabstop>
|
||||
<tabstop>listAddress</tabstop>
|
||||
<tabstop>listChange</tabstop>
|
||||
</tabstops>
|
||||
<resources/>
|
||||
<connections/>
|
||||
|
Loading…
Reference in New Issue
Block a user