ECIES: ECDSA with Kmac and without MAC

I have couple of questions about ECIES. I understand how ECIES work and what I must do if I want to have ECIES with ECDSA for authentication (I understand that for full authentication I have to have PKI, but for simplicity in these examples I will not use PKI). I can use sign-encrypt-sign (as described here ECIES with ECDSA):

ECIES(Bob's public key, M || ECDSA(Alice's static private key, M))

And in this case I have structure of message for sending:

[Alice's ephemeral public key, Alice's static public key, ciphertext, Mac's tag]

I understand that this is secure, but for example Alice do:

fetch Bob's static public key
generate ephemeral key pair
SK = ECDH(Bob's static public key, Alice's ephemeral private key)
Kenc || Kmac = KDF(SK)
Ciphertext = Encrypt(Message, Kenc)
ECDSA's tag = ECDSA(Ciphertext, Alice static private key)
HMAC's tag = MAC(Alice's static public key || Ciphertext || ECDSA's tag, Kmac)

Alice make ECDSA's tag first and after that make MAC's tag based on Alice's static public key, Ciphertext, and ECDSA's tag. Alice have structure of message:

|Alice's ephemeral public key, Alice's static public key, Ciphertext, ECDSA's tag, MAC's tag|

I think this is secure as sign-encrypt-sign, because ECDSA's tag is signed by Kmac and Eve can not just take this message, throw away Alice's ECDSA tag, sign the ciphertext with Eve's own key because after that she need to make MAC's tag and she can not, because she do not know Kmac.

Do I correct understand that this is secure as sign-encrypt-sign?

If this correct, I am not sure that MAC's tag is necessary in this scheme. Alice would do:

fetch Bob's public key
generate ephemeral key pair
SK = ECDH(Bob's public key, Alice's ephemeral private key)
Kenc || Kmac = KDF(SK)
Ciphertext = Encrypt(Message, Kenc)
ECDSA's tag = ECDSA(Alice's public key || Ciphertext || Kmac, Alice's static private key)

And Alice have structure of message for sending:

|Alice's ephemeral public key, Alice's staic public key, C, ECDSA's tag|

I think Bob can use ECDSA's tag for verifying that message was not changed and that this message was sent by Alice. Eve can not compromise the message because she have to know Kmac which is used to make correct ECDSA's tag, is not it?

Or, for example, can I use last scheme only for handshake message and after that encrypt next messages by using symmetric cipher and MAC?

• This question is unanswerable if you don't articulate the security goals you're hoping for. Please step back from jury-rigging compositions of ECDH, KMAC, ECDSA, etc., or any specific cryptography, and write down what you're positively trying to achieve with what resources for what legitimate parties, what powers an an adversary has to subvert those resources, and what you want to ensure the adversary cannot do to the legitimate parties in spite of those powers. – Squeamish Ossifrage Jul 8 '18 at 20:35
• @SqueamishOssifrage, I do not jury-rigging anything. I just take ECIES with sign-then-encryptand and try to understand why people do it instead of the scheme I described (ECDSA plus Kmac without MAC) becase I think making ECDSA's tag and MAC's tag more costly than making only ECDSA's tag. It is about performance. Also I have written that security goals I expected, because I take ECIES like platfrom and think about authentication by using only public keys without PKI and I do not want Eve can do that I have written in my question. Please, read my qestion more carefully. – sribin Jul 9 '18 at 6:00

There are issues in the question, some serious. In reading order:

1. ECIES(Bob's public key, M || ECDSA(Alice's static private key, M)) is sign-then-encrypt, which is perfectly fine. But count the signatures, there's only one (ECIES does not sign). Therefore this is not "sign-encrypt-sign" as described elsewhere.

2. If we wanted to make sign-then-encrypt-then-sign, just replace the resulting ECIES result X by X || ECDSA(Alice's static private key, X). But take care that the final signature leaks who the signer is, when sign-then-encrypt keeps it confidential to all but the holder of the decryption private key.

3. The "message for sending" is said to be [Alice's ephemeral public key, Alice's static public key, ciphertext, Mac's tag]. That's not matching the form of an ECIES cryptogram per SEC 1 Ver. 2.0, 5.1.3 Action 9, where Alice's static public key is not part of the output. Strictly stick to ECIES, or use another name. The ECIES result is [Alice's ephemeral public key || Ciphertext || Mac's tag]. If Alice's identity or public key or certificate is needed, it can be part of the message itself.

4. What's hashed in Kenc || Kmac = KDF(SK) should be the (bytetring representation of the) $x$ coordinate of SK (per 5.1.3 Action 4), without the $y$ coordinate or parity bit. I would note Kenc || Kmac = KDF(SKx) to make the distinction explicit.

5. In Ciphertext = Encrypt(Message, Kenc) it is not stated what Message is. If that's M, then M is not signed. That Message must be M || ECDSA(Alice's static private key, M) in order to match 1. It is critical that the ECDSA signature is encrypted, else confidentiality of the message is largely jeopardized (it becomes trivial to check a guess, e.g. of a coin toss, name, card number..)

6. ECDSA's tag = ECDSA(Ciphertext, Alice static private key) comes as a surprise at this point, since Ciphertext is currently ECIES's internal symmetric ciphertext (denoted $EM$ in 5.1.3 Action 7), and not accessible externally from the ECIES black box. That makes reuse of proper ECIES code hairy: it's result must be parsed to extract the Ciphertext portion (as an aside, the question's notation is inconsistent on order of parameters, and use of possessive for asymmetric keys).

