Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

use safe primes for RSA keys <= 1500 bits #23

Open
cfcs opened this issue Nov 27, 2018 · 2 comments
Open

use safe primes for RSA keys <= 1500 bits #23

cfcs opened this issue Nov 27, 2018 · 2 comments

Comments

@cfcs
Copy link
Contributor

cfcs commented Nov 27, 2018

the nocrypto library does not currently seem to generate safe primes for its RSA keys.

I was advised by a cryptographer that this is "not really" an issue for larger keys, but that it should be done for RSA keys <= "around 1500 bits".

I have not been able to find any papers or research that describe this problem in a way I could comprehend, or gives a lower bound for when it is not necessary to use safe primes.
References to research or comments on this issue would be much appreciated! :)

@cfcs
Copy link
Contributor Author

cfcs commented Nov 27, 2018

The key generation code in https://github.com/mirleft/ocaml-nocrypto/blob/master/src/rsa.ml#L93-L100 (mirleft/ocaml-nocrypto@1dfcf4d) at the time of writing looks like this:

let rprime a b = Z.(gcd a b = one)

let rec generate ?g ?(e = Z.(~$0x10001)) bits =

  if e < Z.three || Numeric.(bits <= Z.bits e || not (pseudoprime e)) then
    invalid_arg "Rsa.generate: e: %a, bits: %d" Z.pp_print e bits;
  (* cfcs: ensure: e >= 3 ; key size > e ; e is prime
      FIPS-186-4 suggests also ensuring e > 2^16 ; e < 2^256
  *)


  let (pb, qb) = (bits / 2, bits - bits / 2) in
  let (p, q)   = Rng.(prime ?g ~msb:2 pb, prime ?g ~msb:2 qb) in
  (* cfcs: generate p and q candidates
      FIPS-186-4: has some additional checks to perform re: gap between these and min/max values..
  *)


  if (p <> q) && rprime e Z.(pred p) && rprime e Z.(pred q) then
  (* cfcs: accept if:
      = p is different from q

      FIPS-186-4: B3.1: (probably primes):
      2. (a): "(p1) and (q1) shall be relatively prime to the public exponent e"
      = gcd e (p-1) <> 1: is not dividable by e
      = gcd e (q-1) <> 1: is not dividable by e
  *)
    priv_of_primes ~e ~p:(max p q) ~q:(min p q)

  else generate ?g ~e bits
  (* cfcs: otherwise try again *)

A check for safe primes would look something like Z.probab_prime ((pred p) / 2) (can't remember the name of the primality testing function from gmp off the top of my head)

@cfcs
Copy link
Contributor Author

cfcs commented Nov 27, 2018

Additionally this priv_of_primes ~e ~p:(max p q) ~q:(min p q) seems to be a typo (I think it should be ~p:(min p q) ~q:(max p q)), I couldn't find the FIPS spec that mandates p < q, but the OpenPGP spec says so on page 44

EDIT: hmm but then there's

  let (pb, qb) = (bits / 2, bits - bits / 2) in

so would need to investigate what's up here.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

No branches or pull requests

1 participant