Skip to content

Commit 5c1dcc5

Browse files
g1itchLee Miller
authored andcommitted
Define functions for generating keys in the highlevelcrypto
1 parent d547a8b commit 5c1dcc5

File tree

2 files changed

+90
-78
lines changed

2 files changed

+90
-78
lines changed

src/class_addressGenerator.py

Lines changed: 14 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@
1616
from bmconfigparser import config
1717
from fallback import RIPEMD160Hash
1818
from network import StoppableThread
19-
from pyelliptic.openssl import OpenSSL
2019
from tr import _translate
2120

2221

@@ -129,17 +128,13 @@ def run(self):
129128
# the \x00 or \x00\x00 bytes thus making the address shorter.
130129
startTime = time.time()
131130
numberOfAddressesWeHadToMakeBeforeWeFoundOneWithTheCorrectRipePrefix = 0
132-
potentialPrivSigningKey = OpenSSL.rand(32)
133-
potentialPubSigningKey = highlevelcrypto.pointMult(
134-
potentialPrivSigningKey)
131+
privSigningKey, pubSigningKey = highlevelcrypto.random_keys()
135132
while True:
136133
numberOfAddressesWeHadToMakeBeforeWeFoundOneWithTheCorrectRipePrefix += 1
137-
potentialPrivEncryptionKey = OpenSSL.rand(32)
138-
potentialPubEncryptionKey = highlevelcrypto.pointMult(
139-
potentialPrivEncryptionKey)
134+
potentialPrivEncryptionKey, potentialPubEncryptionKey = \
135+
highlevelcrypto.random_keys()
140136
sha = hashlib.new('sha512')
141-
sha.update(
142-
potentialPubSigningKey + potentialPubEncryptionKey)
137+
sha.update(pubSigningKey + potentialPubEncryptionKey)
143138
ripe = RIPEMD160Hash(sha.digest()).digest()
144139
if (
145140
ripe[:numberOfNullBytesDemandedOnFrontOfRipeHash]
@@ -164,7 +159,7 @@ def run(self):
164159
addressVersionNumber, streamNumber, ripe)
165160

166161
privSigningKeyWIF = highlevelcrypto.encodeWalletImportFormat(
167-
potentialPrivSigningKey)
162+
privSigningKey)
168163
privEncryptionKeyWIF = highlevelcrypto.encodeWalletImportFormat(
169164
potentialPrivEncryptionKey)
170165

@@ -238,18 +233,15 @@ def run(self):
238233
numberOfAddressesWeHadToMakeBeforeWeFoundOneWithTheCorrectRipePrefix = 0
239234
while True:
240235
numberOfAddressesWeHadToMakeBeforeWeFoundOneWithTheCorrectRipePrefix += 1
241-
potentialPrivSigningKey = hashlib.sha512(
242-
deterministicPassphrase
243-
+ encodeVarint(signingKeyNonce)
244-
).digest()[:32]
245-
potentialPrivEncryptionKey = hashlib.sha512(
246-
deterministicPassphrase
247-
+ encodeVarint(encryptionKeyNonce)
248-
).digest()[:32]
249-
potentialPubSigningKey = highlevelcrypto.pointMult(
250-
potentialPrivSigningKey)
251-
potentialPubEncryptionKey = highlevelcrypto.pointMult(
252-
potentialPrivEncryptionKey)
236+
potentialPrivSigningKey, potentialPubSigningKey = \
237+
highlevelcrypto.deterministic_keys(
238+
deterministicPassphrase,
239+
encodeVarint(signingKeyNonce))
240+
potentialPrivEncryptionKey, potentialPubEncryptionKey = \
241+
highlevelcrypto.deterministic_keys(
242+
deterministicPassphrase,
243+
encodeVarint(encryptionKeyNonce))
244+
253245
signingKeyNonce += 2
254246
encryptionKeyNonce += 2
255247
sha = hashlib.new('sha512')

src/highlevelcrypto.py

Lines changed: 76 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -17,10 +17,10 @@
1717

1818

1919
__all__ = [
20-
'decodeWalletImportFormat', 'encodeWalletImportFormat',
21-
'double_sha512', 'calculateInventoryHash',
20+
'decodeWalletImportFormat', 'deterministic_keys',
21+
'double_sha512', 'calculateInventoryHash', 'encodeWalletImportFormat',
2222
'encrypt', 'makeCryptor', 'pointMult', 'privToPub', 'randomBytes',
23-
'sign', 'verify']
23+
'random_keys', 'sign', 'verify']
2424

2525

2626
# WIF (uses arithmetic ):
@@ -74,14 +74,20 @@ def calculateInventoryHash(data):
7474
return double_sha512(data)[:32]
7575

7676

77-
def makeCryptor(privkey, curve='secp256k1'):
78-
"""Return a private `.pyelliptic.ECC` instance"""
79-
private_key = a.changebase(privkey, 16, 256, minlen=32)
80-
public_key = pointMult(private_key)
81-
cryptor = pyelliptic.ECC(
82-
pubkey_x=public_key[1:-32], pubkey_y=public_key[-32:],
83-
raw_privkey=private_key, curve=curve)
84-
return cryptor
77+
# Keys
78+
79+
def random_keys():
80+
"""Return a pair of keys, private and public"""
81+
priv = randomBytes(32)
82+
pub = pointMult(priv)
83+
return priv, pub
84+
85+
86+
def deterministic_keys(passphrase, nonce):
87+
"""Generate keys from *passphrase* and *nonce* (encoded as varint)"""
88+
priv = hashlib.sha512(passphrase + nonce).digest()[:32]
89+
pub = pointMult(priv)
90+
return priv, pub
8591

