Bitcoin Forum
June 27, 2024, 03:59:26 AM *
News: Latest Bitcoin Core release: 27.0 [Torrent]
 
  Home Help Search Login Register More  
  Show Posts
Pages: « 1 2 3 4 [5] 6 »
81  Bitcoin / Development & Technical Discussion / Re: Bitcoin public keys on: January 05, 2023, 07:42:07 PM
i often read keyhunters are interested in public keys because it can speed up cracking process - true?

let us look at puzzle-115:

Quote
pubkey: 0248d313b0398d4923cdca73b8cfa6532b91b96703902fc8b32fd438a3b7cd7f55
address: 1NLbHuJebVwUZ1XqDjsAyfTRUPwDQbemfv

if the attacker does not know the range of private key how realistic is it that he can crack the key?
if the attacker does know the range of private key how long does take him to crack the key?

what is most efficient cracking tool when you have pubkey - kangaroo or bsgs?

let us say an attacker knows address public key plus a valid signature
does he have better chance now to crack the key?

why all people try to hide public key although it should be public in this system to function?
please explain



1) yes. very much.
2) i dont need to know the range of the private key. mathematicians, programmers, they think that way. its important to them. for security researchers like myself, we tend to think differently. the range is not important but its how we can emulate the correct RSZ and K nonce to the public key is more important.. by knowing K, we alrdy are one step away from revealing the private key.
3) range not important to us. good,nice info but we usually shelve it. coz we know we just need to know the K value used.
4) the best tool i use so far and extremely efficient is the lattice attack script written by Antoine. You can download it at https://github.com/bitlogik/lattice-attack
5) as i found out, nope. u need a little more than that. you got to get to K nonce. Then things are much easier.
6) i am actually trying to prove to my government on why every bitcoin transaction or any other altcoin transaction should not display the public keys and rsz signatures. if we really want bitcoin or any other altcoins to continue to prosper or at least be relevant for another 8 decades, at least, we then need to give out less informations on every transaction. how can we claim, its anonymous or safe when all i need is for you to make 1 transaction and i know your pubkeys and RSZ? im beginning to understand the mathematics deeper..and as i delve further.. i seriously cannot fathom why showing the public keys are ok to most. as thats my first way in to a wallet.

im answering you as a Cyber Security Researcher for 18 years. im trained to think and do my work like how a professional hacker would think and do their research. 11 months on ECDSA though. and this has been one of the best research i had done. my new found respect to Mathematicians. i actually enjoyed doing this research so much.
82  Bitcoin / Development & Technical Discussion / Lattice Attack Script Modified on: January 05, 2023, 07:03:38 PM
Modified the gen_data.py script in https://github.com/bitlogik/lattice-attack.

 Now every set of R,S,Z(HASH) Signatures shows the K_Nonce value used. Does not show up in the json file like the other datas though. It's directly on Terminal. Modified full code below.

In gen_data.py, don't forget to input your own public keys XY coordinates.
Code:

#!/usr/bin/env python3

import argparse
import random
import json

import ecdsa_lib


def generates_signatures(number_sigs, message, kbits, data_type, curve):
    print("Preparing Data")
    d_key = random.randrange(ecdsa_lib.curve_n(curve))
    print("Private key to be found (as demo) :")
    print(hex(d_key))
    sigs = []
    sz_curve = ecdsa_lib.curve_size(curve)
    kbi = int(2 ** kbits)
    print(f"Generating {number_sigs} signatures with curve {curve.upper()}")
    print(f" leaking {kbits} bits for k ({data_type})  ...")
    if message is not None:
        msg = message.encode("utf8")
        # Always hash message provided with SHA2-256, whatever
        hash_int = ecdsa_lib.sha2_int(msg)
    for _ in range(number_sigs):
        if message is None:
            # Use a random different message for each signature
            # Note : there is no associated message from the hash
            #  Do not ever that in practice, this is insecure, only here for demo
            hash_int = random.randrange(ecdsa_lib.curve_n(curve))
        # Compute signatures with k (nonce), r, s, hash
        sig_info = ecdsa_lib.ecdsa_sign_kout(hash_int, d_key, curve)
        # pack and save data as : r, s, hash, k%(2^bits) (partial k : "kp")
        
        sigs.append(
            {
                "r": sig_info[0],
                "s": sig_info[1],
                "kp": sig_info[2] % kbi
                if data_type == "MSB"
                else sig_info[2] >> (sz_curve - kbits),
            }
            
        )
        print(f"k_nonce:{sig_info[2]}")

        if message is None:
            sigs[-1]["hash"] = hash_int
    ret = {
        "curve": curve.upper(),
        "public_key": (31504125288796341338541169388783846543997786027594142627385926708036691251730,
        29015715595623874326232564738946807912877814040423899127791236573353650594580),
        "known_type": data_type,
        "known_bits": kbits,
        "signatures": sigs,
    }
    if message is not None:
        ret["message"] = list(msg)
    return ret


