Any projects which want to use Hush code from now on will need to be licensed as GPLv3 or we will send the lawyers: https://www.softwarefreedom.org/ Notably, Komodo (KMD) is licensed as GPLv2 and is no longer compatible to receive code changes, without causing legal issues. MIT projects, such as Zcash, also cannot pull in changes from the Hush Full Node without permission from The Hush Developers, which may in some circumstances grant an MIT license on a case-by-case basis.
103 lines
1.9 KiB
Python
103 lines
1.9 KiB
Python
#
|
|
#
|
|
# bignum.py
|
|
#
|
|
# This file is copied from python-bitcoinlib.
|
|
#
|
|
# Distributed under the GPLv3 software license, see the accompanying
|
|
# file COPYING or https://www.gnu.org/licenses/gpl-3.0.en.html
|
|
#
|
|
|
|
"""Bignum routines"""
|
|
|
|
from __future__ import absolute_import, division, print_function, unicode_literals
|
|
|
|
import struct
|
|
|
|
|
|
# generic big endian MPI format
|
|
|
|
def bn_bytes(v, have_ext=False):
|
|
ext = 0
|
|
if have_ext:
|
|
ext = 1
|
|
return ((v.bit_length()+7)//8) + ext
|
|
|
|
def bn2bin(v):
|
|
s = bytearray()
|
|
i = bn_bytes(v)
|
|
while i > 0:
|
|
s.append((v >> ((i-1) * 8)) & 0xff)
|
|
i -= 1
|
|
return s
|
|
|
|
def bin2bn(s):
|
|
l = 0
|
|
for ch in s:
|
|
l = (l << 8) | ch
|
|
return l
|
|
|
|
def bn2mpi(v):
|
|
have_ext = False
|
|
if v.bit_length() > 0:
|
|
have_ext = (v.bit_length() & 0x07) == 0
|
|
|
|
neg = False
|
|
if v < 0:
|
|
neg = True
|
|
v = -v
|
|
|
|
s = struct.pack(b">I", bn_bytes(v, have_ext))
|
|
ext = bytearray()
|
|
if have_ext:
|
|
ext.append(0)
|
|
v_bin = bn2bin(v)
|
|
if neg:
|
|
if have_ext:
|
|
ext[0] |= 0x80
|
|
else:
|
|
v_bin[0] |= 0x80
|
|
return s + ext + v_bin
|
|
|
|
def mpi2bn(s):
|
|
if len(s) < 4:
|
|
return None
|
|
s_size = bytes(s[:4])
|
|
v_len = struct.unpack(b">I", s_size)[0]
|
|
if len(s) != (v_len + 4):
|
|
return None
|
|
if v_len == 0:
|
|
return 0
|
|
|
|
v_str = bytearray(s[4:])
|
|
neg = False
|
|
i = v_str[0]
|
|
if i & 0x80:
|
|
neg = True
|
|
i &= ~0x80
|
|
v_str[0] = i
|
|
|
|
v = bin2bn(v_str)
|
|
|
|
if neg:
|
|
return -v
|
|
return v
|
|
|
|
# bitcoin-specific little endian format, with implicit size
|
|
def mpi2vch(s):
|
|
r = s[4:] # strip size
|
|
r = r[::-1] # reverse string, converting BE->LE
|
|
return r
|
|
|
|
def bn2vch(v):
|
|
return bytes(mpi2vch(bn2mpi(v)))
|
|
|
|
def vch2mpi(s):
|
|
r = struct.pack(b">I", len(s)) # size
|
|
r += s[::-1] # reverse string, converting LE->BE
|
|
return r
|
|
|
|
def vch2bn(s):
|
|
return mpi2bn(vch2mpi(s))
|
|
|