# Cryptology: Cryptography, Cryptanalysis and Cryptographic Engineering

> A 25-unit study of the mathematical foundations of cryptology, classical ciphers, AES, RSA, elliptic curves, cryptanalysis, authenticated encryption, digital signatures, TLS 1.3, side channels, and post-quantum cryptography.

- Author: Muhammet Ali Köker
- Language: en
- Canonical: https://alikoker.com.tr/en/cryptology
- Translation: https://alikoker.com.tr/kriptoloji
- Published: 2020-10-15T00:00:00+03:00
- Usage: https://alikoker.com.tr/en/copyright-and-terms-of-use
- Modified: 2026-10-13T01:09:35+03:00
- Type: article

Cryptology encompasses cryptography, which defines information-protection mechanisms under explicit mathematical and adversarial assumptions, and cryptanalysis, which investigates their security properties and limitations. The subject is organized around classical ciphers, number theory, information-theoretic security, computational security definitions, symmetric and public-key algorithms, key management, protocols, and secure implementations. Each method is examined in terms of its assumptions, algorithmic definition, claimed protection, and known limitations.

The mathematical prerequisites connect to [Discrete Mathematics](/en/discrete-mathematics-sets-logic-relations-graphs) and [Data Structures and Algorithm Analysis](/en/data-structures-and-algorithm-analysis). The implementation of cryptographic algorithms relates to [Secure Software Engineering](/en/secure-software-engineering-applied-cybersecurity), while broader defense architectures are covered in [Cybersecurity Engineering](/en/cybersecurity-engineering). Concise definitions are available in the [AES-GCM](/en/wiki/aes-gcm), [HMAC](/en/wiki/hmac), [Cryptographic Hash](/en/wiki/cryptographic-hash), and [TLS 1.3](/en/wiki/tls-1-3) entries. These connections distinguish mathematical properties of a cryptographic primitive from the security of the system that employs it.

Code listings are reproducible instructional demonstrations of the specified mathematical operations. Production deployments require maintained cryptographic libraries, standards-compliant parameter selection, proper key management, and protocol-level verification. Classical ciphers, RSA with small example parameters, and simplified security experiments are not suitable production-security constructions.

## Unit 1: Historical Development of Cryptology and Security Foundations

### Cryptography, cryptanalysis, and system security

Cryptology joins cryptography—the design of mechanisms that protect information under an explicit adversarial model—with cryptanalysis, which examines their assumptions and weaknesses. Security cannot be inferred from the name of an encryption algorithm alone. Key generation and storage, message encoding, peer authentication, and the handling of decrypted data all belong to the same trust boundary. Encrypting a file with AES may protect confidentiality, for example, but without an authentication tag or an independently correct MAC the recipient has no general guarantee of detecting modification. Throughout this course we evaluate each construction by **the property it protects, the assumption it needs, and the conditions under which it fails**.

Confidentiality limits an adversary's ability to learn the message; integrity detects unauthorized change; authentication links a message or session to the claimed party. A non-repudiation claim must additionally distinguish mathematical signature verification from evidence about who actually controlled the signing key. Availability and service continuity extend beyond cryptographic mechanisms into system architecture.

### Historical Development of Cryptographic Methods

Classical substitution and transposition ciphers exposed the tension between key space and language statistics. Kerckhoffs's principle shifted attention away from secrecy of the mechanism toward secrecy of the key. Shannon's information-theoretic treatment identified the conditions for perfect secrecy, while computational cryptography later defined security games against resource-bounded attackers. The replacement of DES by AES, the adoption of RSA and Diffie–Hellman, the emergence of authenticated encryption, and post-quantum standardization are distinct engineering responses to different constraints and threats.

Security design begins by identifying the asset—such as a stored audio recording—then the attacker capabilities, such as network observation, file modification, or key theft. Required properties and trust boundaries lead to a construction, a key-management procedure, and tests. Reversing this order encourages the misuse of strong primitives in unsuitable systems.

### Primitives and protocols

A hash, random generator, and block cipher are *primitives*. A *protocol* combines primitives with identities, freshness, replay protection, state, and failure behavior. Protocol review therefore includes message ordering, visible errors, timeouts, rekeying, and retained context. A security proof for a component does not automatically establish security for every protocol using it.

### Definition and Security Limitations of the Caesar Cipher

A historical cipher makes the encryption problem concrete. First choose an alphabet; in the 26-letter Latin alphabet encode A=0, B=1, ..., Z=25. Caesar encryption is `E_k(x)=(x+k) mod 26`, with decryption `D_k(y)=(y-k) mod 26`. With `k=3`, the word `ATAK` passes through `A→D`, `T→W`, `A→D`, `K→N` and becomes `DWDN`. Correct decryption follows from the inverse of modular addition, not from any security claim. An adversary can evaluate all 26 shifts. In a Turkish-language application, the Turkish alphabet, normalization, and handling of spaces must be specified first; a 26-letter demonstration must not silently be treated as a 29-letter cipher.

The experiment unifies three disciplines. Cryptography defines the transformations and key; cryptanalysis attempts recovery without the key; cryptographic engineering specifies encoding, data formats, invalid input, and the key lifecycle. Recognizing Caesar's failure is the starting point for properly understanding key sizes, public algorithms, and adversarial capabilities in modern primitives such as AES.

### Security Requirements in Historical Development

Monoalphabetic substitution preserves statistical structure. The polyalphabetic Vigenère construction replaced one shift with a repeated sequence, but the key period introduced another weakness. Shannon formalized the information-theoretic conditions behind one-time-pad secrecy. Public-key cryptography provided a new response to the distribution of shared secret keys. Modern authenticated encryption addresses the requirement to specify confidentiality and integrity together. Studying this progression in terms of the problem solved, rather than memorizing invention dates, makes the history technically useful.

## Unit 2: Classical Encryption Methods and Cryptanalysis

