2 ### -*- mode: python, coding: utf-8 -*-
4 ### Tool for generating and verifying primality certificates
6 ### (c) 2017 Straylight/Edgeware
9 ###----- Licensing notice ---------------------------------------------------
11 ### This file is part of the Python interface to Catacomb.
13 ### Catacomb/Python is free software; you can redistribute it and/or modify
14 ### it under the terms of the GNU General Public License as published by
15 ### the Free Software Foundation; either version 2 of the License, or
16 ### (at your option) any later version.
18 ### Catacomb/Python is distributed in the hope that it will be useful,
19 ### but WITHOUT ANY WARRANTY; without even the implied warranty of
20 ### MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 ### GNU General Public License for more details.
23 ### You should have received a copy of the GNU General Public License
24 ### along with Catacomb/Python; if not, write to the Free Software Foundation,
25 ### Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
27 ###--------------------------------------------------------------------------
30 from sys import argv, stdin, stdout, stderr
38 ###--------------------------------------------------------------------------
41 class ExpectedError (Exception):
43 I represent an expected error, which should be reported in a friendly way.
47 def prod(ff, one = 1):
49 Return ONE times the product of the elements of FF.
51 This is not done very efficiently.
53 return reduce(lambda prod, f: prod*f, ff, one)
55 def parse_label(line):
57 Split LINE at an `=' character and return the left and right halves.
59 The returned pieces have leading and trailing whitespace trimmed.
62 if eq < 0: raise ExpectedError('expected `LABEL = ...\'')
63 return line[:eq].strip(), line[eq + 1:].strip()
66 l = s.split(',', n - 1)
67 if n is not None and len(l) != n:
68 raise ExpectedError('expected `,\'-separated list of %d items' % n)
72 """Convert S to a integer."""
73 try: return C.MP(s, 0)
74 except TypeError: raise ExpectedError('invalid integer `%s\'' % s)
78 class ProgressReporter (object):
80 I keep users amused while the program looks for large prime numbers.
82 My main strategy is the printing of incomprehensible runes. I can be
83 muffled by lowering by verbosity level.
85 Prime searches are recursive in nature. When a new recursive level is
86 started, call `push'; and call `pop' when the level is finished. This must
87 be done around the top level too.
90 """Initialize the ProgressReporter."""
95 Update our idea of whether we're active.
97 We don't write inscrutable runes when inactive. The current policy is to
98 write nothing if verbosity is zero, to write runes for the top level only
99 if verbosity is 1, and to write runes always if verbosity is higher than
102 me._active = VERBOSITY >= 2 or (VERBOSITY == 1 and me._level == 0)
104 """Push a new search level."""
107 if me._level > 0: me.p('[')
110 """Pop a search level."""
111 if me._level > 0: me.p(']')
116 """Print CH as a progress rune."""
117 if me._active: stderr.write(ch); stderr.flush()
119 def combinations(r, v):
121 Return an iterator which yields all combinations of R elements from V.
123 V must be an indexable sequence. The each combination is returned as a
124 list, containing elements from V in their original order.
127 ## Set up the selection vector. C will contain the indices of the items of
128 ## V we've selected for the current combination. At all times, C contains
129 ## a strictly increasing sequence of integers in the interval [0, N).
135 ## Yield up the current combination.
136 vv = [v[i] for i in c]
139 ## Now advance to the next one. Find the last index in C which we can
140 ## increment subject to the rules. As we iterate downwards, i will
141 ## contain the index into C, and j will be the maximum acceptable value
142 ## for the corresponding item. We'll step the last index until it
143 ## reaches the limit, and then step the next one down, resetting the last
148 ## If i is zero here, then we've advanced everything as far as it will
152 ## Move down to the next index.
155 ## If this index isn't at its maximum value, then we've found the place
159 ## Step this index on by one, and set the following indices to the
160 ## immediately following values.
162 while i < r: c[i] = j; i += 1; j += 1
164 class ArgFetcher (object):
166 I return arguments from a list, reporting problems when they occur.
168 def __init__(me, argv, errfn):
170 Initialize, returning successive arguments from ARGV.
172 Errors are reported to ERRFN.
178 def arg(me, default = None, must = True):
180 Return the next argument.
182 If MUST is true, then report an error (to the ERRFN) if there are no more
183 arguments; otherwise, return the DEFAULT.
185 if me._i >= me._argc:
186 if must: me._errfn('missing argument')
188 arg = me._argv[me._i]; me._i += 1
190 def int(me, default = None, must = True, min = None, max = None):
192 Return the next argument converted to an integer.
194 If MUST is true, then report an error (to the ERRFN) if there are no more
195 arguments; otherwise return the DEFAULT. Report an error if the next
196 argument is not a valid integer, or if the integer is beyond the MIN and
199 arg = me.arg(default = None, must = must)
200 if arg is None: return default
202 except ValueError: me._errfn('bad integer')
203 if (min is not None and arg < min) or (max is not None and arg > max):
204 me._errfn('out of range')
207 ###--------------------------------------------------------------------------
208 ### Sieving for small primes.
210 class Sieve (object):
212 I represent a collection of small primes, up to some chosen limit.
214 The limit is available as the `limit' attribute. Let L be this limit;
215 then, if N < L^2 is some composite, then N has at least one prime factor
219 ## Figure out the number of bits in a (nonnegative) primitive `int'. We'll
220 ## use a list of these as our sieve.
222 while type(1 << (_NBIT + 1)) == int: _NBIT += 1
224 def __init__(me, limit):
226 Initialize a sieve holding all primes below LIMIT.
229 ## The sieve is maintained in the `_bits' attribute. This is a list of
230 ## integers, used as a bitmask: let 2 < n < L be an odd integer; then bit
231 ## (n - 3)/2 will be clear iff n is prime. Let W be the value of
232 ## `_NBIT', above; then bit W i + j in the sieve is stored in bit j of
235 ## Store the limit for later inspection.
238 ## Calculate the size of sieve we'll need and initialize the bit list.
240 sievesz = (n + me._NBIT - 1)/me._NBIT
241 me._sievemax = sievesz*me._NBIT
242 me._bits = sievesz*[0]
244 ## This is standard Sieve of Eratosthenes. For each index i: if
245 ## bit i is clear, then p = 2 i + 3 is prime, so set the bits
246 ## corresponding to each multiple of p, i.e., bits (k p - 3)/2 =
247 ## (2 k i + 3 - 3)/2 = k i for k > 1.
248 for i in xrange(me._sievemax):
249 if me._bitp(i): i += 1; continue
252 for j in xrange(i + p, me._sievemax, p): me._setbit(j)
255 def _bitp(me, i): i, j = divmod(i, me._NBIT); return (me._bits[i] >> j)&1
256 def _setbit(me, i): i, j = divmod(i, me._NBIT); me._bits[i] |= 1 << j
260 Return an iterator over the known small primes.
265 for j in xrange(me._NBIT):
266 if not (b&1): yield n
269 ## We generate the sieve on demand.
272 def initsieve(sievebits):
276 Ensure that it can be used to check the primality of numbers up to (but not
277 including) 2^SIEVEBITS.
280 if SIEVE is not None: raise ValueError('sieve already defined')
281 if sievebits < 6: sievebits = 6
282 SIEVE = Sieve(1 << (sievebits + 1)/2)
284 ###--------------------------------------------------------------------------
285 ### Primality checking.
289 Check that P is a small prime.
291 If not, raise an `ExpectedError'. The `SIEVE' variable must have been
294 if p < 2: raise ExpectedError('%d too small' % p)
295 if SIEVE.limit*SIEVE.limit < p:
296 raise ExpectedError('%d too large for small prime' % p)
297 for q in SIEVE.smallprimes():
299 if p%q == 0: raise ExpectedError('%d divides %d' % (q, p))
301 def pock_test(p, a, qq):
303 Check that P is prime using Pocklington's criterion.
305 If not, raise an `ExpectedError'.
307 Let Q be the product of the elements of the sequence QQ. The test works as
308 follows. Suppose p is the smallest prime factor of P. If A^{P-1} /== 1
309 (mod P) then P is certainly composite (Fermat's test); otherwise, we have
310 established that the order of A in (Z/pZ)^* divides P - 1. Next, let t =
311 A^{(P-1)/q} for some prime factor q of Q, and let g = gcd(t - 1, P). If g
312 = P then the proof is inconclusive; if 1 < g < P then g is a nontrivial
313 factor of P, so P is composite; otherwise, t has order q in (Z/pZ)^*, so
314 (Z/pZ)^* contains a subgroup of size q, and therefore q divides p - 1. If
315 QQ is a sequence of distinct primes, and the preceding criterion holds for
316 all q in QQ, then Q divides p - 1. If Q^2 < P then the proof is
317 inconclusive; otherwise, let p' be any prime dividing P/p. Then p' >= p >
318 Q, so p p' > Q^2 > P; but p p' divides P, so this is a contradiction.
319 Therefore P/p has no prime factors, and P is prime.
322 ## We don't actually need the distinctness criterion. Suppose that q^e
323 ## divides Q. Then gcd(t - 1, P) = 1 implies that A^{(P-1)/q^{e-1}} has
324 ## order q^e in (Z/pZ)^*, which accounts for the multiplicity.
327 if p < 2: raise ExpectedError('%d too small' % p)
329 raise ExpectedError('too few Pocklington factors for %d' % p)
330 if pow(a, p - 1, p) != 1:
331 raise ExpectedError('%d is Fermat witness for %d' % (a, p))
334 raise ExpectedError('duplicate Pocklington factor %d for %d' % (q, p))
335 g = p.gcd(pow(a, (p - 1)/q, p) - 1)
337 raise ExpectedError('%d order not multiple of %d mod %d' % (a, q, p))
339 raise ExpectedError('%d divides %d' % (g, p))
341 def ecpp_test(p, a, b, x, y, qq):
343 Check that P is prime using Goldwasser and Kilian's ECPP method.
345 If not, raise an `ExpectedError'.
347 Let Q be the product of the elements of the sequence QQ. Suppose p is the
348 smallest prime factor of P. Let g = gcd(4 A^3 + 27 B^2, P). If g = P then
349 the test is inconclusive; otherwise, if g /= 1 then g is a nontrivial
350 factor of P. Define E(GF(p)) = { (x, y) | y^2 = x^3 + A x + B } U { inf }
351 to be the elliptic curve over p with short-Weierstraß coefficients A and B;
352 we have just checked that this curve is not singular. If R = (X, Y) is not
353 a point on this curve, then the test is inconclusive. If Q R is not the
354 point at infinity, then the test fails; otherwise we deduce that P has
355 Q-torsion in E. Let S = (Q/q) R for some prime factor q of Q. If S is the
356 point at infinity then the test is inconclusive; otherwise, q divides the
357 order of S in E. If QQ is a sequence of distinct primes, and the preceding
358 criterion holds for all q in QQ, then Q divides the order of S. Therefore
359 #E(p) >= Q. If Q <= (qrrt(P) + 1)^2 then the test is inconclusive.
360 Otherwise, Hasse's theorem tells us that |p + 1 - #E(p)| <= 2 sqrt(p);
361 hence we must have p + 1 + 2 sqrt(p) = (sqrt(p) + 1)^2 >= #E(p) >= Q >
362 (qrrt(P) + 1)^2; so sqrt(p) + 1 > qrrt(P) + 1, i.e., p^2 > P. As for
363 Pocklington above, if p' is any prime factor of P/p, then p p' >= p^2 > P,
364 which is a contradiction, and we conclude that P is prime.
367 ## This isn't going to work if gcd(P, 6) /= 1: we're going to use the
368 ## large-characteristic addition formulae.
370 if g != 1: raise ExpectedError('%d divides %d' % (g, p))
372 ## We want to check that Q > (qrrt(P) + 1)^2 iff sqrt(Q) > qrrt(P) + 1; but
373 ## calculating square roots is not enjoyable (partly because we have to
374 ## deal with the imprecision). Fortunately, some algebra will help: the
375 ## condition holds iff qrrt(P) < sqrt(Q) - 1 iff P < Q^2 - 4 Q sqrt(Q) +
376 ## 6 Q - 4 sqrt(Q) + 1 = Q (Q + 6) + 1 - 4 sqrt(Q) (Q + 1) iff Q (Q + 6) -
377 ## P + 1 > 4 sqrt(Q) (Q + 1) iff (Q (Q + 6) - P + 1)^2 > 16 Q (Q + 1)^2
379 t, u = Q*(Q + 6) - p + 1, 4*(Q + 1)
380 if t*t <= Q*u*u: raise ExpectedError('too few subgroups for ECPP')
382 ## Construct the curve.
383 E = C.PrimeField(p).ec(a, b) # careful: may not be a prime!
385 ## Find the base point.
388 raise ExpectedError('(%d, %d) is not on the curve' % (x, y))
390 ## Check that it has Q-torsion.
391 if Q*R: raise ExpectedError('(%d, %d) not a %d-torsion point' % (x, y, Q))
393 ## Now check the individual factors.
396 raise ExpectedError('duplicate ECPP factor %d for %d' % (q, p))
399 raise ExpectedError('(%d, %d) order not a multiple of %d' % (x, y, q))
402 raise ExpectedError('%d divides %d' % (g, p))
404 ###--------------------------------------------------------------------------
405 ### Proof steps and proofs.
407 class BaseStep (object):
409 I'm a step in a primality proof.
411 I assert that a particular number is prime, and can check this.
413 This class provides basic protocol for proof steps, mostly to do with
416 The step's label is kept in its `label' attribute. It can be set by the
417 constructor, and is `None' by default. Users can modify this attribute if
418 they like. Labels beginning `$' are assumed to be internal and
419 uninteresting; other labels cause `check' lines to be written to the output
420 listing the actual number of interest.
422 Protocol that proof steps should provide:
424 label A string labelling the proof step and the associated prime
427 p The prime number which this step proves to be prime.
429 check() Check that the proof step is actually correct, assuming that
430 any previous steps have already been verified.
432 out(FILE) Write an appropriate encoding of the proof step to the output
435 def __init__(me, label = None, *arg, **kw):
436 """Initialize a proof step, setting a default label if necessary."""
437 super(BaseStep, me).__init__(*arg, **kw)
441 Write the proof step to an output FILE.
443 Subclasses must implement a method `_out' which actually does the work.
444 Here, we write a `check' line to verify that the proof actually applies
445 to the number we wanted, if the label says that this is an interesting
449 if me.label is not None and not me.label.startswith('$'):
450 file.write('check %s, %d, %d\n' % (me.label, me.p.nbits, me.p))
452 class SmallStep (BaseStep):
454 I represent a claim that a number is a small prime.
456 Such claims act as the base cases in a complicated primality proof. When
457 verifying, the claim is checked by trial division using a collection of
460 def __init__(me, pp, p, *arg, **kw):
462 Initialize a small-prime step.
464 PP is the overall PrimeProof object of which this is a step; P is the
465 small number whose primality is asserted.
467 super(SmallStep, me).__init__(*arg, **kw)
470 """Check that the number is indeed a small prime."""
471 return small_test(me.p)
473 """Write a small-prime step to the FILE."""
474 file.write('small %s = %d\n' % (me.label, me.p))
475 def __repr__(me): return 'SmallStep(%d)' % (me.p)
477 def parse(cls, pp, line):
479 Parse a small-prime step from a LINE in a proof file.
481 SMALL-STEP ::= `small' LABEL `=' P
483 PP is a PrimeProof object holding the results from the previous steps.
485 if SIEVE is None: raise ExpectedError('missing `sievebits\' line')
486 label, p = parse_label(line)
487 return cls(pp, conv_int(p), label = label)
489 class PockStep (BaseStep):
491 I represent a Pocklington certificate for a number.
493 The number is not explicitly represented in a proof file. See `pock_test'
494 for the underlying mathematics.
496 def __init__(me, pp, a, R, qqi, *arg, **kw):
498 Inititialize a Pocklington step.
500 PP is the overall PrimeProof object of which this is a step; A is the
501 generator of a substantial subgroup of units; R is a cofactor; and QQI is
502 a sequence of labels for previous proof steps. If Q is the product of
503 the primes listed in QQI, then the number whose primality is asserted is
506 super(PockStep, me).__init__(*arg, **kw)
510 me._qq = [pp.get_step(qi).p for qi in qqi]
511 me.p = prod(me._qq, 2*R) + 1
513 """Verify a proof step based on Pocklington's theorem."""
514 return pock_test(me.p, me._a, me._qq)
516 """Write a Pocklington step to the FILE."""
517 file.write('pock %s = %d, %d, [%s]\n' % \
519 me._R, ', '.join('%s' % qi for qi in me._qqi)))
520 def __repr__(me): return 'PockStep(%d, %d, %s)' % (me._a, me._R, me._qqi)
522 def parse(cls, pp, line):
524 Parse a Pocklington step from a LINE in a proof file.
526 POCK-STEP ::= `pock' LABEL `=' A `,' R `,' `[' Q-LIST `]'
527 Q-LIST ::= Q [`,' Q-LIST]
529 PP is a PrimeProof object holding the results from the previous steps.
531 label, rest = parse_label(line)
532 a, R, qq = parse_list(rest, 3)
534 if not qq.startswith('[') or not qq.endswith(']'):
535 raise ExpectedError('missing `[...]\' around Pocklington factors')
536 return cls(pp, conv_int(a), conv_int(R),
537 [q.strip() for q in qq[1:-1].split(',')], label = label)
539 class ECPPStep (BaseStep):
541 I represent a Goldwasser--Kilian ECPP certificate for a number.
543 def __init__(me, pp, p, a, b, x, y, qqi, *arg, **kw):
545 Inititialize an ECPP step.
547 PP is the overall PrimeProof object of which this is a step; P is the
548 number whose primality is asserted; A and B are the short Weierstraß
549 curve coefficients; X and Y are the base point coordinates; and QQI is a
550 sequence of labels for previous proof steps.
552 super(ECPPStep, me).__init__(*arg, **kw)
556 me._qq = [pp.get_step(qi).p for qi in qqi]
559 """Verify a proof step based on Goldwasser and Kilian's theorem."""
560 return ecpp_test(me.p, me._a, me._b, me._x, me._y, me._qq)
562 """Write an ECPP step to the FILE."""
563 file.write('ecpp %s = %d, %d, %d, %d, %d, [%s]\n' % \
564 (me.label, me.p, me._a, me._b, me._x, me._y,
565 ', '.join('%s' % qi for qi in me._qqi)))
567 return 'ECPPstep(%d, %d, %d, %d, %d, %s)' % \
568 (me.p, me._a, me._b, me._x, me._y, me._qqi)
570 def parse(cls, pp, line):
572 Parse an ECPP step from a LINE in a proof file.
574 ECPP-STEP ::= `ecpp' LABEL `=' P `,' A `,' B `,' X `,' Y `,'
576 Q-LIST ::= Q [`,' Q-LIST]
578 PP is a PrimeProof object holding the results from the previous steps.
580 label, rest = parse_label(line)
581 p, a, b, x, y, qq = parse_list(rest, 6)
583 if not qq.startswith('[') or not qq.endswith(']'):
584 raise ExpectedError('missing `[...]\' around ECPP factors')
585 return cls(pp, conv_int(p), conv_int(a), conv_int(b),
586 conv_int(x), conv_int(y),
587 [q.strip() for q in qq[1:-1].split(',')], label = label)
591 Handle a `check' line in a proof file.
593 CHECK ::= `check' LABEL, B, N
595 Verify that the proof step with the given LABEL asserts the primality of
596 the integer N, and that 2^{B-1} <= N < 2^B.
598 label, nb, p = parse_list(line, 3)
599 label, nb, p = label.strip(), conv_int(nb), conv_int(p)
600 pi = pp.get_step(label).p
602 raise ExpectedError('check failed: %s = %d /= %d' % (label, pi, p))
604 raise ExpectedError('check failed: nbits(%s) = %d /= %d' % \
605 (label, p.nbits, nb))
606 if VERBOSITY: print ';; %s = %d [%d]' % (label, p, nb)
608 def setsievebits(pp, line):
610 Handle a `sievebits' line in a proof file.
612 SIEVEBITS ::= `sievebits' N
614 Ensure that the verifier is willing to accept small primes up to 2^N.
618 class PrimeProof (object):
620 I represent a proof of primality for one or more numbers.
622 I can encode my proof as a line-oriented text file, in a simple format, and
623 read such a proof back to check it.
626 ## A table to dispatch on keywords read from a file.
627 STEPMAP = { 'small': SmallStep.parse,
628 'pock': PockStep.parse,
629 'ecpp': ECPPStep.parse,
630 'sievebits': setsievebits,
635 Initialize a proof object.
637 me._steps = {} # Maps labels to steps.
638 me._stepseq = [] # Sequence of labels, in order.
639 me._pmap = {} # Maps primes to steps.
642 def addstep(me, step):
644 Add a new STEP to the proof.
646 The STEP may have a label already. If not, a new internal label is
647 chosen. The proof step is checked before being added to the proof. The
651 ## If there's already a step for this prime, and the new step doesn't
652 ## have a label, then return the old one instead.
653 if step.label is None:
654 try: return me._pmap[step.p]
655 except KeyError: pass
657 ## Make sure the step is actually correct.
660 ## Generate a label if the step doesn't have one already.
661 if step.label is None: step.label = '$t%d' % me._i; me._i += 1
663 ## If the label is already taken then we have a problem.
664 if step.label in me._steps:
665 raise ExpectedError('duplicate label `%s\'' % step.label)
667 ## Store the proof step.
668 me._pmap[step.p] = step.label
669 me._steps[step.label] = step
670 me._stepseq.append(step.label)
673 def get_step(me, label):
675 Check that LABEL labels a known step, and return that step.
677 try: return me._steps[label]
678 except KeyError: raise ExpectedError('unknown label `%s\'' % label)
682 Write the proof to the given FILE.
685 ## Prefix the main steps with a `sievebits' line.
686 file.write('sievebits %d\n' % (2*(SIEVE.limit.bit_length() - 1)))
688 ## Write the steps out one by one.
689 for label in me._stepseq: me._steps[label].out(file)
693 Read a proof from a given FILE.
695 FILE ::= {STEP | CHECK | SIEVEBITS} [FILE]
696 STEP ::= SMALL-STEP | POCK-STEP
698 Comments (beginning `;') and blank lines are ignored. Other lines begin
702 for lno, line in enumerate(file, 1):
704 if line.startswith(';'): continue
705 ww = line.split(None, 1)
708 if len(ww) > 1: tail = ww[1]
711 try: op = me.STEPMAP[w]
713 raise ExpectedError('unrecognized keyword `%s\'' % w)
718 except ExpectedError, e:
719 raise ExpectedError('%s:%d: %s' % (file.name, lno, e.message))
722 ###--------------------------------------------------------------------------
723 ### Finding provable primes.
725 class BasePrime (object):
727 I represent a prime number which has been found and can be proven.
729 This object can eventually be turned into a sequence of proof steps and
730 added to a PrimeProof. This isn't done immediately, because some
731 prime-search strategies want to build a pool of provable primes and will
732 then select some subset of them to actually construct the number of final
733 interest. This way, we avoid cluttering the output proof with proofs of
734 uninteresting numbers.
738 p The prime number in question.
740 label(LABEL) Associate LABEL with this prime, and the corresponding proof
741 step. A label can be set in the constructor, or later using
744 register(PP) Register the prime with a PrimeProof, adding any necessary
745 proof steps. Returns the label of the proof step for this
749 Return a proof step for this prime.
751 def __init__(me, label = None, *args, **kw):
752 """Initialize a provable prime number object."""
753 super(BasePrime, me).__init__(*args, **kw)
754 me._index = me._pp = None
756 def label(me, label):
757 """Set this number's LABEL."""
759 def register(me, pp):
761 Register the prime's proof steps with PrimeProof PP.
763 Return the final step's label.
765 if me._pp is not None:
769 me._index = pp.addstep(me._mkstep(pp, label = me._label))
770 ##try: me._index = pp.addstep(me._mkstep(pp, label = me._label))
771 ##except: raise RuntimeError('generated proof failed sanity check')
774 class SmallPrime (BasePrime):
775 """I represent a prime small enough to be checked in isolation."""
776 def __init__(me, p, *args, **kw):
777 super(SmallPrime, me).__init__(*args, **kw)
779 def _mkstep(me, pp, **kw):
780 return SmallStep(pp, me.p, **kw)
782 class PockPrime (BasePrime):
783 """I represent a prime proven using Pocklington's theorem."""
784 def __init__(me, p, a, qq, *args, **kw):
785 super(PockPrime, me).__init__(*args, **kw)
789 def _mkstep(me, pp, **kw):
790 return PockStep(pp, me._a, (me.p - 1)/prod((q.p for q in me._qq), 2),
791 [q.register(pp) for q in me._qq], **kw)
793 def gen_small(nbits, label = None, p = None):
795 Return a new small prime.
797 The prime will be exactly NBITS bits long. The proof step will have the
798 given LABEL attached. Report progress to the ProgressReporter P.
802 ## Pick a random NBITS-bit number.
803 n = C.rand.mp(nbits, 1)
804 assert n.nbits == nbits
806 ## If it's probably prime, then check it against the small primes we
807 ## know. If it passes then we're done. Otherwise, try again.
809 for q in SIEVE.smallprimes():
810 if q*q > n: return SmallPrime(n, label = label)
813 def gen_pock(nbits, nsubbits = 0, label = None, p = ProgressReporter()):
815 Return a new prime provable using Pocklington's theorem.
817 The prime N will be exactly NBITS long, of the form N = 2 Q R + 1. If
818 NSUBBITS is nonzero, then each prime factor of Q will be NSUBBITS bits
819 long; otherwise a suitable default will be chosen. The proof step will
820 have the given LABEL attached. Report progress to the ProgressReporter P.
822 The prime numbers this function returns are a long way from being uniformly
826 ## Pick a suitable value for NSUBBITS if we don't have one.
829 ## This is remarkably tricky. Picking about 1/3 sqrt(NBITS) factors
830 ## seems about right for large numbers, but there's serious trouble
831 ## lurking for small sizes.
832 nsubbits = int(3*M.sqrt(nbits))
833 if nbits < nsubbits + 3: nsubbits = nbits//2 + 1
834 if nbits == 2*nsubbits: nsubbits += 1
836 ## Figure out how many subgroups we'll need.
837 npiece = ((nbits + 1)//2 + nsubbits - 1)//nsubbits
843 ## Come up with a collection of known prime factors.
844 p.p('!'); qq = [gen(nsubbits, p = p) for i in xrange(npiece)]
845 Q = prod(q.p for q in qq)
847 ## Come up with bounds on the cofactor. If we're to have N = 2 Q R + 1,
848 ## and 2^{B-1} <= N < 2^B, then we must have 2^{B-2}/Q <= R < 2^{B-1}/Q.
849 Rbase = (C.MP(0).setbit(nbits - 2) + Q - 1)//Q
850 Rwd = C.MP(0).setbit(nbits - 2)//Q
852 ## Probe the available space of cofactors. If the space is kind of
853 ## narrow, then we want to give up quickly if we're not finding anything
859 ## Pick a random cofactor and examine the number we ended up with.
860 ## Make sure it really does have the length we expect.
861 R = C.rand.range(Rwd) + Rbase
863 assert n.nbits == nbits
865 ## As a complication, if NPIECE is 1, it's just about possible that Q^2
866 ## <= n, in which case this isn't going to work.
869 ## If n has small factors, then pick another cofactor.
870 if C.PrimeFilter.smallfactor(n) == C.PGEN_FAIL: continue
872 ## Work through the small primes to find a suitable generator. The
873 ## value 2 is almost always acceptable, so don't try too hard here.
874 for a in I.islice(SIEVE.smallprimes(), 16):
876 ## First, try the Fermat test. If that fails, then n is definitely
878 if pow(a, n - 1, n) != 1: p.p('.'); break
881 ## Work through the subgroup orders, checking that suitable powers of
882 ## a generate the necessary subgroups.
884 if n.gcd(pow(a, (n - 1)/q.p, n) - 1) != 1:
885 p.p('@'); ok = False; break
890 if ok: p.pop(); return PockPrime(n, a, qq, label = label)
892 def gen(nbits, label = None, p = ProgressReporter()):
894 Generate a prime number with NBITS bits.
896 Give it the LABEL, and report progress to P.
898 if SIEVE.limit >> (nbits + 1)/2: g = gen_small
900 return g(nbits, label = label, p = p)
902 def gen_limlee(nbits, nsubbits,
903 label = None, qlfmt = None, p = ProgressReporter()):
905 Generate a Lim--Lee prime with NBITS bits.
907 Let p be the prime. Then we'll have p = 2 q_0 q_1 ... q_k, with all q_i at
908 least NSUBBITS bits long, and all but q_k exactly that long.
910 The prime will be given the LABEL; progress is reported to P. The factors
911 q_i will be labelled by filling in the `printf'-style format string QLFMT
915 ## Figure out how many factors (p - 1)/2 will have.
916 npiece = nbits//nsubbits
917 if npiece < 2: raise ExpectedError('too few pieces')
919 ## Decide how big to make the pool of factors.
920 poolsz = max(3*npiece + 5, 25) # Heuristic from GnuPG
922 ## Prepare for the main loop.
927 ## Try to make a prime.
931 ## Construct a pool of NSUBBITS-size primes. There's a problem with very
932 ## small sizes: we might not be able to build a pool of distinct primes.
934 for i in xrange(poolsz):
936 q = gen(nsubbits, p = p)
937 if q.p not in qmap: break
939 raise ExpectedError('insufficient diversity')
943 ## Work through combinations of factors from the pool.
944 for qq in combinations(npiece - 1, pool):
946 ## Construct the product of the selected factors.
947 qsmall = prod(q.p for q in qq)
949 ## Maybe we'll need to replace the large factor. Try not to do this
950 ## too often. DISP measures the large factor's performance at
951 ## producing candidates with the right length. If it looks bad then
952 ## we'll have to replace it.
953 if 3*disp*disp > nstep*nstep:
955 if disp < 0: p.p('<')
958 ## If we don't have a large factor, then make one.
960 qbig = gen(nbits - qsmall.nbits, p = p)
963 ## We have a candidate. Calculate it and make sure it has the right
965 n = 2*qsmall*qbig.p + 1
967 if n.nbits < nbits: disp -= 1
968 elif n.nbits > nbits: disp += 1
969 elif C.PrimeFilter.smallfactor(n) == C.PGEN_FAIL: pass
972 ## The candidate has passed the small-primes test. Now check it
973 ## against Pocklington.
974 for a in I.islice(SIEVE.smallprimes(), 16):
977 if pow(a, n - 1, n) != 1: p.p('.'); break
980 ## Find a generator of a sufficiently large subgroup.
981 if n.gcd(pow(a, (n - 1)/qbig.p, n) - 1) != 1: p.p('@'); continue
984 if n.gcd(pow(a, (n - 1)/q.p, n) - 1) != 1:
985 p.p('@'); ok = False; break
990 ## Label the factors.
993 for i, q in enumerate(qq): q.label(qlfmt % i)
995 ## Return the number we found.
996 p.pop(); return PockPrime(n, a, qq, label = label)
998 ###--------------------------------------------------------------------------
1004 ## Prepare an option parser.
1005 op = OP.OptionParser(
1007 pock [-qv] CMD ARGS...
1011 description = 'Generate or verify certified prime numbers.')
1012 op.add_option('-v', '--verbose', dest = 'verbosity',
1013 action = 'count', default = 1,
1014 help = 'Print mysterious runes while looking for prime numbers.')
1015 op.add_option('-q', '--quiet', dest = 'quietude',
1016 action = 'count', default = 0,
1017 help = 'be quiet while looking for prime numbers.')
1018 op.add_option('-s', '--sievebits', dest = 'sievebits',
1019 type = 'int', default = 32,
1020 help = 'Size (in bits) of largest small prime.')
1021 opts, argv = op.parse_args()
1022 VERBOSITY = opts.verbosity - opts.quietude
1023 p = ProgressReporter()
1024 a = ArgFetcher(argv, op.error)
1026 ## Process arguments and do what the user asked.
1030 ## Generate a prime with no special structure.
1031 initsieve(opts.sievebits)
1032 nbits = a.int(min = 4)
1034 p = gen(nbits, 'p', p = p)
1039 ## Generate a Lim--Lee prime.
1040 initsieve(opts.sievebits)
1041 nbits = a.int(min = 4)
1042 nsubbits = a.int(min = 4, max = nbits)
1044 p = gen_limlee(nbits, nsubbits, 'p', 'q_%d', p = p)
1049 ## Check an existing certificate.
1050 fn = a.arg(default = '-', must = False)
1051 if fn == '-': f = stdin
1052 else: f = open(fn, 'r')
1057 raise ExpectedError("unknown command `%s'" % w)
1059 if __name__ == '__main__':
1060 prog = OS.path.basename(argv[0])
1062 except ExpectedError, e: exit('%s: %s' % (prog, e.message))
1063 except IOError, e: exit('%s: %s' % (prog, e))
1065 ###----- That's all, folks --------------------------------------------------