mirror of
https://git.tartarus.org/simon/putty.git
synced 2025-01-09 17:38:00 +00:00
mp_modmul: cope with oversized base values.
Previously, I checked by assertion that the base was less than the modulus. There were two things wrong with this policy. Firstly, it's perfectly _meaningful_ to want to raise a large number to a power mod a smaller number, even if it doesn't come up often in cryptography; secondly, I didn't do it right, because the check was based on the formal sizes (nw fields) of the mp_ints, which meant that it was possible to have a failure of the assertion even in the case where the numerical value of the base _was_ less than the modulus. In particular, this could come up in Diffie-Hellman with a fixed group, because the fixed group modulus was decoded from an MP_LITERAL in sshdh.c which gave a minimal value of nw, but the base was the public value sent by the other end of the connection, which would sometimes be sent with the leading zero byte required by the SSH-2 mpint encoding, and would cause a value of nw one larger, failing the assertion. Fixed by simply using mp_modmul in monty_import, replacing the previous clever-but-restricted strategy that I wrote when I thought I could get away without having to write a general division-based modular reduction at all.
This commit is contained in:
parent
10f80777de
commit
bd84c5e4b3
23
mpint.c
23
mpint.c
@ -1373,21 +1373,19 @@ mp_int *monty_invert(MontyContext *mc, mp_int *x)
|
||||
|
||||
/*
|
||||
* Importing a number into Montgomery representation involves
|
||||
* multiplying it by r and reducing mod m. We could do this using the
|
||||
* straightforward mp_modmul, but since we have the machinery to avoid
|
||||
* division, why don't we use it? If we multiply the number not by r
|
||||
* itself, but by the residue of r^2 mod m, then we can do an actual
|
||||
* Montgomery reduction to reduce the result and remove the extra
|
||||
* factor of r.
|
||||
* multiplying it by r and reducing mod m. We use the general-purpose
|
||||
* mp_modmul for this, in case the input number is out of range.
|
||||
*/
|
||||
void monty_import_into(MontyContext *mc, mp_int *r, mp_int *x)
|
||||
{
|
||||
monty_mul_into(mc, r, x, mc->powers_of_r_mod_m[1]);
|
||||
}
|
||||
|
||||
mp_int *monty_import(MontyContext *mc, mp_int *x)
|
||||
{
|
||||
return monty_mul(mc, x, mc->powers_of_r_mod_m[1]);
|
||||
return mp_modmul(x, mc->powers_of_r_mod_m[0], mc->m);
|
||||
}
|
||||
|
||||
void monty_import_into(MontyContext *mc, mp_int *r, mp_int *x)
|
||||
{
|
||||
mp_int *imported = monty_import(mc, x);
|
||||
mp_copy_into(r, imported);
|
||||
mp_free(imported);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -1450,7 +1448,6 @@ mp_int *monty_pow(MontyContext *mc, mp_int *base, mp_int *exponent)
|
||||
|
||||
mp_int *mp_modpow(mp_int *base, mp_int *exponent, mp_int *modulus)
|
||||
{
|
||||
assert(base->nw <= modulus->nw);
|
||||
assert(modulus->nw > 0);
|
||||
assert(modulus->w[0] & 1);
|
||||
|
||||
|
@ -473,6 +473,10 @@ class mpint(MyTestBase):
|
||||
b, e, m = 0x2B5B93812F253FF91F56B3B4DAD01CA2884B6A80719B0DA4E2159A230C6009EDA97C5C8FD4636B324F9594706EE3AD444831571BA5E17B1B2DFA92DEA8B7E, 0x25, 0xC8FCFD0FD7371F4FE8D0150EFC124E220581569587CCD8E50423FA8D41E0B2A0127E100E92501E5EE3228D12EA422A568C17E0AD2E5C5FCC2AE9159D2B7FB8CB
|
||||
assert(int(mp_modpow(b, e, m)) == pow(b, e, m))
|
||||
|
||||
# Make sure mp_modpow can handle a base larger than the
|
||||
# modulus, by pre-reducing it
|
||||
assert(int(mp_modpow(1<<877, 907, 999979)) == pow(2, 877*907, 999979))
|
||||
|
||||
def testModsqrt(self):
|
||||
moduli = [
|
||||
5, 19, 2**16+1, 2**31-1, 2**128-159, 2**255-19,
|
||||
|
Loading…
Reference in New Issue
Block a user