112 lines
3 KiB
OCaml
112 lines
3 KiB
OCaml
open Format
|
|
|
|
let print_header name =
|
|
printf
|
|
{|
|
|
/*
|
|
Pre-computed %d-bit multiples of the generator point G for the curve %s,
|
|
used for speeding up its scalar multiplication in point_operations.h.
|
|
|
|
Generated by %s
|
|
*/|}
|
|
Sys.word_size name Sys.argv.(0)
|
|
|
|
let pp_array elem_fmt fmt arr =
|
|
let fout = fprintf fmt in
|
|
let len = Array.length arr in
|
|
fout "@[<2>{@\n";
|
|
for i = 0 to len - 1 do
|
|
elem_fmt fmt arr.(i);
|
|
if i < len - 1 then printf ",@ " else printf ""
|
|
done;
|
|
fout "@]@,}"
|
|
|
|
let div_round_up a b = (a / b) + if a mod b = 0 then 0 else 1
|
|
|
|
let pp_string_words ~wordsize fmt str =
|
|
assert (String.length str * 8 mod wordsize = 0);
|
|
let limbs = String.length str * 8 / wordsize in
|
|
(* Truncate at the beginning (little-endian) *)
|
|
let bytes = Bytes.unsafe_of_string str in
|
|
(* let bytes = rev_str_bytes str in *)
|
|
fprintf fmt "@[<2>{@\n";
|
|
for i = 0 to limbs - 1 do
|
|
let index = i * (wordsize / 8) in
|
|
(if wordsize = 64 then
|
|
let w = Bytes.get_int64_le bytes index in
|
|
fprintf fmt "%#016Lx" w
|
|
else
|
|
let w = Bytes.get_int32_le bytes index in
|
|
fprintf fmt "%#08lx" w);
|
|
if i < limbs - 1 then printf ",@ " else printf ""
|
|
done;
|
|
fprintf fmt "@]@,}"
|
|
|
|
let check_shape tables =
|
|
let fe_len = String.length tables.(0).(0).(0) in
|
|
let table_len = fe_len * 2 in
|
|
assert (Array.length tables = table_len);
|
|
Array.iter
|
|
(fun x ->
|
|
assert (Array.length x = 15);
|
|
Array.iter
|
|
(fun x ->
|
|
assert (Array.length x = 3);
|
|
Array.iter (fun x -> assert (String.length x = fe_len)) x)
|
|
x)
|
|
tables
|
|
|
|
let print_tables tables ~wordsize =
|
|
let fe_len = String.length tables.(0).(0).(0) in
|
|
printf "@[<2>static WORD generator_table[%d][15][3][LIMBS] = @," (fe_len * 2);
|
|
pp_array
|
|
(pp_array (pp_array (pp_string_words ~wordsize)))
|
|
std_formatter tables;
|
|
printf "@];@,"
|
|
|
|
let print_toplevel name wordsize (module P : Mirage_crypto_ec.Dh_dsa) =
|
|
let tables = P.Dsa.Precompute.generator_tables () in
|
|
assert (wordsize = Sys.word_size);
|
|
check_shape tables;
|
|
print_header name;
|
|
if wordsize = 64 then
|
|
printf
|
|
"@[<v>#ifndef ARCH_64BIT@,\
|
|
#error \"Cannot use 64-bit tables on a 32-bit architecture\"@,\
|
|
#endif@,\
|
|
@]"
|
|
else
|
|
printf
|
|
"@[<v>#ifdef ARCH_64BIT@,\
|
|
#error \"Cannot use 32-bit tables on a 64-bit architecture\"@,\
|
|
#endif@,\
|
|
@]";
|
|
print_tables ~wordsize tables
|
|
|
|
let curves =
|
|
Mirage_crypto_ec.
|
|
[
|
|
("p256", (module P256 : Dh_dsa));
|
|
("p384", (module P384));
|
|
("p521", (module P521));
|
|
]
|
|
|
|
let usage () =
|
|
printf "Usage: gen_tables [%a] [64 | 32]@."
|
|
(pp_print_list
|
|
~pp_sep:(fun fmt () -> pp_print_string fmt " | ")
|
|
pp_print_string)
|
|
(List.map fst curves)
|
|
|
|
let go =
|
|
let name, curve, wordsize =
|
|
try
|
|
let name, curve =
|
|
List.find (fun (name, _) -> name = Sys.argv.(1)) curves
|
|
in
|
|
(name, curve, int_of_string Sys.argv.(2))
|
|
with _ ->
|
|
usage ();
|
|
exit 1
|
|
in
|
|
print_toplevel name wordsize curve
|