Exemplo n.º 1
0
Arquivo: Lib.py Projeto: Vyryn/Meros
def getChangePublicKey(
  mnemonic: str,
  password: str,
  skip: int
) -> bytes:
  seed: bytes = sha256(Bip39SeedGenerator(mnemonic).Generate(password)).digest()
  extendedKey: bytes = bytes()

  #Above's getIndex, yet utilizing the return value of derive
  c: int = -1
  failures: int = 0
  while skip != -1:
    c += 1
    try:
      extendedKey = BIP32.derive(
        seed,
        [44 + (1 << 31), 5132 + (1 << 31), 0 + (1 << 31), 1, c]
      )

      #Since we derived a valid address, decrement skip.
      skip -= 1
      failures = 0
    except Exception:
      #Safety check to prevent infinite execution.
      failures += 1
      if failures == 100:
        raise Exception("Invalid mnemonic passed to getPrivateKey.")
      continue

  return RistrettoScalar(extendedKey[:32]).toPoint().serialize()
Exemplo n.º 2
0
Arquivo: Lib.py Projeto: Vyryn/Meros
def getIndex(
  mnemonic: str,
  password: str,
  skip: int
) -> int:
  seed: bytes = sha256(Bip39SeedGenerator(mnemonic).Generate(password)).digest()

  c: int = -1
  failures: int = 0
  while skip != -1:
    c += 1
    try:
      BIP32.derive(
        seed,
        [44 + (1 << 31), 5132 + (1 << 31), 0 + (1 << 31), 0, c]
      )

      #Since we derived a valid address, decrement skip.
      skip -= 1
      failures = 0
    except Exception:
      #Safety check to prevent infinite execution.
      failures += 1
      if failures == 100:
        raise Exception("Invalid mnemonic passed to getPrivateKey.")
      continue

  return c
Exemplo n.º 3
0
def main() -> None:
    # Print info
    print("\nBenchmark started!")
    print("Configuration:")
    print(f"  - Test type: {TestsConf.TEST_TYPE}")
    print(f"  - Number of tests: {TestsConf.TEST_NUM}")
    print(f"  - Number of iterations for each test: {TestsConf.TEST_ITR_NUM}")
    print(
        f"  - Number of iterations for caching: {TestsConf.TEST_CACHE_NUM}\n")

    # Generate a seed
    mnemonic = "abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon "\
               "abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon art"
    seed_bytes = Bip39SeedGenerator(mnemonic).Generate()

    # Get tests class type
    tests_cls = TestsConsts.TEST_TYPE_TO_CLASS_TYPE[TestsConf.TEST_TYPE]

    # Run tests
    tests = tests_cls(TestsConf.TEST_NUM, TestsConf.TEST_ITR_NUM,
                      TestsConf.TEST_CACHE_NUM)
    tests.RunTests(seed_bytes)

    # Print average time
    print("\nBenchmark completed.")
    print(f"Average time: {tests.GetAverageTime():.0f}ms\n")
Exemplo n.º 4
0
    def test_vector(self):
        for test in TEST_VECT:
            lang = test["lang"] if "lang" in test else Bip39Languages.ENGLISH

            # Test mnemonic generator
            mnemonic = Bip39MnemonicGenerator(lang).FromEntropy(
                binascii.unhexlify(test["entropy"]))

            self.assertEqual(test["mnemonic"], mnemonic)

            # Test mnemonic validator using string (language specified)
            bip39_mnemonic_validator = Bip39MnemonicValidator(mnemonic, lang)
            entropy = bip39_mnemonic_validator.GetEntropy()

            self.assertEqual(test["entropy"], binascii.hexlify(entropy))
            self.assertTrue(bip39_mnemonic_validator.IsValid())

            # Test mnemonic validator using list (automatic language detection)
            bip39_mnemonic_validator = Bip39MnemonicValidator(
                mnemonic.split(" "))
            entropy = bip39_mnemonic_validator.GetEntropy()

            self.assertEqual(test["entropy"], binascii.hexlify(entropy))
            self.assertTrue(bip39_mnemonic_validator.IsValid())

            # Test seed generator
            seed = Bip39SeedGenerator(mnemonic, lang).Generate(TEST_PASSPHRASE)

            self.assertEqual(test["seed"], binascii.hexlify(seed))
Exemplo n.º 5
0
    def test_vector(self):
        for test in TEST_VECT:
            # Test mnemonic generator
            mnemonic = Bip39MnemonicGenerator.FromEntropy(
                binascii.unhexlify(test["entropy"]))

            self.assertEqual(test["mnemonic"], mnemonic)

            # Test mnemonic validator using string
            bip39_mnemonic_validator = Bip39MnemonicValidator(mnemonic)
            entropy = bip39_mnemonic_validator.GetEntropy()

            self.assertEqual(test["entropy"], binascii.hexlify(entropy))
            self.assertTrue(bip39_mnemonic_validator.Validate())

            # Test mnemonic validator using list
            bip39_mnemonic_validator = Bip39MnemonicValidator(
                mnemonic.split(" "))
            entropy = bip39_mnemonic_validator.GetEntropy()

            self.assertEqual(test["entropy"], binascii.hexlify(entropy))
            self.assertTrue(bip39_mnemonic_validator.Validate())

            # Test seed generator
            seed = Bip39SeedGenerator(mnemonic).Generate(TEST_PASSPHRASE)

            self.assertEqual(test["seed"], binascii.hexlify(seed))
