Example #1
1
    def test_utf8_nfkd(self):
        # The same sentence in various UTF-8 forms
        words_nfkd = u"Pr\u030ci\u0301s\u030cerne\u030c z\u030clut\u030couc\u030cky\u0301 ku\u030an\u030c u\u0301pe\u030cl d\u030ca\u0301belske\u0301 o\u0301dy za\u0301ker\u030cny\u0301 uc\u030cen\u030c be\u030cz\u030ci\u0301 pode\u0301l zo\u0301ny u\u0301lu\u030a"
        words_nfc = u"P\u0159\xed\u0161ern\u011b \u017elu\u0165ou\u010dk\xfd k\u016f\u0148 \xfap\u011bl \u010f\xe1belsk\xe9 \xf3dy z\xe1ke\u0159n\xfd u\u010de\u0148 b\u011b\u017e\xed pod\xe9l z\xf3ny \xfal\u016f"
        words_nfkc = u"P\u0159\xed\u0161ern\u011b \u017elu\u0165ou\u010dk\xfd k\u016f\u0148 \xfap\u011bl \u010f\xe1belsk\xe9 \xf3dy z\xe1ke\u0159n\xfd u\u010de\u0148 b\u011b\u017e\xed pod\xe9l z\xf3ny \xfal\u016f"
        words_nfd = u"Pr\u030ci\u0301s\u030cerne\u030c z\u030clut\u030couc\u030cky\u0301 ku\u030an\u030c u\u0301pe\u030cl d\u030ca\u0301belske\u0301 o\u0301dy za\u0301ker\u030cny\u0301 uc\u030cen\u030c be\u030cz\u030ci\u0301 pode\u0301l zo\u0301ny u\u0301lu\u030a"

        passphrase_nfkd = (
            u"Neuve\u030cr\u030citelne\u030c bezpec\u030cne\u0301 hesli\u0301c\u030cko"
        )
        passphrase_nfc = (
            u"Neuv\u011b\u0159iteln\u011b bezpe\u010dn\xe9 hesl\xed\u010dko"
        )
        passphrase_nfkc = (
            u"Neuv\u011b\u0159iteln\u011b bezpe\u010dn\xe9 hesl\xed\u010dko"
        )
        passphrase_nfd = (
            u"Neuve\u030cr\u030citelne\u030c bezpec\u030cne\u0301 hesli\u0301c\u030cko"
        )

        seed_nfkd = Mnemonic.to_seed(words_nfkd, passphrase_nfkd)
        seed_nfc = Mnemonic.to_seed(words_nfc, passphrase_nfc)
        seed_nfkc = Mnemonic.to_seed(words_nfkc, passphrase_nfkc)
        seed_nfd = Mnemonic.to_seed(words_nfd, passphrase_nfd)

        self.assertEqual(seed_nfkd, seed_nfc)
        self.assertEqual(seed_nfkd, seed_nfkc)
        self.assertEqual(seed_nfkd, seed_nfd)
Example #2
1
def from_seed(seed, passphrase):
    t = seed_type(seed)
    if t == 'old':
        keystore = Old_KeyStore({})
        keystore.add_seed(seed)
    elif t in ['standard', 'segwit']:
        keystore = BIP32_KeyStore({})
        keystore.add_seed(seed)
        keystore.passphrase = passphrase
        bip32_seed = Mnemonic.mnemonic_to_seed(seed, passphrase)
        xtype = 0 if t == 'standard' else 1
        keystore.add_xprv_from_seed(bip32_seed, xtype, "m/")
    return keystore
Example #3
0
    def load_device_by_mnemonic(self, mnemonic, pin, passphrase_protection, label, language, skip_checksum=False):
        m = Mnemonic("english")
        if not skip_checksum and not m.check(mnemonic):
            raise Exception("Invalid mnemonic checksum")

        # Convert mnemonic to UTF8 NKFD
        mnemonic = Mnemonic.normalize_string(mnemonic)

        # Convert mnemonic to ASCII stream
        mnemonic = unicode(str(bytearray(mnemonic, "utf-8")), "utf-8")

        if self.features.initialized:
            raise Exception("Device is initialized already. Call wipe_device() and try again.")

        resp = self.call(
            proto.LoadDevice(
                mnemonic=mnemonic,
                pin=pin,
                passphrase_protection=passphrase_protection,
                language=language,
                label=label,
                skip_checksum=skip_checksum,
            )
        )
        self.init_device()
        return resp
Example #4
0
 def _check_list(self, language, vectors):
     mnemo = Mnemonic(language)
     for v in vectors:
         code = mnemo.to_mnemonic(unhexlify(v[0]))
         seed = hexlify(Mnemonic.to_seed(code, passphrase = 'TREZOR'))
         self.assertIs(mnemo.check(v[1]), True)
         self.assertEqual(v[1], code)
         self.assertEqual(v[2], seed)
Example #5
0
 def test_to_entropy(self):
     data = [
         bytearray((random.getrandbits(8) for _ in range(32))) for _ in range(1024)
     ]
     data.append(b"Lorem ipsum dolor sit amet amet.")
     m = Mnemonic("english")
     for d in data:
         self.assertEqual(m.to_entropy(m.to_mnemonic(d).split()), d)
Example #6
0
def restore(ctx):
    """ Restore a wallet from a mnemonic

    \b
    If you accidently deleted your wallet file or the file
    became corrupted, use this command to restore your wallet. You
    must have your 12 word phrase (mnemonic) that was displayed
    when you created your wallet.
    """
    # Stop daemon if it's running.
    d = None
    try:
        d = get_daemonizer()
    except OSError as e:
        pass

    if d:
        try:
            d.stop()
        except exceptions.DaemonizerError as e:
            click.echo("ERROR: Couldn't stop daemon: %s" % e)
            ctx.exit(code=4)

    # Check to see if the current wallet path exists
    if os.path.exists(ctx.obj['wallet_path']):
        if click.confirm("Wallet file already exists and may have a balance. Do you want to delete it?"):
            os.remove(ctx.obj['wallet_path'])
        else:
            click.echo("Not continuing.")
            ctx.exit(code=4)

    # Ask for mnemonic
    mnemonic = click.prompt("Please enter the wallet's 12 word mnemonic")

    # Sanity check the mnemonic
    m = Mnemonic(language='english')
    if not m.check(mnemonic):
        click.echo("ERROR: Invalid mnemonic.")
        ctx.exit(code=5)

    if click.confirm("Did the wallet have a passphrase?"):
        passphrase = get_passphrase()
    else:
        passphrase = ''

    # Try creating the wallet
    click.echo("\nRestoring...")
    wallet = Two1Wallet.import_from_mnemonic(
        data_provider=ctx.obj['data_provider'],
        mnemonic=mnemonic,
        passphrase=passphrase)

    wallet.to_file(ctx.obj['wallet_path'])
    if Two1Wallet.check_wallet_file(ctx.obj['wallet_path']):
        click.echo("Wallet successfully restored.")
    else:
        click.echo("Wallet not restored.")
        ctx.exit(code=6)
Example #7
0
 def test_to_entropy(self):
     data = [bytearray((random.getrandbits(8) for _ in range(32))) for _ in
             range(1024)]
     data.append(
         b" I'm a little teapot, short and stout. Here is my handle. "
         b"Here is my spout. When I get all steamed up, hear me shout. "
         b"Tip me over and pour me out!! ")
     m = Mnemonic('english')
     for d in data:
         self.assertEqual(m.to_entropy(m.to_mnemonic(d).split()), d)