8692

8793
def hexToPubkey(pubkey):
@@ -91,19 +97,70 @@ def hexToPubkey(pubkey):
9197
return pubkey_bin
9298

9399

94-
def makePubCryptor(pubkey):
95-
"""Return a public `.pyelliptic.ECC` instance"""
96-
pubkey_bin = hexToPubkey(pubkey)
97-
return pyelliptic.ECC(curve='secp256k1', pubkey=pubkey_bin)
98-
99-
100100
def privToPub(privkey):
101101
"""Converts hex private key into hex public key"""
102102
private_key = a.changebase(privkey, 16, 256, minlen=32)
103103
public_key = pointMult(private_key)
104104
return hexlify(public_key)
105105

106106

107+
def pointMult(secret):
108+
"""
109+
Does an EC point multiplication; turns a private key into a public key.
110+
111+
Evidently, this type of error can occur very rarely:
112+
113+
>>> File "highlevelcrypto.py", line 54, in pointMult
114+
>>> group = OpenSSL.EC_KEY_get0_group(k)
115+
>>> WindowsError: exception: access violation reading 0x0000000000000008
116+
"""
117+
while True:
118+
try:
119+
k = OpenSSL.EC_KEY_new_by_curve_name(
120+
OpenSSL.get_curve('secp256k1'))
121+
priv_key = OpenSSL.BN_bin2bn(secret, 32, None)
122+
group = OpenSSL.EC_KEY_get0_group(k)
123+
pub_key = OpenSSL.EC_POINT_new(group)
124+
125+
OpenSSL.EC_POINT_mul(group, pub_key, priv_key, None, None, None)
126+
OpenSSL.EC_KEY_set_private_key(k, priv_key)
127+
OpenSSL.EC_KEY_set_public_key(k, pub_key)
128+
129+
size = OpenSSL.i2o_ECPublicKey(k, None)
130+
mb = OpenSSL.create_string_buffer(size)
131+
OpenSSL.i2o_ECPublicKey(k, OpenSSL.byref(OpenSSL.pointer(mb)))
132+
133+
return mb.raw
134+
135+
except Exception:
136+
import traceback
137+
import time
138+
traceback.print_exc()
139+
time.sleep(0.2)
140+
finally:
141+
OpenSSL.EC_POINT_free(pub_key)
142+
OpenSSL.BN_free(priv_key)
143+
OpenSSL.EC_KEY_free(k)
144+
145+
146+
# Encryption
147+
148+
def makeCryptor(privkey, curve='secp256k1'):
149+
"""Return a private `.pyelliptic.ECC` instance"""
150+
private_key = a.changebase(privkey, 16, 256, minlen=32)
151+
public_key = pointMult(private_key)
152+
cryptor = pyelliptic.ECC(
153+
pubkey_x=public_key[1:-32], pubkey_y=public_key[-32:],
154+
raw_privkey=private_key, curve=curve)
155+
return cryptor
156+
157+
158+
def makePubCryptor(pubkey):
159+
"""Return a public `.pyelliptic.ECC` instance"""
160+
pubkey_bin = hexToPubkey(pubkey)
161+
return pyelliptic.ECC(curve='secp256k1', pubkey=pubkey_bin)
162+
163+
107164
def encrypt(msg, hexPubkey):
108165
"""Encrypts message with hex public key"""
109166
return pyelliptic.ECC(curve='secp256k1').encrypt(
@@ -120,6 +177,8 @@ def decryptFast(msg, cryptor):
120177
return cryptor.decrypt(msg)
121178

122179

180+
# Signatures
181+
123182
def _choose_digest_alg(name):
124183
"""
125184
Choose openssl digest constant by name raises ValueError if not appropriate
@@ -160,42 +219,3 @@ def verify(msg, sig, hexPubkey, digestAlg=None):
160219
sig, msg, digest_alg=_choose_digest_alg(digestAlg))
161220
except:
162221
return False
163-
164-
165-
def pointMult(secret):
166-
"""
167-
Does an EC point multiplication; turns a private key into a public key.
168-
169-
Evidently, this type of error can occur very rarely:
170-
171-
>>> File "highlevelcrypto.py", line 54, in pointMult
172-
>>> group = OpenSSL.EC_KEY_get0_group(k)
173-
>>> WindowsError: exception: access violation reading 0x0000000000000008
174-
"""
175-
while True:
176-
try:
177-
k = OpenSSL.EC_KEY_new_by_curve_name(
178-
OpenSSL.get_curve('secp256k1'))
179-
priv_key = OpenSSL.BN_bin2bn(secret, 32, None)
180-
group = OpenSSL.EC_KEY_get0_group(k)
181-
pub_key = OpenSSL.EC_POINT_new(group)
182-
183-
OpenSSL.EC_POINT_mul(group, pub_key, priv_key, None, None, None)
184-
OpenSSL.EC_KEY_set_private_key(k, priv_key)
185-
OpenSSL.EC_KEY_set_public_key(k, pub_key)
186-
187-
size = OpenSSL.i2o_ECPublicKey(k, None)
188-
mb = OpenSSL.create_string_buffer(size)
189-
OpenSSL.i2o_ECPublicKey(k, OpenSSL.byref(OpenSSL.pointer(mb)))
190-
191-
return mb.raw
192-
193-
except Exception:
194-
import traceback
195-
import time
196-
traceback.print_exc()
197-
time.sleep(0.2)
198-
finally:
199-
OpenSSL.EC_POINT_free(pub_key)
200-
OpenSSL.BN_free(priv_key)
201-
OpenSSL.EC_KEY_free(k)

0 commit comments

Comments
 (0)