Skip to main content

Perfect Secrecy and the One-Time Pad

Perfect secrecy is the cleanest possible confidentiality definition: after seeing the ciphertext, the adversary learns nothing about which message was sent. This is stronger than "hard to break" and stronger than "no known attack." It is an information-theoretic statement, so it does not depend on the attacker's running time or computing power.

The one-time pad is the central construction. Katz and Lindell present it as the canonical perfectly secret encryption scheme and use Shannon's theorem to explain its cost: the secret key must be at least as long as the message. Smart adds information-theoretic language such as entropy, equivocation, and unicity distance, which helps connect perfect secrecy to statistical leakage in classical systems.

Definitions

Let Π=(Gen,Enc,Dec)\Pi=(\mathrm{Gen},\mathrm{Enc},\mathrm{Dec}) be a private-key encryption scheme with message space M\mathcal M, key space K\mathcal K, and ciphertext space C\mathcal C.

The scheme is perfectly secret if for every probability distribution over M\mathcal M, every message mMm\in\mathcal M, and every ciphertext cCc\in\mathcal C with Pr[C=c]>0\Pr[C=c]\gt 0,

Pr[M=mC=c]=Pr[M=m].\Pr[M=m\mid C=c]=\Pr[M=m].

Equivalently, for every pair m0,m1Mm_0,m_1\in\mathcal M and every ciphertext cCc\in\mathcal C,

Pr[EncK(m0)=c]=Pr[EncK(m1)=c],\Pr[\mathrm{Enc}_K(m_0)=c]=\Pr[\mathrm{Enc}_K(m_1)=c],

where KK is sampled by Gen\mathrm{Gen}. This equivalent condition says that the ciphertext distribution is the same no matter which message was encrypted.

The one-time pad over nn-bit strings has:

M=K=C={0,1}n.\mathcal M=\mathcal K=\mathcal C=\{0,1\}^n.

Key generation samples k{0,1}nk\leftarrow\{0,1\}^n uniformly. Encryption and decryption are:

Enck(m)=mk,Deck(c)=ck.\mathrm{Enc}_k(m)=m\oplus k,\qquad \mathrm{Dec}_k(c)=c\oplus k.

Correctness holds because:

Deck(Enck(m))=(mk)k=m.\mathrm{Dec}_k(\mathrm{Enc}_k(m))=(m\oplus k)\oplus k=m.

The phrase one-time is essential. Reusing the pad destroys perfect secrecy.

Key results

The one-time pad is perfectly secret. For any fixed mm and cc, exactly one key makes mm encrypt to cc, namely k=mck=m\oplus c. Since all keys are equally likely,

Pr[EncK(m)=c]=2n\Pr[\mathrm{Enc}_K(m)=c]=2^{-n}

for every m,c{0,1}nm,c\in\{0,1\}^n. The ciphertext distribution is uniform and independent of the message.

Shannon's lower bound says that perfect secrecy requires enough key material. In the common finite setting where every message can be sent with positive probability and decryption is correct, any perfectly secret scheme must satisfy:

KM.|\mathcal K|\ge |\mathcal M|.

For nn-bit messages, this means the key must contain at least nn bits of uncertainty. The one-time pad is therefore optimal in key length, but not convenient: sender and receiver must share a fresh key as long as all data they will ever send.

The reuse attack explains why modern systems do not simply reuse a one-time pad. If

c1=m1k,c2=m2k,c_1=m_1\oplus k,\qquad c_2=m_2\oplus k,

then

c1c2=m1m2.c_1\oplus c_2=m_1\oplus m_2.

The key cancels. The adversary may not learn both messages immediately, but it learns a relation between them. Natural language, file headers, JSON syntax, and protocol constants often make that relation enough to recover large parts of the messages.

Perfect secrecy is different from computational secrecy. Perfect secrecy tolerates unlimited attackers but pays with long secret keys. Computational secrecy permits tiny leakage probabilities against efficient attackers and uses short keys, pseudorandom generators, and block ciphers. Modern cryptography mostly uses computational security because perfect secrecy is too expensive for ordinary network communication.

Proof sketch of Shannon's bound: fix a ciphertext cc that can occur. For every message mm, perfect secrecy requires that mm remain possible after seeing cc. Correct decryption means that for each key kk, the ciphertext cc decrypts to only one message. Therefore the number of messages that can remain possible after cc is at most the number of keys. If all messages must remain possible, MK\vert \mathcal M\vert \le \vert \mathcal K\vert .

The definition quantifies over message distributions because secrecy should not rely on messages being uniform. Real messages are highly nonuniform: yes may be more likely than a random 128-bit string, English text has redundancy, and protocol messages often start with predictable headers. Perfect secrecy says even if the adversary knows that prior distribution exactly, seeing the ciphertext does not update it. The posterior equals the prior.

Entropy gives another way to phrase the same idea. If MM is the message random variable and CC is the ciphertext random variable, perfect secrecy means:

H(MC)=H(M).H(M\mid C)=H(M).

The ciphertext does not reduce uncertainty about the message. This does not mean the ciphertext is useless to the receiver. The receiver has additional information, the key KK, and with KK the conditional entropy collapses:

H(MC,K)=0H(M\mid C,K)=0

for a correct deterministic decryption scheme.

The one-time pad also shows that information-theoretic security and usability can conflict. To send a gigabyte with perfect secrecy, the parties must already share a gigabyte of fresh uniform secret key. If they can securely share that much key in advance, they might also be able to share the message itself. This does not make the one-time pad irrelevant; it is useful in special high-assurance settings and as a conceptual benchmark. It tells us exactly what true secrecy costs.

Computational encryption can be understood as replacing the uniform pad with a pseudorandom pad and replacing equality of distributions with computational indistinguishability. That replacement is enormous. It gives practical communication from short keys, but the guarantee now depends on efficient attackers, assumptions, nonce discipline, and implementation behavior. Perfect secrecy remains the comparison point that makes those compromises visible.

Perfect secrecy also says nothing about authenticity. An attacker can flip any bit of a one-time-pad ciphertext, and the receiver's decrypted plaintext will have the corresponding bit flipped. The receiver has no way to tell from the pad alone whether the ciphertext was modified. This is why information-theoretic encryption still needs an authentication mechanism if active attacks are possible.

The key distribution problem is the main practical obstacle. If two parties share fresh secret pads through a physically secure courier, then the pad can protect later radio messages. If the parties are ordinary web clients and servers meeting for the first time, they need public-key key exchange or a KEM to establish shorter session keys. Perfect secrecy solves message leakage after the key exists; it does not solve how the key was delivered.

The definition is also all-or-nothing. A scheme that leaks the length of a variable-length message is not perfectly secret over a message space containing different lengths, unless length is excluded from the secret. Modern systems often accept length leakage, but perfect secrecy forces the designer to say exactly what the message space contains.

That precision is the enduring value of the definition.

Visual

PropertyOne-time padOrdinary stream cipher
Key lengthsame as messageshort seed key
Security typeinformation-theoreticcomputational
Reuse allowednevernonce/state rules vary
Main proof ideaciphertext uniform for every messagekeystream indistinguishable from random
Main failurereused pad leaks m1m2m_1\oplus m_2nonce reuse can imitate pad reuse

Worked example 1: encrypting and decrypting a one-time pad

Problem: encrypt m=10110010m=10110010 with one-time key k=01101100k=01101100, then decrypt.

Method:

  1. XOR bit by bit:

    m = 1 0 1 1 0 0 1 0
    k = 0 1 1 0 1 1 0 0
    -----------------
    c = 1 1 0 1 1 1 1 0

    So c=11011110c=11011110.

  2. Decrypt by XORing the same key:

    c = 1 1 0 1 1 1 1 0
    k = 0 1 1 0 1 1 0 0
    -----------------
    m = 1 0 1 1 0 0 1 0
  3. Algebraic check:

ck=(mk)k=m(kk)=m.c\oplus k=(m\oplus k)\oplus k=m\oplus (k\oplus k)=m.

The checked answer is ciphertext 1101111011011110 and recovered plaintext 1011001010110010.

Worked example 2: seeing why pad reuse leaks information

Problem: two 8-bit messages are encrypted with the same one-time pad:

c1=00110111,c2=01010110.c_1=00110111,\qquad c_2=01010110.

Assume the attacker guesses that m1=01100001m_1=01100001, the ASCII byte for lowercase a. Recover m2m_2.

Method:

  1. Compute the XOR of ciphertexts:

    c1 = 0 0 1 1 0 1 1 1
    c2 = 0 1 0 1 0 1 1 0
    -----------------
    x = 0 1 1 0 0 0 0 1

    So x=c1c2=01100001x=c_1\oplus c_2=01100001.

  2. Because the same key was used,

x=(m1k)(m2k)=m1m2.x=(m_1\oplus k)\oplus(m_2\oplus k)=m_1\oplus m_2.
  1. Solve for m2m_2:
m2=xm1=0110000101100001=00000000.m_2=x\oplus m_1=01100001\oplus 01100001=00000000.
  1. Check by deriving the key from the guess:
k=c1m1=0011011101100001=01010110.k=c_1\oplus m_1=00110111\oplus01100001=01010110.

Then m2=c2k=0101011001010110=00000000m_2=c_2\oplus k=01010110\oplus01010110=00000000.

The checked answer is m2=00000000m_2=00000000. The example is artificial, but the lesson is real: a single plaintext guess can expose another message when a pad is reused.

Code

import secrets

def otp_encrypt(message: bytes, key: bytes) -> bytes:
if len(message) != len(key):
raise ValueError("one-time pad key must match message length")
return bytes(m ^ k for m, k in zip(message, key))

message = b"attack at dawn"
key = secrets.token_bytes(len(message))
ciphertext = otp_encrypt(message, key)
recovered = otp_encrypt(ciphertext, key)

print(ciphertext.hex())
print(recovered.decode())

Common pitfalls

  • Reusing a one-time pad. This is the classic catastrophic error.
  • Generating the pad with a predictable pseudorandom source and still calling it perfect secrecy.
  • Forgetting that perfect secrecy says the ciphertext leaks no information about the message, not that keys are easy to distribute.
  • Treating compression, encoding, or a fixed XOR mask as an OTP.
  • Using a key shorter than the message and cycling it, which recreates the Vigenere problem in binary form.
  • Confusing "the attacker cannot read this one example" with a proof that the ciphertext distributions are identical.

Connections