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][1], 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 first makes ECDSA's signature/tag of `M`, - 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 after that make MAC's tag based on `Ciphertext`, and optionally `Sharedinfo2` - then concatenate the ephemeral key (which served as the source of the symmetric encryption and MAC keys), `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 sort of encrypt-then-sign-plus-MAC-of-the-symmetric-part-of-the-ciphertext, the encryption 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. It can be understood that an entity 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][2]: > ECDSA keys **shall not** be used for any other purpose ___ 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 a signing step, or both (that can be either by appending or pretending it, 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. [1]: http://www.secg.org/sec1-v2.pdf#page=59 [2]: https://nvlpubs.nist.gov/nistpubs/fips/nist.fips.186-4.pdf#page=35