Mina中的基于DLG的Plonk polynomial commitment scheme代码解析

1. 引言

Mina中的Pickles->Kimchi方案核心,采用基于DLG假设的类似inner product的多项式承诺方案,详细见:

详细的代码实现见:

mina/src/lib/crypto下代码结构为:

  • kimchi_backend:为 the glue between kimchi and snarky/pickles (TODO: move to a kimchi/ folder)
  • kimchi_bindings:为 the glue between ocaml and kimchi (the proof system in rust) # TODO: rename to kimchi
  • proof-systems:为 a submodule pointing to the Rust implementation of kimchi

1.1 crypto/kimchi_backend

在crypto/kimchi_backend目录下包含了the glue between:

此处主要包括3种转换:

  • 1)底层基础(或非泛型)类型:arkwork types (BigInteger256) 和 mina-curves types (Vesta, Pallas, Fp, Fq).
  • 2)底层通用(或泛型)类型:polynomial commitments (Poly_comm), gates (Gates), 等等,分别对2种曲线进行了实例化(Fq_poly_comm, Fp_poly_comm)。
  • 3)高层类型:描述了constraint system、indexes等等,也分别对2种曲线进行了实例化。

crypto/kimchi_backend总体结构为:

kimchi_backend/
├── pasta/ # the instantiations of everything for both curves
│   ├── basic.ml # instantiate a number of things
│   ├── {pallas,vesta}_based_plonk.ml # instantiate the backend for the different curves
│   ├── precomputed.ml
├── common/ # the stuff that both curves have in common
│   ├── bigint.ml
│   ├── curve.ml
│   ├── dlog_plonk_based_keypair.ml
│   ├── dlog_urs.ml
│   ├── endoscale_round.ml
│   ├── field.ml
│   ├── intf.ml
│   ├── plonk_constraint_system.ml # the functor to create a constraint system
│   ├── plonk_dlog_oracles.ml
│   ├── plonk_dlog_proof.ml
│   ├── poly_comm.ml
│   ├── scale_round.ml
│   ├── var.ml
│   ├── version.ml
└── kimchi_backend.ml

Mina代码中:【Fp refers to the base field of Pallas, and the scalar field of Vesta;Fq refers to the base field of Vesta, and the scalar field of Pallas。】

  • Tick对应为Vesta_based_plonk,其Inner_curve为Pallas曲线。对应的为Fp_poly_comm。
  • Tock对应为Pallas_based_plonk,其Inner_curve对应为Vesta曲线。对应的为Fq_poly_comm。
module Tick = struct
  include Kimchi_backend.Pasta.Vesta_based_plonk
  module Inner_curve = Kimchi_backend.Pasta.Pasta.Pallas
end

module Tock = struct
  include Kimchi_backend.Pasta.Pallas_based_plonk
  module Inner_curve = Kimchi_backend.Pasta.Pasta.Vesta
end

module Fq_poly_comm = Kimchi_backend_common.Poly_comm.Make (struct
  module Curve = Pallas
  module Base_field = Fp
  。。。。。

module Fp_poly_comm = Kimchi_backend_common.Poly_comm.Make (struct
  module Curve = Vesta
  module Base_field = Fq
  。。。。。

二者的用途也各不相同:

  • Tick: Vesta (a.k.a. Step), constraint domain size 2 18 2^{18} 218 [用于block and transaction proofs]
  • Tock:Pallas (a.k.a. Wrap), constraint domain size 2 17 2^{17} 217 [用于signatures]

【vesta的round为16,pallas的round为15。】

let name =
    sprintf "%s_%d_v4" Inputs.name (Pickles_types.Nat.to_int Inputs.Rounds.n)

用于签名的Wrap proof system 和 用于区块以及交易的Step proof system的endo曲线配置为:

(* The endo coefficients used by the step proof system *)
module Wrap_inner_curve = struct
  let base : Backend.Tock.Field.t = Kimchi.Vesta.endo_base ()

  let scalar : Backend.Tick.Field.t = Kimchi.Vesta.endo_scalar ()

  let to_field (t : Challenge.Constant.t Scalar_challenge.t) :
      Backend.Tick.Field.t =
    SC.to_field_constant (module Backend.Tick.Field) ~endo:scalar t
end

(* The endo coefficients used by the wrap proof system *)
module Step_inner_curve = struct
  let base : Backend.Tick.Field.t = Kimchi.Pallas.endo_base ()

  let scalar : Backend.Tock.Field.t = Kimchi.Pallas.endo_scalar ()

  let to_field (t : Challenge.Constant.t Scalar_challenge.t) :
      Backend.Tock.Field.t =
    SC.to_field_constant (module Backend.Tock.Field) ~endo:scalar t
end

1.2 crypto/kimchi_bindings

为bindings to kimchiarkworks
crypto/kimchi_bindings总体结构为:

kimchi_bindings/
├── pasta_fp_poseidon # TODO: move this to the automatically-generated stubs
├── pasta_fq_poseidon # TODO: move this to the automatically-generated stubs
└── stubs/       # the rust code that generates the ocaml bindings

2. 关键类型定义

2.1 Poly_comm

Mina在实现Poly_comm时,分为了2种类型:

  • 1)With_degree_bound:即多项式具有固定的degree上限 n n n。若某多项式degree小于上限 n n n,可pad dummy补齐。
  • 2)Without_degree_bound:即对多项式的degree无限制。

