1
0
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:
Pavol Rusnak 2014-08-07 14:34:33 +02:00
parent b9ed9a9cd4
commit 8820ae9873
6 changed files with 122 additions and 39 deletions

1
.gitignore vendored
View File

@ -3,3 +3,4 @@
*~
test-openssl
tests
build-*/

46
bip32.c
View File

@ -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);

View File

@ -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))

View File

@ -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;

View File

@ -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;

View File

@ -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/>