Dash Core  0.12.2.1
P2P Digital Currency
bignum.py
Go to the documentation of this file.
1 #
2 #
3 # bignum.py
4 #
5 # This file is copied from python-bitcoinlib.
6 #
7 # Distributed under the MIT/X11 software license, see the accompanying
8 # file COPYING or http://www.opensource.org/licenses/mit-license.php.
9 #
10 
11 """Bignum routines"""
12 
13 from __future__ import absolute_import, division, print_function, unicode_literals
14 
15 import struct
16 
17 
18 # generic big endian MPI format
19 
20 def bn_bytes(v, have_ext=False):
21  ext = 0
22  if have_ext:
23  ext = 1
24  return ((v.bit_length()+7)//8) + ext
25 
26 def bn2bin(v):
27  s = bytearray()
28  i = bn_bytes(v)
29  while i > 0:
30  s.append((v >> ((i-1) * 8)) & 0xff)
31  i -= 1
32  return s
33 
34 def bin2bn(s):
35  l = 0
36  for ch in s:
37  l = (l << 8) | ch
38  return l
39 
40 def bn2mpi(v):
41  have_ext = False
42  if v.bit_length() > 0:
43  have_ext = (v.bit_length() & 0x07) == 0
44 
45  neg = False
46  if v < 0:
47  neg = True
48  v = -v
49 
50  s = struct.pack(b">I", bn_bytes(v, have_ext))
51  ext = bytearray()
52  if have_ext:
53  ext.append(0)
54  v_bin = bn2bin(v)
55  if neg:
56  if have_ext:
57  ext[0] |= 0x80
58  else:
59  v_bin[0] |= 0x80
60  return s + ext + v_bin
61 
62 def mpi2bn(s):
63  if len(s) < 4:
64  return None
65  s_size = bytes(s[:4])
66  v_len = struct.unpack(b">I", s_size)[0]
67  if len(s) != (v_len + 4):
68  return None
69  if v_len == 0:
70  return 0
71 
72  v_str = bytearray(s[4:])
73  neg = False
74  i = v_str[0]
75  if i & 0x80:
76  neg = True
77  i &= ~0x80
78  v_str[0] = i
79 
80  v = bin2bn(v_str)
81 
82  if neg:
83  return -v
84  return v
85 
86 # bitcoin-specific little endian format, with implicit size
87 def mpi2vch(s):
88  r = s[4:] # strip size
89  r = r[::-1] # reverse string, converting BE->LE
90  return r
91 
92 def bn2vch(v):
93  return bytes(mpi2vch(bn2mpi(v)))
94 
95 def vch2mpi(s):
96  r = struct.pack(b">I", len(s)) # size
97  r += s[::-1] # reverse string, converting LE->BE
98  return r
99 
100 def vch2bn(s):
101  return mpi2bn(vch2mpi(s))
102 
def bn_bytes(v, have_ext=False)
Definition: bignum.py:20