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
8793def 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-
100100def 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+
107164def 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+
123182def _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