def showDetails(mnemonic, passphrase="", i=1):

    myMnemonic = mnemonic
    passphrase = passphrase


    mnemo = Mnemonic('english')
    seed = hexlify(mnemo.to_seed(myMnemonic, passphrase=passphrase))
    print 'Seed:\t\t\t\t', seed

    priv = bitcoin.bip32_master_key(unhexlify(seed))
    print 'Xpriv:\t\t\t\t', priv

    key = bitcoin.encode_privkey(bitcoin.bip32_extract_key(priv), 'wif_compressed')
    print 'Key:\t\t\t\t', key


    pub = bitcoin.bip32_privtopub(priv)
    print 'Derived public key:\t', pub
    pubHex = bitcoin.bip32_extract_key(pub)
    print 'public key (hex):\t', pubHex
    print 'Master Key address:\t', bitcoin.pubtoaddr(pubHex)


    print ""
    print "TREZOR Keys:"

    account = 0
    derivedPrivateKey = bitcoin.bip32_ckd(bitcoin.bip32_ckd(bitcoin.bip32_ckd(priv, 44+HARDENED), HARDENED), HARDENED+account)
    print 'Derived private key:', derivedPrivateKey

    privateKey = bitcoin.encode_privkey(bitcoin.bip32_extract_key(derivedPrivateKey), 'wif_compressed')
    print 'private key (wif):\t', privateKey


    derivedPublicKey = bitcoin.bip32_privtopub(derivedPrivateKey)
    print 'Derived public key:', derivedPublicKey

    publicKeyHex = bitcoin.privtopub(privateKey)
    print 'public key (hex):\t', publicKeyHex

    address = bitcoin.pubtoaddr(publicKeyHex)
    print 'address:\t\t\t', address

    print ""
    print "Account public keys (XPUB)"
    xpubs = []
    for i in range(0, i):
        derivedPrivateKey = bitcoin.bip32_ckd(bitcoin.bip32_ckd(bitcoin.bip32_ckd(priv, 44+HARDENED), HARDENED), HARDENED+i)
        xpub = bitcoin.bip32_privtopub(derivedPrivateKey)
        print 'Account', i, 'xpub:', xpub
        xpubs.append(xpub)

    return xpubs
Example #9
0
 def _check_list(self, language, vectors):
     mnemo = Mnemonic(language)
     for v in vectors:
         code = mnemo.to_mnemonic(unhexlify(v[0]))
         seed = hexlify(Mnemonic.to_seed(code, passphrase="TREZOR"))
         xprv = Mnemonic.to_hd_master_key(unhexlify(seed))
         if sys.version >= "3":
             seed = seed.decode("utf8")
         self.assertIs(mnemo.check(v[1]), True)
         self.assertEqual(v[1], code)
         self.assertEqual(v[2], seed)
         self.assertEqual(v[3], xprv)
Example #10
0
    def _check_list(self, language, vectors):
        mnemo = Mnemonic(language)
        for v in vectors:
            code = mnemo.encode(unhexlify(v[0]))
            data = hexlify(mnemo.decode(code))

            self.assertEqual(v[1], code)
            self.assertEqual(v[0], data)

            print "input:   ", v[0], "(%d bits)" % len(v[0] * 4)
            print "mnemonic:", code, "(%d words)" % len(code.split(' '))
            print
Example #11
0
def restore_wallet(PIN):
    if len(PIN) == 0:
        PIN = choose_PIN_code()

    retry = True
    while retry:
        userWords = []

        print_screen_title("RESTORE AN EXISTING WALLET (step 2/3)")
        print "Please type in your 24 words backup phrase."
        print "Warning: BIP39 is " + term.bold("case-sensitive!") + "\n"

        for i in range(1, 25):
            validWord = False
            while not validWord:
                typedWord = raw_input("Word #" + str(i) + "? ")
                typedWord = typedWord.lower()
                if len(typedWord) > 0:
                    if typedWord in english_wordlist:
                        userWords.append(typedWord)
                        validWord = True
                    else:
                        print "This word is not in the official BIP39 english wordlist."
                else:
                    print "Type a word a please."

        bip39Seed = " ".join(userWords)
        mnemo = Mnemonic("english")

        if mnemo.check(bip39Seed) == False:
            print ""
            print "An " + term.bold("error occurred") + "."
            print "Your BIP39 seed is invalid !\n"
            question = "Try again to type the seed?"
            retry = yes_or_no_question(question)
        else:
            retry = False

            print "\nWe're almost done!"
            print "Here is your BIP39 seed:\n"
            print_wordlist(bip39Seed)
            print "\nPlease check that it is correct."

            question = "Continue and restore your wallet from this seed?"
            choice = yes_or_no_question(question)

            if choice == True:
                start_flashing(PIN, bip39Seed)
            else:
                restore_wallet(PIN)
Example #12
0
 def __init__(self):
     conf = read_config_file("ew.conf")
     if conf['entropy']:
         entropy = binascii.unhexlify(conf['entropy'])
     else:
         mnemo = Mnemonic('english')
         entropy = mnemo.to_entropy(conf['passphrase'])
     print("entropy=" + entropy.hex())
     master = BIP32Node.from_master_secret(entropy, 'BTC')
     print("master address=" + master.address())
     # /m/4544288'/0'/0'/0/0  alias
     alias = master.subkey(i=EW_DERIVATION, is_hardened=True).subkey(i=0, is_hardened=True).subkey(i=0, is_hardened=True).subkey(i=0, is_hardened=False).subkey(i=0, is_hardened=False)
     self.address = alias.address()
     print("alias address=" + self.address)
     self.key = CBitcoinSecret(alias.wif())
Example #13
0
    def test_similarity(self):
        similar = (
            ('a', 'c'), ('a', 'e'), ('a', 'o'),
            ('b', 'd'), ('b', 'h'), ('b', 'p'), ('b', 'q'), ('b', 'r'),
            ('c', 'e'), ('c', 'g'), ('c', 'n'), ('c', 'o'), ('c', 'q'), ('c', 'u'),
            ('d', 'g'), ('d', 'h'), ('d', 'o'), ('d', 'p'), ('d', 'q'),
            ('e', 'f'), ('e', 'o'),
            ('f', 'i'), ('f', 'j'), ('f', 'l'), ('f', 'p'), ('f', 't'),
            ('g', 'j'), ('g', 'o'), ('g', 'p'), ('g', 'q'), ('g', 'y'),
            ('h', 'k'), ('h', 'l'), ('h', 'm'), ('h', 'n'), ('h', 'r'),
            ('i', 'j'), ('i', 'l'), ('i', 't'), ('i', 'y'),
            ('j', 'l'), ('j', 'p'), ('j', 'q'), ('j', 'y'),
            ('k', 'x'),
            ('l', 't'),
            ('m', 'n'), ('m', 'w'),
            ('n', 'u'), ('n', 'z'),
            ('o', 'p'), ('o', 'q'), ('o', 'u'), ('o', 'v'),
            ('p', 'q'), ('p', 'r'),
            ('q', 'y'),
            ('s', 'z'),
            ('u', 'v'), ('u', 'w'), ('u', 'y'),
            ('v', 'w'), ('v', 'y')
        )

        languages = Mnemonic.list_languages()

        fail = False
        for lang in languages:
            mnemo = Mnemonic(lang)

            for w1 in mnemo.wordlist:
                for w2 in mnemo.wordlist:
                    if len(w1) != len(w2):
                        continue

                    if w1 == w2:
                        continue

                    if w1 > w2:
                        # No need to print warning twice
                        continue

                    diff = []
                    for i in range(len(w1)):
                        if w1[i] != w2[i]:
                            if w1[i] < w2[i]:
                                pair = (w1[i], w2[i])
                            else:
                                pair = (w2[i], w1[i])

                            diff.append(pair)
                            # pairs.update((pair,))

                    if len(diff) == 1:
                        if list(diff)[0] in similar:
                            fail = True
                            print("Similar words (%s): %s, %s" % (lang, w1, w2))

        if fail:
            self.assert_(False, "Similar words found")
	def processNext(self):
		self.persoData['seed'] = None
		if self.ui.RestoreWalletButton.isChecked():
			# Check if it's an hexa string
			seedText = str(self.ui.seed.text())
			if len(seedText) == 0:
				QMessageBox.warning(self, "Error", "Please enter a seed", "OK")
				return
			if seedText[-1] == 'X':
				seedText = seedText[0:-1]
			try:
				self.persoData['seed'] = seedText.decode('hex')
			except:
				pass
			if self.persoData['seed'] == None:
				if not MNEMONIC:
					QMessageBox.warning(self, "Error", "Mnemonic API not available. Please install https://github.com/trezor/python-mnemonic", "OK")
					return
				if not self.mnemonic.check(seedText):
					QMessageBox.warning(self, "Error", "Invalid mnemonic", "OK")
					return
				self.persoData['seed'] = Mnemonic.to_seed(seedText)
			else:
				if (len(self.persoData['seed']) < 32) or (len(self.persoData['seed']) > 64):
					QMessageBox.warning(self, "Error", "Invalid seed length", "OK")
					return
		dialog = SecurityDialog(self.persoData, self)
		self.hide()
		dialog.exec_()
