1
0
mirror of https://git.tartarus.org/simon/putty.git synced 2025-01-09 17:38:00 +00:00
putty-source/sshkeygen.h

293 lines
12 KiB
C
Raw Normal View History

/*
* sshkeygen.h: routines used internally to key generation.
*/
Refactor generation of candidate integers in primegen. I've replaced the random number generation and small delta-finding loop in primegen() with a much more elaborate system in its own source file, with unit tests and everything. Immediate benefits: - fixes a theoretical possibility of overflowing the target number of bits, if the random number was so close to the top of the range that the addition of delta * factor pushed it over. However, this only happened with negligible probability. - fixes a directional bias in delta-finding. The previous code incremented the number repeatedly until it found a value coprime to all the right things, which meant that a prime preceded by a particularly long sequence of numbers with tiny factors was more likely to be chosen. Now we select candidate delta values at random, that bias should be eliminated. - changes the semantics of the outermost primegen() function to make them easier to use, because now the caller specifies the 'bits' and 'firstbits' values for the actual returned prime, rather than having to account for the factor you're multiplying it by in DSA. DSA client code is correspondingly adjusted. Future benefits: - having the candidate generation in a separate function makes it easy to reuse in alternative prime generation strategies - the available constraints support applications such as Maurer's algorithm for generating provable primes, or strong primes for RSA in which both p-1 and p+1 have a large factor. So those become things we could experiment with in future.
2020-02-23 14:30:03 +00:00
/* ----------------------------------------------------------------------
* A table of all the primes that fit in a 16-bit integer. Call
* init_primes_array to make sure it's been initialised.
*/
#define NSMALLPRIMES 6542 /* number of primes < 65536 */
extern const unsigned short *const smallprimes;
void init_smallprimes(void);
Refactor generation of candidate integers in primegen. I've replaced the random number generation and small delta-finding loop in primegen() with a much more elaborate system in its own source file, with unit tests and everything. Immediate benefits: - fixes a theoretical possibility of overflowing the target number of bits, if the random number was so close to the top of the range that the addition of delta * factor pushed it over. However, this only happened with negligible probability. - fixes a directional bias in delta-finding. The previous code incremented the number repeatedly until it found a value coprime to all the right things, which meant that a prime preceded by a particularly long sequence of numbers with tiny factors was more likely to be chosen. Now we select candidate delta values at random, that bias should be eliminated. - changes the semantics of the outermost primegen() function to make them easier to use, because now the caller specifies the 'bits' and 'firstbits' values for the actual returned prime, rather than having to account for the factor you're multiplying it by in DSA. DSA client code is correspondingly adjusted. Future benefits: - having the candidate generation in a separate function makes it easy to reuse in alternative prime generation strategies - the available constraints support applications such as Maurer's algorithm for generating provable primes, or strong primes for RSA in which both p-1 and p+1 have a large factor. So those become things we could experiment with in future.
2020-02-23 14:30:03 +00:00
/* ----------------------------------------------------------------------
* A system for making up random candidate integers during prime
* generation. This unconditionally ensures that the numbers have the
* right number of bits and are not divisible by any prime in the
* smallprimes[] array above. It can also impose further constraints,
* as documented below.
*/
typedef struct PrimeCandidateSource PrimeCandidateSource;
/*
* pcs_new: you say how many bits you want the prime to have (with the
* usual semantics that an n-bit number is in the range [2^{n-1},2^n))
* and also optionally specify what you want its topmost 'nfirst' bits
* to be.
Refactor generation of candidate integers in primegen. I've replaced the random number generation and small delta-finding loop in primegen() with a much more elaborate system in its own source file, with unit tests and everything. Immediate benefits: - fixes a theoretical possibility of overflowing the target number of bits, if the random number was so close to the top of the range that the addition of delta * factor pushed it over. However, this only happened with negligible probability. - fixes a directional bias in delta-finding. The previous code incremented the number repeatedly until it found a value coprime to all the right things, which meant that a prime preceded by a particularly long sequence of numbers with tiny factors was more likely to be chosen. Now we select candidate delta values at random, that bias should be eliminated. - changes the semantics of the outermost primegen() function to make them easier to use, because now the caller specifies the 'bits' and 'firstbits' values for the actual returned prime, rather than having to account for the factor you're multiplying it by in DSA. DSA client code is correspondingly adjusted. Future benefits: - having the candidate generation in a separate function makes it easy to reuse in alternative prime generation strategies - the available constraints support applications such as Maurer's algorithm for generating provable primes, or strong primes for RSA in which both p-1 and p+1 have a large factor. So those become things we could experiment with in future.
2020-02-23 14:30:03 +00:00
*
* (The 'first' system is used for RSA keys, where you need to arrange
* that the product of your two primes is in a more tightly
* constrained range than the factor of 4 you'd get by just generating
* two (n/2)-bit primes and multiplying them.)
Refactor generation of candidate integers in primegen. I've replaced the random number generation and small delta-finding loop in primegen() with a much more elaborate system in its own source file, with unit tests and everything. Immediate benefits: - fixes a theoretical possibility of overflowing the target number of bits, if the random number was so close to the top of the range that the addition of delta * factor pushed it over. However, this only happened with negligible probability. - fixes a directional bias in delta-finding. The previous code incremented the number repeatedly until it found a value coprime to all the right things, which meant that a prime preceded by a particularly long sequence of numbers with tiny factors was more likely to be chosen. Now we select candidate delta values at random, that bias should be eliminated. - changes the semantics of the outermost primegen() function to make them easier to use, because now the caller specifies the 'bits' and 'firstbits' values for the actual returned prime, rather than having to account for the factor you're multiplying it by in DSA. DSA client code is correspondingly adjusted. Future benefits: - having the candidate generation in a separate function makes it easy to reuse in alternative prime generation strategies - the available constraints support applications such as Maurer's algorithm for generating provable primes, or strong primes for RSA in which both p-1 and p+1 have a large factor. So those become things we could experiment with in future.
2020-02-23 14:30:03 +00:00
*/
PrimeCandidateSource *pcs_new(unsigned bits);
PrimeCandidateSource *pcs_new_with_firstbits(unsigned bits,
unsigned first, unsigned nfirst);
Refactor generation of candidate integers in primegen. I've replaced the random number generation and small delta-finding loop in primegen() with a much more elaborate system in its own source file, with unit tests and everything. Immediate benefits: - fixes a theoretical possibility of overflowing the target number of bits, if the random number was so close to the top of the range that the addition of delta * factor pushed it over. However, this only happened with negligible probability. - fixes a directional bias in delta-finding. The previous code incremented the number repeatedly until it found a value coprime to all the right things, which meant that a prime preceded by a particularly long sequence of numbers with tiny factors was more likely to be chosen. Now we select candidate delta values at random, that bias should be eliminated. - changes the semantics of the outermost primegen() function to make them easier to use, because now the caller specifies the 'bits' and 'firstbits' values for the actual returned prime, rather than having to account for the factor you're multiplying it by in DSA. DSA client code is correspondingly adjusted. Future benefits: - having the candidate generation in a separate function makes it easy to reuse in alternative prime generation strategies - the available constraints support applications such as Maurer's algorithm for generating provable primes, or strong primes for RSA in which both p-1 and p+1 have a large factor. So those become things we could experiment with in future.
2020-02-23 14:30:03 +00:00
/* Insist that generated numbers must be congruent to 'res' mod 'mod' */
void pcs_require_residue(PrimeCandidateSource *s, mp_int *mod, mp_int *res);
/* Convenience wrapper for the common case where res = 1 */
void pcs_require_residue_1(PrimeCandidateSource *s, mp_int *mod);
/* Same as pcs_require_residue_1, but also records that the modulus is
* known to be prime */
void pcs_require_residue_1_mod_prime(PrimeCandidateSource *s, mp_int *mod);
Refactor generation of candidate integers in primegen. I've replaced the random number generation and small delta-finding loop in primegen() with a much more elaborate system in its own source file, with unit tests and everything. Immediate benefits: - fixes a theoretical possibility of overflowing the target number of bits, if the random number was so close to the top of the range that the addition of delta * factor pushed it over. However, this only happened with negligible probability. - fixes a directional bias in delta-finding. The previous code incremented the number repeatedly until it found a value coprime to all the right things, which meant that a prime preceded by a particularly long sequence of numbers with tiny factors was more likely to be chosen. Now we select candidate delta values at random, that bias should be eliminated. - changes the semantics of the outermost primegen() function to make them easier to use, because now the caller specifies the 'bits' and 'firstbits' values for the actual returned prime, rather than having to account for the factor you're multiplying it by in DSA. DSA client code is correspondingly adjusted. Future benefits: - having the candidate generation in a separate function makes it easy to reuse in alternative prime generation strategies - the available constraints support applications such as Maurer's algorithm for generating provable primes, or strong primes for RSA in which both p-1 and p+1 have a large factor. So those become things we could experiment with in future.
2020-02-23 14:30:03 +00:00
/* Insist that generated numbers must _not_ be congruent to 'res' mod
* 'mod'. This is used to avoid being 1 mod the RSA public exponent,
* which is small, so it only needs ordinary integer parameters. */
void pcs_avoid_residue_small(PrimeCandidateSource *s,
unsigned mod, unsigned res);
/* Exclude any prime that has no chance of being a Sophie Germain prime. */
void pcs_try_sophie_germain(PrimeCandidateSource *s);
PrimeCandidateSource: add one-shot mode. If you want to generate a Sophie Germain / safe prime pair with this code, then after you've made p, you need to test the primality of 2p+1. The easiest way to do that is to make a PrimeCandidateSource that is so constrained as to only be able to deliver 2p+1 as a candidate, and then run the ordinary prime generation system. The problem is that the prime generation loops forever, so if 2p+1 _isn't_ prime, it will just keep testing the same number over and over again and failing the test. To solve this, I add a 'one-shot mode' to the PrimeCandidateSource itself, which will cause it to return NULL if asked to generate a second candidate. Then the prime-generation loops all detect that and return NULL in turn. However, for clients that _don't_ set a pcs into one-shot mode, the API remains unchanged: pcs_generate will not return until it's found a prime (by its own criteria). This feels like a bit of a bodge, API-wise. But the other two obvious approaches turn out more awkward. One option is to extract the Pockle from the PrimeGenerationContext and use that to directly test primality of 2p+1 based on p - but that way you don't get to _probabilistically_ generate safe primes, because that kind of PGC has no Pockle in the first place. (And you can't make one separately, because you can't convince it that an only probabilistically generated p is prime!) Another option is to add a test() method to PrimeGenerationPolicy, that sits alongside generate(). Then, having generated p, you just _test_ 2p+1. But then in the provable case you have to explain to it that it should use p as part of the proof, so that API would get awkward in its own way. So this is actually the least disruptive way to do it!
2020-02-29 06:47:12 +00:00
/* Mark a PrimeCandidateSource as one-shot, so that the prime generation
* function will return NULL if an attempt fails, rather than looping. */
void pcs_set_oneshot(PrimeCandidateSource *s);
Refactor generation of candidate integers in primegen. I've replaced the random number generation and small delta-finding loop in primegen() with a much more elaborate system in its own source file, with unit tests and everything. Immediate benefits: - fixes a theoretical possibility of overflowing the target number of bits, if the random number was so close to the top of the range that the addition of delta * factor pushed it over. However, this only happened with negligible probability. - fixes a directional bias in delta-finding. The previous code incremented the number repeatedly until it found a value coprime to all the right things, which meant that a prime preceded by a particularly long sequence of numbers with tiny factors was more likely to be chosen. Now we select candidate delta values at random, that bias should be eliminated. - changes the semantics of the outermost primegen() function to make them easier to use, because now the caller specifies the 'bits' and 'firstbits' values for the actual returned prime, rather than having to account for the factor you're multiplying it by in DSA. DSA client code is correspondingly adjusted. Future benefits: - having the candidate generation in a separate function makes it easy to reuse in alternative prime generation strategies - the available constraints support applications such as Maurer's algorithm for generating provable primes, or strong primes for RSA in which both p-1 and p+1 have a large factor. So those become things we could experiment with in future.
2020-02-23 14:30:03 +00:00
/* Prepare a PrimeCandidateSource to actually generate numbers. This
* function does last-minute computation that has to be delayed until
* all constraints have been input. */
void pcs_ready(PrimeCandidateSource *s);
/* Actually generate a candidate integer. You must free the result, of
* course. */
mp_int *pcs_generate(PrimeCandidateSource *s);
/* Free a PrimeCandidateSource. */
void pcs_free(PrimeCandidateSource *s);
/* Return some internal fields of the PCS. Used by testcrypt for
* unit-testing this system. */
void pcs_inspect(PrimeCandidateSource *pcs, mp_int **limit_out,
mp_int **factor_out, mp_int **addend_out);
/* Query functions for primegen to use */
unsigned pcs_get_bits(PrimeCandidateSource *pcs);
unsigned pcs_get_bits_remaining(PrimeCandidateSource *pcs);
mp_int *pcs_get_upper_bound(PrimeCandidateSource *pcs);
mp_int **pcs_get_known_prime_factors(PrimeCandidateSource *pcs, size_t *nout);
/* ----------------------------------------------------------------------
* A system for doing Miller-Rabin probabilistic primality tests.
* These benefit from having set up some context beforehand, if you're
* going to do more than one of them on the same candidate prime, so
* we declare an object type here to store that context.
*/
typedef struct MillerRabin MillerRabin;
/* Make and free a Miller-Rabin context. */
MillerRabin *miller_rabin_new(mp_int *p);
void miller_rabin_free(MillerRabin *mr);
/* Perform a single Miller-Rabin test, using a random witness value. */
bool miller_rabin_test_random(MillerRabin *mr);
/* Suggest how many tests are needed to make it sufficiently unlikely
* that a composite number will pass them all */
unsigned miller_rabin_checks_needed(unsigned bits);
/* An extension to the M-R test, which iterates until it either finds
* a witness value that is potentially a primitive root, or one
* that proves the number to be composite. */
mp_int *miller_rabin_find_potential_primitive_root(MillerRabin *mr);
New 'Pockle' object, for verifying primality. This implements an extended form of primality verification using certificates based on Pocklington's theorem. You make a Pockle object, and then try to convince it that one number after another is prime, by means of providing it with a list of prime factors of p-1 and a primitive root. (Or just by saying 'this prime is small enough for you to check yourself'.) Pocklington's theorem requires you to have factors of p-1 whose product is at least the square root of p. I've extended that to support factorisations only as big as the cube root, via an extension of the theorem given in Maurer's paper on generating provable primes. The Pockle object is more or less write-only: it has no methods for reading out its contents. Its only output channel is the return value when you try to insert a prime into it: if it isn't sufficiently convinced that your prime is prime, it will return an error code. So anything for which it returns POCKLE_OK you can be confident of. I'm going to use this for provable prime generation. But exposing this part of the system as an object in its own right means I can write a set of unit tests for this specifically. My negative tests exercise all the different ways a certification can be erroneous or inadequate; the positive tests include proofs of primality of various primes used in elliptic-curve crypto. The Poly1305 proof in particular is taken from a proof in DJB's paper, which has exactly the form of a Pocklington certificate only written in English.
2020-02-23 15:16:30 +00:00
/* ----------------------------------------------------------------------
* A system for proving numbers to be prime, using the Pocklington
* test, which requires knowing a partial factorisation of p-1
* (specifically, factors whose product is at least cbrt(p)) and a
* primitive root.
*
* The API consists of instantiating a 'Pockle' object, which
* internally stores a list of numbers you've already convinced it is
* prime, and can accept further primes if you give a satisfactory
* certificate of their primality based on primes it already knows
* about.
*/
typedef struct Pockle Pockle;
/* In real use, you only really need to know whether the Pockle
* successfully accepted your prime. But for testcrypt, it's useful to
* expose many different failure modes so we can try to provoke them
* all in unit tests and check they're working. */
#define POCKLE_STATUSES(X) \
X(POCKLE_OK) \
X(POCKLE_SMALL_PRIME_NOT_SMALL) \
X(POCKLE_SMALL_PRIME_NOT_PRIME) \
X(POCKLE_PRIME_SMALLER_THAN_2) \
X(POCKLE_FACTOR_NOT_KNOWN_PRIME) \
X(POCKLE_FACTOR_NOT_A_FACTOR) \
X(POCKLE_PRODUCT_OF_FACTORS_TOO_SMALL) \
X(POCKLE_FERMAT_TEST_FAILED) \
X(POCKLE_DISCRIMINANT_IS_SQUARE) \
X(POCKLE_WITNESS_POWER_IS_1) \
X(POCKLE_WITNESS_POWER_NOT_COPRIME) \
/* end of list */
#define DEFINE_ENUM(id) id,
typedef enum PockleStatus { POCKLE_STATUSES(DEFINE_ENUM) } PockleStatus;
#undef DEFINE_ENUM
/* Make a new empty Pockle, containing no primes. */
Pockle *pockle_new(void);
/* Insert a prime below 2^32 into the Pockle. No evidence is required:
* Pockle will check it itself. */
PockleStatus pockle_add_small_prime(Pockle *pockle, mp_int *p);
/* Insert a general prime into the Pockle. You must provide a list of
* prime factors of p-1, whose product exceeds the cube root of p, and
* also a primitive root mod p. */
PockleStatus pockle_add_prime(Pockle *pockle, mp_int *p,
mp_int **factors, size_t nfactors,
mp_int *primitive_root);
/* If you call pockle_mark, and later pass the returned value to
* pockle_release, it will free all the primes that were added to the
* Pockle between those two calls. Useful in recursive algorithms, to
* stop the Pockle growing unboundedly if the recursion keeps having
* to backtrack. */
size_t pockle_mark(Pockle *pockle);
void pockle_release(Pockle *pockle, size_t mark);
/* Free a Pockle. */
void pockle_free(Pockle *pockle);
Generate MPU certificates for proven primes. Conveniently checkable certificates of primality aren't a new concept. I didn't invent them, and I wasn't the first to implement them. Given that, I thought it might be useful to be able to independently verify a prime generated by PuTTY's provable prime system. Then, even if you don't trust _this_ code, you might still trust someone else's verifier, or at least be less willing to believe that both were colluding. The Perl module Math::Prime::Util is the only free software I've found that defines a specific text-file format for certificates of primality. The MPU format (as it calls it) supports various different methods of certifying the primality of a number (most of which, like Pockle's, depend on having previously proved some smaller number(s) to be prime). The system implemented by Pockle is on its list: MPU calls it by the name "BLS5". So this commit introduces extra stored data inside Pockle so that it remembers not just _that_ it believes certain numbers to be prime, but also _why_ it believed each one to be prime. Then there's an extra method in the Pockle API to translate its internal data structures into the text of an MPU certificate for any number it knows about. Math::Prime::Util doesn't come with a command-line verification tool, unfortunately; only a Perl function which you feed a string argument. So also in this commit I add test/mpu-check.pl, which is a trivial command-line client of that function. At the moment, this new piece of API is only exposed via testcrypt. I could easily put some user interface into the key generation tools that would save a few primality certificates alongside the private key, but I have yet to think of any good reason to do it. Mostly this facility is intended for debugging and cross-checking of the _algorithm_, not of any particular prime.
2020-02-29 06:44:13 +00:00
/* Generate a certificate of primality for a prime already known to
* the Pockle, in a format acceptable to Math::Prime::Util. */
strbuf *pockle_mpu(Pockle *pockle, mp_int *p);
/* ----------------------------------------------------------------------
* Callback API that allows key generation to report progress to its
* caller.
*/
typedef struct ProgressReceiverVtable ProgressReceiverVtable;
typedef struct ProgressReceiver ProgressReceiver;
typedef union ProgressPhase ProgressPhase;
union ProgressPhase {
int n;
void *p;
};
struct ProgressReceiver {
const ProgressReceiverVtable *vt;
};
struct ProgressReceiverVtable {
ProgressPhase (*add_linear)(ProgressReceiver *prog, double overall_cost);
ProgressPhase (*add_probabilistic)(ProgressReceiver *prog,
double cost_per_attempt,
double attempt_probability);
void (*ready)(ProgressReceiver *prog);
void (*start_phase)(ProgressReceiver *prog, ProgressPhase phase);
void (*report)(ProgressReceiver *prog, double progress);
void (*report_attempt)(ProgressReceiver *prog);
void (*report_phase_complete)(ProgressReceiver *prog);
};
static inline ProgressPhase progress_add_linear(ProgressReceiver *prog,
double c)
{ return prog->vt->add_linear(prog, c); }
static inline ProgressPhase progress_add_probabilistic(ProgressReceiver *prog,
double c, double p)
{ return prog->vt->add_probabilistic(prog, c, p); }
static inline void progress_ready(ProgressReceiver *prog)
{ prog->vt->ready(prog); }
static inline void progress_start_phase(
ProgressReceiver *prog, ProgressPhase phase)
{ prog->vt->start_phase(prog, phase); }
static inline void progress_report(ProgressReceiver *prog, double progress)
{ prog->vt->report(prog, progress); }
static inline void progress_report_attempt(ProgressReceiver *prog)
{ prog->vt->report_attempt(prog); }
static inline void progress_report_phase_complete(ProgressReceiver *prog)
{ prog->vt->report_phase_complete(prog); }
ProgressPhase null_progress_add_linear(
ProgressReceiver *prog, double c);
ProgressPhase null_progress_add_probabilistic(
ProgressReceiver *prog, double c, double p);
void null_progress_ready(ProgressReceiver *prog);
void null_progress_start_phase(ProgressReceiver *prog, ProgressPhase phase);
void null_progress_report(ProgressReceiver *prog, double progress);
void null_progress_report_attempt(ProgressReceiver *prog);
void null_progress_report_phase_complete(ProgressReceiver *prog);
extern const ProgressReceiverVtable null_progress_vt;
/* A helper function for dreaming up progress cost estimates. */
double estimate_modexp_cost(unsigned bits);
/* ----------------------------------------------------------------------
* The top-level API for generating primes.
*/
typedef struct PrimeGenerationPolicy PrimeGenerationPolicy;
typedef struct PrimeGenerationContext PrimeGenerationContext;
struct PrimeGenerationContext {
const PrimeGenerationPolicy *vt;
};
struct PrimeGenerationPolicy {
ProgressPhase (*add_progress_phase)(const PrimeGenerationPolicy *policy,
ProgressReceiver *prog, unsigned bits);
PrimeGenerationContext *(*new_context)(
const PrimeGenerationPolicy *policy);
void (*free_context)(PrimeGenerationContext *ctx);
mp_int *(*generate)(
PrimeGenerationContext *ctx,
PrimeCandidateSource *pcs, ProgressReceiver *prog);
Generate MPU certificates for proven primes. Conveniently checkable certificates of primality aren't a new concept. I didn't invent them, and I wasn't the first to implement them. Given that, I thought it might be useful to be able to independently verify a prime generated by PuTTY's provable prime system. Then, even if you don't trust _this_ code, you might still trust someone else's verifier, or at least be less willing to believe that both were colluding. The Perl module Math::Prime::Util is the only free software I've found that defines a specific text-file format for certificates of primality. The MPU format (as it calls it) supports various different methods of certifying the primality of a number (most of which, like Pockle's, depend on having previously proved some smaller number(s) to be prime). The system implemented by Pockle is on its list: MPU calls it by the name "BLS5". So this commit introduces extra stored data inside Pockle so that it remembers not just _that_ it believes certain numbers to be prime, but also _why_ it believed each one to be prime. Then there's an extra method in the Pockle API to translate its internal data structures into the text of an MPU certificate for any number it knows about. Math::Prime::Util doesn't come with a command-line verification tool, unfortunately; only a Perl function which you feed a string argument. So also in this commit I add test/mpu-check.pl, which is a trivial command-line client of that function. At the moment, this new piece of API is only exposed via testcrypt. I could easily put some user interface into the key generation tools that would save a few primality certificates alongside the private key, but I have yet to think of any good reason to do it. Mostly this facility is intended for debugging and cross-checking of the _algorithm_, not of any particular prime.
2020-02-29 06:44:13 +00:00
strbuf *(*mpu_certificate)(PrimeGenerationContext *ctx, mp_int *p);
const void *extra; /* additional data a particular impl might need */
};
static inline ProgressPhase primegen_add_progress_phase(
PrimeGenerationContext *ctx, ProgressReceiver *prog, unsigned bits)
{ return ctx->vt->add_progress_phase(ctx->vt, prog, bits); }
static inline PrimeGenerationContext *primegen_new_context(
const PrimeGenerationPolicy *policy)
{ return policy->new_context(policy); }
static inline void primegen_free_context(PrimeGenerationContext *ctx)
{ ctx->vt->free_context(ctx); }
static inline mp_int *primegen_generate(
PrimeGenerationContext *ctx,
PrimeCandidateSource *pcs, ProgressReceiver *prog)
{ return ctx->vt->generate(ctx, pcs, prog); }
Generate MPU certificates for proven primes. Conveniently checkable certificates of primality aren't a new concept. I didn't invent them, and I wasn't the first to implement them. Given that, I thought it might be useful to be able to independently verify a prime generated by PuTTY's provable prime system. Then, even if you don't trust _this_ code, you might still trust someone else's verifier, or at least be less willing to believe that both were colluding. The Perl module Math::Prime::Util is the only free software I've found that defines a specific text-file format for certificates of primality. The MPU format (as it calls it) supports various different methods of certifying the primality of a number (most of which, like Pockle's, depend on having previously proved some smaller number(s) to be prime). The system implemented by Pockle is on its list: MPU calls it by the name "BLS5". So this commit introduces extra stored data inside Pockle so that it remembers not just _that_ it believes certain numbers to be prime, but also _why_ it believed each one to be prime. Then there's an extra method in the Pockle API to translate its internal data structures into the text of an MPU certificate for any number it knows about. Math::Prime::Util doesn't come with a command-line verification tool, unfortunately; only a Perl function which you feed a string argument. So also in this commit I add test/mpu-check.pl, which is a trivial command-line client of that function. At the moment, this new piece of API is only exposed via testcrypt. I could easily put some user interface into the key generation tools that would save a few primality certificates alongside the private key, but I have yet to think of any good reason to do it. Mostly this facility is intended for debugging and cross-checking of the _algorithm_, not of any particular prime.
2020-02-29 06:44:13 +00:00
static inline strbuf *primegen_mpu_certificate(
PrimeGenerationContext *ctx, mp_int *p)
{ return ctx->vt->mpu_certificate(ctx, p); }
extern const PrimeGenerationPolicy primegen_probabilistic;
extern const PrimeGenerationPolicy primegen_provable_fast;
extern const PrimeGenerationPolicy primegen_provable_maurer_simple;
extern const PrimeGenerationPolicy primegen_provable_maurer_complex;
/* ----------------------------------------------------------------------
* The overall top-level API for generating entire key pairs.
*/
2020-03-02 06:52:09 +00:00
int rsa_generate(RSAKey *key, int bits, bool strong,
PrimeGenerationContext *pgc, ProgressReceiver *prog);
int dsa_generate(struct dsa_key *key, int bits, PrimeGenerationContext *pgc,
ProgressReceiver *prog);
int ecdsa_generate(struct ecdsa_key *key, int bits);
int eddsa_generate(struct eddsa_key *key, int bits);