Exemplo n.º 1
0
def genAll(bip=False):
	import random
	import num.rand as rand
	import system.address as address
	import num.enc as enc
	import encrypt.bip38 as bip38
	import hashlib
	
	genFile = open('allKeys', 'w')
	genFile.close()
	
	conn = db.open()
	c = conn.cursor()
	c.execute('select currency from eskimo_currencies order by currency;')
	currencies = c.fetchall()
	for cur in currencies:
		c.execute('select v.version,v.prefix,v.length,c.id,c.longName from eskimo_versions as v inner join eskimo_currencies as c on c.version = v.id where c.currency=?;', (cur[0].upper(),))
		version = c.fetchone()
		if version is None:
			continue
		#randomly choose a prefix if multiples exist
		prefixes = version[1].split('|') 
		prefix = prefixes[random.randint(0, (len(prefixes)-1))] 
		#generate the private and public keys
		privateKey = rand.randomKey(random.getrandbits(512))
		privK256 = enc.encode(privateKey, 256, 32)
		WIF = address.privateKey2Wif(privateKey, version[0], prefix,  version[2])
		publicAddress = address.publicKey2Address(address.privateKey2PublicKey(privateKey), version[0], prefix,  version[2])
		if bip is True:
			BIP = bip38.encrypt(privK256, publicAddress, 'biptest', 1)
			privK, addresshash = bip38.decrypt(BIP, 'biptest', 1)
			#decode the privK from base 256
			privK = enc.decode(privK, 256)
			#hash the address to check the decryption
			addr = address.publicKey2Address(address.privateKey2PublicKey(privK), version[0], prefix,  version[2])
			fail = False
			if hashlib.sha256(hashlib.sha256(addr).digest()).digest()[0:4] != addresshash:
				fail = True
				reason = 'Address Hash doesn\'t match'
			if privK != privateKey:
				fail = True
				reason = 'Private Keys don\'t match'
			BIPWIF =  address.privateKey2Wif(privK, version[0], prefix,  version[2])
		with open('allKeys', 'a') as outfile:
			outfile.write('####### ' + cur[0].upper() + ' - ' + version[4] + ' #######\n')
			outfile.write('Address = ' + publicAddress + '\n')
			outfile.write('WIF     = ' + WIF + '\n')
			if bip is True:
				outfile.write('BIP     = ' + BIP + '\n')
				if fail is True:
					outfile.write('BIP Failed - ' + reason + '\n')
				else:
					outfile.write('BIPWIF  = ' + BIPWIF + '\n')
			outfile.write('\n')
		outfile.close()
	db.close(conn)
	return True
