Bitcoin Forum
July 24, 2024, 11:32:49 PM *
News: Help 1Dq create 15th anniversary forum artwork.
 
   Home   Help Search Login Register More  
Pages: « 1 ... 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 [276] 277 278 »
  Print  
Author Topic: Bitcoin puzzle transaction ~32 BTC prize to who solves it  (Read 197171 times)
kTimesG
Member
**
Offline Offline

Activity: 104
Merit: 24


View Profile
July 23, 2024, 02:32:42 PM
Last edit: July 23, 2024, 02:46:09 PM by kTimesG
Merited by albert0bsd (2)
 #5501

You can use nomachine's Rust Kangaroo a few posts back, or write a Python script that does the job according to your requirements (e.g. "that actually works").
Too slow? Well, don't expect to find something that "actually works", is fast, and solves 130, sitting out there for you to snug up and inherit 13 BTC tomorrow.

Not in Rust. Pure C++ with GMP. Here is the latest version that goes 470K Hops per second.

Theoretically, with 12 cores, it can achieve 5 million hops per second.
The more cores you have, the better the result will be.
However, it's not worth using this for a puzzle above 70bit. A GPU must be used instead....

Pure self-contained Python Kangaroo with no libraries required. 225K Hops per second.

DO NOT USE THIS TO SEARCH FOR 130. It is just an educational, reference-only example. All the math uses Python integers.

kangaroo.py
Code:
import math, os, sys, time


class S:            # Scalar field
    N = 0xfffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141

    @staticmethod
    def add(a, b):
        return (a + b) % S.N


