def get_pubkey(self, form = CKeyForm.HEX): size = ssl.i2o_ECPublicKey(self.k, 0) mb = ctypes.create_string_buffer(size) ssl.i2o_ECPublicKey(self.k, ctypes.byref(ctypes.pointer(mb))) if form is CKeyForm.HEX: return mb.raw elif form is CKeyForm.BASE58: return str(CBase58Data(ser_uint160(Hash160(mb.raw)), CBitcoinAddress.PUBKEY_ADDRESS)) else: raise ValueError("Unknown KeyForm.")
def encrypt_ec_multiply(intermediate, seedb=None): i_buffer = CBase58Data.from_str(intermediate) ownerentropy = i_buffer[7:7 + 8] passpoint_hex = i_buffer[15:15 + 33] flagbyte = array('B', [0]) if i_buffer[6:7] == '\x51': flagbyte[0] |= 0x04 if seedb is None: seedb = os.urandom(24) factorb_hex = SHA256.new(SHA256.new(seedb).digest()).digest() NID_secp256k1 = 714 k = ssl.EC_KEY_new_by_curve_name(NID_secp256k1) group = ssl.EC_KEY_get0_group(k) pub_key = ssl.EC_POINT_new(group) ctx = ssl.BN_CTX_new() passpoint = ssl.EC_POINT_new(group) ssl.EC_POINT_oct2point(group, passpoint, passpoint_hex, 33, ctx) factorb = ssl.BN_bin2bn(factorb_hex, 32, ssl.BN_new()) ssl.EC_POINT_mul(group, pub_key, None, passpoint, factorb, ctx) # FIXME: set correct compression ssl.EC_KEY_set_public_key(k, pub_key) size = ssl.i2o_ECPublicKey(k, 0) mb = ctypes.create_string_buffer(size) ssl.i2o_ECPublicKey(k, ctypes.byref(ctypes.pointer(mb))) generatedaddress = str( CBase58Data(ser_uint160(Hash160(mb.raw)), CBitcoinAddress.PUBKEY_ADDRESS)) addresshash = SHA256.new( SHA256.new(generatedaddress).digest()).digest()[:4] derived = scrypt.hash(passpoint_hex, addresshash + ownerentropy, N=1024, r=1, p=1, buflen=64) derived_half1 = derived[:32] derived_half2 = derived[32:64] #confirmation = Bip38._get_confirmation_code(flagbyte, ownerentropy, factorb_hex, derived_half1, derived_half2, addresshash) cipher = AES.new(derived_half2) ep1 = cipher.encrypt(Bip38.xor_zip(seedb[:16], derived_half1[:16])) ep2 = cipher.encrypt( Bip38.xor_zip(ep1[8:16] + seedb[16:24], derived_half1[16:32])) prefix = '\x43' return str( CBase58Data( prefix + flagbyte.tostring() + addresshash + ownerentropy + ep1[:8] + ep2, 0x01))
def encrypt_ec_multiply(intermediate, seedb=None): i_buffer = CBase58Data.from_str(intermediate) ownerentropy = i_buffer[7:7+8] passpoint_hex = i_buffer[15:15+33] flagbyte=array('B', [0]) if i_buffer[6:7] == '\x51': flagbyte[0] |= 0x04 if seedb is None: seedb = os.urandom(24) factorb_hex = SHA256.new(SHA256.new(seedb).digest()).digest() NID_secp256k1 = 714 k = ssl.EC_KEY_new_by_curve_name(NID_secp256k1) group = ssl.EC_KEY_get0_group(k) pub_key = ssl.EC_POINT_new(group) ctx = ssl.BN_CTX_new() passpoint = ssl.EC_POINT_new(group) ssl.EC_POINT_oct2point(group, passpoint, passpoint_hex, 33, ctx) factorb = ssl.BN_bin2bn(factorb_hex, 32, ssl.BN_new()) ssl.EC_POINT_mul(group, pub_key, None, passpoint, factorb, ctx) # FIXME: set correct compression ssl.EC_KEY_set_public_key(k, pub_key) size = ssl.i2o_ECPublicKey(k, 0) mb = ctypes.create_string_buffer(size) ssl.i2o_ECPublicKey(k, ctypes.byref(ctypes.pointer(mb))) generatedaddress = str(CBase58Data(ser_uint160(Hash160(mb.raw)), CBitcoinAddress.PUBKEY_ADDRESS)) addresshash = SHA256.new(SHA256.new(generatedaddress).digest()).digest()[:4] derived = scrypt.hash(passpoint_hex, addresshash + ownerentropy, N=1024, r=1, p=1, buflen=64) derived_half1 = derived[:32] derived_half2 = derived[32:64] #confirmation = Bip38._get_confirmation_code(flagbyte, ownerentropy, factorb_hex, derived_half1, derived_half2, addresshash) cipher = AES.new(derived_half2) ep1 = cipher.encrypt(Bip38.xor_zip(seedb[:16], derived_half1[:16])) ep2 = cipher.encrypt(Bip38.xor_zip(ep1[8:16] + seedb[16:24], derived_half1[16:32])) prefix = '\x43' return str(CBase58Data(prefix + flagbyte.tostring() + addresshash + ownerentropy + ep1[:8] + ep2, 0x01))
def EvalScript(stack, scriptIn, txTo, inIdx, hashtype): altstack = [] vfExec = [] script = CScript(scriptIn) while script.pc < script.pend: if not script.getop(): return False sop = script.sop fExec = CheckExec(vfExec) if fExec and sop.op <= OP_PUSHDATA4: stack.append(sop.data) continue elif fExec and sop.op == OP_1NEGATE or ((sop.op >= OP_1) and (sop.op <= OP_16)): v = sop.op - (OP_1 - 1) stack.append(bn2vch(v)) elif fExec and sop.op in ISA_BINOP: if not BinOp(sop.op, stack): return False elif fExec and sop.op in ISA_UNOP: if not UnaryOp(sop.op, stack): return False elif fExec and sop.op == OP_2DROP: if len(stack) < 2: return False stack.pop() stack.pop() elif fExec and sop.op == OP_2DUP: if len(stack) < 2: return False v1 = stack[-2] v2 = stack[-1] stack.append(v1) stack.append(v2) elif fExec and sop.op == OP_2OVER: if len(stack) < 4: return False v1 = stack[-4] v2 = stack[-3] stack.append(v1) stack.append(v2) elif fExec and sop.op == OP_2SWAP: if len(stack) < 4: return False tmp = stack[-4] stack[-4] = stack[-2] stack[-2] = tmp tmp = stack[-3] stack[-3] = stack[-1] stack[-1] = tmp elif fExec and sop.op == OP_3DUP: if len(stack) < 3: return False v1 = stack[-3] v2 = stack[-2] v3 = stack[-1] stack.append(v1) stack.append(v2) stack.append(v3) elif fExec and sop.op == OP_CHECKMULTISIG or sop.op == OP_CHECKMULTISIGVERIFY: tmpScript = CScript(script.vch[script.pbegincodehash:script.pend]) ok = CheckMultiSig(sop.op, tmpScript, stack, txTo, inIdx, hashtype) if not ok: return False elif fExec and sop.op == OP_CHECKSIG or sop.op == OP_CHECKSIGVERIFY: if len(stack) < 2: return False vchPubKey = stack.pop() vchSig = stack.pop() tmpScript = CScript(script.vch[script.pbegincodehash:script.pend]) # FIXME: find-and-delete vchSig ok = CheckSig(vchSig, vchPubKey, tmpScript, txTo, inIdx, hashtype) if ok: if sop.op != OP_CHECKSIGVERIFY: stack.append(b"\x01") else: if sop.op == OP_CHECKSIGVERIFY: return False stack.append(b"\x00") elif fExec and sop.op == OP_CODESEPARATOR: script.pbegincodehash = script.pc elif fExec and sop.op == OP_DEPTH: bn = len(stack) stack.append(bn2vch(bn)) elif fExec and sop.op == OP_DROP: if len(stack) < 1: return False stack.pop() elif fExec and sop.op == OP_DUP: if len(stack) < 1: return False v = stack[-1] stack.append(v) elif sop.op == OP_ELSE: if len(vfExec) == 0: return false vfExec[-1] = not vfExec[-1] elif sop.op == OP_ENDIF: if len(vfExec) == 0: return false vfExec.pop() elif fExec and sop.op == OP_EQUAL or sop.op == OP_EQUALVERIFY: if len(stack) < 2: return False v1 = stack.pop() v2 = stack.pop() is_equal = (v1 == v2) if is_equal: stack.append(b"\x01") else: stack.append(b"\x00") if sop.op == OP_EQUALVERIFY: if is_equal: stack.pop() else: return False elif fExec and sop.op == OP_FROMALTSTACK: if len(altstack) < 1: return False v = altstack.pop() stack.append(v) elif fExec and sop.op == OP_HASH160: if len(stack) < 1: return False stack.append(ser_uint160(Hash160(stack.pop()))) elif fExec and sop.op == OP_HASH256: if len(stack) < 1: return False stack.append(ser_uint256(Hash(stack.pop()))) elif sop.op == OP_IF or sop.op == OP_NOTIF: val = False if fExec: if len(stack) < 1: return False vch = stack.pop() val = CastToBool(vch) if sop.op == OP_NOTIF: val = not val vfExec.append(val) elif fExec and sop.op == OP_IFDUP: if len(stack) < 1: return False vch = stack[-1] if CastToBool(vch): stack.append(vch) elif fExec and sop.op == OP_NIP: if len(stack) < 2: return False del stack[-2] elif fExec and sop.op == OP_NOP or (sop.op >= OP_NOP1 and sop.op <= OP_NOP10): pass elif fExec and sop.op == OP_OVER: if len(stack) < 2: return False vch = stack[-2] stack.append(vch) elif fExec and sop.op == OP_PICK or sop.op == OP_ROLL: if len(stack) < 2: return False n = CastToBigNum(stack.pop()) if n < 0 or n >= len(stack): return False vch = stack[-n-1] if sop.op == OP_ROLL: del stack[-n-1] stack.append(vch) elif fExec and sop.op == OP_RETURN: return False elif fExec and sop.op == OP_RIPEMD160: if len(stack) < 1: return False h = hashlib.new('ripemd160') h.update(stack.pop()) stack.append(h.digest()) elif fExec and sop.op == OP_ROT: if len(stack) < 3: return False tmp = stack[-3] stack[-3] = stack[-2] stack[-2] = tmp tmp = stack[-2] stack[-2] = stack[-1] stack[-1] = tmp elif fExec and sop.op == OP_SIZE: if len(stack) < 1: return False bn = len(stack[-1]) stack.append(bn2vch(bn)) elif fExec and sop.op == OP_SHA256: if len(stack) < 1: return False stack.append(hashlib.sha256(stack.pop()).digest()) elif fExec and sop.op == OP_SWAP: if len(stack) < 2: return False tmp = stack[-2] stack[-2] = stack[-1] stack[-1] = tmp elif fExec and sop.op == OP_TOALTSTACK: if len(stack) < 1: return False v = stack.pop() altstack.append(v) elif fExec and sop.op == OP_TUCK: if len(stack) < 2: return False vch = stack[-1] stack.insert(len(stack) - 2, vch) elif fExec and sop.op == OP_VERIFY: if len(stack) < 1: return False v = CastToBool(stack[-1]) if v: stack.pop() else: return False elif fExec and sop.op == OP_WITHIN: if len(stack) < 3: return False bn3 = CastToBigNum(stack.pop()) bn2 = CastToBigNum(stack.pop()) bn1 = CastToBigNum(stack.pop()) v = (bn2 <= bn1) and (bn1 < bn3) if v: stack.append(b"\x01") else: stack.append(b"\x00") elif fExec: #print("Unsupported opcode", OPCODE_NAMES[sop.op]) return False return True
def EvalScript(stack, scriptIn, txTo, inIdx, hashtype): altstack = [] vfExec = [] script = CScript(scriptIn) while script.pc < script.pend: if not script.getop(): return False sop = script.sop fExec = CheckExec(vfExec) if fExec and sop.op <= OP_PUSHDATA4: stack.append(sop.data) continue elif fExec and sop.op == OP_1NEGATE or ((sop.op >= OP_1) and (sop.op <= OP_16)): v = sop.op - (OP_1 - 1) stack.append(bn2vch(v)) elif fExec and sop.op in ISA_BINOP: if not BinOp(sop.op, stack): return False elif fExec and sop.op in ISA_UNOP: if not UnaryOp(sop.op, stack): return False elif fExec and sop.op == OP_2DROP: if len(stack) < 2: return False stack.pop() stack.pop() elif fExec and sop.op == OP_2DUP: if len(stack) < 2: return False v1 = stack[-2] v2 = stack[-1] stack.append(v1) stack.append(v2) elif fExec and sop.op == OP_2OVER: if len(stack) < 4: return False v1 = stack[-4] v2 = stack[-3] stack.append(v1) stack.append(v2) elif fExec and sop.op == OP_2SWAP: if len(stack) < 4: return False tmp = stack[-4] stack[-4] = stack[-2] stack[-2] = tmp tmp = stack[-3] stack[-3] = stack[-1] stack[-1] = tmp elif fExec and sop.op == OP_3DUP: if len(stack) < 3: return False v1 = stack[-3] v2 = stack[-2] v3 = stack[-1] stack.append(v1) stack.append(v2) stack.append(v3) elif fExec and sop.op == OP_CHECKMULTISIG or sop.op == OP_CHECKMULTISIGVERIFY: tmpScript = CScript(script.vch[script.pbegincodehash:script.pend]) ok = CheckMultiSig(sop.op, tmpScript, stack, txTo, inIdx, hashtype) if not ok: return False elif fExec and sop.op == OP_CHECKSIG or sop.op == OP_CHECKSIGVERIFY: if len(stack) < 2: return False vchPubKey = stack.pop() vchSig = stack.pop() tmpScript = CScript(script.vch[script.pbegincodehash:script.pend]) # FIXME: find-and-delete vchSig ok = CheckSig(vchSig, vchPubKey, tmpScript, txTo, inIdx, hashtype) if ok: if sop.op != OP_CHECKSIGVERIFY: stack.append(b"\x01") else: if sop.op == OP_CHECKSIGVERIFY: return False stack.append(b"\x00") elif fExec and sop.op == OP_CODESEPARATOR: script.pbegincodehash = script.pc elif fExec and sop.op == OP_DEPTH: bn = len(stack) stack.append(bn2vch(bn)) elif fExec and sop.op == OP_DROP: if len(stack) < 1: return False stack.pop() elif fExec and sop.op == OP_DUP: if len(stack) < 1: return False v = stack[-1] stack.append(v) elif sop.op == OP_ELSE: if len(vfExec) == 0: return false vfExec[-1] = not vfExec[-1] elif sop.op == OP_ENDIF: if len(vfExec) == 0: return false vfExec.pop() elif fExec and sop.op == OP_EQUAL or sop.op == OP_EQUALVERIFY: if len(stack) < 2: return False v1 = stack.pop() v2 = stack.pop() is_equal = (v1 == v2) if is_equal: stack.append(b"\x01") else: stack.append(b"\x00") if sop.op == OP_EQUALVERIFY: if is_equal: stack.pop() else: return False elif fExec and sop.op == OP_FROMALTSTACK: if len(altstack) < 1: return False v = altstack.pop() stack.append(v) elif fExec and sop.op == OP_HASH160: if len(stack) < 1: return False stack.append(ser_uint160(Hash160(stack.pop()))) elif fExec and sop.op == OP_HASH256: if len(stack) < 1: return False stack.append(ser_uint256(Hash(stack.pop()))) elif sop.op == OP_IF or sop.op == OP_NOTIF: val = False if fExec: if len(stack) < 1: return False vch = stack.pop() val = CastToBool(vch) if sop.op == OP_NOTIF: val = not val vfExec.append(val) elif fExec and sop.op == OP_IFDUP: if len(stack) < 1: return False vch = stack[-1] if CastToBool(vch): stack.append(vch) elif fExec and sop.op == OP_NIP: if len(stack) < 2: return False del stack[-2] elif fExec and sop.op == OP_NOP or (sop.op >= OP_NOP1 and sop.op <= OP_NOP10): pass elif fExec and sop.op == OP_OVER: if len(stack) < 2: return False vch = stack[-2] stack.append(vch) elif fExec and sop.op == OP_PICK or sop.op == OP_ROLL: if len(stack) < 2: return False n = CastToBigNum(stack.pop()) if n < 0 or n >= len(stack): return False vch = stack[-n - 1] if sop.op == OP_ROLL: del stack[-n - 1] stack.append(vch) elif fExec and sop.op == OP_RETURN: return False elif fExec and sop.op == OP_RIPEMD160: if len(stack) < 1: return False h = hashlib.new('ripemd160') h.update(stack.pop()) stack.append(h.digest()) elif fExec and sop.op == OP_ROT: if len(stack) < 3: return False tmp = stack[-3] stack[-3] = stack[-2] stack[-2] = tmp tmp = stack[-2] stack[-2] = stack[-1] stack[-1] = tmp elif fExec and sop.op == OP_SIZE: if len(stack) < 1: return False bn = len(stack[-1]) stack.append(bn2vch(bn)) elif fExec and sop.op == OP_SHA256: if len(stack) < 1: return False stack.append(hashlib.sha256(stack.pop()).digest()) elif fExec and sop.op == OP_SWAP: if len(stack) < 2: return False tmp = stack[-2] stack[-2] = stack[-1] stack[-1] = tmp elif fExec and sop.op == OP_TOALTSTACK: if len(stack) < 1: return False v = stack.pop() altstack.append(v) elif fExec and sop.op == OP_TUCK: if len(stack) < 2: return False vch = stack[-1] stack.insert(len(stack) - 2, vch) elif fExec and sop.op == OP_VERIFY: if len(stack) < 1: return False v = CastToBool(stack[-1]) if v: stack.pop() else: return False elif fExec and sop.op == OP_WITHIN: if len(stack) < 3: return False bn3 = CastToBigNum(stack.pop()) bn2 = CastToBigNum(stack.pop()) bn1 = CastToBigNum(stack.pop()) v = (bn2 <= bn1) and (bn1 < bn3) if v: stack.append(b"\x01") else: stack.append(b"\x00") elif fExec: #print("Unsupported opcode", OPCODE_NAMES[sop.op]) return False return True