Mina中的wrap snark

Posted mutourend

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Mina中的wrap snark相关的知识,希望对你有一定的参考价值。

1. 引言

前序博客有:


所谓wrap snark,是将Tick snark(Mina代码中称为step proof)包裹为Tock snark(Mina代码中称为wrap proof)。
wrap snark的目的是:将一个Tick snark 包裹为一个Tock snark,以便用另一个Tick snark就能证明它。

Tick snark对应的场景为:

  • public 输入: x , π tick x, \\pi_\\texttick x,πtick
  • witness: w w w
  • 待证明relation: Verify tick ( ( x , π tick ) ; w ) = true \\textVerify_\\texttick((x,\\pi_\\texttick);w) = \\texttrue Verifytick((x,πtick);w)=true

经Wrap snark包裹为Tock snark对应的场景为:

  • public 输入: x , π tock x,\\pi_\\texttock x,πtock
  • witness: w , π tick w, \\pi_\\texttick w,πtick
  • 待证明relation: Verify tick ( ( x , π tock ) ; ( w , π tick ) ) = true \\textVerify_\\texttick((x,\\pi_\\texttock);(w, \\pi_\\texttick)) = \\texttrue Verifytick((x,πtock);(w,πtick))=true

2. 关键代码

2.1 pickles_base.domain模块

domain结构定义为:

type t = Pow_2_roots_of_unity of int
let tag, cache_handle, p, Pickles.Provers.[ step ] =
    Pickles.compile ~cache:Cache_dir.cache
      (module Statement_var)
      (module Statement)
      ~typ
      ~branches:(module Nat.N1)
      ~max_proofs_verified:(module Nat.N2)
      ~name:"blockchain-snark"
      ~constraint_constants:
        (Genesis_constants.Constraint_constants.to_snark_keys_header
           constraint_constants )
      ~choices:(fun ~self ->
        [ rule ~proof_level ~constraint_constants T.tag self ] )

根据调用Pickles.compile时的max_proofs_verified参数,相应的wrap_domain取值为:

let wrap_domains ~proofs_verified =
  let h =
    match proofs_verified with 0 -> 13 | 1 -> 14 | 2 -> 15 | _ -> assert false
  in
   Domains.h = Pow_2_roots_of_unity h 

如compile时参数为~max_proofs_verified:(module Nat.N2),对应的wrap_domains为:

ZYD wrap_domains:"h":["Pow_2_roots_of_unity",15] 

如compile时参数为~branches:(module Nat.N1),对应的prev_varss_n和proofs_verified为:【prev_varss_n和proofs_verified数组长度 与 branches参数以及choices参数中rule数组的个数一致。】

ZYD prev_varss_n:1
ZYD proofs_verifieds:1

2.2 pickles.wrap_main_inputs模块

pickles.wrap_main_inputs模块主要针对的是Tock曲线。其中的Other模块针对的为Tick曲线。
其中主要包含了:

  • Sponge模块
  • Input_domain模块
  • Inner_curve模块:对应为Tick曲线
  • Generators模块

2.3 pickles.wrap_verifier模块

pickles.wrap_verifier模块实现了challenge_polynomial函数:

(* given [chals], compute
   \\prod_i (1 + chals.(i) * x^2^k - 1 - i) *)
let challenge_polynomial ~one ~add ~mul chals = ......

pickles.wrap_verifier模块中的Make模块内定义了:

  • print_g等打印函数
  • product、absorb、scalar_to_field、squeeze_challenge、squeeze_scalar等函数
  • assert_n_bits、lowest_128_bits、equal_g、mask、assert_eq_marlin、shift1、shift2等函数
  • bullet_reduce、lagrange、lagrange_with_correction、h_precomp、group_map、map_challenges等函数
  • choose_key、scale_fast、check_bulletproof、iter2、pow2pow、map_plonk_to_field等函数
  • incrementally_verify_proof、mask_evals、combined_evaluation、compute_challenges、actual_evaluation等函数
  • finalize_other_proof函数:
    (* This finalizes the "deferred values" coming from a previous proof over the same field.
     It
     1. Checks that [xi] and [r] where sampled correctly. I.e., by absorbing all the
     evaluation openings and then squeezing.
     2. Checks that the "combined inner product" value used in the elliptic curve part of
     the opening proof was computed correctly, in terms of the evaluation openings and the
     evaluation points.
     3. Check that the "b" value was computed correctly.
     4. Perform the arithmetic checks from marlin. *)
    let finalize_other_proof (type b)
      (module Proofs_verified : Nat.Add.Intf with type n = b)
      ?actual_proofs_verified ~domain ~max_quot_size ~sponge
      ~(old_bulletproof_challenges : (_, b) Vector.t)
      ( xi; combined_inner_product; bulletproof_challenges; b; plonk  :
        ( _
        , _
        , _ Shifted_value.Type2.t
        , _ )
        Types.Step.Proof_state.Deferred_values.In_circuit.t )
       Plonk_types.All_evals.ft_eval1
      ; evals =
          (  evals = evals1; public_input = x_hat1 
          ,  evals = evals2; public_input = x_hat2  )
       = .......
    
  • Other_field模块
  • Challenge模块
  • Digest模块
  • Scalar_challenge模块
  • Ops模块
  • One_hot_vector模块
  • Split_commitments模块
  • Opt模块
  • Pseudo模块
  • Plonk模块
  • Split_evaluations模块
  • Plonk_checks模块
  • 定义index为Plonk_verification_key_evals类型:
    type 'comm t =
       sigma_comm : 'comm Plonk_types.Permuts_vec.Stable.V1.t
      ; coefficients_comm : 'comm Plonk_types.Columns_vec.Stable.V1.t
      ; generic_comm : 'comm
      ; psm_comm : 'comm
      ; complete_add_comm : 'comm
      ; mul_comm : 'comm
      ; emul_comm : 'comm
      ; endomul_scalar_comm : 'comm
      
    