if __name__ == "__main__":
    parser = argparse.ArgumentParser(
        description="Generate data for ECDSA attack."
    )
    parser.add_argument(
        "-f",
        default="data1.json",
        help="File name output",
        metavar="fileout",
    )
    parser.add_argument(
        "-m",
        help="Message string",
        metavar="msg",
    )
    parser.add_argument(
        "-c", default="secp256k1", help="Elliptic curve name", metavar="curve"
    )
    parser.add_argument(
        "-b",
        default=8,
        type=int,
        help="Number of known bits (at least 4)",
        metavar="nbits",
    )
    parser.add_argument(
        "-t", default="MSB", help="bits type : MSB or LSB", metavar="type"
    )
    parser.add_argument(
        "-n",
        default=100,
        type=int,
        help="Number of signatures to generate",
        metavar="num",
    )
    arg = parser.parse_args()
    sigs_data = generates_signatures(arg.n, arg.m, arg.b, arg.t, arg.c)
    with open(arg.f, "w") as fout:
        json.dump(sigs_data, fout)
    print(f"File {arg.f} written with all data.")


Updated the ecdsa_lib.py to include print function for K_Nonce as well.

Code:

#!/usr/bin/env python3

# Lattice ECDSA Attack : ECDSA and cryptographic library

# Install cryptography
#  pip3 install cryptography
#   or
#  apt install python3-cryptography


import hashlib
import secrets

from cryptography.hazmat import backends
from cryptography.hazmat.primitives.asymmetric import ec


CURVES_ORDER = {
    "SECP224R1": int(
        "2695994666715063979466701508701962594045780771442439172168272236" "8061"
    ),
    "SECP256K1": int(
        "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141", 16
    ),
    "SECP256R1": int(
        "11579208921035624876269744694940757352999695522413576034242225906"
        "1068512044369"
    ),
    "SECP384R1": int(
        "39402006196394479212279040100143613805079739270465446667946905279"
        "627659399113263569398956308152294913554433653942643"
    ),
    "SECP521R1": int(
        "68647976601306097149819007990813932172694353001433054093944634591"
        "85543183397655394245057746333217197532963996371363321113864768612"
        "440380340372808892707005449"
    ),
}


def inverse_mod(a_num, m_mod):
    # a_num^-1 mod m_mod, m_mod must be prime
    # If not used on a prime modulo,
    #  can throw ZeroDivisionError.
    if a_num < 0 or m_mod <= a_num:
        a_num = a_num % m_mod
    i, j = a_num, m_mod
    x_a, x_b = 1, 0
    while i != 1:
        quot, rem = divmod(j, i)
        x_rem = x_b - quot * x_a
        j, i, x_b, x_a = i, rem, x_a, x_rem
    return x_a % m_mod


def sha2(raw_message):
    # SHA-2 256
    return hashlib.sha256(raw_message).digest()


def bytes_to_int(bytes_data):
    return int.from_bytes(bytes_data, "big")


def sha2_int(data):
    return bytes_to_int(sha2(data))


def curve_size(curve_name):
    # return the curve size (log2 N) from its name string
    try:
        curve_obj = getattr(ec, curve_name.upper())()
    except Exception as exc:
        raise Exception(
            f"Unknown curves. Curves names available : {list(CURVES_ORDER.keys())}"
        ) from exc
    return curve_obj.key_size


def curve_n(curve_name):
    # return the curve order "N" from its name string
    order = CURVES_ORDER.get(curve_name.upper())
    if not order:
        raise Exception(
            f"Unknown curves. Curves names available : {list(CURVES_ORDER.keys())}"
        )
    return order


def check_publickey(pubkey, curve_str):
    # Check pubkey (x,y) belongs on the curve
    try:
        curve_obj = getattr(ec, curve_str.upper())()
    except Exception as exc:
        raise Exception(
            f"Unknown curves. Curves names available : {list(CURVES_ORDER.keys())}"
        ) from exc
    if len(pubkey) != 2:
        raise Exception(
            'Public key data shall be provided as :\n "public_key" : [ x, y ]'
        )
    publickey_obj = ec.EllipticCurvePublicNumbers(pubkey[0], pubkey[1], curve_obj)
    ret = False
    try:
        publickey_obj.public_key(backends.default_backend())
        ret = True
    except ValueError:
        pass
    return ret


