Define functions for generating keys in the highlevelcrypto

This commit is contained in:
Dmitri Bogomolov 2021-12-09 19:37:15 +02:00 committed by Lee Miller
parent d547a8be2f
commit 5c1dcc5645
Signed by untrusted user: lee.miller
GPG Key ID: 4F97A5EA88F4AB63
2 changed files with 90 additions and 78 deletions

View File

@ -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')

View File

@ -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)