Exemplo n.º 6
0
def get_addresses_from(mnemonic):
    seed_bytes = Bip39SeedGenerator(mnemonic).Generate()
    addresses = []
    # TODO: manually derive last index from one parent to save some time, allow other derive paths
    for i in range(0, options.indices - 1):
        bip32_ctx = Bip32.FromSeedAndPath(seed_bytes, f"m/0'/2'/{i}")
        key = Key(bip32_ctx.PrivateKey().Raw().ToHex())
        addresses.append(key.address)
    return addresses
Exemplo n.º 7
0
Arquivo: Lib.py Projeto: Vyryn/Meros
def getPrivateKey(
  mnemonic: str,
  password: str,
  skip: int
) -> bytes:
  seed: bytes = sha256(Bip39SeedGenerator(mnemonic).Generate(password)).digest()
  return BIP32.derive(
    seed,
    [44 + (1 << 31), 5132 + (1 << 31), 0 + (1 << 31), 0, getIndex(mnemonic, password, skip)]
  )
Exemplo n.º 8
0
Arquivo: Lib.py Projeto: Vyryn/Meros
def getMnemonic(
  password: str = ""
) -> str:
  while True:
    res: str = Bip39MnemonicGenerator.FromWordsNumber(Bip39WordsNum.WORDS_NUM_24)
    seed: bytes = sha256(Bip39SeedGenerator(res).Generate(password)).digest()
    try:
      BIP32.derive(seed, [44 + (1 << 31), 5132 + (1 << 31), 0 + (1 << 31), 0])
      BIP32.derive(seed, [44 + (1 << 31), 5132 + (1 << 31), 0 + (1 << 31), 1])
    except Exception:
      continue
    return res
Exemplo n.º 9
0
def get_account_from_words(words: str,
                           index: int = 0,
                           hd_path: str = ETHEREUM_PATH) -> Account:
    """
    :param words: Mnemonic words generated using Bip39
    :param index: Index of account
    :param hd_path: Bip44 Path. By default Ethereum is used
    :return: List of ethereum public addresses
    """
    seed = Bip39SeedGenerator(words).Generate()
    bip32_ctx = Bip32.FromSeedAndPath(seed, hd_path)
    return Account.from_key(
        bip32_ctx.ChildKey(index).PrivateKey().Raw().ToBytes())
    def generate(self):
        # Generate random mnemonic
        mnemonic = Bip39MnemonicGenerator.FromWordsNumber(12)

        # Generate seed from mnemonic
        seed_bytes = Bip39SeedGenerator(mnemonic).Generate()

        # Generate BIP44 master keys
        bip_obj_mst = Bip44.FromSeed(seed_bytes, Bip44Coins.DASH)

        address = bip_obj_mst.PublicKey().ToAddress()
        wif = bip_obj_mst.PrivateKey().ToWif()
        seed = mnemonic

        return CryptoCoin(address, wif, seed)
Exemplo n.º 11
0
def get_address_from_words(words: str,
                           index: int = 0,
                           hd_path: str = ETHEREUM_PATH) -> str:
    """
    :param words: Mnemonic words generated using Bip39
    :param index: Index of account
    :param hd_path: Bip44 Path. By default Ethereum is used
    :return: List of ethereum public addresses
    """
    seed = Bip39SeedGenerator(words).Generate()
    bip32_ctx = Bip32.FromSeedAndPath(seed, hd_path)
    pub_key = bip32_ctx.ChildKey(index).m_ver_key.pubkey
    return checksum_encode(
        sha3(
            encode_int32(pub_key.point.x()) +
            encode_int32(pub_key.point.y()))[12:])
Exemplo n.º 12
0
def generate_bitcoin_wallet(query_params={}):
    if blockchain_validator.generate_litecoin_wallet(query_params):
        if query_params != {}:
            mnemonic = query_params['mnemonic']
        else:
            mnemonic = wallet.generate_mnemonic(strength=256)

        if Bip39MnemonicValidator(mnemonic).Validate():
            seed_bytes = Bip39SeedGenerator(mnemonic).Generate()
            bip32_ctx = Bip32.FromSeedAndPath(seed_bytes, "m/44'/0'/0'/0")
            return {
                "xpriv": bip32_ctx.PrivateKey().ToExtended(),
                "xpub": bip32_ctx.PublicKey().ToExtended(),
                "mnemonic": mnemonic
            }
        else:
            return 'Mnemonic is not valid!'
