• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

MinaProtocol / mina / 3409

26 Feb 2025 01:10PM UTC coverage: 32.353% (-28.4%) from 60.756%
3409

push

buildkite

web-flow
Merge pull request #16687 from MinaProtocol/dw/merge-compatible-into-develop-20250225

Merge compatible into develop [20250224]

23144 of 71535 relevant lines covered (32.35%)

16324.05 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

34.45
/src/lib/pickles/composition_types/composition_types.ml
1
open Pickles_types
35✔
2
module Scalar_challenge = Kimchi_backend_common.Scalar_challenge
3
module Bulletproof_challenge = Bulletproof_challenge
4
module Branch_data = Branch_data
5
module Digest = Digest
6
module Spec = Spec
7
module Opt = Opt
8
open Core_kernel
9
module Step_impl = Kimchi_pasta_snarky_backend.Step_impl
10
module Wrap_impl = Kimchi_pasta_snarky_backend.Wrap_impl
11

12
let index_to_field_elements =
13
  Pickles_base.Side_loaded_verification_key.index_to_field_elements
14

15
module Zero_values = struct
16
  type ('chal, 'fp) single = { challenge : 'chal; scalar : 'fp }
17

18
  type ('chal, 'chal_var, 'fp, 'fp_var) t =
19
    { value : ('chal, 'fp) single; var : ('chal_var, 'fp_var) single }
20
end
21

22
module Wrap = struct
23
  module Proof_state = struct
24
    (** This module contains structures which contain the scalar-field elements that
25
        are required to finalize the verification of a proof that is partially verified inside
26
        a circuit.
27

28
        Each verifier circuit starts by verifying the parts of a proof involving group operations.
29
        At the end, there is a sequence of scalar-field computations it must perform. Instead of
30
        performing them directly, it exposes the values needed for those computations as a part of
31
        its own public-input, so that the next circuit can do them (since it will use the other curve on the cycle,
32
        and hence can efficiently perform computations in that scalar field). *)
33
    module Deferred_values = struct
34
      module Plonk = struct
35
        module Minimal = struct