def testvectors():
    """
    This function exercises the libraries and double checks that they are
    returning expected data.
    """
    print "Self Checking",
    print_dot()

    if "51477815b762e495e0f7deb01fb2969f2e15ba4615fa4a5aafc23ccf5c3c8bd2".decode('hex') != \
            privkey_to_pubkey("12fab77add10bcabe1b62b3fe8b167e966e4beee38ccf0062fdd207b5906c841".decode('hex'), False):
        return False
    print_dot()

    doublecheck_key_works("12fab77add10bcabe1b62b3fe8b167e966e4beee38ccf0062fdd207b5906c841".decode('hex'), \
            "51477815b762e495e0f7deb01fb2969f2e15ba4615fa4a5aafc23ccf5c3c8bd2".decode('hex'), False)
    print_dot()

    if "51477815-b762e495-e0f7deb0-1fb2969f-2e15ba46-15fa4a5a-afc23ccf-5c3c8bd2-6c4cf980" != \
            pubkey_to_send("51477815b762e495e0f7deb01fb2969f2e15ba4615fa4a5aafc23ccf5c3c8bd2".decode('hex'), False):
        return False
    print_dot()

    if "Fs1Ts7PsKMwo4ftCYxQJ3rW4pLiRBXyGEjMrxtHycLu52aDgKGEy" != \
            private_key_to_human("12fab77add10bcabe1b62b3fe8b167e966e4beee38ccf0062fdd207b5906c841".decode('hex'), False):
        return False
    print_dot()

    if not onlyB58chars("Xw1"):
        return False
    if onlyB58chars("$"):
        return False
    print_dot()

    if "4f4488c609552caf2c7a508108809518e9a1ab3ae6dc259a1e2e9989d053018d".decode('hex') != \
            hashlib.sha256(hashlib.sha256("647812fab77add10bcabe1b62b3fe8b167e966e4beee38ccf0062fdd207b5906c841" \
            .decode('hex')).digest()).digest():
        return False
    print_dot()

    if True != verify_koinify_words("legal winner thank year wave sausage worth useful legal winner thank yellow"):
        return False
    print_dot()
    if True == verify_koinify_words("legal winner thank year wave sausage worth useful legal winner thank thank"):
        return False
    print_dot()
    if "878386efb78845b3355bd15ea4d39ef97d179cb712b77d5c12b6be415fffeffe5f377ba02bf3f8544ab800b955e51fbff09828f682052a20faa6addbbddfb096" \
            .decode('hex') != Mnemonic.to_seed("legal winner thank year wave sausage worth useful legal winner thank yellow", ''):
        return False
    print_dot()
    if "0488ade4000000000000000000598b4595ea72802756519e65a797234231d7d4f13d650cb06db15957c2368b1b007e56ecf5943d79e1f5f87e11c768253d7f3fcf30ae71335611e366c578b4564e"\
            .decode('hex') != BIP32Key.fromEntropy("878386efb78845b3355bd15ea4d39ef97d179cb712b77d5c12b6be415fffeffe5f377ba02bf3f8544ab800b955e51fbff09828f682052a20faa6addbbddfb096"\
            .decode('hex'), public=False).ExtendedKey(private=True, encoded=False):
        return False
    print_dot()
    if "7999d61b8f5efc24b437244ff82b69ba474deeadbf144421f05d5b4b5ab20a8e".decode('hex') != \
            koinify_words_to_private_key("legal winner thank year wave sausage worth useful legal winner thank yellow", False):
        return False
    print("\n")
    # everything checks out ok
    return True
Example #16
0
def process(data, lst):
    code = mnemo.to_mnemonic(unhexlify(data))
    seed = b2h(Mnemonic.to_seed(code, passphrase = 'TREZOR'))
    print('input    : %s (%d bits)' % (data, len(data) * 4))
    print('mnemonic : %s (%d words)' % (code, len(code.split(' '))))
    print('seed     : %s (%d bits)' % (seed, len(seed) * 4))
    print()
    lst.append((data, code, seed))
Example #17
0
 def test_lengths(self):
     # check if wordlists contain words between 3 and 8 characters
     languages = Mnemonic.list_languages()
     for lang in languages:
         mnemo = Mnemonic(lang)
         words = [w for w in mnemo.wordlist if len(w) < 3 or len(w) > 8]
         print("Language '{}'".format(lang))
         self.assertListEqual(words, [])
def verify_koinify_words(words):
    """
    This function checks to make sure there are multiple words and
    that the first word is in the english wordlist.
    Both of these errors would crash the Mnemonic library, so they should be checked before using it.
    The Mnemonic library checks for other errors.
    """
    if ' ' in words:
        wordchecker = Mnemonic('english')
        firstword = words.split(' ')[0]
        if firstword in wordchecker.wordlist:
            check = wordchecker.check(words)
            return check
        else:
            return False
    else:
        return False
Example #19
0
 def test_validchars(self):
     # check if wordlists contain valid characters
     languages = Mnemonic.list_languages()
     for lang in languages:
         mnemo = Mnemonic(lang)
         letters = set(sum([list(w) for w in mnemo.wordlist] ,[]))
         print("Language '{}'".format(lang))
         for l in letters:
             self.assertIn(l, 'abcdefghijklmnopqrstuvwxyz')
def process(ctr, p_hex):
    print '(%i)' % ctr
    print 'input    : %s (%d bits)' % (p_hex, len(p_hex) * 4)
    
    p_mnemonic = mnemo.to_mnemonic(unhexlify(p_hex))
    print 'mnemonic : %s (%d words)' % (p_mnemonic, len(p_mnemonic.split(' ')))

    p_seed = hexlify(Mnemonic.to_seed(p_mnemonic, passphrase = ''))
    print 'seed     : %s (%d bits)' % (p_seed, len(p_seed) * 4)
def process(data, lst, mnemo):
    code = mnemo.to_mnemonic(unhexlify(data))
    _seed = Mnemonic.to_seed(code, passphrase='TREZOR')
    xprv = BIP32Key.fromEntropy(_seed).ExtendedKey()
    _seed = b2h(_seed)
    print('input    : %s (%d bits)' % (data, len(data) * 4))
    print('mnemonic : %s (%d words)' % (code, len(code.split(' '))))
    print('seed     : %s (%d bits)' % (_seed, len(_seed) * 4))
    print('xprv     : %s\n' % xprv)
    lst.append((data, code, _seed, xprv))
Example #22
0
	def __init__(self, language):
		self.mnemo = Mnemonic(language)
		# see https://primes.utm.edu/lists/2small/ for biggest primes that fit into X bits
		self.primes = {
			15: (2**120 - 119),
			19: (2**152 - 17),
			23: (2**184 - 33),
			27: (2**216 - 377),
			31: (2**248 - 237)
		}