Exemplo n.º 2
0
def intermediate2privK(intermediate_passphrase_string):
	"""
	Steps to create new encrypted private keys given intermediate_passphrase_string from owner
	(so we have ownerentropy, and passpoint, but we do not have passfactor or the passphrase):
	"""

	#get ownerentropy and passpoint from the intermediate key
	leadingzbytes = len(re.match('^1*',intermediate_passphrase_string).group(0))
	data = '\x00' * leadingzbytes + enc.encode(enc.decode(intermediate_passphrase_string,58),256)
	assert hashlib.sha256(hashlib.sha256(data[:-4]).digest()).digest().encode('hex')[:4] == data[-4:]
	decodedstring = data[1:-4]
	ownerentropy = decodedstring[7:15]
	passpoint = decodedstring[-33:]

	#1. Set flagbyte.
	#Turn on bit 0x20 if the Bitcoin address will be formed by hashing the compressed public key (optional, saves space, but many Bitcoin implementations aren't compatible with it)
	#Turn on bit 0x04 if ownerentropy contains a value for lotsequence.
	#(While it has no effect on the keypair generation process, the decryption process needs this flag to know how to process ownerentropy)
	flagbyte = chr(0b00100100) # 00 EC 1 compressed 00 future 1 has lotsequence 00 future

	#2. Generate 24 random bytes, call this seedb. Take SHA256(SHA256(seedb)) to yield 32 bytes, call this factorb.
	seedb = os.urandom(24)
	factorb = hashlib.sha256(hashlib.sha256(seedb).digest()).digest()

	#3. ECMultiply passpoint by factorb.
	pub = elip.base10_multiply(enc.decode(factorb, 256), enc.decode(passpoint, 256))

	#4. Use the resulting EC point as a public key and hash it into a Bitcoin address using either compressed or uncompressed public key methodology
	# (specify which methodology is used inside flagbyte).
	# This is the generated Bitcoin address, call it generatedaddress.
	publicKey = ('0' + str(2 + (pub[1] % 2)) + enc.encode(pub[0], 16, 64))
	generatedaddress = address.publicKey2Address(publicKey) ## Remember to add in the currency details here

	#5. Take the first four bytes of SHA256(SHA256(generatedaddress)) and call it addresshash.
	addresshash = hashlib.sha256(hashlib.sha256(generatedaddress).digest()).digest()[:4]

	#6. Now we will encrypt seedb. Derive a second key from passpoint using scrypt
	#Parameters: passphrase is passpoint provided from the first party (expressed in binary as 33 bytes).
	# salt is addresshash + ownerentropy, n=1024, r=1, p=1, length=64. The "+" operator is concatenation.
	encseedb = scrypt.hash(passpoint, addresshash + ownerentropy, 1024, 1, 1, 64)

	#7. Split the result into two 32-byte halves and call them derivedhalf1 and derivedhalf2.
	derivedhalf1 = encseedb[0:32]
	derivedhalf2 = encseedb[32:64]

	#8. Do AES256Encrypt(seedb[0...15] xor derivedhalf1[0...15], derivedhalf2), call the 16-byte result encryptedpart1
	Aes = aes.Aes(derivedhalf2)
	encryptedpart1 = Aes.enc(enc.sxor(seedb[:16], derivedhalf1[:16]))

	#9. Do AES256Encrypt((encryptedpart1[8...15] + seedb[16...23]) xor derivedhalf1[16...31], derivedhalf2), call the 16-byte result encryptedpart2.
	# The "+" operator is concatenation.
	encryptedpart2 = Aes.enc(enc.sxor(encryptedpart1[8:16] + seedb[16:24], derivedhalf1[16:32]))

	#10. The encrypted private key is the Base58Check-encoded concatenation of the following, which totals 39 bytes without Base58 checksum:
	#0x01 0x43 + flagbyte + addresshash + ownerentropy + encryptedpart1[0...7] + encryptedpart2
	inp_fmtd = '\x01\x43' + flagbyte + addresshash + ownerentropy + encryptedpart1[0:8] + encryptedpart2
	check = hashlib.sha256(hashlib.sha256(inp_fmtd).digest()).digest()[:4]
	BIPKey = enc.b58encode(inp_fmtd + check)
	cnfrmcode = confirmationcode(flagbyte, addresshash, ownerentropy, factorb, derivedhalf1, derivedhalf2)
	return BIPKey, generatedaddress, cnfrmcode
