Skip to content

Commit

Permalink
Field: More efficient conversion of into Bignum_bigint.t
Browse files Browse the repository at this point in the history
  • Loading branch information
tizoc committed Nov 22, 2023
1 parent 12a164f commit 709463d
Showing 1 changed file with 23 additions and 13 deletions.
36 changes: 23 additions & 13 deletions src/lib/crypto/kimchi_backend/common/field.ml
Original file line number Diff line number Diff line change
Expand Up @@ -179,20 +179,30 @@ module Make (F : Input_intf) :
let of_sexpable = of_bigint
end)

let zero = of_int 0

let to_bignum_bigint n =
let rec go i two_to_the_i acc =
if Int.equal i size_in_bits then acc
else
let acc' =
if Bigint.test_bit n i then Bignum_bigint.(acc + two_to_the_i)
else acc
in
go (i + 1) Bignum_bigint.(two_to_the_i + two_to_the_i) acc'
in
go 0 Bignum_bigint.one Bignum_bigint.zero

let hash_fold_t s x =
Bignum_bigint.hash_fold_t s (to_bignum_bigint (to_bigint x))
(* For non-zero values, conversion is done by creating the bin_prot representation
of the [Bignum_bigit.t] value, and then parsing it with bin_prot. *)
match compare n zero with
| 0 ->
Bignum_bigint.zero
| c ->
(* Tag for positive values is 1, negative is 2:
https://github.com/janestreet/bignum/blob/6c63419787a4e209e85befd3d823fff2790677e0/bigint/src/bigint.ml#L27-L30 *)
let tag_byte = if c > 0 then '\x01' else '\x02' in
let bytes = to_bytes n in
let len = Bytes.length bytes in
let size_byte = Char.of_int_exn len in
let buf = Bytes.create (2 + len) in
(* First byte is the tag, second the amount of bytes *)
Bytes.unsafe_set buf 0 tag_byte ;
Bytes.unsafe_set buf 1 size_byte ;
(* Copy the bytes representation of the value, skip the tag and size bytes *)
Bytes.unsafe_blit ~src:bytes ~src_pos:0 ~dst_pos:2 ~len ~dst:buf ;
Bin_prot.Reader.of_bytes Bignum_bigint.Stable.V1.bin_reader_t buf

let hash_fold_t s x = Bignum_bigint.hash_fold_t s (to_bignum_bigint x)

let hash = Hash.of_fold hash_fold_t

Expand Down

0 comments on commit 709463d

Please sign in to comment.