Computational Security Definitions
Computational security is the bridge from perfect secrecy to practical cryptography. Instead of demanding that a ciphertext leak exactly zero information to an unlimited adversary, we demand that every efficient adversary has only negligible advantage in a formal experiment. This is the language used throughout modern private-key encryption, public-key encryption, MACs, signatures, and zero-knowledge.
Katz and Lindell make this shift central: modern cryptography needs definitions, assumptions, and reductions. Smart presents the same reductionist spirit later in the text through semantic security, indistinguishability, random oracles, and hybrid encryption. The shared message is that "secure" is not an adjective; it is a quantified statement about adversaries, resources, and success probabilities.
Definitions
A probabilistic polynomial-time adversary, abbreviated PPT adversary, is an algorithm that may use randomness and whose running time is bounded by a polynomial in the security parameter .
The security parameter controls key lengths, group sizes, output lengths, and adversary running times. A scheme is not a single object but a family of schemes indexed by .
A function is negligible if for every positive polynomial there is an such that for all ,
Examples such as are negligible. Functions such as , , and are not negligible because each is inverse-polynomial.
Two ensembles and are computationally indistinguishable if for every PPT distinguisher there exists a negligible function such that:
An experiment is a game between a challenger and an adversary. The challenger samples keys, flips hidden coins, answers allowed oracle queries, and checks whether the adversary wins. The adversary's advantage is its success probability beyond a trivial baseline.
For private-key encryption, a basic indistinguishability experiment is:
- The challenger samples .
- The adversary outputs equal-length messages .
- The challenger samples and returns .
- The adversary outputs .
- The adversary wins if .
The scheme is secure if every PPT adversary wins with probability at most .
Key results
Indistinguishability and semantic security are equivalent for standard encryption settings. Indistinguishability says the adversary cannot tell which of two chosen messages was encrypted. Semantic security says the adversary cannot compute meaningful information about the plaintext from the ciphertext beyond what it could compute without the ciphertext. The equivalence is powerful because indistinguishability is usually easier to prove, while semantic security matches the intuition of "learns nothing useful."
Reductions are the proof mechanism. To prove a scheme secure under an assumption, we show that any adversary breaking the scheme can be transformed into an algorithm breaking the assumption. If the assumption says no efficient algorithm can solve problem , then a successful encryption adversary would contradict that assumption.
A typical reduction has this form:
For example, a stream-cipher encryption proof may say: if adversary distinguishes encryptions using a pseudorandom generator from ideal one-time-pad encryptions, then construct distinguisher that distinguishes the generator output from uniform randomness. Since the one-time pad is perfectly secret, the only possible source of non-negligible advantage is distinguishing the keystream.
Hybrid arguments are a standard way to prove indistinguishability when a scheme has many components. A sequence of experiments begins with the real world and ends with an ideal world. If each adjacent pair is indistinguishable, then the endpoints are indistinguishable. The loss is usually bounded by a sum of adjacent advantages:
Security definitions also depend on oracle access. Eavesdropping security gives the adversary only challenge ciphertexts. Chosen-plaintext attack security, or CPA security, additionally lets it request encryptions of messages of its choice. Chosen-ciphertext attack security, or CCA security, lets it request decryptions too, except for the challenge ciphertext. Each stronger model captures more realistic interaction.
There are two complementary ways to read an asymptotic definition. The first is qualitative: for large enough security parameter, no efficient adversary has more than negligible advantage. The second is concrete: for a fixed implementation, what is the best bound on an adversary running for time , making queries, and receiving advantage ? Katz and Lindell introduce the asymptotic approach because it makes definitions clean and composable. Engineers still need concrete estimates because real keys have fixed sizes. A reduction that loses a factor of may be fine for small and useless for a very busy service.
Definitions also decide what is intentionally outside the model. A CPA experiment does not model decryption-error side channels. A standard EUF-CMA MAC experiment does not automatically model replay unless the definition or protocol state says replays are disallowed. A proof for a single user may not directly cover millions of users unless the reduction accounts for the extra attack surface. These are not defects in formalism; they are reminders that the formal statement must match the deployment question.
The phrase "for every PPT adversary" is doing heavy work. It means security is not tied to a named attack such as frequency analysis, meet-in-the-middle, or padding oracle. If any efficient attack wins, then the scheme fails the definition. Conversely, a proof usually does not enumerate attacks. It shows that a successful adversary, whatever its internal strategy, would imply a successful attack on an assumption.
Negligible probabilities are closed under polynomial sums, which is why the definition is stable. If a protocol has polynomially many bad events and each occurs with negligible probability, the union bound still gives a negligible total failure probability. This closure property is one reason cryptography does not use an arbitrary phrase such as "very small" in its core definitions.
Visual
| Concept | Informal meaning | Why it matters |
|---|---|---|
| PPT adversary | efficient randomized attacker | rules out unlimited brute force |
| negligible function | smaller than any inverse polynomial | formalizes "vanishing advantage" |
| experiment | precise attack game | removes ambiguity from "secure" |
| reduction | converts an attack into a primitive break | ties schemes to assumptions |
| hybrid argument | changes one piece at a time | handles multi-step constructions |
Worked example 1: checking negligibility
Problem: decide whether , , and are negligible.
Method:
- For , compare to any inverse polynomial . Exponential growth eventually beats polynomial growth:
for all sufficiently large . Therefore
eventually for every , so is negligible.
- For , choose the polynomial . The negligible condition would require
eventually, but this is false for every . Therefore is not negligible.
- For , compare to . We need eventually. Taking base-2 logarithms gives
which holds for all sufficiently large . Thus is negligible, although much larger than .
Checked answer: and are negligible; is not.
Worked example 2: computing distinguishing advantage
Problem: in an encryption experiment an adversary guesses the hidden bit correctly with probability . What is its advantage, and is that automatically a break?
Method:
-
The trivial random-guess success probability is .
-
Advantage is the excess over random guessing:
-
Whether this is a break depends on how the probability scales with . If the adversary achieves advantage for arbitrarily large security parameters, then the advantage is not negligible and the scheme is insecure.
-
If instead the measured happens only at a toy parameter such as , the asymptotic definition alone does not decide the real implementation. Concrete security would ask for exact resources, exact key sizes, and exact success probabilities.
Checked answer: the advantage is . It is a formal asymptotic break only if a PPT adversary maintains non-negligible advantage as grows.
Code
from fractions import Fraction
def advantage(success_probability: Fraction) -> Fraction:
return success_probability - Fraction(1, 2)
def empirical_success(correct_guesses: int, trials: int) -> Fraction:
return Fraction(correct_guesses, trials)
success = empirical_success(560, 1000)
adv = advantage(success)
print("success =", float(success))
print("advantage =", float(adv), "=", adv)
Common pitfalls
- Treating "polynomial time" as "fast in practice." A polynomial can still be unusable.
- Calling negligible. It is small, but not negligible by the cryptographic definition.
- Forgetting the security parameter. Fixed-size claims need concrete security, not only asymptotic language.
- Proving that one attack fails and calling the scheme secure. Definitions quantify over all PPT adversaries.
- Ignoring oracle access. CPA and CCA security are different experiments.
- Losing too much in a reduction. A mathematically valid reduction may still give weak concrete parameters.