5.3. Correctness
Theorem5.23
Group: Core X3DH definitions and end-to-end correctness results. (7)
-
Definition 5.20Blueprint label
-
x3dh_keypair
Group- Core X3DH definitions and end-to-end correctness results.
-
-
Definition 5.21Blueprint label
-
x3dh_alice
Group- Core X3DH definitions and end-to-end correctness results.
-
-
Definition 5.22Blueprint label
-
x3dh_bob
Group- Core X3DH definitions and end-to-end correctness results.
-
-
Definition 5.24Blueprint label
-
x3dh_sk_alice
Group- Core X3DH definitions and end-to-end correctness results.
-
-
Definition 5.25Blueprint label
-
x3dh_sk_bob
Group- Core X3DH definitions and end-to-end correctness results.
-
-
Theorem 5.26Blueprint label
-
x3dh_session_key_agree
Group- Core X3DH definitions and end-to-end correctness results.
-
-
Theorem 5.27Blueprint label
-
x3dh_handshake_correct
Group- Core X3DH definitions and end-to-end correctness results.
-
Preview
Definition 5.20
Blueprint label
-
x3dh_keypair
Group
- Core X3DH definitions and end-to-end correctness results.
Associated Lean declarations
-
X3DH_agree[complete]
Used by 3
-
Theorem 5.26Blueprint label
-
x3dh_session_key_agree
Uses target in- statement
- proof
-
-
Theorem 5.27Blueprint label
-
x3dh_handshake_correct
Uses target in- statement
-
-
Theorem 6.7Blueprint label
-
pqxdh_agree
Uses target in- statement
-
Preview
Theorem 5.26
Blueprint label
-
x3dh_session_key_agree
Uses target in
- statement
- proof
If all key pairs are honestly generated from the same generator, then Alice
and Bob compute identical DH tuples. The key algebraic input is
Definition 1.1
Abstract Diffie-Hellman is modeled as scalar multiplication
in a module over a field. DH a B is an abbrev for a • B
(Mathlib's scalar multiplication), so all Module lemmas
apply directly without unfolding.
Code for Theorem5.23●1 theorem
Associated Lean declarations
-
X3DH_agree[complete]
Associated Lean declarations
-
X3DH_agree[complete]
-
theorem X3DH_agree.{u_1, u_2} {F
Type u_1: Type u_1A type universe. `Type ≡ Type 0`, `Type u ≡ Sort (u + 1)`.} [FieldField.{u} (K : Type u) : Type uA `Field` is a `CommRing` with multiplicative inverses for nonzero elements. An instance of `Field K` includes maps `ratCast : ℚ → K` and `qsmul : ℚ → K → K`. Those two fields are needed to implement the `DivisionRing K → Algebra ℚ K` instance since we need to control the specific definitions for some special cases of `K` (in particular `K = ℚ` itself). See also note [forgetful inheritance]. If the field has positive characteristic `p`, our division by zero convention forces `ratCast (1 / p) = 1 / 0 = 0`.FType u_1] {GType u_2: Type u_2A type universe. `Type ≡ Type 0`, `Type u ≡ Sort (u + 1)`.} [AddCommGroupAddCommGroup.{u} (G : Type u) : Type uAn additive commutative group is an additive group with commutative `(+)`.GType u_2] [ModuleModule.{u, v} (R : Type u) (M : Type v) [Semiring R] [AddCommMonoid M] : Type (max u v)A module is a generalization of vector spaces to a scalar semiring. It consists of a scalar semiring `R` and an additive monoid of "vectors" `M`, connected by a "scalar multiplication" operation `r • x : M` (where `r : R` and `x : M`) with some natural associativity and distributivity axioms similar to those on a ring.FType u_1GType u_2] {G₀G: GType u_2} (ikₐKeyPair F G G₀ekₐKeyPair F G G₀ikᵦKeyPair F G G₀spkᵦKeyPair F G G₀: KeyPairKeyPair.{u_1, u_2} (F : Type u_1) (G : Type u_2) [Field F] [AddCommGroup G] [Module F G] (G₀ : G) : Type (max u_1 u_2)A key pair: private scalar and public group element satisfying pub = DH(priv, G₀). The paper defines four key types: identity (IK), signed prekey (SPK), one-time prekey (OPK), and ephemeral (EK).FType u_1GType u_2G₀G) (opkᵦOption (KeyPair F G G₀): OptionOption.{u} (α : Type u) : Type uOptional values, which are either `some` around a value from the underlying type or `none`. `Option` can represent nullable types or computations that might fail. In the codomain of a function type, it can also represent partiality.(KeyPairKeyPair.{u_1, u_2} (F : Type u_1) (G : Type u_2) [Field F] [AddCommGroup G] [Module F G] (G₀ : G) : Type (max u_1 u_2)A key pair: private scalar and public group element satisfying pub = DH(priv, G₀). The paper defines four key types: identity (IK), signed prekey (SPK), one-time prekey (OPK), and ephemeral (EK).FType u_1GType u_2G₀G)) : X3DH_AliceX3DH_Alice.{u_1, u_2} {F : Type u_1} [Field F] {G : Type u_2} [AddCommGroup G] [Module F G] (ikₐ ekₐ : F) (IKᵦ SPKᵦ : G) (OPKᵦ : Option G) : G × G × G × GAlice's DH computations. OPKᵦ is optional; when absent, DH4 = 0.ikₐKeyPair F G G₀.privKeyPair.priv.{u_1, u_2} {F : Type u_1} {G : Type u_2} [Field F] [AddCommGroup G] [Module F G] {G₀ : G} (self : KeyPair F G G₀) : FekₐKeyPair F G G₀.privKeyPair.priv.{u_1, u_2} {F : Type u_1} {G : Type u_2} [Field F] [AddCommGroup G] [Module F G] {G₀ : G} (self : KeyPair F G G₀) : FikᵦKeyPair F G G₀.pubKeyPair.pub.{u_1, u_2} {F : Type u_1} {G : Type u_2} [Field F] [AddCommGroup G] [Module F G] {G₀ : G} (self : KeyPair F G G₀) : GspkᵦKeyPair F G G₀.pubKeyPair.pub.{u_1, u_2} {F : Type u_1} {G : Type u_2} [Field F] [AddCommGroup G] [Module F G] {G₀ : G} (self : KeyPair F G G₀) : G(Option.mapOption.map.{u_1, u_2} {α : Type u_1} {β : Type u_2} (f : α → β) : Option α → Option βApply a function to an optional value, if present. From the perspective of `Option` as a container with at most one value, this is analogous to `List.map`. It can also be accessed via the `Functor Option` instance. Examples: * `(none : Option Nat).map (· + 1) = none` * `(some 3).map (· + 1) = some 4`KeyPair.pubKeyPair.pub.{u_1, u_2} {F : Type u_1} {G : Type u_2} [Field F] [AddCommGroup G] [Module F G] {G₀ : G} (self : KeyPair F G G₀) : GopkᵦOption (KeyPair F G G₀)) =Eq.{u_1} {α : Sort u_1} : α → α → PropThe equality relation. It has one introduction rule, `Eq.refl`. We use `a = b` as notation for `Eq a b`. A fundamental property of equality is that it is an equivalence relation. ``` variable (α : Type) (a b c d : α) variable (hab : a = b) (hcb : c = b) (hcd : c = d) example : a = d := Eq.trans (Eq.trans hab (Eq.symm hcb)) hcd ``` Equality is much more than an equivalence relation, however. It has the important property that every assertion respects the equivalence, in the sense that we can substitute equal expressions without changing the truth value. That is, given `h1 : a = b` and `h2 : p a`, we can construct a proof for `p b` using substitution: `Eq.subst h1 h2`. Example: ``` example (α : Type) (a b : α) (p : α → Prop) (h1 : a = b) (h2 : p a) : p b := Eq.subst h1 h2 example (α : Type) (a b : α) (p : α → Prop) (h1 : a = b) (h2 : p a) : p b := h1 ▸ h2 ``` The triangle in the second presentation is a macro built on top of `Eq.subst` and `Eq.symm`, and you can enter it by typing `\t`. For more information: [Equality](https://lean-lang.org/theorem_proving_in_lean4/quantifiers_and_equality.html#equality) Conventions for notations in identifiers: * The recommended spelling of `=` in identifiers is `eq`.X3DH_BobX3DH_Bob.{u_1, u_2} {F : Type u_1} [Field F] {G : Type u_2} [AddCommGroup G] [Module F G] (ikᵦ spkᵦ : F) (opkᵦ : Option F) (IKₐ EKₐ : G) : G × G × G × GBob's DH computations (mirror of Alice's).ikᵦKeyPair F G G₀.privKeyPair.priv.{u_1, u_2} {F : Type u_1} {G : Type u_2} [Field F] [AddCommGroup G] [Module F G] {G₀ : G} (self : KeyPair F G G₀) : FspkᵦKeyPair F G G₀.privKeyPair.priv.{u_1, u_2} {F : Type u_1} {G : Type u_2} [Field F] [AddCommGroup G] [Module F G] {G₀ : G} (self : KeyPair F G G₀) : F(Option.mapOption.map.{u_1, u_2} {α : Type u_1} {β : Type u_2} (f : α → β) : Option α → Option βApply a function to an optional value, if present. From the perspective of `Option` as a container with at most one value, this is analogous to `List.map`. It can also be accessed via the `Functor Option` instance. Examples: * `(none : Option Nat).map (· + 1) = none` * `(some 3).map (· + 1) = some 4`KeyPair.privKeyPair.priv.{u_1, u_2} {F : Type u_1} {G : Type u_2} [Field F] [AddCommGroup G] [Module F G] {G₀ : G} (self : KeyPair F G G₀) : FopkᵦOption (KeyPair F G G₀)) ikₐKeyPair F G G₀.pubKeyPair.pub.{u_1, u_2} {F : Type u_1} {G : Type u_2} [Field F] [AddCommGroup G] [Module F G] {G₀ : G} (self : KeyPair F G G₀) : GekₐKeyPair F G G₀.pubKeyPair.pub.{u_1, u_2} {F : Type u_1} {G : Type u_2} [Field F] [AddCommGroup G] [Module F G] {G₀ : G} (self : KeyPair F G G₀) : Gtheorem X3DH_agree.{u_1, u_2} {F
Type u_1: Type u_1A type universe. `Type ≡ Type 0`, `Type u ≡ Sort (u + 1)`.} [FieldField.{u} (K : Type u) : Type uA `Field` is a `CommRing` with multiplicative inverses for nonzero elements. An instance of `Field K` includes maps `ratCast : ℚ → K` and `qsmul : ℚ → K → K`. Those two fields are needed to implement the `DivisionRing K → Algebra ℚ K` instance since we need to control the specific definitions for some special cases of `K` (in particular `K = ℚ` itself). See also note [forgetful inheritance]. If the field has positive characteristic `p`, our division by zero convention forces `ratCast (1 / p) = 1 / 0 = 0`.FType u_1] {GType u_2: Type u_2A type universe. `Type ≡ Type 0`, `Type u ≡ Sort (u + 1)`.} [AddCommGroupAddCommGroup.{u} (G : Type u) : Type uAn additive commutative group is an additive group with commutative `(+)`.GType u_2] [ModuleModule.{u, v} (R : Type u) (M : Type v) [Semiring R] [AddCommMonoid M] : Type (max u v)A module is a generalization of vector spaces to a scalar semiring. It consists of a scalar semiring `R` and an additive monoid of "vectors" `M`, connected by a "scalar multiplication" operation `r • x : M` (where `r : R` and `x : M`) with some natural associativity and distributivity axioms similar to those on a ring.FType u_1GType u_2] {G₀G: GType u_2} (ikₐKeyPair F G G₀ekₐKeyPair F G G₀ikᵦKeyPair F G G₀spkᵦKeyPair F G G₀: KeyPairKeyPair.{u_1, u_2} (F : Type u_1) (G : Type u_2) [Field F] [AddCommGroup G] [Module F G] (G₀ : G) : Type (max u_1 u_2)A key pair: private scalar and public group element satisfying pub = DH(priv, G₀). The paper defines four key types: identity (IK), signed prekey (SPK), one-time prekey (OPK), and ephemeral (EK).FType u_1GType u_2G₀G) (opkᵦOption (KeyPair F G G₀): OptionOption.{u} (α : Type u) : Type uOptional values, which are either `some` around a value from the underlying type or `none`. `Option` can represent nullable types or computations that might fail. In the codomain of a function type, it can also represent partiality.(KeyPairKeyPair.{u_1, u_2} (F : Type u_1) (G : Type u_2) [Field F] [AddCommGroup G] [Module F G] (G₀ : G) : Type (max u_1 u_2)A key pair: private scalar and public group element satisfying pub = DH(priv, G₀). The paper defines four key types: identity (IK), signed prekey (SPK), one-time prekey (OPK), and ephemeral (EK).FType u_1GType u_2G₀G)) : X3DH_AliceX3DH_Alice.{u_1, u_2} {F : Type u_1} [Field F] {G : Type u_2} [AddCommGroup G] [Module F G] (ikₐ ekₐ : F) (IKᵦ SPKᵦ : G) (OPKᵦ : Option G) : G × G × G × GAlice's DH computations. OPKᵦ is optional; when absent, DH4 = 0.ikₐKeyPair F G G₀.privKeyPair.priv.{u_1, u_2} {F : Type u_1} {G : Type u_2} [Field F] [AddCommGroup G] [Module F G] {G₀ : G} (self : KeyPair F G G₀) : FekₐKeyPair F G G₀.privKeyPair.priv.{u_1, u_2} {F : Type u_1} {G : Type u_2} [Field F] [AddCommGroup G] [Module F G] {G₀ : G} (self : KeyPair F G G₀) : FikᵦKeyPair F G G₀.pubKeyPair.pub.{u_1, u_2} {F : Type u_1} {G : Type u_2} [Field F] [AddCommGroup G] [Module F G] {G₀ : G} (self : KeyPair F G G₀) : GspkᵦKeyPair F G G₀.pubKeyPair.pub.{u_1, u_2} {F : Type u_1} {G : Type u_2} [Field F] [AddCommGroup G] [Module F G] {G₀ : G} (self : KeyPair F G G₀) : G(Option.mapOption.map.{u_1, u_2} {α : Type u_1} {β : Type u_2} (f : α → β) : Option α → Option βApply a function to an optional value, if present. From the perspective of `Option` as a container with at most one value, this is analogous to `List.map`. It can also be accessed via the `Functor Option` instance. Examples: * `(none : Option Nat).map (· + 1) = none` * `(some 3).map (· + 1) = some 4`KeyPair.pubKeyPair.pub.{u_1, u_2} {F : Type u_1} {G : Type u_2} [Field F] [AddCommGroup G] [Module F G] {G₀ : G} (self : KeyPair F G G₀) : GopkᵦOption (KeyPair F G G₀)) =Eq.{u_1} {α : Sort u_1} : α → α → PropThe equality relation. It has one introduction rule, `Eq.refl`. We use `a = b` as notation for `Eq a b`. A fundamental property of equality is that it is an equivalence relation. ``` variable (α : Type) (a b c d : α) variable (hab : a = b) (hcb : c = b) (hcd : c = d) example : a = d := Eq.trans (Eq.trans hab (Eq.symm hcb)) hcd ``` Equality is much more than an equivalence relation, however. It has the important property that every assertion respects the equivalence, in the sense that we can substitute equal expressions without changing the truth value. That is, given `h1 : a = b` and `h2 : p a`, we can construct a proof for `p b` using substitution: `Eq.subst h1 h2`. Example: ``` example (α : Type) (a b : α) (p : α → Prop) (h1 : a = b) (h2 : p a) : p b := Eq.subst h1 h2 example (α : Type) (a b : α) (p : α → Prop) (h1 : a = b) (h2 : p a) : p b := h1 ▸ h2 ``` The triangle in the second presentation is a macro built on top of `Eq.subst` and `Eq.symm`, and you can enter it by typing `\t`. For more information: [Equality](https://lean-lang.org/theorem_proving_in_lean4/quantifiers_and_equality.html#equality) Conventions for notations in identifiers: * The recommended spelling of `=` in identifiers is `eq`.X3DH_BobX3DH_Bob.{u_1, u_2} {F : Type u_1} [Field F] {G : Type u_2} [AddCommGroup G] [Module F G] (ikᵦ spkᵦ : F) (opkᵦ : Option F) (IKₐ EKₐ : G) : G × G × G × GBob's DH computations (mirror of Alice's).ikᵦKeyPair F G G₀.privKeyPair.priv.{u_1, u_2} {F : Type u_1} {G : Type u_2} [Field F] [AddCommGroup G] [Module F G] {G₀ : G} (self : KeyPair F G G₀) : FspkᵦKeyPair F G G₀.privKeyPair.priv.{u_1, u_2} {F : Type u_1} {G : Type u_2} [Field F] [AddCommGroup G] [Module F G] {G₀ : G} (self : KeyPair F G G₀) : F(Option.mapOption.map.{u_1, u_2} {α : Type u_1} {β : Type u_2} (f : α → β) : Option α → Option βApply a function to an optional value, if present. From the perspective of `Option` as a container with at most one value, this is analogous to `List.map`. It can also be accessed via the `Functor Option` instance. Examples: * `(none : Option Nat).map (· + 1) = none` * `(some 3).map (· + 1) = some 4`KeyPair.privKeyPair.priv.{u_1, u_2} {F : Type u_1} {G : Type u_2} [Field F] [AddCommGroup G] [Module F G] {G₀ : G} (self : KeyPair F G G₀) : FopkᵦOption (KeyPair F G G₀)) ikₐKeyPair F G G₀.pubKeyPair.pub.{u_1, u_2} {F : Type u_1} {G : Type u_2} [Field F] [AddCommGroup G] [Module F G] {G₀ : G} (self : KeyPair F G G₀) : GekₐKeyPair F G G₀.pubKeyPair.pub.{u_1, u_2} {F : Type u_1} {G : Type u_2} [Field F] [AddCommGroup G] [Module F G] {G₀ : G} (self : KeyPair F G G₀) : GX3DH agreement: Alice and Bob compute identical DH tuples.
Proof
Work by cases on OPK, then apply simp with the Module F G lemmas
(smul_smul, mul_comm) plus each key pair's generation equation.
-- PROOF-SOURCE
by
cases opkᵦ with
| none =>
simp [X3DH_Alice, X3DH_Bob, DH,
ikₐ.pub_eq, ekₐ.pub_eq, ikᵦ.pub_eq, spkᵦ.pub_eq,
smul_smul, mul_comm]
| some kp =>
simp [X3DH_Alice, X3DH_Bob, DH,
ikₐ.pub_eq, ekₐ.pub_eq, ikᵦ.pub_eq, spkᵦ.pub_eq, kp.pub_eq,
smul_smul, mul_comm]