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

MinaProtocol / mina / 2863

05 Nov 2024 06:20PM UTC coverage: 30.754% (-16.6%) from 47.311%
2863

push

buildkite

web-flow
Merge pull request #16296 from MinaProtocol/dkijania/more_multi_jobs

more multi jobs in CI

20276 of 65930 relevant lines covered (30.75%)

8631.7 hits per line

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

17.81
/src/lib/snark_bits/bits.ml
1
(* bits.ml *)
2

9✔
3
open Core_kernel
4
open Fold_lib
5
open Bitstring_lib
6

7
(* Someday: Make more efficient by giving Field.unpack a length argument in
8
   camlsnark *)
9
let unpack_field unpack ~bit_length x = List.take (unpack x) bit_length
×
10

11
let bits_per_char = 8
12

13
let pad (type a) ~length ~default (bs : a Bitstring.Lsb_first.t) =
14
  let bs = (bs :> a list) in
×
15
  let padding = length - List.length bs in
×
16
  assert (padding >= 0) ;
×
17
  bs @ List.init padding ~f:(fun _ -> default)
×
18

19
module Vector = struct
20
  module type Basic = sig
21
    type t
22

23
    val length : int
24

25
    val get : t -> int -> bool
26

27
    val set : t -> int -> bool -> t
28
  end
29

30
  module type S = sig
31
    include Basic
32

33
    val empty : t
34

35
    val set : t -> int -> bool -> t
36
  end
37

38
  module UInt64 : S with type t = Unsigned.UInt64.t = struct
39
    open Unsigned.UInt64.Infix
40
    include Unsigned.UInt64
41

42
    let length = 64
43

44
    let empty = zero
45

46
    let get t i = equal ((t lsr i) land one) one
103,168✔
47

48
    let set t i b = if b then t lor (one lsl i) else t land lognot (one lsl i)
×
49
  end
50

51
  module UInt32 : S with type t = Unsigned.UInt32.t = struct
52
    open Unsigned.UInt32.Infix
53
    include Unsigned.UInt32
54

55
    let length = 32
56

57
    let empty = zero
58

59
    let get t i = equal ((t lsr i) land one) one
340,480✔
60

61
    let set t i b = if b then t lor (one lsl i) else t land lognot (one lsl i)
×
62
  end
63

64
  module Make (V : S) : Bits_intf.Convertible_bits with type t = V.t = struct
65
    type t = V.t
66

67
    let fold t =
68
      { Fold.fold =
×
69
          (fun ~init ~f ->
70
            let rec go acc i =
×
71
              if i = V.length then acc else go (f acc (V.get t i)) (i + 1)
×
72
            in
73
            go init 0 )
74
      }
75

76
    let iter t ~f =
77
      for i = 0 to V.length - 1 do
×
78
        f (V.get t i)
×
79
      done
80

81
    let to_bits t = List.init V.length ~f:(V.get t)
75,136✔
82

83
    let of_bits bools =
84
      List.foldi bools ~init:V.empty ~f:(fun i t bool -> V.set t i bool)
×
85

86
    let size_in_bits = V.length
87
  end
88
end
89

90
module UInt64 : Bits_intf.Convertible_bits with type t := Unsigned.UInt64.t =
91
  Vector.Make (Vector.UInt64)
92

93
module UInt32 : Bits_intf.Convertible_bits with type t := Unsigned.UInt32.t =
94
  Vector.Make (Vector.UInt32)
95

96
module type Big_int_intf = sig
97
  include Snarky_backendless.Bigint_intf.S
98

99
  val to_field : t -> field
100
end
101

102
module Make_field0
103
    (Field : Snarky_backendless.Field_intf.S)
104
    (Bigint : Big_int_intf with type field := Field.t) (M : sig
105
      val bit_length : int
106
    end) : Bits_intf.S with type t = Field.t = struct
107
  open M
108

109
  type t = Field.t
110

111
  let fold t =
112
    { Fold.fold =
×
113
        (fun ~init ~f ->
114
          let n = Bigint.of_field t in
×
115
          let rec go acc i =
×
116
            if i = bit_length then acc
×
117
            else go (f acc (Bigint.test_bit n i)) (i + 1)
×
118
          in
119
          go init 0 )
120
    }
121

122
  let iter t ~f =
123
    let n = Bigint.of_field t in
×
124
    for i = 0 to bit_length - 1 do
×
125
      f (Bigint.test_bit n i)
×
126
    done
127

128
  let to_bits t =
129
    let n = Bigint.of_field t in
9✔
130
    let rec go acc i =
9✔
131
      if i < 0 then acc else go (Bigint.test_bit n i :: acc) (i - 1)
9✔
132
    in
133
    go [] (bit_length - 1)
134

135
  let size_in_bits = bit_length
136
end
137

138
module Make_field
139
    (Field : Snarky_backendless.Field_intf.S)
140
    (Bigint : Big_int_intf with type field := Field.t) :
141
  Bits_intf.S with type t = Field.t =
142
  Make_field0 (Field) (Bigint)
