1
0
mirror of https://git.tartarus.org/simon/putty.git synced 2025-01-10 01:48:00 +00:00

Allow asking for provable primes in PuTTYgen.

In Windows PuTTYgen, this is selected by an extra set of radio-button
style menu options in the Key menu. In the command-line version,
there's a new --primes=provable option.

This whole system is new, so I'm not enabling it by default just yet.
I may in future, though: it's running faster than I expected (in
particular, a lot faster than any previous prototype of the same
algorithm I attempted in standalone Python).
This commit is contained in:
Simon Tatham 2020-02-29 06:43:28 +00:00
parent 141663abba
commit 925b98b574
2 changed files with 63 additions and 4 deletions

View File

@ -217,6 +217,7 @@ int main(int argc, char **argv)
bool load_encrypted; bool load_encrypted;
const char *random_device = NULL; const char *random_device = NULL;
int exit_status = 0; int exit_status = 0;
const PrimeGenerationPolicy *primegen = &primegen_probabilistic;
if (is_interactive()) if (is_interactive())
progress_fp = stderr; progress_fp = stderr;
@ -326,6 +327,30 @@ int main(int argc, char **argv)
} }
} else if (!strcmp(opt, "-dump")) { } else if (!strcmp(opt, "-dump")) {
outtype = TEXT; outtype = TEXT;
} else if (!strcmp(opt, "-primes")) {
if (!val && argc > 1)
--argc, val = *++argv;
if (!val) {
errs = true;
fprintf(stderr, "puttygen: option `-%s'"
" expects an argument\n", opt);
} else if (!strcmp(val, "probable") ||
!strcmp(val, "probabilistic")) {
primegen = &primegen_probabilistic;
} else if (!strcmp(val, "provable") ||
!strcmp(val, "simple") ||
!strcmp(val, "maurer-simple")) {
primegen = &primegen_provable_maurer_simple;
} else if (!strcmp(val, "provable-even") ||
!strcmp(val, "even") ||
!strcmp(val, "complex") ||
!strcmp(val, "maurer-complex")) {
primegen = &primegen_provable_maurer_complex;
} else {
errs = true;
fprintf(stderr, "puttygen: unrecognised prime-"
"generation mode `%s'\n", val);
}
} else { } else {
errs = true; errs = true;
fprintf(stderr, fprintf(stderr,
@ -700,8 +725,7 @@ int main(int argc, char **argv)
smemclr(entropy, bits/8); smemclr(entropy, bits/8);
sfree(entropy); sfree(entropy);
PrimeGenerationContext *pgc = primegen_new_context( PrimeGenerationContext *pgc = primegen_new_context(primegen);
&primegen_probabilistic);
if (keytype == DSA) { if (keytype == DSA) {
struct dss_key *dsskey = snew(struct dss_key); struct dss_key *dsskey = snew(struct dss_key);

View File

@ -393,6 +393,7 @@ struct rsa_key_thread_params {
int key_bits; /* bits in key modulus (RSA, DSA) */ int key_bits; /* bits in key modulus (RSA, DSA) */
int curve_bits; /* bits in elliptic curve (ECDSA) */ int curve_bits; /* bits in elliptic curve (ECDSA) */
keytype keytype; keytype keytype;
const PrimeGenerationPolicy *primepolicy;
union { union {
RSAKey *key; RSAKey *key;
struct dss_key *dsskey; struct dss_key *dsskey;
@ -409,8 +410,7 @@ static DWORD WINAPI generate_key_thread(void *param)
win_progress_initialise(&prog); win_progress_initialise(&prog);
PrimeGenerationContext *pgc = primegen_new_context( PrimeGenerationContext *pgc = primegen_new_context(params->primepolicy);
&primegen_probabilistic);
if (params->keytype == DSA) if (params->keytype == DSA)
dsa_generate(params->dsskey, params->key_bits, pgc, &prog.rec); dsa_generate(params->dsskey, params->key_bits, pgc, &prog.rec);
@ -437,6 +437,7 @@ struct MainDlgState {
int key_bits, curve_bits; int key_bits, curve_bits;
bool ssh2; bool ssh2;
keytype keytype; keytype keytype;
const PrimeGenerationPolicy *primepolicy;
char **commentptr; /* points to key.comment or ssh2key.comment */ char **commentptr; /* points to key.comment or ssh2key.comment */
ssh2_userkey ssh2key; ssh2_userkey ssh2key;
unsigned *entropy; unsigned *entropy;
@ -515,6 +516,7 @@ enum {
IDC_BOX_PARAMS, IDC_BOX_PARAMS,
IDC_TYPESTATIC, IDC_KEYSSH1, IDC_KEYSSH2RSA, IDC_KEYSSH2DSA, IDC_TYPESTATIC, IDC_KEYSSH1, IDC_KEYSSH2RSA, IDC_KEYSSH2DSA,
IDC_KEYSSH2ECDSA, IDC_KEYSSH2ED25519, IDC_KEYSSH2ECDSA, IDC_KEYSSH2ED25519,
IDC_PRIMEGEN_PROB, IDC_PRIMEGEN_MAURER_SIMPLE, IDC_PRIMEGEN_MAURER_COMPLEX,
IDC_BITSSTATIC, IDC_BITS, IDC_BITSSTATIC, IDC_BITS,
IDC_CURVESTATIC, IDC_CURVE, IDC_CURVESTATIC, IDC_CURVE,
IDC_NOTHINGSTATIC, IDC_NOTHINGSTATIC,
@ -692,6 +694,22 @@ void ui_set_key_type(HWND hwnd, struct MainDlgState *state, int button)
button, MF_BYCOMMAND); button, MF_BYCOMMAND);
ui_update_key_type_ctrls(hwnd); ui_update_key_type_ctrls(hwnd);
} }
void ui_set_primepolicy(HWND hwnd, struct MainDlgState *state, int option)
{
CheckMenuRadioItem(state->keymenu, IDC_PRIMEGEN_PROB,
IDC_PRIMEGEN_MAURER_COMPLEX, option, MF_BYCOMMAND);
switch (option) {
case IDC_PRIMEGEN_PROB:
state->primepolicy = &primegen_probabilistic;
break;
case IDC_PRIMEGEN_MAURER_SIMPLE:
state->primepolicy = &primegen_provable_maurer_simple;
break;
case IDC_PRIMEGEN_MAURER_COMPLEX:
state->primepolicy = &primegen_provable_maurer_complex;
break;
}
}
void load_key_file(HWND hwnd, struct MainDlgState *state, void load_key_file(HWND hwnd, struct MainDlgState *state,
Filename *filename, bool was_import_cmd) Filename *filename, bool was_import_cmd)
@ -882,6 +900,7 @@ static void start_generating_key(HWND hwnd, struct MainDlgState *state)
params->key_bits = state->key_bits; params->key_bits = state->key_bits;
params->curve_bits = state->curve_bits; params->curve_bits = state->curve_bits;
params->keytype = state->keytype; params->keytype = state->keytype;
params->primepolicy = state->primepolicy;
params->key = &state->key; params->key = &state->key;
params->dsskey = &state->dsskey; params->dsskey = &state->dsskey;
@ -949,6 +968,13 @@ static INT_PTR CALLBACK MainDlgProc(HWND hwnd, UINT msg,
AppendMenu(menu1, MF_ENABLED, IDC_KEYSSH2DSA, "SSH-2 &DSA key"); AppendMenu(menu1, MF_ENABLED, IDC_KEYSSH2DSA, "SSH-2 &DSA key");
AppendMenu(menu1, MF_ENABLED, IDC_KEYSSH2ECDSA, "SSH-2 &ECDSA key"); AppendMenu(menu1, MF_ENABLED, IDC_KEYSSH2ECDSA, "SSH-2 &ECDSA key");
AppendMenu(menu1, MF_ENABLED, IDC_KEYSSH2ED25519, "SSH-2 Ed&25519 key"); AppendMenu(menu1, MF_ENABLED, IDC_KEYSSH2ED25519, "SSH-2 Ed&25519 key");
AppendMenu(menu1, MF_SEPARATOR, 0, 0);
AppendMenu(menu1, MF_ENABLED, IDC_PRIMEGEN_PROB,
"Use probable primes (fast)");
AppendMenu(menu1, MF_ENABLED, IDC_PRIMEGEN_MAURER_SIMPLE,
"Use proven primes (slower)");
AppendMenu(menu1, MF_ENABLED, IDC_PRIMEGEN_MAURER_COMPLEX,
"Use proven primes with even distribution (slowest)");
AppendMenu(menu, MF_POPUP | MF_ENABLED, (UINT_PTR) menu1, "&Key"); AppendMenu(menu, MF_POPUP | MF_ENABLED, (UINT_PTR) menu1, "&Key");
state->keymenu = menu1; state->keymenu = menu1;
@ -1063,6 +1089,7 @@ static INT_PTR CALLBACK MainDlgProc(HWND hwnd, UINT msg,
endbox(&cp); endbox(&cp);
} }
ui_set_key_type(hwnd, state, IDC_KEYSSH2RSA); ui_set_key_type(hwnd, state, IDC_KEYSSH2RSA);
ui_set_primepolicy(hwnd, state, IDC_PRIMEGEN_PROB);
SetDlgItemInt(hwnd, IDC_BITS, DEFAULT_KEY_BITS, false); SetDlgItemInt(hwnd, IDC_BITS, DEFAULT_KEY_BITS, false);
SendDlgItemMessage(hwnd, IDC_CURVE, CB_SETCURSEL, SendDlgItemMessage(hwnd, IDC_CURVE, CB_SETCURSEL,
DEFAULT_CURVE_INDEX, 0); DEFAULT_CURVE_INDEX, 0);
@ -1119,6 +1146,14 @@ static INT_PTR CALLBACK MainDlgProc(HWND hwnd, UINT msg,
ui_set_key_type(hwnd, state, LOWORD(wParam)); ui_set_key_type(hwnd, state, LOWORD(wParam));
break; break;
} }
case IDC_PRIMEGEN_PROB:
case IDC_PRIMEGEN_MAURER_SIMPLE:
case IDC_PRIMEGEN_MAURER_COMPLEX: {
state = (struct MainDlgState *)
GetWindowLongPtr(hwnd, GWLP_USERDATA);
ui_set_primepolicy(hwnd, state, LOWORD(wParam));
break;
}
case IDC_QUIT: case IDC_QUIT:
PostMessage(hwnd, WM_CLOSE, 0, 0); PostMessage(hwnd, WM_CLOSE, 0, 0);
break; break;