DILSHAD737 commited on
Commit
e3b4724
·
1 Parent(s): 25b31ba

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +3 -194
app.py CHANGED
@@ -16,202 +16,11 @@ USE_BIP39 = True
16
  BIP39_PASSPHRASE = ""
17
  HD_DERIVATION = True
18
  ADDRESS_INDEX = 0
19
- CHECK_BIP39_CHECKSUM = False
20
  ADDRESSES_FILE = "12730802_addresses.csv"
21
  MATCHED_FILE = f"matched_keys_{PHRASE_MODE}.txt"
22
- BATCH_SIZE = 5000
23
  NUM_WORKERS = 96
24
  # ============================================================
25
 
26
-
27
- # ---------- secp256k1 ----------
28
- _SECP256K1_N = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141
29
- _HARDENED = 0x80000000
30
-
31
-
32
- def _bip32_derive_child_priv(parent_priv, parent_chain, index):
33
- if index >= _HARDENED:
34
- data = b'\x00' + parent_priv + index.to_bytes(4, 'big')
35
- else:
36
- pub = coincurve.PrivateKey(parent_priv).public_key.format(compressed=True)
37
- data = pub + index.to_bytes(4, 'big')
38
- I = hmac.new(parent_chain, data, hashlib.sha512).digest()
39
- child_int = (int.from_bytes(I[:32], 'big') + int.from_bytes(parent_priv, 'big')) % _SECP256K1_N
40
- if child_int == 0:
41
- raise ValueError("Invalid child key")
42
- return child_int.to_bytes(32, 'big'), I[32:]
43
-
44
-
45
- def seed_to_privkey_hd(seed, address_index=0):
46
- I = hmac.new(b"Bitcoin seed", seed, hashlib.sha512).digest()
47
- key, chain = I[:32], I[32:]
48
- path = [44 + _HARDENED, 60 + _HARDENED, _HARDENED, 0, address_index]
49
- for idx in path:
50
- key, chain = _bip32_derive_child_priv(key, chain, idx)
51
- return key
52
-
53
-
54
- # ---------- BIP39 ----------
55
- try:
56
- import bip39 as _bip39_rust
57
- _USE_RUST_BIP39 = True
58
- except ImportError:
59
- _bip39_rust = None
60
- _USE_RUST_BIP39 = False
61
-
62
- _MNEMONIC = None
63
-
64
- def _get_mnemonic():
65
- global _MNEMONIC
66
- if _MNEMONIC is None:
67
- from mnemonic import Mnemonic
68
- _MNEMONIC = Mnemonic("english")
69
- return _MNEMONIC
70
-
71
- def is_valid_bip39_fast(phrase):
72
- if _USE_RUST_BIP39:
73
- try:
74
- _bip39_rust.bip39_mnemonic_to_entropy(phrase)
75
- return True
76
- except Exception:
77
- return False
78
- return _get_mnemonic().check(phrase)
79
-
80
- def phrase_to_seed(phrase):
81
- if _USE_RUST_BIP39:
82
- return _bip39_rust.bip39_mnemonic_to_seed(phrase, BIP39_PASSPHRASE)
83
- return _get_mnemonic().to_seed(phrase, passphrase=BIP39_PASSPHRASE)
84
-
85
-
86
- # ---------- Address file (lowercase) ----------
87
- def load_addresses(path):
88
- s = set()
89
- with open(path, "r", encoding="utf-8") as f:
90
- for line in f:
91
- a = line.strip().strip('"').strip("'").lstrip("\ufeff").lower()
92
- if a.startswith("0x"):
93
- a = a[2:]
94
- if a and len(a) == 40:
95
- s.add(a)
96
- return frozenset(s)
97
-
98
- def normalize(addr):
99
- a = addr.strip().lower()
100
- if a.startswith("0x"):
101
- a = a[2:]
102
- return a
103
-
104
-
105
- # ---------- Generator ----------
106
- def generate_phrases():
107
- n = len(words)
108
- if PHRASE_MODE == "order":
109
- for perm in permutations(words):
110
- yield " ".join(perm)
111
- elif PHRASE_MODE == "replace":
112
- for i in range(n):
113
- for w in words:
114
- new = words.copy()
115
- new[i] = w
116
- yield " ".join(new)
117
- elif PHRASE_MODE == "subset":
118
- for r in range(1, n + 1):
119
- for combo in combinations(words, r):
120
- yield " ".join(combo)
121
-
122
- def count_total():
123
- n = len(words)
124
- if PHRASE_MODE == "order": return math.factorial(n)
125
- if PHRASE_MODE == "replace": return n * n
126
- if PHRASE_MODE == "subset": return 2**n - 1
127
-
128
-
129
- # ---------- Worker ----------
130
- _KNOWN = None
131
-
132
- def init_worker(known):
133
- global _KNOWN
134
- _KNOWN = known
135
- _get_mnemonic()
136
-
137
- def process_batch(batch):
138
- hits = []
139
- known = _KNOWN
140
- m = _get_mnemonic()
141
- for phrase in batch:
142
- if CHECK_BIP39_CHECKSUM and not is_valid_bip39_fast(phrase):
143
- continue
144
- try:
145
- seed = phrase_to_seed(phrase)
146
- if HD_DERIVATION:
147
- priv = seed_to_privkey_hd(seed, ADDRESS_INDEX)
148
- else:
149
- priv = seed[:32]
150
- pub = coincurve.PrivateKey(priv).public_key.format(compressed=False)[1:]
151
- addr = to_checksum_address(keccak(pub)[-20:])
152
- except Exception:
153
- continue
154
- if normalize(addr) in known:
155
- hits.append((phrase, priv.hex(), addr))
156
- return hits
157
-
158
- def batch_generator():
159
- batch = []
160
- for phrase in generate_phrases():
161
- batch.append(phrase)
162
- if len(batch) >= BATCH_SIZE:
163
- yield batch
164
- batch = []
165
- if batch:
166
- yield batch
167
-
168
-
169
- # ---------- Main ----------
170
- def main():
171
- if not os.path.exists(ADDRESSES_FILE):
172
- raise SystemExit(f"File nahi mili: {ADDRESSES_FILE}")
173
-
174
- total = count_total()
175
- print(f"\nMode: {PHRASE_MODE} | Total: {total:,} | Workers: {NUM_WORKERS}")
176
- print(f"HD: {HD_DERIVATION} (index {ADDRESS_INDEX})\n")
177
-
178
- known = load_addresses(ADDRESSES_FILE)
179
- print(f"Loaded {len(known):,} lowercase addresses\n")
180
-
181
- matches = []
182
- done = 0
183
- start = time.time()
184
- last_log = start
185
-
186
- if os.path.exists(MATCHED_FILE):
187
- os.remove(MATCHED_FILE)
188
-
189
- gc.collect()
190
- gc.freeze()
191
-
192
- with Pool(processes=NUM_WORKERS,
193
- initializer=init_worker,
194
- initargs=(known,),
195
- maxtasksperchild=1000) as pool:
196
- for hits in pool.imap_unordered(process_batch, batch_generator(), chunksize=1):
197
- done += BATCH_SIZE
198
- for phrase, key_hex, addr in hits:
199
- print(f"\n✅ MATCH: {phrase}\n priv: {key_hex}\n addr: {addr}\n")
200
- matches.append((phrase, key_hex, addr))
201
- with open(MATCHED_FILE, "a", encoding="utf-8") as f:
202
- f.write(f"{phrase} | {key_hex} | {addr}\n")
203
-
204
- now = time.time()
205
- if now - last_log >= 5:
206
- elapsed = now - start
207
- rate = done / elapsed if elapsed else 0
208
- eta = (total - done) / rate if rate else 0
209
- print(f" ...{done:,}/{total:,} ({100*done/total:.2f}%) ETA {eta/60:.1f}min")
210
- last_log = now
211
-
212
- elapsed = time.time() - start
213
- print(f"\nDone {elapsed:.1f}s. {len(matches)} match(es).")
214
-
215
-
216
- if __name__ == "__main__":
217
- main()
 
16
  BIP39_PASSPHRASE = ""
17
  HD_DERIVATION = True
18
  ADDRESS_INDEX = 0
19
+ CHECK_BIP39_CHECKSUM = False # ✅ FIX: prefilter band
20
  ADDRESSES_FILE = "12730802_addresses.csv"
21
  MATCHED_FILE = f"matched_keys_{PHRASE_MODE}.txt"
22
+ BATCH_SIZE = 500
23
  NUM_WORKERS = 96
24
  # ============================================================
25
 
26
+ # ... (baaki code same rahega, sirf debug prints hata dein)