2015-07-12 20:36:46 +02:00
|
|
|
import logging
|
2019-03-16 02:36:11 +01:00
|
|
|
import base64
|
2020-03-05 17:54:46 +01:00
|
|
|
import binascii
|
2019-07-18 03:32:45 +02:00
|
|
|
import time
|
2020-03-05 17:54:46 +01:00
|
|
|
import hashlib
|
2015-07-12 20:36:46 +02:00
|
|
|
|
2020-03-05 17:54:46 +01:00
|
|
|
from util.Electrum import dbl_format
|
rev125, Class statistics, OpenSSL disabled on OSX by default because of possible segfault, --disable_openssl command line parameter, Save memory on Connection, Peer and FileRequest objects using slots, Dont store modification time from the far future, Able to query modified files from peer, Allow reannounce in 30secs, Use with command in SiteStorage, Always create dir before write file, PeerCmd shell command to query specific command from peer
2015-04-29 23:12:45 +02:00
|
|
|
from Config import config
|
|
|
|
|
2020-03-05 17:54:46 +01:00
|
|
|
lib_verify_best = "sslcrypto"
|
2019-03-16 02:36:11 +01:00
|
|
|
|
2020-03-21 20:52:56 +01:00
|
|
|
from lib import sslcrypto
|
2020-03-05 17:54:46 +01:00
|
|
|
sslcurve_native = sslcrypto.ecc.get_curve("secp256k1")
|
|
|
|
sslcurve_fallback = sslcrypto.fallback.ecc.get_curve("secp256k1")
|
|
|
|
sslcurve = sslcurve_native
|
2019-03-16 02:36:11 +01:00
|
|
|
|
2019-10-16 15:43:07 +02:00
|
|
|
def loadLib(lib_name, silent=False):
|
2020-03-05 17:54:46 +01:00
|
|
|
global sslcurve, libsecp256k1message, lib_verify_best
|
2019-03-16 02:36:11 +01:00
|
|
|
if lib_name == "libsecp256k1":
|
2019-07-18 03:32:45 +02:00
|
|
|
s = time.time()
|
2019-03-16 02:36:11 +01:00
|
|
|
from lib import libsecp256k1message
|
2019-07-18 03:32:45 +02:00
|
|
|
import coincurve
|
2019-03-16 02:36:11 +01:00
|
|
|
lib_verify_best = "libsecp256k1"
|
2019-10-16 15:43:07 +02:00
|
|
|
if not silent:
|
|
|
|
logging.info(
|
|
|
|
"Libsecpk256k1 loaded: %s in %.3fs" %
|
|
|
|
(type(coincurve._libsecp256k1.lib).__name__, time.time() - s)
|
|
|
|
)
|
2020-03-05 17:54:46 +01:00
|
|
|
elif lib_name == "sslcrypto":
|
|
|
|
sslcurve = sslcurve_native
|
2020-11-03 02:50:21 +01:00
|
|
|
if sslcurve_native == sslcurve_fallback:
|
|
|
|
logging.warning("SSLCurve fallback loaded instead of native")
|
2020-03-05 17:54:46 +01:00
|
|
|
elif lib_name == "sslcrypto_fallback":
|
|
|
|
sslcurve = sslcurve_fallback
|
2019-03-16 02:36:11 +01:00
|
|
|
|
2015-04-28 00:43:17 +02:00
|
|
|
try:
|
2019-03-16 02:36:11 +01:00
|
|
|
if not config.use_libsecp256k1:
|
2015-07-12 20:36:46 +02:00
|
|
|
raise Exception("Disabled by config")
|
2019-03-16 02:36:11 +01:00
|
|
|
loadLib("libsecp256k1")
|
|
|
|
lib_verify_best = "libsecp256k1"
|
|
|
|
except Exception as err:
|
2020-03-05 17:54:46 +01:00
|
|
|
logging.info("Libsecp256k1 load failed: %s" % err)
|
2015-01-12 02:03:45 +01:00
|
|
|
|
|
|
|
|
2020-03-05 17:54:46 +01:00
|
|
|
def newPrivatekey(): # Return new private key
|
|
|
|
return sslcurve.private_to_wif(sslcurve.new_private_key()).decode()
|
version 0.2.0, new lib for bitcoin ecc, dont display or track notify errors, dont reload again within 1 sec, null peer ip fix, signingmoved to ContentManager, content.json include support, content.json multisig ready, content.json proper bitcoincore compatible signing, content.json include permissions, multithreaded publish, publish timeout 60s, no exception on invalid bitcoin address, testcase for new lib, bip32 based persite privatekey generation, multiuser ready, simple json database query command, websocket api fileGet, wrapper loading title stuck bugfix
2015-02-09 02:09:02 +01:00
|
|
|
|
|
|
|
|
|
|
|
def newSeed():
|
2020-03-05 17:54:46 +01:00
|
|
|
return binascii.hexlify(sslcurve.new_private_key()).decode()
|
version 0.2.0, new lib for bitcoin ecc, dont display or track notify errors, dont reload again within 1 sec, null peer ip fix, signingmoved to ContentManager, content.json include support, content.json multisig ready, content.json proper bitcoincore compatible signing, content.json include permissions, multithreaded publish, publish timeout 60s, no exception on invalid bitcoin address, testcase for new lib, bip32 based persite privatekey generation, multiuser ready, simple json database query command, websocket api fileGet, wrapper loading title stuck bugfix
2015-02-09 02:09:02 +01:00
|
|
|
|
|
|
|
|
|
|
|
def hdPrivatekey(seed, child):
|
2020-03-05 17:54:46 +01:00
|
|
|
# Too large child id could cause problems
|
|
|
|
privatekey_bin = sslcurve.derive_child(seed.encode(), child % 100000000)
|
|
|
|
return sslcurve.private_to_wif(privatekey_bin).decode()
|
2015-07-12 20:36:46 +02:00
|
|
|
|
|
|
|
|
|
|
|
def privatekeyToAddress(privatekey): # Return address from private key
|
2019-03-16 02:36:11 +01:00
|
|
|
try:
|
2020-03-05 17:54:46 +01:00
|
|
|
if len(privatekey) == 64:
|
|
|
|
privatekey_bin = bytes.fromhex(privatekey)
|
|
|
|
else:
|
|
|
|
privatekey_bin = sslcurve.wif_to_private(privatekey.encode())
|
2020-03-30 08:16:12 +02:00
|
|
|
return sslcurve.private_to_address(privatekey_bin).decode()
|
2019-03-16 02:36:11 +01:00
|
|
|
except Exception: # Invalid privatekey
|
|
|
|
return False
|
2015-07-12 20:36:46 +02:00
|
|
|
|
|
|
|
|
|
|
|
def sign(data, privatekey): # Return sign to data using private key
|
|
|
|
if privatekey.startswith("23") and len(privatekey) > 52:
|
|
|
|
return None # Old style private key not supported
|
2020-03-05 17:54:46 +01:00
|
|
|
return base64.b64encode(sslcurve.sign(
|
|
|
|
data.encode(),
|
|
|
|
sslcurve.wif_to_private(privatekey.encode()),
|
|
|
|
recoverable=True,
|
|
|
|
hash=dbl_format
|
|
|
|
)).decode()
|
2015-07-12 20:36:46 +02:00
|
|
|
|
|
|
|
|
2019-03-20 00:48:09 +01:00
|
|
|
def verify(data, valid_address, sign, lib_verify=None): # Verify data using address and sign
|
2019-03-16 02:36:11 +01:00
|
|
|
if not lib_verify:
|
|
|
|
lib_verify = lib_verify_best
|
2015-07-12 20:36:46 +02:00
|
|
|
|
2018-10-30 04:41:45 +01:00
|
|
|
if not sign:
|
|
|
|
return False
|
|
|
|
|
2019-03-16 02:36:11 +01:00
|
|
|
if lib_verify == "libsecp256k1":
|
|
|
|
sign_address = libsecp256k1message.recover_address(data.encode("utf8"), sign).decode("utf8")
|
2020-03-05 17:54:46 +01:00
|
|
|
elif lib_verify in ("sslcrypto", "sslcrypto_fallback"):
|
|
|
|
publickey = sslcurve.recover(base64.b64decode(sign), data.encode(), hash=dbl_format)
|
|
|
|
sign_address = sslcurve.public_to_address(publickey).decode()
|
2019-03-16 02:36:11 +01:00
|
|
|
else:
|
|
|
|
raise Exception("No library enabled for signature verification")
|
|
|
|
|
2019-03-20 00:48:09 +01:00
|
|
|
if type(valid_address) is list: # Any address in the list
|
|
|
|
return sign_address in valid_address
|
2019-03-16 02:36:11 +01:00
|
|
|
else: # One possible address
|
2019-03-20 00:48:09 +01:00
|
|
|
return sign_address == valid_address
|