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

Paper › LibsignalBinary/Specifications/CryptoGames/Ratchet › LibsignalSessionApi.leanTier 2 · definitions

LibsignalSessionApi.lean🔗

Tier 2 · definitions used by the computational proof 3 headline theorems depend on it 75 of 450 lines trusted trust banner B3, trusted in part source ↗

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 (8)

libsignal's public session API over abstract stores

Trusted in part. The theorems of Computational/Theorems/ use only key, PreKeySignalMessage, new, ProtoPreKeySignalMessage, encode, PendingPreKey, PendingKyberPreKey, KyberPayload, varint, uint32Field, bytesField from this file (the pre-key message types and the Prost field encoders): read them. Everything else here (the session API, its errors and store calls) and every proof is checked by Lean. See Computational/docs/TRUSTED_BASE.md.

Models the public entry points messageEncrypt (session_management.rs:43–151) and messageDecryptSignal (session_management.rs:297–354) over the core session model of LibsignalSession.lean:

@[expose] public section
namespace CryptoGames
namespace LibsignalSessionApi
open LibsignalSession
5 declarations not shown (lines 53–88): theorems, which Lean checks, or definitions that no headline statement uses

CryptoGames.LibsignalSessionApi.SystemTime.tvNsec, CryptoGames.LibsignalSessionApi.SystemTime.tvSec, CryptoGames.LibsignalSessionApi.SystemTime, CryptoGames.LibsignalSessionApi.SystemTime.unixEpoch, CryptoGames.LibsignalSessionApi.SystemTime.checkedAddSecs, CryptoGames.LibsignalSessionApi.SystemTime.lt, CryptoGames.LibsignalSessionApi.maxUnacknowledgedSessionAge

The session record (state/session.rs, proto/storage.proto)

structure PendingPreKeyL92–104 ↗#

session_structure::PendingPreKey (proto/storage.proto:35–40), as unacknowledged_pre_key_message_items reads it (state/session.rs:549–564).

structure PendingPreKey where /-- `pre_key_id` (`optional uint32`; `PreKeyId`). -/ preKeyId : Option (BitVec 32) /-- `signed_pre_key_id` (stored as `int32`, read back `as u32`, the same 32 bits; `SignedPreKeyId`). -/ signedPreKeyId : BitVec 32 /-- `base_key`, deserialized (see "Deviations"). -/ baseKey : PublicKey /-- `timestamp` (`uint64`): seconds since the Unix epoch when the session was created. -/ timestamp : BitVec 64 deriving DecidableEq

structure PendingKyberPreKeyL106–114 ↗#

session_structure::PendingKyberPreKey (proto/storage.proto:42–45): the Kyber pre-key id (KyberPreKeyId) and the KEM (key encapsulation mechanism) ciphertext of an unacknowledged PQXDH session.

structure PendingKyberPreKey where /-- `pre_key_id` (`uint32`). -/ preKeyId : BitVec 32 /-- `ciphertext` (bytes). -/ ciphertext : List (BitVec 8) deriving DecidableEq
4 declarations not shown (lines 116–156): theorems, which Lean checks, or definitions that no headline statement uses

CryptoGames.LibsignalSessionApi.Session.pendingPreKey, CryptoGames.LibsignalSessionApi.Session, CryptoGames.LibsignalSessionApi.Session.localRegistrationId, CryptoGames.LibsignalSessionApi.Session.pendingKyberPreKey, CryptoGames.LibsignalSessionApi.Session.aliceBaseKey, CryptoGames.LibsignalSessionApi.Session.state, CryptoGames.LibsignalSessionApi.Session.remoteRegistrationId, CryptoGames.LibsignalSessionApi.Session.Wf, CryptoGames.LibsignalSessionApi.SessionRecord.currentSession, CryptoGames.LibsignalSessionApi.SessionRecord, CryptoGames.LibsignalSessionApi.KyberPayload, CryptoGames.LibsignalSessionApi.KyberPayload.preKeyId, CryptoGames.LibsignalSessionApi.KyberPayload.ciphertext

structure ProtoPreKeySignalMessageL158–177 ↗#

prost's proto::wire::PreKeySignalMessage (proto/wire.proto:19–28, proto2: every field is optional).

structure ProtoPreKeySignalMessage where /-- Field 5. -/ registrationId : Option (BitVec 32) /-- Field 1. -/ preKeyId : Option (BitVec 32) /-- Field 6. -/ signedPreKeyId : Option (BitVec 32) /-- Field 7. -/ kyberPreKeyId : Option (BitVec 32) /-- Field 8. -/ kyberCiphertext : Option (List (BitVec 8)) /-- Field 2. -/ baseKey : Option (List (BitVec 8)) /-- Field 3. -/ identityKey : Option (List (BitVec 8)) /-- Field 4 (the serialized inner `SignalMessage`). -/ message : Option (List (BitVec 8)) deriving DecidableEq
namespace Prost

def varintL184–189 ↗#

encode_varint (prost/src/encoding/varint.rs:11–22): base-128 (LEB128), 7 bits per byte, least significant group first, the high bit set on every byte but the last.

