diff options
author | lloyd <[email protected]> | 2009-11-17 21:45:09 +0000 |
---|---|---|
committer | lloyd <[email protected]> | 2009-11-17 21:45:09 +0000 |
commit | d5310f79218a960fea4b8522d4529305971334ce (patch) | |
tree | 1a15d6872f50286ca8bbbd55c36d546233074a2c | |
parent | 0467bf03eae3ace3412b5218210eb15b6c6bd30b (diff) |
Add a simple version of std::async as std_async in async.h and use it
in the RSA and DSA ops.
-rw-r--r-- | src/pubkey/dsa/dsa_op.cpp | 27 | ||||
-rw-r--r-- | src/pubkey/if_algo/if_op.cpp | 21 | ||||
-rw-r--r-- | src/utils/async.h | 33 |
3 files changed, 42 insertions, 39 deletions
diff --git a/src/pubkey/dsa/dsa_op.cpp b/src/pubkey/dsa/dsa_op.cpp index 4c84667eb..03eaebfb0 100644 --- a/src/pubkey/dsa/dsa_op.cpp +++ b/src/pubkey/dsa/dsa_op.cpp @@ -1,13 +1,12 @@ /* * DSA Operations -* (C) 1999-2007 Jack Lloyd +* (C) 1999-2009 Jack Lloyd * * Distributed under the terms of the Botan license */ #include <botan/dsa_op.h> -#include <thread> -#include <future> +#include <botan/async.h> namespace Botan { @@ -43,21 +42,12 @@ bool Default_DSA_Op::verify(const byte msg[], u32bit msg_len, s = inverse_mod(s, q); - // Todo: use async() - - std::packaged_task<BigInt ()> task_s_i( + auto future_s_i = std_async( [&]() { return powermod_g_p(mod_q.multiply(s, i)); }); - auto future_s_i = task_s_i.get_future(); - - std::thread thr_s_i(std::move(task_s_i)); - BigInt s_r = powermod_y_p(mod_q.multiply(s, r)); - BigInt s_i = future_s_i.get(); - thr_s_i.join(); - s = mod_p.multiply(s_i, s_r); return (mod_q.reduce(s) == r); @@ -72,20 +62,13 @@ SecureVector<byte> Default_DSA_Op::sign(const byte in[], u32bit length, if(x == 0) throw Internal_Error("Default_DSA_Op::sign: No private key"); + auto future_r = std_async([&]() { return mod_q.reduce(powermod_g_p(k)); }); + const BigInt& q = group.get_q(); BigInt i(in, length); - std::packaged_task<BigInt ()> task_r( - [&]() { return mod_q.reduce(powermod_g_p(k)); }); - - auto future_r = task_r.get_future(); - - std::thread thr_r(std::move(task_r)); - BigInt s = inverse_mod(k, q); - BigInt r = future_r.get(); - thr_r.join(); s = mod_q.multiply(s, mul_add(x, r, i)); diff --git a/src/pubkey/if_algo/if_op.cpp b/src/pubkey/if_algo/if_op.cpp index a59c7d5f9..7974bf4f0 100644 --- a/src/pubkey/if_algo/if_op.cpp +++ b/src/pubkey/if_algo/if_op.cpp @@ -1,14 +1,13 @@ /* -* IF (RSA/RW) Operation -* (C) 1999-2007 Jack Lloyd +* Integer Factorization Scheme (RSA/RW) Operation +* (C) 1999-2009 Jack Lloyd * * Distributed under the terms of the Botan license */ #include <botan/if_op.h> #include <botan/numthry.h> -#include <future> -#include <thread> +#include <botan/async.h> namespace Botan { @@ -44,23 +43,11 @@ BigInt Default_IF_Op::private_op(const BigInt& i) const * 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)); - + auto future_j1 = std_async([&]() { return powermod_d1_p(i); }); 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); } diff --git a/src/utils/async.h b/src/utils/async.h new file mode 100644 index 000000000..85702c114 --- /dev/null +++ b/src/utils/async.h @@ -0,0 +1,33 @@ +/** +* Standin for C++0x's std::async +* (C) 2009 Jack Lloyd +* +* Distributed under the terms of the Botan license +*/ + +#ifndef BOTAN_ASYNC_H__ +#define BOTAN_ASYNC_H__ + +#include <future> +#include <thread> + +namespace Botan { + +/** +* A simple version of std::async (as it is not in GCC 4.5) +* Will be removed once GCC supports it natively +*/ +template<typename F> +auto std_async(F f) -> std::unique_future<decltype(f())> + { + typedef decltype(f()) result_type; + std::packaged_task<result_type ()> task(std::move(f)); + std::unique_future<result_type> future = task.get_future(); + std::thread thread(std::move(task)); + thread.detach(); + return future; + } + +} + +#endif |