fq12.ml
(*****************************************************************************)
(* *)
(* Copyright (c) 2020-2021 Danny Willems <be.danny.willems@gmail.com> *)
(* *)
(* Permission is hereby granted, free of charge, to any person obtaining a *)
(* copy of this software and associated documentation files (the "Software"),*)
(* to deal in the Software without restriction, including without limitation *)
(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *)
(* and/or sell copies of the Software, and to permit persons to whom the *)
(* Software is furnished to do so, subject to the following conditions: *)
(* *)
(* The above copyright notice and this permission notice shall be included *)
(* in all copies or substantial portions of the Software. *)
(* *)
(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*)
(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *)
(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *)
(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*)
(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *)
(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *)
(* DEALINGS IN THE SOFTWARE. *)
(* *)
(*****************************************************************************)
module Stubs = struct
type fp12
external allocate_fq12 : unit -> fp12 = "allocate_fp12_stubs"
external mul : fp12 -> fp12 -> fp12 -> int = "caml_blst_fp12_mul_stubs"
external one : fp12 -> int = "caml_blst_fp12_one_stubs"
external equal : fp12 -> fp12 -> bool = "caml_blst_fp12_is_equal_stubs"
external is_zero : fp12 -> bool = "caml_blst_fp12_is_zero_stubs"
external inverse : fp12 -> fp12 -> int = "caml_blst_fp12_inverse_stubs"
external sqr : fp12 -> fp12 -> int = "caml_blst_fp12_sqr_stubs"
external pow : fp12 -> fp12 -> Bytes.t -> int -> int
= "caml_blst_fp12_pow_stubs"
external to_bytes : Bytes.t -> fp12 -> int = "caml_blst_fp12_to_bytes_stubs"
external of_bytes : fp12 -> Bytes.t -> int = "caml_blst_fp12_of_bytes_stubs"
end
module Fq12 = struct
exception Not_in_field of Bytes.t
type t = Stubs.fp12
let order =
let fq_order =
Z.of_string
"4002409555221667393417789825735904156556882819939007885332058136124031650490837864442687629129015664037894272559787"
in
Z.pow fq_order 12
let size_in_bytes = 48 * 12
let to_bytes p =
let buffer = Bytes.make size_in_bytes '\000' in
ignore @@ Stubs.to_bytes buffer p ;
buffer
let of_bytes_opt bs =
if Bytes.length bs <> size_in_bytes then None
else
let buffer = Stubs.allocate_fq12 () in
ignore @@ Stubs.of_bytes buffer bs ;
Some buffer
let random ?state () =
let buffer = Stubs.allocate_fq12 () in
let bs =
Bytes.concat
Bytes.empty
(List.init 12 (fun _ -> Fq.(to_bytes (random ?state ()))))
in
ignore @@ Stubs.of_bytes buffer bs ;
buffer
let of_bytes_exn bs =
match of_bytes_opt bs with None -> raise (Not_in_field bs) | Some p -> p
let one =
let buffer = Stubs.allocate_fq12 () in
ignore @@ Stubs.one buffer ;
buffer
let zero = Stubs.allocate_fq12 ()
let size_in_memory = Obj.reachable_words (Obj.repr one) * 8
let eq x y =
let res = Stubs.equal x y in
res
let is_zero p =
let res = eq p zero in
res
let is_one p = eq p one
let mul x y =
let buffer = Stubs.allocate_fq12 () in
ignore @@ Stubs.mul buffer x y ;
buffer
let inverse_opt x =
if is_zero x then None
else
let buffer = Stubs.allocate_fq12 () in
ignore @@ Stubs.inverse buffer x ;
Some buffer
let inverse_exn x =
if is_zero x then raise Division_by_zero
else
let buffer = Stubs.allocate_fq12 () in
ignore @@ Stubs.inverse buffer x ;
buffer
let of_z x0 x1 x2 x3 x4 x5 x6 x7 x8 x9 x10 x11 =
let coordinates = [x0; x1; x2; x3; x4; x5; x6; x7; x8; x9; x10; x11] in
let coordinates =
List.map (fun x -> Bytes.of_string (Z.to_bits x)) coordinates
in
let bs = Bytes.concat Bytes.empty coordinates in
let buffer = Stubs.allocate_fq12 () in
ignore @@ Stubs.of_bytes buffer bs ;
buffer
let of_string x0 x1 x2 x3 x4 x5 x6 x7 x8 x9 x10 x11 =
let x0 = Z.of_string x0 in
let x1 = Z.of_string x1 in
let x2 = Z.of_string x2 in
let x3 = Z.of_string x3 in
let x4 = Z.of_string x4 in
let x5 = Z.of_string x5 in
let x6 = Z.of_string x6 in
let x7 = Z.of_string x7 in
let x8 = Z.of_string x8 in
let x9 = Z.of_string x9 in
let x10 = Z.of_string x10 in
let x11 = Z.of_string x11 in
of_z x0 x1 x2 x3 x4 x5 x6 x7 x8 x9 x10 x11
let pow x n =
let n = Z.erem n (Z.pred order) in
let buffer = Stubs.allocate_fq12 () in
let exp = Z.to_bits n |> Bytes.unsafe_of_string in
let exp_len = Z.numbits n in
ignore @@ Stubs.pow buffer x exp exp_len ;
buffer
end
include Fq12