def getXPRIVKeys(mnemonic, passphrase="", i=1):

    myMnemonic = mnemonic
    passphrase = passphrase

    mnemo = Mnemonic('english')
    seed = hexlify(mnemo.to_seed(myMnemonic, passphrase=passphrase))

    priv = bitcoin.bip32_master_key(unhexlify(seed))

    account = 0
    #derivedPrivateKey = bitcoin.bip32_ckd(bitcoin.bip32_ckd(bitcoin.bip32_ckd(priv, 44+HARDENED), HARDENED), HARDENED+account)

    xprivs = []
    for i in range(0, i):
        derivedPrivateKey = bitcoin.bip32_ckd(bitcoin.bip32_ckd(bitcoin.bip32_ckd(priv, 44+HARDENED), HARDENED), HARDENED+i)
        xprivs.append(derivedPrivateKey)

    return xprivs
Example #24
0
def from_seed(seed, passphrase):
    if is_old_seed(seed):
        keystore = Old_KeyStore({})
        keystore.add_seed(seed)
    elif is_new_seed(seed):
        keystore = BIP32_KeyStore({})
        keystore.add_seed(seed)
        keystore.passphrase = passphrase
        bip32_seed = Mnemonic.mnemonic_to_seed(seed, passphrase)
        keystore.add_xprv_from_seed(bip32_seed, "m/")
    return keystore
def process(data, lst):
    code = mnemo.to_mnemonic(unhexlify(data))
    seed = Mnemonic.to_seed(code, passphrase="TREZOR")
    xprv = BIP32Key.fromEntropy(seed).ExtendedKey()
    seed = b2h(seed)
    print("input    : %s (%d bits)" % (data, len(data) * 4))
    print("mnemonic : %s (%d words)" % (code, len(code.split(" "))))
    print("seed     : %s (%d bits)" % (seed, len(seed) * 4))
    print("xprv     : %s" % xprv)
    print()
    lst.append((data, code, seed, xprv))
Example #26
0
def load_device_by_mnemonic(
    client,
    mnemonic,
    pin,
    passphrase_protection,
    label,
    language="english",
    skip_checksum=False,
    expand=False,
):
    # Convert mnemonic to UTF8 NKFD
    mnemonic = Mnemonic.normalize_string(mnemonic)

    # Convert mnemonic to ASCII stream
    mnemonic = mnemonic.encode()

    m = Mnemonic("english")

    if expand:
        mnemonic = m.expand(mnemonic)

    if not skip_checksum and not m.check(mnemonic):
        raise ValueError("Invalid mnemonic checksum")

    if client.features.initialized:
        raise RuntimeError(
            "Device is initialized already. Call device.wipe() and try again."
        )

    resp = client.call(
        proto.LoadDevice(
            mnemonic=mnemonic,
            pin=pin,
            passphrase_protection=passphrase_protection,
            language=language,
            label=label,
            skip_checksum=skip_checksum,
        )
    )
    client.init_device()
    return resp
Example #27
0
    def test_collision(self):
        # Check for the same words across wordlists.
        # This is prohibited because of auto-detection feature of language.

        words = []
        languages = Mnemonic.list_languages()
        for lang in languages:
            mnemo = Mnemonic(lang)
            words += mnemo.wordlist

        words_unique = list(set(words[:]))
        self.assertEqual(len(words), len(words_unique))
	def __init__(self, persoData, parent = None):
		QDialog.__init__(self, parent)
		self.persoData = persoData
		self.ui = ui.personalization01seed.Ui_Dialog()
		self.ui.setupUi(self)
		self.ui.seed.setEnabled(False)
		self.ui.RestoreWalletButton.toggled.connect(self.restoreWalletToggled)
		self.ui.NextButton.clicked.connect(self.processNext)
		self.ui.CancelButton.clicked.connect(self.processCancel)
		if MNEMONIC:
			self.mnemonic = Mnemonic('english')
			self.ui.mnemonicNotAvailableLabel.hide()
Example #29
0
 def test_expand_word(self):
     m = Mnemonic("english")
     self.assertEqual("", m.expand_word(""))
     self.assertEqual(" ", m.expand_word(" "))
     self.assertEqual("access", m.expand_word("access"))  # word in list
     self.assertEqual(
         "access", m.expand_word("acce")
     )  # unique prefix expanded to word in list
     self.assertEqual("acb", m.expand_word("acb"))  # not found at all
     self.assertEqual("acc", m.expand_word("acc"))  # multi-prefix match
     self.assertEqual("act", m.expand_word("act"))  # exact three letter match
     self.assertEqual(
         "action", m.expand_word("acti")
     )  # unique prefix expanded to word in list
Example #30
0
 def __init__(self, wordfile = 'wordlist.txt'):
     
     # Read create the mnemonic wordlist object
     self.mnemonic = Mnemonic("english")
 
     # Set up a default reference wallet
     self.wallet = Wallet.from_master_secret(bytes(0))
     
     # Set up a Polly communication pipe
     self.polly = PollyCom()
     
     # Default print padding
     self.PAD = "{:35}"
Example #31
0
def xkeys_from_seed(seed, passphrase, derivation):
    from mnemonic import Mnemonic
    xprv, xpub = bip32_root(Mnemonic.mnemonic_to_seed(seed, passphrase), 0)
    xprv, xpub = bip32_private_derivation(xprv, "m/", derivation)
    return xprv, xpub
Example #32
0
 def make_seed(self, nbits=128, entropy=1, language=None):
     """Create a seed"""
     from mnemonic import Mnemonic
     s = Mnemonic(language).make_seed(nbits, custom_entropy=entropy)
     return s.encode('utf8')
Example #33
0
 def use_passphrase(self, passphrase: str) -> None:
     """Respond to passphrase prompts from device with the provided passphrase."""
     self.ui.passphrase = Mnemonic.normalize_string(passphrase)
Example #34
0
 def check_seed(self, seed, entropy=1, language=None):
     """Check that a seed was generated with given entropy"""
     from mnemonic import Mnemonic
     return Mnemonic(language).check_seed(seed, entropy)
Example #35
0
 def test_failed_checksum(self):
     code = (
         "bless cloud wheel regular tiny venue bird web grief security dignity zoo"
     )
     mnemo = Mnemonic("english")
     self.assertFalse(mnemo.check(code))
Example #36
0
def generate_words(language: str = 'english', count: int = 24) -> str:
    from mnemonic import Mnemonic
    mnemonic = Mnemonic(language)
    return mnemonic.generate(strength=int(count * 10.67))
Example #37
0
    def test_reset_device(self):
        words = []
        strength = 128

        def input_flow():
            # Confirm Reset
            btn_code = yield
            assert btn_code == B.ResetDevice
            self.client.debug.press_yes()

            # Backup your seed
            btn_code = yield
            assert btn_code == B.ResetDevice
            self.client.debug.press_yes()

            # safety warning
            btn_code = yield
            assert btn_code == B.ResetDevice
            self.client.debug.press_yes()

            # mnemonic phrases
            btn_code = yield
            assert btn_code == B.ResetDevice
            # 12 words, 3 pages
            for i in range(3):
                time.sleep(1)
                words.extend(self.client.debug.state().reset_word.split())
                if i < 2:
                    self.client.debug.swipe_down()
                else:
                    # last page is confirmation
                    self.client.debug.press_yes()

            # check backup words
            for _ in range(2):
                time.sleep(1)
                index = self.client.debug.state().reset_word_pos
                self.client.debug.input(words[index])

            # confirm recovery seed check
            btn_code = yield
            assert btn_code == B.ResetDevice
            self.client.debug.press_yes()

            # confirm success
            btn_code = yield
            assert btn_code == B.ResetDevice
            self.client.debug.press_yes()

        os_urandom = mock.Mock(return_value=EXTERNAL_ENTROPY)
        with mock.patch("os.urandom", os_urandom), self.client:
            self.client.set_expected_responses([
                proto.ButtonRequest(code=B.ResetDevice),
                proto.EntropyRequest(),
                proto.ButtonRequest(code=B.ResetDevice),
                proto.ButtonRequest(code=B.ResetDevice),
                proto.ButtonRequest(code=B.ResetDevice),
                proto.ButtonRequest(code=B.ResetDevice),
                proto.ButtonRequest(code=B.ResetDevice),
                proto.Success(),
                proto.Features(),
            ])
            self.client.set_input_flow(input_flow)

            # No PIN, no passphrase, don't display random
            device.reset(
                self.client,
                display_random=False,
                strength=strength,
                passphrase_protection=False,
                pin_protection=False,
                label="test",
                language="english",
            )

        # generate mnemonic locally
        internal_entropy = self.client.debug.state().reset_entropy
        entropy = generate_entropy(strength, internal_entropy,
                                   EXTERNAL_ENTROPY)
        expected_mnemonic = Mnemonic("english").to_mnemonic(entropy)

        # Compare that device generated proper mnemonic for given entropies
        assert " ".join(words) == expected_mnemonic

        # Check if device is properly initialized
        resp = self.client.call_raw(proto.Initialize())
        assert resp.initialized is True
        assert resp.needs_backup is False
        assert resp.pin_protection is False
        assert resp.passphrase_protection is False
