From c2c94b8a8b1fddf3ec80b96df439f5e1a11a2079 Mon Sep 17 00:00:00 2001 From: JoelKatz Date: Wed, 4 Apr 2012 12:45:54 -0700 Subject: [PATCH] The crux of ECIES. Generate a secret from two EC keys. At least one private key must be known, but it doesn't matter which. --- src/DeterministicKeys.cpp | 35 +++++++++++++++++++++++++++++++++++ src/key.h | 3 +++ 2 files changed, 38 insertions(+) diff --git a/src/DeterministicKeys.cpp b/src/DeterministicKeys.cpp index e9bb109f0f..4cb416e1ff 100644 --- a/src/DeterministicKeys.cpp +++ b/src/DeterministicKeys.cpp @@ -285,4 +285,39 @@ EC_KEY* CKey::GeneratePrivateDeterministicKey(const NewcoinAddress& family, cons return pkey; } + +static void* ecies_key_derivation(const void *input, size_t ilen, void *output, size_t *olen) +{ // This function must not be changed as it must be what ECDH_compute_key expects + if (*olen < SHA512_DIGEST_LENGTH) + return NULL; + *olen = SHA512_DIGEST_LENGTH; + return SHA512(static_cast(input), ilen, static_cast(output)); +} + + +std::vector CKey::getECIESSecret(CKey& otherKey) +{ // Retrieve a secret generated from an EC key pair. At least one private key must be known. + if(!pkey || !otherKey.pkey) + throw std::runtime_error("missing key"); + + EC_KEY *pubkey, *privkey; + if(EC_KEY_get0_private_key(pkey)) + { + privkey=pkey; + pubkey=otherKey.pkey; + } + else if(EC_KEY_get0_private_key(otherKey.pkey)) + { + privkey=otherKey.pkey; + pubkey=pkey; + } + else throw std::runtime_error("no private key"); + + std::vector ret(SHA512_DIGEST_LENGTH); + if (ECDH_compute_key(&(ret.front()), SHA512_DIGEST_LENGTH, EC_KEY_get0_public_key(pubkey), + privkey, ecies_key_derivation) != SHA512_DIGEST_LENGTH) + throw std::runtime_error("ecdh key failed"); + return ret; +} + // vim:ts=4 diff --git a/src/key.h b/src/key.h index 7eb4d0aeae..3caa26e4e9 100644 --- a/src/key.h +++ b/src/key.h @@ -273,6 +273,9 @@ public: return false; return true; } + + // Returns a 64-byte secret unique to these two keys. At least one private key must be known. + std::vector getECIESSecret(CKey& otherKey); }; #endif