Exemplo n.º 3
0
def confirmcode(confirmationcode, passphrase):
    """
	A confirmation tool, given a passphrase and a confirmation code, can recalculate the address, verify the address hash, and then assert the following:
	"It is confirmed that Bitcoin address address depends on this passphrase".

	To recalculate the address:
	"""
    #decode the confirmationcode to give addresshash, ownerentropy and encryptedpointb
    data = enc.b58decode(confirmationcode)
    checksum = data[-4:]
    hash = hashlib.sha256(hashlib.sha256(data[:-4]).digest()).digest()[:4]
    assert hash == checksum
    addresshash = data[6:10]
    ownerentropy = data[10:18]

    encryptedpointb = data[18:51]
    pointbx1 = encryptedpointb[1:17]
    pointbx2 = encryptedpointb[17:33]

    #1. Derive passfactor using scrypt with ownerentropy and the user's passphrase and use it to recompute passpoint
    passfactor = scrypt.hash(passphrase, ownerentropy, 16384, 8, 8, 32)
    pub = elip.base10_multiply(elip.G, enc.decode(passfactor, 256))
    passpoint = ('0' + str(2 + (pub[1] % 2)) +
                 enc.encode(pub[0], 16, 64)).decode('hex')

    #2. Derive decryption key for pointb using scrypt with passpoint, addresshash, and ownerentropy
    key = scrypt.hash(passpoint, addresshash + ownerentropy, 1024, 1, 1, 64)
    derivedhalf1 = key[0:32]
    derivedhalf2 = key[32:64]

    #3. Decrypt encryptedpointb to yield pointb
    Aes = aes.Aes(derivedhalf2)
    decryptedhalf1 = Aes.dec(pointbx1)
    decryptedhalf2 = Aes.dec(pointbx2)

    pointb = '0' + decryptedhalf1 + decryptedhalf2
    pointb = binascii.unhexlify('%064x' %
                                (long(binascii.hexlify(pointb), 16)
                                 ^ long(binascii.hexlify(derivedhalf1), 16)))

    #4. ECMultiply pointb by passfactor. Use the resulting EC point as a public key and hash it into address using either compressed or uncompressed public key
    # methodology as specified in flagbyte.
    pub = elip.base10_multiply(pointb, enc.decode(passfactor, 256))
    print('pub[0] = ' + str(pub[0]))
    print('pub[1] = ' + str(pub[1]))
    publicKey = ('0' + str(2 + (pub[1] % 2)) + enc.encode(pub[0], 16, 64))

    print('pubKey = ' + publicKey)
    generatedaddress = address.publicKey2Address(publicKey)
    print('generatedaddress = ' + generatedaddress)
    #print(hashlib.sha256(hashlib.sha256(generatedaddress).digest()).digest()[:4])
    #print(addresshash)
    #assert hashlib.sha256(hashlib.sha256(generatedaddress).digest()).digest()[:4] == addresshash
    return
Exemplo n.º 4
0
def confirmcode(confirmationcode, passphrase):
	"""
	A confirmation tool, given a passphrase and a confirmation code, can recalculate the address, verify the address hash, and then assert the following:
	"It is confirmed that Bitcoin address address depends on this passphrase".

	To recalculate the address:
	"""
	#decode the confirmationcode to give addresshash, ownerentropy and encryptedpointb
	data = enc.b58decode(confirmationcode)
	checksum = data[-4:]
	hash = hashlib.sha256(hashlib.sha256(data[:-4]).digest()).digest()[:4]
	assert hash == checksum
	addresshash = data[6:10]
	ownerentropy = data[10:18]

	encryptedpointb = data[18:51]
	pointbx1 = encryptedpointb[1:17]
	pointbx2 = encryptedpointb[17:33]

	#1. Derive passfactor using scrypt with ownerentropy and the user's passphrase and use it to recompute passpoint
	passfactor = scrypt.hash(passphrase, ownerentropy, 16384, 8, 8, 32)
	pub = elip.base10_multiply(elip.G, enc.decode(passfactor, 256))
	passpoint = ('0' + str(2 + (pub[1] % 2)) + enc.encode(pub[0], 16, 64)).decode('hex')

	#2. Derive decryption key for pointb using scrypt with passpoint, addresshash, and ownerentropy
	key = scrypt.hash(passpoint, addresshash + ownerentropy, 1024, 1, 1, 64)
	derivedhalf1 = key[0:32]
	derivedhalf2 = key[32:64]

	#3. Decrypt encryptedpointb to yield pointb
	Aes = aes.Aes(derivedhalf2)
	decryptedhalf1 = Aes.dec(pointbx1)
	decryptedhalf2 = Aes.dec(pointbx2)

	pointb = '0' + decryptedhalf1 + decryptedhalf2
	pointb = binascii.unhexlify('%064x' % (long(binascii.hexlify(pointb), 16) ^ long(binascii.hexlify(derivedhalf1), 16)))

	#4. ECMultiply pointb by passfactor. Use the resulting EC point as a public key and hash it into address using either compressed or uncompressed public key
	# methodology as specified in flagbyte.
	pub = elip.base10_multiply(pointb, enc.decode(passfactor, 256))
	print('pub[0] = ' + str(pub[0]))
	print('pub[1] = ' + str(pub[1]))
	publicKey = ('0' + str(2 + (pub[1] % 2)) + enc.encode(pub[0], 16, 64))

	print('pubKey = ' + publicKey)
	generatedaddress = address.publicKey2Address(publicKey)
	print('generatedaddress = ' + generatedaddress)
	#print(hashlib.sha256(hashlib.sha256(generatedaddress).digest()).digest()[:4])
	#print(addresshash)
	#assert hashlib.sha256(hashlib.sha256(generatedaddress).digest()).digest()[:4] == addresshash
	return