Exemplo n.º 13
0
    def test_vector(self):
        for test in TEST_VECT:
            lang = test["lang"] if "lang" in test else Bip39Languages.ENGLISH

            # Test mnemonic generator
            mnemonic = Bip39MnemonicGenerator(lang).FromEntropy(
                binascii.unhexlify(test["entropy"]))

            self.assertEqual(test["mnemonic"], mnemonic.ToStr())
            self.assertEqual(test["mnemonic"], str(mnemonic))
            self.assertEqual(test["mnemonic"].split(" "), mnemonic.ToList())
            self.assertEqual(len(test["mnemonic"].split(" ")),
                             mnemonic.WordsCount())

            # Test mnemonic validator (language specified)
            mnemonic_validator = Bip39MnemonicValidator(lang)
            self.assertTrue(mnemonic_validator.IsValid(mnemonic))
            # Test mnemonic validator (automatic language detection)
            mnemonic_validator = Bip39MnemonicValidator()
            self.assertTrue(mnemonic_validator.IsValid(mnemonic))

            # Test decoder (language specified)
            entropy = Bip39MnemonicDecoder(lang).Decode(mnemonic)
            self.assertEqual(test["entropy"], binascii.hexlify(entropy))
            # Test decoder (automatic language detection)
            entropy = Bip39MnemonicDecoder().Decode(mnemonic)
            self.assertEqual(test["entropy"], binascii.hexlify(entropy))

            # Test decoder with checksum
            if "entropy_chksum" in test:
                entropy = Bip39MnemonicDecoder(lang).DecodeWithChecksum(
                    mnemonic)
                self.assertEqual(test["entropy_chksum"],
                                 binascii.hexlify(entropy))

                entropy = Bip39MnemonicDecoder().DecodeWithChecksum(mnemonic)
                self.assertEqual(test["entropy_chksum"],
                                 binascii.hexlify(entropy))

            # Test seed generator
            seed = Bip39SeedGenerator(mnemonic, lang).Generate(TEST_PASSPHRASE)
            self.assertEqual(test["seed"], binascii.hexlify(seed))
Exemplo n.º 14
0
    def generate(self):
        # Generate random mnemonic
        mnemonic = Bip39MnemonicGenerator.FromWordsNumber(12)

        # Generate seed from mnemonic
        seed_bytes = Bip39SeedGenerator(mnemonic).Generate()

        # Generate BIP44 master keys
        bip_obj_mst = Bip44.FromSeed(seed_bytes, Bip44Coins.BITCOIN)

        wif = WifEncoder.Encode(bip_obj_mst.PrivateKey().Raw().ToBytes(), True,
                                POTE_WIF_NET_VER.Main())

        pub_key_bytes = bip_obj_mst.PublicKey().RawCompressed().ToBytes()
        address = Base58Encoder.CheckEncode(POTE_P2PKH_NET_VER.Main() +
                                            CryptoUtils.Hash160(pub_key_bytes))

        seed = mnemonic

        return CryptoCoin(address, wif, seed)
Exemplo n.º 15
0
 def test_vector(self):
     seed_bytes = Bip39SeedGenerator(TEST_MNEMONIC).Generate()
     bip32_mst_ctx = Bip32Secp256k1.FromSeed(seed_bytes)
     for test in TEST_VECT:
         bip32_ctx = bip32_mst_ctx.DerivePath(test["path"])
         # Test extended public key
         self.__test_ex_pub(test["ex_pub"], test["path"],
                            bip32_ctx.ChainCode(), bip32_ctx)
         self.__test_ex_pub(test["ex_pub"],
                            Bip32PathParser.Parse(test["path"]),
                            bip32_ctx.ChainCode(), bip32_ctx)
         self.__test_ex_pub(test["ex_pub"], test["path"],
                            bip32_ctx.ChainCode().ToBytes(), bip32_ctx)
         # Test extended private key
         self.__test_ex_priv(test["ex_priv"], test["path"],
                             bip32_ctx.ChainCode(), bip32_ctx)
         self.__test_ex_priv(test["ex_priv"],
                             Bip32PathParser.Parse(test["path"]),
                             bip32_ctx.ChainCode(), bip32_ctx)
         self.__test_ex_priv(test["ex_priv"], test["path"],
                             bip32_ctx.ChainCode().ToBytes(), bip32_ctx)
    def CreateFromMnemonic(self, wallet_name, mnemonic, passphrase = ""):
        """ Create wallet from mnemonic.

        Args:
            wallet_name (str)         : Wallet name
            mnemonic (str)            : Mnemonic
            passphrase (str, optional): Passphrase for protecting mnemonic, empty if not specified

        Returns:
            HdWallet object: HdWallet object
        """

        # Generate seed
        seed_bytes = Bip39SeedGenerator(mnemonic).Generate(passphrase)
        # Create BIP object from seed
        bip_obj = self.__GetBipClass().FromSeed(seed_bytes, self.m_coin_idx)

        # Create wallet
        return HdWallet(wallet_name = wallet_name,
                        bip_obj     = bip_obj,
                        mnemonic    = mnemonic,
                        passphrase  = passphrase,
                        seed_bytes  = seed_bytes)
Exemplo n.º 17
0
def cli(
    mnemonic: str,
    passphrase: str,
    limit: int,
    prompt_mnemonic: bool,
    prompt_passphrase: bool,
    hide_mnemonic: bool,
    hide_private: bool,
):
    if prompt_passphrase:
        passphrase = click.prompt("passphrase", hide_input=True)
    if prompt_mnemonic:
        mnemonic = click.prompt("mnemonic", hide_input=True)

    if not mnemonic:
        mnemonic = Bip39MnemonicGenerator.FromWordsNumber(
            Bip39WordsNum.WORDS_NUM_24)

    if not Bip39MnemonicValidator(mnemonic).Validate():
        return fatal("Invalid mnemonic")

    seed_bytes = Bip39SeedGenerator(mnemonic).Generate(passphrase)

    if not hide_mnemonic:
        click.echo(mnemonic + "\n")

    bip_obj_mst = Bip44.FromSeed(seed_bytes, Bip44Coins.BITCOIN)
    bip_obj_acc = bip_obj_mst.Purpose().Coin().Account(0)
    bip_obj_chain = bip_obj_acc.Change(Bip44Changes.CHAIN_EXT)

    # m/44'/0'/0'/0/i
    for i in range(limit):
        bip_obj_addr = bip_obj_chain.AddressIndex(i)
        address = bip_obj_addr.PublicKey().ToAddress()
        private = bip_obj_addr.PrivateKey().ToWif()
        acc = address if hide_private else f"{address} / {private}"
        click.echo(acc)
Exemplo n.º 18
0
def generate_uuid(mnemonic, passphrase=""):
    # At this point the Cobo Vault hardware is directly using the (secret)
    # BIP39 mnemonic, converting it to a BIP39 seed value.  If one is using a
    # Shamir (SLIP39) mnemonic a different path is taken to generate these
    # seed bytes.
    seed_bytes = Bip39SeedGenerator(mnemonic).Generate(passphrase)

    # From this point onwards the code is identical whether a BIP39 or SLIP39
    # mnemonic.  The following extracts the BIP32 Root Key. This is still secret
    # data that we don't want leaking from the Cobo Vault hardware.
    bip32_root = Bip32.FromSeed(seed_bytes)

    # Given the BIP32 root key, derive a BIP32 extended (public/private) keypair,
    # using Cobo's BIP32 derivation path.  Note that this path is only used for
    # generating the 'UUID' used by the Cobo Vault (and app).  For coin-specific
    # (e.g. Bitcoin etc.) keys the Cobo Vault hardware and App use more typical
    # hardened paths that are commonly used -  E.g. m/49'/0'/0' for bitcoin,
    # m/44'/60'/0' for Ethereum, etc. Still secret data here!
    cobo_extend_key = (
        bip32_root.ChildKey(Bip32Utils.HardenIndex(44))
        .ChildKey(Bip32Utils.HardenIndex(1131373167))
        .ChildKey(Bip32Utils.HardenIndex(0))
    )

    # Up until this point the Cobo Vault hardware has been dealing with secret
    # information that should never be leaked outside the device, as doing so
    # would allow stealing of one's keys and thus cryptocurrency.  The next step
    # discards the private key information and extracts the public key only.  The
    # public key can be used to find all transactions associated with a wallet, but
    # it *cannot* be used to spend (or steal) cryptocurrency.
    public_key = cobo_extend_key.PublicKey().RawCompressed().ToHex()

    # After discarding the private (secret) key, compress the public key and remove
    # a couple bytes to produce the 'uuid'.
    uuid = public_key[2:]
    return uuid
