예제 #1
0
def decrypt(encrypted_privkey, passphrase):
    # 1. Collect encrypted private key and passphrase from user.
    #	passed as parameters
    data = enc.b58decode(encrypted_privkey)
    flagbyte = data[2:3]
    check = data[-4:]
    if check != hashlib.sha256(hashlib.sha256(data[:-4]).digest()).digest()[:4]:
        return False, 'checksum'

    addresshash = data[3:7]
    encryptedhalf1 = data[7:23]
    encryptedhalf2 = data[23:39]

    #3. Derive decryption key for seedb using scrypt with passpoint, addresshash, and ownersalt
    key = scrypt.hash(passphrase, addresshash, 16384, 8, 8)

    derivedhalf1 = key[0:32]
    derivedhalf2 = key[32:64]

    #4. Decrypt encryptedpart2 using AES256Decrypt to yield the last 8 bytes of seedb and the last 8 bytes of encryptedpart1.
    Aes = aes.Aes(derivedhalf2)
    decryptedhalf2 = Aes.dec(encryptedhalf2)

    #5. Decrypt encryptedpart1 to yield the remainder of seedb.
    decryptedhalf1 = Aes.dec(encryptedhalf1)

    priv = decryptedhalf1 + decryptedhalf2
    priv = binascii.unhexlify('%064x' % (long(binascii.hexlify(priv), 16) ^ long(binascii.hexlify(derivedhalf1), 16)))
    return priv, addresshash
예제 #2
0
파일: bip38.py 프로젝트: imcoddy/bippy
def decrypt(encrypted_privkey, passphrase, p):

    #1. Collect encrypted private key and passphrase from user.
    #	passed as parameters
    #2. Derive passfactor using scrypt with ownersalt and the user's passphrase and use it to recompute passpoint
    d = enc.b58decode(encrypted_privkey)
    d = d[2:]
    flagbyte = d[0:1]
    d = d[1:]
    addresshash = d[0:4]
    d = d[4:-4]

    #3. Derive decryption key for seedb using scrypt with passpoint, addresshash, and ownersalt
    key = scrypt.hash(passphrase, addresshash, 16384, 8, p)
    derivedhalf1 = key[0:32]
    derivedhalf2 = key[32:64]
    encryptedhalf1 = d[0:16]
    encryptedhalf2 = d[16:32]

    #4. Decrypt encryptedpart2 using AES256Decrypt to yield the last 8 bytes of seedb and the last 8 bytes of encryptedpart1.
    Aes = aes.Aes(derivedhalf2)
    decryptedhalf2 = Aes.dec(encryptedhalf2)

    #5. Decrypt encryptedpart1 to yield the remainder of seedb.
    decryptedhalf1 = Aes.dec(encryptedhalf1)
    priv = decryptedhalf1 + decryptedhalf2
    priv = binascii.unhexlify('%064x' %
                              (long(binascii.hexlify(priv), 16)
                               ^ long(binascii.hexlify(derivedhalf1), 16)))
    return priv, addresshash
예제 #3
0
def encrypt(pub_address, passphrase):
	"""
		Encrypt the public address
	"""

	#1 base 58 decode the public address
	address = enc.b58decode(pub_address)

	#2. Take a hash of the decoded address to act as a scrypt salt
	salt = hashlib.sha256(hashlib.sha256(address).digest()).digest()[:4]

	#2. Derive a key from the passphrase using scrypt
	key = scrypt.hash(passphrase, salt, 16384, 8, 8)

	#3. Split the key into half 1 and half 2
	derivedhalf1 = key[0:32]
	derivedhalf2 = key[32:64]

	#4 AES encrypt address halves as per bip38
	halflength = int(math.floor(len(address) / 2))
	Aes = aes.Aes(derivedhalf2)
	#for Aes encryption, string needs to have length = 16
	xorhalf1 = enc.sxor(address[:halflength], derivedhalf1[:16]).ljust(16, '0')
	xorhalf2 = enc.sxor(address[halflength:], derivedhalf1[16:32]).ljust(16, '0')
	encryptedhalf1 = Aes.enc(xorhalf1)
	encryptedhalf2 = Aes.enc(xorhalf2)

	#5. The encrypted private key is the Base58Check-encoded concatenation of the following
	# \x78\x8e\xa3\x69\xb6 + address_length + salt + encryptedhalf1 + encryptedhalf2
	encAddress = '\x78\x8e\xa3\x69\xb6' + chr(len(address)) + salt + encryptedhalf1 + encryptedhalf2
	check = hashlib.sha256(hashlib.sha256(encAddress).digest()).digest()[:4]
	return enc.b58encode(encAddress + check)
예제 #4
0
파일: bip38.py 프로젝트: inuitwallet/inuit
def decrypt(encrypted_privkey, passphrase, p):
	"""
	decrypt a bip0038 encrypted private key
	return the key and address hash for adress verification
	"""
	
	print('Decrypting private key...')
	#1. Collect encrypted private key and passphrase from user.
	#	passed as parameters
	#2. Derive passfactor using scrypt with ownersalt and the user's passphrase and use it to recompute passpoint
	d = enc.b58decode(encrypted_privkey)
	d = d[2:]
	flagbyte = d[0:1]
	d = d[1:]
	addresshash = d[0:4]
	d = d[4:-4]	
	
	#3. Derive decryption key for seedb using scrypt with passpoint, addresshash, and ownersalt
	key = scrypt.hash(passphrase,addresshash, 16384, 8, p)
	derivedhalf1 = key[0:32]
	derivedhalf2 = key[32:64]
	encryptedhalf1 = d[0:16]
	encryptedhalf2 = d[16:32]
	Aes = aes.Aes(derivedhalf2)
	
	#4. Decrypt encryptedpart2 using AES256Decrypt to yield the last 8 bytes of seedb and the last 8 bytes of encryptedpart1.
	decryptedhalf2 = Aes.dec(encryptedhalf2)
	
	#5. Decrypt encryptedpart1 to yield the remainder of seedb.
	decryptedhalf1 = Aes.dec(encryptedhalf1)
	priv = decryptedhalf1 + decryptedhalf2
	priv = binascii.unhexlify('%064x' % (long(binascii.hexlify(priv), 16) ^ long(binascii.hexlify(derivedhalf1), 16)))
	return priv, addresshash
예제 #5
0
def encrypt(pub_address, passphrase):
    """
		Encrypt the public address
	"""

    #1 base 58 decode the public address
    address = enc.b58decode(pub_address)

    #2. Take a hash of the decoded address to act as a scrypt salt
    salt = hashlib.sha256(hashlib.sha256(address).digest()).digest()[:4]

    #2. Derive a key from the passphrase using scrypt
    key = scrypt.hash(passphrase, salt, 16384, 8, 8)

    #3. Split the key into half 1 and half 2
    derivedhalf1 = key[0:32]
    derivedhalf2 = key[32:64]

    #4 AES encrypt address halves as per bip38
    halflength = int(math.floor(len(address) / 2))
    Aes = aes.Aes(derivedhalf2)
    #for Aes encryption, string needs to have length = 16
    xorhalf1 = enc.sxor(address[:halflength], derivedhalf1[:16]).ljust(16, '0')
    xorhalf2 = enc.sxor(address[halflength:],
                        derivedhalf1[16:32]).ljust(16, '0')
    encryptedhalf1 = Aes.enc(xorhalf1)
    encryptedhalf2 = Aes.enc(xorhalf2)

    #5. The encrypted private key is the Base58Check-encoded concatenation of the following
    # \x78\x8e\xa3\x69\xb6 + address_length + salt + encryptedhalf1 + encryptedhalf2
    encAddress = '\x78\x8e\xa3\x69\xb6' + chr(
        len(address)) + salt + encryptedhalf1 + encryptedhalf2
    check = hashlib.sha256(hashlib.sha256(encAddress).digest()).digest()[:4]
    return enc.b58encode(encAddress + check)
예제 #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".

	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
예제 #7
0
def checkChecksum(key):
    """
        requires a base58_Check encoded string.
        calculates the hash of the key and compare to the checksum
    """
    # decode to base256
    checkKey = enc.b58decode(key)
    checksum = checkKey[-4:]
    hash = hashlib.sha256(hashlib.sha256(checkKey[:-4]).digest()).digest()[:4]
    if hash == checksum:
        return True
    else:
        return False
예제 #8
0
파일: bip38.py 프로젝트: inuitwallet/bippy
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
예제 #9
0
def decrypt(encSeed, passphrase):
    """
		Decrypt an Electrum seed encrypted with the above method
	"""
    #1. Base 58 decrypt the encrypted key
    # get the two encrypted halves, the check and the salt
    decSeed = enc.b58decode(encSeed)
    check = decSeed[-4:]
    #check that it's not been tampered with
    if check != hashlib.sha256(hashlib.sha256(
            decSeed[:-4]).digest()).digest()[:4]:
        return False, 'checksum'

    salt = decSeed[4:8]
    encryptedhalfs = decSeed[8:len(decSeed) - 4]
    encryptedhalf1 = encryptedhalfs[0:int(math.floor(len(encryptedhalfs) / 2))]
    encryptedhalf2 = encryptedhalfs[int(math.floor(len(encryptedhalfs) / 2)):]

    #2. Derive the decryption key using scrypt
    key = scrypt.hash(passphrase, salt, 16384, 8, 8)
    derivedhalf1 = key[0:32]
    derivedhalf2 = key[32:64]

    #3. Decrypt the encrypted halves
    Aes = aes.Aes(derivedhalf2)
    decryptedhalf1 = Aes.dec(encryptedhalf1)
    decryptedhalf2 = Aes.dec(encryptedhalf2)

    #4 . xor them with the two halves of derivedhalf1 to get the original values
    half1 = enc.sxor(decryptedhalf1, derivedhalf1[:16])
    half2 = enc.sxor(decryptedhalf2, derivedhalf1[16:32])

    #5. build the seed and check it against the check hash
    seed = half1 + half2
    if salt != hashlib.sha256(hashlib.sha256(seed).digest()).digest()[:4]:
        return False, 'salt'

    #6. encode the seed as an Electrum Mnemonic list
    mn = mn_encode(str(seed))

    #6 . return the mnemonic as a single string
    seed = ''
    for word in mn:
        seed += word + ' '
    return True, seed
예제 #10
0
def decrypt(encSeed, passphrase):
	"""
		Decrypt an Electrum seed encrypted with the above method
	"""
	#1. Base 58 decrypt the encrypted key
	# get the two encrypted halves, the check and the salt
	decSeed = enc.b58decode(encSeed)
	check = decSeed[-4:]
	#check that it's not been tampered with
	if check != hashlib.sha256(hashlib.sha256(decSeed[:-4]).digest()).digest()[:4]:
		return False, 'checksum'

	salt = decSeed[4:8]
	encryptedhalfs = decSeed[8:len(decSeed)-4]
	encryptedhalf1 = encryptedhalfs[0:int(math.floor(len(encryptedhalfs) / 2))]
	encryptedhalf2 = encryptedhalfs[int(math.floor(len(encryptedhalfs) / 2)):]

	#2. Derive the decryption key using scrypt
	key = scrypt.hash(passphrase, salt, 16384, 8, 8)
	derivedhalf1 = key[0:32]
	derivedhalf2 = key[32:64]

	#3. Decrypt the encrypted halves
	Aes = aes.Aes(derivedhalf2)
	decryptedhalf1 = Aes.dec(encryptedhalf1)
	decryptedhalf2 = Aes.dec(encryptedhalf2)

	#4 . xor them with the two halves of derivedhalf1 to get the original values
	half1 = enc.sxor(decryptedhalf1, derivedhalf1[:16])
	half2 = enc.sxor(decryptedhalf2, derivedhalf1[16:32])

	#5. build the seed and check it against the check hash
	seed = half1 + half2
	if salt != hashlib.sha256(hashlib.sha256(seed).digest()).digest()[:4]:
		return False, 'salt'

	#6. encode the seed as an Electrum Mnemonic list
	mn = mn_encode(str(seed))

	#6 . return the mnemonic as a single string
	seed = ''
	for word in mn:
		seed += word + ' '
	return True, seed
예제 #11
0
def decrypt(enc_address, passphrase):
    """
		Decrypt an Public Address encrypted with the above method
	"""
    #1. Base 58 decrypt the encrypted key
    # get the two encrypted halves, the check and the salt
    dec_address = enc.b58decode(enc_address)
    check = dec_address[-4:]
    #check that it's not been tampered with
    if check != hashlib.sha256(hashlib.sha256(
            dec_address[:-4]).digest()).digest()[:4]:
        return False, 'checksum'

    length = ord(dec_address[5:6])
    halflength = int(math.floor(length / 2))
    salt = dec_address[6:10]
    encryptedhalfs = dec_address[10:len(dec_address) - 4]
    encryptedhalf1 = encryptedhalfs[:16]
    encryptedhalf2 = encryptedhalfs[16:]

    #2. Derive the decryption key using scrypt
    key = scrypt.hash(passphrase, salt, 16384, 8, 8)
    derivedhalf1 = key[0:32]
    derivedhalf2 = key[32:64]

    #3. Aes decrypt the encrypted halves
    Aes = aes.Aes(derivedhalf2)
    xorhalf1 = Aes.dec(encryptedhalf1)
    xorhalf2 = Aes.dec(encryptedhalf2)

    #4 . xor them with the two halves of derivedhalf1 to get the original values
    half1 = enc.sxor(xorhalf1[:halflength], derivedhalf1[:16])
    half2 = enc.sxor(xorhalf2[:(length - halflength)], derivedhalf1[16:32])

    #5. build the address and check it against the check hash
    pub_address = half1 + half2
    if salt != hashlib.sha256(
            hashlib.sha256(pub_address).digest()).digest()[:4]:
        return False, 'salt'

    #6. return the address as a single string
    return True, enc.b58encode(pub_address)
예제 #12
0
def decrypt(enc_address, passphrase):
	"""
		Decrypt an Public Address encrypted with the above method
	"""
	#1. Base 58 decrypt the encrypted key
	# get the two encrypted halves, the check and the salt
	dec_address = enc.b58decode(enc_address)
	check = dec_address[-4:]
	#check that it's not been tampered with
	if check != hashlib.sha256(hashlib.sha256(dec_address[:-4]).digest()).digest()[:4]:
		return False, 'checksum'

	length = ord(dec_address[5:6])
	halflength = int(math.floor(length / 2))
	salt = dec_address[6:10]
	encryptedhalfs = dec_address[10:len(dec_address) - 4]
	encryptedhalf1 = encryptedhalfs[:16]
	encryptedhalf2 = encryptedhalfs[16:]

	#2. Derive the decryption key using scrypt
	key = scrypt.hash(passphrase, salt, 16384, 8, 8)
	derivedhalf1 = key[0:32]
	derivedhalf2 = key[32:64]

	#3. Aes decrypt the encrypted halves
	Aes = aes.Aes(derivedhalf2)
	xorhalf1 = Aes.dec(encryptedhalf1)
	xorhalf2 = Aes.dec(encryptedhalf2)

	#4 . xor them with the two halves of derivedhalf1 to get the original values
	half1 = enc.sxor(xorhalf1[:halflength], derivedhalf1[:16])
	half2 = enc.sxor(xorhalf2[:(length - halflength)], derivedhalf1[16:32])

	#5. build the address and check it against the check hash
	pub_address = half1 + half2
	if salt != hashlib.sha256(hashlib.sha256(pub_address).digest()).digest()[:4]:
		return False, 'salt'

	#6. return the address as a single string
	return True, enc.b58encode(pub_address)
예제 #13
0
파일: bip38.py 프로젝트: inuitwallet/bippy
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
예제 #14
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