2.4 pickles.wrap_main模块

pickles.wrap_main模块中包含:

  • 1)pad_domains函数:当前假设所有的wrap domains是相同的,当切换到dlog-dlog system时,该函数将有用。
  • 2)Old_bulletproof_chals模块:
    module Old_bulletproof_chals = struct
      type t =
        | T :
            'max_local_max_proofs_verified Nat.t
            * 'max_local_max_proofs_verified Challenges_vector.t
            -> t
    end
    
  • 3)pack_statement、shifts、domain_generator、split_field_typ、split_field等函数函数:
  • 4)wrap_main函数:为The SNARK function for wrapping any proof coming from the given set of keys。
    let wrap_main
        (type max_proofs_verified branches prev_varss prev_valuess env
        max_local_max_proofs_verifieds )
        (full_signature :
          ( max_proofs_verified
          , branches
          , max_local_max_proofs_verifieds )
          Full_signature.t ) (pi_branches : (prev_varss, branches) Hlist.Length.t)
        (step_keys :
          (Wrap_main_inputs.Inner_curve.Constant.t index, branches) Vector.t Lazy.t
          ) (step_widths : (int, branches) Vector.t)
        (step_domains : (Domains.t, branches) Vector.t)
        (prev_wrap_domains :
          (prev_varss, prev_valuess, _, _) H4.T(H4.T(E04(Domains))).t )
        (module Max_proofs_verified : Nat.Add.Intf with type n = max_proofs_verified)
        :
        (max_proofs_verified, max_local_max_proofs_verifieds) Requests.Wrap.t
        * (   ( _
              , _
              , _ Shifted_value.Type1.t
              , _
              , _
              , _
              , _
              , _
              , _ )
              Types.Wrap.Statement.In_circuit.t
           -> unit ) =
    

wrap_main的调用方式,返回的分别为wrap_requests(为 (max_proofs_verified, max_local_max_proofs_verifieds) Requests.Wrap.t类型)和wrap_main(输入为Types.Wrap.Statement.In_circuit.t,输出为unit的函数):

let wrap_requests, wrap_main_main = Wrap_main.wrap_main full_signature prev_varss_length step_vks
        proofs_verifieds step_domains prev_wrap_domains
        (module Max_proofs_verified)

