Documentation

GaudisCrypt.Examples.Pedersen.Commitment

Generic commitment schemes #

A transliteration of EasyCrypt's theories/crypto/Commitment.ec (theory CommitmentProtocol) into the Gaudí module/procedure syntax.

The abstract types of EC's theory CommitmentProtocol: the public value (key), the message space, commitments, and opening keys. Inhabited is needed for program local variables of these types — that one is real content (a default value has to exist).

There is deliberately no DecidableEq here. It was a field (message_deceq), justified by EC's binding experiment comparing m ≠ m', but decidability is never needed for proofs — only to form a Bool-valued program expression via BEq — and no program in this development compares messages, so nothing consumed it. (Commitment never had one either, and that has never been missed.) When BindingExperiment does need m ≠ m', note that these programs are never executed — the semantics is a measure and every proc is noncomputable — so Classical.decEq at the point of use is enough; a class field buys nothing. See Lib/RO/CollisionResistance.lean, which does exactly that.

Instances

    Disjointness of tuple-projection lenses #

    The proc macro binds each local variable to a Lens.id.ofst/.osnd projection chain into the local-state tuple; tuple assignment (c, d <- …) pairs those lenses via Lens.pair, which needs them disjoint. Distinct projection paths are always disjoint, and the instances deriving that (Lens.disjoint_ofst_osnd, Lens.disjoint_chain, …) now live in Language/Lens.lean — the "move them to the proper place" TODO that used to sit here is done, and they are no longer declared in this file.

    ⚠ They still do not make tuple assignment of locals work (re-tested 2026-08-07): the macro binds locals as let-variables, and instance search does not unfold local lets, so disjoint c d is searched at the opaque variables and never reaches these instances.

    Both spellings fail, identically — [lvalRaw|] sends the parenthesised tuple to Lens.pair just as the comma-list does, so there is no way around it by rewriting the assignment:

    c, d   <- call S.commit (…);   -- failed to synthesize instance of type class  disjoint c d
    (c, d) <- call S.commit (…);   -- same
    

    Until the macro binds locals differently (inlining the lens chains, or registering the disjointness facts itself), the experiments below use pair-typed locals and $-projections instead — var cd : Commitment × OpeningKey then ($cd).1/($cd).2.

    Module types #

    module type CommitmentScheme = {
      proc gen() : value
      proc commit(x: value, m: message) : commitment * openingkey
      proc verify(x: value, m: message, c: commitment, d: openingkey) : bool
    }.
    
    Equations
    • One or more equations did not get rendered due to their size.
    Instances For
      Equations
      • One or more equations did not get rendered due to their size.
      Instances For
        Equations
        Instances For
          Equations
          • One or more equations did not get rendered due to their size.
          Instances For
            Equations
            • One or more equations did not get rendered due to their size.
            Instances For
              Equations
              Instances For
                Equations
                • One or more equations did not get rendered due to their size.
                Instances For

                  params and vars are distinct fields of LocalVariableState, so writes through projections of the two commute — no hypothesis on x, y needed.

                  The mirror image of LocalVariableState.disjoint_varsL_paramsL; disjoint.symm is a theorem, not an instance, so search needs both orientations spelled out.

                  instance GaudisCrypt.Examples.Pedersen.Programs.disjoint_intoParams [ProgramSpec] {a b : Type} {paramTypes : List Type} {locals : List ((t : Type) × Inhabited t)} {x : Lens a (paramListToTuple paramTypes)} {y : Lens b (paramListToTuple paramTypes)} [disjoint x y] :

                  Parameter-slot counterpart of Programs.disjoint_intoVars: distinct parameter slots stay disjoint after intoParams (two chain layers).

                  instance GaudisCrypt.Examples.Pedersen.Programs.disjoint_intoVars_intoParams [ProgramSpec] {a b : Type} {paramTypes : List Type} {locals : List ((t : Type) × Inhabited t)} {x : Lens a (paramListToTuple (List.map (fun (x : (t : Type) × Inhabited t) => x.fst) locals))} {y : Lens b (paramListToTuple paramTypes)} :

                  A local variable is disjoint from any parameter: they live in different fields of the scope record, so no disjoint x y hypothesis is required.

                  instance GaudisCrypt.Examples.Pedersen.Programs.disjoint_intoParams_intoVars [ProgramSpec] {a b : Type} {paramTypes : List Type} {locals : List ((t : Type) × Inhabited t)} {x : Lens a (paramListToTuple paramTypes)} {y : Lens b (paramListToTuple (List.map (fun (x : (t : Type) × Inhabited t) => x.fst) locals))} :

                  The other orientation of Programs.disjoint_intoVars_intoParams.

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