aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--botan_version.py7
-rw-r--r--checks/dolook.cpp4
-rw-r--r--checks/ec_tests.cpp18
-rw-r--r--checks/ecdsa.cpp10
-rw-r--r--checks/nist_tests/x509test.cpp93
-rw-r--r--checks/pk_bench.cpp9
-rw-r--r--checks/validate.cpp21
-rw-r--r--checks/validate.dat157
-rwxr-xr-xconfigure.py376
-rw-r--r--doc/_templates/layout.html9
-rw-r--r--doc/algos.txt64
-rw-r--r--doc/build_log.txt5
-rw-r--r--doc/building.txt87
-rw-r--r--doc/conf.py28
-rw-r--r--doc/contents.txt6
-rw-r--r--doc/download.txt59
-rw-r--r--doc/examples/GNUmakefile2
-rw-r--r--doc/examples/cpuid.cpp1
-rw-r--r--doc/examples/socket.h114
-rw-r--r--doc/examples/tls_client.cpp13
-rw-r--r--doc/examples/tls_server.cpp7
-rw-r--r--doc/faq.txt35
-rw-r--r--doc/fpe.txt2
-rw-r--r--doc/index.txt (renamed from doc/welcome.txt)29
-rw-r--r--doc/log.txt193
-rw-r--r--doc/old/insito_manual.pdfbin150405 -> 0 bytes
-rw-r--r--doc/pgpkey.txt2
-rw-r--r--doc/python.txt14
-rw-r--r--doc/reading.txt23
-rw-r--r--doc/ssl.txt32
-rw-r--r--doc/users.txt33
-rw-r--r--readme.txt8
-rw-r--r--src/algo_factory/algo_cache.h10
-rw-r--r--src/alloc/alloc_mmap/mmap_mem.cpp16
-rw-r--r--src/alloc/secmem.h21
-rw-r--r--src/asn1/alg_id.cpp12
-rw-r--r--src/asn1/der_enc.h71
-rw-r--r--src/block/aes_ni/aes_ni.cpp (renamed from src/block/aes_intel/aes_intel.cpp)28
-rw-r--r--src/block/aes_ni/aes_ni.h (renamed from src/block/aes_intel/aes_intel.h)24
-rw-r--r--src/block/aes_ni/info.txt (renamed from src/block/aes_intel/info.txt)2
-rw-r--r--src/block/camellia/camellia.cpp311
-rw-r--r--src/block/camellia/camellia.h35
-rw-r--r--src/block/camellia/info.txt1
-rw-r--r--src/block/gost_28147/gost_28147.cpp25
-rw-r--r--src/block/gost_28147/gost_28147.h2
-rw-r--r--src/block/idea_sse2/idea_sse2.cpp8
-rw-r--r--src/block/noekeon_simd/info.txt2
-rw-r--r--src/block/serpent_simd/info.txt6
-rw-r--r--src/block/serpent_simd/serp_simd.cpp433
-rw-r--r--src/block/serpent_simd/serp_simd_sbox.h425
-rw-r--r--src/block/xtea_simd/info.txt2
-rw-r--r--src/build-data/arch/arm.txt5
-rw-r--r--src/build-data/arch/hitachi-sh.txt7
-rw-r--r--src/build-data/arch/ppc32.txt (renamed from src/build-data/arch/ppc.txt)13
-rw-r--r--src/build-data/arch/ppc64.txt1
-rw-r--r--src/build-data/arch/sparc32.txt2
-rw-r--r--src/build-data/arch/sparc64.txt6
-rw-r--r--src/build-data/arch/superh.txt5
-rw-r--r--src/build-data/arch/x86_32.txt8
-rw-r--r--src/build-data/arch/x86_64.txt6
-rw-r--r--src/build-data/botan-config.in6
-rw-r--r--src/build-data/botan.pc.in4
-rw-r--r--src/build-data/buildh.in4
-rw-r--r--src/build-data/cc/bcc.txt1
-rw-r--r--src/build-data/cc/clang.txt8
-rw-r--r--src/build-data/cc/ekopath.txt5
-rw-r--r--src/build-data/cc/gcc.txt59
-rw-r--r--src/build-data/cc/msvc.txt4
-rw-r--r--src/build-data/cc/sunstudio.txt8
-rw-r--r--src/build-data/makefile/python.in4
-rw-r--r--src/build-data/makefile/unix.in6
-rw-r--r--src/build-data/makefile/unix_shr.in10
-rw-r--r--src/build-data/os/mingw.txt4
-rw-r--r--src/build-data/os/nacl.txt4
-rw-r--r--src/build-data/os/solaris.txt3
-rwxr-xr-xsrc/build-data/scripts/dist.py168
-rw-r--r--src/cert/cvc/info.txt2
-rw-r--r--src/cert/x509cert/x509_ext.cpp15
-rw-r--r--src/codec/base64/base64.cpp150
-rw-r--r--src/codec/base64/base64.h70
-rw-r--r--src/codec/hex/hex.cpp9
-rw-r--r--src/constructs/srp6/info.txt7
-rw-r--r--src/constructs/srp6/srp6.cpp156
-rw-r--r--src/constructs/srp6/srp6.h84
-rw-r--r--src/constructs/srp6/srp6_files.cpp69
-rw-r--r--src/constructs/srp6/srp6_files.h53
-rw-r--r--src/engine/aes_isa_eng/aes_isa_engine.cpp12
-rw-r--r--src/engine/core_engine/core_modes.cpp14
-rw-r--r--src/engine/core_engine/lookup_block.cpp9
-rw-r--r--src/engine/simd_engine/info.txt2
-rw-r--r--src/entropy/dev_random/dev_random.cpp1
-rw-r--r--src/entropy/egd/es_egd.cpp2
-rw-r--r--src/entropy/hres_timer/hres_timer.cpp37
-rw-r--r--src/entropy/hres_timer/hres_timer.h3
-rw-r--r--src/entropy/unix_procs/unix_cmd.cpp1
-rw-r--r--src/filters/buf_filt.cpp2
-rw-r--r--src/filters/codec_filt/b64_filt.cpp137
-rw-r--r--src/filters/codec_filt/b64_filt.h10
-rw-r--r--src/filters/codec_filt/hex_filt.h4
-rw-r--r--src/hash/bmw_512/bmw_512.cpp (renamed from src/hash/bmw/bmw_512.cpp)0
-rw-r--r--src/hash/bmw_512/bmw_512.h (renamed from src/hash/bmw/bmw_512.h)0
-rw-r--r--src/hash/bmw_512/info.txt (renamed from src/hash/bmw/info.txt)0
-rw-r--r--src/hash/sha1/sha160.cpp8
-rw-r--r--src/hash/sha1_sse2/sha1_sse2.cpp11
-rw-r--r--src/hash/skein/skein_512.cpp2
-rw-r--r--src/kdf/prf_ssl3/info.txt (renamed from src/kdf/ssl_prf/info.txt)0
-rw-r--r--src/kdf/prf_ssl3/prf_ssl3.cpp (renamed from src/kdf/ssl_prf/prf_ssl3.cpp)0
-rw-r--r--src/kdf/prf_ssl3/prf_ssl3.h (renamed from src/kdf/ssl_prf/prf_ssl3.h)0
-rw-r--r--src/kdf/prf_tls/info.txt (renamed from src/kdf/tls_prf/info.txt)0
-rw-r--r--src/kdf/prf_tls/prf_tls.cpp (renamed from src/kdf/tls_prf/prf_tls.cpp)0
-rw-r--r--src/kdf/prf_tls/prf_tls.h (renamed from src/kdf/tls_prf/prf_tls.h)0
-rw-r--r--src/kdf/prf_x942/info.txt (renamed from src/kdf/x942_prf/info.txt)0
-rw-r--r--src/kdf/prf_x942/prf_x942.cpp (renamed from src/kdf/x942_prf/prf_x942.cpp)0
-rw-r--r--src/kdf/prf_x942/prf_x942.h (renamed from src/kdf/x942_prf/prf_x942.h)0
-rw-r--r--src/libstate/policy.cpp25
-rw-r--r--src/mac/cmac/cmac.cpp5
-rw-r--r--src/math/bigint/bigint.cpp54
-rw-r--r--src/math/bigint/bigint.h7
-rw-r--r--src/math/ec_gfp/curve_gfp.h (renamed from src/math/numbertheory/curve_gfp.h)57
-rw-r--r--src/math/ec_gfp/info.txt16
-rw-r--r--src/math/ec_gfp/point_gfp.cpp (renamed from src/math/numbertheory/point_gfp.cpp)267
-rw-r--r--src/math/ec_gfp/point_gfp.h (renamed from src/math/numbertheory/point_gfp.h)54
-rw-r--r--src/math/mp/info.txt4
-rw-r--r--src/math/mp/monty_generic/info.txt5
-rw-r--r--src/math/mp/monty_generic/mp_monty.cpp72
-rw-r--r--src/math/mp/mp_asm.cpp3
-rw-r--r--src/math/mp/mp_asm64/info.txt2
-rw-r--r--src/math/mp/mp_comba.cpp1276
-rw-r--r--src/math/mp/mp_core.h39
-rw-r--r--src/math/mp/mp_generic/mp_asm.h2
-rw-r--r--src/math/mp/mp_monty.cpp99
-rw-r--r--src/math/mp/mp_mulop.cpp (renamed from src/math/mp/mulop_generic/mp_mulop.cpp)0
-rw-r--r--src/math/mp/mulop_generic/info.txt5
-rw-r--r--src/math/numbertheory/info.txt7
-rw-r--r--src/math/numbertheory/numthry.cpp24
-rw-r--r--src/math/numbertheory/pow_mod.cpp7
-rw-r--r--src/math/numbertheory/powm_mnt.cpp58
-rw-r--r--src/math/numbertheory/reducer.cpp64
-rw-r--r--src/math/numbertheory/reducer.h4
-rw-r--r--src/passhash/bcrypt/bcrypt.cpp10
-rw-r--r--src/pk_pad/eme1/eme1.cpp59
-rw-r--r--src/pubkey/ec_group/ec_group.h6
-rw-r--r--src/pubkey/ec_group/info.txt5
-rw-r--r--src/pubkey/ecc_key/info.txt1
-rw-r--r--src/pubkey/ecdh/ecdh.h1
-rw-r--r--src/pubkey/ecdsa/ecdsa.cpp5
-rw-r--r--src/pubkey/gost_3410/gost_3410.cpp12
-rw-r--r--src/selftest/selftest.cpp2
-rw-r--r--src/simd/info.txt (renamed from src/utils/simd_32/info.txt)7
-rw-r--r--src/simd/simd_32.h (renamed from src/utils/simd_32/simd_32.h)17
-rw-r--r--src/simd/simd_altivec/info.txt9
-rw-r--r--src/simd/simd_altivec/simd_altivec.h (renamed from src/utils/simd_32/simd_altivec.h)0
-rw-r--r--src/simd/simd_scalar/info.txt7
-rw-r--r--src/simd/simd_scalar/simd_scalar.h (renamed from src/utils/simd_32/simd_scalar.h)0
-rw-r--r--src/simd/simd_sse2/info.txt9
-rw-r--r--src/simd/simd_sse2/simd_sse2.h (renamed from src/utils/simd_32/simd_sse.h)0
-rw-r--r--src/ssl/hello.cpp8
-rw-r--r--src/ssl/info.txt12
-rw-r--r--src/ssl/rec_read.cpp11
-rw-r--r--src/ssl/tls_alerts.h2
-rw-r--r--src/ssl/tls_client.cpp8
-rw-r--r--src/ssl/tls_exceptn.h2
-rw-r--r--src/ssl/tls_handshake_hash.h2
-rw-r--r--src/ssl/tls_magic.h2
-rw-r--r--src/ssl/tls_messages.h25
-rw-r--r--src/ssl/tls_record.h8
-rw-r--r--src/ssl/tls_server.cpp4
-rw-r--r--src/utils/asm_x86_32/info.txt1
-rw-r--r--src/utils/cpuid.cpp36
-rw-r--r--src/utils/cpuid.h9
-rw-r--r--src/utils/dyn_load/dyn_load.cpp5
-rw-r--r--src/utils/exceptn.h4
-rw-r--r--src/utils/version.cpp1
-rw-r--r--src/wrap/python/filter.cpp5
-rw-r--r--src/wrap/python/rsa.cpp18
175 files changed, 4332 insertions, 2253 deletions
diff --git a/botan_version.py b/botan_version.py
index 1d82cb588..a44619e71 100644
--- a/botan_version.py
+++ b/botan_version.py
@@ -1,6 +1,9 @@
release_major = 1
-release_minor = 9
-release_patch = 17
+release_minor = 10
+release_patch = 2
+
+release_vc_rev = None
+release_so_abi_rev = 0
release_datestamp = 0
diff --git a/checks/dolook.cpp b/checks/dolook.cpp
index 1015f4240..a8e08a96b 100644
--- a/checks/dolook.cpp
+++ b/checks/dolook.cpp
@@ -55,6 +55,8 @@ using namespace Botan;
#include "common.h"
+namespace {
+
/* A weird little hack to fit PBKDF algorithms into the validation
* suite You probably wouldn't ever want to actually use the PBKDF
* algorithms like this, the raw PBKDF interface is more convenient
@@ -279,6 +281,8 @@ Filter* lookup_encoder(const std::string& algname)
return 0;
}
+}
+
Filter* lookup(const std::string& algname,
const std::vector<std::string>& params)
{
diff --git a/checks/ec_tests.cpp b/checks/ec_tests.cpp
index bad0d8912..8ed975603 100644
--- a/checks/ec_tests.cpp
+++ b/checks/ec_tests.cpp
@@ -5,12 +5,16 @@
*/
-#include <botan/build.h>
+#include <botan/rng.h>
+
+#if defined(BOTAN_HAS_ECC_GROUP)
+
#include <botan/bigint.h>
#include <botan/numthry.h>
#include <botan/curve_gfp.h>
#include <botan/point_gfp.h>
-#include <botan/ecdsa.h>
+#include <botan/ec_group.h>
+#include <botan/reducer.h>
#include <botan/oids.h>
using namespace Botan;
@@ -22,6 +26,7 @@ using namespace Botan;
#include "validate.h"
#include "common.h"
+
#define CHECK_MESSAGE(expr, print) try { if(!(expr)) std::cout << print << "\n"; } catch(std::exception& e) { std::cout << __FUNCTION__ << ": " << e.what() << "\n"; }
#define CHECK(expr) try { if(!(expr)) std::cout << #expr << "\n"; } catch(std::exception& e) { std::cout << __FUNCTION__ << ": " << e.what() << "\n"; }
@@ -38,7 +43,7 @@ PointGFp create_random_point(RandomNumberGenerator& rng,
{
const BigInt& p = curve.get_p();
- const Modular_Reducer& mod_p = curve.mod_p();
+ Modular_Reducer mod_p(p);
while(true)
{
@@ -813,3 +818,10 @@ void do_ec_tests(RandomNumberGenerator& rng)
std::cout << std::endl;
}
+#else
+
+void do_ec_tests(Botan::RandomNumberGenerator& rng)
+ {
+ }
+
+#endif
diff --git a/checks/ecdsa.cpp b/checks/ecdsa.cpp
index 58f76c9ba..5cf353e58 100644
--- a/checks/ecdsa.cpp
+++ b/checks/ecdsa.cpp
@@ -172,12 +172,12 @@ bool test_ec_sign(RandomNumberGenerator& rng)
PK_Signer signer(priv_key, "EMSA1(SHA-224)");
PK_Verifier verifier(priv_key, "EMSA1(SHA-224)");
- for(u32bit i = 0; i != 256; ++i)
- signer.update((byte)i);
+ for(size_t i = 0; i != 256; ++i)
+ signer.update(static_cast<byte>(i));
SecureVector<byte> sig = signer.signature(rng);
for(u32bit i = 0; i != 256; ++i)
- verifier.update((byte)i);
+ verifier.update(static_cast<byte>(i));
if(!verifier.check_signature(sig))
{
std::cout << "ECDSA self-test failed!";
@@ -186,7 +186,7 @@ bool test_ec_sign(RandomNumberGenerator& rng)
// now check valid signature, different input
for(u32bit i = 1; i != 256; ++i) //starting from 1
- verifier.update((byte)i);
+ verifier.update(static_cast<byte>(i));
if(verifier.check_signature(sig))
{
@@ -198,7 +198,7 @@ bool test_ec_sign(RandomNumberGenerator& rng)
sig[sig.size()/2]++;
for(u32bit i = 0; i != 256; ++i)
- verifier.update((byte)i);
+ verifier.update(static_cast<byte>(i));
if(verifier.check_signature(sig))
{
diff --git a/checks/nist_tests/x509test.cpp b/checks/nist_tests/x509test.cpp
index d89e7c341..66b274c6c 100644
--- a/checks/nist_tests/x509test.cpp
+++ b/checks/nist_tests/x509test.cpp
@@ -1,7 +1,7 @@
/*
- Code to run the X.509v3 processing tests described in "Conformance Testing of
- Relying Party Client Certificate Path Proccessing Logic", which is available
- on NIST's web site.
+ Code to run the X.509v3 processing tests described in "Conformance
+ Testing of Relying Party Client Certificate Path Proccessing Logic",
+ which is available on NIST's web site.
*/
#include <botan/x509path.h>
@@ -18,10 +18,6 @@ using namespace Botan;
#include <dirent.h>
-#define POLICY_TEST1 1000
-#define POLICY_TEST2 2000
-#define POLICY_TEST3 3000
-
std::vector<std::string> dir_listing(const std::string&);
void run_one_test(u32bit, X509_Code,
@@ -263,13 +259,14 @@ void populate_expected_results()
expected_results[33] = VERIFIED;
/*
- Policy tests: a little trickier because there are other inputs which
- affect the result.
+ Policy tests: a little trickier because there are other inputs
+ which affect the result.
- In the case of the tests currently in the suite, the default method (with
- acceptable policy being "any-policy" and with no explict policy required),
- will almost always result in a verified status. This is not particularly
- helpful. So, we do several different tests for each test set:
+ In the case of the tests currently in the suite, the default
+ method (with acceptable policy being "any-policy" and with no
+ explict policy required), will almost always result in a verified
+ status. This is not particularly helpful. So, we should do several
+ different tests for each test set:
1) With the user policy as any-policy and no explicit policy
2) With the user policy as any-policy and an explicit policy required
@@ -281,88 +278,28 @@ void populate_expected_results()
This provides reasonably good coverage of the possible outcomes.
*/
- /*
expected_results[34] = VERIFIED;
- expected_results[34+POLICY_TEST1] = ;
- expected_results[34+POLICY_TEST2] = ;
- expected_results[34+POLICY_TEST3] = ;
expected_results[35] = VERIFIED;
- expected_results[35+POLICY_TEST1] = ;
- expected_results[35+POLICY_TEST2] = ;
- expected_results[35+POLICY_TEST3] = ;
expected_results[36] = VERIFIED;
- expected_results[36+POLICY_TEST1] = ;
- expected_results[36+POLICY_TEST2] = ;
- expected_results[36+POLICY_TEST3] = ;
expected_results[37] = VERIFIED;
- expected_results[37+POLICY_TEST1] = ;
- expected_results[37+POLICY_TEST2] = ;
- expected_results[37+POLICY_TEST3] = ;
expected_results[38] = VERIFIED;
- expected_results[38+POLICY_TEST1] = ;
- expected_results[38+POLICY_TEST2] = ;
- expected_results[38+POLICY_TEST3] = ;
expected_results[39] = VERIFIED;
- expected_results[39+POLICY_TEST1] = ;
- expected_results[39+POLICY_TEST2] = ;
- expected_results[39+POLICY_TEST3] = ;
expected_results[40] = VERIFIED;
- expected_results[40+POLICY_TEST1] = ;
- expected_results[40+POLICY_TEST2] = ;
- expected_results[40+POLICY_TEST3] = ;
expected_results[41] = VERIFIED;
- expected_results[41+POLICY_TEST1] = ;
- expected_results[41+POLICY_TEST2] = ;
- expected_results[41+POLICY_TEST3] = ;
expected_results[42] = VERIFIED;
- expected_results[42+POLICY_TEST1] = ;
- expected_results[42+POLICY_TEST2] = ;
- expected_results[42+POLICY_TEST3] = ;
expected_results[43] = VERIFIED;
- expected_results[43+POLICY_TEST1] = ;
- expected_results[43+POLICY_TEST2] = ;
- expected_results[43+POLICY_TEST3] = ;
expected_results[44] = VERIFIED;
- expected_results[44+POLICY_TEST1] = ;
- expected_results[44+POLICY_TEST2] = ;
- expected_results[44+POLICY_TEST3] = ;
- expected_results[45] = EXPLICT_POLICY_REQUIRED;
- expected_results[45+POLICY_TEST1] = ;
- expected_results[45+POLICY_TEST2] = ;
- expected_results[45+POLICY_TEST3] = ;
- expected_results[46] = ACCEPT;
- expected_results[46+POLICY_TEST1] = ;
- expected_results[46+POLICY_TEST2] = ;
- expected_results[46+POLICY_TEST3] = ;
- expected_results[47] = EXPLICT_POLICY_REQUIRED;
- expected_results[47+POLICY_TEST1] = ;
- expected_results[47+POLICY_TEST2] = ;
- expected_results[47+POLICY_TEST3] = ;
+
+ //expected_results[45] = EXPLICT_POLICY_REQUIRED;
+ //expected_results[46] = ACCEPT;
+ //expected_results[47] = EXPLICT_POLICY_REQUIRED;
+
expected_results[48] = VERIFIED;
- expected_results[48+POLICY_TEST1] = ;
- expected_results[48+POLICY_TEST2] = ;
- expected_results[48+POLICY_TEST3] = ;
expected_results[49] = VERIFIED;
- expected_results[49+POLICY_TEST1] = ;
- expected_results[49+POLICY_TEST2] = ;
- expected_results[49+POLICY_TEST3] = ;
expected_results[50] = VERIFIED;
- expected_results[50+POLICY_TEST1] = ;
- expected_results[50+POLICY_TEST2] = ;
- expected_results[50+POLICY_TEST3] = ;
expected_results[51] = VERIFIED;
- expected_results[51+POLICY_TEST1] = ;
- expected_results[51+POLICY_TEST2] = ;
- expected_results[51+POLICY_TEST3] = ;
expected_results[52] = VERIFIED;
- expected_results[52+POLICY_TEST1] = ;
- expected_results[52+POLICY_TEST2] = ;
- expected_results[52+POLICY_TEST3] = ;
expected_results[53] = VERIFIED;
- expected_results[53+POLICY_TEST1] = ;
- expected_results[53+POLICY_TEST2] = ;
- expected_results[53+POLICY_TEST3] = ;
- */
expected_results[54] = CERT_CHAIN_TOO_LONG;
expected_results[55] = CERT_CHAIN_TOO_LONG;
diff --git a/checks/pk_bench.cpp b/checks/pk_bench.cpp
index b0e689b0c..de8ad0730 100644
--- a/checks/pk_bench.cpp
+++ b/checks/pk_bench.cpp
@@ -65,6 +65,9 @@ using namespace Botan;
#include <memory>
#include <set>
+#define BENCH_FAULT_PROT DISABLE_FAULT_PROTECTION
+//#define BENCH_FAULT_PROT ENABLE_FAULT_PROTECTION
+
namespace {
const char* ec_domains[] = {
@@ -329,7 +332,7 @@ void benchmark_ecdsa(RandomNumberGenerator& rng,
ECDSA_PrivateKey key(rng, params);
keygen_timer.stop();
- PK_Signer sig(key, padding, IEEE_1363, DISABLE_FAULT_PROTECTION);
+ PK_Signer sig(key, padding, IEEE_1363, BENCH_FAULT_PROT);
PK_Verifier ver(key, padding);
benchmark_sig_ver(ver, sig, verify_timer,
@@ -371,7 +374,7 @@ void benchmark_gost_3410(RandomNumberGenerator& rng,
GOST_3410_PrivateKey key(rng, params);
keygen_timer.stop();
- PK_Signer sig(key, padding, IEEE_1363, DISABLE_FAULT_PROTECTION);
+ PK_Signer sig(key, padding, IEEE_1363, BENCH_FAULT_PROT);
PK_Verifier ver(key, padding);
benchmark_sig_ver(ver, sig, verify_timer,
@@ -478,7 +481,7 @@ void benchmark_dsa_nr(RandomNumberGenerator& rng,
algo_name = key.algo_name();
keygen_timer.stop();
- PK_Signer sig(key, padding, IEEE_1363, DISABLE_FAULT_PROTECTION);
+ PK_Signer sig(key, padding, IEEE_1363, BENCH_FAULT_PROT);
PK_Verifier ver(key, padding);
benchmark_sig_ver(ver, sig, verify_timer,
diff --git a/checks/validate.cpp b/checks/validate.cpp
index d79f9783a..65317604e 100644
--- a/checks/validate.cpp
+++ b/checks/validate.cpp
@@ -183,19 +183,23 @@ bool test_bcrypt(RandomNumberGenerator& rng)
#if defined(BOTAN_HAS_BCRYPT)
std::cout << "Testing Bcrypt: " << std::flush;
- const std::string input = "abc";
+ bool ok = true;
// Generated by jBCrypt 0.3
- const std::string fixed_hash =
- "$2a$05$DfPyLs.G6.To9fXEFgUL1O6HpYw3jIXgPcl/L3Qt3jESuWmhxtmpS";
+ if(!check_bcrypt("abc",
+ "$2a$05$DfPyLs.G6.To9fXEFgUL1O6HpYw3jIXgPcl/L3Qt3jESuWmhxtmpS"))
+ {
+ std::cout << "Fixed bcrypt test failed\n";
+ ok = false;
+ }
std::cout << "." << std::flush;
- bool ok = true;
-
- if(!check_bcrypt(input, fixed_hash))
+ // http://www.openwall.com/lists/john-dev/2011/06/19/2
+ if(!check_bcrypt("\xA3",
+ "$2a$05$/OK.fbVrR/bpIqNJ5ianF.Sa7shbm4.OzKpvFnX1pQLmQW96oUlCq"))
{
- std::cout << "Fixed bcrypt test failed\n";
+ std::cout << "Fixed bcrypt test 2 failed\n";
ok = false;
}
@@ -203,7 +207,8 @@ bool test_bcrypt(RandomNumberGenerator& rng)
for(u16bit level = 1; level != 5; ++level)
{
- std::string gen_hash = generate_bcrypt(input, rng, level);
+ const std::string input = "some test passphrase 123";
+ const std::string gen_hash = generate_bcrypt(input, rng, level);
if(!check_bcrypt(input, gen_hash))
{
diff --git a/checks/validate.dat b/checks/validate.dat
index 41e5bf61f..6b9a49e52 100644
--- a/checks/validate.dat
+++ b/checks/validate.dat
@@ -4123,6 +4123,26 @@ F0E1D2C3B4A5968778695A4B3C2D1E0F00112233445566
FEDCBA9876543210:05044B62FA52D080:\
F0E1D2C3B4A5968778695A4B3C2D1E0F0011223344556677
+[Camellia]
+# From RFC 3713
+
+0123456789ABCDEFFEDCBA9876543210:67673138549669730857065648EABE43:\
+0123456789ABCDEFFEDCBA9876543210
+
+0123456789ABCDEFFEDCBA9876543210:B4993401B3E996F84EE5CEE7D79B09B9:\
+0123456789ABCDEFFEDCBA98765432100011223344556677
+
+0123456789ABCDEFFEDCBA9876543210:9ACC237DFF16D76C20EF7C919E3A7509:\
+0123456789ABCDEFFEDCBA987654321000112233445566778899AABBCCDDEEFF
+
+# From NESSIE
+
+00000000000000000000000000000000:6C227F749319A3AA7DA235A9BBA05A2C:\
+80000000000000000000000000000000
+
+FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF:25DD9EB9DD67FBC6E8431F56F4FBE651:\
+FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+
# First one is from RFC 2144. The rest were done with OpenSSL and bits taken
# from /dev/urandom
[CAST-128]
@@ -4406,6 +4426,61 @@ D2FD8867D50D2DFE:0000000000000004:0101010101010101
0000000000000000:E2F5728F0995013C:1002911598100201
0000000000000000:1AEAC39A61F0A464:1002911698100101
+# Tests all sboxes
+01A1D6D039776742:690F5B0D9A26939B:7CA110454A1A6E57
+5CD54CA83DEF57DA:7A389D10354BD271:0131D9619DC1376E
+0248D43806F67172:868EBB51CAB4599A:07A1133E4A0B2686
+51454B582DDF440A:7178876E01F19B2A:3849674C2602319E
+42FD443059577FA2:AF37FB421F8C4095:04B915BA43FEB5B6
+059B5E0851CF143A:86A560F10EC6D85B:0113B970FD34F2CE
+0756D8E0774761D2:0CD3DA020021DC09:0170F175468FB5E6
+762514B829BF486A:EA676B2CB7DB2B7A:43297FAD38E373FE
+3BDD119049372802:DFD64A815CAF1A0F:07A7137045DA2A16
+26955F6835AF609A:5C513C9C4886C088:04689104C2FD3B2F
+164D5E404F275232:0A2AEEAE3FF4AB77:37D06BB516CB7546
+6B056E18759F5CCA:EF1BF03E5DFA575A:1F08260D1AC2465E
+004BD6EF09176062:88BF0DB6D70DEE56:584023641ABA6176
+480D39006EE762F2:A1F9915541020B56:025816164629B007
+437540C8698F3CFA:6FBF1CAFCFFD0556:49793EBC79B3258F
+072D43A077075292:2F22E49BAB7CA1AC:4FB05E1515AB73A7
+02FE55778117F12A:5A6B612CC26CCE4A:49E95D6D4CA229BF
+1D9D5C5018F728C2:5F4C038ED12B2E41:018310DC409B26D6
+305532286D6F295A:63FAC0D034D9F793:1C587F1C13924FEF
+
+# Tests the permutation
+0000000000000000:88D55E54F54C97B4:1046913489980131
+0000000000000000:0C0CC00C83EA48FD:1007103489988020
+0000000000000000:83BC8EF3A6570183:10071034C8980120
+0000000000000000:DF725DCAD94EA2E9:1046103489988020
+0000000000000000:E652B53B550BE8B0:1086911519190101
+0000000000000000:AF527120C485CBB0:1086911519580101
+0000000000000000:0F04CE393DB926D5:5107B01519580101
+0000000000000000:C9F00FFC74079067:1007B01519190101
+0000000000000000:7CFD82A593252B4E:3107915498080101
+0000000000000000:CB49A2F9E91363E3:3107919498080101
+0000000000000000:00B588BE70D23F56:10079115B9080140
+0000000000000000:406A9A6AB43399AE:3107911598080140
+0000000000000000:6CB773611DCA9ADA:1007D01589980101
+0000000000000000:67FD21C17DBB5D70:9107911589980101
+0000000000000000:9592CB4110430787:9107D01589190101
+0000000000000000:A6B7FF68A318DDD3:1007D01598980120
+0000000000000000:4D102196C914CA16:1007940498190101
+0000000000000000:2DFA9F4573594965:0107910491190401
+0000000000000000:B46604816C0E0774:0107910491190101
+0000000000000000:6E7E6221A4F34E87:0107940491190401
+0000000000000000:AA85E74643233199:19079210981A0101
+0000000000000000:2E5A19DB4D1962D6:1007911998190801
+0000000000000000:23A866A809D30894:10079119981A0801
+0000000000000000:D812D961F017D320:1007921098190101
+0000000000000000:055605816E58608F:100791159819010B
+0000000000000000:ABD88E8B1B7716F1:1004801598190101
+0000000000000000:537AC95BE69DA1E1:1004801598190102
+0000000000000000:AED0F6AE3C25CDD8:1004801598190108
+0000000000000000:B3E35A5EE53E7B8D:1002911598100104
+0000000000000000:61C79C71921A2EF8:1002911598190104
+0000000000000000:E2F5728F0995013C:1002911598100201
+0000000000000000:1AEAC39A61F0A464:1002911698100101
+
# Vectors randomly generated using OpenSSL
0CEB1136A85AD37A:9CE3A1058A483F55:309A4B21A2067196
@@ -4693,6 +4768,8 @@ D6A025B07C037A6E1E0653E828FB9E3A3587CDDA5325D4DAA743D113D995D6AF
E07306086FA442A42B107F7F355359DD972BF070C0C71FF5C37FA7C259C7E039
[IDEA]
+7409000000000000:E18315C171B83765:ED1BCC9E9267925F3132BA3A8CF9B764
+
D53FABBF94FF8B5F:1D0CB2AF1654820A:729A27ED8F5C3E8BAF16560D14C90B43
848F836780938169:D7E0468226D0FC56:729A27ED8F5C3E8BAF16560D14C90B43
819440CA2065D112:264A8BBA66959075:729A27ED8F5C3E8BAF16560D14C90B43
@@ -4720,6 +4797,86 @@ FAE6D2BEAA96826E0A141E28323C4650050A0F14191E2328050A0F14191E2328:\
85DF52005608193D2F7DE750212FB7347B7314925DE59C097B7314925DE59C09:\
00010002000300040005000600070008
+C309000000000000A02A000000000000B03D000000000000C942000000000000\
+2B4C000000000000A04E0000000000009857000000000000C860000000000000\
+0063000000000000F2660000000000008698000000000000729D000000000000\
+34A000000000000023A500000000000010AE00000000000025AE000000000000\
+30D600000000000064DB000000000000BCE1000000000000F6E7000000000000\
+4AEC00000000000080F9000000000000E0FE00000000000061FF000000000000:\
+9C3C4F44BB50DF7367DAD70E6FED04E0AEB0344116C6E41F66A1A304E822132D\
+8AFCC1727259D93DD6E742EAEF2FD8C03EAD7890DC4EFACBB8776F3439A3DB1B\
+55D47DC6BC4A43349BA9E85FE178CD1ADBDD4E9D19CA1E7659341251586E1386\
+4A8C4E93A2616A0C18890A622452AD9FD09CB1A9CDC83ABF2FCFA325FA011731\
+9C924852D426132D05DA82EEBC3C261A6036C6477FBE3F65C40B8B02C2F9D8C8\
+B3084034AB3873CF22F20759C145ECCE92CE6B557D6DB959DA0B8AD4E0DFBCEA:\
+F2022315280960F16FD09741D13F693A
+
+7CC254F81BE8E78D765A2E63339FC99A66320DB73158A35A255D051758E95ED4\
+ABB2CDC69BB454110E827441213DDC8770E93EA141E1FC673E017E97EADC6B96\
+8F385C2AECB03BFB32AF3C54EC18DB5C021AFE43FBFAAA3AFB29D1E6053C7C94\
+75D8BE6189F95CBBA8990F95B1EBF1B305EFF700E9A13AE5CA0BCBD0484764BD\
+1F231EA81C7B64C514735AC55E4B79633B706424119E09DCAAD4ACF21B10AF3B\
+33CDE3504847155CBB6F2219BA9B7DF50BE11A1C7F23F829F8A41B13B5CA4EE8\
+983238E0794D3D34BC5F4E77FACB6C05AC86212BAA1A55A2BE70B5733B045CD3\
+3694B3AFE2F0E49E4F321549FD824EA90870D4B28A2954489A0ABCD50E18A844\
+AC5BF38E4CD72D9B0942E506C433AFCDA3847F2DADD47647DE321CEC4AC430F6\
+2023856CFBB20704F4EC0BB920BA86C33E05F1ECD96733B79950A3E314D3D934\
+F75EA0F210A8F6059401BEB4BC4478FA4969E623D01ADA696A7E4C7E5125B348\
+84533A94FB319990325744EE9BBCE9E525CF08F5E9E25E5360AAD2B2D085FA54\
+D835E8D466826498D9A8877565705A8A3F62802944DE7CA5894E5759D351ADAC\
+869580EC17E485F18C0C66F17CC07CBB22FCE466DA610B63AF62BC83B4692F3A\
+FFAF271693AC071FB86D11342D8DEF4F89D4B66335C1C7E4248367D8ED9612EC\
+453902D8E50AF89D7709D1A596C1F41F95AA82CA6C49AE90CD1668BAAC7AA6F2\
+B4A8CA99B2C2372ACB08CF61C9C3805E6E0328DA4CD76A19EDD2D3994C798B00\
+22569AD418D1FEE4D9CD45A391C601FFC92AD91501432FEE150287617C13629E\
+69FC7281CD7165A63EAB49CF714BCE3A75A74F76EA7E64FF81EB61FDFEC39B67\
+BF0DE98C7E4E32BDF97C8C6AC75BA43C02F4B2ED7216ECF3014DF000108B67CF\
+99505B179F8ED4980A6103D1BCA70DBE9BBFAB0ED59801D6E5F2D6F67D3EC516\
+8E212E2DAF02C6B963C98A1F7097DE0C56891A2B211B01070DD8FD8B16C2A1A4\
+E3CFD292D2984B3561D555D16C33DDC2BCF7EDDE13EFE520C7E2ABDDA44D8188\
+1C531AEEEB66244C3B791EA8ACFB6A68F3584606472B260E0DD2EBB21F6C3A3B\
+C0542AABBA4EF8F6C7169E731108DB0460220AA74D31B55B03A00D220D475DCD\
+9B877856D5704C9C86EA0F98F2EB9C530DA7FA5AD8B0B5DB50C2FD5D095A2AA5\
+E2A3FBB71347549A316332234ECE765B7571B64D216B28712E25CF3780F9DC62\
+9CD719B01E6D4A4FD17C731F4AE97BC05A310D7B9C36EDCA5BBC02DBB5DE3D52\
+B65702D4C44C2495C897B5128030D2DB61E056FD1643C871FFCA4DB5A88A075E\
+E10933A655573B1DEEF02F6E20024981E2A07FF8E34769E311B698B9419F1822\
+A84BC8FDA2041A90F449FE154B48962DE81525CB5C8FAE6D45462786E53FA98D\
+8A718A2C75A4BC6AEEBA7F39021567EA2B8CB6871B64F561AB1CE7905B901EE5:\
+9C142A22EDF81444F47272B80A037C169E304393537CECE8003BD80F7B054406\
+3B4A141F9A99D3C6820BAD98BECD914804F389EB2A50E1E2CF22161FC78B9366\
+0E07E2686E70AC0715299C4796F3559FDA802E61CB4ABBF42BAE516BD09FA410\
+085A0A92C6F32A3797D19808D3B3D049B605852E970E5A1B8031D3DC34B5A273\
+F54ED35E21D780204F4B3C512596237153BE9FAF74A44E9A9DCBE96D628AA58B\
+1E3363A94DF540230B38A1ACA440432640E5387D92F1CC1A16F8628A4CB6229F\
+513AB926300668CF97B27643C9C9D0C3030D0CDFBBCB69C3DB199E5D392A97A5\
+1DE6C9881AE5612A69FA0EA026F2F254B929201AFB3AFC8D977C3ED6E12F0118\
+92037D0F49B0144E07A0F0556F0BAC9B3F829C233265439AF711E0B5DD6EC813\
+FD51281E8AA6F031B096C64EE8F03E041FE4DC6B5441141F2D4A308CE8EA77C6\
+483E3CF565EC49CF27A0B13F28D3C63AD7FB6B3A96579D30C9D65F7BA86E56DA\
+6D14AF3C7D170CB5BF5F21C70C1771354DA2850CFF8D9250273828C1FE60C4AC\
+086049404E3D63E04935F03B057B4783B13CF49757A8B5ABB3D2E37E54B881D2\
+36F7DF7FE80E4AE33E9125F54AA96D96BFB15607F0800B215CBF9BB0F7E29080\
+D8504E9BC1F78256593B9565E5AA5FA22032A47041B453D1B154A8D24CD59CF9\
+AA6A8E55363F3DF2B6307ABA5134D67B0DF0AE4FE77F23BF7DF8504FE9DC7F32\
+A8562E2DF585E639847DD624E55B0D0DCCDA72D0F1E072D82D4BC135DC5F7F91\
+30956D401FAB1456527FE087A436C1511CDFEA58202D200E1817E360E8400AAE\
+83B073A63596B033D7E83C6CAB7FDD7069C3B1718EAF60B937CD2458255E68FC\
+D9514FD14AA6E27EC76E75F95F0A678A0F64D49C1B9B8F8DA56DDB8CE640FF6E\
+7195F4A679165F9996F3DDF992E3CB4ED9E9084AFC0038E4BEFB467CC8170AF8\
+F004082BBCB137BBD45C124BE8CEDC89DD565A24830889CE4B9781FC18803BDA\
+1A0A4EB70DA35887B02F18CFF9329E2B7C31B0F5F0648E0508379B52C8FF91CE\
+F939A040A8C20F2F27ED65553680729A2181B3B3C4AA02BFF8DF0A9228A87BBF\
+52B48F473D0F9070C76E4DB6F09FFDFEB629BD0E1944B7016AF34187E2985AEA\
+E30D6480A58F649A0C858E1F1458388A9E822A306AC1AA7465882DE78F242EF7\
+B0CB45D68A057F00D8609587922C8FAD6F1A7FFA34BF2175FC516730A61CF82C\
+6F866C978CC292BCC1F91E6AF1785FCDAA9A43A01E6AEE91E222F8AF8C989F2A\
+4C50B7A1D45BC15E11E5E6E6EF720506B8DF564648BEBFE272C0A77D41295865\
+108150CDB3620970A37DB94F1CC35E434DC33434D99871F6141EB57C9E648AD1\
+BF70E2B7FCEB81EA871DD92F19C366EA532CA4A7BEF9242128B7ADDD308B58FF\
+F5594CB4156A03C6A6ED3F27E8DB20FB2F4208422B7E9E0A4E63A0122560CFBC:\
+67C6697351FF4AEC29CDBAABF2FBE346
+
# Randomly generated by OpenSSL
A1F4C5FC0AF894FB:1F88AD254A1653CB:69E2F555209FCA21ED36E0243F043537
55E31A38B2C91116:8D57CB7AFB401E55:BC0ED7C4A90FE4760B3D971F0F2589F6
diff --git a/configure.py b/configure.py
index f5cd34336..123c91259 100755
--- a/configure.py
+++ b/configure.py
@@ -5,15 +5,16 @@ Configuration program for botan (http://botan.randombit.net/)
(C) 2009-2011 Jack Lloyd
Distributed under the terms of the Botan license
-Tested with
- CPython 2.5, 2.6, 2.7 - OK
- Jython 2.5 - Target detection does not work (use --os and --cpu)
+Tested with CPython 2.6, 2.7, 3.1 and PyPy 1.5
- CPython 2.4 and earlier are not supported
+Python 2.5 works if you change the exception catching syntax:
+ perl -pi -e 's/except (.*) as (.*):/except $1, $2:/g' configure.py
- Use the 2to3 script to use with Python 3
+Jython - Target detection does not work (use --os and --cpu)
- Has not been tested with IronPython or PyPy
+CPython 2.4 and earlier are not supported
+
+Has not been tested with IronPython
"""
import sys
@@ -40,6 +41,25 @@ import botan_version
def flatten(l):
return sum(l, [])
+def get_vc_revision():
+ try:
+ mtn = subprocess.Popen(['mtn', 'automate', 'heads'],
+ stdout=subprocess.PIPE,
+ stderr=subprocess.PIPE)
+
+ (stdout, stderr) = mtn.communicate()
+
+ if(stderr != ''):
+ logging.debug('Error getting rev from monotone - %s' % (stderr))
+ return 'unknown'
+
+ logging.debug('Monotone reported revision ' + stdout.strip())
+
+ return 'mtn:' + stdout.strip()
+ except OSError as e:
+ logging.debug('Error getting rev from monotone - %s' % (e[1]))
+ return 'unknown'
+
class BuildConfigurationInformation(object):
"""
@@ -48,9 +68,11 @@ class BuildConfigurationInformation(object):
version_major = botan_version.release_major
version_minor = botan_version.release_minor
version_patch = botan_version.release_patch
+ version_so_rev = botan_version.release_so_abi_rev
version_datestamp = botan_version.release_datestamp
+ version_vc_rev = botan_version.release_vc_rev
version_string = '%d.%d.%d' % (version_major, version_minor, version_patch)
"""
@@ -58,6 +80,9 @@ class BuildConfigurationInformation(object):
"""
def __init__(self, options, modules):
+ if self.version_vc_rev is None:
+ self.version_vc_rev = get_vc_revision()
+
self.build_dir = os.path.join(options.with_build_dir, 'build')
self.checkobj_dir = os.path.join(self.build_dir, 'checks')
@@ -76,9 +101,17 @@ class BuildConfigurationInformation(object):
self.internal_include_dir = os.path.join(self.botan_include_dir, 'internal')
self.sources = sorted(flatten([mod.sources() for mod in modules]))
- self.public_headers = sorted(flatten([m.public_headers() for m in modules]))
self.internal_headers = sorted(flatten([m.internal_headers() for m in modules]))
+ if options.via_amalgamation:
+ self.build_sources = ['botan_all.cpp']
+ self.build_internal_headers = []
+ else:
+ self.build_sources = self.sources
+ self.build_internal_headers = self.internal_headers
+
+ self.public_headers = sorted(flatten([m.public_headers() for m in modules]))
+
checks_dir = os.path.join(options.base_dir, 'checks')
self.check_sources = sorted(
@@ -124,6 +157,10 @@ class BuildConfigurationInformation(object):
return 'botan-%d.%d.pc' % (self.version_major,
self.version_minor)
+ def config_shell_script(self):
+ return 'botan-config-%d.%d' % (self.version_major,
+ self.version_minor)
+
def username(self):
return getpass.getuser()
@@ -149,12 +186,19 @@ def process_command_line(args):
target_group = optparse.OptionGroup(parser, 'Target options')
- target_group.add_option('--cc', dest='compiler',
- help='set the desired build compiler')
- target_group.add_option('--os',
- help='set the target operating system')
target_group.add_option('--cpu',
help='set the target processor type/model')
+
+ target_group.add_option('--os',
+ help='set the target operating system')
+
+ target_group.add_option('--cc', dest='compiler',
+ help='set the desired build compiler')
+
+ target_group.add_option('--cc-bin', dest='compiler_binary',
+ metavar='BINARY',
+ help='set the name of the compiler binary')
+
target_group.add_option('--with-endian', metavar='ORDER', default=None,
help='override guess of CPU byte order')
@@ -204,10 +248,18 @@ def process_command_line(args):
build_group.add_option('--disable-debug', dest='debug_build',
action='store_false', help=optparse.SUPPRESS_HELP)
+ build_group.add_option('--no-optimizations', dest='no_optimizations',
+ action='store_true', default=False,
+ help=optparse.SUPPRESS_HELP)
+
build_group.add_option('--gen-amalgamation', dest='gen_amalgamation',
default=False, action='store_true',
help='generate amalgamation files')
+ build_group.add_option('--via-amalgamation', dest='via_amalgamation',
+ default=False, action='store_true',
+ help='build via amalgamation')
+
build_group.add_option('--with-tr1-implementation', metavar='WHICH',
dest='with_tr1', default=None,
help='enable TR1 (choices: none, system, boost)')
@@ -234,6 +286,12 @@ def process_command_line(args):
build_group.add_option('--without-sphinx', action='store_false',
dest='with_sphinx', help=optparse.SUPPRESS_HELP)
+ build_group.add_option('--with-visibility', action='store_true',
+ default=None, help=optparse.SUPPRESS_HELP)
+
+ build_group.add_option('--without-visibility', action='store_false',
+ dest='with_visibility', help=optparse.SUPPRESS_HELP)
+
build_group.add_option('--with-doxygen', action='store_true',
default=False,
help='Use Doxygen to generate HTML API docs')
@@ -453,7 +511,13 @@ def lex_me_harder(infofile, to_obj, allowed_groups, name_val_pairs):
lexer.lineno)
elif token in name_val_pairs.keys():
- to_obj.__dict__[token] = lexer.get_token()
+ next_val = lexer.get_token()
+
+ if type(to_obj.__dict__[token]) is list:
+ to_obj.__dict__[token].append(next_val)
+ else:
+ to_obj.__dict__[token] = next_val
+
else: # No match -> error
raise LexerError('Bad token "%s"' % (token), lexer.lineno)
@@ -475,7 +539,7 @@ class ModuleInfo(object):
'comment'],
{
'load_on': 'auto',
- 'define': None,
+ 'define': [],
'uses_tr1': 'false',
'need_isa': None,
'mp_bits': 0 })
@@ -527,8 +591,9 @@ class ModuleInfo(object):
self.uses_tr1 = (True if self.uses_tr1 == 'yes' else False)
if self.comment != []:
- logging.info('Module comment for ' + self.basename + ' - ' +
- ' '.join(self.comment))
+ self.comment = ' '.join(self.comment)
+ else:
+ self.comment = None
def sources(self):
return self.source
@@ -539,6 +604,9 @@ class ModuleInfo(object):
def internal_headers(self):
return self.header_internal
+ def defines(self):
+ return ['HAS_' + d for d in self.define]
+
def compatible_cpu(self, archinfo, options):
arch_name = archinfo.basename
@@ -696,7 +764,8 @@ class CompilerInfo(object):
'lang_flags': '',
'warning_flags': '',
'maintainer_warning_flags': '',
- 'dll_import_flags': '',
+ 'visibility_build_flags': '',
+ 'visibility_attribute': '',
'ar_command': None,
'makefile_style': '',
'has_tr1': False,
@@ -724,6 +793,23 @@ class CompilerInfo(object):
del self.mach_opt
"""
+ Return the shared library build flags, if any
+ """
+ def gen_shared_flags(self, options):
+ def flag_builder():
+ if options.build_shared_lib:
+ yield self.shared_flags
+ if options.with_visibility:
+ yield self.visibility_build_flags
+
+ return ' '.join(list(flag_builder()))
+
+ def gen_visibility_attribute(self, options):
+ if options.build_shared_lib and options.with_visibility:
+ return self.visibility_attribute
+ return ''
+
+ """
Return the machine specific ABI flags
"""
def mach_abi_link_flags(self, osname, arch, submodel, debug_p):
@@ -763,13 +849,18 @@ class CompilerInfo(object):
"""
Return the flags for LIB_OPT
"""
- def library_opt_flags(self, debug_build):
- flags = self.lib_opt_flags
- if debug_build and self.debug_flags != '':
- flags += ' ' + self.debug_flags
- if not debug_build and self.no_debug_flags != '':
- flags += ' ' + self.no_debug_flags
- return flags
+ def library_opt_flags(self, options):
+ def gen_flags():
+ if options.debug_build:
+ yield self.debug_flags
+
+ if not options.no_optimizations:
+ yield self.lib_opt_flags
+
+ if not options.debug_build:
+ yield self.no_debug_flags
+
+ return (' '.join(gen_flags())).strip()
"""
Return the command needed to link a shared object
@@ -838,19 +929,30 @@ def fixup_proc_name(proc):
def canon_processor(archinfo, proc):
proc = fixup_proc_name(proc)
+ # First, try to search for an exact match
for ainfo in archinfo.values():
if ainfo.basename == proc or proc in ainfo.aliases:
return (ainfo.basename, ainfo.basename)
- else:
- for (match,submodel) in ainfo.all_submodels():
- if re.search(match, proc) != None:
- return (ainfo.basename, submodel)
+
+ for (match,submodel) in ainfo.all_submodels():
+ if proc == submodel or proc == match:
+ return (ainfo.basename, submodel)
+
+ logging.debug('Could not find an exact match for CPU "%s"' % (proc))
+
+ # Now, try searching via regex match
+ for ainfo in archinfo.values():
+ for (match,submodel) in ainfo.all_submodels():
+ if re.search(match, proc) != None:
+ logging.debug('Possible match "%s" with "%s" (%s)' % (
+ proc, match, submodel))
+ return (ainfo.basename, submodel)
logging.debug('Known CPU names: ' + ' '.join(
- sorted(sum([[ainfo.basename] + \
- ainfo.aliases + \
- [x for (x,_) in ainfo.all_submodels()]
- for ainfo in archinfo.values()], []))))
+ sorted(flatten([[ainfo.basename] + \
+ ainfo.aliases + \
+ [x for (x,_) in ainfo.all_submodels()]
+ for ainfo in archinfo.values()]))))
raise Exception('Unknown or unidentifiable processor "%s"' % (proc))
@@ -891,7 +993,7 @@ def process_template(template_file, variables):
try:
template = PercentSignTemplate(slurp_file(template_file))
return template.substitute(variables)
- except KeyError, e:
+ except KeyError as e:
raise Exception('Unbound var %s in template %s' % (e, template_file))
"""
@@ -920,13 +1022,21 @@ def create_template_vars(build_config, options, modules, cc, arch, osinfo):
def objectfile_list(sources, obj_dir):
for src in sources:
- basename = os.path.basename(src)
+ (dir,file) = os.path.split(os.path.normpath(src))
+
+ if dir.startswith('src'):
+ parts = dir.split(os.sep)[1:]
+ if file == parts[-1] + '.cpp':
+ name = '_'.join(dir.split(os.sep)[1:]) + '.cpp'
+ else:
+ name = '_'.join(dir.split(os.sep)[1:]) + '_' + file
+ else:
+ name = file
for src_suffix in ['.cpp', '.S']:
- basename = basename.replace(src_suffix,
- '.' + osinfo.obj_suffix)
+ name = name.replace(src_suffix, '.' + osinfo.obj_suffix)
- yield os.path.join(obj_dir, basename)
+ yield os.path.join(obj_dir, name)
def choose_mp_bits():
@@ -965,11 +1075,6 @@ def create_template_vars(build_config, options, modules, cc, arch, osinfo):
return os.path.join(options.with_build_dir, path)
return path
- def only_if_shared(option):
- if options.build_shared_lib:
- return option
- return ''
-
def warning_flags(normal_flags,
maintainer_flags,
maintainer_mode):
@@ -978,10 +1083,12 @@ def create_template_vars(build_config, options, modules, cc, arch, osinfo):
return normal_flags
return {
- 'version_major': build_config.version_major,
- 'version_minor': build_config.version_minor,
- 'version_patch': build_config.version_patch,
- 'version': build_config.version_string,
+ 'version_major': build_config.version_major,
+ 'version_minor': build_config.version_minor,
+ 'version_patch': build_config.version_patch,
+ 'version_vc_rev': build_config.version_vc_rev,
+ 'so_abi_rev': build_config.version_so_rev,
+ 'version': build_config.version_string,
'distribution_info': options.distribution_info,
@@ -1014,26 +1121,26 @@ def create_template_vars(build_config, options, modules, cc, arch, osinfo):
'mp_bits': choose_mp_bits(),
- 'cc': cc.binary_name + cc.mach_abi_link_flags(
- options.os, options.arch, options.cpu, options.debug_build),
+ 'cc': (options.compiler_binary or cc.binary_name) +
+ cc.mach_abi_link_flags(options.os, options.arch,
+ options.cpu, options.debug_build),
- 'lib_opt': cc.library_opt_flags(options.debug_build),
+ 'lib_opt': cc.library_opt_flags(options),
'mach_opt': cc.mach_opts(options.arch, options.cpu),
- 'check_opt': cc.check_opt_flags,
+ 'check_opt': '' if options.no_optimizations else cc.check_opt_flags,
'lang_flags': cc.lang_flags + options.extra_flags,
'warn_flags': warning_flags(cc.warning_flags,
cc.maintainer_warning_flags,
options.maintainer_mode),
- 'shared_flags': only_if_shared(cc.shared_flags),
- 'dll_import_flags': only_if_shared(cc.dll_import_flags),
+ 'shared_flags': cc.gen_shared_flags(options),
+ 'visibility_attribute': cc.gen_visibility_attribute(options),
'so_link': cc.so_link_command_for(osinfo.basename),
'link_to': ' '.join([cc.add_lib_option + lib for lib in link_to()]),
- 'module_defines': make_cpp_macros(
- sorted(['HAS_' + m.define for m in modules if m.define])),
+ 'module_defines': make_cpp_macros(sorted(flatten([m.defines() for m in modules]))),
'target_os_defines': make_cpp_macros(osinfo.defines()),
@@ -1045,7 +1152,7 @@ def create_template_vars(build_config, options, modules, cc, arch, osinfo):
'include_files': makefile_list(build_config.public_headers),
'lib_objs': makefile_list(
- objectfile_list(build_config.sources,
+ objectfile_list(build_config.build_sources,
build_config.libobj_dir)),
'check_objs': makefile_list(
@@ -1053,7 +1160,7 @@ def create_template_vars(build_config, options, modules, cc, arch, osinfo):
build_config.checkobj_dir)),
'lib_build_cmds': '\n'.join(
- build_commands(build_config.sources,
+ build_commands(build_config.build_sources,
build_config.libobj_dir, 'LIB')),
'check_build_cmds': '\n'.join(
@@ -1082,7 +1189,9 @@ def create_template_vars(build_config, options, modules, cc, arch, osinfo):
'so_suffix': osinfo.so_suffix,
'botan_config': prefix_with_build_dir(
- os.path.join(build_config.build_dir, 'botan-config')),
+ os.path.join(build_config.build_dir,
+ build_config.config_shell_script())),
+
'botan_pkgconfig': prefix_with_build_dir(
os.path.join(build_config.build_dir,
build_config.pkg_config_file())),
@@ -1196,6 +1305,14 @@ def choose_modules_to_use(modules, archinfo, options):
logging.info('Skipping, %s - %s' % (
reason, ' '.join(disabled_mods)))
+ for mod in sorted(to_load):
+ if mod.startswith('mp_'):
+ logging.info('Using MP module ' + mod)
+ if mod.startswith('simd_') and mod != 'simd_engine':
+ logging.info('Using SIMD module ' + mod)
+ if modules[mod].comment:
+ logging.info('%s: %s' % (mod, modules[mod].comment))
+
logging.debug('Loading modules %s', ' '.join(sorted(to_load)))
return [modules[mod] for mod in to_load]
@@ -1316,14 +1433,14 @@ def setup_build(build_config, options, template_vars):
try:
if options.clean_build_tree:
shutil.rmtree(build_config.build_dir)
- except OSError, e:
+ except OSError as e:
if e.errno != errno.ENOENT:
logging.error('Problem while removing build dir: %s' % (e))
for dir in build_config.build_dirs:
try:
os.makedirs(dir)
- except OSError, e:
+ except OSError as e:
if e.errno != errno.EEXIST:
logging.error('Error while creating "%s": %s' % (dir, e))
@@ -1343,7 +1460,7 @@ def setup_build(build_config, options, template_vars):
if options.os != 'windows':
yield (options.build_data, 'botan.pc.in', build_config.pkg_config_file())
- yield (options.build_data, 'botan-config.in', 'botan-config')
+ yield (options.build_data, 'botan-config.in', build_config.config_shell_script())
if options.os == 'windows':
yield (options.build_data, 'innosetup.in', 'botan.iss')
@@ -1374,7 +1491,7 @@ def setup_build(build_config, options, template_vars):
for header_file in header_list:
try:
portable_symlink(header_file, dir, link_method)
- except OSError, e:
+ except OSError as e:
if e.errno != errno.EEXIST:
logging.error('Error linking %s into %s: %s' % (
header_file, dir, e))
@@ -1382,7 +1499,7 @@ def setup_build(build_config, options, template_vars):
link_headers(build_config.public_headers, 'public',
build_config.botan_include_dir)
- link_headers(build_config.internal_headers, 'internal',
+ link_headers(build_config.build_internal_headers, 'internal',
build_config.internal_include_dir)
"""
@@ -1459,12 +1576,16 @@ def generate_amalgamation(build_config):
else:
match = std_include.search(line)
- if match:
+ if match and match.group(1) != 'functional':
self.all_std_includes.add(match.group(1))
else:
yield line
- botan_all_h = open('botan_all.h', 'w')
+ amalg_basename = 'botan_all'
+
+ header_name = '%s.h' % (amalg_basename)
+
+ botan_h = open(header_name, 'w')
pub_header_amalag = Amalgamation_Generator(build_config.public_headers)
@@ -1476,31 +1597,30 @@ def generate_amalgamation(build_config):
*/
""" % (build_config.version_string)
- botan_all_h.write(amalg_header)
+ botan_h.write(amalg_header)
- botan_all_h.write("""
+ botan_h.write("""
#ifndef BOTAN_AMALGAMATION_H__
#define BOTAN_AMALGAMATION_H__
""")
- botan_all_h.write(pub_header_amalag.header_includes)
- botan_all_h.write(pub_header_amalag.contents)
- botan_all_h.write("\n#endif\n")
+ botan_h.write(pub_header_amalag.header_includes)
+ botan_h.write(pub_header_amalag.contents)
+ botan_h.write("\n#endif\n")
internal_header_amalag = Amalgamation_Generator(
[s for s in build_config.internal_headers
if s.find('asm_macr_') == -1])
- botan_all_cpp = open('botan_all.cpp', 'w')
-
- botan_all_cpp.write(amalg_header)
+ botan_cpp = open('%s.cpp' % (amalg_basename), 'w')
- botan_all_cpp.write('#include "botan_all.h"\n')
+ botan_cpp.write(amalg_header)
- botan_all_cpp.write(internal_header_amalag.header_includes)
- botan_all_cpp.write(internal_header_amalag.contents)
+ botan_cpp.write('\n#include "%s"\n' % (header_name))
+ botan_cpp.write(internal_header_amalag.header_includes)
+ botan_cpp.write(internal_header_amalag.contents)
for src in build_config.sources:
if src.endswith('.S'):
@@ -1511,7 +1631,7 @@ def generate_amalgamation(build_config):
if botan_include.search(line):
continue
else:
- botan_all_cpp.write(line)
+ botan_cpp.write(line)
"""
Test for the existence of a program
@@ -1543,6 +1663,9 @@ def main(argv = None):
if argv is None:
argv = sys.argv
+ logging.basicConfig(stream = sys.stdout,
+ format = '%(levelname) 7s: %(message)s')
+
options = process_command_line(argv[1:])
def log_level():
@@ -1552,9 +1675,7 @@ def main(argv = None):
return logging.WARNING
return logging.INFO
- logging.basicConfig(stream = sys.stdout,
- format = '%(levelname) 7s: %(message)s',
- level = log_level())
+ logging.getLogger().setLevel(log_level())
logging.debug('%s invoked with options "%s"' % (
argv[0], ' '.join(argv[1:])))
@@ -1573,28 +1694,29 @@ def main(argv = None):
(modules, archinfo, ccinfo, osinfo) = load_info_files(options)
- if options.os is None:
- options.os = platform.system().lower()
-
- if re.match('^cygwin_.*', options.os):
- logging.debug("Converting '%s' to 'cygwin'", options.os)
- options.os = 'cygwin'
-
- logging.info('Guessing target OS is %s (--os to set)' % (options.os))
-
if options.compiler is None:
if options.os == 'windows':
- if have_program('cl'):
- options.compiler = 'msvc'
- elif have_program('g++'):
+ if have_program('g++') and not have_program('cl'):
options.compiler = 'gcc'
else:
options.compiler = 'msvc'
else:
options.compiler = 'gcc'
- logging.info('Guessing to use compiler %s (--cc to set)' % (
+ logging.info('Guessing to use compiler %s (use --cc to set)' % (
options.compiler))
+ if options.os is None:
+ options.os = platform.system().lower()
+
+ if re.match('^cygwin_.*', options.os):
+ logging.debug("Converting '%s' to 'cygwin'", options.os)
+ options.os = 'cygwin'
+
+ if options.os == 'windows' and options.compiler == 'gcc':
+ logging.warning('Detected GCC on Windows; use --os=cygwin or --os=mingw?')
+
+ logging.info('Guessing target OS is %s (use --os to set)' % (options.os))
+
if options.compiler not in ccinfo:
raise Exception('Unknown compiler "%s"; available options: %s' % (
options.compiler, ' '.join(sorted(ccinfo.keys()))))
@@ -1615,7 +1737,7 @@ def main(argv = None):
if options.cpu is None:
(options.arch, options.cpu) = guess_processor(archinfo)
- logging.info('Guessing target processor is a %s/%s (--cpu to set)' % (
+ logging.info('Guessing target processor is a %s/%s (use --cpu to set)' % (
options.arch, options.cpu))
else:
cpu_from_user = options.cpu
@@ -1626,54 +1748,84 @@ def main(argv = None):
logging.info('Target is %s-%s-%s-%s' % (
options.compiler, options.os, options.arch, options.cpu))
+ cc = ccinfo[options.compiler]
+
# Kind of a hack...
options.extra_flags = ''
if options.compiler == 'gcc':
+ def get_gcc_version(gcc_bin):
+ try:
+ subproc_result = subprocess.Popen(
+ gcc_bin.split(' ') + ['-dumpversion'],
+ stdout=subprocess.PIPE,
+ stderr=subprocess.PIPE).communicate()
+
+ gcc_version = ''.join(map(str, subproc_result)).strip()
+
+ logging.info('Detected gcc version %s' % (gcc_version))
+ return gcc_version
+ except OSError:
+ logging.warning('Could not execute %s for version check' % (gcc_bin))
+ return None
+
def is_64bit_arch(arch):
if arch.endswith('64') or arch in ['alpha', 's390x']:
return True
return False
- if not is_64bit_arch(options.arch) and not options.dumb_gcc:
- try:
- matching_version = '(4\.[01234]\.)|(3\.[34]\.)|(2\.95\.[0-4])'
+ gcc_version = get_gcc_version(options.compiler_binary or cc.binary_name)
- gcc_version = ''.join(subprocess.Popen(
- ['g++', '-dumpversion'],
- stdout=subprocess.PIPE,
- stderr=subprocess.PIPE).communicate()).strip()
+ if gcc_version:
- logging.info('Detected GCC version %s' % (gcc_version))
+ if not is_64bit_arch(options.arch) and not options.dumb_gcc:
+ matching_version = '(4\.[01234]\.)|(3\.[34]\.)|(2\.95\.[0-4])'
if re.search(matching_version, gcc_version):
options.dumb_gcc = True
- except OSError:
- logging.warning('Could not execute GCC for version check')
+
+ versions_without_tr1 = '(4\.0\.)|(3\.[0-4]\.)|(2\.95\.[0-4])'
+
+ if options.with_tr1 == None and \
+ re.search(versions_without_tr1, gcc_version):
+ logging.info('Disabling TR1 support for this gcc, too old')
+ options.with_tr1 = 'none'
+
+ versions_without_visibility = '(3\.[0-4]\.)|(2\.95\.[0-4])'
+ if options.with_visibility == None and \
+ re.search(versions_without_visibility, gcc_version):
+ logging.info('Disabling DSO visibility support for this gcc, too old')
+ options.with_visibility = False
if options.dumb_gcc is True:
logging.info('Setting -fpermissive to work around gcc bug')
options.extra_flags = ' -fpermissive'
+ if options.with_visibility is None:
+ options.with_visibility = True
+
if options.with_tr1 == None:
- options.with_tr1 = ('system' if ccinfo[options.compiler].has_tr1 else 'none')
+ if cc.has_tr1:
+ logging.info('Assuming %s has TR1 (use --with-tr1=none to disable)' % (
+ options.compiler))
+ options.with_tr1 = 'system'
+ else:
+ options.with_tr1 = 'none'
if options.with_sphinx is None:
if have_program('sphinx-build'):
- logging.info('Found sphinx-build, will enable; ' +
- 'use --without-sphinx to disable')
+ logging.info('Found sphinx-build, will use it ' +
+ '(use --without-sphinx to disable)')
options.with_sphinx = True
+ if options.via_amalgamation:
+ options.gen_amalgamation = True
+
if options.gen_amalgamation:
if options.asm_ok:
logging.info('Disabling assembly code, cannot use in amalgamation')
options.asm_ok = False
- for mod in ['sha1_sse2', 'serpent_simd']:
- if mod not in options.disabled_modules:
- logging.info('Disabling %s, cannot use in amalgamation' % (mod))
- options.disabled_modules.append(mod)
-
modules_to_use = choose_modules_to_use(modules,
archinfo[options.arch],
options)
@@ -1689,7 +1841,7 @@ def main(argv = None):
template_vars = create_template_vars(build_config, options,
modules_to_use,
- ccinfo[options.compiler],
+ cc,
archinfo[options.arch],
osinfo[options.os])
@@ -1705,7 +1857,7 @@ def main(argv = None):
if __name__ == '__main__':
try:
main()
- except Exception, e:
+ except Exception as e:
logging.error(str(e))
#import traceback
#traceback.print_exc(file=sys.stderr)
diff --git a/doc/_templates/layout.html b/doc/_templates/layout.html
new file mode 100644
index 000000000..c907c7597
--- /dev/null
+++ b/doc/_templates/layout.html
@@ -0,0 +1,9 @@
+{% extends "!layout.html" %}
+
+{% block header %}
+ <div class="header-wrapper">
+ <div class="header">
+ <h1>{{ shorttitle|e }}</h1>
+ </div>
+ </div>
+{% endblock %}
diff --git a/doc/algos.txt b/doc/algos.txt
index bc1477ee7..119b81a7f 100644
--- a/doc/algos.txt
+++ b/doc/algos.txt
@@ -12,39 +12,33 @@ primitives, including:
* Public key cryptography
- * Encryption algorithms RSA, ElGamal, DLIES (padding schemes OAEP,
- PKCS #1 v1.5)
- * Signature algorithms RSA, DSA, ECDSA, GOST 34.10-2001,
- Nyberg-Rueppel, Rabin-Williams (padding schemes PSS, PKCS #1 v1.5,
- X9.31)
- * Key agreement techniques Diffie-Hellman and ECDH
+ * Encryption algorithms RSA, ElGamal, DLIES (padding schemes OAEP,
+ PKCS #1 v1.5)
+ * Signature algorithms RSA, DSA, ECDSA, GOST 34.10-2001,
+ Nyberg-Rueppel, Rabin-Williams (padding schemes PSS, PKCS #1 v1.5,
+ X9.31)
+ * Key agreement techniques Diffie-Hellman and ECDH
* Hash functions
- * NIST hashes: SHA-1, SHA-224, SHA-256, SHA-384, and SHA-512
-
- * RIPE hashes: RIPEMD-160 and RIPEMD-128
-
- * SHA-3 candidates Skein-512, Keccak, and Blue Midnight Wish-512
-
- * Other common hash functions Whirlpool and Tiger
-
- * National standard hashes HAS-160 and GOST 34.11
-
- * Obsolete or insecure hashes MD5, MD4, MD2
-
- * Non-cryptographic checksums Adler32, CRC24, CRC32
+ * NIST hashes: SHA-1, SHA-224, SHA-256, SHA-384, and SHA-512
+ * RIPE hashes: RIPEMD-160 and RIPEMD-128
+ * SHA-3 candidates Skein-512, Keccak, and Blue Midnight Wish-512
+ * Other common hash functions Whirlpool and Tiger
+ * National standard hashes HAS-160 and GOST 34.11
+ * Obsolete or insecure hashes MD5, MD4, MD2
+ * Non-cryptographic checksums Adler32, CRC24, CRC32
* Block ciphers
- * AES (Rijndael) and AES candidates Serpent, Twofish, MARS, CAST-256, RC6
- * DES, and variants 3DES and DESX
- * National/telecom block ciphers SEED, KASUMI, MISTY1, GOST 28147, Skipjack
- * Other block ciphers including Blowfish, CAST-128, IDEA, Noekeon,
- TEA, XTEA, RC2, RC5, SAFER-SK, and Square
- * Block cipher constructions Luby-Rackoff and Lion
- * Block cipher modes ECB, CBC, CBC/CTS, CFB, OFB, CTR, XTS and
- authenticated cipher mode EAX
+ * AES (Rijndael) and AES candidates Serpent, Twofish, MARS, CAST-256, RC6
+ * DES, and variants 3DES and DESX
+ * National/telecom block ciphers SEED, KASUMI, MISTY1, GOST 28147, Skipjack
+ * Other block ciphers including Blowfish, CAST-128, IDEA, Noekeon,
+ TEA, XTEA, RC2, RC5, SAFER-SK, and Square
+ * Block cipher constructions Luby-Rackoff and Lion
+ * Block cipher modes ECB, CBC, CBC/CTS, CFB, OFB, CTR, XTS and
+ authenticated cipher mode EAX
* Stream ciphers ARC4, Salsa20/XSalsa20, Turing, and WiderWake4+1
@@ -53,17 +47,17 @@ primitives, including:
* Public Key Infrastructure
- * X.509 certificates (including generating new self-signed and CA
- certs) and CRLs
- * Certificate path validation
- * PKCS #10 certificate requests (creation and certificate issue)
+ * X.509 certificates (including generating new self-signed and CA
+ certs) and CRLs
+ * Certificate path validation
+ * PKCS #10 certificate requests (creation and certificate issue)
* Other cryptographic utility functions including
- * Key derivation functions for passwords: PBKDF1 (PKCS #5 v1.5),
- PBKDF2 (PKCS #5 v2.0), OpenPGP S2K (RFC 2440)
- * General key derivation functions KDF1 and KDF2 from IEEE 1363
- * PRFs from ANSI X9.42, SSL v3.0, TLS v1.0
+ * Key derivation functions for passwords: PBKDF1 (PKCS #5 v1.5),
+ PBKDF2 (PKCS #5 v2.0), OpenPGP S2K (RFC 2440)
+ * General key derivation functions KDF1 and KDF2 from IEEE 1363
+ * PRFs from ANSI X9.42, SSL v3.0, TLS v1.0
Recommended Algorithms
---------------------------------
diff --git a/doc/build_log.txt b/doc/build_log.txt
index de6197389..2e92a6f90 100644
--- a/doc/build_log.txt
+++ b/doc/build_log.txt
@@ -14,6 +14,11 @@ Debian reports the build results for 1.8 on `a number of platforms
=========== ======= =================== ======================== ============================ ========
Date Version OS CPU Compiler Results
=========== ======= =================== ======================== ============================ ========
+2011-05-09 1.9.17 Debian 6.0 Intel Atom D510 GCC 4.4.5 OK
+2010-05-09 1.9.17 Gentoo 10.0 PowerPC G5 GCC 4.4.5 OK
+2011-05-02 1.9.17 FreeBSD 8.2 x86-64 GCC 4.2.1 OK
+2011-04-25 1.9.16 Gentoo 10.0 Intel Core i7-860 Clang 2.9 Miscompiles SSE2 IDEA
+2011-04-23 1.9.16 Gentoo 10.0 Intel Core i7-860 Sun C++ 5.10 OK
2011-04-22 1.9.16 Gentoo 10.0 Intel Core i7-860 Intel C++ 11.1 OK
2011-04-15 1.9.16 Haiku R1-alpha2 x86 GCC 4.3.3 OK
2011-04-15 1.9.16 Haiku R1-alpha2 x86 GCC 2.95.3 Can't compile
diff --git a/doc/building.txt b/doc/building.txt
index 56beef43e..e16531de4 100644
--- a/doc/building.txt
+++ b/doc/building.txt
@@ -60,10 +60,11 @@ we might see lines like::
INFO: Skipping, incompatible OS - beos_stats cryptoapi_rng win32_crit_section win32_stats
INFO: Skipping, incompatible compiler - mp_msvc64 mp_x86_32_msvc
-The ones that are 'loaded on request only' have to be explicitly asked
-for, because they rely on third party libraries which your system
-might not have. For instance to enable zlib support, add
-``--with-zlib`` to your invocation of ``configure.py``.
+The ones that are skipped because they are 'by request only' have to
+be explicitly asked for, because they rely on third party libraries
+which your system might not have or that you might not want the
+resulting binary to depend on. For instance to enable zlib support,
+add ``--with-zlib`` to your invocation of ``configure.py``.
You can control which algorithms and modules are built using the
options ``--enable-modules=MODS`` and ``--disable-modules=MODS``, for
@@ -136,6 +137,26 @@ self-test program::
$ install_name_tool -change $(otool -X -D libbotan-$VERSION.dylib) \
$PWD/libbotan-$VERSION.dylib check
+Building Universal Binaries
+&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
+
+To build a universal binary for OS X, some simple modifications are
+required. First, create a CPU type for the target universalbinary,
+one that doesn't specify any special handlers. This is done by
+creating an empty file in src/build-data/arch::
+
+ $ touch src/build-data/arch/universalbinary.txt
+
+and then adding a special target for it in gcc, by adding the line::
+
+ universalbinary -> "-force_cpusubtype_ALL -mmacosx-version-min=10.4 -arch i386 -arch ppc"
+
+in the section marked `<mach_abi_linking>` in
+`src/build-data/cc/gcc.txt`. Then configure with::
+
+ $ ./configure.py --cpu=universalbinary [other options here]
+
+
On MS Windows
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -168,26 +189,46 @@ compiler to look for both include files and library files in
place where they will be in the default compiler search paths (consult
your documentation and/or local expert for details).
+Other Build-Related Tasks
+----------------------------------------
+
+.. _building_docs:
+
+Building The Documentation
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+There are two documentation options available, Sphinx and Doxygen.
+Sphinx will be used if ``sphinx-build`` is detected in the PATH, or if
+``--with-sphinx`` is used at configure time. Doxygen is only enabled
+if ``--with-doxygen`` is used. Both are generated by the makefile
+target ``docs``.
+
+
.. _amalgamation:
The Amalgamation Build
-----------------------------------------
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
You can also configure Botan to be built using only a single source
file; this is quite convenient if you plan to embed the library into
-another application. To do so, run ``configure.py`` with
-whatever arguments you would ordinarily use, along with the option
-``--gen-amalgamation``. This will create two (rather large)
-files, ``botan_all.h`` and ``botan_all.cpp``.
+another application. To do so, run ``configure.py`` with whatever
+arguments you would ordinarily use, along with the option
+``--gen-amalgamation``. This will create two (rather large) files,
+``botan_all.h`` and ``botan_all.cpp``.
Whenever you would have included a botan header, you can then include
-``botan_all.h``, and include ``botan_all.cpp`` along
-with the rest of the source files in your build. If you want to be
-able to easily switch between amalgamated and non-amalgamated versions
-(for instance to take advantage of prepackaged versions of botan on
-operating systems that support it), you can instead ignore
-``botan_all.h`` and use the headers from
-``build/include`` as normal.
+``botan_all.h``, and include ``botan_all.cpp`` along with the rest of
+the source files in your build. If you want to be able to easily
+switch between amalgamated and non-amalgamated versions (for instance
+to take advantage of prepackaged versions of botan on operating
+systems that support it), you can instead ignore ``botan_all.h`` and
+use the headers from ``build/include`` as normal.
+
+You can also build the library as normal but using the amalgamation
+instead of the individual source files using ``--via-amalgamation``.
+This is essentially a very simple form of link time optimization;
+because the entire library source is visible to the compiler, it has
+more opportunities for interprocedural optimizations.
Modules Relying on Third Party Libraries
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -206,13 +247,14 @@ enabled at build time; these include:
and decompression. Requires the zlib development libraries to be
installed.
- - ``--with-gnump`` adds an alternative engine for public key cryptography
- that uses the GNU MP library. GNU MP 4.1 or later is required.
+ - ``--with-gnump`` adds an alternative engine for public key
+ cryptography that uses the GNU MP library. GNU MP 4.1 or later is
+ required.
- ``--with-openssl`` adds an engine that uses OpenSSL for some public
key operations and ciphers/hashes. OpenSSL 0.9.7 or later is
- required. Note that (unlike GNU MP) OpenSSL's versions are not
- always faster than the versions built into botan.
+ required. Note that OpenSSL's versions are not always faster than
+ the versions built into botan.
Multiple Builds
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -221,7 +263,6 @@ It may be useful to run multiple builds with different
configurations. Specify ``--build-dir=<dir>`` to set up a build
environment in a different directory.
-
.. _configure_with_python3:
Configuring the Build With Python 3.1
@@ -382,8 +423,8 @@ against is the same one you used to run ``configure.py``.
To install the module, use the ``install`` target.
-Examples of using the Python module can be seen in
-``doc/examples/python``
+See :doc:`Python Bindings <python>` for more information about the
+binding.
Building the Perl XS wrappers
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/doc/conf.py b/doc/conf.py
index 1a5dfe198..65f40314a 100644
--- a/doc/conf.py
+++ b/doc/conf.py
@@ -31,6 +31,24 @@ import botan_version
# If your documentation needs a minimal Sphinx version, state it here.
needs_sphinx = '1.0'
+"""
+Assert that we are running under Sphinx 1.0.7 or later. Earlier
+versions have bugs in the C++ domain that cause crashes. And
+needs_sphinx only allows us to assert needing a particular major/minor
+version.
+"""
+def check_sphinx_version():
+ import sphinx
+
+ version = map(int, sphinx.__version__.split('.'))
+ if version[0] == 1 and version[1] == 0 and version[2] < 7:
+ # Exit rather than throwing to avoid a confusing backtrace
+ print "This Sphinx is too old - upgrade to at least 1.0.7"
+ import sys
+ sys.exit(1)
+
+check_sphinx_version()
+
# Add any Sphinx extension module names here, as strings. They can be extensions
# coming with Sphinx (named 'sphinx.ext.*') or your custom ones.
extensions = []
@@ -103,12 +121,18 @@ pygments_style = 'sphinx'
# The theme to use for HTML and HTML Help pages. See the documentation for
# a list of builtin themes.
-html_theme = 'default'
+html_theme = 'agogo'
# Theme options are theme-specific and customize the look and feel of a theme
# further. For a list of options available for each theme, see the
# documentation.
-#html_theme_options = {}
+html_theme_options = {
+ 'linkcolor': 'blue',
+ 'headerlinkcolor': 'blue',
+ 'headercolor1': 'darkblue',
+ 'headercolor2': 'darkblue',
+ 'textalign': 'left'
+ }
# Add any paths that contain custom themes here, relative to this directory.
#html_theme_path = []
diff --git a/doc/contents.txt b/doc/contents.txt
index 023fa2b1c..dd600d587 100644
--- a/doc/contents.txt
+++ b/doc/contents.txt
@@ -5,7 +5,8 @@ Contents
.. toctree::
:maxdepth: 2
- welcome
+ index
+ reading
building
firststep
filters
@@ -20,10 +21,12 @@ Contents
passhash
rng
fpe
+ python
.. toctree::
:hidden:
+ log
license
credits
faq
@@ -32,7 +35,6 @@ Contents
download
pgpkey
algos
- log
build_log
Indices and tables
diff --git a/doc/download.txt b/doc/download.txt
index b6229cfd6..b8d3e75b3 100644
--- a/doc/download.txt
+++ b/doc/download.txt
@@ -13,51 +13,53 @@ Unsure which release you want? Check the :ref:`FAQ <devel_vs_stable>`.
If you are viewing this documentation offline, a more recent
release `may be available <http://botan.randombit.net/download.html>`_
-Current Stable Release
+Current Stable Release (1.10)
----------------------------------------
-The current stable release is `1.8.11
-<http://botan.randombit.net/news/releases/1_8_11.html>`_ which was
-released on 2010-11-02.
+The current stable release is `1.10.1
+<http://botan.randombit.net/news/releases/1_10_1.html>`_ which was
+released on 2011-07-11.
Sources:
-`1.8.11 tar/gz <http://botan.randombit.net/files/Botan-1.8.11.tgz>`_
-(`1.8.11 tar/gz sig <http://botan.randombit.net/files/Botan-1.8.11.tgz.asc>`_),
+`1.10.1 tar/gz <http://botan.randombit.net/files/Botan-1.10.1.tgz>`_
+(`1.10.1 tar/gz sig <http://botan.randombit.net/files/Botan-1.10.1.tgz.asc>`_),
-`1.8.11 tar/bzip <http://botan.randombit.net/files/Botan-1.8.11.tbz>`_
-(`1.8.11 tar/bzip sig <http://botan.randombit.net/files/Botan-1.8.11.tbz.asc>`_)
+`1.10.1 tar/bzip <http://botan.randombit.net/files/Botan-1.10.1.tbz>`_
+(`1.10.1 tar/bzip sig <http://botan.randombit.net/files/Botan-1.10.1.tbz.asc>`_)
-Windows binary installer for use with Visual C++ 2008:
+..
+ Windows binary installer for use with Visual C++ 2010:
-`1.8.11 x86-32 installer
-<http://botan.randombit.net/files/win32/botan-1.8.11_win32.exe>`_
+ `1.10.1 x86-32 installer
+ <http://botan.randombit.net/files/win32/botan-1.10.1_win32.exe>`_
-`1.8.11 x86-64 installer
-<http://botan.randombit.net/files/win32/botan-1.8.11_win64.exe>`_
+ `1.10.1 x86-64 installer
+ <http://botan.randombit.net/files/win32/botan-1.10.1_win64.exe>`_
-Current Development Release
+Previous Stable Release (1.8)
----------------------------------------
-The current development release is `1.9.16
-<http://botan.randombit.net/news/releases/1_9_16.html>`_ which was
-released on 2011-04-11.
+The previous stable release is `1.8.13
+<http://botan.randombit.net/news/releases/1_8_13.html>`_ which was
+released on 2011-07-02.
Sources:
-`1.9.16 tar/gz <http://botan.randombit.net/files/Botan-1.9.16.tgz>`_
-(`1.9.16 tar/gz sig <http://botan.randombit.net/files/Botan-1.9.16.tgz.asc>`_),
+`1.8.13 tar/gz <http://botan.randombit.net/files/Botan-1.8.13.tgz>`_
+(`1.8.13 tar/gz sig <http://botan.randombit.net/files/Botan-1.8.13.tgz.asc>`_),
-`1.9.16 tar/bzip <http://botan.randombit.net/files/Botan-1.9.16.tbz>`_
-(`1.9.16 tar/bzip sig <http://botan.randombit.net/files/Botan-1.9.16.tbz.asc>`_)
+`1.8.13 tar/bzip <http://botan.randombit.net/files/Botan-1.8.13.tbz>`_
+(`1.8.13 tar/bzip sig <http://botan.randombit.net/files/Botan-1.8.13.tbz.asc>`_)
-Windows binary installer for use with Visual C++ 2010:
+..
+ Windows binary installer for use with Visual C++ 2008:
-`1.9.17-pre x86-32 installer
-<http://botan.randombit.net/files/win32/botan-1.9.17_win32.exe>`_
+ `1.8.13 x86-32 installer
+ <http://botan.randombit.net/files/win32/botan-1.8.13_win32.exe>`_
-`1.9.17-pre x86-64 installer
-<http://botan.randombit.net/files/win32/botan-1.9.17_win64.exe>`_
+ `1.8.13 x86-64 installer
+ <http://botan.randombit.net/files/win32/botan-1.8.13_win64.exe>`_
Accessing Version Control
----------------------------------------
@@ -66,8 +68,9 @@ Botan's development occurs using a distributed version control system
called `Monotone <http://www.monotone.ca>`_.
The main branch of development occurs on the branch named
-``net.randombit.botan``; this is probably the branch you want. To
-download that branch and set up a new workspace, run::
+``net.randombit.botan``; this is probably the branch you want (for
+1.8, use ``net.randombit.botan.1_8`` instead). To download that branch
+and set up a new workspace, run::
$ mtn db init --db=botan.mtn
$ mtn pull --db=botan.mtn randombit.net 'net.randombit.botan'
diff --git a/doc/examples/GNUmakefile b/doc/examples/GNUmakefile
index 44fcfeea5..a5da47a7c 100644
--- a/doc/examples/GNUmakefile
+++ b/doc/examples/GNUmakefile
@@ -3,7 +3,7 @@ BOTAN_CONFIG = botan-config
CXX = g++
CFLAGS = -O2 -ansi -W -Wall -I../../build/include
-LIBS = -L../.. -lbotan
+LIBS = -L../.. -lbotan-1.10
SRCS=$(wildcard *.cpp)
diff --git a/doc/examples/cpuid.cpp b/doc/examples/cpuid.cpp
index 6d4cc7593..bd81e417b 100644
--- a/doc/examples/cpuid.cpp
+++ b/doc/examples/cpuid.cpp
@@ -42,5 +42,6 @@ int main()
print_if_feature("RDTSC", CPUID::has_rdtsc());
print_if_feature("PCMUL", CPUID::has_pcmuludq());
print_if_feature("AES-NI", CPUID::has_aes_ni());
+ print_if_feature("RDRND", CPUID::has_rdrand());
print_if_feature("MOVBE", CPUID::has_movbe());
}
diff --git a/doc/examples/socket.h b/doc/examples/socket.h
index c4fa46600..f7ce98fea 100644
--- a/doc/examples/socket.h
+++ b/doc/examples/socket.h
@@ -10,13 +10,57 @@
#include <stdexcept>
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <sys/time.h>
-#include <netinet/in.h>
-#include <netdb.h>
-#include <unistd.h>
-#include <errno.h>
+#if defined(_MSC_VER)
+ #define SOCKET_IS_WINSOCK 1
+#endif
+
+#if !defined(SOCKET_IS_WINSOCK)
+ #define SOCKET_IS_WINSOCK 0
+#endif
+
+#if SOCKET_IS_WINSOCK
+ #include <winsock.h>
+
+ typedef SOCKET socket_t;
+ const socket_t invalid_socket = INVALID_SOCKET;
+ #define socket_error_code WSAGetLastError()
+ typedef int ssize_t;
+
+ class SocketInitializer
+ {
+ public:
+ SocketInitializer()
+ {
+ WSADATA wsadata;
+ WSAStartup(MAKEWORD(2, 2), &wsadata);
+ }
+
+ ~SocketInitializer()
+ {
+ WSACleanup();
+ }
+ };
+#else
+ #include <sys/types.h>
+ #include <sys/socket.h>
+ #include <sys/time.h>
+ #include <netinet/in.h>
+ #include <netdb.h>
+ #include <unistd.h>
+ #include <errno.h>
+
+ typedef int socket_t;
+ const socket_t invalid_socket = -1;
+ #define socket_error_code errno
+ #define closesocket close
+
+ class SocketInitializer {};
+#endif
+
+#if !defined(MSG_NOSIGNAL)
+ #define MSG_NOSIGNAL 0
+#endif
+
#include <string.h>
class Socket
@@ -29,15 +73,15 @@ class Socket
void close()
{
- if(sockfd != -1)
+ if(sockfd != invalid_socket)
{
- if(::close(sockfd) != 0)
+ if(::closesocket(sockfd) != 0)
throw std::runtime_error("Socket::close failed");
- sockfd = -1;
+ sockfd = invalid_socket;
}
}
- Socket(int fd, const std::string& peer_id = "") :
+ Socket(socket_t fd, const std::string& peer_id = "") :
peer(peer_id), sockfd(fd)
{
}
@@ -46,7 +90,7 @@ class Socket
~Socket() { close(); }
private:
std::string peer;
- int sockfd;
+ socket_t sockfd;
};
class Server_Socket
@@ -57,26 +101,26 @@ class Server_Socket
*/
Socket* accept()
{
- int retval = ::accept(sockfd, 0, 0);
- if(retval == -1)
+ socket_t retval = ::accept(sockfd, 0, 0);
+ if(retval == invalid_socket)
throw std::runtime_error("Server_Socket: accept failed");
return new Socket(retval);
}
void close()
{
- if(sockfd != -1)
+ if(sockfd != invalid_socket)
{
- if(::close(sockfd) != 0)
+ if(::closesocket(sockfd) != 0)
throw std::runtime_error("Server_Socket::close failed");
- sockfd = -1;
+ sockfd = invalid_socket;
}
}
Server_Socket(unsigned short);
~Server_Socket() { close(); }
private:
- int sockfd;
+ socket_t sockfd;
};
/**
@@ -84,7 +128,7 @@ class Server_Socket
*/
Socket::Socket(const std::string& host, unsigned short port) : peer(host)
{
- sockfd = -1;
+ sockfd = invalid_socket;
hostent* host_addr = ::gethostbyname(host.c_str());
@@ -93,8 +137,8 @@ Socket::Socket(const std::string& host, unsigned short port) : peer(host)
if(host_addr->h_addrtype != AF_INET) // FIXME
throw std::runtime_error("Socket: " + host + " has IPv6 address");
- int fd = ::socket(PF_INET, SOCK_STREAM, 0);
- if(fd == -1)
+ socket_t fd = ::socket(PF_INET, SOCK_STREAM, 0);
+ if(fd == invalid_socket)
throw std::runtime_error("Socket: Unable to acquire socket");
sockaddr_in socket_info;
@@ -110,7 +154,7 @@ Socket::Socket(const std::string& host, unsigned short port) : peer(host)
if(::connect(fd, (sockaddr*)&socket_info, sizeof(struct sockaddr)) != 0)
{
- ::close(fd);
+ ::closesocket(fd);
throw std::runtime_error("Socket: connect failed");
}
@@ -122,21 +166,22 @@ Socket::Socket(const std::string& host, unsigned short port) : peer(host)
*/
size_t Socket::read(unsigned char buf[], size_t length)
{
- if(sockfd == -1)
+ if(sockfd == invalid_socket)
throw std::runtime_error("Socket::read: Socket not connected");
size_t got = 0;
while(length)
{
- ssize_t this_time = ::recv(sockfd, buf + got, length, MSG_NOSIGNAL);
+ ssize_t this_time = ::recv(sockfd, (char*)buf + got,
+ length, MSG_NOSIGNAL);
if(this_time == 0)
break;
if(this_time == -1)
{
- if(errno == EINTR)
+ if(socket_error_code == EINTR)
this_time = 0;
else
throw std::runtime_error("Socket::read: Socket read failed");
@@ -153,17 +198,18 @@ size_t Socket::read(unsigned char buf[], size_t length)
*/
void Socket::write(const unsigned char buf[], size_t length)
{
- if(sockfd == -1)
+ if(sockfd == invalid_socket)
throw std::runtime_error("Socket::write: Socket not connected");
size_t offset = 0;
while(length)
{
- ssize_t sent = ::send(sockfd, buf + offset, length, MSG_NOSIGNAL);
+ ssize_t sent = ::send(sockfd, (const char*)buf + offset,
+ length, MSG_NOSIGNAL);
if(sent == -1)
{
- if(errno == EINTR)
+ if(socket_error_code == EINTR)
sent = 0;
else
throw std::runtime_error("Socket::write: Socket write failed");
@@ -179,10 +225,10 @@ void Socket::write(const unsigned char buf[], size_t length)
*/
Server_Socket::Server_Socket(unsigned short port)
{
- sockfd = -1;
+ sockfd = invalid_socket;
- int fd = ::socket(PF_INET, SOCK_STREAM, 0);
- if(fd == -1)
+ socket_t fd = ::socket(PF_INET, SOCK_STREAM, 0);
+ if(fd == invalid_socket)
throw std::runtime_error("Server_Socket: Unable to acquire socket");
sockaddr_in socket_info;
@@ -195,13 +241,13 @@ Server_Socket::Server_Socket(unsigned short port)
if(::bind(fd, (sockaddr*)&socket_info, sizeof(struct sockaddr)) != 0)
{
- ::close(fd);
+ ::closesocket(fd);
throw std::runtime_error("Server_Socket: bind failed");
}
- if(listen(fd, 100) != 0) // FIXME: totally arbitrary
+ if(::listen(fd, 100) != 0) // FIXME: totally arbitrary
{
- ::close(fd);
+ ::closesocket(fd);
throw std::runtime_error("Server_Socket: listen failed");
}
diff --git a/doc/examples/tls_client.cpp b/doc/examples/tls_client.cpp
index eb4a98817..cedfe1ca8 100644
--- a/doc/examples/tls_client.cpp
+++ b/doc/examples/tls_client.cpp
@@ -35,13 +35,15 @@ int main(int argc, char* argv[])
try
{
- LibraryInitializer init;
+ LibraryInitializer botan_init;
std::string host = argv[1];
u32bit port = argc == 3 ? Botan::to_u32bit(argv[2]) : 443;
printf("Connecting to %s:%d...\n", host.c_str(), port);
+ SocketInitializer socket_init;
+
Socket sock(argv[1], port);
AutoSeeded_RNG rng;
@@ -54,10 +56,15 @@ int main(int argc, char* argv[])
printf("Handshake extablished...\n");
+#if 0
std::string http_command = "GET / HTTP/1.1\r\n"
"Server: " + host + ':' + to_string(port) + "\r\n\r\n";
+#else
+ std::string http_command = "GET / HTTP/1.0\r\n\r\n";
+#endif
- tls.write((const byte*)http_command.c_str(), http_command.length());
+ tls.write((const Botan::byte*)http_command.c_str(),
+ http_command.length());
size_t total_got = 0;
@@ -66,7 +73,7 @@ int main(int argc, char* argv[])
if(tls.is_closed())
break;
- byte buf[128+1] = { 0 };
+ Botan::byte buf[128+1] = { 0 };
size_t got = tls.read(buf, sizeof(buf)-1);
printf("%s", buf);
fflush(0);
diff --git a/doc/examples/tls_server.cpp b/doc/examples/tls_server.cpp
index be5677c12..153b26d04 100644
--- a/doc/examples/tls_server.cpp
+++ b/doc/examples/tls_server.cpp
@@ -39,7 +39,8 @@ int main(int argc, char* argv[])
try
{
- LibraryInitializer init;
+ LibraryInitializer botan_init;
+ SocketInitializer socket_init;
AutoSeeded_RNG rng;
@@ -81,12 +82,12 @@ int main(int argc, char* argv[])
printf("Writing some text\n");
char msg[] = "Foo\nBar\nBaz\nQuux\n";
- tls.write((const byte*)msg, strlen(msg));
+ tls.write((const Botan::byte*)msg, strlen(msg));
printf("Now trying a read...\n");
char buf[1024] = { 0 };
- u32bit got = tls.read((byte*)buf, sizeof(buf)-1);
+ u32bit got = tls.read((Botan::byte*)buf, sizeof(buf)-1);
printf("%d: '%s'\n", got, buf);
tls.close();
diff --git a/doc/faq.txt b/doc/faq.txt
index 38be253a7..9658621fe 100644
--- a/doc/faq.txt
+++ b/doc/faq.txt
@@ -28,16 +28,20 @@ stability between releases on the development branch, and API changes
may be made without notice. Feel free to send comments on API changes,
or API problems, to the list.
-If you want to ship a binary that is usable out of the box on a Linux
-distro that ships botan (most do), or you want to ensure you're not
-having to track a moving target, you'll probably prefer using the
+If you don't want to have to worry about tracking a moving target, and
+just want something that works, you'll probably prefer using the
stable releases. If you want to get the latest features, the
-development releases are the obvious choice. If you're building an
-application that will embed botan into it (without relying on a shared
-library), you want to use an amalgamation build, which basically turns
-botan into a single header and a single source file which you can
-easily include in your existing application build; this feature is
-currently only available in the development trees.
+development releases are the obvious choice.
+
+If you want to ship a binary that is usable out of the box on a Linux
+distro that ships botan, you'll probably want to match versions with
+that distro; as of this writing most ship with 1.8.
+
+If you're building an application that will embed botan into it
+(without relying on a shared library), you want to use an amalgamation
+build, which basically turns botan into a single header and a single
+source file which you can easily include in your existing application
+build. In this case you can pick which ever tree you prefer.
The self-test program can't locate the library
-----------------------------------------------
@@ -88,7 +92,7 @@ to use.
For unencrypted keys, you can also manually decode the parameters
using the existing PEM and BER support; see `this post
-<http://lists.randombit.net/pipermail/botan-devel/2010-June/001157.html>`_
+<http://lists.randombit.net/pipermail/botan-devel/2010-June/001156.html>`_
to the dev list for an example.
Is botan FIPS 140 certified?
@@ -155,7 +159,7 @@ You can do any combination of:
* Contact the current lead maintainer personally; currently
`Jack Lloyd <http://www.randombit.net>`_
- (`personal PGP key` <http://www.randombit.net/pgpgkey.html`_)
+ (`personal PGP key <http://www.randombit.net/pgpgkey.html>`_)
* Email the `development list
<http://lists.randombit.net/mailman/listinfo/botan-devel>`_
@@ -165,8 +169,8 @@ You can do any combination of:
Does botan support SSL/TLS, SSH, S/MIME, OpenPGP...
------------------------------------------------------------
-Support for SSL/TLS is included in the most recent development
-releases (1.9.x). Currently SSLv3 and TLS 1.0 and 1.1 are supported.
+Support for SSL/TLS is included in version 1.9.4 and later. Currently
+SSLv3 and TLS 1.0 and 1.1 are supported.
`NetSieben SSH <http://netsieben.com/products/ssh/>`_ is an open
source SSHv2 implementation that uses botan.
@@ -181,9 +185,8 @@ Will it work on my platform XYZ??
----------------------------------------
The most common stumbling block is a compiler that is buggy or can't
-handle modern C++ (specifically, C++98). Check out the `build list
-<http://botan.randombit.net/builds.html>`_ for a sense of which
-platforms are actively being tested.
+handle modern C++ (specifically, C++98). Check out the :doc:`build log
+<build_log>` for a sense of which platforms are actively being tested.
I'm not feeling this, what can I use instead?
------------------------------------------------------------
diff --git a/doc/fpe.txt b/doc/fpe.txt
index 243be87d9..5c035f0b7 100644
--- a/doc/fpe.txt
+++ b/doc/fpe.txt
@@ -2,6 +2,8 @@
Format Preserving Encryption
========================================
+.. versionadded:: 1.9.17
+
Format preserving encryption (FPE) refers to a set of techniques for
encrypting data such that the ciphertext has the same format as the
plaintext. For instance, you can use FPE to encrypt credit card
diff --git a/doc/welcome.txt b/doc/index.txt
index 430a71f20..75e2ca434 100644
--- a/doc/welcome.txt
+++ b/doc/index.txt
@@ -9,8 +9,9 @@ provides applications with most any :doc:`cryptographic algorithm
message processing system <filters>`, and a wide variety of other
features. A third party open source implementation of `SSHv2
<http://www.netsieben.com/products/ssh/>`_ that uses botan is also
-available. In addition to C++ you can use botan from Python or Perl,
-though the current bindings only wrap portions of the library.
+available. In addition to C++ you can use botan from :doc:`Python
+<python>` or Perl, though the current bindings only wrap portions of
+the library.
See the :doc:`faq` for a list of common questions and answers.
@@ -47,7 +48,7 @@ already included in most major package distributions, including
more than a few :doc:`known users <users>`.
It was started as a personal project by `Jack Lloyd
-<http:://www.randombit.net>`_,who continues to be the maintainer and
+<http://www.randombit.net>`_,who continues to be the maintainer and
release manager. Since the first release in 2001, a number of
:doc:`individuals and organizations <credits>` have contributed bug
fixes and new features. Check out the :doc:`release notes <log>` and
@@ -66,25 +67,3 @@ be a bug, please file a ticket in `Bugzilla
A useful reference while reading this manual is the `Doxygen
documentation <http://botan.randombit.net/doxygen>`_.
-Recommended Reading
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-It's a very good idea if you have some knowledge of cryptography
-*before* trying to use the library. This is an area where it is very
-easy to make mistakes, and where things are often subtle and/or
-counterintuitive. Obviously the library tries to provide things at a
-high level precisely to minimize the number of ways things can go
-wrong, but naive use will almost certainly not result in a secure
-system.
-
-Especially recommended are:
-
-- *Cryptography Engineering*
- Niels Ferguson, Bruce Schneier, and Tadayoshi Kohno
-
-- *Security Engineering -- A Guide to Building Dependable Distributed Systems*
- Ross Anderson
-
-- *Handbook of Applied Cryptography*
- Alfred J. Menezes, Paul C. Van Oorschot, and Scott A. Vanstone
- (`available online <http://www.cacr.math.uwaterloo.ca/hac/>`_)
diff --git a/doc/log.txt b/doc/log.txt
index 7e00e87c2..478b27a94 100644
--- a/doc/log.txt
+++ b/doc/log.txt
@@ -4,12 +4,172 @@
Release Notes
========================================
+Series 1.10
+----------------------------------------
+
+Version 1.10.2, Not Yet Released
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+* The SSL/TLS code is disabled by default in this release. A new
+ version is being developed and the current iteration should not be
+ used unless needed for existing code.
+
+* Add the Camellia block cipher
+
+* An implementation of SRP-6a compatible with the specification in
+ RFC 5054 is now available in srp6.h
+
+* The exception catching syntax of configure.py has been changed to
+ the Python 3.x syntax. This syntax also works with Python 2.6 and
+ 2.7, but not with any earlier Python 2 release. A simple search and
+ replace will allow running it under Python 2.5::
+ perl -pi -e 's/except (.*) as (.*):/except $1, $2:/g' configure.py
+
+* If clock_gettime is available on the system, poll all available
+ clock types in the hres_timer poll.
+
+* Add AltiVec detection for IBM POWER7 processors.
+
+* Add AltiVec detection for OpenBSD, contributed by Brad Smith (PR 162)
+
+* Add Google's Native Client as an compile target
+
+* If targetting GCC on a Windows system, configure.py will warn that
+ likely you wanted to configure for either MinGW or Cygwin, not the
+ generic Windows target which is oriented to Win32 plus the Visual
+ C++ runtime.
+
+* Fixed a compilation problem of the dynamic loader hooks under MinGW GCC
+
+* Don't set a soname on OpenBSD, as it doesn't support it (PR 158)
+
+* Fix a configure.py incompatability with the subprocess module
+ included in Python 3.1 (PR 157)
+
+* A bug in configure.py would cause it to interpret `--cpu=s390x` as
+ `s390`. This may have affected other CPUs as well. Now configure.py
+ searches for an exact match, and only if no exact match is found
+ will it search for substring matches.
+
+Version 1.10.1, 2011-07-11
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+* A race condition in `Algorithm_Factory` could cause crashes in
+ multithreaded code. See `this thread on botan-devel
+ <http://lists.randombit.net/pipermail/botan-devel/2011-July/001455.html>`_
+ for details and workarounds.
+
+* The return value of ``name`` has changed for GOST 28147-89 and
+ Skein-512. GOST's ``name`` now includes the name of the sbox, and
+ Skein's includes the personalization string (if nonempty). This
+ allows an object to be properly roundtripped, which is necessary to
+ fix the race condition described above.
+
+* A new distribution script is now included, as
+ ``src/build-data/scripts/dist.py``
+
+* The ``build.h`` header now includes, if available, an identifier of
+ the source revision that was used. This identifier is also included
+ in the result of ``version_string``.
+
+Version 1.10.0, 2011-06-20
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+* Detection for the rdrand instruction being added to upcoming Intel
+ Ivy Bridge processors has been added.
+
+* A template specialization of std::swap was added for the memory
+ container types.
+
Series 1.9
----------------------------------------
-Version 1.9.17, Not Yet Released
+Version 1.9.18, 2011-06-03
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+* Fourth release candidate for 1.10.0
+
+* The GOST 34.10 verification operation was not ensuring that s and r
+ were both greater than zero. This could potentially have meant it
+ would have accepted an invalid all-zero signature as valid for any
+ message. Due to how ECC points are internally represented it instead
+ resulted in an exception being thrown.
+
+* A simple multiexponentation algorithm is now used in ECDSA and
+ GOST-34.10 signature verification, leading to 20 to 25% improvements
+ in ECDSA and 25% to 40% improvements in GOST-34.10 verification
+ performance.
+
+* The internal representation of elliptic curve points has been
+ modified to use Montgomery representation exclusively, resulting in
+ reduced memory usage and a 10 to 20% performance improvement for
+ ECDSA and ECDH.
+
+* In OAEP decoding, scan for the delimiter bytes using a loop that is
+ written without conditionals so as to help avoid timing analysis.
+ Unfortunately GCC at least is 'smart' enough to compile it to
+ jumps anyway.
+
+* The SSE2 implementation of IDEA did not work correctly when compiled
+ by Clang, because the trick it used to emulate a 16 bit unsigned
+ compare in SSE (which doesn't contain one natively) relied on signed
+ overflow working in the 'usual' way. A different method that doesn't
+ rely on signed overflow is now used.
+
+* Add support for compiling SSL using Visual C++ 2010's TR1
+ implementation.
+
+* Fix a bug under Visual C++ 2010 which would cause ``hex_encode`` to
+ crash if given a zero-sized input to encode.
+
+* A new build option ``--via-amalgamation`` will first generate the
+ single-file amalgamation, then build the library from that single
+ file. This option requires a lot of memory and does not parallelize,
+ but the resulting library is smaller and may be faster.
+
+* On Unix, the library and header paths have been changed to allow
+ parallel installation of different versions of the library. Headers
+ are installed into ``<prefix>/include/botan-1.9/botan``, libraries
+ are named ``libbotan-1.9``, and ``botan-config`` is now namespaced
+ (so in this release ``botan-config-1.9``). All of these embedded
+ versions will be 1.10 in the upcoming stable release.
+
+* The soname system has been modified. In this release the library
+ soname is ``libbotan-1.9.so.0``, with the full library being named
+ ``libbotan-1.9.so.0.18``. The ``0`` is the ABI version, and will be
+ incremented whenever a breaking ABI change is made.
+
+* TR1 support is not longer automatically assumed under older versions
+ of GCC
+
+* Functions for base64 decoding that work standalone (without needing
+ to use a pipe) have been added to ``base64.h``
+
+* The function ``BigInt::to_u32bit`` was inadvertently removed in 1.9.11
+ and has been added back.
+
+* The function ``BigInt::get_substring`` did not work correctly with a
+ *length* argument of 32.
+
+* The implementation of ``FD_ZERO`` on Solaris uses ``memset`` and
+ assumes the caller included ``string.h`` on its behalf. Do so to
+ fix compilation in the ``dev_random`` and ``unix_procs`` entropy
+ sources. Patch from Jeremy C. Reed.
+
+* Add two different configuration targets for Atom, since some are
+ 32-bit and some are 64-bit. The 'atom' target now refers to the
+ 64-bit implementations, use 'atom32' to target the 32-bit
+ processors.
+
+* The (incomplete) support for CMS and card verifiable certificates
+ are disabled by default; add ``--enable-modules=cms`` or
+ ``--enable-modules=cvc`` during configuration to turn them back on.
+
+Version 1.9.17, 2011-04-29
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+* Third release candidate for 1.10.0
+
* The format preserving encryption method currently available was
presented in the header ``fpe.h`` and the functions ``fpe_encrypt``
and ``fpe_decrypt``. These were renamed as it is likely that other
@@ -36,6 +196,15 @@ Version 1.9.17, Not Yet Released
``BOTAN_TARGET_ARCH_IS_X86_32``. The classes calling assembly have
also been renamed.
+* Similiarly to the above change, the AES implemenations using the
+ AES-NI instruction set have been renamed from AES_XXX_Intel to
+ AES_XXX_NI.
+
+* Systems that are identified as `sun4u` will default to compiling for
+ 32-bit SPARCv9 code rather than 64-bit. This matches the still
+ common convention for 32-bit SPARC userspaces. If you want 64-bit
+ code on such as system, use ``--cpu=sparc64``.
+
* Some minor fixes for compiling botan under the BeOS
clone/continuation `Haiku <http://haiku-os.org>`_.
@@ -320,6 +489,28 @@ Version 1.9.0, 2009-09-09
Series 1.8
----------------------------------------
+Version 1.8.13, 2011-07-02
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+* A race condition in `Algorithm_Factory` could cause crashes in
+ multithreaded code. See `this thread on botan-devel
+ <http://lists.randombit.net/pipermail/botan-devel/2011-July/001455.html>`_
+ for details and workarounds.
+
+Version 1.8.12, 2011-06-20
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+* If EMSA3(Raw) was used for more than one signature, it would produce
+ incorrect output.
+
+* Fix the --enable-debug option to configure.py
+
+* Improve OS detection on Cygwin
+
+* Fix compilation under Sun Studio 12 on Solaris
+
+* Fix a memory leak in the constructors of DataSource_Stream and
+ DataSink_Stream which would occur if opening the file failed. PR 144
+
Version 1.8.11, 2010-11-02
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/doc/old/insito_manual.pdf b/doc/old/insito_manual.pdf
deleted file mode 100644
index b07146992..000000000
--- a/doc/old/insito_manual.pdf
+++ /dev/null
Binary files differ
diff --git a/doc/pgpkey.txt b/doc/pgpkey.txt
index 1d2f3debc..ef8827835 100644
--- a/doc/pgpkey.txt
+++ b/doc/pgpkey.txt
@@ -2,6 +2,8 @@
PGP Code Signing Key
========================================
+.. highlight:: none
+
The following PGP key is used to sign all releases::
pub 2048R/EFBADFBC 2004-10-30
diff --git a/doc/python.txt b/doc/python.txt
new file mode 100644
index 000000000..dcd274eed
--- /dev/null
+++ b/doc/python.txt
@@ -0,0 +1,14 @@
+
+Python Binding
+========================================
+
+.. highlight:: python
+
+.. note::
+
+ The Python binding should be considered alpha software, and the
+ interfaces may change in the future.
+
+Botan includes a binding for Python, implemented using Boost.Python.
+
+.. literalinclude:: examples/python/rsa.py
diff --git a/doc/reading.txt b/doc/reading.txt
new file mode 100644
index 000000000..a0e547296
--- /dev/null
+++ b/doc/reading.txt
@@ -0,0 +1,23 @@
+
+Recommended Reading
+========================================
+
+It's a very good idea if you have some knowledge of cryptography
+*before* trying to use the library. This is an area where it is very
+easy to make mistakes, and where things are often subtle and/or
+counterintuitive. Obviously the library tries to provide things at a
+high level precisely to minimize the number of ways things can go
+wrong, but naive use will almost certainly not result in a secure
+system.
+
+Especially recommended are:
+
+- *Cryptography Engineering*
+ Niels Ferguson, Bruce Schneier, and Tadayoshi Kohno
+
+- *Security Engineering -- A Guide to Building Dependable Distributed Systems*
+ Ross Anderson
+
+- *Handbook of Applied Cryptography*
+ Alfred J. Menezes, Paul C. Van Oorschot, and Scott A. Vanstone
+ (`available online <http://www.cacr.math.uwaterloo.ca/hac/>`_)
diff --git a/doc/ssl.txt b/doc/ssl.txt
index 7b61fa88c..f536b7198 100644
--- a/doc/ssl.txt
+++ b/doc/ssl.txt
@@ -4,6 +4,8 @@
SSL and TLS
========================================
+.. versionadded:: 1.9.4
+
Botan supports both client and server implementations of the SSL/TLS
protocols, including SSL v3, TLS v1.0, and TLS v1.1. The insecure and
obsolete SSL v2 is not supported.
@@ -15,7 +17,35 @@ feature macro ``BOTAN_HAS_SSL_TLS`` to check.
TLS Clients
----------------------------------------
-A simple TLS client:
+.. cpp:class:: TLS_Client
+
+ .. cpp:function:: TLS_Client( \
+ std::tr1::function<size_t, byte*, size_t> input_fn, \
+ std::tr1::function<void, const byte*, size_t> output_fn, \
+ const TLS_Policy& policy, RandomNumberGenerator& rng)
+
+ Creates a TLS client. It will call *input_fn* to read bytes from
+ the network and call *output_fn* when bytes need to be written to
+ the network.
+
+ .. cpp:function:: size_t read(byte* buf, size_t buf_len)
+
+ Reads up to *buf_len* bytes from the open connection into *buf*,
+ returning the number of bytes actually written.
+
+ .. cpp:function:: void write(const byte* buf, size_t buf_len)
+
+ Writes *buf_len* bytes in *buf* to the remote side
+
+ .. cpp:function:: void close()
+
+ Closes the connection
+
+ .. cpp:function:: std::vector<X509_Certificate> peer_cert_chain()
+
+ Returns the certificate chain of the server
+
+A simple TLS client example:
.. literalinclude:: examples/tls_client.cpp
diff --git a/doc/users.txt b/doc/users.txt
index 9c7d274d3..a48d9e60b 100644
--- a/doc/users.txt
+++ b/doc/users.txt
@@ -28,25 +28,25 @@ Open Source Software
crypto provider
<http://websvn.kde.org/trunk/kdesupport/qca/src/botantools/botan/>`_.
+* `TCHead <http://16s.us/TCHead/>`_ is a utility for analyzing
+ TrueCrypt volume headers.
+
+* `Octopod <http://code.google.com/p/octopod/>`_ is a
+ file sharing system.
+
* `Silverlock <http://www.petroules.com/products/silverlock/>`_
is a GPL password management tool for Windows, OS X, and Linux.</p>
-* `eVersys <http://code.google.com/p/eversys/>`_ is a GPL
- alternative to Rational ClearCase.
-
* `Monotone <http://monotone.ca/>`_, a free distributed
version control system, uses botan for RSA authentication,
content hashing, and message authentication.
-* `Publimark <http://perso.wanadoo.fr/gleguelv/soft/>`_, a
- tool for hiding messages in an audio file.
+* `Publimark <http://www.gleguelv.org/soft/publimark/index.html>`_
+ is a tool for hiding messages in an audio file.
-* `KeySafe <http://www.gnomefiles.org/app.php/KeySafe>`_,
+* `KeySafe <http://therning.org/magnus/computer/keysafe>`_,
a password application for GNOME
-* `Octopod <http://code.google.com/p/octopod/>`_ is a
- file sharing system.
-
* `SuSE <http://gcc.opensuse.org>`_ uses botan as part
of a test suite for the GCC optimizer.
@@ -56,10 +56,6 @@ Open Source Software
* `VNCcrack <http://www.randombit.net/code/vnccrack/>`_
is a password cracker for the VNC authentication/response protocol.
-* `Cutlass <http://www.synacklabs.net/projects/cutlass/>`_, an
- encrypted P2P system providing IM, file transfer, and VoIP, used
- botan.
-
Commercial Software
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -79,9 +75,6 @@ Commercial Software
* `TextEgg <http://www.textegg.com/>`_ is an encrypted document editor.
-* `Trillian Astra <http://www.trillianastra.com>`_, Cerulean Studios
- IM client, uses botan
-
* `Seagate <http://www.seagate.com/www/en-us/support/downloads/>`_
uses botan for the drive encryption in the Maxtor OneTouch III Mini
Edition hard drive.
@@ -89,12 +82,8 @@ Commercial Software
* `Aegeus Technology Ltd <http://www.aegeus-technology.com>`_ used
botan in a research implementation of SPKI.
-* `Portalsphere <http://www.portalsphere.com>`_, a CORBA based
- application server, provides access to botan (though a Tcl wrapper)
- to application developers.
-
-* `E.V.E. Paradox <http://www.eveparadox.com>`_, a suite of games for
- Windows, uses botan.
+* `E.V.E. Paradox <http://www.entropicsoftware.com/eve/eve.html>`_, a
+ suite of games for Windows.
Research Projects
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/readme.txt b/readme.txt
index 35eedfc17..f7bc55f61 100644
--- a/readme.txt
+++ b/readme.txt
@@ -1,4 +1,4 @@
-Botan 1.9.17, Not Yet Released
+Botan 1.10.2, ????-??-??
http://botan.randombit.net/
Botan is a C++ class library for performing a wide variety of
@@ -8,8 +8,8 @@ Bugzilla (http://bugs.randombit.net/) or by sending a report to the
botan-devel mailing list. More information about the mailing list is
at http://lists.randombit.net/mailman/listinfo/botan-devel/
-You can find documentation online at http://botan.randombit.net/docs
-and http://botan.randombit.net/doxygen. A set of example programs can
-be found in the examples directory.
+You can find documentation online at http://botan.randombit.net/ as
+well as in the doc directory in the distribution. Several examples can
+be found in doc/examples as well.
Jack Lloyd ([email protected])
diff --git a/src/algo_factory/algo_cache.h b/src/algo_factory/algo_cache.h
index 0d891ad3f..25f2db023 100644
--- a/src/algo_factory/algo_cache.h
+++ b/src/algo_factory/algo_cache.h
@@ -1,6 +1,6 @@
/*
* An algorithm cache (used by Algorithm_Factory)
-* (C) 2008-2009 Jack Lloyd
+* (C) 2008-2009,2011 Jack Lloyd
*
* Distributed under the terms of the Botan license
*/
@@ -171,14 +171,16 @@ void Algorithm_Cache<T>::add(T* algo,
Mutex_Holder lock(mutex);
- delete algorithms[algo->name()][provider];
- algorithms[algo->name()][provider] = algo;
-
if(algo->name() != requested_name &&
aliases.find(requested_name) == aliases.end())
{
aliases[requested_name] = algo->name();
}
+
+ if(!algorithms[algo->name()][provider])
+ algorithms[algo->name()][provider] = algo;
+ else
+ delete algo;
}
/*
diff --git a/src/alloc/alloc_mmap/mmap_mem.cpp b/src/alloc/alloc_mmap/mmap_mem.cpp
index 78177bcdd..e4b602764 100644
--- a/src/alloc/alloc_mmap/mmap_mem.cpp
+++ b/src/alloc/alloc_mmap/mmap_mem.cpp
@@ -85,20 +85,22 @@ void* MemoryMapping_Allocator::alloc_block(size_t n)
if(file.get_fd() == -1)
throw MemoryMapping_Failed("Could not create file");
- std::vector<byte> zeros(n);
+ std::vector<byte> zeros(4096);
- ssize_t remaining = n;
+ size_t remaining = n;
while(remaining)
{
- ssize_t wrote_here = ::write(file.get_fd(),
- &zeros[0],
- remaining);
+ const size_t write_try = std::min(zeros.size(), remaining);
- if(wrote_here == -1 && errno != EINTR)
+ ssize_t wrote_got = ::write(file.get_fd(),
+ &zeros[0],
+ write_try);
+
+ if(wrote_got == -1 && errno != EINTR)
throw MemoryMapping_Failed("Could not write to file");
- remaining -= wrote_here;
+ remaining -= wrote_got;
}
#ifndef MAP_NOSYNC
diff --git a/src/alloc/secmem.h b/src/alloc/secmem.h
index b06be0d55..6c8a75c44 100644
--- a/src/alloc/secmem.h
+++ b/src/alloc/secmem.h
@@ -34,7 +34,6 @@ class MemoryRegion
*/
bool empty() const { return (used == 0); }
-#if 1
/**
* Get a pointer to the first element in the buffer.
* @return pointer to the first element in the buffer
@@ -46,12 +45,6 @@ class MemoryRegion
* @return constant pointer to the first element in the buffer
*/
operator const T* () const { return buf; }
-#else
-
- T& operator[](size_t n) { return buf[n]; }
- const T& operator[](size_t n) const { return buf[n]; }
-
-#endif
/**
* Get a pointer to the first element in the buffer.
@@ -171,9 +164,9 @@ class MemoryRegion
*/
void swap(MemoryRegion<T>& other);
- ~MemoryRegion() { deallocate(buf, allocated); }
+ virtual ~MemoryRegion() { deallocate(buf, allocated); }
protected:
- MemoryRegion() { buf = 0; alloc = 0; used = allocated = 0; }
+ MemoryRegion() : buf(0), used(0), allocated(0), alloc(0) {}
/**
* Copy constructor
@@ -425,4 +418,14 @@ void zeroise(MemoryRegion<T>& vec)
}
+namespace std {
+
+template<typename T>
+inline void swap(Botan::MemoryRegion<T>& x, Botan::MemoryRegion<T>& y)
+ {
+ x.swap(y);
+ }
+
+}
+
#endif
diff --git a/src/asn1/alg_id.cpp b/src/asn1/alg_id.cpp
index b48db3e50..665e42fb3 100644
--- a/src/asn1/alg_id.cpp
+++ b/src/asn1/alg_id.cpp
@@ -41,8 +41,12 @@ AlgorithmIdentifier::AlgorithmIdentifier(const OID& alg_id,
const byte DER_NULL[] = { 0x05, 0x00 };
oid = alg_id;
+
if(option == USE_NULL_PARAM)
- parameters += std::make_pair(DER_NULL, sizeof(DER_NULL));
+ {
+ parameters += std::make_pair<const byte*, size_t>(
+ DER_NULL, sizeof(DER_NULL));
+ }
}
/*
@@ -54,8 +58,12 @@ AlgorithmIdentifier::AlgorithmIdentifier(const std::string& alg_id,
const byte DER_NULL[] = { 0x05, 0x00 };
oid = OIDS::lookup(alg_id);
+
if(option == USE_NULL_PARAM)
- parameters += std::make_pair(DER_NULL, sizeof(DER_NULL));
+ {
+ parameters += std::make_pair<const byte*, size_t>(
+ DER_NULL, sizeof(DER_NULL));
+ }
}
/*
diff --git a/src/asn1/der_enc.h b/src/asn1/der_enc.h
index f80c518b3..183e43b80 100644
--- a/src/asn1/der_enc.h
+++ b/src/asn1/der_enc.h
@@ -24,30 +24,44 @@ class BOTAN_DLL DER_Encoder
public:
SecureVector<byte> get_contents();
- DER_Encoder& start_cons(ASN1_Tag, ASN1_Tag = UNIVERSAL);
+ DER_Encoder& start_cons(ASN1_Tag type_tag,
+ ASN1_Tag class_tag = UNIVERSAL);
DER_Encoder& end_cons();
- DER_Encoder& start_explicit(u16bit);
+ DER_Encoder& start_explicit(u16bit type_tag);
DER_Encoder& end_explicit();
- DER_Encoder& raw_bytes(const byte[], size_t);
- DER_Encoder& raw_bytes(const MemoryRegion<byte>&);
+ DER_Encoder& raw_bytes(const byte val[], size_t len);
+ DER_Encoder& raw_bytes(const MemoryRegion<byte>& val);
DER_Encoder& encode_null();
- DER_Encoder& encode(bool);
- DER_Encoder& encode(size_t);
- DER_Encoder& encode(const BigInt&);
- DER_Encoder& encode(const MemoryRegion<byte>&, ASN1_Tag);
- DER_Encoder& encode(const byte[], size_t, ASN1_Tag);
-
- DER_Encoder& encode(bool, ASN1_Tag, ASN1_Tag = CONTEXT_SPECIFIC);
- DER_Encoder& encode(size_t, ASN1_Tag, ASN1_Tag = CONTEXT_SPECIFIC);
- DER_Encoder& encode(const BigInt&, ASN1_Tag,
- ASN1_Tag = CONTEXT_SPECIFIC);
- DER_Encoder& encode(const MemoryRegion<byte>&, ASN1_Tag,
- ASN1_Tag, ASN1_Tag = CONTEXT_SPECIFIC);
- DER_Encoder& encode(const byte[], size_t, ASN1_Tag,
- ASN1_Tag, ASN1_Tag = CONTEXT_SPECIFIC);
+ DER_Encoder& encode(bool b);
+ DER_Encoder& encode(size_t s);
+ DER_Encoder& encode(const BigInt& n);
+ DER_Encoder& encode(const MemoryRegion<byte>& v, ASN1_Tag real_type);
+ DER_Encoder& encode(const byte val[], size_t len, ASN1_Tag real_type);
+
+ DER_Encoder& encode(bool b,
+ ASN1_Tag type_tag,
+ ASN1_Tag class_tag = CONTEXT_SPECIFIC);
+
+ DER_Encoder& encode(size_t s,
+ ASN1_Tag type_tag,
+ ASN1_Tag class_tag = CONTEXT_SPECIFIC);
+
+ DER_Encoder& encode(const BigInt& n,
+ ASN1_Tag type_tag,
+ ASN1_Tag class_tag = CONTEXT_SPECIFIC);
+
+ DER_Encoder& encode(const MemoryRegion<byte>& v,
+ ASN1_Tag real_type,
+ ASN1_Tag type_tag,
+ ASN1_Tag class_tag = CONTEXT_SPECIFIC);
+
+ DER_Encoder& encode(const byte v[], size_t len,
+ ASN1_Tag real_type,
+ ASN1_Tag type_tag,
+ ASN1_Tag class_tag = CONTEXT_SPECIFIC);
template<typename T>
DER_Encoder& encode_optional(const T& value, const T& default_value)
@@ -65,13 +79,21 @@ class BOTAN_DLL DER_Encoder
return (*this);
}
- DER_Encoder& encode(const ASN1_Object&);
- DER_Encoder& encode_if(bool, DER_Encoder&);
+ DER_Encoder& encode(const ASN1_Object& obj);
+ DER_Encoder& encode_if(bool pred, DER_Encoder& enc);
+
+ DER_Encoder& add_object(ASN1_Tag type_tag, ASN1_Tag class_tag,
+ const byte rep[], size_t length);
+
+ DER_Encoder& add_object(ASN1_Tag type_tag, ASN1_Tag class_tag,
+ const MemoryRegion<byte>& rep);
+
+ DER_Encoder& add_object(ASN1_Tag type_tag, ASN1_Tag class_tag,
+ const std::string& str);
+
+ DER_Encoder& add_object(ASN1_Tag type_tag, ASN1_Tag class_tag,
+ byte val);
- DER_Encoder& add_object(ASN1_Tag, ASN1_Tag, const byte[], size_t);
- DER_Encoder& add_object(ASN1_Tag, ASN1_Tag, const MemoryRegion<byte>&);
- DER_Encoder& add_object(ASN1_Tag, ASN1_Tag, const std::string&);
- DER_Encoder& add_object(ASN1_Tag, ASN1_Tag, byte);
private:
class DER_Sequence
{
@@ -85,6 +107,7 @@ class BOTAN_DLL DER_Encoder
SecureVector<byte> contents;
std::vector< SecureVector<byte> > set_contents;
};
+
SecureVector<byte> contents;
std::vector<DER_Sequence> subsequences;
};
diff --git a/src/block/aes_intel/aes_intel.cpp b/src/block/aes_ni/aes_ni.cpp
index a2e660f2c..3ee0e608c 100644
--- a/src/block/aes_intel/aes_intel.cpp
+++ b/src/block/aes_ni/aes_ni.cpp
@@ -1,11 +1,11 @@
/*
-* AES using Intel's AES-NI instructions
+* AES using AES-NI instructions
* (C) 2009 Jack Lloyd
*
* Distributed under the terms of the Botan license
*/
-#include <botan/aes_intel.h>
+#include <botan/aes_ni.h>
#include <botan/loadstor.h>
#include <wmmintrin.h>
@@ -103,7 +103,7 @@ __m128i aes_256_key_expansion(__m128i key, __m128i key2)
/*
* AES-128 Encryption
*/
-void AES_128_Intel::encrypt_n(const byte in[], byte out[], size_t blocks) const
+void AES_128_NI::encrypt_n(const byte in[], byte out[], size_t blocks) const
{
const __m128i* in_mm = (const __m128i*)in;
__m128i* out_mm = (__m128i*)out;
@@ -179,7 +179,7 @@ void AES_128_Intel::encrypt_n(const byte in[], byte out[], size_t blocks) const
/*
* AES-128 Decryption
*/
-void AES_128_Intel::decrypt_n(const byte in[], byte out[], size_t blocks) const
+void AES_128_NI::decrypt_n(const byte in[], byte out[], size_t blocks) const
{
const __m128i* in_mm = (const __m128i*)in;
__m128i* out_mm = (__m128i*)out;
@@ -255,7 +255,7 @@ void AES_128_Intel::decrypt_n(const byte in[], byte out[], size_t blocks) const
/*
* AES-128 Key Schedule
*/
-void AES_128_Intel::key_schedule(const byte key[], size_t)
+void AES_128_NI::key_schedule(const byte key[], size_t)
{
#define AES_128_key_exp(K, RCON) \
aes_128_key_expansion(K, _mm_aeskeygenassist_si128(K, RCON))
@@ -304,7 +304,7 @@ void AES_128_Intel::key_schedule(const byte key[], size_t)
/*
* Clear memory of sensitive data
*/
-void AES_128_Intel::clear()
+void AES_128_NI::clear()
{
zeroise(EK);
zeroise(DK);
@@ -313,7 +313,7 @@ void AES_128_Intel::clear()
/*
* AES-192 Encryption
*/
-void AES_192_Intel::encrypt_n(const byte in[], byte out[], size_t blocks) const
+void AES_192_NI::encrypt_n(const byte in[], byte out[], size_t blocks) const
{
const __m128i* in_mm = (const __m128i*)in;
__m128i* out_mm = (__m128i*)out;
@@ -395,7 +395,7 @@ void AES_192_Intel::encrypt_n(const byte in[], byte out[], size_t blocks) const
/*
* AES-192 Decryption
*/
-void AES_192_Intel::decrypt_n(const byte in[], byte out[], size_t blocks) const
+void AES_192_NI::decrypt_n(const byte in[], byte out[], size_t blocks) const
{
const __m128i* in_mm = (const __m128i*)in;
__m128i* out_mm = (__m128i*)out;
@@ -477,7 +477,7 @@ void AES_192_Intel::decrypt_n(const byte in[], byte out[], size_t blocks) const
/*
* AES-192 Key Schedule
*/
-void AES_192_Intel::key_schedule(const byte key[], size_t)
+void AES_192_NI::key_schedule(const byte key[], size_t)
{
__m128i K0 = _mm_loadu_si128((const __m128i*)(key));
__m128i K1 = _mm_loadu_si128((const __m128i*)(key + 8));
@@ -520,7 +520,7 @@ void AES_192_Intel::key_schedule(const byte key[], size_t)
/*
* Clear memory of sensitive data
*/
-void AES_192_Intel::clear()
+void AES_192_NI::clear()
{
zeroise(EK);
zeroise(DK);
@@ -529,7 +529,7 @@ void AES_192_Intel::clear()
/*
* AES-256 Encryption
*/
-void AES_256_Intel::encrypt_n(const byte in[], byte out[], size_t blocks) const
+void AES_256_NI::encrypt_n(const byte in[], byte out[], size_t blocks) const
{
const __m128i* in_mm = (const __m128i*)in;
__m128i* out_mm = (__m128i*)out;
@@ -617,7 +617,7 @@ void AES_256_Intel::encrypt_n(const byte in[], byte out[], size_t blocks) const
/*
* AES-256 Decryption
*/
-void AES_256_Intel::decrypt_n(const byte in[], byte out[], size_t blocks) const
+void AES_256_NI::decrypt_n(const byte in[], byte out[], size_t blocks) const
{
const __m128i* in_mm = (const __m128i*)in;
__m128i* out_mm = (__m128i*)out;
@@ -705,7 +705,7 @@ void AES_256_Intel::decrypt_n(const byte in[], byte out[], size_t blocks) const
/*
* AES-256 Key Schedule
*/
-void AES_256_Intel::key_schedule(const byte key[], size_t)
+void AES_256_NI::key_schedule(const byte key[], size_t)
{
__m128i K0 = _mm_loadu_si128((const __m128i*)(key));
__m128i K1 = _mm_loadu_si128((const __m128i*)(key + 16));
@@ -770,7 +770,7 @@ void AES_256_Intel::key_schedule(const byte key[], size_t)
/*
* Clear memory of sensitive data
*/
-void AES_256_Intel::clear()
+void AES_256_NI::clear()
{
zeroise(EK);
zeroise(DK);
diff --git a/src/block/aes_intel/aes_intel.h b/src/block/aes_ni/aes_ni.h
index a8e6b53e8..ae9e5b3f4 100644
--- a/src/block/aes_intel/aes_intel.h
+++ b/src/block/aes_ni/aes_ni.h
@@ -1,12 +1,12 @@
/*
-* AES using Intel's AES-NI instructions
+* AES using AES-NI instructions
* (C) 2009 Jack Lloyd
*
* Distributed under the terms of the Botan license
*/
-#ifndef BOTAN_AES_INTEL_H__
-#define BOTAN_AES_INTEL_H__
+#ifndef BOTAN_AES_NI_H__
+#define BOTAN_AES_NI_H__
#include <botan/block_cipher.h>
@@ -15,7 +15,7 @@ namespace Botan {
/**
* AES-128 using AES-NI
*/
-class BOTAN_DLL AES_128_Intel : public Block_Cipher_Fixed_Params<16, 16>
+class BOTAN_DLL AES_128_NI : public Block_Cipher_Fixed_Params<16, 16>
{
public:
size_t parallelism() const { return 4; }
@@ -25,9 +25,9 @@ class BOTAN_DLL AES_128_Intel : public Block_Cipher_Fixed_Params<16, 16>
void clear();
std::string name() const { return "AES-128"; }
- BlockCipher* clone() const { return new AES_128_Intel; }
+ BlockCipher* clone() const { return new AES_128_NI; }
- AES_128_Intel() : EK(44), DK(44) { }
+ AES_128_NI() : EK(44), DK(44) { }
private:
void key_schedule(const byte[], size_t);
@@ -37,7 +37,7 @@ class BOTAN_DLL AES_128_Intel : public Block_Cipher_Fixed_Params<16, 16>
/**
* AES-192 using AES-NI
*/
-class BOTAN_DLL AES_192_Intel : public Block_Cipher_Fixed_Params<16, 24>
+class BOTAN_DLL AES_192_NI : public Block_Cipher_Fixed_Params<16, 24>
{
public:
size_t parallelism() const { return 4; }
@@ -47,9 +47,9 @@ class BOTAN_DLL AES_192_Intel : public Block_Cipher_Fixed_Params<16, 24>
void clear();
std::string name() const { return "AES-192"; }
- BlockCipher* clone() const { return new AES_192_Intel; }
+ BlockCipher* clone() const { return new AES_192_NI; }
- AES_192_Intel() : EK(52), DK(52) { }
+ AES_192_NI() : EK(52), DK(52) { }
private:
void key_schedule(const byte[], size_t);
@@ -59,7 +59,7 @@ class BOTAN_DLL AES_192_Intel : public Block_Cipher_Fixed_Params<16, 24>
/**
* AES-256 using AES-NI
*/
-class BOTAN_DLL AES_256_Intel : public Block_Cipher_Fixed_Params<16, 32>
+class BOTAN_DLL AES_256_NI : public Block_Cipher_Fixed_Params<16, 32>
{
public:
size_t parallelism() const { return 4; }
@@ -69,9 +69,9 @@ class BOTAN_DLL AES_256_Intel : public Block_Cipher_Fixed_Params<16, 32>
void clear();
std::string name() const { return "AES-256"; }
- BlockCipher* clone() const { return new AES_256_Intel; }
+ BlockCipher* clone() const { return new AES_256_NI; }
- AES_256_Intel() : EK(60), DK(60) { }
+ AES_256_NI() : EK(60), DK(60) { }
private:
void key_schedule(const byte[], size_t);
diff --git a/src/block/aes_intel/info.txt b/src/block/aes_ni/info.txt
index 8bf0f07ee..597948fc3 100644
--- a/src/block/aes_intel/info.txt
+++ b/src/block/aes_ni/info.txt
@@ -1,4 +1,4 @@
-define AES_INTEL
+define AES_NI
load_on auto
diff --git a/src/block/camellia/camellia.cpp b/src/block/camellia/camellia.cpp
new file mode 100644
index 000000000..054558c35
--- /dev/null
+++ b/src/block/camellia/camellia.cpp
@@ -0,0 +1,311 @@
+/*
+* Camellia
+* (C) 2012 Jack Lloyd
+*
+* Distributed under the terms of the Botan license
+*/
+
+#include <botan/camellia.h>
+#include <botan/loadstor.h>
+
+namespace Botan {
+
+namespace Camellia_F {
+
+u64bit F(u64bit v, u64bit K)
+ {
+ static const byte SBOX[256] = {
+ 0x70, 0x82, 0x2C, 0xEC, 0xB3, 0x27, 0xC0, 0xE5, 0xE4, 0x85, 0x57,
+ 0x35, 0xEA, 0x0C, 0xAE, 0x41, 0x23, 0xEF, 0x6B, 0x93, 0x45, 0x19,
+ 0xA5, 0x21, 0xED, 0x0E, 0x4F, 0x4E, 0x1D, 0x65, 0x92, 0xBD, 0x86,
+ 0xB8, 0xAF, 0x8F, 0x7C, 0xEB, 0x1F, 0xCE, 0x3E, 0x30, 0xDC, 0x5F,
+ 0x5E, 0xC5, 0x0B, 0x1A, 0xA6, 0xE1, 0x39, 0xCA, 0xD5, 0x47, 0x5D,
+ 0x3D, 0xD9, 0x01, 0x5A, 0xD6, 0x51, 0x56, 0x6C, 0x4D, 0x8B, 0x0D,
+ 0x9A, 0x66, 0xFB, 0xCC, 0xB0, 0x2D, 0x74, 0x12, 0x2B, 0x20, 0xF0,
+ 0xB1, 0x84, 0x99, 0xDF, 0x4C, 0xCB, 0xC2, 0x34, 0x7E, 0x76, 0x05,
+ 0x6D, 0xB7, 0xA9, 0x31, 0xD1, 0x17, 0x04, 0xD7, 0x14, 0x58, 0x3A,
+ 0x61, 0xDE, 0x1B, 0x11, 0x1C, 0x32, 0x0F, 0x9C, 0x16, 0x53, 0x18,
+ 0xF2, 0x22, 0xFE, 0x44, 0xCF, 0xB2, 0xC3, 0xB5, 0x7A, 0x91, 0x24,
+ 0x08, 0xE8, 0xA8, 0x60, 0xFC, 0x69, 0x50, 0xAA, 0xD0, 0xA0, 0x7D,
+ 0xA1, 0x89, 0x62, 0x97, 0x54, 0x5B, 0x1E, 0x95, 0xE0, 0xFF, 0x64,
+ 0xD2, 0x10, 0xC4, 0x00, 0x48, 0xA3, 0xF7, 0x75, 0xDB, 0x8A, 0x03,
+ 0xE6, 0xDA, 0x09, 0x3F, 0xDD, 0x94, 0x87, 0x5C, 0x83, 0x02, 0xCD,
+ 0x4A, 0x90, 0x33, 0x73, 0x67, 0xF6, 0xF3, 0x9D, 0x7F, 0xBF, 0xE2,
+ 0x52, 0x9B, 0xD8, 0x26, 0xC8, 0x37, 0xC6, 0x3B, 0x81, 0x96, 0x6F,
+ 0x4B, 0x13, 0xBE, 0x63, 0x2E, 0xE9, 0x79, 0xA7, 0x8C, 0x9F, 0x6E,
+ 0xBC, 0x8E, 0x29, 0xF5, 0xF9, 0xB6, 0x2F, 0xFD, 0xB4, 0x59, 0x78,
+ 0x98, 0x06, 0x6A, 0xE7, 0x46, 0x71, 0xBA, 0xD4, 0x25, 0xAB, 0x42,
+ 0x88, 0xA2, 0x8D, 0xFA, 0x72, 0x07, 0xB9, 0x55, 0xF8, 0xEE, 0xAC,
+ 0x0A, 0x36, 0x49, 0x2A, 0x68, 0x3C, 0x38, 0xF1, 0xA4, 0x40, 0x28,
+ 0xD3, 0x7B, 0xBB, 0xC9, 0x43, 0xC1, 0x15, 0xE3, 0xAD, 0xF4, 0x77,
+ 0xC7, 0x80, 0x9E };
+
+ const u64bit x = v ^ K;
+
+ const byte t1 = SBOX[get_byte(0, x)];
+ const byte t2 = rotate_left(SBOX[get_byte(1, x)], 1);
+ const byte t3 = rotate_left(SBOX[get_byte(2, x)], 7);
+ const byte t4 = SBOX[rotate_left(get_byte(3, x), 1)];
+ const byte t5 = rotate_left(SBOX[get_byte(4, x)], 1);
+ const byte t6 = rotate_left(SBOX[get_byte(5, x)], 7);
+ const byte t7 = SBOX[rotate_left(get_byte(6, x), 1)];
+ const byte t8 = SBOX[get_byte(7, x)];
+
+ const byte y1 = t1 ^ t3 ^ t4 ^ t6 ^ t7 ^ t8;
+ const byte y2 = t1 ^ t2 ^ t4 ^ t5 ^ t7 ^ t8;
+ const byte y3 = t1 ^ t2 ^ t3 ^ t5 ^ t6 ^ t8;
+ const byte y4 = t2 ^ t3 ^ t4 ^ t5 ^ t6 ^ t7;
+ const byte y5 = t1 ^ t2 ^ t6 ^ t7 ^ t8;
+ const byte y6 = t2 ^ t3 ^ t5 ^ t7 ^ t8;
+ const byte y7 = t3 ^ t4 ^ t5 ^ t6 ^ t8;
+ const byte y8 = t1 ^ t4 ^ t5 ^ t6 ^ t7;
+
+ return make_u64bit(y1, y2, y3, y4, y5, y6, y7, y8);
+ }
+
+u64bit FL(u64bit v, u64bit K)
+ {
+ u32bit x1 = (v >> 32);
+ u32bit x2 = (v & 0xFFFFFFFF);
+
+ const u32bit k1 = (K >> 32);
+ const u32bit k2 = (K & 0xFFFFFFFF);
+
+ x2 ^= rotate_left(x1 & k1, 1);
+ x1 ^= (x2 | k2);
+
+ return ((static_cast<u64bit>(x1) << 32) | x2);
+ }
+
+u64bit FLINV(u64bit v, u64bit K)
+ {
+ u32bit x1 = (v >> 32);
+ u32bit x2 = (v & 0xFFFFFFFF);
+
+ const u32bit k1 = (K >> 32);
+ const u32bit k2 = (K & 0xFFFFFFFF);
+
+ x1 ^= (x2 | k2);
+ x2 ^= rotate_left(x1 & k1, 1);
+
+ return ((static_cast<u64bit>(x1) << 32) | x2);
+ }
+
+u64bit left_rot_hi(u64bit h, u64bit l, size_t shift)
+ {
+ return (h << shift) | ((l >> (64-shift)));
+ }
+
+u64bit left_rot_lo(u64bit h, u64bit l, size_t shift)
+ {
+ return (h >> (64-shift)) | (l << shift);
+ }
+
+}
+
+/*
+* Camellia Encryption
+*/
+void Camellia::encrypt_n(const byte in[], byte out[], size_t blocks) const
+ {
+ using namespace Camellia_F;
+
+ for(size_t i = 0; i != blocks; ++i)
+ {
+ u64bit D1 = load_be<u64bit>(in, 0);
+ u64bit D2 = load_be<u64bit>(in, 1);
+
+ const u64bit* K = &SK[0];
+
+ D1 ^= *K++;
+ D2 ^= *K++;
+
+ while(true)
+ {
+ D2 ^= F(D1, *K++);
+ D1 ^= F(D2, *K++);
+ D2 ^= F(D1, *K++);
+ D1 ^= F(D2, *K++);
+ D2 ^= F(D1, *K++);
+ D1 ^= F(D2, *K++);
+
+ if(K == &SK[SK.size()-2])
+ break;
+
+ D1 = FL (D1, *K++);
+ D2 = FLINV(D2, *K++);
+ }
+
+ D2 ^= *K++;
+ D1 ^= *K++;
+
+ store_be(out, D2, D1);
+
+ in += BLOCK_SIZE;
+ out += BLOCK_SIZE;
+ }
+ }
+
+/*
+* Camellia Decryption
+*/
+void Camellia::decrypt_n(const byte in[], byte out[], size_t blocks) const
+ {
+ using namespace Camellia_F;
+
+ for(size_t i = 0; i != blocks; ++i)
+ {
+ u64bit D1 = load_be<u64bit>(in, 0);
+ u64bit D2 = load_be<u64bit>(in, 1);
+
+ const u64bit* K = &SK[SK.size()-1];
+
+ D2 ^= *K--;
+ D1 ^= *K--;
+
+ while(true)
+ {
+ D2 ^= F(D1, *K--);
+ D1 ^= F(D2, *K--);
+ D2 ^= F(D1, *K--);
+ D1 ^= F(D2, *K--);
+ D2 ^= F(D1, *K--);
+ D1 ^= F(D2, *K--);
+
+ if(K == &SK[1])
+ break;
+
+ D1 = FL (D1, *K--);
+ D2 = FLINV(D2, *K--);
+ }
+
+ D1 ^= *K--;
+ D2 ^= *K;
+
+ store_be(out, D2, D1);
+
+ in += BLOCK_SIZE;
+ out += BLOCK_SIZE;
+ }
+ }
+
+/*
+* Camellia Key Schedule
+*/
+void Camellia::key_schedule(const byte key[], size_t length)
+ {
+ using namespace Camellia_F;
+
+ const u64bit Sigma1 = 0xA09E667F3BCC908B;
+ const u64bit Sigma2 = 0xB67AE8584CAA73B2;
+ const u64bit Sigma3 = 0xC6EF372FE94F82BE;
+ const u64bit Sigma4 = 0x54FF53A5F1D36F1C;
+ const u64bit Sigma5 = 0x10E527FADE682D1D;
+ const u64bit Sigma6 = 0xB05688C2B3E6C1FD;
+
+ const u64bit KL_H = load_be<u64bit>(key, 0);
+ const u64bit KL_L = load_be<u64bit>(key, 1);
+
+ const u64bit KR_H = (length >= 24) ? load_be<u64bit>(key, 2) : 0;
+ const u64bit KR_L =
+ (length == 32) ? load_be<u64bit>(key, 3) : ((length == 24) ? ~KR_H : 0);
+
+ u64bit D1 = KL_H ^ KR_H;
+ u64bit D2 = KL_L ^ KR_L;
+ D2 ^= F(D1, Sigma1);
+ D1 ^= F(D2, Sigma2);
+ D1 ^= KL_H;
+ D2 ^= KL_L;
+ D2 ^= F(D1, Sigma3);
+ D1 ^= F(D2, Sigma4);
+
+ const u64bit KA_H = D1;
+ const u64bit KA_L = D2;
+
+ D1 = KA_H ^ KR_H;
+ D2 = KA_L ^ KR_L;
+ D2 ^= F(D1, Sigma5);
+ D1 ^= F(D2, Sigma6);
+
+ const u64bit KB_H = D1;
+ const u64bit KB_L = D2;
+
+ if(length == 16)
+ {
+ SK.resize(26);
+
+ SK[ 0] = KL_H;
+ SK[ 1] = KL_L;
+ SK[ 2] = KA_H;
+ SK[ 3] = KA_L;
+ SK[ 4] = left_rot_hi(KL_H, KL_L, 15);
+ SK[ 5] = left_rot_lo(KL_H, KL_L, 15);
+ SK[ 6] = left_rot_hi(KA_H, KA_L, 15);
+ SK[ 7] = left_rot_lo(KA_H, KA_L, 15);
+ SK[ 8] = left_rot_hi(KA_H, KA_L, 30);
+ SK[ 9] = left_rot_lo(KA_H, KA_L, 30);
+ SK[10] = left_rot_hi(KL_H, KL_L, 45);
+ SK[11] = left_rot_lo(KL_H, KL_L, 45);
+ SK[12] = left_rot_hi(KA_H, KA_L, 45);
+ SK[13] = left_rot_lo(KL_H, KL_L, 60);
+ SK[14] = left_rot_hi(KA_H, KA_L, 60);
+ SK[15] = left_rot_lo(KA_H, KA_L, 60);
+ SK[16] = left_rot_lo(KL_H, KL_L, 77-64);
+ SK[17] = left_rot_hi(KL_H, KL_L, 77-64);
+ SK[18] = left_rot_lo(KL_H, KL_L, 94-64);
+ SK[19] = left_rot_hi(KL_H, KL_L, 94-64);
+ SK[20] = left_rot_lo(KA_H, KA_L, 94-64);
+ SK[21] = left_rot_hi(KA_H, KA_L, 94-64);
+ SK[22] = left_rot_lo(KL_H, KL_L, 111-64);
+ SK[23] = left_rot_hi(KL_H, KL_L, 111-64);
+ SK[24] = left_rot_lo(KA_H, KA_L, 111-64);
+ SK[25] = left_rot_hi(KA_H, KA_L, 111-64);
+ }
+ else
+ {
+ SK.resize(34);
+
+ SK[ 0] = KL_H;
+ SK[ 1] = KL_L;
+ SK[ 2] = KB_H;
+ SK[ 3] = KB_L;
+
+ SK[ 4] = left_rot_hi(KR_H, KR_L, 15);
+ SK[ 5] = left_rot_lo(KR_H, KR_L, 15);
+ SK[ 6] = left_rot_hi(KA_H, KA_L, 15);
+ SK[ 7] = left_rot_lo(KA_H, KA_L, 15);
+
+ SK[ 8] = left_rot_hi(KR_H, KR_L, 30);
+ SK[ 9] = left_rot_lo(KR_H, KR_L, 30);
+ SK[10] = left_rot_hi(KB_H, KB_L, 30);
+ SK[11] = left_rot_lo(KB_H, KB_L, 30);
+
+ SK[12] = left_rot_hi(KL_H, KL_L, 45);
+ SK[13] = left_rot_lo(KL_H, KL_L, 45);
+ SK[14] = left_rot_hi(KA_H, KA_L, 45);
+ SK[15] = left_rot_lo(KA_H, KA_L, 45);
+
+ SK[16] = left_rot_hi(KL_H, KL_L, 60);
+ SK[17] = left_rot_lo(KL_H, KL_L, 60);
+ SK[18] = left_rot_hi(KR_H, KR_L, 60);
+ SK[19] = left_rot_lo(KR_H, KR_L, 60);
+ SK[20] = left_rot_hi(KB_H, KB_L, 60);
+ SK[21] = left_rot_lo(KB_H, KB_L, 60);
+
+ SK[22] = left_rot_lo(KL_H, KL_L, 77-64);
+ SK[23] = left_rot_hi(KL_H, KL_L, 77-64);
+ SK[24] = left_rot_lo(KA_H, KA_L, 77-64);
+ SK[25] = left_rot_hi(KA_H, KA_L, 77-64);
+
+ SK[26] = left_rot_lo(KR_H, KR_L, 94-64);
+ SK[27] = left_rot_hi(KR_H, KR_L, 94-64);
+ SK[28] = left_rot_lo(KA_H, KA_L, 94-64);
+ SK[29] = left_rot_hi(KA_H, KA_L, 94-64);
+ SK[30] = left_rot_lo(KL_H, KL_L, 111-64);
+ SK[31] = left_rot_hi(KL_H, KL_L, 111-64);
+ SK[32] = left_rot_lo(KB_H, KB_L, 111-64);
+ SK[33] = left_rot_hi(KB_H, KB_L, 111-64);
+ }
+ }
+
+}
diff --git a/src/block/camellia/camellia.h b/src/block/camellia/camellia.h
new file mode 100644
index 000000000..aaf3ad9e3
--- /dev/null
+++ b/src/block/camellia/camellia.h
@@ -0,0 +1,35 @@
+/*
+* Camellia
+* (C) 2012 Jack Lloyd
+*
+* Distributed under the terms of the Botan license
+*/
+
+#ifndef BOTAN_CAMELLIA_H__
+#define BOTAN_CAMELLIA_H__
+
+#include <botan/block_cipher.h>
+
+namespace Botan {
+
+/**
+* Camellia
+*/
+class BOTAN_DLL Camellia : public Block_Cipher_Fixed_Params<16, 16, 32, 8>
+ {
+ public:
+ void encrypt_n(const byte in[], byte out[], size_t blocks) const;
+ void decrypt_n(const byte in[], byte out[], size_t blocks) const;
+
+ void clear() { SK.clear(); }
+ std::string name() const { return "Camellia"; }
+ BlockCipher* clone() const { return new Camellia; }
+ private:
+ void key_schedule(const byte key[], size_t length);
+
+ SecureVector<u64bit> SK;
+ };
+
+}
+
+#endif
diff --git a/src/block/camellia/info.txt b/src/block/camellia/info.txt
new file mode 100644
index 000000000..cdb7b3d25
--- /dev/null
+++ b/src/block/camellia/info.txt
@@ -0,0 +1 @@
+define CAMELLIA
diff --git a/src/block/gost_28147/gost_28147.cpp b/src/block/gost_28147/gost_28147.cpp
index 07f3359cd..d4a9faa40 100644
--- a/src/block/gost_28147/gost_28147.cpp
+++ b/src/block/gost_28147/gost_28147.cpp
@@ -1,6 +1,6 @@
/*
* GOST 28147-89
-* (C) 1999-2009 Jack Lloyd
+* (C) 1999-2009,2011 Jack Lloyd
*
* Distributed under the terms of the Botan license
*/
@@ -58,12 +58,31 @@ GOST_28147_89::GOST_28147_89(const GOST_28147_89_Params& param) :
for(size_t i = 0; i != 4; ++i)
for(size_t j = 0; j != 256; ++j)
{
- u32bit T = (param.sbox_entry(2*i , j % 16)) |
- (param.sbox_entry(2*i+1, j / 16) << 4);
+ const u32bit T = (param.sbox_entry(2*i , j % 16)) |
+ (param.sbox_entry(2*i+1, j / 16) << 4);
SBOX[256*i+j] = rotate_left(T, (11+8*i) % 32);
}
}
+std::string GOST_28147_89::name() const
+ {
+ /*
+ 'Guess' the right name for the sbox on the basis of the values.
+ This would need to be updated if support for other sbox parameters
+ is added. Preferably, we would just store the string value in the
+ constructor, but can't break binary compat.
+ */
+ std::string sbox_name = "";
+ if(SBOX[0] == 0x00072000)
+ sbox_name = "R3411_94_TestParam";
+ else if(SBOX[0] == 0x0002D000)
+ sbox_name = "R3411_CryptoPro";
+ else
+ throw Internal_Error("GOST-28147 unrecognized sbox value");
+
+ return "GOST-28147-89(" + sbox_name + ")";
+ }
+
/*
* Two rounds of GOST
*/
diff --git a/src/block/gost_28147/gost_28147.h b/src/block/gost_28147/gost_28147.h
index 75ba74c44..bc26da774 100644
--- a/src/block/gost_28147/gost_28147.h
+++ b/src/block/gost_28147/gost_28147.h
@@ -57,7 +57,7 @@ class BOTAN_DLL GOST_28147_89 : public Block_Cipher_Fixed_Params<8, 32>
void clear() { zeroise(EK); }
- std::string name() const { return "GOST-28147-89"; }
+ std::string name() const;
BlockCipher* clone() const { return new GOST_28147_89(SBOX); }
/**
diff --git a/src/block/idea_sse2/idea_sse2.cpp b/src/block/idea_sse2/idea_sse2.cpp
index b92f51ac3..70698560d 100644
--- a/src/block/idea_sse2/idea_sse2.cpp
+++ b/src/block/idea_sse2/idea_sse2.cpp
@@ -16,7 +16,6 @@ inline __m128i mul(__m128i X, u16bit K_16)
{
const __m128i zeros = _mm_set1_epi16(0);
const __m128i ones = _mm_set1_epi16(1);
- const __m128i high_bit = _mm_set1_epi16(-32767); // 0x8000
const __m128i K = _mm_set1_epi16(K_16);
@@ -29,10 +28,9 @@ inline __m128i mul(__m128i X, u16bit K_16)
__m128i T = _mm_sub_epi16(mul_lo, mul_hi);
// Unsigned compare; cmp = 1 if mul_lo < mul_hi else 0
- const __m128i cmp = _mm_srli_epi16(_mm_cmpgt_epi16(
- _mm_add_epi16(mul_hi, high_bit),
- _mm_add_epi16(mul_lo, high_bit)),
- 15);
+ const __m128i subs = _mm_subs_epu16(mul_hi, mul_lo);
+ const __m128i cmp = _mm_min_epu8(
+ _mm_or_si128(subs, _mm_srli_epi16(subs, 8)), ones);
T = _mm_add_epi16(T, cmp);
diff --git a/src/block/noekeon_simd/info.txt b/src/block/noekeon_simd/info.txt
index b73954cff..deac80702 100644
--- a/src/block/noekeon_simd/info.txt
+++ b/src/block/noekeon_simd/info.txt
@@ -2,6 +2,6 @@ define NOEKEON_SIMD
<requires>
noekeon
-simd_32
+simd
simd_engine
</requires>
diff --git a/src/block/serpent_simd/info.txt b/src/block/serpent_simd/info.txt
index b3bf34972..cd1a0dc7e 100644
--- a/src/block/serpent_simd/info.txt
+++ b/src/block/serpent_simd/info.txt
@@ -2,7 +2,7 @@ define SERPENT_SIMD
<requires>
serpent
-simd_32
+simd
simd_engine
</requires>
@@ -13,7 +13,3 @@ serp_simd.cpp
<header:public>
serp_simd.h
</header:public>
-
-<header:internal>
-serp_simd_sbox.h
-</header:internal>
diff --git a/src/block/serpent_simd/serp_simd.cpp b/src/block/serpent_simd/serp_simd.cpp
index babe68d40..2b5e429fc 100644
--- a/src/block/serpent_simd/serp_simd.cpp
+++ b/src/block/serpent_simd/serp_simd.cpp
@@ -6,7 +6,6 @@
*/
#include <botan/serp_simd.h>
-#include <botan/internal/serp_simd_sbox.h>
#include <botan/internal/simd_32.h>
#include <botan/loadstor.h>
@@ -14,6 +13,420 @@ namespace Botan {
namespace {
+#define SBoxE1(B0, B1, B2, B3) \
+ do { \
+ B3 ^= B0; \
+ SIMD_32 B4 = B1; \
+ B1 &= B3; \
+ B4 ^= B2; \
+ B1 ^= B0; \
+ B0 |= B3; \
+ B0 ^= B4; \
+ B4 ^= B3; \
+ B3 ^= B2; \
+ B2 |= B1; \
+ B2 ^= B4; \
+ B4 = ~B4; \
+ B4 |= B1; \
+ B1 ^= B3; \
+ B1 ^= B4; \
+ B3 |= B0; \
+ B1 ^= B3; \
+ B4 ^= B3; \
+ B3 = B0; \
+ B0 = B1; \
+ B1 = B4; \
+ } while(0);
+
+#define SBoxE2(B0, B1, B2, B3) \
+ do { \
+ B0 = ~B0; \
+ B2 = ~B2; \
+ SIMD_32 B4 = B0; \
+ B0 &= B1; \
+ B2 ^= B0; \
+ B0 |= B3; \
+ B3 ^= B2; \
+ B1 ^= B0; \
+ B0 ^= B4; \
+ B4 |= B1; \
+ B1 ^= B3; \
+ B2 |= B0; \
+ B2 &= B4; \
+ B0 ^= B1; \
+ B1 &= B2; \
+ B1 ^= B0; \
+ B0 &= B2; \
+ B4 ^= B0; \
+ B0 = B2; \
+ B2 = B3; \
+ B3 = B1; \
+ B1 = B4; \
+ } while(0);
+
+#define SBoxE3(B0, B1, B2, B3) \
+ do { \
+ SIMD_32 B4 = B0; \
+ B0 &= B2; \
+ B0 ^= B3; \
+ B2 ^= B1; \
+ B2 ^= B0; \
+ B3 |= B4; \
+ B3 ^= B1; \
+ B4 ^= B2; \
+ B1 = B3; \
+ B3 |= B4; \
+ B3 ^= B0; \
+ B0 &= B1; \
+ B4 ^= B0; \
+ B1 ^= B3; \
+ B1 ^= B4; \
+ B0 = B2; \
+ B2 = B1; \
+ B1 = B3; \
+ B3 = ~B4; \
+ } while(0);
+
+#define SBoxE4(B0, B1, B2, B3) \
+ do { \
+ SIMD_32 B4 = B0; \
+ B0 |= B3; \
+ B3 ^= B1; \
+ B1 &= B4; \
+ B4 ^= B2; \
+ B2 ^= B3; \
+ B3 &= B0; \
+ B4 |= B1; \
+ B3 ^= B4; \
+ B0 ^= B1; \
+ B4 &= B0; \
+ B1 ^= B3; \
+ B4 ^= B2; \
+ B1 |= B0; \
+ B1 ^= B2; \
+ B0 ^= B3; \
+ B2 = B1; \
+ B1 |= B3; \
+ B0 ^= B1; \
+ B1 = B2; \
+ B2 = B3; \
+ B3 = B4; \
+ } while(0);
+
+#define SBoxE5(B0, B1, B2, B3) \
+ do { \
+ B1 ^= B3; \
+ B3 = ~B3; \
+ B2 ^= B3; \
+ B3 ^= B0; \
+ SIMD_32 B4 = B1; \
+ B1 &= B3; \
+ B1 ^= B2; \
+ B4 ^= B3; \
+ B0 ^= B4; \
+ B2 &= B4; \
+ B2 ^= B0; \
+ B0 &= B1; \
+ B3 ^= B0; \
+ B4 |= B1; \
+ B4 ^= B0; \
+ B0 |= B3; \
+ B0 ^= B2; \
+ B2 &= B3; \
+ B0 = ~B0; \
+ B4 ^= B2; \
+ B2 = B0; \
+ B0 = B1; \
+ B1 = B4; \
+ } while(0);
+
+#define SBoxE6(B0, B1, B2, B3) \
+ do { \
+ B0 ^= B1; \
+ B1 ^= B3; \
+ B3 = ~B3; \
+ SIMD_32 B4 = B1; \
+ B1 &= B0; \
+ B2 ^= B3; \
+ B1 ^= B2; \
+ B2 |= B4; \
+ B4 ^= B3; \
+ B3 &= B1; \
+ B3 ^= B0; \
+ B4 ^= B1; \
+ B4 ^= B2; \
+ B2 ^= B0; \
+ B0 &= B3; \
+ B2 = ~B2; \
+ B0 ^= B4; \
+ B4 |= B3; \
+ B4 ^= B2; \
+ B2 = B0; \
+ B0 = B1; \
+ B1 = B3; \
+ B3 = B4; \
+ } while(0);
+
+#define SBoxE7(B0, B1, B2, B3) \
+ do { \
+ B2 = ~B2; \
+ SIMD_32 B4 = B3; \
+ B3 &= B0; \
+ B0 ^= B4; \
+ B3 ^= B2; \
+ B2 |= B4; \
+ B1 ^= B3; \
+ B2 ^= B0; \
+ B0 |= B1; \
+ B2 ^= B1; \
+ B4 ^= B0; \
+ B0 |= B3; \
+ B0 ^= B2; \
+ B4 ^= B3; \
+ B4 ^= B0; \
+ B3 = ~B3; \
+ B2 &= B4; \
+ B3 ^= B2; \
+ B2 = B4; \
+ } while(0);
+
+#define SBoxE8(B0, B1, B2, B3) \
+ do { \
+ SIMD_32 B4 = B1; \
+ B1 |= B2; \
+ B1 ^= B3; \
+ B4 ^= B2; \
+ B2 ^= B1; \
+ B3 |= B4; \
+ B3 &= B0; \
+ B4 ^= B2; \
+ B3 ^= B1; \
+ B1 |= B4; \
+ B1 ^= B0; \
+ B0 |= B4; \
+ B0 ^= B2; \
+ B1 ^= B4; \
+ B2 ^= B1; \
+ B1 &= B0; \
+ B1 ^= B4; \
+ B2 = ~B2; \
+ B2 |= B0; \
+ B4 ^= B2; \
+ B2 = B1; \
+ B1 = B3; \
+ B3 = B0; \
+ B0 = B4; \
+ } while(0);
+
+#define SBoxD1(B0, B1, B2, B3) \
+ do { \
+ B2 = ~B2; \
+ SIMD_32 B4 = B1; \
+ B1 |= B0; \
+ B4 = ~B4; \
+ B1 ^= B2; \
+ B2 |= B4; \
+ B1 ^= B3; \
+ B0 ^= B4; \
+ B2 ^= B0; \
+ B0 &= B3; \
+ B4 ^= B0; \
+ B0 |= B1; \
+ B0 ^= B2; \
+ B3 ^= B4; \
+ B2 ^= B1; \
+ B3 ^= B0; \
+ B3 ^= B1; \
+ B2 &= B3; \
+ B4 ^= B2; \
+ B2 = B1; \
+ B1 = B4; \
+ } while(0);
+
+#define SBoxD2(B0, B1, B2, B3) \
+ do { \
+ SIMD_32 B4 = B1; \
+ B1 ^= B3; \
+ B3 &= B1; \
+ B4 ^= B2; \
+ B3 ^= B0; \
+ B0 |= B1; \
+ B2 ^= B3; \
+ B0 ^= B4; \
+ B0 |= B2; \
+ B1 ^= B3; \
+ B0 ^= B1; \
+ B1 |= B3; \
+ B1 ^= B0; \
+ B4 = ~B4; \
+ B4 ^= B1; \
+ B1 |= B0; \
+ B1 ^= B0; \
+ B1 |= B4; \
+ B3 ^= B1; \
+ B1 = B0; \
+ B0 = B4; \
+ B4 = B2; \
+ B2 = B3; \
+ B3 = B4; \
+ } while(0);
+
+#define SBoxD3(B0, B1, B2, B3) \
+ do { \
+ B2 ^= B3; \
+ B3 ^= B0; \
+ SIMD_32 B4 = B3; \
+ B3 &= B2; \
+ B3 ^= B1; \
+ B1 |= B2; \
+ B1 ^= B4; \
+ B4 &= B3; \
+ B2 ^= B3; \
+ B4 &= B0; \
+ B4 ^= B2; \
+ B2 &= B1; \
+ B2 |= B0; \
+ B3 = ~B3; \
+ B2 ^= B3; \
+ B0 ^= B3; \
+ B0 &= B1; \
+ B3 ^= B4; \
+ B3 ^= B0; \
+ B0 = B1; \
+ B1 = B4; \
+ } while(0);
+
+#define SBoxD4(B0, B1, B2, B3) \
+ do { \
+ SIMD_32 B4 = B2; \
+ B2 ^= B1; \
+ B0 ^= B2; \
+ B4 &= B2; \
+ B4 ^= B0; \
+ B0 &= B1; \
+ B1 ^= B3; \
+ B3 |= B4; \
+ B2 ^= B3; \
+ B0 ^= B3; \
+ B1 ^= B4; \
+ B3 &= B2; \
+ B3 ^= B1; \
+ B1 ^= B0; \
+ B1 |= B2; \
+ B0 ^= B3; \
+ B1 ^= B4; \
+ B0 ^= B1; \
+ B4 = B0; \
+ B0 = B2; \
+ B2 = B3; \
+ B3 = B4; \
+ } while(0);
+
+#define SBoxD5(B0, B1, B2, B3) \
+ do { \
+ SIMD_32 B4 = B2; \
+ B2 &= B3; \
+ B2 ^= B1; \
+ B1 |= B3; \
+ B1 &= B0; \
+ B4 ^= B2; \
+ B4 ^= B1; \
+ B1 &= B2; \
+ B0 = ~B0; \
+ B3 ^= B4; \
+ B1 ^= B3; \
+ B3 &= B0; \
+ B3 ^= B2; \
+ B0 ^= B1; \
+ B2 &= B0; \
+ B3 ^= B0; \
+ B2 ^= B4; \
+ B2 |= B3; \
+ B3 ^= B0; \
+ B2 ^= B1; \
+ B1 = B3; \
+ B3 = B4; \
+ } while(0);
+
+#define SBoxD6(B0, B1, B2, B3) \
+ do { \
+ B1 = ~B1; \
+ SIMD_32 B4 = B3; \
+ B2 ^= B1; \
+ B3 |= B0; \
+ B3 ^= B2; \
+ B2 |= B1; \
+ B2 &= B0; \
+ B4 ^= B3; \
+ B2 ^= B4; \
+ B4 |= B0; \
+ B4 ^= B1; \
+ B1 &= B2; \
+ B1 ^= B3; \
+ B4 ^= B2; \
+ B3 &= B4; \
+ B4 ^= B1; \
+ B3 ^= B4; \
+ B4 = ~B4; \
+ B3 ^= B0; \
+ B0 = B1; \
+ B1 = B4; \
+ B4 = B3; \
+ B3 = B2; \
+ B2 = B4; \
+ } while(0);
+
+#define SBoxD7(B0, B1, B2, B3) \
+ do { \
+ B0 ^= B2; \
+ SIMD_32 B4 = B2; \
+ B2 &= B0; \
+ B4 ^= B3; \
+ B2 = ~B2; \
+ B3 ^= B1; \
+ B2 ^= B3; \
+ B4 |= B0; \
+ B0 ^= B2; \
+ B3 ^= B4; \
+ B4 ^= B1; \
+ B1 &= B3; \
+ B1 ^= B0; \
+ B0 ^= B3; \
+ B0 |= B2; \
+ B3 ^= B1; \
+ B4 ^= B0; \
+ B0 = B1; \
+ B1 = B2; \
+ B2 = B4; \
+ } while(0);
+
+#define SBoxD8(B0, B1, B2, B3) \
+ do { \
+ SIMD_32 B4 = B2; \
+ B2 ^= B0; \
+ B0 &= B3; \
+ B4 |= B3; \
+ B2 = ~B2; \
+ B3 ^= B1; \
+ B1 |= B0; \
+ B0 ^= B2; \
+ B2 &= B4; \
+ B3 &= B4; \
+ B1 ^= B2; \
+ B2 ^= B0; \
+ B0 |= B2; \
+ B4 ^= B1; \
+ B0 ^= B3; \
+ B3 ^= B4; \
+ B4 |= B0; \
+ B3 ^= B2; \
+ B4 ^= B2; \
+ B2 = B1; \
+ B1 = B0; \
+ B0 = B3; \
+ B3 = B4; \
+ } while(0);
+
#define key_xor(round, B0, B1, B2, B3) \
do { \
B0 ^= SIMD_32(keys[4*round ]); \
@@ -175,6 +588,24 @@ void serpent_decrypt_4(const byte in[64],
#undef transform
#undef i_transform
+#undef SBoxE1
+#undef SBoxE2
+#undef SBoxE3
+#undef SBoxE4
+#undef SBoxE5
+#undef SBoxE6
+#undef SBoxE7
+#undef SBoxE8
+
+#undef SBoxD1
+#undef SBoxD2
+#undef SBoxD3
+#undef SBoxD4
+#undef SBoxD5
+#undef SBoxD6
+#undef SBoxD7
+#undef SBoxD8
+
/*
* Serpent Encryption
*/
diff --git a/src/block/serpent_simd/serp_simd_sbox.h b/src/block/serpent_simd/serp_simd_sbox.h
deleted file mode 100644
index 71eca19e5..000000000
--- a/src/block/serpent_simd/serp_simd_sbox.h
+++ /dev/null
@@ -1,425 +0,0 @@
-/*
-* Serpent Sboxes in SIMD form
-* (C) 2009 Jack Lloyd
-*
-* Distributed under the terms of the Botan license
-*/
-
-#ifndef BOTAN_SERPENT_SIMD_SBOXES_H__
-#define BOTAN_SERPENT_SIMD_SBOXES_H__
-
-#define SBoxE1(B0, B1, B2, B3) \
- do { \
- B3 ^= B0; \
- SIMD_32 B4 = B1; \
- B1 &= B3; \
- B4 ^= B2; \
- B1 ^= B0; \
- B0 |= B3; \
- B0 ^= B4; \
- B4 ^= B3; \
- B3 ^= B2; \
- B2 |= B1; \
- B2 ^= B4; \
- B4 = ~B4; \
- B4 |= B1; \
- B1 ^= B3; \
- B1 ^= B4; \
- B3 |= B0; \
- B1 ^= B3; \
- B4 ^= B3; \
- B3 = B0; \
- B0 = B1; \
- B1 = B4; \
- } while(0);
-
-#define SBoxE2(B0, B1, B2, B3) \
- do { \
- B0 = ~B0; \
- B2 = ~B2; \
- SIMD_32 B4 = B0; \
- B0 &= B1; \
- B2 ^= B0; \
- B0 |= B3; \
- B3 ^= B2; \
- B1 ^= B0; \
- B0 ^= B4; \
- B4 |= B1; \
- B1 ^= B3; \
- B2 |= B0; \
- B2 &= B4; \
- B0 ^= B1; \
- B1 &= B2; \
- B1 ^= B0; \
- B0 &= B2; \
- B4 ^= B0; \
- B0 = B2; \
- B2 = B3; \
- B3 = B1; \
- B1 = B4; \
- } while(0);
-
-#define SBoxE3(B0, B1, B2, B3) \
- do { \
- SIMD_32 B4 = B0; \
- B0 &= B2; \
- B0 ^= B3; \
- B2 ^= B1; \
- B2 ^= B0; \
- B3 |= B4; \
- B3 ^= B1; \
- B4 ^= B2; \
- B1 = B3; \
- B3 |= B4; \
- B3 ^= B0; \
- B0 &= B1; \
- B4 ^= B0; \
- B1 ^= B3; \
- B1 ^= B4; \
- B0 = B2; \
- B2 = B1; \
- B1 = B3; \
- B3 = ~B4; \
- } while(0);
-
-#define SBoxE4(B0, B1, B2, B3) \
- do { \
- SIMD_32 B4 = B0; \
- B0 |= B3; \
- B3 ^= B1; \
- B1 &= B4; \
- B4 ^= B2; \
- B2 ^= B3; \
- B3 &= B0; \
- B4 |= B1; \
- B3 ^= B4; \
- B0 ^= B1; \
- B4 &= B0; \
- B1 ^= B3; \
- B4 ^= B2; \
- B1 |= B0; \
- B1 ^= B2; \
- B0 ^= B3; \
- B2 = B1; \
- B1 |= B3; \
- B0 ^= B1; \
- B1 = B2; \
- B2 = B3; \
- B3 = B4; \
- } while(0);
-
-#define SBoxE5(B0, B1, B2, B3) \
- do { \
- B1 ^= B3; \
- B3 = ~B3; \
- B2 ^= B3; \
- B3 ^= B0; \
- SIMD_32 B4 = B1; \
- B1 &= B3; \
- B1 ^= B2; \
- B4 ^= B3; \
- B0 ^= B4; \
- B2 &= B4; \
- B2 ^= B0; \
- B0 &= B1; \
- B3 ^= B0; \
- B4 |= B1; \
- B4 ^= B0; \
- B0 |= B3; \
- B0 ^= B2; \
- B2 &= B3; \
- B0 = ~B0; \
- B4 ^= B2; \
- B2 = B0; \
- B0 = B1; \
- B1 = B4; \
- } while(0);
-
-#define SBoxE6(B0, B1, B2, B3) \
- do { \
- B0 ^= B1; \
- B1 ^= B3; \
- B3 = ~B3; \
- SIMD_32 B4 = B1; \
- B1 &= B0; \
- B2 ^= B3; \
- B1 ^= B2; \
- B2 |= B4; \
- B4 ^= B3; \
- B3 &= B1; \
- B3 ^= B0; \
- B4 ^= B1; \
- B4 ^= B2; \
- B2 ^= B0; \
- B0 &= B3; \
- B2 = ~B2; \
- B0 ^= B4; \
- B4 |= B3; \
- B4 ^= B2; \
- B2 = B0; \
- B0 = B1; \
- B1 = B3; \
- B3 = B4; \
- } while(0);
-
-#define SBoxE7(B0, B1, B2, B3) \
- do { \
- B2 = ~B2; \
- SIMD_32 B4 = B3; \
- B3 &= B0; \
- B0 ^= B4; \
- B3 ^= B2; \
- B2 |= B4; \
- B1 ^= B3; \
- B2 ^= B0; \
- B0 |= B1; \
- B2 ^= B1; \
- B4 ^= B0; \
- B0 |= B3; \
- B0 ^= B2; \
- B4 ^= B3; \
- B4 ^= B0; \
- B3 = ~B3; \
- B2 &= B4; \
- B3 ^= B2; \
- B2 = B4; \
- } while(0);
-
-#define SBoxE8(B0, B1, B2, B3) \
- do { \
- SIMD_32 B4 = B1; \
- B1 |= B2; \
- B1 ^= B3; \
- B4 ^= B2; \
- B2 ^= B1; \
- B3 |= B4; \
- B3 &= B0; \
- B4 ^= B2; \
- B3 ^= B1; \
- B1 |= B4; \
- B1 ^= B0; \
- B0 |= B4; \
- B0 ^= B2; \
- B1 ^= B4; \
- B2 ^= B1; \
- B1 &= B0; \
- B1 ^= B4; \
- B2 = ~B2; \
- B2 |= B0; \
- B4 ^= B2; \
- B2 = B1; \
- B1 = B3; \
- B3 = B0; \
- B0 = B4; \
- } while(0);
-
-#define SBoxD1(B0, B1, B2, B3) \
- do { \
- B2 = ~B2; \
- SIMD_32 B4 = B1; \
- B1 |= B0; \
- B4 = ~B4; \
- B1 ^= B2; \
- B2 |= B4; \
- B1 ^= B3; \
- B0 ^= B4; \
- B2 ^= B0; \
- B0 &= B3; \
- B4 ^= B0; \
- B0 |= B1; \
- B0 ^= B2; \
- B3 ^= B4; \
- B2 ^= B1; \
- B3 ^= B0; \
- B3 ^= B1; \
- B2 &= B3; \
- B4 ^= B2; \
- B2 = B1; \
- B1 = B4; \
- } while(0);
-
-#define SBoxD2(B0, B1, B2, B3) \
- do { \
- SIMD_32 B4 = B1; \
- B1 ^= B3; \
- B3 &= B1; \
- B4 ^= B2; \
- B3 ^= B0; \
- B0 |= B1; \
- B2 ^= B3; \
- B0 ^= B4; \
- B0 |= B2; \
- B1 ^= B3; \
- B0 ^= B1; \
- B1 |= B3; \
- B1 ^= B0; \
- B4 = ~B4; \
- B4 ^= B1; \
- B1 |= B0; \
- B1 ^= B0; \
- B1 |= B4; \
- B3 ^= B1; \
- B1 = B0; \
- B0 = B4; \
- B4 = B2; \
- B2 = B3; \
- B3 = B4; \
- } while(0);
-
-#define SBoxD3(B0, B1, B2, B3) \
- do { \
- B2 ^= B3; \
- B3 ^= B0; \
- SIMD_32 B4 = B3; \
- B3 &= B2; \
- B3 ^= B1; \
- B1 |= B2; \
- B1 ^= B4; \
- B4 &= B3; \
- B2 ^= B3; \
- B4 &= B0; \
- B4 ^= B2; \
- B2 &= B1; \
- B2 |= B0; \
- B3 = ~B3; \
- B2 ^= B3; \
- B0 ^= B3; \
- B0 &= B1; \
- B3 ^= B4; \
- B3 ^= B0; \
- B0 = B1; \
- B1 = B4; \
- } while(0);
-
-#define SBoxD4(B0, B1, B2, B3) \
- do { \
- SIMD_32 B4 = B2; \
- B2 ^= B1; \
- B0 ^= B2; \
- B4 &= B2; \
- B4 ^= B0; \
- B0 &= B1; \
- B1 ^= B3; \
- B3 |= B4; \
- B2 ^= B3; \
- B0 ^= B3; \
- B1 ^= B4; \
- B3 &= B2; \
- B3 ^= B1; \
- B1 ^= B0; \
- B1 |= B2; \
- B0 ^= B3; \
- B1 ^= B4; \
- B0 ^= B1; \
- B4 = B0; \
- B0 = B2; \
- B2 = B3; \
- B3 = B4; \
- } while(0);
-
-#define SBoxD5(B0, B1, B2, B3) \
- do { \
- SIMD_32 B4 = B2; \
- B2 &= B3; \
- B2 ^= B1; \
- B1 |= B3; \
- B1 &= B0; \
- B4 ^= B2; \
- B4 ^= B1; \
- B1 &= B2; \
- B0 = ~B0; \
- B3 ^= B4; \
- B1 ^= B3; \
- B3 &= B0; \
- B3 ^= B2; \
- B0 ^= B1; \
- B2 &= B0; \
- B3 ^= B0; \
- B2 ^= B4; \
- B2 |= B3; \
- B3 ^= B0; \
- B2 ^= B1; \
- B1 = B3; \
- B3 = B4; \
- } while(0);
-
-#define SBoxD6(B0, B1, B2, B3) \
- do { \
- B1 = ~B1; \
- SIMD_32 B4 = B3; \
- B2 ^= B1; \
- B3 |= B0; \
- B3 ^= B2; \
- B2 |= B1; \
- B2 &= B0; \
- B4 ^= B3; \
- B2 ^= B4; \
- B4 |= B0; \
- B4 ^= B1; \
- B1 &= B2; \
- B1 ^= B3; \
- B4 ^= B2; \
- B3 &= B4; \
- B4 ^= B1; \
- B3 ^= B4; \
- B4 = ~B4; \
- B3 ^= B0; \
- B0 = B1; \
- B1 = B4; \
- B4 = B3; \
- B3 = B2; \
- B2 = B4; \
- } while(0);
-
-#define SBoxD7(B0, B1, B2, B3) \
- do { \
- B0 ^= B2; \
- SIMD_32 B4 = B2; \
- B2 &= B0; \
- B4 ^= B3; \
- B2 = ~B2; \
- B3 ^= B1; \
- B2 ^= B3; \
- B4 |= B0; \
- B0 ^= B2; \
- B3 ^= B4; \
- B4 ^= B1; \
- B1 &= B3; \
- B1 ^= B0; \
- B0 ^= B3; \
- B0 |= B2; \
- B3 ^= B1; \
- B4 ^= B0; \
- B0 = B1; \
- B1 = B2; \
- B2 = B4; \
- } while(0);
-
-#define SBoxD8(B0, B1, B2, B3) \
- do { \
- SIMD_32 B4 = B2; \
- B2 ^= B0; \
- B0 &= B3; \
- B4 |= B3; \
- B2 = ~B2; \
- B3 ^= B1; \
- B1 |= B0; \
- B0 ^= B2; \
- B2 &= B4; \
- B3 &= B4; \
- B1 ^= B2; \
- B2 ^= B0; \
- B0 |= B2; \
- B4 ^= B1; \
- B0 ^= B3; \
- B3 ^= B4; \
- B4 |= B0; \
- B3 ^= B2; \
- B4 ^= B2; \
- B2 = B1; \
- B1 = B0; \
- B0 = B3; \
- B3 = B4; \
- } while(0);
-
-#endif
diff --git a/src/block/xtea_simd/info.txt b/src/block/xtea_simd/info.txt
index 5a8445b35..c16bfa2fa 100644
--- a/src/block/xtea_simd/info.txt
+++ b/src/block/xtea_simd/info.txt
@@ -2,6 +2,6 @@ define XTEA_SIMD
<requires>
xtea
-simd_32
+simd
simd_engine
</requires>
diff --git a/src/build-data/arch/arm.txt b/src/build-data/arch/arm.txt
index 14f88c362..b822fe130 100644
--- a/src/build-data/arch/arm.txt
+++ b/src/build-data/arch/arm.txt
@@ -2,6 +2,11 @@
endian little
family arm
+<aliases>
+armel # For Debian
+armhf # For Debian
+</aliases>
+
<submodels>
armv2
armv2a
diff --git a/src/build-data/arch/hitachi-sh.txt b/src/build-data/arch/hitachi-sh.txt
deleted file mode 100644
index bab84b48f..000000000
--- a/src/build-data/arch/hitachi-sh.txt
+++ /dev/null
@@ -1,7 +0,0 @@
-<submodels>
-hitachi-sh1
-hitachi-sh2
-hitachi-sh3
-hitachi-sh3e
-hitachi-sh4
-</submodels>
diff --git a/src/build-data/arch/ppc.txt b/src/build-data/arch/ppc32.txt
index dc3ea7829..e33c8ff24 100644
--- a/src/build-data/arch/ppc.txt
+++ b/src/build-data/arch/ppc32.txt
@@ -5,13 +5,9 @@ family ppc
<aliases>
powerpc
+ppc
</aliases>
-<submodel_aliases>
-g3 -> ppc740
-g4 -> ppc7450
-</submodel_aliases>
-
<submodels>
ppc601
ppc603
@@ -20,8 +16,15 @@ ppc740
ppc750
ppc7400
ppc7450
+e500v2
</submodels>
+<submodel_aliases>
+g3 -> ppc740
+g4 -> ppc7450
+powerpcspe -> e500v2 # for Debian
+</submodel_aliases>
+
<isa_extn>
altivec:ppc7400,ppc7450
</isa_extn>
diff --git a/src/build-data/arch/ppc64.txt b/src/build-data/arch/ppc64.txt
index 7a2e6b6b3..954d9181e 100644
--- a/src/build-data/arch/ppc64.txt
+++ b/src/build-data/arch/ppc64.txt
@@ -11,7 +11,6 @@ g5 -> ppc970
</submodel_aliases>
<submodels>
-rs64a
ppc970
power3
power4
diff --git a/src/build-data/arch/sparc32.txt b/src/build-data/arch/sparc32.txt
index fc015e520..69f3479aa 100644
--- a/src/build-data/arch/sparc32.txt
+++ b/src/build-data/arch/sparc32.txt
@@ -26,4 +26,6 @@ sparcv9 -> sparc32-v9
sparc-v7 -> sparc32-v7
sparc-v8 -> sparc32-v8
sparc-v9 -> sparc32-v9
+
+sun4u -> sparc32-v9
</submodel_aliases>
diff --git a/src/build-data/arch/sparc64.txt b/src/build-data/arch/sparc64.txt
index 7344fa390..3a6acd6c3 100644
--- a/src/build-data/arch/sparc64.txt
+++ b/src/build-data/arch/sparc64.txt
@@ -1,13 +1,11 @@
family sparc
-<aliases>
-sun4u
-</aliases>
-
<submodels>
ultrasparc
ultrasparc3
+niagra
+niagra2
</submodels>
<submodel_aliases>
diff --git a/src/build-data/arch/superh.txt b/src/build-data/arch/superh.txt
new file mode 100644
index 000000000..c7dc09861
--- /dev/null
+++ b/src/build-data/arch/superh.txt
@@ -0,0 +1,5 @@
+<submodels>
+sh2
+sh3
+sh4
+</submodels>
diff --git a/src/build-data/arch/x86_32.txt b/src/build-data/arch/x86_32.txt
index 9289f1b2e..482a53057 100644
--- a/src/build-data/arch/x86_32.txt
+++ b/src/build-data/arch/x86_32.txt
@@ -25,7 +25,7 @@ pentium-m
prescott
k6
athlon
-atom
+atom32
</submodels>
<submodel_aliases>
@@ -62,7 +62,7 @@ intelcput2700 -> prescott
</submodel_aliases>
<isa_extn>
-sse2:pentium4,prescott,pentium-m,atom
-ssse3:atom
-movbe:atom
+sse2:pentium4,prescott,pentium-m,atom32
+ssse3:atom32
+movbe:atom32
</isa_extn>
diff --git a/src/build-data/arch/x86_64.txt b/src/build-data/arch/x86_64.txt
index 59e48329a..922daa104 100644
--- a/src/build-data/arch/x86_64.txt
+++ b/src/build-data/arch/x86_64.txt
@@ -13,10 +13,12 @@ x64
<submodels>
k8
k10
+atom
nocona
core2
nehalem
westmere
+sandybridge
</submodels>
<submodel_aliases>
@@ -36,6 +38,6 @@ corei7cpu860 -> nehalem
<isa_extn>
sse2:all
-ssse3:core2,nehalem,westmere
-aes-ni:westmere
+ssse3:core2,nehalem,westmere,atom,sandybridge
+aes-ni:westmere,sandybridge
</isa_extn>
diff --git a/src/build-data/botan-config.in b/src/build-data/botan-config.in
index f3fa3db94..6780c12b8 100644
--- a/src/build-data/botan-config.in
+++ b/src/build-data/botan-config.in
@@ -2,7 +2,7 @@
# For normal builds:
guess_prefix=`dirname \`dirname $0\``
-includedir=%{includedir}
+includedir=%{includedir}/botan-%{version_major}.%{version_minor}
libdir=%{libdir}
# For workspace builds:
@@ -54,9 +54,9 @@ while test $# -gt 0; do
--libs)
if [ $prefix != "/usr" -a $prefix != "/usr/local" ]
then
- echo -L$prefix/$libdir -lbotan %{link_to}
+ echo -L$prefix/$libdir -lbotan-%{version_major}.%{version_minor} %{link_to}
else
- echo -lbotan %{link_to}
+ echo -lbotan-%{version_major}.%{version_minor} %{link_to}
fi
;;
*)
diff --git a/src/build-data/botan.pc.in b/src/build-data/botan.pc.in
index 70ed65d70..301f84600 100644
--- a/src/build-data/botan.pc.in
+++ b/src/build-data/botan.pc.in
@@ -1,12 +1,12 @@
prefix=%{prefix}
exec_prefix=${prefix}
libdir=${prefix}/%{libdir}
-includedir=${prefix}/include
+includedir=${prefix}/include/botan-%{version_major}.%{version_minor}
Name: Botan
Description: Multi-platform C++ crypto library
Version: %{version}
-Libs: -L${libdir} -lbotan
+Libs: -L${libdir} -lbotan-%{version_major}.%{version_minor}
Libs.private: %{link_to}
Cflags: -I${includedir}
diff --git a/src/build-data/buildh.in b/src/build-data/buildh.in
index 8e0de0183..b3e6f8197 100644
--- a/src/build-data/buildh.in
+++ b/src/build-data/buildh.in
@@ -17,10 +17,12 @@
#define BOTAN_VERSION_PATCH %{version_patch}
#define BOTAN_VERSION_DATESTAMP %{version_datestamp}
+#define BOTAN_VERSION_VC_REVISION "%{version_vc_rev}"
+
#define BOTAN_DISTRIBUTION_INFO "%{distribution_info}"
#ifndef BOTAN_DLL
- #define BOTAN_DLL %{dll_import_flags}
+ #define BOTAN_DLL %{visibility_attribute}
#endif
/* Chunk sizes */
diff --git a/src/build-data/cc/bcc.txt b/src/build-data/cc/bcc.txt
index 93306dde1..f2ea46ef2 100644
--- a/src/build-data/cc/bcc.txt
+++ b/src/build-data/cc/bcc.txt
@@ -15,7 +15,6 @@ lang_flags ""
warning_flags ""
shared_flags ""
-dll_import_flags ""
ar_command lib
diff --git a/src/build-data/cc/clang.txt b/src/build-data/cc/clang.txt
index 5f522cdb6..e5d52db3d 100644
--- a/src/build-data/cc/clang.txt
+++ b/src/build-data/cc/clang.txt
@@ -17,11 +17,12 @@ makefile_style unix
lib_opt_flags "-O2"
check_opt_flags "-O2"
-shared_flags "-fPIC -fvisibility=hidden"
+shared_flags "-fPIC"
debug_flags -g
no_debug_flags "-finline-functions"
-dll_import_flags '__attribute__((visibility("default")))'
+visibility_build_flags "-fvisibility=hidden"
+visibility_attribute '__attribute__((visibility("default")))'
<so_link_flags>
# The default works for GNU ld and several other Unix linkers
@@ -30,7 +31,8 @@ default -> "$(CXX) -shared -fPIC -Wl,-soname,$(SONAME)"
<mach_opt>
x86_64 -> "-march=SUBMODEL"
-nehalem -> "-march=core2 -mssse3 -msse4.1"
+nehalem -> "-march=corei7"
+westmere -> "-march=corei7 -maes"
</mach_opt>
<mach_abi_linking>
diff --git a/src/build-data/cc/ekopath.txt b/src/build-data/cc/ekopath.txt
index 101f6babb..c6e8b6550 100644
--- a/src/build-data/cc/ekopath.txt
+++ b/src/build-data/cc/ekopath.txt
@@ -28,10 +28,9 @@ default -> "$(CXX) -shared -fPIC -Wl,-soname,$(SONAME)"
athlon -> "-mcpu=athlon"
pentium4 -> "-mcpu=pentium4"
-opteron -> "-mcpu=opteron"
-em64t -> "-mcpu=em64t"
+k8 -> "-mcpu=opteron"
core2 -> "-mcpu=core"
-x86 -> "-mcpu=anyx86"
+x86_32 -> "-mcpu=anyx86"
x86_64 -> "-mcpu=athlon64"
</mach_opt>
diff --git a/src/build-data/cc/gcc.txt b/src/build-data/cc/gcc.txt
index fde33cde2..3de85099c 100644
--- a/src/build-data/cc/gcc.txt
+++ b/src/build-data/cc/gcc.txt
@@ -13,15 +13,16 @@ add_lib_option -l
lang_flags "-D_REENTRANT -Wno-long-long"
warning_flags "-W -Wall"
-maintainer_warning_flags "-Werror -Wall -Wextra -Wstrict-aliasing -Wstrict-overflow=5 -Wcast-align -Wmissing-declarations -Wpointer-arith -Wcast-qual -Wold-style-cast"
+maintainer_warning_flags "-Werror -Weffc++ -Wall -Wextra -Wstrict-aliasing -Wstrict-overflow=5 -Wcast-align -Wmissing-declarations -Wpointer-arith -Wcast-qual -Wold-style-cast"
lib_opt_flags "-O3"
check_opt_flags "-O2"
-shared_flags "-fPIC -fvisibility=hidden"
+shared_flags "-fPIC"
debug_flags -g
no_debug_flags "-finline-functions"
-dll_import_flags '__attribute__((visibility("default")))'
+visibility_build_flags "-fvisibility=hidden"
+visibility_attribute '__attribute__((visibility("default")))'
makefile_style unix
@@ -32,36 +33,54 @@ default -> "$(CXX) -shared -fPIC -Wl,-soname,$(SONAME)"
# AIX doesn't seem to have soname support (weird...)
aix -> "$(CXX) -shared -fPIC"
+# OpenBSD doesn't use soname
+openbsd -> "$(CXX) -shared -fPIC"
+
darwin -> "$(CXX) -dynamiclib -fPIC -install_name $(LIBDIR)/$(SONAME)"
hpux -> "$(CXX) -shared -fPIC -Wl,+h,$(SONAME)"
solaris -> "$(CXX) -shared -fPIC -Wl,-h,$(SONAME)"
</so_link_flags>
<mach_opt>
-# Specializations first (they don't need to be, just clearer)
-i386 -> "-mtune=i686 -momit-leaf-frame-pointer"
-ppc601 -> "-mpowerpc -mcpu=601"
-
-# Until GCC gets -march support for these models
-nehalem -> "-march=core2 -msse4.1 -msse4.2"
-westmere -> "-march=core2 -maes -msse4.1 -msse4.2"
-atom -> "-march=i686 -msse2 -mssse3"
-cellppu -> ""
-alpha-ev68 -> "-mcpu=ev6"
-alpha-ev7 -> "-mcpu=ev6"
-
-# Default family options (SUBMODEL is substitued with the real submodel)
-# Anything after the quotes is what should be *removed* from the submodel name
-# before it's put into SUBMODEL.
+# Avoid using -march=i[345]86, instead tune for generic
+i386 -> "-mtune=generic -momit-leaf-frame-pointer"
+i486 -> "-mtune=generic -momit-leaf-frame-pointer"
+i586 -> "-mtune=generic -momit-leaf-frame-pointer"
+
+# Translate to GCC-speak
+nehalem -> "-march=corei7 -momit-leaf-frame-pointer"
+#westmere -> "-march=corei7 -maes -momit-leaf-frame-pointer"
+
+#nehalem -> "-march=core2 -msse4.1 -msse4.2 -momit-leaf-frame-pointer"
+#westmere -> "-march=core2 -msse4.1 -msse4.2 -maes -momit-leaf-frame-pointer"
+
+sandybridge -> "-march=corei7-avx -momit-leaf-frame-pointer"
+atom32 -> "-march=atom -momit-leaf-frame-pointer"
+
+ppc601 -> "-mpowerpc -mcpu=601"
+cellppu -> "-mcpu=cell"
+e500v2 -> "-mcpu=8548"
+
+# No scheduler in GCC for anything after EV67
+alpha-ev68 -> "-mcpu=ev67"
+alpha-ev7 -> "-mcpu=ev67"
+
+# The patch from Debian bug 594159 has this, don't know why though...
+sh4 -> "-m4 -mieee"
+
+# Default family options (SUBMODEL is substitued with the actual
+# submodel name). Anything after the quotes is what should be
+# *removed* from the submodel name before it's put into SUBMODEL.
+
alpha -> "-mcpu=SUBMODEL" alpha-
arm -> "-march=SUBMODEL"
-hitachi-sh -> "-mSUBMODEL" hitachi-sh
+superh -> "-mSUBMODEL" sh
hppa -> "-march=SUBMODEL" hppa
ia64 -> "-mtune=SUBMODEL"
m68k -> "-mSUBMODEL"
mips32 -> "-mips1 -mcpu=SUBMODEL" mips32-
mips64 -> "-mips3 -mcpu=SUBMODEL" mips64-
-ppc -> "-mcpu=SUBMODEL" ppc
+ppc32 -> "-mcpu=SUBMODEL" ppc
ppc64 -> "-mcpu=SUBMODEL" ppc
sparc32 -> "-mcpu=SUBMODEL -Wa,-xarch=v8plus" sparc32-
sparc64 -> "-mcpu=v9 -mtune=SUBMODEL"
diff --git a/src/build-data/cc/msvc.txt b/src/build-data/cc/msvc.txt
index a854a576d..034ea7444 100644
--- a/src/build-data/cc/msvc.txt
+++ b/src/build-data/cc/msvc.txt
@@ -14,8 +14,8 @@ check_opt_flags "/O2 /D_CONSOLE"
lang_flags "/EHs /GR"
warning_flags "/W3 /wd4275 /wd4267"
-shared_flags "/DBOTAN_DLL=__declspec(dllexport)"
-dll_import_flags "__declspec(dllimport)"
+visibility_build_flags "/DBOTAN_DLL=__declspec(dllexport)"
+visibility_attribute "__declspec(dllimport)"
ar_command lib
diff --git a/src/build-data/cc/sunstudio.txt b/src/build-data/cc/sunstudio.txt
index 5fb4c6bb8..43e5fcf8a 100644
--- a/src/build-data/cc/sunstudio.txt
+++ b/src/build-data/cc/sunstudio.txt
@@ -40,13 +40,17 @@ nehalem -> "-xtarget=nehalem"
sparc32-v9 -> "-xchip=ultra -xarch=v8"
+ultrasparc3 -> "-xchip=ultra3"
+niagra1 -> "-xchip=ultraT1"
+niagra2 -> "-xchip=ultraT2"
+
sparc32 -> "-xchip=ultra -xarch=SUBMODEL" sparc32-
-sparc64 -> "-xchip=SUBMODEL" sparc64-
+sparc64 -> "-xchip=generic"
</mach_opt>
<mach_abi_linking>
# Needed on some Linux distros
-#linux -> "-library=stlport4"
+linux -> "-library=stlport4"
sparc64 -> "-xarch=v9"
x86_64 -> "-m64"
diff --git a/src/build-data/makefile/python.in b/src/build-data/makefile/python.in
index 583c91eb5..74620fe06 100644
--- a/src/build-data/makefile/python.in
+++ b/src/build-data/makefile/python.in
@@ -3,6 +3,8 @@ CFLAGS = -Os
LDFLAGS =
WARN_FLAGS = %{warn_flags}
+SERIES = %{version_major}.%{version_minor}
+
PYTHON_ROOT = /usr/lib/python%{python_version}/config
PYTHON_INC = -I/usr/include/python%{python_version}
PYTHON_SITE_PACKAGE_DIR = /usr/lib/python%{python_version}/site-packages/
@@ -19,7 +21,7 @@ all: $(BOTAN_PYTHON_MODDIR)/_botan.so
$(BOTAN_PYTHON_MODDIR)/_botan.so: $(PYTHON_OBJS)
cp %{python_dir}/*.py $(BOTAN_PYTHON_MODDIR)
- $(CXX) -shared -Wl,-soname,$@ $(PYTHON_OBJS) -L. -L$(PYTHON_ROOT) $(LDFLAGS) -lbotan -lboost_python -o $@
+ $(CXX) -shared -Wl,-soname,$@ $(PYTHON_OBJS) -L. -L$(PYTHON_ROOT) $(LDFLAGS) -lbotan-$(SERIES) -lboost_python -o $@
clean:
rm -rf $(BOTAN_PYTHON_MODDIR)/*
diff --git a/src/build-data/makefile/unix.in b/src/build-data/makefile/unix.in
index 1a1128f81..5290beda8 100644
--- a/src/build-data/makefile/unix.in
+++ b/src/build-data/makefile/unix.in
@@ -9,13 +9,14 @@ LINK_TO = %{link_to}
# Version Numbers
VERSION = %{version}
+SERIES = %{version_major}.%{version_minor}
# Installation Settings
DESTDIR = %{prefix}
BINDIR = $(DESTDIR)/bin
LIBDIR = $(DESTDIR)/%{libdir}
-HEADERDIR = $(DESTDIR)/%{includedir}/botan
+HEADERDIR = $(DESTDIR)/%{includedir}/botan-$(SERIES)/botan
DOCDIR = $(DESTDIR)/%{docdir}/botan-$(VERSION)
PKGCONF_DIR = $(LIBDIR)/pkgconfig
@@ -52,7 +53,7 @@ CHECK_FLAGS = $(CHECK_OPT) $(LANG_FLAGS) $(WARN_FLAGS)
LIBRARIES = $(STATIC_LIB)
LIBNAME = %{lib_prefix}libbotan
-STATIC_LIB = $(LIBNAME).a
+STATIC_LIB = $(LIBNAME)-$(SERIES).a
all: $(LIBRARIES)
@@ -85,6 +86,7 @@ clean:
distclean: clean
$(RM_R) %{build_dir}
$(RM) Makefile* $(CONFIG_SCRIPT) $(PKGCONFIG)
+ $(RM) botan_all.cpp botan_all.h
install: $(LIBRARIES) docs
$(ECHO) "Installing Botan into $(DESTDIR)... "
diff --git a/src/build-data/makefile/unix_shr.in b/src/build-data/makefile/unix_shr.in
index c311d9924..31060afbb 100644
--- a/src/build-data/makefile/unix_shr.in
+++ b/src/build-data/makefile/unix_shr.in
@@ -11,13 +11,14 @@ LINK_TO = %{link_to}
# Version Numbers
VERSION = %{version}
+SERIES = %{version_major}.%{version_minor}
# Installation Settings
DESTDIR = %{prefix}
BINDIR = $(DESTDIR)/bin
LIBDIR = $(DESTDIR)/%{libdir}
-HEADERDIR = $(DESTDIR)/%{includedir}/botan
+HEADERDIR = $(DESTDIR)/%{includedir}/botan-$(SERIES)/botan
DOCDIR = $(DESTDIR)/%{docdir}/botan-$(VERSION)
PKGCONF_DIR = $(LIBDIR)/pkgconfig
@@ -54,12 +55,12 @@ CHECK_FLAGS = $(CHECK_OPT) $(LANG_FLAGS) $(WARN_FLAGS)
LIBRARIES = $(STATIC_LIB) $(SHARED_LIB)
LIBNAME = %{lib_prefix}libbotan
-STATIC_LIB = $(LIBNAME).a
+STATIC_LIB = $(LIBNAME)-$(SERIES).a
-SONAME = $(LIBNAME)-%{version_major}.%{version_minor}.%{so_suffix}
+SONAME = $(LIBNAME)-$(SERIES).%{so_suffix}.%{so_abi_rev}
SHARED_LIB = $(SONAME).%{version_patch}
-SYMLINK = libbotan.%{so_suffix}
+SYMLINK = $(LIBNAME)-$(SERIES).%{so_suffix}
all: $(LIBRARIES)
@@ -99,6 +100,7 @@ clean:
distclean: clean
$(RM_R) %{build_dir}
$(RM) Makefile* $(CONFIG_SCRIPT) $(PKGCONFIG)
+ $(RM) botan_all.cpp botan_all.h
install: $(LIBRARIES) docs
$(ECHO) "Installing Botan into $(DESTDIR)... "
diff --git a/src/build-data/os/mingw.txt b/src/build-data/os/mingw.txt
index 08f85b4db..1268298cb 100644
--- a/src/build-data/os/mingw.txt
+++ b/src/build-data/os/mingw.txt
@@ -14,15 +14,13 @@ header_dir include
lib_dir lib
doc_dir share/doc
-install_cmd_data "install -m 644"
-install_cmd_exec "install -m 755"
-
<aliases>
msys
mingw32
</aliases>
<target_features>
+loadlibrary
win32_virtual_lock
win32_get_systemtime
</target_features>
diff --git a/src/build-data/os/nacl.txt b/src/build-data/os/nacl.txt
new file mode 100644
index 000000000..3df798ed8
--- /dev/null
+++ b/src/build-data/os/nacl.txt
@@ -0,0 +1,4 @@
+
+<target_features>
+gettimeofday
+</target_features>
diff --git a/src/build-data/os/solaris.txt b/src/build-data/os/solaris.txt
index 47e7bccbc..0ed785036 100644
--- a/src/build-data/os/solaris.txt
+++ b/src/build-data/os/solaris.txt
@@ -1,5 +1,8 @@
os_type unix
+install_cmd_data '/usr/ucb/install -m 644'
+install_cmd_exec '/usr/ucb/install -m 755'
+
<target_features>
posix_mlock
gettimeofday
diff --git a/src/build-data/scripts/dist.py b/src/build-data/scripts/dist.py
new file mode 100755
index 000000000..8a69e7aa6
--- /dev/null
+++ b/src/build-data/scripts/dist.py
@@ -0,0 +1,168 @@
+#!/usr/bin/python
+
+import optparse
+import subprocess
+import logging
+import os
+import sys
+import shutil
+import tarfile
+import errno
+
+def check_subprocess_results(subproc, name):
+ (stdout, stderr) = subproc.communicate()
+
+ stdout = stdout.strip()
+ stderr = stderr.strip()
+
+ if subproc.returncode != 0:
+ if stdout != '':
+ logging.error(stdout)
+ if stderr != '':
+ logging.error(stderr)
+ raise Exception('Running %s failed' % (name))
+ else:
+ if stderr != '':
+ logging.debug(stderr)
+
+ return stdout
+
+def run_monotone(db, args):
+ mtn = subprocess.Popen(['mtn', '--db', db] + args,
+ stdout=subprocess.PIPE,
+ stderr=subprocess.PIPE)
+
+ return check_subprocess_results(mtn, 'mtn')
+
+def gpg_sign(file, keyid):
+ print file
+ gpg = subprocess.Popen(['gpg', '--armor', '--detach-sign',
+ '--local-user', keyid, file],
+ stdout=subprocess.PIPE,
+ stderr=subprocess.PIPE)
+
+ check_subprocess_results(gpg, 'gpg')
+
+def parse_args(args):
+ parser = optparse.OptionParser()
+ parser.add_option('--verbose', action='store_true',
+ default=False, help='Extra debug output')
+
+ parser.add_option('--output-dir', metavar='DIR',
+ default='.',
+ help='Where to place output (default %default)')
+
+ parser.add_option('--mtn-db', metavar='DB',
+ default=os.getenv('BOTAN_MTN_DB', ''),
+ help='Set monotone db (default \'%default\')')
+
+ parser.add_option('--pgp-key-id', metavar='KEYID',
+ default='EFBADFBC',
+ help='PGP signing key (default %default)')
+
+ return parser.parse_args(args)
+
+def remove_file_if_exists(fspath):
+ try:
+ os.unlink(fspath)
+ except OSError, e:
+ if e.errno != errno.ENOENT:
+ raise
+
+def main(args = None):
+ if args is None:
+ args = sys.argv[1:]
+
+ (options, args) = parse_args(args)
+
+ def log_level():
+ if options.verbose:
+ return logging.DEBUG
+ return logging.INFO
+
+ logging.basicConfig(stream = sys.stdout,
+ format = '%(levelname) 7s: %(message)s',
+ level = log_level())
+
+ if options.mtn_db == '':
+ logging.error('No monotone db set (use --mtn-db)')
+ return 1
+
+ if not os.access(options.mtn_db, os.R_OK):
+ logging.error('Monotone db %s not found' % (options.mtn_db))
+ return 1
+
+ if len(args) != 1:
+ logging.error('Usage: %s version' % (sys.argv[0]))
+ return 1
+
+ try:
+ version = args[0]
+
+ rev_id = run_monotone(options.mtn_db,
+ ['automate', 'select', 't:' + version])
+
+ if rev_id == '':
+ logging.error('No revision for %s found' % (version))
+ return 2
+
+ output_basename = 'Botan-' + version
+ output_name = os.path.join(options.output_dir, output_basename)
+
+ output_tgz = output_name + '.tgz'
+ output_tbz = output_name + '.tbz'
+
+ logging.info('Found revision id %s' % (rev_id))
+
+ if os.access(output_name, os.X_OK):
+ shutil.rmtree(output_name)
+
+ run_monotone(options.mtn_db,
+ ['checkout', '-r', rev_id, output_name])
+
+ shutil.rmtree(os.path.join(output_name, '_MTN'))
+ remove_file_if_exists(os.path.join(output_name, '.mtn-ignore'))
+
+ version_file = os.path.join(output_name, 'botan_version.py')
+ if os.access(version_file, os.R_OK):
+ # rewrite botan_version.py
+
+ contents = open(version_file).readlines()
+
+ def content_rewriter():
+ for line in contents:
+ if line == 'release_vc_rev = None\n':
+ yield 'release_vc_rev = \'mtn:%s\'\n' % (rev_id)
+ else:
+ yield line
+
+ open(version_file, 'w').write(''.join(list(content_rewriter())))
+
+ os.chdir(options.output_dir)
+
+ remove_file_if_exists(output_tgz)
+ remove_file_if_exists(output_tgz + '.asc')
+ archive = tarfile.open(output_tgz, 'w:gz')
+ archive.add(output_basename)
+ archive.close()
+ if options.pgp_key_id != '':
+ gpg_sign(output_tgz, options.pgp_key_id)
+
+ remove_file_if_exists(output_tbz)
+ remove_file_if_exists(output_tbz + '.asc')
+ archive = tarfile.open(output_tbz, 'w:bz2')
+ archive.add(output_basename)
+ archive.close()
+ if options.pgp_key_id != '':
+ gpg_sign(output_tbz, options.pgp_key_id)
+
+ shutil.rmtree(output_name)
+
+ except Exception, e:
+ import traceback
+ traceback.print_exc(file=sys.stderr)
+ logging.error(str(e))
+ return 1
+
+if __name__ == '__main__':
+ sys.exit(main())
diff --git a/src/cert/cvc/info.txt b/src/cert/cvc/info.txt
index c42d909b5..33a872053 100644
--- a/src/cert/cvc/info.txt
+++ b/src/cert/cvc/info.txt
@@ -1,6 +1,6 @@
define CARD_VERIFIABLE_CERTIFICATES
-load_on auto
+load_on request
<header:public>
cvc_ado.h
diff --git a/src/cert/x509cert/x509_ext.cpp b/src/cert/x509cert/x509_ext.cpp
index 462b29669..6e0befaf3 100644
--- a/src/cert/x509cert/x509_ext.cpp
+++ b/src/cert/x509cert/x509_ext.cpp
@@ -443,6 +443,9 @@ class Policy_Information : public ASN1_Object
public:
OID oid;
+ Policy_Information() {}
+ Policy_Information(const OID& oid) : oid(oid) {}
+
void encode_into(DER_Encoder& codec) const
{
codec.start_cons(SEQUENCE)
@@ -466,18 +469,16 @@ class Policy_Information : public ASN1_Object
*/
MemoryVector<byte> Certificate_Policies::encode_inner() const
{
- // FIXME
-#if 1
- throw Internal_Error("Certificate_Policies::encode_inner: Bugged");
-#else
std::vector<Policy_Information> policies;
+ for(size_t i = 0; i != oids.size(); ++i)
+ policies.push_back(oids[i]);
+
return DER_Encoder()
.start_cons(SEQUENCE)
.encode_list(policies)
.end_cons()
.get_contents();
-#endif
}
/*
@@ -491,6 +492,10 @@ void Certificate_Policies::decode_inner(const MemoryRegion<byte>& in)
.start_cons(SEQUENCE)
.decode_list(policies)
.end_cons();
+
+ oids.clear();
+ for(size_t i = 0; i != policies.size(); ++i)
+ oids.push_back(policies[i].oid);
}
/*
diff --git a/src/codec/base64/base64.cpp b/src/codec/base64/base64.cpp
index d6c5ec7c0..6a53a7a9a 100644
--- a/src/codec/base64/base64.cpp
+++ b/src/codec/base64/base64.cpp
@@ -97,5 +97,155 @@ std::string base64_encode(const MemoryRegion<byte>& input)
return base64_encode(&input[0], input.size());
}
+size_t base64_decode(byte output[],
+ const char input[],
+ size_t input_length,
+ size_t& input_consumed,
+ bool final_inputs,
+ bool ignore_ws)
+ {
+ /*
+ * Base64 Decoder Lookup Table
+ * Warning: assumes ASCII encodings
+ */
+ static const byte BASE64_TO_BIN[256] = {
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x80,
+ 0x80, 0xFF, 0xFF, 0x80, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0x80, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0x3E, 0xFF, 0xFF, 0xFF, 0x3F, 0x34, 0x35,
+ 0x36, 0x37, 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0xFF, 0xFF,
+ 0xFF, 0x81, 0xFF, 0xFF, 0xFF, 0x00, 0x01, 0x02, 0x03, 0x04,
+ 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E,
+ 0x0F, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18,
+ 0x19, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x1A, 0x1B, 0x1C,
+ 0x1D, 0x1E, 0x1F, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26,
+ 0x27, 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F, 0x30,
+ 0x31, 0x32, 0x33, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };
+
+ byte* out_ptr = output;
+ byte decode_buf[4];
+ size_t decode_buf_pos = 0;
+ size_t final_truncate = 0;
+
+ clear_mem(output, input_length * 3 / 4);
+
+ for(size_t i = 0; i != input_length; ++i)
+ {
+ const byte bin = BASE64_TO_BIN[static_cast<byte>(input[i])];
+
+ if(bin <= 0x3F)
+ {
+ decode_buf[decode_buf_pos] = bin;
+ decode_buf_pos += 1;
+ }
+ else if(!(bin == 0x81 || (bin == 0x80 && ignore_ws)))
+ {
+ std::string bad_char(1, input[i]);
+ if(bad_char == "\t")
+ bad_char = "\\t";
+ else if(bad_char == "\n")
+ bad_char = "\\n";
+ else if(bad_char == "\r")
+ bad_char = "\\r";
+
+ throw std::invalid_argument(
+ std::string("base64_decode: invalid base64 character '") +
+ bad_char + "'");
+ }
+
+ /*
+ * If we're at the end of the input, pad with 0s and truncate
+ */
+ if(final_inputs && (i == input_length - 1))
+ {
+ if(decode_buf_pos)
+ {
+ for(size_t i = decode_buf_pos; i != 4; ++i)
+ decode_buf[i] = 0;
+ final_truncate = (4 - decode_buf_pos);
+ decode_buf_pos = 4;
+ }
+ }
+
+ if(decode_buf_pos == 4)
+ {
+ out_ptr[0] = (decode_buf[0] << 2) | (decode_buf[1] >> 4);
+ out_ptr[1] = (decode_buf[1] << 4) | (decode_buf[2] >> 2);
+ out_ptr[2] = (decode_buf[2] << 6) | decode_buf[3];
+
+ out_ptr += 3;
+ decode_buf_pos = 0;
+ input_consumed = i+1;
+ }
+ }
+
+ while(input_consumed < input_length &&
+ BASE64_TO_BIN[static_cast<byte>(input[input_consumed])] == 0x80)
+ {
+ ++input_consumed;
+ }
+
+ size_t written = (out_ptr - output) - final_truncate;
+
+ return written;
+ }
+
+size_t base64_decode(byte output[],
+ const char input[],
+ size_t input_length,
+ bool ignore_ws)
+ {
+ size_t consumed = 0;
+ size_t written = base64_decode(output, input, input_length,
+ consumed, true, ignore_ws);
+
+ if(consumed != input_length)
+ throw std::invalid_argument("base64_decode: input did not have full bytes");
+
+ return written;
+ }
+
+size_t base64_decode(byte output[],
+ const std::string& input,
+ bool ignore_ws)
+ {
+ return base64_decode(output, &input[0], input.length(), ignore_ws);
+ }
+
+SecureVector<byte> base64_decode(const char input[],
+ size_t input_length,
+ bool ignore_ws)
+ {
+ SecureVector<byte> bin((round_up<size_t>(input_length, 4) * 3) / 4);
+
+ size_t written = base64_decode(&bin[0],
+ input,
+ input_length,
+ ignore_ws);
+
+ bin.resize(written);
+ return bin;
+ }
+
+SecureVector<byte> base64_decode(const std::string& input,
+ bool ignore_ws)
+ {
+ return base64_decode(&input[0], input.size(), ignore_ws);
+ }
+
}
diff --git a/src/codec/base64/base64.h b/src/codec/base64/base64.h
index 6daac73d8..23a2558bd 100644
--- a/src/codec/base64/base64.h
+++ b/src/codec/base64/base64.h
@@ -48,6 +48,76 @@ std::string BOTAN_DLL base64_encode(const byte input[],
*/
std::string BOTAN_DLL base64_encode(const MemoryRegion<byte>& input);
+/**
+* Perform base64 decoding
+* @param output an array of at least input_length*3/4 bytes
+* @param input some base64 input
+* @param input_length length of input in bytes
+* @param input_consumed is an output parameter which says how many
+* bytes of input were actually consumed. If less than
+* input_length, then the range input[consumed:length]
+* should be passed in later along with more input.
+* @param final_inputs true iff this is the last input, in which case
+ padding is allowed
+* @param ignore_ws ignore whitespace on input; if false, throw an
+ exception if whitespace is encountered
+* @return number of bytes written to output
+*/
+size_t BOTAN_DLL base64_decode(byte output[],
+ const char input[],
+ size_t input_length,
+ size_t& input_consumed,
+ bool final_inputs,
+ bool ignore_ws = true);
+
+/**
+* Perform base64 decoding
+* @param output an array of at least input_length*3/4 bytes
+* @param input some base64 input
+* @param input_length length of input in bytes
+* @param ignore_ws ignore whitespace on input; if false, throw an
+ exception if whitespace is encountered
+* @return number of bytes written to output
+*/
+size_t BOTAN_DLL base64_decode(byte output[],
+ const char input[],
+ size_t input_length,
+ bool ignore_ws = true);
+
+/**
+* Perform base64 decoding
+* @param output an array of at least input_length/3*4 bytes
+* @param input some base64 input
+* @param ignore_ws ignore whitespace on input; if false, throw an
+ exception if whitespace is encountered
+* @return number of bytes written to output
+*/
+size_t BOTAN_DLL base64_decode(byte output[],
+ const std::string& input,
+ bool ignore_ws = true);
+
+/**
+* Perform base64 decoding
+* @param input some base64 input
+* @param input_length the length of input in bytes
+* @param ignore_ws ignore whitespace on input; if false, throw an
+ exception if whitespace is encountered
+* @return decoded base64 output
+*/
+SecureVector<byte> BOTAN_DLL base64_decode(const char input[],
+ size_t input_length,
+ bool ignore_ws = true);
+
+/**
+* Perform base64 decoding
+* @param input some base64 input
+* @param ignore_ws ignore whitespace on input; if false, throw an
+ exception if whitespace is encountered
+* @return decoded base64 output
+*/
+SecureVector<byte> BOTAN_DLL base64_decode(const std::string& input,
+ bool ignore_ws = true);
+
}
#endif
diff --git a/src/codec/hex/hex.cpp b/src/codec/hex/hex.cpp
index 49d6e7190..41ba1298d 100644
--- a/src/codec/hex/hex.cpp
+++ b/src/codec/hex/hex.cpp
@@ -37,9 +37,7 @@ void hex_encode(char output[],
std::string hex_encode(const MemoryRegion<byte>& input,
bool uppercase)
{
- return hex_encode(&input[0],
- input.size(),
- uppercase);
+ return hex_encode(&input[0], input.size(), uppercase);
}
std::string hex_encode(const byte input[],
@@ -47,7 +45,10 @@ std::string hex_encode(const byte input[],
bool uppercase)
{
std::string output(2 * input_length, 0);
- hex_encode(&output[0], input, input_length, uppercase);
+
+ if(input_length)
+ hex_encode(&output[0], input, input_length, uppercase);
+
return output;
}
diff --git a/src/constructs/srp6/info.txt b/src/constructs/srp6/info.txt
new file mode 100644
index 000000000..7962bd383
--- /dev/null
+++ b/src/constructs/srp6/info.txt
@@ -0,0 +1,7 @@
+define SRP6
+
+<requires>
+bigint
+hash
+dl_group
+</requires>
diff --git a/src/constructs/srp6/srp6.cpp b/src/constructs/srp6/srp6.cpp
new file mode 100644
index 000000000..287f0bdfb
--- /dev/null
+++ b/src/constructs/srp6/srp6.cpp
@@ -0,0 +1,156 @@
+/*
+* SRP-6a
+* (C) 2011 Jack Lloyd
+*
+* Distributed under the terms of the Botan license
+*/
+
+#include <botan/srp6.h>
+#include <botan/dl_group.h>
+#include <botan/libstate.h>
+#include <botan/numthry.h>
+#include <memory>
+
+namespace Botan {
+
+namespace {
+
+BigInt hash_seq(const std::string& hash_id,
+ size_t pad_to,
+ const BigInt& in1,
+ const BigInt& in2)
+ {
+ std::auto_ptr<HashFunction> hash_fn(
+ global_state().algorithm_factory().make_hash_function(hash_id));
+
+ hash_fn->update(BigInt::encode_1363(in1, pad_to));
+ hash_fn->update(BigInt::encode_1363(in2, pad_to));
+
+ return BigInt::decode(hash_fn->final());
+ }
+
+BigInt hash_seq(const std::string& hash_id,
+ size_t pad_to,
+ const BigInt& in1,
+ const BigInt& in2,
+ const BigInt& in3)
+ {
+ std::auto_ptr<HashFunction> hash_fn(
+ global_state().algorithm_factory().make_hash_function(hash_id));
+
+ hash_fn->update(BigInt::encode_1363(in1, pad_to));
+ hash_fn->update(BigInt::encode_1363(in2, pad_to));
+ hash_fn->update(BigInt::encode_1363(in3, pad_to));
+
+ return BigInt::decode(hash_fn->final());
+ }
+
+BigInt compute_x(const std::string& hash_id,
+ const std::string& identifier,
+ const std::string& password,
+ const MemoryRegion<byte>& salt)
+ {
+ std::auto_ptr<HashFunction> hash_fn(
+ global_state().algorithm_factory().make_hash_function(hash_id));
+
+ hash_fn->update(identifier);
+ hash_fn->update(":");
+ hash_fn->update(password);
+
+ SecureVector<byte> inner_h = hash_fn->final();
+
+ hash_fn->update(salt);
+ hash_fn->update(inner_h);
+
+ SecureVector<byte> outer_h = hash_fn->final();
+
+ return BigInt::decode(outer_h);
+ }
+
+}
+
+std::pair<BigInt, SymmetricKey>
+SRP6_Client_Session:: step1(const std::string& identifier,
+ const std::string& password,
+ const std::string& group_id,
+ const std::string& hash_id,
+ const MemoryRegion<byte>& salt,
+ const BigInt& B,
+ RandomNumberGenerator& rng)
+ {
+ DL_Group group(group_id);
+ const BigInt& g = group.get_g();
+ const BigInt& p = group.get_p();
+
+ const size_t p_bytes = group.get_p().bytes();
+
+ if(B % p == 0)
+ throw std::runtime_error("Invalid SRP parameter from server");
+
+ BigInt k = hash_seq(hash_id, p_bytes, p, g);
+
+ BigInt a(rng, p.bits() - 1);
+
+ BigInt A = power_mod(g, a, p);
+
+ BigInt u = hash_seq(hash_id, p_bytes, A, B);
+
+ const BigInt x = compute_x(hash_id, identifier, password, salt);
+
+ BigInt S = power_mod((B - (k * power_mod(g, x, p))) % p, (a + (u * x)), p);
+
+ SymmetricKey Sk(BigInt::encode_1363(S, p_bytes));
+
+ return std::make_pair(A, Sk);
+ }
+
+BigInt SRP6_Client_Session::generate_verifier(const std::string& identifier,
+ const std::string& password,
+ const MemoryRegion<byte>& salt,
+ const std::string& group_id,
+ const std::string& hash_id)
+ {
+ const BigInt x = compute_x(hash_id, identifier, password, salt);
+
+ DL_Group group(group_id);
+ return power_mod(group.get_g(), x, group.get_p());
+ }
+
+BigInt SRP6_Server_Session::step1(const BigInt& v,
+ const std::string& group_id,
+ const std::string& hash_id,
+ RandomNumberGenerator& rng)
+ {
+ DL_Group group(group_id);
+ const BigInt& g = group.get_g();
+ const BigInt& p = group.get_p();
+
+ p_bytes = p.bytes();
+
+ BigInt k = hash_seq(hash_id, p_bytes, p, g);
+
+ BigInt b(rng, p.bits() - 1);
+
+ B = (v*k + power_mod(g, b, p)) % p;
+
+ this->v = v;
+ this->b = b;
+ this->p = p;
+ this->hash_id = hash_id;
+
+ return B;
+ }
+
+SymmetricKey SRP6_Server_Session::step2(const BigInt& A)
+ {
+ if(A % p == 0)
+ throw std::runtime_error("Invalid SRP parameter from client");
+
+ BigInt u = hash_seq(hash_id, p_bytes, A, B);
+
+ BigInt S = power_mod(A * power_mod(v, u, p), b, p);
+
+ return BigInt::encode_1363(S, p_bytes);
+ }
+
+}
diff --git a/src/constructs/srp6/srp6.h b/src/constructs/srp6/srp6.h
new file mode 100644
index 000000000..01bd2a4c7
--- /dev/null
+++ b/src/constructs/srp6/srp6.h
@@ -0,0 +1,84 @@
+/*
+* SRP-6a (RFC 5054 compatatible)
+* (C) 2011 Jack Lloyd
+*
+* Distributed under the terms of the Botan license
+*/
+
+#ifndef BOTAN_RFC5054_SRP6_H__
+#define BOTAN_RFC5054_SRP6_H__
+
+#include <botan/bigint.h>
+#include <botan/hash.h>
+#include <botan/rng.h>
+#include <botan/symkey.h>
+#include <string>
+
+namespace Botan {
+
+/**
+* Represents a SRP-6a client session
+*/
+class BOTAN_DLL SRP6_Client_Session
+ {
+ public:
+
+ /**
+ * Client side step 1
+ * @param username the username we are attempting login for
+ * @param password the password we are attempting to use
+ * @param group_id specifies the shared SRP group
+ * @param hash_id specifies a secure hash function
+ * @param salt is the salt value sent by the server
+ * @param B is the server's public value
+ * @param rng is a random number generator
+ *
+ * @return (A,K) the client public key and the shared secret key
+ */
+ std::pair<BigInt,SymmetricKey> step1(const std::string& username,
+ const std::string& password,
+ const std::string& group_id,
+ const std::string& hash_id,
+ const MemoryRegion<byte>& salt,
+ const BigInt& B,
+ RandomNumberGenerator& rng);
+
+ /**
+ * Generate a new SRP-6 verifier
+ * @param identifier a username or other client identifier
+ * @param password the secret used to authenticate user
+ * @param salt a randomly chosen value, at least 128 bits long
+ */
+ static BigInt generate_verifier(const std::string& identifier,
+ const std::string& password,
+ const MemoryRegion<byte>& salt,
+ const std::string& group_id,
+ const std::string& hash_id);
+ };
+
+/**
+* Represents a SRP-6a server session
+*/
+class BOTAN_DLL SRP6_Server_Session
+ {
+ public:
+ /**
+ * Server side step 1
+ * @param v the verification value saved from client registration
+ */
+ BigInt step1(const BigInt& v,
+ const std::string& group_id,
+ const std::string& hash_id,
+ RandomNumberGenerator& rng);
+
+ SymmetricKey step2(const BigInt& A);
+
+ private:
+ std::string hash_id;
+ BigInt B, b, v, S, p;
+ size_t p_bytes;
+ };
+
+}
+
+#endif
diff --git a/src/constructs/srp6/srp6_files.cpp b/src/constructs/srp6/srp6_files.cpp
new file mode 100644
index 000000000..2d685614f
--- /dev/null
+++ b/src/constructs/srp6/srp6_files.cpp
@@ -0,0 +1,69 @@
+/*
+* SRP-6a File Handling
+* (C) 2011 Jack Lloyd
+*
+* Distributed under the terms of the Botan license
+*/
+
+#include <botan/srp6_files.h>
+#include <botan/parsing.h>
+#include <botan/base64.h>
+#include <fstream>
+
+namespace Botan {
+
+SRP6_Authenticator_File::SRP6_Authenticator_File(const std::string& filename)
+ {
+ std::ifstream in(filename.c_str());
+
+ if(!in)
+ return; // no entries
+
+ while(in.good())
+ {
+ std::string line;
+ std::getline(in, line);
+
+ std::vector<std::string> parts = split_on(line, ':');
+
+ if(parts.size() != 4)
+ throw Decoding_Error("Invalid line in SRP authenticator file");
+
+ std::string username = parts[0];
+ BigInt v = BigInt::decode(base64_decode(parts[1]));
+ MemoryVector<byte> salt = base64_decode(parts[2]);
+ BigInt group_id_idx = BigInt::decode(base64_decode(parts[3]));
+
+ std::string group_id;
+
+ if(group_id_idx == 1)
+ group_id = "modp/srp/1024";
+ else if(group_id_idx == 2)
+ group_id = "modp/srp/1536";
+ else if(group_id_idx == 3)
+ group_id = "modp/srp/2048";
+ else
+ continue; // unknown group, ignored
+
+ entries[username] = SRP6_Data(v, salt, group_id);
+ }
+ }
+
+bool SRP6_Authenticator_File::lookup_user(const std::string& username,
+ BigInt& v,
+ MemoryVector<byte>& salt,
+ std::string& group_id) const
+ {
+ std::map<std::string, SRP6_Data>::const_iterator i = entries.find(username);
+
+ if(i == entries.end())
+ return false;
+
+ v = i->second.v;
+ salt = i->second.salt;
+ group_id = i->second.group_id;
+
+ return true;
+ }
+
+}
diff --git a/src/constructs/srp6/srp6_files.h b/src/constructs/srp6/srp6_files.h
new file mode 100644
index 000000000..1def0fd51
--- /dev/null
+++ b/src/constructs/srp6/srp6_files.h
@@ -0,0 +1,53 @@
+/*
+* SRP-6a File Handling
+* (C) 2011 Jack Lloyd
+*
+* Distributed under the terms of the Botan license
+*/
+
+#ifndef BOTAN_SRP6A_FILES_H__
+#define BOTAN_SRP6A_FILES_H__
+
+#include <botan/bigint.h>
+#include <string>
+#include <map>
+
+namespace Botan {
+
+/**
+* A GnuTLS compatible SRP6 authenticator file
+*/
+class SRP6_Authenticator_File
+ {
+ public:
+ /**
+ * @param filename will be opened and processed as a SRP
+ * authenticator file
+ */
+ SRP6_Authenticator_File(const std::string& filename);
+
+ bool lookup_user(const std::string& username,
+ BigInt& v,
+ MemoryVector<byte>& salt,
+ std::string& group_id) const;
+ private:
+ struct SRP6_Data
+ {
+ SRP6_Data() {}
+
+ SRP6_Data(const BigInt& v,
+ const MemoryRegion<byte>& salt,
+ const std::string& group_id) :
+ v(v), salt(salt), group_id(group_id) {}
+
+ BigInt v;
+ MemoryVector<byte> salt;
+ std::string group_id;
+ };
+
+ std::map<std::string, SRP6_Data> entries;
+ };
+
+}
+
+#endif
diff --git a/src/engine/aes_isa_eng/aes_isa_engine.cpp b/src/engine/aes_isa_eng/aes_isa_engine.cpp
index 7f541d583..e56f6e9ca 100644
--- a/src/engine/aes_isa_eng/aes_isa_engine.cpp
+++ b/src/engine/aes_isa_eng/aes_isa_engine.cpp
@@ -8,8 +8,8 @@
#include <botan/internal/aes_isa_engine.h>
#include <botan/cpuid.h>
-#if defined(BOTAN_HAS_AES_INTEL)
- #include <botan/aes_intel.h>
+#if defined(BOTAN_HAS_AES_NI)
+ #include <botan/aes_ni.h>
#endif
namespace Botan {
@@ -18,15 +18,15 @@ BlockCipher*
AES_ISA_Engine::find_block_cipher(const SCAN_Name& request,
Algorithm_Factory&) const
{
-#if defined(BOTAN_HAS_AES_INTEL)
+#if defined(BOTAN_HAS_AES_NI)
if(CPUID::has_aes_ni())
{
if(request.algo_name() == "AES-128")
- return new AES_128_Intel;
+ return new AES_128_NI;
if(request.algo_name() == "AES-192")
- return new AES_192_Intel;
+ return new AES_192_NI;
if(request.algo_name() == "AES-256")
- return new AES_256_Intel;
+ return new AES_256_NI;
}
#endif
diff --git a/src/engine/core_engine/core_modes.cpp b/src/engine/core_engine/core_modes.cpp
index 035cd41c7..8a929e880 100644
--- a/src/engine/core_engine/core_modes.cpp
+++ b/src/engine/core_engine/core_modes.cpp
@@ -1,6 +1,6 @@
/*
* Core Engine
-* (C) 1999-2007 Jack Lloyd
+* (C) 1999-2007,2011 Jack Lloyd
*
* Distributed under the terms of the Botan license
*/
@@ -179,8 +179,8 @@ Keyed_Filter* get_cipher_mode(const BlockCipher* block_cipher,
* Get a cipher object
*/
Keyed_Filter* Core_Engine::get_cipher(const std::string& algo_spec,
- Cipher_Dir direction,
- Algorithm_Factory& af)
+ Cipher_Dir direction,
+ Algorithm_Factory& af)
{
std::vector<std::string> algo_parts = split_on(algo_spec, '/');
if(algo_parts.empty())
@@ -197,8 +197,12 @@ Keyed_Filter* Core_Engine::get_cipher(const std::string& algo_spec,
if(!block_cipher)
return 0;
- if(algo_parts.size() != 2 && algo_parts.size() != 3)
- return 0;
+ if(algo_parts.size() >= 4)
+ return 0; // 4 part mode, not something we know about
+
+ if(algo_parts.size() < 2)
+ throw Lookup_Error("Cipher specification '" + algo_spec +
+ "' is missing mode identifier");
std::string mode = algo_parts[1];
diff --git a/src/engine/core_engine/lookup_block.cpp b/src/engine/core_engine/lookup_block.cpp
index cc5239dd1..c27a13237 100644
--- a/src/engine/core_engine/lookup_block.cpp
+++ b/src/engine/core_engine/lookup_block.cpp
@@ -17,6 +17,10 @@
#include <botan/blowfish.h>
#endif
+#if defined(BOTAN_HAS_CAMELLIA)
+ #include <botan/camellia.h>
+#endif
+
#if defined(BOTAN_HAS_CAST)
#include <botan/cast128.h>
#include <botan/cast256.h>
@@ -130,6 +134,11 @@ BlockCipher* Core_Engine::find_block_cipher(const SCAN_Name& request,
return new Blowfish;
#endif
+#if defined(BOTAN_HAS_CAMELLIA)
+ if(request.algo_name() == "Camellia")
+ return new Camellia;
+#endif
+
#if defined(BOTAN_HAS_CAST)
if(request.algo_name() == "CAST-128")
return new CAST_128;
diff --git a/src/engine/simd_engine/info.txt b/src/engine/simd_engine/info.txt
index aaf218561..229b1daaf 100644
--- a/src/engine/simd_engine/info.txt
+++ b/src/engine/simd_engine/info.txt
@@ -11,5 +11,5 @@ simd_engine.h
</header:internal>
<requires>
-simd_32
+simd
</requires>
diff --git a/src/entropy/dev_random/dev_random.cpp b/src/entropy/dev_random/dev_random.cpp
index b15240aba..d14ae43ae 100644
--- a/src/entropy/dev_random/dev_random.cpp
+++ b/src/entropy/dev_random/dev_random.cpp
@@ -12,6 +12,7 @@
#include <sys/stat.h>
#include <unistd.h>
#include <fcntl.h>
+#include <string.h>
namespace Botan {
diff --git a/src/entropy/egd/es_egd.cpp b/src/entropy/egd/es_egd.cpp
index d2ce2706b..b2b629930 100644
--- a/src/entropy/egd/es_egd.cpp
+++ b/src/entropy/egd/es_egd.cpp
@@ -89,7 +89,7 @@ size_t EGD_EntropySource::EGD_Socket::read(byte outbuf[], size_t length)
throw std::runtime_error("Reading response length from EGD failed");
if(out_len > egd_read_command[1])
- throw std::runtime_error("Bogus length field recieved from EGD");
+ throw std::runtime_error("Bogus length field received from EGD");
ssize_t count = ::read(m_fd, outbuf, out_len);
diff --git a/src/entropy/hres_timer/hres_timer.cpp b/src/entropy/hres_timer/hres_timer.cpp
index 7313590e5..dd1fc6f7c 100644
--- a/src/entropy/hres_timer/hres_timer.cpp
+++ b/src/entropy/hres_timer/hres_timer.cpp
@@ -1,6 +1,6 @@
/*
* High Resolution Timestamp Entropy Source
-* (C) 1999-2009 Jack Lloyd
+* (C) 1999-2009,2011 Jack Lloyd
*
* Distributed under the terms of the Botan license
*/
@@ -22,9 +22,44 @@ void High_Resolution_Timestamp::poll(Entropy_Accumulator& accum)
{
// If Windows, grab the Performance Counter (usually TSC or PIT)
#if defined(BOTAN_TARGET_OS_IS_WINDOWS)
+ {
LARGE_INTEGER tv;
::QueryPerformanceCounter(&tv);
accum.add(tv.QuadPart, 0);
+ }
+#endif
+
+#if defined(BOTAN_TARGET_OS_HAS_CLOCK_GETTIME)
+
+#define CLOCK_POLL(src) \
+ do { \
+ struct timespec ts; \
+ clock_gettime(src, &ts); \
+ accum.add(&ts, sizeof(ts), 0); \
+ } while(0)
+
+#if defined(CLOCK_REALTIME)
+ CLOCK_POLL(CLOCK_REALTIME);
+#endif
+
+#if defined(CLOCK_MONOTONIC)
+ CLOCK_POLL(CLOCK_MONOTONIC);
+#endif
+
+#if defined(CLOCK_MONOTONIC_RAW)
+ CLOCK_POLL(CLOCK_MONOTONIC_RAW);
+#endif
+
+#if defined(CLOCK_PROCESS_CPUTIME_ID)
+ CLOCK_POLL(CLOCK_PROCESS_CPUTIME_ID);
+#endif
+
+#if defined(CLOCK_THREAD_CPUTIME_ID)
+ CLOCK_POLL(CLOCK_THREAD_CPUTIME_ID);
+#endif
+
+#undef CLOCK_POLL
+
#endif
#if BOTAN_USE_GCC_INLINE_ASM
diff --git a/src/entropy/hres_timer/hres_timer.h b/src/entropy/hres_timer/hres_timer.h
index c693b8d4e..8b95c8308 100644
--- a/src/entropy/hres_timer/hres_timer.h
+++ b/src/entropy/hres_timer/hres_timer.h
@@ -14,6 +14,9 @@ namespace Botan {
/**
* Entropy source using high resolution timers
+*
+* @note Any results from timers are marked as not contributing entropy
+* to the poll, as a local attacker could observe them directly.
*/
class High_Resolution_Timestamp : public EntropySource
{
diff --git a/src/entropy/unix_procs/unix_cmd.cpp b/src/entropy/unix_procs/unix_cmd.cpp
index f4ae5054c..930444075 100644
--- a/src/entropy/unix_procs/unix_cmd.cpp
+++ b/src/entropy/unix_procs/unix_cmd.cpp
@@ -12,6 +12,7 @@
#include <sys/time.h>
#include <sys/types.h>
#include <sys/wait.h>
+#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <signal.h>
diff --git a/src/filters/buf_filt.cpp b/src/filters/buf_filt.cpp
index b332d74b8..ca3fa9a3c 100644
--- a/src/filters/buf_filt.cpp
+++ b/src/filters/buf_filt.cpp
@@ -82,7 +82,7 @@ void Buffered_Filter::write(const byte input[], size_t input_size)
void Buffered_Filter::end_msg()
{
if(buffer_pos < final_minimum)
- throw std::runtime_error("Buffered_Operation::final - not enough input");
+ throw std::runtime_error("Buffered filter end_msg without enough input");
size_t spare_blocks = (buffer_pos - final_minimum) / main_block_mod;
diff --git a/src/filters/codec_filt/b64_filt.cpp b/src/filters/codec_filt/b64_filt.cpp
index 8a90f8b5f..9341571d4 100644
--- a/src/filters/codec_filt/b64_filt.cpp
+++ b/src/filters/codec_filt/b64_filt.cpp
@@ -14,32 +14,6 @@
namespace Botan {
/*
-* Base64 Decoder Lookup Table
-* Warning: assumes ASCII encodings
-*/
-static const byte BASE64_TO_BIN[256] = {
-0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
-0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
-0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
-0x80, 0x80, 0x80, 0x80, 0x3E, 0x80, 0x80, 0x80, 0x3F, 0x34, 0x35, 0x36, 0x37,
-0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
-0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C,
-0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19,
-0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20,
-0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D,
-0x2E, 0x2F, 0x30, 0x31, 0x32, 0x33, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
-0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
-0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
-0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
-0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
-0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
-0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
-0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
-0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
-0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
-0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80 };
-
-/*
* Base64_Encoder Constructor
*/
Base64_Encoder::Base64_Encoder(bool breaks, size_t length, bool t_n) :
@@ -68,6 +42,7 @@ void Base64_Encoder::encode_and_send(const byte input[], size_t length,
do_output(&out[0], produced);
+ // FIXME: s/proc/consumed/?
input += proc;
length -= proc;
}
@@ -138,58 +113,9 @@ void Base64_Encoder::end_msg()
/*
* Base64_Decoder Constructor
*/
-Base64_Decoder::Base64_Decoder(Decoder_Checking c) : checking(c)
- {
- in.resize(48);
- out.resize(3);
- position = 0;
- }
-
-/*
-* Check if a character is a valid Base64 char
-*/
-bool Base64_Decoder::is_valid(byte in)
- {
- return (BASE64_TO_BIN[in] != 0x80);
- }
-
-/*
-* Base64 Decoding Operation
-*/
-void Base64_Decoder::decode(const byte in[4], byte out[3])
- {
- out[0] = ((BASE64_TO_BIN[in[0]] << 2) | (BASE64_TO_BIN[in[1]] >> 4));
- out[1] = ((BASE64_TO_BIN[in[1]] << 4) | (BASE64_TO_BIN[in[2]] >> 2));
- out[2] = ((BASE64_TO_BIN[in[2]] << 6) | (BASE64_TO_BIN[in[3]]));
- }
-
-/*
-* Decode and send a block
-*/
-void Base64_Decoder::decode_and_send(const byte block[], size_t length)
- {
- for(size_t i = 0; i != length; i += 4)
- {
- decode(block + i, &out[0]);
- send(out, 3);
- }
- }
-
-/*
-* Handle processing an invalid character
-*/
-void Base64_Decoder::handle_bad_char(byte c)
+Base64_Decoder::Base64_Decoder(Decoder_Checking c) :
+ checking(c), in(64), out(48), position(0)
{
- if(c == '=' || checking == NONE)
- return;
-
- if((checking == IGNORE_WS) && Charset::is_space(c))
- return;
-
- throw Decoding_Error(
- std::string("Base64_Decoder: Invalid base64 character '") +
- static_cast<char>(c) + "'"
- );
}
/*
@@ -197,18 +123,32 @@ void Base64_Decoder::handle_bad_char(byte c)
*/
void Base64_Decoder::write(const byte input[], size_t length)
{
- for(size_t i = 0; i != length; ++i)
+ while(length)
{
- if(is_valid(input[i]))
- in[position++] = input[i];
- else
- handle_bad_char(input[i]);
+ size_t to_copy = std::min<size_t>(length, in.size() - position);
+ copy_mem(&in[position], input, to_copy);
+ position += to_copy;
+
+ size_t consumed = 0;
+ size_t written = base64_decode(&out[0],
+ reinterpret_cast<const char*>(&in[0]),
+ position,
+ consumed,
+ false,
+ checking != FULL_CHECK);
+
+ send(out, written);
- if(position == in.size())
+ if(consumed != position)
{
- decode_and_send(&in[0], in.size());
- position = 0;
+ copy_mem(&in[0], &in[consumed], position - consumed);
+ position = position - consumed;
}
+ else
+ position = 0;
+
+ length -= to_copy;
+ input += to_copy;
}
}
@@ -217,21 +157,22 @@ void Base64_Decoder::write(const byte input[], size_t length)
*/
void Base64_Decoder::end_msg()
{
- if(position != 0)
- {
- size_t start_of_last_block = 4 * (position / 4),
- left_over = position % 4;
- decode_and_send(&in[0], start_of_last_block);
+ size_t consumed = 0;
+ size_t written = base64_decode(&out[0],
+ reinterpret_cast<const char*>(&in[0]),
+ position,
+ consumed,
+ true,
+ checking != FULL_CHECK);
+
+ send(out, written);
+
+ const bool not_full_bytes = consumed != position;
- if(left_over)
- {
- SecureVector<byte> remainder(4);
- copy_mem(&remainder[0], &in[start_of_last_block], left_over);
- decode(&remainder[0], &out[0]);
- send(out, ((left_over == 1) ? (1) : (left_over - 1)));
- }
- }
position = 0;
+
+ if(not_full_bytes)
+ throw std::invalid_argument("Base64_Decoder: Input not full bytes");
}
}
diff --git a/src/filters/codec_filt/b64_filt.h b/src/filters/codec_filt/b64_filt.h
index df3896666..afff53f30 100644
--- a/src/filters/codec_filt/b64_filt.h
+++ b/src/filters/codec_filt/b64_filt.h
@@ -47,7 +47,7 @@ class BOTAN_DLL Base64_Encoder : public Filter
const size_t line_length;
const bool trailing_newline;
- SecureVector<byte> in, out;
+ MemoryVector<byte> in, out;
size_t position, out_position;
};
@@ -78,14 +78,8 @@ class BOTAN_DLL Base64_Decoder : public Filter
*/
Base64_Decoder(Decoder_Checking checking = NONE);
private:
- static void decode(const byte input[4], byte output[3]);
- static bool is_valid(byte c);
-
- void decode_and_send(const byte[], size_t);
- void handle_bad_char(byte);
-
const Decoder_Checking checking;
- SecureVector<byte> in, out;
+ MemoryVector<byte> in, out;
size_t position;
};
diff --git a/src/filters/codec_filt/hex_filt.h b/src/filters/codec_filt/hex_filt.h
index cfbb818d3..0dc38c804 100644
--- a/src/filters/codec_filt/hex_filt.h
+++ b/src/filters/codec_filt/hex_filt.h
@@ -49,7 +49,7 @@ class BOTAN_DLL Hex_Encoder : public Filter
const Case casing;
const size_t line_length;
- SecureVector<byte> in, out;
+ MemoryVector<byte> in, out;
size_t position, counter;
};
@@ -72,7 +72,7 @@ class BOTAN_DLL Hex_Decoder : public Filter
Hex_Decoder(Decoder_Checking checking = NONE);
private:
const Decoder_Checking checking;
- SecureVector<byte> in, out;
+ MemoryVector<byte> in, out;
size_t position;
};
diff --git a/src/hash/bmw/bmw_512.cpp b/src/hash/bmw_512/bmw_512.cpp
index 40338fdf0..40338fdf0 100644
--- a/src/hash/bmw/bmw_512.cpp
+++ b/src/hash/bmw_512/bmw_512.cpp
diff --git a/src/hash/bmw/bmw_512.h b/src/hash/bmw_512/bmw_512.h
index 474b607bb..474b607bb 100644
--- a/src/hash/bmw/bmw_512.h
+++ b/src/hash/bmw_512/bmw_512.h
diff --git a/src/hash/bmw/info.txt b/src/hash/bmw_512/info.txt
index 7170223d7..7170223d7 100644
--- a/src/hash/bmw/info.txt
+++ b/src/hash/bmw_512/info.txt
diff --git a/src/hash/sha1/sha160.cpp b/src/hash/sha1/sha160.cpp
index 7a42ca867..f5daaadb2 100644
--- a/src/hash/sha1/sha160.cpp
+++ b/src/hash/sha1/sha160.cpp
@@ -1,6 +1,6 @@
/*
* SHA-160
-* (C) 1999-2008 Jack Lloyd
+* (C) 1999-2008,2011 Jack Lloyd
*
* Distributed under the terms of the Botan license
*/
@@ -11,6 +11,8 @@
namespace Botan {
+namespace SHA1_F {
+
namespace {
/*
@@ -51,11 +53,15 @@ inline void F4(u32bit A, u32bit& B, u32bit C, u32bit D, u32bit& E, u32bit msg)
}
+}
+
/*
* SHA-160 Compression Function
*/
void SHA_160::compress_n(const byte input[], size_t blocks)
{
+ using namespace SHA1_F;
+
u32bit A = digest[0], B = digest[1], C = digest[2],
D = digest[3], E = digest[4];
diff --git a/src/hash/sha1_sse2/sha1_sse2.cpp b/src/hash/sha1_sse2/sha1_sse2.cpp
index e890967c6..f96afd9ce 100644
--- a/src/hash/sha1_sse2/sha1_sse2.cpp
+++ b/src/hash/sha1_sse2/sha1_sse2.cpp
@@ -1,6 +1,6 @@
/*
* SHA-1 using SSE2
-* (C) 2009-2010 Jack Lloyd
+* (C) 2009-2011 Jack Lloyd
*
* Distributed under the terms of the Botan license
*
@@ -14,6 +14,8 @@
namespace Botan {
+namespace SHA1_SSE2_F {
+
namespace {
/*
@@ -146,11 +148,15 @@ inline void F4(u32bit A, u32bit& B, u32bit C, u32bit D, u32bit& E, u32bit msg)
}
+}
+
/*
* SHA-160 Compression Function using SSE for message expansion
*/
void SHA_160_SSE2::compress_n(const byte input_bytes[], size_t blocks)
{
+ using namespace SHA1_SSE2_F;
+
const __m128i K00_19 = _mm_set1_epi32(0x5A827999);
const __m128i K20_39 = _mm_set1_epi32(0x6ED9EBA1);
const __m128i K40_59 = _mm_set1_epi32(0x8F1BBCDC);
@@ -323,4 +329,7 @@ void SHA_160_SSE2::compress_n(const byte input_bytes[], size_t blocks)
#undef GET_P_32
}
+#undef prep00_15
+#undef prep
+
}
diff --git a/src/hash/skein/skein_512.cpp b/src/hash/skein/skein_512.cpp
index f85968e84..571bf9c0b 100644
--- a/src/hash/skein/skein_512.cpp
+++ b/src/hash/skein/skein_512.cpp
@@ -184,6 +184,8 @@ Skein_512::Skein_512(size_t arg_output_bits,
std::string Skein_512::name() const
{
+ if(personalization != "")
+ return "Skein-512(" + to_string(output_bits) + "," + personalization + ")";
return "Skein-512(" + to_string(output_bits) + ")";
}
diff --git a/src/kdf/ssl_prf/info.txt b/src/kdf/prf_ssl3/info.txt
index 0ef297119..0ef297119 100644
--- a/src/kdf/ssl_prf/info.txt
+++ b/src/kdf/prf_ssl3/info.txt
diff --git a/src/kdf/ssl_prf/prf_ssl3.cpp b/src/kdf/prf_ssl3/prf_ssl3.cpp
index 72cf023e2..72cf023e2 100644
--- a/src/kdf/ssl_prf/prf_ssl3.cpp
+++ b/src/kdf/prf_ssl3/prf_ssl3.cpp
diff --git a/src/kdf/ssl_prf/prf_ssl3.h b/src/kdf/prf_ssl3/prf_ssl3.h
index b07454be2..b07454be2 100644
--- a/src/kdf/ssl_prf/prf_ssl3.h
+++ b/src/kdf/prf_ssl3/prf_ssl3.h
diff --git a/src/kdf/tls_prf/info.txt b/src/kdf/prf_tls/info.txt
index 9531a6a83..9531a6a83 100644
--- a/src/kdf/tls_prf/info.txt
+++ b/src/kdf/prf_tls/info.txt
diff --git a/src/kdf/tls_prf/prf_tls.cpp b/src/kdf/prf_tls/prf_tls.cpp
index 2b57cdd25..2b57cdd25 100644
--- a/src/kdf/tls_prf/prf_tls.cpp
+++ b/src/kdf/prf_tls/prf_tls.cpp
diff --git a/src/kdf/tls_prf/prf_tls.h b/src/kdf/prf_tls/prf_tls.h
index 5237f17c0..5237f17c0 100644
--- a/src/kdf/tls_prf/prf_tls.h
+++ b/src/kdf/prf_tls/prf_tls.h
diff --git a/src/kdf/x942_prf/info.txt b/src/kdf/prf_x942/info.txt
index e51aafd08..e51aafd08 100644
--- a/src/kdf/x942_prf/info.txt
+++ b/src/kdf/prf_x942/info.txt
diff --git a/src/kdf/x942_prf/prf_x942.cpp b/src/kdf/prf_x942/prf_x942.cpp
index fc31effe4..fc31effe4 100644
--- a/src/kdf/x942_prf/prf_x942.cpp
+++ b/src/kdf/prf_x942/prf_x942.cpp
diff --git a/src/kdf/x942_prf/prf_x942.h b/src/kdf/prf_x942/prf_x942.h
index e6093eda6..e6093eda6 100644
--- a/src/kdf/x942_prf/prf_x942.h
+++ b/src/kdf/prf_x942/prf_x942.h
diff --git a/src/libstate/policy.cpp b/src/libstate/policy.cpp
index 05ca6f807..f91eed1d8 100644
--- a/src/libstate/policy.cpp
+++ b/src/libstate/policy.cpp
@@ -302,6 +302,16 @@ void set_default_dl_groups(Library_State& config)
"Nf2tRM/S10+SCL4lj/MklDMo9nMpwP//////////"
"-----END X942 DH PARAMETERS-----");
+ config.set("dl", "modp/srp/1024",
+ "-----BEGIN X942 DH PARAMETERS-----"
+ "MIIBCgKBgQDurwq5rbON1pwz+Ar6j8XoYHJhh3X/PAueojFMnCVldtZ033SW6oHT"
+ "ODtIE9aSxuDg1djiULmL5I5JXB1gidrRXcfXtGFU1rbOjvStabFdSYJVmyl7zxiF"
+ "xSn1ZmYOV+xo7bw8BXJswC/Uy/SXbqqa/VE4/oN2Q1ufxh0vwOsG4wIBAgKBgHdX"
+ "hVzW2cbrThn8BX1H4vQwOTDDuv+eBc9RGKZOErK7azpvukt1QOmcHaQJ60ljcHBq"
+ "7HEoXMXyRySuDrBE7Wiu4+vaMKprW2dHela02K6kwSrNlL3njELilPqzMwcr9jR2"
+ "3h4CuTZgF+pl+ku3VU1+qJx/Qbshrc/jDpfgdYNx"
+ "-----END X942 DH PARAMETERS-----");
+
config.set("dl", "modp/ietf/1536",
"-----BEGIN X942 DH PARAMETERS-----"
"MIIBigKBwQD//////////8kP2qIhaMI0xMZii4DcHNEpAk4IimfMdAILvqY7E5si"
@@ -330,6 +340,21 @@ void set_default_dl_groups(Library_State& config)
"2uKu+DemKWTvFeX7SqwLjBzKpL51SrVyiukTDEx9AogKuUctRVZVNH//////////"
"-----END X942 DH PARAMETERS-----");
+ config.set("dl", "modp/srp/2048",
+ "-----BEGIN X942 DH PARAMETERS-----"
+ "MIICDAKCAQEArGvbQTJKmpvxZt5eE4lYL69ytmUZh+4H/DGSlD21YFCjcynLtKCZ"
+ "7YGT4HV3Z6E91SMSq0sDMQ3Nf0ip2gT9UOgIOWntt2ewz2CVF5oWOrNmGgX71fqq"
+ "6CkYqZYvC5O4Vfl5k+yXXuqoDXQK2/T/dHNZ0EHVwz6nHSgeRGsUdzvKl7Q6I/uA"
+ "Fna9IHpDbGSB8dK5B4cXRhpbnTLmiPh3SFRFI7UksNV9Xqd6J3XS7PoDLPvb9S+z"
+ "eGFgJ5AE5Xrmr4dOcwPOUymczAQce8MI2CpWmPOo0MOCca41+Onb+7aUtcgD2J96"
+ "5DXeI21SX1R1m2XjcvzWjvIPpxEfnkr/cwIBAgKCAQBWNe2gmSVNTfizby8JxKwX"
+ "17lbMozD9wP+GMlKHtqwKFG5lOXaUEz2wMnwOruz0J7qkYlVpYGYhua/pFTtAn6o"
+ "dAQctPbbs9hnsEqLzQsdWbMNAv3q/VV0FIxUyxeFydwq/LzJ9kuvdVQGugVt+n+6"
+ "OazoIOrhn1OOlA8iNYo7neVL2h0R/cALO16QPSG2MkD46VyDw4ujDS3OmXNEfDuk"
+ "KiKR2pJYar6vU70Tuul2fQGWfe36l9m8MLATyAJyvXNXw6c5gecplM5mAg494YRs"
+ "FStMedRoYcE41xr8dO3920pa5AHsT71yGu8RtqkvqjrNsvG5fmtHeQfTiI/PJX+5"
+ "-----END X942 DH PARAMETERS-----");
+
config.set("dl", "modp/ietf/3072",
"-----BEGIN X942 DH PARAMETERS-----"
"MIIDDAKCAYEA///////////JD9qiIWjCNMTGYouA3BzRKQJOCIpnzHQCC76mOxOb"
diff --git a/src/mac/cmac/cmac.cpp b/src/mac/cmac/cmac.cpp
index 7db597fff..baf22f4e8 100644
--- a/src/mac/cmac/cmac.cpp
+++ b/src/mac/cmac/cmac.cpp
@@ -16,7 +16,7 @@ namespace Botan {
SecureVector<byte> CMAC::poly_double(const MemoryRegion<byte>& in,
byte polynomial)
{
- const bool do_xor = (in[0] & 0x80) ? true : false;
+ const byte poly_xor = (in[0] & 0x80) ? polynomial : 0;
SecureVector<byte> out = in;
@@ -28,8 +28,7 @@ SecureVector<byte> CMAC::poly_double(const MemoryRegion<byte>& in,
carry = (temp >> 7);
}
- if(do_xor)
- out[out.size()-1] ^= polynomial;
+ out[out.size()-1] ^= poly_xor;
return out;
}
diff --git a/src/math/bigint/bigint.cpp b/src/math/bigint/bigint.cpp
index 6ee5a75e3..e2e062f2d 100644
--- a/src/math/bigint/bigint.cpp
+++ b/src/math/bigint/bigint.cpp
@@ -1,6 +1,6 @@
/*
* BigInt Base
-* (C) 1999-2008 Jack Lloyd
+* (C) 1999-2011 Jack Lloyd
*
* Distributed under the terms of the Botan license
*/
@@ -26,8 +26,8 @@ BigInt::BigInt(u64bit n)
const size_t limbs_needed = sizeof(u64bit) / sizeof(word);
reg.resize(4*limbs_needed);
- for(size_t j = 0; j != limbs_needed; ++j)
- reg[j] = ((n >> (j*MP_WORD_BITS)) & MP_WORD_MASK);
+ for(size_t i = 0; i != limbs_needed; ++i)
+ reg[i] = ((n >> (i*MP_WORD_BITS)) & MP_WORD_MASK);
}
/*
@@ -171,16 +171,35 @@ u32bit BigInt::get_substring(size_t offset, size_t length) const
throw Invalid_Argument("BigInt::get_substring: Substring size too big");
u64bit piece = 0;
- for(size_t j = 0; j != 8; ++j)
- piece = (piece << 8) | byte_at((offset / 8) + (7-j));
+ for(size_t i = 0; i != 8; ++i)
+ {
+ const byte part = byte_at((offset / 8) + (7-i));
+ piece = (piece << 8) | part;
+ }
- u64bit mask = (1 << length) - 1;
- size_t shift = (offset % 8);
+ const u64bit mask = (static_cast<u64bit>(1) << length) - 1;
+ const size_t shift = (offset % 8);
return static_cast<u32bit>((piece >> shift) & mask);
}
/*
+* Convert this number to a u32bit, if possible
+*/
+u32bit BigInt::to_u32bit() const
+ {
+ if(is_negative())
+ throw Encoding_Error("BigInt::to_u32bit: Number is negative");
+ if(bits() >= 32)
+ throw Encoding_Error("BigInt::to_u32bit: Number is too big to convert");
+
+ u32bit out = 0;
+ for(u32bit j = 0; j != 4; ++j)
+ out = (out << 8) | byte_at(3-j);
+ return out;
+ }
+
+/*
* Set bit number n
*/
void BigInt::set_bit(size_t n)
@@ -214,8 +233,8 @@ void BigInt::mask_bits(size_t n)
const word mask = (static_cast<word>(1) << (n % MP_WORD_BITS)) - 1;
if(top_word < size())
- for(size_t j = top_word + 1; j != size(); ++j)
- reg[j] = 0;
+ for(size_t i = top_word + 1; i != size(); ++i)
+ reg[i] = 0;
reg[top_word] &= mask;
}
@@ -321,8 +340,8 @@ BigInt BigInt::abs() const
void BigInt::binary_encode(byte output[]) const
{
const size_t sig_bytes = bytes();
- for(size_t j = 0; j != sig_bytes; ++j)
- output[sig_bytes-j-1] = byte_at(j);
+ for(size_t i = 0; i != sig_bytes; ++i)
+ output[sig_bytes-i-1] = byte_at(i);
}
/*
@@ -335,14 +354,15 @@ void BigInt::binary_decode(const byte buf[], size_t length)
clear();
reg.resize(round_up<size_t>((length / WORD_BYTES) + 1, 8));
- for(size_t j = 0; j != length / WORD_BYTES; ++j)
+ for(size_t i = 0; i != length / WORD_BYTES; ++i)
{
- size_t top = length - WORD_BYTES*j;
- for(size_t k = WORD_BYTES; k > 0; --k)
- reg[j] = (reg[j] << 8) | buf[top - k];
+ const size_t top = length - WORD_BYTES*i;
+ for(size_t j = WORD_BYTES; j > 0; --j)
+ reg[i] = (reg[i] << 8) | buf[top - j];
}
- for(size_t j = 0; j != length % WORD_BYTES; ++j)
- reg[length / WORD_BYTES] = (reg[length / WORD_BYTES] << 8) | buf[j];
+
+ for(size_t i = 0; i != length % WORD_BYTES; ++i)
+ reg[length / WORD_BYTES] = (reg[length / WORD_BYTES] << 8) | buf[i];
}
/*
diff --git a/src/math/bigint/bigint.h b/src/math/bigint/bigint.h
index 12a7f1701..87c7cb766 100644
--- a/src/math/bigint/bigint.h
+++ b/src/math/bigint/bigint.h
@@ -218,6 +218,13 @@ class BOTAN_DLL BigInt
u32bit get_substring(size_t offset, size_t length) const;
/**
+ * Convert this value into a u32bit, if it is in the range
+ * [0 ... 2**32-1], or otherwise throw an exception.
+ * @result the value as a u32bit if conversion is possible
+ */
+ u32bit to_u32bit() const;
+
+ /**
* @param n the offset to get a byte from
* @result byte at offset n
*/
diff --git a/src/math/numbertheory/curve_gfp.h b/src/math/ec_gfp/curve_gfp.h
index 1ab803ec9..9867f82fe 100644
--- a/src/math/numbertheory/curve_gfp.h
+++ b/src/math/ec_gfp/curve_gfp.h
@@ -2,7 +2,7 @@
* Elliptic curves over GF(p)
*
* (C) 2007 Martin Doering, Christoph Ludwig, Falko Strenzke
-* 2010 Jack Lloyd
+* 2010-2011 Jack Lloyd
*
* Distributed under the terms of the Botan license
*/
@@ -11,7 +11,6 @@
#define BOTAN_GFP_CURVE_H__
#include <botan/numthry.h>
-#include <botan/reducer.h>
namespace Botan {
@@ -34,18 +33,15 @@ class BOTAN_DLL CurveGFp
* @param b second coefficient
*/
CurveGFp(const BigInt& p, const BigInt& a, const BigInt& b) :
- p(p), a(a), b(b), reducer_p(p)
+ p(p), a(a), b(b), p_words(p.sig_words())
{
- r = 1;
- r <<= p.sig_words() * BOTAN_MP_WORD_BITS;
+ BigInt r(BigInt::Power2, p_words * BOTAN_MP_WORD_BITS);
- r_inv = inverse_mod(r, p);
+ p_dash = (((r * inverse_mod(r, p)) - 1) / p).word_at(0);
- p_dash = (((r * r_inv) - 1) / p).word_at(0);
-
- a_r = reducer_p.multiply(a, r);
-
- p_words = p.sig_words();
+ r2 = (r * r) % p;
+ a_r = (a * r) % p;
+ b_r = (b * r) % p;
}
// CurveGFp(const CurveGFp& other) = default;
@@ -68,19 +64,19 @@ class BOTAN_DLL CurveGFp
const BigInt& get_p() const { return p; }
/**
- * @return Montgomery parameter r
+ * @return Montgomery parameter r^2 % p
*/
- const BigInt& get_r() const { return r; }
+ const BigInt& get_r2() const { return r2; }
/**
- * @return Montgomery parameter r^-1
+ * @return a * r mod p
*/
- const BigInt& get_r_inv() const { return r_inv; }
+ const BigInt& get_a_r() const { return a_r; }
/**
- * @return a * r mod p
+ * @return b * r mod p
*/
- const BigInt& get_a_r() const { return a_r; }
+ const BigInt& get_b_r() const { return b_r; }
/**
* @return Montgomery parameter p-dash
@@ -93,23 +89,22 @@ class BOTAN_DLL CurveGFp
size_t get_p_words() const { return p_words; }
/**
- * @return modular reducer for p
- */
- const Modular_Reducer& mod_p() const { return reducer_p; }
-
- /**
* swaps the states of *this and other, does not throw
* @param other curve to swap values with
*/
void swap(CurveGFp& other)
{
+ std::swap(p, other.p);
+
std::swap(a, other.a);
std::swap(b, other.b);
- std::swap(p, other.p);
- std::swap(reducer_p, other.reducer_p);
- std::swap(r, other.r);
- std::swap(r_inv, other.r_inv);
+ std::swap(a_r, other.a_r);
+ std::swap(b_r, other.b_r);
+
+ std::swap(p_words, other.p_words);
+
+ std::swap(r2, other.r2);
std::swap(p_dash, other.p_dash);
}
@@ -120,7 +115,11 @@ class BOTAN_DLL CurveGFp
*/
bool operator==(const CurveGFp& other) const
{
- return (p == other.p && a == other.a && b == other.b);
+ /*
+ Relies on choice of R, but that is fixed by constructor based
+ on size of p
+ */
+ return (p == other.p && a_r == other.a_r && b_r == other.b_r);
}
private:
@@ -130,10 +129,8 @@ class BOTAN_DLL CurveGFp
size_t p_words; // cache of p.sig_words()
// Montgomery parameters
- BigInt r, r_inv, a_r;
+ BigInt r2, a_r, b_r;
word p_dash;
-
- Modular_Reducer reducer_p;
};
/**
diff --git a/src/math/ec_gfp/info.txt b/src/math/ec_gfp/info.txt
new file mode 100644
index 000000000..e6ee1d6bf
--- /dev/null
+++ b/src/math/ec_gfp/info.txt
@@ -0,0 +1,16 @@
+define EC_CURVE_GFP
+
+load_on auto
+
+<header:public>
+curve_gfp.h
+point_gfp.h
+</header:public>
+
+<source>
+point_gfp.cpp
+</source>
+
+<requires>
+numbertheory
+</requires>
diff --git a/src/math/numbertheory/point_gfp.cpp b/src/math/ec_gfp/point_gfp.cpp
index fab731d29..7ac6b4141 100644
--- a/src/math/numbertheory/point_gfp.cpp
+++ b/src/math/ec_gfp/point_gfp.cpp
@@ -1,40 +1,37 @@
/*
-* Arithmetic for point groups of elliptic curves over GF(p)
+* Point arithmetic on elliptic curves over GF(p)
*
* (C) 2007 Martin Doering, Christoph Ludwig, Falko Strenzke
-* 2008-2010 Jack Lloyd
+* 2008-2011 Jack Lloyd
*
* Distributed under the terms of the Botan license
*/
#include <botan/point_gfp.h>
#include <botan/numthry.h>
+#include <botan/reducer.h>
#include <botan/internal/mp_core.h>
namespace Botan {
PointGFp::PointGFp(const CurveGFp& curve) :
- curve(curve),
- coord_x(0),
- coord_y(curve.get_r()),
- coord_z(0)
+ curve(curve), ws(2 * (curve.get_p_words() + 2))
{
+ coord_x = 0;
+ coord_y = monty_mult(1, curve.get_r2());
+ coord_z = 0;
}
PointGFp::PointGFp(const CurveGFp& curve, const BigInt& x, const BigInt& y) :
- curve(curve)
+ curve(curve), ws(2 * (curve.get_p_words() + 2))
{
- const Modular_Reducer& mod_p = curve.mod_p();
-
- coord_x = mod_p.multiply(curve.get_r(), x);
- coord_y = mod_p.multiply(curve.get_r(), y);
- coord_z = mod_p.reduce(curve.get_r());
+ coord_x = monty_mult(x, curve.get_r2());
+ coord_y = monty_mult(y, curve.get_r2());
+ coord_z = monty_mult(1, curve.get_r2());
}
// Montgomery multiplication
-void PointGFp::monty_mult(BigInt& z,
- const BigInt& x, const BigInt& y,
- MemoryRegion<word>& workspace) const
+void PointGFp::monty_mult(BigInt& z, const BigInt& x, const BigInt& y) const
{
//assert(&z != &x && &z != &y);
@@ -52,19 +49,15 @@ void PointGFp::monty_mult(BigInt& z,
z_reg.resize(2*p_size+1);
zeroise(z_reg);
- bigint_mul(&z_reg[0], z_reg.size(),
- &workspace[0],
- x.data(), x.size(), x.sig_words(),
- y.data(), y.size(), y.sig_words());
-
- bigint_monty_redc(&z[0], z.size(),
- &workspace[0],
- p.data(), p_size, p_dash);
+ bigint_monty_mul(&z_reg[0], z_reg.size(),
+ x.data(), x.size(), x.sig_words(),
+ y.data(), y.size(), y.sig_words(),
+ p.data(), p_size, p_dash,
+ &ws[0]);
}
// Montgomery squaring
-void PointGFp::monty_sqr(BigInt& z, const BigInt& x,
- MemoryRegion<word>& workspace) const
+void PointGFp::monty_sqr(BigInt& z, const BigInt& x) const
{
//assert(&z != &x);
@@ -82,17 +75,14 @@ void PointGFp::monty_sqr(BigInt& z, const BigInt& x,
z_reg.resize(2*p_size+1);
zeroise(z_reg);
- bigint_sqr(&z[0], z.size(),
- &workspace[0],
- x.data(), x.size(), x.sig_words());
-
- bigint_monty_redc(&z[0], z.size(),
- &workspace[0],
- p.data(), p_size, p_dash);
+ bigint_monty_sqr(&z_reg[0], z_reg.size(),
+ x.data(), x.size(), x.sig_words(),
+ p.data(), p_size, p_dash,
+ &ws[0]);
}
// Point addition
-void PointGFp::add(const PointGFp& rhs, Workspace& workspace)
+void PointGFp::add(const PointGFp& rhs, std::vector<BigInt>& ws_bn)
{
if(is_zero())
{
@@ -106,9 +96,6 @@ void PointGFp::add(const PointGFp& rhs, Workspace& workspace)
const BigInt& p = curve.get_p();
- MemoryRegion<word>& ws = workspace.ws_monty;
- std::vector<BigInt>& ws_bn = workspace.ws_bn;
-
BigInt& rhs_z2 = ws_bn[0];
BigInt& U1 = ws_bn[1];
BigInt& S1 = ws_bn[2];
@@ -120,17 +107,13 @@ void PointGFp::add(const PointGFp& rhs, Workspace& workspace)
BigInt& H = ws_bn[6];
BigInt& r = ws_bn[7];
- BigInt& x = ws_bn[8];
- BigInt& y = ws_bn[9];
- BigInt& z = ws_bn[10];
+ monty_sqr(rhs_z2, rhs.coord_z);
+ monty_mult(U1, coord_x, rhs_z2);
+ monty_mult(S1, coord_y, monty_mult(rhs.coord_z, rhs_z2));
- monty_sqr(rhs_z2, rhs.coord_z, ws);
- monty_mult(U1, coord_x, rhs_z2, ws);
- monty_mult(S1, coord_y, monty_mult(rhs.coord_z, rhs_z2, ws), ws);
-
- monty_sqr(lhs_z2, coord_z, ws);
- monty_mult(U2, rhs.coord_x, lhs_z2, ws);
- monty_mult(S2, rhs.coord_y, monty_mult(coord_z, lhs_z2, ws), ws);
+ monty_sqr(lhs_z2, coord_z);
+ monty_mult(U2, rhs.coord_x, lhs_z2);
+ monty_mult(S2, rhs.coord_y, monty_mult(coord_z, lhs_z2));
H = U2;
H -= U1;
@@ -146,7 +129,7 @@ void PointGFp::add(const PointGFp& rhs, Workspace& workspace)
{
if(r.is_zero())
{
- mult2(workspace);
+ mult2(ws_bn);
return;
}
@@ -154,36 +137,32 @@ void PointGFp::add(const PointGFp& rhs, Workspace& workspace)
return;
}
- monty_sqr(U2, H, ws);
+ monty_sqr(U2, H);
- monty_mult(S2, U2, H, ws);
+ monty_mult(S2, U2, H);
- U2 = monty_mult(U1, U2, ws);
+ U2 = monty_mult(U1, U2);
- monty_sqr(x, r, ws);
- x -= S2;
- x -= (U2 << 1);
- while(x.is_negative())
- x += p;
+ monty_sqr(coord_x, r);
+ coord_x -= S2;
+ coord_x -= (U2 << 1);
+ while(coord_x.is_negative())
+ coord_x += p;
- U2 -= x;
+ U2 -= coord_x;
if(U2.is_negative())
U2 += p;
- monty_mult(y, r, U2, ws);
- y -= monty_mult(S1, S2, ws);
- if(y.is_negative())
- y += p;
-
- monty_mult(z, monty_mult(coord_z, rhs.coord_z, ws), H, ws);
+ monty_mult(coord_y, r, U2);
+ coord_y -= monty_mult(S1, S2);
+ if(coord_y.is_negative())
+ coord_y += p;
- coord_x = x;
- coord_y = y;
- coord_z = z;
+ monty_mult(coord_z, monty_mult(coord_z, rhs.coord_z), H);
}
// *this *= 2
-void PointGFp::mult2(Workspace& workspace)
+void PointGFp::mult2(std::vector<BigInt>& ws_bn)
{
if(is_zero())
return;
@@ -195,9 +174,6 @@ void PointGFp::mult2(Workspace& workspace)
const BigInt& p = curve.get_p();
- MemoryRegion<word>& ws = workspace.ws_monty;
- std::vector<BigInt>& ws_bn = workspace.ws_bn;
-
BigInt& y_2 = ws_bn[0];
BigInt& S = ws_bn[1];
BigInt& z4 = ws_bn[2];
@@ -208,27 +184,27 @@ void PointGFp::mult2(Workspace& workspace)
BigInt& y = ws_bn[7];
BigInt& z = ws_bn[8];
- monty_sqr(y_2, coord_y, ws);
+ monty_sqr(y_2, coord_y);
- monty_mult(S, coord_x, y_2, ws);
+ monty_mult(S, coord_x, y_2);
S <<= 2; // * 4
while(S >= p)
S -= p;
- monty_sqr(z4, monty_sqr(coord_z, ws), ws);
- monty_mult(a_z4, curve.get_a_r(), z4, ws);
+ monty_sqr(z4, monty_sqr(coord_z));
+ monty_mult(a_z4, curve.get_a_r(), z4);
- M = 3 * monty_sqr(coord_x, ws);
+ M = 3 * monty_sqr(coord_x);
M += a_z4;
while(M >= p)
M -= p;
- monty_sqr(x, M, ws);
+ monty_sqr(x, M);
x -= (S << 1);
while(x.is_negative())
x += p;
- monty_sqr(U, y_2, ws);
+ monty_sqr(U, y_2);
U <<= 3;
while(U >= p)
U -= p;
@@ -237,12 +213,12 @@ void PointGFp::mult2(Workspace& workspace)
while(S.is_negative())
S += p;
- monty_mult(y, M, S, ws);
+ monty_mult(y, M, S);
y -= U;
if(y.is_negative())
y += p;
- monty_mult(z, coord_y, coord_z, ws);
+ monty_mult(z, coord_y, coord_z);
z <<= 1;
if(z >= p)
z -= p;
@@ -255,7 +231,7 @@ void PointGFp::mult2(Workspace& workspace)
// arithmetic operators
PointGFp& PointGFp::operator+=(const PointGFp& rhs)
{
- Workspace ws(curve.get_p_words());
+ std::vector<BigInt> ws(9);
add(rhs, ws);
return *this;
}
@@ -278,6 +254,39 @@ PointGFp& PointGFp::operator*=(const BigInt& scalar)
return *this;
}
+PointGFp multi_exponentiate(const PointGFp& p1, const BigInt& z1,
+ const PointGFp& p2, const BigInt& z2)
+ {
+ const PointGFp p3 = p1 + p2;
+
+ PointGFp H(p1.curve); // create as zero
+ size_t bits_left = std::max(z1.bits(), z2.bits());
+
+ std::vector<BigInt> ws(9);
+
+ while(bits_left)
+ {
+ H.mult2(ws);
+
+ const bool z1_b = z1.get_bit(bits_left - 1);
+ const bool z2_b = z2.get_bit(bits_left - 1);
+
+ if(z1_b == true && z2_b == true)
+ H.add(p3, ws);
+ else if(z1_b)
+ H.add(p1, ws);
+ else if(z2_b)
+ H.add(p2, ws);
+
+ --bits_left;
+ }
+
+ if(z1.is_negative() != z2.is_negative())
+ H.negate();
+
+ return H;
+ }
+
PointGFp operator*(const BigInt& scalar, const PointGFp& point)
{
const CurveGFp& curve = point.get_curve();
@@ -285,7 +294,7 @@ PointGFp operator*(const BigInt& scalar, const PointGFp& point)
if(scalar.is_zero())
return PointGFp(curve); // zero point
- PointGFp::Workspace ws(curve.get_p_words());
+ std::vector<BigInt> ws(9);
if(scalar.abs() <= 2) // special cases for small values
{
@@ -304,6 +313,38 @@ PointGFp operator*(const BigInt& scalar, const PointGFp& point)
const size_t scalar_bits = scalar.bits();
+#if 0
+
+ PointGFp x1 = PointGFp(curve);
+ PointGFp x2 = point;
+
+ size_t bits_left = scalar_bits;
+
+ // Montgomery Ladder
+ while(bits_left)
+ {
+ const bool bit_set = scalar.get_bit(bits_left - 1);
+
+ if(bit_set)
+ {
+ x1.add(x2, ws);
+ x2.mult2(ws);
+ }
+ else
+ {
+ x2.add(x1, ws);
+ x1.mult2(ws);
+ }
+
+ --bits_left;
+ }
+
+ if(scalar.is_negative())
+ x1.negate();
+
+ return x1;
+
+#else
const size_t window_size = 4;
std::vector<PointGFp> Ps(1 << window_size);
@@ -345,6 +386,7 @@ PointGFp operator*(const BigInt& scalar, const PointGFp& point)
H.negate();
return H;
+#endif
}
BigInt PointGFp::get_affine_x() const
@@ -352,23 +394,13 @@ BigInt PointGFp::get_affine_x() const
if(is_zero())
throw Illegal_Transformation("Cannot convert zero point to affine");
- const Modular_Reducer& mod_p = curve.mod_p();
-
-#if 1
- BigInt x = mod_p.multiply(curve.get_r_inv(), coord_x);
- BigInt z = mod_p.multiply(curve.get_r_inv(), coord_z);
-
- BigInt z2 = mod_p.square(z);
- return mod_p.multiply(x, inverse_mod(z2, curve.get_p()));
-#else
-
- SecureVector<word> ws(2 * (curve.get_p_words() + 2));
+ const BigInt& r2 = curve.get_r2();
- BigInt z2 = monty_sqr(coord_z, ws);
+ BigInt z2 = monty_sqr(coord_z);
z2 = inverse_mod(z2, curve.get_p());
- z2 = mod_p.multiply(z2, curve.get_r());
- return monty_mult(coord_x, z2, ws);
-#endif
+
+ z2 = monty_mult(z2, r2);
+ return monty_mult(coord_x, z2);
}
BigInt PointGFp::get_affine_y() const
@@ -376,23 +408,12 @@ BigInt PointGFp::get_affine_y() const
if(is_zero())
throw Illegal_Transformation("Cannot convert zero point to affine");
- const Modular_Reducer& mod_p = curve.mod_p();
+ const BigInt& r2 = curve.get_r2();
-#if 1
- BigInt y = mod_p.multiply(curve.get_r_inv(), coord_y);
- BigInt z = mod_p.multiply(curve.get_r_inv(), coord_z);
-
- BigInt z3 = mod_p.cube(z);
- return mod_p.multiply(y, inverse_mod(z3, curve.get_p()));
-#else
-
- SecureVector<word> ws(2 * (curve.get_p_words() + 2));
-
- BigInt z3 = monty_mult(coord_z, monty_sqr(coord_z, ws), ws);
+ BigInt z3 = monty_mult(coord_z, monty_sqr(coord_z));
z3 = inverse_mod(z3, curve.get_p());
- z3 = mod_p.multiply(z3, curve.get_r());
- return monty_mult(coord_y, z3, ws);
-#endif
+ z3 = monty_mult(z3, r2);
+ return monty_mult(coord_y, z3);
}
bool PointGFp::on_the_curve() const
@@ -407,31 +428,28 @@ bool PointGFp::on_the_curve() const
if(is_zero())
return true;
- const Modular_Reducer& mod_p = curve.mod_p();
+ BigInt y2 = monty_mult(monty_sqr(coord_y), 1);
+ BigInt x3 = monty_mult(coord_x, monty_sqr(coord_x));
- BigInt x = mod_p.multiply(curve.get_r_inv(), coord_x);
- BigInt y = mod_p.multiply(curve.get_r_inv(), coord_y);
- BigInt z = mod_p.multiply(curve.get_r_inv(), coord_z);
+ BigInt ax = monty_mult(coord_x, curve.get_a_r());
- BigInt y2 = mod_p.square(y);
- BigInt x3 = mod_p.cube(x);
+ const BigInt& b_r = curve.get_b_r();
- BigInt ax = mod_p.multiply(x, curve.get_a());
+ BigInt z2 = monty_sqr(coord_z);
- if(z == 1)
+ if(coord_z == z2) // Is z equal to 1 (in Montgomery form)?
{
- if(mod_p.reduce(x3 + ax + curve.get_b()) != y2)
+ if(y2 != monty_mult(x3 + ax + b_r, 1))
return false;
}
- BigInt z2 = mod_p.square(z);
- BigInt z3 = mod_p.multiply(z, z2);
+ BigInt z3 = monty_mult(coord_z, z2);
- BigInt ax_z4 = mod_p.multiply(mod_p.multiply(z3, z), ax);
+ BigInt ax_z4 = monty_mult(ax, monty_sqr(z2));
- BigInt b_z6 = mod_p.multiply(curve.get_b(), mod_p.square(z3));
+ BigInt b_z6 = monty_mult(b_r, monty_sqr(z3));
- if(y2 != mod_p.reduce(x3 + ax_z4 + b_z6))
+ if(y2 != monty_mult(x3 + ax_z4 + b_z6, 1))
return false;
return true;
@@ -444,6 +462,7 @@ void PointGFp::swap(PointGFp& other)
coord_x.swap(other.coord_x);
coord_y.swap(other.coord_y);
coord_z.swap(other.coord_z);
+ ws.swap(other.ws);
}
bool PointGFp::operator==(const PointGFp& other) const
diff --git a/src/math/numbertheory/point_gfp.h b/src/math/ec_gfp/point_gfp.h
index 35ec6d503..b2b6fe2f0 100644
--- a/src/math/numbertheory/point_gfp.h
+++ b/src/math/ec_gfp/point_gfp.h
@@ -1,8 +1,8 @@
/*
-* Arithmetic for point groups of elliptic curves over GF(p)
+* Point arithmetic on elliptic curves over GF(p)
*
* (C) 2007 Martin Doering, Christoph Ludwig, Falko Strenzke
-* 2008-2010 Jack Lloyd
+* 2008-2011 Jack Lloyd
*
* Distributed under the terms of the Botan license
*/
@@ -99,6 +99,18 @@ class BOTAN_DLL PointGFp
friend BOTAN_DLL PointGFp operator*(const BigInt& scalar, const PointGFp& point);
/**
+ * Multiexponentiation
+ * @param p1 a point
+ * @param z1 a scalar
+ * @param p2 a point
+ * @param z2 a scalar
+ * @result (p1 * z1 + p2 * z2)
+ */
+ friend BOTAN_DLL PointGFp multi_exponentiate(
+ const PointGFp& p1, const BigInt& z1,
+ const PointGFp& p2, const BigInt& z2);
+
+ /**
* Negate this point
* @return *this
*/
@@ -153,27 +165,16 @@ class BOTAN_DLL PointGFp
bool operator==(const PointGFp& other) const;
private:
- class Workspace
- {
- public:
- Workspace(size_t p_words) :
- ws_monty(2*(p_words+2)), ws_bn(12) {}
-
- SecureVector<word> ws_monty;
- std::vector<BigInt> ws_bn;
- };
-
/**
* Montgomery multiplication/reduction
* @param x first multiplicand
* @param y second multiplicand
* @param workspace temp space
*/
- BigInt monty_mult(const BigInt& x, const BigInt& y,
- MemoryRegion<word>& workspace) const
+ BigInt monty_mult(const BigInt& x, const BigInt& y) const
{
BigInt result;
- monty_mult(result, x, y, workspace);
+ monty_mult(result, x, y);
return result;
}
@@ -183,22 +184,17 @@ class BOTAN_DLL PointGFp
* @param z output
* @param x first multiplicand
* @param y second multiplicand
- * @param workspace temp space
*/
- void monty_mult(BigInt& z,
- const BigInt& x, const BigInt& y,
- MemoryRegion<word>& workspace) const;
+ void monty_mult(BigInt& z, const BigInt& x, const BigInt& y) const;
/**
* Montgomery squaring/reduction
* @param x multiplicand
- * @param workspace temp space
*/
- BigInt monty_sqr(const BigInt& x,
- MemoryRegion<word>& workspace) const
+ BigInt monty_sqr(const BigInt& x) const
{
BigInt result;
- monty_sqr(result, x, workspace);
+ monty_sqr(result, x);
return result;
}
@@ -207,24 +203,24 @@ class BOTAN_DLL PointGFp
* @warning z cannot alias x
* @param z output
* @param x multiplicand
- * @param workspace temp space
*/
- void monty_sqr(BigInt& z, const BigInt& x,
- MemoryRegion<word>& workspace) const;
+ void monty_sqr(BigInt& z, const BigInt& x) const;
/**
* Point addition
+ * @param workspace temp space, at least 11 elements
*/
- void add(const PointGFp& other, Workspace& workspace);
+ void add(const PointGFp& other, std::vector<BigInt>& workspace);
/**
* Point doubling
- * @param workspace temp space
+ * @param workspace temp space, at least 9 elements
*/
- void mult2(Workspace& workspace);
+ void mult2(std::vector<BigInt>& workspace);
CurveGFp curve;
BigInt coord_x, coord_y, coord_z;
+ mutable SecureVector<word> ws; // workspace for Montgomery
};
// relational operators
diff --git a/src/math/mp/info.txt b/src/math/mp/info.txt
index 911093699..bf7f40d3c 100644
--- a/src/math/mp/info.txt
+++ b/src/math/mp/info.txt
@@ -4,6 +4,8 @@ define BIGINT_MP
mp_asm.cpp
mp_comba.cpp
mp_karat.cpp
+mp_monty.cpp
+mp_mulop.cpp
mp_misc.cpp
mp_shift.cpp
</source>
@@ -18,6 +20,4 @@ mp_core.h
<requires>
mp_x86_64|mp_msvc64|mp_asm64|mp_x86_32|mp_x86_32_msvc|mp_generic
-monty_generic
-mulop_generic
</requires>
diff --git a/src/math/mp/monty_generic/info.txt b/src/math/mp/monty_generic/info.txt
deleted file mode 100644
index cd05ccdc0..000000000
--- a/src/math/mp/monty_generic/info.txt
+++ /dev/null
@@ -1,5 +0,0 @@
-load_on dep
-
-<source>
-mp_monty.cpp
-</source>
diff --git a/src/math/mp/monty_generic/mp_monty.cpp b/src/math/mp/monty_generic/mp_monty.cpp
deleted file mode 100644
index d7f7e0306..000000000
--- a/src/math/mp/monty_generic/mp_monty.cpp
+++ /dev/null
@@ -1,72 +0,0 @@
-/*
-* Montgomery Reduction
-* (C) 1999-2010 Jack Lloyd
-* 2006 Luca Piccarreta
-*
-* Distributed under the terms of the Botan license
-*/
-
-#include <botan/internal/mp_core.h>
-#include <botan/internal/mp_asm.h>
-#include <botan/internal/mp_asmi.h>
-#include <botan/mem_ops.h>
-
-namespace Botan {
-
-extern "C" {
-
-/*
-* Montgomery Reduction Algorithm
-*/
-void bigint_monty_redc(word z[], size_t z_size,
- word ws[],
- const word x[], size_t x_size,
- word u)
- {
- const size_t blocks_of_8 = x_size - (x_size % 8);
-
- for(size_t i = 0; i != x_size; ++i)
- {
- word* z_i = z + i;
-
- const word y = z_i[0] * u;
-
- /*
- bigint_linmul3(ws, x, x_size, y);
- bigint_add2(z_i, z_size - i, ws, x_size+1);
- */
- word carry = 0;
-
- for(size_t j = 0; j != blocks_of_8; j += 8)
- carry = word8_madd3(z_i + j, x + j, y, carry);
-
- for(size_t j = blocks_of_8; j != x_size; ++j)
- z_i[j] = word_madd3(x[j], y, z_i[j], &carry);
-
- word z_sum = z_i[x_size] + carry;
- carry = (z_sum < z_i[x_size]);
- z_i[x_size] = z_sum;
-
- // Note: not constant time
- for(size_t j = x_size + 1; carry && j != z_size - i; ++j)
- {
- ++z_i[j];
- carry = !z_i[j];
- }
- }
-
- word borrow = 0;
- for(size_t i = 0; i != x_size; ++i)
- ws[i] = word_sub(z[x_size + i], x[i], &borrow);
-
- ws[x_size] = word_sub(z[x_size+x_size], 0, &borrow);
-
- copy_mem(ws + x_size + 1, z + x_size, x_size + 1);
-
- copy_mem(z, ws + borrow*(x_size+1), x_size + 1);
- clear_mem(z + x_size + 1, z_size - x_size - 1);
- }
-
-}
-
-}
diff --git a/src/math/mp/mp_asm.cpp b/src/math/mp/mp_asm.cpp
index d164c1d33..3ba52c4b1 100644
--- a/src/math/mp/mp_asm.cpp
+++ b/src/math/mp/mp_asm.cpp
@@ -67,7 +67,8 @@ word bigint_add3_nc(word z[], const word x[], size_t x_size,
*/
void bigint_add2(word x[], size_t x_size, const word y[], size_t y_size)
{
- x[x_size] += bigint_add2_nc(x, x_size, y, y_size);
+ if(bigint_add2_nc(x, x_size, y, y_size))
+ x[x_size] += 1;
}
/*
diff --git a/src/math/mp/mp_asm64/info.txt b/src/math/mp/mp_asm64/info.txt
index 42363e8b0..9af7c4ae7 100644
--- a/src/math/mp/mp_asm64/info.txt
+++ b/src/math/mp/mp_asm64/info.txt
@@ -20,5 +20,5 @@ sparc64
# win, so it's probably worth using elsewhere.
<cc>
gcc
-sunwspro
+sunstudio
</cc>
diff --git a/src/math/mp/mp_comba.cpp b/src/math/mp/mp_comba.cpp
index 2770d3f0a..99dcda176 100644
--- a/src/math/mp/mp_comba.cpp
+++ b/src/math/mp/mp_comba.cpp
@@ -1,6 +1,6 @@
/*
* Comba Multiplication and Squaring
-* (C) 1999-2007 Jack Lloyd
+* (C) 1999-2007,2011 Jack Lloyd
*
* Distributed under the terms of the Botan license
*/
@@ -19,30 +19,30 @@ void bigint_comba_sqr4(word z[8], const word x[4])
{
word w2 = 0, w1 = 0, w0 = 0;
- word3_muladd(&w2, &w1, &w0, x[0], x[0]);
- z[0] = w0; w0 = w1; w1 = w2; w2 = 0;
+ word3_muladd(&w2, &w1, &w0, x[ 0], x[ 0]);
+ z[ 0] = w0; w0 = 0;
- word3_muladd_2(&w2, &w1, &w0, x[0], x[1]);
- z[1] = w0; w0 = w1; w1 = w2; w2 = 0;
+ word3_muladd_2(&w0, &w2, &w1, x[ 0], x[ 1]);
+ z[ 1] = w1; w1 = 0;
- word3_muladd_2(&w2, &w1, &w0, x[0], x[2]);
- word3_muladd(&w2, &w1, &w0, x[1], x[1]);
- z[2] = w0; w0 = w1; w1 = w2; w2 = 0;
+ word3_muladd_2(&w1, &w0, &w2, x[ 0], x[ 2]);
+ word3_muladd(&w1, &w0, &w2, x[ 1], x[ 1]);
+ z[ 2] = w2; w2 = 0;
- word3_muladd_2(&w2, &w1, &w0, x[0], x[3]);
- word3_muladd_2(&w2, &w1, &w0, x[1], x[2]);
- z[3] = w0; w0 = w1; w1 = w2; w2 = 0;
+ word3_muladd_2(&w2, &w1, &w0, x[ 0], x[ 3]);
+ word3_muladd_2(&w2, &w1, &w0, x[ 1], x[ 2]);
+ z[ 3] = w0; w0 = 0;
- word3_muladd_2(&w2, &w1, &w0, x[1], x[3]);
- word3_muladd(&w2, &w1, &w0, x[2], x[2]);
- z[4] = w0; w0 = w1; w1 = w2; w2 = 0;
+ word3_muladd_2(&w0, &w2, &w1, x[ 1], x[ 3]);
+ word3_muladd(&w0, &w2, &w1, x[ 2], x[ 2]);
+ z[ 4] = w1; w1 = 0;
- word3_muladd_2(&w2, &w1, &w0, x[2], x[3]);
- z[5] = w0; w0 = w1; w1 = w2; w2 = 0;
+ word3_muladd_2(&w1, &w0, &w2, x[ 2], x[ 3]);
+ z[ 5] = w2; w2 = 0;
- word3_muladd(&w2, &w1, &w0, x[3], x[3]);
- z[6] = w0;
- z[7] = w1;
+ word3_muladd(&w2, &w1, &w0, x[ 3], x[ 3]);
+ z[ 6] = w0;
+ z[ 7] = w1;
}
/*
@@ -52,36 +52,36 @@ void bigint_comba_mul4(word z[8], const word x[4], const word y[4])
{
word w2 = 0, w1 = 0, w0 = 0;
- word3_muladd(&w2, &w1, &w0, x[0], y[0]);
- z[0] = w0; w0 = w1; w1 = w2; w2 = 0;
+ word3_muladd(&w2, &w1, &w0, x[ 0], y[ 0]);
+ z[ 0] = w0; w0 = 0;
- word3_muladd(&w2, &w1, &w0, x[0], y[1]);
- word3_muladd(&w2, &w1, &w0, x[1], y[0]);
- z[1] = w0; w0 = w1; w1 = w2; w2 = 0;
+ word3_muladd(&w0, &w2, &w1, x[ 0], y[ 1]);
+ word3_muladd(&w0, &w2, &w1, x[ 1], y[ 0]);
+ z[ 1] = w1; w1 = 0;
- word3_muladd(&w2, &w1, &w0, x[0], y[2]);
- word3_muladd(&w2, &w1, &w0, x[1], y[1]);
- word3_muladd(&w2, &w1, &w0, x[2], y[0]);
- z[2] = w0; w0 = w1; w1 = w2; w2 = 0;
+ word3_muladd(&w1, &w0, &w2, x[ 0], y[ 2]);
+ word3_muladd(&w1, &w0, &w2, x[ 1], y[ 1]);
+ word3_muladd(&w1, &w0, &w2, x[ 2], y[ 0]);
+ z[ 2] = w2; w2 = 0;
- word3_muladd(&w2, &w1, &w0, x[0], y[3]);
- word3_muladd(&w2, &w1, &w0, x[1], y[2]);
- word3_muladd(&w2, &w1, &w0, x[2], y[1]);
- word3_muladd(&w2, &w1, &w0, x[3], y[0]);
- z[3] = w0; w0 = w1; w1 = w2; w2 = 0;
+ word3_muladd(&w2, &w1, &w0, x[ 0], y[ 3]);
+ word3_muladd(&w2, &w1, &w0, x[ 1], y[ 2]);
+ word3_muladd(&w2, &w1, &w0, x[ 2], y[ 1]);
+ word3_muladd(&w2, &w1, &w0, x[ 3], y[ 0]);
+ z[ 3] = w0; w0 = 0;
- word3_muladd(&w2, &w1, &w0, x[1], y[3]);
- word3_muladd(&w2, &w1, &w0, x[2], y[2]);
- word3_muladd(&w2, &w1, &w0, x[3], y[1]);
- z[4] = w0; w0 = w1; w1 = w2; w2 = 0;
+ word3_muladd(&w0, &w2, &w1, x[ 1], y[ 3]);
+ word3_muladd(&w0, &w2, &w1, x[ 2], y[ 2]);
+ word3_muladd(&w0, &w2, &w1, x[ 3], y[ 1]);
+ z[ 4] = w1; w1 = 0;
- word3_muladd(&w2, &w1, &w0, x[2], y[3]);
- word3_muladd(&w2, &w1, &w0, x[3], y[2]);
- z[5] = w0; w0 = w1; w1 = w2; w2 = 0;
+ word3_muladd(&w1, &w0, &w2, x[ 2], y[ 3]);
+ word3_muladd(&w1, &w0, &w2, x[ 3], y[ 2]);
+ z[ 5] = w2; w2 = 0;
- word3_muladd(&w2, &w1, &w0, x[3], y[3]);
- z[6] = w0;
- z[7] = w1;
+ word3_muladd(&w2, &w1, &w0, x[ 3], y[ 3]);
+ z[ 6] = w0;
+ z[ 7] = w1;
}
/*
@@ -91,49 +91,49 @@ void bigint_comba_sqr6(word z[12], const word x[6])
{
word w2 = 0, w1 = 0, w0 = 0;
- word3_muladd(&w2, &w1, &w0, x[0], x[0]);
- z[0] = w0; w0 = w1; w1 = w2; w2 = 0;
+ word3_muladd(&w2, &w1, &w0, x[ 0], x[ 0]);
+ z[ 0] = w0; w0 = 0;
- word3_muladd_2(&w2, &w1, &w0, x[0], x[1]);
- z[1] = w0; w0 = w1; w1 = w2; w2 = 0;
+ word3_muladd_2(&w0, &w2, &w1, x[ 0], x[ 1]);
+ z[ 1] = w1; w1 = 0;
- word3_muladd_2(&w2, &w1, &w0, x[0], x[2]);
- word3_muladd(&w2, &w1, &w0, x[1], x[1]);
- z[2] = w0; w0 = w1; w1 = w2; w2 = 0;
+ word3_muladd_2(&w1, &w0, &w2, x[ 0], x[ 2]);
+ word3_muladd(&w1, &w0, &w2, x[ 1], x[ 1]);
+ z[ 2] = w2; w2 = 0;
- word3_muladd_2(&w2, &w1, &w0, x[0], x[3]);
- word3_muladd_2(&w2, &w1, &w0, x[1], x[2]);
- z[3] = w0; w0 = w1; w1 = w2; w2 = 0;
+ word3_muladd_2(&w2, &w1, &w0, x[ 0], x[ 3]);
+ word3_muladd_2(&w2, &w1, &w0, x[ 1], x[ 2]);
+ z[ 3] = w0; w0 = 0;
- word3_muladd_2(&w2, &w1, &w0, x[0], x[4]);
- word3_muladd_2(&w2, &w1, &w0, x[1], x[3]);
- word3_muladd(&w2, &w1, &w0, x[2], x[2]);
- z[4] = w0; w0 = w1; w1 = w2; w2 = 0;
+ word3_muladd_2(&w0, &w2, &w1, x[ 0], x[ 4]);
+ word3_muladd_2(&w0, &w2, &w1, x[ 1], x[ 3]);
+ word3_muladd(&w0, &w2, &w1, x[ 2], x[ 2]);
+ z[ 4] = w1; w1 = 0;
- word3_muladd_2(&w2, &w1, &w0, x[0], x[5]);
- word3_muladd_2(&w2, &w1, &w0, x[1], x[4]);
- word3_muladd_2(&w2, &w1, &w0, x[2], x[3]);
- z[5] = w0; w0 = w1; w1 = w2; w2 = 0;
+ word3_muladd_2(&w1, &w0, &w2, x[ 0], x[ 5]);
+ word3_muladd_2(&w1, &w0, &w2, x[ 1], x[ 4]);
+ word3_muladd_2(&w1, &w0, &w2, x[ 2], x[ 3]);
+ z[ 5] = w2; w2 = 0;
- word3_muladd_2(&w2, &w1, &w0, x[1], x[5]);
- word3_muladd_2(&w2, &w1, &w0, x[2], x[4]);
- word3_muladd(&w2, &w1, &w0, x[3], x[3]);
- z[6] = w0; w0 = w1; w1 = w2; w2 = 0;
+ word3_muladd_2(&w2, &w1, &w0, x[ 1], x[ 5]);
+ word3_muladd_2(&w2, &w1, &w0, x[ 2], x[ 4]);
+ word3_muladd(&w2, &w1, &w0, x[ 3], x[ 3]);
+ z[ 6] = w0; w0 = 0;
- word3_muladd_2(&w2, &w1, &w0, x[2], x[5]);
- word3_muladd_2(&w2, &w1, &w0, x[3], x[4]);
- z[7] = w0; w0 = w1; w1 = w2; w2 = 0;
+ word3_muladd_2(&w0, &w2, &w1, x[ 2], x[ 5]);
+ word3_muladd_2(&w0, &w2, &w1, x[ 3], x[ 4]);
+ z[ 7] = w1; w1 = 0;
- word3_muladd_2(&w2, &w1, &w0, x[3], x[5]);
- word3_muladd(&w2, &w1, &w0, x[4], x[4]);
- z[8] = w0; w0 = w1; w1 = w2; w2 = 0;
+ word3_muladd_2(&w1, &w0, &w2, x[ 3], x[ 5]);
+ word3_muladd(&w1, &w0, &w2, x[ 4], x[ 4]);
+ z[ 8] = w2; w2 = 0;
- word3_muladd_2(&w2, &w1, &w0, x[4], x[5]);
- z[9] = w0; w0 = w1; w1 = w2; w2 = 0;
+ word3_muladd_2(&w2, &w1, &w0, x[ 4], x[ 5]);
+ z[ 9] = w0; w0 = 0;
- word3_muladd(&w2, &w1, &w0, x[5], x[5]);
- z[10] = w0;
- z[11] = w1;
+ word3_muladd(&w0, &w2, &w1, x[ 5], x[ 5]);
+ z[10] = w1;
+ z[11] = w2;
}
/*
@@ -143,64 +143,64 @@ void bigint_comba_mul6(word z[12], const word x[6], const word y[6])
{
word w2 = 0, w1 = 0, w0 = 0;
- word3_muladd(&w2, &w1, &w0, x[0], y[0]);
- z[0] = w0; w0 = w1; w1 = w2; w2 = 0;
-
- word3_muladd(&w2, &w1, &w0, x[0], y[1]);
- word3_muladd(&w2, &w1, &w0, x[1], y[0]);
- z[1] = w0; w0 = w1; w1 = w2; w2 = 0;
-
- word3_muladd(&w2, &w1, &w0, x[0], y[2]);
- word3_muladd(&w2, &w1, &w0, x[1], y[1]);
- word3_muladd(&w2, &w1, &w0, x[2], y[0]);
- z[2] = w0; w0 = w1; w1 = w2; w2 = 0;
-
- word3_muladd(&w2, &w1, &w0, x[0], y[3]);
- word3_muladd(&w2, &w1, &w0, x[1], y[2]);
- word3_muladd(&w2, &w1, &w0, x[2], y[1]);
- word3_muladd(&w2, &w1, &w0, x[3], y[0]);
- z[3] = w0; w0 = w1; w1 = w2; w2 = 0;
-
- word3_muladd(&w2, &w1, &w0, x[0], y[4]);
- word3_muladd(&w2, &w1, &w0, x[1], y[3]);
- word3_muladd(&w2, &w1, &w0, x[2], y[2]);
- word3_muladd(&w2, &w1, &w0, x[3], y[1]);
- word3_muladd(&w2, &w1, &w0, x[4], y[0]);
- z[4] = w0; w0 = w1; w1 = w2; w2 = 0;
-
- word3_muladd(&w2, &w1, &w0, x[0], y[5]);
- word3_muladd(&w2, &w1, &w0, x[1], y[4]);
- word3_muladd(&w2, &w1, &w0, x[2], y[3]);
- word3_muladd(&w2, &w1, &w0, x[3], y[2]);
- word3_muladd(&w2, &w1, &w0, x[4], y[1]);
- word3_muladd(&w2, &w1, &w0, x[5], y[0]);
- z[5] = w0; w0 = w1; w1 = w2; w2 = 0;
-
- word3_muladd(&w2, &w1, &w0, x[1], y[5]);
- word3_muladd(&w2, &w1, &w0, x[2], y[4]);
- word3_muladd(&w2, &w1, &w0, x[3], y[3]);
- word3_muladd(&w2, &w1, &w0, x[4], y[2]);
- word3_muladd(&w2, &w1, &w0, x[5], y[1]);
- z[6] = w0; w0 = w1; w1 = w2; w2 = 0;
-
- word3_muladd(&w2, &w1, &w0, x[2], y[5]);
- word3_muladd(&w2, &w1, &w0, x[3], y[4]);
- word3_muladd(&w2, &w1, &w0, x[4], y[3]);
- word3_muladd(&w2, &w1, &w0, x[5], y[2]);
- z[7] = w0; w0 = w1; w1 = w2; w2 = 0;
-
- word3_muladd(&w2, &w1, &w0, x[3], y[5]);
- word3_muladd(&w2, &w1, &w0, x[4], y[4]);
- word3_muladd(&w2, &w1, &w0, x[5], y[3]);
- z[8] = w0; w0 = w1; w1 = w2; w2 = 0;
-
- word3_muladd(&w2, &w1, &w0, x[4], y[5]);
- word3_muladd(&w2, &w1, &w0, x[5], y[4]);
- z[9] = w0; w0 = w1; w1 = w2; w2 = 0;
-
- word3_muladd(&w2, &w1, &w0, x[5], y[5]);
- z[10] = w0;
- z[11] = w1;
+ word3_muladd(&w2, &w1, &w0, x[ 0], y[ 0]);
+ z[ 0] = w0; w0 = 0;
+
+ word3_muladd(&w0, &w2, &w1, x[ 0], y[ 1]);
+ word3_muladd(&w0, &w2, &w1, x[ 1], y[ 0]);
+ z[ 1] = w1; w1 = 0;
+
+ word3_muladd(&w1, &w0, &w2, x[ 0], y[ 2]);
+ word3_muladd(&w1, &w0, &w2, x[ 1], y[ 1]);
+ word3_muladd(&w1, &w0, &w2, x[ 2], y[ 0]);
+ z[ 2] = w2; w2 = 0;
+
+ word3_muladd(&w2, &w1, &w0, x[ 0], y[ 3]);
+ word3_muladd(&w2, &w1, &w0, x[ 1], y[ 2]);
+ word3_muladd(&w2, &w1, &w0, x[ 2], y[ 1]);
+ word3_muladd(&w2, &w1, &w0, x[ 3], y[ 0]);
+ z[ 3] = w0; w0 = 0;
+
+ word3_muladd(&w0, &w2, &w1, x[ 0], y[ 4]);
+ word3_muladd(&w0, &w2, &w1, x[ 1], y[ 3]);
+ word3_muladd(&w0, &w2, &w1, x[ 2], y[ 2]);
+ word3_muladd(&w0, &w2, &w1, x[ 3], y[ 1]);
+ word3_muladd(&w0, &w2, &w1, x[ 4], y[ 0]);
+ z[ 4] = w1; w1 = 0;
+
+ word3_muladd(&w1, &w0, &w2, x[ 0], y[ 5]);
+ word3_muladd(&w1, &w0, &w2, x[ 1], y[ 4]);
+ word3_muladd(&w1, &w0, &w2, x[ 2], y[ 3]);
+ word3_muladd(&w1, &w0, &w2, x[ 3], y[ 2]);
+ word3_muladd(&w1, &w0, &w2, x[ 4], y[ 1]);
+ word3_muladd(&w1, &w0, &w2, x[ 5], y[ 0]);
+ z[ 5] = w2; w2 = 0;
+
+ word3_muladd(&w2, &w1, &w0, x[ 1], y[ 5]);
+ word3_muladd(&w2, &w1, &w0, x[ 2], y[ 4]);
+ word3_muladd(&w2, &w1, &w0, x[ 3], y[ 3]);
+ word3_muladd(&w2, &w1, &w0, x[ 4], y[ 2]);
+ word3_muladd(&w2, &w1, &w0, x[ 5], y[ 1]);
+ z[ 6] = w0; w0 = 0;
+
+ word3_muladd(&w0, &w2, &w1, x[ 2], y[ 5]);
+ word3_muladd(&w0, &w2, &w1, x[ 3], y[ 4]);
+ word3_muladd(&w0, &w2, &w1, x[ 4], y[ 3]);
+ word3_muladd(&w0, &w2, &w1, x[ 5], y[ 2]);
+ z[ 7] = w1; w1 = 0;
+
+ word3_muladd(&w1, &w0, &w2, x[ 3], y[ 5]);
+ word3_muladd(&w1, &w0, &w2, x[ 4], y[ 4]);
+ word3_muladd(&w1, &w0, &w2, x[ 5], y[ 3]);
+ z[ 8] = w2; w2 = 0;
+
+ word3_muladd(&w2, &w1, &w0, x[ 4], y[ 5]);
+ word3_muladd(&w2, &w1, &w0, x[ 5], y[ 4]);
+ z[ 9] = w0; w0 = 0;
+
+ word3_muladd(&w0, &w2, &w1, x[ 5], y[ 5]);
+ z[10] = w1;
+ z[11] = w2;
}
/*
@@ -210,72 +210,72 @@ void bigint_comba_sqr8(word z[16], const word x[8])
{
word w2 = 0, w1 = 0, w0 = 0;
- word3_muladd(&w2, &w1, &w0, x[0], x[0]);
- z[0] = w0; w0 = w1; w1 = w2; w2 = 0;
-
- word3_muladd_2(&w2, &w1, &w0, x[0], x[1]);
- z[1] = w0; w0 = w1; w1 = w2; w2 = 0;
-
- word3_muladd_2(&w2, &w1, &w0, x[0], x[2]);
- word3_muladd(&w2, &w1, &w0, x[1], x[1]);
- z[2] = w0; w0 = w1; w1 = w2; w2 = 0;
-
- word3_muladd_2(&w2, &w1, &w0, x[0], x[3]);
- word3_muladd_2(&w2, &w1, &w0, x[1], x[2]);
- z[3] = w0; w0 = w1; w1 = w2; w2 = 0;
-
- word3_muladd_2(&w2, &w1, &w0, x[0], x[4]);
- word3_muladd_2(&w2, &w1, &w0, x[1], x[3]);
- word3_muladd(&w2, &w1, &w0, x[2], x[2]);
- z[4] = w0; w0 = w1; w1 = w2; w2 = 0;
-
- word3_muladd_2(&w2, &w1, &w0, x[0], x[5]);
- word3_muladd_2(&w2, &w1, &w0, x[1], x[4]);
- word3_muladd_2(&w2, &w1, &w0, x[2], x[3]);
- z[5] = w0; w0 = w1; w1 = w2; w2 = 0;
-
- word3_muladd_2(&w2, &w1, &w0, x[0], x[6]);
- word3_muladd_2(&w2, &w1, &w0, x[1], x[5]);
- word3_muladd_2(&w2, &w1, &w0, x[2], x[4]);
- word3_muladd(&w2, &w1, &w0, x[3], x[3]);
- z[6] = w0; w0 = w1; w1 = w2; w2 = 0;
-
- word3_muladd_2(&w2, &w1, &w0, x[0], x[7]);
- word3_muladd_2(&w2, &w1, &w0, x[1], x[6]);
- word3_muladd_2(&w2, &w1, &w0, x[2], x[5]);
- word3_muladd_2(&w2, &w1, &w0, x[3], x[4]);
- z[7] = w0; w0 = w1; w1 = w2; w2 = 0;
-
- word3_muladd_2(&w2, &w1, &w0, x[1], x[7]);
- word3_muladd_2(&w2, &w1, &w0, x[2], x[6]);
- word3_muladd_2(&w2, &w1, &w0, x[3], x[5]);
- word3_muladd(&w2, &w1, &w0, x[4], x[4]);
- z[8] = w0; w0 = w1; w1 = w2; w2 = 0;
-
- word3_muladd_2(&w2, &w1, &w0, x[2], x[7]);
- word3_muladd_2(&w2, &w1, &w0, x[3], x[6]);
- word3_muladd_2(&w2, &w1, &w0, x[4], x[5]);
- z[9] = w0; w0 = w1; w1 = w2; w2 = 0;
-
- word3_muladd_2(&w2, &w1, &w0, x[3], x[7]);
- word3_muladd_2(&w2, &w1, &w0, x[4], x[6]);
- word3_muladd(&w2, &w1, &w0, x[5], x[5]);
- z[10] = w0; w0 = w1; w1 = w2; w2 = 0;
-
- word3_muladd_2(&w2, &w1, &w0, x[4], x[7]);
- word3_muladd_2(&w2, &w1, &w0, x[5], x[6]);
- z[11] = w0; w0 = w1; w1 = w2; w2 = 0;
-
- word3_muladd_2(&w2, &w1, &w0, x[5], x[7]);
- word3_muladd(&w2, &w1, &w0, x[6], x[6]);
- z[12] = w0; w0 = w1; w1 = w2; w2 = 0;
-
- word3_muladd_2(&w2, &w1, &w0, x[6], x[7]);
- z[13] = w0; w0 = w1; w1 = w2; w2 = 0;
-
- word3_muladd(&w2, &w1, &w0, x[7], x[7]);
- z[14] = w0;
- z[15] = w1;
+ word3_muladd(&w2, &w1, &w0, x[ 0], x[ 0]);
+ z[ 0] = w0; w0 = 0;
+
+ word3_muladd_2(&w0, &w2, &w1, x[ 0], x[ 1]);
+ z[ 1] = w1; w1 = 0;
+
+ word3_muladd_2(&w1, &w0, &w2, x[ 0], x[ 2]);
+ word3_muladd(&w1, &w0, &w2, x[ 1], x[ 1]);
+ z[ 2] = w2; w2 = 0;
+
+ word3_muladd_2(&w2, &w1, &w0, x[ 0], x[ 3]);
+ word3_muladd_2(&w2, &w1, &w0, x[ 1], x[ 2]);
+ z[ 3] = w0; w0 = 0;
+
+ word3_muladd_2(&w0, &w2, &w1, x[ 0], x[ 4]);
+ word3_muladd_2(&w0, &w2, &w1, x[ 1], x[ 3]);
+ word3_muladd(&w0, &w2, &w1, x[ 2], x[ 2]);
+ z[ 4] = w1; w1 = 0;
+
+ word3_muladd_2(&w1, &w0, &w2, x[ 0], x[ 5]);
+ word3_muladd_2(&w1, &w0, &w2, x[ 1], x[ 4]);
+ word3_muladd_2(&w1, &w0, &w2, x[ 2], x[ 3]);
+ z[ 5] = w2; w2 = 0;
+
+ word3_muladd_2(&w2, &w1, &w0, x[ 0], x[ 6]);
+ word3_muladd_2(&w2, &w1, &w0, x[ 1], x[ 5]);
+ word3_muladd_2(&w2, &w1, &w0, x[ 2], x[ 4]);
+ word3_muladd(&w2, &w1, &w0, x[ 3], x[ 3]);
+ z[ 6] = w0; w0 = 0;
+
+ word3_muladd_2(&w0, &w2, &w1, x[ 0], x[ 7]);
+ word3_muladd_2(&w0, &w2, &w1, x[ 1], x[ 6]);
+ word3_muladd_2(&w0, &w2, &w1, x[ 2], x[ 5]);
+ word3_muladd_2(&w0, &w2, &w1, x[ 3], x[ 4]);
+ z[ 7] = w1; w1 = 0;
+
+ word3_muladd_2(&w1, &w0, &w2, x[ 1], x[ 7]);
+ word3_muladd_2(&w1, &w0, &w2, x[ 2], x[ 6]);
+ word3_muladd_2(&w1, &w0, &w2, x[ 3], x[ 5]);
+ word3_muladd(&w1, &w0, &w2, x[ 4], x[ 4]);
+ z[ 8] = w2; w2 = 0;
+
+ word3_muladd_2(&w2, &w1, &w0, x[ 2], x[ 7]);
+ word3_muladd_2(&w2, &w1, &w0, x[ 3], x[ 6]);
+ word3_muladd_2(&w2, &w1, &w0, x[ 4], x[ 5]);
+ z[ 9] = w0; w0 = 0;
+
+ word3_muladd_2(&w0, &w2, &w1, x[ 3], x[ 7]);
+ word3_muladd_2(&w0, &w2, &w1, x[ 4], x[ 6]);
+ word3_muladd(&w0, &w2, &w1, x[ 5], x[ 5]);
+ z[10] = w1; w1 = 0;
+
+ word3_muladd_2(&w1, &w0, &w2, x[ 4], x[ 7]);
+ word3_muladd_2(&w1, &w0, &w2, x[ 5], x[ 6]);
+ z[11] = w2; w2 = 0;
+
+ word3_muladd_2(&w2, &w1, &w0, x[ 5], x[ 7]);
+ word3_muladd(&w2, &w1, &w0, x[ 6], x[ 6]);
+ z[12] = w0; w0 = 0;
+
+ word3_muladd_2(&w0, &w2, &w1, x[ 6], x[ 7]);
+ z[13] = w1; w1 = 0;
+
+ word3_muladd(&w1, &w0, &w2, x[ 7], x[ 7]);
+ z[14] = w2;
+ z[15] = w0;
}
/*
@@ -285,100 +285,100 @@ void bigint_comba_mul8(word z[16], const word x[8], const word y[8])
{
word w2 = 0, w1 = 0, w0 = 0;
- word3_muladd(&w2, &w1, &w0, x[0], y[0]);
- z[0] = w0; w0 = w1; w1 = w2; w2 = 0;
-
- word3_muladd(&w2, &w1, &w0, x[0], y[1]);
- word3_muladd(&w2, &w1, &w0, x[1], y[0]);
- z[1] = w0; w0 = w1; w1 = w2; w2 = 0;
-
- word3_muladd(&w2, &w1, &w0, x[0], y[2]);
- word3_muladd(&w2, &w1, &w0, x[1], y[1]);
- word3_muladd(&w2, &w1, &w0, x[2], y[0]);
- z[2] = w0; w0 = w1; w1 = w2; w2 = 0;
-
- word3_muladd(&w2, &w1, &w0, x[0], y[3]);
- word3_muladd(&w2, &w1, &w0, x[1], y[2]);
- word3_muladd(&w2, &w1, &w0, x[2], y[1]);
- word3_muladd(&w2, &w1, &w0, x[3], y[0]);
- z[3] = w0; w0 = w1; w1 = w2; w2 = 0;
-
- word3_muladd(&w2, &w1, &w0, x[0], y[4]);
- word3_muladd(&w2, &w1, &w0, x[1], y[3]);
- word3_muladd(&w2, &w1, &w0, x[2], y[2]);
- word3_muladd(&w2, &w1, &w0, x[3], y[1]);
- word3_muladd(&w2, &w1, &w0, x[4], y[0]);
- z[4] = w0; w0 = w1; w1 = w2; w2 = 0;
-
- word3_muladd(&w2, &w1, &w0, x[0], y[5]);
- word3_muladd(&w2, &w1, &w0, x[1], y[4]);
- word3_muladd(&w2, &w1, &w0, x[2], y[3]);
- word3_muladd(&w2, &w1, &w0, x[3], y[2]);
- word3_muladd(&w2, &w1, &w0, x[4], y[1]);
- word3_muladd(&w2, &w1, &w0, x[5], y[0]);
- z[5] = w0; w0 = w1; w1 = w2; w2 = 0;
-
- word3_muladd(&w2, &w1, &w0, x[0], y[6]);
- word3_muladd(&w2, &w1, &w0, x[1], y[5]);
- word3_muladd(&w2, &w1, &w0, x[2], y[4]);
- word3_muladd(&w2, &w1, &w0, x[3], y[3]);
- word3_muladd(&w2, &w1, &w0, x[4], y[2]);
- word3_muladd(&w2, &w1, &w0, x[5], y[1]);
- word3_muladd(&w2, &w1, &w0, x[6], y[0]);
- z[6] = w0; w0 = w1; w1 = w2; w2 = 0;
-
- word3_muladd(&w2, &w1, &w0, x[0], y[7]);
- word3_muladd(&w2, &w1, &w0, x[1], y[6]);
- word3_muladd(&w2, &w1, &w0, x[2], y[5]);
- word3_muladd(&w2, &w1, &w0, x[3], y[4]);
- word3_muladd(&w2, &w1, &w0, x[4], y[3]);
- word3_muladd(&w2, &w1, &w0, x[5], y[2]);
- word3_muladd(&w2, &w1, &w0, x[6], y[1]);
- word3_muladd(&w2, &w1, &w0, x[7], y[0]);
- z[7] = w0; w0 = w1; w1 = w2; w2 = 0;
-
- word3_muladd(&w2, &w1, &w0, x[1], y[7]);
- word3_muladd(&w2, &w1, &w0, x[2], y[6]);
- word3_muladd(&w2, &w1, &w0, x[3], y[5]);
- word3_muladd(&w2, &w1, &w0, x[4], y[4]);
- word3_muladd(&w2, &w1, &w0, x[5], y[3]);
- word3_muladd(&w2, &w1, &w0, x[6], y[2]);
- word3_muladd(&w2, &w1, &w0, x[7], y[1]);
- z[8] = w0; w0 = w1; w1 = w2; w2 = 0;
-
- word3_muladd(&w2, &w1, &w0, x[2], y[7]);
- word3_muladd(&w2, &w1, &w0, x[3], y[6]);
- word3_muladd(&w2, &w1, &w0, x[4], y[5]);
- word3_muladd(&w2, &w1, &w0, x[5], y[4]);
- word3_muladd(&w2, &w1, &w0, x[6], y[3]);
- word3_muladd(&w2, &w1, &w0, x[7], y[2]);
- z[9] = w0; w0 = w1; w1 = w2; w2 = 0;
-
- word3_muladd(&w2, &w1, &w0, x[3], y[7]);
- word3_muladd(&w2, &w1, &w0, x[4], y[6]);
- word3_muladd(&w2, &w1, &w0, x[5], y[5]);
- word3_muladd(&w2, &w1, &w0, x[6], y[4]);
- word3_muladd(&w2, &w1, &w0, x[7], y[3]);
- z[10] = w0; w0 = w1; w1 = w2; w2 = 0;
-
- word3_muladd(&w2, &w1, &w0, x[4], y[7]);
- word3_muladd(&w2, &w1, &w0, x[5], y[6]);
- word3_muladd(&w2, &w1, &w0, x[6], y[5]);
- word3_muladd(&w2, &w1, &w0, x[7], y[4]);
- z[11] = w0; w0 = w1; w1 = w2; w2 = 0;
-
- word3_muladd(&w2, &w1, &w0, x[5], y[7]);
- word3_muladd(&w2, &w1, &w0, x[6], y[6]);
- word3_muladd(&w2, &w1, &w0, x[7], y[5]);
- z[12] = w0; w0 = w1; w1 = w2; w2 = 0;
-
- word3_muladd(&w2, &w1, &w0, x[6], y[7]);
- word3_muladd(&w2, &w1, &w0, x[7], y[6]);
- z[13] = w0; w0 = w1; w1 = w2; w2 = 0;
-
- word3_muladd(&w2, &w1, &w0, x[7], y[7]);
- z[14] = w0;
- z[15] = w1;
+ word3_muladd(&w2, &w1, &w0, x[ 0], y[ 0]);
+ z[ 0] = w0; w0 = 0;
+
+ word3_muladd(&w0, &w2, &w1, x[ 0], y[ 1]);
+ word3_muladd(&w0, &w2, &w1, x[ 1], y[ 0]);
+ z[ 1] = w1; w1 = 0;
+
+ word3_muladd(&w1, &w0, &w2, x[ 0], y[ 2]);
+ word3_muladd(&w1, &w0, &w2, x[ 1], y[ 1]);
+ word3_muladd(&w1, &w0, &w2, x[ 2], y[ 0]);
+ z[ 2] = w2; w2 = 0;
+
+ word3_muladd(&w2, &w1, &w0, x[ 0], y[ 3]);
+ word3_muladd(&w2, &w1, &w0, x[ 1], y[ 2]);
+ word3_muladd(&w2, &w1, &w0, x[ 2], y[ 1]);
+ word3_muladd(&w2, &w1, &w0, x[ 3], y[ 0]);
+ z[ 3] = w0; w0 = 0;
+
+ word3_muladd(&w0, &w2, &w1, x[ 0], y[ 4]);
+ word3_muladd(&w0, &w2, &w1, x[ 1], y[ 3]);
+ word3_muladd(&w0, &w2, &w1, x[ 2], y[ 2]);
+ word3_muladd(&w0, &w2, &w1, x[ 3], y[ 1]);
+ word3_muladd(&w0, &w2, &w1, x[ 4], y[ 0]);
+ z[ 4] = w1; w1 = 0;
+
+ word3_muladd(&w1, &w0, &w2, x[ 0], y[ 5]);
+ word3_muladd(&w1, &w0, &w2, x[ 1], y[ 4]);
+ word3_muladd(&w1, &w0, &w2, x[ 2], y[ 3]);
+ word3_muladd(&w1, &w0, &w2, x[ 3], y[ 2]);
+ word3_muladd(&w1, &w0, &w2, x[ 4], y[ 1]);
+ word3_muladd(&w1, &w0, &w2, x[ 5], y[ 0]);
+ z[ 5] = w2; w2 = 0;
+
+ word3_muladd(&w2, &w1, &w0, x[ 0], y[ 6]);
+ word3_muladd(&w2, &w1, &w0, x[ 1], y[ 5]);
+ word3_muladd(&w2, &w1, &w0, x[ 2], y[ 4]);
+ word3_muladd(&w2, &w1, &w0, x[ 3], y[ 3]);
+ word3_muladd(&w2, &w1, &w0, x[ 4], y[ 2]);
+ word3_muladd(&w2, &w1, &w0, x[ 5], y[ 1]);
+ word3_muladd(&w2, &w1, &w0, x[ 6], y[ 0]);
+ z[ 6] = w0; w0 = 0;
+
+ word3_muladd(&w0, &w2, &w1, x[ 0], y[ 7]);
+ word3_muladd(&w0, &w2, &w1, x[ 1], y[ 6]);
+ word3_muladd(&w0, &w2, &w1, x[ 2], y[ 5]);
+ word3_muladd(&w0, &w2, &w1, x[ 3], y[ 4]);
+ word3_muladd(&w0, &w2, &w1, x[ 4], y[ 3]);
+ word3_muladd(&w0, &w2, &w1, x[ 5], y[ 2]);
+ word3_muladd(&w0, &w2, &w1, x[ 6], y[ 1]);
+ word3_muladd(&w0, &w2, &w1, x[ 7], y[ 0]);
+ z[ 7] = w1; w1 = 0;
+
+ word3_muladd(&w1, &w0, &w2, x[ 1], y[ 7]);
+ word3_muladd(&w1, &w0, &w2, x[ 2], y[ 6]);
+ word3_muladd(&w1, &w0, &w2, x[ 3], y[ 5]);
+ word3_muladd(&w1, &w0, &w2, x[ 4], y[ 4]);
+ word3_muladd(&w1, &w0, &w2, x[ 5], y[ 3]);
+ word3_muladd(&w1, &w0, &w2, x[ 6], y[ 2]);
+ word3_muladd(&w1, &w0, &w2, x[ 7], y[ 1]);
+ z[ 8] = w2; w2 = 0;
+
+ word3_muladd(&w2, &w1, &w0, x[ 2], y[ 7]);
+ word3_muladd(&w2, &w1, &w0, x[ 3], y[ 6]);
+ word3_muladd(&w2, &w1, &w0, x[ 4], y[ 5]);
+ word3_muladd(&w2, &w1, &w0, x[ 5], y[ 4]);
+ word3_muladd(&w2, &w1, &w0, x[ 6], y[ 3]);
+ word3_muladd(&w2, &w1, &w0, x[ 7], y[ 2]);
+ z[ 9] = w0; w0 = 0;
+
+ word3_muladd(&w0, &w2, &w1, x[ 3], y[ 7]);
+ word3_muladd(&w0, &w2, &w1, x[ 4], y[ 6]);
+ word3_muladd(&w0, &w2, &w1, x[ 5], y[ 5]);
+ word3_muladd(&w0, &w2, &w1, x[ 6], y[ 4]);
+ word3_muladd(&w0, &w2, &w1, x[ 7], y[ 3]);
+ z[10] = w1; w1 = 0;
+
+ word3_muladd(&w1, &w0, &w2, x[ 4], y[ 7]);
+ word3_muladd(&w1, &w0, &w2, x[ 5], y[ 6]);
+ word3_muladd(&w1, &w0, &w2, x[ 6], y[ 5]);
+ word3_muladd(&w1, &w0, &w2, x[ 7], y[ 4]);
+ z[11] = w2; w2 = 0;
+
+ word3_muladd(&w2, &w1, &w0, x[ 5], y[ 7]);
+ word3_muladd(&w2, &w1, &w0, x[ 6], y[ 6]);
+ word3_muladd(&w2, &w1, &w0, x[ 7], y[ 5]);
+ z[12] = w0; w0 = 0;
+
+ word3_muladd(&w0, &w2, &w1, x[ 6], y[ 7]);
+ word3_muladd(&w0, &w2, &w1, x[ 7], y[ 6]);
+ z[13] = w1; w1 = 0;
+
+ word3_muladd(&w1, &w0, &w2, x[ 7], y[ 7]);
+ z[14] = w2;
+ z[15] = w0;
}
/*
@@ -389,70 +389,70 @@ void bigint_comba_sqr16(word z[32], const word x[16])
word w2 = 0, w1 = 0, w0 = 0;
word3_muladd(&w2, &w1, &w0, x[ 0], x[ 0]);
- z[ 0] = w0; w0 = w1; w1 = w2; w2 = 0;
+ z[ 0] = w0; w0 = 0;
- word3_muladd_2(&w2, &w1, &w0, x[ 0], x[ 1]);
- z[ 1] = w0; w0 = w1; w1 = w2; w2 = 0;
+ word3_muladd_2(&w0, &w2, &w1, x[ 0], x[ 1]);
+ z[ 1] = w1; w1 = 0;
- word3_muladd_2(&w2, &w1, &w0, x[ 0], x[ 2]);
- word3_muladd(&w2, &w1, &w0, x[ 1], x[ 1]);
- z[ 2] = w0; w0 = w1; w1 = w2; w2 = 0;
+ word3_muladd_2(&w1, &w0, &w2, x[ 0], x[ 2]);
+ word3_muladd(&w1, &w0, &w2, x[ 1], x[ 1]);
+ z[ 2] = w2; w2 = 0;
word3_muladd_2(&w2, &w1, &w0, x[ 0], x[ 3]);
word3_muladd_2(&w2, &w1, &w0, x[ 1], x[ 2]);
- z[ 3] = w0; w0 = w1; w1 = w2; w2 = 0;
+ z[ 3] = w0; w0 = 0;
- word3_muladd_2(&w2, &w1, &w0, x[ 0], x[ 4]);
- word3_muladd_2(&w2, &w1, &w0, x[ 1], x[ 3]);
- word3_muladd(&w2, &w1, &w0, x[ 2], x[ 2]);
- z[ 4] = w0; w0 = w1; w1 = w2; w2 = 0;
+ word3_muladd_2(&w0, &w2, &w1, x[ 0], x[ 4]);
+ word3_muladd_2(&w0, &w2, &w1, x[ 1], x[ 3]);
+ word3_muladd(&w0, &w2, &w1, x[ 2], x[ 2]);
+ z[ 4] = w1; w1 = 0;
- word3_muladd_2(&w2, &w1, &w0, x[ 0], x[ 5]);
- word3_muladd_2(&w2, &w1, &w0, x[ 1], x[ 4]);
- word3_muladd_2(&w2, &w1, &w0, x[ 2], x[ 3]);
- z[ 5] = w0; w0 = w1; w1 = w2; w2 = 0;
+ word3_muladd_2(&w1, &w0, &w2, x[ 0], x[ 5]);
+ word3_muladd_2(&w1, &w0, &w2, x[ 1], x[ 4]);
+ word3_muladd_2(&w1, &w0, &w2, x[ 2], x[ 3]);
+ z[ 5] = w2; w2 = 0;
word3_muladd_2(&w2, &w1, &w0, x[ 0], x[ 6]);
word3_muladd_2(&w2, &w1, &w0, x[ 1], x[ 5]);
word3_muladd_2(&w2, &w1, &w0, x[ 2], x[ 4]);
word3_muladd(&w2, &w1, &w0, x[ 3], x[ 3]);
- z[ 6] = w0; w0 = w1; w1 = w2; w2 = 0;
+ z[ 6] = w0; w0 = 0;
- word3_muladd_2(&w2, &w1, &w0, x[ 0], x[ 7]);
- word3_muladd_2(&w2, &w1, &w0, x[ 1], x[ 6]);
- word3_muladd_2(&w2, &w1, &w0, x[ 2], x[ 5]);
- word3_muladd_2(&w2, &w1, &w0, x[ 3], x[ 4]);
- z[ 7] = w0; w0 = w1; w1 = w2; w2 = 0;
+ word3_muladd_2(&w0, &w2, &w1, x[ 0], x[ 7]);
+ word3_muladd_2(&w0, &w2, &w1, x[ 1], x[ 6]);
+ word3_muladd_2(&w0, &w2, &w1, x[ 2], x[ 5]);
+ word3_muladd_2(&w0, &w2, &w1, x[ 3], x[ 4]);
+ z[ 7] = w1; w1 = 0;
- word3_muladd_2(&w2, &w1, &w0, x[ 0], x[ 8]);
- word3_muladd_2(&w2, &w1, &w0, x[ 1], x[ 7]);
- word3_muladd_2(&w2, &w1, &w0, x[ 2], x[ 6]);
- word3_muladd_2(&w2, &w1, &w0, x[ 3], x[ 5]);
- word3_muladd(&w2, &w1, &w0, x[ 4], x[ 4]);
- z[ 8] = w0; w0 = w1; w1 = w2; w2 = 0;
+ word3_muladd_2(&w1, &w0, &w2, x[ 0], x[ 8]);
+ word3_muladd_2(&w1, &w0, &w2, x[ 1], x[ 7]);
+ word3_muladd_2(&w1, &w0, &w2, x[ 2], x[ 6]);
+ word3_muladd_2(&w1, &w0, &w2, x[ 3], x[ 5]);
+ word3_muladd(&w1, &w0, &w2, x[ 4], x[ 4]);
+ z[ 8] = w2; w2 = 0;
word3_muladd_2(&w2, &w1, &w0, x[ 0], x[ 9]);
word3_muladd_2(&w2, &w1, &w0, x[ 1], x[ 8]);
word3_muladd_2(&w2, &w1, &w0, x[ 2], x[ 7]);
word3_muladd_2(&w2, &w1, &w0, x[ 3], x[ 6]);
word3_muladd_2(&w2, &w1, &w0, x[ 4], x[ 5]);
- z[ 9] = w0; w0 = w1; w1 = w2; w2 = 0;
-
- word3_muladd_2(&w2, &w1, &w0, x[ 0], x[10]);
- word3_muladd_2(&w2, &w1, &w0, x[ 1], x[ 9]);
- word3_muladd_2(&w2, &w1, &w0, x[ 2], x[ 8]);
- word3_muladd_2(&w2, &w1, &w0, x[ 3], x[ 7]);
- word3_muladd_2(&w2, &w1, &w0, x[ 4], x[ 6]);
- word3_muladd(&w2, &w1, &w0, x[ 5], x[ 5]);
- z[10] = w0; w0 = w1; w1 = w2; w2 = 0;
-
- word3_muladd_2(&w2, &w1, &w0, x[ 0], x[11]);
- word3_muladd_2(&w2, &w1, &w0, x[ 1], x[10]);
- word3_muladd_2(&w2, &w1, &w0, x[ 2], x[ 9]);
- word3_muladd_2(&w2, &w1, &w0, x[ 3], x[ 8]);
- word3_muladd_2(&w2, &w1, &w0, x[ 4], x[ 7]);
- word3_muladd_2(&w2, &w1, &w0, x[ 5], x[ 6]);
- z[11] = w0; w0 = w1; w1 = w2; w2 = 0;
+ z[ 9] = w0; w0 = 0;
+
+ word3_muladd_2(&w0, &w2, &w1, x[ 0], x[10]);
+ word3_muladd_2(&w0, &w2, &w1, x[ 1], x[ 9]);
+ word3_muladd_2(&w0, &w2, &w1, x[ 2], x[ 8]);
+ word3_muladd_2(&w0, &w2, &w1, x[ 3], x[ 7]);
+ word3_muladd_2(&w0, &w2, &w1, x[ 4], x[ 6]);
+ word3_muladd(&w0, &w2, &w1, x[ 5], x[ 5]);
+ z[10] = w1; w1 = 0;
+
+ word3_muladd_2(&w1, &w0, &w2, x[ 0], x[11]);
+ word3_muladd_2(&w1, &w0, &w2, x[ 1], x[10]);
+ word3_muladd_2(&w1, &w0, &w2, x[ 2], x[ 9]);
+ word3_muladd_2(&w1, &w0, &w2, x[ 3], x[ 8]);
+ word3_muladd_2(&w1, &w0, &w2, x[ 4], x[ 7]);
+ word3_muladd_2(&w1, &w0, &w2, x[ 5], x[ 6]);
+ z[11] = w2; w2 = 0;
word3_muladd_2(&w2, &w1, &w0, x[ 0], x[12]);
word3_muladd_2(&w2, &w1, &w0, x[ 1], x[11]);
@@ -461,26 +461,26 @@ void bigint_comba_sqr16(word z[32], const word x[16])
word3_muladd_2(&w2, &w1, &w0, x[ 4], x[ 8]);
word3_muladd_2(&w2, &w1, &w0, x[ 5], x[ 7]);
word3_muladd(&w2, &w1, &w0, x[ 6], x[ 6]);
- z[12] = w0; w0 = w1; w1 = w2; w2 = 0;
-
- word3_muladd_2(&w2, &w1, &w0, x[ 0], x[13]);
- word3_muladd_2(&w2, &w1, &w0, x[ 1], x[12]);
- word3_muladd_2(&w2, &w1, &w0, x[ 2], x[11]);
- word3_muladd_2(&w2, &w1, &w0, x[ 3], x[10]);
- word3_muladd_2(&w2, &w1, &w0, x[ 4], x[ 9]);
- word3_muladd_2(&w2, &w1, &w0, x[ 5], x[ 8]);
- word3_muladd_2(&w2, &w1, &w0, x[ 6], x[ 7]);
- z[13] = w0; w0 = w1; w1 = w2; w2 = 0;
-
- word3_muladd_2(&w2, &w1, &w0, x[ 0], x[14]);
- word3_muladd_2(&w2, &w1, &w0, x[ 1], x[13]);
- word3_muladd_2(&w2, &w1, &w0, x[ 2], x[12]);
- word3_muladd_2(&w2, &w1, &w0, x[ 3], x[11]);
- word3_muladd_2(&w2, &w1, &w0, x[ 4], x[10]);
- word3_muladd_2(&w2, &w1, &w0, x[ 5], x[ 9]);
- word3_muladd_2(&w2, &w1, &w0, x[ 6], x[ 8]);
- word3_muladd(&w2, &w1, &w0, x[ 7], x[ 7]);
- z[14] = w0; w0 = w1; w1 = w2; w2 = 0;
+ z[12] = w0; w0 = 0;
+
+ word3_muladd_2(&w0, &w2, &w1, x[ 0], x[13]);
+ word3_muladd_2(&w0, &w2, &w1, x[ 1], x[12]);
+ word3_muladd_2(&w0, &w2, &w1, x[ 2], x[11]);
+ word3_muladd_2(&w0, &w2, &w1, x[ 3], x[10]);
+ word3_muladd_2(&w0, &w2, &w1, x[ 4], x[ 9]);
+ word3_muladd_2(&w0, &w2, &w1, x[ 5], x[ 8]);
+ word3_muladd_2(&w0, &w2, &w1, x[ 6], x[ 7]);
+ z[13] = w1; w1 = 0;
+
+ word3_muladd_2(&w1, &w0, &w2, x[ 0], x[14]);
+ word3_muladd_2(&w1, &w0, &w2, x[ 1], x[13]);
+ word3_muladd_2(&w1, &w0, &w2, x[ 2], x[12]);
+ word3_muladd_2(&w1, &w0, &w2, x[ 3], x[11]);
+ word3_muladd_2(&w1, &w0, &w2, x[ 4], x[10]);
+ word3_muladd_2(&w1, &w0, &w2, x[ 5], x[ 9]);
+ word3_muladd_2(&w1, &w0, &w2, x[ 6], x[ 8]);
+ word3_muladd(&w1, &w0, &w2, x[ 7], x[ 7]);
+ z[14] = w2; w2 = 0;
word3_muladd_2(&w2, &w1, &w0, x[ 0], x[15]);
word3_muladd_2(&w2, &w1, &w0, x[ 1], x[14]);
@@ -490,26 +490,26 @@ void bigint_comba_sqr16(word z[32], const word x[16])
word3_muladd_2(&w2, &w1, &w0, x[ 5], x[10]);
word3_muladd_2(&w2, &w1, &w0, x[ 6], x[ 9]);
word3_muladd_2(&w2, &w1, &w0, x[ 7], x[ 8]);
- z[15] = w0; w0 = w1; w1 = w2; w2 = 0;
-
- word3_muladd_2(&w2, &w1, &w0, x[ 1], x[15]);
- word3_muladd_2(&w2, &w1, &w0, x[ 2], x[14]);
- word3_muladd_2(&w2, &w1, &w0, x[ 3], x[13]);
- word3_muladd_2(&w2, &w1, &w0, x[ 4], x[12]);
- word3_muladd_2(&w2, &w1, &w0, x[ 5], x[11]);
- word3_muladd_2(&w2, &w1, &w0, x[ 6], x[10]);
- word3_muladd_2(&w2, &w1, &w0, x[ 7], x[ 9]);
- word3_muladd(&w2, &w1, &w0, x[ 8], x[ 8]);
- z[16] = w0; w0 = w1; w1 = w2; w2 = 0;
-
- word3_muladd_2(&w2, &w1, &w0, x[ 2], x[15]);
- word3_muladd_2(&w2, &w1, &w0, x[ 3], x[14]);
- word3_muladd_2(&w2, &w1, &w0, x[ 4], x[13]);
- word3_muladd_2(&w2, &w1, &w0, x[ 5], x[12]);
- word3_muladd_2(&w2, &w1, &w0, x[ 6], x[11]);
- word3_muladd_2(&w2, &w1, &w0, x[ 7], x[10]);
- word3_muladd_2(&w2, &w1, &w0, x[ 8], x[ 9]);
- z[17] = w0; w0 = w1; w1 = w2; w2 = 0;
+ z[15] = w0; w0 = 0;
+
+ word3_muladd_2(&w0, &w2, &w1, x[ 1], x[15]);
+ word3_muladd_2(&w0, &w2, &w1, x[ 2], x[14]);
+ word3_muladd_2(&w0, &w2, &w1, x[ 3], x[13]);
+ word3_muladd_2(&w0, &w2, &w1, x[ 4], x[12]);
+ word3_muladd_2(&w0, &w2, &w1, x[ 5], x[11]);
+ word3_muladd_2(&w0, &w2, &w1, x[ 6], x[10]);
+ word3_muladd_2(&w0, &w2, &w1, x[ 7], x[ 9]);
+ word3_muladd(&w0, &w2, &w1, x[ 8], x[ 8]);
+ z[16] = w1; w1 = 0;
+
+ word3_muladd_2(&w1, &w0, &w2, x[ 2], x[15]);
+ word3_muladd_2(&w1, &w0, &w2, x[ 3], x[14]);
+ word3_muladd_2(&w1, &w0, &w2, x[ 4], x[13]);
+ word3_muladd_2(&w1, &w0, &w2, x[ 5], x[12]);
+ word3_muladd_2(&w1, &w0, &w2, x[ 6], x[11]);
+ word3_muladd_2(&w1, &w0, &w2, x[ 7], x[10]);
+ word3_muladd_2(&w1, &w0, &w2, x[ 8], x[ 9]);
+ z[17] = w2; w2 = 0;
word3_muladd_2(&w2, &w1, &w0, x[ 3], x[15]);
word3_muladd_2(&w2, &w1, &w0, x[ 4], x[14]);
@@ -518,70 +518,70 @@ void bigint_comba_sqr16(word z[32], const word x[16])
word3_muladd_2(&w2, &w1, &w0, x[ 7], x[11]);
word3_muladd_2(&w2, &w1, &w0, x[ 8], x[10]);
word3_muladd(&w2, &w1, &w0, x[ 9], x[ 9]);
- z[18] = w0; w0 = w1; w1 = w2; w2 = 0;
-
- word3_muladd_2(&w2, &w1, &w0, x[ 4], x[15]);
- word3_muladd_2(&w2, &w1, &w0, x[ 5], x[14]);
- word3_muladd_2(&w2, &w1, &w0, x[ 6], x[13]);
- word3_muladd_2(&w2, &w1, &w0, x[ 7], x[12]);
- word3_muladd_2(&w2, &w1, &w0, x[ 8], x[11]);
- word3_muladd_2(&w2, &w1, &w0, x[ 9], x[10]);
- z[19] = w0; w0 = w1; w1 = w2; w2 = 0;
-
- word3_muladd_2(&w2, &w1, &w0, x[ 5], x[15]);
- word3_muladd_2(&w2, &w1, &w0, x[ 6], x[14]);
- word3_muladd_2(&w2, &w1, &w0, x[ 7], x[13]);
- word3_muladd_2(&w2, &w1, &w0, x[ 8], x[12]);
- word3_muladd_2(&w2, &w1, &w0, x[ 9], x[11]);
- word3_muladd(&w2, &w1, &w0, x[10], x[10]);
- z[20] = w0; w0 = w1; w1 = w2; w2 = 0;
+ z[18] = w0; w0 = 0;
+
+ word3_muladd_2(&w0, &w2, &w1, x[ 4], x[15]);
+ word3_muladd_2(&w0, &w2, &w1, x[ 5], x[14]);
+ word3_muladd_2(&w0, &w2, &w1, x[ 6], x[13]);
+ word3_muladd_2(&w0, &w2, &w1, x[ 7], x[12]);
+ word3_muladd_2(&w0, &w2, &w1, x[ 8], x[11]);
+ word3_muladd_2(&w0, &w2, &w1, x[ 9], x[10]);
+ z[19] = w1; w1 = 0;
+
+ word3_muladd_2(&w1, &w0, &w2, x[ 5], x[15]);
+ word3_muladd_2(&w1, &w0, &w2, x[ 6], x[14]);
+ word3_muladd_2(&w1, &w0, &w2, x[ 7], x[13]);
+ word3_muladd_2(&w1, &w0, &w2, x[ 8], x[12]);
+ word3_muladd_2(&w1, &w0, &w2, x[ 9], x[11]);
+ word3_muladd(&w1, &w0, &w2, x[10], x[10]);
+ z[20] = w2; w2 = 0;
word3_muladd_2(&w2, &w1, &w0, x[ 6], x[15]);
word3_muladd_2(&w2, &w1, &w0, x[ 7], x[14]);
word3_muladd_2(&w2, &w1, &w0, x[ 8], x[13]);
word3_muladd_2(&w2, &w1, &w0, x[ 9], x[12]);
word3_muladd_2(&w2, &w1, &w0, x[10], x[11]);
- z[21] = w0; w0 = w1; w1 = w2; w2 = 0;
+ z[21] = w0; w0 = 0;
- word3_muladd_2(&w2, &w1, &w0, x[ 7], x[15]);
- word3_muladd_2(&w2, &w1, &w0, x[ 8], x[14]);
- word3_muladd_2(&w2, &w1, &w0, x[ 9], x[13]);
- word3_muladd_2(&w2, &w1, &w0, x[10], x[12]);
- word3_muladd(&w2, &w1, &w0, x[11], x[11]);
- z[22] = w0; w0 = w1; w1 = w2; w2 = 0;
+ word3_muladd_2(&w0, &w2, &w1, x[ 7], x[15]);
+ word3_muladd_2(&w0, &w2, &w1, x[ 8], x[14]);
+ word3_muladd_2(&w0, &w2, &w1, x[ 9], x[13]);
+ word3_muladd_2(&w0, &w2, &w1, x[10], x[12]);
+ word3_muladd(&w0, &w2, &w1, x[11], x[11]);
+ z[22] = w1; w1 = 0;
- word3_muladd_2(&w2, &w1, &w0, x[ 8], x[15]);
- word3_muladd_2(&w2, &w1, &w0, x[ 9], x[14]);
- word3_muladd_2(&w2, &w1, &w0, x[10], x[13]);
- word3_muladd_2(&w2, &w1, &w0, x[11], x[12]);
- z[23] = w0; w0 = w1; w1 = w2; w2 = 0;
+ word3_muladd_2(&w1, &w0, &w2, x[ 8], x[15]);
+ word3_muladd_2(&w1, &w0, &w2, x[ 9], x[14]);
+ word3_muladd_2(&w1, &w0, &w2, x[10], x[13]);
+ word3_muladd_2(&w1, &w0, &w2, x[11], x[12]);
+ z[23] = w2; w2 = 0;
word3_muladd_2(&w2, &w1, &w0, x[ 9], x[15]);
word3_muladd_2(&w2, &w1, &w0, x[10], x[14]);
word3_muladd_2(&w2, &w1, &w0, x[11], x[13]);
word3_muladd(&w2, &w1, &w0, x[12], x[12]);
- z[24] = w0; w0 = w1; w1 = w2; w2 = 0;
+ z[24] = w0; w0 = 0;
- word3_muladd_2(&w2, &w1, &w0, x[10], x[15]);
- word3_muladd_2(&w2, &w1, &w0, x[11], x[14]);
- word3_muladd_2(&w2, &w1, &w0, x[12], x[13]);
- z[25] = w0; w0 = w1; w1 = w2; w2 = 0;
+ word3_muladd_2(&w0, &w2, &w1, x[10], x[15]);
+ word3_muladd_2(&w0, &w2, &w1, x[11], x[14]);
+ word3_muladd_2(&w0, &w2, &w1, x[12], x[13]);
+ z[25] = w1; w1 = 0;
- word3_muladd_2(&w2, &w1, &w0, x[11], x[15]);
- word3_muladd_2(&w2, &w1, &w0, x[12], x[14]);
- word3_muladd(&w2, &w1, &w0, x[13], x[13]);
- z[26] = w0; w0 = w1; w1 = w2; w2 = 0;
+ word3_muladd_2(&w1, &w0, &w2, x[11], x[15]);
+ word3_muladd_2(&w1, &w0, &w2, x[12], x[14]);
+ word3_muladd(&w1, &w0, &w2, x[13], x[13]);
+ z[26] = w2; w2 = 0;
word3_muladd_2(&w2, &w1, &w0, x[12], x[15]);
word3_muladd_2(&w2, &w1, &w0, x[13], x[14]);
- z[27] = w0; w0 = w1; w1 = w2; w2 = 0;
+ z[27] = w0; w0 = 0;
- word3_muladd_2(&w2, &w1, &w0, x[13], x[15]);
- word3_muladd(&w2, &w1, &w0, x[14], x[14]);
- z[28] = w0; w0 = w1; w1 = w2; w2 = 0;
+ word3_muladd_2(&w0, &w2, &w1, x[13], x[15]);
+ word3_muladd(&w0, &w2, &w1, x[14], x[14]);
+ z[28] = w1; w1 = 0;
- word3_muladd_2(&w2, &w1, &w0, x[14], x[15]);
- z[29] = w0; w0 = w1; w1 = w2; w2 = 0;
+ word3_muladd_2(&w1, &w0, &w2, x[14], x[15]);
+ z[29] = w2; w2 = 0;
word3_muladd(&w2, &w1, &w0, x[15], x[15]);
z[30] = w0;
@@ -596,37 +596,37 @@ void bigint_comba_mul16(word z[32], const word x[16], const word y[16])
word w2 = 0, w1 = 0, w0 = 0;
word3_muladd(&w2, &w1, &w0, x[ 0], y[ 0]);
- z[0] = w0; w0 = w1; w1 = w2; w2 = 0;
+ z[ 0] = w0; w0 = 0;
- word3_muladd(&w2, &w1, &w0, x[ 0], y[ 1]);
- word3_muladd(&w2, &w1, &w0, x[ 1], y[ 0]);
- z[1] = w0; w0 = w1; w1 = w2; w2 = 0;
+ word3_muladd(&w0, &w2, &w1, x[ 0], y[ 1]);
+ word3_muladd(&w0, &w2, &w1, x[ 1], y[ 0]);
+ z[ 1] = w1; w1 = 0;
- word3_muladd(&w2, &w1, &w0, x[ 0], y[ 2]);
- word3_muladd(&w2, &w1, &w0, x[ 1], y[ 1]);
- word3_muladd(&w2, &w1, &w0, x[ 2], y[ 0]);
- z[2] = w0; w0 = w1; w1 = w2; w2 = 0;
+ word3_muladd(&w1, &w0, &w2, x[ 0], y[ 2]);
+ word3_muladd(&w1, &w0, &w2, x[ 1], y[ 1]);
+ word3_muladd(&w1, &w0, &w2, x[ 2], y[ 0]);
+ z[ 2] = w2; w2 = 0;
word3_muladd(&w2, &w1, &w0, x[ 0], y[ 3]);
word3_muladd(&w2, &w1, &w0, x[ 1], y[ 2]);
word3_muladd(&w2, &w1, &w0, x[ 2], y[ 1]);
word3_muladd(&w2, &w1, &w0, x[ 3], y[ 0]);
- z[3] = w0; w0 = w1; w1 = w2; w2 = 0;
-
- word3_muladd(&w2, &w1, &w0, x[ 0], y[ 4]);
- word3_muladd(&w2, &w1, &w0, x[ 1], y[ 3]);
- word3_muladd(&w2, &w1, &w0, x[ 2], y[ 2]);
- word3_muladd(&w2, &w1, &w0, x[ 3], y[ 1]);
- word3_muladd(&w2, &w1, &w0, x[ 4], y[ 0]);
- z[4] = w0; w0 = w1; w1 = w2; w2 = 0;
-
- word3_muladd(&w2, &w1, &w0, x[ 0], y[ 5]);
- word3_muladd(&w2, &w1, &w0, x[ 1], y[ 4]);
- word3_muladd(&w2, &w1, &w0, x[ 2], y[ 3]);
- word3_muladd(&w2, &w1, &w0, x[ 3], y[ 2]);
- word3_muladd(&w2, &w1, &w0, x[ 4], y[ 1]);
- word3_muladd(&w2, &w1, &w0, x[ 5], y[ 0]);
- z[5] = w0; w0 = w1; w1 = w2; w2 = 0;
+ z[ 3] = w0; w0 = 0;
+
+ word3_muladd(&w0, &w2, &w1, x[ 0], y[ 4]);
+ word3_muladd(&w0, &w2, &w1, x[ 1], y[ 3]);
+ word3_muladd(&w0, &w2, &w1, x[ 2], y[ 2]);
+ word3_muladd(&w0, &w2, &w1, x[ 3], y[ 1]);
+ word3_muladd(&w0, &w2, &w1, x[ 4], y[ 0]);
+ z[ 4] = w1; w1 = 0;
+
+ word3_muladd(&w1, &w0, &w2, x[ 0], y[ 5]);
+ word3_muladd(&w1, &w0, &w2, x[ 1], y[ 4]);
+ word3_muladd(&w1, &w0, &w2, x[ 2], y[ 3]);
+ word3_muladd(&w1, &w0, &w2, x[ 3], y[ 2]);
+ word3_muladd(&w1, &w0, &w2, x[ 4], y[ 1]);
+ word3_muladd(&w1, &w0, &w2, x[ 5], y[ 0]);
+ z[ 5] = w2; w2 = 0;
word3_muladd(&w2, &w1, &w0, x[ 0], y[ 6]);
word3_muladd(&w2, &w1, &w0, x[ 1], y[ 5]);
@@ -635,28 +635,28 @@ void bigint_comba_mul16(word z[32], const word x[16], const word y[16])
word3_muladd(&w2, &w1, &w0, x[ 4], y[ 2]);
word3_muladd(&w2, &w1, &w0, x[ 5], y[ 1]);
word3_muladd(&w2, &w1, &w0, x[ 6], y[ 0]);
- z[6] = w0; w0 = w1; w1 = w2; w2 = 0;
-
- word3_muladd(&w2, &w1, &w0, x[ 0], y[ 7]);
- word3_muladd(&w2, &w1, &w0, x[ 1], y[ 6]);
- word3_muladd(&w2, &w1, &w0, x[ 2], y[ 5]);
- word3_muladd(&w2, &w1, &w0, x[ 3], y[ 4]);
- word3_muladd(&w2, &w1, &w0, x[ 4], y[ 3]);
- word3_muladd(&w2, &w1, &w0, x[ 5], y[ 2]);
- word3_muladd(&w2, &w1, &w0, x[ 6], y[ 1]);
- word3_muladd(&w2, &w1, &w0, x[ 7], y[ 0]);
- z[7] = w0; w0 = w1; w1 = w2; w2 = 0;
-
- word3_muladd(&w2, &w1, &w0, x[ 0], y[ 8]);
- word3_muladd(&w2, &w1, &w0, x[ 1], y[ 7]);
- word3_muladd(&w2, &w1, &w0, x[ 2], y[ 6]);
- word3_muladd(&w2, &w1, &w0, x[ 3], y[ 5]);
- word3_muladd(&w2, &w1, &w0, x[ 4], y[ 4]);
- word3_muladd(&w2, &w1, &w0, x[ 5], y[ 3]);
- word3_muladd(&w2, &w1, &w0, x[ 6], y[ 2]);
- word3_muladd(&w2, &w1, &w0, x[ 7], y[ 1]);
- word3_muladd(&w2, &w1, &w0, x[ 8], y[ 0]);
- z[8] = w0; w0 = w1; w1 = w2; w2 = 0;
+ z[ 6] = w0; w0 = 0;
+
+ word3_muladd(&w0, &w2, &w1, x[ 0], y[ 7]);
+ word3_muladd(&w0, &w2, &w1, x[ 1], y[ 6]);
+ word3_muladd(&w0, &w2, &w1, x[ 2], y[ 5]);
+ word3_muladd(&w0, &w2, &w1, x[ 3], y[ 4]);
+ word3_muladd(&w0, &w2, &w1, x[ 4], y[ 3]);
+ word3_muladd(&w0, &w2, &w1, x[ 5], y[ 2]);
+ word3_muladd(&w0, &w2, &w1, x[ 6], y[ 1]);
+ word3_muladd(&w0, &w2, &w1, x[ 7], y[ 0]);
+ z[ 7] = w1; w1 = 0;
+
+ word3_muladd(&w1, &w0, &w2, x[ 0], y[ 8]);
+ word3_muladd(&w1, &w0, &w2, x[ 1], y[ 7]);
+ word3_muladd(&w1, &w0, &w2, x[ 2], y[ 6]);
+ word3_muladd(&w1, &w0, &w2, x[ 3], y[ 5]);
+ word3_muladd(&w1, &w0, &w2, x[ 4], y[ 4]);
+ word3_muladd(&w1, &w0, &w2, x[ 5], y[ 3]);
+ word3_muladd(&w1, &w0, &w2, x[ 6], y[ 2]);
+ word3_muladd(&w1, &w0, &w2, x[ 7], y[ 1]);
+ word3_muladd(&w1, &w0, &w2, x[ 8], y[ 0]);
+ z[ 8] = w2; w2 = 0;
word3_muladd(&w2, &w1, &w0, x[ 0], y[ 9]);
word3_muladd(&w2, &w1, &w0, x[ 1], y[ 8]);
@@ -668,34 +668,34 @@ void bigint_comba_mul16(word z[32], const word x[16], const word y[16])
word3_muladd(&w2, &w1, &w0, x[ 7], y[ 2]);
word3_muladd(&w2, &w1, &w0, x[ 8], y[ 1]);
word3_muladd(&w2, &w1, &w0, x[ 9], y[ 0]);
- z[9] = w0; w0 = w1; w1 = w2; w2 = 0;
-
- word3_muladd(&w2, &w1, &w0, x[ 0], y[10]);
- word3_muladd(&w2, &w1, &w0, x[ 1], y[ 9]);
- word3_muladd(&w2, &w1, &w0, x[ 2], y[ 8]);
- word3_muladd(&w2, &w1, &w0, x[ 3], y[ 7]);
- word3_muladd(&w2, &w1, &w0, x[ 4], y[ 6]);
- word3_muladd(&w2, &w1, &w0, x[ 5], y[ 5]);
- word3_muladd(&w2, &w1, &w0, x[ 6], y[ 4]);
- word3_muladd(&w2, &w1, &w0, x[ 7], y[ 3]);
- word3_muladd(&w2, &w1, &w0, x[ 8], y[ 2]);
- word3_muladd(&w2, &w1, &w0, x[ 9], y[ 1]);
- word3_muladd(&w2, &w1, &w0, x[10], y[ 0]);
- z[10] = w0; w0 = w1; w1 = w2; w2 = 0;
-
- word3_muladd(&w2, &w1, &w0, x[ 0], y[11]);
- word3_muladd(&w2, &w1, &w0, x[ 1], y[10]);
- word3_muladd(&w2, &w1, &w0, x[ 2], y[ 9]);
- word3_muladd(&w2, &w1, &w0, x[ 3], y[ 8]);
- word3_muladd(&w2, &w1, &w0, x[ 4], y[ 7]);
- word3_muladd(&w2, &w1, &w0, x[ 5], y[ 6]);
- word3_muladd(&w2, &w1, &w0, x[ 6], y[ 5]);
- word3_muladd(&w2, &w1, &w0, x[ 7], y[ 4]);
- word3_muladd(&w2, &w1, &w0, x[ 8], y[ 3]);
- word3_muladd(&w2, &w1, &w0, x[ 9], y[ 2]);
- word3_muladd(&w2, &w1, &w0, x[10], y[ 1]);
- word3_muladd(&w2, &w1, &w0, x[11], y[ 0]);
- z[11] = w0; w0 = w1; w1 = w2; w2 = 0;
+ z[ 9] = w0; w0 = 0;
+
+ word3_muladd(&w0, &w2, &w1, x[ 0], y[10]);
+ word3_muladd(&w0, &w2, &w1, x[ 1], y[ 9]);
+ word3_muladd(&w0, &w2, &w1, x[ 2], y[ 8]);
+ word3_muladd(&w0, &w2, &w1, x[ 3], y[ 7]);
+ word3_muladd(&w0, &w2, &w1, x[ 4], y[ 6]);
+ word3_muladd(&w0, &w2, &w1, x[ 5], y[ 5]);
+ word3_muladd(&w0, &w2, &w1, x[ 6], y[ 4]);
+ word3_muladd(&w0, &w2, &w1, x[ 7], y[ 3]);
+ word3_muladd(&w0, &w2, &w1, x[ 8], y[ 2]);
+ word3_muladd(&w0, &w2, &w1, x[ 9], y[ 1]);
+ word3_muladd(&w0, &w2, &w1, x[10], y[ 0]);
+ z[10] = w1; w1 = 0;
+
+ word3_muladd(&w1, &w0, &w2, x[ 0], y[11]);
+ word3_muladd(&w1, &w0, &w2, x[ 1], y[10]);
+ word3_muladd(&w1, &w0, &w2, x[ 2], y[ 9]);
+ word3_muladd(&w1, &w0, &w2, x[ 3], y[ 8]);
+ word3_muladd(&w1, &w0, &w2, x[ 4], y[ 7]);
+ word3_muladd(&w1, &w0, &w2, x[ 5], y[ 6]);
+ word3_muladd(&w1, &w0, &w2, x[ 6], y[ 5]);
+ word3_muladd(&w1, &w0, &w2, x[ 7], y[ 4]);
+ word3_muladd(&w1, &w0, &w2, x[ 8], y[ 3]);
+ word3_muladd(&w1, &w0, &w2, x[ 9], y[ 2]);
+ word3_muladd(&w1, &w0, &w2, x[10], y[ 1]);
+ word3_muladd(&w1, &w0, &w2, x[11], y[ 0]);
+ z[11] = w2; w2 = 0;
word3_muladd(&w2, &w1, &w0, x[ 0], y[12]);
word3_muladd(&w2, &w1, &w0, x[ 1], y[11]);
@@ -710,40 +710,40 @@ void bigint_comba_mul16(word z[32], const word x[16], const word y[16])
word3_muladd(&w2, &w1, &w0, x[10], y[ 2]);
word3_muladd(&w2, &w1, &w0, x[11], y[ 1]);
word3_muladd(&w2, &w1, &w0, x[12], y[ 0]);
- z[12] = w0; w0 = w1; w1 = w2; w2 = 0;
-
- word3_muladd(&w2, &w1, &w0, x[ 0], y[13]);
- word3_muladd(&w2, &w1, &w0, x[ 1], y[12]);
- word3_muladd(&w2, &w1, &w0, x[ 2], y[11]);
- word3_muladd(&w2, &w1, &w0, x[ 3], y[10]);
- word3_muladd(&w2, &w1, &w0, x[ 4], y[ 9]);
- word3_muladd(&w2, &w1, &w0, x[ 5], y[ 8]);
- word3_muladd(&w2, &w1, &w0, x[ 6], y[ 7]);
- word3_muladd(&w2, &w1, &w0, x[ 7], y[ 6]);
- word3_muladd(&w2, &w1, &w0, x[ 8], y[ 5]);
- word3_muladd(&w2, &w1, &w0, x[ 9], y[ 4]);
- word3_muladd(&w2, &w1, &w0, x[10], y[ 3]);
- word3_muladd(&w2, &w1, &w0, x[11], y[ 2]);
- word3_muladd(&w2, &w1, &w0, x[12], y[ 1]);
- word3_muladd(&w2, &w1, &w0, x[13], y[ 0]);
- z[13] = w0; w0 = w1; w1 = w2; w2 = 0;
-
- word3_muladd(&w2, &w1, &w0, x[ 0], y[14]);
- word3_muladd(&w2, &w1, &w0, x[ 1], y[13]);
- word3_muladd(&w2, &w1, &w0, x[ 2], y[12]);
- word3_muladd(&w2, &w1, &w0, x[ 3], y[11]);
- word3_muladd(&w2, &w1, &w0, x[ 4], y[10]);
- word3_muladd(&w2, &w1, &w0, x[ 5], y[ 9]);
- word3_muladd(&w2, &w1, &w0, x[ 6], y[ 8]);
- word3_muladd(&w2, &w1, &w0, x[ 7], y[ 7]);
- word3_muladd(&w2, &w1, &w0, x[ 8], y[ 6]);
- word3_muladd(&w2, &w1, &w0, x[ 9], y[ 5]);
- word3_muladd(&w2, &w1, &w0, x[10], y[ 4]);
- word3_muladd(&w2, &w1, &w0, x[11], y[ 3]);
- word3_muladd(&w2, &w1, &w0, x[12], y[ 2]);
- word3_muladd(&w2, &w1, &w0, x[13], y[ 1]);
- word3_muladd(&w2, &w1, &w0, x[14], y[ 0]);
- z[14] = w0; w0 = w1; w1 = w2; w2 = 0;
+ z[12] = w0; w0 = 0;
+
+ word3_muladd(&w0, &w2, &w1, x[ 0], y[13]);
+ word3_muladd(&w0, &w2, &w1, x[ 1], y[12]);
+ word3_muladd(&w0, &w2, &w1, x[ 2], y[11]);
+ word3_muladd(&w0, &w2, &w1, x[ 3], y[10]);
+ word3_muladd(&w0, &w2, &w1, x[ 4], y[ 9]);
+ word3_muladd(&w0, &w2, &w1, x[ 5], y[ 8]);
+ word3_muladd(&w0, &w2, &w1, x[ 6], y[ 7]);
+ word3_muladd(&w0, &w2, &w1, x[ 7], y[ 6]);
+ word3_muladd(&w0, &w2, &w1, x[ 8], y[ 5]);
+ word3_muladd(&w0, &w2, &w1, x[ 9], y[ 4]);
+ word3_muladd(&w0, &w2, &w1, x[10], y[ 3]);
+ word3_muladd(&w0, &w2, &w1, x[11], y[ 2]);
+ word3_muladd(&w0, &w2, &w1, x[12], y[ 1]);
+ word3_muladd(&w0, &w2, &w1, x[13], y[ 0]);
+ z[13] = w1; w1 = 0;
+
+ word3_muladd(&w1, &w0, &w2, x[ 0], y[14]);
+ word3_muladd(&w1, &w0, &w2, x[ 1], y[13]);
+ word3_muladd(&w1, &w0, &w2, x[ 2], y[12]);
+ word3_muladd(&w1, &w0, &w2, x[ 3], y[11]);
+ word3_muladd(&w1, &w0, &w2, x[ 4], y[10]);
+ word3_muladd(&w1, &w0, &w2, x[ 5], y[ 9]);
+ word3_muladd(&w1, &w0, &w2, x[ 6], y[ 8]);
+ word3_muladd(&w1, &w0, &w2, x[ 7], y[ 7]);
+ word3_muladd(&w1, &w0, &w2, x[ 8], y[ 6]);
+ word3_muladd(&w1, &w0, &w2, x[ 9], y[ 5]);
+ word3_muladd(&w1, &w0, &w2, x[10], y[ 4]);
+ word3_muladd(&w1, &w0, &w2, x[11], y[ 3]);
+ word3_muladd(&w1, &w0, &w2, x[12], y[ 2]);
+ word3_muladd(&w1, &w0, &w2, x[13], y[ 1]);
+ word3_muladd(&w1, &w0, &w2, x[14], y[ 0]);
+ z[14] = w2; w2 = 0;
word3_muladd(&w2, &w1, &w0, x[ 0], y[15]);
word3_muladd(&w2, &w1, &w0, x[ 1], y[14]);
@@ -761,40 +761,40 @@ void bigint_comba_mul16(word z[32], const word x[16], const word y[16])
word3_muladd(&w2, &w1, &w0, x[13], y[ 2]);
word3_muladd(&w2, &w1, &w0, x[14], y[ 1]);
word3_muladd(&w2, &w1, &w0, x[15], y[ 0]);
- z[15] = w0; w0 = w1; w1 = w2; w2 = 0;
-
- word3_muladd(&w2, &w1, &w0, x[ 1], y[15]);
- word3_muladd(&w2, &w1, &w0, x[ 2], y[14]);
- word3_muladd(&w2, &w1, &w0, x[ 3], y[13]);
- word3_muladd(&w2, &w1, &w0, x[ 4], y[12]);
- word3_muladd(&w2, &w1, &w0, x[ 5], y[11]);
- word3_muladd(&w2, &w1, &w0, x[ 6], y[10]);
- word3_muladd(&w2, &w1, &w0, x[ 7], y[ 9]);
- word3_muladd(&w2, &w1, &w0, x[ 8], y[ 8]);
- word3_muladd(&w2, &w1, &w0, x[ 9], y[ 7]);
- word3_muladd(&w2, &w1, &w0, x[10], y[ 6]);
- word3_muladd(&w2, &w1, &w0, x[11], y[ 5]);
- word3_muladd(&w2, &w1, &w0, x[12], y[ 4]);
- word3_muladd(&w2, &w1, &w0, x[13], y[ 3]);
- word3_muladd(&w2, &w1, &w0, x[14], y[ 2]);
- word3_muladd(&w2, &w1, &w0, x[15], y[ 1]);
- z[16] = w0; w0 = w1; w1 = w2; w2 = 0;
-
- word3_muladd(&w2, &w1, &w0, x[ 2], y[15]);
- word3_muladd(&w2, &w1, &w0, x[ 3], y[14]);
- word3_muladd(&w2, &w1, &w0, x[ 4], y[13]);
- word3_muladd(&w2, &w1, &w0, x[ 5], y[12]);
- word3_muladd(&w2, &w1, &w0, x[ 6], y[11]);
- word3_muladd(&w2, &w1, &w0, x[ 7], y[10]);
- word3_muladd(&w2, &w1, &w0, x[ 8], y[ 9]);
- word3_muladd(&w2, &w1, &w0, x[ 9], y[ 8]);
- word3_muladd(&w2, &w1, &w0, x[10], y[ 7]);
- word3_muladd(&w2, &w1, &w0, x[11], y[ 6]);
- word3_muladd(&w2, &w1, &w0, x[12], y[ 5]);
- word3_muladd(&w2, &w1, &w0, x[13], y[ 4]);
- word3_muladd(&w2, &w1, &w0, x[14], y[ 3]);
- word3_muladd(&w2, &w1, &w0, x[15], y[ 2]);
- z[17] = w0; w0 = w1; w1 = w2; w2 = 0;
+ z[15] = w0; w0 = 0;
+
+ word3_muladd(&w0, &w2, &w1, x[ 1], y[15]);
+ word3_muladd(&w0, &w2, &w1, x[ 2], y[14]);
+ word3_muladd(&w0, &w2, &w1, x[ 3], y[13]);
+ word3_muladd(&w0, &w2, &w1, x[ 4], y[12]);
+ word3_muladd(&w0, &w2, &w1, x[ 5], y[11]);
+ word3_muladd(&w0, &w2, &w1, x[ 6], y[10]);
+ word3_muladd(&w0, &w2, &w1, x[ 7], y[ 9]);
+ word3_muladd(&w0, &w2, &w1, x[ 8], y[ 8]);
+ word3_muladd(&w0, &w2, &w1, x[ 9], y[ 7]);
+ word3_muladd(&w0, &w2, &w1, x[10], y[ 6]);
+ word3_muladd(&w0, &w2, &w1, x[11], y[ 5]);
+ word3_muladd(&w0, &w2, &w1, x[12], y[ 4]);
+ word3_muladd(&w0, &w2, &w1, x[13], y[ 3]);
+ word3_muladd(&w0, &w2, &w1, x[14], y[ 2]);
+ word3_muladd(&w0, &w2, &w1, x[15], y[ 1]);
+ z[16] = w1; w1 = 0;
+
+ word3_muladd(&w1, &w0, &w2, x[ 2], y[15]);
+ word3_muladd(&w1, &w0, &w2, x[ 3], y[14]);
+ word3_muladd(&w1, &w0, &w2, x[ 4], y[13]);
+ word3_muladd(&w1, &w0, &w2, x[ 5], y[12]);
+ word3_muladd(&w1, &w0, &w2, x[ 6], y[11]);
+ word3_muladd(&w1, &w0, &w2, x[ 7], y[10]);
+ word3_muladd(&w1, &w0, &w2, x[ 8], y[ 9]);
+ word3_muladd(&w1, &w0, &w2, x[ 9], y[ 8]);
+ word3_muladd(&w1, &w0, &w2, x[10], y[ 7]);
+ word3_muladd(&w1, &w0, &w2, x[11], y[ 6]);
+ word3_muladd(&w1, &w0, &w2, x[12], y[ 5]);
+ word3_muladd(&w1, &w0, &w2, x[13], y[ 4]);
+ word3_muladd(&w1, &w0, &w2, x[14], y[ 3]);
+ word3_muladd(&w1, &w0, &w2, x[15], y[ 2]);
+ z[17] = w2; w2 = 0;
word3_muladd(&w2, &w1, &w0, x[ 3], y[15]);
word3_muladd(&w2, &w1, &w0, x[ 4], y[14]);
@@ -809,34 +809,34 @@ void bigint_comba_mul16(word z[32], const word x[16], const word y[16])
word3_muladd(&w2, &w1, &w0, x[13], y[ 5]);
word3_muladd(&w2, &w1, &w0, x[14], y[ 4]);
word3_muladd(&w2, &w1, &w0, x[15], y[ 3]);
- z[18] = w0; w0 = w1; w1 = w2; w2 = 0;
-
- word3_muladd(&w2, &w1, &w0, x[ 4], y[15]);
- word3_muladd(&w2, &w1, &w0, x[ 5], y[14]);
- word3_muladd(&w2, &w1, &w0, x[ 6], y[13]);
- word3_muladd(&w2, &w1, &w0, x[ 7], y[12]);
- word3_muladd(&w2, &w1, &w0, x[ 8], y[11]);
- word3_muladd(&w2, &w1, &w0, x[ 9], y[10]);
- word3_muladd(&w2, &w1, &w0, x[10], y[ 9]);
- word3_muladd(&w2, &w1, &w0, x[11], y[ 8]);
- word3_muladd(&w2, &w1, &w0, x[12], y[ 7]);
- word3_muladd(&w2, &w1, &w0, x[13], y[ 6]);
- word3_muladd(&w2, &w1, &w0, x[14], y[ 5]);
- word3_muladd(&w2, &w1, &w0, x[15], y[ 4]);
- z[19] = w0; w0 = w1; w1 = w2; w2 = 0;
-
- word3_muladd(&w2, &w1, &w0, x[ 5], y[15]);
- word3_muladd(&w2, &w1, &w0, x[ 6], y[14]);
- word3_muladd(&w2, &w1, &w0, x[ 7], y[13]);
- word3_muladd(&w2, &w1, &w0, x[ 8], y[12]);
- word3_muladd(&w2, &w1, &w0, x[ 9], y[11]);
- word3_muladd(&w2, &w1, &w0, x[10], y[10]);
- word3_muladd(&w2, &w1, &w0, x[11], y[ 9]);
- word3_muladd(&w2, &w1, &w0, x[12], y[ 8]);
- word3_muladd(&w2, &w1, &w0, x[13], y[ 7]);
- word3_muladd(&w2, &w1, &w0, x[14], y[ 6]);
- word3_muladd(&w2, &w1, &w0, x[15], y[ 5]);
- z[20] = w0; w0 = w1; w1 = w2; w2 = 0;
+ z[18] = w0; w0 = 0;
+
+ word3_muladd(&w0, &w2, &w1, x[ 4], y[15]);
+ word3_muladd(&w0, &w2, &w1, x[ 5], y[14]);
+ word3_muladd(&w0, &w2, &w1, x[ 6], y[13]);
+ word3_muladd(&w0, &w2, &w1, x[ 7], y[12]);
+ word3_muladd(&w0, &w2, &w1, x[ 8], y[11]);
+ word3_muladd(&w0, &w2, &w1, x[ 9], y[10]);
+ word3_muladd(&w0, &w2, &w1, x[10], y[ 9]);
+ word3_muladd(&w0, &w2, &w1, x[11], y[ 8]);
+ word3_muladd(&w0, &w2, &w1, x[12], y[ 7]);
+ word3_muladd(&w0, &w2, &w1, x[13], y[ 6]);
+ word3_muladd(&w0, &w2, &w1, x[14], y[ 5]);
+ word3_muladd(&w0, &w2, &w1, x[15], y[ 4]);
+ z[19] = w1; w1 = 0;
+
+ word3_muladd(&w1, &w0, &w2, x[ 5], y[15]);
+ word3_muladd(&w1, &w0, &w2, x[ 6], y[14]);
+ word3_muladd(&w1, &w0, &w2, x[ 7], y[13]);
+ word3_muladd(&w1, &w0, &w2, x[ 8], y[12]);
+ word3_muladd(&w1, &w0, &w2, x[ 9], y[11]);
+ word3_muladd(&w1, &w0, &w2, x[10], y[10]);
+ word3_muladd(&w1, &w0, &w2, x[11], y[ 9]);
+ word3_muladd(&w1, &w0, &w2, x[12], y[ 8]);
+ word3_muladd(&w1, &w0, &w2, x[13], y[ 7]);
+ word3_muladd(&w1, &w0, &w2, x[14], y[ 6]);
+ word3_muladd(&w1, &w0, &w2, x[15], y[ 5]);
+ z[20] = w2; w2 = 0;
word3_muladd(&w2, &w1, &w0, x[ 6], y[15]);
word3_muladd(&w2, &w1, &w0, x[ 7], y[14]);
@@ -848,28 +848,28 @@ void bigint_comba_mul16(word z[32], const word x[16], const word y[16])
word3_muladd(&w2, &w1, &w0, x[13], y[ 8]);
word3_muladd(&w2, &w1, &w0, x[14], y[ 7]);
word3_muladd(&w2, &w1, &w0, x[15], y[ 6]);
- z[21] = w0; w0 = w1; w1 = w2; w2 = 0;
-
- word3_muladd(&w2, &w1, &w0, x[ 7], y[15]);
- word3_muladd(&w2, &w1, &w0, x[ 8], y[14]);
- word3_muladd(&w2, &w1, &w0, x[ 9], y[13]);
- word3_muladd(&w2, &w1, &w0, x[10], y[12]);
- word3_muladd(&w2, &w1, &w0, x[11], y[11]);
- word3_muladd(&w2, &w1, &w0, x[12], y[10]);
- word3_muladd(&w2, &w1, &w0, x[13], y[ 9]);
- word3_muladd(&w2, &w1, &w0, x[14], y[ 8]);
- word3_muladd(&w2, &w1, &w0, x[15], y[ 7]);
- z[22] = w0; w0 = w1; w1 = w2; w2 = 0;
-
- word3_muladd(&w2, &w1, &w0, x[ 8], y[15]);
- word3_muladd(&w2, &w1, &w0, x[ 9], y[14]);
- word3_muladd(&w2, &w1, &w0, x[10], y[13]);
- word3_muladd(&w2, &w1, &w0, x[11], y[12]);
- word3_muladd(&w2, &w1, &w0, x[12], y[11]);
- word3_muladd(&w2, &w1, &w0, x[13], y[10]);
- word3_muladd(&w2, &w1, &w0, x[14], y[ 9]);
- word3_muladd(&w2, &w1, &w0, x[15], y[ 8]);
- z[23] = w0; w0 = w1; w1 = w2; w2 = 0;
+ z[21] = w0; w0 = 0;
+
+ word3_muladd(&w0, &w2, &w1, x[ 7], y[15]);
+ word3_muladd(&w0, &w2, &w1, x[ 8], y[14]);
+ word3_muladd(&w0, &w2, &w1, x[ 9], y[13]);
+ word3_muladd(&w0, &w2, &w1, x[10], y[12]);
+ word3_muladd(&w0, &w2, &w1, x[11], y[11]);
+ word3_muladd(&w0, &w2, &w1, x[12], y[10]);
+ word3_muladd(&w0, &w2, &w1, x[13], y[ 9]);
+ word3_muladd(&w0, &w2, &w1, x[14], y[ 8]);
+ word3_muladd(&w0, &w2, &w1, x[15], y[ 7]);
+ z[22] = w1; w1 = 0;
+
+ word3_muladd(&w1, &w0, &w2, x[ 8], y[15]);
+ word3_muladd(&w1, &w0, &w2, x[ 9], y[14]);
+ word3_muladd(&w1, &w0, &w2, x[10], y[13]);
+ word3_muladd(&w1, &w0, &w2, x[11], y[12]);
+ word3_muladd(&w1, &w0, &w2, x[12], y[11]);
+ word3_muladd(&w1, &w0, &w2, x[13], y[10]);
+ word3_muladd(&w1, &w0, &w2, x[14], y[ 9]);
+ word3_muladd(&w1, &w0, &w2, x[15], y[ 8]);
+ z[23] = w2; w2 = 0;
word3_muladd(&w2, &w1, &w0, x[ 9], y[15]);
word3_muladd(&w2, &w1, &w0, x[10], y[14]);
@@ -878,37 +878,37 @@ void bigint_comba_mul16(word z[32], const word x[16], const word y[16])
word3_muladd(&w2, &w1, &w0, x[13], y[11]);
word3_muladd(&w2, &w1, &w0, x[14], y[10]);
word3_muladd(&w2, &w1, &w0, x[15], y[ 9]);
- z[24] = w0; w0 = w1; w1 = w2; w2 = 0;
-
- word3_muladd(&w2, &w1, &w0, x[10], y[15]);
- word3_muladd(&w2, &w1, &w0, x[11], y[14]);
- word3_muladd(&w2, &w1, &w0, x[12], y[13]);
- word3_muladd(&w2, &w1, &w0, x[13], y[12]);
- word3_muladd(&w2, &w1, &w0, x[14], y[11]);
- word3_muladd(&w2, &w1, &w0, x[15], y[10]);
- z[25] = w0; w0 = w1; w1 = w2; w2 = 0;
-
- word3_muladd(&w2, &w1, &w0, x[11], y[15]);
- word3_muladd(&w2, &w1, &w0, x[12], y[14]);
- word3_muladd(&w2, &w1, &w0, x[13], y[13]);
- word3_muladd(&w2, &w1, &w0, x[14], y[12]);
- word3_muladd(&w2, &w1, &w0, x[15], y[11]);
- z[26] = w0; w0 = w1; w1 = w2; w2 = 0;
+ z[24] = w0; w0 = 0;
+
+ word3_muladd(&w0, &w2, &w1, x[10], y[15]);
+ word3_muladd(&w0, &w2, &w1, x[11], y[14]);
+ word3_muladd(&w0, &w2, &w1, x[12], y[13]);
+ word3_muladd(&w0, &w2, &w1, x[13], y[12]);
+ word3_muladd(&w0, &w2, &w1, x[14], y[11]);
+ word3_muladd(&w0, &w2, &w1, x[15], y[10]);
+ z[25] = w1; w1 = 0;
+
+ word3_muladd(&w1, &w0, &w2, x[11], y[15]);
+ word3_muladd(&w1, &w0, &w2, x[12], y[14]);
+ word3_muladd(&w1, &w0, &w2, x[13], y[13]);
+ word3_muladd(&w1, &w0, &w2, x[14], y[12]);
+ word3_muladd(&w1, &w0, &w2, x[15], y[11]);
+ z[26] = w2; w2 = 0;
word3_muladd(&w2, &w1, &w0, x[12], y[15]);
word3_muladd(&w2, &w1, &w0, x[13], y[14]);
word3_muladd(&w2, &w1, &w0, x[14], y[13]);
word3_muladd(&w2, &w1, &w0, x[15], y[12]);
- z[27] = w0; w0 = w1; w1 = w2; w2 = 0;
+ z[27] = w0; w0 = 0;
- word3_muladd(&w2, &w1, &w0, x[13], y[15]);
- word3_muladd(&w2, &w1, &w0, x[14], y[14]);
- word3_muladd(&w2, &w1, &w0, x[15], y[13]);
- z[28] = w0; w0 = w1; w1 = w2; w2 = 0;
+ word3_muladd(&w0, &w2, &w1, x[13], y[15]);
+ word3_muladd(&w0, &w2, &w1, x[14], y[14]);
+ word3_muladd(&w0, &w2, &w1, x[15], y[13]);
+ z[28] = w1; w1 = 0;
- word3_muladd(&w2, &w1, &w0, x[14], y[15]);
- word3_muladd(&w2, &w1, &w0, x[15], y[14]);
- z[29] = w0; w0 = w1; w1 = w2; w2 = 0;
+ word3_muladd(&w1, &w0, &w2, x[14], y[15]);
+ word3_muladd(&w1, &w0, &w2, x[15], y[14]);
+ z[29] = w2; w2 = 0;
word3_muladd(&w2, &w1, &w0, x[15], y[15]);
z[30] = w0;
diff --git a/src/math/mp/mp_core.h b/src/math/mp/mp_core.h
index e1692006e..82bdbad53 100644
--- a/src/math/mp/mp_core.h
+++ b/src/math/mp/mp_core.h
@@ -77,19 +77,35 @@ void bigint_simple_sqr(word z[], const word x[], size_t x_size);
void bigint_linmul2(word x[], size_t x_size, word y);
void bigint_linmul3(word z[], const word x[], size_t x_size, word y);
-/*
+/**
* Montgomery Reduction
-* @param z integer to reduce (also output in first x_size+1 words)
-* @param z_size size of z (should be >= 2*x_size+1)
-* @param workspace array of at least 2*(x_size+1) words
-* @param x modulus
-* @param x_size size of x
-* @param u Montgomery value
+* @param z integer to reduce (also output in first p_size+1 words)
+* @param z_size size of z (should be >= 2*p_size+1)
+* @param p modulus
+* @param p_size size of p
+* @param p_dash Montgomery value
+* @param workspace array of at least 2*(p_size+1) words
*/
void bigint_monty_redc(word z[], size_t z_size,
- word workspace[],
- const word x[], size_t x_size,
- word u);
+ const word p[], size_t p_size, word p_dash,
+ word workspace[]);
+
+/*
+* Montgomery Multiplication
+*/
+void bigint_monty_mul(word z[], size_t z_size,
+ const word x[], size_t x_size, size_t x_sw,
+ const word y[], size_t y_size, size_t y_sw,
+ const word p[], size_t p_size, word p_dash,
+ word workspace[]);
+
+/*
+* Montgomery Squaring
+*/
+void bigint_monty_sqr(word z[], size_t z_size,
+ const word x[], size_t x_size, size_t x_sw,
+ const word p[], size_t p_size, word p_dash,
+ word workspace[]);
/*
* Division operation
@@ -124,8 +140,7 @@ void bigint_comba_mul16(word z[32], const word x[16], const word y[16]);
void bigint_comba_sqr4(word out[8], const word in[4]);
void bigint_comba_sqr6(word out[12], const word in[6]);
void bigint_comba_sqr8(word out[16], const word in[8]);
-void bigint_comba_sqr8(word out[32], const word in[16]);
-void bigint_comba_sqr16(word out[64], const word in[32]);
+void bigint_comba_sqr16(word out[32], const word in[16]);
}
diff --git a/src/math/mp/mp_generic/mp_asm.h b/src/math/mp/mp_generic/mp_asm.h
index ee46e1aa9..7c18343ef 100644
--- a/src/math/mp/mp_generic/mp_asm.h
+++ b/src/math/mp/mp_generic/mp_asm.h
@@ -14,7 +14,7 @@
#if (BOTAN_MP_WORD_BITS == 8)
typedef Botan::u16bit dword;
#elif (BOTAN_MP_WORD_BITS == 16)
- typedef Botan::size_t dword;
+ typedef Botan::u32bit dword;
#elif (BOTAN_MP_WORD_BITS == 32)
typedef Botan::u64bit dword;
#elif (BOTAN_MP_WORD_BITS == 64)
diff --git a/src/math/mp/mp_monty.cpp b/src/math/mp/mp_monty.cpp
new file mode 100644
index 000000000..d37fb5844
--- /dev/null
+++ b/src/math/mp/mp_monty.cpp
@@ -0,0 +1,99 @@
+/*
+* Montgomery Reduction
+* (C) 1999-2011 Jack Lloyd
+* 2006 Luca Piccarreta
+*
+* Distributed under the terms of the Botan license
+*/
+
+#include <botan/internal/mp_core.h>
+#include <botan/internal/mp_asm.h>
+#include <botan/internal/mp_asmi.h>
+#include <botan/mem_ops.h>
+
+namespace Botan {
+
+extern "C" {
+
+/*
+* Montgomery Reduction Algorithm
+*/
+void bigint_monty_redc(word z[], size_t z_size,
+ const word p[], size_t p_size,
+ word p_dash, word ws[])
+ {
+ const size_t blocks_of_8 = p_size - (p_size % 8);
+
+ for(size_t i = 0; i != p_size; ++i)
+ {
+ word* z_i = z + i;
+
+ const word y = z_i[0] * p_dash;
+
+ /*
+ bigint_linmul3(ws, p, p_size, y);
+ bigint_add2(z_i, z_size - i, ws, p_size+1);
+ */
+
+ word carry = 0;
+
+ for(size_t j = 0; j != blocks_of_8; j += 8)
+ carry = word8_madd3(z_i + j, p + j, y, carry);
+
+ for(size_t j = blocks_of_8; j != p_size; ++j)
+ z_i[j] = word_madd3(p[j], y, z_i[j], &carry);
+
+ word z_sum = z_i[p_size] + carry;
+ carry = (z_sum < z_i[p_size]);
+ z_i[p_size] = z_sum;
+
+ for(size_t j = p_size + 1; carry && j != z_size - i; ++j)
+ {
+ ++z_i[j];
+ carry = !z_i[j];
+ }
+ }
+
+ word borrow = 0;
+ for(size_t i = 0; i != p_size; ++i)
+ ws[i] = word_sub(z[p_size + i], p[i], &borrow);
+
+ ws[p_size] = word_sub(z[p_size+p_size], 0, &borrow);
+
+ copy_mem(ws + p_size + 1, z + p_size, p_size + 1);
+
+ copy_mem(z, ws + borrow*(p_size+1), p_size + 1);
+ clear_mem(z + p_size + 1, z_size - p_size - 1);
+ }
+
+void bigint_monty_mul(word z[], size_t z_size,
+ const word x[], size_t x_size, size_t x_sw,
+ const word y[], size_t y_size, size_t y_sw,
+ const word p[], size_t p_size, word p_dash,
+ word ws[])
+ {
+ bigint_mul(&z[0], z_size, &ws[0],
+ &x[0], x_size, x_sw,
+ &y[0], y_size, y_sw);
+
+ bigint_monty_redc(&z[0], z_size,
+ &p[0], p_size, p_dash,
+ &ws[0]);
+ }
+
+void bigint_monty_sqr(word z[], size_t z_size,
+ const word x[], size_t x_size, size_t x_sw,
+ const word p[], size_t p_size, word p_dash,
+ word ws[])
+ {
+ bigint_sqr(&z[0], z_size, &ws[0],
+ &x[0], x_size, x_sw);
+
+ bigint_monty_redc(&z[0], z_size,
+ &p[0], p_size, p_dash,
+ &ws[0]);
+ }
+
+}
+
+}
diff --git a/src/math/mp/mulop_generic/mp_mulop.cpp b/src/math/mp/mp_mulop.cpp
index e6a8ba891..e6a8ba891 100644
--- a/src/math/mp/mulop_generic/mp_mulop.cpp
+++ b/src/math/mp/mp_mulop.cpp
diff --git a/src/math/mp/mulop_generic/info.txt b/src/math/mp/mulop_generic/info.txt
deleted file mode 100644
index 548d0f44b..000000000
--- a/src/math/mp/mulop_generic/info.txt
+++ /dev/null
@@ -1,5 +0,0 @@
-load_on dep
-
-<source>
-mp_mulop.cpp
-</source>
diff --git a/src/math/numbertheory/info.txt b/src/math/numbertheory/info.txt
index 18349ef78..0c6a9aefc 100644
--- a/src/math/numbertheory/info.txt
+++ b/src/math/numbertheory/info.txt
@@ -1,11 +1,9 @@
-load_on auto
-
define BIGINT_MATH
+load_on auto
+
<header:public>
-curve_gfp.h
numthry.h
-point_gfp.h
pow_mod.h
reducer.h
</header:public>
@@ -20,7 +18,6 @@ jacobi.cpp
make_prm.cpp
mp_numth.cpp
numthry.cpp
-point_gfp.cpp
pow_mod.cpp
powm_fw.cpp
powm_mnt.cpp
diff --git a/src/math/numbertheory/numthry.cpp b/src/math/numbertheory/numthry.cpp
index 8018c1d2d..c7896c17a 100644
--- a/src/math/numbertheory/numthry.cpp
+++ b/src/math/numbertheory/numthry.cpp
@@ -1,6 +1,6 @@
/*
* Number Theory Functions
-* (C) 1999-2010 Jack Lloyd
+* (C) 1999-2011 Jack Lloyd
*
* Distributed under the terms of the Botan license
*/
@@ -20,7 +20,7 @@ namespace {
class MillerRabin_Test
{
public:
- bool passes_test(const BigInt& nonce);
+ bool is_witness(const BigInt& nonce);
MillerRabin_Test(const BigInt& num);
private:
BigInt n, r, n_minus_1;
@@ -30,26 +30,32 @@ class MillerRabin_Test
};
/*
-* Miller-Rabin Test
+* Miller-Rabin Test, as described in Handbook of Applied Cryptography
+* section 4.24
*/
-bool MillerRabin_Test::passes_test(const BigInt& a)
+bool MillerRabin_Test::is_witness(const BigInt& a)
{
if(a < 2 || a >= n_minus_1)
throw Invalid_Argument("Bad size for nonce in Miller-Rabin test");
BigInt y = pow_mod(a);
if(y == 1 || y == n_minus_1)
- return true;
+ return false;
for(size_t i = 1; i != s; ++i)
{
y = reducer.square(y);
- if(y == 1)
- return false;
- if(y == n_minus_1)
+ if(y == 1) // found a non-trivial square root
return true;
+
+ if(y == n_minus_1) // -1, trivial square root, so give up
+ return false;
}
+
+ if(y != n_minus_1) // fails Fermat test
+ return true;
+
return false;
}
@@ -297,7 +303,7 @@ bool primality_test(const BigInt& n,
while(nonce < 2 || nonce >= (n-1))
nonce.randomize(rng, NONCE_BITS);
- if(!mr.passes_test(nonce))
+ if(mr.is_witness(nonce))
return false;
}
return true;
diff --git a/src/math/numbertheory/pow_mod.cpp b/src/math/numbertheory/pow_mod.cpp
index a66a1f7df..bf6b29275 100644
--- a/src/math/numbertheory/pow_mod.cpp
+++ b/src/math/numbertheory/pow_mod.cpp
@@ -118,7 +118,12 @@ size_t Power_Mod::window_bits(size_t exp_bits, size_t,
Power_Mod::Usage_Hints hints)
{
static const size_t wsize[][2] = {
- { 2048, 7 }, { 1024, 6 }, { 256, 5 }, { 128, 4 }, { 64, 3 }, { 0, 0 }
+ { 1434, 7 },
+ { 539, 6 },
+ { 197, 4 },
+ { 70, 3 },
+ { 25, 2 },
+ { 0, 0 }
};
size_t window_bits = 1;
diff --git a/src/math/numbertheory/powm_mnt.cpp b/src/math/numbertheory/powm_mnt.cpp
index 421470364..8993f4ba9 100644
--- a/src/math/numbertheory/powm_mnt.cpp
+++ b/src/math/numbertheory/powm_mnt.cpp
@@ -33,13 +33,12 @@ void Montgomery_Exponentiator::set_base(const BigInt& base)
SecureVector<word> workspace(z.size());
g[0] = (base >= modulus) ? (base % modulus) : base;
- bigint_mul(&z[0], z.size(), &workspace[0],
- g[0].data(), g[0].size(), g[0].sig_words(),
- R2.data(), R2.size(), R2.sig_words());
- bigint_monty_redc(&z[0], z.size(),
- &workspace[0],
- modulus.data(), mod_words, mod_prime);
+ bigint_monty_mul(&z[0], z.size(),
+ g[0].data(), g[0].size(), g[0].sig_words(),
+ R2.data(), R2.size(), R2.sig_words(),
+ modulus.data(), mod_words, mod_prime,
+ &workspace[0]);
g[0].assign(&z[0], mod_words + 1);
@@ -52,13 +51,11 @@ void Montgomery_Exponentiator::set_base(const BigInt& base)
const size_t y_sig = y.sig_words();
zeroise(z);
- bigint_mul(&z[0], z.size(), &workspace[0],
- x.data(), x.size(), x_sig,
- y.data(), y.size(), y_sig);
-
- bigint_monty_redc(&z[0], z.size(),
- &workspace[0],
- modulus.data(), mod_words, mod_prime);
+ bigint_monty_mul(&z[0], z.size(),
+ x.data(), x.size(), x_sig,
+ y.data(), y.size(), y_sig,
+ modulus.data(), mod_words, mod_prime,
+ &workspace[0]);
g[i].assign(&z[0], mod_words + 1);
}
@@ -80,12 +77,11 @@ BigInt Montgomery_Exponentiator::execute() const
for(size_t k = 0; k != window_bits; ++k)
{
zeroise(z);
- bigint_sqr(&z[0], z.size(), &workspace[0],
- x.data(), x.size(), x.sig_words());
- bigint_monty_redc(&z[0], z.size(),
- &workspace[0],
- modulus.data(), mod_words, mod_prime);
+ bigint_monty_sqr(&z[0], z.size(),
+ x.data(), x.size(), x.sig_words(),
+ modulus.data(), mod_words, mod_prime,
+ &workspace[0]);
x.assign(&z[0], mod_words + 1);
}
@@ -95,13 +91,11 @@ BigInt Montgomery_Exponentiator::execute() const
const BigInt& y = g[nibble-1];
zeroise(z);
- bigint_mul(&z[0], z.size(), &workspace[0],
- x.data(), x.size(), x.sig_words(),
- y.data(), y.size(), y.sig_words());
-
- bigint_monty_redc(&z[0], z.size(),
- &workspace[0],
- modulus.data(), mod_words, mod_prime);
+ bigint_monty_mul(&z[0], z.size(),
+ x.data(), x.size(), x.sig_words(),
+ y.data(), y.size(), y.sig_words(),
+ modulus.data(), mod_words, mod_prime,
+ &workspace[0]);
x.assign(&z[0], mod_words + 1);
}
@@ -110,8 +104,8 @@ BigInt Montgomery_Exponentiator::execute() const
x.get_reg().resize(2*mod_words+1);
bigint_monty_redc(&x[0], x.size(),
- &workspace[0],
- modulus.data(), mod_words, mod_prime);
+ modulus.data(), mod_words, mod_prime,
+ &workspace[0]);
x.get_reg().resize(mod_words+1);
@@ -134,14 +128,12 @@ Montgomery_Exponentiator::Montgomery_Exponentiator(const BigInt& mod,
mod_words = modulus.sig_words();
- BigInt mod_prime_bn(BigInt::Power2, MP_WORD_BITS);
- mod_prime = (mod_prime_bn - inverse_mod(modulus, mod_prime_bn)).word_at(0);
+ BigInt r(BigInt::Power2, mod_words * BOTAN_MP_WORD_BITS);
+ mod_prime = (((r * inverse_mod(r, mod)) - 1) / mod).word_at(0);
- R_mod = BigInt(BigInt::Power2, MP_WORD_BITS * mod_words);
- R_mod %= modulus;
+ R_mod = r % modulus;
- R2 = BigInt(BigInt::Power2, 2 * MP_WORD_BITS * mod_words);
- R2 %= modulus;
+ R2 = (R_mod * R_mod) % modulus;
}
}
diff --git a/src/math/numbertheory/reducer.cpp b/src/math/numbertheory/reducer.cpp
index 257ece56e..466996e99 100644
--- a/src/math/numbertheory/reducer.cpp
+++ b/src/math/numbertheory/reducer.cpp
@@ -1,6 +1,6 @@
/*
* Modular Reducer
-* (C) 1999-2010 Jack Lloyd
+* (C) 1999-2011 Jack Lloyd
*
* Distributed under the terms of the Botan license
*/
@@ -22,10 +22,8 @@ Modular_Reducer::Modular_Reducer(const BigInt& mod)
mod_words = modulus.sig_words();
modulus_2 = Botan::square(modulus);
- mod2_words = modulus_2.sig_words();
mu = BigInt(BigInt::Power2, 2 * MP_WORD_BITS * mod_words) / modulus;
- mu_words = mu.sig_words();
}
/*
@@ -36,45 +34,49 @@ BigInt Modular_Reducer::reduce(const BigInt& x) const
if(mod_words == 0)
throw Invalid_State("Modular_Reducer: Never initalized");
- BigInt t1 = x;
- t1.set_sign(BigInt::Positive);
-
- if(t1 < modulus)
+ if(x.cmp(modulus, false) < 0)
{
- if(x.is_negative() && t1.is_nonzero())
- return modulus - t1;
+ if(x.is_negative())
+ return x + modulus; // make positive
return x;
}
+ else if(x.cmp(modulus_2, false) < 0)
+ {
+ BigInt t1 = x;
+ t1.set_sign(BigInt::Positive);
+ t1 >>= (MP_WORD_BITS * (mod_words - 1));
+ t1 *= mu;
- if(t1 >= modulus_2)
- return (x % modulus);
+ t1 >>= (MP_WORD_BITS * (mod_words + 1));
+ t1 *= modulus;
- t1 >>= (MP_WORD_BITS * (mod_words - 1));
- t1 *= mu;
- t1 >>= (MP_WORD_BITS * (mod_words + 1));
+ t1.mask_bits(MP_WORD_BITS * (mod_words + 1));
- t1 *= modulus;
- t1.mask_bits(MP_WORD_BITS * (mod_words+1));
+ BigInt t2 = x;
+ t2.set_sign(BigInt::Positive);
+ t2.mask_bits(MP_WORD_BITS * (mod_words + 1));
- BigInt t2 = x;
- t2.set_sign(BigInt::Positive);
- t2.mask_bits(MP_WORD_BITS * (mod_words+1));
+ t2 -= t1;
- t1 = t2 - t1;
+ if(t2.is_negative())
+ {
+ BigInt b_to_k1(BigInt::Power2, MP_WORD_BITS * (mod_words + 1));
+ t2 += b_to_k1;
+ }
- if(t1.is_negative())
+ while(t2 >= modulus)
+ t2 -= modulus;
+
+ if(x.is_positive())
+ return t2;
+ else
+ return (modulus - t2);
+ }
+ else
{
- BigInt b_to_k1(BigInt::Power2, MP_WORD_BITS * (mod_words+1));
- t1 += b_to_k1;
+ // too big, fall back to normal division
+ return (x % modulus);
}
-
- while(t1 >= modulus)
- t1 -= modulus;
-
- if(x.is_negative() && t1.is_nonzero())
- t1 = modulus - t1;
-
- return t1;
}
}
diff --git a/src/math/numbertheory/reducer.h b/src/math/numbertheory/reducer.h
index 05c12a440..76712074c 100644
--- a/src/math/numbertheory/reducer.h
+++ b/src/math/numbertheory/reducer.h
@@ -13,7 +13,7 @@
namespace Botan {
/**
-* Modular Reducer
+* Modular Reducer (using Barrett's technique)
*/
class BOTAN_DLL Modular_Reducer
{
@@ -53,7 +53,7 @@ class BOTAN_DLL Modular_Reducer
Modular_Reducer(const BigInt& mod);
private:
BigInt modulus, modulus_2, mu;
- size_t mod_words, mod2_words, mu_words;
+ size_t mod_words;
};
}
diff --git a/src/passhash/bcrypt/bcrypt.cpp b/src/passhash/bcrypt/bcrypt.cpp
index e533c6081..bb2e9095a 100644
--- a/src/passhash/bcrypt/bcrypt.cpp
+++ b/src/passhash/bcrypt/bcrypt.cpp
@@ -11,11 +11,6 @@
#include <botan/blowfish.h>
#include <botan/base64.h>
-#include <botan/pipe.h>
-#include <botan/b64_filt.h>
-#include <iostream>
-#include <stdio.h>
-
namespace Botan {
namespace {
@@ -89,10 +84,7 @@ MemoryVector<byte> bcrypt_base64_decode(std::string input)
for(size_t i = 0; i != input.size(); ++i)
input[i] = OPENBSD_BASE64_SUB[static_cast<byte>(input[i])];
- //return base64_decode(input);
- Pipe pipe(new Base64_Decoder);
- pipe.process_msg(input);
- return pipe.read_all();
+ return base64_decode(input);
}
std::string make_bcrypt(const std::string& pass,
diff --git a/src/pk_pad/eme1/eme1.cpp b/src/pk_pad/eme1/eme1.cpp
index b49fb9af0..1cc0c332d 100644
--- a/src/pk_pad/eme1/eme1.cpp
+++ b/src/pk_pad/eme1/eme1.cpp
@@ -65,38 +65,47 @@ SecureVector<byte> EME1::unpad(const byte in[], size_t in_length,
if(in_length > key_length)
in_length = 0;
- SecureVector<byte> tmp(key_length);
- tmp.copy(key_length - in_length, in, in_length);
+ SecureVector<byte> input(key_length);
+ input.copy(key_length - in_length, in, in_length);
- mgf->mask(&tmp[Phash.size()], tmp.size() - Phash.size(),
- &tmp[0], Phash.size());
- mgf->mask(&tmp[0], Phash.size(),
- &tmp[Phash.size()], tmp.size() - Phash.size());
+ mgf->mask(&input[Phash.size()], input.size() - Phash.size(),
+ &input[0], Phash.size());
+ mgf->mask(&input[0], Phash.size(),
+ &input[Phash.size()], input.size() - Phash.size());
- const bool phash_ok = same_mem(&tmp[Phash.size()], &Phash[0], Phash.size());
+ bool waiting_for_delim = true;
+ bool bad_input = false;
+ size_t delim_idx = 2 * Phash.size();
- bool delim_ok = true;
- size_t delim_idx = 0;
-
- // Is this vulnerable to timing attacks?
- for(size_t i = Phash.size() + Phash.size(); i != tmp.size(); ++i)
+ /*
+ * GCC 4.5 on x86-64 compiles this in a way that is still vunerable
+ * to timing analysis. Other compilers, or GCC on other platforms,
+ * may or may not.
+ */
+ for(size_t i = delim_idx; i != input.size(); ++i)
{
- if(tmp[i] && !delim_idx)
- {
- if(tmp[i] == 0x01)
- delim_idx = i;
- else
- delim_ok = false;
- }
- }
+ const bool zero_p = !input[i];
+ const bool one_p = input[i] == 0x01;
- if(delim_idx && delim_ok && phash_ok)
- {
- return SecureVector<byte>(&tmp[delim_idx + 1],
- tmp.size() - delim_idx - 1);
+ const bool add_1 = waiting_for_delim && zero_p;
+
+ bad_input |= waiting_for_delim && !(zero_p || one_p);
+
+ delim_idx += add_1;
+
+ waiting_for_delim &= zero_p;
}
- throw Decoding_Error("Invalid EME1 encoding");
+ // If we never saw any non-zero byte, then it's not valid input
+ bad_input |= waiting_for_delim;
+
+ bad_input |= !same_mem(&input[Phash.size()], &Phash[0], Phash.size());
+
+ if(bad_input)
+ throw Decoding_Error("Invalid EME1 encoding");
+
+ return SecureVector<byte>(input + delim_idx + 1,
+ input.size() - delim_idx - 1);
}
/*
diff --git a/src/pubkey/ec_group/ec_group.h b/src/pubkey/ec_group/ec_group.h
index b7b09985e..9430a8e38 100644
--- a/src/pubkey/ec_group/ec_group.h
+++ b/src/pubkey/ec_group/ec_group.h
@@ -40,9 +40,9 @@ class BOTAN_DLL EC_Group
* @param cofactor the cofactor
*/
EC_Group(const CurveGFp& curve,
- const PointGFp& base_point,
- const BigInt& order,
- const BigInt& cofactor) :
+ const PointGFp& base_point,
+ const BigInt& order,
+ const BigInt& cofactor) :
curve(curve),
base_point(base_point),
order(order),
diff --git a/src/pubkey/ec_group/info.txt b/src/pubkey/ec_group/info.txt
index c611914e9..9a686feeb 100644
--- a/src/pubkey/ec_group/info.txt
+++ b/src/pubkey/ec_group/info.txt
@@ -2,8 +2,9 @@ define ECC_GROUP
<requires>
asn1
-numbertheory
-pem
+ec_gfp
libstate
+numbertheory
oid_lookup
+pem
</requires>
diff --git a/src/pubkey/ecc_key/info.txt b/src/pubkey/ecc_key/info.txt
index be281d697..ceb98a79e 100644
--- a/src/pubkey/ecc_key/info.txt
+++ b/src/pubkey/ecc_key/info.txt
@@ -4,6 +4,7 @@ define ECC_PUBLIC_KEY_CRYPTO
alloc
asn1
bigint
+ec_gfp
ec_group
numbertheory
</requires>
diff --git a/src/pubkey/ecdh/ecdh.h b/src/pubkey/ecdh/ecdh.h
index 2edbfe86d..6fe0697bf 100644
--- a/src/pubkey/ecdh/ecdh.h
+++ b/src/pubkey/ecdh/ecdh.h
@@ -22,7 +22,6 @@ class BOTAN_DLL ECDH_PublicKey : public virtual EC_PublicKey
{
public:
-
ECDH_PublicKey(const AlgorithmIdentifier& alg_id,
const MemoryRegion<byte>& key_bits) :
EC_PublicKey(alg_id, key_bits) {}
diff --git a/src/pubkey/ecdsa/ecdsa.cpp b/src/pubkey/ecdsa/ecdsa.cpp
index 9a3510c33..5c45c5ed3 100644
--- a/src/pubkey/ecdsa/ecdsa.cpp
+++ b/src/pubkey/ecdsa/ecdsa.cpp
@@ -80,12 +80,13 @@ bool ECDSA_Verification_Operation::verify(const byte msg[], size_t msg_len,
BigInt r(sig, sig_len / 2);
BigInt s(sig + sig_len / 2, sig_len / 2);
- if(r < 0 || r >= order || s < 0 || s >= order)
+ if(r <= 0 || r >= order || s <= 0 || s >= order)
return false;
BigInt w = inverse_mod(s, order);
- PointGFp R = w * (e * base_point + r * public_point);
+ PointGFp R = w * multi_exponentiate(base_point, e,
+ public_point, r);
if(R.is_zero())
return false;
diff --git a/src/pubkey/gost_3410/gost_3410.cpp b/src/pubkey/gost_3410/gost_3410.cpp
index 507ebb5a0..f97f83aa0 100644
--- a/src/pubkey/gost_3410/gost_3410.cpp
+++ b/src/pubkey/gost_3410/gost_3410.cpp
@@ -17,8 +17,8 @@ namespace Botan {
MemoryVector<byte> GOST_3410_PublicKey::x509_subject_public_key() const
{
// Trust CryptoPro to come up with something obnoxious
- const BigInt& x = public_point().get_affine_x();
- const BigInt& y = public_point().get_affine_y();
+ const BigInt x = public_point().get_affine_x();
+ const BigInt y = public_point().get_affine_y();
size_t part_size = std::max(x.bytes(), y.bytes());
@@ -153,7 +153,7 @@ bool GOST_3410_Verification_Operation::verify(const byte msg[], size_t msg_len,
BigInt s(sig, sig_len / 2);
BigInt r(sig + sig_len / 2, sig_len / 2);
- if(r < 0 || r >= order || s < 0 || s >= order)
+ if(r <= 0 || r >= order || s <= 0 || s >= order)
return false;
e %= order;
@@ -165,7 +165,11 @@ bool GOST_3410_Verification_Operation::verify(const byte msg[], size_t msg_len,
BigInt z1 = (s*v) % order;
BigInt z2 = (-r*v) % order;
- PointGFp R = (z1 * base_point + z2 * public_point);
+ PointGFp R = multi_exponentiate(base_point, z1,
+ public_point, z2);
+
+ if(R.is_zero())
+ return false;
return (R.get_affine_x() == r);
}
diff --git a/src/selftest/selftest.cpp b/src/selftest/selftest.cpp
index 4d2837dac..0dac31cef 100644
--- a/src/selftest/selftest.cpp
+++ b/src/selftest/selftest.cpp
@@ -24,7 +24,7 @@ bool test_filter_kat(Filter* filter,
Pipe pipe(new Hex_Decoder, filter, new Hex_Encoder);
pipe.process_msg(input);
- std::string output = pipe.read_all_as_string();
+ const std::string output = pipe.read_all_as_string();
return (output == expected_output);
}
diff --git a/src/utils/simd_32/info.txt b/src/simd/info.txt
index 362e90235..d0601b141 100644
--- a/src/utils/simd_32/info.txt
+++ b/src/simd/info.txt
@@ -2,7 +2,8 @@ define SIMD_32
<header:internal>
simd_32.h
-simd_sse.h
-simd_scalar.h
-simd_altivec.h
</header:internal>
+
+<requires>
+simd_sse2|simd_altivec|simd_scalar
+</requires>
diff --git a/src/utils/simd_32/simd_32.h b/src/simd/simd_32.h
index e172fa919..4ef0cea85 100644
--- a/src/utils/simd_32/simd_32.h
+++ b/src/simd/simd_32.h
@@ -1,6 +1,6 @@
/*
* Lightweight wrappers for SIMD operations
-* (C) 2009 Jack Lloyd
+* (C) 2009,2011 Jack Lloyd
*
* Distributed under the terms of the Botan license
*/
@@ -9,23 +9,22 @@
#define BOTAN_SIMD_32_H__
#include <botan/types.h>
-#include <botan/rotate.h>
-#if defined(BOTAN_TARGET_CPU_HAS_SSE2) && !defined(BOTAN_NO_SSE_INTRINSICS)
-
- #include <botan/internal/simd_sse.h>
+#if defined(BOTAN_HAS_SIMD_SSE2)
+ #include <botan/internal/simd_sse2.h>
namespace Botan { typedef SIMD_SSE2 SIMD_32; }
-#elif defined(BOTAN_TARGET_CPU_HAS_ALTIVEC)
-
+#elif defined(BOTAN_HAS_SIMD_ALTIVEC)
#include <botan/internal/simd_altivec.h>
namespace Botan { typedef SIMD_Altivec SIMD_32; }
-#else
-
+#elif defined(BOTAN_HAS_SIMD_SCALAR)
#include <botan/internal/simd_scalar.h>
namespace Botan { typedef SIMD_Scalar SIMD_32; }
+#else
+ #error "No SIMD module defined"
+
#endif
#endif
diff --git a/src/simd/simd_altivec/info.txt b/src/simd/simd_altivec/info.txt
new file mode 100644
index 000000000..aa2f01c2d
--- /dev/null
+++ b/src/simd/simd_altivec/info.txt
@@ -0,0 +1,9 @@
+define SIMD_ALTIVEC
+
+need_isa altivec
+
+load_on dep
+
+<header:internal>
+simd_altivec.h
+</header:internal>
diff --git a/src/utils/simd_32/simd_altivec.h b/src/simd/simd_altivec/simd_altivec.h
index 4c412ddec..4c412ddec 100644
--- a/src/utils/simd_32/simd_altivec.h
+++ b/src/simd/simd_altivec/simd_altivec.h
diff --git a/src/simd/simd_scalar/info.txt b/src/simd/simd_scalar/info.txt
new file mode 100644
index 000000000..6817eab80
--- /dev/null
+++ b/src/simd/simd_scalar/info.txt
@@ -0,0 +1,7 @@
+define SIMD_SCALAR
+
+load_on dep
+
+<header:internal>
+simd_scalar.h
+</header:internal>
diff --git a/src/utils/simd_32/simd_scalar.h b/src/simd/simd_scalar/simd_scalar.h
index 2c68622af..2c68622af 100644
--- a/src/utils/simd_32/simd_scalar.h
+++ b/src/simd/simd_scalar/simd_scalar.h
diff --git a/src/simd/simd_sse2/info.txt b/src/simd/simd_sse2/info.txt
new file mode 100644
index 000000000..e56792491
--- /dev/null
+++ b/src/simd/simd_sse2/info.txt
@@ -0,0 +1,9 @@
+define SIMD_SSE2
+
+need_isa sse2
+
+load_on dep
+
+<header:internal>
+simd_sse2.h
+</header:internal>
diff --git a/src/utils/simd_32/simd_sse.h b/src/simd/simd_sse2/simd_sse2.h
index 61fce99a9..61fce99a9 100644
--- a/src/utils/simd_32/simd_sse.h
+++ b/src/simd/simd_sse2/simd_sse2.h
diff --git a/src/ssl/hello.cpp b/src/ssl/hello.cpp
index 2c5a9d2ea..ae0d9607b 100644
--- a/src/ssl/hello.cpp
+++ b/src/ssl/hello.cpp
@@ -190,6 +190,14 @@ void Client_Hello::deserialize(const MemoryRegion<byte>& buf)
}
}
}
+ else if(extension_code == TLSEXT_SRP_IDENTIFIER)
+ {
+ std::vector<byte> name = reader.get_range_vector<byte>(1, 1, 255);
+
+ requested_srp_id.assign(
+ reinterpret_cast<char*>(&name[0]),
+ name.size());
+ }
else
{
reader.discard_next(extension_size);
diff --git a/src/ssl/info.txt b/src/ssl/info.txt
index 586a6cec7..169b76115 100644
--- a/src/ssl/info.txt
+++ b/src/ssl/info.txt
@@ -1,8 +1,12 @@
define SSL_TLS
+load_on request
+
<comment>
-The SSL/TLS code is complex, new, and not yet reviewed, there may be
-serious bugs or security issues.
+A new TLS API is being developed. This version has numerous
+performance and usability issues and will not be supported in the
+future. Only use it if you need it for compatability with code written
+against previous versions.
</comment>
uses_tr1 yes
@@ -57,11 +61,11 @@ emsa3
filters
hmac
md5
+prf_ssl3
+prf_tls
rng
rsa
sha1
ssl3mac
-ssl_prf
-tls_prf
x509cert
</requires>
diff --git a/src/ssl/rec_read.cpp b/src/ssl/rec_read.cpp
index 042aae0c9..7e295f8a4 100644
--- a/src/ssl/rec_read.cpp
+++ b/src/ssl/rec_read.cpp
@@ -213,9 +213,14 @@ size_t Record_Reader::get_record(byte& msg_type,
}
else
{
+ bool padding_good = true;
+
for(size_t i = 0; i != pad_size; ++i)
if(plaintext[plaintext.size()-i-1] != pad_value)
- pad_size = 0;
+ padding_good = false;
+
+ if(!padding_good)
+ pad_size = 0;
}
}
@@ -223,7 +228,7 @@ size_t Record_Reader::get_record(byte& msg_type,
throw Decoding_Error("Record_Reader: Record truncated");
const size_t mac_offset = plaintext.size() - (mac_size + pad_size);
- SecureVector<byte> recieved_mac(&plaintext[mac_offset],
+ SecureVector<byte> received_mac(&plaintext[mac_offset],
mac_size);
const u16bit plain_length = plaintext.size() - (mac_size + pad_size + iv_size);
@@ -242,7 +247,7 @@ size_t Record_Reader::get_record(byte& msg_type,
SecureVector<byte> computed_mac = mac->final();
- if(recieved_mac != computed_mac)
+ if(received_mac != computed_mac)
throw TLS_Exception(BAD_RECORD_MAC, "Record_Reader: MAC failure");
msg_type = header[0];
diff --git a/src/ssl/tls_alerts.h b/src/ssl/tls_alerts.h
index f189cf507..241599aa8 100644
--- a/src/ssl/tls_alerts.h
+++ b/src/ssl/tls_alerts.h
@@ -15,7 +15,7 @@ namespace Botan {
/**
* SSL/TLS Alert Message
*/
-class BOTAN_DLL Alert
+class Alert
{
public:
/**
diff --git a/src/ssl/tls_client.cpp b/src/ssl/tls_client.cpp
index 5447e9904..a136752fd 100644
--- a/src/ssl/tls_client.cpp
+++ b/src/ssl/tls_client.cpp
@@ -294,7 +294,7 @@ void TLS_Client::state_machine()
}
}
else
- throw Unexpected_Message("Unknown message type recieved");
+ throw Unexpected_Message("Unknown message type received");
}
/**
@@ -440,7 +440,7 @@ void TLS_Client::process_handshake_msg(Handshake_Type type,
is_rsa = true;
else
throw TLS_Exception(UNSUPPORTED_CERTIFICATE,
- "Unknown key type recieved in server kex");
+ "Unknown key type received in server kex");
if((is_dsa && state->suite.sig_type() != TLS_ALGO_SIGNER_DSA) ||
(is_rsa && state->suite.sig_type() != TLS_ALGO_SIGNER_RSA))
@@ -469,7 +469,7 @@ void TLS_Client::process_handshake_msg(Handshake_Type type,
is_rsa = true;
else
throw TLS_Exception(HANDSHAKE_FAILURE,
- "Unknown key type recieved in server kex");
+ "Unknown key type received in server kex");
if((is_dh && state->suite.kex_type() != TLS_ALGO_KEYEXCH_DH) ||
(is_rsa && state->suite.kex_type() != TLS_ALGO_KEYEXCH_RSA))
@@ -560,7 +560,7 @@ void TLS_Client::process_handshake_msg(Handshake_Type type,
active = true;
}
else
- throw Unexpected_Message("Unknown handshake message recieved");
+ throw Unexpected_Message("Unknown handshake message received");
}
/**
diff --git a/src/ssl/tls_exceptn.h b/src/ssl/tls_exceptn.h
index a9efc718a..37b9c0d27 100644
--- a/src/ssl/tls_exceptn.h
+++ b/src/ssl/tls_exceptn.h
@@ -32,7 +32,7 @@ class BOTAN_DLL TLS_Exception : public Exception
/**
* Unexpected_Message Exception
*/
-struct Unexpected_Message : public TLS_Exception
+struct BOTAN_DLL Unexpected_Message : public TLS_Exception
{
Unexpected_Message(const std::string& err) :
TLS_Exception(UNEXPECTED_MESSAGE, err) {}
diff --git a/src/ssl/tls_handshake_hash.h b/src/ssl/tls_handshake_hash.h
index ceaa55584..cea612a71 100644
--- a/src/ssl/tls_handshake_hash.h
+++ b/src/ssl/tls_handshake_hash.h
@@ -17,7 +17,7 @@ using namespace Botan;
/**
* TLS Handshake Hash
*/
-class BOTAN_DLL HandshakeHash
+class HandshakeHash
{
public:
void update(const byte in[], size_t length)
diff --git a/src/ssl/tls_magic.h b/src/ssl/tls_magic.h
index 0c2a610b1..00898738e 100644
--- a/src/ssl/tls_magic.h
+++ b/src/ssl/tls_magic.h
@@ -181,6 +181,8 @@ enum TLS_Handshake_Extension_Type {
TLSEXT_USABLE_ELLIPTIC_CURVES = 10,
TLSEXT_EC_POINT_FORMATS = 11,
+ TLSEXT_SRP_IDENTIFIER = 12,
+
TLSEXT_CERTIFICATE_TYPES = 9,
TLSEXT_SESSION_TICKET = 35
};
diff --git a/src/ssl/tls_messages.h b/src/ssl/tls_messages.h
index c5d4d8cb8..e7eaa56e1 100644
--- a/src/ssl/tls_messages.h
+++ b/src/ssl/tls_messages.h
@@ -21,7 +21,7 @@ namespace Botan {
/**
* TLS Handshake Message Base Class
*/
-class BOTAN_DLL HandshakeMessage
+class HandshakeMessage
{
public:
void send(Record_Writer&, HandshakeHash&) const;
@@ -38,7 +38,7 @@ class BOTAN_DLL HandshakeMessage
/**
* Client Hello Message
*/
-class BOTAN_DLL Client_Hello : public HandshakeMessage
+class Client_Hello : public HandshakeMessage
{
public:
Handshake_Type type() const { return CLIENT_HELLO; }
@@ -51,6 +51,8 @@ class BOTAN_DLL Client_Hello : public HandshakeMessage
std::string hostname() const { return requested_hostname; }
+ std::string srp_identifier() const { return requested_srp_id; }
+
bool offered_suite(u16bit) const;
Client_Hello(RandomNumberGenerator& rng,
@@ -75,12 +77,13 @@ class BOTAN_DLL Client_Hello : public HandshakeMessage
std::vector<u16bit> suites;
std::vector<byte> comp_algos;
std::string requested_hostname;
+ std::string requested_srp_id;
};
/**
* Client Key Exchange Message
*/
-class BOTAN_DLL Client_Key_Exchange : public HandshakeMessage
+class Client_Key_Exchange : public HandshakeMessage
{
public:
Handshake_Type type() const { return CLIENT_KEX; }
@@ -112,7 +115,7 @@ class BOTAN_DLL Client_Key_Exchange : public HandshakeMessage
/**
* Certificate Message
*/
-class BOTAN_DLL Certificate : public HandshakeMessage
+class Certificate : public HandshakeMessage
{
public:
Handshake_Type type() const { return CERTIFICATE; }
@@ -130,7 +133,7 @@ class BOTAN_DLL Certificate : public HandshakeMessage
/**
* Certificate Request Message
*/
-class BOTAN_DLL Certificate_Req : public HandshakeMessage
+class Certificate_Req : public HandshakeMessage
{
public:
Handshake_Type type() const { return CERTIFICATE_REQUEST; }
@@ -157,7 +160,7 @@ class BOTAN_DLL Certificate_Req : public HandshakeMessage
/**
* Certificate Verify Message
*/
-class BOTAN_DLL Certificate_Verify : public HandshakeMessage
+class Certificate_Verify : public HandshakeMessage
{
public:
Handshake_Type type() const { return CERTIFICATE_VERIFY; }
@@ -179,7 +182,7 @@ class BOTAN_DLL Certificate_Verify : public HandshakeMessage
/**
* Finished Message
*/
-class BOTAN_DLL Finished : public HandshakeMessage
+class Finished : public HandshakeMessage
{
public:
Handshake_Type type() const { return FINISHED; }
@@ -205,7 +208,7 @@ class BOTAN_DLL Finished : public HandshakeMessage
/**
* Hello Request Message
*/
-class BOTAN_DLL Hello_Request : public HandshakeMessage
+class Hello_Request : public HandshakeMessage
{
public:
Handshake_Type type() const { return HELLO_REQUEST; }
@@ -220,7 +223,7 @@ class BOTAN_DLL Hello_Request : public HandshakeMessage
/**
* Server Hello Message
*/
-class BOTAN_DLL Server_Hello : public HandshakeMessage
+class Server_Hello : public HandshakeMessage
{
public:
Handshake_Type type() const { return SERVER_HELLO; }
@@ -250,7 +253,7 @@ class BOTAN_DLL Server_Hello : public HandshakeMessage
/**
* Server Key Exchange Message
*/
-class BOTAN_DLL Server_Key_Exchange : public HandshakeMessage
+class Server_Key_Exchange : public HandshakeMessage
{
public:
Handshake_Type type() const { return SERVER_KEX; }
@@ -277,7 +280,7 @@ class BOTAN_DLL Server_Key_Exchange : public HandshakeMessage
/**
* Server Hello Done Message
*/
-class BOTAN_DLL Server_Hello_Done : public HandshakeMessage
+class Server_Hello_Done : public HandshakeMessage
{
public:
Handshake_Type type() const { return SERVER_HELLO_DONE; }
diff --git a/src/ssl/tls_record.h b/src/ssl/tls_record.h
index 7a223095f..09fd921c6 100644
--- a/src/ssl/tls_record.h
+++ b/src/ssl/tls_record.h
@@ -16,7 +16,13 @@
#include <vector>
#if defined(BOTAN_USE_STD_TR1)
- #include <tr1/functional>
+
+#if defined(BOTAN_BUILD_COMPILER_IS_MSVC)
+ #include <functional>
+#else
+ #include <tr1/functional>
+#endif
+
#elif defined(BOTAN_USE_BOOST_TR1)
#include <boost/tr1/functional.hpp>
#else
diff --git a/src/ssl/tls_server.cpp b/src/ssl/tls_server.cpp
index 4e071da59..8964be3d7 100644
--- a/src/ssl/tls_server.cpp
+++ b/src/ssl/tls_server.cpp
@@ -262,7 +262,7 @@ void TLS_Server::state_machine()
}
}
else
- throw Unexpected_Message("Unknown message type recieved");
+ throw Unexpected_Message("Unknown message type received");
}
/*
@@ -471,7 +471,7 @@ void TLS_Server::process_handshake_msg(Handshake_Type type,
active = true;
}
else
- throw Unexpected_Message("Unknown handshake message recieved");
+ throw Unexpected_Message("Unknown handshake message received");
}
/*
diff --git a/src/utils/asm_x86_32/info.txt b/src/utils/asm_x86_32/info.txt
index 8534d9aef..21244968f 100644
--- a/src/utils/asm_x86_32/info.txt
+++ b/src/utils/asm_x86_32/info.txt
@@ -19,7 +19,6 @@ solaris
</os>
<cc>
-clang
gcc
icc
</cc>
diff --git a/src/utils/cpuid.cpp b/src/utils/cpuid.cpp
index cb6fdaba5..f6581f09c 100644
--- a/src/utils/cpuid.cpp
+++ b/src/utils/cpuid.cpp
@@ -10,10 +10,20 @@
#include <botan/get_byte.h>
#include <botan/mem_ops.h>
+#if defined(BOTAN_TARGET_CPU_IS_PPC_FAMILY)
+
#if defined(BOTAN_TARGET_OS_IS_DARWIN)
#include <sys/sysctl.h>
#endif
+#if defined(BOTAN_TARGET_OS_IS_OPENBSD)
+ #include <sys/param.h>
+ #include <sys/sysctl.h>
+ #include <machine/cpu.h>
+#endif
+
+#endif
+
#if defined(BOTAN_TARGET_CPU_IS_X86_FAMILY)
#if defined(BOTAN_BUILD_COMPILER_IS_MSVC)
@@ -24,9 +34,9 @@
#elif defined(BOTAN_BUILD_COMPILER_IS_INTEL)
#include <ia32intrin.h>
- #define CALL_CPUID(type, out) do { __cpuid(out, type); } while(0);
+ #define CALL_CPUID(type, out) do { __cpuid(out, type); } while(0)
-#elif (BOTAN_GCC_VERSION >= 430)
+#elif defined(BOTAN_BUILD_COMPILER_IS_GCC) && (BOTAN_GCC_VERSION >= 430)
// Only available starting in GCC 4.3
#include <cpuid.h>
@@ -46,6 +56,20 @@ namespace {
}
+#elif defined(BOTAN_TARGET_ARCH_IS_X86_64) && \
+ (defined(BOTAN_BUILD_COMPILER_IS_CLANG) || defined(BOTAN_BUILD_COMPILER_IS_GCC))
+
+ /*
+ * We can't safely use this on x86-32 as some 32-bit ABIs use ebx as
+ * a PIC register, and in theory there are some x86-32s still out
+ * there that don't support cpuid at all; it requires strange
+ * contortions to detect them.
+ */
+
+ #define CALL_CPUID(type, out) \
+ asm("cpuid\n\t" : "=a" (out[0]), "=b" (out[1]), "=c" (out[2]), "=d" (out[3]) \
+ : "0" (type))
+
#else
#warning "No method of calling CPUID for this compiler"
#endif
@@ -92,10 +116,14 @@ u32bit get_x86_cache_line_size()
bool altivec_check_sysctl()
{
-#if defined(BOTAN_TARGET_OS_IS_DARWIN)
+#if defined(BOTAN_TARGET_OS_IS_DARWIN) || defined(BOTAN_TARGET_OS_IS_OPENBSD)
+#if defined(BOTAN_TARGET_OS_IS_OPENBSD)
+ int sels[2] = { CTL_MACHDEP, CPU_ALTIVEC };
+#else
// From Apple's docs
int sels[2] = { CTL_HW, HW_VECTORUNIT };
+#endif
int vector_type = 0;
size_t length = sizeof(vector_type);
int error = sysctl(sels, 2, &vector_type, &length, NULL, 0);
@@ -128,6 +156,7 @@ bool altivec_check_pvr_emul()
const u16bit PVR_G5_970MP = 0x0044;
const u16bit PVR_G5_970GX = 0x0045;
const u16bit PVR_POWER6 = 0x003E;
+ const u16bit PVR_POWER7 = 0x003F;
const u16bit PVR_CELL_PPU = 0x0070;
// Motorola produced G4s with PVR 0x800[0123C] (at least)
@@ -147,6 +176,7 @@ bool altivec_check_pvr_emul()
altivec_capable |= (pvr == PVR_G5_970MP);
altivec_capable |= (pvr == PVR_G5_970GX);
altivec_capable |= (pvr == PVR_POWER6);
+ altivec_capable |= (pvr == PVR_POWER7);
altivec_capable |= (pvr == PVR_CELL_PPU);
#endif
diff --git a/src/utils/cpuid.h b/src/utils/cpuid.h
index 863ba5b63..ad85ac4fe 100644
--- a/src/utils/cpuid.h
+++ b/src/utils/cpuid.h
@@ -83,6 +83,12 @@ class BOTAN_DLL CPUID
{ return x86_processor_flags_has(CPUID_MOVBE_BIT); }
/**
+ * Check if the processor supports RDRAND
+ */
+ static bool has_rdrand()
+ { return x86_processor_flags_has(CPUID_RDRAND_BIT); }
+
+ /**
* Check if the processor supports AltiVec/VMX
*/
static bool has_altivec() { return altivec_capable; }
@@ -96,7 +102,8 @@ class BOTAN_DLL CPUID
CPUID_SSE42_BIT = 52,
CPUID_MOVBE_BIT = 54,
CPUID_AESNI_BIT = 57,
- CPUID_AVX_BIT = 60
+ CPUID_AVX_BIT = 60,
+ CPUID_RDRAND_BIT = 61
};
static bool x86_processor_flags_has(u64bit bit)
diff --git a/src/utils/dyn_load/dyn_load.cpp b/src/utils/dyn_load/dyn_load.cpp
index 4a8cb16fa..06b8c5df3 100644
--- a/src/utils/dyn_load/dyn_load.cpp
+++ b/src/utils/dyn_load/dyn_load.cpp
@@ -39,7 +39,7 @@ Dynamically_Loaded_Library::Dynamically_Loaded_Library(
raise_runtime_loader_exception(lib_name, dlerror());
#elif defined(BOTAN_TARGET_OS_HAS_LOADLIBRARY)
- lib = ::LoadLibrary(lib_name.c_str());
+ lib = ::LoadLibraryA(lib_name.c_str());
if(!lib)
raise_runtime_loader_exception(lib_name, "LoadLibrary failed");
@@ -65,7 +65,8 @@ void* Dynamically_Loaded_Library::resolve_symbol(const std::string& symbol)
#if defined(BOTAN_TARGET_OS_HAS_DLOPEN)
addr = ::dlsym(lib, symbol.c_str());
#elif defined(BOTAN_TARGET_OS_HAS_LOADLIBRARY)
- addr = ::GetProcAddress((HMODULE)lib, symbol.c_str());
+ addr = reinterpret_cast<void*>(::GetProcAddress((HMODULE)lib,
+ symbol.c_str()));
#endif
if(!addr)
diff --git a/src/utils/exceptn.h b/src/utils/exceptn.h
index 1177a4e7d..3797a5478 100644
--- a/src/utils/exceptn.h
+++ b/src/utils/exceptn.h
@@ -146,8 +146,8 @@ struct BOTAN_DLL Decoding_Error : public Invalid_Argument
*/
struct BOTAN_DLL Integrity_Failure : public Exception
{
- Integrity_Failure(const std::string& what) :
- Exception("Integrity failure: " + what) {}
+ Integrity_Failure(const std::string& msg) :
+ Exception("Integrity failure: " + msg) {}
};
/**
diff --git a/src/utils/version.cpp b/src/utils/version.cpp
index cf3205d19..acc8bee61 100644
--- a/src/utils/version.cpp
+++ b/src/utils/version.cpp
@@ -33,6 +33,7 @@ std::string version_string()
else
out << "released " << version_datestamp();
+ out << ", revision " << BOTAN_VERSION_VC_REVISION;
out << ", distribution " << BOTAN_DISTRIBUTION_INFO << ")";
return out.str();
diff --git a/src/wrap/python/filter.cpp b/src/wrap/python/filter.cpp
index 437c5239f..e329ed708 100644
--- a/src/wrap/python/filter.cpp
+++ b/src/wrap/python/filter.cpp
@@ -26,7 +26,6 @@ class Py_Filter : public Filter
void send_str(const std::string& str)
{
- printf("Py_Filter::send_str\n");
send((const byte*)str.data(), str.length());
}
};
@@ -36,14 +35,12 @@ class FilterWrapper : public Py_Filter, public wrapper<Py_Filter>
public:
void start_msg()
{
- printf("wrapper start_msg\n");
if(override start_msg = this->get_override("start_msg"))
start_msg();
}
void end_msg()
{
- printf("wrapper end_msg\n");
if(override end_msg = this->get_override("end_msg"))
end_msg();
}
@@ -53,7 +50,6 @@ class FilterWrapper : public Py_Filter, public wrapper<Py_Filter>
virtual void write_str(const std::string& str)
{
- printf("wrapper write\n");
this->get_override("write")(str);
}
};
@@ -125,7 +121,6 @@ void prepend_filter(Pipe& pipe, std::auto_ptr<Filter> filter)
void do_send(std::auto_ptr<FilterWrapper> filter, const std::string& data)
{
- printf("Sending %s to %p\n", data.c_str(), filter.get());
filter->send_str(data);
}
diff --git a/src/wrap/python/rsa.cpp b/src/wrap/python/rsa.cpp
index 5e2e0ba30..dc6053503 100644
--- a/src/wrap/python/rsa.cpp
+++ b/src/wrap/python/rsa.cpp
@@ -27,6 +27,8 @@ class Py_RSA_PrivateKey
Py_RSA_PrivateKey(std::string pem_str,
Python_RandomNumberGenerator& rng,
std::string pass);
+ Py_RSA_PrivateKey(std::string pem_str,
+ Python_RandomNumberGenerator& rng);
Py_RSA_PrivateKey(u32bit bits, Python_RandomNumberGenerator& rng);
~Py_RSA_PrivateKey() { delete rsa_key; }
@@ -87,6 +89,21 @@ Py_RSA_PrivateKey::Py_RSA_PrivateKey(u32bit bits,
}
Py_RSA_PrivateKey::Py_RSA_PrivateKey(std::string pem_str,
+ Python_RandomNumberGenerator& rng)
+ {
+ DataSource_Memory in(pem_str);
+
+ Private_Key* pkcs8_key =
+ PKCS8::load_key(in,
+ rng.get_underlying_rng());
+
+ rsa_key = dynamic_cast<RSA_PrivateKey*>(pkcs8_key);
+
+ if(!rsa_key)
+ throw std::invalid_argument("Key is not an RSA key");
+ }
+
+Py_RSA_PrivateKey::Py_RSA_PrivateKey(std::string pem_str,
Python_RandomNumberGenerator& rng,
std::string passphrase)
{
@@ -195,6 +212,7 @@ void export_rsa()
python::class_<Py_RSA_PrivateKey>
("RSA_PrivateKey", python::init<std::string, Python_RandomNumberGenerator&, std::string>())
+ .def(python::init<std::string, Python_RandomNumberGenerator&>())
.def(python::init<u32bit, Python_RandomNumberGenerator&>())
.def("to_string", &Py_RSA_PrivateKey::to_string)
.def("to_ber", &Py_RSA_PrivateKey::to_ber)