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 get_script(self): text = self.template.text variables = {} for var_name, v in self.variable_widgets.items(): var = str(v.text()) var_type = self.template.variables[var_name] # Convert input to appropriate format. if var_type == 'address': try: h160 = CBase58Data(var).to_bytes() except Exception: return 'Error: Could not decode <{}> address.'.format( var_name) var = ''.join(['0x', h160.encode('hex')]) elif var_type == 'text': # var = ''.join(['"', var, '"']) var = var.encode('hex') variables[var_name] = var # Replace the <variable> occurrences with their values. for k, v in variables.items(): old = ''.join(['<', k, '>']) text = text.replace(old, v) return text
def encrypt_no_ec_multiply(self): address = self.k.get_pubkey(form=CKeyForm.BASE58) addresshash = SHA256.new(SHA256.new(address).digest()).digest()[:4] derived = scrypt.hash(self.passphrase, addresshash, N=16384, r=8, p=8, buflen=64) dh1 = derived[:32] dh2 = derived[32:64] cipher = AES.new(dh2) pkey = self.k.get_secret() p1 = Bip38.xor_zip(pkey[:16], dh1[:16]) p2 = Bip38.xor_zip(pkey[16:32], dh1[16:32]) eh1 = cipher.encrypt(p1) eh2 = cipher.encrypt(p2) flagbyte = array('B', [0]) flagbyte[0] |= 0xc0 if self.k.get_compressed() is True: flagbyte[0] |= 0x20 prefix = '\x42' return str( CBase58Data(prefix + flagbyte.tostring() + addresshash + eh1 + eh2, 0x01))
def get_intermediate(self, salt=None, lot=0, sequence=0): if salt is None: if self.ls_numbers is True: salt = os.urandom(4) ownerentropy = salt + pack('>I', (lot * 4096) + sequence) else: salt = os.urandom(8) ownerentropy = salt else: if self.ls_numbers is True: ownerentropy = salt + pack('>I', (lot * 4096) + sequence) else: ownerentropy = salt prefactor = scrypt.hash(self.passphrase, salt, N=16384, r=8, p=8, buflen=32) if self.ls_numbers is True: passfactor = SHA256.new( SHA256.new(prefactor + ownerentropy).digest()).digest() else: passfactor = prefactor passpoint = Bip38._compute_passpoint(passfactor) if self.ls_numbers is True: magic = '\xE9\xB3\xE1\xFF\x39\xE2\x51' else: magic = '\xE9\xB3\xE1\xFF\x39\xE2\x53' return str(CBase58Data(magic + ownerentropy + passpoint, 0x2c))
def _get_confirmation_code(flagbyte, ownerentropy, factorb, derived_half1, derived_half2, addresshash): k = CKey() k.set_compressed(True) k.generate(secret=factorb) pointb = k.get_pubkey() if len(pointb) != 33: return AssertionError('pointb (' + hexlify(pointb) + ') is ' + str(len(pointb)) + ' bytes. It should be 33 bytes.') if pointb[:1] != '\x02' and pointb[:1] != '\x03': return ValueError('pointb is not correct.') pointbprefix = Bip38.xor_zip( pointb[:1], chr(ord(derived_half2[31:32]) & ord('\x01'))) cipher = AES.new(derived_half2) pointbx1 = cipher.encrypt( Bip38.xor_zip(pointb[1:17], derived_half1[:16])) pointbx2 = cipher.encrypt( Bip38.xor_zip(pointb[17:33], derived_half1[16:32])) encryptedpointb = pointbprefix + pointbx1 + pointbx2 if len(encryptedpointb) != 33: return AssertionError('encryptedpointb is not 33 bytes long.') magic = '\x3b\xf6\xa8\x9a' return str( CBase58Data( magic + flagbyte.tostring() + addresshash + ownerentropy + encryptedpointb, 0x64))
def encryptBIP0038(pubkey, privkey, secret): k = CKey() #decode the wallet import format by base58 decoding then dropping the last 4 bytes and the first byte decoded = b58decode(privkey) decoded = decoded[:-4] decoded = decoded[1:] k.generate(decoded) k.set_compressed(False) b = Bip38(k, secret) return str(CBase58Data(b.get_encrypted(), 0x01))
def BitcoinAddress(address): """Bitcoin address validation accepts both testnet and mainnet""" try: assert isinstance(address, str) assert 25 < len(address) < 36 addr = CBase58Data(address) assert addr.nVersion in BITCOIN_VERSION_BYTES return address except Exception: raise ValueError('{} is not a valid bitcoin address'.format(address))
def decode_address(txt): """Decode txt into a RIPEMD-160 hash. Will raise if txt is not a valid address. Returns: Two-tuple of (raw_bytes, address_version) """ addr = CBase58Data(txt) raw = addr.to_bytes() return (addr.to_bytes(), addr.nVersion)
def decode_address(self): txt = str(self.address_line.text()) try: addr = CBase58Data(txt) except Exception: self.hash_line.setText('Could not decode address.') self.addr_version.setValue(0) return self.hash_line.setText(addr.to_bytes().encode('hex')) self.addr_version.setValue(addr.nVersion)
def format_variable_value(value, var_type): """Returns a 2-tuple of (is_valid, formatted_value).""" if var_type == 'address': try: h160 = CBase58Data(value).to_bytes() except Exception: # Check if value is a hash160. if is_hex(value) and len( format_hex_string(value, with_prefix=False)) == 40: h160 = format_hex_string(value, with_prefix=False).decode('hex') else: return False, 'Error: Could not decode address.' return True, '0x' + h160.encode('hex') elif var_type == 'pubkey': if not is_hex(value): return False, 'Error: Pubkey must be hex.' key_hex = format_hex_string(value, with_prefix=False) pub = CPubKey(key_hex.decode('hex')) if not pub.is_fullyvalid: return False, 'Error: Pubkey is invalid.' return True, '0x' + key_hex elif var_type == 'text': try: return True, '0x' + value.encode('hex') except Exception as e: return False, 'Error: ' + str(e) elif var_type == 'signature': if not is_hex(value): return False, 'Error: Signature must be hex.' # We remain algorithm-agnostic by not checking the length. return True, format_hex_string(value, with_prefix=True) elif var_type == 'script': if not is_hex(value): try: scr = Script.from_human(value) return True, format_hex_string(scr.get_hex(), with_prefix=True) except Exception: return False, 'Error: Cannot parse human-readable script.' try: scr = Script( format_hex_string(value, with_prefix=False).decode('hex')) return True, format_hex_string(value, with_prefix=True) except Exception: return False, 'Error: Cannot parse script.' return True, value
def is_valid_bitcoin_address(address, testnet=True): """ Check the address is a valide P2SH or P2PK bitcoin address Arguments: address(str) testnet(bool): True to also accept testnet addresses Returns: (bool): True if it is a valid, False otherwise """ try: assert isinstance(address, str) assert 25 < len(address) < 36 addr = CBase58Data(address) assert addr.nVersion in BITCOIN_VERSION_BYTES return True except Exception: return False
def copy_h160(x): h160 = CBase58Data(x).encode('hex') QApplication.clipboard().setText(h160)
def coerce_address(v): addr_data = CBase58Data(v) if len(v) >= 26 and len(v) <= 35: return addr_data
def is_address(x): try: data = CBase58Data(x) except Exception: return False return len(x) >= 26 and len(x) <= 35
def decryptBIP0038(privkey, password): return str(CBase58Data(Bip38.decrypt(privkey, password), 128))
def validate_address_list_arg(settings): for a in settings.addresses: CBase58Data(a)