![Animated classical substitution cipher and frequency attack](https://alikoker.com.tr/svg/classical-frequency-attack.svg "Classical substitution cipher and frequency attack")

### Substitution, transposition, and the key space

For a letter encoded as `x`, the Caesar transformation is `E_k(x)=(x+k) mod 26`. The affine cipher generalizes it to `E_(a,b)(x)=(ax+b) mod 26`; decryption requires `a` to be coprime with 26. Transposition rearranges the positions of symbols without replacing the symbols themselves. These are historical cryptanalytic models, not contemporary security mechanisms.

In repeating-key polyalphabetic constructions such as Vigenère, the overall frequency distribution hides several offset distributions. Once a candidate key period is found, the ciphertext can be partitioned by index modulo the period and each resulting stream analyzed separately. Kasiski repetition distances and the index of coincidence help rank candidate periods, but can mislead on short or unusual texts. The subsequent process proposes a key, scores the decrypted text using linguistic evidence, and checks the resulting plaintext for semantic consistency.

### Python Demonstration of the Caesar Cipher

This function transforms Latin letters, preserves other characters, and reverses the transformation by using a negative shift. It is an **illustration of a classical cipher**, not a means of protecting private information.

```python
def caesar(text, shift):
    result = []
    for c in text:
        if 'A' <= c <= 'Z':
            result.append(chr((ord(c)-65+shift) % 26 + 65))
        elif 'a' <= c <= 'z':
            result.append(chr((ord(c)-97+shift) % 26 + 97))
        else:
            result.append(c)
    return ''.join(result)

assert caesar(caesar('Cryptology 2026', 9), -9) == 'Cryptology 2026'
```

### Statistical Weaknesses of Classical Ciphers

Frequency analysis shows that structural regularity leaks information even when implementation details are obscured. Rotor machines and mechanical mechanisms complicated these regularities, yet operational procedures, key distribution, and reuse remained vulnerable. History should therefore explain which failure each successive design was intended to address, rather than merely enumerating dates and inventors.

### Caesar, affine, and Vigenère: encryption, inversion, and attack costs

For Caesar encryption, encode each letter, add the same shift `k`, and reduce modulo the alphabet size. Recovering a key from 26 possibilities costs `O(26L)` for a length-`L` message. More importantly, letter frequencies are merely permuted. If the language model predicts probabilities `p_i`, a candidate can be assessed using a chi-squared score such as `Σ_i (o_i-E_i)^2/E_i`; short samples and proper nouns make that score unreliable.

An affine cipher uses `E_(a,b)(x)=(ax+b) mod 26`. Inversion is possible precisely when `gcd(a,26)=1`. Extended Euclid supplies `a^(-1)`, giving `D(y)=a^(-1)(y-b) mod 26`. With `a=5,b=8`, the letter `A` maps to index `8`. There are 12 permissible multipliers and 26 shifts, or just 312 possible keys, and every occurrence of one plaintext letter still maps to the same ciphertext letter. It does not provide modern secrecy.

Vigenère selects the key-letter values `k_0,...,k_(r-1)` and computes `c_i=(m_i+k_(i mod r)) mod 26`. For a candidate key length `r`, the ciphertext separates into `r` Caesar-like columns. Repeated ciphertext fragments can suggest a period through Kasiski analysis; the index of coincidence `IC=Σ_i n_i(n_i-1)/(L(L-1))` supplies a second statistical indicator. Neither yields a guaranteed key; both help rank hypotheses. Reusing a periodic key across messages accumulates statistical structure at corresponding offsets.

### Hill and Permutation-Based Ciphers

The Hill cipher transforms a block by `c=K m mod 26`. Decryption requires the determinant of `K` to be relatively prime to 26, not merely nonzero over the real numbers. A matrix with an even determinant might be invertible over the real field but not modulo 26. In a transposition cipher, the character values stay fixed while their positions are permuted, leaving single-letter frequencies unchanged but altering adjacency. Monoalphabetic, polyalphabetic, block-linear, and transposition methods teach different mathematical mechanisms; none should be mistaken for a secure contemporary design.

### Exhaustive Key Search for the Caesar Cipher

The exhaustive key-search procedure enumerates all Caesar shifts. Selecting a linguistically plausible plaintext is a separate cryptanalytic interpretation step and does not establish a general security property.

```python
ALPHABET = \"ABCDEFGHIJKLMNOPQRSTUVWXYZ\"
def caesar_candidates(ciphertext):
    data = ciphertext.upper()
    if any(ch not in ALPHABET + \" \" for ch in data):
        raise ValueError(\"Use A-Z and spaces for this demonstration\")
    for k in range(26):
        trial = \"\".join(ALPHABET[(ord(c) - 65 - k) % 26] if c != \" \" else \" \" for c in data)
        yield k, trial

assert dict(caesar_candidates(\"DWDN\"))[3] == \"ATAK\"
```

### Playfair, scytale, columnar transposition, and rotor machines

Playfair encrypts letter pairs using a keyed 5×5 square, with separate rules for pairs appearing in the same row, same column, or opposite corners of a rectangle. Encoding decisions such as combining I and J must be specified to ensure consistent decoding. A scytale transforms character positions through the winding of a strip around a cylinder; its mechanism is a permutation rather than a substitution of values. Columnar transposition uses a key-determined column order and readout convention, but multiple stages still retain exploitable linguistic structure.

Electromechanical rotor machines produce evolving substitutions based on changing internal state. In Enigma, rotor order, initial positions, ring settings, and plugboard settings contributed to operational key material; historical cryptanalysis of these systems is not the same as trying 26 Caesar shifts. The security analysis therefore accounts for cipher construction, effective key space, operational procedures and message metadata jointly.

### Comparative Analysis of Classical Cipher Algorithms

Caesar encryption maps a letter to an integer in `0..25` and computes `E_k(x)=(x+k) mod 26`; decryption uses `D_k(y)=(y-k) mod 26`. With `k=3`, `A→D`, `Y→B`, and `Z→C`. The same plaintext letter always maps to the same ciphertext letter, so statistics survive. An affine cipher uses `E_{a,b}(x)=(ax+b) mod 26`. The multiplier must be relatively prime to 26 or no modular inverse exists. With `a=5,b=8`, `A→I`, and recovery uses `x=21(y-8) mod 26`; verify `5·21 mod 26=1`.

Vigenère repeats key-dependent shifts: `c_i=(p_i+k_i) mod 26`. Repetition makes the period a useful attack hypothesis. Given a candidate period `r`, positions with the same `i mod r` can be inspected as independent substitution streams. Common factors of Kasiski repetition distances suggest periods but do not prove one. The index of coincidence, `IC=Σ f_j(f_j−1)/(N(N−1))`, helps distinguish language-like columns from nearly uniform ones; small samples carry substantial uncertainty. Hill encryption transforms entire letter blocks with `c=Kp (mod 26)` and requires `det(K)` to be invertible modulo 26. None of these properties alone provides modern chosen-plaintext security.

### Encryption and Decryption Verification for the Affine Cipher

```python
def affine(text, a=5, b=8, decrypt=False):
    assert __import__('math').gcd(a, 26) == 1
    inv = pow(a, -1, 26)
    out = []
    for ch in text.upper():
        if 'A' <= ch <= 'Z':
            n = ord(ch) - ord('A')
            v = (inv * (n - b)) % 26 if decrypt else (a * n + b) % 26
            out.append(chr(ord('A') + v))
        else:
            out.append(ch)
    return ''.join(out)

assert affine(affine('MATHEMATICS'), decrypt=True) == 'MATHEMATICS'
```

The code demonstrates the historical 26-letter Latin alphabet, not Turkish transliteration or secure communication. Alphabet normalization, spacing conventions, and keyspace assumptions affect historical cryptanalysis.

## Unit 3: Number Theory and Modular Arithmetic

![Animated extended Euclid and modular inverse](https://alikoker.com.tr/svg/extended-euclid-inverse.svg "Extended Euclid and modular inverse")


![Animated square-and-multiply modular exponentiation](https://alikoker.com.tr/svg/square-multiply-modexp.svg "Square-and-multiply modular exponentiation")

### Divisibility, the GCD, and modular inverses

Cryptographic integer arithmetic operates on residue classes rather than on ordinary decimal representations of large numbers. The statement `a ≡ b (mod n)` means that `n` divides `a-b`. Addition and multiplication are well-defined on these classes, whereas modular division is possible only when the divisor has an inverse. An inverse of `a` modulo `n` exists exactly when `gcd(a,n)=1`.

The Euclidean algorithm repeatedly applies `gcd(a,b)=gcd(b,a mod b)`. Its extended form also computes coefficients satisfying `ax+by=gcd(a,b)`; when the GCD equals one, `x mod b` is the inverse of `a`. For example, `17×2753 ≡ 1 (mod 3120)`, so 2753 is the inverse of 17 modulo 3120. The reasoning is the maintained invariant of the algorithm, not the memorization of a numerical answer.

### Exponentiation and the Chinese remainder theorem

Binary exponentiation replaces a loop of `e` multiplications for `a^e mod n` with repeated squaring. In each iteration the base is squared modulo the modulus, and the accumulator is multiplied when the current exponent bit is one. The operation takes approximately `O(log e)` modular multiplications. The Chinese remainder theorem reconstructs a result from residues under pairwise coprime moduli. RSA implementations can use this property for acceleration, provided the implementation also prevents timing and fault leakage.

```python
# Arithmetic illustration only: not a production cryptographic implementation.
def modular_inverse(a, modulus):
    old_r, r = a, modulus
    old_s, s = 1, 0
    while r:
        q = old_r // r
        old_r, r = r, old_r - q * r
        old_s, s = s, old_s - q * s
    if old_r != 1:
        raise ValueError(\"Inverse does not exist\")
    return old_s % modulus

assert modular_inverse(17, 3120) == 2753
assert pow(7, 128, 13) == 3
```

### Primes, Euler's theorem, and implementation limits

Euler's identity `a^φ(n) ≡ 1 (mod n)` requires `gcd(a,n)=1`; Fermat's little theorem is the prime-modulus special case. Satisfying a modular identity does not, by itself, prove that an arbitrary number is prime. Production key generation also requires reliable large-integer arithmetic, appropriate primality algorithms, secure entropy, side-channel-resistant implementations, and standardized key sizes. Small classroom examples are not real keys.

### Numerical Verification of RSA Arithmetic

Choose small classroom primes `p=61`, `q=53`, giving `n=3233` and `λ(n)=lcm(60,52)=780`. With `e=17`, the inverse exponent is `d=413`, because `17×413 mod 780=1`. For `m=65`, the identities `pow(65,17,3233)=2790` and `pow(2790,413,3233)=65` demonstrate the invertibility of the mathematical operation. Real RSA cannot use such tiny primes, and this deterministic transformation lacks OAEP encoding. The result establishes **algebraic correctness**, not secure encryption.

### Composition of Modular Arithmetic Algorithms

For RSA, select two large random primes and compute `n=pq`; derive `λ(n)=lcm(p-1,q-1)`, the exponent of the relevant multiplicative group. Select a public exponent `e` satisfying `gcd(e,λ(n))=1`, then calculate `d=e^(-1) mod λ(n)`. The order is important: if the inverse does not exist, the construction cannot provide its intended reversal on all admissible representatives. A classroom calculation takes `p=61,q=53,n=3233,φ(n)=3120,e=17,d=2753`; for `m=65`, encryption yields `c=65^17 mod 3233=2790` and decryption yields `2790^2753 mod 3233=65`. These values carry no operational security.

Binary exponentiation starts with `result=1`, `base=a mod n`, and `exp=e`. For an odd exponent it updates `result=result·base mod n`; at every iteration it squares the base modulo `n` and halves the integer exponent. The invariant `result·base^exp ≡ a^e (mod n)` accounts for correctness and logarithmic iteration count simultaneously. With a secret exponent, data-dependent branches and memory access can leak information; production software requires appropriate constant-time big-integer primitives rather than an instructional loop.

### Probabilistic Tests in Prime Generation

Generating a large probable prime cannot be replaced with trial division. Candidate generation produces random odd integers of the intended size, rejects small prime factors, and applies probabilistic tests or validated prime generation methods. Miller–Rabin writes `n−1=2^s d` with odd `d`, evaluates `a^d mod n`, and checks a sequence of squares for each witness. Composite values may pass particular witnesses; the error probability depends on test selection and count. RSA security also depends on unpredictable generation, suitable parameter restrictions, and implementation quality, not just primality.

### Algorithmic Verification of the Chinese Remainder Theorem

Optimized RSA inversion evaluates `m_p=c^(d mod (p−1)) mod p` and `m_q=c^(d mod (q−1)) mod q`, then reconstructs `m mod n` with CRT. Working with smaller moduli improves performance, but faulty intermediate values create a separate fault-attack surface. A result can be checked against `m^e mod n == c`; verification, suitable blinding, and a physical fault model belong to the implementation argument.

## Unit 4: Algebraic Structures, Finite Fields and Elliptic-Curve Arithmetic

![Animated elliptic-curve point addition](https://alikoker.com.tr/svg/ecc-point-addition.svg "Elliptic-curve point addition")

### Roles of Groups and Fields in Cryptography

A group has a closed operation, identity, and inverses; commutativity additionally makes it Abelian. A field requires multiplicative inverses for every nonzero element and distributivity between multiplication and addition. The distinction matters operationally: Diffie–Hellman uses a cyclic group, whereas AES byte arithmetic uses the finite field `GF(2^8)`. The ring `Z/nZ` is generally not a field when `n` is composite.

### Polynomial arithmetic in GF(2⁸)

With coefficients in `GF(2)`, the bits of a byte represent polynomial coefficients. Addition is XOR, and multiplication is polynomial multiplication followed by reduction modulo a fixed irreducible polynomial. AES uses `x^8+x^4+x^3+x+1`, encoded as `0x11B`. For instance, multiplying `0x57` by `0x83` in this field yields `0xC1`. These operations explain why AES S-box and MixColumns calculations are not ordinary integer multiplication.

### Elliptic-Curve Group Operations

A simple curve over a prime field has the form `y² ≡ x³+ax+b (mod p)`. The non-singularity condition requires `4a³+27b²` not to vanish modulo `p`. Point addition derives from the line-intersection and reflection rule; computation uses modular inverses. Scalar multiplication `kP` is evaluated through repeated doubling and conditional addition. The difficulty of recovering `k` from `P` and `kP` depends on the selected group.

Real ECC protocols must account for standardized curve parameters, point encoding, subgroup order, cofactors, and invalid-point handling. Calculating on a toy curve neither establishes a secure ECDH implementation nor removes the need for peer authentication.

### Finite-Field Arithmetic Invariants and Tests

For an AES byte, `xtime(a)` means polynomial multiplication by `x` followed by reduction modulo `0x11B`. If the top bit is zero, left shift is sufficient; otherwise the ninth bit is reduced and the low eight bits XORed with `0x1B`. A test should check `xtime(0x57)=0xAE` and `xtime(0x83)=0x1D`. Commutativity of field multiplication and multiplication by zero are useful properties, but passing a handful of examples is not a complete validation of field construction. Constant-time implementation is an additional security layer not proved by this arithmetic example.

### Byte Transformations over GF(2⁸)

AES treats each byte as a polynomial over binary coefficients. `0x57` represents `x^6+x^4+x^2+x+1`; `0x83` represents `x^7+x+1`. Addition is XOR, while multiplication is reduced modulo `m(x)=x^8+x^4+x^3+x+1` (`0x11B`). A standard instructional test is `0x57 · 0x83 = 0xC1`. This is not ordinary CPU integer multiplication: polynomial coefficients add without carries. The `xtime(a)` operation shifts a byte left and, when the old high bit was set, XORs the low eight bits with `0x1B`.

Computing inverses within this field is the algebraic basis of the AES substitution layer. Zero maps to zero as a special case; for other values, the multiplicative inverse in GF(2⁸) is followed by an affine bit transformation. This explains how nonlinearity arises instead of treating the S-box as an arbitrary lookup table.

### Validity Conditions for Elliptic-Curve Points

A short Weierstrass curve `y²=x³+ax+b (mod p)` must satisfy `4a³+27b² ≠ 0 (mod p)` to avoid singularity. Each affine point satisfies the curve equation; the point at infinity is the additive identity. For distinct points, the slope is `(y₂−y₁)(x₂−x₁)^(-1) mod p`; for doubling it is `(3x₁²+a)(2y₁)^(-1) mod p`. When a denominator cannot be inverted, the geometry determines whether the sum is the identity. Operational curve arithmetic additionally needs constant-time multiplication, point validation, and standardized parameters. Toy-curve calculations are not suitable for real key generation.

### Finite-Field and Elliptic-Curve Arithmetic

In AES `GF(2^8)`, a byte represents a polynomial of degree at most seven with coefficients in `GF(2)`. Addition is XOR; multiplication requires polynomial multiplication followed by reduction modulo `m(x)=x^8+x^4+x^3+x+1`. The known result `0x57·0x83=0xC1` is not integer multiplication of 87 and 131. For `xtime(a)`, shift left and XOR `0x1B` if the former high bit was set; `MixColumns` coefficients can then be implemented and checked without blindly copying lookup tables. The S-box uses multiplicative inversion, with a special zero case, followed by an affine transform.

Elliptic-curve cryptography instead operates on a group of curve points. For the toy prime-field equation `y² ≡ x³+ax+b (mod p)`, the result `P+Q` follows the curve's group rule. For distinct points, its slope is `(y_Q−y_P)(x_Q−x_P)^{-1} mod p`; doubling uses the derivative-based slope. Omitting modular inversion or the point at infinity produces incorrect behavior. Real protocols require standardized curves, validated point encodings, subgroup precautions, and constant-time cryptographic libraries rather than textbook-sized fields.

## Unit 5: Information-Theoretic Security and Entropy

![Animated one-time-pad posterior invariance](https://alikoker.com.tr/svg/one-time-pad-posterior.svg "One-time-pad posterior invariance")

### Uncertainty and probability distributions

Shannon entropy `H(X) = -Σ p(x) log₂ p(x)` measures average information in a random variable, not the complexity of one observed value. Conditional entropy `H(M|C)` describes uncertainty about a message remaining after ciphertext is observed. Perfect secrecy requires `P(M=m|C=c)=P(M=m)` for all admissible messages: seeing the ciphertext does not change the probabilities of candidate plaintexts.

### Perfect Secrecy in the One-Time Pad

For an `n`-bit message and an independent, uniform `n`-bit key, let `C=M XOR K`. Every fixed pair `m,c` determines exactly one `k=m XOR c`, so `P(C=c|M=m)=2^-n` independent of `m`. This establishes perfect secrecy when the key is truly random, has the proper length, and is **used once**. Reusing the key in two encryptions reveals `C1 XOR C2=M1 XOR M2`, an immediate relationship between the messages. The one-time pad also lacks inherent integrity: flipping ciphertext bits induces predictable changes to plaintext bits.

### Information-Theoretic and Computational Security

Distributing a fresh independent key as long as every message is expensive at scale. Modern constructions instead derive computationally indistinguishable keystreams from shorter secret keys, giving up unconditional security in favor of assumptions about attacker resources and problem difficulty. Key bit length, entropy of a human-chosen password, and output length are different quantities. Passing a battery of randomness tests is not, by itself, a cryptographic security proof.

### Numerical Modeling of Information Leakage

Take four-bit messages `M1=1010` and `M2=0110`, encrypted with the same `K=1100`. The ciphertexts are `C1=0110` and `C2=1010`. Their XOR is `1100`, exactly the XOR of the two plaintexts. The attacker does not need to know the key to observe this relationship. Predicting some bytes of one message can reveal information about matching bytes of the other. This controlled demonstration isolates key reuse; randomness, delivery integrity, and key distribution are separate requirements.

### Probabilistic Definition of Perfect Secrecy

Shannon's perfect-secrecy criterion is `Pr[M=m | C=c]=Pr[M=m]` for every message `m` and observable ciphertext `c`. A one-time pad uses an independent, uniformly random key `K` of the same `n`-bit length as `M`, exactly once. Encryption and decryption are `C=M XOR K` and `M=C XOR K`. For fixed `m` and `c`, exactly one key `k=m XOR c` connects them; therefore `Pr[C=c | M=m]=2^(-n)`. The ciphertext provides no statistical advantage in distinguishing messages. The entire argument depends on the key being uniformly random, message-length, independent, and non-reused.

Reusing the key produces `C₁ XOR C₂=M₁ XOR M₂`. The key disappears algebraically and information relating the two messages leaks. A known message exposes bits of the other at corresponding positions. This also gives an intuitive reason why modern stream ciphers require nonce uniqueness with a fixed key, though their security further depends on computational assumptions.

### Shannon Entropy, Min-Entropy and Key Length

Shannon entropy `H(X)=-Σ_x p(x)log₂ p(x)` measures average uncertainty. Min-entropy `H∞(X)=-log₂(max_x p(x))` captures predictability of the most likely value. A 256-bit output does not imply 256 bits of entropy: a timestamp-and-counter generator can be perfectly predictable despite long output. A strong CSPRNG cannot repair a predictable seed. An assessment must distinguish nominal keyspace size, actual entropy, password distributions, permitted oracle queries, and online rate limits.

## Unit 6: Computational Security Models and Reduction Proofs

![Animated IND-CPA experiment flow](https://alikoker.com.tr/svg/ind-cpa-game.svg "IND-CPA experiment flow")

### Formal Definition of Security Properties

The statement 'the cipher was not broken' is not a security definition. Modern treatment specifies what the adversary sees, which queries are allowed, how much computation can be used, and how success is measured. In the IND-CPA experiment the adversary chooses two equal-length messages; the experiment encrypts one of them at random; the adversary guesses which one was chosen. The difference between success probability and `1/2` measures distinguishing advantage. Unrandomized deterministic encryption generally fails this experiment because equal inputs produce equal outputs.

IND-CCA is a stronger model allowing selected decryption queries subject to restrictions. The distinction explains why ciphertext modification and observable error behavior can invalidate applications built from confidentiality-only CBC encryption. Even AEAD security relies on its nonce requirements and correct verification of tags.

### Mathematical Structure of Security Reductions

A security proof often constructs an algorithm that would violate a foundational hardness assumption if an efficient attacker against the construction existed. This establishes a model-specific mathematical implication; it does not prove that the source code or surrounding protocol has no bugs. Hybrid proofs connect a real and an ideal experiment through intermediate experiments, bounding the total distinguishing difference by the accumulated changes.

### Parameters and security budgets

A claimed 128-bit symmetric security strength is unrelated to a 128-bit RSA modulus. Asymmetric security depends on the known complexity of factoring and discrete-logarithm attacks, not merely on public-key byte length. Nonce-collision and birthday risks increase with message count. A practical security budget must account for all messages protected by a key during its lifetime, the threat horizon, and the rekeying policy—not just one encryption operation.

### Security Failure in a Distinguishing Experiment

An adversary first submits `M0` to a deterministic encryption oracle and remembers output `C0`. The adversary then submits equal-length `M0,M1` as an IND-CPA challenge. If the challenge output equals `C0`, it guesses `M0`; otherwise it guesses `M1`. Determinism under the same key makes this strategy effective even when the underlying transformation is perfectly invertible. The experiment motivates randomness or nonce context in encryption. Merely having a nonce is still insufficient if uniqueness requirements or construction security are violated.

### Construction of the IND-CPA Security Game

An adversary chooses two equal-length messages `m₀,m₁`. The challenger draws a uniform bit `b∈{0,1}` and returns `c*=Enc(k,m_b)`; the adversary uses permitted encryption queries to predict `b'`. The distinguishing advantage is `Adv=|Pr[b'=b]−1/2|`. Equal length matters because an ordinary ciphertext format can reveal message size. Deterministic encryption is often immediately distinguishable in the chosen-plaintext model: request an encryption of `m₀` and compare it with the challenge.

IND-CCA additionally permits restricted decryption queries, while forbidding decryption of the challenge itself. Malleability and the observability of errors are now important. A claim of IND-CCA security means little until the scheme, allowed oracle queries, error model, and nonce contract have been identified.

### Hybrid Games and Distinguishing Advantage

A proof begins with the real experiment `G₀`. In `G₁`, replace exactly one component—perhaps the output of a PRF—with an ideal random function. The ability to distinguish those games is bounded by a distinguisher against the PRF. Further games `G₂` and beyond alter one property at a time. By the triangle inequality, the total advantage is bounded by `|Pr[G₀]-Pr[G_t]| ≤ Σ_i |Pr[G_i]-Pr[G_(i+1)]|`. This method exposes precisely where an assumption about a computational primitive enters the claim about a complete construction.

### Reduction Loss and Computational Cost

The existence of a reduction does not mean that attacks are mathematically impossible. Running-time loss, number of queries, and success probability must be interpreted at the selected security parameter. If a forgery probability grows by roughly `q/2^t`, then `q` represents the attacker's attempts and `t` the tag length; stating `t` alone omits a meaningful part of the risk. If nonce reuse violates the game assumptions, a proof does not rescue the deployment.

### Experimental Formulation of Cryptographic Security Claims

Functional correctness, `Dec_k(Enc_k(m))=m`, does not by itself prove secrecy. In the IND-CPA game, an adversary selects equal-length `m_0,m_1`, receives `Enc_k(m_b)` for random `b∈{0,1}`, and outputs a guess `b'`. Its advantage is measured through `|Pr[b'=b]−1/2|`. A meaningful claim specifies oracle access, query counts, and the adversary's resource budget. Deterministic encryption that repeats outputs for repeated messages may fail the intended chosen-plaintext secrecy requirement.

A reduction builds an algorithm `B` around a hypothetical successful adversary `A`. `B` simulates the interaction expected by `A` and uses its output to solve a supposedly hard underlying problem. The proof must account for simulation fidelity, loss in success probability, and computation/query costs. Protocol security similarly needs a game for multiple actors and exchanged messages, not merely a locally correct cipher function.

## Unit 7: Cryptographic Randomness and Pseudorandom Constructions

![Animated DRBG lifecycle and reseeding](https://alikoker.com.tr/svg/drbg-reseed-lifecycle.svg "DRBG lifecycle and reseeding")

### Entropy Sources, DRBGs and Key Generation

Cryptographic key generation begins with an operating-system or physical entropy source and proceeds through appropriate conditioning, a generator seed, internal state, and output. Security depends on how well outputs remain unpredictable if an attacker learns earlier values or compromises state. Producing numbers with good-looking statistical distributions differs from preventing efficient prediction. Linear congruential generators useful in simulation are unsuitable for producing cryptographic secrets.

### PRG, PRF, and PRP

A PRG expands a short secret seed into an output indistinguishable from random to efficient attackers. A PRF makes a keyed function family behave like a random function; a PRP describes a keyed family of invertible permutations on fixed-size blocks. AES is used as a block-cipher PRP. Apparent randomness alone neither guarantees uniqueness of every output nor supplies authentication or safe key distribution.

### Cryptographic Randomness Interfaces in Python

The example obtains random bytes through the operating-system cryptographic interface. Randomness alone does not convert an arbitrary password into a cryptographically strong key; password-based key derivation requires a separately specified KDF.

```python
import secrets

session_key = secrets.token_bytes(32)  # 256 bits of key material
recovery_token = secrets.token_urlsafe(24)
assert len(session_key) == 32
```

Entropy-source engineering must consider reboot, virtual-machine cloning, hardware malfunction, and availability constraints. When the trusted source fails, silently falling back to a constant or clock-based seed is worse than making key generation fail explicitly.

### DRBG lifecycle and the origin of seed material

Cryptographic randomness begins when a system obtains entropy from suitable sources, initializes the state of a deterministic random-bit generator, produces output, and reseeds when required. A uniform-looking output distribution is not itself evidence of unpredictability. Whether compromise of the internal state reveals past output or permits future prediction involves distinct security properties. Python's `random` module serves simulations, whereas `secrets` is intended for cryptographic tokens. A password-reset token, session identifier, and encryption nonce each require their own definitions of size, uniqueness, and secrecy.

### PRG, PRF, PRP and Block Cipher Relationships

A PRG expands a short secret seed into a longer pseudorandom bitstream. A PRF `F_k(x)` is deterministic for a fixed secret key and input yet should look like a random function to an attacker without the key. A PRP is an invertible permutation over a fixed-size domain; AES is modeled as a PRP under suitable assumptions. A PRF is not automatically a KDF and a PRP is not an authenticated encryption format: modes, nonces, and authentication may still be needed to protect a protocol record.

### Statistical Randomness versus Cryptographic Security

Balanced bit frequencies across millions of bytes do not demonstrate that an attacker could not predict the initial state. Known-answer tests check standardized behavior, health tests detect certain failure modes, and threat modeling evaluates whether an attacker could observe or influence the source of entropy. Cloned virtual-machine snapshots, restarted containers, and poor initialization of embedded devices can cause unexpected reuse of generator states.

### DRBG Instantiation, Generation and Reseeding

Three operations matter in a cryptographic random generator: `instantiate` creates internal state from a trusted entropy source; `generate` derives output and advances the secret state; `reseed` mixes in fresh entropy when required. An operating system CSPRNG API is the appropriate application abstraction. Time, process identifiers, and deterministic constants are not adequate secret seeds on their own. A reproducible PRNG for experiments and a CSPRNG for keys or nonces serve different purposes.

For AEAD, nonce unpredictability is often less fundamental than meeting the construction's uniqueness requirements. Random 96-bit nonces have a calculable collision probability; long-lived high-throughput keys need explicit usage limits, counters or session separation, and a collision budget. Statistical randomness tests can identify particular output defects, but their passing does not itself establish adversarial security of a DRBG.

## Unit 8: Block Ciphers and the AES Algorithm

![Animated AES round transformation pipeline](https://alikoker.com.tr/svg/aes-round-pipeline.svg "AES round transformation pipeline")

### Mathematical Definition of a Block Cipher

A block cipher is a keyed, invertible mapping on fixed-size blocks. AES always uses a 128-bit block; AES-128, AES-192, and AES-256 specify **key length**, not block size. SubBytes supplies nonlinear substitution, ShiftRows permutes byte positions, MixColumns mixes columns using finite-field arithmetic, and AddRoundKey XORs a round key. Repetition across rounds combines confusion with diffusion. Encrypting one 128-bit block does not automatically give a secure method for encrypting longer messages.

### Feistel and Substitution–Permutation Networks

A Feistel round updates one half of the block using the other half and a round key. The round function need not be invertible: decryption works by reversing the order of round keys. A substitution-permutation network combines nonlinear S-boxes with linear diffusion layers. Differential and linear cryptanalysis analyze how differences and statistical biases propagate; security is not determined by the size of the key space alone.

### AES Test Vectors and Implementation Security

Official test vectors verify functional correspondence to a specification, not constant-time behavior, key lifecycle, or mode selection. Side-channel review must consider cache and lookup-table behavior. DES and Triple DES are useful historical studies but are not default designs for new encryption. Resource-constrained devices may instead employ Ascon-AEAD128 standardized in **NIST SP 800-232 (2025)**, reflecting a different cost profile rather than a universal claim of superior speed or security.

### Verification of AES Round Transformations

When using a maintained library, verify AES against known input-key-output vectors from FIPS 197 instead of rewriting rounds. First check byte ordering and block size; then key length and schedule handling; then encryption-decryption correspondence. Only after that examine mode selection, nonce lifecycle, and rejection of invalid authentication tags. This separation prevents confusing correctness of the primitive with security of a complete message-protection protocol.

### AES-128, AES-192, and AES-256: block, key, and round parameters

AES standardizes the Rijndael family with a 128-bit block. AES-128 uses a 128-bit key and 10 rounds; AES-192 uses a 192-bit key and 12 rounds; AES-256 uses a 256-bit key and 14 rounds. The state always consists of 16 bytes arranged as a 4×4 matrix in column-major order. The parameters `Nb=4`, `Nk=4/6/8`, and `Nr=10/12/14` define block columns, key words, and rounds. A longer AES key does not produce a wider block.

Encryption starts by loading the 16-byte state and XORing the initial round key (`AddRoundKey`). The first `Nr−1` rounds apply `SubBytes`, `ShiftRows`, `MixColumns`, and `AddRoundKey`, in that order. The final round deliberately omits `MixColumns` and uses only `SubBytes`, `ShiftRows`, and `AddRoundKey`. Decryption uses the corresponding inverse operations and reversed round-key order, including `InvShiftRows`, `InvSubBytes`, and `InvMixColumns` for the applicable rounds. The order matters for test vectors that inspect intermediate states.

### Algebra underlying SubBytes

The fixed S-box derives from the multiplicative inverse of each nonzero element of GF(2⁸), followed by an affine bit transformation; zero is treated separately. Thus it combines a nonlinear inverse with a linear-and-constant bit mapping. The test value `0x53` maps to `0xED` and the inverse table restores `0x53`. Understanding this construction is more useful than memorizing byte substitutions: differential behavior and nonlinearity result from these operations. Observing an S-box table is not equivalent to recovering the secret AES key.

### Functions of ShiftRows and MixColumns

`ShiftRows` retains the first row and rotates the second, third, and fourth rows left by one, two, and three byte positions. This permutation changes which bytes meet inside later columns without changing byte values. `MixColumns` multiplies each column by a fixed 4×4 matrix over GF(2⁸); its rows have coefficients `02 03 01 01`, `01 02 03 01`, `01 01 02 03`, and `03 01 01 02`. For example, the column `d4 bf 5d 30` becomes `04 66 81 e5`. The inverse transformation uses coefficients including `0e 0b 0d 09` and recovers the previous column over the same field. These two operations spread local differences across the state.

### Key expansion as a recurrence

AES-128 splits its 16-byte key into four 32-bit words `w[0..3]`. Subsequent words satisfy `w[i]=w[i−4] XOR temp`; at each fourth word `temp=SubWord(RotWord(w[i−1])) XOR Rcon[j]`. AES-192 uses `Nk=6`, while AES-256 uses `Nk=8` and applies an additional `SubWord` when `i mod 8=4`. Expansion yields separate round keys, not an independently negotiated key for every round. AES-256 performs 14 rounds; doubling the nominal key length does not double all forms of operational security. Mode, key lifetime, and nonce policy still govern use over many data blocks.

### End-to-end verification using a published FIPS vector

For the standard vector, plaintext `00112233445566778899aabbccddeeff` under the AES-128 key `000102030405060708090a0b0c0d0e0f` produces ciphertext `69c4e0d86a7b0430d8cdb78070b4c55a`. A comprehensive implementation test examines initial key addition, intermediate round states, and omission of `MixColumns` in the last round. Correctly producing one encrypted block does not design a safe file format or network protocol. Modes and authenticated encryption are addressed in Unit 10.

```python
# Verifies a published single-block AES-128 test vector only.
from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes
key = bytes.fromhex(\"000102030405060708090a0b0c0d0e0f\")
pt  = bytes.fromhex(\"00112233445566778899aabbccddeeff\")
enc = Cipher(algorithms.AES(key), modes.ECB()).encryptor()
assert enc.update(pt) + enc.finalize() == bytes.fromhex(
    \"69c4e0d86a7b0430d8cdb78070b4c55a\")
# ECB is used ONLY to check this one-block FIPS vector, never for data storage.
```

### First-Round Computation in AES-128

For the published block `00112233445566778899aabbccddeeff` and key `000102030405060708090a0b0c0d0e0f`, the initial `AddRoundKey` yields `00102030405060708090a0b0c0d0e0f0`. Applying the S-box to each byte gives round-one `SubBytes` state `63cab7040953d051cd60e0e7ba70e18c`. `ShiftRows` produces `6353e08c0960e104cd70b751bacad0e7`, and `MixColumns` yields `5f72641557f5bc92f7be3b291db9f91a`. XOR with the first expanded round key `d6aa74fdd2af72fadaa678f1d6ab76fe` gives `89d810e8855ace682d1843d8cb128fe4`. These intermediate states make AES an inspectable round transformation rather than a black-box 'encrypt' operation. The complete vector must produce `69c4e0d86a7b0430d8cdb78070b4c55a`.

An incorrect intermediate value helps localize defects: initial key addition suggests byte-order or key errors; `SubBytes` suggests field inverses or the S-box; `ShiftRows` suggests row/column placement; `MixColumns` suggests GF(2⁸) multiplication; an incorrect last `AddRoundKey` suggests expansion. This is a disciplined method for testing a low-level educational AES implementation.

### Comparison of Feistel and SPN Architectures

DES is a 64-bit-block Feistel cipher with 56 effective key bits and 16 rounds. Its swap-and-XOR structure makes decryption possible even when the internal round function is not individually invertible. Triple DES (TDEA) repeats DES operations; it remains relevant for legacy analysis but is unsuitable as a default new design because of older security and block-size constraints. AES uses a substitution–permutation network, not a Feistel construction. Blowfish, Twofish, Camellia, and ARIA are distinct cipher families, not alternative AES 'versions'. Their block sizes, schedules, round structures, standardization, and implementation ecosystems differ. Operational security further depends on the chosen mode, key custody, and authentication policy.

### AES-128/192/256 Key Words and Round Keys

AES always has a 128-bit block. AES-128 uses `Nk=4, Nr=10`, AES-192 uses `Nk=6, Nr=12`, and AES-256 uses `Nk=8, Nr=14`, producing `4(Nr+1)` 32-bit expanded words. Most words follow `w[i]=w[i−Nk] XOR temp`. If `i mod Nk=0`, then `temp=SubWord(RotWord(w[i−1])) XOR Rcon[i/Nk]`; AES-256 also applies `SubWord` at `i mod Nk=4`. Thus AES-256 is not simply AES-128 with four extra rounds: the schedule differs too.

For an AES-128 example, start with words `00010203 04050607 08090a0b 0c0d0e0f`. Rotate the last word to `0d0e0f0c`, substitute to obtain `d7ab76fe`, and apply the first round constant to produce `d6ab76fe`. XOR with the original first word yields `d6aa74fd`; succeeding XOR operations produce `d2af72fa`, `daa678f1`, and `d6ab76fe`. These are the four words of round key one. Checking each word makes it easier to localize a key-expansion bug than comparing only final ciphertext.

### AES Implementations and Related Technical Work

The state-matrix, round-key, and test-vector concerns appear in the [Lightweight AES-128 Implementation in C](/en/lightweight-aes-128-implementation-in-c) article, while the [Lightweight AES-128](/en/lightweight-aes-128-c) project describes the source-code scope. The project implements the AES block core; it does not itself provide GCM, key custody, or constant-time protection and should not be represented as a complete production encryption system. A separate analytical direction is discussed in [Algebraic Representation in AES Cryptanalysis](/en/algebraic-representation-in-aes-cryptanalysis). A concise algebraic representation does not establish a practical full-round AES break.

## Unit 9: Stream Ciphers and Keystream Generation

![Animated CTR-mode keystream generation](https://alikoker.com.tr/svg/ctr-keystream-counter.svg "CTR-mode keystream generation")

### Generating the keystream

A stream cipher XORs a message with bits derived from a key and contextual values such as a nonce or counter. Both `C=M XOR KS` and `M=C XOR KS` are straightforward; the challenge is preventing different messages from receiving the same keystream. If this occurs, `C1 XOR C2=M1 XOR M2`, which can leak substantial information whenever one plaintext is partially predictable.

### ChaCha20 and historical RC4

ChaCha20 uses addition, rotation, and XOR (ARX) on 32-bit words to generate blocks of output. The nonce and block counter determine the position within the stream. Standard ChaCha20-Poly1305 joins this encryption with a tag to form AEAD; ChaCha20 alone does not authenticate messages. RC4 is examined as a **historical negative example** because keystream biases and protocol usage undermined its security.

### Counter Management in Keystream Generation

Before encrypting, define the scope of a key and its nonce policy. During encryption advance the block counter, reject counter exhaustion, and persist the ciphertext with its metadata. If recovery from a backup or restart may reuse a counter under the same key, storage consistency becomes a cryptographic requirement. Randomly generated nonces likewise need a collision-risk analysis at large message volumes.

### XOR streams, state words, and a ChaCha20 quarter-round

A stream cipher produces a keystream `S` from a key and nonce, encrypting with `C=M XOR S` and decrypting with `M=C XOR S`. IETF ChaCha20 uses a 256-bit key, 96-bit nonce, and 32-bit block counter to construct a state of sixteen 32-bit words. Four constants, eight key words, the counter, and three nonce words are arranged in little-endian form. Twenty rounds (ten double rounds) precede feed-forward addition to the initial state and serialization into a 64-byte keystream block.

A quarter-round transforms four words by an add–XOR–rotate chain: `a+=b; d^=a; d<<<16; c+=d; b^=c; b<<<12; a+=b; d^=a; d<<<8; c+=d; b^=c; b<<<7`. Arithmetic wraps modulo `2^32`. Four quarter-rounds work on columns, followed by four on diagonals; repeat this double-round ten times. Salsa20 belongs to a related ARX family but has a distinct structure. RC4's internal permutation and byte-at-a-time generator are historical material, not a modern recommendation.

### ChaCha20-Poly1305 Key Derivation and Authentication

ChaCha20-Poly1305 derives one-time Poly1305 key material from the first keystream block using counter zero; payload encryption starts at counter one. Associated data and ciphertext are formatted with 16-byte alignment padding and their lengths before authentication. The resulting tag is intended to detect unauthorized modification. Reusing a key/nonce pair for different messages critically undermines confidentiality and authentication. When a library owns nonce generation, its documented contract must be followed.

### Counter Wraparound and Keystream Limits

Counter width bounds the number of blocks available under one nonce. The IETF construction has a 32-bit counter and 64-byte blocks, although protocol-level limits may be substantially stricter. Wraparound can reproduce a previous keystream. A production system must make nonce allocation robust against restarts, interrupted transactions, and concurrent writers.

### ChaCha20's 16-word state and block computation

ChaCha20's 512-bit state consists of four constants, eight 32-bit key words, a counter, and a 96-bit nonce. Endianness is part of the specification: words are interpreted little-endian. Each `quarter-round` performs modular `2^32` additions, XORs, and 16-, 12-, 8-, and 7-bit left rotations on four words. Four column and four diagonal quarter-rounds make a double round. Following twenty rounds, the transformed state is added word by word to the initial state to produce a 64-byte keystream block. The counter advances for each block, and exhaustion or reuse of the same key/nonce/counter region compromises confidentiality.

XOR encryption obeys `C=P XOR S` and `P=C XOR S`. Reusing `S` for two messages gives `C_1 XOR C_2=P_1 XOR P_2`, revealing the source of the failure without needing an implementation exploit. ChaCha20-Poly1305 combines the stream cipher with a Poly1305 authentication tag. Raw ChaCha20 does not prove that a received message was unmodified; per-message authentication-key derivation and verification before accepting plaintext are essential.

## Unit 10: Block Cipher Modes of Operation and Authenticated Encryption

![Animated GCM authenticated encryption](https://alikoker.com.tr/svg/gcm-aead-flow.svg "GCM authenticated encryption")

### Security Properties of ECB, CBC and CTR Modes

ECB independently transforms each block, so equal plaintext blocks create equal ciphertext blocks. CBC chains ciphertext blocks through XOR; it needs an appropriate unpredictable IV but **does not provide integrity by itself**. CTR converts a block cipher into a counter-derived keystream and is sensitive to nonce/counter reuse. Confidentiality-only modes do not provide authenticated decryption. In some protocols, distinct externally visible decryption errors can even create oracle risks.

### Inputs and Outputs of Authenticated Encryption

Authenticated Encryption with Associated Data binds an encrypted message to context that need not remain secret but must be authenticated: `encrypt(key, nonce, plaintext, aad) → ciphertext || tag`. Decryption **must not release plaintext to the application** after a wrong key, modified ciphertext, different AAD, or invalid tag. Including a record identifier and protocol version in AAD prevents silent use of ciphertext in another context; replay protection still requires application-level state or freshness checks.

### Authenticated Encryption with AES-GCM in Python

The example uses the high-level AES-GCM interface of the separately installable `cryptography` library. A 96-bit nonce from a CSPRNG **must not be reused under the same key**. Random selection is suitable as a bounded teaching example; high-volume systems must calculate per-key message limits and collision risk.

```python
import secrets
from cryptography.hazmat.primitives.ciphers.aead import AESGCM
from cryptography.exceptions import InvalidTag

key = AESGCM.generate_key(bit_length=256)
aead = AESGCM(key)
nonce = secrets.token_bytes(12)
aad = b'record:v1:42'
sealed = aead.encrypt(nonce, b'example payload', aad)
assert aead.decrypt(nonce, sealed, aad) == b'example payload'
try:
    aead.decrypt(nonce, sealed, b'record:v1:43')
    raise AssertionError('Context change must fail')
except InvalidTag:
    pass
```

GCM nonce-reuse risk and the separate nonce requirements of ChaCha20-Poly1305 must be evaluated explicitly. Standardized Ascon-AEAD128 may suit constrained devices. This example is not a substitute for actual key storage, access control, rotation, or audit design.

### Encrypted Record Format and Restart Conditions

Suppose a service stores `version | key_id | nonce | ciphertext | tag`. The version and key ID select a decryption path, but unverified metadata must not cause unbounded allocation or arbitrary dispatch. Bind the version and record ID to AAD. After rotation, retain a controlled mapping between old ciphertext and the authorized historical key, coordinating deletion with archival recovery. If one record is corrupted, rejection of its tag is safer than guessing another key and releasing unauthenticated data.

### Applications and Security Limits of Encryption Modes

ECB encrypts each 128-bit block independently: equal plaintext blocks under one key produce equal ciphertext blocks, exposing patterns. CBC computes `C₁=E_K(P₁ XOR IV)` and `C_i=E_K(P_i XOR C_(i−1))`, with decryption `P_i=D_K(C_i) XOR C_(i−1)`. CBC can provide confidentiality but not integrity. Padding oracles arise when malformed decryption produces distinguishable errors or related observations. CFB and OFB derive streams from internal block-cipher state but differ in synchronization and error propagation. CTR encrypts counter blocks with `E_K(nonce||counter)` and XORs the output with plaintext; it parallelizes naturally but must never reuse the counter stream. XTS addresses storage-sector encryption rather than general-purpose authenticated message exchange; it does not provide an ordinary message authentication guarantee.

### AES-GCM Counter Encryption and GHASH

AES-GCM combines counter-mode confidentiality with GHASH authentication over GF(2^128). First compute the hash subkey `H=E_K(0^128)`. For a 96-bit nonce, `J₀=nonce||0^31||1` is the initial counter; ciphertext blocks are XORed with AES outputs at counters starting from `inc32(J₀)`. GHASH folds AAD and ciphertext blocks by field multiplication and processes final length fields. The tag is conceptually `T=E_K(J₀) XOR GHASH_H(AAD,C)`, subject to exact standard rules for padding and bit ordering. Releasing plaintext before successful tag verification breaks the authentication contract.

### Effect of Nonce Reuse on GCM Security

Reusing a GCM key and nonce repeats the counter keystream. XORing two ciphertexts may reveal the XOR of their plaintexts, while the GHASH authentication structure becomes vulnerable as well. Generating a random 96-bit nonce for one operation does not by itself justify a long-lived system processing enormous numbers of records. The design must specify the message budget per key, nonce allocator, crash-recovery behavior, and rekeying policy.

### Negative Test for AEAD Integrity Verification

A correct AEAD API encrypts data with AAD and later authenticates both under the same context. Changing one ciphertext bit or supplying different AAD must cause failure instead of yielding plaintext. An application that writes partially decrypted data to disk or a visible buffer before verification turns a strong primitive into a vulnerable protocol.

```python
# cryptography AESGCM example; production nonce allocation needs separate design.
import os
from cryptography.hazmat.primitives.ciphers.aead import AESGCM
from cryptography.exceptions import InvalidTag
key = AESGCM.generate_key(bit_length=256)
nonce, aad, pt = os.urandom(12), b\"record:v1\", b\"example payload\"
sealed = AESGCM(key).encrypt(nonce, pt, aad)
assert AESGCM(key).decrypt(nonce, sealed, aad) == pt
try:
    AESGCM(key).decrypt(nonce, sealed[:-1] + bytes([sealed[-1] ^ 1]), aad)
    raise AssertionError(\"tampered record accepted\")
except InvalidTag:
    pass
```

### Finite-Field Arithmetic in GHASH

GCM couples AES counter-mode encryption with authentication. First compute `H=AES_K(0^128)` and interpret it as an element of `GF(2^128)`. Split AAD and ciphertext into 128-bit blocks and zero-pad only the final incomplete blocks for the authentication calculation. GHASH accumulates `Y_i=(Y_{i−1} XOR X_i)·H`; a final length block binds the bit lengths of AAD and ciphertext. Masking under the initial counter value yields the authentication tag. Thus both ciphertext and the application context supplied as AAD participate in authentication.

An implementation must transmit or reconstruct the nonce, specify the derivation of AAD, and check the complete required tag. On authentication failure, untrusted decrypted bytes must never reach application state, logs, or persistent storage. Reusing the same key/nonce pair undermines GCM's security assumptions. Systems letting many independent services select random 96-bit nonces need explicit collision analysis, key rotation, invocation budgets, and ownership rules.

### Rejection of Invalid Authentication Tags

```python
from cryptography.hazmat.primitives.ciphers.aead import AESGCM
from cryptography.exceptions import InvalidTag
import os
key, nonce, aad = AESGCM.generate_key(bit_length=256), os.urandom(12), b\"record:v1\"
ct = AESGCM(key).encrypt(nonce, b\"verified message\", aad)
assert AESGCM(key).decrypt(nonce, ct, aad) == b\"verified message\"
try:
    AESGCM(key).decrypt(nonce, ct[:-1] + bytes([ct[-1] ^ 1]), aad)
except InvalidTag:
    pass
else:
    raise AssertionError(\"tampered authentication tag accepted\")
```

This example obtains a nonce from the operating system for one message. A long-lived service must also enforce nonce uniqueness under each key across its lifetime.

## Unit 11: Cryptographic Hash Functions and Merkle Trees

![Animated Merkle-tree integrity aggregation](https://alikoker.com.tr/svg/merkle-tree-integrity.svg "Merkle-tree integrity aggregation")

### Resistance Properties of Cryptographic Hash Functions

A cryptographic hash maps input of arbitrary length to an output of fixed or selected length. Preimage resistance makes it difficult to find an input for a given digest; second-preimage resistance protects a known input against replacement by a different one with the same digest; collision resistance makes it difficult to find *any* two distinct inputs with equal digests. For an ideal `n`-bit digest the generic birthday collision cost is roughly `2^(n/2)` operations. An `n`-bit output does not provide `n` bits of security against every attack.

SHA-256 and SHA-512 belong to SHA-2, whereas SHA3-256 and SHAKE use a different sponge construction. Hashing is **not encryption**: there is no decryption key. Nor does a plain digest establish the origin of a message; anyone can hash the same bytes. Authenticity requires a trusted comparison value or a construction such as a MAC or signature.

### Merkle Tree Construction and Verification

Records are divided into leaves, each leaf is hashed with a distinct domain label, and neighboring child hashes are combined into parent nodes. The single root commits to the represented collection. A leaf can be checked through its sibling hashes and positions using a path of `O(log n)` size. Distinguishing leaf and internal-node encodings prevents ambiguous tree interpretations. A Merkle root does not identify the owner of the data or authorize changes unless it is bound to trusted or signed context.

```python
import hashlib

def sha256(data: bytes) -> str:
    return hashlib.sha256(data).hexdigest()

original = sha256(b'archive part 01')
assert original != sha256(b'archive part 02')
```

One observed difference does not establish collision resistance. MD5 and SHA-1 are not suitable choices for new collision-sensitive designs; a historical forensic reference to them must distinguish record provenance from modern security requirements.

### Merkle membership verification

Let four file chunks have leaf digests `h0,h1,h2,h3`. Compute `p01=H(0x01 || h0 || h1)` and `p23=H(0x01 || h2 || h3)`, then `root=H(0x01 || p01 || p23)`. To prove membership of the second chunk, a verifier needs its own leaf digest, `h0`, `p23`, and the sibling ordering rather than the entire file. Prefixing leaves with `0x00` helps distinguish leaves from internal nodes. The authority behind the accepted root must still be independently established.

### SHA-256 Block Processing and Compression

SHA-256 pads a message with one `1` bit, sufficient `0` bits, and a 64-bit representation of the original bit length. Each 512-bit block supplies sixteen 32-bit words, expanded to a 64-word schedule. Eight working variables progress through 64 rounds using `Ch`, `Maj`, `Σ0`, `Σ1`, and round constants; the result is added to the prior chaining state. The standard `SHA-256(\"\")` digest is `e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855`. Passing this test checks implementation behavior, not collision resistance.

SHA-1 and MD5 remain useful historically but are unsuitable for modern collision-resistance requirements. SHA-3 uses a Keccak sponge construction rather than SHA-2's Merkle–Damgård-style compression. Equal output lengths do not imply equivalent internal algorithms. Extendable-output functions such as SHAKE additionally require a specified output size.

### Length Extension Attacks and MAC Distinction

For certain Merkle–Damgård hashes, `Hash(secret||message)` is vulnerable to length-extension techniques because the digest exposes a chaining state related to message padding. Authentication requires a construction such as HMAC with a well-defined key and message format. Merely obtaining a seemingly random digest does not establish the origin of a message.

### Position and Domain Separation in Merkle Proofs

A tree can domain-separate leaves as `H(0x00||data)` and internal nodes as `H(0x01||left||right)`, preventing ambiguous interpretation of node types. Membership proofs carry sibling hashes and left/right position at every level. The verifier recomputes a root and compares it with a previously trusted root. Accepting both a root and matching proof from the same untrusted party does not establish data integrity.

### SHA-256 Padding, Message Scheduling and Compression

SHA-256 maps a byte string into eight 32-bit state words. Append a single `1` bit, then zeros until the message length is congruent to 448 modulo 512, followed by the original bit length encoded in 64 bits. Each 512-bit block starts with 16 words; expand to 64 using `W_t=σ_1(W_{t−2})+W_{t−7}+σ_0(W_{t−15})+W_{t−16} (mod 2^32)`. Perform 64 rounds with `Ch`, `Maj`, `Σ_0`, `Σ_1`, round constants, and the current state; add the result back into the chaining state modulo `2^32`. Rotation, XOR, and modular addition are algorithmic requirements rather than incidental implementation details.

An unkeyed hash does not replace a password KDF or a MAC. Matching SHA-256 digests are useful evidence for comparing files, but if an adversary controls both a file and its expected digest, the comparison does not authenticate the source. Merkle trees hash child values into parent values; verifying a leaf requires its authentication path and a trusted root. The distinction parallels [Forensic File Carving](/en/forensic-file-carver-csharp): recovered bytes, source integrity, and the investigation record are different layers of evidence.

## Unit 12: Message Authentication Codes and Key Derivation Functions

![Animated HMAC and HKDF key separation](https://alikoker.com.tr/svg/hmac-hkdf-key-separation.svg "HMAC and HKDF key separation")

### Security Properties of Message Authentication Codes

A MAC lets parties sharing a secret key verify that data has not changed and was processed with that key. Unlike a digital signature, any party holding the shared key can produce a valid tag, so the MAC does not by itself identify a unique signer to third parties. Verification must reject invalid tags without leaking partial correctness through errors, and tag length should reflect the threat model. Short fixed keys and toy XOR accumulators cannot substitute for standardized HMAC.

HMAC applies a hash using distinct inner and outer keyed pads. Intuitive combinations such as `hash(key || message)` do not automatically share its security properties. GMAC is the authentication component of GCM, while Poly1305 is a one-time MAC construction under specified key-use constraints. Their key and nonce requirements are not interchangeable.

### HKDF Extract and Expand Phases

HKDF first `Extract`s structured pseudorandom key material from its input and then `Expand`s it into subkeys using context (`info`) and output length. Its salt need not be secret, but it must match protocol design. HKDF is not a memory-hard password hashing function and cannot make a low-entropy human password resistant to offline guessing on its own.

```python
import hashlib, hmac

def hkdf_extract(salt: bytes, ikm: bytes) -> bytes:
    return hmac.new(salt, ikm, hashlib.sha256).digest()

def hkdf_expand_one(prk: bytes, context: bytes, size=32) -> bytes:
    if not 1 <= size <= 32:
        raise ValueError('This example derives one SHA-256 block')
    return hmac.new(prk, context + b'\x01', hashlib.sha256).digest()[:size]

prk = hkdf_extract(b'app-salt-v1', b'example input key material')
assert hkdf_expand_one(prk, b'encrypt-v1') != hkdf_expand_one(prk, b'mac-v1')
```

The example illustrates only the single-block expand case of RFC 5869 and is not a replacement for a verified, complete implementation. Separating encryption, authentication, and exporter keys by context prevents their accidental reuse across different operations.

### The two nested HMAC computations

HMAC normalizes its key to the compression function's block size and applies separate inner and outer pads: `HMAC_K(m)=H((K' XOR opad)||H((K' XOR ipad)||m))`. The inner pad repeats byte `0x36` and the outer repeats `0x5c`. Keys longer than a hash block are hashed first and shorter keys padded with zeros. This is a distinct construction from appending a secret to a message and hashing once. Tag length and observable comparison behavior are also part of verification design.

### Separating extraction from expansion in HKDF

HKDF-Extract computes `PRK=HMAC(salt,IKM)`; it does not magically add entropy to weak input material. HKDF-Expand computes `T(1)=HMAC(PRK,info||0x01)`, `T(2)=HMAC(PRK,T(1)||info||0x02)`, concatenating blocks to the desired length. Encoding protocol version, direction, purpose, and session context inside `info` separates outputs derived from the same root secret. HKDF-Expand is not a single SHA-256 call, and the maximum derived length depends on HMAC output size.

### Key Purposes and Protocol Binding

Encryption keys, signing keys, nonce seeds, and message-authentication keys should not be confused as slices of an untyped byte string. A KDF with distinct purpose labels makes intended usage auditable. Reusing one key in both directions of a session can mix record counters and endpoint roles; directional key separation simplifies the security model.

### HMAC and HKDF for Domain-Specific Key Separation

HMAC is not merely the concatenation `H(K||M)`. Its two-layer construction, `H((K' XOR opad)||H((K' XOR ipad)||M))`, provides a keyed authentication primitive with a carefully defined interaction with the underlying hash. Key normalization, hash block size, and the specified `ipad/opad` bytes matter. Constant-time comparison routines such as `hmac.compare_digest` should be used to check received tags; error responses and logs still require careful handling.

HKDF first extracts `PRK=HMAC(salt, IKM)`, then derives outputs through an `Expand` chain using counters and application-specific `info` labels. Encryption, authentication, and record keys derived from one shared secret should have distinct context labels so that one role's key is not silently reused for another. Salt need not be secret, but its selection must be specified. Applying HKDF to a human password does not make guessing the password expensive; password hardening is a separate problem.

```python
from cryptography.hazmat.primitives import hashes
from cryptography.hazmat.primitives.kdf.hkdf import HKDF

def derive(session_secret: bytes, label: bytes) -> bytes:
    return HKDF(algorithm=hashes.SHA256(), length=32,
                salt=b\"session-v1-salt\", info=b\"protocol/v1/\" + label).derive(session_secret)

secret = b\"demo-only-input-key-material-32!\"
assert derive(secret, b\"encryption\") != derive(secret, b\"authentication\")
```

The fixed `session_secret` is only a test input. Production key material must come from a suitable key agreement or secure random source.

## Unit 13: Password-Based Cryptographic Protection and Authentication

### Threat Model for Password Storage

Human passwords are not uniformly distributed high-entropy keys. When an attacker obtains a verification database, guesses can be made offline and in parallel. A fast digest such as `SHA-256(password)` makes each trial cheap. A unique salt prevents equal passwords from producing identical stored values and limits precomputed tables, but does not itself make each guess costly. A pepper may be a server secret kept outside the credential database; its lifecycle and recovery implications also matter.

### Memory-hard derivation

Argon2id combines time and memory costs to raise the price of parallel guessing. `scrypt` is another memory-hard option; PBKDF2 may be needed in particular compatibility regimes. Parameters should be chosen through capacity measurement, considering server memory, concurrent logins, and denial-of-service resistance, rather than copied blindly from an example. Enrollment creates a fresh user-specific salt; verification metadata includes that salt and the chosen cost parameters, never the plaintext password.

### Password Reset and Secure Migration

A successful login can trigger re-encoding with stronger KDF parameters. Replacing the salt does not make a weak password intrinsically stronger; policy and multi-factor authentication address different risks. Reset tokens require cryptographic randomness, short lifetimes, single-use handling, and responses that do not reveal account existence. Password-derived credential verifiers must not share a lifecycle with AEAD keys used to protect application data.

RFC 9106 provides Argon2 internals and test vectors. Production selection must also reflect current organizational policy and maintained libraries.

### Cost Parameters of Password-Based KDFs

Do not select KDF parameters by choosing the fastest outcome on one machine. Define target hardware and concurrent login volume, then measure Argon2id memory cost against response-time constraints. The configuration must raise the cost of parallel guessing without allowing login load to exhaust the server's memory. Failure timing and messages should not reveal whether an account exists. Login throttling complements the KDF rather than replacing it.

### Password Verifier Record Format

A verifier does not store the plaintext password. For each account it obtains an independent random `salt`, applies a password KDF such as Argon2id with specified memory, iteration, and parallelism costs, and stores a formatted record containing the algorithm version, parameters, salt, and derived verifier. On login the stored parameters drive recalculation through a maintained library API with appropriate verification behavior. Salt is public. An optional secret `pepper` belongs in a separate trust boundary and requires its own loss and rotation plan.

An online guessing attack differs from offline cracking of a stolen verifier database. Rate limits, MFA, and request policy dominate the online model; the offline model depends on password distribution and CPU/memory cost per candidate. Raising work factors without measurement may also create denial-of-service risk on the authenticating server.

### Updating Password Derivation Parameters

After successful login, an obsolete work factor may be replaced with new parameters and an atomic record update. Old and new verification formats must not be confused during transition. Password recovery separately requires a random, short-lived, single-use token, a safely stored token verifier, atomic consumption, and a guarantee that the raw token never enters application logs.

### Password verification cost and migration

Password storage should permit later verification without storing the password itself. Store a format identifying the algorithm version, parameters, per-user salt, and derived output. In Argon2id, memory `m`, pass count `t`, and parallelism `p` affect both authorized logins and offline guessing cost. Choose parameters against service concurrency, memory capacity, and latency goals, not from a single benchmark. Excessive memory consumption can itself create a denial-of-service risk.

After successful verification, a service can rehash under newer parameters or a newer algorithm version. Recording the algorithm identifier unambiguously is essential during migration. Multifactor authentication and session controls complement rather than replace a password KDF. Applications must avoid logging passwords, raw derived secrets, or sensitive verification inputs.

## Unit 14: Public-Key Encryption and the RSA Algorithm

![Animated RSA-OAEP hybrid encryption](https://alikoker.com.tr/svg/rsa-oaep-hybrid-flow.svg "RSA-OAEP hybrid encryption")

### RSA Arithmetic and Secure Encoding Schemes

RSA key generation chooses two sufficiently large independent primes `p,q`, forms `n=pq`, computes `λ(n)=lcm(p-1,q-1)`, selects `e` coprime with `λ(n)`, and obtains `d=e^(-1) mod λ(n)`. Classroom equations `c=m^e mod n` and `m=c^d mod n` are mathematically useful, but **textbook RSA** is deterministic and malleable and is not IND-CPA-secure encryption. Arithmetic correctness and cryptographic security are different claims.

### OAEP and hybrid encryption

RSA-OAEP provides standardized randomized encoding analyzed under specified assumptions. Real deployments do not encrypt arbitrary long messages directly with RSA. A short session key or shared secret is established securely; bulk data is protected with AEAD. The receiver validates the asymmetric component, derives session keys, and verifies the authenticated ciphertext. Modern HPKE and KEM constructions likewise require explicit discussion of security models, parameters, and identity assumptions.

### Security Limitations of Educational RSA Code

Small `pow(m,e,n)` examples in the source archive are useful for understanding modular exponentiation but must not be presented as production encryption libraries. In actual code, OAEP hash and mask-generation parameters, message-size restrictions, private-key protection, consistent failure behavior, and the recipient's identity all require verification. A long-lived key does not promise perpetual confidentiality when key compromise and future computing power belong to the threat model.

### ElGamal and algebraic malleability

In a cyclic group, basic ElGamal encryption uses a recipient's public key `h=g^x` and fresh randomness `r` to create `(g^r, m·h^r)`. The recipient raises the first component to secret `x` and removes the resulting shared factor from the second. This connects Diffie–Hellman intuition to encryption, but elementary ElGamal is algebraically malleable and does not, on its own, meet chosen-ciphertext security. The limitation motivates authenticated and encapsulation-based constructions. Elliptic-curve ElGamal, RSA, and code-based techniques rely on different underlying problems.

### RSA Key Generation, Encryption and Decryption

The algebraic core of RSA uses a modulus `n=pq`, a public exponent `e`, and private exponent `d`. Generate suitable primes `p,q`, calculate `n=pq` and `λ(n)=lcm(p−1,q−1)`, verify `gcd(e,λ(n))=1`, and derive `d=e^(-1) mod λ(n)`. The public key is `(n,e)`; the private key contains `(n,d)` and commonly CRT parameters. A representative integer `m` is transformed to `c=m^e mod n` and inverted as `m=c^d mod n`. With toy values `p=61,q=53,n=3233,e=17,d=2753,m=65`, the result `c=2790` makes the full process observable. This only verifies arithmetic: raw textbook RSA is deterministic, algebraically malleable, and not a secure encryption protocol.

### RSA-OAEP Message Encoding

RSA-OAEP begins with message bytes, a selected hash function, and `lHash` of the optional context label. The size condition is `mLen ≤ k−2hLen−2`, where `k` is the RSA modulus length in bytes and `hLen` is the digest length. Construct `DB=lHash||PS||0x01||M`, generate a random `seed`, produce `dbMask` using MGF1, and form `maskedDB=DB XOR dbMask`. Derive `seedMask` and compute `maskedSeed=seed XOR seedMask`. The final encoded message is `EM=0x00||maskedSeed||maskedDB`, interpreted as an integer before public RSA exponentiation. Decryption first performs private exponentiation, then unmasks and checks the encoding. Different visible error classes can form a decryption oracle and must be handled carefully.

### RSA Encryption and Signature Encoding Schemes

OAEP is an encryption encoding, while RSASSA-PSS is a signature scheme. PSS combines a message digest, random salt, and MGF1 within a prescribed EMSA-PSS encoding; signing uses the private key and verification the public key. Historical PKCS#1 v1.5 modes matter for compatibility analysis but require different risk considerations. Neither confidentiality nor signature security follows solely from the existence of modular exponentiation. Security depends on the full encoding, randomization, error behavior, and corresponding standard.

### RSA-OAEP Library Usage and Negative Tests

This code uses a maintained library for OAEP and PSS; it does not implement raw big-integer RSA or treat a signature as an encrypted message.

```python
from cryptography.hazmat.primitives.asymmetric import rsa, padding
from cryptography.hazmat.primitives import hashes
from cryptography.exceptions import InvalidSignature
sk = rsa.generate_private_key(public_exponent=65537, key_size=3072)
pk = sk.public_key()
msg = b\"signed and encrypted classroom record\"
oaep = padding.OAEP(mgf=padding.MGF1(hashes.SHA256()),
                    algorithm=hashes.SHA256(), label=None)
ct = pk.encrypt(msg, oaep)
assert sk.decrypt(ct, oaep) == msg
pss = padding.PSS(mgf=padding.MGF1(hashes.SHA256()),
                  salt_length=padding.PSS.DIGEST_LENGTH)
sig = sk.sign(msg, pss, hashes.SHA256())
pk.verify(sig, msg, pss, hashes.SHA256())
try:
    pk.verify(sig, msg + b\"!\", pss, hashes.SHA256())
    raise AssertionError(\"invalid signature accepted\")
except InvalidSignature:
    pass
```

### RSA-CRT, blinding, and hybrid-encryption boundaries

Direct RSA encryption cannot and should not be used for arbitrarily large messages. Hybrid designs encrypt bulk data under a fresh symmetric key and AEAD, and protect key establishment through an appropriate encapsulation mechanism. CRT accelerates private-key operations but raises fault and side-channel considerations; blinding and verification belong in the implementation review. The private exponent and prime factors remain secret. Publishing the public key is not itself a vulnerability.

### Separating RSA Encryption and Signature Operations

After key generation, RSA's intended operation must be explicit. `RSAES-OAEP` encrypts under the recipient's **public** key, with decryption under the recipient's **private** key. `RSASSA-PSS` signs under the sender's **private** key, while anyone with the correct **public** key can verify. Neither operation should be explained as the simplistic rule 'encrypt with a private key and decrypt with the public key.' PSS does not conceal the message; an OAEP ciphertext does not authenticate who sent it. A protocol using both must select the proper key and context for each purpose.

With RSA-3072 and OAEP using SHA-256, `k=384` bytes and `hLen=32` bytes, so the maximum encoded message size is `384−64−2=318` bytes. This is a size limit of the padding scheme, not an argument for RSA as a bulk-file cipher. Encrypt large data using AES-GCM or ChaCha20-Poly1305 under a symmetric key established by an appropriate method. Matching OAEP labels, selecting the intended MGF1 hash, and validating expected modulus-length encodings belong to the decryption contract.

### Negative Tests for RSA Parameter Mismatch

Trying to decrypt a valid OAEP ciphertext with another private key or an inconsistent label must fail. Altering one byte of a signed message must fail PSS verification. A successful encrypt/decrypt round-trip for correct inputs combined with reliable rejection of wrong context is an important negative API test. The objective is not private-key recovery but demonstrating that unauthorized inputs cannot produce accepted plaintext or signatures.

### RSA-CRT and Secure Encoding Algorithms

Choose two distinct large primes `p,q` and compute `n=pq`. With `λ(n)=lcm(p−1,q−1)`, select a public exponent satisfying `gcd(e,λ(n))=1` and derive `d≡e^{-1} (mod λ(n))`. A small educational example uses `p=61,q=53`, yielding `n=3233`, `φ(n)=3120`, `e=17`, `d=2753`, with `ed≡1 (mod 3120)`. For `m=65`, raw arithmetic gives `65^17 mod 3233=2790` and `2790^2753 mod 3233=65`. This proves only the correctness of the arithmetic core, not security of raw RSA for messages.

For CRT acceleration, compute `dP=d mod (p−1)`, `dQ=d mod (q−1)`, and `qInv=q^{-1} mod p`. Reconstruct from two smaller exponentiations using a Garner-style combination. Production implementations additionally need blinding, secret-independent execution properties, and post-operation integrity checks against fault and side-channel risks. OAEP constructs `DB` from `lHash`, a padding string, `0x01`, and the message; a random `seed` masks it through MGF1, and the seed is masked in turn. PSS signing has a separate encoded-message construction with a salt and verification checks. Neither encoding may be replaced by bare modular exponentiation.

## Unit 15: Diffie–Hellman and Elliptic-Curve Key Agreement

![Animated ECDH shared-secret agreement](https://alikoker.com.tr/svg/ecdh-shared-secret.svg "ECDH shared-secret agreement")

### Computation of a Diffie–Hellman Shared Secret

Classic Diffie–Hellman publishes group parameters `p,g`. One party chooses secret `a`, the other `b`; they exchange `A=g^a mod p` and `B=g^b mod p`. Both compute `B^a ≡ A^b ≡ g^(ab) (mod p)`. An observer's difficulty in computing the shared value depends on the chosen group's hardness assumptions. This algebra does **not** authenticate peers against an active man-in-the-middle who can establish two different sessions.

### ECDH and authenticated exchange

Elliptic-curve Diffie–Hellman uses scalar point multiplication instead of modular exponentiation. X25519 standardizes a key-agreement interface on a particular Montgomery curve. The shared secret should feed a context-bound KDF incorporating session identity, endpoint roles, and the protocol transcript, rather than being used directly as the bulk-encryption key. Specified handling of public-key encodings and small-order inputs matters.

### Session-Key Lifecycle

An authenticated handshake generates ephemeral keys, binds contributions into protocol messages, proves identity with signatures or PSKs, includes the transcript in derivation, and produces separate traffic secrets. Prompt disposal of ephemeral private values helps provide forward secrecy against later long-term key compromise; it does not by itself stop impersonation. Replay prevention and rekeying are separate concerns.

Advanced study can compare authenticated ECDH, HPKE, and post-quantum KEM combinations within one protocol. Merely combining two algorithms is not, by itself, a proof of hybrid security.

### Small-Group Diffie–Hellman Example

For mathematics only, take `p=23,g=5,a=6,b=15`. The public contributions are `A=5^6 mod 23=8` and `B=5^15 mod 23=19`. Party one computes `19^6 mod 23=2`; party two computes `8^15 mod 23=2`. Agreement demonstrates the algebra, but the tiny group makes discrete logarithms easy and no peer authentication exists. It is not suitable for real key exchange.

### Diffie–Hellman Key Agreement and Man-in-the-Middle Risk

Two peers agree on a suitable prime modulus `p` and generator `g` of an appropriate subgroup. Alice chooses secret `a`, Bob chooses `b`; they send `A=g^a mod p` and `B=g^b mod p`. Alice computes `B^a mod p`, Bob computes `A^b mod p`, and both obtain `g^(ab) mod p`. A toy example uses `p=23,g=5,a=6,b=15`, giving `A=8`, `B=19`, and shared value `2`. This exchange alone does not authenticate identity. An active network adversary can establish separate keys with each peer and impersonate them. Agreement on bits is not agreement on the remote party's identity.

### ECDH compared with the X25519 interface

Elliptic-curve Diffie–Hellman represents public values as curve points and obtains a common value by scalar multiplication. X25519 is a standardized interface for a specific Montgomery curve, with RFC 7748 rules for 32-byte inputs, outputs, and scalar handling. The output should be passed into a suitable KDF. Point validation, subgroup concerns, and all-zero shared secrets depend on the precise algorithm specification; rules for one curve must not be assumed for arbitrary curves.

### Transcript and Direction Binding in Key Derivation

A shared secret is material associated with session identity and protocol roles, not merely an isolated bitstring. HKDF can bind protocol version, public exchange values, transcript hash, and direction labels into distinct sending and receiving keys. AEAD counters are then kept per sender and key. This is a stronger, more explicit contract than `hash(shared_secret)` without context.

### Identity Validation in Key Agreement

For finite-field Diffie–Hellman, choose an agreed group `(G,g)` and secrets `a` and `b`. Alice publishes `A=g^a mod p` and Bob publishes `B=g^b mod p`; Alice computes `B^a`, Bob computes `A^b`, and both obtain `g^{ab}`. This equality does not authenticate the peers: a man-in-the-middle can establish two independent shared secrets. Modern ECDH mechanisms such as X25519 standardize scalar operations, but public-key decoding, handling invalid values, and context-specific HKDF derivation remain protocol obligations.

Bind roles, protocol version, nonces, and ephemeral public keys into the transcript hash. Derive traffic keys from the shared secret in the accepted handshake context rather than reusing the raw exchange output. Erasing ephemeral keys after a session also requires separate attention to memory, swap, and crash-dump policies.

## Unit 16: Digital Signature Algorithms and Public-Key Infrastructure

![Animated digital signature and PKI verification](https://alikoker.com.tr/svg/signature-pki-verification.svg "Digital signature and PKI verification")

### Digital Signature Verification Algorithm

A digital signature lets a verifier check evidence created by a private signing key using the corresponding public key. The verifier first identifies the exact signed bytes and their canonical encoding, verifies the signature with the required algorithm and parameters, and binds the public key to the expected identity. **Valid signature does not imply authorized action**: a key may be stolen, permission may have expired, or the document context may have been misinterpreted.

RSA-PSS, ECDSA, and EdDSA rely on different mathematics and nonce requirements. Reusing an ECDSA signing nonce can expose the private key; deterministic nonce derivation mitigates one class of error but does not excuse incorrect implementation. Canonical serialization, domain labels, and versioning avoid signing an ambiguous representation.

### PKI and certificate paths

An X.509 certificate binds a public key to an identity or name through a signature. A TLS client validates certificate signatures along a path to a trusted root, checks the expected DNS name against SAN entries, validates permitted uses and validity dates, and enforces relevant constraints. Trusting a root is also an administrative decision. Revocation and status-check behavior depend on deployment policy and risk.

### Digital Signature Verification and Legal Effect

Mathematically verifying document integrity differs from legally establishing a particular individual's intent and authority. Timestamps, identity records, authorization evidence, and key custody can support wider conclusions. The cryptology course explains the technical mechanisms; the legal interpretation belongs to [Information Technology Law](/en/information-technology-law).

### Certificate transparency and authorization boundaries

Presenting a certificate with a correct SAN does not prove that no misissued certificate exists. Certificate Transparency logs make public-web PKI issuance more auditable, but appearing in a log does not establish application-level authorization. Root-store updates, cross-signing, expiration, and delayed revocation information show that trust decisions have both cryptographic and operational components.

### Mathematical Differences among Signature Algorithms

RSA-PSS combines RSA private exponentiation with randomized message encoding. ECDSA instead uses an elliptic-curve group, a message-digest representative, and an ephemeral scalar `k` whose selection is security-critical. Its signature components include an `r` value derived from a curve point and `s=k^(-1)(z+rd) mod n`. Reuse or predictability of `k` may expose the private key. Ed25519 belongs to a different Edwards-curve signing family, with distinct deterministic nonce derivation, encoding, and group rules. ECDSA and Ed25519 are not interchangeable internal algorithms.

### Prerequisites for Signature Verification

A verifier first checks algorithm identification, key representation, the precise byte representation of the message, and signature encoding; mathematical verification follows. Trust in the identity owning the public key comes from PKI or another authenticated binding. A correct signature does not automatically establish the date of an event, legal authority, or legal validity. Signatures also do not encrypt or conceal the message.

### Certificate Path Validation and Identity Matching

X.509 validation considers an end-entity certificate, intermediates, and a trust anchor. It verifies cryptographic signatures, validity periods, basic constraints, key usage, name constraints, and the application-expected hostname. Revocation and certificate transparency have defined audit and policy roles; they do not prove that an application's business logic is safe. Certificate validation and server authorization must be assessed separately.

### Signatures, Certificates and CMS Containers

Ed25519, ECDSA, and RSA-PSS provide signature functionality through different mathematical operations and assumptions. ECDSA depends on message hashing, a suitable per-signature nonce, and elliptic-curve scalar arithmetic; reusing a nonce with the same private key can be catastrophic. Ed25519 has a different, deterministic signing design. RSA-PSS applies a specified EMSA-PSS encoding before private-key operations. A valid file signature does not independently prove that its certificate identifies the expected organization or that the software is trustworthy: trust roots, purpose restrictions, validity, path building, and revocation policy are separate decisions.

The [PKCS #7 and Cryptographic Message Syntax](/en/pkcs-7-and-cryptographic-message-syntax) article examines containers such as CMS `SignedData` that carry algorithm, signature, certificate, and content relationships. A container format is not an encryption algorithm. A verifier determines the exact bytes and content binding, checks the signature mathematically, and then applies certificate and application trust policies. Validating a signature without its context can attach authority to the wrong document.

## Unit 17: Cryptographic Communication Protocols and TLS 1.3

![Animated TLS 1.3 handshake and key schedule](https://alikoker.com.tr/svg/tls13-handshake-key-schedule.svg "TLS 1.3 handshake and key schedule")

### TLS Handshake and Record Protection

TLS 1.3 negotiates compatible algorithms, derives shared secrets from key contributions, binds handshake transcripts into authentication, and protects application records with separate traffic keys. The conditions for sending application data before a handshake completes are significant: 0-RTT traffic does not have the same replay protection as ordinary established-session data. Version negotiation and transcript binding defend against downgrade and cross-protocol confusion.

**RFC 9846 (July 2026)** retains the TLS 1.3 version number while superseding RFC 8446. Among its tightened requirements are prohibition of reusing `KeyShare` values across connections and prohibition of TLS 1.0/1.1 negotiation. When reading historical TLS 1.3 material, distinguish the protocol version from the revision of its governing RFC.

### Certificate checking and the end-to-end flow

A protected connection proceeds from target-name selection through certificate-path validation, ephemeral secret establishment, key derivation, traffic protection, and connection shutdown. TLS protects the channel, not the safety of application parsing or the security of server-side storage. Disabling hostname verification removes a central part of its endpoint-authentication guarantee.

### TLS Session-Key Management

A key inventory tracks creation time, purpose, permissions, storage location, version, rekeying, and destruction. Encrypted backups, key rotation, and the need to decrypt historical data must be designed together. HSM or KMS integration changes the trust boundary without automatically repairing faulty authorization. During incident response it should be possible to identify which key was exposed and which protected records depended on it.

### Regression testing protocol transitions

A client-server test matrix separates normal handshakes, trusted certificates, wrong target names, obsolete TLS version negotiation, reused ephemeral key shares, and 0-RTT replay conditions. Define expected rejection and error reporting before exercising each case. Updating to a newer RFC also requires verifying the behavior of the deployed TLS library. Successful interoperability measurements do not by themselves establish the complete security level of production traffic.

### What each TLS 1.3 handshake message accomplishes

The client sends `ClientHello` with version and cipher-suite preferences, supported groups, and key-share material. The server responds with `ServerHello`, selecting parameters and providing its key share. The ECDHE result and any permitted PSK feed an HKDF-based schedule for handshake traffic secrets. `EncryptedExtensions` carries negotiated extensions; `Certificate` and `CertificateVerify` authenticate the server; `Finished` authenticates the transcript using derived key material. Application records are then protected under separate AEAD traffic keys. Message order matters for the security state machine and the binding of identity to key agreement.

### HKDF schedule, 0-RTT data, and replay risk

TLS 1.3 derives early, handshake, and application traffic secrets through separate HKDF stages. In some resumed sessions, 0-RTT data reduces latency but brings replay considerations; non-idempotent operations need appropriate defenses. Rekeying, application authorization, and certificate validation remain distinct concerns. RFC 9846 obsoletes RFC 8446 without creating a new TLS version number and tightens requirements including prohibition of KeyShare reuse across connections.

### TLS Errors and Cryptographic Vulnerabilities

An application connection failure does not imply an AES break. A mismatched hostname is an identity-binding failure; an incorrect transcript or KDF output can produce `Finished` or AEAD failures; negotiation of a prohibited old version is a protocol-policy error. Packet-level evidence should be interpreted without needlessly disclosing secrets or application content.

### TLS 1.3 Session Security Sequence

The TLS 1.3 client advertises supported versions, a key share, and cipher-suite options; the server selects compatible parameters. A shared secret feeds an HKDF-based key schedule that derives handshake and application-traffic secrets. The certificate chain and `CertificateVerify` bind the server's asserted identity to the handshake transcript. `Finished` authenticates the observed handshake. Establishing TLS does not automatically authorize an application action, and a mathematically valid certificate for the wrong host name is not sufficient for endpoint authentication.

The record layer uses AEAD with nonces derived from per-traffic-key sequence numbers. Sequence evolution, key updates, and record boundaries are security properties even if hidden from application code. Resumption and 0-RTT require separate treatment: early data does not always have the same anti-replay guarantees as data after a full handshake, so side-effecting application requests need a deliberate admission policy. Consult the current RFC record to distinguish core protocol requirements from subsequent updates.

## Unit 18: Cryptanalysis Methods and Attack Complexity

### Adversary Capabilities and Security Assumptions

An observer who only obtains ciphertext differs from an adversary who can request encryption of chosen messages or decryption of selected ciphertexts. Known-plaintext, chosen-plaintext, and chosen-ciphertext models formalize the capabilities offered by an environment. Distinguishable failure responses or use of plaintext before authentication may unintentionally expose queries that a proof assumed unavailable.

### Differential, linear, and structural methods

Differential cryptanalysis studies the probability of output differences following specified input differences; linear cryptanalysis examines statistical biases in bit relations. Attack cost depends on the cipher structure, round count, data complexity, and query access. Reduced-round teaching models communicate these ideas without reproducing executable exploitation workflows against real systems.

### Classification of Cryptographic Implementation Faults

The supplied teaching files illustrate three distinct problems: **textbook RSA** may compute the right arithmetic without a secure encryption definition; **CBC** may preserve confidentiality while failing to authenticate; and **RC4 or SHA-1-based designs** may inherit deprecated algorithm choices. Review starts by naming the intended property, identifying input-output behavior, writing down assumptions, and specifying a negative test. For AEAD the critical property is that modified AAD causes authentication failure without releasing plaintext. This is defensive verification, not an attack procedure.

### Cryptographic agility

Deprecation can result from shrinking security margins, compliance, implementation cost, platform support, or the lifetime of protected records. Algorithm identifiers and key versions must be bound to stored data, silent downgrade disallowed, and old and new record formats distinguished through reproducible migration tests.

### Factoring algorithms and elliptic curves

RSA risk assessments must reflect the best known integer-factoring methods. Trial division illustrates the basic problem but fails at realistic sizes; Pollard rho, elliptic-curve factorization (ECM), and the number field sieve have different performance regimes depending on input and factor sizes. ECM's use of elliptic-curve arithmetic does not make it the same problem as attacking ECDH in a well-chosen group. The educational goal is controlled complexity analysis tied to realistic key-size claims.

### Cryptanalysis Cost under Adversary Models

In a ciphertext-only setting the attacker sees `C`; a known-plaintext attacker observes pairs `(M,C)`; a chosen-plaintext attacker requests encryption of selected messages; and a chosen-ciphertext attacker has constrained decryption-oracle access. These models are prerequisites to any claim that an encryption scheme has been broken. A brute-force search space of `2^128` candidates does not prove that no more efficient structural technique exists.

### Classical and Modern Cryptanalysis Techniques

Caesar and affine ciphers leak single-letter statistics. Differential cryptanalysis studies deviations from ideal behavior in how chosen input differences `ΔX` propagate to output differences `ΔY`. An S-box difference distribution table counts, for each input difference, how frequently each output difference occurs; these probabilities inform trails through multiple rounds. Linear cryptanalysis instead searches for parity relations among input, output, and key bits whose probability differs from `1/2`. An observable weakness in a reduced-round toy SPN must not be presented as a practical full-round AES key-recovery result.

### Differential Distribution of a Small S-Box

For a four-bit S-box, the difference distribution `DDT[dx][dy]` counts all `x` satisfying `S[x] XOR S[x XOR dx] == dy`. Every row sums to 16 and `DDT[0][0]=16`. This helps explain why attackers may prioritize particular differences, without claiming to prove security of an entire block cipher.

```python
S = [0xC,5,6,0xB,9,0,0xA,0xD,3,0xE,0xF,8,4,7,1,2]
ddt = [[0]*16 for _ in range(16)]
for dx in range(16):
    for x in range(16):
        ddt[dx][S[x] ^ S[x ^ dx]] += 1
assert all(sum(row) == 16 for row in ddt)
assert ddt[0][0] == 16
```

### Cryptanalytic, Protocol and Implementation Attacks

Brute force and structural cryptanalysis can target a cipher's mathematics. Padding oracles, repeated nonces, wrong keys, and distinguishable error responses more often expose a scheme or protocol failure. Timing, power, and cache leakage target physical execution. Keeping these failure classes separate prevents a code defect from being mislabeled an AES break or a true cryptanalytic advance from being ignored.

### Algebraic Representations and Complexity in Cryptanalysis

A cryptanalytic objective must be specified: recovering a key, distinguishing ciphertext, forging an authentication tag, or inducing protocol acceptance are different success criteria. If an approach needs `q` chosen plaintexts, `t` computational steps, and `m` memory, comparing only nominal key counts is misleading. A differential trail or set of equations for reduced-round encryption does not automatically compromise a full standardized cipher. Correlations in linear approximations can fluctuate in small samples; statistical significance has to be established separately.

The [Algebraic Representation in AES Cryptanalysis](/en/algebraic-representation-in-aes-cryptanalysis) article provides a concrete research context for this distinction. Describing a transformation with fewer symbols is not equivalent to recovering a key from its equations within feasible resource limits. The linked analytical work is limited to its stated model and assumptions and does not establish a universal security proof.

## Unit 19: Side-Channel Analysis and Cryptographic Implementation Security

### Mathematical Cipher Design and Physical Implementation

A correct algorithm does not conceal the timing, cache behavior, power usage, or electromagnetic emissions of its implementation. Secret-dependent branches and lookup tables can create observable timing patterns. A constant-time requirement must consider compiler optimizations, library internals, the platform, and error paths, not just an individual loop. Standard constant-time comparison interfaces are preferable to secret-dependent early termination.

### Leakage and fault models

Side-channel analysis begins by specifying whether the adversary can observe a physical device, a shared host, or network timing. Power analysis and fault injection rely on distinct attacker capabilities. Masking distributes intermediate values across shares under particular leakage assumptions but needs good randomness and measurement. Verified modules, secure roots of trust, and HSMs can protect selected key operations; they do not fix protocol or access-policy errors.

### White-Box Cryptography and Key Protection

White-box cryptography studies key protection when an adversary can strongly inspect program code and its execution environment. A key embedded in executable code cannot generally be assumed hidden from an attacker who can inspect memory and machine instructions. Where possible, private keys should remain inside a different trust boundary, with limited permissions and practical revocation and rotation paths.

### Evidence Levels in Cryptographic Testing

Known-answer vectors establish correspondence with specified inputs. Property-based tests check relations such as `decrypt(encrypt(m))=m`. Negative tests verify rejection of invalid tags and nonces. Fuzzing and protocol state exploration target unexpected execution paths. None of these tests by itself establishes absence of side channels or a formal IND-CCA guarantee. Mathematical models, code review, and empirical measurement are complementary.

### Limits of Constant-Time Verification

Two implementations with the same mathematical output may have different leakage. Secret-dependent branches during exponentiation, key-indexed tables, or an early-exit tag comparison create timing or cache patterns. Constant-time techniques seek to remove secret-dependent control flow and memory access, but source-level inspection alone cannot guarantee the compiler and processor preserve those properties. Microarchitecture, frequency scaling, and the memory hierarchy belong in the threat model.

### Blinding, Masking and Fault Detection

RSA blinding transforms an input by a random reversible factor before the private operation, reducing direct correlation between secret computation and observed data. Masking splits intermediate values into randomized shares, requiring suitable entropy and a specified leakage model. Fault checking seeks to prevent malformed CRT computation results from reaching an attacker. These mechanisms are not substitutes for one another.

### HSM and key-lifecycle engineering

Key management covers creation, authorization, usage, rotation, suspension, recovery, and destruction. An HSM can keep selected cryptographic operations inside a distinct trust boundary, but faulty role assignment and incorrect protocol binding remain application-level risks. Standards and audits should examine intended key use, secret-free event logging, and recoverability constraints together.

### Timing, Fault-Injection and Side-Channel Tests

Passing standard test vectors establishes functional compatibility, not freedom from secret-dependent timing or physical leakage. Secret-indexed tables, conditional branches, cache effects, and error behavior may reveal information through different channels. A 'constant-time' claim cannot rest on one wall-clock sample: the threat model, processor, compiler transformations, and measurement setup must be specified. Blinding and masking address particular leakage models, not all conceivable physical attacks.

The [Lightweight AES-128 Implementation in C](/en/lightweight-aes-128-implementation-in-c) and [Lightweight AES-128](/en/lightweight-aes-128-c) records are concrete materials for understanding memory layout and AES rounds. S-box lookup behavior can require cache-side-channel scrutiny independent of correct ciphertext. The project's upstream provenance, licensing notes, and implementation limits belong to its own record and are not inflated by this course.

## Unit 20: Post-Quantum Cryptography and Migration Strategies

### Cryptographic Threat Model of Quantum Computing

Shor's algorithm would affect integer factoring and discrete logarithms on sufficiently large fault-tolerant quantum computers, threatening long-term assumptions behind conventional RSA and ECC public-key systems. Grover's general-search speedup does not break symmetric cryptography in the same way; its implications require key-length and resource analysis. Quantum threats also depend on data retention: traffic recorded today could be analyzed later.

### ML-KEM, ML-DSA, and SLH-DSA

NIST FIPS 203 (2024) standardizes lattice-based **ML-KEM** key encapsulation, FIPS 204 **ML-DSA** signatures, and FIPS 205 **SLH-DSA** hash-based signatures. A KEM offers `KeyGen`, `Encaps`, and `Decaps` to establish a shared secret, rather than directly encrypting arbitrary files. The secret is fed through a protocol-contextualized KDF, and application data is protected using AEAD. Security category, public-key and ciphertext sizes, latency, and implementation maturity must be compared together. A signature algorithm cannot simply replace a KEM, or vice versa.

### Evaluation Criteria for Post-Quantum Migration

For an organization retaining archives for 20 years, refreshing systems every five years, and protecting large record volumes, one encryption benchmark is insufficient. Map current public-key dependencies; handle records, certificates, firmware, and device protocols as distinct migration targets. Measure ML-KEM encapsulation and decapsulation, ciphertext expansion, key-material memory cost, and behavior on invalid encapsulated values. A hybrid design binds classical and post-quantum contributions to the transcript and KDF context; it is not simply the concatenation of two secret values.

### Lattice-Based Key Encapsulation Principles

ML-KEM is a key-encapsulation mechanism: `KeyGen` creates a public/private pair, `Encaps(pk)` produces a shared secret and encapsulated ciphertext, and `Decaps(sk,ct)` lets the intended recipient derive the same secret. Its mathematical basis involves modular algebra and lattice problems with error terms, not the factoring assumption behind RSA. A KEM ciphertext does not directly encrypt a large dataset; a derived symmetric key and AEAD protect files or records. Assessment separates encapsulation size, parameter set, decapsulation behavior, and target security level.

### Comparison of Post-Quantum Signature Families

ML-DSA is a module-lattice-based signature family while SLH-DSA is a stateless hash-based family. They have different key sizes, signature sizes, and performance profiles. A security-category label alone does not identify packet size, microcontroller memory demand, or certificate-chain impact. Migration starts by locating existing RSA/ECC uses and matching alternatives to real system limits.

### Combining Classical and Post-Quantum Key Material

Hybrid key agreement using both ECDHE and ML-KEM needs more than arbitrary byte-string concatenation. A carefully specified combiner and key schedule bind transcript, algorithm identifiers, directions, and unambiguous encodings. Whether the public encapsulation key belongs to the intended remote party is an authentication question that KEM alone does not solve.

### Algorithm and Protocol Changes in Post-Quantum Migration

ML-KEM provides key encapsulation; ML-DSA and SLH-DSA provide digital signatures. A KEM is not an AES replacement that directly encrypts arbitrary files: `Encaps(pk)` yields a shared secret and encapsulation; `Decaps(sk,capsule)` attempts to recover the same secret. A protocol derives an AEAD key from that secret with appropriate context binding. Signature key sizes, message/signature lengths, and verification work influence deployment beyond the nominal security category.

Hybrid combinations must specify their combiner formula, domain separation, failure behavior, and downgrade-resistant negotiation. Existing certificate chains, device memory, wire encodings, and hardware acceleration constraints also affect migration. Calling an algorithm 'quantum safe' is not a measured immunity claim; it is a statement relative to explicit assumptions and standardized security analysis.

## Unit 21: Threshold Cryptography and Secret-Sharing Schemes

![Animated Shamir secret sharing and reconstruction](https://alikoker.com.tr/svg/shamir-secret-sharing.svg "Shamir secret sharing and reconstruction")



Keeping every cryptographic key inside one device or with one operator creates a concentrated operational risk. Threshold cryptography creates an access structure in which a specified number of parties can cooperate. It is more than splitting a byte string into ordinary fragments, and a sharing scheme is not by itself a distributed signing protocol.

### Polynomial Computation in Shamir Secret Sharing

In a `(t,n)` sharing system, at least `t` shares reconstruct a secret, while up to `t−1` should reveal no information in the ideal information-theoretic model. Choose a prime `p`, a secret `s<p`, and independent random coefficients `a₁,...,a_(t−1)`. Form `f(x)=s+a₁x+...+a_(t−1)x^(t−1) mod p`. Evaluate this polynomial at distinct, nonzero `x_i` values and distribute the pairs `(x_i,f(x_i))`. Shares remain sensitive; the random coefficients must be unpredictable.

For a classroom example choose `p=17,s=5,t=3,a₁=2,a₂=3`. Then `f(1)=10`, `f(2)=4`, and `f(3)=4`. Reconstruction evaluates the interpolation polynomial at zero: `f(0)=Σ_i y_i Π_(j≠i)(−x_j)/(x_i−x_j) mod 17`. Distinct points and invertible modular denominators are essential. Adding another random coefficient changes the threshold; biased coefficients can undermine secrecy.

### Share Validation against Malicious Participants

Shamir sharing does not stop a malicious party from supplying an incorrect share. Verifiable secret-sharing variants such as Feldman or Pedersen add commitments enabling specified consistency checks, under their respective cryptographic assumptions. Share delivery, participant authentication, secure storage, and proactive share renewal require separate protocols.

### Threshold signatures, MPC, and key lifecycle

Applying Shamir sharing to an RSA or ECDSA key does not automatically provide a `t`-party signing operation that avoids reconstruction of the private key. A genuine threshold-signature protocol distributes computation; ECDSA in particular requires careful ephemeral-nonce handling and validation of malicious behavior. The engineering decision must also address single points of failure, offline participants, recovery, proactive refresh, and safe audit trails.

### Reconstruction and Invalid Shares in Shamir Schemes

In a `t-of-n` Shamir scheme, represent the secret `s` as an element of a prime field and choose a random polynomial of degree `(t−1)` with constant coefficient `s`. Distribute evaluations `f(x_i)` at distinct nonzero points. At least `t` correct shares reconstruct `f(0)` via Lagrange interpolation; fewer shares do not uniquely determine the random polynomial under the stated field and randomness assumptions.

Shares must be delivered over authenticated confidential channels. An incorrect or adversarial share can corrupt reconstruction; verifiable secret sharing introduces commitments and a more explicit dealer/adversary model. Splitting a secret does not automatically provide access control, rotation, or audit logs, which belong to a complete key-management system.

## Unit 22: Cryptographic Commitments and Zero-Knowledge Proofs

![Animated Sigma-protocol commit-challenge-response](https://alikoker.com.tr/svg/schnorr-protocol.svg "Sigma-protocol commit-challenge-response")

### Cryptographic Commitments versus Hash Digests

A commitment scheme lets a sender publish `Commit(m;r)` and later open it by supplying `(m,r)` to `Verify(commitment,m,r)`. It aims at both hiding (the commitment does not disclose the message) and binding (opening to a different message is computationally infeasible under the assumption). Plain `Hash(m)` may expose a low-entropy message to a dictionary attack; the random value `r` is often essential. A Pedersen-like scheme uses `C=g^m h^r`; its assumptions and who knows the discrete-log relationship between the generators must be stated.

### Phases of Interactive Zero-Knowledge Proofs

Zero-knowledge proofs aim for three separate properties: completeness for a valid witness, soundness against false statements, and zero knowledge about the witness itself. In a simple Schnorr identification example, a public value is `Y=g^x`; the prover chooses random `r` and sends `T=g^r`. The verifier issues fresh challenge `c`, and the prover responds `z=r+cx mod q`. The verifier checks `g^z ?= T·Y^c`. The equality follows algebraically from `g^(r+cx)=g^r(g^x)^c`, but an isolated equality is not a complete security proof. Challenge unpredictability, group conditions, and reuse restrictions still matter.

### Fiat–Shamir and encoding the statement context

Some interactive proofs become non-interactive when the challenge is derived as `c=H(domain||statement||T||context)`. Security then depends on the explicit model of the hash function and other assumptions. Ambiguous encodings of application, session, and statement can cause a proof to be accepted in the wrong context. Saying a system uses 'zero knowledge' does not automatically show that the claim is bound to the intended operation.

### Use Cases and Limitations of Zero-Knowledge Proofs

Credential attributes, transaction statements, and certain privacy-preserving constructions use zero-knowledge systems. ZK does not replace encryption or authorization policy. Prover time, verifier cost, trusted setup, and the family of statements a proof system supports are important engineering constraints.

### Security Properties of Commitments and Zero-Knowledge Proofs

A commitment binds a party to a value while allowing it to reveal that value later. Computational binding makes it difficult to open one commitment as two different messages; hiding prevents a receiver from learning the message before opening. Neither property is automatically perfect: assumptions and randomness quality matter.

A zero-knowledge proof is analyzed through completeness, soundness, and zero knowledge. Sigma protocols often expose these roles as `commit → challenge → response`. The Fiat–Shamir transform derives a challenge from a hash in suitable constructions; its security assumptions and domain separation must fit the protocol model. Zero knowledge for a witness does not automatically conceal application queries, metadata, or authorization decisions.

### Threat Models for Commitments and Zero-Knowledge Proofs

A commitment lets a sender bind to a value and reveal it later; hiding and binding are distinct requirements. In an interactive zero-knowledge protocol a verifier issues a fresh challenge and a prover responds in a manner supporting a statement without exposing the witness. Soundness depends on challenge freshness, contextual binding, and replay assumptions. Fiat–Shamir can turn selected interactive protocols into hash-based non-interactive proofs under additional assumptions, requiring careful domain separation. Zero-knowledge proofs, MPC, and homomorphic encryption are not interchangeable algorithms.

## Unit 23: Secure Multiparty Computation and Homomorphic Encryption

### MPC Threat Model and Information Leakage

Secure multiparty computation lets parties with private inputs `x₁,...,x_n` jointly evaluate a function `f`. The ideal goal is to reveal no more about inputs than permitted by the output and the model. The acceptable collusion threshold, malicious behavior, and communication failures must be specified. 'Computing without pooling data' is not a sufficient formal security definition.

### Computation with Additive Secret Sharing

Over modulus `p`, Alice can represent secret `x` by shares `r` and `x−r mod p`, where `r` is uniformly random. A single share reveals no information about `x`. Addition is locally supported: shares of `(x₁+x₂) mod p` are obtained by adding the corresponding shares. Multiplication is different; it may require preprocessing such as correlated Beaver triples and additional interaction. The number of multiplication gates in an arithmetic circuit consequently affects many MPC protocols' performance.

### Homomorphic Operations and Their Limits

Partially homomorphic encryption supports a selected family of operations. An additive property may be written `Dec(Enc(a) ⊕ Enc(b))=a+b`, but `⊕` denotes the scheme's ciphertext-domain operation and need not be bitwise XOR. Somewhat and fully homomorphic schemes can handle more general circuits at the cost of ciphertext growth, noise management, rescaling, and possibly bootstrapping. CKKS focuses on approximate numerical arithmetic; BFV/BGV families support particular integer/polynomial computations. Naming a family without discussing its computation budget is not a useful engineering analysis.

### MPC and Homomorphic Encryption System Models

Must inputs be hidden only from a processing server, or from other participants too? Who receives the output? Must a malicious server's computation be verifiable? Can the output itself reveal individual information? MPC and FHE decisions depend on these questions and must be related to access control, de-identification, and statistical privacy goals.

### Computational Cost of MPC and Homomorphic Encryption

In secure multiparty computation, participants compute a joint function while keeping private inputs from each other under a specified adversary model. The model must say how many participants can collude, whether the network is synchronous, and whether adversaries are honest-but-curious or malicious. Share-based addition and multiplication in an arithmetic circuit often require interaction and verification messages. The output itself may reveal sensitive information, so hiding intermediate inputs is not the whole privacy policy.

Homomorphic encryption permits selected operations on ciphertexts, but schemes differ greatly in supported computations and cost. Multiplicative depth, noise growth, rescaling/bootstrapping, ciphertext expansion, and key size belong to the actual resource budget. Computing over ciphertext does not automatically solve multi-user authorization, client integrity, or all query-privacy concerns.

### Overview of Advanced Cryptographic Constructions

Shamir secret sharing reconstructs a secret from `t` evaluations of a degree-`t-1` polynomial over an appropriate finite field; secrecy from fewer shares depends on the scheme's randomness and field assumptions. Threshold signatures require an interactive signing protocol rather than merely splitting a key. Zero-knowledge proofs seek to establish a statement without revealing the witness, with completeness, soundness, and zero knowledge defined separately. Secure multiparty computation and homomorphic encryption aim to limit input exposure during computation, but have substantial computational, communication, and adversarial-model costs.

## Unit 24: Cryptographic Protocol Design and Data Formats

### Byte-Level Definition of an Encrypted File Format

A file-encryption format starts with a threat model: data should remain confidential, alterations must be rejected, versions must be identifiable, and wrong keys must not yield accepted plaintext. A header may carry the version, algorithm identifier, KDF parameters, salt, nonce, and required metadata. Fields whose integrity matters must be authenticated, for example as AEAD AAD. A password requires a password KDF; a uniformly random high-entropy key may use a different derivation path. A raw password must not be treated as an AES key.

After obtaining the key, allocate a unique nonce for the record and canonically encode the header into AAD. Seal the plaintext with AEAD and serialize header, ciphertext, and authentication tag. On reading, check length and version limits, reject unsupported parameters, verify the AEAD tag, and **only then** hand plaintext to consumers. On failure discard temporary output and do not record the operation as completed.

### Authentication of Chunked Records

A large file need not fit in memory for one AEAD operation. In a chunked format, authenticate the chunk index, version, and final-chunk indicator as AAD; derive or allocate distinct nonces for every chunk. Without authenticated finality, a malicious party may truncate trailing chunks while presenting a valid prefix. Record identifiers also prevent reordering and splicing chunks across files. A chunking format introduces protocol requirements beyond the security of a single AEAD call.

### Protocol Versioning and Algorithm Migration

An algorithm identifier in a header is not sufficient agility if an attacker can downgrade it. The selected version must be authenticated and the reader must enforce a separate policy of permitted algorithms. Secure migration validates the old record, writes a fresh record under new key material, validates the result, and performs an atomic transition. Deleting an unverified old record risks permanent loss.

### Repeatable Protocol Acceptance Tests

An implementation should test correct key, wrong key, wrong AAD, changed tag, truncated final block, missing record, reordered chunk, and rejection of dangerous nonce reuse. Tests of nonce reuse are designed to show that policy rejects it, not to normalize its use. Independently published algorithm test vectors should supplement application tests.

### Format Parsing and Trust Boundaries

A cryptographic record parser encounters length and version fields before it can authenticate much of the input. Since those fields may be attacker controlled, it must reject length overflows, duplicated fields, and unsupported algorithm identifiers. Algorithm negotiation should be restricted by explicit version-specific allowlists. Even after successful AEAD verification, application payloads need schema validation: ciphertext authentication does not prevent type confusion or authorization failures in a generic parser.

The [PKCS #7 and Cryptographic Message Syntax](/en/pkcs-7-and-cryptographic-message-syntax) article is a relevant examination of the distinction between a cryptographic operation and its container syntax. CMS `SignedData`, `EnvelopedData`, and BER/DER encodings occupy distinct parsing and security layers. If the signed or encrypted content boundary is interpreted incorrectly, data can appear verified while referring to the wrong object. Define the container and its coverage before evaluating the relevant cryptographic assertion.

## Unit 25: Cryptographic Validation, Experimental Design and Performance Analysis

### Test Vectors, Property Testing and Formal Proofs

Cryptographic research must distinguish three kinds of evidence. A known-answer test verifies that the specified key and input produce a published ciphertext or digest. Property testing samples invariants such as `decrypt(encrypt(m))=m`. A formal security proof makes a theoretical claim relative to explicit assumptions and an adversarial model. Passing thousands of function tests cannot rule out weak entropy, nonce reuse, or side-channel leakage.

### Validation with Standard Test Vectors

An AES-128 vector uses `key=000102030405060708090a0b0c0d0e0f`, `pt=00112233445566778899aabbccddeeff`, and expected ciphertext `69c4e0d86a7b0430d8cdb78070b4c55a`. SHA-256 empty-input testing and small RSA modular arithmetic test different layers. Elliptic-curve testing should include invalid key representations and prohibited shared-secret results as appropriate to the interface. Library versions must be recorded because APIs and behavior evolve.

### Design of a Cryptographic Performance Benchmark

A comparison of AES-GCM with ChaCha20-Poly1305 controls key parameters, record sizes, processor acceleration, library version, thread count, buffer policy, warm-up, and measurement loop. Sizes of 1 KiB, 64 KiB, and 16 MiB can expose different bottlenecks. Throughput is `processed_bytes/elapsed_seconds`, while per-record latency is a distinct metric. Speed results should not be presented without comparing the intended security requirements.

RSA-OAEP encryption and decryption, and RSA-PSS signing and verification, are four different operations. ML-KEM encapsulation and decapsulation should be benchmarked against equivalent protocol tasks, not raw RSA attempts to encrypt arbitrary large messages. Report distributions of median, 95th percentile, variation, and memory rather than one impressive measurement.

### Traceability from Threat Models to Experimental Results

A good report records data classification, protection horizon, attacker access, and claimed guarantee before selecting the algorithm. It then traces the key and nonce policy, standard vectors, negative tests, resource measurements, and residual risks. Attractive charts without supporting experiments, or invented performance numbers, would undermine academic credibility. Equations and code here support verification, not unsupported claims of superiority.

### Functional Correctness versus Cryptographic Security Assurance

A cryptographic implementation should pass the standard vectors for each algorithm and also reject invalid inputs correctly. AES-128/192/256 need tests for each key size; RSA-OAEP needs wrong-key and wrong-label tests, PSS needs tampered-message tests, and AEAD needs modified-tag and modified-AAD tests. Throughput alone is not a sufficient benchmark: key scheduling, message-size distributions, nonce generation, data movement, allocations, encryption, and authentication need separately reported costs.

A lightweight AES core and an optimized library must be compared under equivalent requirements. Benchmarking a bare AES block loop against a service that also performs AEAD authentication, nonce management, and I/O confounds the outcome. The [Lightweight AES-128](/en/lightweight-aes-128-c) project supplies source code and provenance information for independent examination; measured performance cannot be inferred from the code record alone. Upstream provenance and local modifications remain distinct technical facts.

### Design of a Reproducible Cryptographic Evaluation

An algorithm comparison first fixes its security objective, adversarial model, key strength, workload, and input sizes. Setup time, encryption/decryption or signing/verification latency, memory, output size, and error behavior are measured separately. Cold versus warm execution, hardware acceleration, and library version must be recorded; one run does not prove general performance superiority. Passing functional tests does not replace a security proof. Good cryptographic migration demonstrates the risk reduction and its cost in a reproducible system-level evaluation instead of merely choosing the newest algorithm.

## References

- Jonathan Katz and Yehuda Lindell. *Introduction to Modern Cryptography*, 3rd ed. CRC Press, 2025.
- Çetin Kaya Koç (ed.). *Cryptographic Engineering*. Springer, 2009.
- Alan G. Konheim. *Computer Security and Cryptography*. Wiley, 2007.
- Helen Fouché Gaines. *Cryptanalysis: A Study of Ciphers and Their Solution* (historical work; publication details of the consulted edition require confirmation).
- Claude E. Shannon. “Communication Theory of Secrecy Systems.” *Bell System Technical Journal*, 1949.
- Whitfield Diffie and Martin E. Hellman. “New Directions in Cryptography.” *IEEE Transactions on Information Theory*, 22(6), 1976. https://doi.org/10.1109/TIT.1976.1055638
- Ronald L. Rivest, Adi Shamir, and Leonard Adleman. “A Method for Obtaining Digital Signatures and Public-Key Cryptosystems.” *Communications of the ACM*, 21(2), 1978. https://doi.org/10.1145/359340.359342
- NIST. *FIPS 197: Advanced Encryption Standard (AES)*, 2001; editorial update 2023. https://csrc.nist.gov/pubs/fips/197/final
- NIST. *SP 800-38D: Recommendation for Block Cipher Modes of Operation: Galois/Counter Mode (GCM) and GMAC*, 2007. https://csrc.nist.gov/pubs/sp/800/38/d/final
- NIST. *FIPS 180-4: Secure Hash Standard (SHS)*, 2015. https://csrc.nist.gov/pubs/fips/180/4/upd1/final
- NIST. *FIPS 202: SHA-3 Standard*, 2015. https://csrc.nist.gov/pubs/fips/202/final
- NIST. *SP 800-232: Ascon-Based Lightweight Cryptography Standards for Constrained Devices*, 2025. https://csrc.nist.gov/pubs/sp/800/232/final
- NIST. *FIPS 203: Module-Lattice-Based Key-Encapsulation Mechanism Standard*, 2024. https://csrc.nist.gov/pubs/fips/203/final
- NIST. *FIPS 204: Module-Lattice-Based Digital Signature Standard*, 2024. https://csrc.nist.gov/pubs/fips/204/final
- NIST. *FIPS 205: Stateless Hash-Based Digital Signature Standard*, 2024. https://csrc.nist.gov/pubs/fips/205/final
- IETF. RFC 2104, *HMAC: Keyed-Hashing for Message Authentication*, 1997. https://www.rfc-editor.org/info/rfc2104
- IETF. RFC 5869, *HMAC-based Extract-and-Expand Key Derivation Function (HKDF)*, 2010. https://www.rfc-editor.org/info/rfc5869
- IETF. RFC 7748, *Elliptic Curves for Security*, 2016. https://www.rfc-editor.org/info/rfc7748
- IETF. RFC 8017, *PKCS #1: RSA Cryptography Specifications Version 2.2*, 2016. https://www.rfc-editor.org/info/rfc8017
- IETF. RFC 8032, *Edwards-Curve Digital Signature Algorithm (EdDSA)*, 2017. https://www.rfc-editor.org/info/rfc8032
- IETF. RFC 8439, *ChaCha20 and Poly1305 for IETF Protocols*, 2018. https://www.rfc-editor.org/info/rfc8439
- IETF. RFC 9106, *Argon2 Memory-Hard Function for Password Hashing and Proof-of-Work Applications*, 2021. https://www.rfc-editor.org/info/rfc9106
- IETF. RFC 9180, *Hybrid Public Key Encryption*, 2022. https://www.rfc-editor.org/info/rfc9180
- IETF. RFC 9846, *The Transport Layer Security (TLS) Protocol Version 1.3*, 2026. https://www.rfc-editor.org/info/rfc9846
- Adi Shamir. “How to Share a Secret.” *Communications of the ACM*, 22(11), 1979. https://doi.org/10.1145/359168.359176
- Chandan Karfa et al. (eds.). *Security, Privacy, and Applied Cryptography Engineering* (SPACE research proceedings). Springer, 2026.
- Kangkook Jee and Aniket Kate (eds.). *Applied Cryptography and Network Security* (ACNS research proceedings). Springer, 2026.

## Cite This Work

Köker, M. A. (2020). Cryptology: Cryptography, Cryptanalysis and Cryptographic Engineering. alikoker.com.tr. https://alikoker.com.tr/en/cryptology

- BibTeX: https://alikoker.com.tr/en/cryptology.bib
- RIS: https://alikoker.com.tr/en/cryptology.ris
- CSL-JSON: https://alikoker.com.tr/en/cryptology.csl.json
