ECIES: key derivation function and symmetric encryption scheme

I am using an elliptic curve library which provided me with a shared secret using my secret key and a foreign public key. Unfortunately an ECIES is not available in the programming language.

I would like to implement an ECIES as follows.

1. Use the shared secret as a seed for a random number generator
2. Create an xor key with the random number generator
3. Compute $cipher = message \oplus key$
4. Transmit $cipher$ and a signature of $cipher$ using my private key

Is this approach correct and safe?

• Although "cypher" can be used "cipher" is much more common nowadays. "Cyper" is incorrect. – Maarten Bodewes Jan 16 '18 at 13:00

What you are describing is a stream cipher created from a generic PRNG. However, an actual stream cipher should be used instead. PRNG's are dangerous in the sense that they are sometimes pre-seeded or re-seeded by the system. If there is no mandated algorithm then the underlying implementation may change as well. Otherwise: yes, a stream cipher can of course be used to obtain confidentiality of the messages if used correctly.

AES in CTR (counter) mode is a pretty safe bet.

You seem to be using encrypt-then-sign. Usually sign-then-encrypt is used. The issue with encrypt-then-sign is that somebody can re-sign the ciphertext and claim ownership of it. The other aspect is that after decryption the signature is lost.

Therefore, usually sign-then-encrypt is used for asymmetric primitives such as ECIES and ECDSA. This may not be a problem in your specific protocol however; you could just want to allow only signatures from one specific private / public key and you could be fine with protecting the ciphertext in transit.

Once you have established a key and authenticated the exchange then you could also use AES-GCM or another authenticated cipher to send messages providing integrity, authenticity and of course confidentiality of the messages.

Note that there is a lot to do if you want to create a transport protocol. In place encryption is a bit easier wrt to possible attack vectors. If the system is secure in the end depends if the possible threats to the system are thwarted.

We can therefore not tell you if your approach is safe; we can tell if it is unsafe though :)

• Thy. Could you give an example on how to use an actual stream cipher? E.g. Salsa20 requires a 32byte key and 12byte nonce and I am not shure how to safely derive the key and nonce from the shared secret. – Manuel Schmidt Jan 16 '18 at 13:06
• Try looking up HKDF. You could also use SHA-256 or 512 as a "poor man's" key derivation function in case implementing HKDF is a bridge too far (i.e. use KDF1 or KDF2, they are basically just hash functions with pre-formatted input). If you deterministically calculate a nonce then remember that you cannot re-use the key. – Maarten Bodewes Jan 16 '18 at 13:12
• Or you could use the PRF from TLS, or a counter based KDF etc. etc. – Maarten Bodewes Jan 16 '18 at 13:14