From 9af72ca1e82483c1c686f5236f658a73e22ba087 Mon Sep 17 00:00:00 2001 From: Simon Tatham Date: Sun, 23 Feb 2020 14:08:57 +0000 Subject: [PATCH] Move init_primes_array out into its own file. 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. --- Recipe | 13 ++++++++----- smallprimes.c | 44 ++++++++++++++++++++++++++++++++++++++++++++ sshkeygen.h | 12 ++++++++++++ sshprime.c | 44 +++++++++----------------------------------- 4 files changed, 73 insertions(+), 40 deletions(-) create mode 100644 smallprimes.c create mode 100644 sshkeygen.h diff --git a/Recipe b/Recipe index 468ad715..2e2fb5f0 100644 --- a/Recipe +++ b/Recipe @@ -281,6 +281,9 @@ UXSSH = SSH uxnoise uxagentc uxgss uxshare # SFTP implementation (pscp, psftp). SFTP = psftpcommon sftp sftpcommon logging cmdline +# Components of the prime-generation system. +SSHPRIME = sshprime smallprimes + # Miscellaneous objects appearing in all the utilities, or all the # network ones, or the Unix or Windows subsets of those in turn. MISC = misc utils marshal memory stripctrl wcwidth @@ -294,7 +297,7 @@ UXMISC = MISCNET UXMISCCOMMON uxproxy uxutils # SSH server. SSHSERVER = SSHCOMMON sshserver settings be_none logging ssh2kex-server - + ssh2userauth-server sshrsag sshprime ssh2connection-server + + ssh2userauth-server sshrsag SSHPRIME ssh2connection-server + sesschan sftpcommon sftpserver proxy cproxy ssh1login-server + ssh1connection-server scpserver @@ -347,7 +350,7 @@ pageant : [G] winpgnt pageant sshrsa sshpubk sshdes ARITH sshmd5 version + sshauxcrypt sshhmac wincapi winnps winnpc winhsock errsock winnet + winhandl callback be_misc winselgui winhandl LIBS -puttygen : [G] winpgen KEYGEN sshprime sshdes ARITH sshmd5 version +puttygen : [G] winpgen KEYGEN SSHPRIME sshdes ARITH sshmd5 version + sshrand winnoise sshsha winstore MISC winctrls sshrsa sshdss winmisc + sshpubk sshaes sshsh256 sshsh512 IMPORT winutils puttygen.res + tree234 notiming winhelp winnojmp CONF LIBS wintime sshecc sshprng @@ -366,7 +369,7 @@ puttytel : [X] GTKTERM uxmisc misc ldisc settings uxsel U_BE_NOSSH plink : [U] uxplink uxcons NONSSH UXSSH U_BE_ALL logging UXMISC uxsignal + ux_x11 noterm uxnogtk sessprep cmdline clicons uxcliloop -PUTTYGEN_UNIX = KEYGEN sshprime sshdes ARITH sshmd5 version sshprng +PUTTYGEN_UNIX = KEYGEN SSHPRIME sshdes ARITH sshmd5 version sshprng + sshrand uxnoise sshsha MISC sshrsa sshdss uxcons uxstore uxmisc + sshpubk sshaes sshsh256 sshsh512 IMPORT puttygen.res time tree234 + uxgen notiming CONF sshecc uxnogtk sshauxcrypt sshhmac @@ -395,9 +398,9 @@ osxlaunch : [UT] osxlaunch fuzzterm : [UT] UXTERM CHARSET MISC version uxmisc uxucs fuzzterm time settings + uxstore be_none uxnogtk memory -testcrypt : [UT] testcrypt SSHCRYPTO sshprng sshprime sshpubk marshal utils +testcrypt : [UT] testcrypt SSHCRYPTO sshprng SSHPRIME sshpubk marshal utils + memory tree234 uxutils KEYGEN -testcrypt : [C] testcrypt SSHCRYPTO sshprng sshprime sshpubk marshal utils +testcrypt : [C] testcrypt SSHCRYPTO sshprng SSHPRIME sshpubk marshal utils + memory tree234 winmiscs KEYGEN testsc : [UT] testsc SSHCRYPTO marshal utils memory tree234 wildcard + sshmac uxutils sshpubk diff --git a/smallprimes.c b/smallprimes.c new file mode 100644 index 00000000..a43b0bde --- /dev/null +++ b/smallprimes.c @@ -0,0 +1,44 @@ +/* + * smallprimes.c: implementation of the array of small primes defined + * in sshkeygen.h. + */ + +#include +#include "ssh.h" +#include "sshkeygen.h" + +/* The real array that stores the primes. It has to be writable in + * this module, but outside this module, we only expose the + * const-qualified pointer 'smallprimes' so that nobody else can + * accidentally overwrite it. */ +static unsigned short smallprimes_array[NSMALLPRIMES]; + +const unsigned short *const smallprimes = smallprimes_array; + +void init_smallprimes(void) +{ + if (smallprimes_array[0]) + return; /* already done */ + + bool A[65536]; + + for (size_t i = 2; i < lenof(A); i++) + A[i] = true; + + for (size_t i = 2; i < lenof(A); i++) { + if (!A[i]) + continue; + for (size_t j = 2*i; j < lenof(A); j += i) + A[j] = false; + } + + size_t pos = 0; + for (size_t i = 2; i < lenof(A); i++) { + if (A[i]) { + assert(pos < NSMALLPRIMES); + smallprimes_array[pos++] = i; + } + } + + assert(pos == NSMALLPRIMES); +} diff --git a/sshkeygen.h b/sshkeygen.h new file mode 100644 index 00000000..89b1a243 --- /dev/null +++ b/sshkeygen.h @@ -0,0 +1,12 @@ +/* + * sshkeygen.h: routines used internally to key generation. + */ + +/* + * 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); diff --git a/sshprime.c b/sshprime.c index cab601df..602d6c15 100644 --- a/sshprime.c +++ b/sshprime.c @@ -5,6 +5,7 @@ #include #include "ssh.h" #include "mpint.h" +#include "sshkeygen.h" /* * This prime generation algorithm is pretty much cribbed from @@ -107,34 +108,6 @@ * but 1s.) */ -static unsigned short primes[6542]; /* # primes < 65536 */ -#define NPRIMES (lenof(primes)) - -static void init_primes_array(void) -{ - if (primes[0]) - return; /* already done */ - - bool A[65536]; - - for (size_t i = 2; i < lenof(A); i++) - A[i] = true; - - for (size_t i = 2; i < lenof(A); i++) { - if (!A[i]) - continue; - for (size_t j = 2*i; j < lenof(A); j += i) - A[j] = false; - } - - size_t pos = 0; - for (size_t i = 2; i < lenof(A); i++) - if (A[i]) - primes[pos++] = i; - - assert(pos == NPRIMES); -} - static unsigned short mp_mod_short(mp_int *x, unsigned short modulus) { /* @@ -176,7 +149,7 @@ mp_int *primegen( int bits, int modulus, int residue, mp_int *factor, int phase, progfn_t pfn, void *pfnparam, unsigned firstbits) { - init_primes_array(); + init_smallprimes(); int progress = 0; @@ -220,16 +193,16 @@ mp_int *primegen( */ /* List the moduli */ - unsigned long moduli[NPRIMES + 1]; - for (size_t i = 0; i < NPRIMES; i++) - moduli[i] = primes[i]; - moduli[NPRIMES] = modulus; + unsigned long moduli[NSMALLPRIMES + 1]; + for (size_t i = 0; i < NSMALLPRIMES; i++) + moduli[i] = smallprimes[i]; + moduli[NSMALLPRIMES] = modulus; /* Find the residue of our starting number mod each of them. Also * set up the multipliers array which tells us how each one will * change when we increment the number (which isn't just 1 if * we're incrementing by multiples of factor). */ - unsigned long residues[NPRIMES + 1], multipliers[NPRIMES + 1]; + unsigned long residues[NSMALLPRIMES + 1], multipliers[NSMALLPRIMES + 1]; for (size_t i = 0; i < lenof(moduli); i++) { residues[i] = mp_mod_short(p, moduli[i]); if (factor) @@ -239,7 +212,8 @@ mp_int *primegen( } /* Adjust the last entry so that it avoids a residue other than zero */ - residues[NPRIMES] = (residues[NPRIMES] + modulus - residue) % modulus; + residues[NSMALLPRIMES] = (residues[NSMALLPRIMES] + modulus + - residue) % modulus; /* * Now loop until no residue in that list is zero, to find a