1
0

trezor: implement support for Shamir recovery

This commit is contained in:
matejcik
2019-10-10 17:31:12 +02:00
parent f4e2781786
commit 3fc70bd97a
2 changed files with 101 additions and 21 deletions

View File

@@ -16,7 +16,7 @@ from electrum.util import bh2u
from ..hw_wallet.qt import QtHandlerBase, QtPluginBase
from ..hw_wallet.plugin import only_hook_if_libraries_available
from .trezor import (TrezorPlugin, TIM_NEW, TIM_RECOVER, TrezorInitSettings,
RECOVERY_TYPE_SCRAMBLED_WORDS, RECOVERY_TYPE_MATRIX)
Capability, BackupType, RecoveryDeviceType)
PASSPHRASE_HELP_SHORT =_(
@@ -199,6 +199,8 @@ class QtPlugin(QtPluginBase):
raise Exception(_("The device was disconnected."))
model = client.get_trezor_model()
fw_version = client.client.version
capabilities = client.client.features.capabilities
have_shamir = Capability.Shamir in capabilities
# label
label = QLabel(_("Enter a label to name your device:"))
@@ -209,22 +211,87 @@ class QtPlugin(QtPluginBase):
hl.addStretch(1)
vbox.addLayout(hl)
# Backup type
gb_backuptype = QGroupBox()
hbox_backuptype = QHBoxLayout()
gb_backuptype.setLayout(hbox_backuptype)
vbox.addWidget(gb_backuptype)
gb_backuptype.setTitle(_('Select backup type:'))
bg_backuptype = QButtonGroup()
rb_single = QRadioButton(gb_backuptype)
rb_single.setText(_('Single seed (BIP39)'))
bg_backuptype.addButton(rb_single)
bg_backuptype.setId(rb_single, BackupType.Bip39)
hbox_backuptype.addWidget(rb_single)
rb_single.setChecked(not have_shamir)
rb_shamir = QRadioButton(gb_backuptype)
rb_shamir.setText(_('Shamir'))
bg_backuptype.addButton(rb_shamir)
bg_backuptype.setId(rb_shamir, BackupType.Slip39_Basic)
hbox_backuptype.addWidget(rb_shamir)
rb_shamir.setChecked(have_shamir)
rb_shamir.setEnabled(Capability.Shamir in capabilities)
rb_shamir_groups = QRadioButton(gb_backuptype)
rb_shamir_groups.setText(_('Super Shamir'))
bg_backuptype.addButton(rb_shamir_groups)
bg_backuptype.setId(rb_shamir_groups, BackupType.Slip39_Advanced)
hbox_backuptype.addWidget(rb_shamir_groups)
rb_shamir_groups.setEnabled(Capability.ShamirGroups in capabilities)
# word count
gb = QGroupBox()
word_count_buttons = {}
gb_numwords = QGroupBox()
hbox1 = QHBoxLayout()
gb.setLayout(hbox1)
vbox.addWidget(gb)
gb.setTitle(_("Select your seed length:"))
gb_numwords.setLayout(hbox1)
vbox.addWidget(gb_numwords)
gb_numwords.setTitle(_("Select seed/share length:"))
bg_numwords = QButtonGroup()
word_counts = (12, 18, 24)
for i, count in enumerate(word_counts):
rb = QRadioButton(gb)
for count in (12, 18, 20, 24, 33):
rb = QRadioButton(gb_numwords)
word_count_buttons[count] = rb
rb.setText(_("{:d} words").format(count))
bg_numwords.addButton(rb)
bg_numwords.setId(rb, i)
bg_numwords.setId(rb, count)
hbox1.addWidget(rb)
rb.setChecked(True)
def configure_word_counts():
if model == "1":
checked_wordcount = 24
else:
checked_wordcount = 12
if method == TIM_RECOVER:
if have_shamir:
valid_word_counts = (12, 18, 20, 24, 33)
else:
valid_word_counts = (12, 18, 24)
elif rb_single.isChecked():
valid_word_counts = (12, 18, 24)
gb_numwords.setTitle(_('Select seed length:'))
else:
valid_word_counts = (20, 33)
checked_wordcount = 20
gb_numwords.setTitle(_('Select share length:'))
word_count_buttons[checked_wordcount].setChecked(True)
for c, btn in word_count_buttons.items():
btn.setVisible(c in valid_word_counts)
bg_backuptype.buttonClicked.connect(configure_word_counts)
configure_word_counts()
# set up conditional visibility:
# 1. backup_type is only visible when creating new seed
gb_backuptype.setVisible(method == TIM_NEW)
# 2. word_count is not visible when recovering on TT
if method == TIM_RECOVER and model != "1":
gb_numwords.setVisible(False)
# PIN
cb_pin = QCheckBox(_('Enable PIN protection'))
cb_pin.setChecked(True)
@@ -255,7 +322,7 @@ class QtPlugin(QtPluginBase):
# ask for recovery type (random word order OR matrix)
bg_rectype = None
if method == TIM_RECOVER and not model == 'T':
if method == TIM_RECOVER and model == '1':
gb_rectype = QGroupBox()
hbox_rectype = QHBoxLayout()
gb_rectype.setLayout(hbox_rectype)
@@ -266,14 +333,14 @@ class QtPlugin(QtPluginBase):
rb1 = QRadioButton(gb_rectype)
rb1.setText(_('Scrambled words'))
bg_rectype.addButton(rb1)
bg_rectype.setId(rb1, RECOVERY_TYPE_SCRAMBLED_WORDS)
bg_rectype.setId(rb1, RecoveryDeviceType.ScrambledWords)
hbox_rectype.addWidget(rb1)
rb1.setChecked(True)
rb2 = QRadioButton(gb_rectype)
rb2.setText(_('Matrix'))
bg_rectype.addButton(rb2)
bg_rectype.setId(rb2, RECOVERY_TYPE_MATRIX)
bg_rectype.setId(rb2, RecoveryDeviceType.Matrix)
hbox_rectype.addWidget(rb2)
# no backup
@@ -293,11 +360,12 @@ class QtPlugin(QtPluginBase):
wizard.exec_layout(vbox, next_enabled=next_enabled)
return TrezorInitSettings(
word_count=word_counts[bg_numwords.checkedId()],
word_count=bg_numwords.checkedId(),
label=name.text(),
pin_enabled=cb_pin.isChecked(),
passphrase_enabled=cb_phrase.isChecked(),
recovery_type=bg_rectype.checkedId() if bg_rectype else None,
backup_type=bg_backuptype.checkedId(),
no_backup=cb_no_backup.isChecked() if cb_no_backup else False,
)