CBCDefs.lean
Declarations on this page (11)
AES-256-CBC with PKCS#7 padding as a one-time cipher
Trusted in part. The theorems of Computational/ use only AesKey, Block, Plain, bytesToBlock, cbcEncrypt, cbcScheme, nBlocks, padLen, pkcs7Blocks, pkcs7Bytes, cbcPkcs7EncryptOnly from this file: read them. Everything else here is checked by Lean. See Computational/.
Models libsignal's signal_crypto::aes_256_cbc_encrypt over an abstract AES-256 block function E : AesKey → Block → Block (DEV-AEAD14), together with monadic CBC cbcM, the PRF wrapper blockPRF, and the one-time IND-CPA-to-PRF reduction cbcRed (CBC.lean). Decryption is specified separately in CBCDecDefs.lean.
@[expose] public sectionopen OracleComp OracleSpec ENNRealnamespace CryptoGamesnamespace CBCabbrev Block
A 128-bit AES block.
abbrev Block := BitVec 128abbrev AesKey
A 256-bit AES key.
abbrev AesKey := BitVec 256def cbcEncrypt
CBC encryption of the blocks P with block function f, starting from the chaining value prev (the IV): C₁ = f (P₁ ⊕ prev), Cᵢ₊₁ = f (Pᵢ₊₁ ⊕ Cᵢ).
DEV-AEAD8 (libsignal): the IV is part of the key. libsignal derives the IV with HKDF (the HMAC-based key derivation) together with the keys, and never transmits it. So the IV is part of the one-time key (k, iv) and not of the ciphertext. Effect: none.
1 declaration not shown (lines 54–62): theorems, which Lean checks, or definitions that no headline statement uses
CryptoGames.
PKCS#7 padding
abbrev Plain
A plaintext of exactly ℓ bytes. CBC with PKCS#7 reveals the length, so the game fixes it.
DEV-AEAD2 (libsignal): one plaintext length per session. ACD19 Def. 2 compares the real ciphertext with a uniformly random one. AES-CBC with PKCS#7 padding reveals the number of blocks, so every plaintext of a session has the same length ℓ; the end-to-end adversary's messages have type CBC. ℓ. Effect: restricts the adversary (no claim for sessions that mix message lengths).
abbrev Plain (ℓ : ℕ) := List.Vector (BitVec 8) ℓdef nBlocks
Number of ciphertext blocks for an ℓ-byte plaintext.
def nBlocks (ℓ : ℕ) : ℕ := ℓ / 16 + 1def padLen
PKCS#7 pad length: 16 − (ℓ mod 16), always in 1..16.
def padLen (ℓ : ℕ) : ℕ := 16 - ℓ % 16def pkcs7Bytes
def bytesToBlock
Little-endian block of (up to) 16 bytes: byte j occupies bits 8j .. 8j+7, as in an AArch64 16-byte load.
def bytesToBlock (bs : List (BitVec 8)) : Block :=
bs.foldr (fun b acc => (acc <<< 8) ||| b.zeroExtend 128) 0def pkcs7Blocks
PKCS#7 padding split into nBlocks ℓ blocks: block i is bytes 16i .. 16i+15.
def pkcs7Blocks {ℓ : ℕ} (m : Plain ℓ) : List.Vector Block (nBlocks ℓ) :=
List.Vector.ofFn fun i => bytesToBlock (((pkcs7Bytes m).drop (16 * i.val)).take 16)The cipher and the PRF
def cbcScheme
CBC with key (k, iv) applied to a deterministic block encoding encode of the message. Decryption is out of scope and always rejects.
abbrev cbcPkcs7EncryptOnly
libsignal's AES-256-CBC with PKCS#7 padding on ℓ-byte plaintexts, AES abstracted as E.
DEV-AEAD14 (machine model): AES and SHA-256 are arbitrary functions. The AES-256 block function E here and the SHA-256 compression function F of AEAD/ are parameters, because in the binary they are hooks whose machine code is not verified (DEV-E8). The assumptions (blockPRF E and HMAC are PRFs) are about whatever the hooks compute. Effect: none.
3 declarations not shown (lines 114–147): theorems, which Lean checks, or definitions that no headline statement uses
CryptoGames., CryptoGames., CryptoGames.
end CBCend CryptoGames