Author

Topic: Recreated Fault Sig Attack on Bitcoin Wallet (Read 178 times)

member
Activity: 785
Merit: 20
$$P2P BTC BRUTE.JOIN NOW ! https://uclck.me/SQPJk
January 31, 2023, 04:22:39 PM
#11

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 !
jr. member
Activity: 77
Merit: 6
Life aint interesting without any cuts and bruises

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!
member
Activity: 785
Merit: 20
$$P2P BTC BRUTE.JOIN NOW ! https://uclck.me/SQPJk

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
jr. member
Activity: 77
Merit: 6
Life aint interesting without any cuts and bruises

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.
member
Activity: 785
Merit: 20
$$P2P BTC BRUTE.JOIN NOW ! https://uclck.me/SQPJk

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 ??
full member
Activity: 161
Merit: 230

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.
member
Activity: 785
Merit: 20
$$P2P BTC BRUTE.JOIN NOW ! https://uclck.me/SQPJk
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
member
Activity: 785
Merit: 20
$$P2P BTC BRUTE.JOIN NOW ! https://uclck.me/SQPJk
full member
Activity: 161
Merit: 230
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?
full member
Activity: 209
Merit: 103
Dr WHO on disney+

below link to Lattice-based weak curve fault attack on ECDSA
first please read : https://eprint.iacr.org/2021/129.pdf

maybe it will give you more information.

calculating new coeff as R=a*G + b*pub and will not work. becouse then you  must change generator of group. if change generator of group - > then must use crt, and so on. Will not work.


and second very important link:

link http://jbreier.com/files/papers/isic_2014_1.pdf  as A Survey of the State-of-the-Art Fault Attacks



full member
Activity: 161
Merit: 230
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.
jr. member
Activity: 77
Merit: 6
Life aint interesting without any cuts and bruises
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

Jump to: