Post
Topic
Board Bitcoin Discussion
Re: Bitcoin puzzle transaction ~32 BTC prize to who solves it
by
digaran
on 12/09/2023, 17:07:05 UTC

Code:
import multiprocessing

# Define the EllipticCurve class
class EllipticCurve:
    def __init__(self, a, b, p):
        self.a = a
        self.b = b
        self.p = 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 = x
        self.y = 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) * pow(2 * self.y, -1, p)) % p
        else:
            s = ((other.y - self.y) * pow(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 = int(s[2:], 16)

            # Calculate y-coordinate from x and parity bit
            y_square = (x * x * x + curve.a * x + curve.b) % curve.p
            y = pow(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 = int.from_bytes(x_bytes, byteorder="big")
            y = int.from_bytes(y_bytes, byteorder="big")

            return Point(x, y, curve)

    def to_hex(self, compressed=True):
        if 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(None, None, curve)

# Define the ec_operations function
def ec_operations(i, target_1, target_2, start_range, end_range):
    P = EllipticCurve(0, 7, 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F)
    G = Point(0x79BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798, 0x483ADA7726A3C4655DA4FBFC0E1108A8FD17B448A68554199C47D08FFB10D4B8, P)

    div_1 = Point.from_hex(target_1, P)
    div_2 = Point.from_hex(target_2, P)
    scalar_1 = i
    scalar_2 = 2 * i
    result_1 = div_2 * scalar_1
    result_2 = div_2 * scalar_2
    sub_result = result_1 - (div_1 * (scalar_1 // 5)) - (result_2 - (div_2 * (scalar_2 // 5)))

    # Write the results to separate files
    with open(f"sub_result_{i}.txt", "a") as file:
        file.write(f"{sub_result.to_hex(compressed=True)}\n")

    print(f"Completed calculation {i}")

if __name__ == "__main__":
    # Set the targets and range for EC operations
    target_1 = "0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798"
    target_2 = "02c6047f9441ed7d6d3045406e95c07cd85c778e4b8cef3ca7abac09b95c709ee5"
    start_range = 20
    end_range = 40

    # Define the range of values to calculate on with multiprocessing
    with multiprocessing.Pool() as pool:
        pool.starmap(ec_operations, [(i, target_1, target_2, start_range, end_range) for i in range(start_range, end_range + 1)])

    print("Calculation completed. Results saved in separate files.")

My man, I think I explained incorrectly, what we want is this :
Example :
T1 = 20
T2 = 40
Start range = 2
End range = 8
Divide t1 by 2 = 10
Divide t2 by 2 = 20
Subtract 10 from 20 = 10.

T1 20/3 = 6.666666667
T2 40/3 = 13.33333333
Subtract 6.666666667 from 13.33333333 = 6.666666663

T1 20/4 = 5
T2 40/4 = 10
Subtract 5 from 10 = 5

And so on, in my example 20 is half of 40, but in reality we can set any target we want, do you think you can modify the code to do that please? Thank you for your time and effort.