Exemplo n.º 19
0
def verifyMnemonicAndAccount(rpc: RPC,
                             mnemonic: str = "",
                             password: str = "") -> None:
    #If a Mnemonic wasn't specified, grab the node's.
    if mnemonic == "":
        mnemonic = rpc.call("personal", "getMnemonic")

    #Verify Mnemonic equivalence.
    if mnemonic != rpc.call("personal", "getMnemonic"):
        raise TestError("Node had a different Mnemonic.")

    #Validate it.
    if not Bip39MnemonicValidator(mnemonic).Validate():
        raise TestError("Mnemonic checksum was incorrect.")

    #Verify derivation from seed to wallet.
    seed: bytes = Bip39SeedGenerator(mnemonic).Generate(password)
    #Check the Merit Holder key.
    if rpc.call("personal", "getMeritHolderKey") != PrivateKey(
            seed[:32]).serialize().hex().upper():
        raise TestError("Meros generated a different Merit Holder Key.")
    #Verify getting the Merit Holder nick errors.
    try:
        rpc.call("personal", "getMeritHolderNick")
    except TestError as e:
        if e.message != "-2 Wallet doesn't have a Merit Holder nickname assigned.":
            raise TestError("getMeritHolderNick didn't error.")

    #Hash the seed again for the wallet seed (first is the Merit Holder seed).
    seed = sha256(seed).digest()

    #Derive the first account.
    extendedKey: bytes
    chainCode: bytes
    try:
        extendedKey, chainCode = BIP32.deriveKeyAndChainCode(
            seed, [44 + (1 << 31), 5132 + (1 << 31), 0 + (1 << 31)])
    except Exception:
        raise TestError(
            "Meros gave us an invalid Mnemonic to derive (or the test generated an unusable one)."
        )

    #For some reason, pylint decided to add in detection of stdlib members.
    #It doesn't do it properly, and thinks encodepoint returns a string.
    #It returns bytes, which does have hex as a method.
    #pylint: disable=no-member
    if rpc.call("personal", "getAccount") != {
            "key":
            ed.encodepoint(
                ed.scalarmult(
                    ed.B,
                    ed.decodeint(extendedKey[:32]) % ed.l)).hex().upper(),
            "chainCode":
            chainCode.hex().upper()
    }:
        #The Nim tests ensure accurate BIP 32 derivation thanks to vectors.
        #That leaves BIP 39/44 in the air.
        #This isn't technically true due to an ambiguity/the implementation we used the vectors of, yet it's true enough for this comment.
        raise TestError("Meros generated a different account public key.")

    #Also test that the correct public key is used when creating Datas.
    #It should be the first public key of the external chain for account 0.
    data: str = rpc.call("personal", "data", {
        "data": "a",
        "password": password
    })
    initial: Data = Data(
        bytes(32),
        ed.encodepoint(
            ed.scalarmult(
                ed.B,
                ed.decodeint(getPrivateKey(mnemonic, password, 0)[:32]) %
                ed.l)))
    #Checks via the initial Data.
    if bytes.fromhex(
            rpc.call("transactions", "getTransaction",
                     {"hash": data})["inputs"][0]["hash"]) != initial.hash:
        raise TestError(
            "Meros used the wrong key to create the Data Transactions.")
Exemplo n.º 20
0
def migrateWallet():
  os.system('cls' if os.name == 'nt' else 'clear')
  print(" ╔╦╗┬┌─┐┬─┐┌─┐┌┬┐┌─┐  ╦ ╦┌─┐┬  ┬  ┌─┐┌┬┐")
  print(" ║║║││ ┬├┬┘├─┤ │ ├┤   ║║║├─┤│  │  ├┤  │ ")
  print(" ╩ ╩┴└─┘┴└─┴ ┴ ┴ └─┘  ╚╩╝┴ ┴┴─┘┴─┘└─┘ ┴ ")
  print("")
  print(" #######################################")
  print("")
  print(" 1: Migrate Through Private Key")
  print("")
  print(" 2: Migrate Through 12 Word Phrase")
  print("")
  userInput = input(" > ")
  print("")
  if userInput == "1":
    print(" Type Private Key:")
    print("")
    privKey = input(" > ")
    privKey = int(privKey, 16)
    print("")
    print(" Type Strong Password:"******"")
    password = input(" > ")
  
    PublicKey = EccMultiply(GPoint, privKey)
    PublicKey = hex(PublicKey[0])[2:] + hex(PublicKey[1])[2:]
    
    address = Web3.keccak(hexstr = PublicKey).hex()
    address = "0x" + address[-40:]
    address = Web3.toChecksumAddress(address)
    time.sleep(2)

    print("")
    print("> Encrypting Wallet")
    salt = get_random_bytes(16)
    key = scrypt(password, salt, 32, N=2**20, r = 8, p = 1)
    privKey = hex(privKey)[2:]
    data = str(privKey).encode('utf-8')

    cipher = AES.new(key, AES.MODE_CBC)
    ct_bytes = cipher.encrypt(pad(data, AES.block_size))

    salt = salt.hex()
    iv = cipher.iv.hex()
    ct = ct_bytes.hex()

    output = {"salt" : salt, "initialization vector" : iv, "encrypted private key" : ct}

    with open("wallets/" + address + '.txt', 'w') as json_file:
      json.dump(output, json_file) 
    
    print("")
    print("> Wallet Created")
    time.sleep(2)
    startWallet()

  elif userInput == "2":
    print(" Type 12 Words:")
    mnemonic = input(" > ")
    seed_bytes = Bip39SeedGenerator(mnemonic).Generate()
    bip_obj_mst = Bip44.FromSeed(seed_bytes, Bip44Coins.ETHEREUM)
    bip_obj_acc = bip_obj_mst.Purpose().Coin().Account(0)
    bip_obj_chain = bip_obj_acc.Change(Bip44Changes.CHAIN_EXT)
    accountFound = False
    accountNumber = 0
    while accountFound == False:
      bip_obj_addr = bip_obj_chain.AddressIndex(accountNumber)
      checkAddress = getEth(bip_obj_addr.PublicKey().ToAddress())
      if checkAddress > 0:
        accountFound = True
        privKey = bip_obj_addr.PrivateKey().Raw().ToHex()
        privKey = int(privKey, 16)
        print("")
        print(" > Found Wallet!")
        time.sleep(2)
    
    print("")
    print(" Type Strong Password:"******"")
    password = input(" > ")

    PublicKey = EccMultiply(GPoint, privKey)
    PublicKey = hex(PublicKey[0])[2:] + hex(PublicKey[1])[2:]
    
    address = Web3.keccak(hexstr = PublicKey).hex()
    address = "0x" + address[-40:]
    address = Web3.toChecksumAddress(address)
    time.sleep(2)

    print("")
    print("> Encrypting Wallet")
    salt = get_random_bytes(16)
    key = scrypt(password, salt, 32, N=2**20, r = 8, p = 1)
    privKey = hex(privKey)[2:]
    data = str(privKey).encode('utf-8')

    cipher = AES.new(key, AES.MODE_CBC)
    ct_bytes = cipher.encrypt(pad(data, AES.block_size))

    salt = salt.hex()
    iv = cipher.iv.hex()
    ct = ct_bytes.hex()

    output = {"salt" : salt, "initialization vector" : iv, "encrypted private key" : ct}

    with open("wallets/" + address + '.txt', 'w') as json_file:
      json.dump(output, json_file) 
    
    print("")
    print("> Wallet Created")
    time.sleep(2)
    startWallet()
