Skip to content

Commit

Permalink
v2.2
Browse files Browse the repository at this point in the history
  • Loading branch information
FahsSani committed Apr 23, 2024
1 parent d03e133 commit c4a2757
Show file tree
Hide file tree
Showing 16 changed files with 1,213 additions and 955 deletions.
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
__pycache__
library
.idea
.idea
venv
11 changes: 6 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,17 +18,18 @@ This multifaceted tool empowers you to effortlessly create secure mnemonic seed

## Features

- **Dice Roll To Mnemonic:**
- **Dice Roll:**
1. Physical Dice or Coin Toss: You have the flexibility to roll physical dice or conduct a coin toss and input the resulting data as either binary (1 or 0) or numbers (1 to 6). This method ensures absolute randomness for generating your mnemonic seed phrase.
2. Dice Roll From Entropy: For a quicker approach, the program can generate random dice rolls for you. The automated dice roll function guarantees the essential randomness needed for a secure seed phrase.
3. Mnemonic Seed Generation: After collecting the dice roll data, the program seamlessly proceeds to generate a valid checksum and creates a BIP39 mnemonic seed phrase. This seed phrase forms the cornerstone for generating Bitcoin private keys and public addresses.
4. Mnemonic Code Converter: The generated mnemonic seed phrase is then processed through the Mnemonic Code Converter, capable of generating BIP39 private keys and public addresses for all script types: Legacy (P2PKH), Nested SegWit (P2SH-P2WPKH), Native SegWit (P2WPKH), and Taproot (P2TR).
- **Seed To Mnemonic:**
- **Mnemonic Converter:**
1. Generate Hex Seed From Entropy: The program can generate a Hex seed from entropy. The automated function guarantees the essential randomness required for secure seed generation.
2. Mnemonic Seed Generation: After collecting the Hex seed, the program seamlessly proceeds to generate a valid checksum and creates a BIP39 mnemonic seed phrase.
3. Own Mnemonic Seed Phrase: You have the option to enter your own mnemonic seed phrase into the program.
4. Mnemonic Code Converter: The generated mnemonic seed phrase is then processed through the Mnemonic Code Converter, capable of generating BIP39 private keys and public addresses for all script types: Legacy (P2PKH), Nested SegWit (P2SH-P2WPKH), Native SegWit (P2WPKH), and Taproot (P2TR).
- **QR Code Generator:** A built in QR code generator from text.
- **BIP85 Generator:** Generate BIP85 Child Keys from your own Mnemonic Seed Phrase or using seeds generated with the tools above, then specify the numbers of words and number of Child Keys using the index number.
- **QR Code Generator:** A built-in QR code generator from text.


## Prerequisites
Expand Down Expand Up @@ -67,7 +68,7 @@ Follow these steps to use the Roll2Mnemonic:
1. Clone or download this repository to your local machine.
2. Ensure you have Python 3.11.x or above installed.
3. Install the necessary Python libraries listed in requirements.txt
4. Launch start.py to initiate the code.
4. Launch main.py to initiate the code.


