TrWireMsg.lean
Declarations on this page (19)
- inductive PbValue
- inductive FieldItem
-
def FieldItem.
toNats - structure EncodingVariation
- def canonicalVariation
- class CanTrWireMsg
- abbrev TrWireHeaderData
-
def TrWireHeaderData.
code - structure SubF
- instance L106
- instance L109
-
def SubF.
length - #combine L157
-
abbrev TrWireMsg.
SubF. pack - instance L165
- def trWireMsgFields?
-
def trWireMsg.
attackerKnowledge -
def trWireMsgArg.
attackerKnowledge - #combine L187
Triple Ratchet SignalMessage Wire Terms
DyLean term algebra and attacker deduction rules for the MAC-authenticated portion of a Triple Ratchet SignalMessage (version byte plus protobuf body, parameterized by EncodingVariation for non-canonical prost encodings).
namespace DY.TrWireinductive PbValue
A protobuf wire value: varint (type 0), length-delimited bytes (type 2), or skipped payload (types 1, 3, and 5).
public
inductive PbValue where
| varint (n : Nat)
| bytes (b : List (BitVec 8))
| unknown (wireType : Nat) (payload : List (BitVec 8))
deriving DecidableEq@[expose] sectioninductive FieldItem
One field occurrence of the SignalMessage protobuf body in wire order.
public
inductive FieldItem where
/-- Known field `tag` (1 to 6) carrying its value from the message. -/
| known (tag keyPad valuePad : Nat)
/-- Overridden, repeated, or unknown field carrying an explicit `PbValue`. -/
| extra (tag : Nat) (value : PbValue) (keyPad valuePad : Nat)
deriving DecidableEq
def FieldItem.
Injective List Nat encoding of a FieldItem.
structure EncodingVariation
Non-canonical protobuf and version-byte encoding choices accepted by prost and libsignal relative to canonicalVariation.
public
structure EncodingVariation where
/-- Low 4 bits of byte 0 (ignored by libsignal). -/
versionLowNibble : Nat
/-- Trailing bytes after the 32-byte key in field 1 (ignored by `PublicKey::deserialize`). -/
ratchetKeyTrailingBytes : List (BitVec 8)
/-- High bits above bit 31 in `known 2` varints (truncated by `as u32`). -/
counterHigh : Nat
/-- High bits above bit 31 in `known 3` varints (truncated by `as u32`). -/
previousCounterHigh : Nat
fields : List FieldItem
deriving DecidableEqenddef canonicalVariation
Canonical encoding emitted by SignalMessage::new: byte 0x44, fields 1 to 4 in order, minimal varints.
@[expose] public
def canonicalVariation : EncodingVariation :=
⟨4, [], 0, 0, [.known 1 0 0, .known 2 0 0, .known 3 0 0, .known 4 0 0]⟩class CanTrWireMsg
public
class CanTrWireMsg (Bytes: Type u) where
trWireMsg: (version: UInt8) → (senderRatchetKey: Bytes) → (counter previousCounter: UInt32) →
(ciphertext pqRatchet: Bytes) → (encodingVariation: EncodingVariation) → Bytesexport CanTrWireMsg (trWireMsg)namespace TrWireMsgabbrev TrWireHeaderData
public
abbrev TrWireHeaderData := UInt8 × UInt32 × UInt32 × EncodingVariation
def TrWireHeaderData.
@[expose] public
def TrWireHeaderData.code (d : TrWireHeaderData) : List (List Nat) :=
let (v, c, pc, ev) := d
[v.toNat, c.toNat, pc.toNat, ev.versionLowNibble, ev.counterHigh, ev.previousCounterHigh] ::
ev.ratchetKeyTrailingBytes.map BitVec.toNat :: ev.fields.map FieldItem.toNatsstructure SubF
public
structure SubF (Bytes: Type) where
version: UInt8
senderRatchetKey: Bytes
counter: UInt32
previousCounter: UInt32
ciphertext: Bytes
pqRatchet: Bytes
encodingVariation: EncodingVariationinstance
public instance: ALaCarte.FunctorSizeOf SubF :=
.ternary SubF.senderRatchetKey SubF.ciphertext SubF.pqRatchetinstance
public instance: SubBytesFunctor SubF :=
.ternaryByCode TrWireHeaderData.code
(fun {x y} hcode => x:TrWireHeaderDatay:TrWireHeaderDatahcode:x.code = y.code⊢ x = y
x:TrWireHeaderDatay:TrWireHeaderDatahcode:x.code = y.codemap_bv:∀ {l₁ l₂ : List (BitVec 8)}, List.map BitVec.toNat l₁ = List.map BitVec.toNat l₂ → l₁ = l₂⊢ x = y
have item_inj : ∀ {a b : FieldItem}, a.toNats = b.toNats → a = b := by
intro a b hi x:TrWireHeaderDatay:TrWireHeaderDatahcode:x.code = y.codemap_bv:∀ {l₁ l₂ : List (BitVec 8)}, List.map BitVec.toNat l₁ = List.map BitVec.toNat l₂ → l₁ = l₂a:FieldItemb:FieldItemhi:a.toNats = b.toNats⊢ a = b
rcases a with ⟨t₁, kp₁, vp₁⟩ | ⟨t₁, n₁ | b₁ | ⟨wt₁, p₁⟩, kp₁, vp₁⟩ known x:TrWireHeaderDatay:TrWireHeaderDatahcode:x.code = y.codemap_bv:∀ {l₁ l₂ : List (BitVec 8)}, List.map BitVec.toNat l₁ = List.map BitVec.toNat l₂ → l₁ = l₂b:FieldItemt₁:Natkp₁:Natvp₁:Nathi:(FieldItem.known t₁ kp₁ vp₁).toNats = b.toNats⊢ FieldItem.known t₁ kp₁ vp₁ = bextra.varint x:TrWireHeaderDatay:TrWireHeaderDatahcode:x.code = y.codemap_bv:∀ {l₁ l₂ : List (BitVec 8)}, List.map BitVec.toNat l₁ = List.map BitVec.toNat l₂ → l₁ = l₂b:FieldItemt₁:Natkp₁:Natvp₁:Natn₁:Nathi:(FieldItem.extra t₁ (PbValue.varint n₁) kp₁ vp₁).toNats = b.toNats⊢ FieldItem.extra t₁ (PbValue.varint n₁) kp₁ vp₁ = bextra.bytes x:TrWireHeaderDatay:TrWireHeaderDatahcode:x.code = y.codemap_bv:∀ {l₁ l₂ : List (BitVec 8)}, List.map BitVec.toNat l₁ = List.map BitVec.toNat l₂ → l₁ = l₂b:FieldItemt₁:Natkp₁:Natvp₁:Natb₁:List (BitVec 8)hi:(FieldItem.extra t₁ (PbValue.bytes b₁) kp₁ vp₁).toNats = b.toNats⊢ FieldItem.extra t₁ (PbValue.bytes b₁) kp₁ vp₁ = bextra.unknown x:TrWireHeaderDatay:TrWireHeaderDatahcode:x.code = y.codemap_bv:∀ {l₁ l₂ : List (BitVec 8)}, List.map BitVec.toNat l₁ = List.map BitVec.toNat l₂ → l₁ = l₂b:FieldItemt₁:Natkp₁:Natvp₁:Natwt₁:Natp₁:List (BitVec 8)hi:(FieldItem.extra t₁ (PbValue.unknown wt₁ p₁) kp₁ vp₁).toNats = b.toNats⊢ FieldItem.extra t₁ (PbValue.unknown wt₁ p₁) kp₁ vp₁ = b <;> known x:TrWireHeaderDatay:TrWireHeaderDatahcode:x.code = y.codemap_bv:∀ {l₁ l₂ : List (BitVec 8)}, List.map BitVec.toNat l₁ = List.map BitVec.toNat l₂ → l₁ = l₂b:FieldItemt₁:Natkp₁:Natvp₁:Nathi:(FieldItem.known t₁ kp₁ vp₁).toNats = b.toNats⊢ FieldItem.known t₁ kp₁ vp₁ = bextra.varint x:TrWireHeaderDatay:TrWireHeaderDatahcode:x.code = y.codemap_bv:∀ {l₁ l₂ : List (BitVec 8)}, List.map BitVec.toNat l₁ = List.map BitVec.toNat l₂ → l₁ = l₂b:FieldItemt₁:Natkp₁:Natvp₁:Natn₁:Nathi:(FieldItem.extra t₁ (PbValue.varint n₁) kp₁ vp₁).toNats = b.toNats⊢ FieldItem.extra t₁ (PbValue.varint n₁) kp₁ vp₁ = bextra.bytes x:TrWireHeaderDatay:TrWireHeaderDatahcode:x.code = y.codemap_bv:∀ {l₁ l₂ : List (BitVec 8)}, List.map BitVec.toNat l₁ = List.map BitVec.toNat l₂ → l₁ = l₂b:FieldItemt₁:Natkp₁:Natvp₁:Natb₁:List (BitVec 8)hi:(FieldItem.extra t₁ (PbValue.bytes b₁) kp₁ vp₁).toNats = b.toNats⊢ FieldItem.extra t₁ (PbValue.bytes b₁) kp₁ vp₁ = bextra.unknown x:TrWireHeaderDatay:TrWireHeaderDatahcode:x.code = y.codemap_bv:∀ {l₁ l₂ : List (BitVec 8)}, List.map BitVec.toNat l₁ = List.map BitVec.toNat l₂ → l₁ = l₂b:FieldItemt₁:Natkp₁:Natvp₁:Natwt₁:Natp₁:List (BitVec 8)hi:(FieldItem.extra t₁ (PbValue.unknown wt₁ p₁) kp₁ vp₁).toNats = b.toNats⊢ FieldItem.extra t₁ (PbValue.unknown wt₁ p₁) kp₁ vp₁ = b
rcases b with ⟨t₂, kp₂, vp₂⟩ | ⟨t₂, n₂ | b₂ | ⟨wt₂, p₂⟩, kp₂, vp₂⟩ extra.unknown.known x:TrWireHeaderDatay:TrWireHeaderDatahcode:x.code = y.codemap_bv:∀ {l₁ l₂ : List (BitVec 8)}, List.map BitVec.toNat l₁ = List.map BitVec.toNat l₂ → l₁ = l₂t₁:Natkp₁:Natvp₁:Natwt₁:Natp₁:List (BitVec 8)t₂:Natkp₂:Natvp₂:Nathi:(FieldItem.extra t₁ (PbValue.unknown wt₁ p₁) kp₁ vp₁).toNats = (FieldItem.known t₂ kp₂ vp₂).toNats⊢ FieldItem.extra t₁ (PbValue.unknown wt₁ p₁) kp₁ vp₁ = FieldItem.known t₂ kp₂ vp₂extra.unknown.extra.varint x:TrWireHeaderDatay:TrWireHeaderDatahcode:x.code = y.codemap_bv:∀ {l₁ l₂ : List (BitVec 8)}, List.map BitVec.toNat l₁ = List.map BitVec.toNat l₂ → l₁ = l₂t₁:Natkp₁:Natvp₁:Natwt₁:Natp₁:List (BitVec 8)t₂:Natkp₂:Natvp₂:Natn₂:Nathi:(FieldItem.extra t₁ (PbValue.unknown wt₁ p₁) kp₁ vp₁).toNats = (FieldItem.extra t₂ (PbValue.varint n₂) kp₂ vp₂).toNats⊢ FieldItem.extra t₁ (PbValue.unknown wt₁ p₁) kp₁ vp₁ = FieldItem.extra t₂ (PbValue.varint n₂) kp₂ vp₂extra.unknown.extra.bytes x:TrWireHeaderDatay:TrWireHeaderDatahcode:x.code = y.codemap_bv:∀ {l₁ l₂ : List (BitVec 8)}, List.map BitVec.toNat l₁ = List.map BitVec.toNat l₂ → l₁ = l₂t₁:Natkp₁:Natvp₁:Natwt₁:Natp₁:List (BitVec 8)t₂:Natkp₂:Natvp₂:Natb₂:List (BitVec 8)hi:(FieldItem.extra t₁ (PbValue.unknown wt₁ p₁) kp₁ vp₁).toNats = (FieldItem.extra t₂ (PbValue.bytes b₂) kp₂ vp₂).toNats⊢ FieldItem.extra t₁ (PbValue.unknown wt₁ p₁) kp₁ vp₁ = FieldItem.extra t₂ (PbValue.bytes b₂) kp₂ vp₂extra.unknown.extra.unknown x:TrWireHeaderDatay:TrWireHeaderDatahcode:x.code = y.codemap_bv:∀ {l₁ l₂ : List (BitVec 8)}, List.map BitVec.toNat l₁ = List.map BitVec.toNat l₂ → l₁ = l₂t₁:Natkp₁:Natvp₁:Natwt₁:Natp₁:List (BitVec 8)t₂:Natkp₂:Natvp₂:Natwt₂:Natp₂:List (BitVec 8)hi:(FieldItem.extra t₁ (PbValue.unknown wt₁ p₁) kp₁ vp₁).toNats =
(FieldItem.extra t₂ (PbValue.unknown wt₂ p₂) kp₂ vp₂).toNats⊢ FieldItem.extra t₁ (PbValue.unknown wt₁ p₁) kp₁ vp₁ = FieldItem.extra t₂ (PbValue.unknown wt₂ p₂) kp₂ vp₂ <;> known.known x:TrWireHeaderDatay:TrWireHeaderDatahcode:x.code = y.codemap_bv:∀ {l₁ l₂ : List (BitVec 8)}, List.map BitVec.toNat l₁ = List.map BitVec.toNat l₂ → l₁ = l₂t₁:Natkp₁:Natvp₁:Natt₂:Natkp₂:Natvp₂:Nathi:(FieldItem.known t₁ kp₁ vp₁).toNats = (FieldItem.known t₂ kp₂ vp₂).toNats⊢ FieldItem.known t₁ kp₁ vp₁ = FieldItem.known t₂ kp₂ vp₂known.extra.varint x:TrWireHeaderDatay:TrWireHeaderDatahcode:x.code = y.codemap_bv:∀ {l₁ l₂ : List (BitVec 8)}, List.map BitVec.toNat l₁ = List.map BitVec.toNat l₂ → l₁ = l₂t₁:Natkp₁:Natvp₁:Natt₂:Natkp₂:Natvp₂:Natn₂:Nathi:(FieldItem.known t₁ kp₁ vp₁).toNats = (FieldItem.extra t₂ (PbValue.varint n₂) kp₂ vp₂).toNats⊢ FieldItem.known t₁ kp₁ vp₁ = FieldItem.extra t₂ (PbValue.varint n₂) kp₂ vp₂known.extra.bytes x:TrWireHeaderDatay:TrWireHeaderDatahcode:x.code = y.codemap_bv:∀ {l₁ l₂ : List (BitVec 8)}, List.map BitVec.toNat l₁ = List.map BitVec.toNat l₂ → l₁ = l₂t₁:Natkp₁:Natvp₁:Natt₂:Natkp₂:Natvp₂:Natb₂:List (BitVec 8)hi:(FieldItem.known t₁ kp₁ vp₁).toNats = (FieldItem.extra t₂ (PbValue.bytes b₂) kp₂ vp₂).toNats⊢ FieldItem.known t₁ kp₁ vp₁ = FieldItem.extra t₂ (PbValue.bytes b₂) kp₂ vp₂known.extra.unknown x:TrWireHeaderDatay:TrWireHeaderDatahcode:x.code = y.codemap_bv:∀ {l₁ l₂ : List (BitVec 8)}, List.map BitVec.toNat l₁ = List.map BitVec.toNat l₂ → l₁ = l₂t₁:Natkp₁:Natvp₁:Natt₂:Natkp₂:Natvp₂:Natwt₂:Natp₂:List (BitVec 8)hi:(FieldItem.known t₁ kp₁ vp₁).toNats = (FieldItem.extra t₂ (PbValue.unknown wt₂ p₂) kp₂ vp₂).toNats⊢ FieldItem.known t₁ kp₁ vp₁ = FieldItem.extra t₂ (PbValue.unknown wt₂ p₂) kp₂ vp₂extra.varint.known x:TrWireHeaderDatay:TrWireHeaderDatahcode:x.code = y.codemap_bv:∀ {l₁ l₂ : List (BitVec 8)}, List.map BitVec.toNat l₁ = List.map BitVec.toNat l₂ → l₁ = l₂t₁:Natkp₁:Natvp₁:Natn₁:Natt₂:Natkp₂:Natvp₂:Nathi:(FieldItem.extra t₁ (PbValue.varint n₁) kp₁ vp₁).toNats = (FieldItem.known t₂ kp₂ vp₂).toNats⊢ FieldItem.extra t₁ (PbValue.varint n₁) kp₁ vp₁ = FieldItem.known t₂ kp₂ vp₂extra.varint.extra.varint x:TrWireHeaderDatay:TrWireHeaderDatahcode:x.code = y.codemap_bv:∀ {l₁ l₂ : List (BitVec 8)}, List.map BitVec.toNat l₁ = List.map BitVec.toNat l₂ → l₁ = l₂t₁:Natkp₁:Natvp₁:Natn₁:Natt₂:Natkp₂:Natvp₂:Natn₂:Nathi:(FieldItem.extra t₁ (PbValue.varint n₁) kp₁ vp₁).toNats = (FieldItem.extra t₂ (PbValue.varint n₂) kp₂ vp₂).toNats⊢ FieldItem.extra t₁ (PbValue.varint n₁) kp₁ vp₁ = FieldItem.extra t₂ (PbValue.varint n₂) kp₂ vp₂extra.varint.extra.bytes x:TrWireHeaderDatay:TrWireHeaderDatahcode:x.code = y.codemap_bv:∀ {l₁ l₂ : List (BitVec 8)}, List.map BitVec.toNat l₁ = List.map BitVec.toNat l₂ → l₁ = l₂t₁:Natkp₁:Natvp₁:Natn₁:Natt₂:Natkp₂:Natvp₂:Natb₂:List (BitVec 8)hi:(FieldItem.extra t₁ (PbValue.varint n₁) kp₁ vp₁).toNats = (FieldItem.extra t₂ (PbValue.bytes b₂) kp₂ vp₂).toNats⊢ FieldItem.extra t₁ (PbValue.varint n₁) kp₁ vp₁ = FieldItem.extra t₂ (PbValue.bytes b₂) kp₂ vp₂extra.varint.extra.unknown x:TrWireHeaderDatay:TrWireHeaderDatahcode:x.code = y.codemap_bv:∀ {l₁ l₂ : List (BitVec 8)}, List.map BitVec.toNat l₁ = List.map BitVec.toNat l₂ → l₁ = l₂t₁:Natkp₁:Natvp₁:Natn₁:Natt₂:Natkp₂:Natvp₂:Natwt₂:Natp₂:List (BitVec 8)hi:(FieldItem.extra t₁ (PbValue.varint n₁) kp₁ vp₁).toNats = (FieldItem.extra t₂ (PbValue.unknown wt₂ p₂) kp₂ vp₂).toNats⊢ FieldItem.extra t₁ (PbValue.varint n₁) kp₁ vp₁ = FieldItem.extra t₂ (PbValue.unknown wt₂ p₂) kp₂ vp₂extra.bytes.known x:TrWireHeaderDatay:TrWireHeaderDatahcode:x.code = y.codemap_bv:∀ {l₁ l₂ : List (BitVec 8)}, List.map BitVec.toNat l₁ = List.map BitVec.toNat l₂ → l₁ = l₂t₁:Natkp₁:Natvp₁:Natb₁:List (BitVec 8)t₂:Natkp₂:Natvp₂:Nathi:(FieldItem.extra t₁ (PbValue.bytes b₁) kp₁ vp₁).toNats = (FieldItem.known t₂ kp₂ vp₂).toNats⊢ FieldItem.extra t₁ (PbValue.bytes b₁) kp₁ vp₁ = FieldItem.known t₂ kp₂ vp₂extra.bytes.extra.varint x:TrWireHeaderDatay:TrWireHeaderDatahcode:x.code = y.codemap_bv:∀ {l₁ l₂ : List (BitVec 8)}, List.map BitVec.toNat l₁ = List.map BitVec.toNat l₂ → l₁ = l₂t₁:Natkp₁:Natvp₁:Natb₁:List (BitVec 8)t₂:Natkp₂:Natvp₂:Natn₂:Nathi:(FieldItem.extra t₁ (PbValue.bytes b₁) kp₁ vp₁).toNats = (FieldItem.extra t₂ (PbValue.varint n₂) kp₂ vp₂).toNats⊢ FieldItem.extra t₁ (PbValue.bytes b₁) kp₁ vp₁ = FieldItem.extra t₂ (PbValue.varint n₂) kp₂ vp₂extra.bytes.extra.bytes x:TrWireHeaderDatay:TrWireHeaderDatahcode:x.code = y.codemap_bv:∀ {l₁ l₂ : List (BitVec 8)}, List.map BitVec.toNat l₁ = List.map BitVec.toNat l₂ → l₁ = l₂t₁:Natkp₁:Natvp₁:Natb₁:List (BitVec 8)t₂:Natkp₂:Natvp₂:Natb₂:List (BitVec 8)hi:(FieldItem.extra t₁ (PbValue.bytes b₁) kp₁ vp₁).toNats = (FieldItem.extra t₂ (PbValue.bytes b₂) kp₂ vp₂).toNats⊢ FieldItem.extra t₁ (PbValue.bytes b₁) kp₁ vp₁ = FieldItem.extra t₂ (PbValue.bytes b₂) kp₂ vp₂extra.bytes.extra.unknown x:TrWireHeaderDatay:TrWireHeaderDatahcode:x.code = y.codemap_bv:∀ {l₁ l₂ : List (BitVec 8)}, List.map BitVec.toNat l₁ = List.map BitVec.toNat l₂ → l₁ = l₂t₁:Natkp₁:Natvp₁:Natb₁:List (BitVec 8)t₂:Natkp₂:Natvp₂:Natwt₂:Natp₂:List (BitVec 8)hi:(FieldItem.extra t₁ (PbValue.bytes b₁) kp₁ vp₁).toNats = (FieldItem.extra t₂ (PbValue.unknown wt₂ p₂) kp₂ vp₂).toNats⊢ FieldItem.extra t₁ (PbValue.bytes b₁) kp₁ vp₁ = FieldItem.extra t₂ (PbValue.unknown wt₂ p₂) kp₂ vp₂extra.unknown.known x:TrWireHeaderDatay:TrWireHeaderDatahcode:x.code = y.codemap_bv:∀ {l₁ l₂ : List (BitVec 8)}, List.map BitVec.toNat l₁ = List.map BitVec.toNat l₂ → l₁ = l₂t₁:Natkp₁:Natvp₁:Natwt₁:Natp₁:List (BitVec 8)t₂:Natkp₂:Natvp₂:Nathi:(FieldItem.extra t₁ (PbValue.unknown wt₁ p₁) kp₁ vp₁).toNats = (FieldItem.known t₂ kp₂ vp₂).toNats⊢ FieldItem.extra t₁ (PbValue.unknown wt₁ p₁) kp₁ vp₁ = FieldItem.known t₂ kp₂ vp₂extra.unknown.extra.varint x:TrWireHeaderDatay:TrWireHeaderDatahcode:x.code = y.codemap_bv:∀ {l₁ l₂ : List (BitVec 8)}, List.map BitVec.toNat l₁ = List.map BitVec.toNat l₂ → l₁ = l₂t₁:Natkp₁:Natvp₁:Natwt₁:Natp₁:List (BitVec 8)t₂:Natkp₂:Natvp₂:Natn₂:Nathi:(FieldItem.extra t₁ (PbValue.unknown wt₁ p₁) kp₁ vp₁).toNats = (FieldItem.extra t₂ (PbValue.varint n₂) kp₂ vp₂).toNats⊢ FieldItem.extra t₁ (PbValue.unknown wt₁ p₁) kp₁ vp₁ = FieldItem.extra t₂ (PbValue.varint n₂) kp₂ vp₂extra.unknown.extra.bytes x:TrWireHeaderDatay:TrWireHeaderDatahcode:x.code = y.codemap_bv:∀ {l₁ l₂ : List (BitVec 8)}, List.map BitVec.toNat l₁ = List.map BitVec.toNat l₂ → l₁ = l₂t₁:Natkp₁:Natvp₁:Natwt₁:Natp₁:List (BitVec 8)t₂:Natkp₂:Natvp₂:Natb₂:List (BitVec 8)hi:(FieldItem.extra t₁ (PbValue.unknown wt₁ p₁) kp₁ vp₁).toNats = (FieldItem.extra t₂ (PbValue.bytes b₂) kp₂ vp₂).toNats⊢ FieldItem.extra t₁ (PbValue.unknown wt₁ p₁) kp₁ vp₁ = FieldItem.extra t₂ (PbValue.bytes b₂) kp₂ vp₂extra.unknown.extra.unknown x:TrWireHeaderDatay:TrWireHeaderDatahcode:x.code = y.codemap_bv:∀ {l₁ l₂ : List (BitVec 8)}, List.map BitVec.toNat l₁ = List.map BitVec.toNat l₂ → l₁ = l₂t₁:Natkp₁:Natvp₁:Natwt₁:Natp₁:List (BitVec 8)t₂:Natkp₂:Natvp₂:Natwt₂:Natp₂:List (BitVec 8)hi:(FieldItem.extra t₁ (PbValue.unknown wt₁ p₁) kp₁ vp₁).toNats =
(FieldItem.extra t₂ (PbValue.unknown wt₂ p₂) kp₂ vp₂).toNats⊢ FieldItem.extra t₁ (PbValue.unknown wt₁ p₁) kp₁ vp₁ = FieldItem.extra t₂ (PbValue.unknown wt₂ p₂) kp₂ vp₂
simp only [FieldItem.toNats, List.cons.injEq] at hi extra.unknown.extra.unknown x:TrWireHeaderDatay:TrWireHeaderDatahcode:x.code = y.codemap_bv:∀ {l₁ l₂ : List (BitVec 8)}, List.map BitVec.toNat l₁ = List.map BitVec.toNat l₂ → l₁ = l₂t₁:Natkp₁:Natvp₁:Natwt₁:Natp₁:List (BitVec 8)t₂:Natkp₂:Natvp₂:Natwt₂:Natp₂:List (BitVec 8)hi:True ∧ t₁ = t₂ ∧ kp₁ = kp₂ ∧ vp₁ = vp₂ ∧ wt₁ = wt₂ ∧ List.map BitVec.toNat p₁ = List.map BitVec.toNat p₂⊢ FieldItem.extra t₁ (PbValue.unknown wt₁ p₁) kp₁ vp₁ = FieldItem.extra t₂ (PbValue.unknown wt₂ p₂) kp₂ vp₂ <;> known.known x:TrWireHeaderDatay:TrWireHeaderDatahcode:x.code = y.codemap_bv:∀ {l₁ l₂ : List (BitVec 8)}, List.map BitVec.toNat l₁ = List.map BitVec.toNat l₂ → l₁ = l₂t₁:Natkp₁:Natvp₁:Natt₂:Natkp₂:Natvp₂:Nathi:True ∧ t₁ = t₂ ∧ kp₁ = kp₂ ∧ vp₁ = vp₂ ∧ True⊢ FieldItem.known t₁ kp₁ vp₁ = FieldItem.known t₂ kp₂ vp₂known.extra.varint x:TrWireHeaderDatay:TrWireHeaderDatahcode:x.code = y.codemap_bv:∀ {l₁ l₂ : List (BitVec 8)}, List.map BitVec.toNat l₁ = List.map BitVec.toNat l₂ → l₁ = l₂t₁:Natkp₁:Natvp₁:Natt₂:Natkp₂:Natvp₂:Natn₂:Nathi:0 = 1 ∧ t₁ = t₂ ∧ kp₁ = kp₂ ∧ vp₁ = vp₂ ∧ [] = [n₂]⊢ FieldItem.known t₁ kp₁ vp₁ = FieldItem.extra t₂ (PbValue.varint n₂) kp₂ vp₂known.extra.bytes x:TrWireHeaderDatay:TrWireHeaderDatahcode:x.code = y.codemap_bv:∀ {l₁ l₂ : List (BitVec 8)}, List.map BitVec.toNat l₁ = List.map BitVec.toNat l₂ → l₁ = l₂t₁:Natkp₁:Natvp₁:Natt₂:Natkp₂:Natvp₂:Natb₂:List (BitVec 8)hi:0 = 2 ∧ t₁ = t₂ ∧ kp₁ = kp₂ ∧ vp₁ = vp₂ ∧ [] = List.map BitVec.toNat b₂⊢ FieldItem.known t₁ kp₁ vp₁ = FieldItem.extra t₂ (PbValue.bytes b₂) kp₂ vp₂known.extra.unknown x:TrWireHeaderDatay:TrWireHeaderDatahcode:x.code = y.codemap_bv:∀ {l₁ l₂ : List (BitVec 8)}, List.map BitVec.toNat l₁ = List.map BitVec.toNat l₂ → l₁ = l₂t₁:Natkp₁:Natvp₁:Natt₂:Natkp₂:Natvp₂:Natwt₂:Natp₂:List (BitVec 8)hi:0 = 3 ∧ t₁ = t₂ ∧ kp₁ = kp₂ ∧ vp₁ = vp₂ ∧ [] = wt₂ :: List.map BitVec.toNat p₂⊢ FieldItem.known t₁ kp₁ vp₁ = FieldItem.extra t₂ (PbValue.unknown wt₂ p₂) kp₂ vp₂extra.varint.known x:TrWireHeaderDatay:TrWireHeaderDatahcode:x.code = y.codemap_bv:∀ {l₁ l₂ : List (BitVec 8)}, List.map BitVec.toNat l₁ = List.map BitVec.toNat l₂ → l₁ = l₂t₁:Natkp₁:Natvp₁:Natn₁:Natt₂:Natkp₂:Natvp₂:Nathi:1 = 0 ∧ t₁ = t₂ ∧ kp₁ = kp₂ ∧ vp₁ = vp₂ ∧ [n₁] = []⊢ FieldItem.extra t₁ (PbValue.varint n₁) kp₁ vp₁ = FieldItem.known t₂ kp₂ vp₂extra.varint.extra.varint x:TrWireHeaderDatay:TrWireHeaderDatahcode:x.code = y.codemap_bv:∀ {l₁ l₂ : List (BitVec 8)}, List.map BitVec.toNat l₁ = List.map BitVec.toNat l₂ → l₁ = l₂t₁:Natkp₁:Natvp₁:Natn₁:Natt₂:Natkp₂:Natvp₂:Natn₂:Nathi:True ∧ t₁ = t₂ ∧ kp₁ = kp₂ ∧ vp₁ = vp₂ ∧ n₁ = n₂ ∧ True⊢ FieldItem.extra t₁ (PbValue.varint n₁) kp₁ vp₁ = FieldItem.extra t₂ (PbValue.varint n₂) kp₂ vp₂extra.varint.extra.bytes x:TrWireHeaderDatay:TrWireHeaderDatahcode:x.code = y.codemap_bv:∀ {l₁ l₂ : List (BitVec 8)}, List.map BitVec.toNat l₁ = List.map BitVec.toNat l₂ → l₁ = l₂t₁:Natkp₁:Natvp₁:Natn₁:Natt₂:Natkp₂:Natvp₂:Natb₂:List (BitVec 8)hi:1 = 2 ∧ t₁ = t₂ ∧ kp₁ = kp₂ ∧ vp₁ = vp₂ ∧ [n₁] = List.map BitVec.toNat b₂⊢ FieldItem.extra t₁ (PbValue.varint n₁) kp₁ vp₁ = FieldItem.extra t₂ (PbValue.bytes b₂) kp₂ vp₂extra.varint.extra.unknown x:TrWireHeaderDatay:TrWireHeaderDatahcode:x.code = y.codemap_bv:∀ {l₁ l₂ : List (BitVec 8)}, List.map BitVec.toNat l₁ = List.map BitVec.toNat l₂ → l₁ = l₂t₁:Natkp₁:Natvp₁:Natn₁:Natt₂:Natkp₂:Natvp₂:Natwt₂:Natp₂:List (BitVec 8)hi:1 = 3 ∧ t₁ = t₂ ∧ kp₁ = kp₂ ∧ vp₁ = vp₂ ∧ n₁ = wt₂ ∧ [] = List.map BitVec.toNat p₂⊢ FieldItem.extra t₁ (PbValue.varint n₁) kp₁ vp₁ = FieldItem.extra t₂ (PbValue.unknown wt₂ p₂) kp₂ vp₂extra.bytes.known x:TrWireHeaderDatay:TrWireHeaderDatahcode:x.code = y.codemap_bv:∀ {l₁ l₂ : List (BitVec 8)}, List.map BitVec.toNat l₁ = List.map BitVec.toNat l₂ → l₁ = l₂t₁:Natkp₁:Natvp₁:Natb₁:List (BitVec 8)t₂:Natkp₂:Natvp₂:Nathi:2 = 0 ∧ t₁ = t₂ ∧ kp₁ = kp₂ ∧ vp₁ = vp₂ ∧ List.map BitVec.toNat b₁ = []⊢ FieldItem.extra t₁ (PbValue.bytes b₁) kp₁ vp₁ = FieldItem.known t₂ kp₂ vp₂extra.bytes.extra.varint x:TrWireHeaderDatay:TrWireHeaderDatahcode:x.code = y.codemap_bv:∀ {l₁ l₂ : List (BitVec 8)}, List.map BitVec.toNat l₁ = List.map BitVec.toNat l₂ → l₁ = l₂t₁:Natkp₁:Natvp₁:Natb₁:List (BitVec 8)t₂:Natkp₂:Natvp₂:Natn₂:Nathi:2 = 1 ∧ t₁ = t₂ ∧ kp₁ = kp₂ ∧ vp₁ = vp₂ ∧ List.map BitVec.toNat b₁ = [n₂]⊢ FieldItem.extra t₁ (PbValue.bytes b₁) kp₁ vp₁ = FieldItem.extra t₂ (PbValue.varint n₂) kp₂ vp₂extra.bytes.extra.bytes x:TrWireHeaderDatay:TrWireHeaderDatahcode:x.code = y.codemap_bv:∀ {l₁ l₂ : List (BitVec 8)}, List.map BitVec.toNat l₁ = List.map BitVec.toNat l₂ → l₁ = l₂t₁:Natkp₁:Natvp₁:Natb₁:List (BitVec 8)t₂:Natkp₂:Natvp₂:Natb₂:List (BitVec 8)hi:True ∧ t₁ = t₂ ∧ kp₁ = kp₂ ∧ vp₁ = vp₂ ∧ List.map BitVec.toNat b₁ = List.map BitVec.toNat b₂⊢ FieldItem.extra t₁ (PbValue.bytes b₁) kp₁ vp₁ = FieldItem.extra t₂ (PbValue.bytes b₂) kp₂ vp₂extra.bytes.extra.unknown x:TrWireHeaderDatay:TrWireHeaderDatahcode:x.code = y.codemap_bv:∀ {l₁ l₂ : List (BitVec 8)}, List.map BitVec.toNat l₁ = List.map BitVec.toNat l₂ → l₁ = l₂t₁:Natkp₁:Natvp₁:Natb₁:List (BitVec 8)t₂:Natkp₂:Natvp₂:Natwt₂:Natp₂:List (BitVec 8)hi:2 = 3 ∧ t₁ = t₂ ∧ kp₁ = kp₂ ∧ vp₁ = vp₂ ∧ List.map BitVec.toNat b₁ = wt₂ :: List.map BitVec.toNat p₂⊢ FieldItem.extra t₁ (PbValue.bytes b₁) kp₁ vp₁ = FieldItem.extra t₂ (PbValue.unknown wt₂ p₂) kp₂ vp₂extra.unknown.known x:TrWireHeaderDatay:TrWireHeaderDatahcode:x.code = y.codemap_bv:∀ {l₁ l₂ : List (BitVec 8)}, List.map BitVec.toNat l₁ = List.map BitVec.toNat l₂ → l₁ = l₂t₁:Natkp₁:Natvp₁:Natwt₁:Natp₁:List (BitVec 8)t₂:Natkp₂:Natvp₂:Nathi:3 = 0 ∧ t₁ = t₂ ∧ kp₁ = kp₂ ∧ vp₁ = vp₂ ∧ wt₁ :: List.map BitVec.toNat p₁ = []⊢ FieldItem.extra t₁ (PbValue.unknown wt₁ p₁) kp₁ vp₁ = FieldItem.known t₂ kp₂ vp₂extra.unknown.extra.varint x:TrWireHeaderDatay:TrWireHeaderDatahcode:x.code = y.codemap_bv:∀ {l₁ l₂ : List (BitVec 8)}, List.map BitVec.toNat l₁ = List.map BitVec.toNat l₂ → l₁ = l₂t₁:Natkp₁:Natvp₁:Natwt₁:Natp₁:List (BitVec 8)t₂:Natkp₂:Natvp₂:Natn₂:Nathi:3 = 1 ∧ t₁ = t₂ ∧ kp₁ = kp₂ ∧ vp₁ = vp₂ ∧ wt₁ = n₂ ∧ List.map BitVec.toNat p₁ = []⊢ FieldItem.extra t₁ (PbValue.unknown wt₁ p₁) kp₁ vp₁ = FieldItem.extra t₂ (PbValue.varint n₂) kp₂ vp₂extra.unknown.extra.bytes x:TrWireHeaderDatay:TrWireHeaderDatahcode:x.code = y.codemap_bv:∀ {l₁ l₂ : List (BitVec 8)}, List.map BitVec.toNat l₁ = List.map BitVec.toNat l₂ → l₁ = l₂t₁:Natkp₁:Natvp₁:Natwt₁:Natp₁:List (BitVec 8)t₂:Natkp₂:Natvp₂:Natb₂:List (BitVec 8)hi:3 = 2 ∧ t₁ = t₂ ∧ kp₁ = kp₂ ∧ vp₁ = vp₂ ∧ wt₁ :: List.map BitVec.toNat p₁ = List.map BitVec.toNat b₂⊢ FieldItem.extra t₁ (PbValue.unknown wt₁ p₁) kp₁ vp₁ = FieldItem.extra t₂ (PbValue.bytes b₂) kp₂ vp₂extra.unknown.extra.unknown x:TrWireHeaderDatay:TrWireHeaderDatahcode:x.code = y.codemap_bv:∀ {l₁ l₂ : List (BitVec 8)}, List.map BitVec.toNat l₁ = List.map BitVec.toNat l₂ → l₁ = l₂t₁:Natkp₁:Natvp₁:Natwt₁:Natp₁:List (BitVec 8)t₂:Natkp₂:Natvp₂:Natwt₂:Natp₂:List (BitVec 8)hi:True ∧ t₁ = t₂ ∧ kp₁ = kp₂ ∧ vp₁ = vp₂ ∧ wt₁ = wt₂ ∧ List.map BitVec.toNat p₁ = List.map BitVec.toNat p₂⊢ FieldItem.extra t₁ (PbValue.unknown wt₁ p₁) kp₁ vp₁ = FieldItem.extra t₂ (PbValue.unknown wt₂ p₂) kp₂ vp₂ grind x:TrWireHeaderDatay:TrWireHeaderDatahcode:x.code = y.codemap_bv:∀ {l₁ l₂ : List (BitVec 8)}, List.map BitVec.toNat l₁ = List.map BitVec.toNat l₂ → l₁ = l₂item_inj:∀ {a b : FieldItem}, a.toNats = b.toNats → a = b⊢ x = y
have map_item : ∀ {l₁ l₂ : List FieldItem},
l₁.map FieldItem.toNats = l₂.map FieldItem.toNats → l₁ = l₂ := by
intro l₁ x:TrWireHeaderDatay:TrWireHeaderDatahcode:x.code = y.codemap_bv:∀ {l₁ l₂ : List (BitVec 8)}, List.map BitVec.toNat l₁ = List.map BitVec.toNat l₂ → l₁ = l₂item_inj:∀ {a b : FieldItem}, a.toNats = b.toNats → a = bl₁:List FieldItem⊢ ∀ {l₂ : List FieldItem}, List.map FieldItem.toNats l₁ = List.map FieldItem.toNats l₂ → l₁ = l₂; induction l₁ with
| nil => nil x:TrWireHeaderDatay:TrWireHeaderDatahcode:x.code = y.codemap_bv:∀ {l₁ l₂ : List (BitVec 8)}, List.map BitVec.toNat l₁ = List.map BitVec.toNat l₂ → l₁ = l₂item_inj:∀ {a b : FieldItem}, a.toNats = b.toNats → a = b⊢ ∀ {l₂ : List FieldItem}, List.map FieldItem.toNats [] = List.map FieldItem.toNats l₂ → [] = l₂ intro l₂ hm nil x:TrWireHeaderDatay:TrWireHeaderDatahcode:x.code = y.codemap_bv:∀ {l₁ l₂ : List (BitVec 8)}, List.map BitVec.toNat l₁ = List.map BitVec.toNat l₂ → l₁ = l₂item_inj:∀ {a b : FieldItem}, a.toNats = b.toNats → a = bl₂:List FieldItemhm:List.map FieldItem.toNats [] = List.map FieldItem.toNats l₂⊢ [] = l₂; cases l₂ nil.nil x:TrWireHeaderDatay:TrWireHeaderDatahcode:x.code = y.codemap_bv:∀ {l₁ l₂ : List (BitVec 8)}, List.map BitVec.toNat l₁ = List.map BitVec.toNat l₂ → l₁ = l₂item_inj:∀ {a b : FieldItem}, a.toNats = b.toNats → a = bhm:List.map FieldItem.toNats [] = List.map FieldItem.toNats []⊢ [] = []nil.cons x:TrWireHeaderDatay:TrWireHeaderDatahcode:x.code = y.codemap_bv:∀ {l₁ l₂ : List (BitVec 8)}, List.map BitVec.toNat l₁ = List.map BitVec.toNat l₂ → l₁ = l₂item_inj:∀ {a b : FieldItem}, a.toNats = b.toNats → a = bhead✝:FieldItemtail✝:List FieldItemhm:List.map FieldItem.toNats [] = List.map FieldItem.toNats (head✝ :: tail✝)⊢ [] = head✝ :: tail✝ <;> nil.nil x:TrWireHeaderDatay:TrWireHeaderDatahcode:x.code = y.codemap_bv:∀ {l₁ l₂ : List (BitVec 8)}, List.map BitVec.toNat l₁ = List.map BitVec.toNat l₂ → l₁ = l₂item_inj:∀ {a b : FieldItem}, a.toNats = b.toNats → a = bhm:List.map FieldItem.toNats [] = List.map FieldItem.toNats []⊢ [] = []nil.cons x:TrWireHeaderDatay:TrWireHeaderDatahcode:x.code = y.codemap_bv:∀ {l₁ l₂ : List (BitVec 8)}, List.map BitVec.toNat l₁ = List.map BitVec.toNat l₂ → l₁ = l₂item_inj:∀ {a b : FieldItem}, a.toNats = b.toNats → a = bhead✝:FieldItemtail✝:List FieldItemhm:List.map FieldItem.toNats [] = List.map FieldItem.toNats (head✝ :: tail✝)⊢ [] = head✝ :: tail✝ simp at hm ⊢ All goals completed! 🐙
| cons a as ih => cons x:TrWireHeaderDatay:TrWireHeaderDatahcode:x.code = y.codemap_bv:∀ {l₁ l₂ : List (BitVec 8)}, List.map BitVec.toNat l₁ = List.map BitVec.toNat l₂ → l₁ = l₂item_inj:∀ {a b : FieldItem}, a.toNats = b.toNats → a = ba:FieldItemas:List FieldItemih:∀ {l₂ : List FieldItem}, List.map FieldItem.toNats as = List.map FieldItem.toNats l₂ → as = l₂⊢ ∀ {l₂ : List FieldItem}, List.map FieldItem.toNats (a :: as) = List.map FieldItem.toNats l₂ → a :: as = l₂
intro l₂ hm cons x:TrWireHeaderDatay:TrWireHeaderDatahcode:x.code = y.codemap_bv:∀ {l₁ l₂ : List (BitVec 8)}, List.map BitVec.toNat l₁ = List.map BitVec.toNat l₂ → l₁ = l₂item_inj:∀ {a b : FieldItem}, a.toNats = b.toNats → a = ba:FieldItemas:List FieldItemih:∀ {l₂ : List FieldItem}, List.map FieldItem.toNats as = List.map FieldItem.toNats l₂ → as = l₂l₂:List FieldItemhm:List.map FieldItem.toNats (a :: as) = List.map FieldItem.toNats l₂⊢ a :: as = l₂; cases l₂ with
| nil => cons.nil x:TrWireHeaderDatay:TrWireHeaderDatahcode:x.code = y.codemap_bv:∀ {l₁ l₂ : List (BitVec 8)}, List.map BitVec.toNat l₁ = List.map BitVec.toNat l₂ → l₁ = l₂item_inj:∀ {a b : FieldItem}, a.toNats = b.toNats → a = ba:FieldItemas:List FieldItemih:∀ {l₂ : List FieldItem}, List.map FieldItem.toNats as = List.map FieldItem.toNats l₂ → as = l₂hm:List.map FieldItem.toNats (a :: as) = List.map FieldItem.toNats []⊢ a :: as = [] simp at hm All goals completed! 🐙
| cons b bs => cons.cons x:TrWireHeaderDatay:TrWireHeaderDatahcode:x.code = y.codemap_bv:∀ {l₁ l₂ : List (BitVec 8)}, List.map BitVec.toNat l₁ = List.map BitVec.toNat l₂ → l₁ = l₂item_inj:∀ {a b : FieldItem}, a.toNats = b.toNats → a = ba:FieldItemas:List FieldItemih:∀ {l₂ : List FieldItem}, List.map FieldItem.toNats as = List.map FieldItem.toNats l₂ → as = l₂b:FieldItembs:List FieldItemhm:List.map FieldItem.toNats (a :: as) = List.map FieldItem.toNats (b :: bs)⊢ a :: as = b :: bs
simp only [List.map, List.cons.injEq] at hm cons.cons x:TrWireHeaderDatay:TrWireHeaderDatahcode:x.code = y.codemap_bv:∀ {l₁ l₂ : List (BitVec 8)}, List.map BitVec.toNat l₁ = List.map BitVec.toNat l₂ → l₁ = l₂item_inj:∀ {a b : FieldItem}, a.toNats = b.toNats → a = ba:FieldItemas:List FieldItemih:∀ {l₂ : List FieldItem}, List.map FieldItem.toNats as = List.map FieldItem.toNats l₂ → as = l₂b:FieldItembs:List FieldItemhm:a.toNats = b.toNats ∧ List.map FieldItem.toNats as = List.map FieldItem.toNats bs⊢ a :: as = b :: bs
rw [item_inj hm.1, cons.cons x:TrWireHeaderDatay:TrWireHeaderDatahcode:x.code = y.codemap_bv:∀ {l₁ l₂ : List (BitVec 8)}, List.map BitVec.toNat l₁ = List.map BitVec.toNat l₂ → l₁ = l₂item_inj:∀ {a b : FieldItem}, a.toNats = b.toNats → a = ba:FieldItemas:List FieldItemih:∀ {l₂ : List FieldItem}, List.map FieldItem.toNats as = List.map FieldItem.toNats l₂ → as = l₂b:FieldItembs:List FieldItemhm:a.toNats = b.toNats ∧ List.map FieldItem.toNats as = List.map FieldItem.toNats bs⊢ b :: as = b :: bs ih hm.2 cons.cons x:TrWireHeaderDatay:TrWireHeaderDatahcode:x.code = y.codemap_bv:∀ {l₁ l₂ : List (BitVec 8)}, List.map BitVec.toNat l₁ = List.map BitVec.toNat l₂ → l₁ = l₂item_inj:∀ {a b : FieldItem}, a.toNats = b.toNats → a = ba:FieldItemas:List FieldItemih:∀ {l₂ : List FieldItem}, List.map FieldItem.toNats as = List.map FieldItem.toNats l₂ → as = l₂b:FieldItembs:List FieldItemhm:a.toNats = b.toNats ∧ List.map FieldItem.toNats as = List.map FieldItem.toNats bs⊢ b :: bs = b :: bs] x:TrWireHeaderDatay:TrWireHeaderDatahcode:x.code = y.codemap_bv:∀ {l₁ l₂ : List (BitVec 8)}, List.map BitVec.toNat l₁ = List.map BitVec.toNat l₂ → l₁ = l₂item_inj:∀ {a b : FieldItem}, a.toNats = b.toNats → a = bmap_item:∀ {l₁ l₂ : List FieldItem}, List.map FieldItem.toNats l₁ = List.map FieldItem.toNats l₂ → l₁ = l₂⊢ x = y
rcases x with ⟨v₁, c₁, pc₁, ⟨low₁, tr₁, ch₁, pch₁, fs₁⟩⟩ y:TrWireHeaderDatamap_bv:∀ {l₁ l₂ : List (BitVec 8)}, List.map BitVec.toNat l₁ = List.map BitVec.toNat l₂ → l₁ = l₂item_inj:∀ {a b : FieldItem}, a.toNats = b.toNats → a = bmap_item:∀ {l₁ l₂ : List FieldItem}, List.map FieldItem.toNats l₁ = List.map FieldItem.toNats l₂ → l₁ = l₂v₁:UInt8c₁:UInt32pc₁:UInt32low₁:Nattr₁:List (BitVec 8)ch₁:Natpch₁:Natfs₁:List FieldItemhcode:TrWireHeaderData.code
(v₁, c₁, pc₁,
{ versionLowNibble := low₁, ratchetKeyTrailingBytes := tr₁, counterHigh := ch₁, previousCounterHigh := pch₁,
fields := fs₁ }) =
y.code⊢ (v₁, c₁, pc₁,
{ versionLowNibble := low₁, ratchetKeyTrailingBytes := tr₁, counterHigh := ch₁, previousCounterHigh := pch₁,
fields := fs₁ }) =
y
rcases y with ⟨v₂, c₂, pc₂, ⟨low₂, tr₂, ch₂, pch₂, fs₂⟩⟩ map_bv:∀ {l₁ l₂ : List (BitVec 8)}, List.map BitVec.toNat l₁ = List.map BitVec.toNat l₂ → l₁ = l₂item_inj:∀ {a b : FieldItem}, a.toNats = b.toNats → a = bmap_item:∀ {l₁ l₂ : List FieldItem}, List.map FieldItem.toNats l₁ = List.map FieldItem.toNats l₂ → l₁ = l₂v₁:UInt8c₁:UInt32pc₁:UInt32low₁:Nattr₁:List (BitVec 8)ch₁:Natpch₁:Natfs₁:List FieldItemv₂:UInt8c₂:UInt32pc₂:UInt32low₂:Nattr₂:List (BitVec 8)ch₂:Natpch₂:Natfs₂:List FieldItemhcode:TrWireHeaderData.code
(v₁, c₁, pc₁,
{ versionLowNibble := low₁, ratchetKeyTrailingBytes := tr₁, counterHigh := ch₁, previousCounterHigh := pch₁,
fields := fs₁ }) =
TrWireHeaderData.code
(v₂, c₂, pc₂,
{ versionLowNibble := low₂, ratchetKeyTrailingBytes := tr₂, counterHigh := ch₂, previousCounterHigh := pch₂,
fields := fs₂ })⊢ (v₁, c₁, pc₁,
{ versionLowNibble := low₁, ratchetKeyTrailingBytes := tr₁, counterHigh := ch₁, previousCounterHigh := pch₁,
fields := fs₁ }) =
(v₂, c₂, pc₂,
{ versionLowNibble := low₂, ratchetKeyTrailingBytes := tr₂, counterHigh := ch₂, previousCounterHigh := pch₂,
fields := fs₂ })
simp only [TrWireHeaderData.code, List.cons.injEq, and_true] at hcode map_bv:∀ {l₁ l₂ : List (BitVec 8)}, List.map BitVec.toNat l₁ = List.map BitVec.toNat l₂ → l₁ = l₂item_inj:∀ {a b : FieldItem}, a.toNats = b.toNats → a = bmap_item:∀ {l₁ l₂ : List FieldItem}, List.map FieldItem.toNats l₁ = List.map FieldItem.toNats l₂ → l₁ = l₂v₁:UInt8c₁:UInt32pc₁:UInt32low₁:Nattr₁:List (BitVec 8)ch₁:Natpch₁:Natfs₁:List FieldItemv₂:UInt8c₂:UInt32pc₂:UInt32low₂:Nattr₂:List (BitVec 8)ch₂:Natpch₂:Natfs₂:List FieldItemhcode:(v₁.toNat = v₂.toNat ∧ c₁.toNat = c₂.toNat ∧ pc₁.toNat = pc₂.toNat ∧ low₁ = low₂ ∧ ch₁ = ch₂ ∧ pch₁ = pch₂) ∧
List.map BitVec.toNat tr₁ = List.map BitVec.toNat tr₂ ∧ List.map FieldItem.toNats fs₁ = List.map FieldItem.toNats fs₂⊢ (v₁, c₁, pc₁,
{ versionLowNibble := low₁, ratchetKeyTrailingBytes := tr₁, counterHigh := ch₁, previousCounterHigh := pch₁,
fields := fs₁ }) =
(v₂, c₂, pc₂,
{ versionLowNibble := low₂, ratchetKeyTrailingBytes := tr₂, counterHigh := ch₂, previousCounterHigh := pch₂,
fields := fs₂ })
obtain ⟨⟨hv, hc, hpc, rfl, rfl, rfl⟩, htr, hfs⟩ := hcode map_bv:∀ {l₁ l₂ : List (BitVec 8)}, List.map BitVec.toNat l₁ = List.map BitVec.toNat l₂ → l₁ = l₂item_inj:∀ {a b : FieldItem}, a.toNats = b.toNats → a = bmap_item:∀ {l₁ l₂ : List FieldItem}, List.map FieldItem.toNats l₁ = List.map FieldItem.toNats l₂ → l₁ = l₂v₁:UInt8c₁:UInt32pc₁:UInt32low₁:Nattr₁:List (BitVec 8)ch₁:Natpch₁:Natfs₁:List FieldItemv₂:UInt8c₂:UInt32pc₂:UInt32tr₂:List (BitVec 8)fs₂:List FieldItemhv:v₁.toNat = v₂.toNathc:c₁.toNat = c₂.toNathpc:pc₁.toNat = pc₂.toNathtr:List.map BitVec.toNat tr₁ = List.map BitVec.toNat tr₂hfs:List.map FieldItem.toNats fs₁ = List.map FieldItem.toNats fs₂⊢ (v₁, c₁, pc₁,
{ versionLowNibble := low₁, ratchetKeyTrailingBytes := tr₁, counterHigh := ch₁, previousCounterHigh := pch₁,
fields := fs₁ }) =
(v₂, c₂, pc₂,
{ versionLowNibble := low₁, ratchetKeyTrailingBytes := tr₂, counterHigh := ch₁, previousCounterHigh := pch₁,
fields := fs₂ })
rw [UInt8.eq_of_toBitVec_eq (BitVec.eq_of_toNat_eq hv), map_bv:∀ {l₁ l₂ : List (BitVec 8)}, List.map BitVec.toNat l₁ = List.map BitVec.toNat l₂ → l₁ = l₂item_inj:∀ {a b : FieldItem}, a.toNats = b.toNats → a = bmap_item:∀ {l₁ l₂ : List FieldItem}, List.map FieldItem.toNats l₁ = List.map FieldItem.toNats l₂ → l₁ = l₂v₁:UInt8c₁:UInt32pc₁:UInt32low₁:Nattr₁:List (BitVec 8)ch₁:Natpch₁:Natfs₁:List FieldItemv₂:UInt8c₂:UInt32pc₂:UInt32tr₂:List (BitVec 8)fs₂:List FieldItemhv:v₁.toNat = v₂.toNathc:c₁.toNat = c₂.toNathpc:pc₁.toNat = pc₂.toNathtr:List.map BitVec.toNat tr₁ = List.map BitVec.toNat tr₂hfs:List.map FieldItem.toNats fs₁ = List.map FieldItem.toNats fs₂⊢ (v₂, c₁, pc₁,
{ versionLowNibble := low₁, ratchetKeyTrailingBytes := tr₁, counterHigh := ch₁, previousCounterHigh := pch₁,
fields := fs₁ }) =
(v₂, c₂, pc₂,
{ versionLowNibble := low₁, ratchetKeyTrailingBytes := tr₂, counterHigh := ch₁, previousCounterHigh := pch₁,
fields := fs₂ })
UInt32.eq_of_toBitVec_eq (BitVec.eq_of_toNat_eq hc), map_bv:∀ {l₁ l₂ : List (BitVec 8)}, List.map BitVec.toNat l₁ = List.map BitVec.toNat l₂ → l₁ = l₂item_inj:∀ {a b : FieldItem}, a.toNats = b.toNats → a = bmap_item:∀ {l₁ l₂ : List FieldItem}, List.map FieldItem.toNats l₁ = List.map FieldItem.toNats l₂ → l₁ = l₂v₁:UInt8c₁:UInt32pc₁:UInt32low₁:Nattr₁:List (BitVec 8)ch₁:Natpch₁:Natfs₁:List FieldItemv₂:UInt8c₂:UInt32pc₂:UInt32tr₂:List (BitVec 8)fs₂:List FieldItemhv:v₁.toNat = v₂.toNathc:c₁.toNat = c₂.toNathpc:pc₁.toNat = pc₂.toNathtr:List.map BitVec.toNat tr₁ = List.map BitVec.toNat tr₂hfs:List.map FieldItem.toNats fs₁ = List.map FieldItem.toNats fs₂⊢ (v₂, c₂, pc₁,
{ versionLowNibble := low₁, ratchetKeyTrailingBytes := tr₁, counterHigh := ch₁, previousCounterHigh := pch₁,
fields := fs₁ }) =
(v₂, c₂, pc₂,
{ versionLowNibble := low₁, ratchetKeyTrailingBytes := tr₂, counterHigh := ch₁, previousCounterHigh := pch₁,
fields := fs₂ })
UInt32.eq_of_toBitVec_eq (BitVec.eq_of_toNat_eq hpc), map_bv:∀ {l₁ l₂ : List (BitVec 8)}, List.map BitVec.toNat l₁ = List.map BitVec.toNat l₂ → l₁ = l₂item_inj:∀ {a b : FieldItem}, a.toNats = b.toNats → a = bmap_item:∀ {l₁ l₂ : List FieldItem}, List.map FieldItem.toNats l₁ = List.map FieldItem.toNats l₂ → l₁ = l₂v₁:UInt8c₁:UInt32pc₁:UInt32low₁:Nattr₁:List (BitVec 8)ch₁:Natpch₁:Natfs₁:List FieldItemv₂:UInt8c₂:UInt32pc₂:UInt32tr₂:List (BitVec 8)fs₂:List FieldItemhv:v₁.toNat = v₂.toNathc:c₁.toNat = c₂.toNathpc:pc₁.toNat = pc₂.toNathtr:List.map BitVec.toNat tr₁ = List.map BitVec.toNat tr₂hfs:List.map FieldItem.toNats fs₁ = List.map FieldItem.toNats fs₂⊢ (v₂, c₂, pc₂,
{ versionLowNibble := low₁, ratchetKeyTrailingBytes := tr₁, counterHigh := ch₁, previousCounterHigh := pch₁,
fields := fs₁ }) =
(v₂, c₂, pc₂,
{ versionLowNibble := low₁, ratchetKeyTrailingBytes := tr₂, counterHigh := ch₁, previousCounterHigh := pch₁,
fields := fs₂ })
map_bv htr, map_bv:∀ {l₁ l₂ : List (BitVec 8)}, List.map BitVec.toNat l₁ = List.map BitVec.toNat l₂ → l₁ = l₂item_inj:∀ {a b : FieldItem}, a.toNats = b.toNats → a = bmap_item:∀ {l₁ l₂ : List FieldItem}, List.map FieldItem.toNats l₁ = List.map FieldItem.toNats l₂ → l₁ = l₂v₁:UInt8c₁:UInt32pc₁:UInt32low₁:Nattr₁:List (BitVec 8)ch₁:Natpch₁:Natfs₁:List FieldItemv₂:UInt8c₂:UInt32pc₂:UInt32tr₂:List (BitVec 8)fs₂:List FieldItemhv:v₁.toNat = v₂.toNathc:c₁.toNat = c₂.toNathpc:pc₁.toNat = pc₂.toNathtr:List.map BitVec.toNat tr₁ = List.map BitVec.toNat tr₂hfs:List.map FieldItem.toNats fs₁ = List.map FieldItem.toNats fs₂⊢ (v₂, c₂, pc₂,
{ versionLowNibble := low₁, ratchetKeyTrailingBytes := tr₂, counterHigh := ch₁, previousCounterHigh := pch₁,
fields := fs₁ }) =
(v₂, c₂, pc₂,
{ versionLowNibble := low₁, ratchetKeyTrailingBytes := tr₂, counterHigh := ch₁, previousCounterHigh := pch₁,
fields := fs₂ }) map_item hfs map_bv:∀ {l₁ l₂ : List (BitVec 8)}, List.map BitVec.toNat l₁ = List.map BitVec.toNat l₂ → l₁ = l₂item_inj:∀ {a b : FieldItem}, a.toNats = b.toNats → a = bmap_item:∀ {l₁ l₂ : List FieldItem}, List.map FieldItem.toNats l₁ = List.map FieldItem.toNats l₂ → l₁ = l₂v₁:UInt8c₁:UInt32pc₁:UInt32low₁:Nattr₁:List (BitVec 8)ch₁:Natpch₁:Natfs₁:List FieldItemv₂:UInt8c₂:UInt32pc₂:UInt32tr₂:List (BitVec 8)fs₂:List FieldItemhv:v₁.toNat = v₂.toNathc:c₁.toNat = c₂.toNathpc:pc₁.toNat = pc₂.toNathtr:List.map BitVec.toNat tr₁ = List.map BitVec.toNat tr₂hfs:List.map FieldItem.toNats fs₁ = List.map FieldItem.toNats fs₂⊢ (v₂, c₂, pc₂,
{ versionLowNibble := low₁, ratchetKeyTrailingBytes := tr₂, counterHigh := ch₁, previousCounterHigh := pch₁,
fields := fs₂ }) =
(v₂, c₂, pc₂,
{ versionLowNibble := low₁, ratchetKeyTrailingBytes := tr₂, counterHigh := ch₁, previousCounterHigh := pch₁,
fields := fs₂ })] All goals completed! 🐙)
(fun x => (x.version, x.counter, x.previousCounter, x.encodingVariation))
SubF.senderRatchetKey SubF.ciphertext SubF.pqRatchet
(fun d rk ct pq =>
{ version := d.1, senderRatchetKey := rk, counter := d.2.1, previousCounter := d.2.2.1,
ciphertext := ct, pqRatchet := pq, encodingVariation := d.2.2.2 })
def SubF.
@[expose] public
def SubF.length [BytesFunctor]: Bytes.PartialLength SubF :=
fun ⟨_, rk, _, _, ct, pq, _⟩ rec => 1 + rec rk + 4 + 4 + rec ct + rec pqend TrWireMsg#combine
#combine into BytesFunctor, BytesLength from
TrWireMsg,variable [BytesFunctor] [BytesFunctor.Has SubF]
abbrev TrWireMsg.
public
abbrev TrWireMsg.SubF.pack (x: TrWireMsg.SubF Bytes) := BytesView.pack xinstance
public
instance: CanTrWireMsg Bytes where
trWireMsg version senderRatchetKey counter previousCounter ciphertext pqRatchet
encodingVariation :=
({version, senderRatchetKey, counter, previousCounter, ciphertext, pqRatchet,
encodingVariation}: TrWireMsg.SubF Bytes).packdef trWireMsgFields?
@[expose] public
def trWireMsgFields? (b: Bytes): Option (TrWireMsg.SubF Bytes) := b.view? TrWireMsg.SubF
def trWireMsg.
@[expose] public
def trWireMsg.attackerKnowledge: SubAttackerKnowledge SubF where
pred p out :=
∃ x: TrWireMsg.SubF Bytes,
out = x.pack ∧ p x.senderRatchetKey ∧ p x.ciphertext ∧ p x.pqRatchet
def trWireMsgArg.
@[expose] public
def trWireMsgArg.attackerKnowledge: SubAttackerKnowledge SubF where
pred p out :=
∃ x: TrWireMsg.SubF Bytes,
p x.pack ∧ (out = x.senderRatchetKey ∨ out = x.ciphertext ∨ out = x.pqRatchet)#combine
#combine [BytesFunctor.Has SubF] into attackerKnowledge' from
trWireMsg,
trWireMsgArg,end DY.TrWire