jedisct1 / libsodium

A modern, portable, easy to use crypto library.
https://libsodium.org
Other
12.35k stars 1.75k forks source link

Not all bits of secret key are significant in crypto_box_open #1279

Closed topiolli closed 1 year ago

topiolli commented 1 year ago

I'm not sure if this is a bug or a feature, but it is worrying. I was writing unit tests for a C++ program that uses the crypto_box functions and noticed that I can change some bits of the recipient's private key and still get the plaintext back.

Here's a repro in Python (pip3 install pysodium):

import pysodium
message = b"Totally random message."
nonce = pysodium.randombytes(pysodium.crypto_box_NONCEBYTES)
alice_public, alice_secret = pysodium.crypto_box_keypair()
bob_public, bob_secret = pysodium.crypto_box_keypair()
ciphertext = pysodium.crypto_box(message, nonce, bob_public, alice_secret)
ba = bytearray(bob_secret)
ba[0] ^= 0x7 # flip three bits
bob_wrong_secret = bytes(ba)
wrong_decrypted = pysodium.crypto_box_open(ciphertext, nonce, alice_public, bob_wrong_secret)
wrong_decrypted == message # True

I can flip any combination of the three LSBs of the first byte of the secret key, and the decryption still works. Why?

jedisct1 commented 1 year ago

https://neilmadden.blog/2020/05/28/whats-the-curve25519-clamping-all-about/

topiolli commented 1 year ago

Thanks, I think I got the idea, broadly.

"It’s actually not too complicated once you realise what it is doing" is however an understatement to me. :smile:

jedisct1 commented 1 year ago

So, nothing to worry about. This is expected, and still plenty secure.