Skip to content

Lecture 2 - Message Integrity

Lecture 2 - Message Integrity

eecs-388

Introduction

  • cryptography - the study of techniques for communicating securely in the presence of an adversary
  • cryptanalysis - the study of techniques for breaking cryptosystems
  • gap between cryptographic theory (beautiful, highly rigorous) and cryptographic practice (delicate engineering)
  • message integrity - ensures that attackers cannot modify messages without being detected

Scenario

Setup

  • Alice wants to send message m to Bob
  • they don’t fully trust the messenger
  • they want to ensure Bob receives exactly what Alice sent (m=mm'=m)

Threat Model

  • adversary Mallory can see/modify/forge messages
  • Mallory wants to trick Bob into accepting a message Alice didn’t send
flowchart LR
	A[Alice] -- m --> B[Mallory]
	B -- m' --> C[Bob]

Approach: Message Verifier

  1. Alice computes verifier v:=f(m)v := f(m)
    graph LR
    A[Alice] -- m,v --> B[Mallory]
    B -- m',v' --> C[Bob]
    
  2. Bob verifies that v=f(m)v' = f(m'), accepts message iff this is true

f()f() is a function that maps every possible input to a pre-computed random output this would require a massive lookup table of size 2len of longest m×22562^{\text{len of longest m}} \times 2^{256} bits

Pseudorandom Functions

Overview

  • objective - a function that performs like a random function, but is still within practical constraints
  1. start with a family of 2n2^n functions f0(),f1(),,f(2n)1()f_0(), f_1(), \dots, f_{(2^n) - 1}(), all known to Mallory
  2. let our verification function v():=fk()v() := f_k() where kk is a secret nn-bit index known only to Alice and Bob

Security Definition (testing the effectiveness of PRF fk()f_k()):

  1. choose secret kk and an RF g()g()
  2. flip a coin to get bit bb
  3. if b=0b=0, let h():=g()h() := g() if b=1b=1, let h():=fk()h() := f_k()
  4. Mallory chooses xx; we announce h(x)h(x) repeat as many times as Mallory likes
  5. Mallory guesses bb in polynomial time
  • in plain english, give Mallory a black box function that is randomly either a RF or PRF. let her run the function on as many functions as she wants, within polynomial time. if she can’t tell the PRF from the RF across multiple runs of this game, then the PRF is secure.

  • we say PRF f()f() is a secure if Mallory can’t do meaningfully better than random at guessing if it’s a PRF or RF

  • note that Mallory can always determine if a function is a PRF given infinite time via a brute force attack

Using a PRF for Message Integrity

  1. let f()f() be a secure PRF (public)
  2. in advance, choose a random key kk known only to Alice and Bob
  3. Alice computes $v := f_k(m)
  4. graph LR
        A[Alice w/ k] -- m,v --> B[Mallory]
        B -- m',v' --> C[Bob w/ k]
    
  5. Bob verifies that v=fk(m)v' = f_k(m'), accepts message iff they are equal
  • if Bob accepts mm', then mm' is identical to mm with chance 11/2n1 - 1/2^n

  • Kerckhoff’s Principle - a cryptosystem should remain secure even if attackers know everything but the key

  • we don’t know if PRFs actually exist (would imply PNPP \neq NP)

Cryptographic Hashes

  • cryptographic hash function - fixed function H()H() with no key, and takes inputs of arbitrary length data and outputs a fixed size digest (nn bits)

  • properties:

    1. pre-image resistance - for a given output hh, hard to find any input mm such that h=H(m)h = H(m)
    2. collision resistance - hard to find any pair of inputs m1,m2H(m1)=H(m2)m_1,m_2 \backepsilon H(m_1) = H(m_2)
    3. second pre-image resistance - for a given input m1m_1, hard to find m2m1H(m1)=H(m2)m_2 \neq m_1 \backepsilon H(m_1) = H(m_2)
  • note that there must exist an infinite number of collisions due to the pigeonhole principle; however, hard to find means computing them is intractable

Hashes with Broken Collision Resistance

MD5

  • broken in 2004
  • now it’s easy to find collisions SHA-1
  • broken in 2017
  • computing first collision cost > $100,000
  • today costs < $10,000

SHA-256

  • widely used hash function that is currently thought to be strong

  • input: arbitrary length data

  • output: 256-bit digest

  • built from a c

  • uses the Merkle-Damgard (MD) construction to accept arbitrary-length input by repeatedly applying h()h():

    1. pad the input mm to next multiple of 512 bits (adds at least 1 bit, uses fixed algorithm) and split into 512-bit blocks: b0,b1,,bn1b_0,b_1, \dots, b_{n-1}
    2. y0:=y_0 := <256-bit constant> y1:=h(y0,b0)yi:=h(yi1,bi1)y_1 := h(y_0,b_0) \dots y_i := h(y_{i-1},b_{i-1})
    3. return yny_n which is defined to be SHA-256(m)
Sep 3, 2026