class F:        # Curve field
    P = 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f

    @staticmethod
    def add(a, b):
        return (a + b) % F.P

    @staticmethod
    def mul(a, b):
        return (a * b) % F.P

    @staticmethod
    def pow(b, e):
        return pow(b, e, F.P)

    @staticmethod
    def sqrt(a):
        return F.pow(a, (F.P + 1) // 4)

    @staticmethod
    def inv(a):
        if a == 0:
            return 0

        r = 1
        s = 0
        low = a % F.P
        high = F.P

        while low > 1:
            q = high // low
            nm = s - q * r
            nw = high - low * q
            high = low
            s = r
            low = nw
            r = nm

        return r % F.P


class Point:            # Affine point
    def __init__(self, x, y, parity=-1):
        self.x = x
        self.y = y if parity == -1 else Point.calc_y(x, parity)

    @classmethod
    def uncompress(cls, s):
        parity, xh = int(s[:2], 16), s[2:]
        if parity not in [2, 3]:
            raise Exception("Expected parity 02 or 03")
        return Point(int(xh, 16), 0, parity % 2)

    @staticmethod
    def calc_y(x, parity):
        y = F.sqrt(F.add(F.pow(x, 3), 7))   # y = sqrt(x**3 + 7)
        return y if parity == y % 2 else F.P - y


class JPoint:           # Jacobian point
    def __init__(self, x, y, z):
        self.x = x
        self.y = y
        self.z = z

    def affine(self):
        z = F.inv(self.z)
        z2 = F.mul(z, z)
        return Point(F.mul(self.x, z2), F.mul(self.y, F.mul(z, z2)))

    def mul(self, n):
        if self.y == 0 or n == 0:
            return JPoint(0, 0, 1)

        if n == 1:
            return self

        if n < 0 or n >= S.N:
            return self.mul(n % S.N)

        if (n % 2) == 0:
            return self.mul(n // 2).double()

        return self.mul(n // 2).double().add(self)

    def double(self):
        if self.y == 0:
            return JPoint(0, 0, 0)

        y2 = F.mul(self.y, self.y)
        s = F.mul(4 * self.x, y2)
        M = F.mul(3 * self.x, self.x)

        x = F.add(F.mul(M, M), - 2 * s)
        return JPoint(x, F.add(F.mul(M, s - x), -F.mul(8 * y2, y2)), F.mul(2 * self.y, self.z))

    def add(self, q):
        if self.y == 0:
            return q
        if q.y == 0:
            return self

        qz2 = F.mul(q.z, q.z)
        pz2 = F.mul(self.z, self.z)
        U1 = F.mul(self.x, qz2)
        U2 = F.mul(q.x, pz2)
        S1 = F.mul(self.y, F.mul(q.z, qz2))
        S2 = F.mul(q.y, F.mul(self.z, pz2))

        if U1 == U2:
            if S1 != S2:
                return JPoint(0, 0, 1)
            return self.double()

        H = F.add(U2, -U1)
        R = F.add(S2, -S1)
        H2 = F.mul(H, H)
        H3 = F.mul(H, H2)
        U1H2 = F.mul(U1, H2)
        nx = F.add(F.mul(R, R), -F.add(H3, 2 * U1H2))
        ny = F.add(F.mul(R, F.add(U1H2, -nx)), -F.mul(S1, H3))
        nz = F.mul(H * self.z, q.z)

        return JPoint(nx, ny, nz)


class Group:
    G = Point(
        0x79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798,
        0x483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8
    )

    @staticmethod
    def add(p, q):
        m = F.mul(F.add(p.y, -q.y), F.inv(F.add(p.x, -q.x)))
        x = F.add(F.add(F.mul(m, m), -p.x), -q.x)
        return Point(x, F.add(F.mul(m, F.add(q.x, -x)), -q.y))

    @classmethod
    def mul(cls, p, k):
        # [k]P point scalar multiplication
        return JPoint(p.x, p.y, 1).mul(k).affine()

    @classmethod
    def batch_add(cls, ga, gb):
        n = len(ga)
        d = [0] * n
        p = [0] * n
        z = 1
        for i in range(n):
            d[i] = F.add(ga[i].x, -gb[i].x)
            z = F.mul(z, d[i])
            p[i] = z

        t = F.inv(z)

        for i in range(n - 1, -1, -1):
            if i > 0:
                xi = F.mul(t, p[i - 1])
                t = F.mul(t, d[i])
            else:
                xi = t

            m = F.mul(F.add(ga[i].y, -gb[i].y), xi)
            ga[i].x = F.add(F.add(F.mul(m, m), -ga[i].x), -gb[i].x)
            ga[i].y = F.add(F.mul(m, F.add(gb[i].x, -ga[i].x)), -gb[i].y)


class TrueRandom:
    def __init__(self, max_value: int, num_bits: int, min_value: int = 0):
        self.upper_bound = max_value - min_value + 1
        self.min = min_value
        self.num_bits = num_bits
        self.domain = 2 ** num_bits
        self.num_bytes = math.ceil(num_bits / 8)
        self.shift = 8 * self.num_bytes - num_bits

    def get_next(self):
        random_bytes = os.urandom(self.num_bytes)

        # trim to num_bits
        random_int = int.from_bytes(random_bytes, byteorder='big') >> self.shift

        # normalize from domain range to target range
        sample = self.upper_bound * random_int // self.domain

        return sample + self.min


def kangaroo_with_results(k1, k2, P, dp, herd_size):
    k_cand, counter, tbl_size = kangaroo(k1, k2, P, dp, herd_size=herd_size)

    k = k_cand[0]
    if k1 <= k <= k2:
        P_check = Group.mul(Group.G, k)
        if P_check.x == P.x:
            print(f'Key: {hex(k)}\nGroup ops: {counter}')

    return k_cand, counter, tbl_size


def create_kangaroo(kang_type, pos: int, herd_pts, herd_distances, k1, k2, P, rnd: TrueRandom, v):
    if kang_type == 0:
        # d = rnd.get_next()                    # [0, k2 - k1)
        d = (k2 - k1 + 1) + pos * v        # b/2 + i*v
        # d = (k2 - k1 + 1) // 2
        herd_distances[pos] = d
        herd_pts[pos] = Group.mul(Group.G, k1 + d)
    else:
        # d = rnd.get_next() - (k2 - k1 + 1) // 2               # [-(k2-k1)/2, (k2-k1)/2]
        d = (k2 - k1 + 1) // 2 + pos * v                             # b + i*v
        # d = 0
        herd_distances[pos] = d
        herd_pts[pos] = Group.add(P, Group.mul(Group.G, d))


def check_col(kang_type, hashmap, herd, dist, pos, k1, k2, P, dp_mask, R, v_rnd,
              respawn_dead=True,
              stop_at_dp=True):
    x = herd[pos].x

    if x & dp_mask == 0:
        item = hashmap.get(x)

        if item is not None:
            if item[0] == kang_type ^ 1:
                # collision
                d_wild, d_tame = (item[1], dist[pos]) if kang_type == 0 else (dist[pos], item[1])
                return [S.add(k1 + d_tame, - d_wild)], 0
            else:
                # print(f'Dead kangaroo at {pos}')
                if respawn_dead:
                    # create_kangaroo(kang_type, pos, herd, dist, k1, k2, P, R)
                    # move along with a small random value
                    d = v_rnd.get_next()
                    dist[pos] += d
                    herd[pos] = Group.add(herd[pos], Group.mul(Group.G, d))

                    # this will recurse until a non-dead kangaroo is produced
                    k, created = check_col(kang_type, hashmap, herd, dist, pos, k1, k2, P, dp_mask, R, v_rnd)
                    return k, 1 + created
        else:
            hashmap[x] = (kang_type, dist[pos])

    return 0, 0


def build_jump_distances(alpha, with_points=False):
    jump_points = []
    jump_distances = []

    # compute A (jump distances) such that average(A) is closest to expected alpha
    # Pollard says choosing A as powers of two feels like "needs more investigation"
    min_diff = 1
    while True:
        jump_distance = 2 ** len(jump_distances)
        jump_distances.append(jump_distance)
        if with_points:
            jump_points.append(Group.mul(Group.G, jump_distance))

        alpha_real = sum(jump_distances) / len(jump_distances)
        diff = abs(1 - alpha_real / alpha)
        if alpha_real >= alpha:
            if diff > min_diff:
                jump_distances.pop()
            break
        if diff < min_diff:
            min_diff = diff

    return jump_distances, jump_points


def kangaroo(k1, k2, P, dp: int, herd_size: int = 128):
    b = k2 - k1 + 1                                                 # size of search interval
    m = herd_size + herd_size                                       # m/2 + m/2
    # parallel case - minimize alpha for total number of jumps
    alpha = m * math.sqrt(b) / 4                                    # m * sqrt(b) / 4

    jump_distances, jump_points = build_jump_distances(alpha, with_points=True)
    alpha_real = sum(jump_distances) / len(jump_distances)

    n = len(jump_distances)

    # adjust alpha to the actual average jump distance
    alpha_expected = alpha
    alpha = alpha_real

    # expected total number of jumps for each trailing kangaroo (1 per processor)
    expected_trailing_jumps = 2 * math.sqrt(b) / m                  # 2 * sqrt(b) / m

    # beta = 0.553                      # serial case
    # ab_jumps = int(alpha * beta)      # serial case
    # max_tame_distance = int(alpha * alpha * beta + b // 2)

    # expected number of jumps done by a trailing kangaroo after it enters the [b, ...] region
    # this would equal the number of jumps done by a tame kangaroo that starts from b
    num_tame_jumps = 4 * alpha / (m * m)                        # 4 * alpha / (m**2)
    max_tame_distance = int(alpha * num_tame_jumps + b)         # average jump size * num jumps + start
    # max_wild_distance = int(alpha * num_tame_jumps + b/2)       # average jump size * num jumps + start
    # = (2*a/m)**2 = (sqrt(b) / 2)**2

    # set v to the "partition" size for a processor, and not a power of two
    v = b // m - 1                          # (b/2) / (m/2)
    # v = herd_size
    v_rnd = TrueRandom(v, 256)

    hashmap = {}
    wilds: list = [None] * herd_size
    tames: list = [None] * herd_size
    w_dist = [0] * herd_size
    t_dist = [0] * herd_size
    counter = 0
    done_ab_jumps = 0

    expected_total_jumps = math.ceil((num_tame_jumps + expected_trailing_jumps) * herd_size)
    print(
        f'processors: {m}'
        f'\n         num jump distances: {n}'
        f'\nmax jumps per tame kangaroo: {math.ceil(num_tame_jumps)}'
        f'\nmax jumps per wild kangaroo: {math.ceil(expected_trailing_jumps)}'
        f'\n       expected total jumps: {expected_total_jumps} {math.log2(expected_total_jumps):.2f} bits'
        f'\n     avg real jump distance: {round(alpha_real)} {math.log2(alpha_real):.2f} bits'
        f'\n avg expected jump distance: {round(alpha_expected)} {math.log2(alpha_expected):.2f} bits'
        f'\n expected max tame distance: {max_tame_distance} {math.log2(max_tame_distance):.2f} bits'
        # f'\n expected max wild distance: {max_wild_distance} {math.log2(max_wild_distance):.2f} bits'
    )

    R = TrueRandom(k2 - k1, 256, 0)
    dp_mask = (1 << dp) - 1

    for idx in range(herd_size):
        create_kangaroo(0, idx, tames, t_dist, k1, k2, P, R, v)
        counter += 1

        k, born = check_col(0, hashmap, tames, t_dist, idx, k1, k2, P, dp_mask, R, v_rnd)
        counter += born
        if k:
            return k, counter, len(hashmap)

        create_kangaroo(1, idx, wilds, w_dist, k1, k2, P, R, v)
        counter += 1

        k, born = check_col(1, hashmap, wilds, w_dist, idx, k1, k2, P, dp_mask, R, v_rnd)
        counter += born
        if k:
            return k, counter, len(hashmap)

    batch_jp: list = [None] * herd_size

    start_time = time.time()
    last_p_time = 0
    while True:
        if done_ab_jumps < num_tame_jumps:
            # jump tames
            for idx in range(herd_size):
                d = tames[idx].x % n
                # tames[idx] = Group.add(tames[idx], jump_points[d])        # un-batched addition
                batch_jp[idx] = jump_points[d]
                t_dist[idx] += jump_distances[d]

            Group.batch_add(tames, batch_jp)

            for idx in range(herd_size):
                counter += 1

                k, born = check_col(0, hashmap, tames, t_dist, idx, k1, k2, P, dp_mask, R, v_rnd)
                counter += born
                if k:
                    return k, counter, len(hashmap)

            done_ab_jumps += 1
            if done_ab_jumps >= num_tame_jumps:
                # new_max = max(t_dist)
                # avg_dist = sum(t_dist) / len(t_dist)
                # print(
                #     f'Tames are done.'
                #     f'\nExpected max tame distance: {max_tame_distance} {math.log2(max_tame_distance):.2f} bits'
                #     f'\nAverage max tame distance:  {avg_dist}  {math.log2(avg_dist):.2f} bits'
                #     f'\nActual max tame distance:   {new_max}  {math.log2(new_max):.2f} bits'
                # )
                # max_tame_distance = max(max_tame_distance, new_max)
                # max_wild_distance = int(max_tame_distance + b / 2)      # add initial tame - wild gap

                # create new tames herd
                for idx in range(herd_size):
                    d = b + idx * v + v_rnd.get_next()    # b/2 + i*v + z

                    t_dist[idx] = d
                    tames[idx] = Group.mul(Group.G, k1 + d)
                    counter += 1

                done_ab_jumps = 0

        for idx in range(herd_size):
            d = wilds[idx].x % n
            # wilds[idx] = Group.add(wilds[idx], jump_points[d])    # unbatched addition
            batch_jp[idx] = jump_points[d]
            w_dist[idx] += jump_distances[d]

        Group.batch_add(wilds, batch_jp)

        for idx in range(herd_size):
            counter += 1

            k, born = check_col(1, hashmap, wilds, w_dist, idx, k1, k2, P, dp_mask, R, v_rnd)
            counter += born
            if k:
                return k, counter, len(hashmap)

            if w_dist[idx] > max_tame_distance:
                # create_kangaroo(1, idx, wilds, w_dist, k1, k2, P, R)
                z = v_rnd.get_next()
                d = b // 2 + idx * v + z        # b + i*v + z

                w_dist[idx] = d
                wilds[idx] = Group.add(P, Group.mul(Group.G, d))

                counter += 1

        total_time = time.time() - start_time
        if total_time - last_p_time > 3:
            last_p_time = total_time
            print(f'Ops: {counter} Table size: {len(hashmap)} Speed: {counter / total_time:.0f} ops/s')


def run_puzzle(idx: int, pub_key, dp: int = 0, herd_size: int = 128, benchmark=0):
    # puzzle #X has (X - 1) unknown bits
    k1 = 1 << (idx - 1)
    k2 = (k1 << 1) - 1

    # subtract k1 to search in a [0, k2 - k1) interval
    k2 -= k1
    k1 = 0

    P = Point.uncompress(pub_key)

    # subtract (k2 - k1)G from P to bring target point's k to [0, k2 - k1) interval
    P = Group.add(P, Group.mul(Group.G, -(k2 + 1)))

    now = time.time()
    _, ops, hashmap_size = kangaroo_with_results(k1, k2, P, dp, herd_size)
    total_time = time.time() - now
    print(f'Ops: {ops} Stored: {hashmap_size}')
    print(f'Speed: {ops / total_time:.0f} ops/s')


if __name__ == '__main__':
    # r, p = int(sys.argv[1]), sys.argv[2]
    # run_puzzle(r, p, dp=0, herd_size=128)

    # run_puzzle(32, '0209c58240e50e3ba3f833c82655e8725c037a2294e14cf5d73a5df8d56159de69',
    #            herd_size=512)

    run_puzzle(48, '0291bee5cf4b14c291c650732faa166040e4c18a14731f9a930c1e87d3ec12debb',
               dp=8, herd_size=1024)

Puzzle 48:
Code:
processors: 2048
         num jump distances: 38
max jumps per tame kangaroo: 6899
max jumps per wild kangaroo: 11586
       expected total jumps: 18927375 24.17 bits
     avg real jump distance: 7233629130 32.75 bits
 avg expected jump distance: 6074001000 32.50 bits
 expected max tame distance: 190638869267657 47.44 bits
...
Ops: 17607859 Table size: 68719 Speed: 225400 ops/s
Key: 0x2de6d7ce3b9b
Group ops: 18288933
Ops: 18288933 Stored: 71317
Speed: 222616 ops/s
cnk1220
Newbie
*
Offline Offline

Activity: 24
Merit: 0


View Profile
July 23, 2024, 03:30:36 PM
 #5502

I think that kangaroos that have been forked or modded from JLp's original kangaroo do not work. and I'm really asking about kangaroo running on 125 bit and above.

how do you know it doesn't work? in this last one there is no number 125 in the code. it's all 256...there is NO way to prove it doesn't work because it's impossible to solve puzzle 130.

So how do you know if it's working? Do you have proof?
Many people claim that they forked and modified the original JPL kangaroo 125-bit program and created new 256-bit kangaroo programs. So do these work? What happens if there is a code error? What if it was created incorrectly?
How would you feel if, after using it for months, someone told you that the program didn't really work?
Let me give an example: the keyhunt bsgs program definitely works.

So, is there anyone who has used the modded kangaroo program and can say this?

What you mean "works"?
How do YOU know keyhuntbsgs works?
albert0bsd
Hero Member
*****
Offline Offline

Activity: 890
Merit: 675



View Profile
July 23, 2024, 04:03:01 PM
Last edit: July 23, 2024, 08:11:30 PM by albert0bsd
 #5503

Just for those who want to know here are all my RAWTX  for the RBF challenge from some days ago and the TXID or Error code  returned from the mempool API:

Code:
Address 197kFKvMHoRJPXktc8xJwMjeTuE9xijBQ found public key 029fd3d2479a37f40d03975cb51ce0fa18cbb709cc46b47caeaa1722cfd3683583
Keyfound 000000000000000000000000000000000000000000000002357CAC24E9C2D41D for address 197kFKvMHoRJPXktc8xJwMjeTuE9xijBQ
UXTO TXID:3ee3fa9738d6f3357966f2283c8cc9409bd24ec1033762b936152717977ce520 index 0  balance 492600

Output to bc1qcrej0q6xqfyr9ecayk3y6khykuugt7za6umuk4 with 490104 satoshis, network bitcoin
Raw TX:
010000000120e57c9717271536b9623703c14ed29b40c98c3c28f2667935f3d63897fae33e000000006a473044022031f4cf9bf5a9dc03b7ee11e8f31c8d362f225b8a9db0c8ed9bce24a833d1301f02201417d3564599b67aeffd53818e004898b7f884ffc6000a691f1e9e232a4927120121029fd3d2479a37f40d03975cb51ce0fa18cbb709cc46b47caeaa1722cfd3683583ffffffff01787a070000000000160014c0f3278346024832e71d25a24d5ae4b73885f85d00000000
TXID: 7e91e4f33f6ead7ebb0d441e180a1ff0f66071b466ea3c6aab2ef9e36f4c98b3

Output to bc1qcrej0q6xqfyr9ecayk3y6khykuugt7za6umuk4 with 488856 satoshis, network bitcoin
Raw TX:
010000000120e57c9717271536b9623703c14ed29b40c98c3c28f2667935f3d63897fae33e000000006a47304402200c97ff52a39e5a42907617847e979c89ff7d660f10862f8c9edd0d32e90fa17802200c74a1117890f4b8248ad0fa2a14d66e283b66732c2fd0e3a59d27d657bbb95b0121029fd3d2479a37f40d03975cb51ce0fa18cbb709cc46b47caeaa1722cfd3683583ffffffff019875070000000000160014c0f3278346024832e71d25a24d5ae4b73885f85d00000000
TXID: 5967ccefbaeee59a85c8f8689cd85684089a91a09b56b3a67d9e7845b237592c


Output to bc1qcrej0q6xqfyr9ecayk3y6khykuugt7za6umuk4 with 488856 satoshis, network bitcoin
Raw TX:
010000000120e57c9717271536b9623703c14ed29b40c98c3c28f2667935f3d63897fae33e000000006a47304402200c97ff52a39e5a42907617847e979c89ff7d660f10862f8c9edd0d32e90fa17802200c74a1117890f4b8248ad0fa2a14d66e283b66732c2fd0e3a59d27d657bbb95b0121029fd3d2479a37f40d03975cb51ce0fa18cbb709cc46b47caeaa1722cfd3683583ffffffff019875070000000000160014c0f3278346024832e71d25a24d5ae4b73885f85d00000000
TXID: sendrawtransaction RPC error: {"code":-26,"message":"txn-mempool-conflict"}


Output to bc1qcrej0q6xqfyr9ecayk3y6khykuugt7za6umuk4 with 488856 satoshis, network bitcoin
Raw TX:
010000000120e57c9717271536b9623703c14ed29b40c98c3c28f2667935f3d63897fae33e000000006a47304402200c97ff52a39e5a42907617847e979c89ff7d660f10862f8c9edd0d32e90fa17802200c74a1117890f4b8248ad0fa2a14d66e283b66732c2fd0e3a59d27d657bbb95b0121029fd3d2479a37f40d03975cb51ce0fa18cbb709cc46b47caeaa1722cfd3683583ffffffff019875070000000000160014c0f3278346024832e71d25a24d5ae4b73885f85d00000000
TXID: 5967ccefbaeee59a85c8f8689cd85684089a91a09b56b3a67d9e7845b237592c

Output to bc1qcrej0q6xqfyr9ecayk3y6khykuugt7za6umuk4 with 488024 satoshis, network bitcoin
Raw TX:
010000000120e57c9717271536b9623703c14ed29b40c98c3c28f2667935f3d63897fae33e000000006b483045022100b6daea5a333af8f3d52134f9b4cab6a59721fcd2a23538c5e29c55d23e21d64802202c7e5799d91ff7921cc6cc3de84bc710aa9e8c9c49841b30a30f3b7e5142e65b0121029fd3d2479a37f40d03975cb51ce0fa18cbb709cc46b47caeaa1722cfd3683583ffffffff015872070000000000160014c0f3278346024832e71d25a24d5ae4b73885f85d00000000
TXID: sendrawtransaction RPC error: {"code":-26,"message":"txn-mempool-conflict"}

Output to bc1qcrej0q6xqfyr9ecayk3y6khykuugt7za6umuk4 with 488856 satoshis, network bitcoin
Raw TX:
010000000120e57c9717271536b9623703c14ed29b40c98c3c28f2667935f3d63897fae33e000000006a47304402200c97ff52a39e5a42907617847e979c89ff7d660f10862f8c9edd0d32e90fa17802200c74a1117890f4b8248ad0fa2a14d66e283b66732c2fd0e3a59d27d657bbb95b0121029fd3d2479a37f40d03975cb51ce0fa18cbb709cc46b47caeaa1722cfd3683583ffffffff019875070000000000160014c0f3278346024832e71d25a24d5ae4b73885f85d00000000
TXID: sendrawtransaction RPC error: {"code":-26,"message":"insufficient fee, rejecting replacement 5967ccefbaeee59a85c8f8689cd85684089a91a09b56b3a67d9e7845b237592c; new feerate 0.00019914 BTC/kvB <= old feerate 0.00029872 BTC/kvB"}

Output to bc1qcrej0q6xqfyr9ecayk3y6khykuugt7za6umuk4 with 488856 satoshis, network bitcoin
Raw TX:
010000000120e57c9717271536b9623703c14ed29b40c98c3c28f2667935f3d63897fae33e000000006a47304402200c97ff52a39e5a42907617847e979c89ff7d660f10862f8c9edd0d32e90fa17802200c74a1117890f4b8248ad0fa2a14d66e283b66732c2fd0e3a59d27d657bbb95b0121029fd3d2479a37f40d03975cb51ce0fa18cbb709cc46b47caeaa1722cfd3683583ffffffff019875070000000000160014c0f3278346024832e71d25a24d5ae4b73885f85d00000000
TXID: sendrawtransaction RPC error: {"code":-26,"message":"insufficient fee, rejecting replacement 5967ccefbaeee59a85c8f8689cd85684089a91a09b56b3a67d9e7845b237592c; new feerate 0.00019914 BTC/kvB <= old feerate 0.00044255 BTC/kvB"}

Output to bc1qcrej0q6xqfyr9ecayk3y6khykuugt7za6umuk4 with 488856 satoshis, network bitcoin
Raw TX:
010000000120e57c9717271536b9623703c14ed29b40c98c3c28f2667935f3d63897fae33e000000006a47304402200c97ff52a39e5a42907617847e979c89ff7d660f10862f8c9edd0d32e90fa17802200c74a1117890f4b8248ad0fa2a14d66e283b66732c2fd0e3a59d27d657bbb95b0121029fd3d2479a37f40d03975cb51ce0fa18cbb709cc46b47caeaa1722cfd3683583ffffffff019875070000000000160014c0f3278346024832e71d25a24d5ae4b73885f85d00000000
TXID: sendrawtransaction RPC error: {"code":-26,"message":"insufficient fee, rejecting replacement 5967ccefbaeee59a85c8f8689cd85684089a91a09b56b3a67d9e7845b237592c; new feerate 0.00019914 BTC/kvB <= old feerate 0.00052825 BTC/kvB"}

Output to bc1qcrej0q6xqfyr9ecayk3y6khykuugt7za6umuk4 with 480536 satoshis, network bitcoin
Raw TX:
010000000120e57c9717271536b9623703c14ed29b40c98c3c28f2667935f3d63897fae33e000000006b4830450221009b36b01ae4710f13457428156736df8d1188e38caf0c0f4ef86ac052823da82d022077abf7b6c2fd28f1b86ecfbb5c7ae3fe452e48102dbae829d3343969c20b77e70121029fd3d2479a37f40d03975cb51ce0fa18cbb709cc46b47caeaa1722cfd3683583ffffffff011855070000000000160014c0f3278346024832e71d25a24d5ae4b73885f85d00000000
TXID: 699fb5b81c331abaa0fd11ed3f7c6b542cfbd180ccb0357d8d159663a7e96ca4


Output to bc1qcrej0q6xqfyr9ecayk3y6khykuugt7za6umuk4 with 475128 satoshis, network bitcoin
Raw TX:
010000000120e57c9717271536b9623703c14ed29b40c98c3c28f2667935f3d63897fae33e000000006a47304402202927628b704125bd1322d7293fb1a9c0fa203ba8e323f46fb195239e917d25ac0220623f9eeee892a4abd1671578c40ace03b34dd8797b45a635904d7182c11f74960121029fd3d2479a37f40d03975cb51ce0fa18cbb709cc46b47caeaa1722cfd3683583ffffffff01f83f070000000000160014c0f3278346024832e71d25a24d5ae4b73885f85d00000000
TXID: 23f023729eb3be2b4c1004bb1610043ecc1befb5b9223db7284c337ac06e9d64


Output to bc1qcrej0q6xqfyr9ecayk3y6khykuugt7za6umuk4 with 488856 satoshis, network bitcoin
Raw TX:
010000000120e57c9717271536b9623703c14ed29b40c98c3c28f2667935f3d63897fae33e000000006a47304402200c97ff52a39e5a42907617847e979c89ff7d660f10862f8c9edd0d32e90fa17802200c74a1117890f4b8248ad0fa2a14d66e283b66732c2fd0e3a59d27d657bbb95b0121029fd3d2479a37f40d03975cb51ce0fa18cbb709cc46b47caeaa1722cfd3683583ffffffff019875070000000000160014c0f3278346024832e71d25a24d5ae4b73885f85d00000000
TXID: <html>
<head><title>429 Too Many Requests</title></head>
<body>
<center><h1>429 Too Many Requests</h1></center>
<center><h2>Sign Up for <a href="https://mempool.space/enterprise">Mempool Enterprise</a> to get increased API limits</h2></center>
</body>
</html>

Output to bc1qcrej0q6xqfyr9ecayk3y6khykuugt7za6umuk4 with 467224 satoshis, network bitcoin
Raw TX:
010000000120e57c9717271536b9623703c14ed29b40c98c3c28f2667935f3d63897fae33e000000006a473044022068357d38b55b987e139ce069de456cb399b04f37861879bb7e425ef84b11816a0220425c3fb1c6fa90ca1d7ab6971375a94d62e36a49041d7cfda338d51f4169a08e0121029fd3d2479a37f40d03975cb51ce0fa18cbb709cc46b47caeaa1722cfd3683583ffffffff011821070000000000160014c0f3278346024832e71d25a24d5ae4b73885f85d00000000
TXID: 354dbcb6fd3532a051e1e363c9122d862949c3d075280d4144f719d6ba99e14a

You can decode RAWTX on: https://www.blockchain.com/explorer/assets/btc/decode-transaction

Just to check if something is odd or not.
nomachine
Member
**
Offline Offline

Activity: 368
Merit: 21


View Profile
July 23, 2024, 08:13:44 PM
Last edit: July 23, 2024, 08:32:02 PM by nomachine
 #5504

You can use nomachine's Rust Kangaroo a few posts back, or write a Python script that does the job according to your requirements (e.g. "that actually works").
Too slow? Well, don't expect to find something that "actually works", is fast, and solves 130, sitting out there for you to snug up and inherit 13 BTC tomorrow.

Not in Rust. Pure C++ with GMP. Here is the latest version that goes 470K Hops per second.

Theoretically, with 12 cores, it can achieve 5 million hops per second.
The more cores you have, the better the result will be.
However, it's not worth using this for a puzzle above 70bit. A GPU must be used instead....

Pure self-contained Python Kangaroo with no libraries required. 225K Hops per second.

DO NOT USE THIS TO SEARCH FOR 130. It is just an educational, reference-only example. All the math uses Python integers.

kangaroo.py
Code:
import math, os, sys, time


class S:            # Scalar field
    N = 0xfffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141

    @staticmethod
    def add(a, b):
        return (a + b) % S.N


class F:        # Curve field
    P = 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f

    @staticmethod
    def add(a, b):
        return (a + b) % F.P

    @staticmethod
    def mul(a, b):
        return (a * b) % F.P

    @staticmethod
    def pow(b, e):
        return pow(b, e, F.P)

    @staticmethod
    def sqrt(a):
        return F.pow(a, (F.P + 1) // 4)

    @staticmethod
    def inv(a):
        if a == 0:
            return 0

        r = 1
        s = 0
        low = a % F.P
        high = F.P

        while low > 1:
            q = high // low
            nm = s - q * r
            nw = high - low * q
            high = low
            s = r
            low = nw
            r = nm

        return r % F.P


class Point:            # Affine point
    def __init__(self, x, y, parity=-1):
        self.x = x
        self.y = y if parity == -1 else Point.calc_y(x, parity)

    @classmethod
    def uncompress(cls, s):
        parity, xh = int(s[:2], 16), s[2:]
        if parity not in [2, 3]:
            raise Exception("Expected parity 02 or 03")
        return Point(int(xh, 16), 0, parity % 2)

    @staticmethod
    def calc_y(x, parity):
        y = F.sqrt(F.add(F.pow(x, 3), 7))   # y = sqrt(x**3 + 7)
        return y if parity == y % 2 else F.P - y


class JPoint:           # Jacobian point
    def __init__(self, x, y, z):
        self.x = x
        self.y = y
        self.z = z

    def affine(self):
        z = F.inv(self.z)
        z2 = F.mul(z, z)
        return Point(F.mul(self.x, z2), F.mul(self.y, F.mul(z, z2)))

    def mul(self, n):
        if self.y == 0 or n == 0:
            return JPoint(0, 0, 1)

        if n == 1:
            return self

        if n < 0 or n >= S.N:
            return self.mul(n % S.N)

        if (n % 2) == 0:
            return self.mul(n // 2).double()

        return self.mul(n // 2).double().add(self)

    def double(self):
        if self.y == 0:
            return JPoint(0, 0, 0)

        y2 = F.mul(self.y, self.y)
        s = F.mul(4 * self.x, y2)
        M = F.mul(3 * self.x, self.x)

        x = F.add(F.mul(M, M), - 2 * s)
        return JPoint(x, F.add(F.mul(M, s - x), -F.mul(8 * y2, y2)), F.mul(2 * self.y, self.z))

    def add(self, q):
        if self.y == 0:
            return q
        if q.y == 0:
            return self

        qz2 = F.mul(q.z, q.z)
        pz2 = F.mul(self.z, self.z)
        U1 = F.mul(self.x, qz2)
        U2 = F.mul(q.x, pz2)
        S1 = F.mul(self.y, F.mul(q.z, qz2))
        S2 = F.mul(q.y, F.mul(self.z, pz2))

        if U1 == U2:
            if S1 != S2:
                return JPoint(0, 0, 1)
            return self.double()

        H = F.add(U2, -U1)
        R = F.add(S2, -S1)
        H2 = F.mul(H, H)
        H3 = F.mul(H, H2)
        U1H2 = F.mul(U1, H2)
        nx = F.add(F.mul(R, R), -F.add(H3, 2 * U1H2))
        ny = F.add(F.mul(R, F.add(U1H2, -nx)), -F.mul(S1, H3))
        nz = F.mul(H * self.z, q.z)

        return JPoint(nx, ny, nz)


class Group:
    G = Point(
        0x79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798,
        0x483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8
    )

    @staticmethod
    def add(p, q):
        m = F.mul(F.add(p.y, -q.y), F.inv(F.add(p.x, -q.x)))
        x = F.add(F.add(F.mul(m, m), -p.x), -q.x)
        return Point(x, F.add(F.mul(m, F.add(q.x, -x)), -q.y))

    @classmethod
    def mul(cls, p, k):
        # [k]P point scalar multiplication
        return JPoint(p.x, p.y, 1).mul(k).affine()

    @classmethod
    def batch_add(cls, ga, gb):
        n = len(ga)
        d = [0] * n
        p = [0] * n
        z = 1
        for i in range(n):
            d[i] = F.add(ga[i].x, -gb[i].x)
            z = F.mul(z, d[i])
            p[i] = z

        t = F.inv(z)

        for i in range(n - 1, -1, -1):
            if i > 0:
                xi = F.mul(t, p[i - 1])
                t = F.mul(t, d[i])
            else:
                xi = t

            m = F.mul(F.add(ga[i].y, -gb[i].y), xi)
            ga[i].x = F.add(F.add(F.mul(m, m), -ga[i].x), -gb[i].x)
            ga[i].y = F.add(F.mul(m, F.add(gb[i].x, -ga[i].x)), -gb[i].y)


class TrueRandom:
    def __init__(self, max_value: int, num_bits: int, min_value: int = 0):
        self.upper_bound = max_value - min_value + 1
        self.min = min_value
        self.num_bits = num_bits
        self.domain = 2 ** num_bits
        self.num_bytes = math.ceil(num_bits / 8)
        self.shift = 8 * self.num_bytes - num_bits

    def get_next(self):
        random_bytes = os.urandom(self.num_bytes)

        # trim to num_bits
        random_int = int.from_bytes(random_bytes, byteorder='big') >> self.shift

        # normalize from domain range to target range
        sample = self.upper_bound * random_int // self.domain

        return sample + self.min


def kangaroo_with_results(k1, k2, P, dp, herd_size):
    k_cand, counter, tbl_size = kangaroo(k1, k2, P, dp, herd_size=herd_size)

    k = k_cand[0]
    if k1 <= k <= k2:
        P_check = Group.mul(Group.G, k)
        if P_check.x == P.x:
            print(f'Key: {hex(k)}\nGroup ops: {counter}')

    return k_cand, counter, tbl_size


def create_kangaroo(kang_type, pos: int, herd_pts, herd_distances, k1, k2, P, rnd: TrueRandom, v):
    if kang_type == 0:
        # d = rnd.get_next()                    # [0, k2 - k1)
        d = (k2 - k1 + 1) + pos * v        # b/2 + i*v
        # d = (k2 - k1 + 1) // 2
        herd_distances[pos] = d
        herd_pts[pos] = Group.mul(Group.G, k1 + d)
    else:
        # d = rnd.get_next() - (k2 - k1 + 1) // 2               # [-(k2-k1)/2, (k2-k1)/2]
        d = (k2 - k1 + 1) // 2 + pos * v                             # b + i*v
        # d = 0
        herd_distances[pos] = d
        herd_pts[pos] = Group.add(P, Group.mul(Group.G, d))


def check_col(kang_type, hashmap, herd, dist, pos, k1, k2, P, dp_mask, R, v_rnd,
              respawn_dead=True,
              stop_at_dp=True):
    x = herd[pos].x

    if x & dp_mask == 0:
        item = hashmap.get(x)

        if item is not None:
            if item[0] == kang_type ^ 1:
                # collision
                d_wild, d_tame = (item[1], dist[pos]) if kang_type == 0 else (dist[pos], item[1])
                return [S.add(k1 + d_tame, - d_wild)], 0
            else:
                # print(f'Dead kangaroo at {pos}')
                if respawn_dead:
                    # create_kangaroo(kang_type, pos, herd, dist, k1, k2, P, R)
                    # move along with a small random value
                    d = v_rnd.get_next()
                    dist[pos] += d
                    herd[pos] = Group.add(herd[pos], Group.mul(Group.G, d))

                    # this will recurse until a non-dead kangaroo is produced
                    k, created = check_col(kang_type, hashmap, herd, dist, pos, k1, k2, P, dp_mask, R, v_rnd)
                    return k, 1 + created
        else:
            hashmap[x] = (kang_type, dist[pos])

    return 0, 0


def build_jump_distances(alpha, with_points=False):
    jump_points = []
    jump_distances = []

    # compute A (jump distances) such that average(A) is closest to expected alpha
    # Pollard says choosing A as powers of two feels like "needs more investigation"
    min_diff = 1
    while True:
        jump_distance = 2 ** len(jump_distances)
        jump_distances.append(jump_distance)
        if with_points:
            jump_points.append(Group.mul(Group.G, jump_distance))

        alpha_real = sum(jump_distances) / len(jump_distances)
        diff = abs(1 - alpha_real / alpha)
        if alpha_real >= alpha:
            if diff > min_diff:
                jump_distances.pop()
            break
        if diff < min_diff:
            min_diff = diff

    return jump_distances, jump_points


def kangaroo(k1, k2, P, dp: int, herd_size: int = 128):
    b = k2 - k1 + 1                                                 # size of search interval
    m = herd_size + herd_size                                       # m/2 + m/2
    # parallel case - minimize alpha for total number of jumps
    alpha = m * math.sqrt(b) / 4                                    # m * sqrt(b) / 4

    jump_distances, jump_points = build_jump_distances(alpha, with_points=True)
    alpha_real = sum(jump_distances) / len(jump_distances)

    n = len(jump_distances)

    # adjust alpha to the actual average jump distance
    alpha_expected = alpha
    alpha = alpha_real

    # expected total number of jumps for each trailing kangaroo (1 per processor)
    expected_trailing_jumps = 2 * math.sqrt(b) / m                  # 2 * sqrt(b) / m

    # beta = 0.553                      # serial case
    # ab_jumps = int(alpha * beta)      # serial case
    # max_tame_distance = int(alpha * alpha * beta + b // 2)

    # expected number of jumps done by a trailing kangaroo after it enters the [b, ...] region
    # this would equal the number of jumps done by a tame kangaroo that starts from b
    num_tame_jumps = 4 * alpha / (m * m)                        # 4 * alpha / (m**2)
    max_tame_distance = int(alpha * num_tame_jumps + b)         # average jump size * num jumps + start
    # max_wild_distance = int(alpha * num_tame_jumps + b/2)       # average jump size * num jumps + start
    # = (2*a/m)**2 = (sqrt(b) / 2)**2

    # set v to the "partition" size for a processor, and not a power of two
    v = b // m - 1                          # (b/2) / (m/2)
    # v = herd_size
    v_rnd = TrueRandom(v, 256)

    hashmap = {}
    wilds: list = [None] * herd_size
    tames: list = [None] * herd_size
    w_dist = [0] * herd_size
    t_dist = [0] * herd_size
    counter = 0
    done_ab_jumps = 0

    expected_total_jumps = math.ceil((num_tame_jumps + expected_trailing_jumps) * herd_size)
    print(
        f'processors: {m}'
        f'\n         num jump distances: {n}'
        f'\nmax jumps per tame kangaroo: {math.ceil(num_tame_jumps)}'
        f'\nmax jumps per wild kangaroo: {math.ceil(expected_trailing_jumps)}'
        f'\n       expected total jumps: {expected_total_jumps} {math.log2(expected_total_jumps):.2f} bits'
        f'\n     avg real jump distance: {round(alpha_real)} {math.log2(alpha_real):.2f} bits'
        f'\n avg expected jump distance: {round(alpha_expected)} {math.log2(alpha_expected):.2f} bits'
        f'\n expected max tame distance: {max_tame_distance} {math.log2(max_tame_distance):.2f} bits'
        # f'\n expected max wild distance: {max_wild_distance} {math.log2(max_wild_distance):.2f} bits'
    )

    R = TrueRandom(k2 - k1, 256, 0)
    dp_mask = (1 << dp) - 1

    for idx in range(herd_size):
        create_kangaroo(0, idx, tames, t_dist, k1, k2, P, R, v)
        counter += 1

        k, born = check_col(0, hashmap, tames, t_dist, idx, k1, k2, P, dp_mask, R, v_rnd)
        counter += born
        if k:
            return k, counter, len(hashmap)

        create_kangaroo(1, idx, wilds, w_dist, k1, k2, P, R, v)
        counter += 1

        k, born = check_col(1, hashmap, wilds, w_dist, idx, k1, k2, P, dp_mask, R, v_rnd)
        counter += born
        if k:
            return k, counter, len(hashmap)

    batch_jp: list = [None] * herd_size

    start_time = time.time()
    last_p_time = 0
    while True:
        if done_ab_jumps < num_tame_jumps:
            # jump tames
            for idx in range(herd_size):
                d = tames[idx].x % n
                # tames[idx] = Group.add(tames[idx], jump_points[d])        # un-batched addition
                batch_jp[idx] = jump_points[d]
                t_dist[idx] += jump_distances[d]

            Group.batch_add(tames, batch_jp)

            for idx in range(herd_size):
                counter += 1

                k, born = check_col(0, hashmap, tames, t_dist, idx, k1, k2, P, dp_mask, R, v_rnd)
                counter += born
                if k:
                    return k, counter, len(hashmap)

            done_ab_jumps += 1
            if done_ab_jumps >= num_tame_jumps:
                # new_max = max(t_dist)
                # avg_dist = sum(t_dist) / len(t_dist)
                # print(
                #     f'Tames are done.'
                #     f'\nExpected max tame distance: {max_tame_distance} {math.log2(max_tame_distance):.2f} bits'
                #     f'\nAverage max tame distance:  {avg_dist}  {math.log2(avg_dist):.2f} bits'
                #     f'\nActual max tame distance:   {new_max}  {math.log2(new_max):.2f} bits'
                # )
                # max_tame_distance = max(max_tame_distance, new_max)
                # max_wild_distance = int(max_tame_distance + b / 2)      # add initial tame - wild gap

                # create new tames herd
                for idx in range(herd_size):
                    d = b + idx * v + v_rnd.get_next()    # b/2 + i*v + z

                    t_dist[idx] = d
                    tames[idx] = Group.mul(Group.G, k1 + d)
                    counter += 1

                done_ab_jumps = 0

        for idx in range(herd_size):
            d = wilds[idx].x % n
            # wilds[idx] = Group.add(wilds[idx], jump_points[d])    # unbatched addition
            batch_jp[idx] = jump_points[d]
            w_dist[idx] += jump_distances[d]

        Group.batch_add(wilds, batch_jp)

        for idx in range(herd_size):
            counter += 1

            k, born = check_col(1, hashmap, wilds, w_dist, idx, k1, k2, P, dp_mask, R, v_rnd)
            counter += born
            if k:
                return k, counter, len(hashmap)

            if w_dist[idx] > max_tame_distance:
                # create_kangaroo(1, idx, wilds, w_dist, k1, k2, P, R)
                z = v_rnd.get_next()
                d = b // 2 + idx * v + z        # b + i*v + z

                w_dist[idx] = d
                wilds[idx] = Group.add(P, Group.mul(Group.G, d))

                counter += 1

        total_time = time.time() - start_time
        if total_time - last_p_time > 3:
            last_p_time = total_time
            print(f'Ops: {counter} Table size: {len(hashmap)} Speed: {counter / total_time:.0f} ops/s')


def run_puzzle(idx: int, pub_key, dp: int = 0, herd_size: int = 128, benchmark=0):
    # puzzle #X has (X - 1) unknown bits
    k1 = 1 << (idx - 1)
    k2 = (k1 << 1) - 1

    # subtract k1 to search in a [0, k2 - k1) interval
    k2 -= k1
    k1 = 0

    P = Point.uncompress(pub_key)

    # subtract (k2 - k1)G from P to bring target point's k to [0, k2 - k1) interval
    P = Group.add(P, Group.mul(Group.G, -(k2 + 1)))

    now = time.time()
    _, ops, hashmap_size = kangaroo_with_results(k1, k2, P, dp, herd_size)
    total_time = time.time() - now
    print(f'Ops: {ops} Stored: {hashmap_size}')
    print(f'Speed: {ops / total_time:.0f} ops/s')


if __name__ == '__main__':
    # r, p = int(sys.argv[1]), sys.argv[2]
    # run_puzzle(r, p, dp=0, herd_size=128)

    # run_puzzle(32, '0209c58240e50e3ba3f833c82655e8725c037a2294e14cf5d73a5df8d56159de69',
    #            herd_size=512)

    run_puzzle(48, '0291bee5cf4b14c291c650732faa166040e4c18a14731f9a930c1e87d3ec12debb',
               dp=8, herd_size=1024)

Puzzle 48:
Code:
processors: 2048
         num jump distances: 38
max jumps per tame kangaroo: 6899
max jumps per wild kangaroo: 11586
       expected total jumps: 18927375 24.17 bits
     avg real jump distance: 7233629130 32.75 bits
 avg expected jump distance: 6074001000 32.50 bits
 expected max tame distance: 190638869267657 47.44 bits
...
Ops: 17607859 Table size: 68719 Speed: 225400 ops/s
Key: 0x2de6d7ce3b9b
Group ops: 18288933
Ops: 18288933 Stored: 71317
Speed: 222616 ops/s


I have almost the same script with Jacobian coordinates in C++ but using #include <boost/multiprecision/cpp_int.hpp>

It's not a million per second, but it's very close.   Grin
benjaniah
Newbie
*
Offline Offline

Activity: 10
Merit: 0


View Profile
July 23, 2024, 09:22:26 PM
 #5505

In regards to all the RBF issues lately, would it not be more productive to push on the Bitcoin developers themselves to fix it? What's so bad about making no RBF actually mean NO RBF? You know, the first-seen spend transaction with NO-RBF/Opt-out-of-RBF flag is the only transaction that the network accepts and cannot be replaced/modified by any other means? It will either get mined into a block eventually, or in the case the fees are too low, sit in the mempool for an indefinite amount of time. Or does their say not even matter because the mining pools themselves would not adopt such a fix, given that it is actually not in their best interest to do so?
kTimesG
Member
**
Offline Offline

Activity: 104
Merit: 24


View Profile
July 23, 2024, 09:24:35 PM
 #5506

I have almost the same script with Jacobian coordinates in C++ but using #include <boost/multiprecision/cpp_int.hpp>

It's not a million per second, but it's very close.   Grin
Are you sure about that? If my script runs at 225k op/s in shitty Python interpreted code, a native version won't run 4 times faster. It would run 50 times faster. On a single core. I'm too tired to prove this. Using libsecp256k1 instead of GMP or whatever, and doing the same batched addition as in my script (which is the core reason of the performance multiplier) reaches 10 M+ op/s, no questions asked. So on an i9 with 6 performance cores it does 60M op/s, and also the rest of 14 efficiency cores each contribute an additional 8M op/s. So a total of around 170 M op/s. But this is futile, it's just a complete waste of electricity.
nomachine
Member
**
Offline Offline

Activity: 368
Merit: 21


View Profile
July 23, 2024, 09:29:39 PM
 #5507

Are you sure about that?

Nah. There are too many numbers on the screen.   Grin
Akito S. M. Hosana
Newbie
*
Offline Offline

Activity: 33
Merit: 0


View Profile
July 23, 2024, 09:37:19 PM
 #5508

Who's kidding here?  Roll Eyes
I don't have 100 M op/s even with GPU.  Cry
kTimesG
Member
**
Offline Offline

Activity: 104
Merit: 24


View Profile
July 23, 2024, 09:44:00 PM
 #5509

In regards to all the RBF issues lately, would it not be more productive to push on the Bitcoin developers themselves to fix it? What's so bad about making no RBF actually mean NO RBF? You know, the first-seen spend transaction with NO-RBF/Opt-out-of-RBF flag is the only transaction that the network accepts and cannot be replaced/modified by any other means? It will either get mined into a block eventually, or in the case the fees are too low, sit in the mempool for an indefinite amount of time. Or does their say not even matter because the mining pools themselves would not adopt such a fix, given that it is actually not in their best interest to do so?
Fix what? There is nothing broken here, buddy. RBF, no RBF, are irrelevant at the protocol level. If you push a TX to pool A and I push a TX to pool B, the network gives zero f**ks about RBF or no RBF. If I push a TX and change my mind, it is my right to be able to change the destination, and this is what RBF is about. You are asking for adding a feature that forbids such rights, resulting in a disaster.
WanderingPhilospher
Full Member
***
Offline Offline

Activity: 1120
Merit: 225

Shooters Shoot...


View Profile
Today at 06:01:35 AM
Merited by albert0bsd (2)
 #5510

Ok, all of you BOT owners. Get ready for round 2 of RBF test.

I am a newb with ding certain things on the blockchain and what I am trying to do.  I probably shouldn't be doing this, but sometimes, mistakes, are the best things to learn from.

I would like all to participate as they did in the last 66 bit bot test. But def at least the winner, albert0bsd. But I know the more, the better chances to test different strategies or programs/processes, so I would like to get all bot owners on board.

Same setup, key is in the 66 bit range.

Address:

166Bitrbfa16oR7DKKSzgdhU4MpVKE4cKb

It seemed like everyone has an auto bot...meaning all you are doing is putting in the address on some type of watch list, and once your program gets a hit for the address, the bots do their thing to find the key and alter the original transaction.

So if everyone who is going to participate, put in the above address into your bot ASAP. I would like to get a response back from at least albert0bsd that he is entered the address and is ready to proceed.

All I ask, if one of you are successful in diverting the coinage, you PM me and tell me how you did it. That's all. Just a request, not a requirement lol.

I'm not sure I will say the exact time I send funds out of the address, because that is more realistic to 66's transfer, no one is going to let us know they are about to sweep the coins...but that could change.

This may fail, may be successful. We all shall see.

Am I missing any information/anything else to put out there?

Ok, bot owners, let's get ready to rumble. Who is ready? Let's do it.
gygy
Newbie
*
Offline Offline

Activity: 3
Merit: 0


View Profile
Today at 06:25:29 AM
 #5511

In regards to all the RBF issues lately, would it not be more productive to push on the Bitcoin developers themselves to fix it? What's so bad about making no RBF actually mean NO RBF? You know, the first-seen spend transaction with NO-RBF/Opt-out-of-RBF flag is the only transaction that the network accepts and cannot be replaced/modified by any other means? It will either get mined into a block eventually, or in the case the fees are too low, sit in the mempool for an indefinite amount of time. Or does their say not even matter because the mining pools themselves would not adopt such a fix, given that it is actually not in their best interest to do so?

Bitcoin is not broken on it's full strength. The thing that is broken is this puzzle on this restricted range.
It would be wiser if the reward was placed on a regular address and you could calculate the private key of the reward address from the private key of the restricted address with a published deterministic algorithm.
gygy
Newbie
*
Offline Offline

Activity: 3
Merit: 0


View Profile
Today at 06:35:39 AM
 #5512

You can use nomachine's Rust Kangaroo a few posts back, or write a Python script that does the job according to your requirements (e.g. "that actually works").
Too slow? Well, don't expect to find something that "actually works", is fast, and solves 130, sitting out there for you to snug up and inherit 13 BTC tomorrow.

Not in Rust. Pure C++ with GMP. Here is the latest version that goes 470K Hops per second.

Theoretically, with 12 cores, it can achieve 5 million hops per second.
The more cores you have, the better the result will be.
However, it's not worth using this for a puzzle above 70bit. A GPU must be used instead....

Pure self-contained Python Kangaroo with no libraries required. 225K Hops per second.

DO NOT USE THIS TO SEARCH FOR 130. It is just an educational, reference-only example. All the math uses Python integers.

kangaroo.py
Code:
import math, os, sys, time
....

Puzzle 48:
Code:
processors: 2048
         num jump distances: 38
max jumps per tame kangaroo: 6899
max jumps per wild kangaroo: 11586
       expected total jumps: 18927375 24.17 bits
     avg real jump distance: 7233629130 32.75 bits
 avg expected jump distance: 6074001000 32.50 bits
 expected max tame distance: 190638869267657 47.44 bits
...
Ops: 17607859 Table size: 68719 Speed: 225400 ops/s
Key: 0x2de6d7ce3b9b
Group ops: 18288933
Ops: 18288933 Stored: 71317
Speed: 222616 ops/s

You need to add the lower boundary of the original search range to the found key to get the correct answer (because of the range was shifted to start at 0).
nomachine
Member
**
Offline Offline

Activity: 368
Merit: 21


View Profile
Today at 07:16:25 AM
 #5513

This may fail, may be successful. We all shall see.

Am I missing any information/anything else to put out there?

Ok, bot owners, let's get ready to rumble. Who is ready? Let's do it.

 You don't need to do it.  Tongue
WanderingPhilospher
Full Member
***
Offline Offline

Activity: 1120
Merit: 225

Shooters Shoot...


View Profile
Today at 07:21:32 AM
 #5514

This may fail, may be successful. We all shall see.

Am I missing any information/anything else to put out there?

Ok, bot owners, let's get ready to rumble. Who is ready? Let's do it.

 You don't need to do it.  Tongue

You skeered? LOL. Let's just try it. It's already set up.
GR Sasa
Member
**
Offline Offline

Activity: 188
Merit: 14


View Profile
Today at 07:27:09 AM
 #5515



You skeered? LOL. Let's just try it. It's already set up.

Wait at least until we finish work, it's 9:26 am and i am just came into office 20 mins too late and got straight motivated by you, but who cares. Will you move the coins today?
nomachine
Member
**
Offline Offline

Activity: 368
Merit: 21


View Profile
Today at 07:28:06 AM
 #5516

This may fail, may be successful. We all shall see.

Am I missing any information/anything else to put out there?

Ok, bot owners, let's get ready to rumble. Who is ready? Let's do it.

 You don't need to do it.  Tongue

You skeered? LOL. Let's just try it. It's already set up.

I will be banned by  mempool.space  due to DDoS ​​attack LOL.
Feron
Jr. Member
*
Offline Offline

Activity: 53
Merit: 1


View Profile
Today at 07:35:51 AM
 #5517

Child Pays For Parent (CPFP) in Bitcoin what it does in practice
WanderingPhilospher
Full Member
***
Offline Offline

Activity: 1120
Merit: 225

Shooters Shoot...


View Profile
Today at 07:43:42 AM
 #5518



You skeered? LOL. Let's just try it. It's already set up.

Wait at least until we finish work, it's 9:26 am and i am just came into office 20 mins too late and got straight motivated by you, but who cares. Will you move the coins today?

No, no time soon (maybe later today - 16 hours or so, at the earliest), I want the people with bots to have the chance to load it into their bot machine lol. So you got time Sasa!

Quote
I will be banned by  mempool.space  due to DDoS ​​attack LOL.

Nah, your IP had a few days to cool off lol. I know you have tweaked your bot. Mind as well give it a whirl.
Akito S. M. Hosana
Newbie
*
Offline Offline

Activity: 33
Merit: 0


View Profile
Today at 07:44:44 AM
 #5519

This may fail, may be successful. We all shall see.

Am I missing any information/anything else to put out there?

Ok, bot owners, let's get ready to rumble. Who is ready? Let's do it.

 You don't need to do it.  Tongue

You skeered? LOL. Let's just try it. It's already set up.

I will be banned by  mempool.space  due to DDoS ​​attack LOL.

SO, you have a botnet to send transactions ? Grin
nomachine
Member
**
Offline Offline

Activity: 368
Merit: 21


View Profile
Today at 07:50:51 AM
 #5520

This may fail, may be successful. We all shall see.

Am I missing any information/anything else to put out there?

Ok, bot owners, let's get ready to rumble. Who is ready? Let's do it.

 You don't need to do it.  Tongue

You skeered? LOL. Let's just try it. It's already set up.

I will be banned by  mempool.space  due to DDoS ​​attack LOL.

SO, you have a botnet to send transactions ? Grin

Nope.  But it's not a bad idea. The more IP addresses and computers involved the better.
Pages: « 1 ... 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 [276] 277 278 »
  Print  
 
Jump to:  

Powered by MySQL Powered by PHP Powered by SMF 1.1.19 | SMF © 2006-2009, Simple Machines Valid XHTML 1.0! Valid CSS!