Commit 78783545 authored by Stephane Glondu's avatar Stephane Glondu

Add GROUP.{of,to}_ints

parent 98d78298
Pipeline #67873 passed with stages
in 17 minutes and 10 seconds
......@@ -39,7 +39,12 @@ let map_and_concat_with_commas f xs =
(** Finite field arithmetic *)
let check_params {p; q; g} =
let check_params {p; q; g; embedding} =
(match embedding with
| None -> true
| Some {padding; bits_per_int} ->
padding > 0 && bits_per_int > 0 && bits_per_int < 32
) &&
Z.probab_prime p 20 > 0 &&
Z.probab_prime q 20 > 0 &&
check_modulo p g &&
......@@ -51,7 +56,7 @@ module type GROUP = Signatures.GROUP
and type group = ff_params
let unsafe_make group =
let {p; q; g} = group in
let {p; q; g; embedding} = group in
let module G = struct
open Z
type t = Z.t
......@@ -67,6 +72,43 @@ let unsafe_make group =
let to_string = Z.to_string
let of_string = Z.of_string
let of_ints =
match embedding with
| None ->
fun _ -> failwith "Group_field.of_bits: missing parameters"
| Some {padding; bits_per_int} ->
let mask_per_int = pred (1 lsl bits_per_int) in
fun xs ->
let n = Array.length xs in
let rec encode_int i accu =
if i < n then
let x = xs.(i) land mask_per_int in
encode_int (succ i) (Z.shift_left accu bits_per_int + of_int x)
else
Z.shift_left accu padding
in
let rec find_element accu =
if check accu then accu else find_element (accu + one)
in
find_element (encode_int 0 zero)
let to_ints =
match embedding with
| None ->
fun _ -> failwith "Group_field.to_bits: missing parameters"
| Some {padding; bits_per_int} ->
let mask_per_int = shift_left one bits_per_int - one in
fun n x ->
let xs = Array.make n 0 in
let rec decode_int i x =
if i >= 0 then (
xs.(i) <- to_int (logand x mask_per_int);
decode_int (pred i) (shift_right x bits_per_int)
)
in
decode_int (pred n) (shift_right x padding);
xs
let read state buf =
match Yojson.Safe.from_lexbuf ~stream:true state buf with
| `String s -> Z.of_string s
......
......@@ -58,4 +58,7 @@ module Z : sig
val probab_prime : t -> int -> int
val bit_length : t -> int
val of_bits : string -> t
val shift_left : t -> int -> t
val shift_right : t -> int -> t
val logand : t -> t -> t
end
......@@ -44,10 +44,16 @@ type 'a trustee_public_key = {
(** {2 Elections} *)
type ff_embedding = {
padding : int;
bits_per_int : int;
}
type ff_params = {
g : number;
p : number;
q : number;
?embedding : ff_embedding option;
}
<doc text="Parameters for a multiplicative subgroup of a finite field.">
......
......@@ -65,6 +65,13 @@ module type GROUP = sig
val of_string : string -> t
(** Conversion from string. *)
val of_ints : int array -> t
(** Convert an int array to a group element. *)
val to_ints : int -> t -> int array
(** Convert a group element to an int array. The first argument is
the size of the array. *)
val read : t reader
(** Reading from a stream. *)
......
......@@ -189,6 +189,9 @@ module Jsbn = struct
method modInverse : bigint t -> bigint t meth
method bitLength : int meth
method isProbablePrime : int -> int meth
method shiftLeft : int -> bigint t meth
method shiftRight : int -> bigint t meth
method _and : bigint t -> bigint t meth
end
class type lib =
......@@ -240,4 +243,8 @@ module Z = struct
then loop (res * z256 + of_int (int_of_char x.[i])) (pred i)
else res
in loop zero (pred n)
let shift_left x n = x##shiftLeft n
let shift_right x n = x##shiftRight n
let logand x y = x##_and y
end
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment