primegen.py 2.8 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374
  1. #!/usr/bin/env python3
  2. from testcrypt import *
  3. import base64
  4. import argparse
  5. import itertools
  6. assert sys.version_info[:2] >= (3,0), "This is Python 3 code"
  7. def main():
  8. opener = lambda mode: lambda fname: lambda: argparse.FileType(mode)(fname)
  9. parser = argparse.ArgumentParser(description='')
  10. IntArg = lambda x: int(x, 0)
  11. parser.add_argument("bits", type=IntArg, nargs="?", default=1024)
  12. parser.add_argument("-s", "--seed")
  13. parser.add_argument("-f", "--firstbits", type=IntArg, default=1)
  14. parser.add_argument("--fast", action='store_const',
  15. dest='policy', const='provable_fast')
  16. parser.add_argument("--complex", action='store_const',
  17. dest='policy', const='provable_maurer_complex')
  18. parser.add_argument("--probabilistic", action='store_const',
  19. dest='policy', const='probabilistic')
  20. parser.add_argument("-q", "--quiet", action='store_true')
  21. parser.add_argument("-b", "--binary", action='store_const',
  22. dest='fmt', const='{:b}')
  23. parser.add_argument("-x", "--hex", action='store_const',
  24. dest='fmt', const='{:x}')
  25. parser.add_argument("-o", "--output", type=opener("w"),
  26. default=opener("w")("-"),
  27. help="file to write the prime to")
  28. parser.add_argument("--mpu", type=opener("w"),
  29. help="MPU certificate output file")
  30. parser.add_argument("--safe", action='store_true')
  31. parser.set_defaults(fmt='{:d}', policy='provable_maurer_simple')
  32. args = parser.parse_args()
  33. seed = args.seed
  34. if seed is None:
  35. with open("/dev/urandom", "rb") as f:
  36. seed = base64.b64encode(f.read(32)).decode("ASCII")
  37. if not args.quiet:
  38. print("seed =", seed)
  39. random_make_prng('sha256', seed)
  40. assert args.firstbits > 0
  41. nfirst = next(i for i in itertools.count() if (args.firstbits >> i) == 0)
  42. pgc = primegen_new_context(args.policy)
  43. if args.safe:
  44. while True:
  45. pcs_q = pcs_new_with_firstbits(args.bits - 1,
  46. args.firstbits, nfirst)
  47. pcs_try_sophie_germain(pcs_q)
  48. q = primegen_generate(pgc, pcs_q)
  49. pcs = pcs_new(args.bits)
  50. pcs_require_residue_1_mod_prime(pcs, q)
  51. pcs_set_oneshot(pcs)
  52. p = primegen_generate(pgc, pcs)
  53. if p is not None:
  54. break
  55. else:
  56. pcs = pcs_new_with_firstbits(args.bits, args.firstbits, nfirst)
  57. p = primegen_generate(pgc, pcs)
  58. with args.output() as f:
  59. print(args.fmt.format(int(p)), file=f)
  60. if args.mpu is not None:
  61. s = primegen_mpu_certificate(pgc, p)
  62. with args.mpu() as f:
  63. f.write(s.decode("ASCII"))
  64. if __name__ == '__main__':
  65. main()