Documentation

GaudisCrypt.Examples.Pedersen.Pedersen

The Pedersen commitment scheme #

A transliteration of EasyCrypt's examples/Pedersen.ec:

The group setup (EC's DLog clone) #

A cyclic group G with generator g and exponent type F (EC's group/exp). Multiplication and exponentiation, what the programs genuinely need of the types — a default element (Inhabited, so local variables can be declared) and Fintype F (real content: SubProbability.uniform samples it, and the wp lemmas sum over it) — and the algebraic laws the proofs need, which are the three fields documented individually below. Correctness needs none of the laws; they are all for Hiding.lean.

Decidable equality is not a field. verify does compare ($c == $c'), and == is BEq derived from DecidableEq — but these programs are never executed: every proc is noncomputable and the semantics is a measure, so the comparison only ever has to denote a Bool, not compute one. Classical.decEq supplies that for free, which is why the instances below are classical and the class is two fields shorter. Nothing in the proofs cares: they reason about =, and beq_self_eq_true and friends hold for any DecidableEq witness.

  • G : Type
  • F : Type
  • g : self.G
  • gmul : self.G → self.G → self.G
  • gpow : self.G → self.F → self.G
  • g_inhabited : Inhabited self.G
  • f_inhabited : Inhabited self.F
  • f_fintype : Fintype self.F
  • f_commring : CommRing self.F

    EC's exponent type is the prime field DL.GP.ZModE; the hiding proof forms d + x * m and its inverse d - x * m, so the additive group and the multiplication are both needed. (Only the ring structure is required — nothing here uses inverses.)

  • gpow_add (h : self.G) (a b : self.F) : self.gpow h (a + b) = self.gmul (self.gpow h a) (self.gpow h b)

    EC's expD: exponentiation turns addition into multiplication.

  • gpow_mul (h : self.G) (a b : self.F) : self.gpow (self.gpow h a) b = self.gpow h (a * b)

    EC's expM: iterated exponentiation multiplies the exponents.

Instances For
    @[reducible]
    Equations
    @[reducible]
    Equations
    theorem GaudisCrypt.Examples.Pedersen.pow_add (group : PedersenGroup) (h : group.G) (a b : group.F) :
    h ^ (a + b) = h ^ a * h ^ b

    gpow_add at the ^/* notation. The class fields have to be stated with the raw gmul/gpow (the instances below them do not exist yet), but every use site sees the notation, and rw matches on the notation's head — not the raw field.

    theorem GaudisCrypt.Examples.Pedersen.pow_mul (group : PedersenGroup) (h : group.G) (a b : group.F) :
    (h ^ a) ^ b = h ^ (a * b)

    gpow_mul at the ^ notation.

    @[reducible]

    EC's PedersenTypes + clone Commitment with …: value/commitment are group elements, message/openingkey are exponents.

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

      The scheme #

      EC's

      module Pedersen : CommitmentScheme = {
        proc gen() : value                = { x <$ dt; h <- g ^ x; return h; }
        proc commit(h, m)                 = { d <$ dt; c <- (g ^ d) * (h ^ m); return (c, d); }
        proc verify(h, m, c, d)           = { c' <- (g ^ d) * (h ^ m); return (c = c'); }
      }.
      

      transcribes directly with the module command. It declares, per procedure f, both the body Pedersen.f.procedure and the module Pedersen.f : Module.Proc …, and assembles them into Pedersen : CommitmentScheme with CommitmentScheme.mk (the field names match the moduletype's, so the record constructor is used rather than a nest of Module.pairs). Pedersen has no module parameters, so it is the scheme — there is nothing to apply it to, and hence no Pedersen.apply_simp.

      theorem GaudisCrypt.Examples.Pedersen.Pedersen.commit.procedure.apply_simp (group : PedersenGroup) (holeArgs✝ : HoleSigs.empty.Instantiation) :
      (procedure group).instantiate holeArgs✝ = proc (h : group.G, m : group.F) : (group.G × group.F) { var d : group.F, c : group.G; d <$ SubProbability.uniform; c <- group.g ^ §d * §h ^ §m; return (§c, §d) }

      Instantiating the holes of Pedersen.commit.procedure with a tuple holeArgs of procedures: the body of proc commit as written, with each hole call replaced by the matching holeArgs.lookup (HoleIndex.zero being the first hole the body declared). True by rfl.

      Deliberately not @[simp], unlike the other apply_simp lemmas: its right-hand side is the whole body written out, so letting it fire on its own would turn any goal mentioning an instantiated procedure into that body. Inlining a procedure is a step to ask for by name (simp [Pedersen.commit.procedure.apply_simp]).

      theorem GaudisCrypt.Examples.Pedersen.Pedersen.verify.procedure.apply_simp (group : PedersenGroup) (holeArgs✝ : HoleSigs.empty.Instantiation) :
      (procedure group).instantiate holeArgs✝ = proc (h : group.G, m : group.F, c : group.G, d : group.F) : Bool { var c' : group.G; c' <- group.g ^ §d * §h ^ §m; return §c == §c' }

      Instantiating the holes of Pedersen.verify.procedure with a tuple holeArgs of procedures: the body of proc verify as written, with each hole call replaced by the matching holeArgs.lookup (HoleIndex.zero being the first hole the body declared). True by rfl.

      Deliberately not @[simp], unlike the other apply_simp lemmas: its right-hand side is the whole body written out, so letting it fire on its own would turn any goal mentioning an instantiated procedure into that body. Inlining a procedure is a step to ask for by name (simp [Pedersen.verify.procedure.apply_simp]).

      noncomputable def GaudisCrypt.Examples.Pedersen.Pedersen.commit.procedure (group : PedersenGroup) :
      proctype (group.G, group.F) -> group.G × group.F

      The body of proc commit of module Pedersen, as a procedure of its own: it calls no module parameter, so it has no holes.

      A hole stands for a call whose callee is not known here — a module parameter is supplied only when the module is applied — so the body is a ProcedureWithHoles, to be instantiated (see Pedersen.commit.procedure.apply_simp) rather than run. Use Pedersen.commit for this procedure as a module.

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

        The module declared by module Pedersen: the record of its procedures Pedersen.gen, Pedersen.commit, Pedersen.verify.

        The declaration has no parameter list, so no procedure of it can call one either and the module is not a function — it is the plain record itself, and there is no Pedersen.apply_simp to apply it with.

        Equations
        • One or more equations did not get rendered due to their size.
        Instances For
          theorem GaudisCrypt.Examples.Pedersen.Pedersen.gen.procedure.apply_simp (group : PedersenGroup) (holeArgs✝ : HoleSigs.empty.Instantiation) :
          (procedure group).instantiate holeArgs✝ = proc () : group.G { var x : group.F, h : group.G; x <$ SubProbability.uniform; h <- group.g ^ §x; return §h }

          Instantiating the holes of Pedersen.gen.procedure with a tuple holeArgs of procedures: the body of proc gen as written, with each hole call replaced by the matching holeArgs.lookup (HoleIndex.zero being the first hole the body declared). True by rfl.

          Deliberately not @[simp], unlike the other apply_simp lemmas: its right-hand side is the whole body written out, so letting it fire on its own would turn any goal mentioning an instantiated procedure into that body. Inlining a procedure is a step to ask for by name (simp [Pedersen.gen.procedure.apply_simp]).

          noncomputable def GaudisCrypt.Examples.Pedersen.Pedersen.verify.procedure (group : PedersenGroup) :
          proctype (group.G, group.F, group.G, group.F) -> Bool

          The body of proc verify of module Pedersen, as a procedure of its own: it calls no module parameter, so it has no holes.

          A hole stands for a call whose callee is not known here — a module parameter is supplied only when the module is applied — so the body is a ProcedureWithHoles, to be instantiated (see Pedersen.verify.procedure.apply_simp) rather than run. Use Pedersen.verify for this procedure as a module.

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

            @[simp]: Pedersen.gen = Module.proc Pedersen.gen.procedure — true by definition, proc gen using no module parameter and so having no holes to fill.

            noncomputable def GaudisCrypt.Examples.Pedersen.Pedersen.commit (group : PedersenGroup) :
            procmod (group.G, group.F) → (group.G × group.F)

            proc commit of module Pedersen as a module: Module.proc Pedersen.commit.procedure, of type Module.Proc (procsig …). It uses no module parameter, so it is not a function — Pedersen.commit.apply_simp says exactly that.

            Equations
            Instances For
              @[simp]

              @[simp]: Pedersen.commit = Module.proc Pedersen.commit.procedure — true by definition, proc commit using no module parameter and so having no holes to fill.

              noncomputable def GaudisCrypt.Examples.Pedersen.Pedersen.verify (group : PedersenGroup) :
              procmod (group.G, group.F, group.G, group.F) → Bool

              proc verify of module Pedersen as a module: Module.proc Pedersen.verify.procedure, of type Module.Proc (procsig …). It uses no module parameter, so it is not a function — Pedersen.verify.apply_simp says exactly that.

              Equations
              Instances For
                @[simp]

                @[simp]: Pedersen.verify = Module.proc Pedersen.verify.procedure — true by definition, proc verify using no module parameter and so having no holes to fill.

                The body of proc gen of module Pedersen, as a procedure of its own: it calls no module parameter, so it has no holes.

                A hole stands for a call whose callee is not known here — a module parameter is supplied only when the module is applied — so the body is a ProcedureWithHoles, to be instantiated (see Pedersen.gen.procedure.apply_simp) rather than run. Use Pedersen.gen for this procedure as a module.

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

                  proc gen of module Pedersen as a module: Module.proc Pedersen.gen.procedure, of type Module.Proc (procsig …). It uses no module parameter, so it is not a function — Pedersen.gen.apply_simp says exactly that.

                  Equations
                  Instances For
                    theorem GaudisCrypt.Examples.Pedersen.wp_commit (group : PedersenGroup) (args : group.G × group.F) (f : ProgramDenotation.Post VariableAssignment (group.types.Commitment × group.types.OpeningKey)) :
                    (procedureDenotation (Pedersen.commit.procedure group) args).wp f = fun (st : VariableAssignment) => ∑ x : group.F, f ((group.g ^ x * args.1 ^ args.2, x), st) / ↑(Fintype.card group.F)