Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mRemoteNG/PuTTYNG.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
AgeCommit message (Collapse)Author
2021-08-27Side-channel-safe rewrite of the Miller-Rabin test.Simon Tatham
Thanks to Mark Wooding for explaining the method of doing this. At first glance it seemed _obviously_ impossible to run an algorithm that needs an iteration per factor of 2 in p-1, without a timing leak giving away the number of factors of 2 in p-1. But it's not, because you can do the M-R checks interleaved with each step of your whole modular exponentiation, and they're cheap enough that you can do them in _every_ step, even the ones where the exponent is too small for M-R to be interested in yet, and then do bitwise masking to exclude the spurious results from the final output.
2021-08-27Add some tests of Miller-Rabin to cryptsuite.Simon Tatham
I'm about to rewrite the Miller-Rabin testing code, so let's start by introducing a test suite that the old version passes, and then I can make sure the new one does too.
2021-04-22Spelling: standardise on "DSA", not "DSS".Simon Tatham
This code base has always been a bit confused about which spelling it likes to use to refer to that signature algorithm. The SSH protocol id is "ssh-dss". But everyone I know refers to it as the Digital Signature _Algorithm_, not the Digital Signature _Standard_. When I moved everything down into the crypto subdir, I took the opportunity to rename sshdss.c to dsa.c. Now I'm doing the rest of the job: all internal identifiers and code comments refer to DSA, and the spelling "dss" only survives in externally visible identifiers that have to remain constant. (Such identifiers include the SSH protocol id, and also the string id used to identify the key type in PuTTY's own host key cache. We can't change the latter without causing everyone a backwards-compatibility headache, and if we _did_ ever decide to do that, we'd surely want to do a much more thorough job of making the cache format more sensible!)
2020-03-07RSA generation: option to generate strong primes.Simon Tatham
A 'strong' prime, as defined by the Handbook of Applied Cryptography, is a prime p such that each of p-1 and p+1 has a large prime factor, and that the large factor q of p-1 is such that q-1 in turn _also_ has a large prime factor. HoAC says that making your RSA key using primes of this form defeats some factoring algorithms - but there are other faster algorithms to which it makes no difference. So this is probably not a useful precaution in practice. However, it has been recommended in the past by some official standards, and it's easy to implement given the new general facility in PrimeCandidateSource that lets you ask for your prime to satisfy an arbitrary modular congruence. (And HoAC also says there's no particular reason _not_ to use strong primes.) So I provide it as an option, just in case anyone wants to select it. The change to the key generation algorithm is entirely in sshrsag.c, and is neatly independent of the prime-generation system in use. If you're using Maurer provable prime generation, then the known factor q of p-1 can be used to help certify p, and the one for q-1 to help with q in turn; if you switch to probabilistic prime generation then you still get an RSA key with the right structure, except that every time the definition says 'prime factor' you just append '(probably)'. (The probabilistic version of this procedure is described as 'Gordon's algorithm' in HoAC section 4.4.2.)
2020-03-07PrimeCandidateSource: add one-shot mode.Simon Tatham
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-03-07PrimeCandidateSource: add Sophie Germain filtering.Simon Tatham
A Sophie Germain prime is a prime p such that 2p+1 is also prime. The larger prime of the pair 2p+1 is also known as a 'safe prime', and is the preferred kind of modulus for conventional Diffie-Hellman. Generating these is harder work than normal prime generation. There's not really much of a technique except to just keep generating candidate primes p and then testing 2p+1. But what you _can_ do to speed things up is to get the prime-candidate generator to help a bit: it's already enforcing that no small prime divides p, and it's easy to get it to also enforce that no small prime divides 2p+1. That check can filter out a lot of bad candidates early, before you waste time on the more expensive checks, so you have a better chance of success with each number that gets as far as Miller-Rabin. Here I add an extra setup function for PrimeCandidateSource which enables those extra checks. After you call pcs_try_sophie_germain(), the PCS will only deliver you numbers for which both p and 2p+1 are free of small factors.
2020-03-07Generate MPU certificates for proven primes.Simon Tatham
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-03-01New system for generating provable prime numbers.Simon Tatham
This uses all the facilities I've been adding in previous commits. It implements Maurer's algorithm for generating a prime together with a Pocklington certificate of its primality, by means of recursing to generate smaller primes to be factors of p-1 for the Pocklington check, then doing a test Miller-Rabin iteration to quickly exclude obvious composites, and then doing the full Pocklington check. In my case, this means I add each prime I generate to a Pockle. So the algorithm says: recursively generate some primes and add them to the PrimeCandidateSource, then repeatedly get a candidate value back from the pcs, check it with M-R, and feed it to the Pockle. If the Pockle accepts it, then we're done (and the Pockle will then know that value is prime when our recursive caller uses it in turn, if we have one). A small refinement to that algorithm is that I iterate M-R until the witness value I tried is such that it at least _might_ be a primitive root - which is to say that M-R didn't get 1 by evaluating any power of it smaller than n-1. That way, there's less chance of the Pockle rejecting the witness value. And sooner or later M-R must _either_ tell me I've got a potential primitive-root witness _or_ tell me it's shown the number to be composite.
2020-03-01Add linear mode to the new progress reporting system.Simon Tatham
The old system I removed in commit 79d3c1783b had both linear and exponential phase types, but the new one only had exponential, because at that point I'd just thrown away all the clients of the linear phase type. But I'm going to add another one shortly, so I have to put it back in.
2020-03-01PrimeCandidateSource: two extra query functions.Simon Tatham
pcs_get_upper_bound lets the holder of a PrimeCandidateSource ask what is the largest value it might ever generate. pcs_get_bits_remaining lets it ask how much extra entropy it's going to generate on top of the requirements that have already been input into it. Both of these will be needed by the upcoming provable-prime work to decide what sizes of subsidiary prime to generate.
2020-03-01PrimeCandidateSource: remember prime factors of n-1.Simon Tatham
We already had a function pcs_require_residue_1() which lets you ask PrimeCandidateSource to ensure it only returns numbers congruent to 1 mod a given value. pcs_require_residue_1_mod_prime() is the same, but it also records the number in a list of prime factors of n-1, which can be queried later. The idea is that if you're generating a DSA key, in which the small prime q must divide p-1, the upcoming provable generation algorithm will be able to recover q from the PrimeCandidateSource and use it as part of the primality certificate, which reduces the number of bits of extra prime factors it also has to make up.
2020-03-01New 'Pockle' object, for verifying primality.Simon Tatham
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-03-01Introduce a vtable system for prime generation.Simon Tatham
The functions primegen() and primegen_add_progress_phase() are gone. In their place is a small vtable system with two methods corresponding to them, plus the usual admin of allocating and freeing contexts. This API change is the starting point for being able to drop in different prime generation algorithms at run time in response to user configuration.
2020-02-29Factor out Miller-Rabin checking into its own file.Simon Tatham
This further cleans up the prime-generation code, to the point where the main primegen() function has almost nothing in it. Also now I'll be able to reuse M-R as a primitive in more sophisticated alternatives to primegen().
2020-02-29New vtable API for keygen progress reporting.Simon Tatham
The old API was one of those horrible things I used to do when I was young and foolish, in which you have just one function, and indicate which of lots of things it's doing by passing in flags. It was crying out to be replaced with a vtable. While I'm at it, I've reworked the code on the Windows side that decides what to do with the progress bar, so that it's based on actually justifiable estimates of probability rather than magic integer constants. Since computers are generally faster now than they were at the start of this project, I've also decided there's no longer any point in making the fixed final part of RSA key generation bother to report progress at all. So the progress bars are now only for the variable part, i.e. the actual prime generations. (This is a reapplication of commit a7bdefb39, without the Miller-Rabin refactoring accidentally folded into it. Also this time I've added -lm to the link options, which for some reason _didn't_ cause me a link failure last time round. No idea why not.)
2020-02-29Revert "New vtable API for keygen progress reporting."Simon Tatham
This reverts commit a7bdefb3942fec5fca41bfa46d77d70b1d6e4fd2. I had accidentally mashed it together with another commit. I did actually want to push both of them, but I'd rather push them separately! So I'm backing out the combined blob, and I'll re-push them with their proper comments and explanations.
2020-02-29New vtable API for keygen progress reporting.Simon Tatham
The old API was one of those horrible things I used to do when I was young and foolish, in which you have just one function, and indicate which of lots of things it's doing by passing in flags. It was crying out to be replaced with a vtable. While I'm at it, I've reworked the code on the Windows side that decides what to do with the progress bar, so that it's based on actually justifiable estimates of probability rather than magic integer constants. Since computers are generally faster now than they were at the start of this project, I've also decided there's no longer any point in making the fixed final part of RSA key generation bother to report progress at all. So the progress bars are now only for the variable part, i.e. the actual prime generations.
2020-02-29New API for primegen(), using PrimeCandidateSource.Simon Tatham
The more features and options I add to PrimeCandidateSource, the more cumbersome it will be to replicate each one in a command-line option to the ultimate primegen() function. So I'm moving to an API in which the client of primegen() constructs a PrimeCandidateSource themself, and passes it in to primegen(). Also, changed the API for pcs_new() so that you don't have to pass 'firstbits' unless you really want to. The net effect is that even though we've added flexibility, we've also simplified the call sites of primegen() in the simple case: if you want a 1234-bit prime, you just need to pass pcs_new(1234) as the argument to primegen, and you're done. The new declaration of primegen() lives in ssh_keygen.h, along with all the types it depends on. So I've had to #include that header in a few new files.
2020-02-23Refactor generation of candidate integers in primegen.Simon Tatham
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-23Move init_primes_array out into its own file.Simon Tatham
Mostly because I just had a neat idea about how to expose that large mutable array without it being a mutable global variable: make it a static in its own module, and expose only a _pointer_ to it, which is const-qualified. While I'm there, changed the name to something more descriptive.