7. HMAC's tag = MAC(Alice's static public key || Ciphertext || ECDSA's tag, Kmac) deviates from ECIES (5.1.3 Action 8). It should be replaced by HMAC's tag = MAC(Ciphertext, Kmac) (or HMAC's tag = MAC(Ciphertext || Sharedinfo2, Kmac) where Sharedinfo2 could be some externally agreed-upon bytestring; that could be Alice's static public key, but I do not see the point).

8. The order is wrong in "Alice make ECDSA's tag first and after that make MAC's tag based on Alice's static public key, Ciphertext, and ECDSA's tag". For sign-then-encrypt that should be: Alice

• makes ECDSA's signature/tag of M (this is typically first, but is independent of the next step and thus order is immaterial);
• draws an ephemeral asymmetric key pair, multiplies Bob's public key by the ephemeral private key and forgets the later, extracts the $x$ coordinate of the result, derives from that the symmetric encryption and MAC keys used in the next two steps;
• then symmetrically enciphers the concatenation of M and that signature/tag (with said concatenation denoted Message in the question), yielding ECIES's internal symmetric ciphertext (denoted Ciphertext in the question and $EM$ in 5.1.3 Action 7);
• then makes MAC's tag based on Ciphertext, and optionally Sharedinfo2;
• then concatenates the ephemeral asymmetric public key, Ciphertext, and MAC (not the optional Sharedinfo2) into the ECIES result.
9. |Alice's ephemeral public key, Alice's static public key, Ciphertext, ECDSA's tag, MAC's tag| is wrong if we are making ECIES, as explained in 2. That should be [Alice's ephemeral public key || Ciphertext || HMAC's tag], per 5.1.3 Action 9 (with the necessary conversion from public key to bytestring implicit), yielding the output of ECIES, which is ECIES(Bob's public key, M || ECDSA(Alice's static private key, M)) of 1.

10. I fail to parse "this is secure as sign-encrypt-sign". Leaving aside "secure as", it does not hold. With the changes indicated, it is made sign-then-encrypt, which is secure. Without the change, this is encrypt-then-sign-the-symmetric-part-of-the-ciphertext-and-include-that-in-the-MACed-data, this is not ECIES, and while I do not immediately see any attack, that's not a valid indication of security.

11. "I am not sure that MAC's tag is necessary in this scheme": the MAC is necessary at least for the encryption to be what's named ECIES, and to benefit of its security argument. It also serves as a protection against poor implementations on the receiving side.

12. In ECDSA's tag = ECDSA(Alice's public key || Ciphertext || Kmac, Alice's static private key), again I do not see why Alice's public key is part of what's signed; and Ciphertext is an internal variable of ECIES, which is dubious.

13. A reading of the question is that Alice reuses the same private key for ECDSA signature and ECIES decryption, which conceivably could have security implication. Formally, it makes ECIES's security argument invalid, and is explicitly against the ECDSA specification in FIPS 186-4:

ECDSA keys shall not be used for any other purpose

Summary: The alternative proposed essentially replaces ECIES's MAC with an ECDSA signature (with ECIES's MAC key entering the data signed), and makes a number of other variations of the standard ECIES (at least, including the public key, and hashing the whole ephemeral public key rather than its $x$ coordinate). That's functionally encrypt-then-sign, with something that is not exactly ECIES and does not benefit from its security proof (though I see no attack). Beware however than any encrypt-then-sign reveals the identity of the signer, when the question started with the equation of sign-then-encrypt with ECIES, which demonstrably keeps the identity of the signer confidential until decryption. The question states that it performs sign-encrypt-sign, when it appears that it does not (unless Message is assumed to be M || ECDSA(Alice's static private key, M) ). The question does not state use of separate key pairs for signature and encryption, as required by standards and the security argument of ECDSA and ECIES.

Recommendations:

• First decide if functionally the need is to have the signer's identity apparent to anyone by examination of the final cryptogram, or revealed only to the holder of the deciphering private key. For asymmetric/hybrid encryption and signature:
• if the signer's identity is to be kept secret, or if in doubt, sign-then-encrypt;
• if the signer's identity is to be apparent, encrypt-then-sign (sign-then-encrypt-then-sign also works here, but is not necessary for security when the next two recommendations are applied; it is however sometime justified, for example if cryptograms normally carrying the signer's ID must be transformable into anonymous ones by merely stripping the external signature, but should remain signed and non-repudiable after decryption).
• In the above, encrypt should be precisely ECIES, including its ephemeral key generation, symmetric encryption, MAC, and concatenation to yield the result.
• In the above, when using ECDSA, sign should be computing the ECDSA signature (including at least one hash step of the whole input) then adding the signature to the input (that can be either by appending or pretending it, as long as it can be unambiguously extracted on verification without risk of triggering implementation bugs).
• If the identity, public key, or certificate of the sender needs to be included, add it immediately after or immediately before performing one signing step (or both); that can be either by appending or pretending the information, as long as it can be unambiguously extracted without risk of triggering implementation bugs.
• When possible: one purpose, one key.

Nothing in this answer should be construed as an endorsement of anything by anyone.