143
    (struct
144
      let bit_length = Field.size_in_bits
145
    end)
146

147
module Small
148
    (Field : Snarky_backendless.Field_intf.S)
149
    (Bigint : Big_int_intf with type field := Field.t) (M : sig
150
      val bit_length : int
151
    end) : Bits_intf.S with type t = Field.t = struct
152
  let () = assert (M.bit_length < Field.size_in_bits)
×
153

154
  include Make_field0 (Field) (Bigint) (M)
155
end
156

157
module Snarkable = struct
158
  module Small_bit_vector
159
      (Impl : Snarky_backendless.Snark_intf.S) (V : sig
160
        type t
161

162
        val empty : t
163

164
        val length : int
165

166
        val get : t -> int -> bool
167

168
        val set : t -> int -> bool -> t
169
      end) :
170
    Bits_intf.Snarkable.Small
171
      with type ('a, 'b) typ := ('a, 'b) Impl.Typ.t
172
       and type 'a checked := 'a Impl.Checked.t
173
       and type boolean_var := Impl.Boolean.var
174
       and type field_var := Impl.Field.Var.t
175
       and type Packed.var = Impl.Field.Var.t
176
       and type Packed.value = V.t
177
       and type Unpacked.var = Impl.Boolean.var list
178
       and type Unpacked.value = V.t
179
       and type comparison_result := Impl.Field.Checked.comparison_result =
180
  struct
181
    open Impl
182

183
    let bit_length = V.length
184

185
    let () = assert (bit_length < Field.size_in_bits)
18✔
186

187
    let size_in_bits = bit_length
188

189
    let init ~f =
190
      let rec go acc i =
×
191
        if i = V.length then acc else go (V.set acc i (f i)) (i + 1)
×
192
      in
193
      go V.empty 0
194

195
    module Packed = struct
196
      type var = Field.Var.t
197

198
      type value = V.t
199

200
      let typ : (var, value) Typ.t =
201
        Field.typ
202
        |> Typ.transport
18✔
203
             ~there:(fun t ->
204
               let rec go two_to_the_i i acc =
×
205
                 if i = V.length then acc
×
206
                 else
207
                   let acc =
×
208
                     if V.get t i then Field.add two_to_the_i acc else acc
×
209
                   in
210
                   go (Field.add two_to_the_i two_to_the_i) (i + 1) acc
×
211
               in
212
               go Field.one 0 Field.zero )
213
             ~back:(fun t ->
214
               let n = Bigint.of_field t in
×
215
               init ~f:(fun i -> Bigint.test_bit n i) )
×
216

217
      let size_in_bits = size_in_bits
218
    end
219

220
    let v_to_list n v =
221
      List.init n ~f:(fun i -> if i < V.length then V.get v i else false)
×
222

223
    let v_of_list vs =
224
      List.foldi vs ~init:V.empty ~f:(fun i acc b ->
×
225
          if i < V.length then V.set acc i b else acc )
×
226

227
    let pack_var = Field.Var.project
228

229
    let pack_value = Fn.id
230

231
    module Unpacked = struct
232
      type var = Boolean.var list
233

234
      type value = V.t
235

236
      let typ : (var, value) Typ.t =
237
        Typ.transport
18✔
238
          (Typ.list ~length:V.length Boolean.typ)
18✔
239
          ~there:(v_to_list V.length) ~back:v_of_list
18✔
240

241
      let var_to_bits = Bitstring.Lsb_first.of_list
242

243
      let var_of_bits = pad ~length:V.length ~default:Boolean.false_
244

245
      let var_to_triples (bs : var) =
246
        Bitstring_lib.Bitstring.pad_to_triple_list ~default:Boolean.false_ bs
×
247

248
      let var_of_value v =
249
        List.init V.length ~f:(fun i -> Boolean.var_of_value (V.get v i))
×
250

251
      let size_in_bits = size_in_bits
252
    end
253

254
    let unpack_var x = Impl.Field.Checked.unpack x ~length:bit_length
×
255

256
    let var_of_field = unpack_var
257

258
    let var_of_field_unsafe = Fn.id
259

260
    let unpack_value (x : Packed.value) : Unpacked.value = x
×
261

262
    let compare_var x y =
263
      Impl.Field.Checked.compare ~bit_length:V.length (pack_var x) (pack_var y)
×
264

265
    let%snarkydef_ increment_if_var bs (b : Boolean.var) =
266
      let open Impl in
×
267
      let v = Field.Var.pack bs in
268
      let v' = Field.Var.add v (b :> Field.Var.t) in
×
269
      Field.Checked.unpack v' ~length:V.length
×
270

271
    let%snarkydef_ increment_var bs =
272
      let open Impl in
×
273
      let v = Field.Var.pack bs in
274
      let v' = Field.Var.add v (Field.Var.constant Field.one) in
×
275
      Field.Checked.unpack v' ~length:V.length
×
276