其中:

  • full_signature对应结构为:
    (full_signature :
      ( max_proofs_verified
      , branches
      , max_local_max_proofs_verifieds )
      Full_signature.t )
    
  • prev_varss_length对应结构为:
    (pi_branches : (prev_varss, branches) Hlist.Length.t)
    
  • step_vks对应结构为:
    (step_keys :
      (Wrap_main_inputs.Inner_curve.Constant.t index, branches) Vector.t Lazy.t
      )
    
  • proofs_verifieds对应结构为:
    (step_widths : (int, branches) Vector.t)
    
  • step_domains对应结构为:【step_domains数组的长度 与 compile时choices中rule数组的长度 一致】
    (step_domains : (Domains.t, branches) Vector.t)
    
  • prev_wrap_domains对应结构为:
    (prev_wrap_domains :
      (prev_varss, prev_valuess, _, _) H4.T(H4.T(E04(Domains))).t )
    
  • Max_proofs_verified对应结构为:
    (module Max_proofs_verified : Nat.Add.Intf with type n = max_proofs_verified)
    
  • 返回的wrap_requests对应结构为:
    (max_proofs_verified, max_local_max_proofs_verifieds) Requests.Wrap.t`
    
  • 返回的wrap_main_main为函数:
    (   ( _
          , _
          , _ Shifted_value.Type1.t
          , _
          , _
          , _
          , _
          , _
          , _ )
          Types.Wrap.Statement.In_circuit.t
       -> unit )
     (* Shifted_value.Type1.t结构为: *)
     type 'f t = Shifted_value of 'f
     (* Types.Wrap.Statement.In_circuit.t结构为: *)
     type ( 'challenge
           , 'scalar_challenge
           , 'fp
           , 'fq
           , 'me_only
           , 'digest
           , 'pass_through
           , 'bp_chals
           , 'index )
           t =
        ( ( 'challenge
          , 'scalar_challenge
          , 'fp )
          Proof_state.Deferred_values.Plonk.In_circuit.t
        , 'scalar_challenge
        , 'fp
        , 'fq
        , 'me_only
        , 'digest
        , 'pass_through
        , 'bp_chals
        , 'index )
        Stable.Latest.t
    (*  Stable.Latest.t结构为: *)
     type ( 'plonk
             , 'scalar_challenge
             , 'fp
             , 'fq
             , 'me_only
             , 'digest
             , 'pass_through
             , 'bp_chals
             , 'index )
             t =
           proof_state :
              ( 'plonk
              , 'scalar_challenge
              , 'fp
              , 'fq
              , 'me_only
              , 'digest
              , 'bp_chals
              , 'index )
              Proof_state.Stable.V1.t
          ; pass_through : 'pass_through
          
    (* Proof_state.Deferred_values.Plonk.In_circuit.t结构为: *)
    	  (** All scalar values deferred by a verifier circuit.
              The values in [poseidon_selector], [vbmul], [complete_add], [endomul], [endomul_scalar], [perm], and [generic]
              are all scalars which will have been used to scale selector polynomials during the
              computation of the linearized polynomial commitment.
    
              Then, we expose them so the next guy (who can do scalar arithmetic) can check that they
              were computed correctly from the evaluations in the proof and the challenges.
          *)
          type ('challenge, 'scalar_challenge, 'fp) t =
             alpha : 'scalar_challenge
            ; beta : 'challenge
            ; gamma : 'challenge
            ; zeta : 'scalar_challenge
                  (* TODO: zeta_to_srs_length is kind of unnecessary.
                     Try to get rid of it when you can.
                  *)
            ; zeta_to_srs_length : 'fp
            ; zeta_to_domain_size : 'fp
            ; poseidon_selector : 'fp
                  (** scalar used on the poseidon selector *)
            ; vbmul : 'fp  (** scalar used on the vbmul selector *)
            ; complete_add : 'fp
                  (** scalar used on the complete_add selector *)
            ; endomul : 'fp  (** scalar used on the endomul selector *)
            ; endomul_scalar : 'fp
                  (** scalar used on the endomul_scalar selector *)
            ; perm : 'fp
                  (** scalar used on one of the permutation polynomial commitments. *)
            ; generic : 'fp Generic_coeffs_vec.t
                  (** scalars used on the coefficient column commitments. *)
            
    

2.5 pickles.wrap模块

pickles.wrap模块中包含:

  • 1)Plonk_checks模块:其中Type1针对Tick曲线,Type2针对Tock曲线。
  • 2)vector_of_list函数:将list输入转换为vector输出。
  • 3)challenge_polynomial函数:为Tick域的challenge_polynomial函数,作用为: given [chals], compute \\prod_i (1 + chals.(i) * x2k - 1 - i) 。
  • 4)tick_rounds:即Tick.Rounds.n。(为16)
  • 5)combined_inner_product函数:
  • 6)Step_acc模块:即为Tick affine坐标系。
  • 7)wrap函数:
    (* The prover for wrapping a proof *)
    let wrap
        (type actual_proofs_verified max_proofs_verified
        max_local_max_proofs_verifieds )
        ~(max_proofs_verified : max_proofs_verified Nat.t)
        (module Max_local_max_proof_verifieds : Hlist.Maxes.S
          with type ns = max_local_max_proofs_verifieds
           and type length = max_proofs_verified )
        (( module
          Req ) :
          (max_proofs_verified, max_local_max_proofs_verifieds) Requests.Wrap.t )
        ~dlog_plonk_index wrap_main to_field_elements ~step_vk ~wrap_domains
        ~step_plonk_indices pk
        ( statement = prev_statement; prev_evals; proof; index = which_index  :
          ( _
          , _
          , (_, actual_proofs_verified) Vector.t
          , (_, actual_proofs_verified) Vector.t
          , max_local_max_proofs_verifieds H1.T(P.Base.Me_only.Wrap).t
          , ( (Tock.Field.t, Tock.Field.t array) Plonk_types.All_evals.t
            , max_proofs_verified )
            Vector.t )
          P.Base.Step.t ) =
    

调用wrap函数为:

		let%map.Promise wrap_proof =
            Wrap.wrap ~max_proofs_verified:Max_proofs_verified.n
              full_signature.maxes wrap_requests
              ~dlog_plonk_index:wrap_vk.commitments wrap_main_main
              A_value.to_field_elements ~step_vk
              ~step_plonk_indices:(Lazy.force step_vks) ~wrap_domains
              (Impls.Wrap.Keypair.pk (fst (Lazy.force wrap_pk)))
              step_proof

参考资料

[1] Mina背后的理想乡:递归零知识证明
[2] Recusive ZK-SNARKS

附录1. Mina系列博客

Mina系列博客有:

以上是关于Mina中的wrap snark的主要内容,如果未能解决你的问题,请参考以下文章

Mina中的Kimchi SNARK

Mina中的zkApp交易snark

Mina中的支付交易snark

Mina中的交易及经济白皮书

Mina中的树结构

包裹在 flexbox 网格中的 flex 项目的相等边距空间