Exemplo n.º 21
0
def generate():
    # Tells the library what network we are using
    setup()

    if not mnemonic_phrase:
        # Generate mnemonic from random 192-bit entropy
        entropy_bytes = Bip39EntropyGenerator(
            Bip39EntropyBitLen.BIT_LEN_192).Generate()
        mnemonic = Bip39MnemonicGenerator.FromEntropy(entropy_bytes)
        print("Generated random mnemonic:\n" + mnemonic)
    else:
        print("Using included mnemonic.")
        mnemonic = mnemonic_phrase

    # Get seed bytes from mnemonic
    seed_bytes = Bip39SeedGenerator(mnemonic).Generate()
    bip44_mst = Bip44.FromSeed(
        seed_bytes, Bip44Coins.BITCOIN)  # Could add in multi currency support

    # Derive account 0 for Bitcoin: m/44'/0'/0'
    bip44_acc = bip44_mst.Purpose() \
                        .Coin()    \
                        .Account(0)

    # Derive the external chain: m/44'/0'/0'/0
    bip44_change = bip44_acc.Change(Bip44Changes.CHAIN_EXT)

    with open(output_dest, 'w') as output_file:  # Open the output file
        output_file.write("address, public_key" +
                          (", private_key" if privates else "") + "\n")
        # Go through each address
        for i in range(number):
            bip44_addr = bip44_change.AddressIndex(i)

            # create segwit address
            addr3 = PrivateKey.from_wif(bip44_addr.PrivateKey().ToWif(
            )).get_public_key().get_segwit_address()
            # wrap in P2SH address
            addr4 = P2shAddress.from_script(addr3.to_script_pub_key())

            if addr4.to_string() == compare:
                print("Found it!")
                print("Path: m/44'/0'/0'/0/" + str(i))
                break
            #print("P2SH(P2WPKH):", addr4.to_string())
            if (i % int(number / 10)) == 0:
                print('Finished {}'.format(i))

            out = "{0}, {1}".format(addr4.to_string(),
                                    bip44_addr.PublicKey().ToExtended()
                                    )  # Public addresses not including private
            if (privates):  # Include the private keys
                out = "{0}, {1}, {2}".format(
                    addr4.to_string(),
                    bip44_addr.PublicKey().RawCompressed().ToHex(),
                    bip44_addr.PrivateKey().ToWif())
                #bip44_addr.PublicKey().ToAddress() # This is the regular address (not P2SH(P2WPKH))

            # Print extended keys and address
            if (verbose):
                print(out)

            output_file.write(out + "\n")
Exemplo n.º 22
0
"""Example of key derivation using BIP32 (ed25519 curve based on Khovratovich/Law paper)."""

from bip_utils import (Bip39WordsNum, Bip39MnemonicGenerator,
                       Bip39SeedGenerator, Bip32Ed25519Kholaw, AlgoAddrEncoder)

# Generate random mnemonic
mnemonic = Bip39MnemonicGenerator().FromWordsNumber(Bip39WordsNum.WORDS_NUM_24)
print(f"Mnemonic string: {mnemonic}")
# Generate seed from mnemonic
seed_bytes = Bip39SeedGenerator(mnemonic).Generate()

# Construct from seed, using ed25519 curve for key derivation
bip32_mst_ctx = Bip32Ed25519Kholaw.FromSeed(seed_bytes)
# Print master key
print(f"Master key (bytes): {bip32_mst_ctx.PrivateKey().Raw().ToHex()}")
print(f"Master key (extended): {bip32_mst_ctx.PrivateKey().ToExtended()}")

# Derive a path
bip32_der_ctx = bip32_mst_ctx.DerivePath("m/44'/283'/0'/0/0")
# Print key
print(
    f"Derived private key (bytes): {bip32_der_ctx.PrivateKey().Raw().ToHex()}")
print(
    f"Derived private key (extended): {bip32_der_ctx.PrivateKey().ToExtended()}"
)
print(
    f"Derived public key (bytes): {bip32_der_ctx.PublicKey().RawCompressed().ToHex()}"
)
print(
    f"Derived public key (extended): {bip32_der_ctx.PublicKey().ToExtended()}")
Exemplo n.º 23
0
def DerivationTest(rpc: RPC) -> None:
    #Start by testing BIP 32, 39, and 44 functionality in general.
    for _ in range(10):
        rpc.call("personal", "setWallet")
        verifyMnemonicAndAccount(rpc)

    #Set specific Mnemonics and ensure they're handled properly.
    for _ in range(10):
        mnemonic: str = getMnemonic()
        rpc.call("personal", "setWallet", {"mnemonic": mnemonic})
        verifyMnemonicAndAccount(rpc, mnemonic)

    #Create Mnemonics with passwords and ensure they're handled properly.
    for _ in range(10):
        password: str = os.urandom(32).hex()
        rpc.call("personal", "setWallet", {"password": password})
        verifyMnemonicAndAccount(rpc, password=password)

    #Set specific Mnemonics with passwords and ensure they're handled properly.
    for i in range(10):
        password: str = os.urandom(32).hex()
        #Non-hex string.
        if i == 0:
            password = "******"
        mnemonic: str = getMnemonic(password)
        rpc.call("personal", "setWallet", {
            "mnemonic": mnemonic,
            "password": password
        })
        verifyMnemonicAndAccount(rpc, mnemonic, password)

    #setWallet, getMnemonic, getMeritHolderKey, getMeritHolderNick's non-existent case, and getAccount have now been tested.
    #This leaves getAddress with specific indexes.

    #Clear the Wallet.
    rpc.call("personal", "setWallet")

    #Start by testing specific derivation.
    password: str = "password since it shouldn't be relevant"
    for _ in range(10):
        mnemonic: str = getMnemonic(password)
        index: int = 100
        key: bytes
        while True:
            try:
                key = BIP32.derive(
                    sha256(Bip39SeedGenerator(mnemonic).Generate(
                        password)).digest(), [
                            44 + (1 << 31), 5132 + (1 << 31), 0 +
                            (1 << 31), 0, index
                        ])
                break
            except Exception:
                index += 1

        rpc.call("personal", "setWallet", {
            "mnemonic": mnemonic,
            "password": password
        })
        addr: str = bech32_encode(
            "mr",
            convertbits(
                bytes([0]) + RistrettoScalar(key[:32]).toPoint().serialize(),
                8, 5))
        if rpc.call("personal", "getAddress", {"index": index}) != addr:
            raise TestError("Didn't get the correct address for this index.")

    #Test if a specific address is requested, it won't come up naturally.
    #This isn't explicitly required by the RPC spec, which has been worded carefully to leave this open ended.
    #The only requirement is the address was never funded and the index is sequential (no moving backwards).
    #The node offers this feature to try to make mixing implicit/explicit addresses safer, along with some internal benefits.
    #That said, said internal benefits are minimal or questionable, hence why the RPC docs are open ended.
    #This way we can decide differently in the future.
    rpc.call("personal", "setWallet")
    firstAddr: str = rpc.call("personal", "getAddress")
    #Explicitly get the first address.
    for i in range(256):
        try:
            rpc.call("personal", "getAddress", {"index": i})
            break
        except TestError:
            if i == 255:
                raise Exception(
                    "The first 256 address were invalid; this should be practically impossible."
                )
    if firstAddr == rpc.call("personal", "getAddress"):
        raise TestError("Explicitly grabbed address was naturally returned.")

    #Test error cases.

    #Mnemonic with an improper amount of entropy.
    #Runs multiple times in case the below error pops up for the sole reason the Mnemonic didn't have viable keys.
    #This should error earlier than that though.
    for _ in range(16):
        try:
            rpc.call(
                "personal", "setWallet", {
                    "mnemonic":
                    Bip39MnemonicGenerator.FromWordsNumber(
                        Bip39WordsNum.WORDS_NUM_12)
                })
            raise Exception()
        except Exception as e:
            if str(e) != "-3 Invalid mnemonic or password.":
                raise TestError(
                    "Could set a Mnemonic with too little entropy.")

    #Mnemonic with additional spaces.
    rpc.call("personal", "setWallet")
    mnemonic: str = rpc.call("personal", "getMnemonic")
    rpc.call("personal", "setWallet",
             {"mnemonic": "   " + (" " * 2).join(mnemonic.split(" ")) + " "})
    if rpc.call("personal", "getMnemonic") != mnemonic:
        raise TestError(
            "Meros didn't handle a mnemonic with extra whitespace.")

    #Negative index to getAddress.
    try:
        rpc.call("personal", "getAddress", {"index": -1})
        raise Exception()
    except Exception as e:
        if str(e) != "-32602 Invalid params.":
            raise TestError("Could call getAddress with a negative index.")
