-
Notifications
You must be signed in to change notification settings - Fork 2
/
utils.py
191 lines (152 loc) · 4.94 KB
/
utils.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
from Crypto.Hash import keccak
import sys
import rlp
from rlp.sedes import big_endian_int, BigEndianInt, Binary
from rlp.utils import decode_hex, ascii_chr, str_to_bytes, encode_hex
from py_ecc.secp256k1 import privtopub, ecdsa_raw_sign, ecdsa_raw_recover
import struct
import pickle
from ipaddr import IPv4Network, IPv6Network, IPv4Address, IPv6Address, Bytes
from netaddr import IPNetwork, IPAddress, IPSet
import random
TT256 = 2 ** 256
TT256M1 = 2 ** 256 - 1
TT255 = 2 ** 255
SECP256K1P = 2**256 - 4294968273
def to_string(value):
return str(value)
def is_numeric(x):
return isinstance(x, (int, long))
def is_string(x):
return isinstance(x, (str, unicode))
def encode_int32(v):
return zpad(int_to_big_endian(v), 32)
def encode_int8(v):
return struct.pack('B', v)
def bytes_to_int(data):
return int(data.encode('hex'), 16)
def sha3_256(x):
return keccak.new(digest_bits=256, data=x).digest()
def sha3(seed):
return sha3_256(to_string(seed))
def sha3rlp(x):
return sha3(rlp.encode(x))
def big_endian_to_int(x):
return big_endian_int.deserialize(str_to_bytes(x).lstrip(b'\x00'))
def int_to_big_endian(x):
return big_endian_int.serialize(x)
def int_to_bytes(value):
if isinstance(value, str):
return value
return int_to_big_endian(value)
def remove_0x_head(s):
return s[2:] if s[:2] in (b'0x', '0x') else s
def parse_as_bin(s):
return decode_hex(s[2:] if s[:2] == '0x' else s)
def parse_as_int(s):
return s if is_numeric(s) else int('0' + s[2:], 16) if s[:2] == '0x' else int(s)
def int_to_addr(x):
o = [b''] * 20
for i in range(20):
o[19 - i] = ascii_chr(x & 0xff)
x >>= 8
return b''.join(o)
def normalize_address(x, allow_blank=False):
if is_numeric(x):
return int_to_addr(x)
if allow_blank and x in {'', b''}:
return b''
if len(x) in (42, 50) and x[:2] in {'0x', b'0x'}:
x = x[2:]
if len(x) in (40, 48):
x = decode_hex(x)
if len(x) == 24:
assert len(x) == 24 and sha3(x[:20])[:4] == x[-4:]
x = x[:20]
if len(x) != 20:
raise Exception("Invalid address format: %r" % x)
return x
def encode_int(v):
"""encodes an integer into serialization"""
if not is_numeric(v) or v < 0 or v >= TT256:
raise Exception("Integer invalid or out of range: %r" % v)
return int_to_big_endian(v)
def zpad(x, l):
""" Left zero pad value `x` at least to length `l`.
>>> zpad('', 1)
'\x00'
>>> zpad('\xca\xfe', 4)
'\x00\x00\xca\xfe'
>>> zpad('\xff', 1)
'\xff'
>>> zpad('\xca\xfe', 2)
'\xca\xfe'
"""
return b'\x00' * max(0, l - len(x)) + x
def privtoaddr(k):
k = normalize_key(k)
x, y = privtopub(k)
return sha3(encode_int32(x) + encode_int32(y))[12:]
def normalize_key(key):
if is_numeric(key):
o = encode_int32(key)
elif len(key) == 32:
o = key
elif len(key) == 64:
o = decode_hex(key)
elif len(key) == 66 and key[:2] == '0x':
o = decode_hex(key[2:])
else:
raise Exception("Invalid key format: %r" % key)
if o == b'\x00' * 32:
raise Exception("Zero privkey invalid")
return o
def ecrecover_to_pub(rawhash, v, r, s):
result = ecdsa_raw_recover(rawhash, (v,r,s))
if result:
x, y = result
pub = encode_int32(x) + encode_int32(y)
else:
raise ValueError('Invalid VRS')
assert len(pub) == 64
return pub
def ecsign(rawhash, key):
v, r, s = ecdsa_raw_sign(rawhash, key)
return v, r, s
def random_privkey():
key = hex(random.SystemRandom().getrandbits(256))
key = key[2:-1].zfill(64)
return key.decode('hex')
def pubkey_to_address(pubkey):
return sha3_256(pubkey)[-20:]
def object_to_bin(o):
return pickle.dumps(o,pickle.HIGHEST_PROTOCOL).encode('hex')
def bin_to_object(b):
return pickle.loads(b.decode('hex'))
def ipaddr_to_netaddr(afi,ipaddr):
if afi == 1:
ip = IPv4Address(Bytes(ipaddr))
elif afi == 2:
ip = IPv6Address(Bytes(ipaddr))
return IPNetwork(str(ip))
def compress_random_no_to_int(input_string, output_int_lenght):
input_str = remove_0x_head(input_string)
ngroups = len(input_str) / output_int_lenght
number = 0x0
for i in range(ngroups):
number = number ^ int(input_str[i*output_int_lenght : (i + 1)*output_int_lenght],output_int_lenght)
return number
address = Binary.fixed_length(20, allow_empty=True)
int20 = BigEndianInt(20)
int32 = BigEndianInt(32)
int256 = BigEndianInt(256)
hash32 = Binary.fixed_length(32)
trie_root = Binary.fixed_length(32, allow_empty=True)
null_address = b'\xff' * 20
#For DKG
#Binary means bytes!! Means 32 bytes = 256 bits
#When encoding hex strings, binary lenght is half of the hex number of chars
share = Binary.fixed_length(32, allow_empty=True)
#dkg_contrib = Binary.fixed_length(268, allow_empty=True)
group_pubkey = Binary.fixed_length(128, allow_empty=True)
group_sig = Binary.fixed_length(64, allow_empty=True)