Bitcoin Forum
May 05, 2024, 06:32:53 AM *
News: Latest Bitcoin Core release: 27.0 [Torrent]
 
  Home Help Search Login Register More  
  Show Posts
Pages: [1]
1  Other / Off-topic / my problem with puzzle BTC #130 on: April 03, 2024, 02:33:23 PM
A few months ago I wrote a method that gave me the freedom to say that practically in 1 month I could collect the reward. However, my happiness did not last long.

In the first instance I was in the wrong range.

My wife betrayed me for a new man and left me homeless, I lost everything I had built in many years of my life, now I only have depression and anxiety because of everything I have experienced, I now sleep at a friend's house and I lost my job thanks to what I suffer from.

The point of suing does not exist in my country, the new man is associated with criminal gangs and I fear for my life if I try to recover something.

My points in favor are that the code is in my mind, and they can't take that away from me.

This illness is the worst thing that has ever happened to me, and I write this to give some context. I know I will get out of this abyss and fulfill my dreams.
I want to leave this in writing here, so that when I achieve my goals I can be an example of improvement, there is no evil that lasts forever and when we want we can move forward no matter what happens.

Happy day to everyone.
2  Bitcoin / Development & Technical Discussion / How secure would such a Bitcoin address be? on: March 19, 2024, 07:06:02 AM
In my free time, for fun, I created this script:

we create an addreess with additional secret code

based on schnorr aggregate signatures

How secure would a bitcoin address system proposed in this way be?

My main thought was to reduce (even further) the probability that if the ECDSA algorithm were violated (paranoid mode), it would be even more difficult to deduce a pk from the public key.


pip install bitcoin

Code:
import schnorr_lib
import hashlib
from bitcoin import *
import random

N = 115792089237316195423570985008687907852837564279074904382605163141518161494337
################################################################################################




privkey = random.randint(1,N-1)

secret_code= 1234567890

msg= b'Hello BitcoinTalk'





################################################################################################


def Pk_shadow(pubX, pubY):
    pub_sh_str = str(pubX)+str(pubY)
    converted_digits = []
    for digit in pub_sh_str:
        nd = int(digit)
        if nd % 2 == 0:
            converted_digits.append(0)
        else:
            converted_digits.append(1)
            bits = "".join(map(str, converted_digits))
            dec = int(bits, 2)
    return dec


upub_dec= privtopub(privkey)
pubKeyX, pubKeyY = upub_dec

pubX=pubKeyX
pubY=pubKeyY
Pk_Sh = ((Pk_shadow(pubX, pubY))) % N

privkey2 = (int(privkey+Pk_Sh)*secret_code) % N


privkey_hex = hex(privkey)[2:]
privkey_hex = '0' + privkey_hex if len(privkey_hex) % 2 != 0 else privkey_hex
privkey2_hex = hex(privkey2)[2:]
privkey2_hex = '0' + privkey2_hex if len(privkey2_hex) % 2 != 0 else privkey2_hex

print(f"Private key: {privkey_hex}"+"\n")
#print(str(privkey2)+"\n")
print(f"Secret Code: {secret_code}"+"\n")
print("msg:", str(msg)[1:]+"\n")

pubkey1 = schnorr_lib.pubkey_gen_from_int(privkey)
pubkey2 = schnorr_lib.pubkey_gen_from_int(privkey2)

msg = hashlib.sha256(msg).digest()
print("msg_hash:", msg.hex()+"\n")

users = [{"privateKey": privkey_hex, "publicKey": pubkey1}, {"privateKey": privkey2_hex, "publicKey": pubkey2}]
sig, agg_pubkey = schnorr_lib.schnorr_musig2_sign(msg, users)

print(f"Aggregated signature: {sig.hex()}"+"\n")
print(f"Aggregated public key: {agg_pubkey.hex()}"+"\n")


verification = schnorr_lib.schnorr_verify(msg, agg_pubkey, sig)

print(f"Aggregated signature verification: {verification}"+"\n")

assert verification


multisig_address = str(scriptaddr(agg_pubkey.hex()))+"\n"

print("Address:","4"+multisig_address[1:])



schnorr_lib.py Thanks to https://github.com/BitPolito/schnorr-sig/blob/master/schnorr_lib.py

Code:
from typing import Tuple, Optional
from binascii import unhexlify
import hashlib
import os

# Elliptic curve parameters
p = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F
n = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141
G = (0x79BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798,
     0x483ADA7726A3C4655DA4FBFC0E1108A8FD17B448A68554199C47D08FFB10D4B8)

# Points are tuples of X and Y coordinates
# the point at infinity is represented by the None keyword
Point = Tuple[int, int]


# Get bytes from an int
def bytes_from_int(a: int) -> bytes:
    return a.to_bytes(32, byteorder="big")


# Get bytes from a hex
def bytes_from_hex(a: hex) -> bytes:
    return unhexlify(a)


# Get bytes from a point
def bytes_from_point(P: Point) -> bytes:
    return bytes_from_int(x(P))


# Get an int from bytes
def int_from_bytes(b: bytes) -> int:
    return int.from_bytes(b, byteorder="big")


# Get an int from hex
def int_from_hex(a: hex) -> int:
    return int.from_bytes(unhexlify(a), byteorder="big")


# Get x coordinate from a point
def x(P: Point) -> int:
    return P[0]


# Get y coordinate from a point
def y(P: Point) -> int:
    return P[1]


# Point addition
def point_add(P1: Optional[Point], P2: Optional[Point]) -> Optional[Point]:
    if P1 is None:
        return P2
    if P2 is None:
        return P1
    if (x(P1) == x(P2)) and (y(P1) != y(P2)):
        return None
    if P1 == P2:
        lam = (3 * x(P1) * x(P1) * pow(2 * y(P1), p - 2, p)) % p
    else:
        lam = ((y(P2) - y(P1)) * pow(x(P2) - x(P1), p - 2, p)) % p
    x3 = (lam * lam - x(P1) - x(P2)) % p
    return x3, (lam * (x(P1) - x3) - y(P1)) % p


# Point multiplication
def point_mul(P: Optional[Point], d: int) -> Optional[Point]:
    R = None
    for i in range(256):
        if (d >> i) & 1:
            R = point_add(R, P)
        P = point_add(P, P)
    return R


# Note:
# This implementation can be sped up by storing the midstate
# after hashing tag_hash instead of rehashing it all the time
# Get the hash digest of (tag_hashed || tag_hashed || message)
def tagged_hash(tag: str, msg: bytes) -> bytes:
    tag_hash = hashlib.sha256(tag.encode()).digest()
    return hashlib.sha256(tag_hash + tag_hash + msg).digest()


# Check if a point is at infinity
def is_infinity(P: Optional[Point]) -> bool:
    return P is None


# Get xor of bytes
def xor_bytes(b0: bytes, b1: bytes) -> bytes:
    return bytes(a ^ b for (a, b) in zip(b0, b1))


# Get a point from bytes
def lift_x_square_y(b: bytes) -> Optional[Point]:
    x = int_from_bytes(b)
    if x >= p:
        return None
    y_sq = (pow(x, 3, p) + 7) % p
    y = pow(y_sq, (p + 1) // 4, p)
    if pow(y, 2, p) != y_sq:
        return None
    return x, y


def lift_x_even_y(b: bytes) -> Optional[Point]:
    P = lift_x_square_y(b)
    if P is None:
        return None
    else:
        return x(P), y(P) if y(P) % 2 == 0 else p - y(P)


# Get hash digest with SHA256
def sha256(b: bytes) -> bytes:
    return hashlib.sha256(b).digest()


# Check if an int is square
def is_square(a: int) -> bool:
    return int(pow(a, (p - 1) // 2, p)) == 1


# Check if a point has square y coordinate
def has_square_y(P: Optional[Point]) -> bool:
    infinity = is_infinity(P)
    if infinity:
        return False
    assert P is not None
    return is_square(y(P))


# Check if a point has even y coordinate
def has_even_y(P: Point) -> bool:
    return y(P) % 2 == 0


# Generate public key from an int
def pubkey_gen_from_int(seckey: int) -> bytes:
    P = point_mul(G, seckey)
    assert P is not None
    return bytes_from_point(P)


# Generate public key from a hex
def pubkey_gen_from_hex(seckey: hex) -> bytes:
    seckey = bytes.fromhex(seckey)
    d0 = int_from_bytes(seckey)
    if not (1 <= d0 <= n - 1):
        raise ValueError(
            'The secret key must be an integer in the range 1..n-1.')
    P = point_mul(G, d0)
    assert P is not None
    return bytes_from_point(P)


# Generate public key (as a point) from an int
def pubkey_point_gen_from_int(seckey: int) -> Point:
    P = point_mul(G, seckey)
    assert P is not None
    return P


# Generate auxiliary random of 32 bytes
def get_aux_rand() -> bytes:
    return os.urandom(32)


# Extract R_x int value from signature
def get_int_R_from_sig(sig: bytes) -> int:
    return int_from_bytes(sig[0:32])


# Extract s int value from signature
def get_int_s_from_sig(sig: bytes) -> int:
    return int_from_bytes(sig[32:64])


# Extract R_x bytes from signature
def get_bytes_R_from_sig(sig: bytes) -> int:
    return sig[0:32]


# Extract s bytes from signature
def get_bytes_s_from_sig(sig: bytes) -> int:
    return sig[32:64]


# Generate Schnorr signature
def schnorr_sign(msg: bytes, privateKey: str) -> bytes:
    if len(msg) != 32:
        raise ValueError('The message must be a 32-byte array.')
    d0 = int_from_hex(privateKey)
    if not (1 <= d0 <= n - 1):
        raise ValueError(
            'The secret key must be an integer in the range 1..n-1.')
    P = point_mul(G, d0)
    assert P is not None
    d = d0 if has_even_y(P) else n - d0
    t = xor_bytes(bytes_from_int(d), tagged_hash("BIP0340/aux", get_aux_rand()))
    k0 = int_from_bytes(tagged_hash("BIP0340/nonce", t + bytes_from_point(P) + msg)) % n
    if k0 == 0:
        raise RuntimeError('Failure. This happens only with negligible probability.')
    R = point_mul(G, k0)
    assert R is not None
    k = n - k0 if not has_even_y(R) else k0
    e = int_from_bytes(tagged_hash("BIP0340/challenge", bytes_from_point(R) + bytes_from_point(P) + msg)) % n
    sig = bytes_from_point(R) + bytes_from_int((k + e * d) % n)
   
    if not schnorr_verify(msg, bytes_from_point(P), sig):
        raise RuntimeError('The created signature does not pass verification.')
    return sig


# Verify Schnorr signature
def schnorr_verify(msg: bytes, pubkey: bytes, sig: bytes) -> bool:
    if len(msg) != 32:
        raise ValueError('The message must be a 32-byte array.')
    if len(pubkey) != 32:
        raise ValueError('The public key must be a 32-byte array.')
    if len(sig) != 64:
        raise ValueError('The signature must be a 64-byte array.')
    P = lift_x_even_y(pubkey)
    r = get_int_R_from_sig(sig)
    s = get_int_s_from_sig(sig)
    if (P is None) or (r >= p) or (s >= n):
        return False
    e = int_from_bytes(tagged_hash("BIP0340/challenge", get_bytes_R_from_sig(sig) + pubkey + msg)) % n
    R = point_add(point_mul(G, s), point_mul(P, n - e))
    if (R is None) or (not has_even_y(R)):
        # print("Please, recompute the sign. R is None or has even y")
        return False
    if x(R) != r:
        # print("There's something wrong")
        return False
    return True


# Generate Schnorr MuSig signature
def schnorr_musig_sign(msg: bytes, users: list) -> bytes:
    if len(msg) != 32:
        raise ValueError('The message must be a 32-byte array.')
   
    # Key aggregation (KeyAgg), L = h(P1 || ... || Pn)
    L = b''
    for u in users:
        L += pubkey_gen_from_hex(u["privateKey"])
    L = sha256(L)

    Rsum = None
    X = None
    for u in users:
        # Get private key di and public key Pi
        di = int_from_hex(u["privateKey"])
        if not (1 <= di <= n - 1):
            raise ValueError('The secret key must be an integer in the range 1..n-1.')
        Pi = pubkey_point_gen_from_int(di)
        assert Pi is not None
       
        # KeyAggCoef
        # ai = h(L||Pi)
        ai = int_from_bytes(sha256(L + bytes_from_point(Pi)))
        u["ai"] = ai

        # Computation of X~
        # X~ = X1 + ... + Xn, Xi = ai * Pi
        X = point_add(X, point_mul(Pi, ai))

        # Random ki with tagged hash
        t = xor_bytes(bytes_from_int(di), tagged_hash("BIP0340/aux", get_aux_rand()))
        ki = int_from_bytes(tagged_hash("BIP0340/nonce", t + bytes_from_point(Pi) + msg)) % n
        if ki == 0:
            raise RuntimeError('Failure. This happens only with negligible probability.')
       
        # Ri = ki * G
        Ri = point_mul(G, ki)
        assert Ri is not None
       
        # Rsum = R1 + ... + Rn
        Rsum = point_add(Rsum, Ri)       
        u["ki"] = ki

    # The aggregate public key X~ needs to be y-even
    if not has_even_y(X):
        for i, u in enumerate(users):
            users[i]["ai"] = n - u["ai"]

    # If the aggregated nonce does not have an even Y
    # then negate  individual nonce scalars (and the aggregate nonce)
    if not has_even_y(Rsum):
        for i, u in enumerate(users):
            users[i]["ki"] = n - u["ki"]

    # c = hash( Rsum || X || M )
    c = int_from_bytes(tagged_hash("BIP0340/challenge", (bytes_from_point(Rsum) + bytes_from_point(X) + msg))) % n

    sSum = 0
    for u in users:
        # Get private key di
        di = int_from_hex(u["privateKey"])
       
        # sSum = s1 + ... + sn,  # si = ki + di * c * ai mod n
        sSum += (di * c * u["ai"] + u["ki"]) % n
    sSum = sSum % n

    signature_bytes = bytes_from_point(Rsum) + bytes_from_int(sSum)

    if not schnorr_verify(msg, bytes_from_point(X), signature_bytes):
        raise RuntimeError('The created signature does not pass verification.')
    return signature_bytes, bytes_from_point(X)


# Generate Schnorr MuSig2 signature
def schnorr_musig2_sign(msg: bytes, users: list) -> bytes:
    if len(msg) != 32:
        raise ValueError('The message must be a 32-byte array.')

    nu = 2

    # Key aggregation (KeyAgg), L = h(P1 || ... || Pn)
    L = b''
    for u in users:
        L += pubkey_gen_from_hex(u["privateKey"])
    L = sha256(L)

    X = None
    for u in users:
        # Get private key di and public key Pi
        di = int_from_hex(u["privateKey"])
        if not (1 <= di <= n - 1):
            raise ValueError('The secret key must be an integer in the range 1..n-1.')
        Pi = pubkey_point_gen_from_int(di)
        assert Pi is not None

        # KeyAggCoef
        # ai = h(L||Pi)
        ai = int_from_bytes(sha256(L + bytes_from_point(Pi)))
        u["ai"] = ai

        # Computation of X~
        # X~ = X1 + ... + Xn, Xi = ai * Pi
        X = point_add(X, point_mul(Pi, ai))

        # First signing round (Sign and SignAgg)
        r_list = []
        R_list = []

        for j in range(nu):
            # Random r with tagged hash
            t = xor_bytes(bytes_from_int(di), tagged_hash("BIP0340/aux", get_aux_rand()))
            r = int_from_bytes(tagged_hash("BIP0340/nonce", t + bytes_from_point(Pi) + msg)) % n
            if r == 0:
                raise RuntimeError('Failure. This happens only with negligible probability.')
       
            # Ri,j = ri,j * G (i represents the user)
            Rij = point_mul(G, r)
            assert Rij is not None

            r_list.append(r)
            R_list.append(Rij)           
        u["r_list"] = r_list
        u["R_list"] = R_list

    # SignAgg
    # for each j in {1 .. nu} aggregator compute Rj as sum of Rij  (where i goes
    # from 1 to n, and n is the number of user, while j is fixed for each round)
    # Rj is a set, where its size is nu
    Rj_list = []
    for j in range(nu):
        Rj_list.append(None)
        for u in users:
            Rj_list[j] = point_add(Rj_list[j], u["R_list"][j])
   
    # Second signing round (Sign', SignAgg', Sign'')
    # Sign'
    Rbytes = b''
    for Rj in Rj_list:
        Rbytes += bytes_from_point(Rj)

    # b = h(R1 || ... || Rn || X || M)
    b = sha256(Rbytes + bytes_from_point(X) + msg)

    Rsum = None
    for j, Rj in enumerate(Rj_list):
        # Rsum = SUM (Rj * b^(j))  (Rsum is R in the paper)
        Rsum = point_add(Rsum, point_mul(Rj, int_from_bytes(b) ** j))
    assert Rsum is not None   

    # The aggregate public key X~ needs to be y-even
    if not has_even_y(X):
        for i, u in enumerate(users):
            users[i]["ai"] = n - u["ai"]

    # If the aggregated nonce does not have an even Y
    # then negate  individual nonce scalars (and the aggregate nonce)
    if not has_even_y(Rsum):
        for i, u in enumerate(users):
            for j, r in enumerate(users[i]["r_list"]):
                users[i]["r_list"][j] = n - users[i]["r_list"][j]

    # c = hash( Rsum || X || M )
    c = int_from_bytes(tagged_hash("BIP0340/challenge", (bytes_from_point(Rsum) + bytes_from_point(X) + msg))) % n

    # SignAgg' step
    sSum = 0
    for u in users:
        # Get private key di
        di = int_from_hex(u["privateKey"])

        rb = 0
        for j in range(nu):
            rb += u["r_list"][j] * int_from_bytes(b)**j

        # ssum = s1 + ... + sn, si = (c*ai*di + r) % n
        sSum += (di * c * u["ai"]  + rb) % n
    sSum = sSum % n

    signature_bytes = bytes_from_point(Rsum) + bytes_from_int(sSum)   
     
    if not schnorr_verify(msg, bytes_from_point(X), signature_bytes):
        raise RuntimeError('The created signature does not pass verification.')
    return signature_bytes, bytes_from_point(X)

3  Other / Off-topic / Merry Cryptmas on: December 24, 2023, 04:08:02 PM
This holiday season, I extend my warmest wishes,

To the Bitcoin community, hoping it flourishes.

May your wallets be filled with digital gold,

May your transactions be secure, fast, cheap and may your investments grow.

As the story of blockchain continues to develop,

Through the ups and downs, we have stood strong together.

Navigating the world of cryptocurrencies, through stormy weather.

Let's celebrate innovation and decentralized power,

That brings Bitcoin, shining like a guiding light.

As we gather with our loved ones, near and far, as the year draws to a close,

let us reflect on the power of blockchain and the potential it holds for such a bright future.
 
Merry Christmas everyone!,

meanwhile, we continue to strive.
4  Bitcoin / Development & Technical Discussion / Binary Baby Step Giant Step with lightweight database - Brute force (BSGS) on: December 10, 2023, 06:39:15 PM
updated 12/11/2023.

The Baby Step Giant Step (BSGS) algorithm is used to solve the discrete logarithm problem efficiently in a cyclic group. The algorithm works by breaking down the problem into two steps:

Baby Steps

In this step, we calculate a list of baby steps by iteratively raising the generator g to different powers. We start with j = 0 and calculate g^j for values of j from 0 up to m-1 , where m is typically chosen as the square root of the group order n . We store each calculation in 1 bit per key, this is the highlight because it considerably minimizes the size of our database.


binary baby step
2000000 Keys

Code:
#by mcdouglasx
import secp256k1 as ice
from bitstring import BitArray

print("creating Baby Step")


#create baby step

num = 2000000 # Keys number in Binary Babystep. same m in search script

Low_m= 20

lm= num // Low_m

Add = 1
Add_pub= ice.scalar_multiplication(Add)

res= ice.point_sequential_increment(lm, Add_pub)

binary = ''
for t in range (lm):

    h= (res[t*65:t*65+65]).hex()
    hc= int(h[2:], 16)
        
        
    if str(hc).endswith(('0','2','4','6','8')):
        A="0"
        binary+= ''.join(str(A))
            
    if str(hc).endswith(('1','3','5','7','9')):
        A="1"
        binary+= ''.join(str(A))
        

my_str = (BitArray(bin=binary))#bin=binary

binary_file = open('baby_steps__binary.bin', 'ab')
my_str.tofile(binary_file)
binary_file.close()

for i in range (1,Low_m):
    print("stage: "+ str(i+1)+"/"+str(20))
    
    lm_upub= ice.scalar_multiplication((lm*i))

    res= ice.point_sequential_increment(lm, lm_upub)

    binary = ''
    for t in range (lm):

        h= (res[t*65:t*65+65]).hex()
        hc= int(h[2:], 16)
            
            
        if str(hc).endswith(('0','2','4','6','8')):
            A="0"
            binary+= ''.join(str(A))
                
        if str(hc).endswith(('1','3','5','7','9')):
            A="1"
            binary+= ''.join(str(A))
            

    my_str = (BitArray(bin=binary))#bin=binary

    binary_file = open('baby_steps__binary.bin', 'ab')
    my_str.tofile(binary_file)
    binary_file.close()


Giant Steps

In this step, we perform giant steps by multiplying, this approach is efficient because it reduces the search space for the discrete logarithm from O(n) to O(sqrt(n)) , significantly speeding up the computation for large cyclic groups.


search script

Code:
#@author: iceland, modified by @mcdouglasx

import time
import random
import bit
import os
import math
import sys
import secp256k1 as ice
import numpy as np
from bitstring import BitArray


##Pk: 33185509 puzzle #30
Target = '03057fbea3a2623382628dde556b2a0698e32428d3cd225f3bd034dca82dd7455a'

bs_file = 'baby_steps__binary.bin'


start = 0
end =   33554431                                       


m = 2000000 # Keys number in Binary Babystep
Cm= 64


public_key = ice.pub2upub(Target).hex()
   

# =============================================================================

def pub2upub(pub_hex):
x = int(pub_hex[2:66],16)
if len(pub_hex) < 70:
y = bit.format.x_to_y(x, int(pub_hex[:2],16)%2)
else:
y = int(pub_hex[66:],16)
return bytes.fromhex('04'+ hex(x)[2:].zfill(64) + hex(y)[2:].zfill(64))

#find baby step file

valid = os.path.isfile(bs_file)
if valid == True:
    print('\nFound the Baby Steps Table file: '+bs_file+'. Will be used directly')
   
    file = bytes(np.fromfile(bs_file))

    baby_steps= BitArray(file)
       
if valid == False:
    print('\nNot Found '+bs_file+'. you must Create This File Now.' )


###############################################################################

st = time.time()
print('\n[+] Starting Program : Binary BSGS mode')

Q = pub2upub(public_key)


# We have to solve P = k.G, we know that k lies in the range ]k1,k2]
k1 = random.randint(start, end) # start from
k2 = k1 + m*m
print('Checking {0} keys from {1}'.format(m*m, k1))

k1G = ice.scalar_multiplication(k1)
mG = ice.scalar_multiplication(m)



st = time.time()

###############################################################################

def findkey(onePoint):
    S = ice.point_subtraction(Q, k1G)
   
    found = False
    step = 0
   
    while found is False and step<(1+k2-k1):
        Sx_1= ice.point_sequential_increment(Cm, S)
        binary = ''
       
        for t in range (Cm):

            h= (Sx_1[t*65:t*65+65]).hex()
            hc= int(h[2:], 16)
               
               
            if str(hc).endswith(('0','2','4','6','8')):
                A="0"
                binary+= ''.join(str(A))
                   
            if str(hc).endswith(('1','3','5','7','9')):
                A="1"
                binary+= ''.join(str(A))

               
       
        b = BitArray(bin=binary)           
        c = bytes(b)
        Sw =c
       
        if b in baby_steps:
            #
            s = c
            f = BitArray(baby_steps)
            inx = f.find(s)
            inx_1=str(inx).replace(",", "")
            inx_0=str(inx_1).replace("(", "")
            inx_2=str(inx_0).replace(")", "")
            b = int(inx_2)
            found = True
            break
        else:
            # Giant step
            S = ice.point_subtraction(S, mG)
            step = step + m
    if found == True:
        #print("k1:",k1)
        #print("step:",step)
        #print("b:",b)
       
        final_key = (k1 + step + b + 1)-1
       
    else:
        final_key = -1
    return final_key


final_key = findkey(Q)

if final_key >0:
    print("BSGS FOUND PrivateKey  :",str(final_key))
    data= open("win.txt", "a")
    data.write("private key = "+str(final_key)+"\n")
    data.write(str("Time Spent : {0:.2f} seconds".format(time.time()-st))+ "\n")
    data.close()
else:
    print('PrivateKey Not Found')


print(str("Time Spent : {0:.2f} seconds".format(time.time()-st)))



This script is just an idea, it is not intended to be fast.
Make your own version in C.

This is a modification of Iceland's work.
5  Local / Español (Spanish) / Creando una base de datos ultra ligera de publickeys para fuerza bruta on: November 30, 2023, 04:38:03 PM

Creando una base de datos superligrera.

Cuando trabajamos en los puzzles de BTC, pensamos de inmediato en la logica de que teniendo muchas keys en una base de datos aumenta nuestra probabilidad de exito, y esto es cierto.

pero luego nos topamos con que abarcan mucho espacio en disco.

les traigo esta posible solucion.

existe pubkeys pares o impares, y no existe un patron secuencial entre ellas por lo tanto se me ocurrio guardar en secuencia restando al target secuencias "x" cantidades de llaves.

solo que almacendo de manera binaria:

0=pubkey par,
1=pubkey impar.

eso nos permite reducir el espacio en disco de la base de datos a un bit por pubkey, para hacernos una idea 32 millones de pubkeys serian 3.81MB en disco(impresionante).

para esta base de datos necesitamos usar este script de python.

para una sola llave publica

Code:
#@mcdouglasx
import secp256k1 as ice
from bitstring import BitArray
import bitcoin


print("Making Binary Data-Base")


target_public_key = "030d282cf2ff536d2c42f105d0b8588821a915dc3f9a05bd98bb23af67a2e92a5b"

target = ice.pub2upub(target_public_key)


num = 10000 # number of keys.

sustract= 1 #amount to subtract each time, If you modify this, use the same amount to scan.

Low_m= 10

lm= num // Low_m
print(lm)

sustract_pub= ice.scalar_multiplication(sustract)

res= ice.point_loop_subtraction(lm, target, sustract_pub)
binary = ''
for t in range (lm):

    h= (res[t*65:t*65+65]).hex()
    hc= int(h[2:], 16)
       
       
    if str(hc).endswith(('0','2','4','6','8')):
        A="0"
        binary+= ''.join(str(A))
           
    if str(hc).endswith(('1','3','5','7','9')):
        A="1"
        binary+= ''.join(str(A))
       

my_str = bytes(BitArray(bin=binary))

binary_file = open('data-base.bin', 'ab')
binary_file.write(my_str)
binary_file.close()

for i in range (1,Low_m):
    lm_upub= sustract_pub= ice.scalar_multiplication((lm*i)*sustract)

    A1= ice.point_subtraction(target, lm_upub)

    sustract_pub= ice.scalar_multiplication(sustract)

    res= ice.point_loop_subtraction(lm, A1, sustract_pub)
   
    binary = ''
    for t in range (lm):

        h= (res[t*65:t*65+65]).hex()
        hc= int(h[2:], 16)
           
           
        if str(hc).endswith(('0','2','4','6','8')):
            A="0"
            binary+= ''.join(str(A))
               
        if str(hc).endswith(('1','3','5','7','9')):
            A="1"
            binary+= ''.join(str(A))
           

    my_str = bytes(BitArray(bin=binary))

    binary_file = open('data-base.bin', 'ab')
    binary_file.write(my_str)
    binary_file.close()

Si desea crear una base de datos más larga de lo que admite tu memoria ram.

Por ejemplo, 1000 millones de claves y su límite de memoria es 100 millones, divida entre 10 cambiando esta variable:

Code:
Low_m= 10

 debes usar numeros asi, sin residuos.

Code:
num = 10000000000000
Low_m= 10000

Code:
num = 20000000000000
Low_m= 2000

Evite hacer esto o encontrará claves privadas con los últimos números modificados.

Code:
num = 14678976447
Low_m= 23


lo hicimos!

Disponemos de una base de datos enorme, con poco espacio en disco.

Debido a que no existe una secuencia entre claves públicas pares e impares, podemos establecer un margen de colisión de 64, 128, 256...
Con esto quiero decir que a medida que aumenta el margen de colisión, la probabilidad de encontrar una secuencia binaria idéntica disminuye.


¿De qué sirve esto?

Solo necesitamos generar secuencias binarias aleatoriamente y verificar si existen en la
base de datos.

buscando una sola clave pública

Code:
#@mcdouglasx
import secp256k1 as ice
import random
from bitstring import BitArray



print("Scanning Binary Sequence")

#Pk: 1033162084
#cPub: 030d282cf2ff536d2c42f105d0b8588821a915dc3f9a05bd98bb23af67a2e92a5b

#range
start= 1033100000
end=   1033200000
       

while True:

    pk= random.randint(start, end)
   
    target = ice.scalar_multiplication(pk)

    num = 64 # collision margin.

    sustract= 1 # #amount to subtract each time.

    sustract_pub= ice.scalar_multiplication(sustract)

    res= ice.point_loop_subtraction(num, target, sustract_pub)
   
    binary = ''
   
    for t in range (num):
       
        h= (res[t*65:t*65+65]).hex()
        hc= int(h[2:], 16)
       
       
        if str(hc).endswith(('0','2','4','6','8')):
            A="0"
            binary+= ''.join(str(A))
           
        if str(hc).endswith(('1','3','5','7','9')):
            A="1"
            binary+= ''.join(str(A))
   
       
    my_str = binary

    b = bytes(BitArray(bin=my_str))
   

    file = open("data-base.bin", "rb")

    dat = bytes(file.read())
   
    if b  in dat:
        s = b
        f = dat
        inx = f.find(s)*sustract
        inx_0=inx
        Pk = (int(pk) + int(inx_0))+int(inx_0)*7
       
        data = open("win.txt","a")
        data.write("Pk:"+" "+str(Pk)+"\n")
        data.close()
        break

para multiples pubkeys

tambien es posible, aunque la base de datos debe ser secuencial esto no implica que no se puedan guardar multiples pk.

ejemplo:
si tenemos 10 targets y queremos una base de datos de 1.000.000.000 de pubkeys dividimos

base de datos/targets

y cada target individualmente abarcara 100 millones de keys.

script en progreso, estoy corrigiendo unos detalles, pronto lo subire.


Este código es sólo una demostración que puede no estar optimizado correctamente, preferiblemente cree su propia versión en C.


No olvide decir gracias, para motivarme a contribuir con otras ideas.
6  Bitcoin / Development & Technical Discussion / lightweight database, for brute force using publickeys-32Mk =3.81MB(secp256k1) on: November 27, 2023, 03:40:06 AM
creating the lightweight database, billions keys.

last edit: 12/06/2023

1-we generate a bin file with the publickeys represented in 1s and 0s.
0=even,
1=odd.

single publickey

Code:
#@mcdouglasx
import secp256k1 as ice
from bitstring import BitArray
import bitcoin


print("Making Binary Data-Base")


target_public_key = "030d282cf2ff536d2c42f105d0b8588821a915dc3f9a05bd98bb23af67a2e92a5b"

target = ice.pub2upub(target_public_key)


num = 10000 # number of keys.

sustract= 1 #amount to subtract each time, If you modify this, use the same amount to scan.

Low_m= 10

lm= num // Low_m
print(lm)

sustract_pub= ice.scalar_multiplication(sustract)

res= ice.point_loop_subtraction(lm, target, sustract_pub)
binary = ''
for t in range (lm):

    h= (res[t*65:t*65+65]).hex()
    hc= int(h[2:], 16)
        
        
    if str(hc).endswith(('0','2','4','6','8')):
        A="0"
        binary+= ''.join(str(A))
            
    if str(hc).endswith(('1','3','5','7','9')):
        A="1"
        binary+= ''.join(str(A))
        

my_str = bytes(BitArray(bin=binary))

binary_file = open('data-base.bin', 'ab')
binary_file.write(my_str)
binary_file.close()

for i in range (1,Low_m):
    lm_upub= sustract_pub= ice.scalar_multiplication((lm*i)*sustract)

    A1= ice.point_subtraction(target, lm_upub)

    sustract_pub= ice.scalar_multiplication(sustract)

    res= ice.point_loop_subtraction(lm, A1, sustract_pub)
    
    binary = ''
    for t in range (lm):

        h= (res[t*65:t*65+65]).hex()
        hc= int(h[2:], 16)
            
            
        if str(hc).endswith(('0','2','4','6','8')):
            A="0"
            binary+= ''.join(str(A))
                
        if str(hc).endswith(('1','3','5','7','9')):
            A="1"
            binary+= ''.join(str(A))
            

    my_str = bytes(BitArray(bin=binary))

    binary_file = open('data-base.bin', 'ab')
    binary_file.write(my_str)
    binary_file.close()


If you want to create a longer database than your memory supports
For example, 1000 million keys and your memory limit is 100 million, divide by 10 changing this variable:

Code:
Low_m= 10


- You should use numbers like this:
Code:
num = 10000000000000 
Low_m= 10000

Code:
num = 20000000000000 
Low_m= 2000

Avoid doing this or you will find private keys with the last numbers changed

Code:
num = 14678976447
Low_m= 23


we did it!

We have a huge database, with little disk space.

Because there is no sequence between even and odd pubkeys we can set a collision margin of 64, 128, 256....
By this I mean that as you increase the collision margin, the probability of finding an identical binary sequence decreases.


What's the use of this?

We just need to randomly generate binary sequences and check if they exist in the
Database.

searching single pubkey

Code:
#@mcdouglasx
import secp256k1 as ice
import random
from bitstring import BitArray



print("Scanning Binary Sequence")

#Pk: 1033162084
#cPub: 030d282cf2ff536d2c42f105d0b8588821a915dc3f9a05bd98bb23af67a2e92a5b

#range
start= 1033100000
end=   1033200000
      

while True:

    pk= random.randint(start, end)
    
    target = ice.scalar_multiplication(pk)

    num = 64 # collision margin.

    sustract= 1 # #amount to subtract each time.

    sustract_pub= ice.scalar_multiplication(sustract)

    res= ice.point_loop_subtraction(num, target, sustract_pub)
    
    binary = ''
    
    for t in range (num):
        
        h= (res[t*65:t*65+65]).hex()
        hc= int(h[2:], 16)
        
        
        if str(hc).endswith(('0','2','4','6','8')):
            A="0"
            binary+= ''.join(str(A))
            
        if str(hc).endswith(('1','3','5','7','9')):
            A="1"
            binary+= ''.join(str(A))
    
        
    my_str = binary

    b = bytes(BitArray(bin=my_str))
    

    file = open("data-base.bin", "rb")

    dat = bytes(file.read())
    
    if b  in dat:
        s = b
        f = dat
        inx = f.find(s)*sustract
        inx_0=inx
        Pk = (int(pk) + int(inx_0))+int(inx_0)*7
        
        data = open("win.txt","a")
        data.write("Pk:"+" "+str(Pk)+"\n")
        data.close()
        break



for multiple pubkeys

- first we create the database by making random subtractions in a range specified by us, you can create your own list at your discretion

Code:
#@mcdouglasx
import secp256k1 as ice
import random

print("Making random sustract Data-Base")

target_public_key = "0209c58240e50e3ba3f833c82655e8725c037a2294e14cf5d73a5df8d56159de69"

target = ice.pub2upub(target_public_key)

targets_num= 1000

start= 0
end=   1000000

for i in range(targets_num):

    A0 = random.randint(start, end)
    A1 = ice.scalar_multiplication(A0)
    A2= ice.point_subtraction(target, A1).hex()
    A3 = ice.to_cpub(A2)
    data = open("rand_subtract.txt","a")
    data.write(str(A3)+" "+"#"+str(A0)+"\n")
    data.close()

Db multi-pubkeys

-we create our database for multiple keys.

Code:
#@mcdouglasx
import secp256k1 as ice
from bitstring import BitArray


print("Making Binary Data-Base")

target__multi_public_keys = "rand_subtract.txt"

with open(target__multi_public_keys, 'r') as f:

    lines= f.readlines()
    X = len(lines)
    
    for line in lines:
      
        mk= ice.pub2upub(str(line.strip()[:66]))

        num = 1024 # number of keys for pub.

        subtract= 1 #amount to subtract each time.

        subtract_pub= ice.scalar_multiplication(subtract)

        res= ice.point_loop_subtraction(num, mk, subtract_pub)
        
        binary = ''
        for t in range (num):

            h= (res[t*65:t*65+65]).hex()
            hc= int(h[2:], 16)
                
                
            if str(hc).endswith(('0','2','4','6','8')):
                A="0"
                binary+= ''.join(str(A))
                    
            if str(hc).endswith(('1','3','5','7','9')):
                A="1"
                binary+= ''.join(str(A))
                

        my_str = BitArray(bin=binary)

        binary_file = open('multi-data-base.bin', 'ab')
        my_str.tofile(binary_file)
        binary_file.close()

scan multiple publickeys, bit version

Code:
#@mcdouglasx
import secp256k1 as ice
import random
from bitstring import BitArray



print("Scanning Binary Sequence")


#range
start= 3090000000        
end=   3093472814

#total number of pubkeys for targets in database.

X= 1024

while True:

    pk= random.randint(start, end)
    
    target = ice.scalar_multiplication(pk)

    num = 64 # collision margin.

    subtract= 1 #amount to subtract each time.

    subtract_pub= ice.scalar_multiplication(subtract)

    res= ice.point_loop_subtraction(num, target, subtract_pub)
    
    binary = ''
    
    for t in range (num):
        
        h= (res[t*65:t*65+65]).hex()
        hc= int(h[2:], 16)
        
        
        if str(hc).endswith(('0','2','4','6','8')):
            A="0"
            binary+= ''.join(str(A))
            
        if str(hc).endswith(('1','3','5','7','9')):
            A="1"
            binary+= ''.join(str(A))
    
        
    my_str = binary

    b = BitArray(bin=my_str)

    c = bytes(b)

    file = open("multi-data-base.bin", "rb")
    dat= BitArray(file.read())
    
    

    if b  in dat:
        
        s = c
        f = dat
        inx = f.find(s)
        inx_1=str(inx).replace(",", "")
        inx_0=str(inx_1).replace("(", "")
        inx_2=str(inx_0).replace(")", "")
        
        Pk = (int(pk) + ((int(inx_2) % X)*subtract))
        cpub=ice.to_cpub(ice.scalar_multiplication(Pk).hex())
        with open("rand_subtract.txt", 'r') as Mk:

            lines= Mk.readlines()
            for line in lines:
                
                mk_0= str(line.strip())
                mk= int(mk_0[68:])
                mk2= mk_0[ :66]
                if mk2 in cpub:
                    print("found")
                    cpub2=ice.to_cpub(ice.scalar_multiplication(Pk+mk).hex())
                    data = open("win.txt","a")
                    data.write("Pk:"+" "+str(Pk+mk)+"\n")
                    data.write("cpub:"+" "+str(cpub2)+"\n")
                    data.close()
                    break
        break

scan multiple publickeys, version bytes (faster).


Code:
#@mcdouglasx
import secp256k1 as ice
import random
from bitstring import BitArray
import numpy as np


print("Scanning Binary Sequence")


#range
start=  3000000000
end=    3095000000



X= 1024 #number of sequential pubkeys for each target

while True:

    pk= random.randint(start, end)
   
    target = ice.scalar_multiplication(pk)

    num = 64 # collision margin.

    subtract= 1 #amount to subtract each time.

    subtract_pub= ice.scalar_multiplication(subtract)

    res= ice.point_loop_subtraction(num, target, subtract_pub)
   
    binary = ''
   
    for t in range (num):
       
        h= (res[t*65:t*65+65]).hex()
        hc= int(h[2:], 16)
       
       
        if str(hc).endswith(('0','2','4','6','8')):
            A="0"
            binary+= ''.join(str(A))
           
        if str(hc).endswith(('1','3','5','7','9')):
            A="1"
            binary+= ''.join(str(A))
   
       
    my_str = binary

    b = BitArray(bin=my_str)
   
    c = bytes(b)

    file = bytes(np.fromfile("multi-data-base.bin"))
   
    dat= (file)
   
   

    if c  in dat:
       
        s = c
        f = BitArray(dat)
        inx = f.find(s)
        inx_1=str(inx).replace(",", "")
        inx_0=str(inx_1).replace("(", "")
        inx_2=str(inx_0).replace(")", "")
       
        Pk = (int(pk) + ((int(inx_2) % X)*subtract))
        cpub=ice.to_cpub(ice.scalar_multiplication(Pk).hex())
        with open("rand_subtract.txt", 'r') as Mk:

            lines= Mk.readlines()
            for line in lines:
               
                mk_0= str(line.strip())
                mk= int(mk_0[68:])
                mk2= mk_0[ :66]
                if mk2 in cpub:
                    print("found")
                    cpub2=ice.to_cpub(ice.scalar_multiplication(Pk+mk).hex())
                    data = open("win.txt","a")
                    data.write("Pk:"+" "+str(Pk+mk)+"\n")
                    data.write("cpub:"+" "+str(cpub2)+"\n")
                    data.close()
                    break
        break


The difference between bit version and byte version is that with bytes some bits are masked within a byte, and it does not detect some collisions.
This does not happen in the bit version.
--------------------------------------------------------------------------


This code is just a demonstration that may not be optimized correctly, preferably make your own version in C.


Don't forget to say thank you, to motivate me to contribute other ideas.

7  Other / Off-topic / reminder: don't trust antivirus on: November 23, 2023, 05:20:05 AM
I was installing an antivirus on a friend's computer and I came across malware especially focused on stealing private keys, either with copy-paste, and with data collection, login files, wallet.dat.
My friend doesn't have bitcoin, fortunately for him.

but I took on the task of analyzing it and managed to extract part of the code.

I scanned it with virustotal, and it's full of red flags.

https://www.virustotal.com/gui/file/4e7ad092f832e4765fc18a975d36a8ed00f4771dcde850213e46536da2c1563a/detection

then modify the script, as follows......(I won't say it, I won't contribute to the internet garbage, I'm poor but honest).

I tested it and it worked.

Anyway, after modifying and recompiling it, virustotal does not detect it as a virus, only Bkav Pro marks it as unsafe because it is an unsigned executable(false positive).


https://www.virustotal.com/gui/file/6e04c245bec6db58d6f13e59638a16489e133c42b3fb45692336a5ed0b6684fd/detection

The moral is that antiviruses are not trustworthy.

prepare your transactions on a offline computer , use a QR generator to send the transaction to your mobile (to avoid using USB with data collection malware).

Those simple steps could save you a headache.

this is by educational proposal, please, don't ask me to tell you how to avoid antivirus, do not offer me money for the code, this post is only to raise awareness, Any attempt will be reported.
8  Bitcoin / Development & Technical Discussion / list of simple mathematical operations in ECC secp256k1 (Python). on: November 20, 2023, 06:30:10 PM
modules used:
Bitcoin
pip install bitcoin
---------------------------
secp256k1

download at https://github.com/iceland2k14/secp256k1

place files in the same folder as the script.




Decimal to Compressed Address

Code:
import secp256k1 as ice
            
target = 1

A0 = ice.scalar_multiplication(target)
A1 = A0.hex()
B0 = ice.pubkey_to_address(0,1, A0)
A2 = ice.to_cpub(A1)

print("Pk:",target)
print("cPub:",A2)
print("Addr:",B0)

addition of two points (publickeys)

Code:
import secp256k1 as ice

#A+B
A= "HERRE COMPRESSED PUBLIC KEY"
B= "HERRE COMPRESSED PUBLIC KEY"

Upub_A= ice.pub2upub(A)
Upub_B= ice.pub2upub(B)

A1= ice.point_addition(Upub_A, Upub_B).hex()

A2 = ice.to_cpub(A1)

print("R:",A2)

subtraction of two points (publickeys)
Code:
import secp256k1 as ice

#A-B
A= "HERE COMPRESSED PUBLIC KEY"
B= "HERE COMPRESSED PUBLIC KEY"

Upub_A= ice.pub2upub(A)
Upub_B= ice.pub2upub(B)

A1= ice.point_subtraction(Upub_A, Upub_B).hex()

A2 = ice.to_cpub(A1)

print("R:",A2)

multiply (publickey*decimal)

Code:
import bitcoin


target= "HERE COMPRESSED PUBLIC KEY"

N= 2

mult= bitcoin.multiply(target, N)

print(mult)


division (publickey/decimal)


Code:
import bitcoin


target= "HERE COMPRESSED PUBLIC KEY"

N= 2

Div= bitcoin.divide(target, N)

print(Div)

edit:

Division in Ecc works differently, I attach a division script with mod N that emulates the process in decimals, for your greater understanding.

Code:
import bitcoin

target= 1361129467683753853853498429727072845823

Div=2

N=115792089237316195423570985008687907852837564279074904382605163141518161494337

a=bitcoin.inv(Div,N)

b= target*a % N

print("pk:",b)


Upub to Cpub

Code:
import secp256k1 as ice
           
target = “UNCOMPRESSED PUB HERE”

A2 = ice.to_cpub(target)
print("Cpub:", A2)
9  Other / Off-topic / What happened to the old school in bitcoin. on: November 11, 2023, 05:43:16 AM
Why are there currently few old users who interact with the forum, are they rich and forgot about the topic? Or do they fear for their security and privacy? I think both reasons are correct and they are following Satoshi's path of disappearing to remain anonymous. It would be nice if one day Satoshi gave us a brief notice that everything is going well in his life, I think he would know how to do it without compromising his identity. I would also like to see posts from old school users expressing new ideas, new projects. In the end, you must continue advancing, innovating, and researching, for the future, not everything in this life is money, there are ideas that are worth more than a fortune... Let us remember that the idea of ​​satoshi currently benefits millions of people. So get your ideas out of the drawer, and share them with the community, as the Bitcointalk team quotes:

Quote
“Because we are able to operate comfortably using advertising and fee revenue along with our BTC reserves, we no longer collect donations. If you want to help the forum, please make good posts, report rule-breaking posts, and invite friends.”

At the moment I have the mathematics behind ECC as a hobby, it is very interesting for me because sometimes I spend hours playing with numbers, I guess I'm not the only one. so if you have something interesting on your mind, don't hesitate to share it.
10  Bitcoin / Development & Technical Discussion / the dilemma of division in ECC-secp256k1 on: November 01, 2023, 06:08:00 PM
given the private key

Pk= 1754225779965324
x= 7476542256
pk_pub= 035703f261cde18efa195bd626af22f35e47a091045370971d612589f642f250e5

we divide pk/X
we obtain...


02756d41db3f13a73d06684232efca6f99753827f6a3260dd50ca77f09b207036a

which in decimal numbers, should be:

234630.624679

either

234630.6246791476704254716112

we subtract the integer part "234630"

234630= 021b79ff0d52a6612cef311c61995259edc2a2a8771b5614d4b9e786f93afcb163


234630.624679 - 234630

we get the pub

02756d41db3f13a73d06684232efca6f99753827f6a3260dd50ca77f09b207036a

It should be the representation of:

0.624679

either

0.6246791476704254716112

but it is not, because if I divide

1/1000000= 0.000001

pub
026103a32c3d713955f09eb4aac723d7cec8492180c398e1398a50ff91937b8edd

and replace G by 0.000001

When generating pk= 624679, it does not match with:

02756d41db3f13a73d06684232efca6f99753827f6a3260dd50ca77f09b207036a

and if we divide


1/10000000000000000000000= 0.0000000000000000000001

pub

021f724a326b56244244206b0ad666dcadfa664e85ad037a9ba90816bbef0c2c43

and replace G by 0.0000000000000000000001

When generating the pk= 6246791476704254716112, it does not match either.

the question is why?

I know that ecc represents decimals and negatives as integers.
but in the same way it should be possible to represent the decimals after the "," or ".".

Could it be a precision problem?

0.6246791476704254716112xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

where the X are a series of unknown numbers?
11  Other / Off-topic / Puzzle, have fun! on: September 24, 2023, 07:52:51 PM

A small puzzle for those who like intelligence challenges.

12  Economy / Invites & Accounts / Apple GSX account on: July 28, 2021, 06:42:43 PM
Greetings someone here has bought a GSX account with them https://www.facebook.com/GSXiCloudDeluxe

I decided to buy from them but they only sell to people referred by someone of their members. Can someone help me refer me to them so I can buy.
Pages: [1]
Powered by MySQL Powered by PHP Powered by SMF 1.1.19 | SMF © 2006-2009, Simple Machines Valid XHTML 1.0! Valid CSS!