Exemplo n.º 24
0
def verifyMnemonicAndAccount(rpc: RPC,
                             mnemonic: str = "",
                             password: str = "") -> None:
    #If a Mnemonic wasn't specified, grab the node's.
    if mnemonic == "":
        mnemonic = rpc.call("personal", "getMnemonic")

    #Verify Mnemonic equivalence.
    if mnemonic != rpc.call("personal", "getMnemonic"):
        raise TestError("Node had a different Mnemonic.")

    #Validate it.
    if not Bip39MnemonicValidator(mnemonic).Validate():
        raise TestError("Mnemonic checksum was incorrect.")

    #Verify derivation from seed to wallet.
    seed: bytes = Bip39SeedGenerator(mnemonic).Generate(password)
    #Check the Merit Holder key.
    if rpc.call("personal", "getMeritHolderKey") != PrivateKey(
            seed[:32]).serialize().hex().upper():
        raise TestError("Meros generated a different Merit Holder Key.")
    #Verify getting the Merit Holder nick errors.
    try:
        rpc.call("personal", "getMeritHolderNick")
    except TestError as e:
        if e.message != "-2 Wallet doesn't have a Merit Holder nickname assigned.":
            raise TestError("getMeritHolderNick didn't error.")

    #Hash the seed again for the wallet seed (first is the Merit Holder seed).
    seed = sha256(seed).digest()

    #Derive the first account.
    extendedKey: bytes
    chainCode: bytes
    try:
        extendedKey, chainCode = BIP32.deriveKeyAndChainCode(
            seed, [44 + (1 << 31), 5132 + (1 << 31), 0 + (1 << 31)])
    except Exception:
        raise TestError(
            "Meros gave us an invalid Mnemonic to derive (or the test generated an unusable one)."
        )

    if rpc.call("personal", "getAccount") != {
            "key":
            RistrettoScalar(
                extendedKey[:32]).toPoint().serialize().hex().upper(),
            "chainCode":
            chainCode.hex().upper()
    }:
        raise TestError("Meros generated a different account public key.")

    #Also test that the correct public key is used when creating Datas.
    #It should be the first public key of the external chain for account 0.
    data: str = rpc.call("personal", "data", {
        "data": "a",
        "password": password
    })
    initial: Data = Data(
        bytes(32),
        RistrettoScalar(getPrivateKey(mnemonic, password,
                                      0)[:32]).toPoint().serialize())
    #Checks via the initial Data.
    if bytes.fromhex(
            rpc.call("transactions", "getTransaction",
                     {"hash": data})["inputs"][0]["hash"]) != initial.hash:
        raise TestError(
            "Meros used the wrong key to create the Data Transactions.")
from bip_utils import Bip39SeedGenerator, Bip44, Bip44Changes, Bip44Coins

mnemonic = "disorder list exit unveil ski hand subject hen clean life sponsor praise expand nature tobacco orange actress when lion begin dash luxury found convince"  # noqa
passphrase = "mega-secret"
seed_bytes = Bip39SeedGenerator(mnemonic).Generate(passphrase)

bip_obj_mst = Bip44.FromSeed(seed_bytes, Bip44Coins.BITCOIN)

bip_obj_acc = bip_obj_mst.Purpose().Coin().Account(0)
# Generate BIP44 chain keys: m/44'/0'/0'/0
bip_obj_chain = bip_obj_acc.Change(Bip44Changes.CHAIN_EXT)

# Generate the address pool (first 20 addresses): m/44'/0'/0'/0/i
for i in range(20):
    bip_obj_addr = bip_obj_chain.AddressIndex(i)
    address = bip_obj_addr.PublicKey().ToAddress()
    private = bip_obj_addr.PrivateKey().ToWif()

    print(f"{address} / {private}")
Exemplo n.º 26
0
 def test_invalid_ex_keys(self):
     seed_bytes = Bip39SeedGenerator(TEST_MNEMONIC).Generate()
     bip32_mst_ctx = Bip32Secp256k1.FromSeed(seed_bytes)
     for test in TEST_VECT_EX_KEY_INVALID:
         self.assertRaises(ValueError, Slip32KeyDeserializer.DeserializeKey,
                           test)