diff --git a/src/highlevelcrypto.py b/src/highlevelcrypto.py index 3d894ae8..f392fe4a 100644 --- a/src/highlevelcrypto.py +++ b/src/highlevelcrypto.py @@ -1,6 +1,10 @@ """ -src/highlevelcrypto.py -====================== +High level cryptographic functions based on `.pyelliptic` OpenSSL bindings. + +.. note:: + Upstream pyelliptic was upgraded from SHA1 to SHA256 for signing. + We must upgrade PyBitmessage gracefully. + `More discussion. `_ """ from binascii import hexlify @@ -12,12 +16,13 @@ from pyelliptic import arithmetic as a def makeCryptor(privkey): - """Return a private pyelliptic.ECC() instance""" + """Return a private `.pyelliptic.ECC` instance""" private_key = a.changebase(privkey, 16, 256, minlen=32) public_key = pointMult(private_key) privkey_bin = '\x02\xca\x00\x20' + private_key pubkey_bin = '\x02\xca\x00\x20' + public_key[1:-32] + '\x00\x20' + public_key[-32:] - cryptor = pyelliptic.ECC(curve='secp256k1', privkey=privkey_bin, pubkey=pubkey_bin) + cryptor = pyelliptic.ECC( + curve='secp256k1', privkey=privkey_bin, pubkey=pubkey_bin) return cryptor @@ -29,7 +34,7 @@ def hexToPubkey(pubkey): def makePubCryptor(pubkey): - """Return a public pyelliptic.ECC() instance""" + """Return a public `.pyelliptic.ECC` instance""" pubkey_bin = hexToPubkey(pubkey) return pyelliptic.ECC(curve='secp256k1', pubkey=pubkey_bin) @@ -43,7 +48,8 @@ def privToPub(privkey): def encrypt(msg, hexPubkey): """Encrypts message with hex public key""" - return pyelliptic.ECC(curve='secp256k1').encrypt(msg, hexToPubkey(hexPubkey)) + return pyelliptic.ECC(curve='secp256k1').encrypt( + msg, hexToPubkey(hexPubkey)) def decrypt(msg, hexPrivkey): @@ -52,36 +58,38 @@ def decrypt(msg, hexPrivkey): def decryptFast(msg, cryptor): - """Decrypts message with an existing pyelliptic.ECC.ECC object""" + """Decrypts message with an existing `.pyelliptic.ECC` object""" return cryptor.decrypt(msg) def sign(msg, hexPrivkey): - """Signs with hex private key""" - # pyelliptic is upgrading from SHA1 to SHA256 for signing. We must - # upgrade PyBitmessage gracefully. - # https://github.com/yann2192/pyelliptic/pull/33 - # More discussion: https://github.com/yann2192/pyelliptic/issues/32 - digestAlg = BMConfigParser().safeGet('bitmessagesettings', 'digestalg', 'sha1') + """ + Signs with hex private key using SHA1 or SHA256 depending on + "digestalg" setting + """ + digestAlg = BMConfigParser().safeGet( + 'bitmessagesettings', 'digestalg', 'sha1') if digestAlg == "sha1": # SHA1, this will eventually be deprecated - return makeCryptor(hexPrivkey).sign(msg, digest_alg=OpenSSL.digest_ecdsa_sha1) + return makeCryptor(hexPrivkey).sign( + msg, digest_alg=OpenSSL.digest_ecdsa_sha1) elif digestAlg == "sha256": # SHA256. Eventually this will become the default return makeCryptor(hexPrivkey).sign(msg, digest_alg=OpenSSL.EVP_sha256) else: - raise ValueError("Unknown digest algorithm %s" % (digestAlg)) + raise ValueError("Unknown digest algorithm %s" % digestAlg) def verify(msg, sig, hexPubkey): - """Verifies with hex public key""" + """Verifies with hex public key using SHA1 or SHA256""" # As mentioned above, we must upgrade gracefully to use SHA256. So # let us check the signature using both SHA1 and SHA256 and if one # of them passes then we will be satisfied. Eventually this can # be simplified and we'll only check with SHA256. try: # old SHA1 algorithm. - sigVerifyPassed = makePubCryptor(hexPubkey).verify(sig, msg, digest_alg=OpenSSL.digest_ecdsa_sha1) + sigVerifyPassed = makePubCryptor(hexPubkey).verify( + sig, msg, digest_alg=OpenSSL.digest_ecdsa_sha1) except: sigVerifyPassed = False if sigVerifyPassed: @@ -89,7 +97,8 @@ def verify(msg, sig, hexPubkey): return True # The signature check using SHA1 failed. Let us try it with SHA256. try: - return makePubCryptor(hexPubkey).verify(sig, msg, digest_alg=OpenSSL.EVP_sha256) + return makePubCryptor(hexPubkey).verify( + sig, msg, digest_alg=OpenSSL.EVP_sha256) except: return False @@ -106,7 +115,8 @@ def pointMult(secret): """ while True: try: - k = OpenSSL.EC_KEY_new_by_curve_name(OpenSSL.get_curve('secp256k1')) + 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) diff --git a/src/shutdown.py b/src/shutdown.py index c81a519a..dbc2af04 100644 --- a/src/shutdown.py +++ b/src/shutdown.py @@ -16,7 +16,9 @@ from queues import ( def doCleanShutdown(): - """Used to tell proof of work worker threads and the objectProcessorThread to exit.""" + """ + Used to tell all the treads to finish work and exit. + """ state.shutdown = 1 objectProcessorQueue.put(('checkShutdownVariable', 'no data')) @@ -52,9 +54,11 @@ def doCleanShutdown(): time.sleep(.25) for thread in threading.enumerate(): - if (thread is not threading.currentThread() and - isinstance(thread, StoppableThread) and - thread.name != 'SQL'): + if ( + thread is not threading.currentThread() + and isinstance(thread, StoppableThread) + and thread.name != 'SQL' + ): logger.debug("Waiting for thread %s", thread.name) thread.join()