## Offline Usage:
Expand Down Expand Up @@ -109,7 +110,7 @@ https://pip.pypa.io/en/stable/installation/
pip download -r requirements.txt -d wheelhouse
```

d. Copy the Python and pip packages you downloaded earlier and the folder Roll2Mnemonic, which contains the repository and the subfolder Wheelhouse, into a USB stick and transfer them to your offline computer.
d. Copy the Python and pip packages you downloaded earlier and the folder Roll2Mnemonic, which contains the repository and the sub-folder Wheelhouse, into a USB stick and transfer them to your offline computer.

e. Install the Python and pip packages then, in a terminal, navigate to the Roll2Mnemonic folder:

Expand Down
1 change: 1 addition & 0 deletions Roll2Mnemonic/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
__pycache__
Empty file added Roll2Mnemonic/__init__.py
Empty file.
72 changes: 72 additions & 0 deletions Roll2Mnemonic/bip85.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
from Roll2Mnemonic.common import *

def _decorate_path(path):
return path.replace("m/", "").replace("'", "p")

def _get_k_from_node(node):
return to_bytes_32(node.secret_exponent())

def _hmac_sha512(message_k):
return hmac.new(key=b'bip-entropy-from-k', msg=message_k, digestmod=hashlib.sha512).digest()

def _derive_k(path, xprv):
path = _decorate_path(path)
node = xprv.subkey_for_path(path)
return _get_k_from_node(node)

def bip32_xprv_to_entropy(path, xprv_string):
xprv = BTC.parse(xprv_string)
if xprv is None:
raise ValueError('ERROR: Invalid xprv')
return _hmac_sha512(_derive_k(path, xprv))

def derive_child_key(xprv_string, words, index):
path = f"83696968p/39p/0p/{words}p/{index}p"

entropy = bip32_xprv_to_entropy(path, xprv_string)

m = Mnemonic("english")
return m.to_mnemonic(entropy[: words * 4 // 3])

def bip85_generator(parent_seed_phrase, parent_passphrase, num_words, index_type, index_specific, indices_start, indices_end):
child_indices = []
parent_bip39_seed = bip39.to_seed(parent_seed_phrase, passphrase=parent_passphrase)
parent_bip32_root_key = BTC.keys.bip32_seed(parent_bip39_seed).hwif(as_private=True)

try:
if index_type == 'Specific':
index = int(index_specific)
if 0 <= index <= 2147483647:
child_indices = [index]
else:
return " Index must be between 0 and 2,147,483,647."

elif index_type == 'Range':
start_index = int(indices_start)
end_index = int(indices_end)

if 0 <= start_index <= end_index <= 2147483647:
child_indices = list(range(start_index, end_index + 1))
else:
return "\nInvalid range. Both start and end indices must be between 0 and 2,147,483,647." \
"\nStart index should be less than or equal to the end index."

except Exception as e:
return "Invalid index, only integers are allowed."

print_red(f" Parent Mnemonic Seed Phrase: {parent_seed_phrase}")
print_red(f" Parent Passphrase : {parent_passphrase}")
print_red(f" Parent BIP39 Seed : {binascii.hexlify(parent_bip39_seed).decode('utf-8')}")
print_red(f" Parent BIP32 Root Key : {parent_bip32_root_key}")
for index in child_indices:
child_key = derive_child_key(parent_bip32_root_key, num_words, index)
print()
print_blue(f" BIP85 Index Number: {index:,.0f}")
print_blue(f" BIP85 Child Key : {child_key}")

print()
print()
print_red(" To verify the data above, visit: https://iancoleman.io/bip39/")
print()

return "BIP85 Child Keys have Been Generated Successfully."
154 changes: 154 additions & 0 deletions Roll2Mnemonic/common.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,154 @@
import random
from mnemonic import Mnemonic
from mnemonic import Mnemonic as bip39
import platform
import subprocess
import keyboard
import os
import locale
import datetime
from bip32utils import BIP32Key
import hashlib
import binascii
import base58
import bech32
from hashlib import sha256
from bitcoinaddress import segwit_addr
from bitcoinaddress.key.key import Key
from bitcoinaddress.address import Address
from bitcoinutils.setup import setup
from bitcoinutils.keys import P2pkhAddress, PrivateKey, PublicKey
from art import *
import tkinter as tk
from tkinter import ttk, messagebox
import qrcode
from PIL import Image, ImageTk
from pycoin.symbols.btc import network as BTC
import hmac
from pycoin.encoding.bytes32 import from_bytes_32, to_bytes_32

# Set the locale to your preferred formatting (e.g., en_US.UTF-8)
locale.setlocale(locale.LC_ALL, 'en_US.UTF-8')

def disclaimer():
# Clear terminal
clear_terminal()

# Print a centered disclaimer notice
text1 = "* DISCLAIMER *"
print_centered_art_text(text1, 6, "Standard")

# Print disclaimer details
print_red(f"""
\n This tool is designed solely for educational purposes. Please refrain from utilizing any keys generated by this tool as actual Bitcoin private keys.
\n Modifying this code may result in generating incorrect keys and addresses.
\n Exercise caution to avoid sending bitcoin to addresses for which you lack the corresponding keys.
\n This tool simplifies the process of converting decimal and binary numbers into corresponding BIP39 mnemonic words then generates a valid mnemonic seed phrase.
\n It also provides in-depth information about the generated mnemonic seed phrase, including private keys, public keys, and addresses.
\n It's important to exercise caution when using it on potentially unsecure devices, as it could lead to financial losses.
\n It is advisable to use a trusted offline device when employing such tools.
\n If you're new to Bitcoin, we highly recommend using established wallet software and adhering to industry best practices to safeguard your digital assets.
\n Always maintain backups of your mnemonic seed phrases in secure, offline locations.
\n Exercise extreme caution when sharing or storing mnemonic seed phrases on digital devices or online platforms.
""")

def foot_note():
print(f"\n To confirm binary to decimal conversion, visit: https://www.rapidtables.com/convert/number/binary-to-decimal.html")
print(" To cross-check decimal to index/word conversion, visit: https://github.com/bitcoin/bips/blob/master/bip-0039/english.txt")
print(" To confirm your mnemonic seed phrase, visit: https://iancoleman.io/bip39/")
print(" Note that binary numbers start from 0, while the BIP39 wordlist starts from 1, so remember to add 1 to the decimal result to match the word.")

def main():
# Clear terminal
clear_terminal()

# Print title
text2 = "* ROLL TO MNEMONIC *"
print_centered_art_text(text2, 5, "Standard")

# Information box
creator_info = f"Created By : Sani Fahs"
twitter_info = f"Twitter : @SaniExp"
github_info = f"GitHub : https://github.com/FahsSani"
lightning_info = f"Lightning Donations : sani@walletofsatoshi.com"
max_info_length = max(len(creator_info), len(twitter_info), len(github_info), len(lightning_info))
box_width = max_info_length + 4
info_box = " " + "+" + "-" * (box_width - 2) + "+"
info_box += f"\n | {creator_info.ljust(max_info_length)} |"
info_box += f"\n | {twitter_info.ljust(max_info_length)} |"
info_box += f"\n | {github_info.ljust(max_info_length)} |"
info_box += f"\n | {lightning_info.ljust(max_info_length)} |"
info_box += "\n +" + "-" * (box_width - 2) + "+"
print_bright_orange(info_box)

# Functions to print text in color
def print_red(*args):
text = ' '.join(map(str, args))
print("\033[91m" + text + "\033[0m") # '\033[91m' is the ANSI escape code for red color

def print_blue(*args):
text = ' '.join(map(str, args))
print("\033[94m" + text + "\033[0m") # '\033[94m' is the ANSI escape code for blue color

def print_green(*args):
text = ' '.join(map(str, args))
print("\033[92m" + text + "\033[0m") # '\033[92m' is the ANSI escape code for green color

def print_cyan(*args):
text = ' '.join(map(str, args))
print("\033[96m" + text + "\033[0m") # '\033[93m' is the ANSI escape code for orange color

def print_purple(*args):
text = ' '.join(map(str, args))
print("\033[95m" + text + "\033[0m") # '\033[95m' is the ANSI escape code for purple color

def print_bright_orange(*args):
text = ' '.join(map(str, args))
print("\033[38;5;208m" + text + "\033[0m") # '\033[38;5;208m' is the ANSI escape code for bright orange color

# Clear terminal
def clear_terminal():
os.system('cls' if os.name == 'nt' else 'clear')

# Display a centered art text
def print_centered_art_text(text, convert, fonttype):
# Default terminal width (you can adjust this value)
terminal_width = 166 # Adjust to your screen size

# Calculate the number of spaces needed to center the text
padding = " " * ((terminal_width - (len(text) * convert)) // 2)

# Combine padding and the input text
centered_text = padding + text

# Print centered text
tprint(centered_text, font=fonttype)

def maximize_window():
system = platform.system()

if system == 'Windows':
# Windows: Send Win + Up Arrow
keyboard.press_and_release('win+up')
elif system == 'Darwin':
# macOS: Send Ctrl + Command + F
keyboard.press_and_release('ctrl+cmd+f')
elif system == 'Linux':
try:
# Linux: Send Alt + F10 (using wmctrl if available)
subprocess.check_output(['wmctrl', '--version'])
subprocess.run(['wmctrl', '-r', ':ACTIVE:', '-b', 'add,maximized_vert,maximized_horz'])
except subprocess.CalledProcessError:
# If wmctrl is not available, send Alt + F10 using keyboard
keyboard.press_and_release('alt+f10')
else:
print(f"Unsupported operating system: {system}")

# Function to check if a seed phrase is valid
def is_valid_seed(seed_phrase):
try:
mnemo = Mnemonic("english")
return mnemo.check(seed_phrase)
except ValueError:
return False
Loading

0 comments on commit c4a2757

Please sign in to comment.