277
    let%snarkydef_ equal_var (n : Unpacked.var) (n' : Unpacked.var) =
278
      Field.Checked.equal (pack_var n) (pack_var n')
×
279

280
    let%snarkydef_ assert_equal_var (n : Unpacked.var) (n' : Unpacked.var) =
281
      Field.Checked.Assert.equal (pack_var n) (pack_var n')
×
282

283
    let if_ (cond : Boolean.var) ~(then_ : Unpacked.var) ~(else_ : Unpacked.var)
284
        : Unpacked.var Checked.t =
285
      match
×
286
        List.map2 then_ else_ ~f:(fun then_ else_ ->
287
            Boolean.if_ cond ~then_ ~else_ )
×
288
      with
289
      | Ok result ->
×
290
          Checked.List.all result
291
      | Unequal_lengths ->
×
292
          failwith "Bits.if_: unpacked bit lengths were unequal"
293
  end
294

295
  module UInt64 (Impl : Snarky_backendless.Snark_intf.S) =
296
    Small_bit_vector (Impl) (Vector.UInt64)
297
  module UInt32 (Impl : Snarky_backendless.Snark_intf.S) =
298
    Small_bit_vector (Impl) (Vector.UInt32)
299

300
  module Field_backed
301
      (Impl : Snarky_backendless.Snark_intf.S) (M : sig
302
        val bit_length : int
303
      end) =
304
  struct
305
    open Impl
306
    include M
307

308
    let size_in_bits = bit_length
309

310
    module Packed = struct
311
      type var = Field.Var.t
312

313
      type value = Field.t
314

315
      let typ = Typ.field
316

317
      let assert_equal = Field.Checked.Assert.equal
318

319
      let size_in_bits = size_in_bits
320
    end
321

322
    module Unpacked = struct
323
      type var = Boolean.var list
324

325
      type value = Field.t
326

327
      let typ : (var, value) Typ.t =
328
        Typ.transport
×
329
          (Typ.list ~length:bit_length Boolean.typ)
×
330
          ~there:(unpack_field Field.unpack ~bit_length)
×
331
          ~back:Field.project
332

333
      let var_to_bits = Bitstring_lib.Bitstring.Lsb_first.of_list
334

335
      let var_of_bits = pad ~length:bit_length ~default:Boolean.false_
336

337
      let var_to_triples (bs : var) =
338
        Bitstring_lib.Bitstring.pad_to_triple_list ~default:Boolean.false_ bs
×
339

340
      let var_of_value v =
341
        unpack_field Field.unpack ~bit_length v
×
342
        |> List.map ~f:Boolean.var_of_value
×
343

344
      let size_in_bits = size_in_bits
345
    end
346

347
    let project_value = Fn.id
348

349
    let project_var = Field.Var.project
350

351
    let choose_preimage_var : Packed.var -> Unpacked.var Checked.t =
352
      Field.Checked.choose_preimage_var ~length:bit_length
353

354
    let unpack_value = Fn.id
355
  end
356

357
  module Field (Impl : Snarky_backendless.Snark_intf.S) :
358
    Bits_intf.Snarkable.Lossy
359
      with type ('a, 'b) typ := ('a, 'b) Impl.Typ.t
360
       and type 'a checked := 'a Impl.Checked.t
361
       and type boolean_var := Impl.Boolean.var
362
       and type Packed.var = Impl.Field.Var.t
363
       and type Packed.value = Impl.Field.t
364
       and type Unpacked.var = Impl.Boolean.var list
365
       and type Unpacked.value = Impl.Field.t =
366
    Field_backed
367
      (Impl)
368
      (struct
369
        let bit_length = Impl.Field.size_in_bits
370
      end)
371

372
  module Small
373
      (Impl : Snarky_backendless.Snark_intf.S) (M : sig
374
        val bit_length : int
375
      end) :
376
    Bits_intf.Snarkable.Faithful
377
      with type ('a, 'b) typ := ('a, 'b) Impl.Typ.t
378
       and type 'a checked := 'a Impl.Checked.t
379
       and type boolean_var := Impl.Boolean.var
380
       and type Packed.var = Impl.Field.Var.t
381
       and type Packed.value = Impl.Field.t
382
       and type Unpacked.var = Impl.Boolean.var list
383
       and type Unpacked.value = Impl.Field.t = struct
384
    let () = assert (M.bit_length < Impl.Field.size_in_bits)
×
385

386
    include Field_backed (Impl) (M)
387

388
    let pack_var bs =
389
      assert (Mina_stdlib.List.Length.Compare.(bs = M.bit_length)) ;
×
390
      project_var bs
391

392
    let pack_value = Fn.id
393

394
    let unpack_var = Impl.Field.Checked.unpack ~length:M.bit_length
395
  end
396
end
397

398
module Make_unpacked
399
    (Impl : Snarky_backendless.Snark_intf.S) (M : sig
400
      val bit_length : int
401
    end) =
402
struct
403
  open Impl
404

405
  module T = struct
406
    type var = Boolean.var list
407

408
    type value = Boolean.value list
409
  end
410

411
  include T
412

413
  let typ : (var, value) Typ.t = Typ.list ~length:M.bit_length Boolean.typ
×
414
end
9✔
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