def varint (n : ℕ) : List (BitVec 8) := if h : n < 128 then [BitVec.ofNat 8 n] else BitVec.ofNat 8 (n % 128 + 128) :: varint (n / 128) termination_by n decreasing_by All goals completed! 🐙

encode_key (prost/src/encoding.rs:106–110): the varint of tag << 3 | wire_type.

def key (tag wireType : ℕ) : List (BitVec 8) := varint (8 * tag + wireType)

def uint32FieldL194–199 ↗#

An optional uint32 field (uint32::encode: the varint! macro, prost/src/encoding.rs:263–266, at :356): nothing for None; else key (wire type 0, varint) and the value as a varint.

def uint32Field (tag : ℕ) : Option (BitVec 32) → List (BitVec 8) | none => [] | some v => key tag 0 ++ varint v.toNat

def bytesFieldL201–205 ↗#

An optional bytes field (bytes::encode, prost/src/encoding.rs:691–695): nothing for None; else key (wire type 2, length-delimited), the length as a varint, the bytes.

def bytesField (tag : ℕ) : Option (List (BitVec 8)) → List (BitVec 8) | none => [] | some b => key tag 2 ++ varint b.length ++ b
end Prost

def ProtoPreKeySignalMessage.encodeL209–222 ↗#

prost's encoder for proto::wire::PreKeySignalMessage (Message::encode, infallible into a Vec: expect("can always append to a Vec")): the fields in ascending tag order (prost-derive sorts the fields by tag, prost-derive/src/lib.rs:91), each Some field emitted, each None omitted. Concrete, unlike the session model's abstract SignalMessage codec; checked byte-exactly by the KATs (known-answer tests).

17 declarations not shown (lines 224–447): theorems, which Lean checks, or definitions that no headline statement uses

CryptoGames.LibsignalSessionApi.PreKeySignalMessage.preKeyId, CryptoGames.LibsignalSessionApi.PreKeySignalMessage.message, CryptoGames.LibsignalSessionApi.PreKeySignalMessage.identityKey, CryptoGames.LibsignalSessionApi.PreKeySignalMessage.registrationId, CryptoGames.LibsignalSessionApi.PreKeySignalMessage.kyberPayload, CryptoGames.LibsignalSessionApi.PreKeySignalMessage.messageVersion, CryptoGames.LibsignalSessionApi.PreKeySignalMessage, CryptoGames.LibsignalSessionApi.PreKeySignalMessage.baseKey, CryptoGames.LibsignalSessionApi.PreKeySignalMessage.signedPreKeyId, CryptoGames.LibsignalSessionApi.PreKeySignalMessage.serialized, CryptoGames.LibsignalSessionApi.PreKeySignalMessage.new, CryptoGames.LibsignalSessionApi.CiphertextMessage.signalMessage, CryptoGames.LibsignalSessionApi.CiphertextMessage, CryptoGames.LibsignalSessionApi.CiphertextMessage.preKeySignalMessage, CryptoGames.LibsignalSessionApi.Direction.sending, CryptoGames.LibsignalSessionApi.Direction, CryptoGames.LibsignalSessionApi.Direction.receiving, CryptoGames.LibsignalSessionApi.IdentityChange.replacedExisting, CryptoGames.LibsignalSessionApi.IdentityChange, CryptoGames.LibsignalSessionApi.IdentityChange.newOrUnchanged, CryptoGames.LibsignalSessionApi.StoreAnswers.isTrustedIdentity, CryptoGames.LibsignalSessionApi.StoreAnswers, CryptoGames.LibsignalSessionApi.StoreAnswers.loadSession, CryptoGames.LibsignalSessionApi.StoreAnswers.storeSession, CryptoGames.LibsignalSessionApi.StoreAnswers.saveIdentity, CryptoGames.LibsignalSessionApi.StoreCall.saveIdentity, CryptoGames.LibsignalSessionApi.StoreCall.isTrustedIdentity, CryptoGames.LibsignalSessionApi.StoreCall.loadSession, CryptoGames.LibsignalSessionApi.StoreCall, CryptoGames.LibsignalSessionApi.StoreCall.storeSession, CryptoGames.LibsignalSessionApi.ApiError, CryptoGames.LibsignalSessionApi.ApiError.protocol, CryptoGames.LibsignalSessionApi.ApiError.sessionNotFound, CryptoGames.LibsignalSessionApi.ApiError.store, CryptoGames.LibsignalSessionApi.ApiError.panic, CryptoGames.LibsignalSessionApi.ApiError.untrustedIdentity, CryptoGames.LibsignalSessionApi.Api, CryptoGames.LibsignalSessionApi.Api.run, CryptoGames.LibsignalSessionApi.storeCall, CryptoGames.LibsignalSessionApi.ApiError.ofProtocol, CryptoGames.LibsignalSessionApi.liftProtocol, CryptoGames.LibsignalSessionApi.execOk, CryptoGames.LibsignalSessionApi.messageEncrypt, CryptoGames.LibsignalSessionApi.SessionRecord.tryDecryptFromRecord, CryptoGames.LibsignalSessionApi.messageDecryptSignal

end LibsignalSessionApi
end CryptoGames