Esempio n. 1
0
def randomKey(entropy):
    """
    256 bit number from equally strong urandom, user entropy, and timer parts
    """
    if entropy.bit_length() < 250:
        print('Insufficient entropy parameter to generate key')
        return False
    from random import SystemRandom

    osrndi = SystemRandom()
    entstr = enc.encode(entropy, 16) + enc.encode(osrndi.getrandbits(512), 256) + str(clockrnd())
    osrnd = SystemRandom(entstr)
    privkey = 0
    while privkey < 1 or privkey > elip.N:
        privkey = enc.decode(hashlib.sha256(enc.encode(osrnd.getrandbits(512), 256)).digest(), 256) ^ osrnd.getrandbits(
            256)
        for lbit in xrange(clockrnd() % 64 + 64):
            clockstr = hex(clockrnd()) + str(clockrnd()) + entstr
            # Slice a moving 256 bit window out of SHA512
            clock32 = hashlib.sha512(clockstr).digest()[1 + (lbit % 29): 33 + (lbit % 29)]
            randhash = hashlib.sha512(enc.encode(osrnd.getrandbits(512), 256)).digest()[
                       0 + (lbit % 31): 32 + (lbit % 31)]
            privkey ^= enc.decode(randhash, 256) ^ enc.decode(clock32, 256) ^ osrndi.getrandbits(256)
            osrnd = SystemRandom(hashlib.sha512(clock32 + randhash + entstr).digest())  # reseed
    return privkey
Esempio n. 2
0
def randomKey(entropy):
    """
    256 bit number from equally strong urandom, user entropy, and timer parts
    """
    if entropy.bit_length() < 250:
        print('Insufficient entropy parameter to generate key')
        return False
    from random import SystemRandom

    osrndi = SystemRandom()
    entstr = enc.encode(entropy, 16) + enc.encode(osrndi.getrandbits(512),
                                                  256) + str(clockrnd())
    osrnd = SystemRandom(entstr)
    privkey = 0
    while privkey < 1 or privkey > elip.N:
        privkey = enc.decode(
            hashlib.sha256(enc.encode(osrnd.getrandbits(512), 256)).digest(),
            256) ^ osrnd.getrandbits(256)
        for lbit in xrange(clockrnd() % 64 + 64):
            clockstr = hex(clockrnd()) + str(clockrnd()) + entstr
            # Slice a moving 256 bit window out of SHA512
            clock32 = hashlib.sha512(clockstr).digest()[1 + (lbit % 29):33 +
                                                        (lbit % 29)]
            randhash = hashlib.sha512(
                enc.encode(osrnd.getrandbits(512),
                           256)).digest()[0 + (lbit % 31):32 + (lbit % 31)]
            privkey ^= enc.decode(randhash, 256) ^ enc.decode(
                clock32, 256) ^ osrndi.getrandbits(256)
            osrnd = SystemRandom(
                hashlib.sha512(clock32 + randhash + entstr).digest())  # reseed
    return privkey
Esempio n. 3
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
Esempio n. 4
0
def privateKey2PublicKey(priv, isCompressed=True):
	""" integer 256 bit ECC private key to hexstring compressed or uncompressed public key
	"""
	pub = elip.base10_multiply(elip.G, priv)
	if isCompressed is True:
		#starts with 2 or 3 based on whether y is even or not
		return '0' + str(2 + (pub[1] % 2)) + enc.encode(pub[0], 16, 64)
	else:
		#starts with 04 and then x and y
		return '04' + enc.encode(pub[0], 16, 64) + enc.encode(pub[1], 16, 64)
Esempio n. 5
0
def privateKey2PublicKey(priv, isCompressed=True):
    """ integer 256 bit ECC private key to hexstring compressed or uncompressed public key
	"""
    pub = elip.base10_multiply(elip.G, priv)
    if isCompressed is True:
        #starts with 2 or 3 based on whether y is even or not
        return '0' + str(2 + (pub[1] % 2)) + enc.encode(pub[0], 16, 64)
    else:
        #starts with 04 and then x and y
        return '04' + enc.encode(pub[0], 16, 64) + enc.encode(pub[1], 16, 64)
Esempio 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".

	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
Esempio n. 7
0
def privateKey2Wif(privateKey,
                   version=0,
                   prefix=1,
                   length=0,
                   isCompressed=True):
    if isCompressed is True:
        return base58Encode(
            enc.encode(privateKey, 256, 32) + '\x01', (128 + int(version)),
            prefix, length)
    else:
        return base58Encode(enc.encode(privateKey, 256, 32),
                            (128 + int(version)), prefix, length)
Esempio n. 8
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
Esempio n. 9
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
Esempio n. 10
0
def confirmationcode(flagbyte, addresshash, ownerentropy, factorb,
                     derivedhalf1, derivedhalf2):
    """
	The party generating the Bitcoin address has the option to return a confirmation code back to owner which allows owner
	to independently verify that he has been given a Bitcoin address that actually depends on his passphrase,
	and to confirm the lot and sequence numbers (if applicable).
	This protects owner from being given a Bitcoin address by the second party that is unrelated to the key derivation and possibly spendable by the second party.
	If a Bitcoin address given to owner can be successfully regenerated through the confirmation process,
	owner can be reasonably assured that any spending without the passphrase is infeasible.
	This confirmation code is 75 characters starting with "cfrm38".

	To generate it, we need flagbyte, addresshash, ownerentropy, factorb, derivedhalf1 and derivedhalf2 from the original encryption operation.
	"""
    #1. ECMultiply factorb by G, call the result pointb. The result is 33 bytes (compressed key format).
    pub = elip.base10_multiply(elip.G, enc.decode(factorb, 256))
    pointb = ('0' + str(2 + (pub[1] % 2)) + enc.encode(pub[0], 16, 64))[:33]

    #2. The first byte is 0x02 or 0x03. XOR it by (derivedhalf2[31] & 0x01), call the resulting byte pointbprefix.
    pointbprefix = enc.sxor(pointb[:1], str(derivedhalf2[31]) + '\x01')

    #3. Do AES256Encrypt(pointb[1...16] xor derivedhalf1[0...15], derivedhalf2) and call the result pointbx1.
    Aes = aes.Aes(derivedhalf2)
    pointbx1 = Aes.enc(enc.sxor(pointb[1:17], derivedhalf1[0:16]))

    #4. Do AES256Encrypt(pointb[17...32] xor derivedhalf1[16...31], derivedhalf2) and call the result pointbx2.
    pointbx2 = Aes.enc(enc.sxor(pointb[17:33], derivedhalf1[16:32]))

    #5. Concatenate pointbprefix + pointbx1 + pointbx2 (total 33 bytes) and call the result encryptedpointb.
    encryptedpointb = pointbprefix + pointbx1 + pointbx2

    #6. The result is a Base58Check-encoded concatenation of the following:
    #0x64 0x3B 0xF6 0xA8 0x9A + flagbyte + addresshash + ownerentropy + encryptedpointb
    inp_fmtd = '\x64\x3B\xF6\xA8\x9A' + flagbyte + addresshash + ownerentropy + encryptedpointb
    check = hashlib.sha256(hashlib.sha256(inp_fmtd).digest()).digest()[:4]
    return enc.b58encode(inp_fmtd + check)
Esempio n. 11
0
def confirmationcode(flagbyte, addresshash, ownerentropy, factorb, derivedhalf1, derivedhalf2):
	"""
	The party generating the Bitcoin address has the option to return a confirmation code back to owner which allows owner
	to independently verify that he has been given a Bitcoin address that actually depends on his passphrase,
	and to confirm the lot and sequence numbers (if applicable).
	This protects owner from being given a Bitcoin address by the second party that is unrelated to the key derivation and possibly spendable by the second party.
	If a Bitcoin address given to owner can be successfully regenerated through the confirmation process,
	owner can be reasonably assured that any spending without the passphrase is infeasible.
	This confirmation code is 75 characters starting with "cfrm38".

	To generate it, we need flagbyte, addresshash, ownerentropy, factorb, derivedhalf1 and derivedhalf2 from the original encryption operation.
	"""
	#1. ECMultiply factorb by G, call the result pointb. The result is 33 bytes (compressed key format).
	pub = elip.base10_multiply(elip.G, enc.decode(factorb, 256))
	pointb = ('0' + str(2 + (pub[1] % 2)) + enc.encode(pub[0], 16, 64))[:33]

	#2. The first byte is 0x02 or 0x03. XOR it by (derivedhalf2[31] & 0x01), call the resulting byte pointbprefix.
	pointbprefix = enc.sxor(pointb[:1], str(derivedhalf2[31]) + '\x01')

	#3. Do AES256Encrypt(pointb[1...16] xor derivedhalf1[0...15], derivedhalf2) and call the result pointbx1.
	Aes = aes.Aes(derivedhalf2)
	pointbx1 = Aes.enc(enc.sxor(pointb[1:17], derivedhalf1[0:16]))

	#4. Do AES256Encrypt(pointb[17...32] xor derivedhalf1[16...31], derivedhalf2) and call the result pointbx2.
	pointbx2 = Aes.enc(enc.sxor(pointb[17:33], derivedhalf1[16:32]))

	#5. Concatenate pointbprefix + pointbx1 + pointbx2 (total 33 bytes) and call the result encryptedpointb.
	encryptedpointb = pointbprefix + pointbx1 + pointbx2

	#6. The result is a Base58Check-encoded concatenation of the following:
	#0x64 0x3B 0xF6 0xA8 0x9A + flagbyte + addresshash + ownerentropy + encryptedpointb
	inp_fmtd = '\x64\x3B\xF6\xA8\x9A' + flagbyte + addresshash + ownerentropy + encryptedpointb
	check = hashlib.sha256(hashlib.sha256(inp_fmtd).digest()).digest()[:4]
	return enc.b58encode(inp_fmtd + check)
