def test_ecrecover(rounds=100): st = time.time() for i in range(rounds): p = ecdsa_raw_recover(msg, vrs) elapsed = time.time() - st print 'py took: %.2fsecs / %dμs per op / %d recoveries per sec' % \ (elapsed, elapsed / rounds * 10**6, rounds / elapsed)
def sign_btc(msghash, priv, pub): V, R, S = bitcoin.ecdsa_raw_sign(msghash, priv) assert bitcoin.ecdsa_raw_verify(msghash, (V, R, S), pub) Q = bitcoin.ecdsa_raw_recover(msghash, (V, R, S)) assert addr == bitcoin.encode_pubkey( Q, 'hex_compressed') if V >= 31 else bitcoin.encode_pubkey(Q, 'hex') return (V, R, S)
def verify_signature(addr, h, xxx_todo_changeme): (V, R, S) = xxx_todo_changeme pub = bitcoin.ecdsa_raw_recover(h, (V, R, S)) pub = bitcoin.encode_pubkey(pub, 'bin') addr_ = utils.sha3(pub[1:])[12:] assert addr_ == addr return True
def __init__(self, nonce, gasprice, startgas, to, value, data, v=0, r=0, s=0): self.nonce = nonce self.gasprice = gasprice self.startgas = startgas self.to = to self.value = value self.data = data self.v, self.r, self.s = v, r, s # Determine sender if self.r and self.s: rawhash = utils.sha3(self.serialize(False)) pub = encode_pubkey( ecdsa_raw_recover(rawhash, (self.v, self.r, self.s)), 'bin') self.sender = utils.sha3(pub[1:])[-20:].encode('hex') # does not include signature else: self.sender = 0
def verify_signature(addr, h, V_R_S): V, R, S = V_R_S pub = bitcoin.ecdsa_raw_recover(h, (V, R, S)) pub = bitcoin.encode_pubkey(pub, 'bin') addr_ = utils.sha3(pub[1:])[12:] assert addr_ == addr return True
def ecdsa_recover(message, signature): assert len(signature) == 65 pub = bitcoin.ecdsa_raw_recover(message, _decode_sig(signature)) assert pub, 'pubkey could not be recovered' pub = bitcoin.encode_pubkey(pub, 'bin_electrum') assert len(pub) == 64 return pub
def ecdsa_recover(message, signature): assert len(signature) == 65 pub = bitcoin.ecdsa_raw_recover(message, _decode_sig(signature)) assert pub, "pubkey could not be recovered" pub = bitcoin.encode_pubkey(pub, "bin_electrum") assert len(pub) == 64 return pub
def recoverPub(msg, signature): hashedmessage = sha3.keccak_256(msg.encode('utf-8')).hexdigest() x, y = bitcoin.ecdsa_raw_recover(hashedmessage.decode('hex'), _decode_sig(signature.decode('hex'))) pub = str(hex(x))[2:-1].zfill(64) + str(hex(y))[2:-1].zfill(64) print pub return pub
def verify_dc_sig(self, sig, msghash, msgsize, from_addr, data): # data comes in as array of byte array (bytes as ints, from js) tohash = byte_arrays_to_string(data) assert (msghash == utils.sha3(tohash)) X, Y = ecdsa_raw_recover(msghash, sig) pX = utils.int_to_big_endian(X).encode('hex') pY = utils.int_to_big_endian(Y).encode('hex') pub = '04' + pX + pY return ecdsa_raw_verify(msghash, sig, pub.decode('hex'))
def verify_dc_sig(self, sig, msghash, msgsize, from_addr, data): # data comes in as array of byte array (bytes as ints, from js) tohash = byte_arrays_to_string(data) assert (msghash == utils.sha3(tohash)) X, Y = ecdsa_raw_recover(msghash, sig) pX = utils.int_to_big_endian(X).encode('hex') pY = utils.int_to_big_endian(Y).encode('hex') pub = '04'+pX+pY return ecdsa_raw_verify(msghash, sig, pub.decode('hex'))
def ecdsa_verify_addr(msg, sig, addr): isTestnet = addr[0] not in P2PKH_PREFIXES if not checkPivxAddr(addr, isTestnet): return False v, r, s = decode_sig(sig) Q = ecdsa_raw_recover(electrum_sig_hash(msg), (v, r, s)) Qenc = encode_pubkey(Q, 'hex_compressed') if v >= 31 else encode_pubkey( Q, 'hex') return pubkey_to_address(Qenc, isTestnet) == addr
def test_recover(): msg = 'test' mhash = hashlib.sha256(msg.encode()).digest() priv = ecdsa.random_privkey() pub = ecdsa.pubkey(priv) sig = ecdsa.sign(priv, msg) assert ecdsa.verify(pub, sig, msg) res = ecdsa.recover_via_msg(sig, msg) vrs = sig[0].value, sig[1].value, sig[2].value ans = bitcoin.ecdsa_raw_recover(mhash, vrs) assert (pub.value[0].value, pub.value[1].value) == ans assert pub == res
def validate(token): """ Validate a given token. Returns an object if valid or None """ try: parts = token.split('.') sig = json.loads(decode64(parts[1])) vrs = (sig['v'], from_hex(sig['r']), from_hex(sig['s'])) q = ecdsa_raw_recover(sha256(parts[0]), vrs) return { 'id': pubToEtherAddress(q), 'payload': json.loads(decode64(parts[0])) } except Exception as e: return None
def recover(cls, message, vrs): """ Args: message (string): message vrs (tuple): tuple of v, r, s (r, s in hex) """ # Convert r, s from hex to int. rd = int(vrs[1], 16) sd = int(vrs[2], 16) # Get raw recover of public key. pub_key_raw = bitcoin.ecdsa_raw_recover(message, (vrs[0], rd, sd)) return bitcoin.encode_pubkey(pub_key_raw, 'hex_electrum')
def check_sign(cls, message, signature): prefix = '\x19Ethereum Signed Message:\n32' message_hash = cls.sha3(text=message) full_message = cls.bytes_to_hex(prefix) + message_hash full_hash = cls.sha3(hexstr=full_message) r = int(signature[0:66], 16) s = int('0x' + signature[66:130], 16) v = int('0x' + signature[130:132], 16) if not v == 27 and not v == 28: v += 27 recovered = bitcoin.ecdsa_raw_recover(full_hash, (v, r, s)) pub = bitcoin.encode_pubkey(recovered, 'bin') address = cls.sha3(hexstr=pub[1:].hex())[24:64] return '0x' + address
def spend(self, owner): assert isinstance(owner, (str, bytes)) assert len(owner) == 20 # Sign it, so it can be accepted by an address messageHash = utils.sha3(owner + self._pubkey) V, R, S = b.ecdsa_raw_sign(messageHash, self._seckey) recoveredPublicKey = b.ecdsa_raw_recover(messageHash, (V, R, S)) assert b.pubtoaddr(recoveredPublicKey) == b.privtoaddr(self._seckey) # Correctly encoded return ", ".join([ "\"0x%s\"" % (hexlify(self._pubkey), ), "%d" % (V, ), "\"0x%064X\"" % (R, ), "\"0x%064X\"" % (S, ), ])
def proc_ecrecover(ext, msg): print 'ecrecover proc', msg.gas OP_GAS = 500 gas_cost = OP_GAS if msg.gas < gas_cost: return 0, 0, [] b = [0] * 32 msg.data.extract_copy(b, 0, 0, 32) h = ''.join([chr(x) for x in b]) v = msg.data.extract32(32) r = msg.data.extract32(64) s = msg.data.extract32(96) if r >= bitcoin.N or s >= bitcoin.P or v < 27 or v > 28: return 1, msg.gas - 500, [0] * 32 pub = bitcoin.encode_pubkey(bitcoin.ecdsa_raw_recover(h, (v, r, s)), 'bin') o = [0] * 12 + [ord(x) for x in utils.sha3(pub[1:])[-20:]] return 1, msg.gas - gas_cost, o
def check_sign(self, message, signature): prefix = '\x19Ethereum Signed Message:\n32' msghash = self.sha3(text=message) full_message = self.bytes_to_hex(prefix) + msghash full_hash = self.sha3(hexstr=full_message) r = int(signature[0:66], 16) s = int('0x' + signature[66:130], 16) v = int('0x' + signature[130:132], 16) if not v == 27 and not v == 28: v += 27 recovered_addr = b.ecdsa_raw_recover(full_hash, (v, r, s)) pub = b.encode_pubkey(recovered_addr, 'bin') # address = binascii.hexlify(utils.sha3(pub[1:]))[24:64] address = self.sha3(hexstr=pub[1:].hex())[24:64] return '0x' + address
def recover(cls, message, vrs): """ Args: message (string): message vrs (tuple): tuple of v, r, s (r, s in hex) """ # Convert r, s from hex to int. rd = int(vrs[1], 16) sd = int(vrs[2], 16) # Get raw recover of public key. pub_key_raw = bitcoin.ecdsa_raw_recover(message, (vrs[0], rd, sd)) # Get x, y of public key and remove 0x from beginning. x = hex(pub_key_raw[0]).replace('0x', '') y = hex(pub_key_raw[1]).replace('0x', '') return x + y
def parse(cls, data): if re.match('^[0-9a-fA-F]*$', data): data = data.decode('hex') o = rlp.decode(data) tx = cls(decode_int(o[0]), decode_int(o[1]), decode_int(o[2]), decode_int(o[3]), o[4].encode('hex'), o[5], decode_int(o[6]), decode_int(o[7]), decode_int(o[8])) rawhash = sha3(rlp.encode(tx.serialize(False))) pub = encode_pubkey( ecdsa_raw_recover(rawhash, (tx.v, tx.r, tx.s)), 'bin') tx.sender = sha3(pub[1:])[-20:].encode('hex') return tx
def check_signature(req): signature = "0x" + req.sign contract = "0x" + req.contract client = req.client dest = req.dest t = req.t.secs end = req.end.secs if client in dictc: if not (dictc[client] < t.req.secs): return False dictc[client] = t.req.secs msg = contract + client + dest + str(t) + str(end) web3 = Web3(RPCProvider(host="127.0.0.1", port="8545")) web3.config.defaultAccount = '0xa28779d29c49fd57d0fc4130e5ebec07c2c79ef5' abi = '[{"constant":false,"inputs":[],"name":"kill","outputs":[],"type":"function"},{"constant":true,"inputs":[],"name":"owns","outputs":[{"name":"","type":"address"}],"type":"function"},{"constant":true,"inputs":[],"name":"greet","outputs":[{"name":"","type":"string"}],"type":"function"},{"inputs":[{"name":"_greeting","type":"string"}],"type":"constructor"}]' contracto = web3.eth.contract(abi) inst = contracto.at('0xbc8c629cd7477fd580b8f9e8da49e5aad364b769') if (int(t) > int(rospy.get_rostime().secs)): diff = t - int(rospy.get_rostime().secs) else: diff = int(rospy.get_rostime().secs) - t if (diff > 600): return False print "msg: " + msg + " sign: " + signature + " contract: " + contract hash_msg = utils.sha3(msg).encode('hex') r = long(signature[0:66], 16) s = long('0x' + signature[66:130], 16) v = long('0x' + signature[130:132], 16) if not (v == 27 and v == 28): v += 27 address_from_hash = bitcoin.ecdsa_raw_recover(hash_msg.decode('hex'), (v, r, s)) public_key = bitcoin.encode_pubkey(address_from_hash, 'bin') if ('0x' + utils.sha3(public_key[1:]).encode('hex')[24:64] == inst.owns()): return True else: return False
def check_signature(req): signature = "0x" + req.sign contract = "0x" + req.contract client = req.client dest = req.dest t = req.t.secs end = req.end.secs if client in dictc: if not (dictc[client] < t.req.secs): return False dictc[client] = t.req.secs msg = contract + client + dest + str(t) + str(end) web3 = Web3(RPCProvider(host="127.0.0.1", port="8545")) web3.config.defaultAccount = '0xa28779d29c49fd57d0fc4130e5ebec07c2c79ef5' abi = '[{"constant":false,"inputs":[],"name":"kill","outputs":[],"type":"function"},{"constant":true,"inputs":[],"name":"owns","outputs":[{"name":"","type":"address"}],"type":"function"},{"constant":true,"inputs":[],"name":"greet","outputs":[{"name":"","type":"string"}],"type":"function"},{"inputs":[{"name":"_greeting","type":"string"}],"type":"constructor"}]' contracto = web3.eth.contract(abi) inst = contracto.at('0xbc8c629cd7477fd580b8f9e8da49e5aad364b769') if (int(t) > int(rospy.get_rostime().secs)): diff = t - int(rospy.get_rostime().secs) else: diff = int(rospy.get_rostime().secs) - t if (diff > 600): return False print "msg: " + msg + " sign: " + signature + " contract: " + contract hash_msg = utils.sha3(msg).encode('hex') r = long(signature[0:66], 16) s = long('0x' + signature[66:130], 16) v = long('0x' + signature[130:132], 16) if not (v == 27 and v == 28): v += 27 address_from_hash = bitcoin.ecdsa_raw_recover( hash_msg.decode('hex'), (v, r, s)) public_key = bitcoin.encode_pubkey(address_from_hash, 'bin') if ('0x' + utils.sha3(public_key[1:]).encode('hex')[24:64] == inst.owns()): return True else: return False
def proc_ecrecover(ext, msg): # print('ecrecover proc', msg.gas) OP_GAS = opcodes.GECRECOVER gas_cost = OP_GAS if msg.gas < gas_cost: return 0, 0, [] b = [0] * 32 msg.data.extract_copy(b, 0, 0, 32) h = b''.join([ascii_chr(x) for x in b]) v = msg.data.extract32(32) r = msg.data.extract32(64) s = msg.data.extract32(96) if r >= bitcoin.N or s >= bitcoin.P or v < 27 or v > 28: return 1, msg.gas - opcodes.GECRECOVER, [0] * 32 recovered_addr = bitcoin.ecdsa_raw_recover(h, (v, r, s)) if recovered_addr in (False, (0, 0)): return 1, msg.gas - gas_cost, [] pub = bitcoin.encode_pubkey(recovered_addr, 'bin') o = [0] * 12 + [safe_ord(x) for x in utils.sha3(pub[1:])[-20:]] return 1, msg.gas - gas_cost, o
def __init__(*args): self = args[0] if len(args) == 2: self.parse(args[1]) else: self.nonce = args[1] self.value = args[2] self.gasprice = args[3] self.startgas = args[4] self.to = utils.coerce_addr_to_bin(args[5]) self.data = args[6] # includes signature if len(args) > 7: self.v, self.r, self.s = args[7:10] if self.r > 0 and self.s > 0: rawhash = sha3(rlp.encode(self.serialize(False))) pub = encode_pubkey( ecdsa_raw_recover(rawhash, (self.v, self.r, self.s)), 'bin') self.sender = sha3(pub[1:])[-20:].encode('hex') # does not include signature else: self.v, self.r, self.s = 0,0,0 self.sender = 0
def __init__(*args): self = args[0] if len(args) == 2: self.parse(args[1]) else: self.nonce = args[1] self.value = args[2] self.gasprice = args[3] self.startgas = args[4] self.to = utils.coerce_addr_to_bin(args[5]) self.data = args[6] # includes signature if len(args) > 7: self.v, self.r, self.s = args[7:10] if self.r > 0 and self.s > 0: rawhash = sha3(rlp.encode(self.serialize(False))) pub = encode_pubkey( ecdsa_raw_recover(rawhash, (self.v, self.r, self.s)), 'bin') self.sender = sha3(pub[1:])[-20:].encode('hex') # does not include signature else: self.v, self.r, self.s = 0, 0, 0 self.sender = 0
def ecrecover_to_pub(rawhash, v, r, s): if secp256k1: # Legendre symbol check; the secp256k1 library does not seem to do this pk = secp256k1.PublicKey(flags=secp256k1.ALL_FLAGS) xc = r * r * r + 7 assert pow(xc, (SECP256K1P - 1) // 2, SECP256K1P) == 1 try: pk.public_key = pk.ecdsa_recover( rawhash, pk.ecdsa_recoverable_deserialize( zpad(bytearray_to_bytestr(int_to_32bytearray(r)), 32) + zpad(bytearray_to_bytestr(int_to_32bytearray(s)), 32), v - 27 ), raw=True ) pub = pk.serialize(compressed=False)[1:] except: pub = b"\x00" * 64 else: recovered_addr = ecdsa_raw_recover(rawhash, (v, r, s)) pub = encode_pubkey(recovered_addr, 'bin_electrum') assert len(pub) == 64 return pub
def test_ecrecover(rounds = 100): st = time.time() rounds = 100 for i in range(rounds): p = ecdsa_raw_recover(msg, vrs) print 'py took', (time.time() - st)
def int_to_bytes(x): # pyethereum int to bytes does not handle negative numbers assert -(1<<255) <= x < (1<<255) return utils.int_to_bytes((1<<256) + x if x < 0 else x) def broadcast(p, r, h, sig): print 'player[%d]'%p.i, 'broadcasts', r, h.encode('hex'), sig def sign(h, priv): assert len(h) == 32 V, R, S = bitcoin.ecdsa_raw_sign(h, priv) return V,R,S def verify_signature(addr, h, (V,R,S)): pub = bitcoin.ecdsa_raw_recover(h, (V,R,S)) pub = bitcoin.encode_pubkey(pub, 'bin') addr_ = utils.sha3(pub[1:])[12:] assert addr_ == addr return True def getstatus(): depositsL = contract.deposits(0) depositsR = contract.deposits(1) creditsL = contract.credits(0) creditsR = contract.credits(1) wdrawL = contract.withdrawals(0) wdrawR = contract.withdrawals(1) print 'Status:', ['OK','PENDING'][contract.status()] print '[L] deposits:', depositsL, 'credits:', creditsL, 'withdrawals:', wdrawL print '[R] deposits:', depositsR, 'credits:', creditsR, 'withdrawals:', wdrawR
def verify_signature(addr, h, sig): pub = bitcoin.ecdsa_raw_recover(h, sig) # sig=V,R,S pub = bitcoin.encode_pubkey(pub, 'bin') addr_ = utils.sha3(pub[1:])[12:] assert addr_ == addr return True
def recover(messageHash, r, sv): return pubkey_to_ethaddr( b.ecdsa_raw_recover(messageHash, unpack_signature(r, sv)))
def test_ecrecover(rounds=100): st = time.time() rounds = 100 for i in range(rounds): p = ecdsa_raw_recover(msg, vrs) print 'py took', (time.time() - st)
random.seed(12312421412) from bitcoin import privtopub, encode_pubkey, ecdsa_raw_sign, ecdsa_raw_recover import time # import pyximport # pyximport.install() #from ecrecover import ecdsa_sign, ecdsa_verify, ecdsa_recover, test_big from ecdsa_recover import ecdsa_raw_recover as c_ecdsa_raw_recover from ecdsa_recover import ecdsa_raw_sign as c_ecdsa_raw_sign priv = ''.join(chr(random.randint(0, 255)) for i in range(32)) pub = privtopub(priv) msg = ''.join(chr(random.randint(0, 255)) for i in range(32)) vrs = ecdsa_raw_sign(msg, priv) assert vrs == c_ecdsa_raw_sign(msg, priv) p = ecdsa_raw_recover(msg, vrs) p2 = c_ecdsa_raw_recover(msg, vrs) assert p == p2 assert encode_pubkey(p, 'bin') == pub def test_ecrecover(rounds=100): st = time.time() rounds = 100 for i in range(rounds): p = ecdsa_raw_recover(msg, vrs) print 'py took', (time.time() - st) def test_cecrecover(rounds=100): st = time.time()
def verify_signature(addr, h, v_r_s): pub = bitcoin.ecdsa_raw_recover(h, v_r_s) pub = bitcoin.encode_pubkey(pub, 'bin') addr_ = keccak(pub[1:])[12:] return addr_.lower() == addr.lower()
def apply_op(block, tx, msg, code, compustate): op, in_args, out_args = get_op_data(code, compustate.pc) # empty stack error if in_args > len(compustate.stack): return [] # out of gas error fee = calcfee(block, tx, msg, compustate, op) if fee > compustate.gas: if debug: print("Out of gas", compustate.gas, "need", fee) print(op, list(reversed(compustate.stack))) return OUT_OF_GAS stackargs = [] for i in range(in_args): stackargs.append(compustate.stack.pop()) if debug: import serpent if op[:4] == 'PUSH': start, n = compustate.pc + 1, int(op[4:]) print(op, utils.big_endian_to_int(code[start:start + n])) else: print(op, ' '.join(map(str, stackargs)), serpent.decode_datalist(compustate.memory)) # Apply operation oldgas = compustate.gas oldpc = compustate.pc compustate.gas -= fee compustate.pc += 1 stk = compustate.stack mem = compustate.memory if op == 'STOP': return [] elif op == 'ADD': stk.append((stackargs[0] + stackargs[1]) % 2 ** 256) elif op == 'SUB': stk.append((stackargs[0] - stackargs[1]) % 2 ** 256) elif op == 'MUL': stk.append((stackargs[0] * stackargs[1]) % 2 ** 256) elif op == 'DIV': if stackargs[1] == 0: return [] stk.append(stackargs[0] / stackargs[1]) elif op == 'MOD': if stackargs[1] == 0: return [] stk.append(stackargs[0] % stackargs[1]) elif op == 'SDIV': if stackargs[1] == 0: return [] if stackargs[0] >= 2 ** 255: stackargs[0] -= 2 ** 256 if stackargs[1] >= 2 ** 255: stackargs[1] -= 2 ** 256 stk.append((stackargs[0] / stackargs[1]) % 2 ** 256) elif op == 'SMOD': if stackargs[1] == 0: return [] if stackargs[0] >= 2 ** 255: stackargs[0] -= 2 ** 256 if stackargs[1] >= 2 ** 255: stackargs[1] -= 2 ** 256 stk.append((stackargs[0] % stackargs[1]) % 2 ** 256) elif op == 'EXP': stk.append(pow(stackargs[0], stackargs[1], 2 ** 256)) elif op == 'NEG': stk.append(2 ** 256 - stackargs[0]) elif op == 'LT': stk.append(1 if stackargs[0] < stackargs[1] else 0) elif op == 'GT': stk.append(1 if stackargs[0] > stackargs[1] else 0) elif op == 'SLT': if stackargs[0] >= 2 ** 255: stackargs[0] -= 2 ** 256 if stackargs[1] >= 2 ** 255: stackargs[1] -= 2 ** 256 stk.append(1 if stackargs[0] < stackargs[1] else 0) elif op == 'SGT': if stackargs[0] >= 2 ** 255: stackargs[0] -= 2 ** 256 if stackargs[1] >= 2 ** 255: stackargs[1] -= 2 ** 256 stk.append(1 if stackargs[0] > stackargs[1] else 0) elif op == 'EQ': stk.append(1 if stackargs[0] == stackargs[1] else 0) elif op == 'NOT': stk.append(0 if stackargs[0] else 1) elif op == 'AND': stk.append(stackargs[0] & stackargs[1]) elif op == 'OR': stk.append(stackargs[0] | stackargs[1]) elif op == 'XOR': stk.append(stackargs[0] ^ stackargs[1]) elif op == 'BYTE': if stackargs[0] >= 32: stk.append(0) else: stk.append((stackargs[1] / 256 ** stackargs[0]) % 256) elif op == 'SHA3': if len(mem) < ceil32(stackargs[0] + stackargs[1]): mem.extend([0] * (ceil32(stackargs[0] + stackargs[1]) - len(mem))) data = ''.join(map(chr, mem[stackargs[0]:stackargs[0] + stackargs[1]])) print 'data time!' print data print data.encode('hex') stk.append(int(utils.sha3(data).encode('hex'), 16)) elif op == 'ECVERIFY': # parameters: msg_hash (32), v (32), r (32), s (32), pubX (32), pubY (32) # stack should have all args msg_hash, v, r, s, pubX, pubY = stackargs pubX = utils.int_to_big_endian(pubX).encode('hex') pubY = utils.int_to_big_endian(pubY).encode('hex') msg_hash = utils.int_to_big_endian(msg_hash) pub = ('04' + pubX + pubY).decode('hex') verified = ecdsa_raw_verify(msg_hash, (v, r, s), pub) print 'verified: ', verified stk.append(verified) elif op == 'ECRECOVER': # parameters: msg_hash (32), v (32), r (32), s (32), p (64 - empty array to hold pubkey) # stack should have all args msg_hash, v, r, s = stackargs msg_hash = utils.int_to_big_endian(msg_hash) pubX, pubY = ecdsa_raw_recover(msg_hash, (v, r, s)) stk.append(pubX) stk.append(pubY) elif op == 'PUB2ADDR': pubX, pubY = stackargs pubX = utils.int_to_big_endian(pubX).encode('hex') pubY = utils.int_to_big_endian(pubY).encode('hex') pub = pubX + pubY pub = pub.decode('hex') addr = utils.sha3(pub)[12:] stk.append(addr) elif op == 'ADDRESS': stk.append(msg.to) elif op == 'BALANCE': stk.append(block.get_balance(msg.to)) elif op == 'ORIGIN': stk.append(tx.sender) elif op == 'CALLER': stk.append(utils.coerce_to_int(msg.sender)) elif op == 'CALLVALUE': stk.append(msg.value) elif op == 'CALLDATALOAD': if stackargs[0] >= len(msg.data): stk.append(0) else: dat = msg.data[stackargs[0]:stackargs[0] + 32] stk.append(utils.big_endian_to_int(dat + '\x00' * (32 - len(dat)))) elif op == 'CALLDATASIZE': stk.append(len(msg.data)) elif op == 'CALLDATACOPY': if len(mem) < ceil32(stackargs[1] + stackargs[2]): mem.extend([0] * (ceil32(stackargs[1] + stackargs[2]) - len(mem))) for i in range(stackargs[2]): if stackargs[0] + i < len(msg.data): mem[stackargs[1] + i] = ord(msg.data[stackargs[0] + i]) else: mem[stackargs[1] + i] = 0 elif op == 'GASPRICE': stk.append(tx.gasprice) elif op == 'CODECOPY': if len(mem) < ceil32(stackargs[1] + stackargs[2]): mem.extend([0] * (ceil32(stackargs[1] + stackargs[2]) - len(mem))) for i in range(stackargs[2]): if stackargs[0] + i < len(code): mem[stackargs[1] + i] = ord(code[stackargs[0] + i]) else: mem[stackargs[1] + i] = 0 elif op == 'PREVHASH': stk.append(utils.big_endian_to_int(block.prevhash)) elif op == 'COINBASE': stk.append(utils.big_endian_to_int(block.coinbase.decode('hex'))) elif op == 'TIMESTAMP': stk.append(block.timestamp) elif op == 'NUMBER': stk.append(block.number) elif op == 'DIFFICULTY': stk.append(block.difficulty) elif op == 'GASLIMIT': stk.append(block.gaslimit) elif op == 'POP': pass elif op == 'DUP': stk.append(stackargs[0]) stk.append(stackargs[0]) elif op == 'SWAP': stk.append(stackargs[0]) stk.append(stackargs[1]) elif op == 'MLOAD': if len(mem) < ceil32(stackargs[0] + 32): mem.extend([0] * (ceil32(stackargs[0] + 32) - len(mem))) data = ''.join(map(chr, mem[stackargs[0]:stackargs[0] + 32])) stk.append(utils.big_endian_to_int(data)) elif op == 'MSTORE': if len(mem) < ceil32(stackargs[0] + 32): mem.extend([0] * (ceil32(stackargs[0] + 32) - len(mem))) v = stackargs[1] #if isinstance(v, str): # v = int(v.encode('hex'), 16) for i in range(31, -1, -1): mem[stackargs[0] + i] = v % 256 v /= 256 elif op == 'MSTORE8': if len(mem) < ceil32(stackargs[0] + 1): mem.extend([0] * (ceil32(stackargs[0] + 1) - len(mem))) mem[stackargs[0]] = stackargs[1] % 256 elif op == 'SLOAD': stk.append(block.get_storage_data(msg.to, stackargs[0])) elif op == 'SSTORE': block.set_storage_data(msg.to, stackargs[0], stackargs[1]) elif op == 'JUMP': compustate.pc = stackargs[0] elif op == 'JUMPI': if stackargs[1]: compustate.pc = stackargs[0] elif op == 'PC': stk.append(compustate.pc) elif op == 'MSIZE': stk.append(len(mem)) elif op == 'GAS': stk.append(oldgas) elif op[:4] == 'PUSH': pushnum = int(op[4:]) compustate.pc = oldpc + 1 + pushnum dat = code[oldpc + 1: oldpc + 1 + pushnum] stk.append(utils.big_endian_to_int(dat)) elif op == 'CREATE': if len(mem) < ceil32(stackargs[2] + stackargs[3]): mem.extend([0] * (ceil32(stackargs[2] + stackargs[3]) - len(mem))) gas = stackargs[0] value = stackargs[1] data = ''.join(map(chr, mem[stackargs[2]:stackargs[2] + stackargs[3]])) if debug: print("Sub-contract:", msg.to, value, gas, data) addr, gas, code = create_contract( block, tx, Message(msg.to, '', value, gas, data)) if debug: print("Output of contract creation:", addr, code) if addr: stk.append(utils.coerce_to_int(addr)) else: stk.append(0) elif op == 'CALL': if len(mem) < ceil32(stackargs[3] + stackargs[4]): mem.extend([0] * (ceil32(stackargs[3] + stackargs[4]) - len(mem))) if len(mem) < ceil32(stackargs[5] + stackargs[6]): mem.extend([0] * (ceil32(stackargs[5] + stackargs[6]) - len(mem))) gas = stackargs[0] to = utils.encode_int(stackargs[1]) to = (('\x00' * (32 - len(to))) + to)[12:] value = stackargs[2] data = ''.join(map(chr, mem[stackargs[3]:stackargs[3] + stackargs[4]])) if debug: print("Sub-call:", utils.coerce_addr_to_hex(msg.to), utils.coerce_addr_to_hex(to), value, gas, data) result, gas, data = apply_msg( block, tx, Message(msg.to, to, value, gas, data)) if debug: print("Output of sub-call:", result, data, "length", len(data), "expected", stackargs[6]) for i in range(stackargs[6]): mem[stackargs[5] + i] = 0 if result == 0: stk.append(0) else: stk.append(1) compustate.gas += gas for i in range(len(data)): mem[stackargs[5] + i] = data[i] elif op == 'RETURN': if len(mem) < ceil32(stackargs[0] + stackargs[1]): mem.extend([0] * (ceil32(stackargs[0] + stackargs[1]) - len(mem))) return mem[stackargs[0]:stackargs[0] + stackargs[1]] elif op == 'SUICIDE': to = utils.encode_int(stackargs[0]) to = (('\x00' * (32 - len(to))) + to)[12:] block.delta_balance(to, block.get_balance(msg.to)) block.state.update(msg.to, '') return []
import random random.seed(12312421412) from bitcoin import privtopub, encode_pubkey, ecdsa_raw_sign, ecdsa_raw_recover import time # import pyximport # pyximport.install() #from ecrecover import ecdsa_sign, ecdsa_verify, ecdsa_recover, test_big from ecdsa_recover import ecdsa_raw_recover as c_ecdsa_raw_recover from ecdsa_recover import ecdsa_raw_sign as c_ecdsa_raw_sign priv = ''.join(chr(random.randint(0, 255)) for i in range(32)) pub = privtopub(priv) msg = ''.join(chr(random.randint(0, 255)) for i in range(32)) vrs = ecdsa_raw_sign(msg, priv) assert vrs == c_ecdsa_raw_sign(msg, priv) p = ecdsa_raw_recover(msg, vrs) p2 = c_ecdsa_raw_recover(msg, vrs) assert p == p2 assert encode_pubkey(p, 'bin') == pub def test_ecrecover(rounds = 100): st = time.time() rounds = 100 for i in range(rounds): p = ecdsa_raw_recover(msg, vrs) print 'py took', (time.time() - st) def test_cecrecover(rounds = 100): st = time.time() for i in range(rounds): p = c_ecdsa_raw_recover(msg, vrs)