diff options
author | lloyd <[email protected]> | 2010-09-23 22:06:49 +0000 |
---|---|---|
committer | lloyd <[email protected]> | 2010-09-23 22:06:49 +0000 |
commit | 3bbffca94fcd9830544934fac28e337f91c5d78f (patch) | |
tree | 6dbda1aa31a71032453d1987f13e519599a3509c /src | |
parent | 3ee42dc0cafad7a398ed7fd2b9bdb4ab7f771873 (diff) |
In the IDEA key schedule, using the extended Euclidean algorithm to
compute the inverses mod 65537 exposed a timing vulnerability. Avoid
this by instead using exponentiation, which takes constant time (up to
variability in the multiplication operation, at least).
Diffstat (limited to 'src')
-rw-r--r-- | src/block/idea/idea.cpp | 31 |
1 files changed, 14 insertions, 17 deletions
diff --git a/src/block/idea/idea.cpp b/src/block/idea/idea.cpp index 7673ead7e..5f0b5f195 100644 --- a/src/block/idea/idea.cpp +++ b/src/block/idea/idea.cpp @@ -33,29 +33,26 @@ inline u16bit mul(u16bit x, u16bit y) /* * Find multiplicative inverses modulo 65537 +* +* 65537 is prime; thus Fermat's little theorem tells us that +* x^65537 == x modulo 65537, which means +* x^(65537-2) == x^-1 modulo 65537 since +* x^(65537-2) * x == 1 mod 65537 +* +* Do the exponentiation with a basic square and multiply: all bits are +* of exponent are 1 so we always multiply */ u16bit mul_inv(u16bit x) { - if(x <= 1) - return x; - - u16bit t0 = static_cast<u16bit>(65537 / x), t1 = 1; - u16bit y = static_cast<u16bit>(65537 % x); + u16bit y = x; - while(y != 1) + for(u32bit i = 0; i != 15; ++i) { - u16bit q = x / y; - x %= y; - t1 += q * t0; - - if(x == 1) - return t1; - - q = y / x; - y %= x; - t0 += q * t1; + y = mul(y, y); // square + y = mul(y, x); } - return (1 - t0); + + return y; } /** |