Bitcoin Forum
November 13, 2024, 05:59:36 AM *
News: Latest Bitcoin Core release: 28.0 [Torrent]
 
   Home   Help Search Login Register More  
Pages: [1]
  Print  
Author Topic: Recreated Fault Sig Attack on Bitcoin Wallet  (Read 477 times)
krashfire (OP)
Member
**
Offline Offline

Activity: 127
Merit: 14

Life aint interesting without any cuts and bruises


View Profile
January 03, 2023, 11:23:28 AM
Last edit: January 03, 2023, 07:51:03 PM by krashfire
 #1

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


KRASH
ymgve2
Full Member
***
Offline Offline

Activity: 161
Merit: 230


View Profile
January 04, 2023, 03:05:00 AM
Last edit: January 04, 2023, 03:21:33 AM by ymgve2
 #2

The ouptut of the first program doesn't contain a private key. How do you know 107749115139875514357274396597987236665757310837906895959705889341744968705665 is the correct private key for those values?

edit: just checked, the public key for that private key is 18937642771426163626487493468157767561404567341272835442397463474527806095299, 48085753477814850198787397705162128287610204980059015577563321458947326271695 which is NOT the public key you inputted in your script. In other words, your modified program gave the wrong solution.
ymgve2
Full Member
***
Offline Offline

Activity: 161
Merit: 230


View Profile
January 31, 2023, 12:56:21 AM
Last edit: February 01, 2023, 04:27:13 AM by achow101
 #3

what you think about this attack ? How to make pubkeys  from another curve for realise this attack:

[mod note: malware link removed]

https://github.com/christianlundkvist/blog/blob/master/2020_05_26_secp256k1_twist_attacks/secp256k1_twist_attacks.md

haw you any ideas ?



Russian website that requires you to install obscure binary executables? What could possibly go wrong?
COBRAS
Member
**
Offline Offline

Activity: 1018
Merit: 23


View Profile
January 31, 2023, 01:01:06 AM
Last edit: February 01, 2023, 04:27:27 AM by achow101
 #4

what you think about this attack ? How to make pubkeys  from another curve for realise this attack:

[mod note: malware link removed]

https://github.com/christianlundkvist/blog/blob/master/2020_05_26_secp256k1_twist_attacks/secp256k1_twist_attacks.md

haw you any ideas ?



Russian website that requires you to install obscure binary executables? What could possibly go wrong?

This is without russian, English only https://github.com/demining/Twist-Attack