Example #38
0
    def test_detection(self):
        self.assertEqual('english', Mnemonic.detect_language('security'))

        with self.assertRaises(Exception):
            Mnemonic.detect_language('xxxxxxx')
Example #39
0
 def test_expand(self):
     m = Mnemonic('english')
     self.assertEqual('access', m.expand('access'))
     self.assertEqual('access access acb acc act action',
                      m.expand('access acce acb acc act acti'))
Example #40
0
def get_bip39_seed_from_mnemonic(mnemonic: str, passphrase='') -> bytes:
    seed = Mnemonic.to_seed(mnemonic=mnemonic, passphrase=passphrase)
    return seed
Example #41
0
 def check_seed(self, seed, custom_entropy, language):
     from mnemonic import Mnemonic
     return Mnemonic(language).check_seed(seed, custom_entropy)
Example #42
0
 def make_seed(self, nbits, custom_entropy, language):
     from mnemonic import Mnemonic
     s = Mnemonic(language).make_seed(nbits, custom_entropy=custom_entropy)
     return s.encode('utf8')
 def check_seedphrase(seedphrase, language='english'):
     return Mnemonic(language).check(seedphrase)
    def test_reset_device_pin(self, client):
        external_entropy = b"zlutoucky kun upel divoke ody" * 2
        strength = 128

        ret = client.call_raw(
            proto.ResetDevice(
                display_random=True,
                strength=strength,
                passphrase_protection=True,
                pin_protection=True,
                language="english",
                label="test",
            ))

        # Do you want ... ?
        assert isinstance(ret, proto.ButtonRequest)
        client.debug.press_yes()
        ret = client.call_raw(proto.ButtonAck())

        # Entropy screen #1
        assert isinstance(ret, proto.ButtonRequest)
        client.debug.press_yes()
        ret = client.call_raw(proto.ButtonAck())

        # Entropy screen #2
        assert isinstance(ret, proto.ButtonRequest)
        client.debug.press_yes()
        ret = client.call_raw(proto.ButtonAck())

        assert isinstance(ret, proto.PinMatrixRequest)

        # Enter PIN for first time
        pin_encoded = client.debug.encode_pin("654")
        ret = client.call_raw(proto.PinMatrixAck(pin=pin_encoded))
        assert isinstance(ret, proto.PinMatrixRequest)

        # Enter PIN for second time
        pin_encoded = client.debug.encode_pin("654")
        ret = client.call_raw(proto.PinMatrixAck(pin=pin_encoded))

        # Provide entropy
        assert isinstance(ret, proto.EntropyRequest)
        internal_entropy = client.debug.read_reset_entropy()
        ret = client.call_raw(proto.EntropyAck(entropy=external_entropy))

        # Generate mnemonic locally
        entropy = generate_entropy(strength, internal_entropy,
                                   external_entropy)
        expected_mnemonic = Mnemonic("english").to_mnemonic(entropy)

        mnemonic = []
        for _ in range(strength // 32 * 3):
            assert isinstance(ret, proto.ButtonRequest)
            mnemonic.append(client.debug.read_reset_word())
            client.debug.press_yes()
            client.call_raw(proto.ButtonAck())

        mnemonic = " ".join(mnemonic)

        # Compare that device generated proper mnemonic for given entropies
        assert mnemonic == expected_mnemonic

        mnemonic = []
        for _ in range(strength // 32 * 3):
            assert isinstance(ret, proto.ButtonRequest)
            mnemonic.append(client.debug.read_reset_word())
            client.debug.press_yes()
            resp = client.call_raw(proto.ButtonAck())

        assert isinstance(resp, proto.Success)

        mnemonic = " ".join(mnemonic)

        # Compare that second pass printed out the same mnemonic once again
        assert mnemonic == expected_mnemonic

        # Check if device is properly initialized
        resp = client.call_raw(proto.Initialize())
        assert resp.initialized is True
        assert resp.needs_backup is False
        assert resp.pin_protection is True
        assert resp.passphrase_protection is True

        # Do passphrase-protected action, PassphraseRequest should be raised
        resp = client.call_raw(proto.Ping(passphrase_protection=True))
        assert isinstance(resp, proto.PassphraseRequest)
        client.call_raw(proto.Cancel())
Example #45
0

def process(data, lst):
    code = mnemo.to_mnemonic(unhexlify(data))
    seed = hexlify(Mnemonic.to_seed(code, passphrase='TREZOR'))
    print 'input    : %s (%d bits)' % (data, len(data) * 4)
    print 'mnemonic : %s (%d words)' % (code, len(code.split(' ')))
    print 'seed     : %s (%d bits)' % (seed, len(seed) * 4)
    print
    lst.append((data, code, seed))


if __name__ == '__main__':
    out = {}

    for lang in Mnemonic.list_languages():
        mnemo = Mnemonic(lang)
        out[lang] = []

        # Generate corner cases
        data = []
        for l in range(16, 32 + 1, 8):
            for b in ['00', '7f', '80', 'ff']:
                process(b * l, out[lang])

        # Generate random seeds
        for i in range(12):
            data = hexlify(''.join(
                chr(choice(range(0, 256))) for _ in range(8 * (i % 3 + 2))))
            process(data, out[lang])
    def test_reset_device(self):

        # No PIN, no passphrase
        external_entropy = b"zlutoucky kun upel divoke ody" * 2
        strength = 128

        ret = self.client.call_raw(
            proto.ResetDevice(
                display_random=False,
                strength=strength,
                passphrase_protection=False,
                pin_protection=False,
                language="english",
                label="test",
            )
        )

        assert isinstance(ret, proto.ButtonRequest)
        self.client.debug.press_yes()
        ret = self.client.call_raw(proto.ButtonAck())

        # Provide entropy
        assert isinstance(ret, proto.EntropyRequest)
        internal_entropy = self.client.debug.read_reset_entropy()
        ret = self.client.call_raw(proto.EntropyAck(entropy=external_entropy))

        # Generate mnemonic locally
        entropy = generate_entropy(strength, internal_entropy, external_entropy)
        expected_mnemonic = Mnemonic("english").to_mnemonic(entropy)

        mnemonic = []
        for _ in range(strength // 32 * 3):
            assert isinstance(ret, proto.ButtonRequest)
            mnemonic.append(self.client.debug.read_reset_word())
            self.client.debug.press_yes()
            self.client.call_raw(proto.ButtonAck())

        mnemonic = " ".join(mnemonic)

        # Compare that device generated proper mnemonic for given entropies
        assert mnemonic == expected_mnemonic

        mnemonic = []
        for _ in range(strength // 32 * 3):
            assert isinstance(ret, proto.ButtonRequest)
            mnemonic.append(self.client.debug.read_reset_word())
            self.client.debug.press_yes()
            resp = self.client.call_raw(proto.ButtonAck())

        assert isinstance(resp, proto.Success)

        mnemonic = " ".join(mnemonic)

        # Compare that second pass printed out the same mnemonic once again
        assert mnemonic == expected_mnemonic

        # Check if device is properly initialized
        resp = self.client.call_raw(proto.Initialize())
        assert resp.initialized is True
        assert resp.needs_backup is False
        assert resp.pin_protection is False
        assert resp.passphrase_protection is False

        # Do passphrase-protected action, PassphraseRequest should NOT be raised
        resp = self.client.call_raw(proto.Ping(passphrase_protection=True))
        assert isinstance(resp, proto.Success)

        # Do PIN-protected action, PinRequest should NOT be raised
        resp = self.client.call_raw(proto.Ping(pin_protection=True))
        assert isinstance(resp, proto.Success)
Example #47
0
def new_device_manual():
    err = None
    device_type = ""
    device_name = ""
    xpubs = ""
    strength = 128
    mnemonic = generate_mnemonic(strength=strength)
    if request.method == "POST":
        action = request.form["action"]
        device_type = request.form["device_type"]
        device_name = request.form["device_name"]
        if action == "newcolddevice":
            if not device_name:
                err = "Device name must not be empty"
            elif device_name in app.specter.device_manager.devices_names:
                err = "Device with this name already exists"
            xpubs = request.form["xpubs"]
            if not xpubs:
                err = "xpubs name must not be empty"
            keys, failed = Key.parse_xpubs(xpubs)
            if len(failed) > 0:
                err = "Failed to parse these xpubs:\n" + "\n".join(failed)
            if err is None:
                device = app.specter.device_manager.add_device(
                    name=device_name, device_type=device_type, keys=keys
                )
                return redirect(
                    url_for("devices_endpoint.device", device_alias=device.alias)
                )
        elif action == "newhotdevice":
            if not device_name:
                err = "Device name must not be empty"
            elif device_name in app.specter.device_manager.devices_names:
                err = "Device with this name already exists"
            if len(request.form["mnemonic"].split(" ")) not in [12, 15, 18, 21, 24]:
                err = "Invalid mnemonic entered: Must contain either: 12, 15, 18, 21, or 24 words."
            mnemo = Mnemonic("english")
            if not mnemo.check(request.form["mnemonic"]):
                err = "Invalid mnemonic entered."
            range_start = int(request.form["range_start"])
            range_end = int(request.form["range_end"])
            if range_start > range_end:
                err = "Invalid address range selected."
            if err is None:
                mnemonic = request.form["mnemonic"]
                paths = [
                    l.strip()
                    for l in request.form["derivation_paths"].split("\n")
                    if len(l) > 0
                ]
                passphrase = request.form["passphrase"]
                file_password = request.form["file_password"]
                device = app.specter.device_manager.add_device(
                    name=device_name, device_type=device_type, keys=[]
                )
                try:
                    device.setup_device(file_password, app.specter.wallet_manager)
                    device.add_hot_wallet_keys(
                        mnemonic,
                        passphrase,
                        paths,
                        file_password,
                        app.specter.wallet_manager,
                        is_testnet(app.specter.chain),
                        keys_range=[range_start, range_end],
                    )
                    return redirect(
                        url_for("devices_endpoint.device", device_alias=device.alias)
                    )
                except Exception as e:
                    handle_exception(e)
                    flash(f"Failed to setup hot wallet. Error: {e}", "error")
                    app.specter.device_manager.remove_device(
                        device,
                        app.specter.wallet_manager,
                        bitcoin_datadir=app.specter.bitcoin_datadir,
                        chain=app.specter.chain,
                    )
        elif action == "generatemnemonic":
            strength = int(request.form["strength"])
            mnemonic = generate_mnemonic(strength=strength)
    return render_template(
        "device/new_device_manual.jinja",
        device_type=device_type,
        device_name=device_name,
        xpubs=xpubs,
        mnemonic=mnemonic,
        strength=strength,
        error=err,
        specter=app.specter,
        rand=rand,
    )
Example #48
0
 def __init__(self, transport, ask_for_pin_fun, ask_for_pass_fun, passphrase_encoding):
     keepkey_TextUIMixin.__init__(self, transport)
     self.ask_for_pin_fun = ask_for_pin_fun
     self.ask_for_pass_fun = ask_for_pass_fun
     self.passphrase_encoding = passphrase_encoding
     self.__mnemonic = Mnemonic('english')
Example #49
0
class HDWallet(BaseWallet):
    """ Hierarchical Deterministic Wallet based in BIP32 (https://github.com/bitcoin/bips/blob/master/bip-0032.mediawiki)
    """
    def __init__(self,
                 *,
                 words: Optional[Any] = None,
                 language: str = 'english',
                 passphrase: bytes = b'',
                 gap_limit: int = 20,
                 word_count: int = 24,
                 directory: str = './',
                 pubsub: Optional[Any] = None,
                 reactor: Optional[Any] = None,
                 initial_key_generation: Optional[Any] = None) -> None:
        """
        :param words: words to generate the seed. It's a string with the words separated by a single space.
        If None we generate new words when starting the wallet
        :type words: string

        :param language: language of the words
        :type language: string

        :param passphrase: one more security level to generate the seed
        :type passphrase: bytes

        :param gap_limit: maximum of unused addresses in sequence
        (default value based in https://github.com/bitcoin/bips/blob/master/bip-0044.mediawiki#address-gap-limit)
        :type gap_limit: int

        :param word_count: quantity of words that are gonna generate the seed
        Possible choices are [12, 15, 18, 21, 24]
        :type word_count: int

        :param initial_key_generation: number of keys that will be generated in the initialization
        If not set we make it equal to gap_limit
        :type initial_key_generation: int

        :raises ValueError: Raised on invalid word_count
        """
        super().__init__(directory=directory, pubsub=pubsub, reactor=reactor)

        # Dict[string(base58), BIP32Key]
        self.keys: Dict[str, Any] = {}

        # Last index that the address was shared
        # We use this index to know which address should be shared with the user
        # This index together with last_generated_index show us if the gap limit was achieved
        self.last_shared_index = 0

        # Last index that the address was generated
        self.last_generated_index = 0

        # Maximum gap between indexes of last generated address and last used address
        self.gap_limit = gap_limit

        # XXX Should we  save this data in the object?
        self.language = language
        self.words = words
        self.passphrase = passphrase
        self.mnemonic = None

        # Used in admin frontend to know which wallet is being used
        self.type = self.WalletType.HD

        # Validating word count
        if word_count not in WORD_COUNT_CHOICES:
            raise ValueError(
                'Word count ({}) is not one of the options {}.'.format(
                    word_count, WORD_COUNT_CHOICES))
        self.word_count = word_count

        # Number of keys that will be generated in the initialization
        self.initial_key_generation = initial_key_generation or gap_limit

    def _manually_initialize(self):
        """ Create words (if is None) and start seed and master node
            Then we generate the first addresses, so we can check if we already have transactions
        """
        self.mnemonic = Mnemonic(self.language)

        if not self.words:
            # Initialized but still locked
            return

        # Validate words first
        self.validate_words()

        assert isinstance(self.passphrase,
                          bytes), 'Passphrase must be in bytes'

        # Master seed
        seed = self.mnemonic.to_seed(self.words,
                                     self.passphrase.decode('utf-8'))

        # Master node
        from pycoin.networks.registry import network_for_netcode
        _register_pycoin_networks()
        network = network_for_netcode('htr')
        key = network.keys.bip32_seed(seed)

        # Until account key should be hardened
        # Chain path = 44'/0'/0'/0
        # 44' (hardened) -> BIP44
        # 280' (hardened) -> Coin type (280 = hathor)
        # 0' (hardened) -> Account
        # 0 -> Chain
        self.chain_key = key.subkey_for_path('44H/280H/0H/0')

        for key in self.chain_key.children(self.initial_key_generation, 0,
                                           False):
            self._key_generated(key, key.child_index())

    def get_private_key(self, address58: str) -> 'EllipticCurvePrivateKey':
        """ We get the private key bytes and generate the cryptography object

            :param address58: address in base58
            :type address58: string

            :return: Private key object.
            :rtype: :py:class:`cryptography.hazmat.primitives.asymmetric.ec.EllipticCurvePrivateKey`
        """
        return self.keys[address58]

    def generate_new_key(self, index):
        """ Generate a new key in the tree at defined index
            We add this new key to self.keys and set last_generated_index

            :param index: index to generate the key
            :type index: int
        """
        new_key = self.chain_key.subkey(index)
        self._key_generated(new_key, index)

    def _key_generated(self, key, index):
        """ Add generated key to self.keys and set last_generated_index

            :param key: generated key of hd wallet
            :type key: pycoin.key.Key.Key

            :param index: index to generate the key
            :type index: int
        """
        self.keys[self.get_address(key)] = key
        self.last_generated_index = index

    def get_address(self, new_key):
        return new_key.address()

    def get_key_at_index(self, index):
        """ Return the key generated by the index in the parameter

            :param index: index to return the key
            :type index: int
        """
        return self.chain_key.subkey(index)

    def tokens_received(self, address58: str) -> None:
        """ Method called when the wallet receive new tokens

            If the gap limit is not yet achieved we generate more keys

            :param address58: address that received the token in base58
            :type address58: string
        """
        received_key = self.keys[address58]

        # If the gap now is less than the limit, we generate the new keys until the limit
        # Because we might be in sync phase, so we need those keys pre generated
        diff = self.last_generated_index - received_key.child_index()
        if (self.gap_limit - diff) > 0:
            for _ in range(self.gap_limit - diff):
                self.generate_new_key(self.last_generated_index + 1)

        # Last shared index should be at least the index after the received one
        self.last_shared_index = max(self.last_shared_index,
                                     received_key.child_index() + 1)

    def get_unused_address(self, mark_as_used: bool = True) -> str:
        """ Return an address that is not used yet

            :param mark_as_used: if True we consider that this address is already used
            :type mark_as_used: bool

            :return: unused address in base58
            :rtype: string
        """
        if self.last_shared_index != self.last_generated_index:
            # Only in case we are not yet in the gap limit
            if mark_as_used:
                self.last_shared_index += 1
        else:
            if mark_as_used:
                self.publish_update(HathorEvents.WALLET_GAP_LIMIT,
                                    limit=self.gap_limit)

        key = self.get_key_at_index(self.last_shared_index)
        return self.get_address(key)

    def is_locked(self) -> bool:
        """ Return if wallet is currently locked
            The wallet is locked if self.words is None

            :return: if wallet is locked
            :rtype: bool
        """
        return self.words is None

    def lock(self):
        """ Lock the wallet
            Set all parameters to default values
        """
        self.words = None
        self.keys = {}
        self.passphrase = b''
        self.language = ''
        self.unspent_txs = {}
        self.spent_txs = []
        self.balance = 0
        self.last_shared_index = 0
        self.last_generated_index = 0

    def unlock(self,
               tx_storage,
               words=None,
               passphrase=b'',
               language='english'):
        """ Unlock the wallet
            Set all parameters to initialize the wallet and load the txs

            :param tx_storage: storage from where I should load the txs
            :type tx_storage: :py:class:`hathor.transaction.storage.transaction_storage.TransactionStorage`

            :param words: words to generate the seed. It's a string with the words separated by a single space.
            If None we generate new words when starting the wallet
            :type words: string

            :param language: language of the words
            :type language: string

            :param passphrase: one more security level to generate the seed
            :type passphrase: bytes

            :return: hd wallet words. Generated in this method or passed as parameter
            :rtype: string
        """
        self.language = language
        if not words:
            # Decide to choose words automatically
            # Can be a different language than self.mnemonic
            m = Mnemonic(self.language)
            # We can't pass the word_count to generate method, only the strength
            # Multiplying by 10.67 gives the result we expect
            words = m.generate(strength=int(self.word_count * 10.67))
        self.words = words
        self.passphrase = passphrase
        self._manually_initialize()
        self.load_txs(tx_storage)
        return words

    def load_txs(self, tx_storage):
        """ Load all saved txs to fill the wallet txs

            :param tx_storage: storage from where I should load the txs
            :type tx_storage: :py:class:`hathor.transaction.storage.transaction_storage.TransactionStorage`
        """
        for tx in tx_storage._topological_sort():
            self.on_new_tx(tx)

    def validate_words(self):
        """ Validate if set of words is valid
            If words is None or is not valid we raise error

            :raises InvalidWords: when the words are invalid
        """
        if not self.words or not self.mnemonic.check(self.words):
            raise InvalidWords

    def get_input_aux_data(self, data_to_sign: bytes,
                           private_key: 'Key') -> Tuple[bytes, bytes]:
        """ Sign the data to be used in input and get public key compressed in bytes

            :param data_to_sign: Data to be signed
            :type data_to_sign: bytes

            :param private_key: private key to sign data
            :type private_key: pycoin.key.Key.Key

            :return: public key compressed in bytes and signature
            :rtype: tuple[bytes, bytes]
        """
        prehashed_msg = hashlib.sha256(
            hashlib.sha256(data_to_sign).digest()).digest()
        signature = private_key.sign(prehashed_msg)
        return private_key.sec(), signature
Example #50
0
 def test_expand(self):
     m = Mnemonic("english")
     self.assertEqual("access", m.expand("access"))
     self.assertEqual(
         "access access acb acc act action", m.expand("access acce acb acc act acti")
     )
Example #51
0
 def set_passphrase(self, passphrase):
     self.passphrase = Mnemonic.normalize_string(passphrase)
Example #52
0
    def test_detection(self):
        self.assertEqual("english", Mnemonic.detect_language("security"))

        with self.assertRaises(Exception):
            Mnemonic.detect_language("xxxxxxx")
Example #53
0
 def set_mnemonic(self, mnemonic):
     self.mnemonic = Mnemonic.normalize_string(mnemonic).split(' ')
    def test_reset_device_skip_backup(self, client):
        ret = client.call_raw(
            proto.ResetDevice(
                display_random=False,
                strength=self.strength,
                passphrase_protection=False,
                pin_protection=False,
                language="english",
                label="test",
                skip_backup=True,
            ))

        assert isinstance(ret, proto.ButtonRequest)
        client.debug.press_yes()
        ret = client.call_raw(proto.ButtonAck())

        # Provide entropy
        assert isinstance(ret, proto.EntropyRequest)
        internal_entropy = client.debug.read_reset_entropy()
        ret = client.call_raw(proto.EntropyAck(entropy=self.external_entropy))
        assert isinstance(ret, proto.Success)

        # Check if device is properly initialized
        ret = client.call_raw(proto.Initialize())
        assert ret.initialized is True
        assert ret.needs_backup is True
        assert ret.unfinished_backup is False
        assert ret.no_backup is False

        # Generate mnemonic locally
        entropy = generate_entropy(self.strength, internal_entropy,
                                   self.external_entropy)
        expected_mnemonic = Mnemonic("english").to_mnemonic(entropy)

        # start Backup workflow
        ret = client.call_raw(proto.BackupDevice())

        mnemonic = []
        for _ in range(self.strength // 32 * 3):
            assert isinstance(ret, proto.ButtonRequest)
            mnemonic.append(client.debug.read_reset_word())
            client.debug.press_yes()
            client.call_raw(proto.ButtonAck())

        mnemonic = " ".join(mnemonic)

        # Compare that device generated proper mnemonic for given entropies
        assert mnemonic == expected_mnemonic

        mnemonic = []
        for _ in range(self.strength // 32 * 3):
            assert isinstance(ret, proto.ButtonRequest)
            mnemonic.append(client.debug.read_reset_word())
            client.debug.press_yes()
            ret = client.call_raw(proto.ButtonAck())

        assert isinstance(ret, proto.Success)

        mnemonic = " ".join(mnemonic)

        # Compare that second pass printed out the same mnemonic once again
        assert mnemonic == expected_mnemonic

        # start backup again - should fail
        ret = client.call_raw(proto.BackupDevice())
        assert isinstance(ret, proto.Failure)
def get_cwid_from_mnemonic(words):

    # print("\nMnemonic:", words)

    entropy = Mnemonic('english').to_entropy(words)
    # print("Entropy:", entropy.hex())

    cborEnt = cbor.dumps(bytes(entropy))
    # print("Serialised:", cborEnt.hex(), "\n")

    seed = hashlib.blake2b(cborEnt, digest_size=32)
    # print("Seed:", seed.hexdigest())

    cborSeed = cbor.dumps(seed.digest())
    # print("Serialised:", cborSeed.hex(), "\n")

    passPhrase = ''
    # print("Spending pass:"******"Serialised:", passPhrase.hex())

    seedBuf = cbor.dumps(cborSeed)

    hashedSeed = hashlib.blake2b(seedBuf, digest_size=32)
    salt = cbor.dumps(hashedSeed.digest())
    # print("Salt:", salt.hex())

    hashedPass = scrypt.hash(passPhrase, salt, buflen=32)
    # print("Pass:"******"14|8|1|" + base64.standard_b64encode(hashedPass).decode() + "|" + base64.standard_b64encode(
        salt).decode()
    encryptedPass = cbor.dumps(encryptedPass.encode('utf-8'))
    # print("Encrypted Pass:"******"Base64-ed:", base64.standard_b64encode(encryptedPass).decode(), "\n")

    for i in range(5, 1000):
        buf = hmac.new(cborSeed, b'Root Seed Chain %d' % i, hashlib.sha512).digest()
        buf_l, buf_r = buf[:32], buf[32:]
        if hashlib.sha512(buf_l).digest()[31] & 32 == 0:
            # print(b'Root Seed Chain %d' % i)
            bip32 = ed25519.SigningKey(buf_l)
            break

    # print("SecretKey:", buf_l.hex())
    # print("ChainCode:", buf_r.hex())

    xpub = bip32.vk_s + buf_r
    # print("XPub:", xpub.hex())

    addrType = 0
    addrAttributes = {}
    addrRoot = [
        addrType,
        [addrType, xpub],
        addrAttributes
    ]

    addrRoot = cbor.dumps(addrRoot)
    # print("addrRoot:", addrRoot.hex())

    sha3 = hashlib.sha3_256(addrRoot)
    # print("SHA3:", sha3.hexdigest())

    addrRoot = hashlib.blake2b(sha3.digest(), digest_size=28)
    # print("Blake2b:", addrRoot.hexdigest())

    abstractHash = addrRoot.digest()
    address = [
        abstractHash,
        addrAttributes,
        addrType
    ]
    address = cbor.dumps(address)
    crc = binascii.crc32(address)
    taggedAddress = cbor.Tag(24, address)
    cwid = cbor.dumps([taggedAddress, crc])
    cwid = base58.b58encode(cwid)
    # print("CwID:", cwid.decode(), "\n")
    return cwid.decode()
Example #56
0
 def use_mnemonic(self, mnemonic: str) -> None:
     """Use the provided mnemonic to respond to device.
     Only applies to T1, where device prompts the host for mnemonic words."""
     self.mnemonic = Mnemonic.normalize_string(mnemonic).split(" ")
 def generate(self):
     seed = Mnemonic('english').generate()
     wif = seed
     address = get_cwid_from_mnemonic(seed)
     return CryptoCoin(address, wif, seed)
Example #58
0
import sys

try:
    # make the test data
    from mnemonic import Mnemonic

    eng = Mnemonic('english')

    with open('b39_data.py', 'wt') as fd:
        print('vectors = [', file=fd)
        for ln in [16, 20, 24, 28, 32]:
            for val in [b'\0', b'\xff', b'\xab\xcd', b'\xa5\xa5', b'\xAA', b'\x55']:
                vector = val * (ln // len(val))
                exp = eng.to_mnemonic(vector)
                print('(%r, %r),' % (vector, exp), file=fd)
        print(']', file=fd)

    sys.path.insert(0, '..')
    # continue to test below on desktop
    from binascii import a2b_hex

except ImportError:
    sys.path.insert(0, '')      # bugfix
    from ubinascii import unhexlify as a2b_hex
    pass

import bip39
from ngu_tests import b39_data
from ngu_tests import b39_vectors

def test_vectors():
Example #59
0
 def make_seed(self, nbits=132, entropy=1, language=None, segwit=False):
     """Create a seed"""
     from .mnemonic import Mnemonic
     t = 'segwit' if segwit else 'standard'
     s = Mnemonic(language).make_seed(t, nbits, custom_entropy=entropy)
     return s
    def test_reset_device_pin(self):
        external_entropy = b'zlutoucky kun upel divoke ody' * 2
        strength = 128

        ret = self.client.call_raw(proto.ResetDevice(display_random=True,
                                               strength=strength,
                                               passphrase_protection=True,
                                               pin_protection=True,
                                               language='english',
                                               label='test'))

        self.assertIsInstance(ret, proto.ButtonRequest)
        self.client.debug.press_yes()
        ret = self.client.call_raw(proto.ButtonAck())

        self.assertIsInstance(ret, proto.PinMatrixRequest)

        # Enter PIN for first time
        pin_encoded = self.client.debug.encode_pin('654')
        ret = self.client.call_raw(proto.PinMatrixAck(pin=pin_encoded))
        self.assertIsInstance(ret, proto.PinMatrixRequest)

        # Enter PIN for second time
        pin_encoded = self.client.debug.encode_pin('654')
        ret = self.client.call_raw(proto.PinMatrixAck(pin=pin_encoded))

        # Provide entropy
        self.assertIsInstance(ret, proto.EntropyRequest)
        internal_entropy = self.client.debug.read_reset_entropy()
        ret = self.client.call_raw(proto.EntropyAck(entropy=external_entropy))

        # Generate mnemonic locally
        entropy = generate_entropy(strength, internal_entropy, external_entropy)
        expected_mnemonic = Mnemonic('english').to_mnemonic(entropy)

        mnemonic = []
        for _ in range(strength//32*3):
            self.assertIsInstance(ret, proto.ButtonRequest)
            mnemonic.append(self.client.debug.read_reset_word())
            self.client.debug.press_yes()
            self.client.call_raw(proto.ButtonAck())

        mnemonic = ' '.join(mnemonic)

        # Compare that device generated proper mnemonic for given entropies
        self.assertEqual(mnemonic, expected_mnemonic)

        mnemonic = []
        for _ in range(strength//32*3):
            self.assertIsInstance(ret, proto.ButtonRequest)
            mnemonic.append(self.client.debug.read_reset_word())
            self.client.debug.press_yes()
            resp = self.client.call_raw(proto.ButtonAck())

        self.assertIsInstance(resp, proto.Success)

        mnemonic = ' '.join(mnemonic)

        # Compare that second pass printed out the same mnemonic once again
        self.assertEqual(mnemonic, expected_mnemonic)

        # Check if device is properly initialized
        resp = self.client.call_raw(proto.Initialize())
        self.assertTrue(resp.pin_protection)
        self.assertTrue(resp.passphrase_protection)

        # Do passphrase-protected action, PassphraseRequest should be raised
        resp = self.client.call_raw(proto.Ping(passphrase_protection=True))
        self.assertIsInstance(resp, proto.PassphraseRequest)
        self.client.call_raw(proto.Cancel())

        # Do PIN-protected action, PinRequest should be raised
        resp = self.client.call_raw(proto.Ping(pin_protection=True))
        self.assertIsInstance(resp, proto.PinMatrixRequest)
        self.client.call_raw(proto.Cancel())