36
          [%%versioned
37
          module Stable = struct
38
            module V1 = struct
39
              (** Challenges from the PLONK IOP. These, plus the evaluations that are already in the proof, are
40
                  all that's needed to derive all the values in the [In_circuit] version below.
41

42
                  See src/lib/pickles/plonk_checks/plonk_checks.ml for the computation of the [In_circuit] value
43
                  from the [Minimal] value.
44
              *)
45
              type ('challenge, 'scalar_challenge, 'bool) t =
60✔
46
                    ( 'challenge
47
                    , 'scalar_challenge
48
                    , 'bool )
49
                    Mina_wire_types.Pickles_composition_types.Wrap.Proof_state
50
                    .Deferred_values
51
                    .Plonk
52
                    .Minimal
53
                    .V1
54
                    .t =
55
                { alpha : 'scalar_challenge
×
56
                ; beta : 'challenge
×
57
                ; gamma : 'challenge
×
58
                ; zeta : 'scalar_challenge
×
59
                ; joint_combiner : 'scalar_challenge option
×
60
                ; feature_flags : 'bool Plonk_types.Features.Stable.V1.t
×
61
                }
62
              [@@deriving sexp, compare, yojson, hlist, hash, equal]
105✔
63

64
              let to_latest = Fn.id
65
            end
66
          end]
67

68
          let map_challenges t ~f ~scalar =
69
            { t with
×
70
              alpha = scalar t.alpha
×
71
            ; beta = f t.beta
×
72
            ; gamma = f t.gamma
×
73
            ; zeta = scalar t.zeta
×
74
            ; joint_combiner = Option.map ~f:scalar t.joint_combiner
×
75
            }
76

77
          module In_circuit = struct
78
            type ('challenge, 'scalar_challenge, 'bool) t =
79
              { alpha : 'scalar_challenge
80
              ; beta : 'challenge
81
              ; gamma : 'challenge
82
              ; zeta : 'scalar_challenge
83
              ; joint_combiner : ('scalar_challenge, 'bool) Opt.t
84
              ; feature_flags : 'bool Plonk_types.Features.t
85
              }
86
          end
87
        end
88

89
        open Pickles_types
90

91
        module In_circuit = struct
92
          (** All scalar values deferred by a verifier circuit.
93
              We expose them so the next guy (who can do scalar arithmetic) can check that they
94
              were computed correctly from the evaluations in the proof and the challenges.
95
          *)
96
          type ( 'challenge
80✔
97
               , 'scalar_challenge
98
               , 'fp
99
               , 'fp_opt
100
               , 'scalar_challenge_opt
101
               , 'bool )
102
               t =
×
103
            { alpha : 'scalar_challenge
×
104
            ; beta : 'challenge
×
105
            ; gamma : 'challenge
×
106
            ; zeta : 'scalar_challenge
×
107
                  (* TODO: zeta_to_srs_length is kind of unnecessary.
108
                     Try to get rid of it when you can.
109
                  *)
110
            ; zeta_to_srs_length : 'fp
×
111
            ; zeta_to_domain_size : 'fp
×
112
            ; perm : 'fp
×
113
                  (** scalar used on one of the permutation polynomial commitments. *)
114
            ; feature_flags : 'bool Plonk_types.Features.t
×
115
            ; joint_combiner : 'scalar_challenge_opt
×
116
            }
117
          [@@deriving sexp, compare, yojson, hlist, hash, equal, fields]
×
118

119
          let map_challenges t ~f ~scalar =
120
            { t with
40✔
121
              alpha = scalar t.alpha
40✔
122
            ; beta = f t.beta
40✔
123
            ; gamma = f t.gamma
40✔
124
            ; joint_combiner = Opt.map ~f:scalar t.joint_combiner
40✔
125
            ; zeta = scalar t.zeta
40✔
126
            }
127

128
          let map_fields t ~f =
129
            { t with
60✔
130
              zeta_to_srs_length = f t.zeta_to_srs_length
60✔
131
            ; zeta_to_domain_size = f t.zeta_to_domain_size
60✔
132
            ; perm = f t.perm
60✔
133
            }
134

135
          let typ (type fp) ~dummy_scalar_challenge ~challenge ~scalar_challenge
136
              ~bool
137
              ~feature_flags:
138
                ({ Plonk_types.Features.Full.uses_lookups; _ } as feature_flags)
139
              (fp : (fp, _) Step_impl.Typ.t) =
140
            Step_impl.Typ.of_hlistable
40✔
141
              [ Scalar_challenge.typ scalar_challenge
40✔
142
              ; challenge
143
              ; challenge
144
              ; Scalar_challenge.typ scalar_challenge
40✔
145
              ; fp
146
              ; fp
147
              ; fp
148
              ; Plonk_types.Features.typ
40✔
149
                  ~feature_flags:(Plonk_types.Features.of_full feature_flags)
40✔
150
                  bool
151
              ; Opt.typ uses_lookups ~dummy:dummy_scalar_challenge
40✔
152
                  (Scalar_challenge.typ scalar_challenge)
40✔
153
              ]
154
              ~var_to_hlist:to_hlist ~var_of_hlist:of_hlist
155
              ~value_to_hlist:to_hlist ~value_of_hlist:of_hlist
156
        end
157

158
        let to_minimal (type challenge scalar_challenge fp fp_opt lookup_opt)
159
            (t :
160
              ( challenge
161
              , scalar_challenge
162
              , fp
163
              , fp_opt
164
              , lookup_opt
165
              , 'bool )
166
              In_circuit.t ) ~(to_option : lookup_opt -> scalar_challenge option)
167
            : (challenge, scalar_challenge, 'bool) Minimal.t =
168
          { alpha = t.alpha
40✔
169
          ; beta = t.beta
170
          ; zeta = t.zeta
171
          ; gamma = t.gamma
172
          ; joint_combiner = to_option t.joint_combiner
40✔
173
          ; feature_flags = t.feature_flags
174
          }
175
      end
176

177
      [%%versioned
178
      module Stable = struct
179
        [@@@no_toplevel_latest_type]
180

181
        module V1 = struct
182
          (** All the deferred values needed, comprising values from the PLONK IOP verification,
183
    values from the inner-product argument, and [which_branch] which is needed to know
184
    the proper domain to use. *)
185
          type ( 'plonk
35✔
186
               , 'scalar_challenge
187
               , 'fp
188
               , 'bulletproof_challenges
189
               , 'branch_data )
190
               t =
280✔
191
                ( 'plonk
192
                , 'scalar_challenge
193
                , 'fp
194
                , 'bulletproof_challenges
195
                , 'branch_data )
196
                Mina_wire_types.Pickles_composition_types.Wrap.Proof_state
197
                .Deferred_values
198
                .V1
199
                .t =
200
            { plonk : 'plonk
×
201
            ; combined_inner_product : 'fp
×
202
                  (** combined_inner_product = sum_{i < num_evaluation_points} sum_{j < num_polys} r^i xi^j f_j(pt_i) *)
203
            ; b : 'fp
×
204
                  (** b = challenge_poly plonk.zeta + r * challenge_poly (domain_generrator * plonk.zeta)
205
                where challenge_poly(x) = \prod_i (1 + bulletproof_challenges.(i) * x^{2^{k - 1 - i}})
206
            *)
207
            ; xi : 'scalar_challenge
×
208
                  (** The challenge used for combining polynomials *)
209
            ; bulletproof_challenges : 'bulletproof_challenges
×
210
                  (** The challenges from the inner-product argument that was partially verified. *)
211
            ; branch_data : 'branch_data
×
212
                  (** Data specific to which step branch of the proof-system was verified *)
213
            }
214
          [@@deriving sexp, compare, yojson, hlist, hash, equal]
105✔
215

216
          let to_latest = Fn.id
217
        end
218
      end]
219

220
      type ( 'plonk
80✔
221
           , 'scalar_challenge
222
           , 'fp
223
           , 'bulletproof_challenges
224
           , 'branch_data )
225
           t =
226
            ( 'plonk
227
            , 'scalar_challenge
228
            , 'fp
229
            , 'bulletproof_challenges
230
            , 'branch_data )
231
            Stable.Latest.t =
232
        { plonk : 'plonk
×
233
        ; combined_inner_product : 'fp
×
234
        ; b : 'fp
×
235
        ; xi : 'scalar_challenge
×
236
        ; bulletproof_challenges : 'bulletproof_challenges
×
237
        ; branch_data : 'branch_data
×
238
        }
239
      [@@deriving sexp, compare, yojson, hlist, hash, equal]
240

241
      module Minimal = struct
242
        [%%versioned
243
        module Stable = struct
244
          module V1 = struct
245
            type ( 'challenge
193✔
246
                 , 'scalar_challenge
247
                 , 'fp
248
                 , 'bool
249
                 , 'bulletproof_challenges
250
                 , 'branch_data )
251
                 t =
315✔
252
                  ( 'challenge
253
                  , 'scalar_challenge
254
                  , 'fp
255
                  , 'bool
256
                  , 'bulletproof_challenges
257
                  , 'branch_data )
258
                  Mina_wire_types.Pickles_composition_types.Wrap.Proof_state
259
                  .Deferred_values
260
                  .Minimal
261
                  .V1
262
                  .t =
263
              { plonk :
×
264
                  ( 'challenge
×
265
                  , 'scalar_challenge
×
266
                  , 'bool )
×
267
                  Plonk.Minimal.Stable.V1.t
×
268
              ; bulletproof_challenges : 'bulletproof_challenges
×
269
              ; branch_data : 'branch_data
×
270
              }
271
            [@@deriving sexp, compare, yojson, hash, equal]
105✔
272
          end
273
        end]
274

275
        let map_challenges { plonk; bulletproof_challenges; branch_data } ~f
276
            ~scalar =
277
          { plonk = Plonk.Minimal.map_challenges ~f ~scalar plonk
×
278
          ; bulletproof_challenges
279
          ; branch_data
280
          }
281
      end
282

283
      let map_challenges
284
          { plonk
285
          ; combined_inner_product
286
          ; b : 'fp
287
          ; xi
288
          ; bulletproof_challenges
289
          ; branch_data
290
          } ~f:_ ~scalar =
291
        { xi = scalar xi
×
292
        ; combined_inner_product
293
        ; b
294
        ; plonk
295
        ; bulletproof_challenges
296
        ; branch_data
297
        }
298

299
      module In_circuit = struct
300
        type ( 'challenge
×
301
             , 'scalar_challenge
302
             , 'fp
303
             , 'fp_opt
304
             , 'lookup_opt
305
             , 'bulletproof_challenges
306
             , 'branch_data
307
             , 'bool )
308
             t =
309
          ( ( 'challenge
×
310
            , 'scalar_challenge
×
311
            , 'fp
×
312
            , 'fp_opt
×
313
            , 'lookup_opt
×
314
            , 'bool )
×
315
            Plonk.In_circuit.t
×
316
          , 'scalar_challenge
×
317
          , 'fp
×
318
          , 'bulletproof_challenges
×
319
          , 'branch_data )
×
320
          Stable.Latest.t
×
321
        [@@deriving sexp, compare, yojson, hash, equal]
×
322

323
        let to_hlist, of_hlist = (to_hlist, of_hlist)
324

325
        let typ (type fp) ~dummy_scalar_challenge ~challenge ~scalar_challenge
326
            ~feature_flags (fp : (fp, _) Step_impl.Typ.t) index =
327
          Step_impl.Typ.of_hlistable
40✔
328
            [ Plonk.In_circuit.typ ~dummy_scalar_challenge ~challenge
40✔
329
                ~scalar_challenge ~bool:Step_impl.Boolean.typ ~feature_flags fp
330
            ; fp
331
            ; fp
332
            ; Scalar_challenge.typ scalar_challenge
40✔
333
            ; Vector.typ
40✔
334
                (Bulletproof_challenge.typ scalar_challenge)
40✔
335
                Backend.Tick.Rounds.n
336
            ; index
337
            ]
338
            ~var_to_hlist:to_hlist ~var_of_hlist:of_hlist
339
            ~value_to_hlist:to_hlist ~value_of_hlist:of_hlist
340
      end
341

342
      let to_minimal
343
          ({ plonk
344
           ; combined_inner_product = _
345
           ; b = _
346
           ; xi = _
347
           ; bulletproof_challenges
348
           ; branch_data
349
           } :
350
            _ In_circuit.t ) ~to_option : _ Minimal.t =
351
        { plonk = Plonk.to_minimal ~to_option plonk
×
352
        ; bulletproof_challenges
353
        ; branch_data
354
        }
355
    end
356

357
    (** The component of the proof accumulation state that is only computed on by the
358
        "wrapping" proof system, and that can be handled opaquely by any "step" circuits. *)
359
    module Messages_for_next_wrap_proof = struct
360
      [%%versioned
361
      module Stable = struct
362
        module V1 = struct
363
          type ('g1, 'bulletproof_challenges) t =
85✔
364
                ( 'g1
365
                , 'bulletproof_challenges )
366
                Mina_wire_types.Pickles_composition_types.Wrap.Proof_state
367
                .Messages_for_next_wrap_proof
368
                .V1
369
                .t =
370
            { challenge_polynomial_commitment : 'g1
×
371
            ; old_bulletproof_challenges : 'bulletproof_challenges
×
372
            }
373
          [@@deriving sexp, compare, yojson, hlist, hash, equal]
175✔
374
        end
375
      end]
376

377
      let to_field_elements (type g f)
378
          { challenge_polynomial_commitment; old_bulletproof_challenges }
379
          ~g1:(g1_to_field_elements : g -> f list) =
380
        Array.concat
24✔
381
          [ Vector.to_array old_bulletproof_challenges
24✔
382
            |> Array.concat_map ~f:Vector.to_array
24✔
383
          ; Array.of_list (g1_to_field_elements challenge_polynomial_commitment)
24✔
384
          ]
385

386
      let wrap_typ g1 chal ~length =
387
        Wrap_impl.Typ.of_hlistable
×
388
          [ g1; Vector.wrap_typ chal length ]
×
389
          ~var_to_hlist:to_hlist ~var_of_hlist:of_hlist ~value_to_hlist:to_hlist
390
          ~value_of_hlist:of_hlist
391
    end
392

393
    [%%versioned
394
    module Stable = struct
395
      module V1 = struct
396
        type ( 'plonk
115✔
397
             , 'scalar_challenge
398
             , 'fp
399
             , 'messages_for_next_wrap_proof
400
             , 'digest
401
             , 'bp_chals
402
             , 'index )
403
             t =
350✔
404
              ( 'plonk
405
              , 'scalar_challenge
406
              , 'fp
407
              , 'messages_for_next_wrap_proof
408
              , 'digest
409
              , 'bp_chals
410
              , 'index )
411
              Mina_wire_types.Pickles_composition_types.Wrap.Proof_state.V1.t =
412
          { deferred_values :
×
413
              ( 'plonk
×
414
              , 'scalar_challenge
×
415
              , 'fp
×
416
              , 'bp_chals
×
417
              , 'index )
×
418
              Deferred_values.Stable.V1.t
×
419
          ; sponge_digest_before_evaluations : 'digest
×
420
          ; messages_for_next_wrap_proof : 'messages_for_next_wrap_proof
×
421
                (** Parts of the statement not needed by the other circuit. Represented as a hash inside the
422
              circuit which is then "unhashed". *)
423
          }
424
        [@@deriving sexp, compare, yojson, hlist, hash, equal]
105✔
425
      end
426
    end]
427

428
    module Minimal = struct
429
      [%%versioned
430
      module Stable = struct
431
        module V1 = struct
432
          type ( 'challenge
193✔
433
               , 'scalar_challenge
434
               , 'fp
435
               , 'bool
436
               , 'messages_for_next_wrap_proof
437
               , 'digest
438
               , 'bp_chals
439
               , 'index )
440
               t =
385✔
441
                ( 'challenge
442
                , 'scalar_challenge
443
                , 'fp
444
                , 'bool
445
                , 'messages_for_next_wrap_proof
446
                , 'digest
447
                , 'bp_chals
448
                , 'index )
449
                Mina_wire_types.Pickles_composition_types.Wrap.Proof_state
450
                .Minimal
451
                .V1
452
                .t =
453
            { deferred_values :
×
454
                ( 'challenge
×
455
                , 'scalar_challenge
×
456
                , 'fp
×
457
                , 'bool
×
458
                , 'bp_chals
×
459
                , 'index )
×
460
                Deferred_values.Minimal.Stable.V1.t
×
461
            ; sponge_digest_before_evaluations : 'digest
×
462
            ; messages_for_next_wrap_proof : 'messages_for_next_wrap_proof
×
463
                  (** Parts of the statement not needed by the other circuit. Represented as a hash inside the
464
              circuit which is then "unhashed". *)
465
            }
466
          [@@deriving sexp, compare, yojson, hash, equal]
105✔
467
        end
468
      end]
469
    end
470

471
    module In_circuit = struct
472
      type ( 'challenge
×
473
           , 'scalar_challenge
474
           , 'fp
475
           , 'fp_opt
476
           , 'lookup_opt
477
           , 'bool
478
           , 'messages_for_next_wrap_proof
479
           , 'digest
480
           , 'bp_chals
481
           , 'index )
482
           t =
483
        ( ( 'challenge
×
484
          , 'scalar_challenge
×
485
          , 'fp
×
486
          , 'fp_opt
×
487
          , 'lookup_opt
×
488
          , 'bool )
×
489
          Deferred_values.Plonk.In_circuit.t
×
490
        , 'scalar_challenge
×
491
        , 'fp
×
492
        , 'messages_for_next_wrap_proof
×
493
        , 'digest
×
494
        , 'bp_chals
×
495
        , 'index )
×
496
        Stable.Latest.t
×
497
      [@@deriving sexp, compare, yojson, hash, equal]
×
498

499
      let to_hlist, of_hlist = (to_hlist, of_hlist)
500

501
      let typ (type fp) ~dummy_scalar_challenge ~challenge ~scalar_challenge
502
          ~feature_flags (fp : (fp, _) Step_impl.Typ.t)
503
          messages_for_next_wrap_proof digest index =
504
        Step_impl.Typ.of_hlistable
40✔
505
          [ Deferred_values.In_circuit.typ ~dummy_scalar_challenge ~challenge
40✔
506
              ~scalar_challenge ~feature_flags fp index
507
          ; digest
508
          ; messages_for_next_wrap_proof
509
          ]
510
          ~var_to_hlist:to_hlist ~var_of_hlist:of_hlist ~value_to_hlist:to_hlist
511
          ~value_of_hlist:of_hlist
512
    end
513

514
    let to_minimal
515
        ({ deferred_values
516
         ; sponge_digest_before_evaluations
517
         ; messages_for_next_wrap_proof
518
         } :
519
          _ In_circuit.t ) ~to_option : _ Minimal.t =
520
      { deferred_values = Deferred_values.to_minimal ~to_option deferred_values
×
521
      ; sponge_digest_before_evaluations
522
      ; messages_for_next_wrap_proof
523
      }
524
  end
525

526
  (** The component of the proof accumulation state that is only computed on by the
527
      "stepping" proof system, and that can be handled opaquely by any "wrap" circuits. *)
528
  module Messages_for_next_step_proof = struct
529
    type ('g, 's, 'challenge_polynomial_commitments, 'bulletproof_challenges) t =
×
530
      { app_state : 's
×
531
            (** The actual application-level state (e.g., for Mina, this is the protocol state which contains the
532
    merkle root of the ledger, state related to consensus, etc.) *)
533
      ; dlog_plonk_index : 'g Plonk_verification_key_evals.t
×
534
            (** The verification key corresponding to the wrap-circuit for this recursive proof system.
535
          It gets threaded through all the circuits so that the step circuits can verify proofs against
536
          it.
537
      *)
538
      ; challenge_polynomial_commitments : 'challenge_polynomial_commitments
×
539
      ; old_bulletproof_challenges : 'bulletproof_challenges
×
540
      }
541
    [@@deriving sexp]
542

543
    let to_field_elements (type g f)
544
        { app_state
545
        ; dlog_plonk_index
546
        ; challenge_polynomial_commitments
547
        ; old_bulletproof_challenges
548
        } ~app_state:app_state_to_field_elements ~comm ~(g : g -> f list) =
549
      Array.concat
×
550
        [ index_to_field_elements ~g:comm dlog_plonk_index
×
551
        ; app_state_to_field_elements app_state
×
552
        ; Vector.map2 challenge_polynomial_commitments
×
553
            old_bulletproof_challenges ~f:(fun comm chals ->
554
              Array.append (Array.of_list (g comm)) (Vector.to_array chals) )
×
555
          |> Vector.to_list |> Array.concat
×
556
        ]
557

558
    let to_field_elements_without_index (type g f)
559
        { app_state
560
        ; dlog_plonk_index = _
561
        ; challenge_polynomial_commitments
562
        ; old_bulletproof_challenges
563
        } ~app_state:app_state_to_field_elements ~(g : g -> f list) =
564
      Array.concat
88✔
565
        [ app_state_to_field_elements app_state
88✔
566
        ; Vector.map2 challenge_polynomial_commitments
88✔
567
            old_bulletproof_challenges ~f:(fun comm chals ->
568
              Array.append (Array.of_list (g comm)) (Vector.to_array chals) )
120✔
569
          |> Vector.to_list |> Array.concat
88✔
570
        ]
571

572
    open Snarky_backendless.H_list
573

574
    let[@warning "-45"] to_hlist
575
        { app_state
576
        ; dlog_plonk_index
577
        ; challenge_polynomial_commitments
578
        ; old_bulletproof_challenges
579
        } =
580
      [ app_state
×
581
      ; dlog_plonk_index
582
      ; challenge_polynomial_commitments
583
      ; old_bulletproof_challenges
584
      ]
585

586
    let[@warning "-45"] of_hlist
587
        ([ app_state
588
         ; dlog_plonk_index
589
         ; challenge_polynomial_commitments
590
         ; old_bulletproof_challenges
591
         ] :
592
          (unit, _) t ) =
593
      { app_state
×
594
      ; dlog_plonk_index
595
      ; challenge_polynomial_commitments
596
      ; old_bulletproof_challenges
597
      }
598
  end
599

600
  module Lookup_parameters = struct
601
    (* Values needed for computing lookup parts of the verifier circuit. *)
602
    type ('chal, 'chal_var, 'fp, 'fp_var) t =
603
      { zero : ('chal, 'chal_var, 'fp, 'fp_var) Zero_values.t
604
      ; use : Opt.Flag.t
605
      }
606

607
    let opt_spec { zero = { value; var }; use } =
608
      Spec.T.Opt
94✔
609
        { inner = Struct [ Scalar Challenge ]
610
        ; flag = use
611
        ; dummy1 =
612
            [ Kimchi_backend_common.Scalar_challenge.create value.challenge ]
94✔
613
        ; dummy2 =
614
            [ Kimchi_backend_common.Scalar_challenge.create var.challenge ]
94✔
615
        }
616
  end
617

618
  (** This is the full statement for "wrap" proofs which contains
619
      - the application-level statement (app_state)
620
      - data needed to perform the final verification of the proof, which correspond
621
        to parts of incompletely verified proofs.
622
  *)
623
  module Statement = struct
624
    [%%versioned
625
    module Stable = struct
626
      module V1 = struct
627
        type ( 'plonk
×
628
             , 'scalar_challenge
629
             , 'fp
630
             , 'messages_for_next_wrap_proof
631
             , 'digest
632
             , 'messages_for_next_step_proof
633
             , 'bp_chals
634
             , 'index )
635
             t =
385✔
636
              ( 'plonk
637
              , 'scalar_challenge
638
              , 'fp
639
              , 'messages_for_next_wrap_proof
640
              , 'digest
641
              , 'messages_for_next_step_proof
642
              , 'bp_chals
643
              , 'index )
644
              Mina_wire_types.Pickles_composition_types.Wrap.Statement.V1.t =
645
          { proof_state :
×
646
              ( 'plonk
×
647
              , 'scalar_challenge
×
648
              , 'fp
×
649
              , 'messages_for_next_wrap_proof
×
650
              , 'digest
×
651
              , 'bp_chals
×
652
              , 'index )
×
653
              Proof_state.Stable.V1.t
×
654
          ; messages_for_next_step_proof : 'messages_for_next_step_proof
×
655
          }
656
        [@@deriving compare, yojson, sexp, hash, equal]
35✔
657
      end
658
    end]
659

660
    module Minimal = struct
661
      [%%versioned
662
      module Stable = struct
663
        module V1 = struct
664
          type ( 'challenge
156✔
665
               , 'scalar_challenge
666
               , 'fp
667
               , 'bool
668
               , 'messages_for_next_wrap_proof
669
               , 'digest
670
               , 'messages_for_next_step_proof
671
               , 'bp_chals
672
               , 'index )
673
               t =
420✔
674
                ( 'challenge
675
                , 'scalar_challenge
676
                , 'fp
677
                , 'bool
678
                , 'messages_for_next_wrap_proof
679
                , 'digest
680
                , 'messages_for_next_step_proof
681
                , 'bp_chals
682
                , 'index )
683
                Mina_wire_types.Pickles_composition_types.Wrap.Statement.Minimal
684
                .V1
685
                .t =
686
            { proof_state :
×
687
                ( 'challenge
×
688
                , 'scalar_challenge
×
689
                , 'fp
×
690
                , 'bool
×
691
                , 'messages_for_next_wrap_proof
×
692
                , 'digest
×
693
                , 'bp_chals
×
694
                , 'index )
×
695
                Proof_state.Minimal.Stable.V1.t
×
696
            ; messages_for_next_step_proof : 'messages_for_next_step_proof
×
697
            }
698
          [@@deriving compare, yojson, sexp, hash, equal]
105✔
699
        end
700
      end]
701
    end
702

703
    module In_circuit = struct
704
      type ( 'challenge
×
705
           , 'scalar_challenge
706
           , 'fp
707
           , 'fp_opt
708
           , 'lookup_opt
709
           , 'bool
710
           , 'messages_for_next_wrap_proof
711
           , 'digest
712
           , 'messages_for_next_step_proof
713
           , 'bp_chals
714
           , 'index )
715
           t =
716
        ( ( 'challenge
×
717
          , 'scalar_challenge
×
718
          , 'fp
×
719
          , 'fp_opt
×
720
          , 'lookup_opt
×
721
          , 'bool )
×
722
          Proof_state.Deferred_values.Plonk.In_circuit.t
×
723
        , 'scalar_challenge
×
724
        , 'fp
×
725
        , 'messages_for_next_wrap_proof
×
726
        , 'digest
×
727
        , 'messages_for_next_step_proof
×
728
        , 'bp_chals
×
729
        , 'index )
×
730
        Stable.Latest.t
×
731
      [@@deriving compare, yojson, sexp, hash, equal]
×
732

733
      (** A layout of the raw data in a statement, which is needed for
734
          representing it inside the circuit. *)
735
      let spec impl lookup feature_flags =
736
        let feature_flags_spec =
94✔
737
          let [ f1; f2; f3; f4; f5; f6; f7; f8 ] =
738
            (* Ensure that layout is the same *)
739
            Plonk_types.Features.to_data feature_flags
740
          in
741
          let constant x =
94✔
742
            Spec.T.Constant (x, (fun x y -> assert (Bool.equal x y)), B Bool)
×
743
          in
744
          let maybe_constant flag =
745
            match flag with
752✔
746
            | Opt.Flag.Yes ->
×
747
                constant true
748
            | Opt.Flag.No ->
320✔
749
                constant false
750
            | Opt.Flag.Maybe ->
432✔
751
                Spec.T.B Bool
752
          in
753
          Spec.T.Struct
754
            [ maybe_constant f1
94✔
755
            ; maybe_constant f2
94✔
756
            ; maybe_constant f3
94✔
757
            ; maybe_constant f4
94✔
758
            ; maybe_constant f5
94✔
759
            ; maybe_constant f6
94✔
760
            ; maybe_constant f7
94✔
761
            ; maybe_constant f8
94✔
762
            ]
763
        in
764
        Spec.T.Struct
765
          [ Vector (B Field, Nat.N5.n)
766
          ; Vector (B Challenge, Nat.N2.n)
767
          ; Vector (Scalar Challenge, Nat.N3.n)
768
          ; Vector (B Digest, Nat.N3.n)
769
          ; Vector (B Bulletproof_challenge, Backend.Tick.Rounds.n)
770
          ; Vector (B Branch_data, Nat.N1.n)
771
          ; feature_flags_spec
772
          ; Lookup_parameters.opt_spec lookup
94✔
773
          ]
774

775
      (** Convert a statement (as structured data) into the flat data-based representation. *)
776
      let[@warning "-45"] to_data
777
          ({ proof_state =
778
               { deferred_values =
779
                   { xi
780
                   ; combined_inner_product
781
                   ; b
782
                   ; branch_data
783
                   ; bulletproof_challenges
784
                   ; plonk =
785
                       { alpha
786
                       ; beta
787
                       ; gamma
788
                       ; zeta
789
                       ; zeta_to_srs_length
790
                       ; zeta_to_domain_size
791
                       ; perm
792
                       ; feature_flags
793
                       ; joint_combiner
794
                       }
795
                   }
796
               ; sponge_digest_before_evaluations
797
               ; messages_for_next_wrap_proof
798
                 (* messages_for_next_wrap_proof is represented as a digest (and then unhashed) inside the circuit *)
799
               }
800
           ; messages_for_next_step_proof
801
             (* messages_for_next_step_proof is represented as a digest inside the circuit *)
802
           } :
803
            _ t ) ~option_map =
804
        let open Vector in
40✔
805
        let fp =
806
          [ combined_inner_product
807
          ; b
808
          ; zeta_to_srs_length
809
          ; zeta_to_domain_size
810
          ; perm
811
          ]
812
        in
813
        let challenge = [ beta; gamma ] in
814
        let scalar_challenge = [ alpha; zeta; xi ] in
815
        let digest =
816
          [ sponge_digest_before_evaluations
817
          ; messages_for_next_wrap_proof
818
          ; messages_for_next_step_proof
819
          ]
820
        in
821
        let index = [ branch_data ] in
822
        Hlist.HlistId.
823
          [ fp
824
          ; challenge
825
          ; scalar_challenge
826
          ; digest
827
          ; bulletproof_challenges
828
          ; index
829
          ; Plonk_types.Features.to_data feature_flags
40✔
830
          ; option_map joint_combiner ~f:(fun x -> Hlist.HlistId.[ x ])
8✔
831
          ]
832

833
      (** Construct a statement (as structured data) from the flat data-based representation. *)
834
      let[@warning "-45"] of_data
835
          Hlist.HlistId.
836
            [ fp
837
            ; challenge
838
            ; scalar_challenge
839
            ; digest
840
            ; bulletproof_challenges
841
            ; index
842
            ; feature_flags
843
            ; joint_combiner
844
            ] ~option_map : _ t =
845
        let open Vector in
8✔
846
        let [ combined_inner_product
847
            ; b
848
            ; zeta_to_srs_length
849
            ; zeta_to_domain_size
850
            ; perm
851
            ] =
852
          fp
853
        in
854
        let [ beta; gamma ] = challenge in
855
        let [ alpha; zeta; xi ] = scalar_challenge in
856
        let [ sponge_digest_before_evaluations
857
            ; messages_for_next_wrap_proof
858
            ; messages_for_next_step_proof
859
            ] =
860
          digest
861
        in
862
        let [ branch_data ] = index in
863
        let feature_flags = Plonk_types.Features.of_data feature_flags in
864
        { proof_state =
8✔
865
            { deferred_values =
866
                { xi
867
                ; combined_inner_product
868
                ; b
869
                ; branch_data
870
                ; bulletproof_challenges
871
                ; plonk =
872
                    { alpha
873
                    ; beta
874
                    ; gamma
875
                    ; zeta
876
                    ; zeta_to_srs_length
877
                    ; zeta_to_domain_size
878
                    ; perm
879
                    ; feature_flags
880
                    ; joint_combiner =
881
                        option_map joint_combiner ~f:(fun Hlist.HlistId.[ x ] ->
8✔
882
                            x )
×
883
                    }
884
                }
885
            ; sponge_digest_before_evaluations
886
            ; messages_for_next_wrap_proof
887
            }
888
        ; messages_for_next_step_proof
889
        }
890
    end
891

892
    let to_minimal
893
        ({ proof_state; messages_for_next_step_proof } : _ In_circuit.t)
894
        ~to_option : _ Minimal.t =
895
      { proof_state = Proof_state.to_minimal ~to_option proof_state
×
896
      ; messages_for_next_step_proof
897
      }
898
  end
899
end
900

901
module Step = struct
902
  module Plonk_polys = Nat.N10
903

904
  module Bulletproof = struct
905
    include Plonk_types.Openings.Bulletproof
906

907
    module Advice = struct
908
      (** This is data that can be computed in linear time from the proof + statement.
909

910
          It doesn't need to be sent on the wire, but it does need to be provided to the verifier
911
      *)
912
      type 'fq t =
×
913
        { b : 'fq
914
        ; combined_inner_product : 'fq (* sum_i r^i sum_j xi^j f_j(pt_i) *)
915
        }
916
      [@@deriving hlist]
917
    end
918
  end
919

920
  module Proof_state = struct
921
    module Deferred_values = struct
922
      module Plonk = struct
923
        module Minimal = struct
924
          [%%versioned
925
          module Stable = struct
926
            module V1 = struct
927
              (** Challenges from the PLONK IOP. These, plus the evaluations that are already in the proof, are
928
                  all that's needed to derive all the values in the [In_circuit] version below.
929

930
                  See src/lib/pickles/plonk_checks/plonk_checks.ml for the computation of the [In_circuit] value
931
                  from the [Minimal] value.
932
              *)
933
              type ('challenge, 'scalar_challenge) t =
×
934
                { alpha : 'scalar_challenge
×
935
                ; beta : 'challenge
×
936
                ; gamma : 'challenge
×
937
                ; zeta : 'scalar_challenge
×
938
                }
939
              [@@deriving sexp, compare, yojson, hlist, hash, equal]
35✔
940
            end
941
          end]
942

943
          let to_wrap ~feature_flags { alpha; beta; gamma; zeta } :
944
              _ Wrap.Proof_state.Deferred_values.Plonk.Minimal.t =
945
            { alpha; beta; gamma; zeta; joint_combiner = None; feature_flags }
16✔
946

947
          let of_wrap
948
              ({ alpha
949
               ; beta
950
               ; gamma
951
               ; zeta
952
               ; joint_combiner = _
953
               ; feature_flags = _
954
               } :
955
                _ Wrap.Proof_state.Deferred_values.Plonk.Minimal.t ) =
956
            { alpha; beta; gamma; zeta }
×
957
        end
958

959
        open Pickles_types
960

961
        module In_circuit = struct
962
          (** All scalar values deferred by a verifier circuit.
963
              The values in [vbmul], [complete_add], [endomul], [endomul_scalar], and [perm]
964
              are all scalars which will have been used to scale selector polynomials during the
965
              computation of the linearized polynomial commitment.
966

967
              Then, we expose them so the next guy (who can do scalar arithmetic) can check that they
968
              were computed correctly from the evaluations in the proof and the challenges.
969
          *)
970
          type ('challenge, 'scalar_challenge, 'fp) t =
×
971
            { alpha : 'scalar_challenge
×
972
            ; beta : 'challenge
×
973
            ; gamma : 'challenge
×
974
            ; zeta : 'scalar_challenge
×
975
                  (* TODO: zeta_to_srs_length is kind of unnecessary.
976
                     Try to get rid of it when you can.
977
                  *)
978
            ; zeta_to_srs_length : 'fp
×
979
            ; zeta_to_domain_size : 'fp
×
980
            ; perm : 'fp
×
981
                  (** scalar used on one of the permutation polynomial commitments. *)
982
            }
983
          [@@deriving sexp, compare, yojson, hlist, hash, equal, fields]
984

985
          let to_wrap ~opt_none ~false_
986
              { alpha
987
              ; beta
988
              ; gamma
989
              ; zeta
990
              ; zeta_to_srs_length
991
              ; zeta_to_domain_size
992
              ; perm
993
              } : _ Wrap.Proof_state.Deferred_values.Plonk.In_circuit.t =
994
            { alpha
56✔
995
            ; beta
996
            ; gamma
997
            ; zeta
998
            ; zeta_to_srs_length
999
            ; zeta_to_domain_size
1000
            ; perm
1001
            ; feature_flags =
1002
                { range_check0 = false_
1003
                ; range_check1 = false_
1004
                ; foreign_field_add = false_
1005
                ; foreign_field_mul = false_
1006
                ; xor = false_
1007
                ; rot = false_
1008
                ; lookup = false_
1009
                ; runtime_tables = false_
1010
                }
1011
            ; joint_combiner = opt_none
1012
            }
1013

1014
          let of_wrap ~assert_none ~assert_false
1015
              ({ alpha
1016
               ; beta
1017
               ; gamma
1018
               ; zeta
1019
               ; zeta_to_srs_length
1020
               ; zeta_to_domain_size
1021
               ; perm
1022
               ; feature_flags
1023
               ; joint_combiner
1024
               } :
1025
                _ Wrap.Proof_state.Deferred_values.Plonk.In_circuit.t ) =
1026
            let () =
4✔
1027
              let { Plonk_types.Features.range_check0
1028
                  ; range_check1
1029
                  ; foreign_field_add
1030
                  ; foreign_field_mul
1031
                  ; xor
1032
                  ; rot
1033
                  ; lookup
1034
                  ; runtime_tables
1035
                  } =
1036
                feature_flags
1037
              in
1038
              assert_false range_check0 ;
1039
              assert_false range_check1 ;
4✔
1040
              assert_false foreign_field_add ;
4✔
1041
              assert_false foreign_field_mul ;
4✔
1042
              assert_false xor ;
4✔
1043
              assert_false rot ;
4✔
1044
              assert_false lookup ;
4✔
1045
              assert_false runtime_tables
4✔
1046
            in
1047
            assert_none joint_combiner ;
1048
            { alpha
4✔
1049
            ; beta
1050
            ; gamma
1051
            ; zeta
1052
            ; zeta_to_srs_length
1053
            ; zeta_to_domain_size
1054
            ; perm
1055
            }
1056

1057
          let map_challenges t ~f ~scalar =
1058
            { t with
16✔
1059
              alpha = scalar t.alpha
16✔
1060
            ; beta = f t.beta
16✔
1061
            ; gamma = f t.gamma
16✔
1062
            ; zeta = scalar t.zeta
16✔
1063
            }
1064

1065
          let map_fields t ~f =
1066
            { t with
16✔
1067
              zeta_to_srs_length = f t.zeta_to_srs_length
16✔
1068
            ; zeta_to_domain_size = f t.zeta_to_domain_size
16✔
1069
            ; perm = f t.perm
16✔
1070
            }
1071
        end
1072

1073
        let to_minimal (type challenge scalar_challenge fp)
1074
            (t : (challenge, scalar_challenge, fp) In_circuit.t) :
1075
            (challenge, scalar_challenge) Minimal.t =
1076
          { alpha = t.alpha; beta = t.beta; zeta = t.zeta; gamma = t.gamma }
16✔
1077
      end
1078

1079
      (** All the scalar-field values needed to finalize the verification of a proof
1080
    by checking that the correct values were used in the "group operations" part of the
1081
    verifier.
1082

1083
    Consists of some evaluations of PLONK polynomials (columns, permutation aggregation, etc.)
1084
    and the remainder are things related to the inner product argument.
1085
*)
1086
      type ('plonk, 'scalar_challenge, 'fq, 'bulletproof_challenges) t_ =
×
1087
        { plonk : 'plonk
×
1088
        ; combined_inner_product : 'fq
×
1089
              (** combined_inner_product = sum_{i < num_evaluation_points} sum_{j < num_polys} r^i xi^j f_j(pt_i) *)
1090
        ; xi : 'scalar_challenge
×
1091
              (** The challenge used for combining polynomials *)
1092
        ; bulletproof_challenges : 'bulletproof_challenges
×
1093
              (** The challenges from the inner-product argument that was partially verified. *)
1094
        ; b : 'fq
×
1095
              (** b = challenge_poly plonk.zeta + r * challenge_poly (domain_generrator * plonk.zeta)
1096
                where challenge_poly(x) = \prod_i (1 + bulletproof_challenges.(i) * x^{2^{k - 1 - i}})
1097
            *)
1098
        }
1099
      [@@deriving sexp, compare, yojson]
1100

1101
      module Minimal = struct
1102
        type ('challenge, 'scalar_challenge, 'fq, 'bulletproof_challenges) t =
×
1103
          ( ('challenge, 'scalar_challenge) Plonk.Minimal.t
×
1104
          , 'scalar_challenge
×
1105
          , 'fq
×
1106
          , 'bulletproof_challenges )
×
1107
          t_
×
1108
        [@@deriving sexp, compare, yojson]
×
1109
      end
1110

1111
      module In_circuit = struct
1112
        type ('challenge, 'scalar_challenge, 'fq, 'bulletproof_challenges) t =
×
1113
          ( ('challenge, 'scalar_challenge, 'fq) Plonk.In_circuit.t
×
1114
          , 'scalar_challenge
×
1115
          , 'fq
×
1116
          , 'bulletproof_challenges )
×
1117
          t_
×
1118
        [@@deriving sexp, compare, yojson]
×
1119
      end
1120
    end
1121

1122
    module Messages_for_next_wrap_proof =
1123
      Wrap.Proof_state.Messages_for_next_wrap_proof
1124
    module Messages_for_next_step_proof = Wrap.Messages_for_next_step_proof
1125

1126
    module Per_proof = struct
1127
      (** For each proof that a step circuit verifies, we do not verify the whole proof.
1128
          Specifically,
1129
          - we defer calculations involving the "other field" (i.e., the scalar-field of the group
1130
            elements involved in the proof.
1131
          - we do not fully verify the inner-product argument as that would be O(n) and instead
1132
            do the accumulator trick.
1133

1134
          As a result, for each proof that a step circuit verifies, we must expose some data
1135
          related to it as part of the step circuit's statement, in order to allow those proofs
1136
          to be fully verified eventually.
1137

1138
          This is that data. *)
1139
      type ( 'plonk
×
1140
           , 'scalar_challenge
1141
           , 'fq
1142
           , 'bulletproof_challenges
1143
           , 'digest
1144
           , 'bool )
1145
           t_ =
1146
        { deferred_values :
×
1147
            ( 'plonk
×
1148
            , 'scalar_challenge
×
1149
            , 'fq
×
1150
            , 'bulletproof_challenges )
×
1151
            Deferred_values.t_
×
1152
              (** Scalar values related to the proof *)
1153
        ; should_finalize : 'bool
×
1154
              (** We allow circuits in pickles proof systems to decide if it's OK that a proof did
1155
    not recursively verify. In that case, when we expose the unfinalized bits, we need
1156
    to communicate that it's OK if those bits do not "finalize". That's what this boolean
1157
    is for. *)
1158
        ; sponge_digest_before_evaluations : 'digest
×
1159
        }
1160
      [@@deriving sexp, compare, yojson]
×
1161

1162
      module Minimal = struct
1163
        type ( 'challenge
×
1164
             , 'scalar_challenge
1165
             , 'fq
1166
             , 'bulletproof_challenges
1167
             , 'digest
1168
             , 'bool )
1169
             t =
1170
          ( ('challenge, 'scalar_challenge) Deferred_values.Plonk.Minimal.t
×
1171
          , 'scalar_challenge
×
1172
          , 'fq
×
1173
          , 'bulletproof_challenges
×
1174
          , 'digest
×
1175
          , 'bool )
×
1176
          t_
×
1177
        [@@deriving sexp, compare, yojson]
×
1178
      end
1179

1180
      module In_circuit = struct
1181
        type ( 'challenge
×
1182
             , 'scalar_challenge
1183
             , 'fq
1184
             , 'bulletproof_challenges
1185
             , 'digest
1186
             , 'bool )
1187
             t =
1188
          ( ( 'challenge
×
1189
            , 'scalar_challenge
×
1190
            , 'fq )
×
1191
            Deferred_values.Plonk.In_circuit.t
×
1192
          , 'scalar_challenge
×
1193
          , 'fq
×
1194
          , 'bulletproof_challenges
×
1195
          , 'digest
×
1196
          , 'bool )
×
1197
          t_
×
1198
        [@@deriving sexp, compare, yojson]
×
1199

1200
        (** A layout of the raw data in this value, which is needed for
1201
          representing it inside the circuit. *)
1202
        let spec bp_log2 =
1203
          Spec.T.Struct
100✔
1204
            [ Vector (B Field, Nat.N5.n)
1205
            ; Vector (B Digest, Nat.N1.n)
1206
            ; Vector (B Challenge, Nat.N2.n)
1207
            ; Vector (Scalar Challenge, Nat.N3.n)
1208
            ; Vector (B Bulletproof_challenge, bp_log2)
1209
            ; Vector (B Bool, Nat.N1.n)
1210
            ]
1211

1212
        let[@warning "-45"] to_data
1213
            ({ deferred_values =
1214
                 { xi
1215
                 ; bulletproof_challenges
1216
                 ; b
1217
                 ; combined_inner_product
1218
                 ; plonk =
1219
                     { alpha
1220
                     ; beta
1221
                     ; gamma
1222
                     ; zeta
1223
                     ; zeta_to_srs_length
1224
                     ; zeta_to_domain_size
1225
                     ; perm
1226
                     }
1227
                 }
1228
             ; should_finalize
1229
             ; sponge_digest_before_evaluations
1230
             } :
1231
              _ t ) =
1232
          let open Vector in
172✔
1233
          let fq =
1234
            [ combined_inner_product
1235
            ; b
1236
            ; zeta_to_srs_length
1237
            ; zeta_to_domain_size
1238
            ; perm
1239
            ]
1240
          in
1241
          let challenge = [ beta; gamma ] in
1242
          let scalar_challenge = [ alpha; zeta; xi ] in
1243
          let digest = [ sponge_digest_before_evaluations ] in
1244
          let bool = [ should_finalize ] in
1245
          let open Hlist.HlistId in
1246
          [ fq
1247
          ; digest
1248
          ; challenge
1249
          ; scalar_challenge
1250
          ; bulletproof_challenges
1251
          ; bool
1252
          ]
1253

1254
        let[@warning "-45"] of_data
1255
            Hlist.HlistId.
1256
              [ Vector.
1257
                  [ combined_inner_product
1258
                  ; b
1259
                  ; zeta_to_srs_length
1260
                  ; zeta_to_domain_size
1261
                  ; perm
1262
                  ]
1263
              ; Vector.[ sponge_digest_before_evaluations ]
1264
              ; Vector.[ beta; gamma ]
1265
              ; Vector.[ alpha; zeta; xi ]
1266
              ; bulletproof_challenges
1267
              ; Vector.[ should_finalize ]
1268
              ] : _ t =
1269
          { deferred_values =
60✔
1270
              { xi
1271
              ; bulletproof_challenges
1272
              ; b
1273
              ; combined_inner_product
1274
              ; plonk =
1275
                  { alpha
1276
                  ; beta
1277
                  ; gamma
1278
                  ; zeta
1279
                  ; zeta_to_srs_length
1280
                  ; zeta_to_domain_size
1281
                  ; perm
1282
                  }
1283
              }
1284
          ; should_finalize
1285
          ; sponge_digest_before_evaluations
1286
          }
1287
      end
1288

1289
      let typ fq ~assert_16_bits =
1290
        let open In_circuit in
44✔
1291
        Spec.typ fq ~assert_16_bits (spec Backend.Tock.Rounds.n)
44✔
1292
        |> Step_impl.Typ.transport ~there:to_data ~back:of_data
44✔
1293
        |> Step_impl.Typ.transport_var ~there:to_data ~back:of_data
1294

1295
      let wrap_typ fq ~assert_16_bits =
1296
        let open In_circuit in
16✔
1297
        Spec.wrap_typ fq ~assert_16_bits (spec Backend.Tock.Rounds.n)
16✔
1298
        |> Wrap_impl.Typ.transport ~there:to_data ~back:of_data
16✔
1299
        |> Wrap_impl.Typ.transport_var ~there:to_data ~back:of_data
1300
    end
1301

1302
    type ('unfinalized_proofs, 'messages_for_next_step_proof) t =
16✔
1303
      { unfinalized_proofs : 'unfinalized_proofs
×
1304
            (** A vector of the "per-proof" structures defined above, one for each proof
1305
    that the step-circuit partially verifies. *)
1306
      ; messages_for_next_step_proof : 'messages_for_next_step_proof
×
1307
            (** The component of the proof accumulation state that is only computed on by the
1308
          "stepping" proof system, and that can be handled opaquely by any "wrap" circuits. *)
1309
      }
1310
    [@@deriving sexp, compare, yojson, hlist]
1311

1312
    let spec unfinalized_proofs messages_for_next_step_proof =
1313
      Spec.T.Struct [ unfinalized_proofs; messages_for_next_step_proof ]
×
1314

1315
    include struct
1316
      open Hlist.HlistId
1317

1318
      let _to_data { unfinalized_proofs; messages_for_next_step_proof } =
1319
        [ Vector.map unfinalized_proofs ~f:Per_proof.In_circuit.to_data
×
1320
        ; messages_for_next_step_proof
1321
        ]
1322

1323
      let _of_data [ unfinalized_proofs; messages_for_next_step_proof ] =
1324
        { unfinalized_proofs =
×
1325
            Vector.map unfinalized_proofs ~f:Per_proof.In_circuit.of_data
×
1326
        ; messages_for_next_step_proof
1327
        }
1328
    end [@@warning "-45"]
1329

1330
    let[@warning "-60"] wrap_typ (type n) ~assert_16_bits
1331
        (proofs_verified : (Opt.Flag.t Plonk_types.Features.t, n) Vector.t) fq :
1332
        (((_, _) Vector.t, _) t, ((_, _) Vector.t, _) t) Wrap_impl.Typ.t =
1333
      let per_proof _ = Per_proof.wrap_typ fq ~assert_16_bits in
8✔
1334
      let unfinalized_proofs =
1335
        Vector.wrap_typ' (Vector.map proofs_verified ~f:per_proof)
8✔
1336
      in
1337
      let messages_for_next_step_proof =
8✔
1338
        Spec.wrap_typ fq ~assert_16_bits (B Spec.Digest)
1339
      in
1340
      Wrap_impl.Typ.of_hlistable
8✔
1341
        [ unfinalized_proofs; messages_for_next_step_proof ]
1342
        ~var_to_hlist:to_hlist ~var_of_hlist:of_hlist ~value_to_hlist:to_hlist
1343
        ~value_of_hlist:of_hlist
1344
  end
1345

1346
  module Statement = struct
1347
    type ( 'unfinalized_proofs
×
1348
         , 'messages_for_next_step_proof
1349
         , 'messages_for_next_wrap_proof )
1350
         t =
1351
      { proof_state :
×
1352
          ('unfinalized_proofs, 'messages_for_next_step_proof) Proof_state.t
×
1353
      ; messages_for_next_wrap_proof : 'messages_for_next_wrap_proof
×
1354
            (** The component of the proof accumulation state that is only computed on by the
1355
        "wrapping" proof system, and that can be handled opaquely by any "step" circuits. *)
1356
      }
1357
    [@@deriving sexp, compare, yojson]
×
1358

1359
    let[@warning "-45"] to_data
1360
        { proof_state = { unfinalized_proofs; messages_for_next_step_proof }
1361
        ; messages_for_next_wrap_proof
1362
        } =
1363
      let open Hlist.HlistId in
56✔
1364
      [ Vector.map unfinalized_proofs
56✔
1365
          ~f:Proof_state.Per_proof.In_circuit.to_data
1366
      ; messages_for_next_step_proof
1367
      ; messages_for_next_wrap_proof
1368
      ]
1369

1370
    let[@warning "-45"] of_data
1371
        Hlist.HlistId.
1372
          [ unfinalized_proofs
1373
          ; messages_for_next_step_proof
1374
          ; messages_for_next_wrap_proof
1375
          ] =
1376
      { proof_state =
×
1377
          { unfinalized_proofs =
1378
              Vector.map unfinalized_proofs
×
1379
                ~f:Proof_state.Per_proof.In_circuit.of_data
1380
          ; messages_for_next_step_proof
1381
          }
1382
      ; messages_for_next_wrap_proof
1383
      }
1384

1385
    let spec proofs_verified bp_log2 =
1386
      let per_proof = Proof_state.Per_proof.In_circuit.spec bp_log2 in
40✔
1387
      Spec.T.Struct
40✔
1388
        [ Vector (per_proof, proofs_verified)
1389
        ; B Digest
1390
        ; Vector (B Digest, proofs_verified)
1391
        ]
1392
  end
1393
end
1394

1395
module Nvector = Vector.With_length
1396
module Wrap_bp_vec = Backend.Tock.Rounds_vector
1397
module Step_bp_vec = Backend.Tick.Rounds_vector
1398

1399
module Challenges_vector = struct
1400
  type 'n t = (Wrap_impl.Field.t Wrap_bp_vec.t, 'n) Vector.t
1401

1402
  module Constant = struct
1403
    type 'n t = (Wrap_impl.Field.Constant.t Wrap_bp_vec.t, 'n) Vector.t
1404
  end
1405
end
70✔
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc