Define functions for generating keys in the highlevelcrypto
This commit is contained in:
parent
d547a8be2f
commit
5c1dcc5645
|
@ -16,7 +16,6 @@ from addresses import decodeAddress, encodeAddress, encodeVarint
|
||||||
from bmconfigparser import config
|
from bmconfigparser import config
|
||||||
from fallback import RIPEMD160Hash
|
from fallback import RIPEMD160Hash
|
||||||
from network import StoppableThread
|
from network import StoppableThread
|
||||||
from pyelliptic.openssl import OpenSSL
|
|
||||||
from tr import _translate
|
from tr import _translate
|
||||||
|
|
||||||
|
|
||||||
|
@ -129,17 +128,13 @@ class addressGenerator(StoppableThread):
|
||||||
# the \x00 or \x00\x00 bytes thus making the address shorter.
|
# the \x00 or \x00\x00 bytes thus making the address shorter.
|
||||||
startTime = time.time()
|
startTime = time.time()
|
||||||
numberOfAddressesWeHadToMakeBeforeWeFoundOneWithTheCorrectRipePrefix = 0
|
numberOfAddressesWeHadToMakeBeforeWeFoundOneWithTheCorrectRipePrefix = 0
|
||||||
potentialPrivSigningKey = OpenSSL.rand(32)
|
privSigningKey, pubSigningKey = highlevelcrypto.random_keys()
|
||||||
potentialPubSigningKey = highlevelcrypto.pointMult(
|
|
||||||
potentialPrivSigningKey)
|
|
||||||
while True:
|
while True:
|
||||||
numberOfAddressesWeHadToMakeBeforeWeFoundOneWithTheCorrectRipePrefix += 1
|
numberOfAddressesWeHadToMakeBeforeWeFoundOneWithTheCorrectRipePrefix += 1
|
||||||
potentialPrivEncryptionKey = OpenSSL.rand(32)
|
potentialPrivEncryptionKey, potentialPubEncryptionKey = \
|
||||||
potentialPubEncryptionKey = highlevelcrypto.pointMult(
|
highlevelcrypto.random_keys()
|
||||||
potentialPrivEncryptionKey)
|
|
||||||
sha = hashlib.new('sha512')
|
sha = hashlib.new('sha512')
|
||||||
sha.update(
|
sha.update(pubSigningKey + potentialPubEncryptionKey)
|
||||||
potentialPubSigningKey + potentialPubEncryptionKey)
|
|
||||||
ripe = RIPEMD160Hash(sha.digest()).digest()
|
ripe = RIPEMD160Hash(sha.digest()).digest()
|
||||||
if (
|
if (
|
||||||
ripe[:numberOfNullBytesDemandedOnFrontOfRipeHash]
|
ripe[:numberOfNullBytesDemandedOnFrontOfRipeHash]
|
||||||
|
@ -164,7 +159,7 @@ class addressGenerator(StoppableThread):
|
||||||
addressVersionNumber, streamNumber, ripe)
|
addressVersionNumber, streamNumber, ripe)
|
||||||
|
|
||||||
privSigningKeyWIF = highlevelcrypto.encodeWalletImportFormat(
|
privSigningKeyWIF = highlevelcrypto.encodeWalletImportFormat(
|
||||||
potentialPrivSigningKey)
|
privSigningKey)
|
||||||
privEncryptionKeyWIF = highlevelcrypto.encodeWalletImportFormat(
|
privEncryptionKeyWIF = highlevelcrypto.encodeWalletImportFormat(
|
||||||
potentialPrivEncryptionKey)
|
potentialPrivEncryptionKey)
|
||||||
|
|
||||||
|
@ -238,18 +233,15 @@ class addressGenerator(StoppableThread):
|
||||||
numberOfAddressesWeHadToMakeBeforeWeFoundOneWithTheCorrectRipePrefix = 0
|
numberOfAddressesWeHadToMakeBeforeWeFoundOneWithTheCorrectRipePrefix = 0
|
||||||
while True:
|
while True:
|
||||||
numberOfAddressesWeHadToMakeBeforeWeFoundOneWithTheCorrectRipePrefix += 1
|
numberOfAddressesWeHadToMakeBeforeWeFoundOneWithTheCorrectRipePrefix += 1
|
||||||
potentialPrivSigningKey = hashlib.sha512(
|
potentialPrivSigningKey, potentialPubSigningKey = \
|
||||||
deterministicPassphrase
|
highlevelcrypto.deterministic_keys(
|
||||||
+ encodeVarint(signingKeyNonce)
|
deterministicPassphrase,
|
||||||
).digest()[:32]
|
encodeVarint(signingKeyNonce))
|
||||||
potentialPrivEncryptionKey = hashlib.sha512(
|
potentialPrivEncryptionKey, potentialPubEncryptionKey = \
|
||||||
deterministicPassphrase
|
highlevelcrypto.deterministic_keys(
|
||||||
+ encodeVarint(encryptionKeyNonce)
|
deterministicPassphrase,
|
||||||
).digest()[:32]
|
encodeVarint(encryptionKeyNonce))
|
||||||
potentialPubSigningKey = highlevelcrypto.pointMult(
|
|
||||||
potentialPrivSigningKey)
|
|
||||||
potentialPubEncryptionKey = highlevelcrypto.pointMult(
|
|
||||||
potentialPrivEncryptionKey)
|
|
||||||
signingKeyNonce += 2
|
signingKeyNonce += 2
|
||||||
encryptionKeyNonce += 2
|
encryptionKeyNonce += 2
|
||||||
sha = hashlib.new('sha512')
|
sha = hashlib.new('sha512')
|
||||||
|
|
|
@ -17,10 +17,10 @@ from pyelliptic import arithmetic as a
|
||||||
|
|
||||||
|
|
||||||
__all__ = [
|
__all__ = [
|
||||||
'decodeWalletImportFormat', 'encodeWalletImportFormat',
|
'decodeWalletImportFormat', 'deterministic_keys',
|
||||||
'double_sha512', 'calculateInventoryHash',
|
'double_sha512', 'calculateInventoryHash', 'encodeWalletImportFormat',
|
||||||
'encrypt', 'makeCryptor', 'pointMult', 'privToPub', 'randomBytes',
|
'encrypt', 'makeCryptor', 'pointMult', 'privToPub', 'randomBytes',
|
||||||
'sign', 'verify']
|
'random_keys', 'sign', 'verify']
|
||||||
|
|
||||||
|
|
||||||
# WIF (uses arithmetic ):
|
# WIF (uses arithmetic ):
|
||||||
|
@ -74,6 +74,77 @@ def calculateInventoryHash(data):
|
||||||
return double_sha512(data)[:32]
|
return double_sha512(data)[:32]
|
||||||
|
|
||||||
|
|
||||||
|
# Keys
|
||||||
|
|
||||||
|
def random_keys():
|
||||||
|
"""Return a pair of keys, private and public"""
|
||||||
|
priv = randomBytes(32)
|
||||||
|
pub = pointMult(priv)
|
||||||
|
return priv, pub
|
||||||
|
|
||||||
|
|
||||||
|
def deterministic_keys(passphrase, nonce):
|
||||||
|
"""Generate keys from *passphrase* and *nonce* (encoded as varint)"""
|
||||||
|
priv = hashlib.sha512(passphrase + nonce).digest()[:32]
|
||||||
|
pub = pointMult(priv)
|
||||||
|
return priv, pub
|
||||||
|
|
||||||
|
|
||||||
|
def hexToPubkey(pubkey):
|
||||||
|
"""Convert a pubkey from hex to binary"""
|
||||||
|
pubkey_raw = a.changebase(pubkey[2:], 16, 256, minlen=64)
|
||||||
|
pubkey_bin = b'\x02\xca\x00 ' + pubkey_raw[:32] + b'\x00 ' + pubkey_raw[32:]
|
||||||
|
return pubkey_bin
|
||||||
|
|
||||||
|
|
||||||
|
def privToPub(privkey):
|
||||||
|
"""Converts hex private key into hex public key"""
|
||||||
|
private_key = a.changebase(privkey, 16, 256, minlen=32)
|
||||||
|
public_key = pointMult(private_key)
|
||||||
|
return hexlify(public_key)
|
||||||
|
|
||||||
|
|
||||||
|
def pointMult(secret):
|
||||||
|
"""
|
||||||
|
Does an EC point multiplication; turns a private key into a public key.
|
||||||
|
|
||||||
|
Evidently, this type of error can occur very rarely:
|
||||||
|
|
||||||
|
>>> File "highlevelcrypto.py", line 54, in pointMult
|
||||||
|
>>> group = OpenSSL.EC_KEY_get0_group(k)
|
||||||
|
>>> WindowsError: exception: access violation reading 0x0000000000000008
|
||||||
|
"""
|
||||||
|
while True:
|
||||||
|
try:
|
||||||
|
k = OpenSSL.EC_KEY_new_by_curve_name(
|
||||||
|
OpenSSL.get_curve('secp256k1'))
|
||||||
|
priv_key = OpenSSL.BN_bin2bn(secret, 32, None)
|
||||||
|
group = OpenSSL.EC_KEY_get0_group(k)
|
||||||
|
pub_key = OpenSSL.EC_POINT_new(group)
|
||||||
|
|
||||||
|
OpenSSL.EC_POINT_mul(group, pub_key, priv_key, None, None, None)
|
||||||
|
OpenSSL.EC_KEY_set_private_key(k, priv_key)
|
||||||
|
OpenSSL.EC_KEY_set_public_key(k, pub_key)
|
||||||
|
|
||||||
|
size = OpenSSL.i2o_ECPublicKey(k, None)
|
||||||
|
mb = OpenSSL.create_string_buffer(size)
|
||||||
|
OpenSSL.i2o_ECPublicKey(k, OpenSSL.byref(OpenSSL.pointer(mb)))
|
||||||
|
|
||||||
|
return mb.raw
|
||||||
|
|
||||||
|
except Exception:
|
||||||
|
import traceback
|
||||||
|
import time
|
||||||
|
traceback.print_exc()
|
||||||
|
time.sleep(0.2)
|
||||||
|
finally:
|
||||||
|
OpenSSL.EC_POINT_free(pub_key)
|
||||||
|
OpenSSL.BN_free(priv_key)
|
||||||
|
OpenSSL.EC_KEY_free(k)
|
||||||
|
|
||||||
|
|
||||||
|
# Encryption
|
||||||
|
|
||||||
def makeCryptor(privkey, curve='secp256k1'):
|
def makeCryptor(privkey, curve='secp256k1'):
|
||||||
"""Return a private `.pyelliptic.ECC` instance"""
|
"""Return a private `.pyelliptic.ECC` instance"""
|
||||||
private_key = a.changebase(privkey, 16, 256, minlen=32)
|
private_key = a.changebase(privkey, 16, 256, minlen=32)
|
||||||
|
@ -84,26 +155,12 @@ def makeCryptor(privkey, curve='secp256k1'):
|
||||||
return cryptor
|
return cryptor
|
||||||
|
|
||||||
|
|
||||||
def hexToPubkey(pubkey):
|
|
||||||
"""Convert a pubkey from hex to binary"""
|
|
||||||
pubkey_raw = a.changebase(pubkey[2:], 16, 256, minlen=64)
|
|
||||||
pubkey_bin = b'\x02\xca\x00 ' + pubkey_raw[:32] + b'\x00 ' + pubkey_raw[32:]
|
|
||||||
return pubkey_bin
|
|
||||||
|
|
||||||
|
|
||||||
def makePubCryptor(pubkey):
|
def makePubCryptor(pubkey):
|
||||||
"""Return a public `.pyelliptic.ECC` instance"""
|
"""Return a public `.pyelliptic.ECC` instance"""
|
||||||
pubkey_bin = hexToPubkey(pubkey)
|
pubkey_bin = hexToPubkey(pubkey)
|
||||||
return pyelliptic.ECC(curve='secp256k1', pubkey=pubkey_bin)
|
return pyelliptic.ECC(curve='secp256k1', pubkey=pubkey_bin)
|
||||||
|
|
||||||
|
|
||||||
def privToPub(privkey):
|
|
||||||
"""Converts hex private key into hex public key"""
|
|
||||||
private_key = a.changebase(privkey, 16, 256, minlen=32)
|
|
||||||
public_key = pointMult(private_key)
|
|
||||||
return hexlify(public_key)
|
|
||||||
|
|
||||||
|
|
||||||
def encrypt(msg, hexPubkey):
|
def encrypt(msg, hexPubkey):
|
||||||
"""Encrypts message with hex public key"""
|
"""Encrypts message with hex public key"""
|
||||||
return pyelliptic.ECC(curve='secp256k1').encrypt(
|
return pyelliptic.ECC(curve='secp256k1').encrypt(
|
||||||
|
@ -120,6 +177,8 @@ def decryptFast(msg, cryptor):
|
||||||
return cryptor.decrypt(msg)
|
return cryptor.decrypt(msg)
|
||||||
|
|
||||||
|
|
||||||
|
# Signatures
|
||||||
|
|
||||||
def _choose_digest_alg(name):
|
def _choose_digest_alg(name):
|
||||||
"""
|
"""
|
||||||
Choose openssl digest constant by name raises ValueError if not appropriate
|
Choose openssl digest constant by name raises ValueError if not appropriate
|
||||||
|
@ -160,42 +219,3 @@ def verify(msg, sig, hexPubkey, digestAlg=None):
|
||||||
sig, msg, digest_alg=_choose_digest_alg(digestAlg))
|
sig, msg, digest_alg=_choose_digest_alg(digestAlg))
|
||||||
except:
|
except:
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
|
||||||
def pointMult(secret):
|
|
||||||
"""
|
|
||||||
Does an EC point multiplication; turns a private key into a public key.
|
|
||||||
|
|
||||||
Evidently, this type of error can occur very rarely:
|
|
||||||
|
|
||||||
>>> File "highlevelcrypto.py", line 54, in pointMult
|
|
||||||
>>> group = OpenSSL.EC_KEY_get0_group(k)
|
|
||||||
>>> WindowsError: exception: access violation reading 0x0000000000000008
|
|
||||||
"""
|
|
||||||
while True:
|
|
||||||
try:
|
|
||||||
k = OpenSSL.EC_KEY_new_by_curve_name(
|
|
||||||
OpenSSL.get_curve('secp256k1'))
|
|
||||||
priv_key = OpenSSL.BN_bin2bn(secret, 32, None)
|
|
||||||
group = OpenSSL.EC_KEY_get0_group(k)
|
|
||||||
pub_key = OpenSSL.EC_POINT_new(group)
|
|
||||||
|
|
||||||
OpenSSL.EC_POINT_mul(group, pub_key, priv_key, None, None, None)
|
|
||||||
OpenSSL.EC_KEY_set_private_key(k, priv_key)
|
|
||||||
OpenSSL.EC_KEY_set_public_key(k, pub_key)
|
|
||||||
|
|
||||||
size = OpenSSL.i2o_ECPublicKey(k, None)
|
|
||||||
mb = OpenSSL.create_string_buffer(size)
|
|
||||||
OpenSSL.i2o_ECPublicKey(k, OpenSSL.byref(OpenSSL.pointer(mb)))
|
|
||||||
|
|
||||||
return mb.raw
|
|
||||||
|
|
||||||
except Exception:
|
|
||||||
import traceback
|
|
||||||
import time
|
|
||||||
traceback.print_exc()
|
|
||||||
time.sleep(0.2)
|
|
||||||
finally:
|
|
||||||
OpenSSL.EC_POINT_free(pub_key)
|
|
||||||
OpenSSL.BN_free(priv_key)
|
|
||||||
OpenSSL.EC_KEY_free(k)
|
|
||||||
|
|
Reference in New Issue
Block a user