Forking what is left of ZeroNet and hopefully adding an AT Proto Frontend/Proxy
at main 101 lines 3.4 kB view raw
1import logging 2import base64 3import binascii 4import time 5import hashlib 6 7from util.Electrum import dbl_format 8from Config import config 9 10import util.OpensslFindPatch 11 12lib_verify_best = "sslcrypto" 13 14from lib import sslcrypto 15sslcurve_native = sslcrypto.ecc.get_curve("secp256k1") 16sslcurve_fallback = sslcrypto.fallback.ecc.get_curve("secp256k1") 17sslcurve = sslcurve_native 18 19def loadLib(lib_name, silent=False): 20 global sslcurve, libsecp256k1message, lib_verify_best 21 if lib_name == "libsecp256k1": 22 s = time.time() 23 from lib import libsecp256k1message 24 import coincurve 25 lib_verify_best = "libsecp256k1" 26 if not silent: 27 logging.info( 28 "Libsecpk256k1 loaded: %s in %.3fs" % 29 (type(coincurve._libsecp256k1.lib).__name__, time.time() - s) 30 ) 31 elif lib_name == "sslcrypto": 32 sslcurve = sslcurve_native 33 if sslcurve_native == sslcurve_fallback: 34 logging.warning("SSLCurve fallback loaded instead of native") 35 elif lib_name == "sslcrypto_fallback": 36 sslcurve = sslcurve_fallback 37 38try: 39 if not config.use_libsecp256k1: 40 raise Exception("Disabled by config") 41 loadLib("libsecp256k1") 42 lib_verify_best = "libsecp256k1" 43except Exception as err: 44 logging.info("Libsecp256k1 load failed: %s" % err) 45 46 47def newPrivatekey(): # Return new private key 48 return sslcurve.private_to_wif(sslcurve.new_private_key()).decode() 49 50 51def newSeed(): 52 return binascii.hexlify(sslcurve.new_private_key()).decode() 53 54 55def hdPrivatekey(seed, child): 56 # Too large child id could cause problems 57 privatekey_bin = sslcurve.derive_child(seed.encode(), child % 100000000) 58 return sslcurve.private_to_wif(privatekey_bin).decode() 59 60 61def privatekeyToAddress(privatekey): # Return address from private key 62 try: 63 if len(privatekey) == 64: 64 privatekey_bin = bytes.fromhex(privatekey) 65 else: 66 privatekey_bin = sslcurve.wif_to_private(privatekey.encode()) 67 return sslcurve.private_to_address(privatekey_bin).decode() 68 except Exception: # Invalid privatekey 69 return False 70 71 72def sign(data, privatekey): # Return sign to data using private key 73 if privatekey.startswith("23") and len(privatekey) > 52: 74 return None # Old style private key not supported 75 return base64.b64encode(sslcurve.sign( 76 data.encode(), 77 sslcurve.wif_to_private(privatekey.encode()), 78 recoverable=True, 79 hash=dbl_format 80 )).decode() 81 82 83def verify(data, valid_address, sign, lib_verify=None): # Verify data using address and sign 84 if not lib_verify: 85 lib_verify = lib_verify_best 86 87 if not sign: 88 return False 89 90 if lib_verify == "libsecp256k1": 91 sign_address = libsecp256k1message.recover_address(data.encode("utf8"), sign).decode("utf8") 92 elif lib_verify in ("sslcrypto", "sslcrypto_fallback"): 93 publickey = sslcurve.recover(base64.b64decode(sign), data.encode(), hash=dbl_format) 94 sign_address = sslcurve.public_to_address(publickey).decode() 95 else: 96 raise Exception("No library enabled for signature verification") 97 98 if type(valid_address) is list: # Any address in the list 99 return sign_address in valid_address 100 else: # One possible address 101 return sign_address == valid_address