From 76f8edae7b343d8898984e26ae49c7f91dd7017e Mon Sep 17 00:00:00 2001 From: jMyles Date: Fri, 6 Oct 2017 11:38:46 -0700 Subject: [PATCH] CryptoPower sign() and verify() now work properly. --- nkms/crypto/powers.py | 24 ++++++++++++--- tests/crypto/test_keypairs.py | 2 +- tests/crypto/test_keyring.py | 30 ++++++++++--------- ...test_crypto_characters_and_their_powers.py | 4 +-- 4 files changed, 39 insertions(+), 21 deletions(-) diff --git a/nkms/crypto/powers.py b/nkms/crypto/powers.py index 78ff27afe..650984a43 100644 --- a/nkms/crypto/powers.py +++ b/nkms/crypto/powers.py @@ -5,6 +5,7 @@ import msgpack import sha3 from py_ecc.secp256k1 import N, privtopub, ecdsa_raw_sign, ecdsa_raw_recover +from nkms.crypto.hash import signature_hash from nkms.crypto.keypairs import EncryptingKeypair @@ -46,7 +47,7 @@ class CryptoPower(object): """ Signs a message and returns a signature with the keccak hash. - :param Iterable message: Message to sign in an iterable of bytes + :param Iterable messages: Messages to sign in an iterable of bytes :rtype: bytestring :return: Signature of message @@ -55,13 +56,24 @@ class CryptoPower(object): sig_keypair = self._power_ups[SigningKeypair] except KeyError: raise NoSigningPower - # msg_digest = sig_keypair.digest(*messages) # This didn't work. I guess we don't hash things before signing / verifying? - msg_digest = b"".join(messages) # This does work. + msg_digest = b"".join(signature_hash(m) for m in messages) # This does work. return sig_keypair.sign(msg_digest) + def verify(self, signature, *messages, pubkey=None): + """ + Inverse of sign() above. + """ + try: + sig_keypair = self._power_ups[SigningKeypair] + except KeyError: + raise NoSigningPower + msg_digest = b"".join(signature_hash(m) for m in messages) # This does work. + return sig_keypair.verify(signature, msg_digest, pubkey) + def encrypt_for(self, pubkey_sign_id, cleartext): try: enc_keypair = self._power_ups[EncryptingKeypair] + # TODO: Actually encrypt. except KeyError: raise NoSigningPower @@ -119,6 +131,8 @@ class SigningKeypair(PowerUp): def sign(self, msghash): """ + TODO: Use crypto API sign() + Signs a hashed message and returns a msgpack'ed v, r, and s. :param bytes msghash: Hash of the message @@ -129,8 +143,10 @@ class SigningKeypair(PowerUp): v, r, s = ecdsa_raw_sign(msghash, self.priv_key) return self._vrs_msgpack_dump(v, r, s) - def verify(self, msghash, signature, pubkey=None): + def verify(self, signature, msghash, pubkey=None): """ + TODO: Use crypto API verify() + Takes a msgpacked signature and verifies the message. :param bytes msghash: The hashed message to verify diff --git a/tests/crypto/test_keypairs.py b/tests/crypto/test_keypairs.py index efde81ba6..19db42072 100644 --- a/tests/crypto/test_keypairs.py +++ b/tests/crypto/test_keypairs.py @@ -30,7 +30,7 @@ class TestSigningKeypair(unittest.TestCase): self.assertTrue(32, len(sig[1])) # Check r self.assertTrue(32, len(sig[2])) # Check s - verify_sig = self.keypair_b.verify(msg_digest, signature, + verify_sig = self.keypair_b.verify(signature, msg_digest, pubkey=self.keypair_a.pub_key) self.assertTrue(verify_sig) diff --git a/tests/crypto/test_keyring.py b/tests/crypto/test_keyring.py index 97d3ce172..68d282063 100644 --- a/tests/crypto/test_keyring.py +++ b/tests/crypto/test_keyring.py @@ -1,7 +1,9 @@ -import unittest -import msgpack import random +import unittest + +import msgpack import npre.elliptic_curve as ec + from nkms.crypto.keyring import KeyRing # from nacl.secret import SecretBox from nkms.crypto.powers import CryptoPower, SigningKeypair @@ -19,21 +21,21 @@ class TestKeyRing(unittest.TestCase): signature = self.power_of_signing.sign(self.msg) sig = msgpack.loads(signature) - self.assertTrue(1, len(sig[0])) # Check v - self.assertTrue(32, len(sig[1])) # Check r - self.assertTrue(32, len(sig[2])) # Check s + self.assertTrue(1, len(sig[0])) # Check v + self.assertTrue(32, len(sig[1])) # Check r + self.assertTrue(32, len(sig[2])) # Check s def test_verification(self): signature = self.power_of_signing.sign(self.msg) sig = msgpack.loads(signature) - self.assertTrue(1, len(sig[0])) # Check v - self.assertTrue(32, len(sig[1])) # Check r - self.assertTrue(32, len(sig[2])) # Check s + self.assertTrue(1, len(sig[0])) # Check v + self.assertTrue(32, len(sig[1])) # Check r + self.assertTrue(32, len(sig[2])) # Check s - # TODO: So ugly. Obviously CryptoPower needs to be able to verify. - is_valid = self.power_of_signing._power_ups[SigningKeypair].verify(self.msg, signature, - pubkey=self.power_of_signing.public_keys[SigningKeypair]) + is_valid = self.power_of_signing.verify(signature, self.msg, + pubkey=self.power_of_signing.public_keys[ + SigningKeypair]) self.assertTrue(is_valid) def test_key_generation(self): @@ -56,8 +58,8 @@ class TestKeyRing(unittest.TestCase): # Generate the re-encryption key and the ephemeral key data reenc_key, enc_symm_key_bob, enc_priv_e = self.keyring_a.rekey( - self.keyring_a.enc_privkey, - self.keyring_b.enc_pubkey) + self.keyring_a.enc_privkey, + self.keyring_b.enc_pubkey) # Re-encrypt Alice's symm key enc_symm_key_ab = self.keyring_a.reencrypt(reenc_key, @@ -161,7 +163,7 @@ class TestKeyRing(unittest.TestCase): path_priv_a = int.from_bytes(path_priv_a, byteorder='big') rk_ab, enc_symm_key_bob, enc_priv_e = self.keyring_a.rekey( - path_priv_a, self.keyring_b.enc_pubkey) + path_priv_a, self.keyring_b.enc_pubkey) enc_path_key, enc_path_symm_key = enc_keys[0] reenc_path_symm_key = self.keyring_a.reencrypt(rk_ab, enc_path_symm_key) diff --git a/tests/storage/test_crypto_characters_and_their_powers.py b/tests/storage/test_crypto_characters_and_their_powers.py index 50c293770..8b7befdcc 100644 --- a/tests/storage/test_crypto_characters_and_their_powers.py +++ b/tests/storage/test_crypto_characters_and_their_powers.py @@ -12,8 +12,8 @@ def test_signing_only_power_can_sign(): message = b"Llamas." content_hash(message) - signed_thing = alices_seal(message) - verification = alice._crypto_power._power_ups[SigningKeypair].verify(message, signed_thing) + signature = alices_seal(message) + verification = alice._crypto_power.verify(signature, message) assert verification