Skip to content

Commit

Permalink
Merge pull request HelloZeroNet#2503 from imachug/compressed-keys
Browse files Browse the repository at this point in the history
Support compressed keys
  • Loading branch information
HelloZeroNet authored Mar 30, 2020
2 parents 56acac8 + 0a9a9b5 commit fa880d9
Show file tree
Hide file tree
Showing 5 changed files with 31 additions and 13 deletions.
2 changes: 1 addition & 1 deletion plugins/CryptMessage/CryptMessage.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ def eciesDecryptMulti(encrypted_datas, privatekey):


def eciesDecrypt(ciphertext, privatekey):
return curve.decrypt(base64.b64decode(ciphertext), curve.wif_to_private(privatekey), derivation="sha512")
return curve.decrypt(base64.b64decode(ciphertext), curve.wif_to_private(privatekey.encode()), derivation="sha512")


def decodePubkey(pubkey):
Expand Down
6 changes: 3 additions & 3 deletions plugins/CryptMessage/CryptMessagePlugin.py
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ def actionEcdsaVerify(self, to, data, address, signature):

# Gets the publickey of a given privatekey
def actionEccPrivToPub(self, to, privatekey):
self.response(to, curve.private_to_public(curve.wif_to_private(privatekey)))
self.response(to, curve.private_to_public(curve.wif_to_private(privatekey.encode())))

# Gets the address of a given publickey
def actionEccPubToAddr(self, to, publickey):
Expand Down Expand Up @@ -149,8 +149,8 @@ def getEncryptPublickey(self, address, param_index=0):
index = param_index

if "encrypt_publickey_%s" % index not in site_data:
privatekey = self.getEncryptPrivatekey(address, param_index)
publickey = curve.private_to_public(curve.wif_to_private(privatekey))
privatekey = self.getEncryptPrivatekey(address, param_index).encode()
publickey = curve.private_to_public(curve.wif_to_private(privatekey) + b"\x01")
site_data["encrypt_publickey_%s" % index] = base64.b64encode(publickey).decode("utf8")
return site_data["encrypt_publickey_%s" % index]

Expand Down
3 changes: 1 addition & 2 deletions src/Crypt/CryptBitcoin.py
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ def privatekeyToAddress(privatekey): # Return address from private key
privatekey_bin = bytes.fromhex(privatekey)
else:
privatekey_bin = sslcurve.wif_to_private(privatekey.encode())
return sslcurve.private_to_address(privatekey_bin, is_compressed=False).decode()
return sslcurve.private_to_address(privatekey_bin).decode()
except Exception: # Invalid privatekey
return False

Expand All @@ -71,7 +71,6 @@ def sign(data, privatekey): # Return sign to data using private key
return base64.b64encode(sslcurve.sign(
data.encode(),
sslcurve.wif_to_private(privatekey.encode()),
is_compressed=False,
recoverable=True,
hash=dbl_format
)).decode()
Expand Down
31 changes: 25 additions & 6 deletions src/lib/sslcrypto/_ecc.py
Original file line number Diff line number Diff line change
Expand Up @@ -296,11 +296,18 @@ def _decode_public_key_openssl(self, public_key, partial=False):
return x, y


def new_private_key(self):
return self._backend.new_private_key()
def new_private_key(self, is_compressed=False):
return self._backend.new_private_key() + (b"\x01" if is_compressed else b"")


def private_to_public(self, private_key, is_compressed=True):
def private_to_public(self, private_key):
if len(private_key) == self._backend.public_key_length:
is_compressed = False
elif len(private_key) == self._backend.public_key_length + 1 and private_key[-1] == 1:
is_compressed = True
private_key = private_key[:-1]
else:
raise ValueError("Private key has invalid length")
x, y = self._backend.private_to_public(private_key)
return self._encode_public_key(x, y, is_compressed=is_compressed)

Expand All @@ -322,12 +329,16 @@ def public_to_address(self, public_key):
return base58.b58encode_check(b"\x00" + hash160)


def private_to_address(self, private_key, is_compressed=True):
def private_to_address(self, private_key):
# Kinda useless but left for quick migration from pybitcointools
return self.public_to_address(self.private_to_public(private_key, is_compressed=is_compressed))
return self.public_to_address(self.private_to_public(private_key))


def derive(self, private_key, public_key):
if len(private_key) == self._backend.public_key_length + 1 and private_key[-1] == 1:
private_key = private_key[:-1]
if len(private_key) != self._backend.public_key_length:
raise ValueError("Private key has invalid length")
if not isinstance(public_key, tuple):
public_key = self._decode_public_key(public_key)
return self._backend.ecdh(private_key, public_key)
Expand Down Expand Up @@ -447,7 +458,15 @@ def decrypt(self, ciphertext, private_key, algo="aes-256-cbc", derivation="sha25
return self._aes.decrypt(ciphertext, iv, k_enc, algo=algo)


def sign(self, data, private_key, hash="sha256", recoverable=False, is_compressed=True, entropy=None):
def sign(self, data, private_key, hash="sha256", recoverable=False, entropy=None):
if len(private_key) == self._backend.public_key_length:
is_compressed = False
elif len(private_key) == self._backend.public_key_length + 1 and private_key[-1] == 1:
is_compressed = True
private_key = private_key[:-1]
else:
raise ValueError("Private key has invalid length")

data = self._digest(data, hash)
if not entropy:
v = b"\x01" * len(data)
Expand Down
2 changes: 1 addition & 1 deletion src/lib/sslcrypto/openssl/ecc.py
Original file line number Diff line number Diff line change
Expand Up @@ -311,7 +311,7 @@ def new_private_key(self):
# To big integer
private_key = BN(lib.EC_KEY_get0_private_key(eckey), link_only=True)
# To binary
private_key_buf = private_key.bytes()
private_key_buf = private_key.bytes(self.public_key_length)
# Cleanup
lib.EC_KEY_free(eckey)
return private_key_buf
Expand Down

0 comments on commit fa880d9

Please sign in to comment.