<commit_before>open Sexplib.Conv
open Uncommon

type pub  = { p : Z.t ; q : Z.t ; gg : Z.t ; y : Z.t } with sexp
type priv = { p : Z.t ; q : Z.t ; gg : Z.t ; x : Z.t ; y : Z.t } with sexp

let pub_of_priv { p; q; gg; y; _ } = { p; q; gg; y }

type keysize = [ `Fips1024 | `Fips2048 | `Fips3072 | `Exactly of int * int ]

let expand_size = function
  | `Fips1024  -> (1024, 160)
  | `Fips2048  -> (2048, 256)
  | `Fips3072  -> (3072, 256)
  | `Exactly (l, n) -> (l, n)

type mask = [ `No | `Yes | `Yes_with of Rng.g ]

let expand_mask = function
  | `No         -> `No
  | `Yes        -> `Yes None
  | `Yes_with g -> `Yes (Some g)

(*
 * FIPS.186-4-style derivation:
 * - p and q are derived using a method numerically like the one described in
 *   A.1.1.2, adapted to use the native rng.
 * - g is derived as per A.2.1.
 *)
let params ?g size =
  let (l, n) = expand_size size in
  let q = Rng.prime ?g ~msb:1 ~bits:n in
  let p =
    let q_q  = Z.(q * ~$2)
    and mask = Z.((lsl) one) (l - 1) in
    until Numeric.pseudoprime @@ fun () ->
      let w = Rng.Z.gen_bits ?g l in
      let x = Z.(w lor mask) in
      Z.(x - (x mod q_q) + one) in
  let gg =
    let e = Z.(pred p / q) in
    until ((<>) Z.one) @@ fun () ->
      let h = Rng.Z.gen_r ?g Z.(~$2) Z.(pred p) in
      Z.(powm h e p) in
  (p, q, gg)

let generate ?g size =
  let (p, q, gg) = params ?g size in
  let x = Rng.Z.gen_r ?g Z.one q in<commit_msg>use ~msb to simplify dsa key generation<commit_after>open Sexplib.Conv
open Uncommon

type pub  = { p : Z.t ; q : Z.t ; gg : Z.t ; y : Z.t } with sexp
type priv = { p : Z.t ; q : Z.t ; gg : Z.t ; x : Z.t ; y : Z.t } with sexp

let pub_of_priv { p; q; gg; y; _ } = { p; q; gg; y }

type keysize = [ `Fips1024 | `Fips2048 | `Fips3072 | `Exactly of int * int ]

let expand_size = function
  | `Fips1024  -> (1024, 160)
  | `Fips2048  -> (2048, 256)
  | `Fips3072  -> (3072, 256)
  | `Exactly (l, n) -> (l, n)

type mask = [ `No | `Yes | `Yes_with of Rng.g ]

let expand_mask = function
  | `No         -> `No
  | `Yes        -> `Yes None
  | `Yes_with g -> `Yes (Some g)

(*
 * FIPS.186-4-style derivation:
 * - p and q are derived using a method numerically like the one described in
 *   A.1.1.2, adapted to use the native rng.
 * - g is derived as per A.2.1.
 *)
let params ?g size =
  let (l, n) = expand_size size in
  let q = Rng.prime ?g ~msb:1 ~bits:n in
  let p =
    let q_q  = Z.(q * ~$2) in
    until Numeric.pseudoprime @@ fun () ->
      let x = Rng.Z.gen_bits ?g ~msb:1 l in
      Z.(x - (x mod q_q) + one) in
  let gg =
    let e = Z.(pred p / q) in
    until ((<>) Z.one) @@ fun () ->
      let h = Rng.Z.gen_r ?g Z.(~$2) Z.(pred p) in
      Z.(powm h e p) in
  (p, q, gg)

let generate ?g size =
  let (p, q, gg) = params ?g size in
  let x = Rng.Z.gen_r ?g Z.one q in
{'fraction_non_alphanumeric': 0.16916488222698073, 'fraction_numerical': 0.04139900071377588, 'mean_word_length': 2.0667396061269145, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 23, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2295075', 'n_tokens_mistral': 1310, 'n_tokens_neox': 1231, 'n_words': 418}