Exemplo n.º 5
0
def genBIPKey(passphrase, entropy='', privateKey=''):
    """
        Generate a BIP38 private key + public addresses
    """
    # generate the private and public keys
    if privateKey == '':
        privateKey = int(rand.randomKey(rand.entropy(entropy)))
    privK256 = enc.encode(privateKey, 256, 32)
    bPublicAddress, sPublicAddress = address.publicKey2Address(
        address.privateKey2PublicKey(privateKey))
    #BIP38 encryption
    BIP = bip38.encrypt(privK256, bPublicAddress, sPublicAddress,
                        str(passphrase))
    return BIP, bPublicAddress, sPublicAddress
Exemplo n.º 6
0
def confirmcode(confirmationcode, passphrase):
    """
	A confirmation tool, given a passphrase and a confirmation code, can recalculate the address, verify the address hash, and then assert the following:
	"It is confirmed that Bitcoin address address depends on this passphrase".
	If applicable: "The lot number is lotnumber and the sequence number is sequencenumber."

	To recalculate the address:
	"""
    #decode the confirmationcode to give addresshash, ownerentropy and encryptedpointb
    data = enc.encode(enc.decode(confirmationcode, 58), 256)
    assert hashlib.sha256(hashlib.sha256(
        data[:-4]).digest()).digest()[:4] == data[-4:]
    addresshash = data[6:10]
    ownerentropy = data[10:18]
    encryptedpointb = data[18:51]
    pointbprefix = encryptedpointb[:1]
    pointbx1 = encryptedpointb[1:17]
    pointbx2 = encryptedpointb[17:]

    #1. Derive passfactor using scrypt with ownerentropy and the user's passphrase and use it to recompute passpoint
    prefactor = scrypt.hash(passphrase, ownerentropy[:4], 16384, 8, 8, 32)
    passfactor = hashlib.sha256(
        hashlib.sha256(prefactor + ownerentropy).digest()).digest()
    pub = elip.base10_multiply(elip.G, enc.decode(passfactor, 256))
    passpoint = ('0' + str(2 + (pub[1] % 2)) +
                 enc.encode(pub[0], 16, 64)).decode('hex')

    #2. Derive decryption key for pointb using scrypt with passpoint, addresshash, and ownerentropy
    key = scrypt.hash(passpoint, addresshash + ownerentropy, 1024, 1, 1, 64)
    derivedhalf1 = key[0:32]
    derivedhalf2 = key[32:64]

    #3. Decrypt encryptedpointb to yield pointb
    Aes = aes.Aes(derivedhalf2)
    pointb = pointbprefix + Aes.dec(pointbx1) + Aes.dec(pointbx2)
    print('pointb = ' + pointb.encode('hex'))

    #4. ECMultiply pointb by passfactor. Use the resulting EC point as a public key and hash it into address using either compressed or uncompressed public key
    # methodology as specifid in flagbyte.
    pub = elip.base10_multiply(enc.decode(passfactor, 256),
                               enc.decode(pointb, 256))
    privK = ('0' + str(2 + (pub[1] % 2)) + enc.encode(pub[0], 16, 64))
    generatedaddress = address.publicKey2Address(privK)
    #print(generatedaddress)
    #print(hashlib.sha256(hashlib.sha256(generatedaddress).digest()).digest()[:4])
    #print(addresshash)
    #assert hashlib.sha256(hashlib.sha256(generatedaddress).digest()).digest()[:4] == addresshash
    return
Exemplo n.º 7
0
def decBIPKey(encrypted_privK, passphrase):
    """
        Decrypt an encrypted Private key
        Show the corresponding public address
    """
    privK, addresshash = bip38.decrypt(str(encrypted_privK), str(passphrase))
    privK = enc.decode(privK, 256)
    # calculate the addresses from the key
    bPublicAddress, sPublicAddress = address.publicKey2Address(
        address.privateKey2PublicKey(privK))
    #check our generated address against the address hash from BIP
    if hashlib.sha256(
            hashlib.sha256(bPublicAddress + sPublicAddress).digest()).digest(
            )[0:4] != addresshash:
        return False, False, False
    else:
        return address.privateKey2Wif(privK), bPublicAddress, sPublicAddress
Exemplo n.º 8
0
def vanity(currency, string):
	"""
		Generate a vanity address
	"""
	#using the currencies.json file, get the currency data
	with open('currencies.json', 'r') as dataFile:
		currencies = json.load(dataFile)
	for cur in currencies:
		if cur['currency'] == currency:
			break
	#randomly choose a prefix if multiples exist
	prefixes = cur['prefix'].split('|')
	prefix = prefixes[random.randint(0, (len(prefixes)-1))]
	#generate the private and public keys
	vanityAddress = ''
	while vanityAddress[:(len(string)+1)] != prefix + string:
		privateKey = int(rand.randomKey(random.getrandbits(512)))
		vanityAddress = address.publicKey2Address(address.privateKey2PublicKey(privateKey), int(cur['version']), prefix, int(cur['length']))
		print(vanityAddress)
	print(vanityAddress, privateKey)
	return
Exemplo n.º 9
0
def genBIPKey(currency, passphrase, entropy='', privateKey='', isCompressed=True):
	"""
	Generate a BIP38 privatekey + public address#
	"""
	#using the currencies.json file, get the currency data
	with open('res/json/currencies.json', 'r') as dataFile:
		currencies = json.load(dataFile)
	for cur in currencies:
		if cur['currency'] == currency:
			break
	#randomly choose a prefix if multiples exist
	prefixes = cur['prefix'].split('|') 
	prefix = prefixes[random.randint(0, (len(prefixes) - 1))]
	#generate the private and public keys
	if privateKey == '':
		privateKey = int(rand.randomKey(rand.entropy(entropy)))
	privK256 = enc.encode(privateKey, 256, 32)
	publicAddress = address.publicKey2Address(address.privateKey2PublicKey(privateKey, isCompressed), int(cur['version']), prefix, int(cur['length']))
	#BIP38 encryption
	BIP = bip38.encrypt(privK256, publicAddress, str(passphrase), 8)
	return BIP, publicAddress
Exemplo n.º 10
0
def decBIPKey(encrypted_privK, passphrase, currency):
	"""
	Decrypt an encrypted Private key
	Show the corresponding public address
	"""
	#using the currencies.json file, get the currency data
	with open('res/json/currencies.json', 'r') as dataFile:
		currencies = json.load(dataFile)
	for cur in currencies:
		if cur['currency'] == currency:
			break 
	#randomly choose a prefix if multiples exist
	prefixes = cur['prefix'].split('|')
	prefix = prefixes[random.randint(0, (len(prefixes)-1))]
	#decrypt the BIP key
	PrivK, Addresshash = bip38.decrypt(str(encrypted_privK), str(passphrase), 8)
	PrivK = enc.decode(PrivK, 256)
	#calculate the address from the key
	publicAddress = address.publicKey2Address(address.privateKey2PublicKey(PrivK), int(cur['version']), prefix, int(cur['length']))
	#check our generated address against the address hash from BIP
	if hashlib.sha256(hashlib.sha256(publicAddress).digest()).digest()[0:4] != Addresshash:
		return False, False
	else:
		return address.privateKey2Wif(PrivK, cur['version'], prefix, cur['length']), publicAddress
Exemplo n.º 11
0
def intermediate2privK(intermediate_passphrase_string):
    """
	Steps to create new encrypted private keys given intermediate_passphrase_string from owner
	(so we have ownerentropy, and passpoint, but we do not have passfactor or the passphrase):
	"""

    #get ownerentropy and passpoint from the intermediate key
    #check the checksum en route
    decstring = enc.b58decode(intermediate_passphrase_string)
    checksum = decstring[-4:]
    if checksum != hashlib.sha256(hashlib.sha256(
            decstring[:-4]).digest()).digest()[:4]:
        return False, 'checksum'

    decodedstring = decstring[:-4]
    ownerentropy = decodedstring[8:16]
    passpoint = decodedstring[-33:]
    print(passpoint)

    #1. Set flagbyte.
    #Turn on bit 0x20 if the Bitcoin address will be formed by hashing the compressed public key (optional, saves space, but many Bitcoin implementations aren't compatible with it)
    #Turn on bit 0x04 if ownerentropy contains a value for lotsequence.
    #(While it has no effect on the keypair generation process, the decryption process needs this flag to know how to process ownerentropy)
    flagbyte = chr(
        0b00100000
    )  # 00 EC 1 compressed 00 future 0 has no lotsequence 00 future

    #2. Generate 24 random bytes, call this seedb. Take SHA256(SHA256(seedb)) to yield 32 bytes, call this factorb.
    seedb = os.urandom(24)
    seedb = b'ABCDEFGHIJKLMNOPQRSTUVWX'
    #seedb = bytearray(b'ABCDEFGHIJKLMNOPQRSTUVWX')
    #for c in seedb: print(c)
    factorb = hashlib.sha256(hashlib.sha256(seedb).digest()).digest()

    #3. ECMultiply passpoint by factorb.
    pub = elip.base10_multiply(enc.decode(passpoint, 256),
                               enc.decode(factorb, 256))

    #4. Use the resulting EC point as a public key and hash it into a Bitcoin address using either compressed or uncompressed public key methodology
    # (specify which methodology is used inside flagbyte).
    # This is the generated Bitcoin address, call it generatedaddress.
    publicKey = ('0' + str(2 + (pub[1] % 2)) + enc.encode(pub[0], 16, 64))

    generatedaddress = address.publicKey2Address(
        publicKey)  ## TODO Remember to add in the currency details here

    #5. Take the first four bytes of SHA256(SHA256(generatedaddress)) and call it addresshash.
    addresshash = hashlib.sha256(
        hashlib.sha256(generatedaddress).digest()).digest()[:4]

    #6. Now we will encrypt seedb. Derive a second key from passpoint using scrypt
    #Parameters: passphrase is passpoint provided from the first party (expressed in binary as 33 bytes).
    # salt is addresshash + ownerentropy, n=1024, r=1, p=1, length=64. The "+" operator is concatenation.
    encseedb = scrypt.hash(passpoint, addresshash + ownerentropy, 1024, 1, 1,
                           64)

    #7. Split the result into two 32-byte halves and call them derivedhalf1 and derivedhalf2.
    derivedhalf1 = encseedb[0:32]
    derivedhalf2 = encseedb[32:64]

    #8. Do AES256Encrypt(seedb[0...15] xor derivedhalf1[0...15], derivedhalf2), call the 16-byte result encryptedpart1
    Aes = aes.Aes(derivedhalf2)
    encryptedpart1 = Aes.enc(enc.sxor(seedb[:16], derivedhalf1[:16]))

    #9. Do AES256Encrypt((encryptedpart1[8...15] + seedb[16...23]) xor derivedhalf1[16...31], derivedhalf2), call the 16-byte result encryptedpart2.
    # The "+" operator is concatenation.
    encryptedpart2 = Aes.enc(
        enc.sxor(encryptedpart1[8:16] + seedb[16:24], derivedhalf1[16:32]))

    #10. The encrypted private key is the Base58Check-encoded concatenation of the following, which totals 39 bytes without Base58 checksum:
    #0x01 0x43 + flagbyte + addresshash + ownerentropy + encryptedpart1[0...7] + encryptedpart2
    input = '\x01\x43' + flagbyte + addresshash + ownerentropy + encryptedpart1[
        0:8] + encryptedpart2
    checksum = hashlib.sha256(hashlib.sha256(input).digest()).digest()[:4]
    BIPKey = enc.b58encode(input + checksum)
    cnfrmcode = confirmationcode(flagbyte, addresshash, ownerentropy, factorb,
                                 derivedhalf1, derivedhalf2)
    return BIPKey, generatedaddress, cnfrmcode