def privkey_to_pubkey(pv_key_int, curve_name):
    # Return public point coordinates (Scalar multiplication of pvkey with base point G)
    ec_backend = getattr(ec, curve_name.upper())()
    pubkey = (
        ec.derive_private_key(pv_key_int, ec_backend, backends.default_backend())
        .public_key()
        .public_numbers()
    )
    return [pubkey.x, pubkey.y]


def ecdsa_sign_kout(z_hash, pvkey, curve_name):
    # Perform ECDSA, but insecurely return the private k nonce
    n_mod = curve_n(curve_name)
    k_nonce = secrets.randbelow(n_mod)
    r_sig = scalar_mult_x(k_nonce, curve_name)
    s_sig = inverse_mod(k_nonce, n_mod) * (z_hash + r_sig * pvkey) % n_mod
    print(f"k_nonce: {k_nonce}")
    return r_sig, s_sig, k_nonce
    


def scalar_mult_x(d_scalar, curve):
    # Scalar multiplication of d with base point G
    # and return x, like ECDH with G.
    return privkey_to_pubkey(d_scalar, curve)[0]


With R,S,Z(HASH) & now K nonce revealed, You can now proceed here and input your datas. https://rawcdn.githack.com/nlitsme/bitcoinexplainer/aa50e86e8c72c04a7986f5f7c43bc2f98df94107/ecdsacrack.html to get to the Private key.

Wth this, its almost a done deal to get to the private key. Good luck.
83  Bitcoin / Development & Technical Discussion / Recreated Fault Sig Attack on Bitcoin Wallet on: January 03, 2023, 11:23:28 AM
I realize that you can't recreate the attack by using the R,S,Z(H) on blockchain.com. I am not sure why. I believe for different software, it can hash the signatures over and over and over again. So technically, we will never know whats the correct R,S,Z(H) Signatures.

The Only way is to create the R,S,Z signatures. Which i did by inputting my Public Keys X,Y Coordinates in the full code below.

Input
Code:

import argparse
import base64
import functools
import json
import hashlib
import os
import tarfile
import urllib.request


# Original data set for traces get from :

RESOURCE_URL = (
    "https://github.com/orangecertcc/ecdummyrpa/raw/"
    "main/sample.tar.gz"
)


# Helpers from ecdsa_lib


def sha2(raw_message):
    # SHA-2 256
    return hashlib.sha256(raw_message).digest()


def sha2_int(data):
    return int.from_bytes(sha2(data), "big")


# Special helpers for this case


def sigDER_to_ints(sigDER):
    lenr = int(sigDER[3])
    lens = int(sigDER[5 + lenr])
    r = int.from_bytes(sigDER[4 : lenr + 4], "big")
    s = int.from_bytes(sigDER[lenr + 6 : lenr + 6 + lens], "big")
    return r, s


def pubkeyPEM_to_X962(PEMstring):
    PEMparts = PEMstring.split("-----")
    pubkey_b64 = PEMparts[2].strip("\r\n")
    # end of DER is X962 public key
    return base64.b64decode(pubkey_b64)[-65:]


def pubkeyX962_to_intpair(DERpubk):
    x_int = int.from_bytes(DERpubk[1:33], "big")
    y_int = int.from_bytes(DERpubk[33:], "big")
    return [x_int, y_int]


def pubkeyPEM_to_xy(PEMstr):
    return pubkeyX962_to_intpair(pubkeyPEM_to_X962(PEMstr))


def load_traces():
    # Reads traces from this RPA campain
    # Prepare to an almost compliant with LatticeAttack
    # But it requires then filtering to compute "kp" from "trace"
    files = os.listdir("test")
    nsig = len(files) // 3
    print(f"{len(files)} files detected for {nsig} signatures")
    traces = []
    for i in range(nsig):
        with open(f"test/trace_{i}.txt", "r") as tracef:
            data_trace = [float(line) for line in tracef]
        with open(f"test/signature_{i}.bin", "rb") as sigf:
            DERsig = sigf.read()
        with open(f"test/message_{i}.txt", "rb") as msgf:
            msg = msgf.read()
        trace_data = {}
        sig_ints = sigDER_to_ints(DERsig)
        trace_data["hash"] = sha2_int(msg)
        trace_data["r"] = sig_ints[0]
        trace_data["s"] = sig_ints[1]
        trace_data["trace"] = data_trace
        traces.append(trace_data)
    return traces


KNOWN_BITS = 7


def mean_compute(table_array):
    # compute arithmetic mean value to get the height of the valley
    return functools.reduce(lambda i, j: i + j, table_array) / len(table_array)


