From 2e4e2db4932b1771069b97326a80bb19777666d1 Mon Sep 17 00:00:00 2001 From: Daniele Lacamera Date: Thu, 4 Apr 2019 14:39:55 +0200 Subject: [PATCH] Ed25519Private can now handle public keys --- src/wolfcrypt/_build_ffi.py | 2 ++ src/wolfcrypt/ciphers.py | 19 +++++++++++++++---- tests/test_ciphers.py | 3 ++- 3 files changed, 19 insertions(+), 5 deletions(-) diff --git a/src/wolfcrypt/_build_ffi.py b/src/wolfcrypt/_build_ffi.py index ac81739..859aa8f 100644 --- a/src/wolfcrypt/_build_ffi.py +++ b/src/wolfcrypt/_build_ffi.py @@ -171,6 +171,8 @@ ffi.cdef( void wc_ed25519_free(ed25519_key* ed25519); int wc_ed25519_make_key(WC_RNG* rng, int keysize, ed25519_key* key); + int wc_ed25519_make_public(ed25519_key* key, unsigned char* pubKey, + word32 pubKeySz); int wc_ed25519_size(ed25519_key* key); int wc_ed25519_sig_size(ed25519_key* key); int wc_ed25519_sign_msg(const byte* in, word32 inlen, byte* out, diff --git a/src/wolfcrypt/ciphers.py b/src/wolfcrypt/ciphers.py index 88aa098..80d2e7f 100644 --- a/src/wolfcrypt/ciphers.py +++ b/src/wolfcrypt/ciphers.py @@ -674,11 +674,18 @@ class Ed25519Private(Ed25519Public): idx[0] = 0 if pub: ret = _lib.wc_ed25519_import_private_key(key, len(key), pub, len(pub), self.native_object); + if ret < 0: + raise WolfCryptError("Key decode error (%d)" % ret) else: ret = _lib.wc_ed25519_import_private_only(key, len(key), self.native_object); + if ret < 0: + raise WolfCryptError("Key decode error (%d)" % ret) + pubkey = _ffi.new("byte[%d]" % (self.size * 4)) + ret = _lib.wc_ed25519_make_public(self.native_object, pubkey, self.size) + if ret < 0: + raise WolfCryptError("Public key generate error (%d)" % ret) + ret = _lib.wc_ed25519_import_public(pubkey, self.size, self.native_object); - if ret < 0: - raise WolfCryptError("Key decode error (%d)" % ret) if self.size <= 0: # pragma: no cover raise WolfCryptError("Key decode error (%d)" % self.size) if self.max_signature_size <= 0: # pragma: no cover @@ -692,15 +699,19 @@ class Ed25519Private(Ed25519Public): Returns the encoded key. """ key = _ffi.new("byte[%d]" % (self.size * 4)) + pubkey = _ffi.new("byte[%d]" % (self.size * 4)) size = _ffi.new("word32[1]") size[0] = _lib.wc_ed25519_priv_size(self.native_object) ret = _lib.wc_ed25519_export_private_only(self.native_object, key, size) if ret != 0: # pragma: no cover - raise WolfCryptError("Key encode error (%d)" % ret) + raise WolfCryptError("Private key encode error (%d)" % ret) + ret = _lib.wc_ed25519_export_public(self.native_object, pubkey, size) + if ret != 0: # pragma: no cover + raise WolfCryptError("Public key encode error (%d)" % ret) - return _ffi.buffer(key, size[0])[:] + return _ffi.buffer(key, size[0])[:], _ffi.buffer(pubkey, size[0])[:] def sign(self, plaintext): """ diff --git a/tests/test_ciphers.py b/tests/test_ciphers.py index 8d985ab..1188883 100644 --- a/tests/test_ciphers.py +++ b/tests/test_ciphers.py @@ -355,7 +355,8 @@ def test_ed25519_key_encoding(vectors): priv.decode_key(vectors[Ed25519Private].key) pub.decode_key(vectors[Ed25519Public].key) - assert priv.encode_key() == vectors[Ed25519Private].key + assert priv.encode_key()[0] == vectors[Ed25519Private].key + assert priv.encode_key()[1] == vectors[Ed25519Public].key # Automatically re-generated from private-only assert pub.encode_key() == vectors[Ed25519Public].key