There you will find both the source code and the compiled versions for Windows.
Based on original v1.7 JLP Kangaroo
OT version needed to accumulate tame kangaroos.
OW is only produced wild kangaroos and is needed to find the public key.
Also you need a program that will make changes (public key, range) to the working file with DPs.
P.s. Here is a script that changes the public key and range in the working file.
from math import log2
import os
HEADW = 0xFA6A8001 # work file
HEADERSIZE=156
def bytes_to_num(byte_data):
return int.from_bytes(byte_data, byteorder='little')
def checkhead(wf):
head = bytes_to_num(wf.read(4))
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 False
version = bytes_to_num(bytes(wf.read(4)))
dp1 = bytes_to_num(bytes(wf.read(4)))
RangeStart = bytes_to_num(bytes(wf.read(32)))
RangeEnd = bytes_to_num(bytes(wf.read(32)))
x = bytes_to_num(bytes(wf.read(32)))
y = bytes_to_num(bytes(wf.read(32)))
count = bytes_to_num(bytes(wf.read(8)))
time = bytes_to_num(bytes(wf.read(8)))
print(
f'Header : {head:08x}'
f'\nVersion : {version:d}'
f'\nDP Bits : {dp1}'
f'\nStart : {RangeStart:032x}'
f'\nStop : {RangeEnd:032x}'
f'\nPubKey X : {x:032x}'
f'\nPubKey Y : {y:032x}'
f'\nCount : 2^{log2(count):.3f}'
)
wf.close()
return True
def getuncompressedpub(compressed_key):
p=2**256 - 2**32 - 977
y_parity = int(compressed_key[:2],16) - 2
if y_parity>1:
x = int(compressed_key[2:66], 16)
y = int(compressed_key[66:130], 16)
return (x,y)
x = int(compressed_key[2:], 16)
a = (pow(x, 3, p) + 7) % p
y = pow(a, (p+1)//4, p)
if y % 2 != y_parity:
y = -y % p
return (x,y)
def MakeChanges(workfile, NewPubCompressed, NewRB, NewRE):
if os.path.exists(f'{workfile}'):
print('Old header:')
if workinfo(workfile):
#make some changes
(x,y)= getuncompressedpub(NewPubCompressed)
with open(workfile, 'r+b') as wf:
try:
wf.seek(12)
wf.write(NewRB.to_bytes(32, byteorder='little'))
wf.write(NewRE.to_bytes(32, byteorder='little'))
wf.write(x.to_bytes(32, byteorder='little'))
wf.write(y.to_bytes(32, byteorder='little'))
except Exception as e:
print(f'File error {e}')
print('New header:')
workinfo(workfile)
else:
print(f'File {workfile} is not exist')
return
if __name__ == '__main__':
parser = argparse.ArgumentParser()
parser.add_argument('-f', dest='workfile', type=str, required=True, help='WorkFile path')
parser.add_argument('-pub', dest='pub', required=True, type=str, help='Compressed public key')
parser.add_argument('-rb', dest='rb', required=True, type=str, help='Begin range')
parser.add_argument('-re', dest='re', required=True, type=str, help='End range')
args = parser.parse_args()
if args.workfile:
print(f'Workfile {args.workfile}')
MakeChanges(args.workfile, args.pub, int(args.rb,16), int(args.re,16))