2.2 Messages

Messages结构为:

	type 'g t =
        { w_comm : 'g Without_degree_bound.Stable.V1.t Columns_vec.Stable.V1.t
        ; z_comm : 'g Without_degree_bound.Stable.V1.t
        ; t_comm : 'g Without_degree_bound.Stable.V1.t
        }

2.3 Shifts

Shifts结构为:

type 'field t = 'field array

2.4 Openings

Openings包含2部分:

  • 1)Bulletproof定义:
    type ('g, 'fq) t =
          { lr : ('g * 'g) array; z_1 : 'fq; z_2 : 'fq; delta : 'g; sg : 'g }
    
  • 2)Openings定义:
    type ('g, 'fq, 'fqv) t =
        { proof : ('g, 'fq) Bulletproof.Stable.V1.t
        ; evals : 'fqv Evals.Stable.V2.t * 'fqv Evals.Stable.V2.t
        ; ft_eval1 : 'fq
        }
    

2.5 Evals

Evals结构为:【其中w表示witness columns,s表示sigma columns】

	type 'a t =
        { w : 'a Columns_vec.Stable.V1.t
        ; z : 'a
        ; s : 'a Permuts_minus_1_vec.Stable.V1.t
        ; generic_selector : 'a
        ; poseidon_selector : 'a
        }

2.6 All_evals

All_evals包含2部分:

  • 1)With_public_input定义为:
    type ('f, 'f_multi) t =
          { public_input : 'f; evals : 'f_multi Evals.Stable.V2.t }
    
  • 2)All_evals定义为:
    type ('f, 'f_multi) t =
          { public_input : 'f; evals : 'f_multi Evals.Stable.V2.t }
    

2.7 Proof

Proof结构为:

	type ('g, 'fq, 'fqv) t =
        { messages : 'g Messages.Stable.V2.t
        ; openings : ('g, 'fq, 'fqv) Openings.Stable.V2.t
        }

3. Vesta_based_plonk和Pallas_based_plonk

3.1 generate_keypair

let generate_keypair ~exposing x =
      let x =
        inject_wrapper exposing x ~f:(fun x () -> Proof_system.mark_active ~f:x)
      in
      Perform.generate_keypair ~run:as_stateful ~exposing x
      
let rec inject_wrapper : type r_var r_value k_var k_value.
           (r_var, r_value, k_var, k_value) Data_spec.t
        -> f:(r_var -> r_var)
        -> k_var
        -> k_var =
     fun spec ~f ->
      match spec with
      | [] ->
          fun x -> f x
      | _ :: spec ->
          fun x a -> inject_wrapper spec ~f (x a)

let as_stateful x state' =
      state := state' ;
      let a = x () in
      (!state, a)

let generate_keypair ~run ~exposing k =
      Run.generate_keypair ~run ~exposing k

let generate_keypair :
           run:(_, _, 'checked) Checked.Runner.run
        -> exposing:('checked, _, 'k_var, _) t
        -> 'k_var
        -> Keypair.t =
     fun ~run ~exposing k ->
      Keypair.generate (constraint_system ~run ~exposing k)

let constraint_system (type a s checked k_var) :
           run:(a, s, checked) Checked.Runner.run
        -> exposing:(checked, _, k_var, _) t
        -> k_var
        -> R1CS_constraint_system.t =
     fun ~run ~exposing k -> r1cs_h ~run (ref 1) exposing k

let generate = Fn.compose of_backend_keypair Backend.Keypair.create

3.2 generate_witness

let generate_witness spec x =
      let x =
        inject_wrapper spec x ~f:(fun x () -> Proof_system.mark_active ~f:x)
      in
      Perform.generate_witness ~run:as_stateful spec x

let generate_witness ~run t k s = Run.generate_witness ~run t s k

let generate_witness = generate_witness_conv ~f:Fn.id

let generate_witness_conv :
           run:('a, 's, 'checked) Checked.Runner.run
        -> f:(Proof_inputs.t -> 'out)
        -> ('checked, 'out, 'k_var, 'k_value) t
        -> ?handlers:Handler.t list
        -> 's
        -> 'k_var
        -> 'k_value =
     fun ~run ~f t ?handlers s k ->
      conv
        (fun c primary ->
          let auxiliary =
            Checked.auxiliary_input ~run ?handlers
              ~num_inputs:(Field.Vector.length primary)
              c s primary
          in
          f {Proof_inputs.public_inputs= primary; auxiliary_inputs= auxiliary}
          )
        t k

附录1. Mina系列博客

Mina系列博客有:

猜你喜欢

转载自blog.csdn.net/mutourend/article/details/124882555