Post
Topic
Board Development & Technical Discussion
Re: Pollard's kangaroo ECDLP solver
by
wedom
on 20/10/2021, 13:47:53 UTC
Does anybody has this script, its gone.
...

I found the code of a script for browsing workfiles, which the author has now removed. (I hope he does not mind)

kangaroo-tool.py

Code:
#!/usr/bin/env python3
# -*- coding: utf-8 -*-

import sys, os
if sys.version_info.major<3:
    print("Python3 required")
    sys.exit(0)

import argparse
from struct import unpack
from binascii import hexlify,unhexlify
from math import log2

HEADW = 0xFA6A8001  # Full work file
HEADK = 0xFA6A8002  # Kangaroo only file

HASH_SIZE = 2**18

TAME=False
WILD=True




def bytes_to_num(b):
    return int(hexlify(b), 16)

def GetTimeStr(dTime):
  tmp = ''
  nbDay = dTime / 86400.0
  if nbDay >= 1:
    nbYear = nbDay / 365.0
    if nbYear > 1:
      if nbYear < 5:
        tmp += "%.1fy" % (nbYear)
      else:
        tmp += "%gy" % (nbYear)
    else:
      tmp += "%.1fd" % (nbDay)

  else:

    iTime = dTime
    nbHour = ((iTime % 86400) / 3600)
    nbMin = (((iTime % 86400) % 3600) / 60)
    nbSec = (iTime % 60)

    if nbHour == 0:
      if nbMin == 0:
        tmp += "%02ds" % (nbSec)
      else:
        tmp += "%02d:%02d" % (nbMin, nbSec)
    else:
      tmp += "%02d:%02d:%02d" % (nbHour, nbMin, nbSec)

  return tmp


def checkhead(wf):
    head = unpack('I', wf.read(4))[0]
    if head==HEADW:
        return head
    else:
        print('HEADER ERROR %08x %08x' % (head, HEADW))
        return False

def workinfo(workfile):

  wf = open(workfile, 'rb')
  head = checkhead(wf)
  if not head:
    print('Invalid WorkFile Header')
    return
  version = unpack('I', wf.read(4))[0]
  dp1 = unpack('I', wf.read(4))[0]
  RangeStart = bytes(wf.read(32))[::-1]
  RangeEnd = bytes(wf.read(32))[::-1]
  x = bytes(wf.read(32))[::-1]
  y = bytes(wf.read(32))[::-1]
  count = unpack('Q', wf.read(8))[0]
  time = unpack('d', wf.read(8))[0]

  print('Header   : %08x' % head)
  print('Version  : %d' % version)
  print('DP Bits  : %08x' % dp1)
  print('Start    : %x' % bytes_to_num(RangeStart))
  print('Stop     : %x' % bytes_to_num(RangeEnd))
  print('PubKey X : %s' % hexlify(x).decode())
  print('PubKey Y : %s' % hexlify(y).decode())

  if count>0:
    print('Count    : %d 2^%.3f' % (count, log2(count)))
  else:
    print('Count    : %d' % (count))

  print('Time     : %s' % GetTimeStr(time))

  wf.close()


def workexport(workfile):

    wf = open(workfile, 'rb')
    head = checkhead(wf)
    if not head:
      print('Invalid WorkFile Header')
      return
    wf.seek(156,0) # Skip WorkFile header

    tameFile = open('tame.txt','a')
    wildFile = open('wild.txt','a')

    for h in range(HASH_SIZE):
      nbItem = unpack('I', wf.read(4))[0]
      maxItem = unpack('I', wf.read(4))[0]
      for i in range(nbItem):
        x = bytes(wf.read(16))[::-1]
        d = bytes(wf.read(16))[::-1]

        sign = (bytes_to_num(d) & 0x80000000000000000000000000000000)>0
        htype = (bytes_to_num(d) & 0x40000000000000000000000000000000)>0

        if htype==TAME:
          tameFile.write('%05x%032x ' % (h, bytes_to_num(x)))
          tameFile.write('%032x\n' % (bytes_to_num(d) & 0x3fffffffffffffffffffffffffffffff))
        else:
          wildFile.write('%05x%032x ' % (h, bytes_to_num(x)))
          if sign:
            wildFile.write('-')
          wildFile.write('%032x\n' % (bytes_to_num(d) & 0x3fffffffffffffffffffffffffffffff))

        if args.verbose:
          sys.stdout.write('%s' % ('Tame' if htype==TAME else 'Wild'))
          sys.stdout.write(' %05x%032x ' % (h, bytes_to_num(x)))
          if sign:
            sys.stdout.write('-')
          sys.stdout.write('%032x\n' % (bytes_to_num(d) & 0x3fffffffffffffffffffffffffffffff))


if __name__ == '__main__':
    parser = argparse.ArgumentParser()
    parser.add_argument('-f', dest='workfile', type=str, required=True, help='WorkFile path')
    parser.add_argument('--winfo', dest='winfo', action='store_true', help='Show workfile info')
    parser.add_argument('--wexport', dest='wexport', action='store_true', help='Export workfile into tame.txt and wild.txt')
    parser.add_argument('-v', dest='verbose', action='store_true', help='Verbose')
    args = parser.parse_args()

    if args.workfile:
        print("[+] Workfile %s" % args.workfile)

    if args.winfo:
        workinfo(args.workfile)

    if args.wexport:
        workexport(args.workfile)