Exemplo n.º 12
0
def confirmcode(confirmationcode, passphrase):
	"""
	A confirmation tool, given a passphrase and a confirmation code, can recalculate the address, verify the address hash, and then assert the following:
	"It is confirmed that Bitcoin address address depends on this passphrase".
	If applicable: "The lot number is lotnumber and the sequence number is sequencenumber."

	To recalculate the address:
	"""
	#decode the confirmationcode to give addresshash, ownerentropy and encryptedpointb
	data = enc.encode(enc.decode(confirmationcode,58),256)
	assert hashlib.sha256(hashlib.sha256(data[:-4]).digest()).digest()[:4] == data[-4:]
	addresshash = data[6:10]
	ownerentropy = data[10:18]
	encryptedpointb = data[18:51]
	pointbprefix = encryptedpointb[:1]
	pointbx1 = encryptedpointb[1:17]
	pointbx2 = encryptedpointb[17:]

	#1. Derive passfactor using scrypt with ownerentropy and the user's passphrase and use it to recompute passpoint
	prefactor = scrypt.hash(passphrase, ownerentropy[:4], 16384, 8, 8, 32)
	passfactor = hashlib.sha256(hashlib.sha256(prefactor + ownerentropy).digest()).digest()
	pub = elip.base10_multiply(elip.G, enc.decode(passfactor, 256))
	passpoint = ('0' + str(2 + (pub[1] % 2)) + enc.encode(pub[0], 16, 64)).decode('hex')

	#2. Derive decryption key for pointb using scrypt with passpoint, addresshash, and ownerentropy
	key = scrypt.hash(passpoint, addresshash + ownerentropy, 1024, 1, 1, 64)
	derivedhalf1 = key[0:32]
	derivedhalf2 = key[32:64]

	#3. Decrypt encryptedpointb to yield pointb
	Aes = aes.Aes(derivedhalf2)
	pointb = pointbprefix + Aes.dec(pointbx1) + Aes.dec(pointbx2)
	print('pointb = ' + pointb.encode('hex'))

	#4. ECMultiply pointb by passfactor. Use the resulting EC point as a public key and hash it into address using either compressed or uncompressed public key
	# methodology as specifid in flagbyte.
	pub = elip.base10_multiply(enc.decode(passfactor, 256), enc.decode(pointb, 256))
	privK = ('0' + str(2 + (pub[1] % 2)) + enc.encode(pub[0], 16, 64))
	generatedaddress = address.publicKey2Address(privK)
	#print(generatedaddress)
	#print(hashlib.sha256(hashlib.sha256(generatedaddress).digest()).digest()[:4])
	#print(addresshash)
	#assert hashlib.sha256(hashlib.sha256(generatedaddress).digest()).digest()[:4] == addresshash
	return






	#Decryption
	#
	#Collect encrypted private key and passphrase from user.
	#Derive passfactor using scrypt with ownerentropy and the user's passphrase and use it to recompute passpoint
	#Derive decryption key for seedb using scrypt with passpoint, addresshash, and ownersalt
	#Decrypt encryptedpart2 using AES256Decrypt to yield the last 8 bytes of seedb and the last 8 bytes of encryptedpart1.
	#Decrypt encryptedpart1 to yield the remainder of seedb.
	#Use seedb to compute factorb.
	#Multiply passfactor by factorb mod N to yield the private key associated with generatedaddress.
	#Convert that private key into a Bitcoin address, honoring the compression preference specified in the encrypted key.
	#Hash the Bitcoin address, and verify that addresshash from the encrypted private key record matches the hash. If not, report that the passphrase entry was incorrect.
#