Exemplo n.º 1
0
 def test_from_words_num(self):
     for test in TEST_WORDS_NUM_MAIN:
         if test["is_valid"]:
             mnemonic = Bip39MnemonicGenerator.FromWordsNumber(test["words_num"])
             self.assertEqual(len(mnemonic.split(" ")), test["words_num"])
         else:
             self.assertRaises(ValueError, Bip39MnemonicGenerator.FromWordsNumber, test["words_num"])
Exemplo n.º 2
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
    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)
    def CreateRandom(self, wallet_name, words_num):
        """ Create wallet randomly.

        Args:
            wallet_name (str)           : Wallet name
            words_num (HdWalletWordsNum): Words number, must be a HdWalletWordsNum enum

        Returns:
            HdWallet object: HdWallet object

        Raises:
            TypeError: If words number is not of HdWalletWordsNum enum
        """
        if not isinstance(words_num, HdWalletWordsNum):
            raise TypeError("Words number is not an enumerative of HdWalletWordsNum")

        mnemonic = Bip39MnemonicGenerator.FromWordsNumber(words_num)

        return self.CreateFromMnemonic(wallet_name, mnemonic)
Exemplo n.º 5
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.º 6
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.º 7
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.º 8
0
 def test_from_valid_words_num(self):
     for test_words_num in TEST_VECT_WORDS_NUM_VALID:
         mnemonic = Bip39MnemonicGenerator.FromWordsNumber(test_words_num)
         self.assertEqual(len(mnemonic.split(" ")), test_words_num)