Post
Topic
Board Bitcoin Discussion
Re: Bitcoin puzzle transaction ~32 BTC prize to who solves it
by
digaran
on 14/08/2023, 15:42:47 UTC

what are the parameters to put in place and what codes or tools would be required to achieve that goal mentioned above?
I'm not a code/tool expert, and I'm pretty sure all the existing ones lack something, I don't know maybe BSGS can do what I said.
If I had a perfect idea I could have used it myself, I only type what comes to my mind, whether it's possible or doable currently, I don't know. Hints is what I can provide the best.😉

Here is the code doing exactly what digaran explained earlier... I used on puzzle 125, chant it when someone else found it. I am not optimistic of it! you can have it if you've huge ram... it works on more more of a simple phenomenon rather then complex... In the script checkpoint.txt file has only public key x coordinates in decimal format. Why only x because, if you have public  keys of private keys from 1 to 1 billion, they are actually two billion public keys, first billion from 1 to 1 billion and the last billion,, both billion have same x coordinate,, so kind of really big help there Grin... The script first loads the file checkpoints.txt. so in this file I kept 80 million public keys from 2 - 80000000. The file size was 5.88 GB, been running on 8 GB RAM system. Here is how script works with a simple example you can modify relevant figures in script as per your needs...
Suppose our public key has the private key of 87 (which we don't know obviously) we have checkpoints from 1-5 (which is really big if we compare 80 million with 125 puzzle key distance),, so what the script does it, is subtracts a set jump from pubkey and checks the resulting point within checkpoints, you can set your own jump.. suppose you want to set jump size as 20, here is how script works:

87-20=67 (not in checkpoints)
67-20=47  (not in checkpoints)
47-20=27(not in checkpoints)
27-20=7(not in checkpoints)
7-20=-13(not in checkpoints)

As you know the range you can set the step size to suite the range, in our case, it is suitable to have 5 steps if we choose its size as 20...

After finishing 5 stepts, the script subtracts 5 from 87 and saves the progress in j_value.txt file, after every iteration it changes the value in j_value.txt file. So if you shutdown or power goes off, next time script restarts from where it left...
After first iteration script subtract 10 from 87-10=77
(10 because you have first 5 and last 5)
next iteration is like
77-20=57 (not in checkpoints)
57-20=37  (not in checkpoints)
37-20=17(not in checkpoints)
17-20=-3(matched)
-3 is matching because its inverse point is 3 and both have same x coordinate...
If a match is found, the script save that point in results.txt file.
I forget to mention xy.txt file has the decimal x and y coordinate of puzzle pub key.
Here is whole script: Chill
Code:
Pcurve = 2**256 - 2**32 - 2**9 - 2**8 - 2**7 - 2**6 - 2**4 -1 # The proven prime
N=0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 # Number of points in the field
Acurve = 0; Bcurve = 7 # These two defines the elliptic curve. y^2 = x^3 + Acurve * x + Bcurve
Gx = 55066263022277343669578718895168534326250603453777594175500187360389116729240
Gy = 32670510020758816978083085130507043184471273380659243275938904335757337482424
GPoint = (Gx,Gy) # This is our generator point. Trillions of dif ones possible

def modinv(a, n=Pcurve):
    lm, hm = 1, 0
    low, high = a % n, n
    while low > 1:
        ratio = high // low
        nm, new = hm - lm * ratio, high - low * ratio
        lm, low, hm, high = nm, new, lm, low
    return lm % n

def ECadd(a, b):
    if a == 'O':
        return b
    if b == 'O':
        return a
    if a == b:
        LamAdd = ((3 * a[0] * a[0] + Acurve) * modinv(2 * a[1], Pcurve)) % Pcurve
    else:
        LamAdd = ((b[1] - a[1]) * modinv(b[0] - a[0], Pcurve)) % Pcurve
    x = (LamAdd * LamAdd - a[0] - b[0]) % Pcurve
    y = (LamAdd * (a[0] - x) - a[1]) % Pcurve
    return (x, y)


def ECsub(a, b):
    if b == 'O':
        return a
    if isinstance(a, str):
        a = tuple(map(int, a.split()))
    if isinstance(b, str):
        b = tuple(map(int, b.split()))
    neg_b = (b[0], -b[1] % Pcurve)
    return ECadd(a, neg_b)


def ECmul(a, b):
    result = 'O'
    while b > 0:
        if b % 2 == 1:
            result = ECadd(result, a)
        a = ECadd(a, a)
        b = b // 2
    return result

# Read the x, y coordinates from xy.txt
with open("xy.txt", "r") as f:
    x, y = map(int, f.read().strip().split())
    point = (x, y)

# Read the checkpoint x-coordinates from checkpoints.txt
with open("checkpoints.txt", "r") as f:
    checkpoints = set(map(int, f.read().strip().split()))

filename_out = "results.txt"


sub_count = 0


# read the last value of j from file
try:
    with open("j_value.txt", "r") as f:
        last_j_value = int(f.readline())
except:
    last_j_value = 0

# loop for multiplication factor 0, 2, 4, 6, 8, 10, 12, 14, .......
found_match = False
for j in range(last_j_value, 10000001):
    if found_match:
        break
    sub_count = 160000000 * j
    for k in range(100001): # loop for 1lac subtract iterations
        if k == 0:  # first iteration
            pass
        else:
            sub_count += 212676479325586539664609129644855
        result = ECmul(GPoint, sub_count)
        result = ECsub(point, result)
        print(sub_count)
        if result[0] in checkpoints:
            with open(filename_out, "w") as f_out:
                subtractions = sub_count // 212676479325586539664609129644855
                f_out.write("{} {} {}".format(result[0], result[1], subtractions))
            found_match = True
            break
    # save the value of j to file after each iteration
    with open("j_value.txt", "w") as f:
        f.write(str(j))

7-20=-13(not in checkpoints)

Really nice one, too bad I don't know how to run scripts, I'm just a windows person used to double click on exe files. 😅


Here is another idea, lets see if it can be done or has any merits to it.

If we know the exact start and end range of a public key, we could divide the end range by a number to reduce it down as much as possible, maybe making it a 6 digits number, now we only have to change our 6 digit number and multiply it by the number which we first divided our end range with, we need to change the numbers in a way that it never goes beyond our end range when multiplied.

Now, before doing that, we need to add and subtract 1 G to our target and divide the results by 2, e.g. if our target is 256, we add 1, 2, 3, 4 etc and divide them all by 2 also we will add n/2 to all the results just to be safe and keep all of the keys to compare with our multiplication result.  Eventually if we change our nonce, ( 6 digit number ) enough times and multiply it with powers of 2, 3 etc somewhere we should see a known key.

A simple example :

Start range 1, end range 512, our target is 95, now we divide 512 by 32 to get 16.

But first lets generate some offsets for our target.

Add 1 to 95 = 96/2 = 48
Add 3 to 95 = 98/2 = 49
Add 5 to 95 = 100/2 = 50
Sub 1 from 95 = 94/2 = 47
Sub 15 from 95 = 80/2 = 40

Now we have 48, 49, 50, 47 and 40, then we multiply 16 by 2, 3, 4, 5, 6, 7, etc until we see one of the keys above.

Imagine if we generate different offsets, like billions of them, then we could simply keep multiplying to find one of our targets.


This just came to my mind today, it's not cooked well , yet!😉