Author

Topic: Bitcoin puzzle transaction ~32 BTC prize to who solves it - page 135. (Read 215608 times)

member
Activity: 272
Merit: 20
the right steps towerds the goal
Important Message to the Creator:

'00008657895489568954e6270000ffffffff000049924a526a523a520a52198c'


What is this? where it comes from?

I checked it in some hexadecimal editor and there is no a message there:



Can you add some more of context please?


hero member
Activity: 862
Merit: 662
Important Message to the Creator:

'00008657895489568954e6270000ffffffff000049924a526a523a520a52198c'


What is this? where it comes from?

I checked it in some hexadecimal editor and there is no a message there:



Can you add some more of context please?
member
Activity: 93
Merit: 16
why not ? Grin
Without predictable SEED there will be more chances  Smiley
member
Activity: 462
Merit: 24
let us just assume that this is possible

Code:
import random, sys, os, time
from datetime import datetime, timedelta
import secp256k1 as ice
from concurrent.futures import ThreadPoolExecutor

os.system("clear")
t = time.ctime()
sys.stdout.write("\033[01;33m")
sys.stdout.write(f"[+] {t}" + "\n")
sys.stdout.flush()

# Define the check_private_key function
def check_private_key(dec, add_set):
    while True:
        dec = random.randint(min_number, max_number)
        HASH160 = ice.privatekey_to_h160(0, True, dec).hex()
        sys.stdout.write("\033[01;33m")
        sys.stdout.write(f"\r[+] {HASH160}" + "\r")
        sys.stdout.flush()
        if HASH160 == add_set:
            dec_to_hex = hex(dec).split('x')[-1]
            HASH160_wif = ice.btc_pvk_to_wif(dec)
            print('\n')
            print(f" Key Found:  |\033[32m {dec_to_hex} \033[0m")
            print(f" WIF         |\033[32m {HASH160_wif} \033[0m")
            print(f" Address     |\033[32m {add_set} \033[0m")
            with open("FOUND_66PUZZLE.txt", "a") as f:
                f.write("HEX:               " + str(dec_to_hex) + '\n' + "Address HASH160:   " + str(add_set) + '\n' + "Private Key:       " + str(HASH160_wif) + '\n')
                f.flush()
                f.close()
            return

# Specify the start and end date and times
start_datetime = datetime(2014, 1, 1, 0, 0, 0)
end_datetime = datetime(2015, 1, 15, 19, 7, 14)

# Calculate the time range in seconds
time_range_seconds = (end_datetime - start_datetime).total_seconds()

# Define the range of numbers and Hash 160
min_number = 36893488147419103232
max_number = 73786976294838206463
add_set = "20d45a6a762535700ce9e0b216e31994335db8a5"

# Initialize a ThreadPoolExecutor
executor = ThreadPoolExecutor(max_workers=10)

current_datetime = start_datetime

while current_datetime <= end_datetime:
    # Format the current datetime to exclude fractional seconds
    timestamp = current_datetime.strftime('%Y-%m-%d %H:%M:%S')

    # Convert the formatted timestamp to a Unix timestamp
    timestamp = int(datetime.strptime(timestamp, '%Y-%m-%d %H:%M:%S').timestamp())

    # Initialize the random number generator with the timestamp
    random.seed(timestamp)

    # Generate a random number within the specified range
    dec = random.randint(min_number, max_number)

    # Submit the check_private_key function as a task to the ThreadPoolExecutor
    future = executor.submit(check_private_key, dec, add_set)

    # Check if the generated private key matches the provided address
    if future.result():
        executor.shutdown()
        break  # Exit the loop if a match is found

    # Increment the current datetime by one second for the next timestamp
    current_datetime += timedelta(seconds=1)

why not ? Grin
member
Activity: 272
Merit: 20
the right steps towerds the goal
Important Message to the Creator:

'00008657895489568954e6270000ffffffff000049924a526a523a520a52198c'

