I'm working on a cryptography-related project, which uses ECC (elliptic curve cryptography). And one of the things that I need is a "secure" communication channel for two entities.

I need someone to review the design. 1. First step is establishing a "shared secret". This is done in terms of Diffie-Hellman protocol. However I've read that it's not a good practice to use the "master" key for this. Because once it's compromised - all the past and future communication history of this entity is compromised as well.

So, A and B both generate nonces (scalars), and exchange the public nonces (i.e. points, G * nonce). Each multiplies its private scalar by peer's point, and they come up with the same point. Its x-coordinate is the shared secret.

2. For traffic encryption I use the AES-256 symmetric encryption in a CTR mode, as a stream cipher. The shared secret is hashed (via SHA-256), this is the symmetric key. Then it's hashed again, and this gives the IV (which is, in case of CTR, is the initial value of the "counter").

I know that the weakness of the CTR stream cipher is that anyone can easily modify the encrypted message (flip bits), and a sort of HMAC is needed. However I'd like to keep the overhead is small as I can. For this I attach a CRC-32 checksum of the message with the message counter, which is increased after every message sent. That is:

CipherMessage = AES-Stream-Cipher XOR (PlainMessage | CRC32(PlainMessage | MsgCounter++))

The initial value of MsgCounter is secret as well (derive from the shared secret)

3. After secure channel is established both entities prove their identities. This is done in terms of Schnorr's signature. Both send their public keys (points) with the Schnorr's signature. The signed message is the peer's public nonce. This scheme both proves the ownership of the public key, and prevents the man-in-the-middle attack (since we are signing the public nonce, which was used in establishing the secure channel for those specific entities).

4. One minor point: for all the "public" keys and nonces, which assume an elliptic-curve points, we actually transfer only the X-coordinate. The peer always selects the appropriate Y-coordinate in an unambiguous way (for example, assuming it must be even), and the private scalars are always selected appropriately (if they eventually correspond to a point with inappropriate Y-coordinate - they are just negated).

So, my question is, is this design secure enought? I understand that CRC-32 doesn't sound secure, brute-forcing 32 bits is relatively easy. But in my case this is only used in "live" communication, and whenever error in protocol is detected, the peer is banned for a substantial time.

Thanks in advance

  • 1
    $\begingroup$ Why not just use an established standard? TLS for example. Rolling your own crypto is never a good idea. $\endgroup$
    – mikeazo
    Commented Jul 6, 2018 at 12:51
  • $\begingroup$ I know. Let's assume for a moment it's a purely academic question $\endgroup$
    – valdo
    Commented Jul 6, 2018 at 13:03
  • $\begingroup$ sounds good. Had to be stated though. You may have seen some of the studies that show that some high percentage of code samples in answers on SO have significant vulnerabilities. Don't want this site to turn out that way too. $\endgroup$
    – mikeazo
    Commented Jul 6, 2018 at 13:05
  • $\begingroup$ after poncho's answer: doesn't some KEM + AES-GCM already fit your requirements? $\endgroup$ Commented Jul 9, 2022 at 8:54

1 Answer 1


For this I attach a CRC-32 checksum of the message with the message counter, which is increased after every message sent.

Bad Idea.

This still allows anyone to arbitrarily flip bits in the plaintext (by flipping the corresponding bit in the ciphertext, and figuring out which bits flip in the CBC; this is a trivial computation that can be done instantly)

Even if there is no existing security protocol that meets your needs, what you could do instead of a CRC is use an HMAC, and truncate it to 32 bits. That would mean that the above attack would succeed with probability $2^{-32}$ (which is the best you can do with a 32 bit tag)

  • $\begingroup$ Thanks, but I think you missed that the CRC includes, in addition to the message, an unknown counter. So that figuring-out the CRC of the modified message isn't trivial at all. Regarding truncated HMAC - this sounds good, but I'd like to save computational cost, if practically it's equivalent to what CRC can achieve. $\endgroup$
    – valdo
    Commented Jul 6, 2018 at 13:06
  • $\begingroup$ @valdo, how many bits is the secret value? $\endgroup$
    – mikeazo
    Commented Jul 6, 2018 at 13:35
  • 2
    $\begingroup$ @valdo, also you may be interested in this post $\endgroup$
    – mikeazo
    Commented Jul 6, 2018 at 13:37
  • 2
    $\begingroup$ @Valdo: actually, it turns out that the value of the unknown counter is irrelevant to which bits of the CRC the attacker will need to flip to adjust for the altered plaintext/ciphertext. That unknown counter doesn't add any protection $\endgroup$
    – poncho
    Commented Jul 6, 2018 at 14:16
  • $\begingroup$ @poncho: Thanks a lot! I knew that CRC wasn't designed for cryptography, but wasn't aware of such an invariance, and thought it might be a good idea to use it as a "cheap HMAC". So it should be a standard HMAC, possibly truncated, initialized by (for instance) the same shared secret negotiated during D.H. phase. Apart from this, do you see other weaknesses? $\endgroup$
    – valdo
    Commented Jul 6, 2018 at 21:29

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.