diff --git a/default.nix b/default.nix index 79f035e..07a0cd5 100644 --- a/default.nix +++ b/default.nix @@ -19,8 +19,10 @@ in pkgs.fastStdenv.mkDerivation { gmp gmpxx libcxx - glibc - glibc.static + # for linux + #glibc + #glibc.static + clang # for i-shiny objects nixfmt ocamlformat ]); diff --git a/examples/kzg.ml b/examples/kzg.ml index bee062c..d5bc9f4 100644 --- a/examples/kzg.ml +++ b/examples/kzg.ml @@ -87,7 +87,7 @@ module KZG : let commit c p = assert (Polynomial.degree p < Vector.length c.srs_g1); let f x p cm = - let n = Polynomial.(Finite_field.(residue_class (inj_field x)).%[0]) in + let n = Option.get Finite_field.(inj_prime_field (inj_field x)) in Elliptic_curve.(add c.curve cm (mul c.curve ~n ~p)) in let acc = Elliptic_curve.zero c.curve in @@ -111,16 +111,12 @@ module KZG : Elliptic_curve.( sub c.curve Vector.(c.srs_g2.%[2]) - (mul c.curve - ~n:Polynomial.((Finite_field.residue_class x).%[0]) - ~p:c.g2)) + (mul c.curve ~n:(Option.get Finite_field.(inj_prime_field x)) ~p:c.g2)) in let numerator = Elliptic_curve.( sub c.curve cm - (mul c.curve - ~n:Polynomial.((Finite_field.residue_class y).%[0]) - ~p:c.g1)) + (mul c.curve ~n:(Option.get Finite_field.(inj_prime_field y)) ~p:c.g1)) in let lhs = Elliptic_curve.weil_pairing c.curve ~l:c.curve_subgroup_order pi @@ -137,10 +133,9 @@ let c = let g = Finite_field.generator ~order:ToyCurve.r in let secret = Finite_field.random g in let coeff p i = + let n = Finite_field.pow secret (Integer.of_int i) in Elliptic_curve.mul ToyCurve.curve - ~n: - Polynomial.( - Finite_field.(residue_class (pow secret (Integer.of_int i))).%[0]) + ~n:(Option.get Finite_field.(inj_prime_field n)) ~p in let srs_g1 = Vector.init 100 ~f:(coeff ToyCurve.g1) in diff --git a/examples/number_fields.ml b/examples/number_fields.ml index 064be67..a418e7c 100644 --- a/examples/number_fields.ml +++ b/examples/number_fields.ml @@ -23,15 +23,21 @@ let () = Printf.eprintf "%b\n" (Polynomial.is_irreducible q) let qmin : Integer.t Polynomial.t = Polynomial.minimal q let () = Printf.eprintf "%s\n" (Polynomial.to_string qmin) +let inj_rat = + Polynomial.inj_base_ring ~inj:(fun x -> + x |> Integer.inj_rat |> Rational.inj_ring) + let () = - Printf.eprintf "%b\n" Number_field.(are_isomorphic (create q) (create qmin)) + Printf.eprintf "%b\n" + Number_field.(are_isomorphic (create (inj_rat q)) (create (inj_rat qmin))) (* Gaussian integers: the ring Z[i] (here we work in the field Q(i)) *) let gaussian_integers = (* Q(i) = Q[X]/(X^2+1) *) Number_field.create (Polynomial.create - [| Integer.of_int 1; Integer.of_int 0; Integer.of_int 1 |]) + [| Integer.of_int 1; Integer.of_int 0; Integer.of_int 1 |] + |> inj_rat) (* Euclidean division of 6 + 8i by 1 + 5i. *) let a = diff --git a/pari_bindings/dune b/pari_bindings/dune index 7997b9b..9d9eedd 100644 --- a/pari_bindings/dune +++ b/pari_bindings/dune @@ -23,7 +23,7 @@ (chdir libpari (system - "if [ \"$(uname)\" = \"Darwin\" ]; then CC=$(find /usr/local/bin -name \"gcc-[0-9]*\" 2>&1 | head -n 1) ./Configure --prefix=local --with-gmp-lib=/opt/homebrew/lib --with-gmp-include=/opt/homebrew/include; elif [ \"$(uname)\" = \"FreeBSD\" ]; then ./Configure --prefix=local --with-gmp-lib=/usr/local/lib --with-gmp-include=/usr/local/include; else ./Configure --prefix=local; fi;")) + "if [ \"$(uname)\" = \"Darwin\" ]; then if [ ! command -v nix &> /dev/null ]; then ./Configure --prefix=local; else CC=$(find /usr/local/bin -name \"gcc-[0-9]*\" 2>&1 | head -n 1) ./Configure --prefix=local --with-gmp-lib=/opt/homebrew/lib --with-gmp-include=/opt/homebrew/include ; fi; elif [ \"$(uname)\" = \"FreeBSD\" ]; then ./Configure --prefix=local --with-gmp-lib=/usr/local/lib --with-gmp-include=/usr/local/include; else ./Configure --prefix=local; fi;")) (ignore-stderr (with-accepted-exit-codes (or 0 1) diff --git a/src/dune b/src/dune index cb3045a..66fea3f 100644 --- a/src/dune +++ b/src/dune @@ -15,6 +15,8 @@ (library (name Pari) (public_name pari) + (flags + (:standard -w -37)) (libraries core ctypes.stubs diff --git a/src/pari.ml b/src/pari.ml index 9a50c43..9630917 100644 --- a/src/pari.ml +++ b/src/pari.ml @@ -4,19 +4,19 @@ type ('kind, 'structure) typ = gen let t = gen -type group -type ring -type field -type unique_factorization_domain -type complex -type real -type rational -type integer -type polynomial -type integer_mod -type finite_field -type number_field -type elliptic_curve +type group = Group +type ring = Ring +type field = Field +type unique_factorization_domain = Unique_factorization_domain +type complex = Complex +type real = Real +type rational = Rational +type integer = Integer +type 'a polynomial = Polynomial of 'a +type integer_mod = Integer_mod +type finite_field = Finite_field +type number_field = Number_field +type elliptic_curve = Elliptic_curve let register_gc v = Gc.finalise_last (fun () -> pari_free Ctypes.(coerce gen (ptr void) v)) v @@ -273,6 +273,8 @@ module Polynomial = struct acc := f p.%[i] Vector.(v.%[i + 1]) !acc done; !acc + + let inj_base_ring ~inj:_ p = p end module Integer_mod = struct @@ -383,6 +385,16 @@ module Finite_field = struct let prime_field_element x ~p = ff_z_mul (ff_1 (generator ~order:p)) x + let inj_prime_field x = + let p = ff_to_fpxq_i x in + + if + glength p = Signed.Long.one + || Polynomial.degree p = 0 + || Polynomial.degree p = 1 + then Some Polynomial.(p.%[0]) + else None + let finite_field_element coeffs a = let len = Array.length coeffs in fst diff --git a/src/pari.mli b/src/pari.mli index 240f810..b944092 100644 --- a/src/pari.mli +++ b/src/pari.mli @@ -96,18 +96,18 @@ type bb_group type bb_field type bb_algebra type bb_ring -type ring -type field -type unique_factorization_domain -type complex -type real -type rational -type integer -type polynomial -type integer_mod -type finite_field -type number_field -type elliptic_curve +type ring = private Ring +type field = private Field +type unique_factorization_domain = private Unique_factorization_domain +type complex = private Complex +type real = private Real +type rational = private Rational +type integer = private Integer +type 'a polynomial = private Polynomial of 'a +type integer_mod = private Integer_mod +type finite_field = private Finite_field +type number_field = private Number_field +type elliptic_curve = private Elliptic_curve val factor : ('kind, unique_factorization_domain) typ -> @@ -197,7 +197,7 @@ and Integer : sig end end -type group +type group = private Group type 'a group_structure = { mul : ('a, group) typ -> ('a, group) typ -> ('a, group) typ; @@ -267,7 +267,7 @@ module Matrix : sig end module rec Polynomial : sig - type 'a t = (polynomial, ring) typ constraint 'a = ('b, ring) typ + type 'a t = ('a polynomial, ring) typ constraint 'a = ('b, ring) typ val to_string : 'a t -> string val mul : 'a t -> 'a t -> 'a t @@ -351,6 +351,8 @@ module rec Polynomial : sig 'a t -> ('b, _) Vector.t -> ('c, 'd) typ + + val inj_base_ring : inj:('a -> 'b) -> 'a t -> 'b t end and Fp : sig @@ -367,6 +369,7 @@ and Finite_field : sig val inj_field : (finite_field, ring) typ -> t val generator : order:Integer.t -> t val prime_field_element : Integer.t -> p:Integer.t -> t + val inj_prime_field : t -> Fp.t option val finite_field_element : Integer.t array -> t -> t val create : p:int -> degree:int -> (finite_field, ring) typ Polynomial.t