Please visualize this key by visiting the following link to read the message: (https://btckeygen.com/)

Kindly fund the key if you have received my message..
jr. member
Activity: 75
Merit: 5
Why do you use linux time? Satoshi was using windows, either vista or seven, maybe even 8, or xp. 😂 we just need to look for all the keys. Lol
You know what we should do? We should use the same technic to search for rmd160 hash patterns and find collisions. 🙃

I can assume that the Satoshi was using some script (errors = ZERO) with Lagrange interpolation, determining the formula that generates the values may require a different approach, such as symbolic regression or other mathematical techniques together with random numbers and time. I am lost in numbers and hypotheses now. I need green grass.. Grin

There is nothing to worry about for now, maybe some could go back in time to see what position Satoshi was taking while throwing the dice or flipping the coins, maybe that way we can know what position we need to also take in order to be able to replicate the same method. How many minutes do you think you need to throw a dice or flip a coin to get puzzle 1 to puzzle 256?
256+254+254+253+252+251+250+249+248+247+246+245+244+243+242+241+240+239+238+237+236+235+234+233+232+231+230+229+228+227+226+225+224+223+222+221+220+219+218+217+216+215+214+213+212+211+210+209+208+207+206+205+204+203+202+201+200+199+198+197+196+195+194+193+192+191+190+189+188+187+186+185+184+183+182+181+180+179+178+177+176+175+174+173+172+171+170+169+168+167+166+165+164+163+162+161+160+159+158+157+156+155+154+153+152+151+150+149+148+147+146+145+144+143+142+141+140+139+138+137+136+135+134+133+132+131+130+129+128+127+126+125+124+123+122+121+120+119+118+117+116+115+114+113+112+111+110+109+108+107+106+105+104+103+102+101+100+99+98+97+96+95+94+93+92+91+90+89+88+87+86+85+84+83+82+81+80+79+78+77+76+75+74+73+72+71+70+69+68+67+66+65+64+63+62+61+60+59+58+57+56+55+54+53+52+51+50+49+48+47+46+45+44+43+42+41+40+39+38+37+36+35+34+33+32+31+30+29+28+27+26+25+24+23+22+21+20+19+18+17+16+15+14+13+12+11+10+9+8+7+6+5+4+3+2+1 = 32895

so you can as well agree with me that the problem here has nothing to do with a pattern or some kind of formula... we have so many ways of getting private keys without making any mistakes. ZERO FREE ERROR VERIFIED METHODS

There is no assumptions here, whenever the person that solved puzzle 120 and 125 is ready he will solve puzzle 130 again. Now for puzzle 66, the highest pool scanned so far is less than 5% so don't expect any results any time soon from these pools. the key range is so vast and the computational resources is so limited We can't complain about wrong bit keys only except there's an evidence that someone successfully scan the full range for any puzzle level and the PK is not found within that range so please let's stop making assumptions and let's focus on better ways to tackle the puzzle. @Digaran mentioned something earlier and said

Why do you use linux time? Satoshi was using windows, either vista or seven, maybe even 8, or xp. 😂 we just need to look for all the keys. Lol
You know what we should do? We should use the same technic to search for rmd160 hash patterns and find collisions. 🙃
let us just assume that this is possible 160 bit is a whole new world and for RMD160 collision you would find so many SHA256 matching so many RMD160 you won't be limited to finding the private keys for puzzle 66 within just the 66 bit range. there would be an enormous range to cover and you would find perfectly matching private keys matching so many RMD160 hashes. but without further ado, I must say we have a great task at hand and we will stop at nothing to find an end to this puzzle
copper member
Activity: 1330
Merit: 899
🖤😏
I can assume that the Satoshi was using some script (errors = ZERO) with Lagrange interpolation, determining the formula that generates the values may require a different approach, such as symbolic regression or other mathematical techniques together with random numbers and time. I am lost in numbers and hypotheses now. I need green grass.. Grin
What I understand from your post is ZERO, because I have no idea what you just said, while I could pretend that I understand, lol.  Speaking of grass, yeah I haven't smoked for years.... wait are we talking about smoking them or hugging them?😂


Today I discovered something new, I just need to test a few things then I will post about it God willing. 

Ps, it's nothing important, just a few ideas to solve DLP, we shall see if it works or not.😉
member
Activity: 462
Merit: 24
Why do you use linux time? Satoshi was using windows, either vista or seven, maybe even 8, or xp. 😂 we just need to look for all the keys. Lol
You know what we should do? We should use the same technic to search for rmd160 hash patterns and find collisions. 🙃

I can assume that the Satoshi was using some script (errors = ZERO) with Lagrange interpolation, determining the formula that generates the values may require a different approach, such as symbolic regression or other mathematical techniques together with random numbers and time. I am lost in numbers and hypotheses now. I need green grass.. Grin
copper member
Activity: 1330
Merit: 899
🖤😏
Why do you use linux time? Satoshi was using windows, either vista or seven, maybe even 8, or xp. 😂 we just need to look for all the keys. Lol
You know what we should do? We should use the same technic to search for rmd160 hash patterns and find collisions. 🙃
member
Activity: 93
Merit: 16
Because it's not just time involved here in seed. A parameter is missing. Grin
Because other functions are involved. This Hierarchical Deterministic Wallets.
https://github.com/bitcoin/bips/blob/master/bip-0032.mediawiki
member
Activity: 462
Merit: 24
Because it's not just time involved here in seed. A parameter is missing. Grin
member
Activity: 93
Merit: 16
Yo Nomachine,

nice catch, where's our current puzzle 66 in there,

thanks works like a charm.

The same thing, but only after 100 years. Grin  I think this script is useless.
Code:
====================================
linuxtime:  4573737217
Puzzle 1
Private Key :  0x1
Timestamp:  2114-12-08 21:33:37
====================================
linuxtime:  4576602332
Puzzle 2
Private Key :  0x3
Timestamp:  2115-01-11 01:25:32
====================================
linuxtime:  4576602332
Puzzle 3
Private Key :  0x7
Timestamp:  2115-01-11 01:25:32
====================================
linuxtime:  4571281403
Puzzle 4
Private Key :  0x8
Timestamp:  2114-11-10 11:23:23
====================================
linuxtime:  4575384117
Puzzle 5
Private Key :  0x15
Timestamp:  2114-12-27 23:01:57
====================================
linuxtime:  4576538378
Puzzle 6
Private Key :  0x31
Timestamp:  2115-01-10 07:39:38
====================================
linuxtime:  4571025590
Puzzle 7
Private Key :  0x4c
Timestamp:  2114-11-07 12:19:50
====================================
linuxtime:  4570872102
Puzzle 10
Private Key :  0x202
Timestamp:  2114-11-05 17:41:42
====================================
linuxtime:  4576802823
Puzzle 8
Private Key :  0xe0
Timestamp:  2115-01-13 09:07:03
====================================
linuxtime:  4574581413
Puzzle 13
Private Key :  0x1460
Timestamp:  2114-12-18 16:03:33
====================================
linuxtime:  4571991458
Puzzle 12
Private Key :  0xa7b
Timestamp:  2114-11-18 16:37:38
====================================
linuxtime:  4575374435
Puzzle 9
Private Key :  0x1d3
Timestamp:  2114-12-27 20:20:35
====================================
linuxtime:  4570872160
Puzzle 11
Private Key :  0x483
Timestamp:  2114-11-05 17:42:40
====================================
linuxtime:  4575758239
Puzzle 15
Private Key :  0x68f3
Timestamp:  2115-01-01 06:57:19
====================================
linuxtime:  4572100404
Puzzle 14
Private Key :  0x2930
Timestamp:  2114-11-19 22:53:24
====================================
linuxtime:  4573632515
Puzzle 20
Private Key :  0xd2c55
Timestamp:  2114-12-07 16:28:35
====================================

member
Activity: 462
Merit: 24
Have you tried from 2000 up to 2015? You should also try 1990 to 2000, don't leave anything to chance, because for all we know he was a random guy using time and date to produce entropy. 😉


Nope. Only 2014-2015

Puzzle 65
Code:
import random
from datetime import datetime, timedelta

# Specify the start and end date and times
start_datetime_pre = datetime(2015, 1, 1, 0, 0, 0)
end_datetime_pre = datetime(2015, 1, 15, 19, 7, 14)

# Define the range of numbers
min_number = 18446744073709551615
max_number = 36893488147419103231

# Specify the target number
target_number = 30568377312064202855

# Specify the target pattern
target_pattern = '305683'

current_datetime = start_datetime_pre
time_step = timedelta(seconds=1)

while current_datetime <= end_datetime_pre:
    # Calculate the time range in seconds
    time_range_seconds = 1

    # Initialize binary search boundaries
    low_timestamp = int(current_datetime.timestamp())
    high_timestamp = int(current_datetime.timestamp())
    found_datetime = None  # Initialize found_datetime

    while low_timestamp <= high_timestamp:
        # Calculate the middle timestamp
        mid_timestamp = (low_timestamp + high_timestamp) // 2

        # Use the middle timestamp as the seed to generate a number
        random.seed(mid_timestamp)
        generated_number = random.randint(min_number, max_number)

        # Check if the generated number starts with the specified pattern
        if str(generated_number).startswith(target_pattern):
            found_datetime = datetime.fromtimestamp(mid_timestamp)
            break  # Break out of the inner loop when a match is found

        if generated_number < target_number:
            low_timestamp = mid_timestamp + 1
        else:
            high_timestamp = mid_timestamp - 1

    if found_datetime is not None:
        print("Pattern Found:", generated_number, "Found Timestamp:", found_datetime.strftime('%Y-%m-%d %H:%M:%S'))

    # Increment the current datetime by one second for the next timestamp
    current_datetime += time_step

Pattern Found: 30568335039670351430 Found Timestamp: 2015-01-01 22:52:54
Pattern Found: 30568326435315315618 Found Timestamp: 2015-01-05 02:12:12
Pattern Found: 30568385998074263793 Found Timestamp: 2015-01-12 13:05:27
Pattern Found: 30568318046551998275 Found Timestamp: 2015-01-14 07:04:04
Pattern Found: 30568367946192456402 Found Timestamp: 2015-01-14 12:26:35

2015-01-14 12:26:35 is the closest... missing many decimal places.

 if we use the same timestamp  2015-01-14 12:26:35 - puzzle 66 starts with 490151 or
49015112019902008018

This is just an assumption. Smiley
copper member
Activity: 1330
Merit: 899
🖤😏
Have you tried from 2000 up to 2015? You should also try 1990 to 2000, don't leave anything to chance, because for all we know he was a random guy using time and date to produce entropy. 😉
full member
Activity: 431
Merit: 105
Yo Nomachine,

nice catch, where's our current puzzle 66 in there,

thanks works like a charm.
member
Activity: 462
Merit: 24

 There is no pattern here. But there is a time when a puzzle was created. I even went back in time and generating numbers from 2015. Every second of that year.


https://bitcointalksearch.org/topic/m.62144570

Almost six months ago, I undertook various tasks of a similar stuffs..

Code:
import random
from datetime import datetime, timedelta

# List of target Puzzle, each corresponding to a range
target_numbers = [
    (1, 1), (2, 3), (3, 7), (4, 8), (5, 21), (6, 49), (7, 76), (8, 224), (9, 467), (10, 514),
    (11, 1155), (12, 2683), (13, 5216), (14, 10544), (15, 26867), (16, 51510),
    (17, 95823), (18, 198669), (19, 357535), (20, 863317), (21, 1811764),
    (22, 3007503), (23, 5598802), (24, 14428676), (25, 33185509),
    (26, 54538862), (27, 111949941), (28, 227634408), (29, 400708894),
    (30, 1033162084), (31, 2102388551), (32, 3093472814), (33, 7137437912),
    (34, 14133072157), (35, 20112871792), (36, 42387769980), (37, 100251560595),
    (38, 146971536592), (39, 323724968937), (40, 1003651412950),
    (41, 1458252205147), (42, 2895374552463), (43, 7409811047825),
    (44, 15404761757071), (45, 19996463086597), (46, 51408670348612),
    (47, 119666659114170), (48, 191206974700443), (49, 409118905032525),
    (50, 611140496167764), (51, 2058769515153876), (52, 4216495639600700),
    (53, 6763683971478124), (54, 9974455244496707), (55, 30045390491869460),
    (56, 44218742292676575), (57, 138245758910846492), (58, 199976667976342049),
    (59, 525070384258266191), (60, 1135041350219496382), (61, 1425787542618654982),
    (62, 3908372542507822062), (63, 8993229949524469768),
    (64, 17799667357578236628), (65, 30568377312064202855)
]

# Sort the target_numbers list by the first element of each tuple (the range start)
target_numbers.sort(key=lambda x: x[0])

# Specify the start and end date and times for the search
start_datetime_pre = datetime(2014, 11, 1, 0, 0, 0)
end_datetime_pre = datetime(2015, 1, 15, 19, 7, 14)
current_datetime = start_datetime_pre
time_step = timedelta(seconds=1)

# Initialize a set to keep track of found target numbers
found_targets = set()

# Function to find the seed for a single target number
def find_seed_for_target(target_num, current_time):
    num, target_number = target_num
    min_number = 2 ** (num - 1)
    max_number = (2 ** num) - 1

    low_seed = int(current_time.timestamp())
    high_seed = int(end_datetime_pre.timestamp())

    found_seed = None

    while low_seed <= high_seed:
        mid_seed = (low_seed + high_seed) // 2

        random.seed(mid_seed)
        generated_number = random.randint(min_number, max_number)

        if generated_number == target_number:
            found_seed = mid_seed
            break
        elif generated_number < target_number:
            low_seed = mid_seed + 1
        else:
            high_seed = mid_seed - 1

    return found_seed

# Iterate through the time range
while current_datetime <= end_datetime_pre:
    # Find seeds for all target numbers
    found_seeds = [find_seed_for_target(target, current_datetime) for target in target_numbers]

    # Print the results for each target number if found and not already printed
    for i, (num, target_number) in enumerate(target_numbers, start=1):
        if found_seeds[i - 1] is not None and target_number not in found_targets:
            linuxtime = found_seeds[i - 1]
            timestamp = datetime.fromtimestamp(linuxtime)
            formatted_time = timestamp.strftime('%Y-%m-%d %H:%M:%S')
            print(f"Puzzle {i} : Private Key : {target_number} | Timestamp: {formatted_time}")
            found_targets.add(target_number)

    # Move to the next second
    current_datetime += time_step



You'd be surprised what this finds. You just need to guess the year and date range. Grin
It takes a long time to find Puzzle timestamps above 20...
copper member
Activity: 1330
Merit: 899
🖤😏
@digaran
So I ran the code and I got 63 pubkeys
I need to ask what would be the target 1 and target 2
and how can I further divide the pubkey of 130 to as low as 100 or 90 or 80 bit range
after hitting a target from the public key results, how would I further calculate the private key to get my target private key
You should try to put 130 pub on target 1 and put G on target 2, and then calculate the range like this:

Suppose we have a key in 130 bit range, dividing it by 64 gives us what? Lets try 2^130/64= 2^124, so you would need to have 2^124 public keys saved to compare the results of subtraction with, now if you divide 2^130/2^124= 64, now you only need to store 64 public keys starting from 1 to 64 for comparison, but you don't need to generate 2^124 divisions, just a few millions which would take a few days with my slow script, so first you need to boost the speed.

I have already discussed about the possibility of finding a solution to solve private keys, and this is it, I won't be guiding anyone step by step on how to do it, if Satoshi or anyone who really cares about bitcoin and actually is an expert, they will figure it out soon enough, I have promised God not to reveal the final steps to anyone, let's hope nobody figures it out.

Note, it's not an easy task, because solving each key requires a lot of steps, so many tries, so many errors but it can be done.
jr. member
Activity: 75
Merit: 5
As the "master math guru" of this community 🤥😂  I have always wondered, can God make it so when 2+2 you get 5, I mean he can do anything right? So how could we believe all of the rules of physics, mathematics? If it's possible to change the rules like that? It would be like saying since God can do anything, he should be able to clone himself infinitely, or more importantly, can God kill himself? These questions are taunting and impossible to know the answer for sure, but logic says he shouldn't be able to make 2+2=5, or create clones of himself or self destruct, that means logically even God has limits to his power.
@digaran
So I ran the code and I got 63 pubkeys
I need to ask what would be the target 1 and target 2
and how can I further divide the pubkey of 130 to as low as 100 or 90 or 80 bit range
after hitting a target from the public key results, how would I further calculate the private key to get my target private key
copper member
Activity: 1330
Merit: 899
🖤😏
As the "master math guru" of this community 🤥😂  I have always wondered, can God make it so when 2+2 you get 5, I mean he can do anything right? So how could we believe all of the rules of physics, mathematics? If it's possible to change the rules like that? It would be like saying since God can do anything, he should be able to clone himself infinitely, or more importantly, can God kill himself? These questions are taunting and impossible to know the answer for sure, but logic says he shouldn't be able to make 2+2=5, or create clones of himself or self destruct, that means logically even God has limits to his power.

But is that really the case?  Did he create the rules out of nothing or were these rules always there along side him?



I believe we are only one of the versions of infinite possible versions, so yes it is possible to see 2+2=5 under different governing rules of different universes, while it doesn't make any sense to us because we only know of 2+2=4, governing  principles of our universe does not allow us to figure out how it is possible to have two plus two equal five, this is our limit, we can't go beyond this limit.



Now what is my point? There is a solution to solve these keys, also there is a relation between rmd160 and ecc keys, just because we can't think what they are doesn't mean they don't exist. If you seek knowledge, ask the source of knowledge.  But if you quit trying midway, you will get nothing, so chop chop and God bless you.😉


Edit : this is my achievement after working on elliptic curve cryptography for more than 8 months.

I set it to print the result of subtraction, if you want to see the result for scalar_1 remove "print" from the third line and add "print" to first line, so result_1 is the result of scalar_2 division, this happens when I work by myself and a world dominating AI. 😂

Code:
import gmpy2 as mpz
from gmpy2 import powmod

# Define the ec_operations function
def ec_operations(start_range, end_range, scalar_1, scalar_2, n, divide_1_by_odd=True, divide_1_by_even=True, divide_2_by_odd=True, divide_2_by_even=True):
    for i in range(start_range + (start_range%2), end_range, 1):
        # divide scalar 1 by odd or even numbers
        if i%2 == 0 and not divide_1_by_even:
            continue
        elif i%2 == 1 and not divide_1_by_odd:
            continue
        try:
            # calculate inverse modulo of i
            i_inv = powmod(i, n-2, n)

            # multiply the scalar targets by i modulo n
            result_1 = scalar_2 * i_inv % n
            result_2 = scalar_1 * i_inv % n

            # divide scalar 2 by odd or even numbers
            if i%2 == 0 and not divide_2_by_even:
                continue
            elif i%2 == 1 and not divide_2_by_odd:
                continue

            # subtract the results
            sub_result = (result_2 - result_1) % n

            # print results separately
            (f"{i}-{hex(result_1)[2:]}")
            (f"{i}-{hex(result_2)[2:]}")
            print(f"{i}-{hex(sub_result)[2:]}")

        except ZeroDivisionError:
            pass


if __name__ == "__main__":
    # Set the targets and range for the operations
    scalar_1 = 0x0000000000000000000000000000000ff9450a667168a48762abcbe86653a6a1
    scalar_2 = 0x0000000000000000000000000000000000000000000000000000000000000001

    n = mpz.mpz("0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141")

    start_range = 2
    end_range = 65

    ec_operations(start_range, end_range, scalar_1, scalar_2, n)

Note, you can also change "1" in the following line to divide by odd or even,
Code:
for i in range(start_range + (start_range%2), end_range, 1):

Replace 1 with 2 and print subtraction result to see it divides by 2, 4, 6 etc, replacing it with 3, will divide by 2, 5, 8, 11 etc, since our start range is 2 it will start from 2 and adds 3 each step.

Even though I have already posted the script for point calculations, to make it easier for you to havd both scripts in one place, here goes the same script operating with public keys:

Code:
import gmpy2 as mpz
from gmpy2 import powmod

# Define the EllipticCurve class
class EllipticCurve:
    def __init__(self, a, b, p):
        self.a = mpz.mpz(a)
        self.b = mpz.mpz(b)
        self.p = mpz.mpz(p)

    def contains(self, point):
        x, y = point.x, point.y
        return (y * y) % self.p == (x * x * x + self.a * x + self.b) % self.p

    def __str__(self):
        return f"y^2 = x^3 + {self.a}x + {self.b} mod {self.p}"

# Define the Point class
class Point:
    def __init__(self, x, y, curve):
        self.x = mpz.mpz(x)
        self.y = mpz.mpz(y)
        self.curve = curve

    def __eq__(self, other):
        return self.x == other.x and self.y == other.y and self.curve == other.curve

    def __ne__(self, other):
        return not self == other

    def __add__(self, other):
        if self.curve != other.curve:
            raise ValueError("Cannot add points on different curves")

        # Case when one point is zero
        if self == Point.infinity(self.curve):
            return other
        if other == Point.infinity(self.curve):
            return self

        if self.x == other.x and self.y != other.y:
            return Point.infinity(self.curve)

        p = self.curve.p
        s = 0
        if self == other:
            s = ((3 * self.x * self.x + self.curve.a) * powmod(2 * self.y, -1, p)) % p
        else:
            s = ((other.y - self.y) * powmod(other.x - self.x, -1, p)) % p

        x = (s * s - self.x - other.x) % p
        y = (s * (self.x - x) - self.y) % p

        return Point(x, y, self.curve)

    def __sub__(self, other):
        if self.curve != other.curve:
            raise ValueError("Cannot subtract points on different curves")

        # Case when one point is zero
        if self == Point.infinity(self.curve):
            return other
        if other == Point.infinity(self.curve):
            return self

        return self + Point(other.x, (-other.y) % self.curve.p, self.curve)

    def __mul__(self, n):
        if not isinstance(n, int):
            raise ValueError("Multiplication is defined for integers only")

        n = n % (self.curve.p - 1)
        res = Point.infinity(self.curve)
        addend = self

        while n:
            if n & 1:
                res += addend

            addend += addend
            n >>= 1

        return res

    def __str__(self):
        return f"({self.x}, {self.y}) on {self.curve}"

    @staticmethod
    def from_hex(s, curve):
        if len(s) == 66 and s.startswith("02") or s.startswith("03"):
            compressed = True
        elif len(s) == 130 and s.startswith("04"):
            compressed = False
        else:
            raise ValueError("Hex string is not a valid compressed or uncompressed point")

        if compressed:
            is_odd = s.startswith("03")
            x = mpz.mpz(s[2:], 16)

            # Calculate y-coordinate from x and parity bit
            y_square = (x * x * x + curve.a * x + curve.b) % curve.p
            y = powmod(y_square, (curve.p + 1) // 4, curve.p)
            if is_odd != (y & 1):
                y = -y % curve.p

            return Point(x, y, curve)
        else:
            s_bytes = bytes.fromhex(s)
            uncompressed = s_bytes[0] == 4
            if not uncompressed:
                raise ValueError("Only uncompressed or compressed points are supported")

            num_bytes = len(s_bytes) // 2
            x_bytes = s_bytes[1 : num_bytes + 1]
            y_bytes = s_bytes[num_bytes + 1 :]

            x = mpz.mpz(int.from_bytes(x_bytes, byteorder="big"))
            y = mpz.mpz(int.from_bytes(y_bytes, byteorder="big"))

            return Point(x, y, curve)

    def to_hex(self, compressed=True):
        if self.x is None and self.y is None:
            return "00"
        elif compressed:
            prefix = "03" if self.y & 1 else "02"
            return prefix + hex(self.x)[2:].zfill(64)
        else:
            x_hex = hex(self.x)[2:].zfill(64)
            y_hex = hex(self.y)[2:].zfill(64)
            return "04" + x_hex + y_hex

    @staticmethod
    def infinity(curve):
        return Point(-1, -1, curve)

# Define the ec_mul function
def ec_mul(point, scalar, base_point):
    result = Point.infinity(point.curve)
    addend = point

    while scalar:
        if scalar & 1:
            result += addend

        addend += addend
        scalar >>= 1

    return result

# Define the ec_operations function
def ec_operations(start_range, end_range, target_1, target_2, curve, divide_1_by_odd=True, divide_1_by_even=True, divide_2_by_odd=True, divide_2_by_even=True):
    # Define parameters for secp256k1 curve
    n = mpz.mpz("0xfffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141")
    G = Point(
        mpz.mpz("0x79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798"),
        mpz.mpz("0x483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8"),
        curve
    )

    for i in range(start_range + ( start_range%2), end_range, 1 ):
        # divide target 1 by odd or even numbers
        if i%2 == 0 and not divide_1_by_even:
            continue
        elif i%2 == 1 and not divide_1_by_odd:
            continue
        try:
            # calculate inverse modulo of i
            i_inv = powmod(i, n-2, n)

            # divide the targets by i modulo n
            result_1 = ec_mul(target_1, i_inv, G)
            result_2 = ec_mul(target_2, i_inv, G)

            # divide target 2 by odd or even numbers
            if i%2 == 0 and not divide_2_by_even:
                continue
            elif i%2 == 1 and not divide_2_by_odd:
                continue

            # subtract the results
            sub_result = result_1 - result_2

            # print the results  separately
            (f"{i}-{result_1.to_hex()}")
            (f"{i}-{result_2.to_hex()}")
            print(f"{i}-{sub_result.to_hex()}")

        except ZeroDivisionError:
            pass


if __name__ == "__main__":
    # Set the targets and range for the operations
    curve = EllipticCurve(
        mpz.mpz(0),
        mpz.mpz(7),
        mpz.mpz("0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F")
    )

    target_1 = Point.from_hex("03db8705a402eabb367c23a611249d01f4c631c0a449093ca97ff5d19a5cbce7aa", curve)

    target_2 = Point.from_hex("0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798", curve)
   
    start_range = 1
    end_range = 65
   
    ec_operations(start_range, end_range, target_2, target_1, curve)

Special thanks to @mcdouglasx for dividing by range code, and to @nomachine for gympy2 and mpz introduction.

Ps, I'm not working to solve these puzzles, I am just studying elliptic curve, I haven't tested my methods on puzzle keys.
hero member
Activity: 630
Merit: 731
Bitcoin g33k
a seed makes it easier to manage sensitive data like the private keys and addresses he generated but at the same time represents a SPOF (Single Point of Failure). However that's not a big deal. he must take care of safe storage either way. Whether he stores only one seed or several seeds safely, what role does that play in this application. Be it random or hierarchical deterministic, we're still stuck  Cool
Jump to: