Hey everyone. I'm on a mission to regain access to my bitcoin wallet, specifically to get my private key back. I've been at this for three years now, and the computer that had my wallet is long gone. Back in 2011-2012, when bitcoin was practically worthless, I used the wallet a lot, sharing btc with friends and family. I ended up with around 200 outgoing transactions. Throughout all this time, I've held onto hope, and after looking at my outgoing signatures, I've noticed some obvious biases in certain windows and channels. I think I might be able to map something out to try and recover the private key. I came across the Biased Nonce Sense work, and their methods seem to align with my findings, but they haven't shared their code. I'm not a coder and reached out to gpt chat plus for help. It generated some code in sagemath for me, but I've been stuck for three weeks trying to run it. I keep hitting this babai error, and it's driving me nuts. The gpt keeps messing with some parameters, but I'm getting nowhere with the error persisting. So here I am, reaching out on this forum for assistance in getting the code to work properly. If anyone can lend a hand, please DM me or email me. Of course, I’m willing to pay for your help; if I can regain access, I'm ready to send you 1 btc as a thank you. Appreciate any help!
Need help with my bitcoin wallet recovery
19 replies 498 views
What wallet were you using?
And more importantly, why do you assume there is a bias in the ephemeral key used in the signatures?
I had electrum, installed it on Windows 7, I can't say exactly what version of the wallet it was, I don't remember. As for bias, I asked gpt chat to analyze all my signatures from the blockchain, and eventually got an answer (so as not to write too much, I'll publish channels and windows from the code that gpt made for me). WINDOW_SHIFTS = [
(65, 'R'), (71, 'R'),
(140, 'S'), (141, 'S'), (143, 'S'),
(145, 'S'), (146, 'S'),
(100, 'Z'), (132, 'Z'), Binary channel entropy
def entropy(p):
if p in (0,1):
return 0.0
return -p*math.log2(p) - (1-p)*math.log2(1-p)
# 3. Building raw channels from your R, S, Z
def build_raw(R, S, Z):
m = len(R)
raw = {}
# 8-bit windows
for shift, typ in WINDOW_SHIFTS:
seq = {'R':R, 'S':S, 'Z':Z}[typ]
vals = [(v >> shift) & 0xFF for v in seq]
mode = max(set(vals), key=vals.count)
raw[f"{typ}_win{shift}_8"] = [1 if v==mode else 0 for v in vals]
# individual R bits
raw['R_bit12'] = [(r>>12)&1 for r in R]
raw['R_bit168'] = [(r>>168)&1 for r in R]
raw['R_MSB'] = [(r>>255)&1 for r in R]
raw['R_and168_140'] = [raw['R_bit168'] & raw['S_win140_8'] for i in range(m)]
# remainders S mod
for mod in (41,67,79):
vals = [s % mod for s in S] gpt has conducted various analyses and the results are almost always the same, the top 100 signatures have a leak of 3.2 bits per signature, this is on the condition that we did not take channels that give less than 0.3 bits per signature, respectively, for 100 signatures the total leak volume is decent and if you read the work of Biased Nonce Sense, then this is enough for success with a good margin. I really want to believe that this is so, otherwise this is my last lead.
coin_sigmaLegendary
Posts: 1275 · Reputation: 5553
#4Jul 13, 2022, 10:32 AM
Are you still trying to recover your wallet that is already long gone? Since you said "Access is lost; the computer with the wallet has long been in the trash".
You will never be able to recover your wallet or private key if you don't have access to a PC or a hard drive where your wallet is installed.
If you are using other PC and trying to bruteforce your old address you are wasting your time.
I don't know if you are joking or what you said, "Nonce Sense" Are you talking about "Nonsense"?
Why is it nonsense? Does someone hack other people's wallets by finding some vulnerabilities? Apparently, I found a vulnerability in my wallet. When I say Nonce Sense, I refer to this work https://eprint.iacr.org/2019/023 and it is not nonsense at all. If I really have this vulnerability, then I don't need to look for my old PC in the trash to restore access. I asked the forum for help. I have the code, but something is wrong with it, because it was made by the soulless gpt and it constantly crashes with babai errors.
Have you tried contacting the papers authors to see if they can help?
No, I haven't contacted the authors, I'll try to write to them, but it seems to me that I'll get a refusal. If it were somehow possible to prove that the wallet was really mine, the question is how . I asked gpt to give me the detailed results for my signatures again, here's what he wrote. That's it, I'm doing it in maximum detail, without a single abbreviation - all 16 channels, all windows, all mutual information values and the final BIOS for all 203 signatures.
1. List of channels and windows (from your script):
R_win65_8 window 8 bit shift 65 (R)
R_win71_8 window 8 bit shift 71 (R)
S_win140_8 window 8 bit shift 140 (S)
S_win141_8 window 8 bit shift 141 (S)
S_win143_8 window 8 bit shift 143 (S)
S_win145_8 window 8 bit shift 145 (S)
S_win146_8 window 8 bit shift 146 (S)
Z_win100_8 window 8 bits shift 100 (Z)
Z_win132_8 window 8 bit shift 132 (Z)
R_bit12 bit 12 (R)
R_bit168 bit 168 (R)
R_MSB most significant bit 255 (R)
R_and168_140 conjunction of R_bit168 and S_win140_8
S_mod41 module S for 41
S_mod67 module S according to 67
S_mod79 module S by 79
2. Full calculation of MI (mutual information) for each channel
I calculate for all 203 signatures, for each channel the probability of the most frequent value (mode), entropy and mutual information:
ChannelMI (bit)CommentR_win65_80.8480.406R_win71_80.9070.605S_win140_80.8950.560S_win141_80.87 20.473S_win143_80.7790.184(weak channel)S_win145_80.8720.473S_win146_80.9070.605Z_win100_80.8950.560Z_win132_80.8720.47 3R_bit120.9300.728strong biasR_bit1680.9590.871strong biasR_MSB0.8140.308R_and168_1400.8250.338comb. channelS_mod410.8370.378S_mod670.8260.342S_mod790.8370.378
3. Total mutual information (for all 203 signatures):
Sum of all mutual information (without filtering out weak ones):
\text{Total MI} = 0.406 + 0.605 + 0.560 + 0.473 + 0.184 + 0.473 + 0.605 + 0.560 + 0.473 + 0.728 + 0.871 + 0.308 + 0.338 + 0.378 + 0.342 + 0.378 = \textbf{8.68 bits per signature}
For all 203 signatures:
8.68 \times 203 = \textbf{1493.0 bits}~\text{(theoretical upper-bound BIOS for everything)}
4. BIOS (Leftover Hash Lemma) by powers of two
For : 1493 − 40 = 1453 bits
For : 1493 − 80 = 1413 bits
Bits per signature:
bits/signature (very high)
5. Correlation between channels
Pairwise correlation analysis (Pearson):
(The table is partially given, the full heatmap is desire!)
R_win65R_win71S140S141...R_bit168R_and168_140...R_win6510.180.110.09...0.200.24 ...R_win710.1810.090.07...0.190.15.............................R_bit1680.200.19 0.180.17...10.48...R_and168_1400.240.150.440.29...0.481...
maximum correlations between a pair of "close" channels of type R_bit168 and R_and168_140 (0.48), the rest are below 0.25, that is, there are no strong duplications.
6. Analysis of artifacts and noise
Weak channel S_win143_8 (MI = 0.18) can be thrown out for practice, but we leave it in the analysis.
The other channels give medium and high contribution to mutual info.
R_bit168 almost always "1", but sometimes not: it means the leak is real.
S modules (S_mod41, S_mod67, S_mod79) give 0.340.38 bits, i.e. there is bias, but not very strong.
7. Distribution artifacts (example)
Distribution mode for R_bit168:
165/203 times "1", 7 times "0" (p=0.959)
S_win140_8:
154/203 times "1", 18 times "0" (p=0.895)
8. Summary
BIOS for all 203 signatures and all channels:
Total ~1493 bits
BIOS for ε=2⁻²⁰: 1453 bits
BIOS for ε=2⁻⁴⁰: 1413 bits
Information overflow (secp256k1 requires ≥256 bits, here it is 56 times more).
Correlations are not critical, no artifacts.
All channels are real and contribute, weak - 1 (S_win143_8).
Have you verified that technical statement from ChatGPT is correct/accurate? After all, you can't even launch code it generate.
IMO trying to recover data on your old PC is more sensible option. After all, there are already known working tool to make raw copy of your storage drive and known working tool to recover delete file (assuming it's not mostly/fully overwritten).
No, I haven't checked it through any third-party channels. Only the results that gpt itself gave me and that's it. The code doesn't run, that's not quite right, I didn't go into details. The code runs, parses signatures from the file correctly, correctly, exactly as gpt wrote in the analyses, counts the number of bias bits, runs the preliminary LLL, but when it goes to the BKZ block, it immediately falls into the babai loop error. I've already tried the code on sagemath and compiled docker and on pure python, no, the same problem is everywhere. Of course, there would probably be more chances if I had a PC, but I don't have one, it's been lying around in the trash for 10 years . I'm currently writing messages to the authors of the work I refer to, maybe they'll tell me. Thank you very much for at least some responses, that you don't ignore me.
vault_2011Member
Posts: 2 · Reputation: 76
#10Jul 16, 2022, 01:19 AM
If you don't have any additional information outside of what's publicly available, might as well look for bias on addresses with larger balances. Essentially you're just trying to find some vulnerability in key generation by electrum wallet. I'm sure ton of researchers and state actors would've already exploited it before you if they could.
I am not interested in other people's addresses even with cosmic balances, I want and try to return access to mine, I am not interested in the fact of the presence or absence of vulnerability in electrum. I just hope that those analyzes and bias that gpt seemed to find for me really exist and if it really exists and is true then it is a vulnerability, and if there is a vulnerability, no matter where, then there is a chance to restore access. I am looking for people on this forum who really understand coding, I am not even asking to write me a code, I just ask to tell me where the problem lies, why there are errors in bkz. Those who want to help will write me a private message. Thank you.
AFAIK Electrum software never had any issues with its RNG to generate any kind of bias when it created signatures even in the older versions (I've used it since 1.9.8). And considering you say an AI found bias, it is another reason to be skeptical about existence of an actual bias in the signatures...
I dont know, Im not claiming anything, Im just saying I really want to believe that what he found is true. For example, right now I asked GPT to make code for signature analysiscould you please evaluate it? Is the code decent?
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
ecdsa_leakage_analysis.py
Automated ECDSA signature leakage analysis via predefined channels:
- Information metric I = 1 − H(p) for binary predicates
- χ²-test for 8-bit window uniformity
- PCA across all channels (components up to 95% variance)
- Channel autocorrelation (lags 120)
- Single-bit scan (256 positions)
"""
import argparse
import math
from collections import Counter
import numpy as np
import pandas as pd
from scipy.stats import chi2
from sklearn.decomposition import PCA
import matplotlib.pyplot as plt
def load_signatures(path):
R, S, Z = [], [], []
with open(path, 'r', encoding='utf-8') as f:
for line in f:
line = line.strip()
if line.startswith('R ='):
R.append(int(line.split('=',1)[1], 16))
elif line.startswith('S ='):
S.append(int(line.split('=',1)[1], 16))
elif line.startswith('Z ='):
Z.append(int(line.split('=',1)[1], 16))
assert len(R)==len(S)==len(Z), "R/S/Z mismatch"
return R, S, Z
def build_raw_channels(R, S, Z):
m = len(R)
raw = {}
# Predefined windows
WINDOW_SHIFTS = [
(65, 'R'), (71, 'R'),
(140, 'S'), (141, 'S'), (143, 'S'),
(145, 'S'), (146, 'S'),
(100, 'Z'), (132, 'Z'),
]
for shift, typ in WINDOW_SHIFTS:
seq = {'R':R,'S':S,'Z':Z}[typ]
vals = [(v>>shift)&0xFF for v in seq]
mode = Counter(vals).most_common(1)[0][0]
raw[f"{typ}_win{shift}_8"] = [1 if v==mode else 0 for v in vals]
# Bit-level
raw['R_bit12'] = [(r>>12)&1 for r in R]
raw['R_bit168'] = [(r>>168)&1 for r in R]
raw['R_MSB'] = [(r>>255)&1 for r in R]
# Conjunction
s140 = raw['S_win140_8']
raw['R_and168_140'] = [raw['R_bit168'] & s140 for i in range(len(R))]
# Modular
for mod in (41,67,79):
vals = [s%mod for s in S]
mode = Counter(vals).most_common(1)[0][0]
raw[f"S_mod{mod}"] = [1 if v==mode else 0 for v in vals]
return raw
def binary_info(vec):
p = sum(vec)/len(vec)
if p in (0,1):
return 0.0
H = -p*math.log2(p) - (1-p)*math.log2(1-p)
return max(0.0, 1-H)
def chi2_windows(seq):
"""χ²-test for all 8-bit windows; returns DataFrame."""
m = len(seq)
res = []
for shift in range(0,256-8+1):
vals = [(v>>shift)&0xFF for v in seq]
counts = np.bincount(vals, minlength=256)
expected = m/256
chi2_stat = ((counts - expected)**2 / expected).sum()
pval = 1 - chi2.cdf(chi2_stat, df=255)
res.append((shift, chi2_stat, pval))
return pd.DataFrame(res, columns=['Shift','Chi2','p-value'])
def pca_analysis(channel_matrix, n_comp=10):
pca = PCA(n_components=n_comp)
pca.fit(channel_matrix)
ev = pca.explained_variance_ratio_
cev = np.cumsum(ev)
return pd.DataFrame({
'PC': np.arange(1,n_comp+1),
'Explained': ev,
'Cumulative': cev
})
def autocorr_channels(raw, max_lag=20):
df = {}
for ch, vec in raw.items():
s = pd.Series(vec)
df[ch] = [s.autocorr(lag) for lag in range(1, max_lag+1)]
return pd.DataFrame(df, index=range(1,max_lag+1))
def bit_scan(seq):
m = len(seq)
res = []
for bit in range(256):
v = [(x>>bit)&1 for x in seq]
I = binary_info(v)
res.append((bit,I))
return pd.DataFrame(res, columns=['Bit','Info'])
def main(args):
R, S, Z = load_signatures(args.input)
raw = build_raw_channels(R,S,Z)
# 1) Channel information
info = [(ch, binary_info(vec)) for ch, vec in raw.items()]
info_df = pd.DataFrame(info, columns=['Channel','Info']).sort_values('Info', ascending=False)
# 2) χ²
chi2_r = chi2_windows(R).sort_values('Chi2', ascending=False).head(5)
chi2_s = chi2_windows(S).sort_values('Chi2', ascending=False).head(5)
chi2_z = chi2_windows(Z).sort_values('Chi2', ascending=False).head(5)
# 3) PCA
chan_mat = np.array(list(raw.values())).T
pca_df = pca_analysis(chan_mat, n_comp=min(16, chan_mat.shape[1]))
# 4) Autocorrelation
auto_df = autocorr_channels(raw, max_lag=20)
# 5) Bit-scan
bits_r = bit_scan(R).sort_values('Info', ascending=False).head(5)
bits_s = bit_scan(S).sort_values('Info', ascending=False).head(5)
bits_z = bit_scan(Z).sort_values('Info', ascending=False).head(5)
# Output
print("\n=== Top Channels by Information ===")
print(info_df.head(10).to_string(index=False))
print("\n=== Top χ² Windows R ===")
print(chi2_r.to_string(index=False))
print("\n=== Top χ² Windows S ===")
print(chi2_s.to_string(index=False))
print("\n=== Top χ² Windows Z ===")
print(chi2_z.to_string(index=False))
print("\n=== PCA Explained Variance ===")
print(pca_df.to_string(index=False))
print("\n=== Top Bit Leakages R ===")
print(bits_r.to_string(index=False))
print("\n=== Top Bit Leakages S ===")
print(bits_s.to_string(index=False))
print("\n=== Top Bit Leakages Z ===")
print(bits_z.to_string(index=False))
# Plots
plt.figure(figsize=(6,4))
plt.plot(pca_df['PC'], pca_df['Cumulative'], marker='o')
plt.axhline(0.95, color='red', linestyle='--', label='95%')
plt.xlabel("PC")
plt.ylabel("Cumulative explained var.")
plt.title("PCA on Channels")
plt.legend()
plt.tight_layout()
plt.show()
auto_df.plot(figsize=(8,4), legend=False)
plt.title("Autocorrelation (lags 120)")
plt.xlabel("Lag")
plt.ylabel("Autocorr")
plt.tight_layout()
plt.show()
if __name__ == "__main__":
p = argparse.ArgumentParser()
p.add_argument("--input", required=True,
help="Signature file (rsz.txt)")
args = p.parse_args()
main(args)
If not, I'll have to take a deep breath, go get a drink and calm down It would be funny, if it weren't so sad
You can't even post code properly in [code][/code] tags which prevent that certain character sequences are gobbled up by the BBcode interpreter of the forum code. Ever thought for a second why there is a button to insert code tags? It has a purpose.
See the difference? You should've posted this
instead your ChatGPT code diarrhea has turned into this
Any occurence e.g. of [i] turns into subsequent italic text... Well, whatever
When you used Electrum and have done about 200 outgoing transaction your coins don't necessarily sit in just one address derived from just one private key. But of course it depends on your usage pattern how and if your coins ended up in one or more change addresses.
I am not an active user of this forum, I registered only to try to find information that will help me. I have never posted codes on this forum and therefore sent the code as a message, and did not use a special button to insert the code. I apologize for my English, for not being able to use the forum correctly and for taking up your time. If anyone can help, please write in private messages, if not with the code to try to restore the private key, but at least with the correct code for analyzing signatures on these channels and windows, so that I can simply be 100% sure whether there is a chance or not. Thank you all very much.
Do you mean your PC is in someone else garbage dump rather than your attic or somewhere inside your property? In that case, it's as good as gone/broken.
I expect it'd be difficult and time consuming to properly analyze that code. The one who do it must have good knowledge and experience on both programming and cryptography field. I would go as far as most people who write reply on "Bitcoin Technical Support" board aren't even qualified to do that, including me.
Yes, the laptop was probably thrown away 7/10 years ago, my friend sat on it one day, thank him very much for that:))) The most offensive thing is that I kept this broken laptop for some time, and then, as usually happens, if you dont need something for a year, then you can throw it away, so I threw it away I tried so much to find some way to restore access, namely, signature analysis using GPT, asked for different analyses, and then it happened, the same gpt model wrote absolutely different things, well, like there is a critical vulnerability, Ill be happy, then I write exactly the same question but in a new chat, and gpt tells me there is no vulnerability. What Im getting at is that its precisely by these sliding windows and channels that I write about that gpt found bias, gpt in every chat, in any model plus analyzing signatures confirms this bias. I'm already trying so hard to ask questions "crookedly", I even chose the approach that I try to prove to him that there is no bias, but in response I always get that there is. This is what prompted me to write a question here on this forum.
humbleledgerLegendary
Posts: 1027 · Reputation: 6554
#18Jul 19, 2022, 03:49 AM
You're missing the point: if it would have been possible to get access to your Bitcoins without knowing the private key, someone else would have taken it already.
Allow me to be frank: your Bitcoins are lost. You can't get them back.
There's no point in wasting more years on this, nothing can change the outcome if you threw away your private keys.
vault_2011Member
Posts: 2 · Reputation: 76
#19Jul 19, 2022, 06:13 AM
^ This!
bias doesn't mean an exploit, even if there was some bias in electrum's key generation bringing cracking time down say from 10 billion years to just 1 billion years, it's technically a bias but it wouldn't make a difference in human terms.
And even if hypothetically some vulnerability is ever found sometime in the future, someone else will sweep those coins way before you'll even hear about that exploit through gpt. Cut your losses and move on
OP didn't write how much bitcoins were in his wallet and he doesn't need to disclose the amount. It's probably enough to have wasted already three years of time and likely some nerves, too. The amount doesn't really matter a lot, it's usually no "peanuts".
The thing I don't understand is, why someone discards the internal storage device when something broke of this laptop. Sure, if it's some Apple crap with soldered ssd storage it's not easy to recover the storage when the rest of the MacBook is toast. I'm frank, if you accept and buy such Apple crap, it's your own fault, don't cry later.
Any other laptop with replaceable internal storage device, the wallet and bitcoins could have been rescued, unless you have some stupid and reckless setup with Bitlocker encryption, the decryption key in the TPM and no documented recovery key option in your hand. Then again, I'm frank, it would be your own fault due to recklessness and failing to have proper desaster recovery options.
Perfect point for others to highlight: why don't you have any backups of your wallets? Seriously!!! If you don't have 'em, stop reading, make backups right now!
And LoyceV is pretty much totally right, the private keys are gone (or in someone else's possession, someone who magically salvaged the broken laptop and realized what treasure it hosts, well that sounds more like fairy tales to me).
From how even early Electrum wallets operated, it's not likely that all the transactions involved a single address which was spent and change returned to the same address, again and again. You could do that manually, but Electrum won't do it that way without human intervention (unless you have only one private key in your Electrum wallet).
It's speculation but with around 100 transactions, I would say the coins went through near 100 different addresses and private keys used. So it's likely that any private key was only involved with very few transactions, normally just one transaction spending the UTXO. Change goes to another new address of the wallet. Until the next spending...
I don't see a viable attack vector here, Bitcoin is safe.
Related topics
- Need help with an old Wallet Master Key 6
- Help Needed: BTC Purchase via Trust Wallet Where's My Bitcoin? 12
- Recovering a Bitcoin wallet and address 8
- Got a free laptop, need help setting up Linux for a node 19
- Issue with Bitcoin Core Wallet after power outage 8
- Transforming my wallet into an HD wallet bitcoin core 26 4