diff --git a/src/wolfcrypt/_build_ffi.py b/src/wolfcrypt/_build_ffi.py index b041aaf..eb39095 100644 --- a/src/wolfcrypt/_build_ffi.py +++ b/src/wolfcrypt/_build_ffi.py @@ -178,6 +178,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 ebe43d4..410e1a2 100644 --- a/src/wolfcrypt/ciphers.py +++ b/src/wolfcrypt/ciphers.py @@ -770,11 +770,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 @@ -788,15 +795,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 57d94c3..5e5116d 100644 --- a/tests/test_ciphers.py +++ b/tests/test_ciphers.py @@ -392,7 +392,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