diff options
author | lloyd <[email protected]> | 2009-11-17 17:40:48 +0000 |
---|---|---|
committer | lloyd <[email protected]> | 2009-11-17 17:40:48 +0000 |
commit | aa361909f881b791cdce67993f3ab0d6af47c140 (patch) | |
tree | e5e4d36ee7cfca0366a11aa90bae4d213d5ec8af | |
parent | 49b20f4e4ff3b8e3141905871ccae9fc70e77a1d (diff) |
In IF decryption, two large powmods are done, one mod p and one mod q. Spawn
one of them off in a new thread and compute the other on the current thread.
Performance on my Core2 shows a 60 to 90% improvement in overall speed in
RSA private key operations. Will probably be even better once std::async
is available (not currently in GCC) since it will probably use a thread pool
which will amortize the thread creation/shutdown cost.
-rw-r--r-- | src/pubkey/if_algo/if_op.cpp | 23 |
1 files changed, 22 insertions, 1 deletions
diff --git a/src/pubkey/if_algo/if_op.cpp b/src/pubkey/if_algo/if_op.cpp index 27aef453e..a59c7d5f9 100644 --- a/src/pubkey/if_algo/if_op.cpp +++ b/src/pubkey/if_algo/if_op.cpp @@ -7,6 +7,8 @@ #include <botan/if_op.h> #include <botan/numthry.h> +#include <future> +#include <thread> namespace Botan { @@ -38,8 +40,27 @@ BigInt Default_IF_Op::private_op(const BigInt& i) const if(q == 0) throw Internal_Error("Default_IF_Op::private_op: No private key"); - BigInt j1 = powermod_d1_p(i); + /* + * A simple std::bind(powermod_d1_p, i) would work instead of a + * lambda but GCC 4.5's std::result_of doesn't use decltype and gets + * confused + * + * Todo: use std::async() once it is in GCC + * auto future_j1 = std::async(std::bind(powermod_d1_p, i)); + * BigInt j2 = powermod_d2_q(i); + * BigInt j1 = future.get(); + */ + std::packaged_task<BigInt ()> task_j1([&]() { return powermod_d1_p(i); }); + auto future_j1 = task_j1.get_future(); + + std::thread thr_j1(std::move(task_j1)); + BigInt j2 = powermod_d2_q(i); + + BigInt j1 = future_j1.get(); + + thr_j1.join(); + j1 = reducer.reduce(sub_mul(j1, j2, c)); return mul_add(j1, q, j2); } |