IND-security of the hashed one-time pad #
The encryption Enc(k, m) = H(k) ⊕ m with H a random oracle and key
k ← input is left-or-right indistinguishable: an adversary making at
most q oracle queries cannot tell an encryption of m₀ from one of
m₁, beyond its chance of querying the key:
|Pr[A : guess | enc m₀] − Pr[A : guess | enc m₁]| ≤ 2 (q + 1) / |input|
Proof, by game hopping #
The challenger samples the key k, computes H(k) (a fresh uniform value
on the empty cache), publishes the ciphertext c = H(k) ⊕ m_b, then runs
the adversary's query loop. The two worlds differ only in m_b.
- Preprogramming (
enc_game_eq_pre):H(k)on the empty oracle is a freshuniformwritten intoRO[k], exposing the sample that the OTP coupling acts on. - One-time-pad coupling + up-to-bad (
enc_game_relE): couple the key samples by identity and the masks by the bijectionhk ↦ hk + (m₀ − m₁), so the published ciphertexts coincide (hk + m₀ = (hk + m₀ − m₁) + m₁). The two runs then differ only atRO[k]— exactly the OW up-to-bad invariantInvUB k hk— so the shared loop body relates by the OW corebody_relE, and the guesses agree until the adversary queriesk. - Bad bound (
enc_bad_bound):Pr[adversary queries k] ≤ (q+1)/|input|, a deferred-sampling reduction to theguess_experimentframework, in three steps:enc_pre_bad_eq_nopre(dropping theRO[k]preprogramming is invisible —relE.bad_eq),enc_nopre_bad_le_gexp(reindex the mask to a fresh ciphertext somdrops out,sum_comm, tail monotonicityenc_tail_mono), andgexp_env_c_bound(the guess-experiment bound, reusing OW'sgame_1_correspondence).
We reuse ow_challenge_x as the key register and chal_x_queried_gh
as the "queried the key" flag, so lazy_query_tracked and the entire
OW up-to-bad core (body_relE, InvUB, …) apply verbatim.
Result #
enc_ind_secure (fully proved, no sorry): for a q-query adversary,
Pr[A guesses ∣ enc m₀] ≤ Pr[A guesses ∣ enc m₁] + (q+1)/|input|. By
symmetry in m₀, m₁, |Pr₀ − Pr₁| ≤ (q+1)/|input|. The whole proof is
game hopping in the relational calculus, reusing the OW up-to-bad core and
guess-experiment framework wholesale.
A commutative group structure on the output type, modelling the
one-time-pad mask (e.g. bitwise XOR). Axiomatized on the opaque
output, consistent with its other instances.
The IND game: sample key, compute H(key) (the challenger's own,
untracked query), publish H(key) ⊕ m, initialize the
"queried the key" flag, run the adversary's tracked query loop, read
its guess. The result bit is the adversary's guess.
Equations
- One or more equations did not get rendered due to their size.
Instances For
The preprogrammed form: H(key) on the empty oracle is a fresh
uniform sample written into RO[key].
Equations
- One or more equations did not get rendered due to their size.
Instances For
The win indicator and bad event #
Stage 1: indistinguishability up to the bad event #
The two encryption worlds, after preprogramming, are related by one
relE judgment whose post is encPost. The loop reuses the OW up-to-bad
body coupling body_relE verbatim.
The game-level coupling: the two preprogrammed worlds relate at
encPost — flags agree, and on good runs the guesses agree. Peels the
shared prefix (lazy_init, key sample, set key) and applies the OTP
tail.
The preprogramming mini-hop #
H(key) on the empty oracle is a fresh uniform written into RO[key]:
enc_game and enc_game_pre have equal wp.
Stage 1 result: indistinguishability up to the bad event #
One-sided up-to-bad bound: the guess probability in world m₀ is
at most that in world m₁ plus the chance the adversary queries the
key. (enc_game_pre-level; the mini-hop transfers it to enc_game.)
Indistinguishability up to the bad event (at the enc_game level).
The guess probability in world m₀ exceeds that in world m₁ by at
most the chance the adversary queries the key.
Stage 2: bounding the bad event #
Pr[adversary queries the key] ≤ (q+1)/|input|. We drop the RO[key]
preprogramming (the runs are identical until the key is queried), reindex
the mask to a fresh independent ciphertext, and bound by a
guess_experiment built from the OW body_game_1/final_game_1 — for
which game_1_correspondence already supplies the schema inequality.
The game with H(key) not preprogrammed into RO[key]: a lazy query
to the key would sample fresh. Identical to enc_game_pre until the
key is queried (the bad event).
Equations
- One or more equations did not get rendered due to their size.
Instances For
Dropping the preprogramming is invisible to the bad event. The two
games differ only by set RO[key], so they sit at InvUB, and their
bad flags agree (relE.bad_eq).
The env of the bad-event guess experiment: lazy oracle, then publish a
fresh uniform ciphertext (the mask reindex makes m disappear).
Equations
Instances For
The guess-experiment bound for the bad event: the adversary hits
the uniform key with probability ≤ (q+1)/|input|. Reuses OW's
game_1_correspondence (env-generic) + the generic interim bound.
The lazy-run bad event is bounded by the guess-experiment matched
event: reindex the mask to a fresh ciphertext (m drops out), commute
the sums, and apply the tail bound termwise.
The bad-event bound: Pr[adversary queries the key] ≤ (q+1)/|input|.
Mini-hop → drop preprogramming → guess-experiment bound.
The headline theorem #
IND-security of the hashed one-time pad. The adversary's guess
probability in the m₀ world exceeds that in the m₁ world by at most
(q+1)/|input| (its chance of querying the key). Symmetric in m₀, m₁,
so |Pr₀ − Pr₁| ≤ (q+1)/|input|.