Esempio n. 12
0
def base58Encode(r160, magicbyte=0, prefix=1, length=0):
	""" Base58 encoding w leading zero compact
	"""
	from re import match as re_match
	inp_fmtd = chr(int(magicbyte if magicbyte < 255 else 255)) + r160
	leadingzbytes = len(re_match('^\x00*', inp_fmtd).group(0))
	checksum = hashlib.sha256(hashlib.sha256(inp_fmtd).digest()).digest()[:4]
	return str(prefix) * leadingzbytes + enc.encode(enc.decode(inp_fmtd + checksum, 256), 58, 0)
Esempio n. 13
0
def generate(cur, bip=False):
	"""
		public and private key generator.
		optional BIP0038 encryption
	"""
	#check that the given currency is in the system
	conn = db.open()
	c = conn.cursor()
	#pull the version details from the database
	c.execute('select v.version,v.prefix,v.length,c.id,c.longName,c.version from inuit_versions as v inner join inuit_currencies as c on c.version = v.id where c.currency=?;', (cur.upper(),))
	version = c.fetchone()
	if version is None:
		print(cur.upper() + ' is not currently listed as a currency')
		return False
	#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(inp.keyboardEntropy())
	privK256 = enc.encode(privateKey, 256, 32)
	publicAddress = publicKey2Address(privateKey2PublicKey(privateKey), version[0], prefix,  version[2])
	#optional BIP0038 encryption
	get.flushKeybuffer(get._Getch())
	encrypt = 'y'
	if encrypt == 'y':
		bipPass1 = 'pass1' 
		bipPass2 = 'pass2'
		while bipPass1 != bipPass2 or len(bipPass1) < 1:
			bipPass1 = inp.secure_passphrase('Enter your BIP0038 passphrase')
			bipPass2 = inp.secure_passphrase('Re-enter your passphrase to confirm')
			if bipPass1 != bipPass2:
				print('The passphrases entered did not match.')
			elif len(bipPass1) < 1:
				print('No passphrase was entered!')
		reminder = raw_input('Enter an optional reminder for your password : '******'')
		#print('Enter the number of rounds of encryption.')
		#p = raw_input('A smaller number means quicker but less secure. (8) : ').strip()
		#p = 8 if p == '' else int(p)
		p = 8
		privK = bip38.encrypt(privK256, publicAddress, bipPass1, p)
		isBip = True
	else:
		privK = privateKey
		isBip = False
	#save details to the database
	c.execute('insert into inuit_privK (privK, currency) values (?,?);', (str(privK).encode('base64','strict'), version[3]))
	privKid = c.lastrowid
	c.execute('insert into inuit_addresses (address, currency) values (?,?);', (publicAddress.encode('base64','strict'), version[3]))
	addId = c.lastrowid
	c.execute('insert into inuit_master (address, privK, version) values (?,?,?);', (addId, privKid, version[5]))
	if isBip is True:
		c.execute('insert into inuit_bip (privK, reminder, p) values (?,?,?);', (privKid, reminder, p))
	db.close(conn)
	print('')
	print(version[4] + ' Address : ' + publicAddress)
	return privK, publicAddress
Esempio n. 14
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
Esempio n. 15
0
def base58Encode(r160, magicbyte=0, prefix=1, length=0):
    """ Base58 encoding w leading zero compact
	"""
    from re import match as re_match
    inp_fmtd = chr(int(magicbyte if magicbyte < 255 else 255)) + r160
    leadingzbytes = len(re_match('^\x00*', inp_fmtd).group(0))
    checksum = hashlib.sha256(hashlib.sha256(inp_fmtd).digest()).digest()[:4]
    return str(prefix) * leadingzbytes + enc.encode(
        enc.decode(inp_fmtd + checksum, 256), 58, 0)
Esempio n. 16
0
def dumpPrivKey(address):
	'''
		retrieve private key from database for given address
		option to decrypt BIP0038 encrypted keys
		display as base58 and WIF
	'''
	conn = db.open()
	c = conn.cursor()
	#get the needed data from the database
	c.execute('select p.id,p.privK,v.version,v.prefix,v.length,c.longName from eskimo_privK as p inner join eskimo_master as m on p.id = m.privK inner join eskimo_addresses as a on a.id = m.address inner join eskimo_currencies as c on p.currency = c.id inner join eskimo_versions as v on c.version = v.id where a.address=?;', (address.encode('base64', 'strict'),))
	privData = c.fetchone()
	if privData is None:
		print(address + ' was not found')
		return False
	#check if the private key is bip encoded and get the password reminder if it is
	c.execute('select reminder, p from eskimo_bip where privK=?;', (privData[0],))
	bip = c.fetchone()
	if bip is None:
		isBip = False
	else:
		isBip = True
		reminder = bip[0]
		p = bip[1]
	privK = privData[1].decode('base64', 'strict')
	#ask if the user wants to decrypt a bip encrypted key
	if isBip:
		print('The private key found is BIP0038 encrypted.')
		decrypt = raw_input('Would you like to decrypt it? (n) ').lower().strip()
		if decrypt == 'y':
			bipPass1 = 'pass1' 
			bipPass2 = 'pass2'
			while bipPass1 != bipPass2 or len(bipPass1) < 1:
				bipPass1 = inp.secure_passphrase('Enter your BIP0038 passphrase ' + ('(' + bip[0] + ')' if bip[0] != '' else ''))
				bipPass2 = inp.secure_passphrase('Re-enter your passphrase to confirm')
				if bipPass1 != bipPass2:
					print('The passphrases entered did not match.')
				elif len(bipPass1) < 1:
					print('No passphrase was entered')
			#decrypt the private key using the supplied password
			privK, addresshash = bip38.decrypt(privK, bipPass1, p)
			#decode the privK from base 256
			privK = enc.decode(privK, 256)
			#hash the address to check the decryption
			address = publicKey2Address(privateKey2PublicKey(privK), privData[2], privData[3], privData[4])
			if hashlib.sha256(hashlib.sha256(address).digest()).digest()[0:4] != addresshash:
				print('\nUnable to decrypt.')
				print('Please try again with a different passphrase.')
				return False
		else:
			print('\n' + privData[5] + ' Address = ' + str(address))
			print('\nBIP0038 encrypted private key : ' + privK)
			return True	
	print('\n' + privData[5] + ' Address = ' + str(address))			
	print('\nPrivate key : ')
	print('HEX : ' + enc.encode(privK, 16))
	print('WIF : ' + privateKey2Wif(privK, privData[2], privData[3], privData[4]))
	return True
Esempio n. 17
0
def intermediate(passphrase):
    """
	Encrypting a private key with EC multiplication offers the ability for someone to generate encrypted keys knowing only an EC point derived from the original passphrase and
	some salt generated by the passphrase's owner, and without knowing the passphrase itself.
	Only the person who knows the original passphrase can decrypt the private key.
	A code known as an intermediate code conveys the information needed to generate such a key without knowledge of the passphrase.

	This methodology does not offer the ability to encrypt a known private key - this means that the process of creating encrypted keys is also the process of generating new addresses.
	On the other hand, this serves a security benefit for someone possessing an address generated this way:
	if the address can be recreated by decrypting its private key with a passphrase, and it's a strong passphrase one can be certain only he knows himself,
	then he can safely conclude that nobody could know the private key to that address.

	The person who knows the passphrase and who is the intended beneficiary of the private keys is called the owner.
	He will generate one or more "intermediate codes", which are the first factor of a two-factor redemption system, and will give them to someone else we'll call printer,
	who generates a key pair with an intermediate code can know the address and encrypted private key, but cannot decrypt the private key without the original passphrase.

	An intermediate code should, but is not required to, embed a printable "lot" and "sequence" number for the benefit of the user.
	The proposal forces these lot and sequence numbers to be included in any valid private keys generated from them.
	An owner who has requested multiple private keys to be generated for him will be advised by applications to ensure that each private key has a unique lot and sequence number
	consistent with the intermediate codes he generated.
	These mainly help protect owner from potential mistakes and/or attacks that could be made by printer.

	The "lot" and "sequence" number are combined into a single 32 bit number.
	20 bits are used for the lot number and 12 bits are used for the sequence number,
	such that the lot number can be any decimal number between 0 and 1048575, and the sequence number can be any decimal number between 0 and 4095.
	For programs that generate batches of intermediate codes for an owner,
	it is recommended that lot numbers be chosen at random within the range 100000-999999 and that sequence numbers are assigned starting with 1.

	We are not using Lot Sequence and sequence so some changes are made to the instructions

	"""

    #1. Generate 8 random bytes, call them ownerentropy.
    ownerentropy = os.urandom(8)

    #4. Derive a key from the passphrase using scrypt
    #Parameters: passphrase is the passphrase itself encoded in UTF-8. salt is ownersalt. n=16384, r=8, p=8, length=32.
    #Call the resulting 32 bytes passfactor.
    passfactor = scrypt.hash(passphrase, ownerentropy, 16384, 8, 8, 32)

    #6. Compute the elliptic curve point G * passfactor, and convert the result to compressed notation (33 bytes). Call this passpoint.
    #Compressed notation is used for this purpose regardless of whether the intent is to create Bitcoin addresses with or without compressed public keys.
    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')

    #7. Convey ownerentropy and passpoint to the party generating the keys, along with a checksum to ensure integrity.
    #The following Base58Check-encoded format is recommended for this purpose: magic bytes "2C E9 B3 E1 FF 39 E2 53" followed by ownerentropy, and then passpoint.
    #The resulting string will start with the word "passphrase" due to the constant bytes,
    #will be 72 characters in length, and encodes 49 bytes (8 bytes constant + 8 bytes ownerentropy + 33 bytes passpoint).
    #The checksum is handled in the Base58Check encoding. The resulting string is called intermediate_passphrase_string.
    input = '\x2C\xE9\xB3\xE1\xFF\x39\xE2\x53' + ownerentropy + passpoint
    checksum = hashlib.sha256(hashlib.sha256(input).digest()).digest()[:4]
    intermediate_passphrase_string = enc.b58encode(input + checksum)
    return intermediate_passphrase_string
Esempio n. 18
0
def intermediate(passphrase):
	"""
	Encrypting a private key with EC multiplication offers the ability for someone to generate encrypted keys knowing only an EC point derived from the original passphrase and
	some salt generated by the passphrase's owner, and without knowing the passphrase itself.
	Only the person who knows the original passphrase can decrypt the private key.
	A code known as an intermediate code conveys the information needed to generate such a key without knowledge of the passphrase.

	This methodology does not offer the ability to encrypt a known private key - this means that the process of creating encrypted keys is also the process of generating new addresses.
	On the other hand, this serves a security benefit for someone possessing an address generated this way:
	if the address can be recreated by decrypting its private key with a passphrase, and it's a strong passphrase one can be certain only he knows himself,
	then he can safely conclude that nobody could know the private key to that address.

	The person who knows the passphrase and who is the intended beneficiary of the private keys is called the owner.
	He will generate one or more "intermediate codes", which are the first factor of a two-factor redemption system, and will give them to someone else we'll call printer,
	who generates a key pair with an intermediate code can know the address and encrypted private key, but cannot decrypt the private key without the original passphrase.

	An intermediate code should, but is not required to, embed a printable "lot" and "sequence" number for the benefit of the user.
	The proposal forces these lot and sequence numbers to be included in any valid private keys generated from them.
	An owner who has requested multiple private keys to be generated for him will be advised by applications to ensure that each private key has a unique lot and sequence number
	consistent with the intermediate codes he generated.
	These mainly help protect owner from potential mistakes and/or attacks that could be made by printer.

	The "lot" and "sequence" number are combined into a single 32 bit number.
	20 bits are used for the lot number and 12 bits are used for the sequence number,
	such that the lot number can be any decimal number between 0 and 1048575, and the sequence number can be any decimal number between 0 and 4095.
	For programs that generate batches of intermediate codes for an owner,
	it is recommended that lot numbers be chosen at random within the range 100000-999999 and that sequence numbers are assigned starting with 1.

	We are not using Lot Sequence and sequence so some changes are made to the instructions

	"""

	#1. Generate 8 random bytes, call them ownerentropy.
	ownerentropy = os.urandom(8)

	#4. Derive a key from the passphrase using scrypt
	#Parameters: passphrase is the passphrase itself encoded in UTF-8. salt is ownersalt. n=16384, r=8, p=8, length=32.
	#Call the resulting 32 bytes passfactor.
	passfactor = scrypt.hash(passphrase, ownerentropy, 16384, 8, 8, 32)

	#6. Compute the elliptic curve point G * passfactor, and convert the result to compressed notation (33 bytes). Call this passpoint.
	#Compressed notation is used for this purpose regardless of whether the intent is to create Bitcoin addresses with or without compressed public keys.
	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')

	#7. Convey ownerentropy and passpoint to the party generating the keys, along with a checksum to ensure integrity.
	#The following Base58Check-encoded format is recommended for this purpose: magic bytes "2C E9 B3 E1 FF 39 E2 53" followed by ownerentropy, and then passpoint.
	#The resulting string will start with the word "passphrase" due to the constant bytes,
	#will be 72 characters in length, and encodes 49 bytes (8 bytes constant + 8 bytes ownerentropy + 33 bytes passpoint).
	#The checksum is handled in the Base58Check encoding. The resulting string is called intermediate_passphrase_string.
	input = '\x2C\xE9\xB3\xE1\xFF\x39\xE2\x53' + ownerentropy + passpoint
	checksum = hashlib.sha256(hashlib.sha256(input).digest()).digest()[:4]
	intermediate_passphrase_string = enc.b58encode(input + checksum)
	return intermediate_passphrase_string
Esempio n. 19
0
def privKeyVersion(privK, cur, isCompressed = True):
	"""
		determine what sort of private key we have
		convert it to raw (base 10) and return

		No need to alert to a bad checksum as this should have already been checked in the input check
	"""
	isWIF, comment = isWif(privK, cur)
	if isWIF is True:
		if isCompressed is True:
			privK = enc.decode(enc.encode(enc.decode(privK, 58), 256)[1:-5], 256)
		else:
			privK = enc.decode(enc.encode(enc.decode(privK, 58), 256)[1:-4], 256)
	elif isHex(privK):
		privK = enc.decode(privK, 16)
	elif isBase64(privK):
		privK = privK.decode('base64', 'strict')
	elif isBase6(privK):
		privK = privK.decode('base6', 'strict')
	return privK
Esempio n. 20
0
def privKeyVersion(privK, cur, isCompressed=True):
    """
		determine what sort of private key we have
		convert it to raw (base 10) and return

		No need to alert to a bad checksum as this should have already been checked in the input check
	"""
    isWIF, comment = isWif(privK, cur)
    if isWIF is True:
        if isCompressed is True:
            privK = enc.decode(
                enc.encode(enc.decode(privK, 58), 256)[1:-5], 256)
        else:
            privK = enc.decode(
                enc.encode(enc.decode(privK, 58), 256)[1:-4], 256)
    elif isHex(privK):
        privK = enc.decode(privK, 16)
    elif isBase64(privK):
        privK = privK.decode('base64', 'strict')
    elif isBase6(privK):
        privK = privK.decode('base6', 'strict')
    return privK
Esempio n. 21
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
Esempio n. 22
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
Esempio n. 23
0
def dumpPrivKey(address):
    """
		retrieve private key from database for given address
		option to decrypt BIP0038 encrypted keys
		display as base58 and WIF
	"""
    conn = db.open()
    c = conn.cursor()
    # get the needed data from the database
    c.execute(
        "select p.id,p.privK,v.version,v.prefix,v.length,c.longName from inuit_privK as p inner join inuit_master as m on p.id = m.privK inner join inuit_addresses as a on a.id = m.address inner join inuit_currencies as c on p.currency = c.id inner join inuit_versions as v on c.version = v.id where a.address=?;",
        (address.encode("base64", "strict"),),
    )
    privData = c.fetchone()
    if privData is None:
        print(address + " was not found")
        return False
        # check if the private key is bip encoded and get the password reminder if it is
    c.execute("select reminder, p from inuit_bip where privK=?;", (privData[0],))
    bip = c.fetchone()
    if bip is None:
        isBip = False
    else:
        isBip = True
        reminder = bip[0]
        p = bip[1]
    privK = privData[1].decode("base64", "strict")
    # ask if the user wants to decrypt a bip encrypted key
    if isBip:
        print("The private key found is BIP0038 encrypted.")
        decrypt = raw_input("Would you like to decrypt it? (n) ").lower().strip()
        if decrypt == "y":
            bipPass1 = "pass1"
            bipPass2 = "pass2"
            while bipPass1 != bipPass2 or len(bipPass1) < 1:
                bipPass1 = inp.secure_passphrase(
                    "Enter your BIP0038 passphrase " + ("(" + bip[0] + ")" if bip[0] != "" else "")
                )
                bipPass2 = inp.secure_passphrase("Re-enter your passphrase to confirm")
                if bipPass1 != bipPass2:
                    print("The passphrases entered did not match.")
                elif len(bipPass1) < 1:
                    print("No passphrase was entered")
                    # decrypt the private key using the supplied password
            privK, addresshash = bip38.decrypt(privK, bipPass1, p)
            # decode the privK from base 256
            privK = enc.decode(privK, 256)
            # hash the address to check the decryption
            address = publicKey2Address(privateKey2PublicKey(privK), privData[2], privData[3], privData[4])
            if hashlib.sha256(hashlib.sha256(address).digest()).digest()[0:4] != addresshash:
                print("\nUnable to decrypt.")
                print("Please try again with a different passphrase.")
                return False
        else:
            print("\n" + privData[5] + " Address = " + str(address))
            print("\nBIP0038 encrypted private key : " + privK)
            return True
    print("\n" + privData[5] + " Address = " + str(address))
    print("\nPrivate key : ")
    print("HEX : " + enc.encode(privK, 16))
    print("WIF : " + privateKey2Wif(privK, privData[2], privData[3], privData[4]))
    return True
Esempio n. 24
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.
#
Esempio n. 25
0
def privateKey2Wif(privateKey, version=0, prefix=1, length=0):
	"""
	convert a private key to WIF format
	"""
	return base58Encode(enc.encode(privateKey, 256, 32) + '\x01', (128+int(version)), prefix, length)
Esempio n. 26
0
def privateKey2PublicKey(priv):
	""" integer 256 bit ECC private key to hexstring compressed public key
	"""
	pub = elip.base10_multiply(elip.G, priv)
	return '0' + str(2 + (pub[1] % 2)) + enc.encode(pub[0], 16, 64)
Esempio n. 27
0
def privateKey2Wif(privateKey, version=0, prefix=1, length=0):
	return base58Encode(enc.encode(privateKey, 256, 32) + '\x01', (128+int(version)), prefix, length)
Esempio n. 28
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
Esempio n. 29
0
def privateKey2Wif(privateKey, version=0, prefix=1, length=0, isCompressed=True):
	if isCompressed is True:
		return base58Encode(enc.encode(privateKey, 256, 32) + '\x01', (128+int(version)), prefix, length)
	else:
		return base58Encode(enc.encode(privateKey, 256, 32), (128+int(version)), prefix, length)
Esempio n. 30
0
def privateKey2Wif(privateKey, compressed=True):
    """
        Return private key in compressed WIF format
    """
    return base58Encode(enc.encode(privateKey, 256, 32) + '\x01', 191, 'B')
Esempio n. 31
0
def privateKey2Wif(privateKey, compressed=True):
    """
        Return private key in compressed WIF format
    """
    return base58Encode(enc.encode(privateKey, 256, 32) + '\x01', 191, 'B')
Esempio n. 32
0
def privateKey2PublicKey(priv, compressed=True):
    """
        integer 256 bit ECC private key to hexstring compressed public key
    """
    pub = elip.base10_multiply(elip.G, priv)
    return '0' + str(2 + (pub[1] % 2)) + enc.encode(pub[0], 16, 64)