[
ymgve2
Full Member
***
Offline Offline

Activity: 161
Merit: 230


View Profile
January 31, 2023, 01:05:40 AM
 #5


This is without russian, English only https://github.com/demining/Twist-Attack

In the middle of that tutorial, it tells you to download a completely opaque "attacksafe" binary and run it.

Some of the attack types listed for that program in the tutorial are pure nonsense and can't be done by a single program (like "supply chain attack" or "rowhammer attack") which makes me suspect it's just a trojan.
COBRAS
Member
**
Offline Offline

Activity: 1018
Merit: 23


View Profile
January 31, 2023, 01:15:35 AM
 #6


This is without russian, English only https://github.com/demining/Twist-Attack

In the middle of that tutorial, it tells you to download a completely opaque "attacksafe" binary and run it.

Some of the attack types listed for that program in the tutorial are pure nonsense and can't be done by a single program (like "supply chain attack" or "rowhammer attack") which makes me suspect it's just a trojan.

you can try calculate yourself pubkeys Q11...Q64 without use safeattack and find priv https://github.com/demining/CryptoDeepTools/tree/bbd83042e7405508cd2e646ad1b0819da0f9c58d/18TwistAttack

Question how to calculate Q11...Q64, using Sighnature and Base points  P11..P64 ??

[
krashfire (OP)
Member
**
Offline Offline

Activity: 127
Merit: 14

Life aint interesting without any cuts and bruises


View Profile
January 31, 2023, 10:02:05 AM
 #7


This is without russian, English only https://github.com/demining/Twist-Attack

In the middle of that tutorial, it tells you to download a completely opaque "attacksafe" binary and run it.

Some of the attack types listed for that program in the tutorial are pure nonsense and can't be done by a single program (like "supply chain attack" or "rowhammer attack") which makes me suspect it's just a trojan.

you can try calculate yourself pubkeys Q11...Q64 without use safeattack and find priv https://github.com/demining/CryptoDeepTools/tree/bbd83042e7405508cd2e646ad1b0819da0f9c58d/18TwistAttack

Question how to calculate Q11...Q64, using Sighnature and Base points  P11..P64 ??

Thanks cobra.. I will be trying that attack next.

KRASH
COBRAS
Member
**
Offline Offline

Activity: 1018
Merit: 23


View Profile
January 31, 2023, 12:12:32 PM
 #8


This is without russian, English only https://github.com/demining/Twist-Attack

In the middle of that tutorial, it tells you to download a completely opaque "attacksafe" binary and run it.

Some of the attack types listed for that program in the tutorial are pure nonsense and can't be done by a single program (like "supply chain attack" or "rowhammer attack") which makes me suspect it's just a trojan.

you can try calculate yourself pubkeys Q11...Q64 without use safeattack and find priv https://github.com/demining/CryptoDeepTools/tree/bbd83042e7405508cd2e646ad1b0819da0f9c58d/18TwistAttack

Question how to calculate Q11...Q64, using Sighnature and Base points  P11..P64 ??

Thanks cobra.. I will be trying that attack next.


Need to modify haved sighnature for send to fake base point(publick key) and after recalculate senders sighnature and get from recalculated sighnature new pubkey of sender.  I ask at crypto.stackexchange now answer how to make attack !!! https://crypto.stackexchange.com/questions/103993/how-to-calculate-points-for-twist


this attack can be imlosible to make it, or work only from bug sughnatures I think .. unfortunately. Bat maybe we can copy result of cryptodeep. I waiting then you start to try this attack.

Br

[
krashfire (OP)
Member
**
Offline Offline

Activity: 127
Merit: 14

Life aint interesting without any cuts and bruises


View Profile
January 31, 2023, 07:41:59 PM
 #9


This is without russian, English only https://github.com/demining/Twist-Attack

In the middle of that tutorial, it tells you to download a completely opaque "attacksafe" binary and run it.

Some of the attack types listed for that program in the tutorial are pure nonsense and can't be done by a single program (like "supply chain attack" or "rowhammer attack") which makes me suspect it's just a trojan.

you can try calculate yourself pubkeys Q11...Q64 without use safeattack and find priv https://github.com/demining/CryptoDeepTools/tree/bbd83042e7405508cd2e646ad1b0819da0f9c58d/18TwistAttack

Question how to calculate Q11...Q64, using Sighnature and Base points  P11..P64 ??

Thanks cobra.. I will be trying that attack next.


Need to modify haved sighnature for send to fake base point(publick key) and after recalculate senders sighnature and get from recalculated sighnature new pubkey of sender.  I ask at crypto.stackexchange now answer how to make attack !!! https://crypto.stackexchange.com/questions/103993/how-to-calculate-points-for-twist


this attack can be imlosible to make it, or work only from bug sughnatures I think .. unfortunately. Bat maybe we can copy result of cryptodeep. I waiting then you start to try this attack.

Br
ok will do!

KRASH
COBRAS
Member
**
Offline Offline

Activity: 1018
Merit: 23


View Profile
January 31, 2023, 08:22:39 PM
 #10


This is without russian, English only https://github.com/demining/Twist-Attack

In the middle of that tutorial, it tells you to download a completely opaque "attacksafe" binary and run it.

Some of the attack types listed for that program in the tutorial are pure nonsense and can't be done by a single program (like "supply chain attack" or "rowhammer attack") which makes me suspect it's just a trojan.

you can try calculate yourself pubkeys Q11...Q64 without use safeattack and find priv https://github.com/demining/CryptoDeepTools/tree/bbd83042e7405508cd2e646ad1b0819da0f9c58d/18TwistAttack

Question how to calculate Q11...Q64, using Sighnature and Base points  P11..P64 ??

Thanks cobra.. I will be trying that attack next.


Need to modify haved sighnature for send to fake base point(publick key) and after recalculate senders sighnature and get from recalculated sighnature new pubkey of sender.  I ask at crypto.stackexchange now answer how to make attack !!! https://crypto.stackexchange.com/questions/103993/how-to-calculate-points-for-twist


this attack can be imlosible to make it, or work only from bug sughnatures I think .. unfortunately. Bat maybe we can copy result of cryptodeep. I waiting then you start to try this attack.

Br
ok will do!

great !

[
krashfire (OP)
Member
**
Offline Offline

Activity: 127
Merit: 14

Life aint interesting without any cuts and bruises


View Profile
February 04, 2023, 04:24:44 AM
 #11

Cobra.. that one is a paid version. I don't have money.
So I code it myself. Just a simple twist attack in JavaScript.

This works.

Code:
The following code is an example of an ECDSA secp256k1 twist attack.

// Generate a random private key
var privateKey = crypto.randomBytes(32);

// Generate a public key from the private key
var publicKey = secp256k1.publicKeyCreate(privateKey);

// Generate a random message
var message = crypto.randomBytes(32);

// Sign the message with the private key
var signature = secp256k1.sign(message, privateKey);

// Generate a twisted public key
var twistedPublicKey = secp256k1.publicKeyTweakAdd(publicKey, crypto.randomBytes(32));

// Verify the signature with the twisted public key
var valid = secp256k1.verify(message, signature, twistedPublicKey);

// Output the result
console.log("Signature is valid: " + valid);

Test it man.

KRASH
COBRAS
Member
**
Offline Offline

Activity: 1018
Merit: 23


View Profile
February 04, 2023, 04:32:59 AM
 #12

Cobra.. that one is a paid version. I don't have money.
So I code it myself. Just a simple twist attack in JavaScript.

This works.

Code:
The following code is an example of an ECDSA secp256k1 twist attack.

// Generate a random private key
var privateKey = crypto.randomBytes(32);

// Generate a public key from the private key
var publicKey = secp256k1.publicKeyCreate(privateKey);

// Generate a random message
var message = crypto.randomBytes(32);

// Sign the message with the private key
var signature = secp256k1.sign(message, privateKey);

// Generate a twisted public key
var twistedPublicKey = secp256k1.publicKeyTweakAdd(publicKey, crypto.randomBytes(32));

// Verify the signature with the twisted public key
var valid = secp256k1.verify(message, signature, twistedPublicKey);

// Output the result
console.log("Signature is valid: " + valid);

Test it man.

Yes Bro. I will test and make a massage.

Br

[
krashfire (OP)
Member
**
Offline Offline

Activity: 127
Merit: 14

Life aint interesting without any cuts and bruises


View Profile
February 04, 2023, 04:34:56 AM
 #13

This is in python code.

Code:
#This example twist attack on secp256k1 uses the Python library 'ecdsa'

import ecdsa

#Generate a random private key
priv_key = ecdsa.util.randrange(2**256)

#Generate a public key from the private key
pub_key = ecdsa.SigningKey.from_secret_exponent(priv_key, curve=ecdsa.SECP256k1).verifying_key

#Generate a random point on the curve
P = ecdsa.ellipticcurve.Point(ecdsa.SECP256k1.curve, ecdsa.util.randrange(ecdsa.SECP256k1.curve.p()), ecdsa.util.randrange(ecdsa.SECP256k1.curve.p()))

#Calculate the twist attack
Q = P + pub_key.pubkey.point

#Verify that the attack was successful
if Q.x() == pub_key.pubkey.point.x() and Q.y

KRASH
COBRAS
Member
**
Offline Offline

Activity: 1018
Merit: 23


View Profile
February 04, 2023, 05:09:11 AM
Last edit: February 04, 2023, 05:51:59 AM by COBRAS
 #14

This is in python code.

Code:
#This example twist attack on secp256k1 uses the Python library 'ecdsa'

import ecdsa

#Generate a random private key
priv_key = ecdsa.util.randrange(2**256)

#Generate a public key from the private key
pub_key = ecdsa.SigningKey.from_secret_exponent(priv_key, curve=ecdsa.SECP256k1).verifying_key

#Generate a random point on the curve
P = ecdsa.ellipticcurve.Point(ecdsa.SECP256k1.curve, ecdsa.util.randrange(ecdsa.SECP256k1.curve.p()), ecdsa.util.randrange(ecdsa.SECP256k1.curve.p()))

#Calculate the twist attack
Q = P + pub_key.pubkey.point

#Verify that the attack was successful
if Q.x() == pub_key.pubkey.point.x() and Q.y



File "HelloWorld.py", line 18
    if Q.x() == pub_key.pubkey.point.x() and  Q.y
                                                ^
SyntaxError: invalid syntax

?

twist atk is like invalid curve attack:

"For an invalid curve attack, you are not so much mapping points from a curve to another. The attacker chooses an appropriate point P
 on the new curve and send this malicious point, and the victim computes Q=x∗P
. But computing Q
 will simply use the "computation rules" of the malicious curve. The reason, you called n
 is not needed for computing Q
. So, the victim is tricked to reveal some information on x
. Repeat with different n
 until x
 can be fully revealed. And this is fixed by verifying that the point received indeed lies on the "secure" curve."


this is a attac exp, all publick keys


https://github.com/demining/CryptoDeepTools/blob/main/18TwistAttack/discrete.py

and this


https://github.com/christianlundkvist/blog/blob/master/2020_05_26_secp256k1_twist_attacks/files/recover_private_key.sagews

we need mult secret x to fake pub from twist !

so we neeb emulate sending btc from good wallet to twist publick key

another help:

https://cryptodeep.ru/kangaroo/ in this toturial R usead as Pubkey

how to compute priv to pubkey from twist using sighnature ?

why you think what this is a twist ? Q = P + pub_key.pubkey.point for twist we need poin of a cyrve for ex


E3 = EllipticCurve(GF(p), [0,3])

P31 = E3([93579283295185043256820683457089915228054046133395133419577655037763911527649, 112632096923660630255684142108084503413038643268482102767008195691777477419906])
ord31 = 109903

?

does R of sighnature for twist pubkey will be from curve of twist ?





[
Pages: [1]
  Print  
 
Jump to:  

Powered by MySQL Powered by PHP Powered by SMF 1.1.19 | SMF © 2006-2009, Simple Machines Valid XHTML 1.0! Valid CSS!