Documentation

Cryptlib.Protocols.Pigeonhole.Replica

Pigeonhole replica #

A replica stores, per box ID (a public key), a payload and a signature over it under that key. Requests are handled by the state machine step:

Not modelled: storage failures, read repair, epochs.

A stored payload and its signature. An empty payload is a tombstone.

Instances For
    Equations
    Instances For

      A request as the replica receives it, after MKEM decryption.

      Instances For

        Reply result codes.

        Instances For
          Instances For

            Handle one request. boxSize is the required payload length.

            Equations
            • One or more equations did not get rendered due to their size.
            Instances For

              Every stored box verifies under its own ID.

              Equations
              Instances For

                Every request preserves Valid.

                theorem Cryptlib.Protocols.Pigeonhole.Replica.write_success_verifies {Sg : Primitives.Sign.Sign.Signature} [DecidableEq Sg.PublicKey] (boxSize : Nat) (s : Store Sg) (id : Sg.PublicKey) (payload : ByteArray) (sig : Sg.Sig) (h : (step boxSize s (Request.write id payload sig)).snd = Reply.writeReply Code.success) :
                Sg.verify id (if payload.size = 0 then ByteArray.empty else payload) sig = true

                An accepted write's signature verifies under the box ID.

                theorem Cryptlib.Protocols.Pigeonhole.Replica.step_write_cases {Sg : Primitives.Sign.Sign.Signature} [DecidableEq Sg.PublicKey] (boxSize : Nat) (s : Store Sg) (id : Sg.PublicKey) (payload : ByteArray) (sig : Sg.Sig) :
                (step boxSize s (Request.write id payload sig)).fst = s ∨ ∃ (e : Entry Sg), (step boxSize s (Request.write id payload sig)).fst = s.put id e ∧ Sg.verify id (if payload.size = 0 then ByteArray.empty else payload) sig = true

                A write leaves the store unchanged, or stores a verified entry under its box ID.

                theorem Cryptlib.Protocols.Pigeonhole.Replica.write_fresh {Sg : Primitives.Sign.Sign.Signature} [DecidableEq Sg.PublicKey] (boxSize : Nat) (s : Store Sg) (id : Sg.PublicKey) (payload : ByteArray) (sig : Sg.Sig) (hne : payload.size ≠ 0) (hsz : payload.size = boxSize) (hv : Sg.verify id payload sig = true) (hfree : s id = none) :
                step boxSize s (Request.write id payload sig) = (s.put id { payload := payload, sig := sig }, Reply.writeReply Code.success)

                A well-formed, correctly signed write to a free box is accepted and stores the box.

                theorem Cryptlib.Protocols.Pigeonhole.Replica.write_existing {Sg : Primitives.Sign.Sign.Signature} [DecidableEq Sg.PublicKey] (boxSize : Nat) (s : Store Sg) (id : Sg.PublicKey) (payload : ByteArray) (sig : Sg.Sig) (hne : payload.size ≠ 0) (hsz : payload.size = boxSize) (hv : Sg.verify id payload sig = true) (e : Entry Sg) (hex : s id = some e) :

                A non-empty write to an existing box is refused and changes nothing.

                A read leaves the store unchanged and returns the stored entry.

                theorem Cryptlib.Protocols.Pigeonhole.Replica.read_after_write {Sg : Primitives.Sign.Sign.Signature} [DecidableEq Sg.PublicKey] (boxSize : Nat) (s : Store Sg) (id : Sg.PublicKey) (payload : ByteArray) (sig : Sg.Sig) (hne : payload.size ≠ 0) :
                (step boxSize (s.put id { payload := payload, sig := sig }) (Request.read id)).snd = Reply.readReply Code.success (some { payload := payload, sig := sig })

                Reading a box just written returns what was written.

                theorem Cryptlib.Protocols.Pigeonhole.Replica.tombstone_then_read {Sg : Primitives.Sign.Sign.Signature} [DecidableEq Sg.PublicKey] (boxSize : Nat) (s : Store Sg) (id : Sg.PublicKey) (sig : Sg.Sig) (hv : Sg.verify id ByteArray.empty sig = true) :
                step boxSize s (Request.write id ByteArray.empty sig) = (s.put id { payload := ByteArray.empty, sig := sig }, Reply.writeReply Code.success) ∧ (step boxSize (s.put id { payload := ByteArray.empty, sig := sig }) (Request.read id)).snd = Reply.readReply Code.tombstone (some { payload := ByteArray.empty, sig := sig })

                A signed tombstone replaces the box; a read then reports a tombstone.

                theorem Cryptlib.Protocols.Pigeonhole.Replica.step_frame {Sg : Primitives.Sign.Sign.Signature} [DecidableEq Sg.PublicKey] (boxSize : Nat) (s : Store Sg) (r : Request Sg) (x : Sg.PublicKey) (h : (step boxSize s r).fst x ≠ s x) :
                ∃ (payload : ByteArray), ∃ (sig : Sg.Sig), r = Request.write x payload sig ∧ Sg.verify x (if payload.size = 0 then ByteArray.empty else payload) sig = true

                A request that changes the entry at x is a write to x whose signature verifies.