AlphaProof Code: Verifying Signal’s Security at the Machine-Code Level

Paper › Symbolic/Specifications/Refinement › CliSetup.leanTier 2 · definitions

CliSetup.lean🔗

Tier 2 · definitions used by the symbolic proof 3 headline theorems depend on it 60 of 116 lines trusted source ↗

trust banner in the header: none; the closure computes B2 for the symbolic proof

Read the definitions shown. Only the declarations that the headline statements use are shown, with the namespace, section, open and variable commands needed to read them. The collapsed runs are theorems, which Lean checks, and definitions that no headline statement uses.

Declarations on this page (18)

Initial CLI Directories

Initial filesystem directory snapshots (initDirs) provisioned for Alice and Bob before any signal-session CLI invocation in the refinement statement, encoding the setup keys and registration IDs of ProtocolSetup with no pre-existing session files.

@[expose] public section
set_option autoImplicit false
namespace DY.Libsignal.Composed.Refinement.Cli
open DY DY.Comparse
open CryptoProofLib.Refinement (ExternInterpretation)
open DY.Libsignal.Composed.Refinement

def aliceUuidL38 ↗#

def aliceUuid : String := "8a6f1c2e-3b4d-4e5f-9a0b-1c2d3e4f5a6b"

def bobUuidL40 ↗#

def bobUuid : String := "5d3e2f10-7a8b-4c9d-8e0f-a1b2c3d4e5f6"

def nameOfL42 ↗#

def nameOf (r : ProtocolSetup) (p : Participant) : String := if p = r.alice then aliceUuid else bobUuid

def peerNameOfL44–45 ↗#

def peerNameOf (r : ProtocolSetup) (p : Participant) : String := if p = r.alice then bobUuid else aliceUuid

def addrOfL47 ↗#

def addrOf (r : ProtocolSetup) (p : Participant) : Address := ⟨nameOf r p, 1⟩

def peerOfL49 ↗#

def peerOf (r : ProtocolSetup) (p : Participant) : Address := ⟨peerNameOf r p, 1⟩

def sessionPathOfL51 ↗#

def sessionPathOf (r : ProtocolSetup) (p : Participant) : String := sessionFile (peerOf r p)

def textBytesL53–54 ↗#

UTF-8 byte encoding of s.

def textBytes (s : String) : HwBytes := s.toUTF8.toList.map fun b => BitVec.ofNat 8 b.toNat

def parseUuidBytesL56–63 ↗#

Decode hexadecimal byte pairs from a hyphenated UUID string.

def parseUuidBytes (s : String) : HwBytes := let hexVal (c : Char) : Nat := if c.isDigit then c.toNat - '0'.toNat else c.toLower.toNat - 'a'.toNat + 10 let rec pairs : List Char → HwBytes | a :: b :: rest => BitVec.ofNat 8 (16 * hexVal a + hexVal b) :: pairs rest | _ => [] pairs (s.toList.filter (· != '-'))

def serializeAddressL65–67 ↗#

Binary ProtocolAddress encoding (0x00 ACI tag || 16-byte UUID || 1-byte device ID).

def serializeAddress (a : Address) : HwBytes := 0x00#8 :: parseUuidBytes a.name ++ [BitVec.ofNat 8 a.device]

def serializeAddressesL69–71 ↗#

Concatenated (sender, recipient) binary addresses written into SignalMessage field 6.

def serializeAddresses (sender recipient : Address) : HwBytes := serializeAddress sender ++ serializeAddress recipient

abbrev DirectorySnapshotL73–74 ↗#

Regular files in a participant's working directory (none when absent).

abbrev DirectorySnapshot := String → Option HwBytes

def idSecretL76–77 ↗#

def idSecret (r : ProtocolSetup) (p : Participant) : HwBytes := if p = r.alice then r.ikASecBytes else r.ikBSecBytes

def peerIdSecretL79–80 ↗#

def peerIdSecret (r : ProtocolSetup) (p : Participant) : HwBytes := if p = r.alice then r.ikBSecBytes else r.ikASecBytes

def regIdOfL82 ↗#

def regIdOf (r : ProtocolSetup) (p : Participant) : BitVec 32 := if p = r.alice then r.regIdA else r.regIdB

def commonFilesL84–92 ↗#

Files provisioned for both Alice and Bob: address, identity-key-pair, registration-id, and pinned identities/<peer>.

def commonFiles (interp : ExternInterpretation) (r : ProtocolSetup) (p : Participant) : List (String × HwBytes) := [(addressFile, textBytes (addrOf r p).text), (identityKeyPairFile, IdentityKeyPairStructure.encode ⟨ecKey (pubBytes interp (idSecret r p)), idSecret r p⟩), (registrationIdFile, le32 (regIdOf r p)), (identityFile (peerNameOf r p), ecKey (pubBytes interp (peerIdSecret r p)))]

def bobPreKeyFilesL94–107 ↗#

Bob's pre-key files: signed pre-key, last-resort Kyber pre-key with empty .base-keys, and optional one-time pre-key when r.withOpk holds.

def initDirsL109–117 ↗#

Initial directory snapshot for each participant (commonFiles for Alice, commonFiles ++ bobPreKeyFiles for Bob, empty otherwise).

def initDirs (interp : ExternInterpretation) (r : ProtocolSetup) (p : Participant) : DirectorySnapshot := if p = r.alice then filesOf (commonFiles interp r p) else if p = r.bob then filesOf (commonFiles interp r p ++ bobPreKeyFiles interp r) else fun _ => none
end DY.Libsignal.Composed.Refinement.Cli