def select_sig(sig_candidate):
    # Filtering the good signatures
    # mean value < limit
    # "A valley considerably lower than the others indicating a nonce that has
    #    its 7 least significant bits set to 0."
    LIMIT = 20
    DISCARD_SIZE = 0.25  # Discard first and last 25% = keeps "half" middle
    trace_len = len(sig_candidate["trace"])
    start_idx = int(trace_len * DISCARD_SIZE)
    trace_interest = sig_candidate["trace"][start_idx : trace_len - start_idx]
    val = mean_compute(trace_interest)
    return val < LIMIT


def compute_kp(onesig):
    # Generate final data objects (with kp)
    sigout = {}
    sigout["hash"] = onesig["hash"]
    sigout["r"] = onesig["r"]
    sigout["s"] = onesig["s"]
    sigout["kp"] = [""]
    return sigout


def get_data_source(res_url):
    # Get tar gz file at given url and extract files locally
    # Use this only on known trusted or friendly TAR files,
    # as this can write files anywhere locally
    with urllib.request.urlopen(
        urllib.request.Request(res_url, headers={"User-Agent": "Mozilla"})
    ) as remote_data:
        tardata = tarfile.open(fileobj=remote_data, mode="r:gz")
        print("Extracting data files ...")
        tardata.extractall()


if __name__ == "__main__":
    parser = argparse.ArgumentParser(
        description="Load ecdummyRPA traces mesurements for ECDSA attack file format."
    )
    parser.add_argument(
        "-f",
        default="data.json",
        help="File name output",
        metavar="fileout",
    )
    arg = parser.parse_args()

    # Test if data were downloaded by testing presence of pubkey file
    if not os.path.exists("pubkey.pem"):
        print("Downloading raw data ...")
        get_data_source(RESOURCE_URL)

    print("Loading files ...")
    sigs_data = load_traces()
    print("Filtering signatures traces")
    sigs_data_selected = [compute_kp(asig) for asig in sigs_data if select_sig(asig)]
    with open("pubkey.pem", "r") as pkf:
        pubkey_pem = pkf.read()
    global_data = {
        "curve": "SECP256k1",
        "public_key": (Input X here, Input Y here),
        "known_type": "LSB",
        "known_bits": KNOWN_BITS,
        "signatures": sigs_data_selected,
    }
    with open(arg.f, "w") as fout:
        json.dump(global_data, fout)
    print(f"File {arg.f} written with all data.")



Output
Code:
"curve": "SECP256K1",
    "public_key": [
        31504125288796341338541169388783846543997786027594142627385926708036691251730,
        29015715595623874326232564738946807912877814040423899127791236573353650594580
    ],
    "known_type": "LSB",
    "known_bits": 6,
    "signatures": [
        {
            "r": 17456122099107622875979177060034160065534440309384765110770021588156777535269,
            "s": 39548918176628970790297874101648966881380966278908886743977542233652364916621,
            "kp": 20,
            "hash": 92211084921678517086309436176248290676365250150878786017110534405419087808719
        },
        {
            "r": 23913541315081963661847822603754285037803706978735367208728912448433920129361,
            "s": 92518508463905780686593084152628940334651401106826544410053244574796065086889,
            "kp": 13,
            "hash": 21236183650018659484557387187850143636235316156689640733937135357581028327853
        },

Massive Credit to Bitlogik for the gen_input.py on  https://github.com/bitlogik/lattice-attack

then with the R,S,Z(H) signatures given, i input the signatures in the code below. Originally coded by William J. Buchanan
And article written here: https://asecuritysite.com/ecc/ecd7


Modified by me to allow public keys and RSZ inputs.

Input
Code:

import ecdsa
import random
import libnum
import hashlib
import sys

P = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141
G = ecdsa.SECP256k1.generator
order = G.order()
priv1 = random.randrange(1,order)
Public_key = (31504125288796341338541169388783846543997786027594142627385926708036691251730,
29015715595623874326232564738946807912877814040423899127791236573353650594580)


k = random.randrange(1, 2**127)

msg1="HelloHello"
msg2="IamBB"
if (len(sys.argv)>1):
msg=(sys.argv[1])

# Input R, S Signatures here  
r = 17456122099107622875979177060034160065534440309384765110770021588156777535269
s = 39548918176628970790297874101648966881380966278908886743977542233652364916621
h = int(hashlib.sha256(msg1.encode()).hexdigest(),base=16)



# Now generate a fault
rf = r
sf = (libnum.invmod(k,order)*(h+priv1*rf)) % order
hf = int(hashlib.sha256(msg2.encode()).hexdigest(),base=16)
kf = hf*(s-sf) * libnum.invmod(sf*r-s*rf,order)
valinv = libnum.invmod( (sf*r-s*rf),order)
dx = (hf*(s-sf)* valinv) % order


print(f"Sig 1 (Good):")
print(f" R :{r}")
print(f" S1:{s}")
print(f" H1:{h}")
print(f" K :{k}")
print(f" ------------------------------------------------")
print(f" ------------------------------------------------")
print(f" ------------------------------------------------")

print(f"Sig 2 (Faulty):")
print(f" R :{rf}")
print(f" S2:{sf}")
print(f" H2:{hf}")
print(f" K :{kf}")

print (f"\nRecovered private key: {dx}")



Output
Code:

Sig 1 (Good):
 R :17456122099107622875979177060034160065534440309384765110770021588156777535269
 S1:39548918176628970790297874101648966881380966278908886743977542233652364916621
 H1:11209404430005450692776394377220775389388011163944676048947869460159787075727
 K :15903292315272842822984172996837488417
 ------------------------------------------------
 ------------------------------------------------
 ------------------------------------------------
Sig 2 (Faulty):
 R :17456122099107622875979177060034160065534440309384765110770021588156777535269
 S2:96338585688289334914636720032979620932082282355556627366484199230071141146598
 H2:54726123683982229645080045215760981633879898681032674670062989804976143680540
 K :-188432705557505607344590839989163044641633590292582796389468919499880245866943402758495487463160167555366829032436838039969514252512664280259846882814057850528865220835685847937360676866739560844105311285127539338911992423544765060

Recovered private key: 107749115139875514357274396597987236665757310837906895959705889341744968705665

I took one of the RSZ generated and create the same R signature to give out the K value(Which does not matter cause it was randomly generated) and i got the correct Private Key.

However, i want to create a different R signature and now try out another attack. (Same nonce K use to sign different message)

 What should i change at the R here? or What is the correct formula in python?
Quote

# Now generate a fault
rf = r
sf = (libnum.invmod(k,order)*(h+priv1*rf)) % order
hf = int(hashlib.sha256(msg2.encode()).hexdigest(),base=16)
kf = hf*(s-sf) * libnum.invmod(sf*r-s*rf,order)
valinv = libnum.invmod( (sf*r-s*rf),order)
dx = (hf*(s-sf)* valinv) % order

84  Bitcoin / Development & Technical Discussion / Re: Reused R nonce faulty signature attack on: December 31, 2022, 04:12:02 PM
it is not finished.

try your self. secp256k1 if you add abstract thinking you will see "there are another properties" that you can use.

You should observe the values as output and think what is going on and test it.

a lot of us had make thousend test to verify thousends posiibilities.

some times you must "go away" and create you own pattern , sometimes expand "calculation" for new  coeffs.

I still observe and have a good result.


no one on this forum will really share with his knowledge. TRY Harder and be positive.



🥰🥰
85  Bitcoin / Development & Technical Discussion / Re: Formula to calculate Private keys on: December 31, 2022, 10:26:26 AM
What is the formula to calculate private keys if you already have all the R,S,Z(H) K Value? 
Where d= private_key.


d = (k * s - z) * r-1 mod n

Source: https://learnmeabitcoin.com/technical/ecdsa (Why do you need to generate a random point each time? (Mathematical Explanation)
thank u so much. Cheers brother.
86  Bitcoin / Development & Technical Discussion / Formula to calculate Private keys on: December 31, 2022, 06:03:08 AM
What is the formula to calculate private keys if you already have all the R,S,Z(H) K Value? 
Where d= private_key.
87  Bitcoin / Development & Technical Discussion / Re: Hex to Wif Mass convertor on: December 31, 2022, 05:15:08 AM
can anyone recommend a mass hex to wif convertor that actually works? tried the ones readily available on github, but it dont work.
Did you try this?
https://github.com/joesciii/BitcoinKeyConverter,
This tool may help you convert hex priv keys to wif offline. Instructions to use it given within the program.
Also, dont try too many random convertors online and risk your keys being stolen.
just tested this. it works. thanks bro.
88  Bitcoin / Development & Technical Discussion / Re: Bitcoin public keys on: December 31, 2022, 04:35:06 AM
So if i were to give my public key x coordinate input, i should only change the G? And leave the rest as is. Ok thank you so much pooya.
Sorry I made a small mistake, P in this code is actually the public key and you should change that if you want to use another key. F is the curve's prime and G is as I said the generator point and is a constant that shouldn't be changed.
ok got it pooya. thank you so much.
89  Bitcoin / Development & Technical Discussion / Hex to Wif Mass convertor on: December 31, 2022, 04:30:21 AM
can anyone recommend a mass hex to wif convertor that actually works? tried the ones readily available on github, but it dont work.
90  Bitcoin / Development & Technical Discussion / Reused R nonce faulty signature attack on: December 30, 2022, 10:04:42 AM
i recreate the attack and modify the code based on this article.

https://asecuritysite.com/ecdsa/ecd7

it does work in giving out the private keys.

Code:

import ecdsa
import random
import libnum
import hashlib
import sys

P = 2^256 - 2^32 - 2^9 - 2^8 - 2^7 - 2^6 - 2^4 - 1
N = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141
order = N
priv1 = 20
G = (31504125288796341338541169388783846543997786027594142627385926708036691251730,
29015715595623874326232564738946807912877814040423899127791236573353650594580)


k = int(input("K:"))
if k < 1 or k > 2**127:
   raise ValueError("Input is out of range")

r = 66117490189936270206987461679613764204679654666049042771015493508015054858077
s = 49674599047379925216583523329074143648157909613025861611589669633503106636260
h = 99349198094759850433167046658148287296315819226051723223179339267006213272520

msg="HelloHello"



# Now generate a fault
rf = r
sf = (libnum.invmod(k,order)*(h+priv1*rf)) % order
hf = int(hashlib.sha256(msg.encode()).hexdigest(),base=16)
k = hf*(s-sf) * libnum.invmod(sf*r-s*rf,order)
valinv = libnum.invmod( (sf*r-s*rf),order)
dx = (hf*(s-sf)* valinv) % order

print(f"k: {k}")
print(f"Sig 1 (Good): r1={r}, s1={s}, h1={h}")
print(f"Sig 2 (Faulty): r2={rf}, s2={sf}, h2={hf}")
print (f"\nRecovered private key: {dx}")

however, the private keys given are not of the targeted wallet address. so nope, your bitcoins are still safe.
my inputs could be wrong though, correct me if im wrong. thank u so much.

Code:

K:2410
k: -8798166015846973725561614309791304655239378187079711764294056475330149015934906772429315822306934901393705779350762680499808112349218839583434901201485582221473728750380597901824590880328183205377959771799530340013137323794330090
Sig 1 (Good): r1=66117490189936270206987461679613764204679654666049042771015493508015054858077, s1=49674599047379925216583523329074143648157909613025861611589669633503106636260, h1=99349198094759850433167046658148287296315819226051723223179339267006213272520
Sig 2 (Faulty): r2=66117490189936270206987461679613764204679654666049042771015493508015054858077, s2=94761076309972293894096285019617727370519309086943504219315190442656806572338, h2=11209404430005450692776394377220775389388011163944676048947869460159787075727

Recovered private key: 37708835787268217211476314887030394677427639753441187644516074530096113903948

91  Bitcoin / Development & Technical Discussion / Re: Bitcoin public keys on: December 30, 2022, 12:41:52 AM
~
Do you have a python or sage code I can look at? I'm a security researcher and I really need to see whether I can recreate a valid (not signed) RSZ.
Read this: https://bitcoin.stackexchange.com/questions/81115/if-someone-wanted-to-pretend-to-be-satoshi-by-posting-a-fake-signature-to-defrau/
yeah..they gave the codes there as well. thank you pooya. appreciate it.



what is the G and P inputs? is P the public keys input?

Quote

F = FiniteField (0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F)
C = EllipticCurve ([F (0), F (7)])
G = C.lift_x(0x79BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798)
N = FiniteField (C.order())
P = P=-C.lift_x(0x11db93e1dcdb8a016b49840f8c53bc1eb68a382e97b1482ecad7b148a6909a5c) # block 9 coinbase payout key.
def forge(c, a=-1):  # Create a forged 'ECDSA'  (hashless) signature
  # set a to something other than -1 to be less obvious
  a = N(a)
  R = c*G + int(a)*P
  s = N(int(R.xy()[0]))/a
  m = N(c)*N(int(R.xy()[0]))/a
  print( 'hash1 = %d'%m)
  print( 'r1 = %d'%(int(R.xy()[0])))
  print( 's1 = %d'%s)
for c in range(1,10):
  forge(c)


Mod note: Consecutive posts merged
92  Bitcoin / Development & Technical Discussion / Re: Bitcoin public keys on: December 30, 2022, 12:36:47 AM
Quote
Do you have a python or sage code I can look at? I'm a security researcher and I really need to see whether I can recreate a valid (not signed) RSZ.
It is better to understand the math behind that. Then, you will write that code easily by yourself, and you will go beyond that example.

So, a signature is a relation between some public key, and another "signature public key". You start from private key "d" and "signature private key" called "nonce" and often named as "k". You start from "s=(z+rd)/k" relation, rewrite it, and then convert from private to public keys. Then, if you understand it after such conversion, you know everything you need.
Code:
s=(z+rd)/k
sk=z+rd
sk-z=rd
rd=sk-z
d=(sk-z)/r
d=(s/r)k-(z/r)
Q=d*G
R=k*G
Q=(s/r)R-(z/r)
Then, when you know "Q" on the left side, you can put anything you want on the right side. Just pick two numbers: "s/r" and "z/r". Then, you will get your "R", and "r=R.x" from that, and then "s=(s/r)*r" and "z=(z/r)*r", then you will have a valid (r,s,z) tuple for that public key.

Also, you can go beyond that example, and convert it in another direction. So, by choosing some message, you can hash it, then you will get some z. Then, you can pick some (r,s) pair, and generate a valid Q from your (r,s,z) tuple. Then, you will reach some public key, with a valid signature, where you don't know the private key. It is called "public key recovery", and it is why you can type some address, and some signature, and no public key is needed, because it can be calculated. For example:
Quote
Code:
message="Hello World"
address="1psPJZYEJrjPtY6kw5Tqtj4mW2yXSSDuH"
signature="GwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAE="
Here, nobody knows the private key for 1psPJZYEJrjPtY6kw5Tqtj4mW2yXSSDuH, it is a "trap address", but this signature is valid.

So, to sum up: If you understand "Q=(s/r)R-(z/r)", then you know, that you can choose some Q, and get some matching (r,s,z) tuple, or vice versa: you can choose some (r,s,z) tuple, and find some Q by using public key recovery. Understanding this equation is all you need to go in both directions, and build other fake signatures beyond that. Also, for now it is only a nice mathematical trick, you cannot move any real coins with those tricks.

ahhh...very clear. Thank You So much.
93  Bitcoin / Development & Technical Discussion / Re: Bitcoin public keys on: December 28, 2022, 04:15:56 PM
Example: an attacker has the public keys of a wallet and he recreate/reverse the procedure to get a new RSZ signatures?
Yes, you can recreate a valid RSZ trio for any public key very easily. In fact some people used this method to attempt scamming others into believing they were the "real Satoshi Nakamoto". Keep in mind that Z is the hash of the message not the message and ECC does not work like that, you have to have a message (in bitcoin it is the transactions) not the hash (Z) alone.
And no you won't be able to spend anybody else's bitcoins this way Wink

Do you have a python or sage code I can look at? I'm a security researcher and I really need to see whether I can recreate a valid (not signed) RSZ.
94  Bitcoin / Development & Technical Discussion / Re: Bitcoin public keys on: December 28, 2022, 09:25:31 AM
RSZ thing is related to the signed transaction, it has nothing to do with the public key itself.
What do you mean by "public keys of the wallet"? Do you talk about public keys derived from the one master private key using one of derivation path?


I mean the public keys that's shown together with the signed transactions ..like in blockchain.com  so it's not possible to recreate the RSZ just from knowing the public keys right?
95  Bitcoin / Development & Technical Discussion / Bitcoin public keys on: December 28, 2022, 09:02:36 AM
Is it even possible to recreate the R, S , Z(H) signatures from the public keys? 

Example: an attacker has the public keys of a wallet and he recreate/reverse the procedure to get a new RSZ signatures? Maybe my question is illogical to some. Bear with me please.

I'm still learning.
 
Thank you. 
96  Bitcoin / Development & Technical Discussion / Re: Fault attack on secp256k1 on: December 09, 2022, 11:51:33 PM
You said "crack any wallet" though. Fault attacks can not be used to crack any wallet. They can only be used when you have some amount of control over the system that signs/creates a wallet at the moment of signing/creation.



Alright... Are you here to argue with me on what's the word used or would you like to blame the author for the word used?  Have you actually tried this method? I understand your meaning and the general meaning of fault attack.

HOWEVER, that's what the author of this website claim it is.

SO... despite of the choice of words used..

What or how can I modify this script so that it accepts my r, s, h and public key inputs?

Quote

#python fault.py
Message: Hello
k: 2377122631336757091406456643105226705197917127899304611236234685727643570878493 8957571817458862979584232284037410229596452277879610955286764320595345098952800 839149842089242517072957658427855833009982523662157423292631792006806365
Sig 1 (Good): r=41552918092331466876589119583071324014922831660434505150350778883250206623908, s=103219685505031464720805837014021801697332755430913759423777864063262658295904
Sig 2 (Faulty): r=41552918092331466876589119583071324014922831660434505150350778883250206623909, s=30990528248984818891301551608571623728524592243310248921245102910474460702403

Generated private key: 89452984132331904393121726602673115409896713988677951449044374033056235521792

Recovered private key: 89452984132331904393121726602673115409896713988677951449044374033056235521792
97  Bitcoin / Development & Technical Discussion / Re: Nonce Reuse Fault attack on secp256k1 on: December 09, 2022, 08:32:50 PM
Yeah. Agreed. I was thinking the same thing.. Click the link. The author too call it fault attack.

Hmm maYbe I should edit the subject of this topic.
98  Bitcoin / Development & Technical Discussion / Nonce reuse fault attack on secp256k1 on: December 09, 2022, 07:46:00 PM
Hi, I was wondering whether anyone had tried Nonce Reuse fault attack on SECP256K1.

It seems so much easier to crack any wallet with this attack. Read here> https://asecuritysite.com/ecdsa/ecd7

I had tried lattice attack on my wallet address for 5 weeks now. It works but really slow.

I am considering starting a new attack for my research. Your inputs are greatly appreciated.

How can i modify this script to accept my R,S,H and public keys ? Please help. Thank You so much.  Cheesy



Code is here.

Quote

import ecdsa
import random
import libnum
import hashlib
import sys


G = ecdsa.SECP256k1.generator
order = G.order()

priv1 = random.randrange(1,order)
 
Public_key = ecdsa.ecdsa.Public_key(G, G * priv1)
d = ecdsa.ecdsa.Private_key(Public_key, priv1)

k = random.randrange(1, 2**127)

msg="Hello"

if (len(sys.argv)>1):
   msg=(sys.argv[1])



h = int(hashlib.sha256(msg.encode()).hexdigest(),base=16)
sig = d.sign(h, k)


r,s = sig.r,sig.s

# Now generate a fault
rf = sig.r+1
sf=(libnum.invmod(k,order)*(h+priv1*rf)) % order

k = h*(s-sf) * libnum.invmod(sf*r-s*rf,order)


valinv = libnum.invmod( (sf*r-s*rf),order)

dx =(h*(s-sf)* valinv) % order

print(f"Message: {msg}")
print(f"k: {k}")

print(f"Sig 1 (Good): r={r}, s={s}")
print(f"Sig 2 (Faulty): r={rf}, s={sf}")

print (f"\nGenerated private key: {priv1}")
print (f"\nRecovered private key: {dx}")

Result is here.

Quote
#python fault.py
Message: Hello
k: 2377122631336757091406456643105226705197917127899304611236234685727643570878493 8957571817458862979584232284037410229596452277879610955286764320595345098952800 839149842089242517072957658427855833009982523662157423292631792006806365
Sig 1 (Good): r=41552918092331466876589119583071324014922831660434505150350778883250206623908, s=103219685505031464720805837014021801697332755430913759423777864063262658295904
Sig 2 (Faulty): r=41552918092331466876589119583071324014922831660434505150350778883250206623909, s=30990528248984818891301551608571623728524592243310248921245102910474460702403

Generated private key: 89452984132331904393121726602673115409896713988677951449044374033056235521792

Recovered private key: 89452984132331904393121726602673115409896713988677951449044374033056235521792

99  Bitcoin / Development & Technical Discussion / Re: lattice-attack || how to run without error on: December 04, 2022, 12:50:08 PM

Some problems with install fpylll

Developer using Ubuntu >= 20.04
So try on Ubuntu 20.04

pip install git+https://github.com/bitlogik/lattice-attack
pip install git+https://github.com/fplll/fpylll.git

All command try installs not successful both on os windows and Linux

using conda not successful too
conda install -c conda-forge fpylll

all methods include update apt too

sudo add-apt-repository universe
sudo apt update
sudo apt install python3-fpylll

pip install Cython

all fail


remove sagemath and it will work. somehow fpylll clash with sagemath and it does not run properly. removing sagemath will solve your issue. in debian,
#apt remove sagemath
#apt update

then run your lattice_attack.py again.
100  Bitcoin / Development & Technical Discussion / Re: Generating 100 R, s, Z signatures on: November 21, 2022, 11:42:47 PM
Why don't you simply make 100 raw transactions with the same input containing the pubkey, but with different amounts? You should certainly get 100 different RSZ tuples that way. You don't need to use a sample RSZ for this, you just need an input that is associated with the public key you type.
I don't have that much bitcoins to spend.

1. You can create signed raw transaction without broadcasting it, which means you never spend your Bitcoin.
2. You could use Testnet or Regtest network. Although you might need to obtain some coin from faucet (for testnet), perform initial node setup (for regtest) or make small change on your script.


oh i did not know that. ok will do. thank you.
Pages: « 1 2 3 4 [5] 6 »
Powered by MySQL Powered by PHP Powered by SMF 1.1.19 | SMF © 2006-2009, Simple Machines Valid XHTML 1.0! Valid CSS!