Compare commits

...

296 Commits

Author SHA1 Message Date
Jeffrey Walton 0c82df181c Update documentation 2019-08-31 07:46:19 -04:00
Jeffrey Walton 033f204a86 Fix .Net 2002 compile
This testing occurs on Windows XP. We are still rockin it
2019-08-27 14:44:27 -04:00
Jeffrey Walton b067d16e88 Update documentation 2019-08-27 10:28:13 -04:00
Jeffrey Walton 29453dcf08
Update comments 2019-08-27 07:52:33 -04:00
Jeffrey Walton 56165883fc
Update comments 2019-08-27 07:08:07 -04:00
Jeffrey Walton 54c8819c70
Fix ElGamal compile on Linux 2019-08-27 06:44:02 -04:00
Jeffrey Walton fcbfd68dfb
Add specialized Validate() to ElGamal
This was added for compatibility with BouncyCastle and other libraries. ElGamals paper and the HAC says to select x over the interval [1,p-1]. Crypto++ selects x over [1,q-1] as with other GFP schemes. Crypto++ fails to validate some of the keys of other libraries.
DL_PublicKey_GFP_OldFormat used to perform a reduction on x, but I think it treated a symptom and not the underlying cause. The underlying cause was, Crypto++ wass too strict in validating the parameter.
Note that wikipedia says to select the privaye key x over [1,q-1]. We are unable to find a reference for the practice, though it is OK.
2019-08-27 06:38:25 -04:00
Jeffrey Walton 90b0699edd
Add private key test data for ElGamal 2019-08-27 06:10:38 -04:00
Jeffrey Walton e06e3bd7a9
Fix ECP::Double and brainpoolP256r1 (GH #878) 2019-08-26 18:33:26 -04:00
Jeffrey Walton 66a6994e99
Add asserts to pubkey.h 2019-08-26 14:44:52 -04:00
Jeffrey Walton 8fa8ec9913
Update documentation 2019-08-25 12:20:21 -04:00
Jeffrey Walton db6d6b38b8
Update documentation 2019-08-25 12:00:28 -04:00
Jeffrey Walton 72f2b72920
Add test data from bug report (GH #876) 2019-08-24 18:00:03 -04:00
Jeffrey Walton f78c3c00d2
Regenerate ElGamal test data 2019-08-24 17:49:41 -04:00
Jeffrey Walton ff941db163
Update documentation 2019-08-24 16:59:39 -04:00
Jeffrey Walton a2c06c35b8
Use ASN1::elGamal() in ElGamal keys (GH #876) 2019-08-24 16:17:03 -04:00
Jeffrey Walton a7e83e6bf4
Update asserts in gfpcrypt.cpp 2019-08-24 15:48:14 -04:00
Jeffrey Walton 3d96234038
Fix typedef for MSVC (GH #876) 2019-08-24 06:44:14 -04:00
Jeffrey Walton 29e3818fd2
Add typedef for ElGamal::PrivateKey and ElGamal::PublicKey (GH #876) 2019-08-24 04:44:22 -04:00
Jeffrey Walton b80693d532
Add OID for ElGamal encryption (GH #876) 2019-08-24 03:18:29 -04:00
Jeffrey Walton 8130bd7a24
Update comments 2019-08-19 08:30:11 -04:00
Jeffrey Walton b9ff95f35a
Add define for CRYPTOPP_BOOL_ARM64 2019-08-18 04:27:25 -04:00
Jeffrey Walton 6545754337
Check size_t to DWORD and ULONG conversions
DWORD and ULONG are 32-bit. The conversion from size_t could fail, and the RNG would return a truncated result. I think it is low risk, but the test for the conversion test is cheap.
2019-08-17 21:19:04 -04:00
Jeffrey Walton d49c1a1605
Update documentation 2019-08-17 14:49:03 -04:00
Jeffrey Walton e22700f741
Fix use of MaxDerivedKeyLength (GH #874) 2019-08-16 07:12:14 -04:00
Jeffrey Walton c0a5a06a82
Fix use of MaxDerivedKeyLength (GH #874)
Also fix memcpy with NULL buffer
2019-08-16 06:45:30 -04:00
Jeffrey Walton 2ba9d3d00f
Restore former Test_RandomNumberGenerator behavior
There's no need to special case for HURD. No one uses it
2019-08-12 14:55:05 -04:00
Jeffrey Walton 7606c35fda
Update comments 2019-08-12 06:32:21 -04:00
Jeffrey Walton ea08de08d6
Add missing pumpAll to Test_RandomNumberGenerator 2019-08-12 06:27:10 -04:00
Jeffrey Walton 197f5fb1df
Add ASSERT to check m_fd for values <0
We are seeing RNG falures on HURD, but we are not throwing when constructing BlockingRng or NonblockingRng. This is despite the fact that /dev/urandom is missing during testing. NonblockingRng should always thwo when /dev/urandom is missing.
2019-08-12 05:40:22 -04:00
Jeffrey Walton 6028587b9f
Tighten Test_RandomNumberGenerator test
Debian HURD was slipping between the cracks. HURD appeared to be a minor failure because entropy on the heap improved the test result. After we zero'd the block, it was a catastrophic failure.
2019-08-12 05:34:11 -04:00
Jeffrey Walton 34e49627b7 Use C++ dynamic initialization if available 2019-08-12 00:11:41 -04:00
Jeffrey Walton 2d6895acb4 Update documentation 2019-08-11 22:37:15 -04:00
Jeffrey Walton 247418eec0 Use Bash arithmetic operators 2019-08-11 14:54:14 -04:00
Jeffrey Walton 11c5d14f85
Whitespace check-in 2019-08-10 03:24:52 -04:00
Jeffrey Walton 04b2a20c5d
Restore ECP ABI (GH #869)
Placing AdditionFunction as an inner class of ECP broke the ABI. We need to maintain the ABI so distros can patch Crypto++ 8.2.
2019-08-09 17:34:14 -04:00
Jeffrey Walton 7ac5791199
Fix cryptest.sh when swap is 0
If there is enough RAM then we don't need a swap file. I've got a Core i7-8800 with 64 GB or RAM that does not need a swap file.
2019-08-09 17:18:58 -04:00
Jeffrey Walton 242df465e8
Update comments 2019-08-07 23:30:48 -04:00
Jeffrey Walton c4700ae0b9
Avoid bitwise operation on boolean values 2019-08-07 23:27:33 -04:00
Jeffrey Walton 348e8e3b30
Clear unreachable code warnings under VC++ 2019-08-07 22:54:32 -04:00
Jeffrey Walton 1a5155fd96
Split public key benchmarks into integers and elliptic curves 2019-08-07 04:20:37 -04:00
Jeffrey Walton f3dd3d2559
Avoid temporary ECP::Point in ECP Addition and Double
This regains a lot of performance lost to the const-timeness (GH #869)
2019-08-07 02:43:13 -04:00
Jeffrey Walton b5fe6ab383
Clear parenthesis warning with GCC 2019-08-07 01:57:59 -04:00
Jeffrey Walton 7dc3b73e92
Add rdseed.asm to FileList.txt 2019-08-06 23:25:01 -04:00
Jeffrey Walton 7bba334641
Whitespace check-in 2019-08-06 21:42:43 -04:00
Jeffrey Walton b1c691b53a
Fix RDSEED hang on x86 (GH #872) (#873)
Calls to `MASM_RDSEED_GenerateBlock` would hang for an unknown reasons on Windows 10 and VS2017/VS2019 toolchains. Similar calls to `MASM_RDRAND_GenerateBlock` worked as expected. They were effectively the same code. The only differences were the function names and the opcodes (they were literally copy/paste).

Splitting `rdrand.asm` (with both `RDRAND` and `RDSEED`) into `rdrand.asm` (with `RDRAND`) and `rdseed.asm` (with `RDSEED`) resolved the issue. We don't know why.
2019-08-06 21:01:22 -04:00
Jeffrey Walton e5ab7919f9
Remove unneeded T in ECP Add()
Switch to 'R' variable in AdditionFunction to avoid shadow warnings
2019-08-06 03:28:53 -04:00
Jeffrey Walton 0ded32192e
Avoid branches in Montgomery Add() (GH #869) 2019-08-06 03:14:03 -04:00
Jeffrey Walton 5ae70e22b9
Avoid branches in Montgomery Double() (GH #869) 2019-08-06 01:23:37 -04:00
Jeffrey Walton df18c5b745 Add Debug and Release linker flags 2019-08-06 00:20:59 -04:00
Jeffrey Walton 41864fd49e Use local labels for RDRAND and RDSEED code (GH #872)
This did not fix the issue, but it is something on the TODO list.
2019-08-06 00:18:56 -04:00
Jeffrey Walton a01711e347 Fix CopyToRoot target with spaces in path 2019-08-05 13:27:54 -04:00
Jeffrey Walton c9ef9420e7
Fix ECP leakage in Add() and Double() (GH #869, PR #871)
This check-in provides the fix for leaks in ECP's Add() and Double(). The fixes were taken from Joost Renes, Craig Costello, and Lejla Batina's [Complete addition formulas for prime order elliptic curves](https://eprint.iacr.org/2015/1060.pdf).

The Pull Request includes two additional changes that were related to testing the primary fix. First, an `AuthenticatedKeyAgreementWithRolesValidate` interface was added. It allows us to test key agreement when roles are involved. Roles are "client", "server", "initiator", "recipient", etc.

Second, `SetGlobalSeed` was added to `test.cpp` to help with reproducible results. We had code in two different places that set the seed value for the random number generator. But it was sloppy and doing a poor job since results could not be reproduced under some circumstances.
2019-08-05 03:51:58 -04:00
Jeffrey Walton b3eb4c6a69
Fix AuthenticatedKeyAgreementWithRolesValidate messages 2019-08-03 23:59:25 -04:00
Jeffrey Walton 5aac8506bd
Use recipient rather than responder in authenticated key agreement
The recipient may not respond (though they do in the case of these key agreement schemes)
2019-08-03 23:52:50 -04:00
Jeffrey Walton 0b42a18cde
Update documentation 2019-08-03 23:25:15 -04:00
Jeffrey Walton 4e6dd922f7
Update documentation 2019-08-03 22:33:46 -04:00
Jeffrey Walton c3e0d123b2
Update documentation 2019-08-03 22:08:07 -04:00
Jeffrey Walton 37c0fb7ba8
Update documentation 2019-08-03 22:05:01 -04:00
Jeffrey Walton 057c2b434b
Update documentation 2019-08-03 21:58:26 -04:00
Jeffrey Walton 47a58050c6
Update documentation 2019-08-03 19:22:17 -04:00
Jeffrey Walton 2e6ccd7fb1
Fix authenticated key agreement domain parameter consistency test 2019-08-03 17:01:02 -04:00
Jeffrey Walton 7eeb954b23
Add AuthenticatedKeyAgreementValidateWithRoles free standing test function 2019-08-03 16:32:36 -04:00
Jeffrey Walton 3c5cb828b1
Spelling 2019-08-03 15:38:39 -04:00
Jeffrey Walton 84c4ae429f
Fix const-ness in HMQV and FHMQV 2019-08-03 03:24:26 -04:00
Jeffrey Walton 176cab0dc5
Update comments
Reference the bug report in DL_SignerBase::SignAndRestart for future readers
2019-07-29 10:36:29 -04:00
Ján Jančár f68f00f560 Fix ECDSA scalar multiplication leakage of bit-length. (GH #870)
This fixes the timing leakage of bit-length of nonces in ECDSA by essentially
fixing the bit-length, by using a nonce equivalent modulo the subgroup order.
2019-07-29 10:12:14 -04:00
Jeffrey Walton 739e5799e3 Whitespace check-in 2019-07-27 15:56:15 -04:00
Jeffrey Walton e4c402ace9
Clear truncation warning in rng.cpp (PR #867) 2019-07-25 04:52:24 -04:00
Andrew Marshall 12382a14be Use fixed size temporary in LC_RNG for consistency across platforms (#867) 2019-07-23 12:39:51 -04:00
Jeffrey Walton 614795f3e1
Add -DNDEBUG for openSUSE standrad build test 2019-07-22 16:10:43 -04:00
Jeffrey Walton 6eab4b7c32
Add openSUSE standard build test (GH #865) 2019-07-22 15:37:25 -04:00
Jeffrey Walton 9d2cab7548
Add CRYPTOPP_CXX14 define 2019-07-22 01:08:12 -04:00
Jeffrey Walton a7f2796dda
Update comments 2019-07-21 22:21:10 -04:00
Jeffrey Walton 7b7827e9cb
Clear Clang warning on SSE2 load 2019-07-21 22:20:55 -04:00
Jeffrey Walton 46e58df837
Add LINK_LIBRARY_PATH (GH #866) 2019-07-21 15:57:26 -04:00
Jeffrey Walton 3747e3d944
Don't use BASH_SOURCE in cryptest.sh 2019-07-21 03:19:14 -04:00
Jeffrey Walton ed7f4a0493
Use LINK_LIBRARY in cryptest-symbols.sh script (GH #866) 2019-07-21 03:16:01 -04:00
Jeffrey Walton dfaf2fc453
Remove references to GNUmakefile.shared (GH# 866) 2019-07-21 03:06:44 -04:00
Jeffrey Walton ef6e57990e
Use LINK_LIBRARY in cryptest.sh script (GH #866) 2019-07-21 03:02:43 -04:00
Jeffrey Walton 52ad132134
Add link-library variable to Makefiles (GH #866)
This should help distros and Crypto++ test scripts
2019-07-21 02:24:06 -04:00
Jeffrey Walton 5957b19fb8
Fix AVX2 feature test under Clang 3.3
Clang 3.3 appears to support some of AVX2, but it is missing _mm256_broadcastsi128_si256.
2019-07-21 00:27:23 -04:00
Jeffrey Walton 22a55bbbc5
Use wildcard for FORTIFY_SOURCE filter on TCXXFLAGS (GH #865) 2019-07-19 11:26:20 -04:00
Jeffrey Walton 417fbd719a
Fix missing if statement
Copy/paste error from the regular GNUmakefile
2019-07-19 00:16:23 -04:00
Jeffrey Walton 058a59814f
Fix TCXXFLAGS using openSUSE standard flags (GH #865) 2019-07-19 00:14:25 -04:00
Jeffrey Walton 07c208dbc6
Filter out static_assert from Posix assert test 2019-07-14 22:43:31 -04:00
Jeffrey Walton 769643bbe1
Fix macro paste in CRYPTOPP_ASSERT_JOIN 2019-07-14 19:09:05 -04:00
Jeffrey Walton 388a2e6ded
Fix macro paste in CRYPTOPP_ASSERT_JOIN 2019-07-14 19:04:52 -04:00
Jeffrey Walton f5881d121a
CRYPTOPP_CXX11_STATIC_ASSERT -> CRYPTOPP_CXX14_STATIC_ASSERT
WHoops, this is a C++14 feature
2019-07-14 19:02:58 -04:00
Jeffrey Walton 002e794ae2
Use C++ static_assert from N3928 when available 2019-07-14 18:28:51 -04:00
Jeffrey Walton 5de1089c8c
Update documentation 2019-07-14 12:50:50 -04:00
Jeffrey Walton e8b07b162f
Avoid preprocessor error in SIZE_MAX (GH #864) 2019-07-14 00:52:30 -04:00
Jeffrey Walton 6ae9c055cc
Move CRYPTOPP_CXX11 down in list of defines 2019-07-11 12:12:19 -04:00
Jeffrey Walton f0d7917719
Move CRYPTOPP_NO_CXX11 and CRYPTOPP_NO_CXX17 to config_cxx.h
It looks like these two were overlooked during refactoring
2019-07-11 12:10:19 -04:00
Jeffrey Walton 8260dd1e81
Increase m_buf size (GH #862) 2019-07-10 15:54:48 -04:00
Jeffrey Walton 6d69043403
Add BufferedTransformation GetWord64 and PutWord64 (GH #862) 2019-07-10 10:04:58 -04:00
Jeffrey Walton a76c6a203f
Update documentation 2019-07-10 08:10:44 -04:00
Jeffrey Walton 60e7bf3081
Update documentation 2019-07-08 18:46:27 -04:00
Jeffrey Walton 195cd6e7c8
Update documentation 2019-07-06 16:06:27 -04:00
Jeffrey Walton 2ffa70fbc6
Clear asserts under DEBUG builds 2019-07-06 15:57:08 -04:00
Jeffrey Walton fd7115fc8b
Remove duplicate CRYPTOPP_GCC_VERSION test 2019-07-06 08:06:00 -04:00
Jeffrey Walton b76a010dda
Cleanup PowerPC defines 2019-07-06 07:35:36 -04:00
Jeffrey Walton f0a2967191
Fix missing binary operator 2019-07-06 07:07:16 -04:00
Jeffrey Walton 37de652635
Use C++ feature test macros when available
There are not too many of them. __cpp_threadsafe_static_init may be useful for less frequently used compilers and platforms.
2019-07-06 07:03:26 -04:00
Jeffrey Walton 76fa704cbe
Avoid potential uninitialized read in AutoSeededX917RNG
This is a minor fix to AutoSeededX917RNG::Reseed. Valgrind produces a finding if user input is too small or seed size is too large. The constraints make it a little tricky to use correctly. HKDF will always produce the correct amount of material with provable security, and avoid the Valgrind finding.
2019-07-06 02:58:43 -04:00
Jeffrey Walton 6c995e215a Fold CRYPTOPP_VALGRIND into CRYPTOPP_COVERAGE 2019-07-05 19:10:01 -04:00
Jeffrey Walton d4b3e1535a
Limit GCC workaround to 5.3 on PowerPC
GCC fixed the issue at GCC 5.3. Also see https://gcc.gnu.org/bugzilla/show_bug.cgi?id=31690
2019-07-05 18:08:05 -04:00
Jeffrey Walton 9c28cf2227
Whitespace check-in
Cleanup after the VMAC fixes
2019-07-05 17:26:50 -04:00
Jeffrey Walton ad99fc5b05
Clear Asan finding in VMAC under 32-bit inline ASM (GH #860)
Second try. The first try cleared the Asan finding but broke at -O3. Eventually we will skin this cat.
2019-07-05 16:33:01 -04:00
Jeffrey Walton 7fd751ed36
Revert Asan finding in VMAC change (GH #860)
cryptest.sh showed it broke at -O3
2019-07-05 11:58:35 -04:00
Jeffrey Walton f7986129df
Clear Asan finding in VMAC under 32-bit inline ASM (GH #860)
This one has been nagging us for a while. Tested OK under i686 and x86_64.
2019-07-05 03:38:03 -04:00
Jeffrey Walton 6bead34bd9
Update headers for 'make dep' 2019-07-05 02:42:27 -04:00
Jeffrey Walton ae04195d1f
Use xattr in cryptest-autotools.sh 2019-07-04 16:06:51 -04:00
Jeffrey Walton 6afa6fc213
Fix cryptest-autotools.sh on OS X
Needed to remove quarantine bit
2019-07-04 15:36:17 -04:00
Jeffrey Walton 6eeebaf26b
Update documentation 2019-07-04 13:57:33 -04:00
Jeffrey Walton 2baa37efac
Clear unused parameter warnings for GCC with -Wextra (GH #856) 2019-07-03 15:17:53 -04:00
Jeffrey Walton cd0d145635 Add legacy ECIES EC2N cryptosystem and kat (GH #856) 2019-07-03 03:06:58 -04:00
Jeffrey Walton ce6d3c1306 Add legacy ECIES ECP cryptosystem and kat (GH #856) 2019-07-03 01:41:23 -04:00
Mouse 5d0ceb3b04
Revert #857 for now
Travis CI fails "deep tests" of DLIES with #857 applied. Let's revert it for now and get back to
```c++
    cipherKey = key + MAC::DEDAULT_KEYLENGTH;
```
and see if it improves the situation.
2019-07-02 23:24:45 -04:00
Jeffrey Walton eeb7dadc76
Fix missing _mm_roti_epi32 and _mm_roti_epi64 under GCC (GH #859) 2019-07-02 19:10:11 -04:00
Jeffrey Walton fbbf0a08e8
Add missing XOP header for blake2b_simd.cpp (GH #859)
The Gentoo folks caught a bug at https://bugs.gentoo.org/689162. The 689162 bug uses -march=bdver1 -msse4.1 on a AMD Bulldozer machine.

Investigating the issue we are missing the XOP header blake2b_simd.cpp. However, adding the XOP header is not enough for this particular config. Four source files fail to compile with the expected headers. We are waiting on the GCC folks to get back to us with a fix.
2019-07-02 16:55:00 -04:00
Alon Bar-Lev 2eb400c52f config: guard CRYPTOPP_SSE2_INTRIN_AVAILABLE with CRYPTOPP_DISABLE_SSE2 (#858)
Signed-off-by: Alon Bar-Lev <alon.barlev@gmail.com>
2019-07-02 16:45:03 -04:00
Mouse c80a7ad028
Merge pull request #857 from rectalogic/nullhash
Use MAC::DIGESTSIZE in ECIES SymmetricEncrypt/SymmetricDecrypt
2019-07-02 11:06:29 -04:00
Mouse 97f5174226
Complete change from DEFAULT_KEYLENGTH to DIGESTSIZE in DLAES
Change from `MAC::DEFAULT_KEYLENGTH` to `MAC::DIGESTSIZE` in `DL_EncryptionAlgorithm_Xor` was only partially done. This was discovered when null hash was used. This, along with the proposed fix, was discovered by Andrew Wason (thanks!).
2019-07-02 11:02:07 -04:00
Andrew Wason 9c307ff4ba Use MAC::DIGESTSIZE in ECIES SymmetricEncrypt/SymmetricDecrypt
Fixes #856
2019-07-02 10:47:46 -04:00
Jeffrey Walton 445ec61125
Remove copy ctor from DERGeneralEncoder and BERGeneralDecoder
GCC was giving too many warnings at -Wextra. We also could not comply with Rule of 3 because it resulted in compile failures in C++98 and C++03
2019-07-01 13:29:46 -04:00
Jeffrey Walton c3d4e79a09
Use CRYPTOPP_CXX11_DELETED_FUNCTIONS in NotCopyable 2019-07-01 13:27:51 -04:00
Jeffrey Walton 36e8dfeca8
Add define for C++11 deleted functions 2019-07-01 08:17:22 -04:00
Jeffrey Walton 18d5e5528f Fix divide by 0 finding (GH #855)
I'm not sure which tool is producing this finding. I am pretty sure it is a false positive, but clear it for the sake of dark and silent cockpits
2019-06-28 14:22:03 -04:00
Jeffrey Walton 26a59cd94b
Update README 2019-06-15 06:42:34 -04:00
Jeffrey Walton 840bc65740
Update README 2019-06-15 06:20:49 -04:00
Mouse 03619c0800
Merge pull request #853 from DimaStebaev/pull-request
Compilation warning fix.
2019-06-12 07:37:52 -04:00
Dmytro Stebaiev d24c991913
Pull changes from master branch 2019-06-10 11:25:46 +03:00
Jeffrey Walton 0ea4354157
Update comments 2019-06-09 12:52:10 -04:00
Jeffrey Walton 570a8e1b36
Whitespace check-in 2019-06-09 12:12:46 -04:00
Jeffrey Walton 955ac6fe24
Rework SSE2 and AVX2 loads and stores 2019-06-09 04:29:40 -04:00
Jeffrey Walton 8c78985de2
Add ModularArithmetic::operator= 2019-06-09 02:56:30 -04:00
Jeffrey Walton c1f4d17e10
Cleanup BERGeneralDecoder constructors
For real this time...
2019-06-09 02:03:06 -04:00
Jeffrey Walton 55fe6a2191
Cleanup BERGeneralDecoder constructors 2019-06-09 02:00:53 -04:00
Jeffrey Walton 8fab1c3677
Revert changes for lgtm findings
This broke SunCC to the point of no repair. SunCC is using AVX2 instructions for C++ and SSE2. Man this compiler sucks...
2019-06-09 01:49:44 -04:00
Jeffrey Walton 3ce1823fd1
Fix SunCC compile
Sun's compiler is mostly braindead.
2019-06-09 00:00:22 -04:00
Jeffrey Walton 6a11f00768
Clear lgtm findings 2019-06-08 12:59:14 -04:00
Jeffrey Walton 43b01973b1
Clear lgtm findings
We did some refactoring and added sse_simd.h. Over time more SSE functions will likely move into sse_simd.h
2019-06-08 11:00:11 -04:00
Jeffrey Walton afffba7b7b
Add -mtune=native option to makefile
Added for Solaris 11 .3 on SPARC64
2019-06-07 13:02:25 -04:00
Dmytro Stebaiev fa9187ac77
Fix compilation warning 2019-06-07 18:17:15 +03:00
Jeffrey Walton ed4996f652
Cleanup governor.sh script 2019-06-05 23:21:00 -04:00
Jeffrey Walton 29a30b74b0
Update head comments 2019-06-05 23:09:58 -04:00
Jeffrey Walton 17fa3031b3
Clear lgtm finding in ECP class 2019-06-05 10:52:45 -04:00
Jeffrey Walton d8122cec16
Avoid ARM rev on Aarch64
This broke Aarch64
2019-06-04 21:17:13 -04:00
Jeffrey Walton 6c009ddf43
Remove dummy operator= in ModularArithmetic 2019-06-04 19:05:33 -04:00
Jeffrey Walton 994c98b6c0
Fix GCC compile on AIX
In file included from test.cpp:31:0:
validate.h:213:93: error: operator '||' has no right operand
 #elif (_POSIX_C_SOURCE >= 1 || _XOPEN_SOURCE || _BSD_SOURCE || _SVID_SOURCE || _POSIX_SOURCE)
2019-06-04 09:45:33 -04:00
Jeffrey Walton 3afb1f1099
Fix GCC compile on AIX
In file included from test.cpp:31:0:
validate.h:213:93: error: operator '||' has no right operand
 #elif (_POSIX_C_SOURCE >= 1 || _XOPEN_SOURCE || _BSD_SOURCE || _SVID_SOURCE || _POSIX_SOURCE)
2019-06-04 09:37:28 -04:00
Jeffrey Walton 198b081df5
Add assert to RemainingLength member function 2019-06-04 09:29:01 -04:00
Jeffrey Walton 238578a808
Clear lgtm findings
The lgtm service asks for scoped calls to IsolatedInitialize. The code is a tad bit more readable, so we will clear the findings.
2019-06-04 05:31:46 -04:00
Jeffrey Walton 462bcc859d
Update Poly1305 nonce length check 2019-06-04 04:39:19 -04:00
Jeffrey Walton a644008679
Cleanup ASN.1 encoders and decoders (GH #851) 2019-06-04 02:49:16 -04:00
Jeffrey Walton ab538471b1
Update documentation 2019-06-04 02:46:43 -04:00
Jeffrey Walton f330c0eca8
Clear warning on missing assignment operator 2019-06-03 23:17:15 -04:00
Jeffrey Walton c76711237a
Call base class IsolatedInitialize 2019-06-03 06:45:58 -04:00
Jeffrey Walton 3faf716d73
Call base class IsolatedInitialize 2019-06-03 06:44:58 -04:00
Jeffrey Walton 0a20141f36
Clear warning for assignment operator in HuffmanNode 2019-06-03 06:32:24 -04:00
Jeffrey Walton 54d48ac1f4
Add header guard for serpentp.h 2019-06-03 06:17:58 -04:00
Jeffrey Walton 342cdb9589
Clear lgtm warning on unsafe functions 2019-06-03 05:41:58 -04:00
Jeffrey Walton 959494871f
Guard use of volatile cast in TEA and XTEA 2019-06-02 05:29:08 -04:00
Jeffrey Walton 9538f2d715
Fix compile on iOS 2019-06-01 08:05:39 -04:00
Jeffrey Walton f00b0427aa
Exit setenv script if not sourced 2019-06-01 07:43:32 -04:00
Jeffrey Walton 1a0d7c516d
Disable BMI2 code paths in Integer class (GH #850) 2019-06-01 00:14:19 -04:00
Jeffrey Walton 8e27c6b3fa
Fix OS X compile with Clang later than 6.0
It looks like Apple Clang 6.0 does not provide _blsr_u32 and friends. Later versions of Clang defines _blsr_u32 and it causes a stream of warnings.
2019-05-31 23:33:17 -04:00
Jeffrey Walton 392ec3465e
Fix OS X compile with Clang 6.0 2019-05-31 23:03:24 -04:00
Jeffrey Walton 4952fa489d
Use BMI2 when available for MultiplyWordsLoHi, MulAcc and friends
Using BMI2 saves about 0.03 ms on a Core i5 6400 @ 2.7 GHz. It is small but measurable. It also gives GCC more freedom in selecting memory or register operands
2019-05-31 09:42:39 -04:00
Jeffrey Walton fb0bef1eb6
Use BMI2 when available for MultiplyWordsLoHi, MulAcc and friends
Using BMI2 saves about 0.03 ms on a Core i5 6400 @ 2.7 GHz. It is small but measurable. It also gives GCC more freedom in selecting memory or register operands
2019-05-31 05:37:35 -04:00
Jeffrey Walton aed6e935d6
Update documentation 2019-05-30 23:22:47 -04:00
Jeffrey Walton 1f2be58434
Update Doxygen comments 2019-05-30 22:30:22 -04:00
Jeffrey Walton 0dd07252d2
Update comments 2019-05-28 20:19:34 -04:00
Jeffrey Walton e40de18538
Update comments 2019-05-28 20:18:58 -04:00
Jeffrey Walton b61da7acfe
Update cryptest-autotools script 2019-05-28 06:36:01 -04:00
Jeffrey Walton a2e7c26f6c
Add 16-bit rev16 and rbit 2019-05-28 02:50:58 -04:00
Jeffrey Walton 623059f28c
Use ARM rev and rbit when appropriate
We tried to add a ByteReverse(word64) and BitReverse(word64) overloads but GCC was producing bad code for it.
2019-05-27 14:27:12 -04:00
Jeffrey Walton 81da61fe7b
Breakout sha_block_data_order and sha_block_data_order_neon (GH #847) 2019-05-26 22:10:26 -04:00
Jeffrey Walton d4b533a60f
Add Thumb and Arm versions of CPU_ProbeARMv7() 2019-05-26 17:06:55 -04:00
Jeffrey Walton 7cd8d0278a
Remove VFP_ABI_PUSH and VFP_ABI_POP macros 2019-05-26 02:14:03 -04:00
Jeffrey Walton 9a3c1e351d
Clear Valgrind finding in IncrementCounterByOne
The single buffer IncrementCounterByOne generated a Valgrind finding on ARM. This commit uses the same pattern for both overloads in case Valgrind wants to fire on the two-buffer version.
2019-05-25 19:49:49 -04:00
Jeffrey Walton ca11105a40
Clear sign comparison warning under GCC 2019-05-25 17:00:32 -04:00
Jeffrey Walton f90c162b68
Fix IncrementCounterByOne
This was introduced earlier in the day when clearing a Valgrind finding. It tested good with the self tests. However, we double process byte[0] if there's a carry.
2019-05-25 07:02:32 -04:00
Jeffrey Walton fc10a7f1ea
Fix SHA512 on ARM benchmarks
This was a mistake when porting from Cryptogams to Crypto++. The macros VFP_ABI_PUSH and VFP_ABI_POP needed to be defined because they save and restore SIMD register state. They were originally missing during the port. The benchmarks would hang because the doubles we used for benchmarking were blown away in sha512_block_data_order_neon.
2019-05-25 06:23:19 -04:00
Jeffrey Walton 92df2a685f
Clear Valgrind warnings on ARM
I don't believe these should have been findings. They were clear on x86, Aarch64 and PowerPC.
2019-05-25 03:41:05 -04:00
Jeffrey Walton 1400757fea
Update comments 2019-05-25 00:43:27 -04:00
Jeffrey Walton ea96b9d375
Use CRYPTOGAMS_armcap_P for ARM (GH #846)
Andy advised against removing the global caps variable. This commit reintroduces CRYPTOGAMS_armcap_P. However, due to the shared object symbol loading problem, we needed to use CRYPTOGAMS_armcap_P as a global, and not CRYPTOGAMS_armcap as a local. Using CRYPTOGAMS_armcap_P directly caused the symbol to be marked as R_ARM_ABS32 which avoids the problem with R_ARM_REL32.
2019-05-24 16:33:47 -04:00
Jeffrey Walton 1650cac3f3
Update comments 2019-05-23 19:35:05 -04:00
Jeffrey Walton 2a09376211
Remove const_cast from CryptogamsArmCaps() 2019-05-23 03:17:17 -04:00
Jeffrey Walton c5bb85754f
Add RDRAND and RDSEED test programs
These are for Autotools on Solaris.
2019-05-22 21:25:31 -04:00
Jeffrey Walton fed4a55f39
Update cryptest-autotools script 2019-05-22 21:03:19 -04:00
Jeffrey Walton 57b85fafce
Update Cryptogams SHA headers (GH #846) 2019-05-22 19:11:16 -04:00
Jeffrey Walton 7eaa5837e0
Fix "unexpected reloc type 0x03" for ARM shared object (GH #846) 2019-05-22 19:00:08 -04:00
Jeffrey Walton ce5d5d5c0f
Use CRYPTOGAMS_armcap_loc for word label 2019-05-22 06:37:16 -04:00
Jeffrey Walton 0a4b370d3f
Use CRYPTOGAMS_armcaps
It looks like CRYPTOGAMS_armcap was used in some places, and it broke Autotools
2019-05-22 05:46:06 -04:00
Jeffrey Walton 13e3a19e94
Remove __KERNEL__ guard
Andy's code is used in the Linux kernel. The define is not needed here.
2019-05-22 05:12:16 -04:00
Jeffrey Walton 073c246595
Rename CRYPTOGAMS_armcap_P to CRYPTOGAMS_armcap 2019-05-22 05:01:27 -04:00
Jeffrey Walton 50dd3ad354
Spelling 2019-05-22 03:04:38 -04:00
Jeffrey Walton 7287a79669
Use config_ver.h in change-version script 2019-05-22 02:56:37 -04:00
Jeffrey Walton 1abab8050e
Clear documentation warnings 2019-05-22 02:53:26 -04:00
Jeffrey Walton 879b8c6fe9
Remove unused CLANG_INTEGRATED_ASSEMBLER from Makefile
This is an artifact that should have been removed at CRYPTOPP_DISABLE_MIXED_ASM.
2019-05-21 20:05:44 -04:00
Jeffrey Walton f396ade93a
Rename XGETBV to XGETBV64 2019-05-21 19:44:48 -04:00
Jeffrey Walton 6f3be56c9d
Update comments 2019-05-21 19:40:11 -04:00
Jeffrey Walton 02cdbf61d3
Rename ExtendedControlRegister to XGETBV 2019-05-21 19:31:13 -04:00
Jeffrey Walton cf85d768b4
Fix armv8l-unknown-linux-gnueabihf yet again 2019-05-21 18:48:13 -04:00
Jeffrey Walton 5e15b46234
Fix Aarch64 compile in CPU_ProbeARMv7
Previous to the Cryptogams cut-in we could be sloppy and return anything for ARMv8. Now e have real code backing ARMv7 we need to return an accurate value.
2019-05-21 08:13:52 -04:00
Jeffrey Walton 268ea61f1c
Cutover to CRYPTOPP_LLVM_CLANG_VERSION (GH #845)
We were using CRYPTOPP_CLANG_VERSION in some places.
2019-05-21 07:54:47 -04:00
Jeffrey Walton 2d4a932c33
Remove -tvos_simulator_version_min from AppleTVSimulator
It did not clear the problem.
2019-05-21 07:08:41 -04:00
Jeffrey Walton 5b1cae0c63
Fix compile using MSVC 2013 ARM 2019-05-21 06:54:33 -04:00
Jeffrey Walton 751515901b
Limit Cryptogams AES and SHA to Linux distros
The Apple assembler cannot translate the source files for iOS.
2019-05-21 05:59:58 -04:00
Jeffrey Walton ddb9249444
Fix source warning 2019-05-21 05:44:21 -04:00
Jeffrey Walton 1973674732
Add sanity check to setenv-*.sh scripts
Prompt user to source the script when required. Whitespace check-in
2019-05-21 05:37:40 -04:00
Jeffrey Walton 3e897eb0f6
Use CRYPTOPP_ARM_NEON_AVAILABLE in neon_simd.cpp 2019-05-21 05:11:24 -04:00
Jeffrey Walton 02baab2307
Enable Cryptogams AES on ARM using Clang
It looks like AES needed -mthumb for Clang. SHA must not use -mthumb under Clang due to a crash.
2019-05-21 04:23:40 -04:00
Jeffrey Walton 6acbbf1849
Fix crash in GCM mode on ARM with -mthumb 2019-05-21 04:03:22 -04:00
Jeffrey Walton 08235400b0
Add CRYPTOPP_CLANG_VERSION for ARM asm defines
We should be using both CRYPTOPP_APPLE_CLANG_VERSION and CRYPTOPP_LLVM_CLANG_VERSION. We'll loop back to it when we have some time.
2019-05-21 03:02:35 -04:00
Jeffrey Walton 5fb03078eb
Use void return value for Cryptogams SHA functions 2019-05-21 02:38:30 -04:00
Jeffrey Walton e8603143dc
Whitespace check-in
We also simplified the CPU_ProbeNEON logic a bit to a vmov.u32 and vshl.u32.
2019-05-21 02:21:15 -04:00
Jeffrey Walton 40251d9b7f
Guard CPU_ProbeARMv7 with CRYPTOPP_BOOL_ARM32 (GH #844)
We make these queries available on all platforms so folks don't need to guard code.
2019-05-20 23:33:06 -04:00
Jeffrey Walton c456d6aa69
Guard CPU_ProbeARMv7 with CRYPTOPP_BOOL_ARM32 (GH #844)
We make these queries available on all platforms so folks don't need to guard code.
2019-05-20 23:30:12 -04:00
Jeffrey Walton cc011d2e44
Remove Aarch32 and Aarch64 from CPU_QueryARMv7
I believe some of the code may be generated differently. When testing CPU_ProbeARMv7 I had trouble compiling it on ARMv8.
2019-05-20 23:09:57 -04:00
Jeffrey Walton a9be7ced86
Fix CPU_QueryARMv7 for Clang (GH #844)
This fixes the query under Clang. This appears to be a trickier problem because there is no explicit define for HWCAP_ARMv7. We rely on HWCAP_NEON as a proxy, or fallback to a CPU_ProbeARMv7.
2019-05-20 23:02:36 -04:00
Jeffrey Walton a164c1f41d
Fix CPU_ProbeARMv7 for Clang (GH #844)
This fixes the probe undr Clang. However, we need to fix the CPU_QueryARMv7
2019-05-20 21:41:57 -04:00
Jeffrey Walton c0cff24953
Update comments 2019-05-20 17:11:59 -04:00
Jeffrey Walton b1b6ea5b78
Fold declarations for CRYPTOGAMS_armcaps
Also declare storage for CRYPTOGAMS_armcaps. This moves the symbol from BSS to initialized data. The Cryptogams module declares the symbol as common, so they are weak and use our declaration.
2019-05-20 17:03:57 -04:00
Jeffrey Walton 5c7c092336
Cleanup Cryptogams defines 2019-05-20 16:39:26 -04:00
Jeffrey Walton 00155d42cc
Enable Cryptogams SHA asm for Clang
AES is still disabled
2019-05-20 15:29:30 -04:00
Jeffrey Walton 9590481c7f
Update cryptest-autotools.sh 2019-05-20 03:48:02 -04:00
Jeffrey Walton 122529ed4a
Add test for automake in cryptest-autotools.sh 2019-05-19 21:46:36 -04:00
Jeffrey Walton e0b60439bf
Fix Scrypt crash when blockSize is 0 (GH #842)
This may change in the future. I prefer to recover, and use default block size when block size is 0. But this stops the immediate problem of a crash.
2019-05-19 21:24:32 -04:00
Jeffrey Walton 2c0455edf8
Add additional asserts in Scrypt::ValidateParameters (GH #842)
We still need to figure out what to do, but we can start warning users immediately.
2019-05-19 18:52:37 -04:00
Jeffrey Walton e3788aacc5
Display C++ for SHA512_AlgorithmProvider on ARM 2019-05-19 18:17:46 -04:00
Jeffrey Walton 6528561cb3
Update comments 2019-05-19 18:10:09 -04:00
Jeffrey Walton e19a6152b5
Return CRYPTOGAMS_armcaps in CryptogamsArmCaps 2019-05-19 16:51:40 -04:00
Jeffrey Walton 62d53e6c44
Disable Cryptogams ASM on static Transform function
This needs mmore testing.
2019-05-19 16:46:01 -04:00
Jeffrey Walton d38e5a954d
Add ARM SHA512 asm implementation from Cryptogams (GH #841, PR #843)
Cryptogams is Andy Polyakov's project used to create high speed crypto algorithms and share them with other developers. Cryptogams  has a dual license. First is the OpenSSL license because Andy contributes to OpenSSL. Second is a BSD license for those who want a more permissive license.

Andy's implementation runs about 45% faster than C/C++ code. Testing on a 1.8 GHz Cortex-A17 shows Cryptograms at 45 cpb, and C++ at 79 cpb.

The integration instructions are documented at [Cryptogams SHA](https://wiki.openssl.org/index.php/Cryptogams_SHA) on the OpenSSL wiki.
2019-05-19 16:29:45 -04:00
Jeffrey Walton 4c9ca6b723
Add ARM SHA256 asm implementation from Cryptogams (GH #840, PR #840)
Cryptogams is Andy Polyakov's project used to create high speed crypto algorithms and share them with other developers. Cryptogams  has a dual license. First is the OpenSSL license because Andy contributes to OpenSSL. Second is a BSD license for those who want a more permissive license.

Andy's implementation runs about 45% faster than C/C++ code. Testing on a 1 GHz Cortex-A7 shows Cryptograms at 17 cpb, and C++ at 30 cpb.

The integration instructions are documented at [Cryptogams SHA](https://wiki.openssl.org/index.php/Cryptogams_SHA) on the OpenSSL wiki.
2019-05-19 06:59:12 -04:00
Jeffrey Walton 8c99b1cd75
Add call to automake in cryptest-automake.sh 2019-05-19 02:26:44 -04:00
Jeffrey Walton ffb11da13b
Add call to automake in cryptest-automake.sh 2019-05-19 02:19:47 -04:00
Jeffrey Walton 1a63112faf
Add ARM SHA1 asm implementation from Cryptogams (GH #837, PR #838)
Add ARM SHA1 asm implementation from Cryptogams.

Cryptogams is Andy Polyakov's project used to create high speed crypto algorithms and share them with other developers. Cryptogams  has a dual license. First is the OpenSSL license because Andy contributes to OpenSSL. Second is a BSD license for those who want a more permissive license.

Andy's implementation runs about 30% faster than C/C++ code. Testing on a 1 GHz Cortex-A7 shows Cryptograms at 16 cpb, and C++ at 23 cpb.

The integration instructions are documented at [Cryptogams SHA](https://wiki.openssl.org/index.php/Cryptogams_SHA) on the OpenSSL wiki.
2019-05-18 23:07:17 -04:00
Jeffrey Walton 4a21619bff
Regenerate Cryptogams AES assembly file
> It does not look like much has changed in the last year.
2019-05-18 06:49:51 -04:00
Jeffrey Walton 6cc9c81fa5
Use test_arm_sha1.cxx for feature tests 2019-05-17 23:45:23 -04:00
Jeffrey Walton 83ee4e1fc0
Use test_arm_sha1.cxx for feature tests 2019-05-17 23:42:15 -04:00
Jeffrey Walton f027361369
Split test_arm_sha.cxx into SHA1 and SHA256 tests 2019-05-17 22:19:26 -04:00
Jeffrey Walton c51f0ecbfd
Make config.h more Autoconf friendly (GH #835, PR #836) 2019-05-17 15:18:17 -04:00
Jeffrey Walton b25b6f0892
Cleanup SIMON64 and SPECK64 flags in Makefile (GH #834) 2019-05-16 18:57:57 -04:00
Jeffrey Walton edc0952b25
Whitespace check-in 2019-05-16 02:47:44 -04:00
Jeffrey Walton ef3968f551
Guard x86 cache line size 2019-05-08 21:20:49 -04:00
Jeffrey Walton 72a71eb230
Use fallback in detecting ARM and PowerPC cache line size 2019-05-08 19:54:05 -04:00
Jeffrey Walton c91813c0b4
Use fallback in detecting VIA cach line size 2019-05-08 19:46:23 -04:00
Jeffrey Walton 40e5891635
Use CPU_QuerySHA256 for ARM 2019-05-08 19:31:31 -04:00
Jeffrey Walton 73bf2f29c0
Add "AMDisbetter!" cpuid detection 2019-05-08 18:51:12 -04:00
Jeffrey Walton 986fded372
Spelling 2019-05-08 18:33:55 -04:00
Jeffrey Walton d9aed27ad3
Add code for VIA L1 data cache line size 2019-05-08 18:29:33 -04:00
Jeffrey Walton 30fc56d58c
Clear alignment warnings on ARM 32-bit platforms 2019-05-01 12:54:25 -04:00
Jeffrey Walton 337d1c88c8
Use armv7l for machine of Clang triplet armv8l-unknown-linux-gnueabihf (GH #831)
Autotools uses armv7l. We should be safe using the same machine.
2019-05-01 11:00:34 -04:00
Jeffrey Walton a5fe6fa6da
Remove unneeded perm check in cryptest-autotools.sh 2019-05-01 10:45:11 -04:00
Jeffrey Walton 4acdcc46d0
Try workaround Clang triplet on ARMv7l (GH #831) 2019-05-01 01:48:00 -04:00
Jeffrey Walton 7ef3dacdc2
Remove C++11 constexpr code for CRYPTOPP_ALIGN_DATA (PR #830)
I don't have faith in it even though it has tested good so far.
2019-04-30 23:00:56 -04:00
Jeffrey Walton ff544c386c
Use dynamic_cast in ed25519 (GH #829) 2019-04-30 20:29:21 -04:00
Jeffrey Walton a379c5644a
Clear alignment warnings on ARM 32-bit platforms (#828) 2019-04-30 17:53:58 -04:00
Jeffrey Walton b9fe3a3415
Clear alignment warnings on ARM 32-bit platforms 2019-04-29 22:40:07 -04:00
Jeffrey Walton 6c60e2cd1d
Add conservative governor setting
This governor setting is showing up on dev-board 4.19 kernels
2019-04-29 18:21:50 -04:00
Jeffrey Walton a11ac1e879
Use ConstBytePtr in TestDataNameValuePairs (GH #827) 2019-04-29 00:13:32 -04:00
Jeffrey Walton 38a4bb55cf
Post-release version increment 2019-04-29 00:12:18 -04:00
Jeffrey Walton 9dcc26c582
Prepare for Crypto++ 8.2 release
Make ConstBytePtr return non-NULL pointer
2019-04-28 19:37:23 -04:00
Jeffrey Walton ec1aa8874c
Prepare for Crypto++ 8.2 release
Fix SHAKE-128 and SHAKE-256 tests
2019-04-28 19:09:45 -04:00
Jeffrey Walton 7ba4657375
Prepare for Crypto++ 8.2 release
Fix VS2010 compile on WIndows Vista; Add BytePtr inline function
2019-04-28 18:10:03 -04:00
Jeffrey Walton c9703ab5ea
Prepare for Crypto++ 8.2 release
Fix VS2010 compile on WIndows Vista
2019-04-28 17:27:09 -04:00
Jeffrey Walton a04014aa48
Prepare for Crypto++ 8.2 release
Fix Fedora 7 compile
2019-04-28 15:21:26 -04:00
Jeffrey Walton e705fa7fad
Prepare for Crypto++ 8.2 release 2019-04-28 12:47:07 -04:00
Jeffrey Walton 4e0c3ed837
Prepare for Crypto++ 8.2 release 2019-04-28 11:48:32 -04:00
Jeffrey Walton 9e22df09a1
Prepare for Crypto++ 8.2 release 2019-04-28 11:48:04 -04:00
Jeffrey Walton 68b4fc0d8b
Prepare for Crypto++ 8.2 release 2019-04-28 11:30:32 -04:00
Jeffrey Walton c9dc95a45c
Clear GCC multiline comment warning 2019-04-27 23:30:33 -04:00
Jeffrey Walton fd2fd0c199
Remove unneeded permutes
Loading byte arrays does not suffer the endian swaps.
2019-04-27 23:09:30 -04:00
Jeffrey Walton 90f52dd9ae
Regenerate cryptest.nmake list 2019-04-27 21:37:23 -04:00
Jeffrey Walton b16d37e347
Clear C4296 under MSVC++ (GH #821) 2019-04-27 21:21:56 -04:00
Jeffrey Walton 255a6f2aa0
Clear UBsan warning -Wstringop-overflow 2019-04-27 21:08:02 -04:00
Jeffrey Walton 39418a8512
Use PowerPC unaligned loads and stores with Power8 (GH #825, PR #826)
Use PowerPC unaligned loads and stores with Power8. Formerly we were using Power7 as the floor because the IBM POWER Architecture manuals said unaligned loads and stores were available. However, some compilers generate bad code for unaligned loads and stores using `-march=power7`, so bump to a known good.
2019-04-27 20:35:01 -04:00
Jeffrey Walton d451751eb2
Update SKIPJACK documentation (GH #824) 2019-04-27 14:40:53 -04:00
Jeffrey Walton cdaac6b844
Add SKIPJACK/CBC test vectors (GH #824)
Generated using Botan 1.11.17, https://github.com/noloader/cryptopp-test/tree/master/SKIPJACK
2019-04-27 14:21:48 -04:00
Jeffrey Walton d1b1554188
Add SKIPJACK test vectors from SP800-17, Table 6, pp. 140-42 (GH #824) 2019-04-27 13:24:54 -04:00
Jeffrey Walton e8107e9cb8
Update documentation
The library uses both PKCS #5 and PKCS #7 padding
2019-04-04 07:20:33 -04:00
Jeffrey Walton 9f8017a276
Fix missing GF2NT_233_Multiply_Reduce_CLMUL in the cursed DLL (GH #783)
This should have been checked-in during GH #783 and PR #784. I think there was one mailing list message about missing symbols GF2NT_233_Multiply_Reduce_CLMUL and GF2NT_233_Square_Reduce_CLMUL. I missed it when attempting to reproduce the issue. I can duplicate it now using VS2013. I think the addition of CRYPTOPP_DLL caused the issue to surface.
2019-03-21 08:13:14 -04:00
Jeffrey Walton fc3b16e3a3
Fix SHAKE compile error with old GCC (GH #818) 2019-03-18 08:06:48 -04:00
Jeffrey Walton 0d17eea82c
Add x25519 default constructor 2019-03-04 19:43:33 -05:00
Jeffrey Walton 08b9e21e5a
Use TCXXFLAGS for feature tests in GNUmakefile-cross
This mirrors PR #815, where we used CXXFLAGS instead of TCXXFLAGS for feature tests
2019-02-28 06:42:16 -05:00
Nicolas Chauvet (kwizart) 7c7a12c584 Use TCXXFLAGS instead of CXXFLAGS (#815)
As done with others tests. This will avoid a miss-detection of aarch64 features
when using flags such as _FORTIFY_SOURCE that needs to be filtered for testing

This fixes https://github.com/weidai11/cryptopp/issues/812

V2: Fix all cases

Signed-off-by: Nicolas Chauvet <kwizart@gmail.com>
2019-02-28 06:37:18 -05:00
Jeffrey Walton 84ab1f3c66
Remove early NEON qualification tests from Makefile (GH #812, GH #813)
The makefile tries to pre-qualify NEON (for lack of a better term), and sets IS_NEON accordingly. If IS_NEON=1, then we go on to perform test compiles to see if -mfloat-abi=X -mfpu=neon (and friends) actually work. Effectively we are performing a test to see if we should perform another test.

The IS_NEON flag predates our compile time feature tests. It was kind of helpful when we were trying to sort out if a platform and compiler options supported NEON without a compile test. That was an absolute mess and we quickly learned we needed a real compile time feature test (which we now have).

Additionally, Debian and Fedora ARMEL builds are failing because we are misdetecting NEON availability. It looks like we fail to set IS_NEON properly, so we never get into the code paths that set either (1) -mfloat-abi=X -mfpu=neon or (2) -DCRYPTOPP_DISABLE_NEON or -DCRYPTOPP_DISABLE_ASM. Later, the makefile builds a *_simd.cpp and the result is an error that NEON needs to be activated (or disabled).

This commit removes IS_NEON so we immediately move to compile time feature tests.
2019-02-27 19:35:04 -05:00
Jeffrey Walton 8624a91988
Spelling 2019-02-24 17:00:20 -05:00
Jeffrey Walton 3183970300
Add missing BLAKE2 constructors
BLAKE2b and BLAKE2s are both missing a constructor that takes only the digest size. Also see https://groups.google.com/d/msg/cryptopp-users/QCFGYw8q3Yo/vpBCqz-vBgAJ
2019-02-24 15:45:00 -05:00
Jeffrey Walton 758939ab2e
Fix missing BlockSize() in BLAKE2 classes (GH #811) 2019-02-23 14:13:31 -05:00
Jeffrey Walton 6138b8a127
Post-release version increment
Also see https://www.cryptopp.com/wiki/Release_Process#Increment_version_numbers
2019-02-23 14:03:49 -05:00
Jeffrey Walton 20e9e0cb10
Prepare for Crypto++ 8.1 release
This should have been checked in with 1c34979592. Too late now, but fix it anyway.
2019-02-23 13:57:40 -05:00
177 changed files with 15792 additions and 5692 deletions

View File

@ -41,7 +41,7 @@ PROJECT_NAME = Crypto++
# could be handy for archiving the generated documentation or if some version # could be handy for archiving the generated documentation or if some version
# control system is used. # control system is used.
PROJECT_NUMBER = 8.1 PROJECT_NUMBER = 8.3
# Using the PROJECT_BRIEF tag one can provide an optional one line description # Using the PROJECT_BRIEF tag one can provide an optional one line description
# for a project that appears at the top of each page and should give viewer a # for a project that appears at the top of each page and should give viewer a

View File

@ -66,6 +66,16 @@ channels.h
cmac.cpp cmac.cpp
cmac.h cmac.h
config.h config.h
config_align.h
config_asm.h
config_cpu.h
config_cxx.h
config_dll.h
config_int.h
config_misc.h
config_ns.h
config_os.h
config_ver.h
cpu.cpp cpu.cpp
cpu.h cpu.h
crc.cpp crc.cpp
@ -269,6 +279,7 @@ rdrand.s
rdrand.asm rdrand.asm
rdrand.cpp rdrand.cpp
rdrand.h rdrand.h
rdseed.asm
rdtables.cpp rdtables.cpp
regtest1.cpp regtest1.cpp
regtest2.cpp regtest2.cpp
@ -304,6 +315,12 @@ serpentp.h
sha.cpp sha.cpp
sha_simd.cpp sha_simd.cpp
sha.h sha.h
sha1_armv4.h
sha1_armv4.S
sha256_armv4.h
sha256_armv4.S
sha512_armv4.h
sha512_armv4.S
sha3.cpp sha3.cpp
sha3.h sha3.h
shacal2.cpp shacal2.cpp
@ -421,6 +438,8 @@ TestData/dlie2048.dat
TestData/dsa1024.dat TestData/dsa1024.dat
TestData/dsa1024b.dat TestData/dsa1024b.dat
TestData/dsa512.dat TestData/dsa512.dat
TestData/ecies_p160.dat
TestData/ecies_t163.dat
TestData/ed25519.dat TestData/ed25519.dat
TestData/ed25519_ver.dat TestData/ed25519_ver.dat
TestData/ed25519v0.dat TestData/ed25519v0.dat
@ -542,6 +561,7 @@ TestVectors/shacal2.txt
TestVectors/simeck.txt TestVectors/simeck.txt
TestVectors/simon.txt TestVectors/simon.txt
TestVectors/siphash.txt TestVectors/siphash.txt
TestVectors/skipjack.txt
TestVectors/sm3.txt TestVectors/sm3.txt
TestVectors/sm4.txt TestVectors/sm4.txt
TestVectors/sosemanuk.txt TestVectors/sosemanuk.txt
@ -561,9 +581,10 @@ TestPrograms/test_arm_asimd.cxx
TestPrograms/test_arm_crc.cxx TestPrograms/test_arm_crc.cxx
TestPrograms/test_arm_neon.cxx TestPrograms/test_arm_neon.cxx
TestPrograms/test_arm_pmull.cxx TestPrograms/test_arm_pmull.cxx
TestPrograms/test_arm_sha.cxx TestPrograms/test_arm_sha1.cxx
TestPrograms/test_arm_sha3.cxx TestPrograms/test_arm_sha256.cxx
TestPrograms/test_arm_sha512.cxx TestPrograms/test_arm_sha512.cxx
TestPrograms/test_arm_sha3.cxx
TestPrograms/test_arm_sm3.cxx TestPrograms/test_arm_sm3.cxx
TestPrograms/test_arm_sm4.cxx TestPrograms/test_arm_sm4.cxx
TestPrograms/test_cxx.cxx TestPrograms/test_cxx.cxx
@ -583,6 +604,8 @@ TestPrograms/test_x86_avx2.cxx
TestPrograms/test_x86_avx512.cxx TestPrograms/test_x86_avx512.cxx
TestPrograms/test_x86_clmul.cxx TestPrograms/test_x86_clmul.cxx
TestPrograms/test_x86_cpuid.cxx TestPrograms/test_x86_cpuid.cxx
TestPrograms/test_x86_rdrand.cxx
TestPrograms/test_x86_rdseed.cxx
TestPrograms/test_x86_sha.cxx TestPrograms/test_x86_sha.cxx
TestPrograms/test_x86_sse2.cxx TestPrograms/test_x86_sse2.cxx
TestPrograms/test_x86_sse3.cxx TestPrograms/test_x86_sse3.cxx

View File

@ -10,12 +10,16 @@ SHELL = /bin/sh
# If needed # If needed
TMPDIR ?= /tmp TMPDIR ?= /tmp
# Used for ARMv7 and NEON.
FP_ABI ?= hard
# Used for feature tests # Used for feature tests
TOUT ?= a.out TOUT ?= a.out
TOUT := $(strip $(TOUT)) TOUT := $(strip $(TOUT))
# Allow override for the cryptest.exe recipe. Change to
# ./libcryptopp.so or ./libcryptopp.dylib to suit your
# taste. https://github.com/weidai11/cryptopp/issues/866
LINK_LIBRARY ?= libcryptopp.a
LINK_LIBRARY_PATH ?= ./
# Command and arguments # Command and arguments
AR ?= ar AR ?= ar
ARFLAGS ?= -cr # ar needs the dash on OpenBSD ARFLAGS ?= -cr # ar needs the dash on OpenBSD
@ -25,6 +29,7 @@ CP ?= cp
MV ?= mv MV ?= mv
RM ?= rm -f RM ?= rm -f
GREP ?= grep GREP ?= grep
SED ?= sed
CHMOD ?= chmod CHMOD ?= chmod
MKDIR ?= mkdir -p MKDIR ?= mkdir -p
@ -35,11 +40,17 @@ LDCONF ?= /sbin/ldconfig -n
ifneq ($(wildcard /usr/xpg4/bin/grep),) ifneq ($(wildcard /usr/xpg4/bin/grep),)
GREP := /usr/xpg4/bin/grep GREP := /usr/xpg4/bin/grep
endif endif
ifneq ($(wildcard /usr/xpg4/bin/sed),)
SED := /usr/xpg4/bin/sed
endif
# Attempt to determine target machine, fallback to "this" machine. # Yet another Clang hack. I think the LLVM devs are making the shit up
# The target machine is the one the package runs on. Most people # as they go. Also see https://github.com/weidai11/cryptopp/issues/831.
# call this the "target", but not Autotools. MACHINEX := $(shell $(CXX) $(CXXFLAGS) -dumpmachine 2>/dev/null)
HOSTX := $(shell $(CXX) $(CXXFLAGS) -dumpmachine 2>/dev/null | cut -f 1 -d '-') ifeq ($(MACHINEX),armv8l-unknown-linux-gnueabihf)
MACHINEX := armv7l-unknown-linux-gnueabihf
endif
HOSTX := $(shell echo $(MACHINEX) | cut -f 1 -d '-')
ifeq ($(HOSTX),) ifeq ($(HOSTX),)
HOSTX := $(shell uname -m 2>/dev/null) HOSTX := $(shell uname -m 2>/dev/null)
endif endif
@ -53,8 +64,6 @@ IS_SPARC64 := $(shell echo "$(HOSTX)" | $(GREP) -i -c -E 'sun|sparc64')
IS_ARM32 := $(shell echo "$(HOSTX)" | $(GREP) -i -c -E 'arm|armhf|arm7l|eabihf') IS_ARM32 := $(shell echo "$(HOSTX)" | $(GREP) -i -c -E 'arm|armhf|arm7l|eabihf')
IS_ARMV8 := $(shell echo "$(HOSTX)" | $(GREP) -i -c -E 'aarch32|aarch64|arm64|armv8') IS_ARMV8 := $(shell echo "$(HOSTX)" | $(GREP) -i -c -E 'aarch32|aarch64|arm64|armv8')
IS_NEON := $(shell $(CXX) $(CXXFLAGS) -dumpmachine 2>/dev/null | $(GREP) -i -c -E 'armv7|armhf|arm7l|eabihf|armv8|aarch32|aarch64')
# Attempt to determine platform # Attempt to determine platform
SYSTEMX := $(shell $(CXX) $(CXXFLAGS) -dumpmachine 2>/dev/null) SYSTEMX := $(shell $(CXX) $(CXXFLAGS) -dumpmachine 2>/dev/null)
ifeq ($(SYSTEMX),) ifeq ($(SYSTEMX),)
@ -116,9 +125,10 @@ else ifeq ($(findstring distclean,$(MAKECMDGOALS)),trim)
DETECT_FEATURES := 0 DETECT_FEATURES := 0
endif endif
# Strip out -Wall, -Wextra and friends for feature testing # Strip out -Wall, -Wextra and friends for feature testing. FORTIFY_SOURCE is removed
# because it requires -O1 or higher, but we use -O0 to tame the optimizer.
ifeq ($(DETECT_FEATURES),1) ifeq ($(DETECT_FEATURES),1)
TCXXFLAGS := $(filter-out -Wall -Wextra -Werror% -Wunused -Wconversion -Wp%, $(CXXFLAGS)) TCXXFLAGS := $(filter-out -D_FORTIFY_SOURCE=% -Wall -Wextra -Werror% -Wunused -Wconversion -Wp%, $(CXXFLAGS))
ifneq ($(strip $(TCXXFLAGS)),) ifneq ($(strip $(TCXXFLAGS)),)
$(info Using testing flags: $(TCXXFLAGS)) $(info Using testing flags: $(TCXXFLAGS))
endif endif
@ -161,6 +171,11 @@ else
ZOPT = -O0 ZOPT = -O0
endif endif
# Fix CXX on Cygwin 1.1.4
ifeq ($(CXX),gcc)
CXX := g++
endif
# On ARM we may compile aes_armv4.S though the CC compiler # On ARM we may compile aes_armv4.S though the CC compiler
ifeq ($(GCC_COMPILER),1) ifeq ($(GCC_COMPILER),1)
CC=gcc CC=gcc
@ -187,19 +202,11 @@ ifeq ($(INCLUDEDIR),)
INCLUDEDIR := $(PREFIX)/include INCLUDEDIR := $(PREFIX)/include
endif endif
# Fix CXX on Cygwin 1.1.4
ifeq ($(CXX),gcc)
CXX := g++
endif
# We honor ARFLAGS, but the "v" option used by default causes a noisy make # We honor ARFLAGS, but the "v" option used by default causes a noisy make
ifeq ($(ARFLAGS),rv) ifeq ($(ARFLAGS),rv)
ARFLAGS = r ARFLAGS = r
endif endif
# Clang integrated assembler will be used with -Wa,-q
CLANG_INTEGRATED_ASSEMBLER ?= 0
# Original MinGW targets Win2k by default, but lacks proper Win2k support # Original MinGW targets Win2k by default, but lacks proper Win2k support
# if target Windows version is not specified, use Windows XP instead # if target Windows version is not specified, use Windows XP instead
ifeq ($(IS_MINGW),1) ifeq ($(IS_MINGW),1)
@ -273,9 +280,7 @@ ifeq ($(DETECT_FEATURES),1)
KECCAK_FLAG = $(SSSE3_FLAG) KECCAK_FLAG = $(SSSE3_FLAG)
LEA_FLAG = $(SSSE3_FLAG) LEA_FLAG = $(SSSE3_FLAG)
SIMECK_FLAG = $(SSSE3_FLAG) SIMECK_FLAG = $(SSSE3_FLAG)
SIMON64_FLAG = $(SSSE3_FLAG)
SIMON128_FLAG = $(SSSE3_FLAG) SIMON128_FLAG = $(SSSE3_FLAG)
SPECK64_FLAG = $(SSSE3_FLAG)
SPECK128_FLAG = $(SSSE3_FLAG) SPECK128_FLAG = $(SSSE3_FLAG)
SUN_LDFLAGS += $(SSSE3_FLAG) SUN_LDFLAGS += $(SSSE3_FLAG)
else else
@ -439,37 +444,37 @@ endif
##### ARM A-32, Aach64 and NEON ##### ##### ARM A-32, Aach64 and NEON #####
########################################################### ###########################################################
ifneq ($(IS_ARM32)$(IS_ARMV8)$(IS_NEON),000) ifneq ($(IS_ARM32)$(IS_ARMV8),00)
ifeq ($(DETECT_FEATURES),1) ifeq ($(DETECT_FEATURES),1)
ifeq ($(IS_ARM32)$(IS_NEON),11) ifneq ($(IS_ARM32),0)
TPROG = TestPrograms/test_arm_neon.cxx TPROG = TestPrograms/test_arm_neon.cxx
TOPT = -march=armv7-a -mfloat-abi=$(FP_ABI) -mfpu=neon TOPT = -march=armv7-a -mfpu=neon
HAVE_OPT = $(shell $(CXX) $(TCXXFLAGS) $(ZOPT) $(TOPT) $(TPROG) -o $(TOUT) 2>&1 | tr ' ' '\n' | wc -l) HAVE_OPT = $(shell $(CXX) $(TCXXFLAGS) $(ZOPT) $(TOPT) $(TPROG) -o $(TOUT) 2>&1 | tr ' ' '\n' | wc -l)
ifeq ($(strip $(HAVE_OPT)),0) ifeq ($(strip $(HAVE_OPT)),0)
NEON_FLAG = -march=armv7-a -mfloat-abi=$(FP_ABI) -mfpu=neon NEON_FLAG = -march=armv7-a -mfpu=neon
ARIA_FLAG = -march=armv7-a -mfloat-abi=$(FP_ABI) -mfpu=neon ARIA_FLAG = -march=armv7-a -mfpu=neon
AES_FLAG = -march=armv7-a -mfloat-abi=$(FP_ABI) -mfpu=neon AES_FLAG = -march=armv7-a -mfpu=neon
CRC_FLAG = -march=armv7-a -mfloat-abi=$(FP_ABI) -mfpu=neon CRC_FLAG = -march=armv7-a -mfpu=neon
GCM_FLAG = -march=armv7-a -mfloat-abi=$(FP_ABI) -mfpu=neon GCM_FLAG = -march=armv7-a -mfpu=neon
BLAKE2B_FLAG = -march=armv7-a -mfloat-abi=$(FP_ABI) -mfpu=neon BLAKE2B_FLAG = -march=armv7-a -mfpu=neon
BLAKE2S_FLAG = -march=armv7-a -mfloat-abi=$(FP_ABI) -mfpu=neon BLAKE2S_FLAG = -march=armv7-a -mfpu=neon
CHACHA_FLAG = -march=armv7-a -mfloat-abi=$(FP_ABI) -mfpu=neon CHACHA_FLAG = -march=armv7-a -mfpu=neon
CHAM_FLAG = -march=armv7-a -mfloat-abi=$(FP_ABI) -mfpu=neon CHAM_FLAG = -march=armv7-a -mfpu=neon
LEA_FLAG = -march=armv7-a -mfloat-abi=$(FP_ABI) -mfpu=neon LEA_FLAG = -march=armv7-a -mfpu=neon
SHA_FLAG = -march=armv7-a -mfloat-abi=$(FP_ABI) -mfpu=neon SHA_FLAG = -march=armv7-a -mfpu=neon
SIMECK_FLAG = -march=armv7-a -mfloat-abi=$(FP_ABI) -mfpu=neon SIMECK_FLAG = -march=armv7-a -mfpu=neon
SIMON64_FLAG = -march=armv7-a -mfloat-abi=$(FP_ABI) -mfpu=neon SIMON64_FLAG = -march=armv7-a -mfpu=neon
SIMON128_FLAG = -march=armv7-a -mfloat-abi=$(FP_ABI) -mfpu=neon SIMON128_FLAG = -march=armv7-a -mfpu=neon
SPECK64_FLAG = -march=armv7-a -mfloat-abi=$(FP_ABI) -mfpu=neon SPECK64_FLAG = -march=armv7-a -mfpu=neon
SPECK128_FLAG = -march=armv7-a -mfloat-abi=$(FP_ABI) -mfpu=neon SPECK128_FLAG = -march=armv7-a -mfpu=neon
SM4_FLAG = -march=armv7-a -mfloat-abi=$(FP_ABI) -mfpu=neon SM4_FLAG = -march=armv7-a -mfpu=neon
else else
CXXFLAGS += -DCRYPTOPP_DISABLE_ASM CXXFLAGS += -DCRYPTOPP_DISABLE_ASM
endif endif
# IS_NEON # IS_ARM32
endif endif
ifeq ($(IS_ARMV8),1) ifeq ($(IS_ARMV8),1)
@ -485,7 +490,7 @@ ifeq ($(IS_ARMV8),1)
TPROG = TestPrograms/test_arm_asimd.cxx TPROG = TestPrograms/test_arm_asimd.cxx
TOPT = -march=armv8-a TOPT = -march=armv8-a
HAVE_OPT = $(shell $(CXX) $(CXXFLAGS) $(ACLE_FLAG) $(ZOPT) $(TOPT) $(TPROG) -o $(TOUT) 2>&1 | tr ' ' '\n' | wc -l) HAVE_OPT = $(shell $(CXX) $(TCXXFLAGS) $(ACLE_FLAG) $(ZOPT) $(TOPT) $(TPROG) -o $(TOUT) 2>&1 | tr ' ' '\n' | wc -l)
ifeq ($(strip $(HAVE_OPT)),0) ifeq ($(strip $(HAVE_OPT)),0)
ASIMD_FLAG = -march=armv8-a ASIMD_FLAG = -march=armv8-a
ARIA_FLAG = -march=armv8-a ARIA_FLAG = -march=armv8-a
@ -508,7 +513,7 @@ ifeq ($(IS_ARMV8),1)
ifneq ($(ASIMD_FLAG),) ifneq ($(ASIMD_FLAG),)
TPROG = TestPrograms/test_arm_crc.cxx TPROG = TestPrograms/test_arm_crc.cxx
TOPT = -march=armv8-a+crc TOPT = -march=armv8-a+crc
HAVE_OPT = $(shell $(CXX) $(CXXFLAGS) $(ACLE_FLAG) $(ZOPT) $(TOPT) $(TPROG) -o $(TOUT) 2>&1 | tr ' ' '\n' | wc -l) HAVE_OPT = $(shell $(CXX) $(TCXXFLAGS) $(ACLE_FLAG) $(ZOPT) $(TOPT) $(TPROG) -o $(TOUT) 2>&1 | tr ' ' '\n' | wc -l)
ifeq ($(strip $(HAVE_OPT)),0) ifeq ($(strip $(HAVE_OPT)),0)
CRC_FLAG = -march=armv8-a+crc CRC_FLAG = -march=armv8-a+crc
else else
@ -517,7 +522,7 @@ ifeq ($(IS_ARMV8),1)
TPROG = TestPrograms/test_arm_aes.cxx TPROG = TestPrograms/test_arm_aes.cxx
TOPT = -march=armv8-a+crypto TOPT = -march=armv8-a+crypto
HAVE_OPT = $(shell $(CXX) $(CXXFLAGS) $(ACLE_FLAG) $(ZOPT) $(TOPT) $(TPROG) -o $(TOUT) 2>&1 | tr ' ' '\n' | wc -l) HAVE_OPT = $(shell $(CXX) $(TCXXFLAGS) $(ACLE_FLAG) $(ZOPT) $(TOPT) $(TPROG) -o $(TOUT) 2>&1 | tr ' ' '\n' | wc -l)
ifeq ($(strip $(HAVE_OPT)),0) ifeq ($(strip $(HAVE_OPT)),0)
AES_FLAG = -march=armv8-a+crypto AES_FLAG = -march=armv8-a+crypto
else else
@ -526,7 +531,7 @@ ifeq ($(IS_ARMV8),1)
TPROG = TestPrograms/test_arm_pmull.cxx TPROG = TestPrograms/test_arm_pmull.cxx
TOPT = -march=armv8-a+crypto TOPT = -march=armv8-a+crypto
HAVE_OPT = $(shell $(CXX) $(CXXFLAGS) $(ACLE_FLAG) $(ZOPT) $(TOPT) $(TPROG) -o $(TOUT) 2>&1 | tr ' ' '\n' | wc -l) HAVE_OPT = $(shell $(CXX) $(TCXXFLAGS) $(ACLE_FLAG) $(ZOPT) $(TOPT) $(TPROG) -o $(TOUT) 2>&1 | tr ' ' '\n' | wc -l)
ifeq ($(strip $(HAVE_OPT)),0) ifeq ($(strip $(HAVE_OPT)),0)
GCM_FLAG = -march=armv8-a+crypto GCM_FLAG = -march=armv8-a+crypto
GF2N_FLAG = -march=armv8-a+crypto GF2N_FLAG = -march=armv8-a+crypto
@ -534,9 +539,9 @@ ifeq ($(IS_ARMV8),1)
CXXFLAGS += -DCRYPTOPP_ARM_PMULL_AVAILABLE=0 CXXFLAGS += -DCRYPTOPP_ARM_PMULL_AVAILABLE=0
endif endif
TPROG = TestPrograms/test_arm_sha.cxx TPROG = TestPrograms/test_arm_sha1.cxx
TOPT = -march=armv8-a+crypto TOPT = -march=armv8-a+crypto
HAVE_OPT = $(shell $(CXX) $(CXXFLAGS) $(ACLE_FLAG) $(ZOPT) $(TOPT) $(TPROG) -o $(TOUT) 2>&1 | tr ' ' '\n' | wc -l) HAVE_OPT = $(shell $(CXX) $(TCXXFLAGS) $(ACLE_FLAG) $(ZOPT) $(TOPT) $(TPROG) -o $(TOUT) 2>&1 | tr ' ' '\n' | wc -l)
ifeq ($(strip $(HAVE_OPT)),0) ifeq ($(strip $(HAVE_OPT)),0)
SHA_FLAG = -march=armv8-a+crypto SHA_FLAG = -march=armv8-a+crypto
else else
@ -545,7 +550,7 @@ ifeq ($(IS_ARMV8),1)
TPROG = TestPrograms/test_arm_sm3.cxx TPROG = TestPrograms/test_arm_sm3.cxx
TOPT = -march=armv8.4-a+crypto TOPT = -march=armv8.4-a+crypto
HAVE_OPT = $(shell $(CXX) $(CXXFLAGS) $(ACLE_FLAG) $(ZOPT) $(TOPT) $(TPROG) -o $(TOUT) 2>&1 | tr ' ' '\n' | wc -l) HAVE_OPT = $(shell $(CXX) $(TCXXFLAGS) $(ACLE_FLAG) $(ZOPT) $(TOPT) $(TPROG) -o $(TOUT) 2>&1 | tr ' ' '\n' | wc -l)
ifeq ($(strip $(HAVE_OPT)),0) ifeq ($(strip $(HAVE_OPT)),0)
SM3_FLAG = -march=armv8.4-a+crypto SM3_FLAG = -march=armv8.4-a+crypto
SM4_FLAG = -march=armv8.4-a+crypto SM4_FLAG = -march=armv8.4-a+crypto
@ -553,7 +558,7 @@ ifeq ($(IS_ARMV8),1)
TPROG = TestPrograms/test_arm_sha3.cxx TPROG = TestPrograms/test_arm_sha3.cxx
TOPT = -march=armv8.4-a+crypto TOPT = -march=armv8.4-a+crypto
HAVE_OPT = $(shell $(CXX) $(CXXFLAGS) $(ACLE_FLAG) $(ZOPT) $(TOPT) $(TPROG) -o $(TOUT) 2>&1 | tr ' ' '\n' | wc -l) HAVE_OPT = $(shell $(CXX) $(TCXXFLAGS) $(ACLE_FLAG) $(ZOPT) $(TOPT) $(TPROG) -o $(TOUT) 2>&1 | tr ' ' '\n' | wc -l)
ifeq ($(strip $(HAVE_OPT)),0) ifeq ($(strip $(HAVE_OPT)),0)
SHA3_FLAG = -march=armv8.4-a+crypto SHA3_FLAG = -march=armv8.4-a+crypto
endif endif
@ -567,7 +572,7 @@ endif
# DETECT_FEATURES # DETECT_FEATURES
endif endif
# IS_ARM32, IS_ARMV8, IS_NEON # IS_ARM32, IS_ARMV8
endif endif
########################################################### ###########################################################
@ -622,13 +627,21 @@ ifeq ($(DETECT_FEATURES),1)
TOPT = $(POWER8_FLAG) TOPT = $(POWER8_FLAG)
HAVE_OPT = $(shell $(CXX) $(TCXXFLAGS) $(ZOPT) $(TOPT) $(TPROG) -o $(TOUT) 2>&1 | tr ' ' '\n' | wc -l) HAVE_OPT = $(shell $(CXX) $(TCXXFLAGS) $(ZOPT) $(TOPT) $(TPROG) -o $(TOUT) 2>&1 | tr ' ' '\n' | wc -l)
ifeq ($(strip $(HAVE_OPT)),0) ifeq ($(strip $(HAVE_OPT)),0)
AES_FLAG = $(POWER8_FLAG)
ARIA_FLAG = $(POWER8_FLAG)
BLAKE2B_FLAG = $(POWER8_FLAG) BLAKE2B_FLAG = $(POWER8_FLAG)
BLAKE2S_FLAG = $(POWER8_FLAG)
CHACHA_FLAG = $(POWER8_FLAG)
CHAM_FLAG = $(POWER8_FLAG)
CRC_FLAG = $(POWER8_FLAG) CRC_FLAG = $(POWER8_FLAG)
GCM_FLAG = $(POWER8_FLAG) GCM_FLAG = $(POWER8_FLAG)
GF2N_FLAG = $(POWER8_FLAG) GF2N_FLAG = $(POWER8_FLAG)
AES_FLAG = $(POWER8_FLAG) LEA_FLAG = $(POWER8_FLAG)
SHA_FLAG = $(POWER8_FLAG) SHA_FLAG = $(POWER8_FLAG)
SHACAL2_FLAG = $(POWER8_FLAG) SHACAL2_FLAG = $(POWER8_FLAG)
SIMECK_FLAG = $(POWER8_FLAG)
SIMON64_FLAG = $(POWER8_FLAG)
SPECK64_FLAG = $(POWER8_FLAG)
SIMON128_FLAG = $(POWER8_FLAG) SIMON128_FLAG = $(POWER8_FLAG)
SPECK128_FLAG = $(POWER8_FLAG) SPECK128_FLAG = $(POWER8_FLAG)
else else
@ -641,16 +654,7 @@ ifeq ($(DETECT_FEATURES),1)
TPROG = TestPrograms/test_ppc_power7.cxx TPROG = TestPrograms/test_ppc_power7.cxx
TOPT = $(POWER7_FLAG) TOPT = $(POWER7_FLAG)
HAVE_OPT = $(shell $(CXX) $(TCXXFLAGS) $(ZOPT) $(TOPT) $(TPROG) -o $(TOUT) 2>&1 | tr ' ' '\n' | wc -l) HAVE_OPT = $(shell $(CXX) $(TCXXFLAGS) $(ZOPT) $(TOPT) $(TPROG) -o $(TOUT) 2>&1 | tr ' ' '\n' | wc -l)
ifeq ($(strip $(HAVE_OPT)),0) ifneq ($(strip $(HAVE_OPT)),0)
ARIA_FLAG = $(POWER7_FLAG)
BLAKE2S_FLAG = $(POWER7_FLAG)
CHACHA_FLAG = $(POWER7_FLAG)
CHAM_FLAG = $(POWER7_FLAG)
LEA_FLAG = $(POWER7_FLAG)
SIMECK_FLAG = $(POWER7_FLAG)
SIMON64_FLAG = $(POWER7_FLAG)
SPECK64_FLAG = $(POWER7_FLAG)
else
POWER7_FLAG = POWER7_FLAG =
endif endif
@ -693,18 +697,12 @@ ifeq ($(DETECT_FEATURES),1)
##################################################################### #####################################################################
# Fixups for algorithms that can drop to a lower ISA, if needed # Fixups for algorithms that can drop to a lower ISA, if needed
# Drop to Power7 if Power8 is not available. # Drop to Power4 if Power8 not available
ifeq ($(POWER8_FLAG),) ifeq ($(POWER8_FLAG),)
ifneq ($(POWER7_FLAG),)
GCM_FLAG = $(POWER7_FLAG)
endif
endif
# Drop to Power4 if Power7 not available
ifeq ($(POWER7_FLAG),)
ifneq ($(ALTIVEC_FLAG),) ifneq ($(ALTIVEC_FLAG),)
BLAKE2S_FLAG = $(ALTIVEC_FLAG) BLAKE2S_FLAG = $(ALTIVEC_FLAG)
CHACHA_FLAG = $(ALTIVEC_FLAG) CHACHA_FLAG = $(ALTIVEC_FLAG)
GCM_FLAG = $(ALTIVEC_FLAG)
SIMON64_FLAG = $(ALTIVEC_FLAG) SIMON64_FLAG = $(ALTIVEC_FLAG)
SPECK64_FLAG = $(ALTIVEC_FLAG) SPECK64_FLAG = $(ALTIVEC_FLAG)
endif endif
@ -869,6 +867,15 @@ ifeq ($(findstring native,$(MAKECMDGOALS)),native)
NATIVE_OPT = -march=native NATIVE_OPT = -march=native
endif # NATIVE_OPT endif # NATIVE_OPT
# And tune
ifeq ($(NATIVE_OPT),)
TOPT = -mtune=native
HAVE_OPT = $(shell $(CXX) $(TCXXFLAGS) $(ZOPT) $(TOPT) $(TPROG) -o $(TOUT) 2>&1 | tr ' ' '\n' | wc -l)
ifeq ($(strip $(HAVE_OPT)),0)
NATIVE_OPT = -mtune=native
endif # NATIVE_OPT
endif
# Try SunCC next # Try SunCC next
ifeq ($(NATIVE_OPT),) ifeq ($(NATIVE_OPT),)
TOPT = -native TOPT = -native
@ -956,9 +963,9 @@ ifneq ($(filter valgrind,$(MAKECMDGOALS)),)
CXXFLAGS := $(CXXFLAGS:-g%=-g3) CXXFLAGS := $(CXXFLAGS:-g%=-g3)
CXXFLAGS := $(CXXFLAGS:-O%=-O1) CXXFLAGS := $(CXXFLAGS:-O%=-O1)
CXXFLAGS := $(CXXFLAGS:-xO%=-xO1) CXXFLAGS := $(CXXFLAGS:-xO%=-xO1)
ifeq ($(findstring -DCRYPTOPP_VALGRIND,$(CXXFLAGS)),) ifeq ($(findstring -DCRYPTOPP_COVERAGE,$(CXXFLAGS)),)
CXXFLAGS += -DCRYPTOPP_VALGRIND CXXFLAGS += -DCRYPTOPP_COVERAGE
endif # -DCRYPTOPP_VALGRIND endif # -DCRYPTOPP_COVERAGE
endif # Valgrind endif # Valgrind
# Debug testing on GNU systems. Triggered by -DDEBUG. # Debug testing on GNU systems. Triggered by -DDEBUG.
@ -1004,7 +1011,7 @@ ifeq ($(findstring lean,$(MAKECMDGOALS)),lean)
endif # Dead code stripping endif # Dead code stripping
# For Shared Objects, Diff, Dist/Zip rules # For Shared Objects, Diff, Dist/Zip rules
LIB_VER := $(shell $(GREP) "define CRYPTOPP_VERSION" config.h | cut -d" " -f 3) LIB_VER := $(shell $(GREP) "define CRYPTOPP_VERSION" config_ver.h | cut -d" " -f 3)
LIB_MAJOR := $(shell echo $(LIB_VER) | cut -c 1) LIB_MAJOR := $(shell echo $(LIB_VER) | cut -c 1)
LIB_MINOR := $(shell echo $(LIB_VER) | cut -c 2) LIB_MINOR := $(shell echo $(LIB_VER) | cut -c 2)
LIB_PATCH := $(shell echo $(LIB_VER) | cut -c 3) LIB_PATCH := $(shell echo $(LIB_VER) | cut -c 3)
@ -1061,12 +1068,18 @@ ifneq ($(IS_MINGW),0)
INCL += resource.h INCL += resource.h
endif endif
# Cryptogams AES for ARMv4 and above. We couple to ARMv7. # Cryptogams source files. We couple to ARMv7.
# Avoid iOS. It cannot consume the assembly. # Limit to Linux. The source files target the GNU assembler.
ifeq ($(IS_ARM32),1) # Also see https://www.cryptopp.com/wiki/Cryptogams.
CRYPTOGAMS_AES_FLAG = -march=armv7-a ifeq ($(IS_ARM32)$(IS_LINUX),11)
CRYPTOGAMS_AES_FLAG += -Wa,--noexecstack ifeq ($(CLANG_COMPILER),1)
SRCS += aes_armv4.S CRYPTOGAMS_ARMV7_FLAG = -march=armv7-a -Wa,--noexecstack
CRYPTOGAMS_ARMV7_THUMB_FLAG = -march=armv7-a -mthumb -Wa,--noexecstack
else
CRYPTOGAMS_ARMV7_FLAG = -march=armv7-a -Wa,--noexecstack
CRYPTOGAMS_ARMV7_THUMB_FLAG = -march=armv7-a -Wa,--noexecstack
endif
SRCS += aes_armv4.S sha1_armv4.S sha256_armv4.S sha512_armv4.S
endif endif
# List cryptlib.cpp first, then cpu.cpp, then integer.cpp to tame C++ static initialization problems. # List cryptlib.cpp first, then cpu.cpp, then integer.cpp to tame C++ static initialization problems.
@ -1281,10 +1294,14 @@ remove uninstall:
-$(RM) -r $(DESTDIR)$(INCLUDEDIR)/cryptopp -$(RM) -r $(DESTDIR)$(INCLUDEDIR)/cryptopp
-$(RM) $(DESTDIR)$(LIBDIR)/libcryptopp.a -$(RM) $(DESTDIR)$(LIBDIR)/libcryptopp.a
-$(RM) $(DESTDIR)$(BINDIR)/cryptest.exe -$(RM) $(DESTDIR)$(BINDIR)/cryptest.exe
@-$(RM) $(DESTDIR)$(LIBDIR)/libcryptopp.dylib ifneq ($(wildcard $(DESTDIR)$(LIBDIR)/libcryptopp.dylib),)
-$(RM) $(DESTDIR)$(LIBDIR)/libcryptopp.dylib
endif
ifneq ($(wildcard $(DESTDIR)$(LIBDIR)/libcryptopp.so),)
-$(RM) $(DESTDIR)$(LIBDIR)/libcryptopp.so
endif
@-$(RM) $(DESTDIR)$(LIBDIR)/libcryptopp.so$(SOLIB_VERSION_SUFFIX) @-$(RM) $(DESTDIR)$(LIBDIR)/libcryptopp.so$(SOLIB_VERSION_SUFFIX)
@-$(RM) $(DESTDIR)$(LIBDIR)/libcryptopp.so$(SOLIB_COMPAT_SUFFIX) @-$(RM) $(DESTDIR)$(LIBDIR)/libcryptopp.so$(SOLIB_COMPAT_SUFFIX)
@-$(RM) $(DESTDIR)$(LIBDIR)/libcryptopp.so
@-$(RM) $(DESTDIR)$(LIBDIR)/pkgconfig/libcryptopp.pc @-$(RM) $(DESTDIR)$(LIBDIR)/pkgconfig/libcryptopp.pc
@-$(RM) -r $(DESTDIR)$(DATADIR)/cryptopp @-$(RM) -r $(DESTDIR)$(DATADIR)/cryptopp
@ -1313,8 +1330,8 @@ endif
libcryptopp.dylib: $(LIBOBJS) libcryptopp.dylib: $(LIBOBJS)
$(CXX) -dynamiclib -o $@ $(strip $(CXXFLAGS)) -install_name "$@" -current_version "$(LIB_MAJOR).$(LIB_MINOR).$(LIB_PATCH)" -compatibility_version "$(LIB_MAJOR).$(LIB_MINOR)" -headerpad_max_install_names $(LDFLAGS) $(LIBOBJS) $(CXX) -dynamiclib -o $@ $(strip $(CXXFLAGS)) -install_name "$@" -current_version "$(LIB_MAJOR).$(LIB_MINOR).$(LIB_PATCH)" -compatibility_version "$(LIB_MAJOR).$(LIB_MINOR)" -headerpad_max_install_names $(LDFLAGS) $(LIBOBJS)
cryptest.exe:libcryptopp.a $(TESTOBJS) cryptest.exe: $(LINK_LIBRARY) $(TESTOBJS)
$(CXX) -o $@ $(strip $(CXXFLAGS)) $(TESTOBJS) ./libcryptopp.a $(LDFLAGS) $(LDLIBS) $(CXX) -o $@ $(strip $(CXXFLAGS)) $(TESTOBJS) $(LINK_LIBRARY_PATH)$(LINK_LIBRARY) $(LDFLAGS) $(LDLIBS)
# Makes it faster to test changes # Makes it faster to test changes
nolib: $(OBJS) nolib: $(OBJS)
@ -1349,7 +1366,7 @@ libcryptopp.pc:
@echo '' >> libcryptopp.pc @echo '' >> libcryptopp.pc
@echo 'Name: Crypto++' >> libcryptopp.pc @echo 'Name: Crypto++' >> libcryptopp.pc
@echo 'Description: Crypto++ cryptographic library' >> libcryptopp.pc @echo 'Description: Crypto++ cryptographic library' >> libcryptopp.pc
@echo 'Version: 8.1' >> libcryptopp.pc @echo 'Version: 8.3' >> libcryptopp.pc
@echo 'URL: https://cryptopp.com/' >> libcryptopp.pc @echo 'URL: https://cryptopp.com/' >> libcryptopp.pc
@echo '' >> libcryptopp.pc @echo '' >> libcryptopp.pc
@echo 'Cflags: -I$${includedir}' >> libcryptopp.pc @echo 'Cflags: -I$${includedir}' >> libcryptopp.pc
@ -1366,14 +1383,14 @@ endif
.PHONY: trim .PHONY: trim
trim: trim:
ifneq ($(IS_DARWIN),0) ifneq ($(IS_DARWIN),0)
sed -i '' -e's/[[:space:]]*$$//' *.supp *.txt *.sh .*.yml *.h *.cpp *.asm *.s *.S $(SED) -i '' -e's/[[:space:]]*$$//' *.supp *.txt *.sh .*.yml *.h *.cpp *.asm *.s *.S
sed -i '' -e's/[[:space:]]*$$//' *.sln *.vcxproj *.filters GNUmakefile GNUmakefile-cross $(SED) -i '' -e's/[[:space:]]*$$//' *.sln *.vcxproj *.filters GNUmakefile GNUmakefile-cross
sed -i '' -e's/[[:space:]]*$$//' TestData/*.dat TestVectors/*.txt TestPrograms/*.cxx TestScripts/*.* $(SED) -i '' -e's/[[:space:]]*$$//' TestData/*.dat TestVectors/*.txt TestPrograms/*.cxx TestScripts/*.*
make convert make convert
else else
sed -i -e's/[[:space:]]*$$//' *.supp *.txt *.sh .*.yml *.h *.cpp *.asm *.s *.S $(SED) -i -e's/[[:space:]]*$$//' *.supp *.txt *.sh .*.yml *.h *.cpp *.asm *.s *.S
sed -i -e's/[[:space:]]*$$//' *.sln *.vcxproj *.filters GNUmakefile GNUmakefile-cross $(SED) -i -e's/[[:space:]]*$$//' *.sln *.vcxproj *.filters GNUmakefile GNUmakefile-cross
sed -i -e's/[[:space:]]*$$//' TestData/*.dat TestVectors/*.txt TestPrograms/*.cxx TestScripts/*.* $(SED) -i -e's/[[:space:]]*$$//' TestData/*.dat TestVectors/*.txt TestPrograms/*.cxx TestScripts/*.*
make convert make convert
endif endif
@ -1428,9 +1445,9 @@ ifeq ($(wildcard GNUmakefile.deps),GNUmakefile.deps)
-include GNUmakefile.deps -include GNUmakefile.deps
endif # Dependencies endif # Dependencies
# Cryptogams ARM asm implementation. # Cryptogams ARM asm implementation. AES needs -mthumb for Clang
aes_armv4.o : aes_armv4.S aes_armv4.o : aes_armv4.S
$(CC) $(strip $(CXXFLAGS) $(CRYPTOGAMS_AES_FLAG) -mfloat-abi=$(FP_ABI) -c) $< $(CXX) $(strip $(CXXFLAGS) $(CRYPTOGAMS_ARMV7_THUMB_FLAG) -c) $<
# SSSE3 or NEON available # SSSE3 or NEON available
aria_simd.o : aria_simd.cpp aria_simd.o : aria_simd.cpp
@ -1512,6 +1529,18 @@ rijndael_simd.o : rijndael_simd.cpp
sha_simd.o : sha_simd.cpp sha_simd.o : sha_simd.cpp
$(CXX) $(strip $(CXXFLAGS) $(SHA_FLAG) -c) $< $(CXX) $(strip $(CXXFLAGS) $(SHA_FLAG) -c) $<
# Cryptogams SHA1 asm implementation.
sha1_armv4.o : sha1_armv4.S
$(CXX) $(strip $(CXXFLAGS) $(CRYPTOGAMS_ARMV7_FLAG) -c) $<
# Cryptogams SHA256 asm implementation.
sha256_armv4.o : sha256_armv4.S
$(CXX) $(strip $(CXXFLAGS) $(CRYPTOGAMS_ARMV7_FLAG) -c) $<
# Cryptogams SHA512 asm implementation.
sha512_armv4.o : sha512_armv4.S
$(CXX) $(strip $(CXXFLAGS) $(CRYPTOGAMS_ARMV7_FLAG) -c) $<
sha3_simd.o : sha3_simd.cpp sha3_simd.o : sha3_simd.cpp
$(CXX) $(strip $(CXXFLAGS) $(SHA3_FLAG) -c) $< $(CXX) $(strip $(CXXFLAGS) $(SHA3_FLAG) -c) $<

View File

@ -11,6 +11,12 @@ FP_ABI ?= hard
TOUT ?= a.out TOUT ?= a.out
TOUT := $(strip $(TOUT)) TOUT := $(strip $(TOUT))
# Allow override for the cryptest.exe recipe. Change to
# ./libcryptopp.so or ./libcryptopp.dylib to suit your
# taste. https://github.com/weidai11/cryptopp/issues/866
LINK_LIBRARY ?= ./libcryptopp.a
LINK_LIBRARY_PATH ?= ./
# Default CXXFLAGS if none were provided # Default CXXFLAGS if none were provided
CXXFLAGS ?= -DNDEBUG -g2 -O3 -fPIC -pipe CXXFLAGS ?= -DNDEBUG -g2 -O3 -fPIC -pipe
@ -21,7 +27,8 @@ CP ?= cp
MV ?= mv MV ?= mv
CHMOD ?= chmod CHMOD ?= chmod
MKDIR ?= mkdir -p MKDIR ?= mkdir -p
EGREP ?= egrep GREP ?= grep
SED ?= sed
LN ?= ln -sf LN ?= ln -sf
LDCONF ?= /sbin/ldconfig -n LDCONF ?= /sbin/ldconfig -n
@ -31,6 +38,19 @@ IS_ANDROID ?= 0
IS_ARM_EMBEDDED ?= 0 IS_ARM_EMBEDDED ?= 0
IS_NEON ?= 0 IS_NEON ?= 0
# Yet another Clang hack. I think the LLVM devs are making the shit up
# as they go. Also see https://github.com/weidai11/cryptopp/issues/831.
MACHINEX := $(shell $(CXX) $(CXXFLAGS) -dumpmachine 2>/dev/null)
ifeq ($(MACHINEX),armv8l-unknown-linux-gnueabihf)
MACHINEX := armv7l-unknown-linux-gnueabihf
endif
HOSTX := $(shell echo $(MACHINEX) | cut -f 1 -d '-')
ifeq ($(HOSTX),)
HOSTX := $(shell uname -m 2>/dev/null)
endif
IS_LINUX := $(shell echo $(MACHINEX) | $(GREP) -i -c "Linux")
# Can be used by Android and Embeeded cross-compiles. Disable by default because # Can be used by Android and Embeeded cross-compiles. Disable by default because
# Android and embedded users typically don't run this configuration. # Android and embedded users typically don't run this configuration.
HAS_SOLIB_VERSION ?= 0 HAS_SOLIB_VERSION ?= 0
@ -136,8 +156,8 @@ endif
# Wait until CXXFLAGS have been set by setenv scripts. # Wait until CXXFLAGS have been set by setenv scripts.
GCC_COMPILER := $(shell $(CXX) --version 2>/dev/null | $(EGREP) -v -E 'llvm|clang' | $(EGREP) -i -c -E '(gcc|g\+\+)') GCC_COMPILER := $(shell $(CXX) --version 2>/dev/null | $(GREP) -v -E 'llvm|clang' | $(GREP) -i -c -E '(gcc|g\+\+)')
CLANG_COMPILER := $(shell $(CXX) --version 2>/dev/null | $(EGREP) -i -c -E 'llvm|clang') CLANG_COMPILER := $(shell $(CXX) --version 2>/dev/null | $(GREP) -i -c -E 'llvm|clang')
HOSTX := $(shell $(CXX) $(CXXFLAGS) -dumpmachine 2>/dev/null | cut -f 1 -d '-') HOSTX := $(shell $(CXX) $(CXXFLAGS) -dumpmachine 2>/dev/null | cut -f 1 -d '-')
ifeq ($(HOSTX),) ifeq ($(HOSTX),)
@ -149,15 +169,15 @@ endif
# -arch arm64 yields x86_64 instead of aarch64 or arm64. # -arch arm64 yields x86_64 instead of aarch64 or arm64.
ifeq ($(CLANG_COMPILER),1) ifeq ($(CLANG_COMPILER),1)
IS_X86 := $(shell echo $(CXXFLAGS) | $(EGREP) -v 64 | $(EGREP) -i -c -E 'i.86') IS_X86 := $(shell echo $(CXXFLAGS) | $(GREP) -v 64 | $(GREP) -i -c -E 'i.86')
IS_X64 := $(shell echo $(CXXFLAGS) | $(EGREP) -i -c -E 'x86_64|amd64') IS_X64 := $(shell echo $(CXXFLAGS) | $(GREP) -i -c -E 'x86_64|amd64')
IS_ARM32 := $(shell echo $(CXXFLAGS) | $(EGREP) -v 64 | $(EGREP) -i -c -E 'arm|armhf|arm7l|eabihf') IS_ARM32 := $(shell echo $(CXXFLAGS) | $(GREP) -v 64 | $(GREP) -i -c -E 'arm|armhf|arm7l|eabihf')
IS_ARMV8 := $(shell echo $(CXXFLAGS) | $(EGREP) -i -c -E 'aarch32|aarch64|arm64|armv8') IS_ARMV8 := $(shell echo $(CXXFLAGS) | $(GREP) -i -c -E 'aarch32|aarch64|arm64|armv8')
else else
IS_X86 := $(shell echo $(HOSTX) | $(EGREP) -v 64 | $(EGREP) -i -c -E 'i.86') IS_X86 := $(shell echo $(HOSTX) | $(GREP) -v 64 | $(GREP) -i -c -E 'i.86')
IS_X64 := $(shell echo $(HOSTX) | $(EGREP) -i -c -E 'x86_64|amd64') IS_X64 := $(shell echo $(HOSTX) | $(GREP) -i -c -E 'x86_64|amd64')
IS_ARM32 := $(shell echo $(HOSTX) | $(EGREP) -v 64 | $(EGREP) -i -c -E 'arm|armhf|arm7l|eabihf') IS_ARM32 := $(shell echo $(HOSTX) | $(GREP) -v 64 | $(GREP) -i -c -E 'arm|armhf|arm7l|eabihf')
IS_ARMV8 := $(shell echo $(HOSTX) | $(EGREP) -i -c -E 'aarch32|aarch64|arm64|armv8') IS_ARMV8 := $(shell echo $(HOSTX) | $(GREP) -i -c -E 'aarch32|aarch64|arm64|armv8')
endif endif
$(info Here's what we found... IS_X86: $(IS_X86), IS_X64: $(IS_X64), IS_ARM32: $(IS_ARM32), IS_ARMV8: $(IS_ARMV8)) $(info Here's what we found... IS_X86: $(IS_X86), IS_X64: $(IS_X64), IS_ARM32: $(IS_ARM32), IS_ARMV8: $(IS_ARMV8))
@ -178,9 +198,10 @@ else ifeq ($(findstring distclean,$(MAKECMDGOALS)),trim)
DETECT_FEATURES := 0 DETECT_FEATURES := 0
endif endif
# Strip out -Wall, -Wextra and friends for feature testing # Strip out -Wall, -Wextra and friends for feature testing. FORTIFY_SOURCE is removed
# because it requires -O1 or higher, but we use -O0 to tame the optimizer.
ifeq ($(DETECT_FEATURES),1) ifeq ($(DETECT_FEATURES),1)
TCXXFLAGS := $(filter-out -Wall -Wextra -Werror% -Wunused -Wconversion -Wp%, $(CXXFLAGS)) TCXXFLAGS := $(filter-out -D_FORTIFY_SOURCE=% -Wall -Wextra -Werror% -Wunused -Wconversion -Wp%, $(CXXFLAGS))
ifneq ($(strip $(TCXXFLAGS)),) ifneq ($(strip $(TCXXFLAGS)),)
$(info Using testing flags: $(TCXXFLAGS)) $(info Using testing flags: $(TCXXFLAGS))
endif endif
@ -227,9 +248,7 @@ ifeq ($(DETECT_FEATURES),1)
CHAM_FLAG = $(SSSE3_FLAG) CHAM_FLAG = $(SSSE3_FLAG)
LEA_FLAG = $(SSSE3_FLAG) LEA_FLAG = $(SSSE3_FLAG)
SIMECK_FLAG = $(SSSE3_FLAG) SIMECK_FLAG = $(SSSE3_FLAG)
SIMON64_FLAG = $(SSSE3_FLAG)
SIMON128_FLAG = $(SSSE3_FLAG) SIMON128_FLAG = $(SSSE3_FLAG)
SPECK64_FLAG = $(SSSE3_FLAG)
SPECK128_FLAG = $(SSSE3_FLAG) SPECK128_FLAG = $(SSSE3_FLAG)
else else
SSSE3_FLAG = SSSE3_FLAG =
@ -384,10 +403,10 @@ ifeq ($(IS_ARM32),1)
SM4_FLAG = $(NEON_FLAG) SM4_FLAG = $(NEON_FLAG)
else else
NEON_FLAG = NEON_FLAG =
CXXFLAGS += -DCRYPTOPP_DISABLE_NEON CXXFLAGS += -DCRYPTOPP_DISABLE_ASM
endif endif
# IS_NEON # IS_ARM32
endif endif
ifeq ($(IS_ARMV8),1) ifeq ($(IS_ARMV8),1)
@ -417,7 +436,7 @@ ifeq ($(IS_ARMV8),1)
TPROG = TestPrograms/test_arm_asimd.cxx TPROG = TestPrograms/test_arm_asimd.cxx
TOPT = $(ASIMD_FLAG) TOPT = $(ASIMD_FLAG)
HAVE_OPT = $(shell $(CXX) $(CXXFLAGS) $(ACLE_FLAG) $(ZOPT) $(TOPT) $(TPROG) -o $(TOUT) 2>&1 | tr ' ' '\n' | wc -l) HAVE_OPT = $(shell $(CXX) $(TCXXFLAGS) $(ACLE_FLAG) $(ZOPT) $(TOPT) $(TPROG) -o $(TOUT) 2>&1 | tr ' ' '\n' | wc -l)
ifeq ($(strip $(HAVE_OPT)),0) ifeq ($(strip $(HAVE_OPT)),0)
ARIA_FLAG = $(ASIMD_FLAG) ARIA_FLAG = $(ASIMD_FLAG)
BLAKE2B_FLAG = $(ASIMD_FLAG) BLAKE2B_FLAG = $(ASIMD_FLAG)
@ -439,7 +458,7 @@ ifeq ($(IS_ARMV8),1)
TPROG = TestPrograms/test_arm_crc.cxx TPROG = TestPrograms/test_arm_crc.cxx
TOPT = $(CRC_FLAG) TOPT = $(CRC_FLAG)
HAVE_OPT = $(shell $(CXX) $(CXXFLAGS) $(ACLE_FLAG) $(ZOPT) $(TOPT) $(TPROG) -o $(TOUT) 2>&1 | tr ' ' '\n' | wc -l) HAVE_OPT = $(shell $(CXX) $(TCXXFLAGS) $(ACLE_FLAG) $(ZOPT) $(TOPT) $(TPROG) -o $(TOUT) 2>&1 | tr ' ' '\n' | wc -l)
ifneq ($(strip $(HAVE_OPT)),0) ifneq ($(strip $(HAVE_OPT)),0)
CRC_FLAG = CRC_FLAG =
CXXFLAGS += -DCRYPTOPP_ARM_CRC32_AVAILABLE=0 CXXFLAGS += -DCRYPTOPP_ARM_CRC32_AVAILABLE=0
@ -447,7 +466,7 @@ ifeq ($(IS_ARMV8),1)
TPROG = TestPrograms/test_arm_aes.cxx TPROG = TestPrograms/test_arm_aes.cxx
TOPT = $(AES_FLAG) TOPT = $(AES_FLAG)
HAVE_OPT = $(shell $(CXX) $(CXXFLAGS) $(ACLE_FLAG) $(ZOPT) $(TOPT) $(TPROG) -o $(TOUT) 2>&1 | tr ' ' '\n' | wc -l) HAVE_OPT = $(shell $(CXX) $(TCXXFLAGS) $(ACLE_FLAG) $(ZOPT) $(TOPT) $(TPROG) -o $(TOUT) 2>&1 | tr ' ' '\n' | wc -l)
ifneq ($(strip $(HAVE_OPT)),0) ifneq ($(strip $(HAVE_OPT)),0)
AES_FLAG = AES_FLAG =
CXXFLAGS += -DCRYPTOPP_ARM_AES_AVAILABLE=0 CXXFLAGS += -DCRYPTOPP_ARM_AES_AVAILABLE=0
@ -455,15 +474,15 @@ ifeq ($(IS_ARMV8),1)
TPROG = TestPrograms/test_arm_pmull.cxx TPROG = TestPrograms/test_arm_pmull.cxx
TOPT = $(PMULL_FLAG) TOPT = $(PMULL_FLAG)
HAVE_OPT = $(shell $(CXX) $(CXXFLAGS) $(ACLE_FLAG) $(ZOPT) $(TOPT) $(TPROG) -o $(TOUT) 2>&1 | tr ' ' '\n' | wc -l) HAVE_OPT = $(shell $(CXX) $(TCXXFLAGS) $(ACLE_FLAG) $(ZOPT) $(TOPT) $(TPROG) -o $(TOUT) 2>&1 | tr ' ' '\n' | wc -l)
ifneq ($(strip $(HAVE_OPT)),0) ifneq ($(strip $(HAVE_OPT)),0)
PMULL_FLAG = PMULL_FLAG =
CXXFLAGS += -DCRYPTOPP_ARM_PMULL_AVAILABLE=0 CXXFLAGS += -DCRYPTOPP_ARM_PMULL_AVAILABLE=0
endif endif
TPROG = TestPrograms/test_arm_sha.cxx TPROG = TestPrograms/test_arm_sha1.cxx
TOPT = $(SHA_FLAG) TOPT = $(SHA_FLAG)
HAVE_OPT = $(shell $(CXX) $(CXXFLAGS) $(ACLE_FLAG) $(ZOPT) $(TOPT) $(TPROG) -o $(TOUT) 2>&1 | tr ' ' '\n' | wc -l) HAVE_OPT = $(shell $(CXX) $(TCXXFLAGS) $(ACLE_FLAG) $(ZOPT) $(TOPT) $(TPROG) -o $(TOUT) 2>&1 | tr ' ' '\n' | wc -l)
ifneq ($(strip $(HAVE_OPT)),0) ifneq ($(strip $(HAVE_OPT)),0)
SHA_FLAG = SHA_FLAG =
CXXFLAGS += -DCRYPTOPP_ARM_SHA_AVAILABLE=0 CXXFLAGS += -DCRYPTOPP_ARM_SHA_AVAILABLE=0
@ -471,7 +490,7 @@ ifeq ($(IS_ARMV8),1)
TPROG = TestPrograms/test_arm_sm3.cxx TPROG = TestPrograms/test_arm_sm3.cxx
TOPT = -march=armv8.4-a+crypto TOPT = -march=armv8.4-a+crypto
HAVE_OPT = $(shell $(CXX) $(CXXFLAGS) $(ACLE_FLAG) $(ZOPT) $(TOPT) $(TPROG) -o $(TOUT) 2>&1 | tr ' ' '\n' | wc -l) HAVE_OPT = $(shell $(CXX) $(TCXXFLAGS) $(ACLE_FLAG) $(ZOPT) $(TOPT) $(TPROG) -o $(TOUT) 2>&1 | tr ' ' '\n' | wc -l)
ifeq ($(strip $(HAVE_OPT)),0) ifeq ($(strip $(HAVE_OPT)),0)
SM3_FLAG = -march=armv8.4-a+crypto SM3_FLAG = -march=armv8.4-a+crypto
SM4_FLAG = -march=armv8.4-a+crypto SM4_FLAG = -march=armv8.4-a+crypto
@ -479,7 +498,7 @@ ifeq ($(IS_ARMV8),1)
TPROG = TestPrograms/test_arm_sha3.cxx TPROG = TestPrograms/test_arm_sha3.cxx
TOPT = -march=armv8.4-a+crypto TOPT = -march=armv8.4-a+crypto
HAVE_OPT = $(shell $(CXX) $(CXXFLAGS) $(ACLE_FLAG) $(ZOPT) $(TOPT) $(TPROG) -o $(TOUT) 2>&1 | tr ' ' '\n' | wc -l) HAVE_OPT = $(shell $(CXX) $(TCXXFLAGS) $(ACLE_FLAG) $(ZOPT) $(TOPT) $(TPROG) -o $(TOUT) 2>&1 | tr ' ' '\n' | wc -l)
ifeq ($(strip $(HAVE_OPT)),0) ifeq ($(strip $(HAVE_OPT)),0)
SHA3_FLAG = -march=armv8.4-a+crypto SHA3_FLAG = -march=armv8.4-a+crypto
SHA512_FLAG = -march=armv8.4-a+crypto SHA512_FLAG = -march=armv8.4-a+crypto
@ -531,7 +550,7 @@ endif # Asan
# LD gold linker testing. Triggered by 'LD=ld.gold'. # LD gold linker testing. Triggered by 'LD=ld.gold'.
ifeq ($(findstring ld.gold,$(LD)),ld.gold) ifeq ($(findstring ld.gold,$(LD)),ld.gold)
ifeq ($(findstring -fuse-ld=gold,$(CXXFLAGS)),) ifeq ($(findstring -fuse-ld=gold,$(CXXFLAGS)),)
ELF_FORMAT := $(shell file `which ld.gold` 2>&1 | cut -d":" -f 2 | $(EGREP) -i -c "elf") ELF_FORMAT := $(shell file `which ld.gold` 2>&1 | cut -d":" -f 2 | $(GREP) -i -c "elf")
ifneq ($(ELF_FORMAT),0) ifneq ($(ELF_FORMAT),0)
LDFLAGS += -fuse-ld=gold LDFLAGS += -fuse-ld=gold
endif # ELF/ELF64 endif # ELF/ELF64
@ -544,15 +563,15 @@ ifneq ($(filter valgrind,$(MAKECMDGOALS)),)
CXXFLAGS := $(CXXFLAGS:-g%=-g3) CXXFLAGS := $(CXXFLAGS:-g%=-g3)
CXXFLAGS := $(CXXFLAGS:-O%=-O1) CXXFLAGS := $(CXXFLAGS:-O%=-O1)
CXXFLAGS := $(CXXFLAGS:-xO%=-xO1) CXXFLAGS := $(CXXFLAGS:-xO%=-xO1)
ifeq ($(findstring -DCRYPTOPP_VALGRIND,$(CXXFLAGS)),) ifeq ($(findstring -DCRYPTOPP_COVERAGE,$(CXXFLAGS)),)
CXXFLAGS += -DCRYPTOPP_VALGRIND CXXFLAGS += -DCRYPTOPP_COVERAGE
endif # -DCRYPTOPP_VALGRIND endif # -DCRYPTOPP_COVERAGE
endif # Valgrind endif # Valgrind
# Debug testing on GNU systems. Triggered by -DDEBUG. # Debug testing on GNU systems. Triggered by -DDEBUG.
# Newlib test due to http://sourceware.org/bugzilla/show_bug.cgi?id=20268 # Newlib test due to http://sourceware.org/bugzilla/show_bug.cgi?id=20268
ifneq ($(filter -DDEBUG -DDEBUG=1,$(CXXFLAGS)),) ifneq ($(filter -DDEBUG -DDEBUG=1,$(CXXFLAGS)),)
USING_GLIBCXX := $(shell $(CXX) $(CXXFLAGS) -E pch.cpp 2>&1 | $(EGREP) -i -c "__GLIBCXX__") USING_GLIBCXX := $(shell $(CXX) $(CXXFLAGS) -E pch.cpp 2>&1 | $(GREP) -i -c "__GLIBCXX__")
ifneq ($(USING_GLIBCXX),0) ifneq ($(USING_GLIBCXX),0)
ifeq ($(HAS_NEWLIB),0) ifeq ($(HAS_NEWLIB),0)
ifeq ($(findstring -D_GLIBCXX_DEBUG,$(CXXFLAGS)),) ifeq ($(findstring -D_GLIBCXX_DEBUG,$(CXXFLAGS)),)
@ -590,14 +609,18 @@ SRCS := cryptlib.cpp cpu.cpp integer.cpp $(filter-out cryptlib.cpp cpu.cpp integ
# For Makefile.am; resource.h is Windows # For Makefile.am; resource.h is Windows
INCL := $(filter-out resource.h,$(sort $(wildcard *.h))) INCL := $(filter-out resource.h,$(sort $(wildcard *.h)))
# Cryptogams AES for ARMv4 and above. We couple to ARMv7. # Cryptogams source files. We couple to ARMv7.
# Avoid iOS. It cannot consume the assembly. # Limit to Linux. The source files target the GNU assembler.
ifeq ($(IS_ARM32),1) # Also see https://www.cryptopp.com/wiki/Cryptogams.
ifneq ($(IS_IOS),1) ifeq ($(IS_ARM32)$(IS_LINUX),11)
CRYPTOGAMS_AES_FLAG = -march=armv7-a ifeq ($(CLANG_COMPILER),1)
CRYPTOGAMS_AES_FLAG += -Wa,--noexecstack CRYPTOGAMS_ARMV7_FLAG = -march=armv7-a -Wa,--noexecstack
SRCS += aes_armv4.S CRYPTOGAMS_ARMV7_THUMB_FLAG = -march=armv7-a -mthumb -Wa,--noexecstack
else
CRYPTOGAMS_ARMV7_FLAG = -march=armv7-a -Wa,--noexecstack
CRYPTOGAMS_ARMV7_THUMB_FLAG = -march=armv7-a -Wa,--noexecstack
endif endif
SRCS += aes_armv4.S sha1_armv4.S sha256_armv4.S sha512_armv4.S
endif endif
# List cryptlib.cpp first, then cpu.cpp, then integer.cpp to tame C++ static initialization problems. # List cryptlib.cpp first, then cpu.cpp, then integer.cpp to tame C++ static initialization problems.
@ -613,7 +636,7 @@ TESTOBJS := $(TESTSRCS:.cpp=.o)
LIBOBJS := $(filter-out $(TESTOBJS),$(OBJS)) LIBOBJS := $(filter-out $(TESTOBJS),$(OBJS))
# For Shared Objects, Diff, Dist/Zip rules # For Shared Objects, Diff, Dist/Zip rules
LIB_VER := $(shell $(EGREP) "define CRYPTOPP_VERSION" config.h | cut -d" " -f 3) LIB_VER := $(shell $(GREP) "define CRYPTOPP_VERSION" config_ver.h | cut -d" " -f 3)
LIB_MAJOR := $(shell echo $(LIB_VER) | cut -c 1) LIB_MAJOR := $(shell echo $(LIB_VER) | cut -c 1)
LIB_MINOR := $(shell echo $(LIB_VER) | cut -c 2) LIB_MINOR := $(shell echo $(LIB_VER) | cut -c 2)
LIB_PATCH := $(shell echo $(LIB_VER) | cut -c 3) LIB_PATCH := $(shell echo $(LIB_VER) | cut -c 3)
@ -770,8 +793,8 @@ endif
libcryptopp.dylib: $(LIBOBJS) $(AOSP_CPU_OBJ) libcryptopp.dylib: $(LIBOBJS) $(AOSP_CPU_OBJ)
$(CXX) -dynamiclib -o $@ $(strip $(CXXFLAGS)) -install_name "$@" -current_version "$(LIB_MAJOR).$(LIB_MINOR).$(LIB_PATCH)" -compatibility_version "$(LIB_MAJOR).$(LIB_MINOR)" -headerpad_max_install_names $(LDFLAGS) $(LIBOBJS) $(AOSP_CPU_OBJ) $(CXX) -dynamiclib -o $@ $(strip $(CXXFLAGS)) -install_name "$@" -current_version "$(LIB_MAJOR).$(LIB_MINOR).$(LIB_PATCH)" -compatibility_version "$(LIB_MAJOR).$(LIB_MINOR)" -headerpad_max_install_names $(LDFLAGS) $(LIBOBJS) $(AOSP_CPU_OBJ)
cryptest.exe: libcryptopp.a $(TESTOBJS) cryptest.exe: $(LINK_LIBRARY) $(TESTOBJS)
$(CXX) -o $@ $(strip $(CXXFLAGS)) $(TESTOBJS) ./libcryptopp.a $(LDFLAGS) $(LDLIBS) $(CXX) -o $@ $(strip $(CXXFLAGS)) $(TESTOBJS) $(LINK_LIBRARY_PATH)$(LINK_LIBRARY) $(LDFLAGS) $(LDLIBS)
# Used to generate list of source files for Autotools, CMakeList and Android.mk # Used to generate list of source files for Autotools, CMakeList and Android.mk
.PHONY: sources .PHONY: sources
@ -800,9 +823,9 @@ ifeq ($(wildcard GNUmakefile.deps),GNUmakefile.deps)
-include GNUmakefile.deps -include GNUmakefile.deps
endif # Dependencies endif # Dependencies
# Cryptogams ARM asm implementation. # Cryptogams ARM asm implementation. AES needs -mthumb for Clang
aes_armv4.o : aes_armv4.S aes_armv4.o : aes_armv4.S
$(CXX) $(strip $(CXXFLAGS) -fpermissive $(CRYPTOGAMS_AES_FLAG) -c) $< $(CXX) $(strip $(CXXFLAGS) $(CRYPTOGAMS_ARMV7_THUMB_FLAG) -c) $<
cpu-features.o: cpu-features.h cpu-features.c cpu-features.o: cpu-features.h cpu-features.c
$(CXX) $(strip $(CXXFLAGS) -fpermissive -c) cpu-features.c $(CXX) $(strip $(CXXFLAGS) -fpermissive -c) cpu-features.c
@ -867,6 +890,18 @@ rijndael_simd.o : rijndael_simd.cpp
sha_simd.o : sha_simd.cpp sha_simd.o : sha_simd.cpp
$(CXX) $(strip $(CXXFLAGS) $(SHA_FLAG) -c) $< $(CXX) $(strip $(CXXFLAGS) $(SHA_FLAG) -c) $<
# Cryptogams SHA1 asm implementation.
sha1_armv4.o : sha1_armv4.S
$(CXX) $(strip $(CXXFLAGS) $(CRYPTOGAMS_ARMV7_FLAG) -c) $<
# Cryptogams SHA256 asm implementation.
sha256_armv4.o : sha256_armv4.S
$(CXX) $(strip $(CXXFLAGS) $(CRYPTOGAMS_ARMV7_FLAG) -c) $<
# Cryptogams SHA512 asm implementation.
sha512_armv4.o : sha512_armv4.S
$(CXX) $(strip $(CXXFLAGS) $(CRYPTOGAMS_ARMV7_FLAG) -c) $<
# SSE4.2/SHA-NI or ARMv8a available # SSE4.2/SHA-NI or ARMv8a available
shacal2_simd.o : shacal2_simd.cpp shacal2_simd.o : shacal2_simd.cpp
$(CXX) $(strip $(CXXFLAGS) $(SHA_FLAG) -c) $< $(CXX) $(strip $(CXXFLAGS) $(SHA_FLAG) -c) $<

View File

@ -455,10 +455,10 @@ last several releases.
8.1.0 - February 22, 2019 8.1.0 - February 22, 2019
- minor release, no recompile of programs required - minor release, no recompile of programs required
- expanded community input and support - expanded community input and support
56 unique contributors as of this release * 56 unique contributors as of this release
- fix OS X PowerPC builds with Clang - fix OS X PowerPC builds with Clang
- add Microsoft ARM64 support - add Microsoft ARM64 support
- fix iPhone Simulator build due to missign symbols - fix iPhone Simulator build due to missing symbols
- add CRYPTOPP_BUGGY_SIMD_LOAD_AND_STORE - add CRYPTOPP_BUGGY_SIMD_LOAD_AND_STORE
- add carryless multiplies for NIST b233 and k233 curves - add carryless multiplies for NIST b233 and k233 curves
- fix OpenMP build due to use of OpenMP 4 with down-level compilers - fix OpenMP build due to use of OpenMP 4 with down-level compilers
@ -467,3 +467,16 @@ last several releases.
- add SHAKE-128 and SHAKE-256 - add SHAKE-128 and SHAKE-256
- fix AVX2 build due to _mm256_broadcastsi128_si256 - fix AVX2 build due to _mm256_broadcastsi128_si256
- add IETF ChaCha, XChaCha, ChaChaPoly1305 and XChaChaPoly1305 - add IETF ChaCha, XChaCha, ChaChaPoly1305 and XChaChaPoly1305
8.2.0 - April 28, 2019
- minor release, no recompile of programs required
- expanded community input and support
* 56 unique contributors as of this release
- use PowerPC unaligned loads and stores with Power8
- add SKIPJACK test vectors
- fix SHAKE-128 and SHAKE-256 compile
- removed IS_NEON from Makefile
- fix Aarch64 build on Fedora 29
- fix missing GF2NT_233_Multiply_Reduce_CLMUL in FIPS DLL
- add missing BLAKE2 constructors
- fix missing BlockSize() in BLAKE2 classes

View File

@ -29,8 +29,9 @@ Daniel J. Bernstein, Jack Lloyd - chacha.cpp, chacha_simd.cpp, chacha_avx.cpp
Andrew Moon - ed25519, x25519, donna_32.cpp, donna_64.cpp, donna_sse.cpp Andrew Moon - ed25519, x25519, donna_32.cpp, donna_64.cpp, donna_sse.cpp
The Crypto++ Library uses portions of Andy Polyakov's CRYPTOGAMS for Poly1305 The Crypto++ Library uses portions of Andy Polyakov's CRYPTOGAMS for Poly1305
scalar multiplication and aes_armv4.S. CRYPTOGAMS is dual licensed with a scalar multiplication, aes_armv4.S, sha1_armv4.S and sha256_armv4.S. CRYPTOGAMS
permissive BSD-style license. The CRYPTOGAMS license is reproduced below. is dual licensed with a permissive BSD-style license. The CRYPTOGAMS license is
reproduced below.
The Crypto++ Library uses portions of Jack Lloyd's Botan for ChaCha SSE2 and The Crypto++ Library uses portions of Jack Lloyd's Botan for ChaCha SSE2 and
AVX. Botan placed the code in public domain for Crypto++ to use. AVX. Botan placed the code in public domain for Crypto++ to use.

View File

@ -1,5 +1,5 @@
Crypto++: free C++ Class Library of Cryptographic Schemes Crypto++: free C++ Class Library of Cryptographic Schemes
Version 8.0 - DEC/28/2018 Version 8.3 - TBD
Crypto++ Library is a free C++ class library of cryptographic schemes. Crypto++ Library is a free C++ class library of cryptographic schemes.
Currently the library contains the following algorithms: Currently the library contains the following algorithms:
@ -205,23 +205,29 @@ library in your programs to help avoid unwanted redirections.
*** Side Channel Attacks *** *** Side Channel Attacks ***
Crypto++ attempts to resist side channel attacks using various remediations. We Crypto++ attempts to resist side channel attacks using various remediations.
believe the library is mostly hardened but the remdiations may be incomplete. The The remdiations are applied as a best effort but are probably incomplete. They
first line of defense uses hardware instructions when possible for block ciphers, are incomplete due to cpu speculation bugs like Spectre, Meltdown, Foreshadow.
hashes and other primitives. Hardware acceleration remediates many timing attacks. The attacks target both cpu caches and internal buffers. Intel generally refers
The library also uses cache-aware algoirthms and access patterns to minimize leakage. to internal buffer attacks as "Microarchitectural Data Sampling" (MDS).
Some of the public key algorithms have branches and some of the branches depend on The library uses hardware instructions when possible for block ciphers, hashes
data that can be private or secret. The branching occurs in some field operations and other operations. The hardware acceleration remediates some timing
like exponentiation over integers and elliptic curves. The branching has been attacks. The library also uses cache-aware algoirthms and access patterns
minimized but not completely eliminated. to minimize leakage cache evictions.
Crypto++ does not enagage Specter remediations at this time. The GCC options for Some of the public key algorithms have branches and some of the branches depend
Specter are -mfunction-return=thunk and -mindirect-branch=thunk, and the library on data that can be private or secret. The branching occurs in some field
uses them during testing. If you want the Specter workarounds then add the GCC operations like exponentiation over integers and elliptic curves. The branching
options to your CXXFLAGS when building the library. has been minimized but not completely eliminated.
If you suspect or find an information leak then please report it. Crypto++ does not enagage Specter remediations at this time. The GCC options
for Specter are -mfunction-return=thunk and -mindirect-branch=thunk, and the
library uses them during testing. If you want the Specter workarounds then add
the GCC options to your CXXFLAGS when building the library.
To help resist attacks you should disable hyperthreading on cpus. If you
suspect or find an information leak then please report it.
*** Documentation and Support *** *** Documentation and Support ***
@ -290,8 +296,36 @@ documentation is one of the highest returns on investment.
The items in this section comprise the most recent history. Please see History.txt The items in this section comprise the most recent history. Please see History.txt
for the record back to Crypto++ 1.0. for the record back to Crypto++ 1.0.
8.0.0 - December 28, 2018 8.2.0 - April 28, 2019
- minor release, no recompile of programs required
- expanded community input and support
* 56 unique contributors as of this release
- use PowerPC unaligned loads and stores with Power8
- add SKIPJACK test vectors
- fix SHAKE-128 and SHAKE-256 compile
- removed IS_NEON from Makefile
- fix Aarch64 build on Fedora 29
- fix missing GF2NT_233_Multiply_Reduce_CLMUL in FIPS DLL
- add missing BLAKE2 constructors
- fix missing BlockSize() in BLAKE2 classes
8.1.0 - February 22, 2019
- minor release, no recompile of programs required
- expanded community input and support
* 56 unique contributors as of this release
- fix OS X PowerPC builds with Clang
- add Microsoft ARM64 support
- fix iPhone Simulator build due to missing symbols
- add CRYPTOPP_BUGGY_SIMD_LOAD_AND_STORE
- add carryless multiplies for NIST b233 and k233 curves
- fix OpenMP build due to use of OpenMP 4 with down-level compilers
- add SignStream and VerifyStream for ed25519 and large files
- fix missing AlgorithmProvider in PanamaHash
- add SHAKE-128 and SHAKE-256
- fix AVX2 build due to _mm256_broadcastsi128_si256
- add IETF ChaCha, XChaCha, ChaChaPoly1305 and XChaChaPoly1305
8.0.0 - December 28, 2018
- major release, recompile of programs required - major release, recompile of programs required
- expanded community input and support - expanded community input and support
* 54 unique contributors as of this release * 54 unique contributors as of this release

1
TestData/ecies_p160.dat Normal file
View File

@ -0,0 +1 @@
3081C80201003081A406072A8648CE3D0201308198020101302006072A8648CE3D0101021500FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7FFFFFFF302C0414FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7FFFFFFC04141C97BEFC54BD7A8B65ACF89F81D4D4ADC565FA450429044A96B5688EF573284664698968C38BB913CBFC8223A628553168947D59DCC912042351377AC5FB3202150100000000000000000001F4C8F927AED3CA752257020101041C301A02010104150023A68821ABB99DBB8429ED2320D61A8EA4C6D81B

1
TestData/ecies_t163.dat Normal file
View File

@ -0,0 +1 @@
3081D10201003081AD06072A8648CE3D02013081A1020101302506072A8648CE3D0102301A020200A306092A8648CE3D010203033009020103020106020107302E041507B6882CAAEFA84F9554FF8428BD88E246D2782AE204150713612DCDDCB40AAB946BDA29CA91F73AF958AFD9042B040369979697AB43897789566789567F787A7876A65400435EDB42EFAFB2989D51FEFCE3C80988F41FF883021503FFFFFFFFFFFFFFFFFFFF48AAB689C29CA710279B020102041C301A02010104150003693AB4D83EE8B544548BE7647AEA0EA64E8211

View File

@ -1 +1 @@
308201A40201003082011706072A8648CE3804013082010A028181008B333697371663F8869E3EC80A414E46BBAFE41F6D40E754A01ADA60FE7D12ACD16DE311C4115293114F6B92A54195909276380F04BCD4ED5CD993ED7F516DF7A752B928E5035E0D3A1A979A1CDE8387734338793C02001D59B662D4FC8F2BF0EABB1F553F9F46F57E74BCABCBA4E458812DB601FCD04609D435317181236B9702818045999B4B9B8B31FC434F1F640520A7235DD7F20FB6A073AA500D6D307F3E895668B6F188E208A94988A7B5C952A0CAC8493B1C07825E6A76AE6CC9F6BFA8B6FBD3A95C947281AF069D0D4BCD0E6F41C3B9A19C3C9E01000EACDB316A7E4795F8755D8FAA9FCFA37ABF3A5E55E5D2722C4096DB00FE682304EA1A98B8C091B5CB02010204818302818045999B4B9B8B31FC434F1F640520A7235DD7F20FB6A073AA500D6D307F3E895668B6F188E208A94988A7B5C952A0CAC8493B1C07825E6A76AE6CC9F6BFA8B6FBD3A95C947281AF069D0D4BCD0E6F41C3B9A19C3C9E01000EACDB316A7E4795F8755D8FAA9FCFA37ABF3A5E2958F40032EF29CB145C7481380458812D62F09287 308201360201003082011606062B0E070201013082010A02818100D18892CC35AD9E532C53810019E525CDE08882E6344D6787C366B171D68948F53D74F7923B148E0A0B4C9B956D695384DE24AC3034000B3C4AD4C8226470BBD88B5B053BCCB01E608B1352D6ED16324745253BDB204308E065368CB9D75ACDB290E671BD4CA1608500BFACD758E6E9EFAC8CCBAD83BE7E397A62E4F55634FC3B02818068C449661AD6CF299629C0800CF292E6F04441731A26B3C3E1B358B8EB44A47A9EBA7BC91D8A470505A64DCAB6B4A9C26F1256181A00059E256A641132385DEC45AD829DE6580F304589A96B768B1923A2929DED90218470329B465CEBAD66D9487338DEA650B042805FD66BAC7374F7D64665D6C1DF3F1CBD31727AAB1A7E1D0201030417021504ED7AED68B1A5EFDE11262210D9F1121D4A119CE8

View File

@ -0,0 +1,18 @@
#include <arm_neon.h>
#include <stdint.h>
// test_acle.h determines if this is available. Then,
// -DCRYPTOPP_ARM_ACLE_AVAILABLE=0 is added to CXXFLAGS
// if the ACLE header is not available.
#if (CRYPTOPP_ARM_ACLE_AVAILABLE)
# include <arm_acle.h>
#endif
int main(int argc, char* argv[])
{
uint32x4_t y = {0};
y=vsha1cq_u32(y,0,y);
y=vsha1mq_u32(y,1,y);
y=vsha1pq_u32(y,2,y);
return 0;
}

View File

@ -11,9 +11,6 @@
int main(int argc, char* argv[]) int main(int argc, char* argv[])
{ {
uint32x4_t y = {0}; uint32x4_t y = {0};
y=vsha1cq_u32(y,0,y);
y=vsha1mq_u32(y,1,y);
y=vsha1pq_u32(y,2,y);
y=vsha256hq_u32(y, y, y); y=vsha256hq_u32(y, y, y);
y=vsha256h2q_u32(y, y, y); y=vsha256h2q_u32(y, y, y);
y=vsha256su1q_u32(y, y, y); y=vsha256su1q_u32(y, y, y);

View File

@ -1,7 +1,9 @@
#include <immintrin.h> #include <immintrin.h>
int main(int argc, char* argv[]) int main(int argc, char* argv[])
{ {
__m256i x = _mm256_setzero_si256(); // _mm256_broadcastsi128_si256 due to Clang
x=_mm256_add_epi64 (x,x); __m128i x = _mm_setzero_si128 ();
__m256i y = _mm256_broadcastsi128_si256 (x);
y = _mm256_add_epi64 (y,y);
return 0; return 0;
} }

View File

@ -0,0 +1,7 @@
#include <immintrin.h>
int main(int argc, char* argv[])
{
unsigned int x=0;
(void)_rdrand32_step (&x);
return x == 0 ? 0 : 0;
}

View File

@ -0,0 +1,7 @@
#include <immintrin.h>
int main(int argc, char* argv[])
{
unsigned int x=0;
(void)_rdseed32_step (&x);
return x == 0 ? 0 : 0;
}

View File

@ -4,11 +4,14 @@
# building the docs. Before running the script, copy it to the root # building the docs. Before running the script, copy it to the root
# directory. After running this script, you can 'make docs' # directory. After running this script, you can 'make docs'
sed 's|Library 8.1 API|Library 8.0 API|g' cryptlib.h > cryptlib.h.new sed 's|Library 8.3 API|Library 8.2 API|g' cryptlib.h > cryptlib.h.new
mv cryptlib.h.new cryptlib.h mv cryptlib.h.new cryptlib.h
sed 's|= 8.1|= 8.0|g' Doxyfile > Doxyfile.new sed 's|= 8.3|= 8.2|g' Doxyfile > Doxyfile.new
mv Doxyfile.new Doxyfile mv Doxyfile.new Doxyfile
sed 's|CRYPTOPP_VERSION 810|CRYPTOPP_VERSION 800|g' config.h > config.h.new sed 's|CRYPTOPP_MINOR 3|CRYPTOPP_MINOR 2|g' config_ver.h > config_ver.h.new
mv config.h.new config.h mv config_ver.h.new config_ver.h
sed 's|CRYPTOPP_VERSION 830|CRYPTOPP_VERSION 820|g' config_ver.h > config_ver.h.new
mv config_ver.h.new config_ver.h

View File

@ -6,17 +6,13 @@ function cleanup {
} }
trap cleanup EXIT trap cleanup EXIT
#############################################################################
GREP=grep GREP=grep
SED=sed SED=sed
AWK=awk AWK=awk
MAKE=make MAKE=make
# Fixup ancient Bash
# https://unix.stackexchange.com/q/468579/56041
if [[ -z "$BASH_SOURCE" ]]; then
BASH_SOURCE="$0"
fi
# Fixup, Solaris and friends # Fixup, Solaris and friends
if [[ (-d /usr/xpg4/bin) ]]; then if [[ (-d /usr/xpg4/bin) ]]; then
SED=/usr/xpg4/bin/sed SED=/usr/xpg4/bin/sed
@ -34,7 +30,6 @@ if [[ "$IS_DARWIN" -ne 0 ]]; then
export LC_ALL=C export LC_ALL=C
fi fi
# Fixup for Solaris and BSDs
# Fixup for Solaris and BSDs # Fixup for Solaris and BSDs
if [[ ! -z $(command -v gmake) ]]; then if [[ ! -z $(command -v gmake) ]]; then
MAKE=gmake MAKE=gmake
@ -53,24 +48,30 @@ elif [[ ! -z $(command -v glibtool) ]]; then
LIBTOOLIZE=$(command -v glibtool) LIBTOOLIZE=$(command -v glibtool)
fi fi
# Fecth the three required files #############################################################################
if ! wget --no-check-certificate 'https://raw.githubusercontent.com/noloader/cryptopp-autotools/master/Makefile.am' -O Makefile.am; then
echo "Makefile.am download failed"
[[ "$0" = "${BASH_SOURCE[0]}" ]] && exit 1 || return 1
fi
if ! wget --no-check-certificate 'https://raw.githubusercontent.com/noloader/cryptopp-autotools/master/configure.ac' -O configure.ac; then echo "Downloading configure.ac"
if ! wget -O configure.ac -q --no-check-certificate 'https://raw.githubusercontent.com/noloader/cryptopp-autotools/master/configure.ac'; then
echo "configure.ac download failed" echo "configure.ac download failed"
[[ "$0" = "${BASH_SOURCE[0]}" ]] && exit 1 || return 1 [[ "$0" = "${BASH_SOURCE[0]}" ]] && exit 1 || return 1
fi fi
if ! wget --no-check-certificate 'https://raw.githubusercontent.com/noloader/cryptopp-autotools/master/libcryptopp.pc.in' -O libcryptopp.pc.in; then echo "Downloading Makefile.am"
if ! wget -O Makefile.am -q --no-check-certificate 'https://raw.githubusercontent.com/noloader/cryptopp-autotools/master/Makefile.am'; then
echo "Makefile.am download failed"
[[ "$0" = "${BASH_SOURCE[0]}" ]] && exit 1 || return 1
fi
echo "Downloading libcryptopp.pc.in"
if ! wget -O libcryptopp.pc.in -q --no-check-certificate 'https://raw.githubusercontent.com/noloader/cryptopp-autotools/master/libcryptopp.pc.in'; then
echo "libcryptopp.pc.in download failed" echo "libcryptopp.pc.in download failed"
[[ "$0" = "${BASH_SOURCE[0]}" ]] && exit 1 || return 1 [[ "$0" = "${BASH_SOURCE[0]}" ]] && exit 1 || return 1
fi fi
mkdir -p m4/ mkdir -p m4/
#############################################################################
if [[ -z $(command -v autoupdate) ]]; then if [[ -z $(command -v autoupdate) ]]; then
echo "Cannot find autoupdate. Things may fail." echo "Cannot find autoupdate. Things may fail."
fi fi
@ -79,56 +80,71 @@ if [[ -z "$LIBTOOLIZE" ]]; then
echo "Cannot find libtoolize. Things may fail." echo "Cannot find libtoolize. Things may fail."
fi fi
if [[ -z $(command -v automake) ]]; then
echo "Cannot find automake. Things may fail."
fi
if [[ -z $(command -v autoreconf) ]]; then if [[ -z $(command -v autoreconf) ]]; then
echo "Cannot find autoreconf. Things may fail." echo "Cannot find autoreconf. Things may fail."
fi fi
echo "Running autoupdate" echo "Running autoupdate"
if ! autoupdate 2>/dev/null; then if ! autoupdate &>/dev/null; then
echo "autoupdate failed." echo "autoupdate failed."
[[ "$0" = "${BASH_SOURCE[0]}" ]] && exit 1 || return 1 [[ "$0" = "${BASH_SOURCE[0]}" ]] && exit 1 || return 1
fi fi
echo "Running libtoolize" echo "Running libtoolize"
if ! "$LIBTOOLIZE" 2>/dev/null; then if ! "$LIBTOOLIZE" --force --install &>/dev/null; then
echo "libtoolize failed." echo "libtoolize failed... skipping."
[[ "$0" = "${BASH_SOURCE[0]}" ]] && exit 1 || return 1 # [[ "$0" = "${BASH_SOURCE[0]}" ]] && exit 1 || return 1
fi fi
# Run autoreconf twice on failure. Also see # Run autoreconf twice on failure. Also see
# https://github.com/tracebox/tracebox/issues/57 # https://github.com/tracebox/tracebox/issues/57
echo "Running autoreconf" echo "Running autoreconf"
if ! autoreconf 2>/dev/null; then if ! autoreconf --force --install &>/dev/null; then
echo "autoreconf failed, running again." echo "autoreconf failed, running again."
if ! autoreconf -fi; then if ! autoreconf --force --install; then
echo "autoreconf failed, again." echo "autoreconf failed, again."
[[ "$0" = "${BASH_SOURCE[0]}" ]] && exit 1 || return 1 [[ "$0" = "${BASH_SOURCE[0]}" ]] && exit 1 || return 1
fi fi
fi fi
# Sparc need +w #############################################################################
if [[ -e config.sub ]]; then
chmod +w config.sub
fi
if [[ -e config.guess ]]; then
chmod +w config.guess
fi
# Update config.sub config.guess. GNU recommends using the latest for all projects. # Update config.sub config.guess. GNU recommends using the latest for all projects.
echo "Updating config.sub" echo "Updating config.sub"
wget --no-check-certificate 'https://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub' -O config.sub wget -O config.sub.new -q --no-check-certificate 'https://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub'
if [[ -e config.sub ]]; then # Solaris removes +w, can't overwrite
chmod +w config.sub
mv config.sub.new config.sub
chmod +x config.sub chmod +x config.sub
if [[ "$IS_DARWIN" -ne 0 ]] && [[ -n $(command -v xattr) ]]; then
echo "Removing config.sub quarantine"
xattr -d "com.apple.quarantine" config.sub &>/dev/null
fi fi
echo "Updating config.guess" echo "Updating config.guess"
wget --no-check-certificate 'https://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess' -O config.guess wget -O config.guess.new -q --no-check-certificate 'https://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess'
if [[ -e config.guess ]]; then # Solaris removes +w, can't overwrite
chmod +w config.guess
mv config.guess.new config.guess
chmod +x config.guess chmod +x config.guess
if [[ "$IS_DARWIN" -ne 0 ]] && [[ -n $(command -v xattr) ]]; then
echo "Removing config.guess quarantine"
xattr -d "com.apple.quarantine" config.guess &>/dev/null
fi fi
#############################################################################
echo "Running configure"
echo ""
if ! ./configure; then if ! ./configure; then
echo "configure failed." echo "configure failed."
[[ "$0" = "${BASH_SOURCE[0]}" ]] && exit 1 || return 1 [[ "$0" = "${BASH_SOURCE[0]}" ]] && exit 1 || return 1
@ -136,6 +152,8 @@ fi
"$MAKE" clean 2>/dev/null "$MAKE" clean 2>/dev/null
#############################################################################
if ! "$MAKE" -j2 -f Makefile; then if ! "$MAKE" -j2 -f Makefile; then
echo "make failed." echo "make failed."
[[ "$0" = "${BASH_SOURCE[0]}" ]] && exit 1 || return 1 [[ "$0" = "${BASH_SOURCE[0]}" ]] && exit 1 || return 1

View File

@ -18,7 +18,7 @@ fi
PWD_DIR=$(pwd) PWD_DIR=$(pwd)
function cleanup { function cleanup {
rm -f adhoc.cpp *.a *.o *.so *.dylib GNUmakefile-symbols rm -f adhoc.cpp *.a *.o *.so *.dylib
cd "$PWD_DIR" cd "$PWD_DIR"
} }
trap cleanup EXIT trap cleanup EXIT
@ -26,7 +26,7 @@ trap cleanup EXIT
############################################ ############################################
# Tags to test # Tags to test
OLD_VERSION_TAG=CRYPTOPP_8_0_0 OLD_VERSION_TAG=CRYPTOPP_8_2_0
NEW_VERSION_TAG=master NEW_VERSION_TAG=master
############################################ ############################################
@ -40,7 +40,7 @@ if [[ ! (-z "$DIRTY") ]]; then
read -p "Type 'Y' to proceed or 'N' to exit. Proceed? " -n 1 -r read -p "Type 'Y' to proceed or 'N' to exit. Proceed? " -n 1 -r
echo # (optional) move to a new line echo # (optional) move to a new line
if [[ !($REPLY =~ ^[Yy]$) ]]; then if [[ !($REPLY =~ ^[Yy]$) ]]; then
[[ "$0" = "$BASH_SOURCE" ]] && exit 0 || return 0 exit 0
fi fi
else else
echo echo
@ -222,29 +222,13 @@ fi
"$MAKE" distclean &>/dev/null "$MAKE" distclean &>/dev/null
rm -f GNUmakefile-symbols
git checkout master -f &>/dev/null git checkout master -f &>/dev/null
cp GNUmakefile GNUmakefile-symbols
git checkout "$OLD_VERSION_TAG" -f &>/dev/null git checkout "$OLD_VERSION_TAG" -f &>/dev/null
if [[ "$?" -ne "0" ]]; then if [[ "$?" -ne "0" ]]; then
echo "Failed to checkout $OLD_VERSION_TAG" echo "Failed to checkout $OLD_VERSION_TAG"
[[ "$0" = "$BASH_SOURCE" ]] && exit 1 || return 1 exit 1
fi
echo
echo "****************************************************************"
echo "Patching makefile for dynamic linking by cryptest.exe"
echo "****************************************************************"
if [[ "$IS_DARWIN" -ne "0" ]]; then
"$SED" "$SED_OPTS" -e 's|libcryptopp.a $(TESTOBJS)|libcryptopp.dylib $(TESTOBJS)|g' GNUmakefile-symbols
"$SED" "$SED_OPTS" -e 's|$(TESTOBJS) ./libcryptopp.a |$(TESTOBJS) ./libcryptopp.dylib |g' GNUmakefile-symbols
else
"$SED" "$SED_OPTS" -e 's|libcryptopp.a $(TESTOBJS)|libcryptopp.so $(TESTOBJS)|g' GNUmakefile-symbols
"$SED" "$SED_OPTS" -e 's|$(TESTOBJS) ./libcryptopp.a |$(TESTOBJS) ./libcryptopp.so |g' GNUmakefile-symbols
fi fi
echo echo
@ -253,17 +237,17 @@ echo "Building dynamic library for $OLD_VERSION_TAG"
echo "****************************************************************" echo "****************************************************************"
echo echo
"$MAKE" "${MAKEARGS[@]}" -f GNUmakefile-symbols dynamic
if [[ "$IS_DARWIN" -ne "0" ]]; then if [[ "$IS_DARWIN" -ne "0" ]]; then
LIBNAME=libcryptopp.dylib LINK_LIBRARY=libcryptopp.dylib
else else
LIBNAME=libcryptopp.so LINK_LIBRARY=libcryptopp.so
fi fi
if [[ ! -f "$LIBNAME" ]]; then LINK_LIBRARY="$LINK_LIBRARY" "$MAKE" "${MAKEARGS[@]}" -f GNUmakefile dynamic
if [[ ! -f "$LINK_LIBRARY" ]]; then
echo "Failed to make $OLD_VERSION_TAG library" echo "Failed to make $OLD_VERSION_TAG library"
[[ "$0" = "$BASH_SOURCE" ]] && exit 1 || return 1 exit 1
fi fi
echo echo
@ -272,11 +256,11 @@ echo "Building cryptest.exe for $OLD_VERSION_TAG"
echo "****************************************************************" echo "****************************************************************"
echo echo
"$MAKE" "${MAKEARGS[@]}" -f GNUmakefile-symbols cryptest.exe "$MAKE" "${MAKEARGS[@]}" -f GNUmakefile cryptest.exe
if [[ ! -f "cryptest.exe" ]]; then if [[ ! -f "cryptest.exe" ]]; then
echo "Failed to make cryptest.exe" echo "Failed to make cryptest.exe"
[[ "$0" = "$BASH_SOURCE" ]] && exit 1 || return 1 exit 1
fi fi
echo echo
@ -304,7 +288,7 @@ git checkout "$NEW_VERSION_TAG" -f &>/dev/null
if [[ "$?" -ne "0" ]]; then if [[ "$?" -ne "0" ]]; then
echo "Failed to checkout $OLD_VERSION_TAG" echo "Failed to checkout $OLD_VERSION_TAG"
[[ "$0" = "$BASH_SOURCE" ]] && exit 1 || return 1 exit 1
fi fi
echo echo
@ -313,11 +297,11 @@ echo "Building dynamic library for $NEW_VERSION_TAG"
echo "****************************************************************" echo "****************************************************************"
echo echo
"$MAKE" "${MAKEARGS[@]}" -f GNUmakefile-symbols dynamic LINK_LIBRARY="$LINK_LIBRARY" "$MAKE" "${MAKEARGS[@]}" -f GNUmakefile dynamic
if [[ ! -f "$LIBNAME" ]]; then if [[ ! -f "$LINK_LIBRARY" ]]; then
echo "Failed to make $NEW_VERSION_TAG library" echo "Failed to make $NEW_VERSION_TAG library"
[[ "$0" = "$BASH_SOURCE" ]] && exit 1 || return 1 exit 1
fi fi
echo echo
@ -338,7 +322,7 @@ git checkout master -f &>/dev/null
if [[ "$?" -ne "0" ]]; then if [[ "$?" -ne "0" ]]; then
echo "Failed to checkout Master" echo "Failed to checkout Master"
[[ "$0" = "$BASH_SOURCE" ]] && exit 1 || return 1 exit 1
fi fi
[[ "$0" = "$BASH_SOURCE" ]] && exit 0 || return 0 exit 0

File diff suppressed because it is too large Load Diff

View File

@ -1,25 +1,25 @@
#!/usr/bin/env bash #!/usr/bin/env bash
# This scripts queries and modifies CPU scaling frequencies to produce more # This scripts queries and modifies CPU scaling frequencies to produce more
# accurate benchmark results. To move from a low energy state C-state to a # accurate benchmark results. To move from a low energy state to a higher
# higher one, run 'governor.sh performance'. To move back to a low power state # one, run 'governor.sh performance'. To move back to a low power state
# run 'governor.sh powersave' or reboot. The script is based on code by # run 'governor.sh powersave' or 'governor.sh ondemand' or reboot. The script
# Andy Polyakov, http://www.openssl.org/~appro/cryptogams/. # based on code by Andy Polyakov, http://www.openssl.org/~appro/cryptogams/.
# Fixup ancient Bash # Fixup ancient Bash
# https://unix.stackexchange.com/q/468579/56041 # https://unix.stackexchange.com/q/468579/56041
if [[ -z "$BASH_SOURCE" ]]; then if [[ -z "${BASH_SOURCE[0]}" ]]; then
BASH_SOURCE="$0" BASH_SOURCE="$0"
fi fi
if [[ "$EUID" -ne 0 ]]; then if [[ "$EUID" -ne 0 ]]; then
echo "This script must be run as root" echo "This script must be run as root"
[[ "$0" = "$BASH_SOURCE" ]] && exit 1 || return 1 [[ "$0" = "${BASH_SOURCE[0]}" ]] && exit 1 || return 1
fi fi
if [ "x$1" = "x" ]; then if [ "x$1" = "x" ]; then
echo "usage: $0 on[demand]|pe[rformance]|po[wersave]|us[erspace]?" echo "usage: $0 on[demand]|pe[rformance]|po[wersave]|us[erspace]?"
[[ "$0" = "$BASH_SOURCE" ]] && exit 1 || return 1 [[ "$0" = "${BASH_SOURCE[0]}" ]] && exit 1 || return 1
fi fi
# "on demand" may result in a "invalid write argument" or similar # "on demand" may result in a "invalid write argument" or similar
@ -27,40 +27,41 @@ case $1 in
on*|de*) governor="ondemand";; on*|de*) governor="ondemand";;
po*|pw*) governor="powersave";; po*|pw*) governor="powersave";;
pe*) governor="performance";; pe*) governor="performance";;
co*) governor="conservative";;
us*) governor="userspace";; us*) governor="userspace";;
\?) ;; \?) ;;
*) echo "$1: unrecognized governor";; *) echo "$1: unrecognized governor";;
esac esac
if [ -z "$governor" ]; then if [ -z "$governor" ]; then
[[ "$0" = "$BASH_SOURCE" ]] && exit 1 || return 1 [[ "$0" = "${BASH_SOURCE[0]}" ]] && exit 1 || return 1
fi fi
cpus=$(ls /sys/devices/system/cpu/cpu*/cpufreq/scaling_governor 2>/dev/null) cpus=$(ls /sys/devices/system/cpu/cpu*/cpufreq/scaling_governor 2>/dev/null)
if [ -z "$cpus" ]; then if [ -z "$cpus" ]; then
echo "Failed to read CPU system device tree" echo "Failed to read CPU system device tree"
[[ "$0" = "$BASH_SOURCE" ]] && exit 1 || return 1 [[ "$0" = "${BASH_SOURCE[0]}" ]] && exit 1 || return 1
fi fi
echo "Current CPU governor scaling settings:" echo "Current CPU governor scaling settings:"
count=0 count=0
for cpu in $cpus; do for cpu in $cpus; do
echo " CPU $count:" $(cat "$cpu") echo " CPU $count: $(cat "$cpu")"
((count++)) ((count++))
done done
if [ "x$governor" != "x" ]; then if [ "x$governor" != "x" ]; then
for cpu in $cpus; do for cpu in $cpus; do
echo $governor > $cpu echo "$governor" > "$cpu"
done done
fi fi
echo "New CPU governor scaling settings:" echo "New CPU governor scaling settings:"
count=0 count=0
for cpu in $cpus; do for cpu in $cpus; do
echo " CPU $count:" $(cat "$cpu") echo " CPU $count: $(cat "$cpu")"
((count++)) ((count++))
done done
[[ "$0" = "$BASH_SOURCE" ]] && exit 0 || return 0 [[ "$0" = "${BASH_SOURCE[0]}" ]] && exit 0 || return 0

View File

@ -18,6 +18,12 @@
# set -eu # set -eu
# Sanity check
if [ "$0" = "${BASH_SOURCE[0]}" ]; then
echo "Please source this setenv script"
exit 0
fi
unset IS_CROSS_COMPILE unset IS_CROSS_COMPILE
unset IS_IOS unset IS_IOS
@ -39,7 +45,7 @@ unset CPP CC CXX LD AS AR RANLIB STRIP
# Similar to a "make clean" # Similar to a "make clean"
if [ x"${1-}" = "xunset" ]; then if [ x"${1-}" = "xunset" ]; then
echo "Unsetting script variables. PATH may remain tainted" echo "Unsetting script variables. PATH may remain tainted"
[ "$0" = "$BASH_SOURCE" ] && exit 0 || return 0 [ "$0" = "${BASH_SOURCE[0]}" ] && exit 0 || return 0
fi fi
# Set AOSP_TOOLCHAIN_SUFFIX to your preference of tools and STL library. # Set AOSP_TOOLCHAIN_SUFFIX to your preference of tools and STL library.
@ -71,7 +77,7 @@ if [ -z "${AOSP_API-}" ]; then
else else
echo "WARNING: Using AOSP_API has been deprecated. Please use AOSP_API_VERSION instead." echo "WARNING: Using AOSP_API has been deprecated. Please use AOSP_API_VERSION instead."
echo "If you set for example AOSP_API=android-23 then now instead set AOSP_API_VERSION=23" echo "If you set for example AOSP_API=android-23 then now instead set AOSP_API_VERSION=23"
[ "$0" = "$BASH_SOURCE" ] && exit 1 || return 1 [ "$0" = "${BASH_SOURCE[0]}" ] && exit 1 || return 1
fi fi
##################################################################### #####################################################################
@ -98,7 +104,7 @@ fi
# Error checking # Error checking
if [ ! -d "$ANDROID_NDK_ROOT/toolchains" ]; then if [ ! -d "$ANDROID_NDK_ROOT/toolchains" ]; then
echo "ERROR: ANDROID_NDK_ROOT is not a valid path. Please set it." echo "ERROR: ANDROID_NDK_ROOT is not a valid path. Please set it."
[ "$0" = "$BASH_SOURCE" ] && exit 1 || return 1 [ "$0" = "${BASH_SOURCE[0]}" ] && exit 1 || return 1
fi fi
##################################################################### #####################################################################
@ -127,7 +133,7 @@ case "$THE_ARCH" in
;; ;;
hard|armv7a-hard|armeabi-v7a-hard) hard|armv7a-hard|armeabi-v7a-hard)
echo hard, armv7a-hard and armeabi-v7a-hard are not supported, as android uses softfloats echo hard, armv7a-hard and armeabi-v7a-hard are not supported, as android uses softfloats
[ "$0" = "$BASH_SOURCE" ] && exit 1 || return 1 [ "$0" = "${BASH_SOURCE[0]}" ] && exit 1 || return 1
#TOOLCHAIN_ARCH="arm-linux-androideabi" #TOOLCHAIN_ARCH="arm-linux-androideabi"
#TOOLCHAIN_NAME="arm-linux-androideabi" #TOOLCHAIN_NAME="arm-linux-androideabi"
#AOSP_ABI="armeabi-v7a" #AOSP_ABI="armeabi-v7a"
@ -178,7 +184,7 @@ case "$THE_ARCH" in
;; ;;
*) *)
echo "ERROR: Unknown architecture $1" echo "ERROR: Unknown architecture $1"
[ "$0" = "$BASH_SOURCE" ] && exit 1 || return 1 [ "$0" = "${BASH_SOURCE[0]}" ] && exit 1 || return 1
;; ;;
esac esac
@ -218,48 +224,48 @@ done
# Error checking # Error checking
if [ -z "$AOSP_TOOLCHAIN_PATH" ] || [ ! -d "$AOSP_TOOLCHAIN_PATH" ]; then if [ -z "$AOSP_TOOLCHAIN_PATH" ] || [ ! -d "$AOSP_TOOLCHAIN_PATH" ]; then
echo "ERROR: AOSP_TOOLCHAIN_PATH is not valid. Please edit this script." echo "ERROR: AOSP_TOOLCHAIN_PATH is not valid. Please edit this script."
[ "$0" = "$BASH_SOURCE" ] && exit 1 || return 1 [ "$0" = "${BASH_SOURCE[0]}" ] && exit 1 || return 1
fi fi
# Error checking # Error checking
if [ ! -e "$AOSP_TOOLCHAIN_PATH/$CPP" ]; then if [ ! -e "$AOSP_TOOLCHAIN_PATH/$CPP" ]; then
echo "ERROR: Failed to find Android cpp. Please edit this script." echo "ERROR: Failed to find Android cpp. Please edit this script."
[ "$0" = "$BASH_SOURCE" ] && exit 1 || return 1 [ "$0" = "${BASH_SOURCE[0]}" ] && exit 1 || return 1
fi fi
# Error checking # Error checking
if [ ! -e "$AOSP_TOOLCHAIN_PATH/$CC" ]; then if [ ! -e "$AOSP_TOOLCHAIN_PATH/$CC" ]; then
echo "ERROR: Failed to find Android gcc. Please edit this script." echo "ERROR: Failed to find Android gcc. Please edit this script."
[ "$0" = "$BASH_SOURCE" ] && exit 1 || return 1 [ "$0" = "${BASH_SOURCE[0]}" ] && exit 1 || return 1
fi fi
if [ ! -e "$AOSP_TOOLCHAIN_PATH/$CXX" ]; then if [ ! -e "$AOSP_TOOLCHAIN_PATH/$CXX" ]; then
echo "ERROR: Failed to find Android g++. Please edit this script." echo "ERROR: Failed to find Android g++. Please edit this script."
[ "$0" = "$BASH_SOURCE" ] && exit 1 || return 1 [ "$0" = "${BASH_SOURCE[0]}" ] && exit 1 || return 1
fi fi
# Error checking # Error checking
if [ ! -e "$AOSP_TOOLCHAIN_PATH/$RANLIB" ]; then if [ ! -e "$AOSP_TOOLCHAIN_PATH/$RANLIB" ]; then
echo "ERROR: Failed to find Android ranlib. Please edit this script." echo "ERROR: Failed to find Android ranlib. Please edit this script."
[ "$0" = "$BASH_SOURCE" ] && exit 1 || return 1 [ "$0" = "${BASH_SOURCE[0]}" ] && exit 1 || return 1
fi fi
# Error checking # Error checking
if [ ! -e "$AOSP_TOOLCHAIN_PATH/$AR" ]; then if [ ! -e "$AOSP_TOOLCHAIN_PATH/$AR" ]; then
echo "ERROR: Failed to find Android ar. Please edit this script." echo "ERROR: Failed to find Android ar. Please edit this script."
[ "$0" = "$BASH_SOURCE" ] && exit 1 || return 1 [ "$0" = "${BASH_SOURCE[0]}" ] && exit 1 || return 1
fi fi
# Error checking # Error checking
if [ ! -e "$AOSP_TOOLCHAIN_PATH/$AS" ]; then if [ ! -e "$AOSP_TOOLCHAIN_PATH/$AS" ]; then
echo "ERROR: Failed to find Android as. Please edit this script." echo "ERROR: Failed to find Android as. Please edit this script."
[ "$0" = "$BASH_SOURCE" ] && exit 1 || return 1 [ "$0" = "${BASH_SOURCE[0]}" ] && exit 1 || return 1
fi fi
# Error checking # Error checking
if [ ! -e "$AOSP_TOOLCHAIN_PATH/$LD" ]; then if [ ! -e "$AOSP_TOOLCHAIN_PATH/$LD" ]; then
echo "ERROR: Failed to find Android ld. Please edit this script." echo "ERROR: Failed to find Android ld. Please edit this script."
[ "$0" = "$BASH_SOURCE" ] && exit 1 || return 1 [ "$0" = "${BASH_SOURCE[0]}" ] && exit 1 || return 1
fi fi
# Only modify/export PATH if AOSP_TOOLCHAIN_PATH good # Only modify/export PATH if AOSP_TOOLCHAIN_PATH good
@ -278,10 +284,10 @@ fi
# Error checking # Error checking
if [ ! -d "$ANDROID_NDK_ROOT/platforms/$AOSP_API" ]; then if [ ! -d "$ANDROID_NDK_ROOT/platforms/$AOSP_API" ]; then
echo "ERROR: AOSP_API is not valid. Does the NDK support the API? Please edit this script." echo "ERROR: AOSP_API is not valid. Does the NDK support the API? Please edit this script."
[ "$0" = "$BASH_SOURCE" ] && exit 1 || return 1 [ "$0" = "${BASH_SOURCE[0]}" ] && exit 1 || return 1
elif [ ! -d "$ANDROID_NDK_ROOT/platforms/$AOSP_API/$AOSP_ARCH" ]; then elif [ ! -d "$ANDROID_NDK_ROOT/platforms/$AOSP_API/$AOSP_ARCH" ]; then
echo "ERROR: AOSP_ARCH is not valid. Does the NDK support the architecture? Please edit this script." echo "ERROR: AOSP_ARCH is not valid. Does the NDK support the architecture? Please edit this script."
[ "$0" = "$BASH_SOURCE" ] && exit 1 || return 1 [ "$0" = "${BASH_SOURCE[0]}" ] && exit 1 || return 1
fi fi
# Android SYSROOT. It will be used on the command line with --sysroot # Android SYSROOT. It will be used on the command line with --sysroot
@ -328,7 +334,7 @@ case "$THE_STL" in
echo WARNING: llvm is still in experimental state and migth not work as expected echo WARNING: llvm is still in experimental state and migth not work as expected
if [ ! -d "$LLVM_INCLUDE_DIR" ]; then if [ ! -d "$LLVM_INCLUDE_DIR" ]; then
echo "ERROR: Unable to locate include LLVM directory at $LLVM_INCLUDE_DIR -- has it moved since NDK r16beta1?" echo "ERROR: Unable to locate include LLVM directory at $LLVM_INCLUDE_DIR -- has it moved since NDK r16beta1?"
[ "$0" = "$BASH_SOURCE" ] && exit 1 || return 1 [ "$0" = "${BASH_SOURCE[0]}" ] && exit 1 || return 1
fi fi
AOSP_STL_INC="$LLVM_INCLUDE_DIR" AOSP_STL_INC="$LLVM_INCLUDE_DIR"
AOSP_STL_LIB="$ANDROID_NDK_ROOT/sources/cxx-stl/llvm-libc++/libs/$AOSP_ABI/libc++_static.a" AOSP_STL_LIB="$ANDROID_NDK_ROOT/sources/cxx-stl/llvm-libc++/libs/$AOSP_ABI/libc++_static.a"
@ -337,26 +343,26 @@ case "$THE_STL" in
echo WARNING: llvm is still in experimental state and migth not work as expected echo WARNING: llvm is still in experimental state and migth not work as expected
if [ ! -d "$LLVM_INCLUDE_DIR" ]; then if [ ! -d "$LLVM_INCLUDE_DIR" ]; then
echo "ERROR: Unable to locate LLVM include directory at $LLVM_INCLUDE_DIR -- has it moved since NDK r16beta1?" echo "ERROR: Unable to locate LLVM include directory at $LLVM_INCLUDE_DIR -- has it moved since NDK r16beta1?"
[ "$0" = "$BASH_SOURCE" ] && exit 1 || return 1 [ "$0" = "${BASH_SOURCE[0]}" ] && exit 1 || return 1
fi fi
AOSP_STL_INC="$LLVM_INCLUDE_DIR" AOSP_STL_INC="$LLVM_INCLUDE_DIR"
AOSP_STL_LIB="$ANDROID_NDK_ROOT/sources/cxx-stl/llvm-libc++/libs/$AOSP_ABI/libc++_shared.so" AOSP_STL_LIB="$ANDROID_NDK_ROOT/sources/cxx-stl/llvm-libc++/libs/$AOSP_ABI/libc++_shared.so"
;; ;;
*) *)
echo "ERROR: Unknown STL library $2" echo "ERROR: Unknown STL library $2"
[ "$0" = "$BASH_SOURCE" ] && exit 1 || return 1 [ "$0" = "${BASH_SOURCE[0]}" ] && exit 1 || return 1
esac esac
# Error checking # Error checking
if [ ! -d "$AOSP_STL_INC" ] || [ ! -e "$AOSP_STL_INC/memory" ]; then if [ ! -d "$AOSP_STL_INC" ] || [ ! -e "$AOSP_STL_INC/memory" ]; then
echo "ERROR: AOSP_STL_INC is not valid. Please edit this script." echo "ERROR: AOSP_STL_INC is not valid. Please edit this script."
[ "$0" = "$BASH_SOURCE" ] && exit 1 || return 1 [ "$0" = "${BASH_SOURCE[0]}" ] && exit 1 || return 1
fi fi
# Error checking # Error checking
if [ ! -e "$AOSP_STL_LIB" ]; then if [ ! -e "$AOSP_STL_LIB" ]; then
echo "ERROR: AOSP_STL_LIB is not valid. Please edit this script." echo "ERROR: AOSP_STL_LIB is not valid. Please edit this script."
[ "$0" = "$BASH_SOURCE" ] && exit 1 || return 1 [ "$0" = "${BASH_SOURCE[0]}" ] && exit 1 || return 1
fi fi
export AOSP_STL_INC export AOSP_STL_INC
@ -372,13 +378,13 @@ fi
if [[ ! -e "$ANDROID_NDK_ROOT/sources/android/cpufeatures/cpu-features.h" ]]; then if [[ ! -e "$ANDROID_NDK_ROOT/sources/android/cpufeatures/cpu-features.h" ]]; then
echo "ERROR: Unable to locate cpu-features.h" echo "ERROR: Unable to locate cpu-features.h"
[ "$0" = "$BASH_SOURCE" ] && exit 1 || return 1 [ "$0" = "${BASH_SOURCE[0]}" ] && exit 1 || return 1
fi fi
cp "$ANDROID_NDK_ROOT/sources/android/cpufeatures/cpu-features.h" . cp "$ANDROID_NDK_ROOT/sources/android/cpufeatures/cpu-features.h" .
if [[ ! -e "$ANDROID_NDK_ROOT/sources/android/cpufeatures/cpu-features.c" ]]; then if [[ ! -e "$ANDROID_NDK_ROOT/sources/android/cpufeatures/cpu-features.c" ]]; then
echo "ERROR: Unable to locate cpu-features.c" echo "ERROR: Unable to locate cpu-features.c"
[ "$0" = "$BASH_SOURCE" ] && exit 1 || return 1 [ "$0" = "${BASH_SOURCE[0]}" ] && exit 1 || return 1
fi fi
cp "$ANDROID_NDK_ROOT/sources/android/cpufeatures/cpu-features.c" . cp "$ANDROID_NDK_ROOT/sources/android/cpufeatures/cpu-features.c" .
@ -446,4 +452,4 @@ echo "shared object using 'HAS_SOLIB_VERSION=1 make -f GNUmakefile-cross'"
echo "*******************************************************************************" echo "*******************************************************************************"
echo echo
[ "$0" = "$BASH_SOURCE" ] && exit 0 || return 0 [ "$0" = "${BASH_SOURCE[0]}" ] && exit 0 || return 0

View File

@ -20,6 +20,12 @@
# set -eu # set -eu
# Sanity check
if [ "$0" = "${BASH_SOURCE[0]}" ]; then
echo "Please source this setenv script"
exit 0
fi
unset IS_CROSS_COMPILE unset IS_CROSS_COMPILE
unset IS_IOS unset IS_IOS
@ -39,7 +45,7 @@ unset CPP CC CXX LD AS AR RANLIB STRIP
# Similar to a "make clean" # Similar to a "make clean"
if [ x"${1-}" = "xunset" ]; then if [ x"${1-}" = "xunset" ]; then
echo "Unsetting script variables. PATH may remain tainted" echo "Unsetting script variables. PATH may remain tainted"
[ "$0" = "$BASH_SOURCE" ] && exit 0 || return 0 [ "$0" = "${BASH_SOURCE[0]}" ] && exit 0 || return 0
fi fi
# Set AOSP_TOOLCHAIN_SUFFIX to your preference of tools and STL library. # Set AOSP_TOOLCHAIN_SUFFIX to your preference of tools and STL library.
@ -90,7 +96,7 @@ fi
# Error checking # Error checking
if [ ! -d "$ANDROID_NDK_ROOT/toolchains" ]; then if [ ! -d "$ANDROID_NDK_ROOT/toolchains" ]; then
echo "ERROR: ANDROID_NDK_ROOT is not a valid path. Please set it." echo "ERROR: ANDROID_NDK_ROOT is not a valid path. Please set it."
[ "$0" = "$BASH_SOURCE" ] && exit 1 || return 1 [ "$0" = "${BASH_SOURCE[0]}" ] && exit 1 || return 1
fi fi
##################################################################### #####################################################################
@ -168,7 +174,7 @@ case "$THE_ARCH" in
;; ;;
*) *)
echo "ERROR: Unknown architecture $1" echo "ERROR: Unknown architecture $1"
[ "$0" = "$BASH_SOURCE" ] && exit 1 || return 1 [ "$0" = "${BASH_SOURCE[0]}" ] && exit 1 || return 1
;; ;;
esac esac
@ -204,48 +210,48 @@ done
# Error checking # Error checking
if [ -z "$AOSP_TOOLCHAIN_PATH" ] || [ ! -d "$AOSP_TOOLCHAIN_PATH" ]; then if [ -z "$AOSP_TOOLCHAIN_PATH" ] || [ ! -d "$AOSP_TOOLCHAIN_PATH" ]; then
echo "ERROR: AOSP_TOOLCHAIN_PATH is not valid. Please edit this script." echo "ERROR: AOSP_TOOLCHAIN_PATH is not valid. Please edit this script."
[ "$0" = "$BASH_SOURCE" ] && exit 1 || return 1 [ "$0" = "${BASH_SOURCE[0]}" ] && exit 1 || return 1
fi fi
# Error checking # Error checking
if [ ! -e "$AOSP_TOOLCHAIN_PATH/$CPP" ]; then if [ ! -e "$AOSP_TOOLCHAIN_PATH/$CPP" ]; then
echo "ERROR: Failed to find Android cpp. Please edit this script." echo "ERROR: Failed to find Android cpp. Please edit this script."
[ "$0" = "$BASH_SOURCE" ] && exit 1 || return 1 [ "$0" = "${BASH_SOURCE[0]}" ] && exit 1 || return 1
fi fi
# Error checking # Error checking
if [ ! -e "$AOSP_TOOLCHAIN_PATH/$CC" ]; then if [ ! -e "$AOSP_TOOLCHAIN_PATH/$CC" ]; then
echo "ERROR: Failed to find Android gcc. Please edit this script." echo "ERROR: Failed to find Android gcc. Please edit this script."
[ "$0" = "$BASH_SOURCE" ] && exit 1 || return 1 [ "$0" = "${BASH_SOURCE[0]}" ] && exit 1 || return 1
fi fi
if [ ! -e "$AOSP_TOOLCHAIN_PATH/$CXX" ]; then if [ ! -e "$AOSP_TOOLCHAIN_PATH/$CXX" ]; then
echo "ERROR: Failed to find Android g++. Please edit this script." echo "ERROR: Failed to find Android g++. Please edit this script."
[ "$0" = "$BASH_SOURCE" ] && exit 1 || return 1 [ "$0" = "${BASH_SOURCE[0]}" ] && exit 1 || return 1
fi fi
# Error checking # Error checking
if [ ! -e "$AOSP_TOOLCHAIN_PATH/$RANLIB" ]; then if [ ! -e "$AOSP_TOOLCHAIN_PATH/$RANLIB" ]; then
echo "ERROR: Failed to find Android ranlib. Please edit this script." echo "ERROR: Failed to find Android ranlib. Please edit this script."
[ "$0" = "$BASH_SOURCE" ] && exit 1 || return 1 [ "$0" = "${BASH_SOURCE[0]}" ] && exit 1 || return 1
fi fi
# Error checking # Error checking
if [ ! -e "$AOSP_TOOLCHAIN_PATH/$AR" ]; then if [ ! -e "$AOSP_TOOLCHAIN_PATH/$AR" ]; then
echo "ERROR: Failed to find Android ar. Please edit this script." echo "ERROR: Failed to find Android ar. Please edit this script."
[ "$0" = "$BASH_SOURCE" ] && exit 1 || return 1 [ "$0" = "${BASH_SOURCE[0]}" ] && exit 1 || return 1
fi fi
# Error checking # Error checking
if [ ! -e "$AOSP_TOOLCHAIN_PATH/$AS" ]; then if [ ! -e "$AOSP_TOOLCHAIN_PATH/$AS" ]; then
echo "ERROR: Failed to find Android as. Please edit this script." echo "ERROR: Failed to find Android as. Please edit this script."
[ "$0" = "$BASH_SOURCE" ] && exit 1 || return 1 [ "$0" = "${BASH_SOURCE[0]}" ] && exit 1 || return 1
fi fi
# Error checking # Error checking
if [ ! -e "$AOSP_TOOLCHAIN_PATH/$LD" ]; then if [ ! -e "$AOSP_TOOLCHAIN_PATH/$LD" ]; then
echo "ERROR: Failed to find Android ld. Please edit this script." echo "ERROR: Failed to find Android ld. Please edit this script."
[ "$0" = "$BASH_SOURCE" ] && exit 1 || return 1 [ "$0" = "${BASH_SOURCE[0]}" ] && exit 1 || return 1
fi fi
# Only modify/export PATH if AOSP_TOOLCHAIN_PATH good # Only modify/export PATH if AOSP_TOOLCHAIN_PATH good
@ -264,10 +270,10 @@ fi
# Error checking # Error checking
if [ ! -d "$ANDROID_NDK_ROOT/platforms/$AOSP_API" ]; then if [ ! -d "$ANDROID_NDK_ROOT/platforms/$AOSP_API" ]; then
echo "ERROR: AOSP_API is not valid. Does the NDK support the API? Please edit this script." echo "ERROR: AOSP_API is not valid. Does the NDK support the API? Please edit this script."
[ "$0" = "$BASH_SOURCE" ] && exit 1 || return 1 [ "$0" = "${BASH_SOURCE[0]}" ] && exit 1 || return 1
elif [ ! -d "$ANDROID_NDK_ROOT/platforms/$AOSP_API/$AOSP_ARCH" ]; then elif [ ! -d "$ANDROID_NDK_ROOT/platforms/$AOSP_API/$AOSP_ARCH" ]; then
echo "ERROR: AOSP_ARCH is not valid. Does the NDK support the architecture? Please edit this script." echo "ERROR: AOSP_ARCH is not valid. Does the NDK support the architecture? Please edit this script."
[ "$0" = "$BASH_SOURCE" ] && exit 1 || return 1 [ "$0" = "${BASH_SOURCE[0]}" ] && exit 1 || return 1
fi fi
# Android SYSROOT. It will be used on the command line with --sysroot # Android SYSROOT. It will be used on the command line with --sysroot
@ -312,7 +318,7 @@ case "$THE_STL" in
llvm-static) llvm-static)
if [ ! -d "$LLVM_INCLUDE_DIR" ]; then if [ ! -d "$LLVM_INCLUDE_DIR" ]; then
echo "ERROR: Unable to locate include LLVM directory at $LLVM_INCLUDE_DIR -- has it moved since NDK r16beta1?" echo "ERROR: Unable to locate include LLVM directory at $LLVM_INCLUDE_DIR -- has it moved since NDK r16beta1?"
[ "$0" = "$BASH_SOURCE" ] && exit 1 || return 1 [ "$0" = "${BASH_SOURCE[0]}" ] && exit 1 || return 1
fi fi
AOSP_STL_INC="$LLVM_INCLUDE_DIR" AOSP_STL_INC="$LLVM_INCLUDE_DIR"
AOSP_STL_LIB="$ANDROID_NDK_ROOT/sources/cxx-stl/llvm-libc++/libs/$AOSP_ABI/libc++_static.a" AOSP_STL_LIB="$ANDROID_NDK_ROOT/sources/cxx-stl/llvm-libc++/libs/$AOSP_ABI/libc++_static.a"
@ -320,26 +326,26 @@ case "$THE_STL" in
llvm|llvm-shared) llvm|llvm-shared)
if [ ! -d "$LLVM_INCLUDE_DIR" ]; then if [ ! -d "$LLVM_INCLUDE_DIR" ]; then
echo "ERROR: Unable to locate LLVM include directory at $LLVM_INCLUDE_DIR -- has it moved since NDK r16beta1?" echo "ERROR: Unable to locate LLVM include directory at $LLVM_INCLUDE_DIR -- has it moved since NDK r16beta1?"
[ "$0" = "$BASH_SOURCE" ] && exit 1 || return 1 [ "$0" = "${BASH_SOURCE[0]}" ] && exit 1 || return 1
fi fi
AOSP_STL_INC="$LLVM_INCLUDE_DIR" AOSP_STL_INC="$LLVM_INCLUDE_DIR"
AOSP_STL_LIB="$ANDROID_NDK_ROOT/sources/cxx-stl/llvm-libc++/libs/$AOSP_ABI/libc++_shared.so" AOSP_STL_LIB="$ANDROID_NDK_ROOT/sources/cxx-stl/llvm-libc++/libs/$AOSP_ABI/libc++_shared.so"
;; ;;
*) *)
echo "ERROR: Unknown STL library $2" echo "ERROR: Unknown STL library $2"
[ "$0" = "$BASH_SOURCE" ] && exit 1 || return 1 [ "$0" = "${BASH_SOURCE[0]}" ] && exit 1 || return 1
esac esac
# Error checking # Error checking
if [ ! -d "$AOSP_STL_INC" ] || [ ! -e "$AOSP_STL_INC/memory" ]; then if [ ! -d "$AOSP_STL_INC" ] || [ ! -e "$AOSP_STL_INC/memory" ]; then
echo "ERROR: AOSP_STL_INC is not valid. Please edit this script." echo "ERROR: AOSP_STL_INC is not valid. Please edit this script."
[ "$0" = "$BASH_SOURCE" ] && exit 1 || return 1 [ "$0" = "${BASH_SOURCE[0]}" ] && exit 1 || return 1
fi fi
# Error checking # Error checking
if [ ! -e "$AOSP_STL_LIB" ]; then if [ ! -e "$AOSP_STL_LIB" ]; then
echo "ERROR: AOSP_STL_LIB is not valid. Please edit this script." echo "ERROR: AOSP_STL_LIB is not valid. Please edit this script."
[ "$0" = "$BASH_SOURCE" ] && exit 1 || return 1 [ "$0" = "${BASH_SOURCE[0]}" ] && exit 1 || return 1
fi fi
export AOSP_STL_INC export AOSP_STL_INC
@ -355,13 +361,13 @@ fi
if [[ ! -e "$ANDROID_NDK_ROOT/sources/android/cpufeatures/cpu-features.h" ]]; then if [[ ! -e "$ANDROID_NDK_ROOT/sources/android/cpufeatures/cpu-features.h" ]]; then
echo "ERROR: Unable to locate cpu-features.h" echo "ERROR: Unable to locate cpu-features.h"
[ "$0" = "$BASH_SOURCE" ] && exit 1 || return 1 [ "$0" = "${BASH_SOURCE[0]}" ] && exit 1 || return 1
fi fi
cp "$ANDROID_NDK_ROOT/sources/android/cpufeatures/cpu-features.h" . cp "$ANDROID_NDK_ROOT/sources/android/cpufeatures/cpu-features.h" .
if [[ ! -e "$ANDROID_NDK_ROOT/sources/android/cpufeatures/cpu-features.c" ]]; then if [[ ! -e "$ANDROID_NDK_ROOT/sources/android/cpufeatures/cpu-features.c" ]]; then
echo "ERROR: Unable to locate cpu-features.c" echo "ERROR: Unable to locate cpu-features.c"
[ "$0" = "$BASH_SOURCE" ] && exit 1 || return 1 [ "$0" = "${BASH_SOURCE[0]}" ] && exit 1 || return 1
fi fi
cp "$ANDROID_NDK_ROOT/sources/android/cpufeatures/cpu-features.c" . cp "$ANDROID_NDK_ROOT/sources/android/cpufeatures/cpu-features.c" .
@ -427,4 +433,4 @@ echo "shared object using 'HAS_SOLIB_VERSION=1 make -f GNUmakefile-cross'"
echo "*******************************************************************************" echo "*******************************************************************************"
echo echo
[ "$0" = "$BASH_SOURCE" ] && exit 0 || return 0 [ "$0" = "${BASH_SOURCE[0]}" ] && exit 0 || return 0

View File

@ -15,6 +15,12 @@
# set -eu # set -eu
# Sanity check
if [ "$0" = "${BASH_SOURCE[0]}" ]; then
echo "Please source this setenv script"
exit 0
fi
# Unset old options # Unset old options
unset IS_CROSS_COMPILE unset IS_CROSS_COMPILE
@ -29,7 +35,7 @@ fi
if [ ! -d "$ARM_EMBEDDED_TOOLCHAIN" ]; then if [ ! -d "$ARM_EMBEDDED_TOOLCHAIN" ]; then
echo "ARM_EMBEDDED_TOOLCHAIN is not valid" echo "ARM_EMBEDDED_TOOLCHAIN is not valid"
[ "$0" = "$BASH_SOURCE" ] && exit 1 || return 1 [ "$0" = "${BASH_SOURCE[0]}" ] && exit 1 || return 1
fi fi
# Fedora # Fedora
@ -50,37 +56,37 @@ export RANLIB="$ARM_EMBEDDED_TOOLCHAIN/$TOOL_PREFIX-ranlib"
# Test a few of the tools # Test a few of the tools
if [ ! -e "$CPP" ]; then if [ ! -e "$CPP" ]; then
echo "ERROR: CPP is not valid" echo "ERROR: CPP is not valid"
[ "$0" = "$BASH_SOURCE" ] && exit 1 || return 1 [ "$0" = "${BASH_SOURCE[0]}" ] && exit 1 || return 1
fi fi
if [ ! -e "$CC" ]; then if [ ! -e "$CC" ]; then
echo "ERROR: CC is not valid" echo "ERROR: CC is not valid"
[ "$0" = "$BASH_SOURCE" ] && exit 1 || return 1 [ "$0" = "${BASH_SOURCE[0]}" ] && exit 1 || return 1
fi fi
if [ ! -e "$CXX" ]; then if [ ! -e "$CXX" ]; then
echo "ERROR: CXX is not valid" echo "ERROR: CXX is not valid"
[ "$0" = "$BASH_SOURCE" ] && exit 1 || return 1 [ "$0" = "${BASH_SOURCE[0]}" ] && exit 1 || return 1
fi fi
if [ ! -e "$AR" ]; then if [ ! -e "$AR" ]; then
echo "ERROR: AR is not valid" echo "ERROR: AR is not valid"
[ "$0" = "$BASH_SOURCE" ] && exit 1 || return 1 [ "$0" = "${BASH_SOURCE[0]}" ] && exit 1 || return 1
fi fi
if [ ! -e "$AS" ]; then if [ ! -e "$AS" ]; then
echo "ERROR: AS is not valid" echo "ERROR: AS is not valid"
[ "$0" = "$BASH_SOURCE" ] && exit 1 || return 1 [ "$0" = "${BASH_SOURCE[0]}" ] && exit 1 || return 1
fi fi
if [ ! -e "$RANLIB" ]; then if [ ! -e "$RANLIB" ]; then
echo "ERROR: RANLIB is not valid" echo "ERROR: RANLIB is not valid"
[ "$0" = "$BASH_SOURCE" ] && exit 1 || return 1 [ "$0" = "${BASH_SOURCE[0]}" ] && exit 1 || return 1
fi fi
if [ ! -e "$LD" ]; then if [ ! -e "$LD" ]; then
echo "ERROR: LD is not valid" echo "ERROR: LD is not valid"
[ "$0" = "$BASH_SOURCE" ] && exit 1 || return 1 [ "$0" = "${BASH_SOURCE[0]}" ] && exit 1 || return 1
fi fi
# The Crypto++ Makefile uses these to disable host settings like # The Crypto++ Makefile uses these to disable host settings like
@ -94,7 +100,7 @@ fi
if [ ! -d "$ARM_EMBEDDED_SYSROOT" ]; then if [ ! -d "$ARM_EMBEDDED_SYSROOT" ]; then
echo "ERROR: ARM_EMBEDDED_SYSROOT is not valid" echo "ERROR: ARM_EMBEDDED_SYSROOT is not valid"
[ "$0" = "$BASH_SOURCE" ] && exit 1 || return 1 [ "$0" = "${BASH_SOURCE[0]}" ] && exit 1 || return 1
fi fi
# Fix C++ header paths for Ubuntu # Fix C++ header paths for Ubuntu
@ -104,12 +110,12 @@ ARM_EMBEDDED_CXX_HEADERS="$ARM_EMBEDDED_SYSROOT/include/c++/$ARM_EMBEDDED_TOOLCH
if [ ! -d "$ARM_EMBEDDED_CXX_HEADERS" ]; then if [ ! -d "$ARM_EMBEDDED_CXX_HEADERS" ]; then
echo "ERROR: ARM_EMBEDDED_CXX_HEADERS is not valid" echo "ERROR: ARM_EMBEDDED_CXX_HEADERS is not valid"
[ "$0" = "$BASH_SOURCE" ] && exit 1 || return 1 [ "$0" = "${BASH_SOURCE[0]}" ] && exit 1 || return 1
fi fi
if [ ! -d "$ARM_EMBEDDED_CXX_HEADERS/arm-linux-gnueabi" ]; then if [ ! -d "$ARM_EMBEDDED_CXX_HEADERS/arm-linux-gnueabi" ]; then
echo "ERROR: ARM_EMBEDDED_CXX_HEADERS is not valid" echo "ERROR: ARM_EMBEDDED_CXX_HEADERS is not valid"
[ "$0" = "$BASH_SOURCE" ] && exit 1 || return 1 [ "$0" = "${BASH_SOURCE[0]}" ] && exit 1 || return 1
fi fi
# Finally, the flags... # Finally, the flags...
@ -142,4 +148,4 @@ echo "shared object using 'HAS_SOLIB_VERSION=1 make -f GNUmakefile-cross'"
echo "*******************************************************************************" echo "*******************************************************************************"
echo echo
[ "$0" = "$BASH_SOURCE" ] && exit 0 || return 0 [ "$0" = "${BASH_SOURCE[0]}" ] && exit 0 || return 0

View File

@ -13,6 +13,12 @@
# set -eu # set -eu
# Sanity check
if [ "$0" = "${BASH_SOURCE[0]}" ]; then
echo "Please source this setenv script"
exit 0
fi
######################################### #########################################
##### Clear old options ##### ##### Clear old options #####
######################################### #########################################
@ -149,7 +155,7 @@ fi
if [ ! -d "$XCODE_DEVELOPER" ]; then if [ ! -d "$XCODE_DEVELOPER" ]; then
echo "ERROR: unable to find XCODE_DEVELOPER directory." echo "ERROR: unable to find XCODE_DEVELOPER directory."
[ "$0" = "$BASH_SOURCE" ] && exit 1 || return 1 [ "$0" = "${BASH_SOURCE[0]}" ] && exit 1 || return 1
fi fi
# Default toolchain location # Default toolchain location
@ -157,7 +163,7 @@ XCODE_TOOLCHAIN="$XCODE_DEVELOPER/usr/bin"
if [ ! -d "$XCODE_TOOLCHAIN" ]; then if [ ! -d "$XCODE_TOOLCHAIN" ]; then
echo "ERROR: unable to find XCODE_TOOLCHAIN directory." echo "ERROR: unable to find XCODE_TOOLCHAIN directory."
[ "$0" = "$BASH_SOURCE" ] && exit 1 || return 1 [ "$0" = "${BASH_SOURCE[0]}" ] && exit 1 || return 1
fi fi
# XCODE_DEVELOPER_TOP is the top of the development tools tree # XCODE_DEVELOPER_TOP is the top of the development tools tree
@ -165,7 +171,7 @@ XCODE_DEVELOPER_TOP="$XCODE_DEVELOPER/Platforms/$APPLE_SDK.platform/Developer"
if [ ! -d "$XCODE_DEVELOPER_TOP" ]; then if [ ! -d "$XCODE_DEVELOPER_TOP" ]; then
echo "ERROR: unable to find XCODE_DEVELOPER_TOP directory." echo "ERROR: unable to find XCODE_DEVELOPER_TOP directory."
[ "$0" = "$BASH_SOURCE" ] && exit 1 || return 1 [ "$0" = "${BASH_SOURCE[0]}" ] && exit 1 || return 1
fi fi
# IOS_TOOLCHAIN is the location of the actual compiler tools. # IOS_TOOLCHAIN is the location of the actual compiler tools.
@ -177,7 +183,7 @@ fi
if [ -z "$IOS_TOOLCHAIN" ] || [ ! -d "$IOS_TOOLCHAIN" ]; then if [ -z "$IOS_TOOLCHAIN" ] || [ ! -d "$IOS_TOOLCHAIN" ]; then
echo "ERROR: unable to find Xcode cross-compiler tools." echo "ERROR: unable to find Xcode cross-compiler tools."
[ "$0" = "$BASH_SOURCE" ] && exit 1 || return 1 [ "$0" = "${BASH_SOURCE[0]}" ] && exit 1 || return 1
fi fi
# #
@ -196,7 +202,7 @@ done
# Error checking # Error checking
if [ -z "$XCODE_SDK" ]; then if [ -z "$XCODE_SDK" ]; then
echo "ERROR: unable to find a SDK." echo "ERROR: unable to find a SDK."
[ "$0" = "$BASH_SOURCE" ] && exit 1 || return 1 [ "$0" = "${BASH_SOURCE[0]}" ] && exit 1 || return 1
fi fi
# https://github.com/weidai11/cryptopp/issues/635 # https://github.com/weidai11/cryptopp/issues/635
@ -237,7 +243,7 @@ fi
# https://stackoverflow.com/q/24841283/608639 # https://stackoverflow.com/q/24841283/608639
# -tvos_simulator_version_min does not work though it is in LLVM sources. # -tvos_simulator_version_min does not work though it is in LLVM sources.
if [ "$APPLE_SDK" == "AppleTVSimulator" ]; then if [ "$APPLE_SDK" == "AppleTVSimulator" ]; then
IOS_FLAGS="$IOS_FLAGS -tvos_simulator_version_min -DCRYPTOPP_DISABLE_ASM" IOS_FLAGS="$IOS_FLAGS -DCRYPTOPP_DISABLE_ASM"
fi fi
# Simulator uses i386 or x86_64, Device uses ARMv5, ARMv6, ARMv7, ARMv7s or ARMv8 # Simulator uses i386 or x86_64, Device uses ARMv5, ARMv6, ARMv7, ARMv7s or ARMv8
@ -285,7 +291,7 @@ if [ ! -z "$IOS_TOOLCHAIN" ] && [ ! -z "$XCODE_TOOLCHAIN" ]; then
fi fi
else else
echo "ERROR: unable to set new PATH." echo "ERROR: unable to set new PATH."
[ "$0" = "$BASH_SOURCE" ] && exit 1 || return 1 [ "$0" = "${BASH_SOURCE[0]}" ] && exit 1 || return 1
fi fi
######################################## ########################################
@ -307,7 +313,7 @@ do
done done
if [ "$FOUND_ALL" -eq "0" ]; then if [ "$FOUND_ALL" -eq "0" ]; then
[ "$0" = "$BASH_SOURCE" ] && exit 1 || return 1 [ "$0" = "${BASH_SOURCE[0]}" ] && exit 1 || return 1
fi fi
# Exports added for Autotools. GNUmakefile-cross does not use them. # Exports added for Autotools. GNUmakefile-cross does not use them.
@ -329,4 +335,4 @@ echo "shared object using 'HAS_SOLIB_VERSION=1 make -f GNUmakefile-cross'"
echo "*******************************************************************************" echo "*******************************************************************************"
echo echo
[ "$0" = "$BASH_SOURCE" ] && exit 0 || return 0 [ "$0" = "${BASH_SOURCE[0]}" ] && exit 0 || return 0

View File

@ -49,6 +49,7 @@ Test: TestVectors/sha.txt
Test: TestVectors/simeck.txt Test: TestVectors/simeck.txt
Test: TestVectors/simon.txt Test: TestVectors/simon.txt
Test: TestVectors/siphash.txt Test: TestVectors/siphash.txt
Test: TestVectors/skipjack.txt
Test: TestVectors/sm3.txt Test: TestVectors/sm3.txt
Test: TestVectors/sm4.txt Test: TestVectors/sm4.txt
Test: TestVectors/sosemanuk.txt Test: TestVectors/sosemanuk.txt

1046
TestVectors/skipjack.txt Normal file

File diff suppressed because it is too large Load Diff

View File

@ -355,9 +355,7 @@ inline size_t AdvancedProcessBlocks128_6x1_NEON(F1 func1, F6 func6,
CRYPTOPP_ASSERT(length >= 16); CRYPTOPP_ASSERT(length >= 16);
const unsigned int w_one[] = {0, 0<<24, 0, 1<<24}; const unsigned int w_one[] = {0, 0<<24, 0, 1<<24};
const unsigned int w_two[] = {0, 2<<24, 0, 2<<24};
const uint32x4_t s_one = vld1q_u32(w_one); const uint32x4_t s_one = vld1q_u32(w_one);
const uint32x4_t s_two = vld1q_u32(w_two);
const size_t blockSize = 16; const size_t blockSize = 16;
// const size_t neonBlockSize = 16; // const size_t neonBlockSize = 16;
@ -511,9 +509,7 @@ inline size_t AdvancedProcessBlocks128_4x1_NEON(F1 func1, F4 func4,
CRYPTOPP_ASSERT(length >= 16); CRYPTOPP_ASSERT(length >= 16);
const unsigned int w_one[] = {0, 0<<24, 0, 1<<24}; const unsigned int w_one[] = {0, 0<<24, 0, 1<<24};
const unsigned int w_two[] = {0, 2<<24, 0, 2<<24};
const uint32x4_t s_one = vld1q_u32(w_one); const uint32x4_t s_one = vld1q_u32(w_one);
const uint32x4_t s_two = vld1q_u32(w_two);
const size_t blockSize = 16; const size_t blockSize = 16;
// const size_t neonBlockSize = 16; // const size_t neonBlockSize = 16;
@ -647,9 +643,7 @@ inline size_t AdvancedProcessBlocks128_6x2_NEON(F2 func2, F6 func6,
CRYPTOPP_ASSERT(length >= 16); CRYPTOPP_ASSERT(length >= 16);
const unsigned int w_one[] = {0, 0<<24, 0, 1<<24}; const unsigned int w_one[] = {0, 0<<24, 0, 1<<24};
const unsigned int w_two[] = {0, 2<<24, 0, 2<<24};
const uint32x4_t s_one = vld1q_u32(w_one); const uint32x4_t s_one = vld1q_u32(w_one);
const uint32x4_t s_two = vld1q_u32(w_two);
const size_t blockSize = 16; const size_t blockSize = 16;
// const size_t neonBlockSize = 16; // const size_t neonBlockSize = 16;

View File

@ -7,31 +7,6 @@
@ details see http://www.openssl.org/~appro/cryptogams/. @ details see http://www.openssl.org/~appro/cryptogams/.
@ ==================================================================== @ ====================================================================
@ AES for ARMv4
@ January 2007.
@
@ Code uses single 1K S-box and is >2 times faster than code generated
@ by gcc-3.4.1. This is thanks to unique feature of ARMv4 ISA, which
@ allows to merge logical or arithmetic operation with shift or rotate
@ in one instruction and emit combined result every cycle. The module
@ is endian-neutral. The performance is ~42 cycles/byte for 128-bit
@ key [on single-issue Xscale PXA250 core].
@ May 2007.
@
@ AES_set_[en|de]crypt_key is added.
@ July 2010.
@
@ Rescheduling for dual-issue pipeline resulted in 12% improvement on
@ Cortex A8 core and ~25 cycles per byte processed with 128-bit key.
@ February 2011.
@
@ Profiler-assisted and platform-specific optimization resulted in 16%
@ improvement on Cortex A8 core and ~21.5 cycles per byte.
@ JW, JUL 2018: Begin defines from taken from arm_arch.h @ JW, JUL 2018: Begin defines from taken from arm_arch.h
@ The defines were included through the header. @ The defines were included through the header.
@ -92,7 +67,6 @@
@ JW, JUL 2018: End defines from taken from arm_arch.h @ JW, JUL 2018: End defines from taken from arm_arch.h
@ Back to original Cryptogams code @ Back to original Cryptogams code
.text
#if defined(__thumb2__) && !defined(__APPLE__) #if defined(__thumb2__) && !defined(__APPLE__)
.syntax unified .syntax unified
.thumb .thumb
@ -101,6 +75,8 @@
#undef __thumb2__ #undef __thumb2__
#endif #endif
.text
.type AES_Te,%object .type AES_Te,%object
.align 5 .align 5
AES_Te: AES_Te:
@ -1237,6 +1213,3 @@ _armv4_AES_decrypt:
sub r10,r10,#1024 sub r10,r10,#1024
ldr pc,[sp],#4 @ pop and return ldr pc,[sp],#4 @ pop and return
.size _armv4_AES_decrypt,.-_armv4_AES_decrypt .size _armv4_AES_decrypt,.-_armv4_AES_decrypt
.byte 65,69,83,32,102,111,114,32,65,82,77,118,52,44,32,67,82,89,80,84,79,71,65,77,83,32,98,121,32,60,97,112,112,114,111,64,111,112,101,110,115,115,108,46,111,114,103,62,0
.align 2
.align 2

View File

@ -320,10 +320,12 @@ public:
if (m_throwIfNotUsed && !m_used) if (m_throwIfNotUsed && !m_used)
throw ParameterNotUsed(m_name); throw ParameterNotUsed(m_name);
} }
#if !defined(CRYPTOPP_CXX17_EXCEPTIONS) && !defined(CRYPTOPP_UNCAUGHT_EXCEPTION_AVAILABLE) #if !defined(CRYPTOPP_UNCAUGHT_EXCEPTION_AVAILABLE)
# if !defined(CRYPTOPP_CXX17_EXCEPTIONS)
catch(const Exception&) catch(const Exception&)
{ {
} }
# endif
#endif #endif
} }

View File

@ -24,7 +24,7 @@
# include <arm_acle.h> # include <arm_acle.h>
#endif #endif
// Clang __m128i casts, http://bugs.llvm.org/show_bug.cgi?id=20670 // Clang intrinsic casts, http://bugs.llvm.org/show_bug.cgi?id=20670
#define M128_CAST(x) ((__m128i *)(void *)(x)) #define M128_CAST(x) ((__m128i *)(void *)(x))
#define CONST_M128_CAST(x) ((const __m128i *)(const void *)(x)) #define CONST_M128_CAST(x) ((const __m128i *)(const void *)(x))

19
asn.cpp
View File

@ -394,14 +394,20 @@ void EncodedObjectFilter::Put(const byte *inString, size_t length)
} }
} }
BERGeneralDecoder::BERGeneralDecoder(BufferedTransformation &inQueue)
: m_inQueue(inQueue), m_length(0), m_finished(false)
{
Init(DefaultTag);
}
BERGeneralDecoder::BERGeneralDecoder(BufferedTransformation &inQueue, byte asnTag) BERGeneralDecoder::BERGeneralDecoder(BufferedTransformation &inQueue, byte asnTag)
: m_inQueue(inQueue), m_finished(false) : m_inQueue(inQueue), m_length(0), m_finished(false)
{ {
Init(asnTag); Init(asnTag);
} }
BERGeneralDecoder::BERGeneralDecoder(BERGeneralDecoder &inQueue, byte asnTag) BERGeneralDecoder::BERGeneralDecoder(BERGeneralDecoder &inQueue, byte asnTag)
: m_inQueue(inQueue), m_finished(false) : m_inQueue(inQueue), m_length(0), m_finished(false)
{ {
Init(asnTag); Init(asnTag);
} }
@ -501,13 +507,18 @@ lword BERGeneralDecoder::ReduceLength(lword delta)
return delta; return delta;
} }
DERGeneralEncoder::DERGeneralEncoder(BufferedTransformation &outQueue)
: m_outQueue(outQueue), m_asnTag(DefaultTag), m_finished(false)
{
}
DERGeneralEncoder::DERGeneralEncoder(BufferedTransformation &outQueue, byte asnTag) DERGeneralEncoder::DERGeneralEncoder(BufferedTransformation &outQueue, byte asnTag)
: ByteQueue(), m_outQueue(outQueue), m_asnTag(asnTag), m_finished(false) : m_outQueue(outQueue), m_asnTag(asnTag), m_finished(false)
{ {
} }
DERGeneralEncoder::DERGeneralEncoder(DERGeneralEncoder &outQueue, byte asnTag) DERGeneralEncoder::DERGeneralEncoder(DERGeneralEncoder &outQueue, byte asnTag)
: ByteQueue(), m_outQueue(outQueue), m_asnTag(asnTag), m_finished(false) : m_outQueue(outQueue), m_asnTag(asnTag), m_finished(false)
{ {
} }

210
asn.h
View File

@ -258,21 +258,99 @@ private:
class CRYPTOPP_DLL BERGeneralDecoder : public Store class CRYPTOPP_DLL BERGeneralDecoder : public Store
{ {
public: public:
/// \brief Default ASN.1 tag
enum {DefaultTag = SEQUENCE | CONSTRUCTED};
virtual ~BERGeneralDecoder(); virtual ~BERGeneralDecoder();
/// \brief Construct an ASN.1 decoder
/// \param inQueue input byte queue
/// \details BERGeneralDecoder uses DefaultTag
explicit BERGeneralDecoder(BufferedTransformation &inQueue);
/// \brief Construct an ASN.1 decoder
/// \param inQueue input byte queue
/// \param asnTag ASN.1 tag
explicit BERGeneralDecoder(BufferedTransformation &inQueue, byte asnTag); explicit BERGeneralDecoder(BufferedTransformation &inQueue, byte asnTag);
/// \brief Construct an ASN.1 decoder
/// \param inQueue input byte queue
/// \param asnTag ASN.1 tag
explicit BERGeneralDecoder(BERGeneralDecoder &inQueue, byte asnTag); explicit BERGeneralDecoder(BERGeneralDecoder &inQueue, byte asnTag);
bool IsDefiniteLength() const {return m_definiteLength;} /// \brief Determine length encoding
lword RemainingLength() const {CRYPTOPP_ASSERT(m_definiteLength); return m_length;} /// \returns true if the ASN.1 object is definite length encoded, false otherwise
bool IsDefiniteLength() const {
return m_definiteLength;
}
/// \brief Determine remaining length
/// \returns number of octets that remain to be consumed
/// \details RemainingLength() is only valid if IsDefiniteLength()
/// returns true.
lword RemainingLength() const {
CRYPTOPP_ASSERT(m_definiteLength);
return IsDefiniteLength() ? m_length : 0;
}
/// \brief Determine end of stream
/// \returns true if all octets have been consumed, false otherwise
bool EndReached() const; bool EndReached() const;
/// \brief Determine next octet
/// \returns next octet in the stream
/// \details PeekByte does not consume the octet.
/// \throws BERDecodeError if there are no octets remaining
byte PeekByte() const; byte PeekByte() const;
/// \brief Determine next octet
/// \details CheckByte reads the next byte in the stream and verifies
/// the octet matches b.
/// \throws BERDecodeError if the next octet is not b
void CheckByte(byte b); void CheckByte(byte b);
/// \brief Transfer bytes to another BufferedTransformation
/// \param target the destination BufferedTransformation
/// \param transferBytes the number of bytes to transfer
/// \param channel the channel on which the transfer should occur
/// \param blocking specifies whether the object should block when
/// processing input
/// \return the number of bytes that remain in the transfer block
/// (i.e., bytes not transferred)
/// \details TransferTo2() removes bytes and moves
/// them to the destination. Transfer begins at the index position
/// in the current stream, and not from an absolute position in the
/// stream.
/// \details transferBytes is an \a IN and \a OUT parameter. When
/// the call is made, transferBytes is the requested size of the
/// transfer. When the call returns, transferBytes is the number
/// of bytes that were transferred.
size_t TransferTo2(BufferedTransformation &target, lword &transferBytes, const std::string &channel=DEFAULT_CHANNEL, bool blocking=true); size_t TransferTo2(BufferedTransformation &target, lword &transferBytes, const std::string &channel=DEFAULT_CHANNEL, bool blocking=true);
/// \brief Copy bytes to another BufferedTransformation
/// \param target the destination BufferedTransformation
/// \param begin the 0-based index of the first byte to copy in
/// the stream
/// \param end the 0-based index of the last byte to copy in
/// the stream
/// \param channel the channel on which the transfer should occur
/// \param blocking specifies whether the object should block when
/// processing input
/// \return the number of bytes that remain in the copy block
/// (i.e., bytes not copied)
/// \details CopyRangeTo2 copies bytes to the
/// destination. The bytes are not removed from this object. Copying
/// begins at the index position in the current stream, and not from
/// an absolute position in the stream.
/// \details begin is an \a IN and \a OUT parameter. When the call is
/// made, begin is the starting position of the copy. When the call
/// returns, begin is the position of the first byte that was \a not
/// copied (which may be different than end). begin can be used for
/// subsequent calls to CopyRangeTo2().
size_t CopyRangeTo2(BufferedTransformation &target, lword &begin, lword end=LWORD_MAX, const std::string &channel=DEFAULT_CHANNEL, bool blocking=true) const; size_t CopyRangeTo2(BufferedTransformation &target, lword &begin, lword end=LWORD_MAX, const std::string &channel=DEFAULT_CHANNEL, bool blocking=true) const;
// call this to denote end of sequence /// \brief Signals the end of messages to the object
/// \details Call this to denote end of sequence
void MessageEnd(); void MessageEnd();
protected: protected:
@ -291,12 +369,28 @@ private:
class CRYPTOPP_DLL DERGeneralEncoder : public ByteQueue class CRYPTOPP_DLL DERGeneralEncoder : public ByteQueue
{ {
public: public:
/// \brief Default ASN.1 tag
enum {DefaultTag = SEQUENCE | CONSTRUCTED};
virtual ~DERGeneralEncoder(); virtual ~DERGeneralEncoder();
explicit DERGeneralEncoder(BufferedTransformation &outQueue, byte asnTag = SEQUENCE | CONSTRUCTED); /// \brief Construct an ASN.1 encoder
explicit DERGeneralEncoder(DERGeneralEncoder &outQueue, byte asnTag = SEQUENCE | CONSTRUCTED); /// \param outQueue output byte queue
/// \details DERGeneralEncoder uses DefaultTag
explicit DERGeneralEncoder(BufferedTransformation &outQueue);
// call this to denote end of sequence /// \brief Construct an ASN.1 encoder
/// \param outQueue output byte queue
/// \param asnTag ASN.1 tag
explicit DERGeneralEncoder(BufferedTransformation &outQueue, byte asnTag);
/// \brief Construct an ASN.1 encoder
/// \param outQueue output byte queue
/// \param asnTag ASN.1 tag
explicit DERGeneralEncoder(DERGeneralEncoder &outQueue, byte asnTag);
/// \brief Signals the end of messages to the object
/// \details Call this to denote end of sequence
void MessageEnd(); void MessageEnd();
private: private:
@ -309,9 +403,31 @@ private:
class CRYPTOPP_DLL BERSequenceDecoder : public BERGeneralDecoder class CRYPTOPP_DLL BERSequenceDecoder : public BERGeneralDecoder
{ {
public: public:
explicit BERSequenceDecoder(BufferedTransformation &inQueue, byte asnTag = SEQUENCE | CONSTRUCTED) /// \brief Default ASN.1 tag
enum {DefaultTag = SEQUENCE | CONSTRUCTED};
/// \brief Construct an ASN.1 decoder
/// \param inQueue input byte queue
/// \details BERSequenceDecoder uses DefaultTag
explicit BERSequenceDecoder(BufferedTransformation &inQueue)
: BERGeneralDecoder(inQueue, DefaultTag) {}
/// \brief Construct an ASN.1 decoder
/// \param inQueue input byte queue
/// \param asnTag ASN.1 tag
explicit BERSequenceDecoder(BufferedTransformation &inQueue, byte asnTag)
: BERGeneralDecoder(inQueue, asnTag) {} : BERGeneralDecoder(inQueue, asnTag) {}
explicit BERSequenceDecoder(BERSequenceDecoder &inQueue, byte asnTag = SEQUENCE | CONSTRUCTED)
/// \brief Construct an ASN.1 decoder
/// \param inQueue input byte queue
/// \details BERSequenceDecoder uses DefaultTag
explicit BERSequenceDecoder(BERSequenceDecoder &inQueue)
: BERGeneralDecoder(inQueue, DefaultTag) {}
/// \brief Construct an ASN.1 decoder
/// \param inQueue input byte queue
/// \param asnTag ASN.1 tag
explicit BERSequenceDecoder(BERSequenceDecoder &inQueue, byte asnTag)
: BERGeneralDecoder(inQueue, asnTag) {} : BERGeneralDecoder(inQueue, asnTag) {}
}; };
@ -319,9 +435,31 @@ public:
class CRYPTOPP_DLL DERSequenceEncoder : public DERGeneralEncoder class CRYPTOPP_DLL DERSequenceEncoder : public DERGeneralEncoder
{ {
public: public:
explicit DERSequenceEncoder(BufferedTransformation &outQueue, byte asnTag = SEQUENCE | CONSTRUCTED) /// \brief Default ASN.1 tag
enum {DefaultTag = SEQUENCE | CONSTRUCTED};
/// \brief Construct an ASN.1 encoder
/// \param outQueue output byte queue
/// \details DERSequenceEncoder uses DefaultTag
explicit DERSequenceEncoder(BufferedTransformation &outQueue)
: DERGeneralEncoder(outQueue, DefaultTag) {}
/// \brief Construct an ASN.1 encoder
/// \param outQueue output byte queue
/// \param asnTag ASN.1 tag
explicit DERSequenceEncoder(BufferedTransformation &outQueue, byte asnTag)
: DERGeneralEncoder(outQueue, asnTag) {} : DERGeneralEncoder(outQueue, asnTag) {}
explicit DERSequenceEncoder(DERSequenceEncoder &outQueue, byte asnTag = SEQUENCE | CONSTRUCTED)
/// \brief Construct an ASN.1 encoder
/// \param outQueue output byte queue
/// \details DERSequenceEncoder uses DefaultTag
explicit DERSequenceEncoder(DERSequenceEncoder &outQueue)
: DERGeneralEncoder(outQueue, DefaultTag) {}
/// \brief Construct an ASN.1 encoder
/// \param outQueue output byte queue
/// \param asnTag ASN.1 tag
explicit DERSequenceEncoder(DERSequenceEncoder &outQueue, byte asnTag)
: DERGeneralEncoder(outQueue, asnTag) {} : DERGeneralEncoder(outQueue, asnTag) {}
}; };
@ -329,9 +467,31 @@ public:
class CRYPTOPP_DLL BERSetDecoder : public BERGeneralDecoder class CRYPTOPP_DLL BERSetDecoder : public BERGeneralDecoder
{ {
public: public:
explicit BERSetDecoder(BufferedTransformation &inQueue, byte asnTag = SET | CONSTRUCTED) /// \brief Default ASN.1 tag
enum {DefaultTag = SET | CONSTRUCTED};
/// \brief Construct an ASN.1 decoder
/// \param inQueue input byte queue
/// \details BERSetDecoder uses DefaultTag
explicit BERSetDecoder(BufferedTransformation &inQueue)
: BERGeneralDecoder(inQueue, DefaultTag) {}
/// \brief Construct an ASN.1 decoder
/// \param inQueue input byte queue
/// \param asnTag ASN.1 tag
explicit BERSetDecoder(BufferedTransformation &inQueue, byte asnTag)
: BERGeneralDecoder(inQueue, asnTag) {} : BERGeneralDecoder(inQueue, asnTag) {}
explicit BERSetDecoder(BERSetDecoder &inQueue, byte asnTag = SET | CONSTRUCTED)
/// \brief Construct an ASN.1 decoder
/// \param inQueue input byte queue
/// \details BERSetDecoder uses DefaultTag
explicit BERSetDecoder(BERSetDecoder &inQueue)
: BERGeneralDecoder(inQueue, DefaultTag) {}
/// \brief Construct an ASN.1 decoder
/// \param inQueue input byte queue
/// \param asnTag ASN.1 tag
explicit BERSetDecoder(BERSetDecoder &inQueue, byte asnTag)
: BERGeneralDecoder(inQueue, asnTag) {} : BERGeneralDecoder(inQueue, asnTag) {}
}; };
@ -339,9 +499,31 @@ public:
class CRYPTOPP_DLL DERSetEncoder : public DERGeneralEncoder class CRYPTOPP_DLL DERSetEncoder : public DERGeneralEncoder
{ {
public: public:
explicit DERSetEncoder(BufferedTransformation &outQueue, byte asnTag = SET | CONSTRUCTED) /// \brief Default ASN.1 tag
enum {DefaultTag = SET | CONSTRUCTED};
/// \brief Construct an ASN.1 encoder
/// \param outQueue output byte queue
/// \details DERSetEncoder uses DefaultTag
explicit DERSetEncoder(BufferedTransformation &outQueue)
: DERGeneralEncoder(outQueue, DefaultTag) {}
/// \brief Construct an ASN.1 encoder
/// \param outQueue output byte queue
/// \param asnTag ASN.1 tag
explicit DERSetEncoder(BufferedTransformation &outQueue, byte asnTag)
: DERGeneralEncoder(outQueue, asnTag) {} : DERGeneralEncoder(outQueue, asnTag) {}
explicit DERSetEncoder(DERSetEncoder &outQueue, byte asnTag = SET | CONSTRUCTED)
/// \brief Construct an ASN.1 encoder
/// \param outQueue output byte queue
/// \details DERSetEncoder uses DefaultTag
explicit DERSetEncoder(DERSetEncoder &outQueue)
: DERGeneralEncoder(outQueue, DefaultTag) {}
/// \brief Construct an ASN.1 encoder
/// \param outQueue output byte queue
/// \param asnTag ASN.1 tag
explicit DERSetEncoder(DERSetEncoder &outQueue, byte asnTag)
: DERGeneralEncoder(outQueue, asnTag) {} : DERGeneralEncoder(outQueue, asnTag) {}
}; };

View File

@ -36,7 +36,9 @@ public:
, m_outputBlockSize(0), m_bytePos(0), m_bitPos(0) , m_outputBlockSize(0), m_bytePos(0), m_bitPos(0)
{ {
Detach(attachment); Detach(attachment);
IsolatedInitialize(MakeParameters(Name::EncodingLookupArray(), alphabet) BaseN_Encoder::IsolatedInitialize(
MakeParameters
(Name::EncodingLookupArray(), alphabet)
(Name::Log2Base(), log2base) (Name::Log2Base(), log2base)
(Name::Pad(), padding != -1) (Name::Pad(), padding != -1)
(Name::PaddingByte(), byte(padding))); (Name::PaddingByte(), byte(padding)));
@ -78,7 +80,10 @@ public:
, m_outputBlockSize(0), m_bytePos(0), m_bitPos(0) , m_outputBlockSize(0), m_bytePos(0), m_bitPos(0)
{ {
Detach(attachment); Detach(attachment);
IsolatedInitialize(MakeParameters(Name::DecodingLookupArray(), lookup)(Name::Log2Base(), log2base)); BaseN_Decoder::IsolatedInitialize(
MakeParameters
(Name::DecodingLookupArray(), lookup)
(Name::Log2Base(), log2base));
} }
void IsolatedInitialize(const NameValuePairs &parameters); void IsolatedInitialize(const NameValuePairs &parameters);
@ -121,7 +126,9 @@ public:
: m_groupSize(0), m_counter(0) : m_groupSize(0), m_counter(0)
{ {
Detach(attachment); Detach(attachment);
IsolatedInitialize(MakeParameters(Name::GroupSize(), groupSize) Grouper::IsolatedInitialize(
MakeParameters
(Name::GroupSize(), groupSize)
(Name::Separator(), ConstByteArrayParameter(separator)) (Name::Separator(), ConstByteArrayParameter(separator))
(Name::Terminator(), ConstByteArrayParameter(terminator))); (Name::Terminator(), ConstByteArrayParameter(terminator)));
} }

48
bench.h
View File

@ -16,14 +16,48 @@ NAMESPACE_BEGIN(Test)
// More granular control over benchmarks // More granular control over benchmarks
enum TestClass { enum TestClass {
UnkeyedRNG=(1<<0),UnkeyedHash=(1<<1),UnkeyedOther=(1<<2), /// \brief Random number generators
SharedKeyMAC=(1<<3),SharedKeyStream=(1<<4),SharedKeyBlock=(1<<5),SharedKeyOther=(1<<6), UnkeyedRNG=(1<<0),
PublicKeyAgreement=(1<<7),PublicKeyEncryption=(1<<8),PublicKeySignature=(1<<9),PublicKeyOther=(1<<10), /// \brief Message digests
UnkeyedHash=(1<<1),
/// \brief Other unkeyed algorithms
UnkeyedOther=(1<<2),
/// \brief Message authentication codes
SharedKeyMAC=(1<<3),
/// \brief Stream ciphers
SharedKeyStream=(1<<4),
/// \brief Block ciphers ciphers
SharedKeyBlock=(1<<5),
/// \brief Other shared key algorithms
SharedKeyOther=(1<<6),
/// \brief Key agreement algorithms over integers
PublicKeyAgreement=(1<<7),
/// \brief Encryption algorithms over integers
PublicKeyEncryption=(1<<8),
/// \brief Signature algorithms over integers
PublicKeySignature=(1<<9),
/// \brief Other public key algorithms over integers
PublicKeyOther=(1<<10),
/// \brief Key agreement algorithms over EC
PublicKeyAgreementEC=(1<<11),
/// \brief Encryption algorithms over EC
PublicKeyEncryptionEC=(1<<12),
/// \brief Signature algorithms over EC
PublicKeySignatureEC=(1<<13),
/// \brief Other public key algorithms over EC
PublicKeyOtherEC=(1<<14),
Unkeyed=UnkeyedRNG|UnkeyedHash|UnkeyedOther, Unkeyed=UnkeyedRNG|UnkeyedHash|UnkeyedOther,
SharedKey=SharedKeyMAC|SharedKeyStream|SharedKeyBlock|SharedKeyOther, SharedKey=SharedKeyMAC|SharedKeyStream|SharedKeyBlock|SharedKeyOther,
PublicKey=PublicKeyAgreement|PublicKeyEncryption|PublicKeySignature|PublicKeyOther, PublicKey=PublicKeyAgreement|PublicKeyEncryption|PublicKeySignature|PublicKeyOther,
All=Unkeyed|SharedKey|PublicKey, PublicKeyEC=PublicKeyAgreementEC|PublicKeyEncryptionEC|PublicKeySignatureEC|PublicKeyOtherEC,
TestFirst=(0), TestLast=(1<<11)
All=Unkeyed|SharedKey|PublicKey|PublicKeyEC,
TestFirst=(0), TestLast=(1<<15)
}; };
extern const double CLOCK_TICKS_PER_SECOND; extern const double CLOCK_TICKS_PER_SECOND;
@ -45,8 +79,10 @@ void Benchmark(Test::TestClass suites, double t, double hertz);
void Benchmark1(double t, double hertz); void Benchmark1(double t, double hertz);
// Shared key systems // Shared key systems
void Benchmark2(double t, double hertz); void Benchmark2(double t, double hertz);
// Public key systems // Public key systems over integers
void Benchmark3(double t, double hertz); void Benchmark3(double t, double hertz);
// Public key systems over elliptic curves
void Benchmark4(double t, double hertz);
// These are defined in bench1.cpp // These are defined in bench1.cpp
extern void OutputResultKeying(double iterations, double timeTaken); extern void OutputResultKeying(double iterations, double timeTaken);

View File

@ -351,6 +351,8 @@ void BenchmarkWithCommand(int argc, const char* const argv[])
if (command == "b") // All benchmarks if (command == "b") // All benchmarks
Benchmark(Test::All, runningTime, cpuFreq); Benchmark(Test::All, runningTime, cpuFreq);
else if (command == "b4") // Public key algorithms over EC
Test::Benchmark(Test::PublicKeyEC, runningTime, cpuFreq);
else if (command == "b3") // Public key algorithms else if (command == "b3") // Public key algorithms
Test::Benchmark(Test::PublicKey, runningTime, cpuFreq); Test::Benchmark(Test::PublicKey, runningTime, cpuFreq);
else if (command == "b2") // Shared key algorithms else if (command == "b2") // Shared key algorithms
@ -392,6 +394,13 @@ void Benchmark(Test::TestClass suites, double t, double hertz)
Benchmark3(t, hertz); Benchmark3(t, hertz);
} }
// Public key algorithms over EC
if (suites & Test::PublicKeyEC)
{
std::cout << "\n<BR>";
Benchmark4(t, hertz);
}
g_testEnd = ::time(NULLPTR); g_testEnd = ::time(NULLPTR);
std::ostringstream oss; std::ostringstream oss;

View File

@ -12,6 +12,12 @@
#include "smartptr.h" #include "smartptr.h"
#include "stdcpp.h" #include "stdcpp.h"
#include "vmac.h"
#include "hmac.h"
#include "ttmac.h"
#include "cmac.h"
#include "dmac.h"
#if CRYPTOPP_MSC_VERSION #if CRYPTOPP_MSC_VERSION
# pragma warning(disable: 4355) # pragma warning(disable: 4355)
#endif #endif

View File

@ -365,21 +365,29 @@ void Benchmark3(double t, double hertz)
BenchMarkKeyAgreement<LUC_DH>("TestData/lucd1024.dat", "LUCDIF 1024", t); BenchMarkKeyAgreement<LUC_DH>("TestData/lucd1024.dat", "LUCDIF 1024", t);
BenchMarkKeyAgreement<MQV>("TestData/mqv1024.dat", "MQV 1024", t); BenchMarkKeyAgreement<MQV>("TestData/mqv1024.dat", "MQV 1024", t);
BenchMarkKeyAgreement<MQV>("TestData/mqv2048.dat", "MQV 2048", t); BenchMarkKeyAgreement<MQV>("TestData/mqv2048.dat", "MQV 2048", t);
#if 0
BenchMarkKeyAgreement<ECHMQV160>("TestData/hmqv160.dat", "HMQV P-160", t);
BenchMarkKeyAgreement<ECHMQV256>("TestData/hmqv256.dat", "HMQV P-256", t);
BenchMarkKeyAgreement<ECHMQV384>("TestData/hmqv384.dat", "HMQV P-384", t);
BenchMarkKeyAgreement<ECHMQV512>("TestData/hmqv512.dat", "HMQV P-512", t);
BenchMarkKeyAgreement<ECFHMQV160>("TestData/fhmqv160.dat", "FHMQV P-160", t);
BenchMarkKeyAgreement<ECFHMQV256>("TestData/fhmqv256.dat", "FHMQV P-256", t);
BenchMarkKeyAgreement<ECFHMQV384>("TestData/fhmqv384.dat", "FHMQV P-384", t);
BenchMarkKeyAgreement<ECFHMQV512>("TestData/fhmqv512.dat", "FHMQV P-512", t);
#endif
} }
std::cout << "\n<TBODY style=\"background: yellow;\">"; std::cout << "\n</TABLE>" << std::endl;
}
void Benchmark4(double t, double hertz)
{
g_allocatedTime = t;
g_hertz = hertz;
const char *mco;
if (g_hertz > 1.0f)
mco = "<TH>Megacycles/Operation";
else
mco = "";
std::cout << "\n<TABLE>";
std::cout << "\n<COLGROUP><COL style=\"text-align: left;\"><COL style=";
std::cout << "\"text-align: right;\"><COL style=\"text-align: right;\">";
std::cout << "\n<THEAD style=\"background: #F0F0F0\">";
std::cout << "\n<TR><TH>Operation<TH>Milliseconds/Operation" << mco;
std::cout << "\n<TBODY style=\"background: white;\">";
{ {
ed25519::Signer sign(Test::GlobalRNG()); ed25519::Signer sign(Test::GlobalRNG());
ed25519::Verifier verify(sign); ed25519::Verifier verify(sign);
@ -391,7 +399,27 @@ void Benchmark3(double t, double hertz)
BenchMarkAgreement("x25519", agree, t); BenchMarkAgreement("x25519", agree, t);
} }
std::cout << "\n<TBODY style=\"background: white;\">"; #if 0
std::cout << "\n<TBODY style=\"background: yellow;\">";
{
BenchMarkKeyAgreement<ECMQV160>("TestData/mqv160.dat", "MQV P-160", t);
BenchMarkKeyAgreement<ECMQV256>("TestData/mqv256.dat", "MQV P-256", t);
BenchMarkKeyAgreement<ECMQV384>("TestData/mqv384.dat", "MQV P-384", t);
BenchMarkKeyAgreement<ECMQV512>("TestData/mqv512.dat", "MQV P-521", t);
BenchMarkKeyAgreement<ECHMQV160>("TestData/hmqv160.dat", "HMQV P-160", t);
BenchMarkKeyAgreement<ECHMQV256>("TestData/hmqv256.dat", "HMQV P-256", t);
BenchMarkKeyAgreement<ECHMQV384>("TestData/hmqv384.dat", "HMQV P-384", t);
BenchMarkKeyAgreement<ECHMQV512>("TestData/hmqv512.dat", "HMQV P-521", t);
BenchMarkKeyAgreement<ECFHMQV160>("TestData/fhmqv160.dat", "FHMQV P-160", t);
BenchMarkKeyAgreement<ECFHMQV256>("TestData/fhmqv256.dat", "FHMQV P-256", t);
BenchMarkKeyAgreement<ECFHMQV384>("TestData/fhmqv384.dat", "FHMQV P-384", t);
BenchMarkKeyAgreement<ECFHMQV512>("TestData/fhmqv512.dat", "FHMQV P-521", t);
}
#endif
std::cout << "\n<TBODY style=\"background: yellow;\">";
{ {
ECIES<ECP>::Decryptor cpriv(Test::GlobalRNG(), ASN1::secp256k1()); ECIES<ECP>::Decryptor cpriv(Test::GlobalRNG(), ASN1::secp256k1());
ECIES<ECP>::Encryptor cpub(cpriv); ECIES<ECP>::Encryptor cpub(cpriv);
@ -418,7 +446,7 @@ void Benchmark3(double t, double hertz)
BenchMarkAgreement("ECMQVC over GF(p) 256", ecmqvc, t); BenchMarkAgreement("ECMQVC over GF(p) 256", ecmqvc, t);
} }
std::cout << "\n<TBODY style=\"background: yellow;\">"; std::cout << "\n<TBODY style=\"background: white;\">";
{ {
ECIES<EC2N>::Decryptor cpriv(Test::GlobalRNG(), ASN1::sect233r1()); ECIES<EC2N>::Decryptor cpriv(Test::GlobalRNG(), ASN1::sect233r1());
ECIES<EC2N>::Encryptor cpub(cpriv); ECIES<EC2N>::Encryptor cpub(cpriv);

View File

@ -38,24 +38,34 @@
// https://github.com/weidai11/cryptopp/issues/743 // https://github.com/weidai11/cryptopp/issues/743
#if defined(__xlC__) && (__xlC__ < 0x0d01) #if defined(__xlC__) && (__xlC__ < 0x0d01)
# define CRYPTOPP_DISABLE_ALTIVEC 1 # define CRYPTOPP_DISABLE_ALTIVEC 1
# define CRYPTOPP_POWER7_ALTIVEC 1
# undef CRYPTOPP_POWER7_AVAILABLE # undef CRYPTOPP_POWER7_AVAILABLE
# undef CRYPTOPP_POWER8_AVAILABLE
# undef CRYPTOPP_ALTIVEC_AVAILABLE # undef CRYPTOPP_ALTIVEC_AVAILABLE
#endif #endif
// Can't use GetAlignmentOf<word64>() because of C++11 and constexpr
// Can use 'const unsigned int' because of MSVC 2013
#if (CRYPTOPP_BOOL_X86 || CRYPTOPP_BOOL_X32 || CRYPTOPP_BOOL_X64)
# define ALIGN_SPEC32 16
# define ALIGN_SPEC64 16
#else
# define ALIGN_SPEC32 4
# define ALIGN_SPEC64 8
#endif
NAMESPACE_BEGIN(CryptoPP) NAMESPACE_BEGIN(CryptoPP)
// Export the tables to the SIMD files // Export the tables to the SIMD files
extern const word32 BLAKE2S_IV[8]; extern const word32 BLAKE2S_IV[8];
extern const word64 BLAKE2B_IV[8]; extern const word64 BLAKE2B_IV[8];
CRYPTOPP_ALIGN_DATA(16) CRYPTOPP_ALIGN_DATA(ALIGN_SPEC32)
const word32 BLAKE2S_IV[8] = { const word32 BLAKE2S_IV[8] = {
0x6A09E667UL, 0xBB67AE85UL, 0x3C6EF372UL, 0xA54FF53AUL, 0x6A09E667UL, 0xBB67AE85UL, 0x3C6EF372UL, 0xA54FF53AUL,
0x510E527FUL, 0x9B05688CUL, 0x1F83D9ABUL, 0x5BE0CD19UL 0x510E527FUL, 0x9B05688CUL, 0x1F83D9ABUL, 0x5BE0CD19UL
}; };
CRYPTOPP_ALIGN_DATA(16) CRYPTOPP_ALIGN_DATA(ALIGN_SPEC64)
const word64 BLAKE2B_IV[8] = { const word64 BLAKE2B_IV[8] = {
W64LIT(0x6a09e667f3bcc908), W64LIT(0xbb67ae8584caa73b), W64LIT(0x6a09e667f3bcc908), W64LIT(0xbb67ae8584caa73b),
W64LIT(0x3c6ef372fe94f82b), W64LIT(0xa54ff53a5f1d36f1), W64LIT(0x3c6ef372fe94f82b), W64LIT(0xa54ff53a5f1d36f1),
@ -72,7 +82,7 @@ using CryptoPP::word32;
using CryptoPP::word64; using CryptoPP::word64;
using CryptoPP::rotrConstant; using CryptoPP::rotrConstant;
CRYPTOPP_ALIGN_DATA(16) CRYPTOPP_ALIGN_DATA(ALIGN_SPEC32)
const byte BLAKE2S_SIGMA[10][16] = { const byte BLAKE2S_SIGMA[10][16] = {
{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 }, { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 },
{ 14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3 }, { 14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3 },
@ -86,7 +96,7 @@ const byte BLAKE2S_SIGMA[10][16] = {
{ 10, 2, 8, 4, 7, 6, 1, 5, 15, 11, 9, 14, 3, 12, 13 , 0 }, { 10, 2, 8, 4, 7, 6, 1, 5, 15, 11, 9, 14, 3, 12, 13 , 0 },
}; };
CRYPTOPP_ALIGN_DATA(16) CRYPTOPP_ALIGN_DATA(ALIGN_SPEC32)
const byte BLAKE2B_SIGMA[12][16] = { const byte BLAKE2B_SIGMA[12][16] = {
{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 }, { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 },
{ 14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3 }, { 14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3 },
@ -171,8 +181,8 @@ extern void BLAKE2_Compress32_NEON(const byte* input, BLAKE2s_State& state);
extern void BLAKE2_Compress64_NEON(const byte* input, BLAKE2b_State& state); extern void BLAKE2_Compress64_NEON(const byte* input, BLAKE2b_State& state);
#endif #endif
#if CRYPTOPP_POWER7_AVAILABLE #if CRYPTOPP_POWER8_AVAILABLE
extern void BLAKE2_Compress32_POWER7(const byte* input, BLAKE2s_State& state); extern void BLAKE2_Compress32_POWER8(const byte* input, BLAKE2s_State& state);
#elif CRYPTOPP_ALTIVEC_AVAILABLE #elif CRYPTOPP_ALTIVEC_AVAILABLE
extern void BLAKE2_Compress32_ALTIVEC(const byte* input, BLAKE2s_State& state); extern void BLAKE2_Compress32_ALTIVEC(const byte* input, BLAKE2s_State& state);
#endif #endif
@ -233,8 +243,8 @@ unsigned int BLAKE2s::OptimalDataAlignment() const
return 4; return 4;
else else
#endif #endif
#if (CRYPTOPP_POWER7_AVAILABLE) #if (CRYPTOPP_POWER8_AVAILABLE)
if (HasPower7()) if (HasPower8())
return 16; return 16;
else else
#elif (CRYPTOPP_ALTIVEC_AVAILABLE) #elif (CRYPTOPP_ALTIVEC_AVAILABLE)
@ -257,9 +267,9 @@ std::string BLAKE2s::AlgorithmProvider() const
return "NEON"; return "NEON";
else else
#endif #endif
#if (CRYPTOPP_POWER7_AVAILABLE) #if (CRYPTOPP_POWER8_AVAILABLE)
if (HasPower7()) if (HasPower8())
return "Power7"; return "Power8";
else else
#elif (CRYPTOPP_ALTIVEC_AVAILABLE) #elif (CRYPTOPP_ALTIVEC_AVAILABLE)
if (HasAltivec()) if (HasAltivec())
@ -343,6 +353,26 @@ BLAKE2b::BLAKE2b(bool treeMode, unsigned int digestSize)
(Name::TreeMode(), treeMode)); (Name::TreeMode(), treeMode));
} }
BLAKE2s::BLAKE2s(unsigned int digestSize)
: m_digestSize(digestSize), m_keyLength(0), m_treeMode(false)
{
CRYPTOPP_ASSERT(digestSize <= DIGESTSIZE);
UncheckedSetKey(NULLPTR, 0, MakeParameters
(Name::DigestSize(), (int)digestSize)
(Name::TreeMode(), false));
}
BLAKE2b::BLAKE2b(unsigned int digestSize)
: m_digestSize(digestSize), m_keyLength(0), m_treeMode(false)
{
CRYPTOPP_ASSERT(digestSize <= DIGESTSIZE);
UncheckedSetKey(NULLPTR, 0, MakeParameters
(Name::DigestSize(), (int)digestSize)
(Name::TreeMode(), false));
}
BLAKE2s::BLAKE2s(const byte *key, size_t keyLength, const byte* salt, size_t saltLength, BLAKE2s::BLAKE2s(const byte *key, size_t keyLength, const byte* salt, size_t saltLength,
const byte* personalization, size_t personalizationLength, bool treeMode, unsigned int digestSize) const byte* personalization, size_t personalizationLength, bool treeMode, unsigned int digestSize)
: m_digestSize(digestSize), m_keyLength(static_cast<unsigned int>(keyLength)), m_treeMode(treeMode) : m_digestSize(digestSize), m_keyLength(static_cast<unsigned int>(keyLength)), m_treeMode(treeMode)
@ -670,10 +700,10 @@ void BLAKE2s::Compress(const byte *input)
return BLAKE2_Compress32_NEON(input, m_state); return BLAKE2_Compress32_NEON(input, m_state);
} }
#endif #endif
#if CRYPTOPP_POWER7_AVAILABLE #if CRYPTOPP_POWER8_AVAILABLE
if(HasPower7()) if(HasPower8())
{ {
return BLAKE2_Compress32_POWER7(input, m_state); return BLAKE2_Compress32_POWER8(input, m_state);
} }
#elif CRYPTOPP_ALTIVEC_AVAILABLE #elif CRYPTOPP_ALTIVEC_AVAILABLE
if(HasAltivec()) if(HasAltivec())

View File

@ -256,17 +256,25 @@ public:
/// \brief Construct a BLAKE2s hash /// \brief Construct a BLAKE2s hash
/// \param digestSize the digest size, in bytes /// \param digestSize the digest size, in bytes
/// \param treeMode flag indicating tree mode /// \param treeMode flag indicating tree mode
/// \since Crypto++ 5.6.4
BLAKE2s(bool treeMode=false, unsigned int digestSize = DIGESTSIZE); BLAKE2s(bool treeMode=false, unsigned int digestSize = DIGESTSIZE);
/// \brief Construct a BLAKE2s hash
/// \param digestSize the digest size, in bytes
/// \details treeMode flag is set to false
/// \since Crypto++ 8.2
BLAKE2s(unsigned int digestSize);
/// \brief Construct a BLAKE2s hash /// \brief Construct a BLAKE2s hash
/// \param key a byte array used to key the cipher /// \param key a byte array used to key the cipher
/// \param keyLength the size of the byte array /// \param keyLength the size of the byte array
/// \param salt a byte array used as salt /// \param salt a byte array used as salt
/// \param saltLength the size of the byte array /// \param saltLength the size of the byte array
/// \param personalization a byte array used as prsonalization string /// \param personalization a byte array used as personalization string
/// \param personalizationLength the size of the byte array /// \param personalizationLength the size of the byte array
/// \param treeMode flag indicating tree mode /// \param treeMode flag indicating tree mode
/// \param digestSize the digest size, in bytes /// \param digestSize the digest size, in bytes
/// \since Crypto++ 5.6.4
BLAKE2s(const byte *key, size_t keyLength, const byte* salt = NULLPTR, size_t saltLength = 0, BLAKE2s(const byte *key, size_t keyLength, const byte* salt = NULLPTR, size_t saltLength = 0,
const byte* personalization = NULLPTR, size_t personalizationLength = 0, const byte* personalization = NULLPTR, size_t personalizationLength = 0,
bool treeMode=false, unsigned int digestSize = DIGESTSIZE); bool treeMode=false, unsigned int digestSize = DIGESTSIZE);
@ -278,6 +286,7 @@ public:
/// Message Authentication Code (MAC)</A>. For example, "BLAKE2b-512" and "BLAKE2s-256". /// Message Authentication Code (MAC)</A>. For example, "BLAKE2b-512" and "BLAKE2s-256".
std::string AlgorithmName() const {return std::string(BLAKE2s_Info::StaticAlgorithmName()) + "-" + IntToString(DigestSize()*8);} std::string AlgorithmName() const {return std::string(BLAKE2s_Info::StaticAlgorithmName()) + "-" + IntToString(DigestSize()*8);}
unsigned int BlockSize() const {return BLOCKSIZE;}
unsigned int DigestSize() const {return m_digestSize;} unsigned int DigestSize() const {return m_digestSize;}
unsigned int OptimalDataAlignment() const; unsigned int OptimalDataAlignment() const;
@ -354,17 +363,25 @@ public:
/// \brief Construct a BLAKE2b hash /// \brief Construct a BLAKE2b hash
/// \param digestSize the digest size, in bytes /// \param digestSize the digest size, in bytes
/// \param treeMode flag indicating tree mode /// \param treeMode flag indicating tree mode
/// \since Crypto++ 5.6.4
BLAKE2b(bool treeMode=false, unsigned int digestSize = DIGESTSIZE); BLAKE2b(bool treeMode=false, unsigned int digestSize = DIGESTSIZE);
/// \brief Construct a BLAKE2s hash
/// \param digestSize the digest size, in bytes
/// \details treeMode flag is set to false
/// \since Crypto++ 8.2
BLAKE2b(unsigned int digestSize);
/// \brief Construct a BLAKE2b hash /// \brief Construct a BLAKE2b hash
/// \param key a byte array used to key the cipher /// \param key a byte array used to key the cipher
/// \param keyLength the size of the byte array /// \param keyLength the size of the byte array
/// \param salt a byte array used as salt /// \param salt a byte array used as salt
/// \param saltLength the size of the byte array /// \param saltLength the size of the byte array
/// \param personalization a byte array used as prsonalization string /// \param personalization a byte array used as personalization string
/// \param personalizationLength the size of the byte array /// \param personalizationLength the size of the byte array
/// \param treeMode flag indicating tree mode /// \param treeMode flag indicating tree mode
/// \param digestSize the digest size, in bytes /// \param digestSize the digest size, in bytes
/// \since Crypto++ 5.6.4
BLAKE2b(const byte *key, size_t keyLength, const byte* salt = NULLPTR, size_t saltLength = 0, BLAKE2b(const byte *key, size_t keyLength, const byte* salt = NULLPTR, size_t saltLength = 0,
const byte* personalization = NULLPTR, size_t personalizationLength = 0, const byte* personalization = NULLPTR, size_t personalizationLength = 0,
bool treeMode=false, unsigned int digestSize = DIGESTSIZE); bool treeMode=false, unsigned int digestSize = DIGESTSIZE);
@ -376,6 +393,7 @@ public:
/// Message Authentication Code (MAC)</A>. For example, "BLAKE2b-512" and "BLAKE2s-256". /// Message Authentication Code (MAC)</A>. For example, "BLAKE2b-512" and "BLAKE2s-256".
std::string AlgorithmName() const {return std::string(BLAKE2b_Info::StaticAlgorithmName()) + "-" + IntToString(DigestSize()*8);} std::string AlgorithmName() const {return std::string(BLAKE2b_Info::StaticAlgorithmName()) + "-" + IntToString(DigestSize()*8);}
unsigned int BlockSize() const {return BLOCKSIZE;}
unsigned int DigestSize() const {return m_digestSize;} unsigned int DigestSize() const {return m_digestSize;}
unsigned int OptimalDataAlignment() const; unsigned int OptimalDataAlignment() const;

View File

@ -28,10 +28,17 @@
// https://github.com/weidai11/cryptopp/issues/743 // https://github.com/weidai11/cryptopp/issues/743
#if defined(__xlC__) && (__xlC__ < 0x0d01) #if defined(__xlC__) && (__xlC__ < 0x0d01)
# define CRYPTOPP_DISABLE_ALTIVEC 1 # define CRYPTOPP_DISABLE_ALTIVEC 1
# undef CRYPTOPP_POWER7_AVAILABLE # undef CRYPTOPP_POWER8_AVAILABLE
# undef CRYPTOPP_ALTIVEC_AVAILABLE # undef CRYPTOPP_ALTIVEC_AVAILABLE
#endif #endif
#if defined(__XOP__)
# include <ammintrin.h>
# if defined(__GNUC__)
# include <x86intrin.h>
# endif
#endif
#if (CRYPTOPP_SSE41_AVAILABLE) #if (CRYPTOPP_SSE41_AVAILABLE)
# include <emmintrin.h> # include <emmintrin.h>
# include <tmmintrin.h> # include <tmmintrin.h>

View File

@ -8,9 +8,9 @@
// appropriate instructions sets in some build configurations. // appropriate instructions sets in some build configurations.
// The BLAKE2b and BLAKE2s numbers are consistent with the BLAKE2 team's // The BLAKE2b and BLAKE2s numbers are consistent with the BLAKE2 team's
// numbers. However, we have an Altivec/POWER7 implementation of BLAKE2s, // numbers. However, we have an Altivec/POWER8 implementation of BLAKE2s,
// and a POWER8 implementation of BLAKE2b (BLAKE2 is missing them). The // and a POWER8 implementation of BLAKE2b (BLAKE2 is missing them). The
// Altivec/POWER7 code is about 2x faster than C++ when using GCC 5.0 or // Altivec/POWER8 code is about 2x faster than C++ when using GCC 5.0 or
// above. The POWER8 code is about 2.5x faster than C++ when using GCC 5.0 // above. The POWER8 code is about 2.5x faster than C++ when using GCC 5.0
// or above. If you use GCC 4.0 (PowerMac) or GCC 4.8 (GCC Compile Farm) // or above. If you use GCC 4.0 (PowerMac) or GCC 4.8 (GCC Compile Farm)
// then the PowerPC code will be slower than C++. Be sure to use GCC 5.0 // then the PowerPC code will be slower than C++. Be sure to use GCC 5.0
@ -38,11 +38,17 @@
// https://github.com/weidai11/cryptopp/issues/743 // https://github.com/weidai11/cryptopp/issues/743
#if defined(__xlC__) && (__xlC__ < 0x0d01) #if defined(__xlC__) && (__xlC__ < 0x0d01)
# define CRYPTOPP_DISABLE_ALTIVEC 1 # define CRYPTOPP_DISABLE_ALTIVEC 1
# define CRYPTOPP_POWER7_ALTIVEC 1 # undef CRYPTOPP_POWER8_AVAILABLE
# undef CRYPTOPP_POWER7_AVAILABLE
# undef CRYPTOPP_ALTIVEC_AVAILABLE # undef CRYPTOPP_ALTIVEC_AVAILABLE
#endif #endif
#if defined(__XOP__)
# include <ammintrin.h>
# if defined(__GNUC__)
# include <x86intrin.h>
# endif
#endif
#if (CRYPTOPP_SSE41_AVAILABLE) #if (CRYPTOPP_SSE41_AVAILABLE)
# include <emmintrin.h> # include <emmintrin.h>
# include <tmmintrin.h> # include <tmmintrin.h>
@ -692,7 +698,7 @@ void BLAKE2_Compress32_NEON(const byte* input, BLAKE2s_State& state)
} }
#endif // CRYPTOPP_ARM_NEON_AVAILABLE #endif // CRYPTOPP_ARM_NEON_AVAILABLE
#if (CRYPTOPP_POWER7_AVAILABLE || CRYPTOPP_ALTIVEC_AVAILABLE) #if (CRYPTOPP_POWER8_AVAILABLE || CRYPTOPP_ALTIVEC_AVAILABLE)
inline uint32x4_p VecLoad32(const void* p) inline uint32x4_p VecLoad32(const void* p)
{ {
@ -838,7 +844,7 @@ inline uint32x4_p VectorSet32(const uint32x4_p a, const uint32x4_p b,
const uint32x4_p t0 = VectorSet32<W,X>(a, b); const uint32x4_p t0 = VectorSet32<W,X>(a, b);
const uint32x4_p t1 = VectorSet32<Y,Z>(c, d); const uint32x4_p t1 = VectorSet32<Y,Z>(c, d);
// Power7 follows SSE2's implementation, and this is _mm_set_epi32. // PowerPC follows SSE2's implementation, and this is _mm_set_epi32.
const uint8x16_p mask = {20,21,22,23, 16,17,18,19, 4,5,6,7, 0,1,2,3}; const uint8x16_p mask = {20,21,22,23, 16,17,18,19, 4,5,6,7, 0,1,2,3};
return VecPermute(t0, t1, mask); return VecPermute(t0, t1, mask);
} }
@ -863,10 +869,10 @@ uint32x4_p VectorSet32<3,1,3,1>(const uint32x4_p a, const uint32x4_p b,
return VecPermute(a, c, mask); return VecPermute(a, c, mask);
} }
// BLAKE2_Compress32_CORE will use either POWER7 or ALTIVEC, // BLAKE2_Compress32_CORE will use either POWER8 or ALTIVEC,
// depending on the flags used to compile this source file. The // depending on the flags used to compile this source file. The
// abstractions are handled in VecLoad, VecStore and friends. In // abstractions are handled in VecLoad, VecStore and friends. In
// the future we may to provide both POWER7 or ALTIVEC at the same // the future we may provide both POWER8 or ALTIVEC at the same
// time to better support distros. // time to better support distros.
void BLAKE2_Compress32_CORE(const byte* input, BLAKE2s_State& state) void BLAKE2_Compress32_CORE(const byte* input, BLAKE2s_State& state)
{ {
@ -1015,11 +1021,11 @@ void BLAKE2_Compress32_CORE(const byte* input, BLAKE2s_State& state)
VecStore32LE(state.h()+0, VecXor(ff0, VecXor(row1, row3))); VecStore32LE(state.h()+0, VecXor(ff0, VecXor(row1, row3)));
VecStore32LE(state.h()+4, VecXor(ff1, VecXor(row2, row4))); VecStore32LE(state.h()+4, VecXor(ff1, VecXor(row2, row4)));
} }
#endif // CRYPTOPP_POWER7_AVAILABLE || CRYPTOPP_ALTIVEC_AVAILABLE #endif // CRYPTOPP_POWER8_AVAILABLE || CRYPTOPP_ALTIVEC_AVAILABLE
#if (CRYPTOPP_POWER7_AVAILABLE) #if (CRYPTOPP_POWER8_AVAILABLE)
void BLAKE2_Compress32_POWER7(const byte* input, BLAKE2s_State& state) void BLAKE2_Compress32_POWER8(const byte* input, BLAKE2s_State& state)
{ {
BLAKE2_Compress32_CORE(input, state); BLAKE2_Compress32_CORE(input, state);
} }

View File

@ -28,8 +28,8 @@ extern void ChaCha_OperateKeystream_AVX2(const word32 *state, const byte* input,
extern void ChaCha_OperateKeystream_SSE2(const word32 *state, const byte* input, byte *output, unsigned int rounds); extern void ChaCha_OperateKeystream_SSE2(const word32 *state, const byte* input, byte *output, unsigned int rounds);
#endif #endif
#if (CRYPTOPP_POWER7_AVAILABLE) #if (CRYPTOPP_POWER8_AVAILABLE)
extern void ChaCha_OperateKeystream_POWER7(const word32 *state, const byte* input, byte *output, unsigned int rounds); extern void ChaCha_OperateKeystream_POWER8(const word32 *state, const byte* input, byte *output, unsigned int rounds);
#elif (CRYPTOPP_ALTIVEC_AVAILABLE) #elif (CRYPTOPP_ALTIVEC_AVAILABLE)
extern void ChaCha_OperateKeystream_ALTIVEC(const word32 *state, const byte* input, byte *output, unsigned int rounds); extern void ChaCha_OperateKeystream_ALTIVEC(const word32 *state, const byte* input, byte *output, unsigned int rounds);
#endif #endif
@ -153,13 +153,13 @@ void ChaCha_OperateKeystream(KeystreamOperation operation,
} }
#endif #endif
#if (CRYPTOPP_POWER7_AVAILABLE) #if (CRYPTOPP_POWER8_AVAILABLE)
if (HasPower7()) if (HasPower8())
{ {
while (iterationCount >= 4 && MultiBlockSafe(state[12], 4)) while (iterationCount >= 4 && MultiBlockSafe(state[12], 4))
{ {
const bool xorInput = (operation & INPUT_NULL) != INPUT_NULL; const bool xorInput = (operation & INPUT_NULL) != INPUT_NULL;
ChaCha_OperateKeystream_POWER7(state, xorInput ? input : NULLPTR, output, rounds); ChaCha_OperateKeystream_POWER8(state, xorInput ? input : NULLPTR, output, rounds);
// MultiBlockSafe avoids overflow on the counter words // MultiBlockSafe avoids overflow on the counter words
state[12] += 4; state[12] += 4;
@ -267,9 +267,9 @@ std::string ChaCha_AlgorithmProvider()
return "NEON"; return "NEON";
else else
#endif #endif
#if (CRYPTOPP_POWER7_AVAILABLE) #if (CRYPTOPP_POWER8_AVAILABLE)
if (HasPower7()) if (HasPower8())
return "Power7"; return "Power8";
else else
#elif (CRYPTOPP_ALTIVEC_AVAILABLE) #elif (CRYPTOPP_ALTIVEC_AVAILABLE)
if (HasAltivec()) if (HasAltivec())

View File

@ -91,14 +91,14 @@ NAMESPACE_BEGIN(CryptoPP)
void ChaCha_OperateKeystream_AVX2(const word32 *state, const byte* input, byte *output, unsigned int rounds) void ChaCha_OperateKeystream_AVX2(const word32 *state, const byte* input, byte *output, unsigned int rounds)
{ {
MAYBE_CONST __m128i* state_mm = (MAYBE_CONST __m128i*)(state); const __m256i state0 = _mm256_broadcastsi128_si256(
MAYBE_CONST __m256i* input_mm = (MAYBE_CONST __m256i*)(input); _mm_loadu_si128(reinterpret_cast<const __m128i*>(state+0*4)));
__m256i* output_mm = reinterpret_cast<__m256i*>(output); const __m256i state1 = _mm256_broadcastsi128_si256(
_mm_loadu_si128(reinterpret_cast<const __m128i*>(state+1*4)));
const __m256i state0 = _mm256_broadcastsi128_si256(_mm_loadu_si128(state_mm + 0)); const __m256i state2 = _mm256_broadcastsi128_si256(
const __m256i state1 = _mm256_broadcastsi128_si256(_mm_loadu_si128(state_mm + 1)); _mm_loadu_si128(reinterpret_cast<const __m128i*>(state+2*4)));
const __m256i state2 = _mm256_broadcastsi128_si256(_mm_loadu_si128(state_mm + 2)); const __m256i state3 = _mm256_broadcastsi128_si256(
const __m256i state3 = _mm256_broadcastsi128_si256(_mm_loadu_si128(state_mm + 3)); _mm_loadu_si128(reinterpret_cast<const __m128i*>(state+3*4)));
const __m256i CTR0 = _mm256_set_epi32(0, 0, 0, 0, 0, 0, 0, 4); const __m256i CTR0 = _mm256_set_epi32(0, 0, 0, 0, 0, 0, 0, 4);
const __m256i CTR1 = _mm256_set_epi32(0, 0, 0, 1, 0, 0, 0, 5); const __m256i CTR1 = _mm256_set_epi32(0, 0, 0, 1, 0, 0, 0, 5);
@ -304,80 +304,112 @@ void ChaCha_OperateKeystream_AVX2(const word32 *state, const byte* input, byte *
X3_3 = _mm256_add_epi32(X3_3, state3); X3_3 = _mm256_add_epi32(X3_3, state3);
X3_3 = _mm256_add_epi64(X3_3, CTR3); X3_3 = _mm256_add_epi64(X3_3, CTR3);
if (input_mm) if (input)
{ {
_mm256_storeu_si256(output_mm + 0, _mm256_xor_si256(_mm256_loadu_si256(input_mm + 0), _mm256_storeu_si256(reinterpret_cast<__m256i*>(output+0*32),
_mm256_permute2x128_si256(X0_0, X0_1, 1 + (3 << 4)))); _mm256_xor_si256(_mm256_permute2x128_si256(X0_0, X0_1, 1 + (3 << 4)),
_mm256_storeu_si256(output_mm + 1, _mm256_xor_si256(_mm256_loadu_si256(input_mm + 1), _mm256_loadu_si256(reinterpret_cast<const __m256i*>(input+0*32))));
_mm256_permute2x128_si256(X0_2, X0_3, 1 + (3 << 4)))); _mm256_storeu_si256(reinterpret_cast<__m256i*>(output+1*32),
_mm256_storeu_si256(output_mm + 2, _mm256_xor_si256(_mm256_loadu_si256(input_mm + 2), _mm256_xor_si256(_mm256_permute2x128_si256(X0_2, X0_3, 1 + (3 << 4)),
_mm256_permute2x128_si256(X1_0, X1_1, 1 + (3 << 4)))); _mm256_loadu_si256(reinterpret_cast<const __m256i*>(input+1*32))));
_mm256_storeu_si256(output_mm + 3, _mm256_xor_si256(_mm256_loadu_si256(input_mm + 3), _mm256_storeu_si256(reinterpret_cast<__m256i*>(output+2*32),
_mm256_permute2x128_si256(X1_2, X1_3, 1 + (3 << 4)))); _mm256_xor_si256(_mm256_permute2x128_si256(X1_0, X1_1, 1 + (3 << 4)),
_mm256_loadu_si256(reinterpret_cast<const __m256i*>(input+2*32))));
_mm256_storeu_si256(reinterpret_cast<__m256i*>(output+3*32),
_mm256_xor_si256(_mm256_permute2x128_si256(X1_2, X1_3, 1 + (3 << 4)),
_mm256_loadu_si256(reinterpret_cast<const __m256i*>(input+3*32))));
} }
else else
{ {
_mm256_storeu_si256(output_mm + 0, _mm256_permute2x128_si256(X0_0, X0_1, 1 + (3 << 4))); _mm256_storeu_si256(reinterpret_cast<__m256i*>(output+0*32),
_mm256_storeu_si256(output_mm + 1, _mm256_permute2x128_si256(X0_2, X0_3, 1 + (3 << 4))); _mm256_permute2x128_si256(X0_0, X0_1, 1 + (3 << 4)));
_mm256_storeu_si256(output_mm + 2, _mm256_permute2x128_si256(X1_0, X1_1, 1 + (3 << 4))); _mm256_storeu_si256(reinterpret_cast<__m256i*>(output+1*32),
_mm256_storeu_si256(output_mm + 3, _mm256_permute2x128_si256(X1_2, X1_3, 1 + (3 << 4))); _mm256_permute2x128_si256(X0_2, X0_3, 1 + (3 << 4)));
_mm256_storeu_si256(reinterpret_cast<__m256i*>(output+2*32),
_mm256_permute2x128_si256(X1_0, X1_1, 1 + (3 << 4)));
_mm256_storeu_si256(reinterpret_cast<__m256i*>(output+3*32),
_mm256_permute2x128_si256(X1_2, X1_3, 1 + (3 << 4)));
} }
if (input_mm) if (input)
{ {
_mm256_storeu_si256(output_mm + 4, _mm256_xor_si256(_mm256_loadu_si256(input_mm + 4), _mm256_storeu_si256(reinterpret_cast<__m256i*>(output+4*32),
_mm256_permute2x128_si256(X2_0, X2_1, 1 + (3 << 4)))); _mm256_xor_si256(_mm256_permute2x128_si256(X2_0, X2_1, 1 + (3 << 4)),
_mm256_storeu_si256(output_mm + 5, _mm256_xor_si256(_mm256_loadu_si256(input_mm + 5), _mm256_loadu_si256(reinterpret_cast<const __m256i*>(input+4*32))));
_mm256_permute2x128_si256(X2_2, X2_3, 1 + (3 << 4)))); _mm256_storeu_si256(reinterpret_cast<__m256i*>(output+5*32),
_mm256_storeu_si256(output_mm + 6, _mm256_xor_si256(_mm256_loadu_si256(input_mm + 6), _mm256_xor_si256(_mm256_permute2x128_si256(X2_2, X2_3, 1 + (3 << 4)),
_mm256_permute2x128_si256(X3_0, X3_1, 1 + (3 << 4)))); _mm256_loadu_si256(reinterpret_cast<const __m256i*>(input+5*32))));
_mm256_storeu_si256(output_mm + 7, _mm256_xor_si256(_mm256_loadu_si256(input_mm + 7), _mm256_storeu_si256(reinterpret_cast<__m256i*>(output+6*32),
_mm256_permute2x128_si256(X3_2, X3_3, 1 + (3 << 4)))); _mm256_xor_si256(_mm256_permute2x128_si256(X3_0, X3_1, 1 + (3 << 4)),
_mm256_loadu_si256(reinterpret_cast<const __m256i*>(input+6*32))));
_mm256_storeu_si256(reinterpret_cast<__m256i*>(output+7*32),
_mm256_xor_si256(_mm256_permute2x128_si256(X3_2, X3_3, 1 + (3 << 4)),
_mm256_loadu_si256(reinterpret_cast<const __m256i*>(input+7*32))));
} }
else else
{ {
_mm256_storeu_si256(output_mm + 4, _mm256_permute2x128_si256(X2_0, X2_1, 1 + (3 << 4))); _mm256_storeu_si256(reinterpret_cast<__m256i*>(output+4*32),
_mm256_storeu_si256(output_mm + 5, _mm256_permute2x128_si256(X2_2, X2_3, 1 + (3 << 4))); _mm256_permute2x128_si256(X2_0, X2_1, 1 + (3 << 4)));
_mm256_storeu_si256(output_mm + 6, _mm256_permute2x128_si256(X3_0, X3_1, 1 + (3 << 4))); _mm256_storeu_si256(reinterpret_cast<__m256i*>(output+5*32),
_mm256_storeu_si256(output_mm + 7, _mm256_permute2x128_si256(X3_2, X3_3, 1 + (3 << 4))); _mm256_permute2x128_si256(X2_2, X2_3, 1 + (3 << 4)));
_mm256_storeu_si256(reinterpret_cast<__m256i*>(output+6*32),
_mm256_permute2x128_si256(X3_0, X3_1, 1 + (3 << 4)));
_mm256_storeu_si256(reinterpret_cast<__m256i*>(output+7*32),
_mm256_permute2x128_si256(X3_2, X3_3, 1 + (3 << 4)));
} }
if (input_mm) if (input)
{ {
_mm256_storeu_si256(output_mm + 8, _mm256_xor_si256(_mm256_loadu_si256(input_mm + 8), _mm256_storeu_si256(reinterpret_cast<__m256i*>(output+ 8*32),
_mm256_permute2x128_si256(X0_0, X0_1, 0 + (2 << 4)))); _mm256_xor_si256(_mm256_permute2x128_si256(X0_0, X0_1, 0 + (2 << 4)),
_mm256_storeu_si256(output_mm + 9, _mm256_xor_si256(_mm256_loadu_si256(input_mm + 9), _mm256_loadu_si256(reinterpret_cast<const __m256i*>(input+8*32))));
_mm256_permute2x128_si256(X0_2, X0_3, 0 + (2 << 4)))); _mm256_storeu_si256(reinterpret_cast<__m256i*>(output+ 9*32),
_mm256_storeu_si256(output_mm + 10, _mm256_xor_si256(_mm256_loadu_si256(input_mm + 10), _mm256_xor_si256(_mm256_permute2x128_si256(X0_2, X0_3, 0 + (2 << 4)),
_mm256_permute2x128_si256(X1_0, X1_1, 0 + (2 << 4)))); _mm256_loadu_si256(reinterpret_cast<const __m256i*>(input+9*32))));
_mm256_storeu_si256(output_mm + 11, _mm256_xor_si256(_mm256_loadu_si256(input_mm + 11), _mm256_storeu_si256(reinterpret_cast<__m256i*>(output+10*32),
_mm256_permute2x128_si256(X1_2, X1_3, 0 + (2 << 4)))); _mm256_xor_si256(_mm256_permute2x128_si256(X1_0, X1_1, 0 + (2 << 4)),
_mm256_loadu_si256(reinterpret_cast<const __m256i*>(input+10*32))));
_mm256_storeu_si256(reinterpret_cast<__m256i*>(output+11*32),
_mm256_xor_si256(_mm256_permute2x128_si256(X1_2, X1_3, 0 + (2 << 4)),
_mm256_loadu_si256(reinterpret_cast<const __m256i*>(input+11*32))));
} }
else else
{ {
_mm256_storeu_si256(output_mm + 8, _mm256_permute2x128_si256(X0_0, X0_1, 0 + (2 << 4))); _mm256_storeu_si256(reinterpret_cast<__m256i*>(output+ 8*32),
_mm256_storeu_si256(output_mm + 9, _mm256_permute2x128_si256(X0_2, X0_3, 0 + (2 << 4))); _mm256_permute2x128_si256(X0_0, X0_1, 0 + (2 << 4)));
_mm256_storeu_si256(output_mm + 10, _mm256_permute2x128_si256(X1_0, X1_1, 0 + (2 << 4))); _mm256_storeu_si256(reinterpret_cast<__m256i*>(output+ 9*32),
_mm256_storeu_si256(output_mm + 11, _mm256_permute2x128_si256(X1_2, X1_3, 0 + (2 << 4))); _mm256_permute2x128_si256(X0_2, X0_3, 0 + (2 << 4)));
_mm256_storeu_si256(reinterpret_cast<__m256i*>(output+10*32),
_mm256_permute2x128_si256(X1_0, X1_1, 0 + (2 << 4)));
_mm256_storeu_si256(reinterpret_cast<__m256i*>(output+11*32),
_mm256_permute2x128_si256(X1_2, X1_3, 0 + (2 << 4)));
} }
if (input_mm) if (input)
{ {
_mm256_storeu_si256(output_mm + 12, _mm256_xor_si256(_mm256_loadu_si256(input_mm + 12), _mm256_storeu_si256(reinterpret_cast<__m256i*>(output+12*32),
_mm256_permute2x128_si256(X2_0, X2_1, 0 + (2 << 4)))); _mm256_xor_si256(_mm256_permute2x128_si256(X2_0, X2_1, 0 + (2 << 4)),
_mm256_storeu_si256(output_mm + 13, _mm256_xor_si256(_mm256_loadu_si256(input_mm + 13), _mm256_loadu_si256(reinterpret_cast<const __m256i*>(input+12*32))));
_mm256_permute2x128_si256(X2_2, X2_3, 0 + (2 << 4)))); _mm256_storeu_si256(reinterpret_cast<__m256i*>(output+13*32),
_mm256_storeu_si256(output_mm + 14, _mm256_xor_si256(_mm256_loadu_si256(input_mm + 14), _mm256_xor_si256(_mm256_permute2x128_si256(X2_2, X2_3, 0 + (2 << 4)),
_mm256_permute2x128_si256(X3_0, X3_1, 0 + (2 << 4)))); _mm256_loadu_si256(reinterpret_cast<const __m256i*>(input+13*32))));
_mm256_storeu_si256(output_mm + 15, _mm256_xor_si256(_mm256_loadu_si256(input_mm + 15), _mm256_storeu_si256(reinterpret_cast<__m256i*>(output+14*32),
_mm256_permute2x128_si256(X3_2, X3_3, 0 + (2 << 4)))); _mm256_xor_si256(_mm256_permute2x128_si256(X3_0, X3_1, 0 + (2 << 4)),
_mm256_loadu_si256(reinterpret_cast<const __m256i*>(input+14*32))));
_mm256_storeu_si256(reinterpret_cast<__m256i*>(output+15*32),
_mm256_xor_si256(_mm256_permute2x128_si256(X3_2, X3_3, 0 + (2 << 4)),
_mm256_loadu_si256(reinterpret_cast<const __m256i*>(input+15*32))));
} }
else else
{ {
_mm256_storeu_si256(output_mm + 12, _mm256_permute2x128_si256(X2_0, X2_1, 0 + (2 << 4))); _mm256_storeu_si256(reinterpret_cast<__m256i*>(output+12*32),
_mm256_storeu_si256(output_mm + 13, _mm256_permute2x128_si256(X2_2, X2_3, 0 + (2 << 4))); _mm256_permute2x128_si256(X2_0, X2_1, 0 + (2 << 4)));
_mm256_storeu_si256(output_mm + 14, _mm256_permute2x128_si256(X3_0, X3_1, 0 + (2 << 4))); _mm256_storeu_si256(reinterpret_cast<__m256i*>(output+13*32),
_mm256_storeu_si256(output_mm + 15, _mm256_permute2x128_si256(X3_2, X3_3, 0 + (2 << 4))); _mm256_permute2x128_si256(X2_2, X2_3, 0 + (2 << 4)));
_mm256_storeu_si256(reinterpret_cast<__m256i*>(output+14*32),
_mm256_permute2x128_si256(X3_0, X3_1, 0 + (2 << 4)));
_mm256_storeu_si256(reinterpret_cast<__m256i*>(output+15*32),
_mm256_permute2x128_si256(X3_2, X3_3, 0 + (2 << 4)));
} }
// https://software.intel.com/en-us/articles/avoiding-avx-sse-transition-penalties // https://software.intel.com/en-us/articles/avoiding-avx-sse-transition-penalties

View File

@ -46,6 +46,9 @@
#if defined(__XOP__) #if defined(__XOP__)
# include <ammintrin.h> # include <ammintrin.h>
# if defined(__GNUC__)
# include <x86intrin.h>
# endif
#endif #endif
// C1189: error: This header is specific to ARM targets // C1189: error: This header is specific to ARM targets
@ -209,7 +212,7 @@ inline __m128i RotateLeft<16>(const __m128i val)
#if (CRYPTOPP_ALTIVEC_AVAILABLE) #if (CRYPTOPP_ALTIVEC_AVAILABLE)
// ChaCha_OperateKeystream_POWER7 is optimized for POWER7. However, Altivec // ChaCha_OperateKeystream_POWER8 is optimized for POWER7. However, Altivec
// is supported by using vec_ld and vec_st, and using a composite VecAdd // is supported by using vec_ld and vec_st, and using a composite VecAdd
// that supports 64-bit element adds. vec_ld and vec_st add significant // that supports 64-bit element adds. vec_ld and vec_st add significant
// overhead when memory is not aligned. Despite the drawbacks Altivec // overhead when memory is not aligned. Despite the drawbacks Altivec
@ -565,14 +568,10 @@ void ChaCha_OperateKeystream_NEON(const word32 *state, const byte* input, byte *
void ChaCha_OperateKeystream_SSE2(const word32 *state, const byte* input, byte *output, unsigned int rounds) void ChaCha_OperateKeystream_SSE2(const word32 *state, const byte* input, byte *output, unsigned int rounds)
{ {
const __m128i* state_mm = reinterpret_cast<const __m128i*>(state); const __m128i state0 = _mm_load_si128(reinterpret_cast<const __m128i*>(state+0*4));
const __m128i* input_mm = reinterpret_cast<const __m128i*>(input); const __m128i state1 = _mm_load_si128(reinterpret_cast<const __m128i*>(state+1*4));
__m128i* output_mm = reinterpret_cast<__m128i*>(output); const __m128i state2 = _mm_load_si128(reinterpret_cast<const __m128i*>(state+2*4));
const __m128i state3 = _mm_load_si128(reinterpret_cast<const __m128i*>(state+3*4));
const __m128i state0 = _mm_load_si128(state_mm + 0);
const __m128i state1 = _mm_load_si128(state_mm + 1);
const __m128i state2 = _mm_load_si128(state_mm + 2);
const __m128i state3 = _mm_load_si128(state_mm + 3);
__m128i r0_0 = state0; __m128i r0_0 = state0;
__m128i r0_1 = state1; __m128i r0_1 = state1;
@ -772,62 +771,62 @@ void ChaCha_OperateKeystream_SSE2(const word32 *state, const byte* input, byte *
r3_3 = _mm_add_epi32(r3_3, state3); r3_3 = _mm_add_epi32(r3_3, state3);
r3_3 = _mm_add_epi64(r3_3, _mm_set_epi32(0, 0, 0, 3)); r3_3 = _mm_add_epi64(r3_3, _mm_set_epi32(0, 0, 0, 3));
if (input_mm) if (input)
{ {
r0_0 = _mm_xor_si128(_mm_loadu_si128(input_mm + 0), r0_0); r0_0 = _mm_xor_si128(_mm_loadu_si128(reinterpret_cast<const __m128i*>(input+0*16)), r0_0);
r0_1 = _mm_xor_si128(_mm_loadu_si128(input_mm + 1), r0_1); r0_1 = _mm_xor_si128(_mm_loadu_si128(reinterpret_cast<const __m128i*>(input+1*16)), r0_1);
r0_2 = _mm_xor_si128(_mm_loadu_si128(input_mm + 2), r0_2); r0_2 = _mm_xor_si128(_mm_loadu_si128(reinterpret_cast<const __m128i*>(input+2*16)), r0_2);
r0_3 = _mm_xor_si128(_mm_loadu_si128(input_mm + 3), r0_3); r0_3 = _mm_xor_si128(_mm_loadu_si128(reinterpret_cast<const __m128i*>(input+3*16)), r0_3);
} }
_mm_storeu_si128(output_mm + 0, r0_0); _mm_storeu_si128(reinterpret_cast<__m128i*>(output+0*16), r0_0);
_mm_storeu_si128(output_mm + 1, r0_1); _mm_storeu_si128(reinterpret_cast<__m128i*>(output+1*16), r0_1);
_mm_storeu_si128(output_mm + 2, r0_2); _mm_storeu_si128(reinterpret_cast<__m128i*>(output+2*16), r0_2);
_mm_storeu_si128(output_mm + 3, r0_3); _mm_storeu_si128(reinterpret_cast<__m128i*>(output+3*16), r0_3);
if (input_mm) if (input)
{ {
r1_0 = _mm_xor_si128(_mm_loadu_si128(input_mm + 4), r1_0); r1_0 = _mm_xor_si128(_mm_loadu_si128(reinterpret_cast<const __m128i*>(input+4*16)), r1_0);
r1_1 = _mm_xor_si128(_mm_loadu_si128(input_mm + 5), r1_1); r1_1 = _mm_xor_si128(_mm_loadu_si128(reinterpret_cast<const __m128i*>(input+5*16)), r1_1);
r1_2 = _mm_xor_si128(_mm_loadu_si128(input_mm + 6), r1_2); r1_2 = _mm_xor_si128(_mm_loadu_si128(reinterpret_cast<const __m128i*>(input+6*16)), r1_2);
r1_3 = _mm_xor_si128(_mm_loadu_si128(input_mm + 7), r1_3); r1_3 = _mm_xor_si128(_mm_loadu_si128(reinterpret_cast<const __m128i*>(input+7*16)), r1_3);
} }
_mm_storeu_si128(output_mm + 4, r1_0); _mm_storeu_si128(reinterpret_cast<__m128i*>(output+4*16), r1_0);
_mm_storeu_si128(output_mm + 5, r1_1); _mm_storeu_si128(reinterpret_cast<__m128i*>(output+5*16), r1_1);
_mm_storeu_si128(output_mm + 6, r1_2); _mm_storeu_si128(reinterpret_cast<__m128i*>(output+6*16), r1_2);
_mm_storeu_si128(output_mm + 7, r1_3); _mm_storeu_si128(reinterpret_cast<__m128i*>(output+7*16), r1_3);
if (input_mm) if (input)
{ {
r2_0 = _mm_xor_si128(_mm_loadu_si128(input_mm + 8), r2_0); r2_0 = _mm_xor_si128(_mm_loadu_si128(reinterpret_cast<const __m128i*>(input+ 8*16)), r2_0);
r2_1 = _mm_xor_si128(_mm_loadu_si128(input_mm + 9), r2_1); r2_1 = _mm_xor_si128(_mm_loadu_si128(reinterpret_cast<const __m128i*>(input+ 9*16)), r2_1);
r2_2 = _mm_xor_si128(_mm_loadu_si128(input_mm + 10), r2_2); r2_2 = _mm_xor_si128(_mm_loadu_si128(reinterpret_cast<const __m128i*>(input+10*16)), r2_2);
r2_3 = _mm_xor_si128(_mm_loadu_si128(input_mm + 11), r2_3); r2_3 = _mm_xor_si128(_mm_loadu_si128(reinterpret_cast<const __m128i*>(input+11*16)), r2_3);
} }
_mm_storeu_si128(output_mm + 8, r2_0); _mm_storeu_si128(reinterpret_cast<__m128i*>(output+ 8*16), r2_0);
_mm_storeu_si128(output_mm + 9, r2_1); _mm_storeu_si128(reinterpret_cast<__m128i*>(output+ 9*16), r2_1);
_mm_storeu_si128(output_mm + 10, r2_2); _mm_storeu_si128(reinterpret_cast<__m128i*>(output+10*16), r2_2);
_mm_storeu_si128(output_mm + 11, r2_3); _mm_storeu_si128(reinterpret_cast<__m128i*>(output+11*16), r2_3);
if (input_mm) if (input)
{ {
r3_0 = _mm_xor_si128(_mm_loadu_si128(input_mm + 12), r3_0); r3_0 = _mm_xor_si128(_mm_loadu_si128(reinterpret_cast<const __m128i*>(input+12*16)), r3_0);
r3_1 = _mm_xor_si128(_mm_loadu_si128(input_mm + 13), r3_1); r3_1 = _mm_xor_si128(_mm_loadu_si128(reinterpret_cast<const __m128i*>(input+13*16)), r3_1);
r3_2 = _mm_xor_si128(_mm_loadu_si128(input_mm + 14), r3_2); r3_2 = _mm_xor_si128(_mm_loadu_si128(reinterpret_cast<const __m128i*>(input+14*16)), r3_2);
r3_3 = _mm_xor_si128(_mm_loadu_si128(input_mm + 15), r3_3); r3_3 = _mm_xor_si128(_mm_loadu_si128(reinterpret_cast<const __m128i*>(input+15*16)), r3_3);
} }
_mm_storeu_si128(output_mm + 12, r3_0); _mm_storeu_si128(reinterpret_cast<__m128i*>(output+12*16), r3_0);
_mm_storeu_si128(output_mm + 13, r3_1); _mm_storeu_si128(reinterpret_cast<__m128i*>(output+13*16), r3_1);
_mm_storeu_si128(output_mm + 14, r3_2); _mm_storeu_si128(reinterpret_cast<__m128i*>(output+14*16), r3_2);
_mm_storeu_si128(output_mm + 15, r3_3); _mm_storeu_si128(reinterpret_cast<__m128i*>(output+15*16), r3_3);
} }
#endif // CRYPTOPP_SSE2_INTRIN_AVAILABLE #endif // CRYPTOPP_SSE2_INTRIN_AVAILABLE
#if (CRYPTOPP_POWER7_AVAILABLE || CRYPTOPP_ALTIVEC_AVAILABLE) #if (CRYPTOPP_POWER8_AVAILABLE || CRYPTOPP_ALTIVEC_AVAILABLE)
// ChaCha_OperateKeystream_CORE will use either POWER7 or ALTIVEC, // ChaCha_OperateKeystream_CORE will use either POWER7 or ALTIVEC,
// depending on the flags used to compile this source file. The // depending on the flags used to compile this source file. The
@ -1096,11 +1095,11 @@ inline void ChaCha_OperateKeystream_CORE(const word32 *state, const byte* input,
VecStore32LE(output + 15*16, r3_3); VecStore32LE(output + 15*16, r3_3);
} }
#endif // CRYPTOPP_POWER7_AVAILABLE || CRYPTOPP_ALTIVEC_AVAILABLE #endif // CRYPTOPP_POWER8_AVAILABLE || CRYPTOPP_ALTIVEC_AVAILABLE
#if (CRYPTOPP_POWER7_AVAILABLE) #if (CRYPTOPP_POWER8_AVAILABLE)
void ChaCha_OperateKeystream_POWER7(const word32 *state, const byte* input, byte *output, unsigned int rounds) void ChaCha_OperateKeystream_POWER8(const word32 *state, const byte* input, byte *output, unsigned int rounds)
{ {
ChaCha_OperateKeystream_CORE(state, input, output, rounds); ChaCha_OperateKeystream_CORE(state, input, output, rounds);
} }

View File

@ -24,6 +24,9 @@
#if defined(__XOP__) #if defined(__XOP__)
# include <ammintrin.h> # include <ammintrin.h>
# if defined(__GNUC__)
# include <x86intrin.h>
# endif
#endif #endif
#if defined(__AVX512F__) #if defined(__AVX512F__)
@ -31,6 +34,10 @@
# include <immintrin.h> # include <immintrin.h>
#endif #endif
// Clang intrinsic casts, http://bugs.llvm.org/show_bug.cgi?id=20670
#define DOUBLE_CAST(x) ((double*)(void*)(x))
#define CONST_DOUBLE_CAST(x) ((const double*)(const void*)(x))
// Squash MS LNK4221 and libtool warnings // Squash MS LNK4221 and libtool warnings
extern const char CHAM_SIMD_FNAME[] = __FILE__; extern const char CHAM_SIMD_FNAME[] = __FILE__;
@ -355,7 +362,7 @@ inline void CHAM64_Enc_Block(__m128i &block0,
for (int i=0; i<static_cast<int>(rounds); i+=4) for (int i=0; i<static_cast<int>(rounds); i+=4)
{ {
__m128i k, kr, t1, t2, t3, t4; __m128i k, kr, t1, t2, t3, t4;
k = _mm_castpd_si128(_mm_load_sd((const double*)(&subkeys[(i+0) & MASK]))); k = _mm_castpd_si128(_mm_load_sd(CONST_DOUBLE_CAST(&subkeys[(i+0) & MASK])));
// Shuffle out key // Shuffle out key
kr = _mm_shuffle_epi8(k, _mm_set_epi8(1,0,1,0, 1,0,1,0, 1,0,1,0, 1,0,1,0)); kr = _mm_shuffle_epi8(k, _mm_set_epi8(1,0,1,0, 1,0,1,0, 1,0,1,0, 1,0,1,0));
@ -428,7 +435,7 @@ inline void CHAM64_Dec_Block(__m128i &block0,
for (int i = static_cast<int>(rounds)-1; i >= 0; i-=4) for (int i = static_cast<int>(rounds)-1; i >= 0; i-=4)
{ {
__m128i k, kr, t1, t2, t3, t4; __m128i k, kr, t1, t2, t3, t4;
k = _mm_castpd_si128(_mm_load_sd((const double*)(&subkeys[(i-3) & MASK]))); k = _mm_castpd_si128(_mm_load_sd(CONST_DOUBLE_CAST(&subkeys[(i-3) & MASK])));
// Shuffle out key // Shuffle out key
kr = _mm_shuffle_epi8(k, _mm_set_epi8(7,6,7,6, 7,6,7,6, 7,6,7,6, 7,6,7,6)); kr = _mm_shuffle_epi8(k, _mm_set_epi8(7,6,7,6, 7,6,7,6, 7,6,7,6, 7,6,7,6));
@ -505,7 +512,7 @@ inline void CHAM64_Enc_2_Blocks(__m128i &block0,
for (int i=0; i<static_cast<int>(rounds); i+=4) for (int i=0; i<static_cast<int>(rounds); i+=4)
{ {
__m128i k, kr, t1, t2, t3, t4; __m128i k, kr, t1, t2, t3, t4;
k = _mm_castpd_si128(_mm_load_sd((const double*)(&subkeys[i & MASK]))); k = _mm_castpd_si128(_mm_load_sd(CONST_DOUBLE_CAST(&subkeys[(i+0) & MASK])));
// Shuffle out key // Shuffle out key
kr = _mm_shuffle_epi8(k, _mm_set_epi8(1,0,1,0, 1,0,1,0, 1,0,1,0, 1,0,1,0)); kr = _mm_shuffle_epi8(k, _mm_set_epi8(1,0,1,0, 1,0,1,0, 1,0,1,0, 1,0,1,0));
@ -579,7 +586,7 @@ inline void CHAM64_Dec_2_Blocks(__m128i &block0,
for (int i = static_cast<int>(rounds)-1; i >= 0; i-=4) for (int i = static_cast<int>(rounds)-1; i >= 0; i-=4)
{ {
__m128i k, kr, t1, t2, t3, t4; __m128i k, kr, t1, t2, t3, t4;
k = _mm_castpd_si128(_mm_load_sd((const double*)(&subkeys[(i-3) & MASK]))); k = _mm_castpd_si128(_mm_load_sd(CONST_DOUBLE_CAST(&subkeys[(i-3) & MASK])));
// Shuffle out key // Shuffle out key
kr = _mm_shuffle_epi8(k, _mm_set_epi8(7,6,7,6, 7,6,7,6, 7,6,7,6, 7,6,7,6)); kr = _mm_shuffle_epi8(k, _mm_set_epi8(7,6,7,6, 7,6,7,6, 7,6,7,6, 7,6,7,6));
@ -814,7 +821,7 @@ inline void CHAM128_Enc_Block(__m128i &block0,
for (int i=0; i<static_cast<int>(rounds); i+=4) for (int i=0; i<static_cast<int>(rounds); i+=4)
{ {
__m128i k, k1, k2, t1, t2; __m128i k, k1, k2, t1, t2;
k = _mm_castpd_si128(_mm_load_sd((const double*)(&subkeys[(i+0) & MASK]))); k = _mm_castpd_si128(_mm_load_sd(CONST_DOUBLE_CAST(&subkeys[(i+0) & MASK])));
// Shuffle out two subkeys // Shuffle out two subkeys
k1 = _mm_shuffle_epi8(k, _mm_set_epi8(3,2,1,0, 3,2,1,0, 3,2,1,0, 3,2,1,0)); k1 = _mm_shuffle_epi8(k, _mm_set_epi8(3,2,1,0, 3,2,1,0, 3,2,1,0, 3,2,1,0));
@ -831,8 +838,7 @@ inline void CHAM128_Enc_Block(__m128i &block0,
b = RotateLeft32<1>(_mm_add_epi32(t1, t2)); b = RotateLeft32<1>(_mm_add_epi32(t1, t2));
counter = _mm_add_epi32(counter, increment); counter = _mm_add_epi32(counter, increment);
k = _mm_castpd_si128(_mm_load_sd(CONST_DOUBLE_CAST(&subkeys[(i+2) & MASK])));
k = _mm_castpd_si128(_mm_load_sd((const double*)(&subkeys[(i+2) & MASK])));
// Shuffle out two subkeys // Shuffle out two subkeys
k1 = _mm_shuffle_epi8(k, _mm_set_epi8(3,2,1,0, 3,2,1,0, 3,2,1,0, 3,2,1,0)); k1 = _mm_shuffle_epi8(k, _mm_set_epi8(3,2,1,0, 3,2,1,0, 3,2,1,0, 3,2,1,0));
@ -874,7 +880,7 @@ inline void CHAM128_Dec_Block(__m128i &block0,
for (int i = static_cast<int>(rounds)-1; i >= 0; i-=4) for (int i = static_cast<int>(rounds)-1; i >= 0; i-=4)
{ {
__m128i k, k1, k2, t1, t2; __m128i k, k1, k2, t1, t2;
k = _mm_castpd_si128(_mm_load_sd((const double*)(&subkeys[(i-1) & MASK]))); k = _mm_castpd_si128(_mm_load_sd(CONST_DOUBLE_CAST(&subkeys[(i-1) & MASK])));
// Shuffle out two subkeys // Shuffle out two subkeys
k1 = _mm_shuffle_epi8(k, _mm_set_epi8(7,6,5,4, 7,6,5,4, 7,6,5,4, 7,6,5,4)); k1 = _mm_shuffle_epi8(k, _mm_set_epi8(7,6,5,4, 7,6,5,4, 7,6,5,4, 7,6,5,4));
@ -893,7 +899,7 @@ inline void CHAM128_Dec_Block(__m128i &block0,
c = _mm_xor_si128(_mm_sub_epi32(t1, t2), counter); c = _mm_xor_si128(_mm_sub_epi32(t1, t2), counter);
counter = _mm_sub_epi32(counter, decrement); counter = _mm_sub_epi32(counter, decrement);
k = _mm_castpd_si128(_mm_load_sd((const double*)(&subkeys[(i-3) & MASK]))); k = _mm_castpd_si128(_mm_load_sd(CONST_DOUBLE_CAST(&subkeys[(i-3) & MASK])));
// Shuffle out two subkeys // Shuffle out two subkeys
k1 = _mm_shuffle_epi8(k, _mm_set_epi8(7,6,5,4, 7,6,5,4, 7,6,5,4, 7,6,5,4)); k1 = _mm_shuffle_epi8(k, _mm_set_epi8(7,6,5,4, 7,6,5,4, 7,6,5,4, 7,6,5,4));
@ -937,7 +943,7 @@ inline void CHAM128_Enc_4_Blocks(__m128i &block0, __m128i &block1,
for (int i=0; i<static_cast<int>(rounds); i+=4) for (int i=0; i<static_cast<int>(rounds); i+=4)
{ {
__m128i k, k1, k2, t1, t2; __m128i k, k1, k2, t1, t2;
k = _mm_castpd_si128(_mm_load_sd((const double*)(&subkeys[(i+0) & MASK]))); k = _mm_castpd_si128(_mm_load_sd(CONST_DOUBLE_CAST(&subkeys[(i+0) & MASK])));
// Shuffle out two subkeys // Shuffle out two subkeys
k1 = _mm_shuffle_epi8(k, _mm_set_epi8(3,2,1,0, 3,2,1,0, 3,2,1,0, 3,2,1,0)); k1 = _mm_shuffle_epi8(k, _mm_set_epi8(3,2,1,0, 3,2,1,0, 3,2,1,0, 3,2,1,0));
@ -954,7 +960,7 @@ inline void CHAM128_Enc_4_Blocks(__m128i &block0, __m128i &block1,
b = RotateLeft32<1>(_mm_add_epi32(t1, t2)); b = RotateLeft32<1>(_mm_add_epi32(t1, t2));
counter = _mm_add_epi32(counter, increment); counter = _mm_add_epi32(counter, increment);
k = _mm_castpd_si128(_mm_load_sd((const double*)(&subkeys[(i+2) & MASK]))); k = _mm_castpd_si128(_mm_load_sd(CONST_DOUBLE_CAST(&subkeys[(i+2) & MASK])));
// Shuffle out two subkeys // Shuffle out two subkeys
k1 = _mm_shuffle_epi8(k, _mm_set_epi8(3,2,1,0, 3,2,1,0, 3,2,1,0, 3,2,1,0)); k1 = _mm_shuffle_epi8(k, _mm_set_epi8(3,2,1,0, 3,2,1,0, 3,2,1,0, 3,2,1,0));
@ -999,7 +1005,7 @@ inline void CHAM128_Dec_4_Blocks(__m128i &block0, __m128i &block1,
for (int i = static_cast<int>(rounds)-1; i >= 0; i-=4) for (int i = static_cast<int>(rounds)-1; i >= 0; i-=4)
{ {
__m128i k, k1, k2, t1, t2; __m128i k, k1, k2, t1, t2;
k = _mm_castpd_si128(_mm_load_sd((const double*)(&subkeys[(i-1) & MASK]))); k = _mm_castpd_si128(_mm_load_sd(CONST_DOUBLE_CAST(&subkeys[(i-1) & MASK])));
// Shuffle out two subkeys // Shuffle out two subkeys
k1 = _mm_shuffle_epi8(k, _mm_set_epi8(7,6,5,4, 7,6,5,4, 7,6,5,4, 7,6,5,4)); k1 = _mm_shuffle_epi8(k, _mm_set_epi8(7,6,5,4, 7,6,5,4, 7,6,5,4, 7,6,5,4));
@ -1018,7 +1024,7 @@ inline void CHAM128_Dec_4_Blocks(__m128i &block0, __m128i &block1,
c = _mm_xor_si128(_mm_sub_epi32(t1, t2), counter); c = _mm_xor_si128(_mm_sub_epi32(t1, t2), counter);
counter = _mm_sub_epi32(counter, decrement); counter = _mm_sub_epi32(counter, decrement);
k = _mm_castpd_si128(_mm_load_sd((const double*)(&subkeys[(i-3) & MASK]))); k = _mm_castpd_si128(_mm_load_sd(CONST_DOUBLE_CAST(&subkeys[(i-3) & MASK])));
// Shuffle out two subkeys // Shuffle out two subkeys
k1 = _mm_shuffle_epi8(k, _mm_set_epi8(7,6,5,4, 7,6,5,4, 7,6,5,4, 7,6,5,4)); k1 = _mm_shuffle_epi8(k, _mm_set_epi8(7,6,5,4, 7,6,5,4, 7,6,5,4, 7,6,5,4));

1278
config.h

File diff suppressed because it is too large Load Diff

61
config_align.h Normal file
View File

@ -0,0 +1,61 @@
// config_align.h - written and placed in public domain by Jeffrey Walton
// the bits that make up this source file are from the
// library's monolithic config.h.
/// \file config_align.h
/// \brief Library configuration file
/// \details <tt>config.h</tt> was split into components in May 2019 to better
/// integrate with Autoconf and its feature tests. The splitting occured so
/// users could continue to include <tt>config.h</tt> while allowing Autoconf
/// to write new <tt>config_asm.h</tt> and new <tt>config_cxx.h</tt> using
/// its feature tests.
/// \sa <A HREF="https://github.com/weidai11/cryptopp/issues/835">Issue 835</A>
/// \since Crypto++ 8.3
#ifndef CRYPTOPP_CONFIG_ALIGN_H
#define CRYPTOPP_CONFIG_ALIGN_H
#include "config_cpu.h"
#include "config_cxx.h"
#include "config_ver.h"
// Nearly all Intel's and AMD's have SSE. Enable it independent of SSE ASM and intrinscs
#if (CRYPTOPP_BOOL_X86 || CRYPTOPP_BOOL_X32 || CRYPTOPP_BOOL_X64 || CRYPTOPP_BOOL_PPC32 || CRYPTOPP_BOOL_PPC64) && !defined(CRYPTOPP_DISABLE_ASM)
#define CRYPTOPP_BOOL_ALIGN16 1
#else
#define CRYPTOPP_BOOL_ALIGN16 0
#endif
// How to allocate 16-byte aligned memory (for SSE2)
// posix_memalign see https://forum.kde.org/viewtopic.php?p=66274
#if defined(_MSC_VER)
#define CRYPTOPP_MM_MALLOC_AVAILABLE
#elif defined(__linux__) || defined(__sun__) || defined(__CYGWIN__)
#define CRYPTOPP_MEMALIGN_AVAILABLE
#elif defined(__APPLE__) || defined(__NetBSD__) || defined(__OpenBSD__) || defined(__DragonFly__)
#define CRYPTOPP_MALLOC_ALIGNMENT_IS_16
#elif (defined(_GNU_SOURCE) || ((_XOPEN_SOURCE + 0) >= 600)) && (_POSIX_ADVISORY_INFO > 0)
#define CRYPTOPP_POSIX_MEMALIGN_AVAILABLE
#else
#define CRYPTOPP_NO_ALIGNED_ALLOC
#endif
// Sun Studio Express 3 (December 2006) provides GCC-style attributes.
// IBM XL C/C++ alignment modifier per Optimization Guide, pp. 19-20.
// __IBM_ATTRIBUTES per XLC 12.1 AIX Compiler Manual, p. 473.
// CRYPTOPP_ALIGN_DATA may not be reliable on AIX.
#ifndef CRYPTOPP_ALIGN_DATA
#if defined(CRYPTOPP_CXX11_ALIGNAS)
#define CRYPTOPP_ALIGN_DATA(x) alignas(x)
#elif defined(_MSC_VER)
#define CRYPTOPP_ALIGN_DATA(x) __declspec(align(x))
#elif defined(__GNUC__) || defined(__clang__) || (__SUNPRO_CC >= 0x5100)
#define CRYPTOPP_ALIGN_DATA(x) __attribute__((aligned(x)))
#elif defined(__xlc__) || defined(__xlC__)
#define CRYPTOPP_ALIGN_DATA(x) __attribute__((aligned(x)))
#else
#define CRYPTOPP_ALIGN_DATA(x)
#endif
#endif
#endif // CRYPTOPP_CONFIG_ALIGN_H

418
config_asm.h Normal file
View File

@ -0,0 +1,418 @@
// config_asm.h - written and placed in public domain by Jeffrey Walton
// the bits that make up this source file are from the
// library's monolithic config.h.
/// \file config_asm.h
/// \brief Library configuration file
/// \details <tt>config.h</tt> was split into components in May 2019 to better
/// integrate with Autoconf and its feature tests. The splitting occured so
/// users could continue to include <tt>config.h</tt> while allowing Autoconf
/// to write new <tt>config_asm.h</tt> and new <tt>config_cxx.h</tt> using
/// its feature tests.
/// \sa <A HREF="https://github.com/weidai11/cryptopp/issues/835">Issue 835</A>
/// \since Crypto++ 8.3
#ifndef CRYPTOPP_CONFIG_ASM_H
#define CRYPTOPP_CONFIG_ASM_H
#include "config_os.h"
#include "config_cpu.h"
#include "config_ver.h"
// Define this to disable ASM, intrinsics and built-ins. The library will be
// compiled using C++ only. The library code will not include SSE2 (and
// above), NEON, Aarch32, Aarch64, or Altivec (and above). Note the compiler
// may use higher ISAs depending on compiler options, but the library will not
// explictly use the ISAs. When disabling ASM, it is best to do it from
// config.h to ensure the library and all programs share the setting.
// #define CRYPTOPP_DISABLE_ASM 1
// https://github.com/weidai11/cryptopp/issues/719
#if defined(__native_client__) && !defined(CRYPTOPP_DISABLE_ASM)
# define CRYPTOPP_DISABLE_ASM 1
#endif
// Some Clang and SunCC cannot handle mixed asm with positional arguments,
// where the body is Intel style with no prefix and the templates are
// AT&T style. Define this if the Makefile misdetects the configuration.
// Also see https://bugs.llvm.org/show_bug.cgi?id=39895 .
// #define CRYPTOPP_DISABLE_MIXED_ASM 1
// CRYPTOPP_ALLOW_UNALIGNED_DATA_ACCESS is no longer honored. It
// was removed at https://github.com/weidai11/cryptopp/issues/682
// #define CRYPTOPP_ALLOW_UNALIGNED_DATA_ACCESS 1
// It is OK to remove the hard stop below, but you are on your own.
// After building the library be sure to run self tests described
// https://www.cryptopp.com/wiki/Release_Process#Self_Tests
// Some relevant bug reports can be found at:
// * Clang: http://github.com/weidai11/cryptopp/issues/147
// * Native Client: https://github.com/weidai11/cryptopp/issues/719
#if (defined(_MSC_VER) && defined(__clang__))
# error: "Unsupported configuration"
#endif
// You may need to force include a C++ header on Android when using STLPort to ensure
// _STLPORT_VERSION is defined: CXXFLAGS="-DNDEBUG -g2 -O2 -std=c++11 -include iosfwd"
// TODO: Figure out C++17 and lack of std::uncaught_exception
#if (defined(_MSC_VER) && _MSC_VER <= 1300) || defined(__MWERKS__) || (defined(_STLPORT_VERSION) && ((_STLPORT_VERSION < 0x450) || defined(_STLP_NO_UNCAUGHT_EXCEPT_SUPPORT)))
#define CRYPTOPP_DISABLE_UNCAUGHT_EXCEPTION
#endif
// ***************** IA32 CPU features ********************
#if (CRYPTOPP_BOOL_X86 || CRYPTOPP_BOOL_X32 || CRYPTOPP_BOOL_X64)
// Apple Clang prior to 5.0 cannot handle SSE2
#if !defined(CRYPTOPP_DISABLE_ASM) && defined(CRYPTOPP_APPLE_CLANG_VERSION) && (CRYPTOPP_APPLE_CLANG_VERSION < 50000)
# define CRYPTOPP_DISABLE_ASM 1
#endif
// Sun Studio 12.1 provides GCC inline assembly
// http://blogs.oracle.com/x86be/entry/gcc_style_asm_inlining_support
#if !defined(CRYPTOPP_DISABLE_ASM) && defined(__SUNPRO_CC) && (__SUNPRO_CC < 0x5100)
# define CRYPTOPP_DISABLE_ASM 1
#endif
#if !defined(CRYPTOPP_DISABLE_ASM) && ((defined(_MSC_VER) && defined(_M_IX86)) || (defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__))))
// C++Builder 2010 does not allow "call label" where label is defined within inline assembly
#define CRYPTOPP_X86_ASM_AVAILABLE 1
#if !defined(CRYPTOPP_DISABLE_SSE2) && (defined(_MSC_VER) || CRYPTOPP_GCC_VERSION >= 30300 || defined(__SSE2__))
#define CRYPTOPP_SSE2_ASM_AVAILABLE 1
#endif
#if !defined(CRYPTOPP_DISABLE_SSSE3) && (_MSC_VER >= 1500 || CRYPTOPP_GCC_VERSION >= 40300 || defined(__SSSE3__))
#define CRYPTOPP_SSSE3_ASM_AVAILABLE 1
#endif
#endif
#if !defined(CRYPTOPP_DISABLE_ASM) && defined(_MSC_VER) && defined(_M_X64)
#define CRYPTOPP_X64_MASM_AVAILABLE 1
#endif
#if !defined(CRYPTOPP_DISABLE_ASM) && defined(__GNUC__) && defined(__x86_64__)
#define CRYPTOPP_X64_ASM_AVAILABLE 1
#endif
// 32-bit SunCC does not enable SSE2 by default.
#if !defined(CRYPTOPP_DISABLE_ASM) && !defined(CRYPTOPP_DISABLE_SSE2) && (defined(_MSC_VER) || CRYPTOPP_GCC_VERSION >= 30300 || defined(__SSE2__) || (__SUNPRO_CC >= 0x5100))
#define CRYPTOPP_SSE2_INTRIN_AVAILABLE 1
#endif
#if !defined(CRYPTOPP_DISABLE_ASM) && !defined(CRYPTOPP_DISABLE_SSSE3)
# if defined(__SSSE3__) || (_MSC_VER >= 1500) || \
(CRYPTOPP_GCC_VERSION >= 40300) || (__INTEL_COMPILER >= 1000) || (__SUNPRO_CC >= 0x5110) || \
(CRYPTOPP_LLVM_CLANG_VERSION >= 20300) || (CRYPTOPP_APPLE_CLANG_VERSION >= 40000)
#define CRYPTOPP_SSSE3_AVAILABLE 1
# endif
#endif
// Intrinsics availible in GCC 4.3 (http://gcc.gnu.org/gcc-4.3/changes.html) and
// MSVC 2008 (http://msdn.microsoft.com/en-us/library/bb892950%28v=vs.90%29.aspx)
// SunCC could generate SSE4 at 12.1, but the intrinsics are missing until 12.4.
#if !defined(CRYPTOPP_DISABLE_SSE4) && defined(CRYPTOPP_SSSE3_AVAILABLE) && \
(defined(__SSE4_1__) || (CRYPTOPP_MSC_VERSION >= 1500) || \
(CRYPTOPP_GCC_VERSION >= 40300) || (__INTEL_COMPILER >= 1000) || (__SUNPRO_CC >= 0x5110) || \
(CRYPTOPP_LLVM_CLANG_VERSION >= 20300) || (CRYPTOPP_APPLE_CLANG_VERSION >= 40000))
#define CRYPTOPP_SSE41_AVAILABLE 1
#endif
#if !defined(CRYPTOPP_DISABLE_SSE4) && defined(CRYPTOPP_SSSE3_AVAILABLE) && \
(defined(__SSE4_2__) || (CRYPTOPP_MSC_VERSION >= 1500) || (__SUNPRO_CC >= 0x5110) || \
(CRYPTOPP_GCC_VERSION >= 40300) || (__INTEL_COMPILER >= 1000) || \
(CRYPTOPP_LLVM_CLANG_VERSION >= 20300) || (CRYPTOPP_APPLE_CLANG_VERSION >= 40000))
#define CRYPTOPP_SSE42_AVAILABLE 1
#endif
// Couple to CRYPTOPP_DISABLE_AESNI, but use CRYPTOPP_CLMUL_AVAILABLE so we can selectively
// disable for misbehaving platofrms and compilers, like Solaris or some Clang.
#if defined(CRYPTOPP_DISABLE_AESNI)
#define CRYPTOPP_DISABLE_CLMUL 1
#endif
// Requires Sun Studio 12.3 (SunCC 0x5120) in theory.
#if !defined(CRYPTOPP_DISABLE_ASM) && !defined(CRYPTOPP_DISABLE_CLMUL) && defined(CRYPTOPP_SSE42_AVAILABLE) && \
(defined(__PCLMUL__) || (_MSC_FULL_VER >= 150030729) || (__SUNPRO_CC >= 0x5120) || \
(CRYPTOPP_GCC_VERSION >= 40300) || (__INTEL_COMPILER >= 1110) || \
(CRYPTOPP_LLVM_CLANG_VERSION >= 30200) || (CRYPTOPP_APPLE_CLANG_VERSION >= 40300))
#define CRYPTOPP_CLMUL_AVAILABLE 1
#endif
// Requires Sun Studio 12.3 (SunCC 0x5120)
#if !defined(CRYPTOPP_DISABLE_ASM) && !defined(CRYPTOPP_DISABLE_AESNI) && defined(CRYPTOPP_SSE42_AVAILABLE) && \
(defined(__AES__) || (_MSC_FULL_VER >= 150030729) || (__SUNPRO_CC >= 0x5120) || \
(CRYPTOPP_GCC_VERSION >= 40300) || (__INTEL_COMPILER >= 1110) || \
(CRYPTOPP_LLVM_CLANG_VERSION >= 30200) || (CRYPTOPP_APPLE_CLANG_VERSION >= 40300))
#define CRYPTOPP_AESNI_AVAILABLE 1
#endif
// Requires Binutils 2.24
#if !defined(CRYPTOPP_DISABLE_AVX) && defined(CRYPTOPP_SSE42_AVAILABLE) && \
(defined(__AVX2__) || (CRYPTOPP_MSC_VERSION >= 1800) || (__SUNPRO_CC >= 0x5130) || \
(CRYPTOPP_GCC_VERSION >= 40700) || (__INTEL_COMPILER >= 1400) || \
(CRYPTOPP_LLVM_CLANG_VERSION >= 30100) || (CRYPTOPP_APPLE_CLANG_VERSION >= 40600))
#define CRYPTOPP_AVX_AVAILABLE 1
#endif
// Requires Binutils 2.24
#if !defined(CRYPTOPP_DISABLE_AVX2) && defined(CRYPTOPP_AVX_AVAILABLE) && \
(defined(__AVX2__) || (CRYPTOPP_MSC_VERSION >= 1800) || (__SUNPRO_CC >= 0x5130) || \
(CRYPTOPP_GCC_VERSION >= 40900) || (__INTEL_COMPILER >= 1400) || \
(CRYPTOPP_LLVM_CLANG_VERSION >= 30100) || (CRYPTOPP_APPLE_CLANG_VERSION >= 40600))
#define CRYPTOPP_AVX2_AVAILABLE 1
#endif
// Guessing at SHA for SunCC. Its not in Sun Studio 12.6. Also see
// http://stackoverflow.com/questions/45872180/which-xarch-for-sha-extensions-on-solaris
#if !defined(CRYPTOPP_DISABLE_ASM) && !defined(CRYPTOPP_DISABLE_SHANI) && defined(CRYPTOPP_SSE42_AVAILABLE) && \
(defined(__SHA__) || (CRYPTOPP_MSC_VERSION >= 1900) || (__SUNPRO_CC >= 0x5160) || \
(CRYPTOPP_GCC_VERSION >= 40900) || (__INTEL_COMPILER >= 1300) || \
(CRYPTOPP_LLVM_CLANG_VERSION >= 30400) || (CRYPTOPP_APPLE_CLANG_VERSION >= 50100))
#define CRYPTOPP_SHANI_AVAILABLE 1
#endif
// Fixup Android and SSE, Crypto. It may be enabled based on compiler version.
#if (defined(__ANDROID__) || defined(ANDROID))
# if (CRYPTOPP_BOOL_X86)
# undef CRYPTOPP_SSE41_AVAILABLE
# undef CRYPTOPP_SSE42_AVAILABLE
# undef CRYPTOPP_CLMUL_AVAILABLE
# undef CRYPTOPP_AESNI_AVAILABLE
# undef CRYPTOPP_SHANI_AVAILABLE
# endif
# if (CRYPTOPP_BOOL_X64)
# undef CRYPTOPP_CLMUL_AVAILABLE
# undef CRYPTOPP_AESNI_AVAILABLE
# undef CRYPTOPP_SHANI_AVAILABLE
# endif
#endif
// Fixup for SunCC 12.1-12.4. Bad code generation in AES_Encrypt and friends.
#if defined(__SUNPRO_CC) && (__SUNPRO_CC <= 0x5130)
# undef CRYPTOPP_AESNI_AVAILABLE
#endif
// Fixup for SunCC 12.1-12.6. Compiler crash on GCM_Reduce_CLMUL and friends.
// http://github.com/weidai11/cryptopp/issues/226
#if defined(__SUNPRO_CC) && (__SUNPRO_CC <= 0x5150)
# undef CRYPTOPP_CLMUL_AVAILABLE
#endif
#endif // X86, X32, X64
// ***************** ARM CPU features ********************
#if (CRYPTOPP_BOOL_ARM32 || CRYPTOPP_BOOL_ARMV8)
// We don't have an ARM big endian test rig. Disable
// ARM-BE ASM and instrinsics until we can test it.
#if (CRYPTOPP_BIG_ENDIAN)
# define CRYPTOPP_DISABLE_ASM 1
#endif
// Requires ACLE 1.0. -mfpu=neon or above must be present
// Requires GCC 4.3, Clang 2.8 or Visual Studio 2012
// Do not use APPLE_CLANG_VERSION; use __ARM_FEATURE_XXX instead.
#if !defined(CRYPTOPP_ARM_NEON_AVAILABLE) && !defined(CRYPTOPP_DISABLE_ASM)
# if defined(__arm__) || defined(__ARM_NEON) || defined(__ARM_FEATURE_NEON) || defined(_M_ARM)
# if (CRYPTOPP_GCC_VERSION >= 40300) || (CRYPTOPP_LLVM_CLANG_VERSION >= 20800) || \
(CRYPTOPP_MSC_VERSION >= 1700)
# define CRYPTOPP_ARM_NEON_AVAILABLE 1
# endif // Compilers
# endif // Platforms
#endif
// ARMv8 and ASIMD. -march=armv8-a or above must be present
// Requires GCC 4.8, Clang 3.3 or Visual Studio 2017
// Do not use APPLE_CLANG_VERSION; use __ARM_FEATURE_XXX instead.
#if !defined(CRYPTOPP_ARM_ASIMD_AVAILABLE) && !defined(CRYPTOPP_DISABLE_ASM)
# if defined(__aarch32__) || defined(__aarch64__) || defined(_M_ARM64)
# if defined(__ARM_NEON) || defined(__ARM_FEATURE_NEON) || defined(__ARM_FEATURE_ASIMD) || \
(CRYPTOPP_GCC_VERSION >= 40800) || (CRYPTOPP_LLVM_CLANG_VERSION >= 30300) || \
(CRYPTOPP_MSC_VERSION >= 1916)
# define CRYPTOPP_ARM_NEON_AVAILABLE 1
# define CRYPTOPP_ARM_ASIMD_AVAILABLE 1
# endif // Compilers
# endif // Platforms
#endif
// ARMv8 and ASIMD. -march=armv8-a+crc or above must be present
// Requires GCC 4.8, Clang 3.3 or Visual Studio 2017
// Do not use APPLE_CLANG_VERSION; use __ARM_FEATURE_XXX instead.
#if !defined(CRYPTOPP_ARM_CRC32_AVAILABLE) && !defined(CRYPTOPP_DISABLE_ASM)
# if defined(__aarch32__) || defined(__aarch64__) || defined(_M_ARM64)
# if defined(__ARM_FEATURE_CRC32) || (CRYPTOPP_GCC_VERSION >= 40800) || \
(CRYPTOPP_LLVM_CLANG_VERSION >= 30300) || (CRYPTOPP_MSC_VERSION >= 1916)
# define CRYPTOPP_ARM_CRC32_AVAILABLE 1
# endif // Compilers
# endif // Platforms
#endif
// ARMv8 and ASIMD. -march=armv8-a+crypto or above must be present
// Requires GCC 4.8, Clang 3.3 or Visual Studio 2017
// Do not use APPLE_CLANG_VERSION; use __ARM_FEATURE_XXX instead.
#if !defined(CRYPTOPP_ARM_PMULL_AVAILABLE) && !defined(CRYPTOPP_DISABLE_ASM)
# if defined(__aarch32__) || defined(__aarch64__) || defined(_M_ARM64)
# if defined(__ARM_FEATURE_CRYPTO) || (CRYPTOPP_GCC_VERSION >= 40800) || \
(CRYPTOPP_LLVM_CLANG_VERSION >= 30300) || (CRYPTOPP_MSC_VERSION >= 1916)
# define CRYPTOPP_ARM_PMULL_AVAILABLE 1
# endif // Compilers
# endif // Platforms
#endif
// ARMv8 and AES. -march=armv8-a+crypto or above must be present
// Requires GCC 4.8, Clang 3.3 or Visual Studio 2017
// Do not use APPLE_CLANG_VERSION; use __ARM_FEATURE_XXX instead.
#if !defined(CRYPTOPP_ARM_AES_AVAILABLE) && !defined(CRYPTOPP_DISABLE_ASM)
# if defined(__aarch32__) || defined(__aarch64__) || defined(_M_ARM64)
# if defined(__ARM_FEATURE_CRYPTO) || (CRYPTOPP_GCC_VERSION >= 40800) || \
(CRYPTOPP_LLVM_CLANG_VERSION >= 30300) || (CRYPTOPP_MSC_VERSION >= 1916)
# define CRYPTOPP_ARM_AES_AVAILABLE 1
# endif // Compilers
# endif // Platforms
#endif
// ARMv8 and SHA-1, SHA-256. -march=armv8-a+crypto or above must be present
// Requires GCC 4.8, Clang 3.3 or Visual Studio 2017
// Do not use APPLE_CLANG_VERSION; use __ARM_FEATURE_XXX instead.
#if !defined(CRYPTOPP_ARM_SHA_AVAILABLE) && !defined(CRYPTOPP_DISABLE_ASM)
# if defined(__aarch32__) || defined(__aarch64__) || defined(_M_ARM64)
# if defined(__ARM_FEATURE_CRYPTO) || (CRYPTOPP_GCC_VERSION >= 40800) || \
(CRYPTOPP_LLVM_CLANG_VERSION >= 30300) || (CRYPTOPP_MSC_VERSION >= 1916)
# define CRYPTOPP_ARM_SHA1_AVAILABLE 1
# define CRYPTOPP_ARM_SHA2_AVAILABLE 1
# endif // Compilers
# endif // Platforms
#endif
// ARMv8 and SHA-512, SHA-3. -march=armv8.4-a+crypto or above must be present
// Requires GCC 8.0, Clang ??? or Visual Studio 20??
// Do not use APPLE_CLANG_VERSION; use __ARM_FEATURE_XXX instead.
#if !defined(CRYPTOPP_ARM_SHA3_AVAILABLE) && !defined(CRYPTOPP_DISABLE_ASM)
# if defined(__aarch32__) || defined(__aarch64__) || defined(_M_ARM64)
# if defined(__ARM_FEATURE_SHA3) || (CRYPTOPP_GCC_VERSION >= 80000)
# define CRYPTOPP_ARM_SHA512_AVAILABLE 1
# define CRYPTOPP_ARM_SHA3_AVAILABLE 1
# endif // Compilers
# endif // Platforms
#endif
// ARMv8 and SM3, SM4. -march=armv8.4-a+crypto or above must be present
// Requires GCC 8.0, Clang ??? or Visual Studio 20??
// Do not use APPLE_CLANG_VERSION; use __ARM_FEATURE_XXX instead.
#if !defined(CRYPTOPP_ARM_SM3_AVAILABLE) && !defined(CRYPTOPP_DISABLE_ASM)
# if defined(__aarch32__) || defined(__aarch64__) || defined(_M_ARM64)
# if defined(__ARM_FEATURE_SM3) || (CRYPTOPP_GCC_VERSION >= 80000)
# define CRYPTOPP_ARM_SM3_AVAILABLE 1
# define CRYPTOPP_ARM_SM4_AVAILABLE 1
# endif // Compilers
# endif // Platforms
#endif
// Limit the <arm_acle.h> include.
#if !defined(CRYPTOPP_ARM_ACLE_AVAILABLE)
# if defined(__aarch32__) || defined(__aarch64__) || (__ARM_ARCH >= 8) || defined(__ARM_ACLE)
# if !defined(__ANDROID__) && !defined(ANDROID) && !defined(__APPLE__)
# define CRYPTOPP_ARM_ACLE_AVAILABLE 1
# endif
# endif
#endif
// Fixup Apple Clang and PMULL. Apple defines __ARM_FEATURE_CRYPTO for Xcode 6
// but does not provide PMULL. TODO: determine when PMULL is available.
#if defined(CRYPTOPP_APPLE_CLANG_VERSION) && (CRYPTOPP_APPLE_CLANG_VERSION < 70000)
# undef CRYPTOPP_ARM_PMULL_AVAILABLE
#endif
// Fixup Android and CRC32. It may be enabled based on compiler version.
#if (defined(__ANDROID__) || defined(ANDROID)) && !defined(__ARM_FEATURE_CRC32)
# undef CRYPTOPP_ARM_CRC32_AVAILABLE
#endif
// Fixup Android and Crypto. It may be enabled based on compiler version.
#if (defined(__ANDROID__) || defined(ANDROID)) && !defined(__ARM_FEATURE_CRYPTO)
# undef CRYPTOPP_ARM_PMULL_AVAILABLE
# undef CRYPTOPP_ARM_AES_AVAILABLE
# undef CRYPTOPP_ARM_SHA1_AVAILABLE
# undef CRYPTOPP_ARM_SHA2_AVAILABLE
#endif
// Cryptogams offers an ARM asm implementations for AES and SHA. Crypto++ does
// not provide an asm implementation. The Cryptogams AES implementation is
// about 50% faster than C/C++, and SHA implementation is about 30% faster
// than C/C++. Define this to use the Cryptogams AES and SHA implementations
// on GNU Linux systems. When defined, Crypto++ will use aes_armv4.S,
// sha1_armv4.S and sha256_armv4.S. https://www.cryptopp.com/wiki/Cryptogams.
#if !defined(CRYPTOPP_DISABLE_ASM) && defined(__arm__) && defined(__linux__)
# if defined(__GNUC__) || defined(__clang__)
# define CRYPTOGAMS_ARM_AES 1
# define CRYPTOGAMS_ARM_SHA1 1
# define CRYPTOGAMS_ARM_SHA256 1
# define CRYPTOGAMS_ARM_SHA512 1
# endif
#endif
#endif // ARM32, ARM64
// ***************** AltiVec and Power8 ********************
#if (CRYPTOPP_BOOL_PPC32 || CRYPTOPP_BOOL_PPC64)
#if defined(CRYPTOPP_DISABLE_ALTIVEC) || defined(CRYPTOPP_DISABLE_ASM)
# undef CRYPTOPP_DISABLE_ALTIVEC
# undef CRYPTOPP_DISABLE_POWER7
# undef CRYPTOPP_DISABLE_POWER8
# undef CRYPTOPP_DISABLE_POWER9
# define CRYPTOPP_DISABLE_ALTIVEC 1
# define CRYPTOPP_DISABLE_POWER7 1
# define CRYPTOPP_DISABLE_POWER8 1
# define CRYPTOPP_DISABLE_POWER9 1
#endif
// An old Apple G5 with GCC 4.01 has AltiVec, but its only Power4 or so.
#if !defined(CRYPTOPP_ALTIVEC_AVAILABLE) && !defined(CRYPTOPP_DISABLE_ALTIVEC)
# if defined(_ARCH_PWR4) || defined(__ALTIVEC__) || \
(CRYPTOPP_XLC_VERSION >= 100000) || (CRYPTOPP_GCC_VERSION >= 40001) || \
(CRYPTOPP_LLVM_CLANG_VERSION >= 20900)
# define CRYPTOPP_ALTIVEC_AVAILABLE 1
# endif
#endif
// We need Power7 for unaligned loads and stores
#if !defined(CRYPTOPP_POWER7_AVAILABLE) && !defined(CRYPTOPP_DISABLE_POWER7) && defined(CRYPTOPP_ALTIVEC_AVAILABLE)
# if defined(_ARCH_PWR7) || (CRYPTOPP_XLC_VERSION >= 100000) || \
(CRYPTOPP_GCC_VERSION >= 40100) || (CRYPTOPP_LLVM_CLANG_VERSION >= 30100)
# define CRYPTOPP_POWER7_AVAILABLE 1
# endif
#endif
// We need Power8 for in-core crypto and 64-bit vector types
#if !defined(CRYPTOPP_POWER8_AVAILABLE) && !defined(CRYPTOPP_DISABLE_POWER8) && defined(CRYPTOPP_POWER7_AVAILABLE)
# if defined(_ARCH_PWR8) || (CRYPTOPP_XLC_VERSION >= 130000) || \
(CRYPTOPP_GCC_VERSION >= 40800) || (CRYPTOPP_LLVM_CLANG_VERSION >= 70000)
# define CRYPTOPP_POWER8_AVAILABLE 1
# endif
#endif
// Power9 for random numbers
#if !defined(CRYPTOPP_POWER9_AVAILABLE) && !defined(CRYPTOPP_DISABLE_POWER9) && defined(CRYPTOPP_POWER8_AVAILABLE)
# if defined(_ARCH_PWR9) || (CRYPTOPP_XLC_VERSION >= 130200) || \
(CRYPTOPP_GCC_VERSION >= 70000) || (CRYPTOPP_LLVM_CLANG_VERSION >= 80000)
# define CRYPTOPP_POWER9_AVAILABLE 1
# endif
#endif
#if !defined(CRYPTOPP_POWER8_AES_AVAILABLE) && !defined(CRYPTOPP_DISABLE_POWER8_AES) && defined(CRYPTOPP_POWER8_AVAILABLE)
# if defined(__CRYPTO__) || defined(_ARCH_PWR8) || (CRYPTOPP_XLC_VERSION >= 130000) || \
(CRYPTOPP_GCC_VERSION >= 40800) || (CRYPTOPP_LLVM_CLANG_VERSION >= 70000)
//# define CRYPTOPP_POWER8_CRC_AVAILABLE 1
# define CRYPTOPP_POWER8_AES_AVAILABLE 1
# define CRYPTOPP_POWER8_VMULL_AVAILABLE 1
# define CRYPTOPP_POWER8_SHA_AVAILABLE 1
# endif
#endif
#endif // PPC32, PPC64
#endif // CRYPTOPP_CONFIG_ASM_H

103
config_cpu.h Normal file
View File

@ -0,0 +1,103 @@
// config_cpu.h - written and placed in public domain by Jeffrey Walton
// the bits that make up this source file are from the
// library's monolithic config.h.
/// \file config_cpu.h
/// \brief Library configuration file
/// \details <tt>config.h</tt> was split into components in May 2019 to better
/// integrate with Autoconf and its feature tests. The splitting occured so
/// users could continue to include <tt>config.h</tt> while allowing Autoconf
/// to write new <tt>config_asm.h</tt> and new <tt>config_cxx.h</tt> using
/// its feature tests.
/// \sa <A HREF="https://github.com/weidai11/cryptopp/issues/835">Issue 835</A>
/// <A HREF="https://sourceforge.net/p/predef/wiki/Architectures/">Sourceforge
/// Pre-defined Compiler Macros</A>
/// \since Crypto++ 8.3
#ifndef CRYPTOPP_CONFIG_CPU_H
#define CRYPTOPP_CONFIG_CPU_H
#include "config_ver.h"
#if (defined(__ILP32__) || defined(_ILP32)) && defined(__x86_64__)
#define CRYPTOPP_BOOL_X32 1
#elif (defined(_M_X64) || defined(__x86_64__))
#define CRYPTOPP_BOOL_X64 1
#elif (defined(_M_IX86) || defined(__i386__) || defined(__i386) || defined(_X86_) || defined(__I86__) || defined(__INTEL__))
#define CRYPTOPP_BOOL_X86 1
#endif
// Microsoft added ARM64 define December 2017.
#if defined(__arm64__) || defined(__aarch32__) || defined(__aarch64__) || defined(_M_ARM64)
#define CRYPTOPP_BOOL_ARMV8 1
#endif
#if defined(__arm64__) || defined(__aarch64__) || defined(_M_ARM64)
#define CRYPTOPP_BOOL_ARM64 1
#elif defined(__arm__) || defined(_M_ARM)
#define CRYPTOPP_BOOL_ARM32 1
#endif
// And PowerPC.
#if defined(__ppc64__) || defined(__powerpc64__) || defined(__PPC64__) || defined(_ARCH_PPC64)
#define CRYPTOPP_BOOL_PPC64 1
#elif defined(__powerpc__) || defined(__ppc__) || defined(__PPC__) || defined(_ARCH_PPC)
#define CRYPTOPP_BOOL_PPC32 1
#endif
// And MIPS. TODO: finish these defines
#if defined(__mips64__)
#define CRYPTOPP_BOOL_MIPS64 1
#elif defined(__mips__)
#define CRYPTOPP_BOOL_MIPS32 1
#endif
// And SPARC.
#if defined(__sparc64__) || defined(__sparc64) || defined(__sparcv9) || defined(__sparc_v9__)
#define CRYPTOPP_BOOL_SPARC64 1
#elif defined(__sparc__) || defined(__sparc) || defined(__sparcv8) || defined(__sparc_v8__)
#define CRYPTOPP_BOOL_SPARC32 1
#endif
// This should be a lower bound on the L1 cache line size.
// It's used for defense against timing attacks.
#ifndef CRYPTOPP_L1_CACHE_LINE_SIZE
#if defined(CRYPTOPP_BOOL_X32) || defined(CRYPTOPP_BOOL_X64) || defined(CRYPTOPP_BOOL_ARMV8) || \
defined(CRYPTOPP_BOOL_PPC64) || defined(CRYPTOPP_BOOL_MIPS64) || defined(CRYPTOPP_BOOL_SPARC64)
#define CRYPTOPP_L1_CACHE_LINE_SIZE 64
#else
// L1 cache line size is 32 on Pentium III and earlier
#define CRYPTOPP_L1_CACHE_LINE_SIZE 32
#endif
#endif
// The section attribute attempts to initialize CPU flags to avoid Valgrind findings above -O1
#if ((defined(__MACH__) && defined(__APPLE__)) && ((CRYPTOPP_LLVM_CLANG_VERSION >= 30600) || (CRYPTOPP_APPLE_CLANG_VERSION >= 70100) || (CRYPTOPP_GCC_VERSION >= 40300)))
#define CRYPTOPP_SECTION_INIT __attribute__((section ("__DATA,__data")))
#elif (defined(__ELF__) && (CRYPTOPP_GCC_VERSION >= 40300))
#define CRYPTOPP_SECTION_INIT __attribute__((section ("nocommon")))
#elif defined(__ELF__) && (defined(__xlC__) || defined(__ibmxl__))
#define CRYPTOPP_SECTION_INIT __attribute__((section ("nocommon")))
#else
#define CRYPTOPP_SECTION_INIT
#endif
// How to disable CPU feature probing. We determine machine
// capabilities by performing an os/platform *query* first,
// like getauxv(). If the *query* fails, we move onto a
// cpu *probe*. The cpu *probe* tries to exeute an instruction
// and then catches a SIGILL on Linux or the exception
// EXCEPTION_ILLEGAL_INSTRUCTION on Windows. Some OSes
// fail to hangle a SIGILL gracefully, like Apple OSes. Apple
// machines corrupt memory and variables around the probe.
#if defined(__APPLE__)
#define CRYPTOPP_NO_CPU_FEATURE_PROBES 1
#endif
// Flavor of inline assembly language
#if defined(_MSC_VER) || defined(__BORLANDC__)
#define CRYPTOPP_MS_STYLE_INLINE_ASSEMBLY 1
#else
#define CRYPTOPP_GNU_STYLE_INLINE_ASSEMBLY 1
#endif
#endif

233
config_cxx.h Normal file
View File

@ -0,0 +1,233 @@
// config_cxx.h - written and placed in public domain by Jeffrey Walton
// the bits that make up this source file are from the
// library's monolithic config.h.
/// \file config_cxx.h
/// \brief Library configuration file
/// \details <tt>config.h</tt> was split into components in May 2019 to better
/// integrate with Autoconf and its feature tests. The splitting occured so
/// users could continue to include <tt>config.h</tt> while allowing Autoconf
/// to write new <tt>config_asm.h</tt> and new <tt>config_cxx.h</tt> using
/// its feature tests.
/// \sa <A HREF="https://github.com/weidai11/cryptopp/issues/835">Issue 835</A>
/// \since Crypto++ 8.3
// Visual Studio began at VS2010, http://msdn.microsoft.com/en-us/library/hh567368%28v=vs.110%29.aspx
// and https://docs.microsoft.com/en-us/cpp/visual-cpp-language-conformance
// Intel, http://software.intel.com/en-us/articles/c0x-features-supported-by-intel-c-compiler
// GCC, http://gcc.gnu.org/projects/cxx0x.html
// Clang, http://clang.llvm.org/cxx_status.html
#ifndef CRYPTOPP_CONFIG_CXX_H
#define CRYPTOPP_CONFIG_CXX_H
#include "config_os.h"
#include "config_cpu.h"
#include "config_ver.h"
// Ancient Crypto++ define, dating back to C++98 and C++03.
#ifndef CRYPTOPP_DISABLE_UNCAUGHT_EXCEPTION
# define CRYPTOPP_UNCAUGHT_EXCEPTION_AVAILABLE 1
#endif
// Compatibility with non-clang compilers.
#ifndef __has_feature
# define __has_feature(x) 0
#endif
// Define CRYPTOPP_NO_CXX11 to avoid C++11 related features shown at the
// end of this file. Some compilers and standard C++ headers advertise C++11
// but they are really just C++03 with some additional C++11 headers and
// non-conforming classes. You might also consider `-std=c++03` or
// `-std=gnu++03`, but they are required options when building the library
// and all programs. CRYPTOPP_NO_CXX11 is probably easier to manage but it may
// cause -Wterminate warnings under GCC. MSVC++ has a similar warning.
// Also see https://github.com/weidai11/cryptopp/issues/529
// #define CRYPTOPP_NO_CXX11 1
// Define CRYPTOPP_NO_CXX17 to avoid C++17 related features shown at the end of
// this file. At the moment it should only affect std::uncaught_exceptions.
// #define CRYPTOPP_NO_CXX17 1
// C++11 macro version, https://stackoverflow.com/q/7223991/608639
#if !defined(CRYPTOPP_NO_CXX11)
# if ((_MSC_VER >= 1600) || (__cplusplus >= 201103L)) && !defined(_STLPORT_VERSION)
# define CRYPTOPP_CXX11 1
# endif
#endif
// Hack ahead. Apple's standard library does not have C++'s unique_ptr in C++11.
// We can't test for unique_ptr directly because some of the non-Apple Clangs
// on OS X fail the same way. However, modern standard libraries have
// <forward_list>, so we test for it instead. Thanks to Jonathan Wakely for
// devising the clever test for modern/ancient versions. TODO: test under
// Xcode 3, where g++ is really g++.
#if defined(__APPLE__) && defined(__clang__)
# if !(defined(__has_include) && __has_include(<forward_list>))
# undef CRYPTOPP_CXX11
# endif
#endif
// C++14 macro version, https://stackoverflow.com/q/26089319/608639
#if defined(CRYPTOPP_CXX11) && !defined(CRYPTOPP_NO_CXX14)
# if ((_MSC_VER >= 1900) || (__cplusplus >= 201402L)) && !defined(_STLPORT_VERSION)
# define CRYPTOPP_CXX14 1
# endif
#endif
// C++17 macro version, https://stackoverflow.com/q/38456127/608639
#if defined(CRYPTOPP_CXX14) && !defined(CRYPTOPP_NO_CXX17)
# if ((_MSC_VER >= 1900) || (__cplusplus >= 201703L)) && !defined(_STLPORT_VERSION)
# define CRYPTOPP_CXX17 1
# endif
#endif
// ***************** C++11 and above ********************
#if defined(CRYPTOPP_CXX11)
// atomics: MS at VS2012 (17.00); GCC at 4.4; Clang at 3.1/3.2; Intel 13.0; SunCC 5.14.
#if (CRYPTOPP_MSC_VERSION >= 1700) || __has_feature(cxx_atomic) || \
(__INTEL_COMPILER >= 1300) || (CRYPTOPP_GCC_VERSION >= 40400) || (__SUNPRO_CC >= 0x5140)
# define CRYPTOPP_CXX11_ATOMICS 1
#endif // atomics
// synchronization: MS at VS2012 (17.00); GCC at 4.4; Clang at 3.3; Xcode 5.0; Intel 12.0; SunCC 5.13.
// TODO: verify Clang and Intel versions; find __has_feature(x) extension for Clang
#if (CRYPTOPP_MSC_VERSION >= 1700) || (CRYPTOPP_LLVM_CLANG_VERSION >= 30300) || \
(CRYPTOPP_APPLE_CLANG_VERSION >= 50000) || (__INTEL_COMPILER >= 1200) || \
(CRYPTOPP_GCC_VERSION >= 40400) || (__SUNPRO_CC >= 0x5130)
// Hack ahead. New GCC compilers like GCC 6 on AIX 7.0 or earlier as well as original MinGW
// don't have the synchronization gear. However, Wakely's test used for Apple does not work
// on the GCC/AIX combination. Another twist is we need other stuff from C++11,
// like no-except destructors. Dumping preprocessors shows the following may
// apply: http://stackoverflow.com/q/14191566/608639.
# include <cstddef>
# if !defined(__GLIBCXX__) || defined(_GLIBCXX_HAS_GTHREADS)
# define CRYPTOPP_CXX11_SYNCHRONIZATION 1
# endif
#endif // synchronization
// Dynamic Initialization and Destruction with Concurrency ("Magic Statics")
// MS at VS2015 with Vista (19.00); GCC at 4.3; LLVM Clang at 2.9; Apple Clang at 4.0; Intel 11.1; SunCC 5.13.
// Microsoft's implementation only works for Vista and above, so its further
// limited. http://connect.microsoft.com/VisualStudio/feedback/details/1789709
#if (__cpp_threadsafe_static_init >= 200806) || \
(CRYPTOPP_MSC_VERSION >= 1900) && ((WINVER >= 0x0600) || (_WIN32_WINNT >= 0x0600)) || \
(CRYPTOPP_LLVM_CLANG_VERSION >= 20900) || (CRYPTOPP_APPLE_CLANG_VERSION >= 40000) || \
(__INTEL_COMPILER >= 1110) || (CRYPTOPP_GCC_VERSION >= 40300) || (__SUNPRO_CC >= 0x5130)
# define CRYPTOPP_CXX11_DYNAMIC_INIT 1
#endif // Dynamic Initialization compilers
// deleted functions: MS at VS2013 (18.00); GCC at 4.3; Clang at 2.9; Intel 12.1; SunCC 5.13.
#if (CRYPTOPP_MSC_VERSION >= 1800) || (CRYPTOPP_LLVM_CLANG_VERSION >= 20900) || \
(CRYPTOPP_APPLE_CLANG_VERSION >= 40000) || (__INTEL_COMPILER >= 1210) || \
(CRYPTOPP_GCC_VERSION >= 40300) || (__SUNPRO_CC >= 0x5130)
# define CRYPTOPP_CXX11_DELETED_FUNCTIONS 1
#endif // deleted functions
// alignof/alignas: MS at VS2015 (19.00); GCC at 4.8; Clang at 3.0; Intel 15.0; SunCC 5.13.
#if (CRYPTOPP_MSC_VERSION >= 1900) || __has_feature(cxx_alignas) || \
(__INTEL_COMPILER >= 1500) || (CRYPTOPP_GCC_VERSION >= 40800) || (__SUNPRO_CC >= 0x5130)
# define CRYPTOPP_CXX11_ALIGNAS 1
#endif // alignas
// alignof: MS at VS2015 (19.00); GCC at 4.5; Clang at 2.9; Intel 15.0; SunCC 5.13.
#if (CRYPTOPP_MSC_VERSION >= 1900) || __has_feature(cxx_alignof) || \
(__INTEL_COMPILER >= 1500) || (CRYPTOPP_GCC_VERSION >= 40500) || (__SUNPRO_CC >= 0x5130)
# define CRYPTOPP_CXX11_ALIGNOF 1
#endif // alignof
// lambdas: MS at VS2012 (17.00); GCC at 4.9; Clang at 3.3; Intel 12.0; SunCC 5.14.
#if (CRYPTOPP_MSC_VERSION >= 1700) || __has_feature(cxx_lambdas) || \
(__INTEL_COMPILER >= 1200) || (CRYPTOPP_GCC_VERSION >= 40900) || (__SUNPRO_CC >= 0x5140)
# define CRYPTOPP_CXX11_LAMBDA 1
#endif // lambdas
// noexcept: MS at VS2015 (19.00); GCC at 4.6; Clang at 3.0; Intel 14.0; SunCC 5.13.
#if (CRYPTOPP_MSC_VERSION >= 1900) || __has_feature(cxx_noexcept) || \
(__INTEL_COMPILER >= 1400) || (CRYPTOPP_GCC_VERSION >= 40600) || (__SUNPRO_CC >= 0x5130)
# define CRYPTOPP_CXX11_NOEXCEPT 1
#endif // noexcept compilers
// variadic templates: MS at VS2013 (18.00); GCC at 4.3; Clang at 2.9; Intel 12.1; SunCC 5.13.
#if (__cpp_variadic_templates >= 200704) || __has_feature(cxx_variadic_templates) || \
(CRYPTOPP_MSC_VERSION >= 1800) || (__INTEL_COMPILER >= 1210) || \
(CRYPTOPP_GCC_VERSION >= 40300) || (__SUNPRO_CC >= 0x5130)
# define CRYPTOPP_CXX11_VARIADIC_TEMPLATES 1
#endif // variadic templates
// constexpr: MS at VS2015 (19.00); GCC at 4.6; Clang at 3.1; Intel 16.0; SunCC 5.13.
// Intel has mis-supported the feature since at least ICPC 13.00
#if (__cpp_constexpr >= 200704) || __has_feature(cxx_constexpr) || \
(CRYPTOPP_MSC_VERSION >= 1900) || (__INTEL_COMPILER >= 1600) || \
(CRYPTOPP_GCC_VERSION >= 40600) || (__SUNPRO_CC >= 0x5130)
# define CRYPTOPP_CXX11_CONSTEXPR 1
#endif // constexpr compilers
// strong typed enums: MS at VS2012 (17.00); GCC at 4.4; Clang at 3.3; Intel 14.0; SunCC 5.12.
// Mircorosft and Intel had partial support earlier, but we require full support.
#if (CRYPTOPP_MSC_VERSION >= 1700) || __has_feature(cxx_strong_enums) || \
(__INTEL_COMPILER >= 1400) || (CRYPTOPP_GCC_VERSION >= 40400) || (__SUNPRO_CC >= 0x5120)
# define CRYPTOPP_CXX11_ENUM 1
#endif // constexpr compilers
// nullptr_t: MS at VS2010 (16.00); GCC at 4.6; Clang at 3.3; Intel 10.0; SunCC 5.13.
#if (CRYPTOPP_MSC_VERSION >= 1600) || __has_feature(cxx_nullptr) || \
(__INTEL_COMPILER >= 1000) || (CRYPTOPP_GCC_VERSION >= 40600) || \
(__SUNPRO_CC >= 0x5130) || defined(__IBMCPP_NULLPTR)
# define CRYPTOPP_CXX11_NULLPTR 1
#endif // nullptr_t compilers
#endif // CRYPTOPP_CXX11
// ***************** C++14 and above ********************
#if defined(CRYPTOPP_CXX14)
// Extended static_assert with one argument
// Microsoft cannot handle the single argument static_assert as of VS2019 (cl.exe 19.00)
#if (__cpp_static_assert >= 201411)
# define CRYPTOPP_CXX14_STATIC_ASSERT 1
#endif // static_assert
#endif
// ***************** C++17 and above ********************
// C++17 is available
#if defined(CRYPTOPP_CXX17)
// C++17 uncaught_exceptions: MS at VS2015 (19.00); GCC at 6.0; Clang at 3.5; Intel 18.0.
// Clang and __EXCEPTIONS see http://releases.llvm.org/3.6.0/tools/clang/docs/ReleaseNotes.html
#if defined(__clang__)
# if __EXCEPTIONS && __has_feature(cxx_exceptions)
# if __cpp_lib_uncaught_exceptions
# define CRYPTOPP_CXX17_EXCEPTIONS 1
# endif
# endif
#elif (CRYPTOPP_MSC_VERSION >= 1900) || (__INTEL_COMPILER >= 1800) || \
(CRYPTOPP_GCC_VERSION >= 60000) || (__cpp_lib_uncaught_exceptions)
# define CRYPTOPP_CXX17_EXCEPTIONS 1
#endif // uncaught_exceptions compilers
#endif // CRYPTOPP_CXX17
// ***************** C++ fixups ********************
#if defined(CRYPTOPP_CXX11_NOEXCEPT)
# define CRYPTOPP_THROW noexcept(false)
# define CRYPTOPP_NO_THROW noexcept(true)
#else
# define CRYPTOPP_THROW
# define CRYPTOPP_NO_THROW
#endif // CRYPTOPP_CXX11_NOEXCEPT
// Hack... C++11 nullptr_t type safety and analysis
#if defined(CRYPTOPP_CXX11_NULLPTR) && !defined(NULLPTR)
# define NULLPTR nullptr
#elif !defined(NULLPTR)
# define NULLPTR NULL
#endif // CRYPTOPP_CXX11_NULLPTR
#endif // CRYPTOPP_CONFIG_CXX_H

77
config_dll.h Normal file
View File

@ -0,0 +1,77 @@
// config_dll.h - written and placed in public domain by Jeffrey Walton
// the bits that make up this source file are from the
// library's monolithic config.h.
/// \file config_dll.h
/// \brief Library configuration file
/// \details <tt>config.h</tt> was split into components in May 2019 to better
/// integrate with Autoconf and its feature tests. The splitting occured so
/// users could continue to include <tt>config.h</tt> while allowing Autoconf
/// to write new <tt>config_asm.h</tt> and new <tt>config_cxx.h</tt> using
/// its feature tests.
/// \sa <A HREF="https://github.com/weidai11/cryptopp/issues/835">Issue 835</A>
/// \since Crypto++ 8.3
#ifndef CRYPTOPP_CONFIG_DLL_H
#define CRYPTOPP_CONFIG_DLL_H
#include "config_os.h"
#if !defined(CRYPTOPP_DOXYGEN_PROCESSING)
#if defined(CRYPTOPP_WIN32_AVAILABLE)
#ifdef CRYPTOPP_EXPORTS
# define CRYPTOPP_IS_DLL
# define CRYPTOPP_DLL __declspec(dllexport)
#elif defined(CRYPTOPP_IMPORTS)
# define CRYPTOPP_IS_DLL
# define CRYPTOPP_DLL __declspec(dllimport)
#else
# define CRYPTOPP_DLL
#endif
// C++ makes const internal linkage
#define CRYPTOPP_TABLE extern
#define CRYPTOPP_API __cdecl
#else // not CRYPTOPP_WIN32_AVAILABLE
// C++ makes const internal linkage
#define CRYPTOPP_TABLE extern
#define CRYPTOPP_DLL
#define CRYPTOPP_API
#endif // CRYPTOPP_WIN32_AVAILABLE
#if defined(__MWERKS__)
# define CRYPTOPP_EXTERN_DLL_TEMPLATE_CLASS extern class CRYPTOPP_DLL
#elif defined(__BORLANDC__) || defined(__SUNPRO_CC)
# define CRYPTOPP_EXTERN_DLL_TEMPLATE_CLASS template class CRYPTOPP_DLL
#else
# define CRYPTOPP_EXTERN_DLL_TEMPLATE_CLASS extern template class CRYPTOPP_DLL
#endif
#if defined(CRYPTOPP_MANUALLY_INSTANTIATE_TEMPLATES) && !defined(CRYPTOPP_IMPORTS)
# define CRYPTOPP_DLL_TEMPLATE_CLASS template class CRYPTOPP_DLL
#else
# define CRYPTOPP_DLL_TEMPLATE_CLASS CRYPTOPP_EXTERN_DLL_TEMPLATE_CLASS
#endif
#if defined(__MWERKS__)
# define CRYPTOPP_EXTERN_STATIC_TEMPLATE_CLASS extern class
#elif defined(__BORLANDC__) || defined(__SUNPRO_CC)
# define CRYPTOPP_EXTERN_STATIC_TEMPLATE_CLASS template class
#else
# define CRYPTOPP_EXTERN_STATIC_TEMPLATE_CLASS extern template class
#endif
#if defined(CRYPTOPP_MANUALLY_INSTANTIATE_TEMPLATES) && !defined(CRYPTOPP_EXPORTS)
# define CRYPTOPP_STATIC_TEMPLATE_CLASS template class
#else
# define CRYPTOPP_STATIC_TEMPLATE_CLASS CRYPTOPP_EXTERN_STATIC_TEMPLATE_CLASS
#endif
#endif // CRYPTOPP_DOXYGEN_PROCESSING
#endif // CRYPTOPP_CONFIG_DLL_H

103
config_int.h Normal file
View File

@ -0,0 +1,103 @@
// config_int.h - written and placed in public domain by Jeffrey Walton
// the bits that make up this source file are from the
// library's monolithic config.h.
/// \file config_int.h
/// \brief Library configuration file
/// \details <tt>config.h</tt> was split into components in May 2019 to better
/// integrate with Autoconf and its feature tests. The splitting occured so
/// users could continue to include <tt>config.h</tt> while allowing Autoconf
/// to write new <tt>config_asm.h</tt> and new <tt>config_cxx.h</tt> using
/// its feature tests.
/// \sa <A HREF="https://github.com/weidai11/cryptopp/issues/835">Issue 835</A>
/// \since Crypto++ 8.3
#ifndef CRYPTOPP_CONFIG_INT_H
#define CRYPTOPP_CONFIG_INT_H
#include "config_ns.h"
#include "config_ver.h"
// Originally in global namespace to avoid ambiguity with other byte typedefs.
// Moved to Crypto++ namespace due to C++17, std::byte and potential compile
// problems. Also see http://www.cryptopp.com/wiki/std::byte and
// http://github.com/weidai11/cryptopp/issues/442.
// typedef unsigned char byte;
#define CRYPTOPP_NO_GLOBAL_BYTE 1
NAMESPACE_BEGIN(CryptoPP)
// Signed words added at Issue 609 for early versions of and Visual Studio and
// the NaCl gear. Also see https://github.com/weidai11/cryptopp/issues/609.
typedef unsigned char byte;
typedef unsigned short word16;
typedef unsigned int word32;
typedef signed char sbyte;
typedef signed short sword16;
typedef signed int sword32;
#if defined(_MSC_VER) || defined(__BORLANDC__)
typedef signed __int64 sword64;
typedef unsigned __int64 word64;
#define SW64LIT(x) x##i64
#define W64LIT(x) x##ui64
#elif (_LP64 || __LP64__)
typedef signed long sword64;
typedef unsigned long word64;
#define SW64LIT(x) x##L
#define W64LIT(x) x##UL
#else
typedef signed long long sword64;
typedef unsigned long long word64;
#define SW64LIT(x) x##LL
#define W64LIT(x) x##ULL
#endif
// define large word type, used for file offsets and such
typedef word64 lword;
const lword LWORD_MAX = W64LIT(0xffffffffffffffff);
// define hword, word, and dword. these are used for multiprecision integer arithmetic
// Intel compiler won't have _umul128 until version 10.0. See http://softwarecommunity.intel.com/isn/Community/en-US/forums/thread/30231625.aspx
#if (defined(_MSC_VER) && (!defined(__INTEL_COMPILER) || __INTEL_COMPILER >= 1000) && (defined(_M_X64) || defined(_M_IA64))) || (defined(__DECCXX) && defined(__alpha__)) || (defined(__INTEL_COMPILER) && defined(__x86_64__)) || (defined(__SUNPRO_CC) && defined(__x86_64__))
typedef word32 hword;
typedef word64 word;
#else
#define CRYPTOPP_NATIVE_DWORD_AVAILABLE 1
#if defined(__alpha__) || defined(__ia64__) || defined(_ARCH_PPC64) || defined(__x86_64__) || defined(__mips64) || defined(__sparc64__)
#if ((CRYPTOPP_GCC_VERSION >= 30400) || (CRYPTOPP_LLVM_CLANG_VERSION >= 30000) || (CRYPTOPP_APPLE_CLANG_VERSION >= 40300)) && (__SIZEOF_INT128__ >= 16)
// GCC 4.0.1 on MacOS X is missing __umodti3 and __udivti3
// GCC 4.8.3 and bad uint128_t ops on PPC64/POWER7 (Issue 421)
// mode(TI) division broken on amd64 with GCC earlier than GCC 3.4
typedef word32 hword;
typedef word64 word;
typedef __uint128_t dword;
typedef __uint128_t word128;
#define CRYPTOPP_WORD128_AVAILABLE 1
#else
// if we're here, it means we're on a 64-bit CPU but we don't have a way to obtain 128-bit multiplication results
typedef word16 hword;
typedef word32 word;
typedef word64 dword;
#endif
#else
// being here means the native register size is probably 32 bits or less
#define CRYPTOPP_BOOL_SLOW_WORD64 1
typedef word16 hword;
typedef word32 word;
typedef word64 dword;
#endif
#endif
#ifndef CRYPTOPP_BOOL_SLOW_WORD64
# define CRYPTOPP_BOOL_SLOW_WORD64 0
#endif
const unsigned int WORD_SIZE = sizeof(word);
const unsigned int WORD_BITS = WORD_SIZE * 8;
NAMESPACE_END
#endif // CRYPTOPP_CONFIG_INT_H

180
config_misc.h Normal file
View File

@ -0,0 +1,180 @@
// config_misc.h - written and placed in public domain by Jeffrey Walton
// the bits that make up this source file are from the
// library's monolithic config.h.
/// \file config_misc.h
/// \brief Library configuration file
/// \details <tt>config.h</tt> was split into components in May 2019 to better
/// integrate with Autoconf and its feature tests. The splitting occured so
/// users could continue to include <tt>config.h</tt> while allowing Autoconf
/// to write new <tt>config_asm.h</tt> and new <tt>config_cxx.h</tt> using
/// its feature tests.
/// \sa <A HREF="https://github.com/weidai11/cryptopp/issues/835">Issue 835</A>
/// \since Crypto++ 8.3
#ifndef CRYPTOPP_CONFIG_MISC_H
#define CRYPTOPP_CONFIG_MISC_H
#include "config_asm.h"
#include "config_cxx.h"
#include "config_os.h"
#include "config_ver.h"
// Define this if running on a big-endian CPU
// big endian will be assumed if CRYPTOPP_LITTLE_ENDIAN is not non-0
#if !defined(CRYPTOPP_LITTLE_ENDIAN) && !defined(CRYPTOPP_BIG_ENDIAN) && (defined(__BIG_ENDIAN__) || (defined(__s390__) || defined(__s390x__) || defined(__zarch__)) || (defined(__m68k__) || defined(__MC68K__)) || defined(__sparc) || defined(__sparc__) || defined(__hppa__) || defined(__MIPSEB__) || defined(__ARMEB__) || (defined(__MWERKS__) && !defined(__INTEL__)))
# define CRYPTOPP_BIG_ENDIAN 1
#endif
// Define this if running on a little-endian CPU
// big endian will be assumed if CRYPTOPP_LITTLE_ENDIAN is not non-0
#if !defined(CRYPTOPP_BIG_ENDIAN) && !defined(CRYPTOPP_LITTLE_ENDIAN)
# define CRYPTOPP_LITTLE_ENDIAN 1
#endif
// Define this if you want to set a prefix for TestData/ and TestVectors/
// Be sure to add the trailing slash since its simple concatenation.
// After https://github.com/weidai11/cryptopp/issues/760 the library
// should find the test vectors and data without much effort. It
// will search in "./" and "$ORIGIN/../share/cryptopp" automatically.
#ifndef CRYPTOPP_DATA_DIR
# define CRYPTOPP_DATA_DIR ""
#endif
// Define this to disable the test suite from searching for test
// vectors and data in "./" and "$ORIGIN/../share/cryptopp". The
// library will still search in CRYPTOPP_DATA_DIR, regardless.
// Some distros may want to disable this feature. Also see
// https://github.com/weidai11/cryptopp/issues/760
// #ifndef CRYPTOPP_DISABLE_DATA_DIR_SEARCH
// # define CRYPTOPP_DISABLE_DATA_DIR_SEARCH
// #endif
// Define this if you want or need the library's memcpy_s and memmove_s.
// See http://github.com/weidai11/cryptopp/issues/28.
// #if !defined(CRYPTOPP_WANT_SECURE_LIB)
// # define CRYPTOPP_WANT_SECURE_LIB
// #endif
// Define this if ARMv8 shifts are slow. ARM Cortex-A53 and Cortex-A57 shift
// operation perform poorly, so NEON and ASIMD code that relies on shifts
// or rotates often performs worse than C/C++ code. Also see
// http://github.com/weidai11/cryptopp/issues/367.
#define CRYPTOPP_SLOW_ARMV8_SHIFT 1
// CRYPTOPP_DEBUG enables the library's CRYPTOPP_ASSERT. CRYPTOPP_ASSERT
// raises a SIGTRAP (Unix) or calls DebugBreak() (Windows). CRYPTOPP_ASSERT
// is only in effect when CRYPTOPP_DEBUG, DEBUG or _DEBUG is defined. Unlike
// Posix assert, CRYPTOPP_ASSERT is not affected by NDEBUG (or failure to
// define it).
// Also see http://github.com/weidai11/cryptopp/issues/277, CVE-2016-7420
#if (defined(DEBUG) || defined(_DEBUG)) && !defined(CRYPTOPP_DEBUG)
# define CRYPTOPP_DEBUG 1
#endif
// File system code to use when creating GZIP archive.
// http://www.gzip.org/format.txt
#if !defined(GZIP_OS_CODE)
# if defined(__macintosh__)
# define GZIP_OS_CODE 7
# elif defined(__unix__) || defined(__linux__)
# define GZIP_OS_CODE 3
# else
# define GZIP_OS_CODE 0
# endif
#endif
// Try this if your CPU has 256K internal cache or a slow multiply instruction
// and you want a (possibly) faster IDEA implementation using log tables
// #define IDEA_LARGECACHE
// Define this if, for the linear congruential RNG, you want to use
// the original constants as specified in S.K. Park and K.W. Miller's
// CACM paper.
// #define LCRNG_ORIGINAL_NUMBERS
// Define this if you want Integer's operator<< to honor std::showbase (and
// std::noshowbase). If defined, Integer will use a suffix of 'b', 'o', 'h'
// or '.' (the last for decimal) when std::showbase is in effect. If
// std::noshowbase is set, then the suffix is not added to the Integer. If
// not defined, existing behavior is preserved and Integer will use a suffix
// of 'b', 'o', 'h' or '.' (the last for decimal).
// #define CRYPTOPP_USE_STD_SHOWBASE
// Define this if you want to decouple AlgorithmParameters and Integer
// The decoupling should make it easier for the linker to remove Integer
// related code for those who do not need Integer, and avoid a potential
// race during AssignIntToInteger pointer initialization. Also
// see http://github.com/weidai11/cryptopp/issues/389.
// #define CRYPTOPP_NO_ASSIGN_TO_INTEGER
// Need GCC 4.6/Clang 1.7/Apple Clang 2.0 or above due to "GCC diagnostic {push|pop}"
#if (CRYPTOPP_GCC_VERSION >= 40600) || (CRYPTOPP_LLVM_CLANG_VERSION >= 10700) || \
(CRYPTOPP_APPLE_CLANG_VERSION >= 20000)
#define CRYPTOPP_GCC_DIAGNOSTIC_AVAILABLE 1
#endif
// Portable way to suppress warnings.
// Moved from misc.h due to circular depenedencies.
#ifndef CRYPTOPP_UNUSED
#define CRYPTOPP_UNUSED(x) ((void)(x))
#endif
// how to disable inlining
#if defined(_MSC_VER)
# define CRYPTOPP_NOINLINE_DOTDOTDOT
# define CRYPTOPP_NOINLINE __declspec(noinline)
#elif defined(__xlc__) || defined(__xlC__) || defined(__ibmxl__)
# define CRYPTOPP_NOINLINE_DOTDOTDOT ...
# define CRYPTOPP_NOINLINE __attribute__((noinline))
#elif defined(__GNUC__)
# define CRYPTOPP_NOINLINE_DOTDOTDOT
# define CRYPTOPP_NOINLINE __attribute__((noinline))
#else
# define CRYPTOPP_NOINLINE_DOTDOTDOT ...
# define CRYPTOPP_NOINLINE
#endif
// http://stackoverflow.com/a/13867690/608639
#if defined(CRYPTOPP_CXX11_CONSTEXPR)
# define CRYPTOPP_STATIC_CONSTEXPR static constexpr
# define CRYPTOPP_CONSTEXPR constexpr
#else
# define CRYPTOPP_STATIC_CONSTEXPR static
# define CRYPTOPP_CONSTEXPR
#endif // CRYPTOPP_CXX11_CONSTEXPR
#if defined(CRYPTOPP_DOXYGEN_PROCESSING)
# define CRYPTOPP_CONSTANT(x) static const int x;
#elif defined(CRYPTOPP_CXX11_ENUM)
# define CRYPTOPP_CONSTANT(x) enum : int { x };
#elif defined(CRYPTOPP_CXX11_CONSTEXPR)
# define CRYPTOPP_CONSTANT(x) constexpr static int x;
#else
# define CRYPTOPP_CONSTANT(x) static const int x;
#endif
// Warnings
#ifdef _MSC_VER
// 4127: conditional expression is constant
// 4512: assignment operator not generated
// 4661: no suitable definition provided for explicit template instantiation request
// 4910: '__declspec(dllexport)' and 'extern' are incompatible on an explicit instantiation
# pragma warning(disable: 4127 4512 4661 4910)
// Security related, possible defects
// http://blogs.msdn.com/b/vcblog/archive/2010/12/14/off-by-default-compiler-warnings-in-visual-c.aspx
# pragma warning(once: 4191 4242 4263 4264 4266 4302 4826 4905 4906 4928)
#endif
#ifdef __BORLANDC__
// 8037: non-const function called for const object. needed to work around BCB2006 bug
# pragma warn -8037
#endif
// [GCC Bug 53431] "C++ preprocessor ignores #pragma GCC diagnostic". Clang honors it.
#if CRYPTOPP_GCC_DIAGNOSTIC_AVAILABLE
# pragma GCC diagnostic ignored "-Wunknown-pragmas"
# pragma GCC diagnostic ignored "-Wunused-function"
#endif
#endif // CRYPTOPP_CONFIG_MISC_H

68
config_ns.h Normal file
View File

@ -0,0 +1,68 @@
// config_ns.h - written and placed in public domain by Jeffrey Walton
// the bits that make up this source file are from the
// library's monolithic config.h.
/// \file config_ns.h
/// \brief Library configuration file
/// \details <tt>config.h</tt> was split into components in May 2019 to better
/// integrate with Autoconf and its feature tests. The splitting occured so
/// users could continue to include <tt>config.h</tt> while allowing Autoconf
/// to write new <tt>config_asm.h</tt> and new <tt>config_cxx.h</tt> using
/// its feature tests.
/// \sa <A HREF="https://github.com/weidai11/cryptopp/issues/835">Issue 835</A>
/// \since Crypto++ 8.3
#ifndef CRYPTOPP_CONFIG_NAMESPACE_H
#define CRYPTOPP_CONFIG_NAMESPACE_H
// namespace support is now required
#ifdef NO_NAMESPACE
# error namespace support is now required
#endif
#ifdef CRYPTOPP_DOXYGEN_PROCESSING
/// \namespace CryptoPP
/// \brief Crypto++ library namespace
/// \details Nearly all classes are located in the CryptoPP namespace. Within
/// the namespace, there are two additional namespaces.
/// <ul>
/// <li>Name - namespace for names used with NameValuePairs and documented
/// in argnames.h
/// <li>NaCl - namespace for NaCl test functions like crypto_box,
/// crypto_box_open, crypto_sign, and crypto_sign_open
/// <li>Donna - namespace for curve25519 library operations. The name was
/// selected due to use of Langley and Moon's curve25519-donna.
/// <li>Test - namespace for testing and benchmarks classes
/// <li>Weak - namespace for weak and wounded algorithms, like ARC4, MD5
/// and Pananma
/// </ul>
namespace CryptoPP { }
// Bring in the symbols found in the weak namespace; and fold Weak1 into Weak
#define CRYPTOPP_ENABLE_NAMESPACE_WEAK 1
#define Weak1 Weak
// Avoid putting "CryptoPP::" in front of everything in Doxygen output
#define CryptoPP
#define NAMESPACE_BEGIN(x)
#define NAMESPACE_END
// Get Doxygen to generate better documentation for these typedefs
#define DOCUMENTED_TYPEDEF(x, y) class y : public x {};
// Make "protected" "private" so the functions and members are not documented
#define protected private
#else
// Not Doxygen
#define NAMESPACE_BEGIN(x) namespace x {
#define NAMESPACE_END }
#define DOCUMENTED_TYPEDEF(x, y) typedef x y;
#endif // CRYPTOPP_DOXYGEN_PROCESSING
#define ANONYMOUS_NAMESPACE_BEGIN namespace {
#define ANONYMOUS_NAMESPACE_END }
#define USING_NAMESPACE(x) using namespace x;
#define DOCUMENTED_NAMESPACE_BEGIN(x) namespace x {
#define DOCUMENTED_NAMESPACE_END }
#endif // CRYPTOPP_CONFIG_NAMESPACE_H

152
config_os.h Normal file
View File

@ -0,0 +1,152 @@
// config_os.h - written and placed in public domain by Jeffrey Walton
// the bits that make up this source file are from the
// library's monolithic config.h.
/// \file config_os.h
/// \brief Library configuration file
/// \details <tt>config.h</tt> was split into components in May 2019 to better
/// integrate with Autoconf and its feature tests. The splitting occured so
/// users could continue to include <tt>config.h</tt> while allowing Autoconf
/// to write new <tt>config_asm.h</tt> and new <tt>config_cxx.h</tt> using
/// its feature tests.
/// \sa <A HREF="https://github.com/weidai11/cryptopp/issues/835">Issue 835</A>
/// \since Crypto++ 8.3
#ifndef CRYPTOPP_CONFIG_OS_H
#define CRYPTOPP_CONFIG_OS_H
#include "config_ver.h"
// Windows platform
#if defined(_WIN32) || defined(_WIN64) || defined(__CYGWIN__)
#define CRYPTOPP_WIN32_AVAILABLE
#endif
// Unix and Linux platforms
#if defined(__unix__) || defined(__MACH__) || defined(__NetBSD__) || defined(__sun)
#define CRYPTOPP_UNIX_AVAILABLE
#endif
// BSD platforms
#if defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) || defined(__DragonFly__)
#define CRYPTOPP_BSD_AVAILABLE
#endif
// Microsoft compilers
#if defined(_MSC_VER) || defined(__fastcall)
#define CRYPTOPP_FASTCALL __fastcall
#else
#define CRYPTOPP_FASTCALL
#endif
// Microsoft compilers
#if defined(_MSC_VER)
#define CRYPTOPP_NO_VTABLE __declspec(novtable)
#else
#define CRYPTOPP_NO_VTABLE
#endif
// Define this if you want to disable all OS-dependent features,
// such as sockets and OS-provided random number generators
// #define NO_OS_DEPENDENCE
// Define this to use features provided by Microsoft's CryptoAPI.
// Currently the only feature used is Windows random number generation.
// This macro will be ignored if NO_OS_DEPENDENCE is defined.
// #define USE_MS_CRYPTOAPI
// Define this to use features provided by Microsoft's CryptoNG API.
// CryptoNG API is available in Vista and above and its cross platform,
// including desktop apps and store apps. Currently the only feature
// used is Windows random number generation.
// This macro will be ignored if NO_OS_DEPENDENCE is defined.
// #define USE_MS_CNGAPI
// If the user did not make a choice, then select CryptoNG if
// targeting Windows 8 or above.
#if !defined(USE_MS_CRYPTOAPI) && !defined(USE_MS_CNGAPI)
# if !defined(_USING_V110_SDK71_) && ((WINVER >= 0x0602 /*_WIN32_WINNT_WIN8*/) || \
(_WIN32_WINNT >= 0x0602 /*_WIN32_WINNT_WIN8*/))
# define USE_MS_CNGAPI
# else
# define USE_MS_CRYPTOAPI
# endif
#endif
// Begin OS features, like init priorities and random numbers
#ifndef NO_OS_DEPENDENCE
// CRYPTOPP_INIT_PRIORITY attempts to manage initialization of C++ static objects.
// Under GCC, the library uses init_priority attribute in the range
// [CRYPTOPP_INIT_PRIORITY, CRYPTOPP_INIT_PRIORITY+100]. Under Windows,
// CRYPTOPP_INIT_PRIORITY enlists "#pragma init_seg(lib)". The platforms
// with gaps are Apple and Sun because they require linker scripts. Apple and
// Sun will use the library's Singletons to initialize and acquire resources.
// Also see http://cryptopp.com/wiki/Static_Initialization_Order_Fiasco
#ifndef CRYPTOPP_INIT_PRIORITY
# define CRYPTOPP_INIT_PRIORITY 250
#endif
// CRYPTOPP_USER_PRIORITY is for other libraries and user code that is using Crypto++
// and managing C++ static object creation. It is guaranteed not to conflict with
// values used by (or would be used by) the Crypto++ library.
#ifndef CRYPTOPP_USER_PRIORITY
# define CRYPTOPP_USER_PRIORITY (CRYPTOPP_INIT_PRIORITY+101)
#endif
// Most platforms allow us to specify when to create C++ objects. Apple and Sun do not.
#if (CRYPTOPP_INIT_PRIORITY > 0) && !(defined(NO_OS_DEPENDENCE) || defined(__APPLE__) || defined(__sun__))
# if (CRYPTOPP_GCC_VERSION >= 30000) || (CRYPTOPP_LLVM_CLANG_VERSION >= 20900) || (_INTEL_COMPILER >= 800)
# define HAVE_GCC_INIT_PRIORITY 1
# elif (CRYPTOPP_MSC_VERSION >= 1310)
# define HAVE_MSC_INIT_PRIORITY 1
# elif defined(__xlc__) || defined(__xlC__) || defined(__ibmxl__)
# define HAVE_XLC_INIT_PRIORITY 1
# endif
#endif // CRYPTOPP_INIT_PRIORITY, NO_OS_DEPENDENCE, Apple, Sun
#if defined(CRYPTOPP_WIN32_AVAILABLE) || defined(CRYPTOPP_UNIX_AVAILABLE)
# define HIGHRES_TIMER_AVAILABLE
#endif
#ifdef CRYPTOPP_WIN32_AVAILABLE
# if !defined(WINAPI_FAMILY)
# define THREAD_TIMER_AVAILABLE
# elif defined(WINAPI_FAMILY)
# if (WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP))
# define THREAD_TIMER_AVAILABLE
# endif
# endif
#endif
#if defined(CRYPTOPP_UNIX_AVAILABLE) || defined(CRYPTOPP_DOXYGEN_PROCESSING)
# define NONBLOCKING_RNG_AVAILABLE
# define BLOCKING_RNG_AVAILABLE
# define OS_RNG_AVAILABLE
#endif
// Cygwin/Newlib requires _XOPEN_SOURCE=600
#if defined(CRYPTOPP_UNIX_AVAILABLE)
# define UNIX_SIGNALS_AVAILABLE 1
#endif
#ifdef CRYPTOPP_WIN32_AVAILABLE
# if !defined(WINAPI_FAMILY)
# define NONBLOCKING_RNG_AVAILABLE
# define OS_RNG_AVAILABLE
# elif defined(WINAPI_FAMILY)
# if (WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP))
# define NONBLOCKING_RNG_AVAILABLE
# define OS_RNG_AVAILABLE
# elif !(WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP))
# if ((WINVER >= 0x0A00 /*_WIN32_WINNT_WIN10*/) || (_WIN32_WINNT >= 0x0A00 /*_WIN32_WINNT_WIN10*/))
# define NONBLOCKING_RNG_AVAILABLE
# define OS_RNG_AVAILABLE
# endif
# endif
# endif
#endif
#endif // NO_OS_DEPENDENCE
#endif // CRYPTOPP_CONFIG_OS_H

46
config_ver.h Normal file
View File

@ -0,0 +1,46 @@
// config_ver.h - written and placed in public domain by Jeffrey Walton
// the bits that make up this source file are from the
// library's monolithic config.h.
/// \file config_ver.h
/// \brief Library configuration file
/// \details <tt>config.h</tt> was split into components in May 2019 to better
/// integrate with Autoconf and its feature tests. The splitting occured so
/// users could continue to include <tt>config.h</tt> while allowing Autoconf
/// to write new <tt>config_asm.h</tt> and new <tt>config_cxx.h</tt> using
/// its feature tests.
/// \sa <A HREF="https://github.com/weidai11/cryptopp/issues/835">Issue 835</A>
/// \since Crypto++ 8.3
#ifndef CRYPTOPP_CONFIG_VERSION_H
#define CRYPTOPP_CONFIG_VERSION_H
// Library version macro. Since this macro is in a header, it reflects
// the version of the library the headers came from. It is not
// necessarily the version of the library built as a shared object if
// versions are inadvertently mixed and matched.
#define CRYPTOPP_MAJOR 8
#define CRYPTOPP_MINOR 3
#define CRYPTOPP_REVISION 0
#define CRYPTOPP_VERSION 830
#ifdef __GNUC__
# define CRYPTOPP_GCC_VERSION (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__)
#endif
#if defined(__xlc__) || defined(__xlC__)
# define CRYPTOPP_XLC_VERSION ((__xlC__ / 256) * 10000 + (__xlC__ % 256) * 100)
#endif
// Apple and LLVM's Clang. Apple Clang version 7.0 roughly equals LLVM Clang version 3.7
#if defined(__clang__) && defined(__apple_build_version__)
# define CRYPTOPP_APPLE_CLANG_VERSION (__clang_major__ * 10000 + __clang_minor__ * 100 + __clang_patchlevel__)
#elif defined(__clang__)
# define CRYPTOPP_LLVM_CLANG_VERSION (__clang_major__ * 10000 + __clang_minor__ * 100 + __clang_patchlevel__)
#endif
#ifdef _MSC_VER
# define CRYPTOPP_MSC_VERSION (_MSC_VER)
#endif
#endif // CRYPTOPP_CONFIG_VERSION_H

119
cpu.cpp
View File

@ -58,7 +58,7 @@ unsigned long int getauxval(unsigned long int) { return 0; }
// Visual Studio 2008 and below is missing _xgetbv. See x64dll.asm for the body. // Visual Studio 2008 and below is missing _xgetbv. See x64dll.asm for the body.
#if defined(_MSC_VER) && _MSC_VER <= 1500 && defined(_M_X64) #if defined(_MSC_VER) && _MSC_VER <= 1500 && defined(_M_X64)
extern "C" unsigned long long __fastcall ExtendedControlRegister(unsigned int); extern "C" unsigned long long __fastcall XGETBV64(unsigned int);
#endif #endif
ANONYMOUS_NAMESPACE_BEGIN ANONYMOUS_NAMESPACE_BEGIN
@ -109,6 +109,8 @@ bool IsAppleMachineARMv8(unsigned int device, unsigned int version)
bool IsAppleMachineARMv84(unsigned int device, unsigned int version) bool IsAppleMachineARMv84(unsigned int device, unsigned int version)
{ {
CRYPTOPP_UNUSED(device);
CRYPTOPP_UNUSED(version);
return false; return false;
} }
#endif // __APPLE__ #endif // __APPLE__
@ -274,10 +276,14 @@ static inline bool IsIntel(const word32 output[4])
static inline bool IsAMD(const word32 output[4]) static inline bool IsAMD(const word32 output[4])
{ {
// This is the "AuthenticAMD" string. Some early K5's can return "AMDisbetter!" // This is the "AuthenticAMD" string.
return (output[1] /*EBX*/ == 0x68747541) && return ((output[1] /*EBX*/ == 0x68747541) &&
(output[2] /*ECX*/ == 0x444D4163) && (output[2] /*ECX*/ == 0x444D4163) &&
(output[3] /*EDX*/ == 0x69746E65); (output[3] /*EDX*/ == 0x69746E65)) ||
// Some early K5's can return "AMDisbetter!"
((output[1] /*EBX*/ == 0x69444d41) &&
(output[2] /*ECX*/ == 0x74656273) &&
(output[3] /*EDX*/ == 0x21726574));
} }
static inline bool IsHygon(const word32 output[4]) static inline bool IsHygon(const word32 output[4])
@ -290,10 +296,14 @@ static inline bool IsHygon(const word32 output[4])
static inline bool IsVIA(const word32 output[4]) static inline bool IsVIA(const word32 output[4])
{ {
// This is the "CentaurHauls" string. Some non-PadLock's can return "VIA VIA VIA " // This is the "CentaurHauls" string.
return (output[1] /*EBX*/ == 0x746e6543) && return ((output[1] /*EBX*/ == 0x746e6543) &&
(output[2] /*ECX*/ == 0x736c7561) && (output[2] /*ECX*/ == 0x736c7561) &&
(output[3] /*EDX*/ == 0x48727561); (output[3] /*EDX*/ == 0x48727561)) ||
// Some non-PadLock's return "VIA VIA VIA "
((output[1] /*EBX*/ == 0x32414956) &&
(output[2] /*ECX*/ == 0x32414956) &&
(output[3] /*EDX*/ == 0x32414956));
} }
void DetectX86Features() void DetectX86Features()
@ -341,8 +351,8 @@ void DetectX86Features()
word64 xcr0 = a | static_cast<word64>(d) << 32; word64 xcr0 = a | static_cast<word64>(d) << 32;
g_hasAVX = (xcr0 & YMM_FLAG) == YMM_FLAG; g_hasAVX = (xcr0 & YMM_FLAG) == YMM_FLAG;
// Visual Studio 2008 and below lack xgetbv // Visual Studio 2010 and below lack xgetbv
#elif defined(_MSC_VER) && _MSC_VER <= 1500 && defined(_M_IX86) #elif defined(_MSC_VER) && _MSC_VER <= 1600 && defined(_M_IX86)
word32 a=0, d=0; word32 a=0, d=0;
__asm { __asm {
push eax push eax
@ -363,7 +373,7 @@ void DetectX86Features()
// Visual Studio 2008 and below lack xgetbv // Visual Studio 2008 and below lack xgetbv
#elif defined(_MSC_VER) && _MSC_VER <= 1500 && defined(_M_X64) #elif defined(_MSC_VER) && _MSC_VER <= 1500 && defined(_M_X64)
word64 xcr0 = ExtendedControlRegister(0); word64 xcr0 = XGETBV64(0);
g_hasAVX = (xcr0 & YMM_FLAG) == YMM_FLAG; g_hasAVX = (xcr0 & YMM_FLAG) == YMM_FLAG;
// Downlevel SunCC // Downlevel SunCC
@ -425,6 +435,7 @@ void DetectX86Features()
} }
else if (IsVIA(cpuid0)) else if (IsVIA(cpuid0))
{ {
// Two bits: available and enabled
CRYPTOPP_CONSTANT( RNG_FLAGS = (0x3 << 2)) CRYPTOPP_CONSTANT( RNG_FLAGS = (0x3 << 2))
CRYPTOPP_CONSTANT( ACE_FLAGS = (0x3 << 6)) CRYPTOPP_CONSTANT( ACE_FLAGS = (0x3 << 6))
CRYPTOPP_CONSTANT(ACE2_FLAGS = (0x3 << 8)) CRYPTOPP_CONSTANT(ACE2_FLAGS = (0x3 << 8))
@ -432,9 +443,10 @@ void DetectX86Features()
CRYPTOPP_CONSTANT( PMM_FLAGS = (0x3 << 12)) CRYPTOPP_CONSTANT( PMM_FLAGS = (0x3 << 12))
CpuId(0xC0000000, 0, cpuid2); CpuId(0xC0000000, 0, cpuid2);
if (cpuid2[0] >= 0xC0000001) word32 extendedFeatures = cpuid2[0];
if (extendedFeatures >= 0xC0000001)
{ {
// Extended features available
CpuId(0xC0000001, 0, cpuid2); CpuId(0xC0000001, 0, cpuid2);
g_hasPadlockRNG = (cpuid2[3] /*EDX*/ & RNG_FLAGS) == RNG_FLAGS; g_hasPadlockRNG = (cpuid2[3] /*EDX*/ & RNG_FLAGS) == RNG_FLAGS;
g_hasPadlockACE = (cpuid2[3] /*EDX*/ & ACE_FLAGS) == ACE_FLAGS; g_hasPadlockACE = (cpuid2[3] /*EDX*/ & ACE_FLAGS) == ACE_FLAGS;
@ -442,7 +454,21 @@ void DetectX86Features()
g_hasPadlockPHE = (cpuid2[3] /*EDX*/ & PHE_FLAGS) == PHE_FLAGS; g_hasPadlockPHE = (cpuid2[3] /*EDX*/ & PHE_FLAGS) == PHE_FLAGS;
g_hasPadlockPMM = (cpuid2[3] /*EDX*/ & PMM_FLAGS) == PMM_FLAGS; g_hasPadlockPMM = (cpuid2[3] /*EDX*/ & PMM_FLAGS) == PMM_FLAGS;
} }
if (extendedFeatures >= 0xC0000005)
{
CpuId(0xC0000005, 0, cpuid2);
g_cacheLineSize = GETBYTE(cpuid2[2] /*ECX*/, 0);
} }
}
#if defined(_SC_LEVEL1_DCACHE_LINESIZE)
// Glibc does not implement on some platforms. The runtime returns 0 instead of error.
// https://sourceware.org/git/?p=glibc.git;a=blob;f=sysdeps/posix/sysconf.c
int cacheLineSize = sysconf(_SC_LEVEL1_DCACHE_LINESIZE);
if (g_cacheLineSize == 0 && cacheLineSize > 0)
g_cacheLineSize = cacheLineSize;
#endif
if (g_cacheLineSize == 0) if (g_cacheLineSize == 0)
g_cacheLineSize = CRYPTOPP_L1_CACHE_LINE_SIZE; g_cacheLineSize = CRYPTOPP_L1_CACHE_LINE_SIZE;
@ -474,7 +500,7 @@ word32 CRYPTOPP_SECTION_INIT g_cacheLineSize = CRYPTOPP_L1_CACHE_LINE_SIZE;
// then *Probe* the cpu executing an instruction and an observe a SIGILL if unsupported. // then *Probe* the cpu executing an instruction and an observe a SIGILL if unsupported.
// The probes are in source files where compilation options like -march=armv8-a+crc make // The probes are in source files where compilation options like -march=armv8-a+crc make
// intrinsics available. They are expensive when compared to a standard OS feature query. // intrinsics available. They are expensive when compared to a standard OS feature query.
// Always perform the feature quesry first. For Linux see // Always perform the feature query first. For Linux see
// http://sourceware.org/ml/libc-help/2017-08/msg00012.html // http://sourceware.org/ml/libc-help/2017-08/msg00012.html
// Avoid probes on Apple platforms because Apple's signal handling for SIGILLs appears broken. // Avoid probes on Apple platforms because Apple's signal handling for SIGILLs appears broken.
// We are trying to figure out a way to feature test without probes. Also see // We are trying to figure out a way to feature test without probes. Also see
@ -486,13 +512,14 @@ extern bool CPU_ProbeNEON();
extern bool CPU_ProbeCRC32(); extern bool CPU_ProbeCRC32();
extern bool CPU_ProbeAES(); extern bool CPU_ProbeAES();
extern bool CPU_ProbeSHA1(); extern bool CPU_ProbeSHA1();
extern bool CPU_ProbeSHA2(); extern bool CPU_ProbeSHA256();
extern bool CPU_ProbeSHA512(); extern bool CPU_ProbeSHA512();
extern bool CPU_ProbeSHA3(); extern bool CPU_ProbeSHA3();
extern bool CPU_ProbeSM3(); extern bool CPU_ProbeSM3();
extern bool CPU_ProbeSM4(); extern bool CPU_ProbeSM4();
extern bool CPU_ProbePMULL(); extern bool CPU_ProbePMULL();
// https://github.com/torvalds/linux/blob/master/arch/arm/include/uapi/asm/hwcap.h
// https://github.com/torvalds/linux/blob/master/arch/arm64/include/uapi/asm/hwcap.h // https://github.com/torvalds/linux/blob/master/arch/arm64/include/uapi/asm/hwcap.h
#ifndef HWCAP_ARMv7 #ifndef HWCAP_ARMv7
# define HWCAP_ARMv7 (1 << 29) # define HWCAP_ARMv7 (1 << 29)
@ -500,8 +527,8 @@ extern bool CPU_ProbePMULL();
#ifndef HWCAP_ASIMD #ifndef HWCAP_ASIMD
# define HWCAP_ASIMD (1 << 1) # define HWCAP_ASIMD (1 << 1)
#endif #endif
#ifndef HWCAP_ARM_NEON #ifndef HWCAP_NEON
# define HWCAP_ARM_NEON 4096 # define HWCAP_NEON (1 << 12)
#endif #endif
#ifndef HWCAP_CRC32 #ifndef HWCAP_CRC32
# define HWCAP_CRC32 (1 << 7) # define HWCAP_CRC32 (1 << 7)
@ -548,15 +575,13 @@ extern bool CPU_ProbePMULL();
inline bool CPU_QueryARMv7() inline bool CPU_QueryARMv7()
{ {
#if defined(__aarch32__) || defined(__aarch64__) #if defined(__ANDROID__) && defined(__arm__)
// ARMv7 or above
return true;
#elif defined(__ANDROID__) && defined(__arm__)
if (((android_getCpuFamily() & ANDROID_CPU_FAMILY_ARM) != 0) && if (((android_getCpuFamily() & ANDROID_CPU_FAMILY_ARM) != 0) &&
((android_getCpuFeatures() & ANDROID_CPU_ARM_FEATURE_ARMv7) != 0)) ((android_getCpuFeatures() & ANDROID_CPU_ARM_FEATURE_ARMv7) != 0))
return true; return true;
#elif defined(__linux__) && defined(__arm__) #elif defined(__linux__) && defined(__arm__)
if ((getauxval(AT_HWCAP) & HWCAP_ARMv7) != 0) if ((getauxval(AT_HWCAP) & HWCAP_ARMv7) != 0 ||
(getauxval(AT_HWCAP) & HWCAP_NEON) != 0)
return true; return true;
#elif defined(__APPLE__) && defined(__arm__) #elif defined(__APPLE__) && defined(__arm__)
// Apple hardware is ARMv7 or above. // Apple hardware is ARMv7 or above.
@ -582,7 +607,7 @@ inline bool CPU_QueryNEON()
if ((getauxval(AT_HWCAP2) & HWCAP2_ASIMD) != 0) if ((getauxval(AT_HWCAP2) & HWCAP2_ASIMD) != 0)
return true; return true;
#elif defined(__linux__) && defined(__arm__) #elif defined(__linux__) && defined(__arm__)
if ((getauxval(AT_HWCAP) & HWCAP_ARM_NEON) != 0) if ((getauxval(AT_HWCAP) & HWCAP_NEON) != 0)
return true; return true;
#elif defined(__APPLE__) && defined(__aarch64__) #elif defined(__APPLE__) && defined(__aarch64__)
// Core feature set for Aarch32 and Aarch64. // Core feature set for Aarch32 and Aarch64.
@ -685,7 +710,7 @@ inline bool CPU_QuerySHA1()
return false; return false;
} }
inline bool CPU_QuerySHA2() inline bool CPU_QuerySHA256()
{ {
#if defined(__ANDROID__) && defined(__aarch64__) #if defined(__ANDROID__) && defined(__aarch64__)
if (((android_getCpuFamily() & ANDROID_CPU_FAMILY_ARM64) != 0) && if (((android_getCpuFamily() & ANDROID_CPU_FAMILY_ARM64) != 0) &&
@ -819,13 +844,13 @@ void DetectArmFeatures()
g_hasPMULL = CPU_QueryPMULL() || CPU_ProbePMULL(); g_hasPMULL = CPU_QueryPMULL() || CPU_ProbePMULL();
g_hasAES = CPU_QueryAES() || CPU_ProbeAES(); g_hasAES = CPU_QueryAES() || CPU_ProbeAES();
g_hasSHA1 = CPU_QuerySHA1() || CPU_ProbeSHA1(); g_hasSHA1 = CPU_QuerySHA1() || CPU_ProbeSHA1();
g_hasSHA2 = CPU_QuerySHA2() || CPU_ProbeSHA2(); g_hasSHA2 = CPU_QuerySHA256() || CPU_ProbeSHA256();
g_hasSHA512 = CPU_QuerySHA512(); // || CPU_ProbeSHA512(); g_hasSHA512 = CPU_QuerySHA512(); // || CPU_ProbeSHA512();
g_hasSHA3 = CPU_QuerySHA3(); // || CPU_ProbeSHA3(); g_hasSHA3 = CPU_QuerySHA3(); // || CPU_ProbeSHA3();
g_hasSM3 = CPU_QuerySM3(); // || CPU_ProbeSM3(); g_hasSM3 = CPU_QuerySM3(); // || CPU_ProbeSM3();
g_hasSM4 = CPU_QuerySM4(); // || CPU_ProbeSM4(); g_hasSM4 = CPU_QuerySM4(); // || CPU_ProbeSM4();
#if defined(__linux__) && defined(_SC_LEVEL1_DCACHE_LINESIZE) #if defined(_SC_LEVEL1_DCACHE_LINESIZE)
// Glibc does not implement on some platforms. The runtime returns 0 instead of error. // Glibc does not implement on some platforms. The runtime returns 0 instead of error.
// https://sourceware.org/git/?p=glibc.git;a=blob;f=sysdeps/posix/sysconf.c // https://sourceware.org/git/?p=glibc.git;a=blob;f=sysdeps/posix/sysconf.c
int cacheLineSize = sysconf(_SC_LEVEL1_DCACHE_LINESIZE); int cacheLineSize = sysconf(_SC_LEVEL1_DCACHE_LINESIZE);
@ -833,6 +858,9 @@ void DetectArmFeatures()
g_cacheLineSize = cacheLineSize; g_cacheLineSize = cacheLineSize;
#endif #endif
if (g_cacheLineSize == 0)
g_cacheLineSize = CRYPTOPP_L1_CACHE_LINE_SIZE;
*const_cast<volatile bool*>(&g_ArmDetectionDone) = true; *const_cast<volatile bool*>(&g_ArmDetectionDone) = true;
} }
@ -862,24 +890,6 @@ extern bool CPU_ProbeSHA256();
extern bool CPU_ProbeSHA512(); extern bool CPU_ProbeSHA512();
extern bool CPU_ProbeDARN(); extern bool CPU_ProbeDARN();
// Linux define values from 64-Bit ELF V2 ABI Specification.
// http://openpowerfoundation.org/wp-content/uploads/resources/leabi/content/ch_preface.html
#ifndef PPC_FEATURE_HAS_ALTIVEC
# define PPC_FEATURE_HAS_ALTIVEC 0x10000000
#endif
#ifndef PPC_FEATURE_ARCH_2_06
# define PPC_FEATURE_ARCH_2_06 0x00000100
#endif
#ifndef PPC_FEATURE2_ARCH_2_07
# define PPC_FEATURE2_ARCH_2_07 0x80000000
#endif
#ifndef PPC_FEATURE2_ARCH_3_00
# define PPC_FEATURE2_ARCH_3_00 0x00800000
#endif
#ifndef PPC_FEATURE2_VEC_CRYPTO
# define PPC_FEATURE2_VEC_CRYPTO 0x02000000
#endif
// AIX defines. We used to just call __power_7_andup() // AIX defines. We used to just call __power_7_andup()
// and friends but at Power9, too many compilers were // and friends but at Power9, too many compilers were
// missing __power_9_andup(). Instead we switched to // missing __power_9_andup(). Instead we switched to
@ -901,7 +911,7 @@ extern bool CPU_ProbeDARN();
// was available much earlier for other vendors. // was available much earlier for other vendors.
inline bool CPU_QueryAltivec() inline bool CPU_QueryAltivec()
{ {
#if defined(__linux__) #if defined(__linux__) && defined(PPC_FEATURE_HAS_ALTIVEC)
if ((getauxval(AT_HWCAP) & PPC_FEATURE_HAS_ALTIVEC) != 0) if ((getauxval(AT_HWCAP) & PPC_FEATURE_HAS_ALTIVEC) != 0)
return true; return true;
#elif defined(_AIX) #elif defined(_AIX)
@ -918,7 +928,7 @@ inline bool CPU_QueryAltivec()
inline bool CPU_QueryPower7() inline bool CPU_QueryPower7()
{ {
// Power7 and ISA 2.06 // Power7 and ISA 2.06
#if defined(__linux__) #if defined(__linux__) && defined(PPC_FEATURE_ARCH_2_06)
if ((getauxval(AT_HWCAP) & PPC_FEATURE_ARCH_2_06) != 0) if ((getauxval(AT_HWCAP) & PPC_FEATURE_ARCH_2_06) != 0)
return true; return true;
#elif defined(_AIX) #elif defined(_AIX)
@ -931,7 +941,7 @@ inline bool CPU_QueryPower7()
inline bool CPU_QueryPower8() inline bool CPU_QueryPower8()
{ {
// Power8 and ISA 2.07 provide in-core crypto. // Power8 and ISA 2.07 provide in-core crypto.
#if defined(__linux__) #if defined(__linux__) && defined(PPC_FEATURE2_ARCH_2_07)
if ((getauxval(AT_HWCAP2) & PPC_FEATURE2_ARCH_2_07) != 0) if ((getauxval(AT_HWCAP2) & PPC_FEATURE2_ARCH_2_07) != 0)
return true; return true;
#elif defined(_AIX) #elif defined(_AIX)
@ -944,7 +954,7 @@ inline bool CPU_QueryPower8()
inline bool CPU_QueryPower9() inline bool CPU_QueryPower9()
{ {
// Power9 and ISA 3.0. // Power9 and ISA 3.0.
#if defined(__linux__) #if defined(__linux__) && defined(PPC_FEATURE2_ARCH_3_00)
if ((getauxval(AT_HWCAP2) & PPC_FEATURE2_ARCH_3_00) != 0) if ((getauxval(AT_HWCAP2) & PPC_FEATURE2_ARCH_3_00) != 0)
return true; return true;
#elif defined(_AIX) #elif defined(_AIX)
@ -958,7 +968,7 @@ inline bool CPU_QueryAES()
{ {
// Power8 and ISA 2.07 provide in-core crypto. Glibc // Power8 and ISA 2.07 provide in-core crypto. Glibc
// 2.24 or higher is required for PPC_FEATURE2_VEC_CRYPTO. // 2.24 or higher is required for PPC_FEATURE2_VEC_CRYPTO.
#if defined(__linux__) #if defined(__linux__) && defined(PPC_FEATURE2_VEC_CRYPTO)
if ((getauxval(AT_HWCAP2) & PPC_FEATURE2_VEC_CRYPTO) != 0) if ((getauxval(AT_HWCAP2) & PPC_FEATURE2_VEC_CRYPTO) != 0)
return true; return true;
#elif defined(_AIX) #elif defined(_AIX)
@ -972,7 +982,7 @@ inline bool CPU_QueryPMULL()
{ {
// Power8 and ISA 2.07 provide in-core crypto. Glibc // Power8 and ISA 2.07 provide in-core crypto. Glibc
// 2.24 or higher is required for PPC_FEATURE2_VEC_CRYPTO. // 2.24 or higher is required for PPC_FEATURE2_VEC_CRYPTO.
#if defined(__linux__) #if defined(__linux__) && defined(PPC_FEATURE2_VEC_CRYPTO)
if ((getauxval(AT_HWCAP2) & PPC_FEATURE2_VEC_CRYPTO) != 0) if ((getauxval(AT_HWCAP2) & PPC_FEATURE2_VEC_CRYPTO) != 0)
return true; return true;
#elif defined(_AIX) #elif defined(_AIX)
@ -986,7 +996,7 @@ inline bool CPU_QuerySHA256()
{ {
// Power8 and ISA 2.07 provide in-core crypto. Glibc // Power8 and ISA 2.07 provide in-core crypto. Glibc
// 2.24 or higher is required for PPC_FEATURE2_VEC_CRYPTO. // 2.24 or higher is required for PPC_FEATURE2_VEC_CRYPTO.
#if defined(__linux__) #if defined(__linux__) && defined(PPC_FEATURE2_VEC_CRYPTO)
if ((getauxval(AT_HWCAP2) & PPC_FEATURE2_VEC_CRYPTO) != 0) if ((getauxval(AT_HWCAP2) & PPC_FEATURE2_VEC_CRYPTO) != 0)
return true; return true;
#elif defined(_AIX) #elif defined(_AIX)
@ -999,7 +1009,7 @@ inline bool CPU_QuerySHA512()
{ {
// Power8 and ISA 2.07 provide in-core crypto. Glibc // Power8 and ISA 2.07 provide in-core crypto. Glibc
// 2.24 or higher is required for PPC_FEATURE2_VEC_CRYPTO. // 2.24 or higher is required for PPC_FEATURE2_VEC_CRYPTO.
#if defined(__linux__) #if defined(__linux__) && defined(PPC_FEATURE2_VEC_CRYPTO)
if ((getauxval(AT_HWCAP2) & PPC_FEATURE2_VEC_CRYPTO) != 0) if ((getauxval(AT_HWCAP2) & PPC_FEATURE2_VEC_CRYPTO) != 0)
return true; return true;
#elif defined(_AIX) #elif defined(_AIX)
@ -1013,7 +1023,7 @@ inline bool CPU_QuerySHA512()
inline bool CPU_QueryDARN() inline bool CPU_QueryDARN()
{ {
// Power9 and ISA 3.0 provide DARN. // Power9 and ISA 3.0 provide DARN.
#if defined(__linux__) #if defined(__linux__) && defined(PPC_FEATURE2_ARCH_3_00)
if ((getauxval(AT_HWCAP2) & PPC_FEATURE2_ARCH_3_00) != 0) if ((getauxval(AT_HWCAP2) & PPC_FEATURE2_ARCH_3_00) != 0)
return true; return true;
#elif defined(_AIX) #elif defined(_AIX)
@ -1042,7 +1052,7 @@ void DetectPowerpcFeatures()
int cacheLineSize = getsystemcfg(SC_L1C_DLS); int cacheLineSize = getsystemcfg(SC_L1C_DLS);
if (cacheLineSize > 0) if (cacheLineSize > 0)
g_cacheLineSize = cacheLineSize; g_cacheLineSize = cacheLineSize;
#elif defined(__linux__) && defined(_SC_LEVEL1_DCACHE_LINESIZE) #elif defined(_SC_LEVEL1_DCACHE_LINESIZE)
// Glibc does not implement on some platforms. The runtime returns 0 instead of error. // Glibc does not implement on some platforms. The runtime returns 0 instead of error.
// https://sourceware.org/git/?p=glibc.git;a=blob;f=sysdeps/posix/sysconf.c // https://sourceware.org/git/?p=glibc.git;a=blob;f=sysdeps/posix/sysconf.c
int cacheLineSize = sysconf(_SC_LEVEL1_DCACHE_LINESIZE); int cacheLineSize = sysconf(_SC_LEVEL1_DCACHE_LINESIZE);
@ -1050,6 +1060,9 @@ void DetectPowerpcFeatures()
g_cacheLineSize = cacheLineSize; g_cacheLineSize = cacheLineSize;
#endif #endif
if (g_cacheLineSize == 0)
g_cacheLineSize = CRYPTOPP_L1_CACHE_LINE_SIZE;
*const_cast<volatile bool*>(&g_PowerpcDetectionDone) = true; *const_cast<volatile bool*>(&g_PowerpcDetectionDone) = true;
} }

View File

@ -212,6 +212,7 @@
<ClCompile Include="gcm.cpp" /> <ClCompile Include="gcm.cpp" />
<ClCompile Include="gcm_simd.cpp" /> <ClCompile Include="gcm_simd.cpp" />
<ClCompile Include="gf2n.cpp" /> <ClCompile Include="gf2n.cpp" />
<ClCompile Include="gf2n_simd.cpp" />
<ClCompile Include="gfpcrypt.cpp" /> <ClCompile Include="gfpcrypt.cpp" />
<ClCompile Include="hex.cpp" /> <ClCompile Include="hex.cpp" />
<ClCompile Include="hmac.cpp" /> <ClCompile Include="hmac.cpp" />
@ -255,6 +256,16 @@
<ClInclude Include="channels.h" /> <ClInclude Include="channels.h" />
<ClInclude Include="cmac.h" /> <ClInclude Include="cmac.h" />
<ClInclude Include="config.h" /> <ClInclude Include="config.h" />
<ClInclude Include="config_align.h" />
<ClInclude Include="config_asm.h" />
<ClInclude Include="config_cpu.h" />
<ClInclude Include="config_cxx.h" />
<ClInclude Include="config_dll.h" />
<ClInclude Include="config_int.h" />
<ClInclude Include="config_misc.h" />
<ClInclude Include="config_ns.h" />
<ClInclude Include="config_os.h" />
<ClInclude Include="config_ver.h" />
<ClInclude Include="cpu.h" /> <ClInclude Include="cpu.h" />
<ClInclude Include="cryptlib.h" /> <ClInclude Include="cryptlib.h" />
<ClInclude Include="des.h" /> <ClInclude Include="des.h" />

View File

@ -98,6 +98,9 @@
<ClCompile Include="gf2n.cpp"> <ClCompile Include="gf2n.cpp">
<Filter>Source Files</Filter> <Filter>Source Files</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="gf2n_simd.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="gfpcrypt.cpp"> <ClCompile Include="gfpcrypt.cpp">
<Filter>Source Files</Filter> <Filter>Source Files</Filter>
</ClCompile> </ClCompile>
@ -229,6 +232,36 @@
<ClInclude Include="config.h"> <ClInclude Include="config.h">
<Filter>Header Files</Filter> <Filter>Header Files</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="config_align.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="config_asm.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="config_cpu.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="config_cxx.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="config_dll.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="config_int.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="config_misc.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="config_ns.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="config_os.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="config_ver.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="cpu.h"> <ClInclude Include="cpu.h">
<Filter>Header Files</Filter> <Filter>Header Files</Filter>
</ClInclude> </ClInclude>

View File

@ -69,21 +69,22 @@ LIB_SRCS = \
gcm_simd.cpp gf256.cpp gf2_32.cpp gf2n.cpp gf2n_simd.cpp gfpcrypt.cpp \ gcm_simd.cpp gf256.cpp gf2_32.cpp gf2n.cpp gf2n_simd.cpp gfpcrypt.cpp \
gost.cpp gzip.cpp hc128.cpp hc256.cpp hex.cpp hight.cpp hmac.cpp \ gost.cpp gzip.cpp hc128.cpp hc256.cpp hex.cpp hight.cpp hmac.cpp \
hrtimer.cpp ida.cpp idea.cpp iterhash.cpp kalyna.cpp kalynatab.cpp \ hrtimer.cpp ida.cpp idea.cpp iterhash.cpp kalyna.cpp kalynatab.cpp \
keccak.cpp keccakc.cpp lea.cpp lea_simd.cpp luc.cpp mars.cpp marss.cpp \ keccak.cpp keccak_core.cpp keccak_simd.cpp lea.cpp lea_simd.cpp luc.cpp \
md2.cpp md4.cpp md5.cpp misc.cpp modes.cpp mqueue.cpp mqv.cpp \ mars.cpp marss.cpp md2.cpp md4.cpp md5.cpp misc.cpp modes.cpp mqueue.cpp \
nbtheory.cpp neon_simd.cpp oaep.cpp osrng.cpp padlkrng.cpp panama.cpp \ mqv.cpp nbtheory.cpp neon_simd.cpp oaep.cpp osrng.cpp padlkrng.cpp \
pkcspad.cpp poly1305.cpp polynomi.cpp ppc_power7.cpp ppc_power8.cpp \ panama.cpp pkcspad.cpp poly1305.cpp polynomi.cpp ppc_power7.cpp \
ppc_power9.cpp ppc_simd.cpp pssr.cpp pubkey.cpp queue.cpp rabbit.cpp \ ppc_power8.cpp ppc_power9.cpp ppc_simd.cpp pssr.cpp pubkey.cpp queue.cpp \
rabin.cpp randpool.cpp rc2.cpp rc5.cpp rc6.cpp rdrand.cpp rdtables.cpp \ rabbit.cpp rabin.cpp randpool.cpp rc2.cpp rc5.cpp rc6.cpp rdrand.cpp \
rijndael.cpp rijndael_simd.cpp ripemd.cpp rng.cpp rsa.cpp rw.cpp \ rdtables.cpp rijndael.cpp rijndael_simd.cpp ripemd.cpp rng.cpp rsa.cpp \
safer.cpp salsa.cpp scrypt.cpp seal.cpp seed.cpp serpent.cpp sha.cpp \ rw.cpp safer.cpp salsa.cpp scrypt.cpp seal.cpp seed.cpp serpent.cpp \
sha3.cpp sha_simd.cpp shacal2.cpp shacal2_simd.cpp shark.cpp sharkbox.cpp \ sha.cpp sha3.cpp sha_simd.cpp shacal2.cpp shacal2_simd.cpp shake.cpp \
simeck.cpp simeck_simd.cpp simon.cpp simon128_simd.cpp simon64_simd.cpp \ shark.cpp sharkbox.cpp simeck.cpp simeck_simd.cpp simon.cpp \
skipjack.cpp sm3.cpp sm4.cpp sm4_simd.cpp sosemanuk.cpp speck.cpp \ simon128_simd.cpp simon64_simd.cpp skipjack.cpp sm3.cpp sm4.cpp \
speck128_simd.cpp speck64_simd.cpp square.cpp squaretb.cpp sse_simd.cpp \ sm4_simd.cpp sosemanuk.cpp speck.cpp speck128_simd.cpp speck64_simd.cpp \
strciphr.cpp tea.cpp tftables.cpp threefish.cpp tiger.cpp tigertab.cpp \ square.cpp squaretb.cpp sse_simd.cpp strciphr.cpp tea.cpp tftables.cpp \
ttmac.cpp tweetnacl.cpp twofish.cpp vmac.cpp wake.cpp whrlpool.cpp \ threefish.cpp tiger.cpp tigertab.cpp ttmac.cpp tweetnacl.cpp twofish.cpp \
xed25519.cpp xtr.cpp xtrcrypt.cpp zdeflate.cpp zinflate.cpp zlib.cpp vmac.cpp wake.cpp whrlpool.cpp xed25519.cpp xtr.cpp xtrcrypt.cpp \
zdeflate.cpp zinflate.cpp zlib.cpp
LIB_OBJS = \ LIB_OBJS = \
cryptlib.obj cpu.obj integer.obj 3way.obj adler32.obj algebra.obj \ cryptlib.obj cpu.obj integer.obj 3way.obj adler32.obj algebra.obj \
@ -99,24 +100,25 @@ LIB_OBJS = \
gcm_simd.obj gf256.obj gf2_32.obj gf2n.obj gf2n_simd.obj gfpcrypt.obj \ gcm_simd.obj gf256.obj gf2_32.obj gf2n.obj gf2n_simd.obj gfpcrypt.obj \
gost.obj gzip.obj hc128.obj hc256.obj hex.obj hight.obj hmac.obj \ gost.obj gzip.obj hc128.obj hc256.obj hex.obj hight.obj hmac.obj \
hrtimer.obj ida.obj idea.obj iterhash.obj kalyna.obj kalynatab.obj \ hrtimer.obj ida.obj idea.obj iterhash.obj kalyna.obj kalynatab.obj \
keccak.obj keccakc.obj lea.obj lea_simd.obj luc.obj mars.obj marss.obj \ keccak.obj keccak_core.obj keccak_simd.obj lea.obj lea_simd.obj luc.obj \
md2.obj md4.obj md5.obj misc.obj modes.obj mqueue.obj mqv.obj \ mars.obj marss.obj md2.obj md4.obj md5.obj misc.obj modes.obj mqueue.obj \
nbtheory.obj neon_simd.obj oaep.obj osrng.obj padlkrng.obj panama.obj \ mqv.obj nbtheory.obj neon_simd.obj oaep.obj osrng.obj padlkrng.obj \
pkcspad.obj poly1305.obj polynomi.obj ppc_power7.obj ppc_power8.obj \ panama.obj pkcspad.obj poly1305.obj polynomi.obj ppc_power7.obj \
ppc_power9.obj ppc_simd.obj pssr.obj pubkey.obj queue.obj rabbit.obj \ ppc_power8.obj ppc_power9.obj ppc_simd.obj pssr.obj pubkey.obj queue.obj \
rabin.obj randpool.obj rc2.obj rc5.obj rc6.obj rdrand.obj rdtables.obj \ rabbit.obj rabin.obj randpool.obj rc2.obj rc5.obj rc6.obj rdrand.obj \
rijndael.obj rijndael_simd.obj ripemd.obj rng.obj rsa.obj rw.obj \ rdtables.obj rijndael.obj rijndael_simd.obj ripemd.obj rng.obj rsa.obj \
safer.obj salsa.obj scrypt.obj seal.obj seed.obj serpent.obj sha.obj \ rw.obj safer.obj salsa.obj scrypt.obj seal.obj seed.obj serpent.obj \
sha3.obj sha_simd.obj shacal2.obj shacal2_simd.obj shark.obj sharkbox.obj \ sha.obj sha3.obj sha_simd.obj shacal2.obj shacal2_simd.obj shake.obj \
simeck.obj simeck_simd.obj simon.obj simon128_simd.obj simon64_simd.obj \ shark.obj sharkbox.obj simeck.obj simeck_simd.obj simon.obj \
skipjack.obj sm3.obj sm4.obj sm4_simd.obj sosemanuk.obj speck.obj \ simon128_simd.obj simon64_simd.obj skipjack.obj sm3.obj sm4.obj \
speck128_simd.obj speck64_simd.obj square.obj squaretb.obj sse_simd.obj \ sm4_simd.obj sosemanuk.obj speck.obj speck128_simd.obj speck64_simd.obj \
strciphr.obj tea.obj tftables.obj threefish.obj tiger.obj tigertab.obj \ square.obj squaretb.obj sse_simd.obj strciphr.obj tea.obj tftables.obj \
ttmac.obj tweetnacl.obj twofish.obj vmac.obj wake.obj whrlpool.obj \ threefish.obj tiger.obj tigertab.obj ttmac.obj tweetnacl.obj twofish.obj \
xed25519.obj xtr.obj xtrcrypt.obj zdeflate.obj zinflate.obj zlib.obj vmac.obj wake.obj whrlpool.obj xed25519.obj xtr.obj xtrcrypt.obj \
zdeflate.obj zinflate.obj zlib.obj
ASM_OBJS = \ ASM_OBJS = \
rdrand-x86.obj rdrand-x64.obj x64masm.obj x64dll.obj rdrand-x86.obj rdrand-x64.obj rdseed-x86.obj rdseed-x64.obj x64masm.obj x64dll.obj
TEST_SRCS = \ TEST_SRCS = \
test.cpp bench1.cpp bench2.cpp bench3.cpp datatest.cpp \ test.cpp bench1.cpp bench2.cpp bench3.cpp datatest.cpp \
@ -151,12 +153,14 @@ LDFLAGS = /nologo /SUBSYSTEM:CONSOLE /DEBUG
ARFLAGS = /nologo ARFLAGS = /nologo
LDLIBS = LDLIBS =
# Debug build. # Compiler debug build.
# CXXFLAGS = $(CXXFLAGS) /DDEBUG /D_DEBUG /Oi /Oy- /Od /MTd # CXXFLAGS = $(CXXFLAGS) /DDEBUG /D_DEBUG /Oi /Oy- /Od /MTd
# Release build. Add /OPT:REF to linker # Compiler release build.
CXXFLAGS = $(CXXFLAGS) /DNDEBUG /D_NDEBUG /Oi /Oy /O2 /MT CXXFLAGS = $(CXXFLAGS) /DNDEBUG /D_NDEBUG /Oi /Oy /O2 /MT
# Linker flags. # Linker debug build.
LDFLAGS = $(LDFLAGS) /OPT:REF # LDFLAGS = $(LDFLAGS) /DEBUG
# Linker release build.
LDFLAGS = $(LDFLAGS) /DEBUG /OPT:REF
# Attempt to detect when <sdkddkver.h> and <winapifamily.h> are available # Attempt to detect when <sdkddkver.h> and <winapifamily.h> are available
# http://stackoverflow.com/q/40577415 ? # http://stackoverflow.com/q/40577415 ?
@ -192,10 +196,12 @@ PLATFORM = x64
# CXXFLAGS = $(CXXFLAGS) /DWINAPI_FAMILY=WINAPI_FAMILY_APP # CXXFLAGS = $(CXXFLAGS) /DWINAPI_FAMILY=WINAPI_FAMILY_APP
AS = ml.exe AS = ml.exe
ASFLAGS = /nologo /D_M_X86 /W3 /Cx /Zi /safeseh ASFLAGS = /nologo /D_M_X86 /W3 /Cx /Zi /safeseh
LIB_SRCS = $(LIB_SRCS) rdrand.cpp rdrand.asm LIB_SRCS = $(LIB_SRCS) rdrand.cpp rdrand.asm rdseed.asm
LIB_OBJS = $(LIB_OBJS) rdrand-x86.obj LIB_OBJS = $(LIB_OBJS) rdrand-x86.obj rdseed-x86.obj
LDFLAGS = $(LDFLAGS) /MACHINE:X86 LDFLAGS = $(LDFLAGS) /MACHINE:X86
LDLIBS = $(LDLIBS) kernel32.lib LDLIBS = $(LDLIBS) kernel32.lib
RDRAND_OBJ = rdrand-x86.obj
RDSEED_OBJ = rdseed-x86.obj
!ENDIF !ENDIF
# May need $(VCINSTALLDIR)\bin\amd64\ml64.exe # May need $(VCINSTALLDIR)\bin\amd64\ml64.exe
@ -205,10 +211,12 @@ LDLIBS = $(LDLIBS) kernel32.lib
# CXXFLAGS = $(CXXFLAGS) /DWINAPI_FAMILY=WINAPI_FAMILY_APP # CXXFLAGS = $(CXXFLAGS) /DWINAPI_FAMILY=WINAPI_FAMILY_APP
AS = ml64.exe AS = ml64.exe
ASFLAGS = /nologo /D_M_X64 /W3 /Cx /Zi ASFLAGS = /nologo /D_M_X64 /W3 /Cx /Zi
LIB_SRCS = $(LIB_SRCS) rdrand.cpp rdrand.asm LIB_SRCS = $(LIB_SRCS) rdrand.cpp rdrand.asm rdseed.asm
LIB_OBJS = $(LIB_OBJS) rdrand-x64.obj x64masm.obj x64dll.obj LIB_OBJS = $(LIB_OBJS) rdrand-x64.obj rdseed-x64.obj x64masm.obj x64dll.obj
LDFLAGS = $(LDFLAGS) /MACHINE:X64 LDFLAGS = $(LDFLAGS) /MACHINE:X64
LDLIBS = $(LDLIBS) kernel32.lib LDLIBS = $(LDLIBS) kernel32.lib
RDRAND_OBJ = rdrand-x64.obj
RDSEED_OBJ = rdseed-x64.obj
!ENDIF !ENDIF
!IF "$(PLATFORM)" == "ARM" || "$(PLATFORM)" == "arm" || "$(PLATFORM)" == "ARM64" || "$(PLATFORM)" == "arm64" !IF "$(PLATFORM)" == "ARM" || "$(PLATFORM)" == "arm" || "$(PLATFORM)" == "ARM64" || "$(PLATFORM)" == "arm64"
@ -256,13 +264,13 @@ clean ::
$(RM) /F /Q pch.obj $(LIB_OBJS) $(ASM_OBJS) $(TEST_OBJS) *.pdb 2>nul $(RM) /F /Q pch.obj $(LIB_OBJS) $(ASM_OBJS) $(TEST_OBJS) *.pdb 2>nul
distclean :: clean distclean :: clean
!IF EXIST ($(USERNAME).sdf) !IF EXIST ("$(USERNAME).sdf")
attrib -r -a -s -h $(USERNAME).sdf 2>nul attrib -r -a -s -h "$(USERNAME).sdf" 2>nul
$(RM) /F /Q $(USERNAME).sdf 2>nul $(RM) /F /Q "$(USERNAME).sdf" 2>nul
!ENDIF !ENDIF
!IF EXIST ($(USERNAME).suo) !IF EXIST ("$(USERNAME).suo")
attrib -r -a -s -h $(USERNAME).suo 2>nul attrib -r -a -s -h $(USERNAME).suo" 2>nul
$(RM) /F /Q $(USERNAME).suo 2>nul $(RM) /F /Q $(USERNAME).suo" 2>nul
!ENDIF !ENDIF
!IF EXIST (Win32\) !IF EXIST (Win32\)
$(RMDIR) Win32\ /q /s 2>nul $(RMDIR) Win32\ /q /s 2>nul
@ -279,21 +287,25 @@ pch.pch: pch.h pch.cpp
$(CXX) $(CXXFLAGS) /Yc"pch.h" /Fp"pch.pch" /c pch.cpp $(CXX) $(CXXFLAGS) /Yc"pch.h" /Fp"pch.pch" /c pch.cpp
# No precompiled headers # No precompiled headers
iterhash.obj: iterhash.obj: iterhash.h iterhash.cpp
$(CXX) $(CXXFLAGS) /Y- /c iterhash.cpp $(CXX) $(CXXFLAGS) /Y- /c iterhash.cpp
dll.obj: dll.obj: dll.h dll.cpp
$(CXX) $(CXXFLAGS) /Y- /c dll.cpp $(CXX) $(CXXFLAGS) /Y- /c dll.cpp
rdrand.obj: rdrand.obj: rdrand.h rdrand.cpp
$(CXX) $(CXXFLAGS) /c rdrand.cpp $(CXX) $(CXXFLAGS) /c rdrand.cpp
# Built for x86/x64 # Built for x86/x64
rdrand-x86.obj: rdrand-x86.obj: rdrand.asm
$(AS) $(ASFLAGS) /Fo rdrand-x86.obj /c rdrand.asm $(AS) $(ASFLAGS) /Fo rdrand-x86.obj /c rdrand.asm
rdrand-x64.obj: rdrand-x64.obj: rdrand.asm
$(AS) $(ASFLAGS) /Fo rdrand-x64.obj /c rdrand.asm $(AS) $(ASFLAGS) /Fo rdrand-x64.obj /c rdrand.asm
x64masm.obj: rdseed-x86.obj: rdseed.asm
$(AS) $(ASFLAGS) /Fo rdseed-x86.obj /c rdseed.asm
rdseed-x64.obj: rdseed.asm
$(AS) $(ASFLAGS) /Fo rdseed-x64.obj /c rdseed.asm
x64masm.obj: x64masm.asm
$(AS) $(ASFLAGS) /Fo x64masm.obj /c x64masm.asm $(AS) $(ASFLAGS) /Fo x64masm.obj /c x64masm.asm
x64dll.obj: x64dll.obj: x64dll.asm
$(AS) $(ASFLAGS) /Fo x64dll.obj /c x64dll.asm $(AS) $(ASFLAGS) /Fo x64dll.obj /c x64dll.asm
# You may need to delete this on early versions of Visual Studio. # You may need to delete this on early versions of Visual Studio.

File diff suppressed because it is too large Load Diff

View File

@ -195,7 +195,10 @@
<!-- The rule copies cryptest.exe to the project --> <!-- The rule copies cryptest.exe to the project -->
<!-- root directory so it can be executed in place --> <!-- root directory so it can be executed in place -->
<Target Name="CopyCryptestToRoot"> <Target Name="CopyCryptestToRoot">
<Exec Command="copy $(Platform)\Output\$(Configuration)\cryptest.exe $(SolutionDir)" /> <Exec Command="copy &quot;$(Platform)\Output\$(Configuration)\cryptest.exe&quot; &quot;$(SolutionDir)&quot;" />
</Target>
<Target Name="CopyToRoot">
<Exec Command="copy &quot;$(Platform)\Output\$(Configuration)\cryptest.exe&quot; &quot;$(SolutionDir)&quot;" />
</Target> </Target>
<!-- Source Files --> <!-- Source Files -->
<ItemGroup> <ItemGroup>

View File

@ -16,7 +16,6 @@
#ifndef CRYPTOPP_IMPORTS #ifndef CRYPTOPP_IMPORTS
#include "cryptlib.h" #include "cryptlib.h"
#include "misc.h"
#include "filters.h" #include "filters.h"
#include "algparam.h" #include "algparam.h"
#include "fips140.h" #include "fips140.h"
@ -26,6 +25,7 @@
#include "secblock.h" #include "secblock.h"
#include "smartptr.h" #include "smartptr.h"
#include "stdcpp.h" #include "stdcpp.h"
#include "misc.h"
NAMESPACE_BEGIN(CryptoPP) NAMESPACE_BEGIN(CryptoPP)
@ -333,20 +333,20 @@ void RandomNumberGenerator::GenerateIntoBufferedTransformation(BufferedTransform
} }
} }
size_t KeyDerivationFunction::MinDerivedLength() const size_t KeyDerivationFunction::MinDerivedKeyLength() const
{ {
return 0; return 0;
} }
size_t KeyDerivationFunction::MaxDerivedLength() const size_t KeyDerivationFunction::MaxDerivedKeyLength() const
{ {
return static_cast<size_t>(-1); return static_cast<size_t>(-1);
} }
void KeyDerivationFunction::ThrowIfInvalidDerivedLength(size_t length) const void KeyDerivationFunction::ThrowIfInvalidDerivedKeyLength(size_t length) const
{ {
if (!IsValidDerivedLength(length)) if (!IsValidDerivedLength(length))
throw InvalidDerivedLength(GetAlgorithm().AlgorithmName(), length); throw InvalidDerivedKeyLength(GetAlgorithm().AlgorithmName(), length);
} }
void KeyDerivationFunction::SetParameters(const NameValuePairs& params) { void KeyDerivationFunction::SetParameters(const NameValuePairs& params) {
@ -405,8 +405,9 @@ RandomNumberGenerator & NullRNG()
bool HashTransformation::TruncatedVerify(const byte *digest, size_t digestLength) bool HashTransformation::TruncatedVerify(const byte *digest, size_t digestLength)
{ {
// Allocate at least 1 for calculated to avoid triggering diagnostics
ThrowIfInvalidTruncatedSize(digestLength); ThrowIfInvalidTruncatedSize(digestLength);
SecByteBlock calculated(digestLength); SecByteBlock calculated(digestLength ? digestLength : 1);
TruncatedFinal(calculated, digestLength); TruncatedFinal(calculated, digestLength);
return VerifyBufsEqual(calculated, digest, digestLength); return VerifyBufsEqual(calculated, digest, digestLength);
} }
@ -742,6 +743,12 @@ size_t BufferedTransformation::ChannelPutWord32(const std::string &channel, word
return ChannelPut(channel, m_buf, 4, blocking); return ChannelPut(channel, m_buf, 4, blocking);
} }
size_t BufferedTransformation::ChannelPutWord64(const std::string &channel, word64 value, ByteOrder order, bool blocking)
{
PutWord(false, order, m_buf, value);
return ChannelPut(channel, m_buf, 8, blocking);
}
size_t BufferedTransformation::PutWord16(word16 value, ByteOrder order, bool blocking) size_t BufferedTransformation::PutWord16(word16 value, ByteOrder order, bool blocking)
{ {
return ChannelPutWord16(DEFAULT_CHANNEL, value, order, blocking); return ChannelPutWord16(DEFAULT_CHANNEL, value, order, blocking);
@ -752,22 +759,20 @@ size_t BufferedTransformation::PutWord32(word32 value, ByteOrder order, bool blo
return ChannelPutWord32(DEFAULT_CHANNEL, value, order, blocking); return ChannelPutWord32(DEFAULT_CHANNEL, value, order, blocking);
} }
// Issue 340 size_t BufferedTransformation::PutWord64(word64 value, ByteOrder order, bool blocking)
#if CRYPTOPP_GCC_DIAGNOSTIC_AVAILABLE {
# pragma GCC diagnostic push return ChannelPutWord64(DEFAULT_CHANNEL, value, order, blocking);
# pragma GCC diagnostic ignored "-Wconversion" }
# pragma GCC diagnostic ignored "-Wsign-conversion"
#endif
size_t BufferedTransformation::PeekWord16(word16 &value, ByteOrder order) const size_t BufferedTransformation::PeekWord16(word16 &value, ByteOrder order) const
{ {
byte buf[2] = {0, 0}; byte buf[2] = {0, 0};
size_t len = Peek(buf, 2); size_t len = Peek(buf, 2);
if (order) if (order == BIG_ENDIAN_ORDER)
value = (buf[0] << 8) | buf[1]; value = ((word16)buf[0] << 8) | (word16)buf[1];
else else
value = (buf[1] << 8) | buf[0]; value = ((word16)buf[1] << 8) | (word16)buf[0];
return len; return len;
} }
@ -777,18 +782,32 @@ size_t BufferedTransformation::PeekWord32(word32 &value, ByteOrder order) const
byte buf[4] = {0, 0, 0, 0}; byte buf[4] = {0, 0, 0, 0};
size_t len = Peek(buf, 4); size_t len = Peek(buf, 4);
if (order) if (order == BIG_ENDIAN_ORDER)
value = (buf[0] << 24) | (buf[1] << 16) | (buf[2] << 8) | buf [3]; value = ((word32)buf[0] << 24) | ((word32)buf[1] << 16) |
((word32)buf[2] << 8) | (word32)buf[3];
else else
value = (buf[3] << 24) | (buf[2] << 16) | (buf[1] << 8) | buf [0]; value = ((word32)buf[3] << 24) | ((word32)buf[2] << 16) |
((word32)buf[1] << 8) | (word32)buf[0];
return len; return len;
} }
// Issue 340 size_t BufferedTransformation::PeekWord64(word64 &value, ByteOrder order) const
#if CRYPTOPP_GCC_DIAGNOSTIC_AVAILABLE {
# pragma GCC diagnostic pop byte buf[8] = {0, 0, 0, 0, 0, 0, 0, 0};
#endif size_t len = Peek(buf, 8);
if (order == BIG_ENDIAN_ORDER)
value = ((word64)buf[0] << 56) | ((word64)buf[1] << 48) | ((word64)buf[2] << 40) |
((word64)buf[3] << 32) | ((word64)buf[4] << 24) | ((word64)buf[5] << 16) |
((word64)buf[6] << 8) | (word64)buf[7];
else
value = ((word64)buf[7] << 56) | ((word64)buf[6] << 48) | ((word64)buf[5] << 40) |
((word64)buf[4] << 32) | ((word64)buf[3] << 24) | ((word64)buf[2] << 16) |
((word64)buf[1] << 8) | (word64)buf[0];
return len;
}
size_t BufferedTransformation::GetWord16(word16 &value, ByteOrder order) size_t BufferedTransformation::GetWord16(word16 &value, ByteOrder order)
{ {
@ -800,6 +819,11 @@ size_t BufferedTransformation::GetWord32(word32 &value, ByteOrder order)
return (size_t)Skip(PeekWord32(value, order)); return (size_t)Skip(PeekWord32(value, order));
} }
size_t BufferedTransformation::GetWord64(word64 &value, ByteOrder order)
{
return (size_t)Skip(PeekWord64(value, order));
}
void BufferedTransformation::Attach(BufferedTransformation *newAttachment) void BufferedTransformation::Attach(BufferedTransformation *newAttachment)
{ {
if (AttachedTransformation() && AttachedTransformation()->Attachable()) if (AttachedTransformation() && AttachedTransformation()->Attachable())

View File

@ -3,7 +3,7 @@
/// \file cryptlib.h /// \file cryptlib.h
/// \brief Abstract base classes that provide a uniform interface to this library. /// \brief Abstract base classes that provide a uniform interface to this library.
/*! \mainpage Crypto++ Library 8.1 API Reference /*! \mainpage Crypto++ Library 8.3 API Reference
<dl> <dl>
<dt>Abstract Base Classes<dd> <dt>Abstract Base Classes<dd>
cryptlib.h cryptlib.h
@ -202,6 +202,9 @@ private:
class CRYPTOPP_DLL InvalidArgument : public Exception class CRYPTOPP_DLL InvalidArgument : public Exception
{ {
public: public:
/// \brief Construct an InvalidArgument
/// \param s the message for the exception
/// \details The member function <tt>what()</tt> returns <tt>s</tt>.
explicit InvalidArgument(const std::string &s) : Exception(INVALID_ARGUMENT, s) {} explicit InvalidArgument(const std::string &s) : Exception(INVALID_ARGUMENT, s) {}
}; };
@ -209,6 +212,9 @@ public:
class CRYPTOPP_DLL InvalidDataFormat : public Exception class CRYPTOPP_DLL InvalidDataFormat : public Exception
{ {
public: public:
/// \brief Construct an InvalidDataFormat
/// \param s the message for the exception
/// \details The member function <tt>what()</tt> returns <tt>s</tt>.
explicit InvalidDataFormat(const std::string &s) : Exception(INVALID_DATA_FORMAT, s) {} explicit InvalidDataFormat(const std::string &s) : Exception(INVALID_DATA_FORMAT, s) {}
}; };
@ -216,6 +222,9 @@ public:
class CRYPTOPP_DLL InvalidCiphertext : public InvalidDataFormat class CRYPTOPP_DLL InvalidCiphertext : public InvalidDataFormat
{ {
public: public:
/// \brief Construct an InvalidCiphertext
/// \param s the message for the exception
/// \details The member function <tt>what()</tt> returns <tt>s</tt>.
explicit InvalidCiphertext(const std::string &s) : InvalidDataFormat(s) {} explicit InvalidCiphertext(const std::string &s) : InvalidDataFormat(s) {}
}; };
@ -223,6 +232,9 @@ public:
class CRYPTOPP_DLL NotImplemented : public Exception class CRYPTOPP_DLL NotImplemented : public Exception
{ {
public: public:
/// \brief Construct an NotImplemented
/// \param s the message for the exception
/// \details The member function <tt>what()</tt> returns <tt>s</tt>.
explicit NotImplemented(const std::string &s) : Exception(NOT_IMPLEMENTED, s) {} explicit NotImplemented(const std::string &s) : Exception(NOT_IMPLEMENTED, s) {}
}; };
@ -230,6 +242,9 @@ public:
class CRYPTOPP_DLL CannotFlush : public Exception class CRYPTOPP_DLL CannotFlush : public Exception
{ {
public: public:
/// \brief Construct an CannotFlush
/// \param s the message for the exception
/// \details The member function <tt>what()</tt> returns <tt>s</tt>.
explicit CannotFlush(const std::string &s) : Exception(CANNOT_FLUSH, s) {} explicit CannotFlush(const std::string &s) : Exception(CANNOT_FLUSH, s) {}
}; };
@ -238,6 +253,13 @@ class CRYPTOPP_DLL OS_Error : public Exception
{ {
public: public:
virtual ~OS_Error() throw() {} virtual ~OS_Error() throw() {}
/// \brief Construct an OS_Error
/// \param errorType the error type
/// \param s the message for the exception
/// \param operation the operation for the exception
/// \param errorCode the error code
/// \details The member function <tt>what()</tt> returns <tt>s</tt>.
OS_Error(ErrorType errorType, const std::string &s, const std::string& operation, int errorCode) OS_Error(ErrorType errorType, const std::string &s, const std::string& operation, int errorCode)
: Exception(errorType, s), m_operation(operation), m_errorCode(errorCode) {} : Exception(errorType, s), m_operation(operation), m_errorCode(errorCode) {}
@ -255,7 +277,8 @@ protected:
struct CRYPTOPP_DLL DecodingResult struct CRYPTOPP_DLL DecodingResult
{ {
/// \brief Constructs a DecodingResult /// \brief Constructs a DecodingResult
/// \details isValidCoding is initialized to false and messageLength is initialized to 0. /// \details isValidCoding is initialized to false and messageLength is
/// initialized to 0.
explicit DecodingResult() : isValidCoding(false), messageLength(0) {} explicit DecodingResult() : isValidCoding(false), messageLength(0) {}
/// \brief Constructs a DecodingResult /// \brief Constructs a DecodingResult
/// \param len the message length /// \param len the message length
@ -264,11 +287,13 @@ struct CRYPTOPP_DLL DecodingResult
/// \brief Compare two DecodingResult /// \brief Compare two DecodingResult
/// \param rhs the other DecodingResult /// \param rhs the other DecodingResult
/// \return true if both isValidCoding and messageLength are equal, false otherwise /// \return true if either isValidCoding or messageLength is \a not equal,
/// false otherwise
bool operator==(const DecodingResult &rhs) const {return isValidCoding == rhs.isValidCoding && messageLength == rhs.messageLength;} bool operator==(const DecodingResult &rhs) const {return isValidCoding == rhs.isValidCoding && messageLength == rhs.messageLength;}
/// \brief Compare two DecodingResult /// \brief Compare two DecodingResult
/// \param rhs the other DecodingResult /// \param rhs the other DecodingResult
/// \return true if either isValidCoding or messageLength is \a not equal, false otherwise /// \return true if either isValidCoding or messageLength is \a not equal,
/// false otherwise
/// \details Returns <tt>!operator==(rhs)</tt>. /// \details Returns <tt>!operator==(rhs)</tt>.
bool operator!=(const DecodingResult &rhs) const {return !operator==(rhs);} bool operator!=(const DecodingResult &rhs) const {return !operator==(rhs);}
@ -279,24 +304,28 @@ struct CRYPTOPP_DLL DecodingResult
}; };
/// \brief Interface for retrieving values given their names /// \brief Interface for retrieving values given their names
/// \details This class is used to safely pass a variable number of arbitrarily typed arguments to functions /// \details This class is used to safely pass a variable number of arbitrarily
/// and to read values from keys and crypto parameters. /// typed arguments to functions and to read values from keys and crypto parameters.
/// \details To obtain an object that implements NameValuePairs for the purpose of parameter /// \details To obtain an object that implements NameValuePairs for the purpose of
/// passing, use the MakeParameters() function. /// parameter passing, use the MakeParameters() function.
/// \details To get a value from NameValuePairs, you need to know the name and the type of the value. /// \details To get a value from NameValuePairs, you need to know the name and the
/// Call GetValueNames() on a NameValuePairs object to obtain a list of value names that it supports. /// type of the value. Call GetValueNames() on a NameValuePairs object to obtain a
/// then look at the Name namespace documentation to see what the type of each value is, or /// list of value names that it supports. then look at the Name namespace
/// alternatively, call GetIntValue() with the value name, and if the type is not int, a /// documentation to see what the type of each value is, or alternatively, call
/// ValueTypeMismatch exception will be thrown and you can get the actual type from the exception object. /// GetIntValue() with the value name, and if the type is not int, a
/// ValueTypeMismatch exception will be thrown and you can get the actual type from
/// the exception object.
/// \sa NullNameValuePairs, g_nullNameValuePairs, /// \sa NullNameValuePairs, g_nullNameValuePairs,
/// <A HREF="http://www.cryptopp.com/wiki/NameValuePairs">NameValuePairs</A> on the Crypto++ wiki /// <A HREF="http://www.cryptopp.com/wiki/NameValuePairs">NameValuePairs</A> on the
/// Crypto++ wiki
class NameValuePairs class NameValuePairs
{ {
public: public:
virtual ~NameValuePairs() {} virtual ~NameValuePairs() {}
/// \brief Thrown when an unexpected type is encountered /// \brief Thrown when an unexpected type is encountered
/// \details Exception thrown when trying to retrieve a value using a different type than expected /// \details Exception thrown when trying to retrieve a value using a different
/// type than expected
class CRYPTOPP_DLL ValueTypeMismatch : public InvalidArgument class CRYPTOPP_DLL ValueTypeMismatch : public InvalidArgument
{ {
public: public:
@ -1477,11 +1506,11 @@ public:
/// \brief Determine minimum number of bytes /// \brief Determine minimum number of bytes
/// \returns Minimum number of bytes which can be derived /// \returns Minimum number of bytes which can be derived
virtual size_t MinDerivedLength() const; virtual size_t MinDerivedKeyLength() const;
/// \brief Determine maximum number of bytes /// \brief Determine maximum number of bytes
/// \returns Maximum number of bytes which can be derived /// \returns Maximum number of bytes which can be derived
virtual size_t MaxDerivedLength() const; virtual size_t MaxDerivedKeyLength() const;
/// \brief Returns a valid key length for the derivation function /// \brief Returns a valid key length for the derivation function
/// \param keylength the size of the derived key, in bytes /// \param keylength the size of the derived key, in bytes
@ -1503,7 +1532,7 @@ public:
/// \param secretLen the size of the secret buffer, in bytes /// \param secretLen the size of the secret buffer, in bytes
/// \param params additional initialization parameters to configure this object /// \param params additional initialization parameters to configure this object
/// \returns the number of iterations performed /// \returns the number of iterations performed
/// \throws InvalidDerivedLength if <tt>derivedLen</tt> is invalid for the scheme /// \throws InvalidDerivedKeyLength if <tt>derivedLen</tt> is invalid for the scheme
/// \details DeriveKey() provides a standard interface to derive a key from /// \details DeriveKey() provides a standard interface to derive a key from
/// a secret seed and other parameters. Each class that derives from KeyDerivationFunction /// a secret seed and other parameters. Each class that derives from KeyDerivationFunction
/// provides an overload that accepts most parameters used by the derivation function. /// provides an overload that accepts most parameters used by the derivation function.
@ -1525,7 +1554,7 @@ protected:
/// \brief Validates the derived key length /// \brief Validates the derived key length
/// \param length the size of the derived key material, in bytes /// \param length the size of the derived key material, in bytes
/// \throws InvalidKeyLength if the key length is invalid /// \throws InvalidKeyLength if the key length is invalid
void ThrowIfInvalidDerivedLength(size_t length) const; void ThrowIfInvalidDerivedKeyLength(size_t length) const;
}; };
/// \brief Interface for password based key derivation functions /// \brief Interface for password based key derivation functions
@ -1614,8 +1643,8 @@ public:
/// \brief Input a byte for processing /// \brief Input a byte for processing
/// \param inByte the 8-bit byte (octet) to be processed. /// \param inByte the 8-bit byte (octet) to be processed.
/// \param blocking specifies whether the object should block when processing input. /// \param blocking specifies whether the object should block when processing input.
/// \return the number of bytes that remain in the block (i.e., bytes not processed). 0 indicates all /// \return the number of bytes that remain in the block (i.e., bytes not processed).
/// bytes were processed. /// 0 indicates all bytes were processed.
/// \details <tt>Put(byte)</tt> calls <tt>Put(byte*, size_t)</tt>. /// \details <tt>Put(byte)</tt> calls <tt>Put(byte*, size_t)</tt>.
size_t Put(byte inByte, bool blocking=true) size_t Put(byte inByte, bool blocking=true)
{return Put(&inByte, 1, blocking);} {return Put(&inByte, 1, blocking);}
@ -1624,8 +1653,8 @@ public:
/// \param inString the byte buffer to process /// \param inString the byte buffer to process
/// \param length the size of the string, in bytes /// \param length the size of the string, in bytes
/// \param blocking specifies whether the object should block when processing input /// \param blocking specifies whether the object should block when processing input
/// \return the number of bytes that remain in the block (i.e., bytes not processed). 0 indicates all /// \return the number of bytes that remain in the block (i.e., bytes not processed).
/// bytes were processed. /// 0 indicates all bytes were processed.
/// \details Internally, Put() calls Put2(). /// \details Internally, Put() calls Put2().
size_t Put(const byte *inString, size_t length, bool blocking=true) size_t Put(const byte *inString, size_t length, bool blocking=true)
{return Put2(inString, length, 0, blocking);} {return Put2(inString, length, 0, blocking);}
@ -1634,18 +1663,26 @@ public:
/// \param value the 16-bit value to be processed /// \param value the 16-bit value to be processed
/// \param order the ByteOrder of the value to be processed. /// \param order the ByteOrder of the value to be processed.
/// \param blocking specifies whether the object should block when processing input /// \param blocking specifies whether the object should block when processing input
/// \return the number of bytes that remain in the block (i.e., bytes not processed). 0 indicates all /// \return the number of bytes that remain in the block (i.e., bytes not processed).
/// bytes were processed. /// 0 indicates all bytes were processed.
size_t PutWord16(word16 value, ByteOrder order=BIG_ENDIAN_ORDER, bool blocking=true); size_t PutWord16(word16 value, ByteOrder order=BIG_ENDIAN_ORDER, bool blocking=true);
/// Input a 32-bit word for processing. /// Input a 32-bit word for processing.
/// \param value the 32-bit value to be processed. /// \param value the 32-bit value to be processed.
/// \param order the ByteOrder of the value to be processed. /// \param order the ByteOrder of the value to be processed.
/// \param blocking specifies whether the object should block when processing input. /// \param blocking specifies whether the object should block when processing input.
/// \return the number of bytes that remain in the block (i.e., bytes not processed). 0 indicates all /// \return the number of bytes that remain in the block (i.e., bytes not processed).
/// bytes were processed. /// 0 indicates all bytes were processed.
size_t PutWord32(word32 value, ByteOrder order=BIG_ENDIAN_ORDER, bool blocking=true); size_t PutWord32(word32 value, ByteOrder order=BIG_ENDIAN_ORDER, bool blocking=true);
/// Input a 64-bit word for processing.
/// \param value the 64-bit value to be processed.
/// \param order the ByteOrder of the value to be processed.
/// \param blocking specifies whether the object should block when processing input.
/// \return the number of bytes that remain in the block (i.e., bytes not processed).
/// 0 indicates all bytes were processed.
size_t PutWord64(word64 value, ByteOrder order=BIG_ENDIAN_ORDER, bool blocking=true);
/// \brief Request space which can be written into by the caller /// \brief Request space which can be written into by the caller
/// \param size the requested size of the buffer /// \param size the requested size of the buffer
/// \return byte pointer to the space to input data /// \return byte pointer to the space to input data
@ -1781,18 +1818,23 @@ public:
/// \brief Flush buffered input and/or output, with signal propagation /// \brief Flush buffered input and/or output, with signal propagation
/// \param hardFlush is used to indicate whether all data should be flushed /// \param hardFlush is used to indicate whether all data should be flushed
/// \param propagation the number of attached transformations the Flush() signal should be passed /// \param propagation the number of attached transformations the Flush()
/// \param blocking specifies whether the object should block when processing input /// signal should be passed
/// \details propagation count includes this object. Setting propagation to <tt>1</tt> means this /// \param blocking specifies whether the object should block when processing
/// object only. Setting propagation to <tt>-1</tt> means unlimited propagation. /// input
/// \note Hard flushes must be used with care. It means try to process and output everything, even if /// \details propagation count includes this object. Setting propagation to
/// there may not be enough data to complete the action. For example, hard flushing a HexDecoder /// <tt>1</tt> means this object only. Setting propagation to <tt>-1</tt>
/// would cause an error if you do it after inputing an odd number of hex encoded characters. /// means unlimited propagation.
/// \note For some types of filters, like ZlibDecompressor, hard flushes can only /// \note Hard flushes must be used with care. It means try to process and
/// be done at "synchronization points". These synchronization points are positions in the data /// output everything, even if there may not be enough data to complete the
/// stream that are created by hard flushes on the corresponding reverse filters, in this /// action. For example, hard flushing a HexDecoder would cause an error if
/// example ZlibCompressor. This is useful when zlib compressed data is moved across a /// you do it after inputing an odd number of hex encoded characters.
/// network in packets and compression state is preserved across packets, as in the SSH2 protocol. /// \note For some types of filters, like ZlibDecompressor, hard flushes can
/// only be done at "synchronization points". These synchronization points
/// are positions in the data stream that are created by hard flushes on the
/// corresponding reverse filters, in this example ZlibCompressor. This is
/// useful when zlib compressed data is moved across a network in packets
/// and compression state is preserved across packets, as in the SSH2 protocol.
virtual bool Flush(bool hardFlush, int propagation=-1, bool blocking=true); virtual bool Flush(bool hardFlush, int propagation=-1, bool blocking=true);
/// \brief Marks the end of a series of messages, with signal propagation /// \brief Marks the end of a series of messages, with signal propagation
@ -1856,7 +1898,7 @@ public:
/// \param peekMax the number of bytes to Peek /// \param peekMax the number of bytes to Peek
/// \return the number of bytes read during the call. /// \return the number of bytes read during the call.
/// \details Peek does not remove bytes from the object. Use the return value of /// \details Peek does not remove bytes from the object. Use the return value of
/// Get() to detect short reads. /// Peek() to detect short reads.
virtual size_t Peek(byte *outString, size_t peekMax) const; virtual size_t Peek(byte *outString, size_t peekMax) const;
/// \brief Retrieve a 16-bit word /// \brief Retrieve a 16-bit word
@ -1870,15 +1912,23 @@ public:
/// \param value the 32-bit value to be retrieved /// \param value the 32-bit value to be retrieved
/// \param order the ByteOrder of the value to be processed. /// \param order the ByteOrder of the value to be processed.
/// \return the number of bytes consumed during the call. /// \return the number of bytes consumed during the call.
/// \details Use the return value of GetWord16() to detect short reads. /// \details Use the return value of GetWord32() to detect short reads.
size_t GetWord32(word32 &value, ByteOrder order=BIG_ENDIAN_ORDER); size_t GetWord32(word32 &value, ByteOrder order=BIG_ENDIAN_ORDER);
/// \brief Retrieve a 64-bit word
/// \param value the 64-bit value to be retrieved
/// \param order the ByteOrder of the value to be processed.
/// \return the number of bytes consumed during the call.
/// \details Use the return value of GetWord64() to detect short reads.
/// \since Crypto++ 8.3
size_t GetWord64(word64 &value, ByteOrder order=BIG_ENDIAN_ORDER);
/// \brief Peek a 16-bit word /// \brief Peek a 16-bit word
/// \param value the 16-bit value to be retrieved /// \param value the 16-bit value to be retrieved
/// \param order the ByteOrder of the value to be processed. /// \param order the ByteOrder of the value to be processed.
/// \return the number of bytes consumed during the call. /// \return the number of bytes consumed during the call.
/// \details Peek does not consume bytes in the stream. Use the return value /// \details Peek does not consume bytes in the stream. Use the return value
/// of GetWord16() to detect short reads. /// of PeekWord16() to detect short reads.
size_t PeekWord16(word16 &value, ByteOrder order=BIG_ENDIAN_ORDER) const; size_t PeekWord16(word16 &value, ByteOrder order=BIG_ENDIAN_ORDER) const;
/// \brief Peek a 32-bit word /// \brief Peek a 32-bit word
@ -1886,9 +1936,18 @@ public:
/// \param order the ByteOrder of the value to be processed. /// \param order the ByteOrder of the value to be processed.
/// \return the number of bytes consumed during the call. /// \return the number of bytes consumed during the call.
/// \details Peek does not consume bytes in the stream. Use the return value /// \details Peek does not consume bytes in the stream. Use the return value
/// of GetWord16() to detect short reads. /// of PeekWord32() to detect short reads.
size_t PeekWord32(word32 &value, ByteOrder order=BIG_ENDIAN_ORDER) const; size_t PeekWord32(word32 &value, ByteOrder order=BIG_ENDIAN_ORDER) const;
/// \brief Peek a 64-bit word
/// \param value the 64-bit value to be retrieved
/// \param order the ByteOrder of the value to be processed.
/// \return the number of bytes consumed during the call.
/// \details Peek does not consume bytes in the stream. Use the return value
/// of PeekWord64() to detect short reads.
/// \since Crypto++ 8.3
size_t PeekWord64(word64 &value, ByteOrder order=BIG_ENDIAN_ORDER) const;
/// move transferMax bytes of the buffered output to target as input /// move transferMax bytes of the buffered output to target as input
/// \brief Transfer bytes from this object to another BufferedTransformation /// \brief Transfer bytes from this object to another BufferedTransformation
@ -2035,7 +2094,7 @@ public:
/// \param channel the channel on which the transfer should occur /// \param channel the channel on which the transfer should occur
/// \param blocking specifies whether the object should block when processing input /// \param blocking specifies whether the object should block when processing input
/// \return the number of bytes that remain in the transfer block (i.e., bytes not transferred) /// \return the number of bytes that remain in the transfer block (i.e., bytes not transferred)
/// \details TransferTo() removes bytes from this object and moves them to the destination. /// \details TransferTo2() removes bytes from this object and moves them to the destination.
/// Transfer begins at the index position in the current stream, and not from an absolute /// Transfer begins at the index position in the current stream, and not from an absolute
/// position in the stream. /// position in the stream.
/// \details byteCount is an \a IN and \a OUT parameter. When the call is made, /// \details byteCount is an \a IN and \a OUT parameter. When the call is made,
@ -2144,6 +2203,15 @@ public:
/// number of bytes that were not processed. /// number of bytes that were not processed.
size_t ChannelPutWord32(const std::string &channel, word32 value, ByteOrder order=BIG_ENDIAN_ORDER, bool blocking=true); size_t ChannelPutWord32(const std::string &channel, word32 value, ByteOrder order=BIG_ENDIAN_ORDER, bool blocking=true);
/// \brief Input a 64-bit word for processing on a channel.
/// \param channel the channel to process the data.
/// \param value the 64-bit value to be processed.
/// \param order the ByteOrder of the value to be processed.
/// \param blocking specifies whether the object should block when processing input.
/// \return 0 indicates all bytes were processed during the call. Non-0 indicates the
/// number of bytes that were not processed.
size_t ChannelPutWord64(const std::string &channel, word64 value, ByteOrder order=BIG_ENDIAN_ORDER, bool blocking=true);
/// \brief Signal the end of a message /// \brief Signal the end of a message
/// \param channel the channel to process the data. /// \param channel the channel to process the data.
/// \param propagation the number of attached transformations the ChannelMessageEnd() signal should be passed /// \param propagation the number of attached transformations the ChannelMessageEnd() signal should be passed
@ -2272,7 +2340,10 @@ protected:
{return propagation != 0 ? propagation - 1 : 0;} {return propagation != 0 ? propagation - 1 : 0;}
private: private:
byte m_buf[4]; // for ChannelPutWord16 and ChannelPutWord32, to ensure buffer isn't deallocated before non-blocking operation completes // for ChannelPutWord16, ChannelPutWord32 and ChannelPutWord64,
// to ensure the buffer isn't deallocated before non-blocking
// operation completes
byte m_buf[8];
}; };
/// \brief An input discarding BufferedTransformation /// \brief An input discarding BufferedTransformation

View File

@ -373,6 +373,16 @@
<Command>ml64.exe /c /nologo /D_M_X64 /W3 /Cx /Zi /Fo"$(IntDir)rdrand-x64.obj" "%(FullPath)"</Command> <Command>ml64.exe /c /nologo /D_M_X64 /W3 /Cx /Zi /Fo"$(IntDir)rdrand-x64.obj" "%(FullPath)"</Command>
<Outputs>$(IntDir)\rdrand-x64.obj;%(Outputs)</Outputs> <Outputs>$(IntDir)\rdrand-x64.obj;%(Outputs)</Outputs>
</CustomBuild> </CustomBuild>
<CustomBuild Condition="'$(Platform)'=='Win32'" Include="rdseed.asm">
<Message>Building and assembling rdseed.asm</Message>
<Command>ml.exe /c /nologo /D_M_X86 /W3 /Cx /Zi /safeseh /Fo"$(IntDir)rdseed-x86.obj" "%(FullPath)"</Command>
<Outputs>$(IntDir)\rdseed-x86.obj;%(Outputs)</Outputs>
</CustomBuild>
<CustomBuild Condition="'$(Platform)'=='x64'" Include="rdseed.asm">
<Message>Building and assembling rdseed.asm</Message>
<Command>ml64.exe /c /nologo /D_M_X64 /W3 /Cx /Zi /Fo"$(IntDir)rdseed-x64.obj" "%(FullPath)"</Command>
<Outputs>$(IntDir)\rdseed-x64.obj;%(Outputs)</Outputs>
</CustomBuild>
<CustomBuild Condition="'$(Platform)'=='x64' AND ('$(Configuration)'=='Debug' Or '$(Configuration)'=='Release')" Include="x64dll.asm"> <CustomBuild Condition="'$(Platform)'=='x64' AND ('$(Configuration)'=='Debug' Or '$(Configuration)'=='Release')" Include="x64dll.asm">
<Message>Building and assembling x64dll.asm</Message> <Message>Building and assembling x64dll.asm</Message>
<Command>ml64.exe /c /nologo /D_M_X64 /W3 /Zi /Fo"$(IntDir)x64dll.obj" "%(FullPath)"</Command> <Command>ml64.exe /c /nologo /D_M_X64 /W3 /Zi /Fo"$(IntDir)x64dll.obj" "%(FullPath)"</Command>
@ -412,6 +422,16 @@
<ClInclude Include="channels.h" /> <ClInclude Include="channels.h" />
<ClInclude Include="cmac.h" /> <ClInclude Include="cmac.h" />
<ClInclude Include="config.h" /> <ClInclude Include="config.h" />
<ClInclude Include="config_align.h" />
<ClInclude Include="config_asm.h" />
<ClInclude Include="config_cpu.h" />
<ClInclude Include="config_cxx.h" />
<ClInclude Include="config_dll.h" />
<ClInclude Include="config_int.h" />
<ClInclude Include="config_misc.h" />
<ClInclude Include="config_ns.h" />
<ClInclude Include="config_os.h" />
<ClInclude Include="config_ver.h" />
<ClInclude Include="cpu.h" /> <ClInclude Include="cpu.h" />
<ClInclude Include="crc.h" /> <ClInclude Include="crc.h" />
<ClInclude Include="cryptlib.h" /> <ClInclude Include="cryptlib.h" />

View File

@ -615,6 +615,36 @@
<ClInclude Include="config.h"> <ClInclude Include="config.h">
<Filter>Header Files</Filter> <Filter>Header Files</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="config_align.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="config_asm.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="config_cpu.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="config_cxx.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="config_dll.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="config_int.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="config_misc.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="config_ns.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="config_os.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="config_ver.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="cpu.h"> <ClInclude Include="cpu.h">
<Filter>Header Files</Filter> <Filter>Header Files</Filter>
</ClInclude> </ClInclude>
@ -1034,6 +1064,9 @@
<CustomBuild Include="rdrand.asm"> <CustomBuild Include="rdrand.asm">
<Filter>Source Files</Filter> <Filter>Source Files</Filter>
</CustomBuild> </CustomBuild>
<CustomBuild Include="rdseed.asm">
<Filter>Source Files</Filter>
</CustomBuild>
<CustomBuild Include="x64dll.asm"> <CustomBuild Include="x64dll.asm">
<Filter>Source Files</Filter> <Filter>Source Files</Filter>
</CustomBuild> </CustomBuild>

View File

@ -27,8 +27,8 @@ LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
// //
VS_VERSION_INFO VERSIONINFO VS_VERSION_INFO VERSIONINFO
FILEVERSION 8,1,0,0 FILEVERSION 8,3,0,0
PRODUCTVERSION 8,1,0,0 PRODUCTVERSION 8,3,0,0
FILEFLAGSMASK 0x3fL FILEFLAGSMASK 0x3fL
#ifdef _DEBUG #ifdef _DEBUG
FILEFLAGS 0x1L FILEFLAGS 0x1L
@ -46,13 +46,13 @@ BEGIN
VALUE "Comments", "Free crypto library, more information available at www.cryptopp.com" VALUE "Comments", "Free crypto library, more information available at www.cryptopp.com"
VALUE "CompanyName", "Wei Dai" VALUE "CompanyName", "Wei Dai"
VALUE "FileDescription", "Crypto++® Library DLL" VALUE "FileDescription", "Crypto++® Library DLL"
VALUE "FileVersion", "8, 1, 0, 0" VALUE "FileVersion", "8, 3, 0, 0"
VALUE "InternalName", "cryptopp" VALUE "InternalName", "cryptopp"
VALUE "LegalCopyright", "Copyright© 1995-2018 by Wei Dai" VALUE "LegalCopyright", "Copyright© 1995-2019 by Wei Dai"
VALUE "LegalTrademarks", "Crypto++®" VALUE "LegalTrademarks", "Crypto++®"
VALUE "OriginalFilename", "cryptopp.dll" VALUE "OriginalFilename", "cryptopp.dll"
VALUE "ProductName", "Crypto++® Library" VALUE "ProductName", "Crypto++® Library"
VALUE "ProductVersion", "8, 1, 0, 0" VALUE "ProductVersion", "8, 3, 0, 0"
END END
END END
BLOCK "VarFileInfo" BLOCK "VarFileInfo"

11
darn.h
View File

@ -2,11 +2,12 @@
// DARN requires POWER9/ISA 3.0. // DARN requires POWER9/ISA 3.0.
// At the moment only GCC 7.0 (and above) seems to support __builtin_darn() // At the moment only GCC 7.0 (and above) seems to support __builtin_darn()
// and __builtin_darn_32(). Clang 7.0 does not provide them, but it does // and __builtin_darn_32(). However, GCC generates incorrect code. Clang 7.0
// support assembly instructions. XLC is unknown, but there are no hits when // does not provide them, but it does support assembly instructions. XLC is
// searching IBM's site. To cover more platforms we provide GCC inline // unknown, but there are no hits when searching IBM's site. To cover more
// assembly like we do with RDRAND and RDSEED. Platforms that don't support // platforms we provide GCC inline assembly like we do with RDRAND and RDSEED.
// GCC inline assembly or the builtin will fail the compile. Also see // Platforms that don't support GCC inline assembly or the builtin will fail
// to compile. Also see https://gcc.gnu.org/bugzilla/show_bug.cgi?id=91481 and
// https://gcc.gnu.org/onlinedocs/gcc/Basic-PowerPC-Built-in-Functions-Available-on-ISA-3_002e0.html // https://gcc.gnu.org/onlinedocs/gcc/Basic-PowerPC-Built-in-Functions-Available-on-ISA-3_002e0.html
/// \file darn.h /// \file darn.h

View File

@ -8,7 +8,6 @@
#include "factory.h" #include "factory.h"
#include "integer.h" #include "integer.h"
#include "filters.h" #include "filters.h"
#include "hex.h"
#include "randpool.h" #include "randpool.h"
#include "files.h" #include "files.h"
#include "trunhash.h" #include "trunhash.h"
@ -16,6 +15,8 @@
#include "smartptr.h" #include "smartptr.h"
#include "validate.h" #include "validate.h"
#include "stdcpp.h" #include "stdcpp.h"
#include "misc.h"
#include "hex.h"
#include "trap.h" #include "trap.h"
#include <iostream> #include <iostream>
@ -208,7 +209,7 @@ void PutDecodedDatumInto(const TestData &data, const char *name, BufferedTransfo
while (repeat--) while (repeat--)
{ {
q.Put(reinterpret_cast<const byte*>(&s2[0]), s2.size()); q.Put(ConstBytePtr(s2), BytePtrSize(s2));
RandomizedTransfer(q, target, false); RandomizedTransfer(q, target, false);
} }
} }
@ -265,10 +266,11 @@ public:
*reinterpret_cast<int *>(pValue) = atoi(value.c_str()); *reinterpret_cast<int *>(pValue) = atoi(value.c_str());
else if (valueType == typeid(word64)) else if (valueType == typeid(word64))
{ {
std::string x(value); errno = 0; std::string x(value.empty() ? "0" : value);
const char* beg = &x[0]; const char* beg = &x[0];
char* end = &x[0] + value.size(); char* end = &x[0] + value.size();
errno = 0;
*reinterpret_cast<word64*>(pValue) = STRTOUL64(beg, &end, 0); *reinterpret_cast<word64*>(pValue) = STRTOUL64(beg, &end, 0);
if (errno != 0) if (errno != 0)
return false; return false;
@ -279,7 +281,7 @@ public:
{ {
m_temp.clear(); m_temp.clear();
PutDecodedDatumInto(m_data, name, StringSink(m_temp).Ref()); PutDecodedDatumInto(m_data, name, StringSink(m_temp).Ref());
reinterpret_cast<ConstByteArrayParameter *>(pValue)->Assign(reinterpret_cast<const byte *>(&m_temp[0]), m_temp.size(), false); reinterpret_cast<ConstByteArrayParameter *>(pValue)->Assign(ConstBytePtr(m_temp), BytePtrSize(m_temp), false);
} }
else else
throw ValueTypeMismatch(name, typeid(std::string), valueType); throw ValueTypeMismatch(name, typeid(std::string), valueType);
@ -496,8 +498,8 @@ void TestSymmetricCipher(TestData &v, const NameValuePairs &overrideParameters)
} }
else else
{ {
encryptor->SetKey(reinterpret_cast<const byte*>(&key[0]), key.size(), pairs); encryptor->SetKey(ConstBytePtr(key), BytePtrSize(key), pairs);
decryptor->SetKey(reinterpret_cast<const byte*>(&key[0]), key.size(), pairs); decryptor->SetKey(ConstBytePtr(key), BytePtrSize(key), pairs);
} }
word64 seek64 = pairs.GetWord64ValueWithDefault("Seek64", 0); word64 seek64 = pairs.GetWord64ValueWithDefault("Seek64", 0);
@ -547,13 +549,13 @@ void TestSymmetricCipher(TestData &v, const NameValuePairs &overrideParameters)
encrypted.reserve(10000 * plaintext.size()); encrypted.reserve(10000 * plaintext.size());
for (int j=0; j<10000; j++) for (int j=0; j<10000; j++)
{ {
cipher->ProcessString(reinterpret_cast<byte*>(&buf[0]), buf.size()); cipher->ProcessString(BytePtr(buf), BytePtrSize(buf));
encrypted.append(buf.begin(), buf.end()); encrypted.append(buf.begin(), buf.end());
} }
encrypted.erase(0, encrypted.size() - keybuf.size()); encrypted.erase(0, encrypted.size() - keybuf.size());
xorbuf(reinterpret_cast<byte*>(&keybuf[0]), reinterpret_cast<const byte*>(&encrypted[0]), keybuf.size()); xorbuf(BytePtr(keybuf), BytePtr(encrypted), BytePtrSize(keybuf));
cipher->SetKey(reinterpret_cast<const byte*>(&keybuf[0]), keybuf.size()); cipher->SetKey(BytePtr(keybuf), BytePtrSize(keybuf));
} }
encrypted.assign(buf.begin(), buf.end()); encrypted.assign(buf.begin(), buf.end());
@ -641,8 +643,8 @@ void TestAuthenticatedSymmetricCipher(TestData &v, const NameValuePairs &overrid
member_ptr<AuthenticatedSymmetricCipher> encryptor, decryptor; member_ptr<AuthenticatedSymmetricCipher> encryptor, decryptor;
encryptor.reset(ObjectFactoryRegistry<AuthenticatedSymmetricCipher, ENCRYPTION>::Registry().CreateObject(name.c_str())); encryptor.reset(ObjectFactoryRegistry<AuthenticatedSymmetricCipher, ENCRYPTION>::Registry().CreateObject(name.c_str()));
decryptor.reset(ObjectFactoryRegistry<AuthenticatedSymmetricCipher, DECRYPTION>::Registry().CreateObject(name.c_str())); decryptor.reset(ObjectFactoryRegistry<AuthenticatedSymmetricCipher, DECRYPTION>::Registry().CreateObject(name.c_str()));
encryptor->SetKey(reinterpret_cast<const byte*>(&key[0]), key.size(), pairs); encryptor->SetKey(ConstBytePtr(key), BytePtrSize(key), pairs);
decryptor->SetKey(reinterpret_cast<const byte*>(&key[0]), key.size(), pairs); decryptor->SetKey(ConstBytePtr(key), BytePtrSize(key), pairs);
// Code coverage // Code coverage
(void)encryptor->AlgorithmName(); (void)encryptor->AlgorithmName();
@ -736,7 +738,7 @@ void TestDigestOrMAC(TestData &v, bool testDigest)
mac.reset(ObjectFactoryRegistry<MessageAuthenticationCode>::Registry().CreateObject(name.c_str())); mac.reset(ObjectFactoryRegistry<MessageAuthenticationCode>::Registry().CreateObject(name.c_str()));
pHash = mac.get(); pHash = mac.get();
std::string key = GetDecodedDatum(v, "Key"); std::string key = GetDecodedDatum(v, "Key");
mac->SetKey(reinterpret_cast<const byte *>(&key[0]), key.size(), pairs); mac->SetKey(ConstBytePtr(key), BytePtrSize(key), pairs);
// Code coverage // Code coverage
(void)mac->AlgorithmName(); (void)mac->AlgorithmName();
@ -779,8 +781,7 @@ void TestKeyDerivationFunction(TestData &v)
kdf.reset(ObjectFactoryRegistry<KeyDerivationFunction>::Registry().CreateObject(name.c_str())); kdf.reset(ObjectFactoryRegistry<KeyDerivationFunction>::Registry().CreateObject(name.c_str()));
std::string calculated; calculated.resize(expected.size()); std::string calculated; calculated.resize(expected.size());
kdf->DeriveKey(reinterpret_cast<byte*>(&calculated[0]), calculated.size(), kdf->DeriveKey(BytePtr(calculated), BytePtrSize(calculated), BytePtr(secret), BytePtrSize(secret), pairs);
reinterpret_cast<const byte*>(&secret[0]), secret.size(), pairs);
if(calculated != expected) if(calculated != expected)
{ {

View File

@ -37,6 +37,18 @@
// Squash MS LNK4221 and libtool warnings // Squash MS LNK4221 and libtool warnings
extern const char DONNA32_FNAME[] = __FILE__; extern const char DONNA32_FNAME[] = __FILE__;
ANONYMOUS_NAMESPACE_BEGIN
// Can't use GetAlignmentOf<word32>() because of C++11 and constexpr
// Can use 'const unsigned int' because of MSVC 2013
#if (CRYPTOPP_BOOL_X86 || CRYPTOPP_BOOL_X32 || CRYPTOPP_BOOL_X64)
# define ALIGN_SPEC 16
#else
# define ALIGN_SPEC 4
#endif
ANONYMOUS_NAMESPACE_END
#if defined(CRYPTOPP_CURVE25519_32BIT) #if defined(CRYPTOPP_CURVE25519_32BIT)
#include "donna_32.h" #include "donna_32.h"
@ -431,7 +443,7 @@ curve25519_swap_conditional(bignum25519 x, bignum25519 qpx, word32 iswap) {
*/ */
void void
curve25519_pow_two5mtwo0_two250mtwo0(bignum25519 b) { curve25519_pow_two5mtwo0_two250mtwo0(bignum25519 b) {
ALIGN(16) bignum25519 t0,c; ALIGN(ALIGN_SPEC) bignum25519 t0,c;
/* 2^5 - 2^0 */ /* b */ /* 2^5 - 2^0 */ /* b */
/* 2^10 - 2^5 */ curve25519_square_times(t0, b, 5); /* 2^10 - 2^5 */ curve25519_square_times(t0, b, 5);
@ -455,7 +467,7 @@ curve25519_pow_two5mtwo0_two250mtwo0(bignum25519 b) {
*/ */
void void
curve25519_recip(bignum25519 out, const bignum25519 z) { curve25519_recip(bignum25519 out, const bignum25519 z) {
ALIGN(16) bignum25519 a, t0, b; ALIGN(ALIGN_SPEC) bignum25519 a, t0, b;
/* 2 */ curve25519_square(a, z); /* a = 2 */ /* 2 */ curve25519_square(a, z); /* a = 2 */
/* 8 */ curve25519_square_times(t0, a, 2); /* 8 */ curve25519_square_times(t0, a, 2);
@ -913,7 +925,33 @@ curve25519_contract(byte out[32], const bignum25519 in) {
/* out = (flag) ? in : out */ /* out = (flag) ? in : out */
inline void inline void
curve25519_move_conditional_bytes(byte out[96], const byte in[96], word32 flag) { curve25519_move_conditional_bytes(byte out[96], const byte in[96], word32 flag)
{
// TODO: enable this code path once we can test and benchmark it.
// It is about 48 insns shorter, it avoids punning which may be UB,
// and it is guaranteed constant time.
#if defined(__GNUC__) && defined(__i686__) && 0
const word32 iter = 96/sizeof(word32);
word32* outl = reinterpret_cast<word32*>(out);
const word32* inl = reinterpret_cast<const word32*>(in);
word32 idx=0, val;
__asm__ __volatile__ (
".att_syntax ;\n"
"cmpl $0, %[flag] ;\n" // compare, set ZERO flag
"movl %[iter], %%ecx ;\n" // load iteration count
"1: ;\n"
" movl (%[idx],%[out]), %[val] ;\n" // val = out[idx]
" cmovnzl (%[idx],%[in]), %[val] ;\n" // copy in[idx] to val if NZ
" movl %[val], (%[idx],%[out]) ;\n" // out[idx] = val
" leal 4(%[idx]), %[idx] ;\n" // increment index
" loopnz 1b ;\n" // does not affect flags
: [out] "+S" (outl), [in] "+D" (inl),
[idx] "+b" (idx), [val] "=r" (val)
: [flag] "g" (flag), [iter] "I" (iter)
: "ecx", "memory", "cc"
);
#else
const word32 nb = flag - 1, b = ~nb; const word32 nb = flag - 1, b = ~nb;
const word32 *inl = (const word32 *)in; const word32 *inl = (const word32 *)in;
word32 *outl = (word32 *)out; word32 *outl = (word32 *)out;
@ -941,6 +979,7 @@ curve25519_move_conditional_bytes(byte out[96], const byte in[96], word32 flag)
outl[21] = (outl[21] & nb) | (inl[21] & b); outl[21] = (outl[21] & nb) | (inl[21] & b);
outl[22] = (outl[22] & nb) | (inl[22] & b); outl[22] = (outl[22] & nb) | (inl[22] & b);
outl[23] = (outl[23] & nb) | (inl[23] & b); outl[23] = (outl[23] & nb) | (inl[23] & b);
#endif
} }
/* if (iswap) swap(a, b) */ /* if (iswap) swap(a, b) */
@ -967,7 +1006,7 @@ curve25519_swap_conditional(bignum25519 a, bignum25519 b, word32 iswap) {
*/ */
void void
curve25519_pow_two5mtwo0_two250mtwo0(bignum25519 b) { curve25519_pow_two5mtwo0_two250mtwo0(bignum25519 b) {
ALIGN(16) bignum25519 t0,c; ALIGN(ALIGN_SPEC) bignum25519 t0,c;
/* 2^5 - 2^0 */ /* b */ /* 2^5 - 2^0 */ /* b */
/* 2^10 - 2^5 */ curve25519_square_times(t0, b, 5); /* 2^10 - 2^5 */ curve25519_square_times(t0, b, 5);
@ -991,7 +1030,7 @@ curve25519_pow_two5mtwo0_two250mtwo0(bignum25519 b) {
*/ */
void void
curve25519_recip(bignum25519 out, const bignum25519 z) { curve25519_recip(bignum25519 out, const bignum25519 z) {
ALIGN(16) bignum25519 a,t0,b; ALIGN(ALIGN_SPEC) bignum25519 a,t0,b;
/* 2 */ curve25519_square_times(a, z, 1); /* a = 2 */ /* 2 */ curve25519_square_times(a, z, 1); /* a = 2 */
/* 8 */ curve25519_square_times(t0, a, 2); /* 8 */ curve25519_square_times(t0, a, 2);
@ -1009,7 +1048,7 @@ curve25519_recip(bignum25519 out, const bignum25519 z) {
*/ */
void void
curve25519_pow_two252m3(bignum25519 two252m3, const bignum25519 z) { curve25519_pow_two252m3(bignum25519 two252m3, const bignum25519 z) {
ALIGN(16) bignum25519 b,c,t0; ALIGN(ALIGN_SPEC) bignum25519 b,c,t0;
/* 2 */ curve25519_square_times(c, z, 1); /* c = 2 */ /* 2 */ curve25519_square_times(c, z, 1); /* c = 2 */
/* 8 */ curve25519_square_times(t0, c, 2); /* t0 = 8 */ /* 8 */ curve25519_square_times(t0, c, 2); /* t0 = 8 */
@ -1865,7 +1904,7 @@ ed25519_publickey_CXX(byte publicKey[32], const byte secretKey[32])
using namespace CryptoPP::Donna::Ed25519; using namespace CryptoPP::Donna::Ed25519;
bignum256modm a; bignum256modm a;
ALIGN(16) ge25519 A; ALIGN(ALIGN_SPEC) ge25519 A;
hash_512bits extsk; hash_512bits extsk;
/* A = aB */ /* A = aB */
@ -1889,7 +1928,7 @@ ed25519_sign_CXX(std::istream& stream, const byte sk[32], const byte pk[32], byt
using namespace CryptoPP::Donna::Ed25519; using namespace CryptoPP::Donna::Ed25519;
bignum256modm r, S, a; bignum256modm r, S, a;
ALIGN(16) ge25519 R; ALIGN(ALIGN_SPEC) ge25519 R;
hash_512bits extsk, hashr, hram; hash_512bits extsk, hashr, hram;
// Unfortunately we need to read the stream twice. The fisrt time calculates // Unfortunately we need to read the stream twice. The fisrt time calculates
@ -1938,7 +1977,7 @@ ed25519_sign_CXX(const byte *m, size_t mlen, const byte sk[32], const byte pk[32
using namespace CryptoPP::Donna::Ed25519; using namespace CryptoPP::Donna::Ed25519;
bignum256modm r, S, a; bignum256modm r, S, a;
ALIGN(16) ge25519 R; ALIGN(ALIGN_SPEC) ge25519 R;
hash_512bits extsk, hashr, hram; hash_512bits extsk, hashr, hram;
ed25519_extsk(extsk, sk); ed25519_extsk(extsk, sk);
@ -1990,7 +2029,7 @@ ed25519_sign_open_CXX(std::istream& stream, const byte pk[32], const byte RS[64]
using namespace CryptoPP::Donna::Ed25519; using namespace CryptoPP::Donna::Ed25519;
ALIGN(16) ge25519 R, A; ALIGN(ALIGN_SPEC) ge25519 R, A;
hash_512bits hash; hash_512bits hash;
bignum256modm hram, S; bignum256modm hram, S;
byte checkR[32]; byte checkR[32];
@ -2018,7 +2057,7 @@ ed25519_sign_open_CXX(const byte *m, size_t mlen, const byte pk[32], const byte
using namespace CryptoPP::Donna::Ed25519; using namespace CryptoPP::Donna::Ed25519;
ALIGN(16) ge25519 R, A; ALIGN(ALIGN_SPEC) ge25519 R, A;
hash_512bits hash; hash_512bits hash;
bignum256modm hram, S; bignum256modm hram, S;
byte checkR[32]; byte checkR[32];

View File

@ -37,6 +37,18 @@
// Squash MS LNK4221 and libtool warnings // Squash MS LNK4221 and libtool warnings
extern const char DONNA64_FNAME[] = __FILE__; extern const char DONNA64_FNAME[] = __FILE__;
ANONYMOUS_NAMESPACE_BEGIN
// Can't use GetAlignmentOf<word64>() because of C++11 and constexpr
// Can use 'const unsigned int' because of MSVC 2013
#if (CRYPTOPP_BOOL_X86 || CRYPTOPP_BOOL_X32 || CRYPTOPP_BOOL_X64)
# define ALIGN_SPEC 16
#else
# define ALIGN_SPEC 8
#endif
ANONYMOUS_NAMESPACE_END
#if defined(CRYPTOPP_CURVE25519_64BIT) #if defined(CRYPTOPP_CURVE25519_64BIT)
#include "donna_64.h" #include "donna_64.h"
@ -359,7 +371,7 @@ curve25519_swap_conditional(bignum25519 x, bignum25519 qpx, word64 iswap) {
*/ */
void void
curve25519_pow_two5mtwo0_two250mtwo0(bignum25519 b) { curve25519_pow_two5mtwo0_two250mtwo0(bignum25519 b) {
ALIGN(16) bignum25519 t0,c; ALIGN(ALIGN_SPEC) bignum25519 t0,c;
/* 2^5 - 2^0 */ /* b */ /* 2^5 - 2^0 */ /* b */
/* 2^10 - 2^5 */ curve25519_square_times(t0, b, 5); /* 2^10 - 2^5 */ curve25519_square_times(t0, b, 5);
@ -383,7 +395,7 @@ curve25519_pow_two5mtwo0_two250mtwo0(bignum25519 b) {
*/ */
void void
curve25519_recip(bignum25519 out, const bignum25519 z) { curve25519_recip(bignum25519 out, const bignum25519 z) {
ALIGN(16) bignum25519 a, t0, b; ALIGN(ALIGN_SPEC) bignum25519 a, t0, b;
/* 2 */ curve25519_square(a, z); /* a = 2 */ /* 2 */ curve25519_square(a, z); /* a = 2 */
/* 8 */ curve25519_square_times(t0, a, 2); /* 8 */ curve25519_square_times(t0, a, 2);
@ -735,10 +747,36 @@ curve25519_contract(byte *out, const bignum25519 input) {
/* out = (flag) ? in : out */ /* out = (flag) ? in : out */
inline void inline void
curve25519_move_conditional_bytes(byte out[96], const byte in[96], word64 flag) { curve25519_move_conditional_bytes(byte out[96], const byte in[96], word64 flag)
{
// TODO: enable this code path once we can test and benchmark it.
// It is about 24 insns shorter, it avoids punning which may be UB,
// and it is guaranteed constant time.
#if defined(__GNUC__) && defined(__x86_64__) && 0
const word32 iter = 96/sizeof(word64);
word64* outq = reinterpret_cast<word64*>(out);
const word64* inq = reinterpret_cast<const word64*>(in);
word64 idx=0, val;
__asm__ __volatile__ (
".att_syntax ;\n"
"cmpq $0, %[flag] ;\n" // compare, set ZERO flag
"movq %[iter], %%rcx ;\n" // load iteration count
"1: ;\n"
" movq (%[idx],%[out]), %[val] ;\n" // val = out[idx]
" cmovnzq (%[idx],%[in]), %[val] ;\n" // copy in[idx] to val if NZ
" movq %[val], (%[idx],%[out]) ;\n" // out[idx] = val
" leaq 8(%[idx]), %[idx] ;\n" // increment index
" loopnz 1b ;\n" // does not affect flags
: [out] "+S" (outq), [in] "+D" (inq),
[idx] "+b" (idx), [val] "=r" (val)
: [flag] "g" (flag), [iter] "I" (iter)
: "rcx", "memory", "cc"
);
#else
const word64 nb = flag - 1, b = ~nb; const word64 nb = flag - 1, b = ~nb;
const word64 *inq = (const word64 *)in; const word64 *inq = (const word64 *)(const void*)in;
word64 *outq = (word64 *)out; word64 *outq = (word64 *)(void *)out;
outq[0] = (outq[0] & nb) | (inq[0] & b); outq[0] = (outq[0] & nb) | (inq[0] & b);
outq[1] = (outq[1] & nb) | (inq[1] & b); outq[1] = (outq[1] & nb) | (inq[1] & b);
outq[2] = (outq[2] & nb) | (inq[2] & b); outq[2] = (outq[2] & nb) | (inq[2] & b);
@ -751,6 +789,7 @@ curve25519_move_conditional_bytes(byte out[96], const byte in[96], word64 flag)
outq[9] = (outq[9] & nb) | (inq[9] & b); outq[9] = (outq[9] & nb) | (inq[9] & b);
outq[10] = (outq[10] & nb) | (inq[10] & b); outq[10] = (outq[10] & nb) | (inq[10] & b);
outq[11] = (outq[11] & nb) | (inq[11] & b); outq[11] = (outq[11] & nb) | (inq[11] & b);
#endif
} }
/* if (iswap) swap(a, b) */ /* if (iswap) swap(a, b) */
@ -1065,7 +1104,7 @@ contract256_slidingwindow_modm(signed char r[256], const bignum256modm s, int wi
*/ */
void void
curve25519_pow_two5mtwo0_two250mtwo0(bignum25519 b) { curve25519_pow_two5mtwo0_two250mtwo0(bignum25519 b) {
ALIGN(16) bignum25519 t0,c; ALIGN(ALIGN_SPEC) bignum25519 t0,c;
/* 2^5 - 2^0 */ /* b */ /* 2^5 - 2^0 */ /* b */
/* 2^10 - 2^5 */ curve25519_square_times(t0, b, 5); /* 2^10 - 2^5 */ curve25519_square_times(t0, b, 5);
@ -1089,7 +1128,7 @@ curve25519_pow_two5mtwo0_two250mtwo0(bignum25519 b) {
*/ */
void void
curve25519_recip(bignum25519 out, const bignum25519 z) { curve25519_recip(bignum25519 out, const bignum25519 z) {
ALIGN(16) bignum25519 a,t0,b; ALIGN(ALIGN_SPEC) bignum25519 a,t0,b;
/* 2 */ curve25519_square_times(a, z, 1); /* a = 2 */ /* 2 */ curve25519_square_times(a, z, 1); /* a = 2 */
/* 8 */ curve25519_square_times(t0, a, 2); /* 8 */ curve25519_square_times(t0, a, 2);
@ -1107,7 +1146,7 @@ curve25519_recip(bignum25519 out, const bignum25519 z) {
*/ */
void void
curve25519_pow_two252m3(bignum25519 two252m3, const bignum25519 z) { curve25519_pow_two252m3(bignum25519 two252m3, const bignum25519 z) {
ALIGN(16) bignum25519 b,c,t0; ALIGN(ALIGN_SPEC) bignum25519 b,c,t0;
/* 2 */ curve25519_square_times(c, z, 1); /* c = 2 */ /* 2 */ curve25519_square_times(c, z, 1); /* c = 2 */
/* 8 */ curve25519_square_times(t0, c, 2); /* t0 = 8 */ /* 8 */ curve25519_square_times(t0, c, 2); /* t0 = 8 */
@ -1580,7 +1619,7 @@ ed25519_publickey_CXX(byte publicKey[32], const byte secretKey[32])
using namespace CryptoPP::Donna::Ed25519; using namespace CryptoPP::Donna::Ed25519;
bignum256modm a; bignum256modm a;
ALIGN(16) ge25519 A; ALIGN(ALIGN_SPEC) ge25519 A;
hash_512bits extsk; hash_512bits extsk;
/* A = aB */ /* A = aB */
@ -1604,7 +1643,7 @@ ed25519_sign_CXX(std::istream& stream, const byte sk[32], const byte pk[32], byt
using namespace CryptoPP::Donna::Ed25519; using namespace CryptoPP::Donna::Ed25519;
bignum256modm r, S, a; bignum256modm r, S, a;
ALIGN(16) ge25519 R; ALIGN(ALIGN_SPEC) ge25519 R;
hash_512bits extsk, hashr, hram; hash_512bits extsk, hashr, hram;
// Unfortunately we need to read the stream twice. The fisrt time calculates // Unfortunately we need to read the stream twice. The fisrt time calculates
@ -1652,7 +1691,7 @@ ed25519_sign_CXX(const byte *m, size_t mlen, const byte sk[32], const byte pk[32
using namespace CryptoPP::Donna::Ed25519; using namespace CryptoPP::Donna::Ed25519;
bignum256modm r, S, a; bignum256modm r, S, a;
ALIGN(16) ge25519 R; ALIGN(ALIGN_SPEC) ge25519 R;
hash_512bits extsk, hashr, hram; hash_512bits extsk, hashr, hram;
ed25519_extsk(extsk, sk); ed25519_extsk(extsk, sk);
@ -1703,7 +1742,7 @@ ed25519_sign_open_CXX(const byte *m, size_t mlen, const byte pk[32], const byte
using namespace CryptoPP::Donna::Ed25519; using namespace CryptoPP::Donna::Ed25519;
ALIGN(16) ge25519 R, A; ALIGN(ALIGN_SPEC) ge25519 R, A;
hash_512bits hash; hash_512bits hash;
bignum256modm hram, S; bignum256modm hram, S;
byte checkR[32]; byte checkR[32];
@ -1731,7 +1770,7 @@ ed25519_sign_open_CXX(std::istream& stream, const byte pk[32], const byte RS[64]
using namespace CryptoPP::Donna::Ed25519; using namespace CryptoPP::Donna::Ed25519;
ALIGN(16) ge25519 R, A; ALIGN(ALIGN_SPEC) ge25519 R, A;
hash_512bits hash; hash_512bits hash;
bignum256modm hram, S; bignum256modm hram, S;
byte checkR[32]; byte checkR[32];

View File

@ -1059,13 +1059,13 @@ int curve25519_mult_SSE2(byte sharedKey[32], const byte secretKey[32], const byt
packed32bignum25519 qx, qz, pqz, pqx; packed32bignum25519 qx, qz, pqz, pqx;
packed64bignum25519 nq, sq, sqscalar, prime, primex, primez, nqpq; packed64bignum25519 nq, sq, sqscalar, prime, primex, primez, nqpq;
bignum25519mulprecomp preq; bignum25519mulprecomp preq;
size_t i=0, bit=0, lastbit=0; size_t bit=0, lastbit=0;
curve25519_expand(nqpqx, othersKey); curve25519_expand(nqpqx, othersKey);
curve25519_mul_precompute(&preq, nqpqx); curve25519_mul_precompute(&preq, nqpqx);
/* do bits 254..3 */ /* do bits 254..3 */
for (i = 254, lastbit=0; i >= 3; i--) { for (size_t i = 254, lastbit=0; i >= 3; i--) {
bit = (e[i/8] >> (i & 7)) & 1; bit = (e[i/8] >> (i & 7)) & 1;
curve25519_swap_conditional(nqx, nqpqx, (word32)(bit ^ lastbit)); curve25519_swap_conditional(nqx, nqpqx, (word32)(bit ^ lastbit));
curve25519_swap_conditional(nqz, nqpqz, (word32)(bit ^ lastbit)); curve25519_swap_conditional(nqz, nqpqz, (word32)(bit ^ lastbit));
@ -1098,7 +1098,7 @@ int curve25519_mult_SSE2(byte sharedKey[32], const byte secretKey[32], const byt
curve25519_swap_conditional(nqz, nqpqz, (word32)bit); curve25519_swap_conditional(nqz, nqpqz, (word32)bit);
/* do bits 2..0 */ /* do bits 2..0 */
for (i = 0; i < 3; i++) { for (size_t i = 0; i < 3; i++) {
curve25519_compute_nq(nq, nqx, nqz); curve25519_compute_nq(nq, nqx, nqz);
curve25519_square_packed64(sq, nq); /* sq = nq^2 */ curve25519_square_packed64(sq, nq); /* sq = nq^2 */
curve25519_121665_packed64(sqscalar, sq); /* sqscalar = sq * [121666,121665] */ curve25519_121665_packed64(sqscalar, sq); /* sqscalar = sq * [121666,121665] */

6
drbg.h
View File

@ -207,6 +207,9 @@ public:
size_t nonceLength=0, const byte* personalization=NULLPTR, size_t personalizationLength=0) size_t nonceLength=0, const byte* personalization=NULLPTR, size_t personalizationLength=0)
: NIST_DRBG(), m_c(SEEDLENGTH), m_v(SEEDLENGTH), m_reseed(0) : NIST_DRBG(), m_c(SEEDLENGTH), m_v(SEEDLENGTH), m_reseed(0)
{ {
std::memset(m_c, 0x00, m_c.size());
std::memset(m_v, 0x00, m_v.size());
if (entropy != NULLPTR && entropyLength != 0) if (entropy != NULLPTR && entropyLength != 0)
DRBG_Instantiate(entropy, entropyLength, nonce, nonceLength, personalization, personalizationLength); DRBG_Instantiate(entropy, entropyLength, nonce, nonceLength, personalization, personalizationLength);
} }
@ -324,6 +327,9 @@ public:
size_t nonceLength=0, const byte* personalization=NULLPTR, size_t personalizationLength=0) size_t nonceLength=0, const byte* personalization=NULLPTR, size_t personalizationLength=0)
: NIST_DRBG(), m_k(HASH::DIGESTSIZE), m_v(HASH::DIGESTSIZE), m_reseed(0) : NIST_DRBG(), m_k(HASH::DIGESTSIZE), m_v(HASH::DIGESTSIZE), m_reseed(0)
{ {
std::memset(m_k, 0x00, m_k.size());
std::memset(m_v, 0x00, m_v.size());
if (entropy != NULLPTR && entropyLength != 0) if (entropy != NULLPTR && entropyLength != 0)
DRBG_Instantiate(entropy, entropyLength, nonce, nonceLength, personalization, personalizationLength); DRBG_Instantiate(entropy, entropyLength, nonce, nonceLength, personalization, personalizationLength);
} }

View File

@ -16,7 +16,8 @@ ANONYMOUS_NAMESPACE_BEGIN
using CryptoPP::EC2N; using CryptoPP::EC2N;
#if defined(HAVE_GCC_INIT_PRIORITY) #if defined(HAVE_GCC_INIT_PRIORITY)
const EC2N::Point g_identity __attribute__ ((init_priority (CRYPTOPP_INIT_PRIORITY + 50))) = EC2N::Point(); #define INIT_ATTRIBUTE __attribute__ ((init_priority (CRYPTOPP_INIT_PRIORITY + 51)))
const EC2N::Point g_identity INIT_ATTRIBUTE = EC2N::Point();
#elif defined(HAVE_MSC_INIT_PRIORITY) #elif defined(HAVE_MSC_INIT_PRIORITY)
#pragma warning(disable: 4075) #pragma warning(disable: 4075)
#pragma init_seg(".CRT$XCU") #pragma init_seg(".CRT$XCU")
@ -260,7 +261,7 @@ const EC2N::Point& EC2N::Double(const Point &P) const
// ******************************************************** // ********************************************************
/* #if 0
EcPrecomputation<EC2N>& EcPrecomputation<EC2N>::operator=(const EcPrecomputation<EC2N> &rhs) EcPrecomputation<EC2N>& EcPrecomputation<EC2N>::operator=(const EcPrecomputation<EC2N> &rhs)
{ {
m_ec = rhs.m_ec; m_ec = rhs.m_ec;
@ -312,7 +313,7 @@ EC2N::Point EcPrecomputation<EC2N>::CascadeExponentiate(const Integer &exponent,
{ {
return m_ep.CascadeExponentiate(exponent, static_cast<const EcPrecomputation<EC2N> &>(pc2).m_ep, exponent2); return m_ep.CascadeExponentiate(exponent, static_cast<const EcPrecomputation<EC2N> &>(pc2).m_ep, exponent2);
} }
*/ #endif
NAMESPACE_END NAMESPACE_END

1
ec2n.h
View File

@ -3,7 +3,6 @@
/// \file ec2n.h /// \file ec2n.h
/// \brief Classes for Elliptic Curves over binary fields /// \brief Classes for Elliptic Curves over binary fields
#ifndef CRYPTOPP_EC2N_H #ifndef CRYPTOPP_EC2N_H
#define CRYPTOPP_EC2N_H #define CRYPTOPP_EC2N_H

View File

@ -28,6 +28,9 @@
#include "ec2n.h" #include "ec2n.h"
#include "misc.h" #include "misc.h"
#include <iostream>
#include <sstream>
// Squash MS LNK4221 and libtool warnings // Squash MS LNK4221 and libtool warnings
#ifndef CRYPTOPP_MANUALLY_INSTANTIATE_TEMPLATES #ifndef CRYPTOPP_MANUALLY_INSTANTIATE_TEMPLATES
extern const char ECCRYPTO_FNAME[] = __FILE__; extern const char ECCRYPTO_FNAME[] = __FILE__;
@ -683,6 +686,13 @@ OID DL_GroupParameters_EC<EC>::GetAlgorithmID() const
return ASN1::id_ecPublicKey(); return ASN1::id_ecPublicKey();
} }
std::ostream& operator<<(std::ostream& os, const DL_GroupParameters_EC<ECP>::Element& obj)
{
std::ostringstream oss;
oss << "(" << std::hex << obj.x << ", " << std::hex << obj.y << ")";
return os << oss.str();
}
// ****************************************************************** // ******************************************************************
template <class EC> template <class EC>

View File

@ -22,6 +22,8 @@
#include "ecp.h" #include "ecp.h"
#include "ec2n.h" #include "ec2n.h"
#include <iosfwd>
#if CRYPTOPP_MSC_VERSION #if CRYPTOPP_MSC_VERSION
# pragma warning(push) # pragma warning(push)
# pragma warning(disable: 4231 4275) # pragma warning(disable: 4231 4275)
@ -168,6 +170,8 @@ protected:
mutable bool m_compress, m_encodeAsOID; // presentation details mutable bool m_compress, m_encodeAsOID; // presentation details
}; };
inline std::ostream& operator<<(std::ostream& os, const DL_GroupParameters_EC<ECP>::Element& obj);
/// \brief Elliptic Curve Discrete Log (DL) public key /// \brief Elliptic Curve Discrete Log (DL) public key
/// \tparam EC elliptic curve field /// \tparam EC elliptic curve field
template <class EC> template <class EC>

541
ecp.cpp
View File

@ -15,10 +15,12 @@
ANONYMOUS_NAMESPACE_BEGIN ANONYMOUS_NAMESPACE_BEGIN
using CryptoPP::ECP; using CryptoPP::ECP;
using CryptoPP::Integer;
using CryptoPP::ModularArithmetic; using CryptoPP::ModularArithmetic;
#if defined(HAVE_GCC_INIT_PRIORITY) #if defined(HAVE_GCC_INIT_PRIORITY)
const ECP::Point g_identity __attribute__ ((init_priority (CRYPTOPP_INIT_PRIORITY + 51))) = ECP::Point(); #define INIT_ATTRIBUTE __attribute__ ((init_priority (CRYPTOPP_INIT_PRIORITY + 50)))
const ECP::Point g_identity INIT_ATTRIBUTE = ECP::Point();
#elif defined(HAVE_MSC_INIT_PRIORITY) #elif defined(HAVE_MSC_INIT_PRIORITY)
#pragma warning(disable: 4075) #pragma warning(disable: 4075)
#pragma init_seg(".CRT$XCU") #pragma init_seg(".CRT$XCU")
@ -39,6 +41,503 @@ inline ECP::Point FromMontgomery(const ModularArithmetic &mr, const ECP::Point &
return P.identity ? P : ECP::Point(mr.ConvertOut(P.x), mr.ConvertOut(P.y)); return P.identity ? P : ECP::Point(mr.ConvertOut(P.x), mr.ConvertOut(P.y));
} }
inline Integer IdentityToInteger(bool val)
{
return val ? Integer::One() : Integer::Zero();
}
struct ProjectivePoint
{
ProjectivePoint() {}
ProjectivePoint(const Integer &x, const Integer &y, const Integer &z)
: x(x), y(y), z(z) {}
Integer x, y, z;
};
/// \brief Addition and Double functions
/// \sa <A HREF="https://eprint.iacr.org/2015/1060.pdf">Complete
/// addition formulas for prime order elliptic curves</A>
struct AdditionFunction
{
explicit AdditionFunction(const ECP::Field& field,
const ECP::FieldElement &a, const ECP::FieldElement &b, ECP::Point &r);
// Double(P)
ECP::Point operator()(const ECP::Point& P) const;
// Add(P, Q)
ECP::Point operator()(const ECP::Point& P, const ECP::Point& Q) const;
protected:
/// \brief Parameters and representation for Addition
/// \details Addition and Doubling will use different algorithms,
/// depending on the <tt>A</tt> coefficient and the representation
/// (Affine or Montgomery with precomputation).
enum Alpha {
/// \brief Coefficient A is 0
A_0 = 1,
/// \brief Coefficient A is -3
A_3 = 2,
/// \brief Coefficient A is arbitrary
A_Star = 4,
/// \brief Representation is Montgomery
A_Montgomery = 8
};
const ECP::Field& field;
const ECP::FieldElement &a, &b;
ECP::Point &R;
Alpha m_alpha;
};
#define X p.x
#define Y p.y
#define Z p.z
#define X1 p.x
#define Y1 p.y
#define Z1 p.z
#define X2 q.x
#define Y2 q.y
#define Z2 q.z
#define X3 r.x
#define Y3 r.y
#define Z3 r.z
AdditionFunction::AdditionFunction(const ECP::Field& field,
const ECP::FieldElement &a, const ECP::FieldElement &b, ECP::Point &r)
: field(field), a(a), b(b), R(r), m_alpha(static_cast<Alpha>(0))
{
if (field.IsMontgomeryRepresentation())
{
m_alpha = A_Montgomery;
}
else
{
if (a == 0)
{
m_alpha = A_0;
}
else if (a == -3 || (a - field.GetModulus()) == -3)
{
m_alpha = A_3;
}
else
{
m_alpha = A_Star;
}
}
}
ECP::Point AdditionFunction::operator()(const ECP::Point& P) const
{
if (m_alpha == A_3)
{
// Gyrations attempt to maintain constant-timeness
// We need either (P.x, P.y, 1) or (0, 1, 0).
const Integer x = P.x * IdentityToInteger(!P.identity);
const Integer y = P.y * IdentityToInteger(!P.identity) + 1 * IdentityToInteger(P.identity);
const Integer z = 1 * IdentityToInteger(!P.identity);
ProjectivePoint p(x, y, z), r;
ECP::FieldElement t0 = field.Square(X);
ECP::FieldElement t1 = field.Square(Y);
ECP::FieldElement t2 = field.Square(Z);
ECP::FieldElement t3 = field.Multiply(X, Y);
t3 = field.Add(t3, t3);
Z3 = field.Multiply(X, Z);
Z3 = field.Add(Z3, Z3);
Y3 = field.Multiply(b, t2);
Y3 = field.Subtract(Y3, Z3);
X3 = field.Add(Y3, Y3);
Y3 = field.Add(X3, Y3);
X3 = field.Subtract(t1, Y3);
Y3 = field.Add(t1, Y3);
Y3 = field.Multiply(X3, Y3);
X3 = field.Multiply(X3, t3);
t3 = field.Add(t2, t2);
t2 = field.Add(t2, t3);
Z3 = field.Multiply(b, Z3);
Z3 = field.Subtract(Z3, t2);
Z3 = field.Subtract(Z3, t0);
t3 = field.Add(Z3, Z3);
Z3 = field.Add(Z3, t3);
t3 = field.Add(t0, t0);
t0 = field.Add(t3, t0);
t0 = field.Subtract(t0, t2);
t0 = field.Multiply(t0, Z3);
Y3 = field.Add(Y3, t0);
t0 = field.Multiply(Y, Z);
t0 = field.Add(t0, t0);
Z3 = field.Multiply(t0, Z3);
X3 = field.Subtract(X3, Z3);
Z3 = field.Multiply(t0, t1);
Z3 = field.Add(Z3, Z3);
Z3 = field.Add(Z3, Z3);
const ECP::FieldElement inv = field.MultiplicativeInverse(Z3.IsZero() ? Integer::One() : Z3);
X3 = field.Multiply(X3, inv); Y3 = field.Multiply(Y3, inv);
// More gyrations
R.x = X3*Z3.NotZero();
R.y = Y3*Z3.NotZero();
R.identity = Z3.IsZero();
return R;
}
else if (m_alpha == A_0)
{
// Gyrations attempt to maintain constant-timeness
// We need either (P.x, P.y, 1) or (0, 1, 0).
const Integer x = P.x * IdentityToInteger(!P.identity);
const Integer y = P.y * IdentityToInteger(!P.identity) + 1 * IdentityToInteger(P.identity);
const Integer z = 1 * IdentityToInteger(!P.identity);
ProjectivePoint p(x, y, z), r;
const ECP::FieldElement b3 = field.Multiply(b, 3);
ECP::FieldElement t0 = field.Square(Y);
Z3 = field.Add(t0, t0);
Z3 = field.Add(Z3, Z3);
Z3 = field.Add(Z3, Z3);
ECP::FieldElement t1 = field.Add(Y, Z);
ECP::FieldElement t2 = field.Square(Z);
t2 = field.Multiply(b3, t2);
X3 = field.Multiply(t2, Z3);
Y3 = field.Add(t0, t2);
Z3 = field.Multiply(t1, Z3);
t1 = field.Add(t2, t2);
t2 = field.Add(t1, t2);
t0 = field.Subtract(t0, t2);
Y3 = field.Multiply(t0, Y3);
Y3 = field.Add(X3, Y3);
t1 = field.Multiply(X, Y);
X3 = field.Multiply(t0, t1);
X3 = field.Add(X3, X3);
const ECP::FieldElement inv = field.MultiplicativeInverse(Z3.IsZero() ? Integer::One() : Z3);
X3 = field.Multiply(X3, inv); Y3 = field.Multiply(Y3, inv);
// More gyrations
R.x = X3*Z3.NotZero();
R.y = Y3*Z3.NotZero();
R.identity = Z3.IsZero();
return R;
}
#if 0
// Code path disabled at the moment due to https://github.com/weidai11/cryptopp/issues/878
else if (m_alpha == A_Star)
{
// Gyrations attempt to maintain constant-timeness
// We need either (P.x, P.y, 1) or (0, 1, 0).
const Integer x = P.x * IdentityToInteger(!P.identity);
const Integer y = P.y * IdentityToInteger(!P.identity) + 1 * IdentityToInteger(P.identity);
const Integer z = 1 * IdentityToInteger(!P.identity);
ProjectivePoint p(x, y, z), r;
const ECP::FieldElement b3 = field.Multiply(b, 3);
ECP::FieldElement t0 = field.Square(Y);
Z3 = field.Add(t0, t0);
Z3 = field.Add(Z3, Z3);
Z3 = field.Add(Z3, Z3);
ECP::FieldElement t1 = field.Add(Y, Z);
ECP::FieldElement t2 = field.Square(Z);
t2 = field.Multiply(b3, t2);
X3 = field.Multiply(t2, Z3);
Y3 = field.Add(t0, t2);
Z3 = field.Multiply(t1, Z3);
t1 = field.Add(t2, t2);
t2 = field.Add(t1, t2);
t0 = field.Subtract(t0, t2);
Y3 = field.Multiply(t0, Y3);
Y3 = field.Add(X3, Y3);
t1 = field.Multiply(X, Y);
X3 = field.Multiply(t0, t1);
X3 = field.Add(X3, X3);
const ECP::FieldElement inv = field.MultiplicativeInverse(Z3.IsZero() ? Integer::One() : Z3);
X3 = field.Multiply(X3, inv); Y3 = field.Multiply(Y3, inv);
// More gyrations
R.x = X3*Z3.NotZero();
R.y = Y3*Z3.NotZero();
R.identity = Z3.IsZero();
return R;
}
#endif
else // A_Montgomery
{
// More gyrations
bool identity = !!(P.identity + (P.y == field.Identity()));
ECP::FieldElement t = field.Square(P.x);
t = field.Add(field.Add(field.Double(t), t), a);
t = field.Divide(t, field.Double(P.y));
ECP::FieldElement x = field.Subtract(field.Subtract(field.Square(t), P.x), P.x);
R.y = field.Subtract(field.Multiply(t, field.Subtract(P.x, x)), P.y);
R.x.swap(x);
// More gyrations
R.x *= IdentityToInteger(!identity);
R.y *= IdentityToInteger(!identity);
R.identity = identity;
return R;
}
}
ECP::Point AdditionFunction::operator()(const ECP::Point& P, const ECP::Point& Q) const
{
if (m_alpha == A_3)
{
// Gyrations attempt to maintain constant-timeness
// We need either (P.x, P.y, 1) or (0, 1, 0).
const Integer x1 = P.x * IdentityToInteger(!P.identity);
const Integer y1 = P.y * IdentityToInteger(!P.identity) + 1 * IdentityToInteger(P.identity);
const Integer z1 = 1 * IdentityToInteger(!P.identity);
const Integer x2 = Q.x * IdentityToInteger(!Q.identity);
const Integer y2 = Q.y * IdentityToInteger(!Q.identity) + 1 * IdentityToInteger(Q.identity);
const Integer z2 = 1 * IdentityToInteger(!Q.identity);
ProjectivePoint p(x1, y1, z1), q(x2, y2, z2), r;
ECP::FieldElement t0 = field.Multiply(X1, X2);
ECP::FieldElement t1 = field.Multiply(Y1, Y2);
ECP::FieldElement t2 = field.Multiply(Z1, Z2);
ECP::FieldElement t3 = field.Add(X1, Y1);
ECP::FieldElement t4 = field.Add(X2, Y2);
t3 = field.Multiply(t3, t4);
t4 = field.Add(t0, t1);
t3 = field.Subtract(t3, t4);
t4 = field.Add(Y1, Z1);
X3 = field.Add(Y2, Z2);
t4 = field.Multiply(t4, X3);
X3 = field.Add(t1, t2);
t4 = field.Subtract(t4, X3);
X3 = field.Add(X1, Z1);
Y3 = field.Add(X2, Z2);
X3 = field.Multiply(X3, Y3);
Y3 = field.Add(t0, t2);
Y3 = field.Subtract(X3, Y3);
Z3 = field.Multiply(b, t2);
X3 = field.Subtract(Y3, Z3);
Z3 = field.Add(X3, X3);
X3 = field.Add(X3, Z3);
Z3 = field.Subtract(t1, X3);
X3 = field.Add(t1, X3);
Y3 = field.Multiply(b, Y3);
t1 = field.Add(t2, t2);
t2 = field.Add(t1, t2);
Y3 = field.Subtract(Y3, t2);
Y3 = field.Subtract(Y3, t0);
t1 = field.Add(Y3, Y3);
Y3 = field.Add(t1, Y3);
t1 = field.Add(t0, t0);
t0 = field.Add(t1, t0);
t0 = field.Subtract(t0, t2);
t1 = field.Multiply(t4, Y3);
t2 = field.Multiply(t0, Y3);
Y3 = field.Multiply(X3, Z3);
Y3 = field.Add(Y3, t2);
X3 = field.Multiply(t3, X3);
X3 = field.Subtract(X3, t1);
Z3 = field.Multiply(t4, Z3);
t1 = field.Multiply(t3, t0);
Z3 = field.Add(Z3, t1);
const ECP::FieldElement inv = field.MultiplicativeInverse(Z3.IsZero() ? Integer::One() : Z3);
X3 = field.Multiply(X3, inv); Y3 = field.Multiply(Y3, inv);
// More gyrations
R.x = X3*Z3.NotZero();
R.y = Y3*Z3.NotZero();
R.identity = Z3.IsZero();
return R;
}
else if (m_alpha == A_0)
{
// Gyrations attempt to maintain constant-timeness
// We need either (P.x, P.y, 1) or (0, 1, 0).
const Integer x1 = P.x * IdentityToInteger(!P.identity);
const Integer y1 = P.y * IdentityToInteger(!P.identity) + 1 * IdentityToInteger(P.identity);
const Integer z1 = 1 * IdentityToInteger(!P.identity);
const Integer x2 = Q.x * IdentityToInteger(!Q.identity);
const Integer y2 = Q.y * IdentityToInteger(!Q.identity) + 1 * IdentityToInteger(Q.identity);
const Integer z2 = 1 * IdentityToInteger(!Q.identity);
ProjectivePoint p(x1, y1, z1), q(x2, y2, z2), r;
const ECP::FieldElement b3 = field.Multiply(b, 3);
ECP::FieldElement t0 = field.Square(Y);
Z3 = field.Add(t0, t0);
Z3 = field.Add(Z3, Z3);
Z3 = field.Add(Z3, Z3);
ECP::FieldElement t1 = field.Add(Y, Z);
ECP::FieldElement t2 = field.Square(Z);
t2 = field.Multiply(b3, t2);
X3 = field.Multiply(t2, Z3);
Y3 = field.Add(t0, t2);
Z3 = field.Multiply(t1, Z3);
t1 = field.Add(t2, t2);
t2 = field.Add(t1, t2);
t0 = field.Subtract(t0, t2);
Y3 = field.Multiply(t0, Y3);
Y3 = field.Add(X3, Y3);
t1 = field.Multiply(X, Y);
X3 = field.Multiply(t0, t1);
X3 = field.Add(X3, X3);
const ECP::FieldElement inv = field.MultiplicativeInverse(Z3.IsZero() ? Integer::One() : Z3);
X3 = field.Multiply(X3, inv); Y3 = field.Multiply(Y3, inv);
// More gyrations
R.x = X3*Z3.NotZero();
R.y = Y3*Z3.NotZero();
R.identity = Z3.IsZero();
return R;
}
#if 0
// Code path disabled at the moment due to https://github.com/weidai11/cryptopp/issues/878
else if (m_alpha == A_Star)
{
// Gyrations attempt to maintain constant-timeness
// We need either (P.x, P.y, 1) or (0, 1, 0).
const Integer x1 = P.x * IdentityToInteger(!P.identity);
const Integer y1 = P.y * IdentityToInteger(!P.identity) + 1 * IdentityToInteger(P.identity);
const Integer z1 = 1 * IdentityToInteger(!P.identity);
const Integer x2 = Q.x * IdentityToInteger(!Q.identity);
const Integer y2 = Q.y * IdentityToInteger(!Q.identity) + 1 * IdentityToInteger(Q.identity);
const Integer z2 = 1 * IdentityToInteger(!Q.identity);
ProjectivePoint p(x1, y1, z1), q(x2, y2, z2), r;
const ECP::FieldElement b3 = field.Multiply(b, 3);
ECP::FieldElement t0 = field.Multiply(X1, X2);
ECP::FieldElement t1 = field.Multiply(Y1, Y2);
ECP::FieldElement t2 = field.Multiply(Z1, Z2);
ECP::FieldElement t3 = field.Add(X1, Y1);
ECP::FieldElement t4 = field.Add(X2, Y2);
t3 = field.Multiply(t3, t4);
t4 = field.Add(t0, t1);
t3 = field.Subtract(t3, t4);
t4 = field.Add(X1, Z1);
ECP::FieldElement t5 = field.Add(X2, Z2);
t4 = field.Multiply(t4, t5);
t5 = field.Add(t0, t2);
t4 = field.Subtract(t4, t5);
t5 = field.Add(Y1, Z1);
X3 = field.Add(Y2, Z2);
t5 = field.Multiply(t5, X3);
X3 = field.Add(t1, t2);
t5 = field.Subtract(t5, X3);
Z3 = field.Multiply(a, t4);
X3 = field.Multiply(b3, t2);
Z3 = field.Add(X3, Z3);
X3 = field.Subtract(t1, Z3);
Z3 = field.Add(t1, Z3);
Y3 = field.Multiply(X3, Z3);
t1 = field.Add(t0, t0);
t1 = field.Add(t1, t0);
t2 = field.Multiply(a, t2);
t4 = field.Multiply(b3, t4);
t1 = field.Add(t1, t2);
t2 = field.Subtract(t0, t2);
t2 = field.Multiply(a, t2);
t4 = field.Add(t4, t2);
t0 = field.Multiply(t1, t4);
Y3 = field.Add(Y3, t0);
t0 = field.Multiply(t5, t4);
X3 = field.Multiply(t3, X3);
X3 = field.Subtract(X3, t0);
t0 = field.Multiply(t3, t1);
Z3 = field.Multiply(t5, Z3);
Z3 = field.Add(Z3, t0);
const ECP::FieldElement inv = field.MultiplicativeInverse(Z3.IsZero() ? Integer::One() : Z3);
X3 = field.Multiply(X3, inv); Y3 = field.Multiply(Y3, inv);
// More gyrations
R.x = X3*Z3.NotZero();
R.y = Y3*Z3.NotZero();
R.identity = Z3.IsZero();
return R;
}
#endif
else // A_Montgomery
{
// More gyrations
bool return_Q = P.identity;
bool return_P = Q.identity;
bool double_P = field.Equal(P.x, Q.x) && field.Equal(P.y, Q.y);
bool identity = field.Equal(P.x, Q.x) && !field.Equal(P.y, Q.y);
// This code taken from Double(P) for below
identity = !!((double_P * (P.identity + (P.y == field.Identity()))) + identity);
ECP::Point S = R;
if (double_P)
{
// This code taken from Double(P)
ECP::FieldElement t = field.Square(P.x);
t = field.Add(field.Add(field.Double(t), t), a);
t = field.Divide(t, field.Double(P.y));
ECP::FieldElement x = field.Subtract(field.Subtract(field.Square(t), P.x), P.x);
R.y = field.Subtract(field.Multiply(t, field.Subtract(P.x, x)), P.y);
R.x.swap(x);
}
else
{
// Original Add(P,Q) code
ECP::FieldElement t = field.Subtract(Q.y, P.y);
t = field.Divide(t, field.Subtract(Q.x, P.x));
ECP::FieldElement x = field.Subtract(field.Subtract(field.Square(t), P.x), Q.x);
R.y = field.Subtract(field.Multiply(t, field.Subtract(P.x, x)), P.y);
R.x.swap(x);
}
// More gyrations
R.x = R.x * IdentityToInteger(!identity);
R.y = R.y * IdentityToInteger(!identity);
R.identity = identity;
if (return_Q)
return (R = S), Q;
else if (return_P)
return (R = S), P;
else
return (S = R), R;
}
}
#undef X
#undef Y
#undef Z
#undef X1
#undef Y1
#undef Z1
#undef X2
#undef Y2
#undef Z2
#undef X3
#undef Y3
#undef Z3
ANONYMOUS_NAMESPACE_END ANONYMOUS_NAMESPACE_END
NAMESPACE_BEGIN(CryptoPP) NAMESPACE_BEGIN(CryptoPP)
@ -243,34 +742,14 @@ const ECP::Point& ECP::Inverse(const Point &P) const
const ECP::Point& ECP::Add(const Point &P, const Point &Q) const const ECP::Point& ECP::Add(const Point &P, const Point &Q) const
{ {
if (P.identity) return Q; AdditionFunction add(GetField(), m_a, m_b, m_R);
if (Q.identity) return P; return (m_R = add(P, Q));
if (GetField().Equal(P.x, Q.x))
return GetField().Equal(P.y, Q.y) ? Double(P) : Identity();
FieldElement t = GetField().Subtract(Q.y, P.y);
t = GetField().Divide(t, GetField().Subtract(Q.x, P.x));
FieldElement x = GetField().Subtract(GetField().Subtract(GetField().Square(t), P.x), Q.x);
m_R.y = GetField().Subtract(GetField().Multiply(t, GetField().Subtract(P.x, x)), P.y);
m_R.x.swap(x);
m_R.identity = false;
return m_R;
} }
const ECP::Point& ECP::Double(const Point &P) const const ECP::Point& ECP::Double(const Point &P) const
{ {
if (P.identity || P.y==GetField().Identity()) return Identity(); AdditionFunction add(GetField(), m_a, m_b, m_R);
return (m_R = add(P));
FieldElement t = GetField().Square(P.x);
t = GetField().Add(GetField().Add(GetField().Double(t), t), m_a);
t = GetField().Divide(t, GetField().Double(P.y));
FieldElement x = GetField().Subtract(GetField().Subtract(GetField().Square(t), P.x), P.x);
m_R.y = GetField().Subtract(GetField().Multiply(t, GetField().Subtract(P.x, x)), P.y);
m_R.x.swap(x);
m_R.identity = false;
return m_R;
} }
template <class T, class Iterator> void ParallelInvert(const AbstractRing<T> &ring, Iterator begin, Iterator end) template <class T, class Iterator> void ParallelInvert(const AbstractRing<T> &ring, Iterator begin, Iterator end)
@ -310,20 +789,11 @@ template <class T, class Iterator> void ParallelInvert(const AbstractRing<T> &ri
} }
} }
struct ProjectivePoint
{
ProjectivePoint() {}
ProjectivePoint(const Integer &x, const Integer &y, const Integer &z)
: x(x), y(y), z(z) {}
Integer x,y,z;
};
class ProjectiveDoubling class ProjectiveDoubling
{ {
public: public:
ProjectiveDoubling(const ModularArithmetic &m_mr, const Integer &m_a, const Integer &m_b, const ECPPoint &Q) ProjectiveDoubling(const ModularArithmetic &m_mr, const Integer &m_a, const Integer &m_b, const ECPPoint &Q)
: mr(m_mr), firstDoubling(true), negated(false) : mr(m_mr)
{ {
CRYPTOPP_UNUSED(m_b); CRYPTOPP_UNUSED(m_b);
if (Q.identity) if (Q.identity)
@ -360,7 +830,6 @@ public:
const ModularArithmetic &mr; const ModularArithmetic &mr;
ProjectivePoint P; ProjectivePoint P;
bool firstDoubling, negated;
Integer sixteenY4, aZ4, twoY, fourY2, S, M; Integer sixteenY4, aZ4, twoY, fourY2, S, M;
}; };

22
ecp.h
View File

@ -35,11 +35,15 @@ public:
/// \brief Construct an ECP /// \brief Construct an ECP
ECP() {} ECP() {}
/// \brief Copy construct an ECP /// \brief Construct an ECP
/// \param ecp the other ECP object /// \param ecp the other ECP object
/// \param convertToMontgomeryRepresentation flag indicating if the curve should be converted to a MontgomeryRepresentation /// \param convertToMontgomeryRepresentation flag indicating if the curve
/// should be converted to a MontgomeryRepresentation.
/// \details Prior to Crypto++ 8.3 the default value for
/// convertToMontgomeryRepresentation was false. it was changed due to
/// two audit tools finding, "Signature-compatible with a copy constructor".
/// \sa ModularArithmetic, MontgomeryRepresentation /// \sa ModularArithmetic, MontgomeryRepresentation
ECP(const ECP &ecp, bool convertToMontgomeryRepresentation = false); ECP(const ECP &ecp, bool convertToMontgomeryRepresentation);
/// \brief Construct an ECP /// \brief Construct an ECP
/// \param modulus the prime modulus /// \param modulus the prime modulus
@ -50,14 +54,22 @@ public:
/// \brief Construct an ECP from BER encoded parameters /// \brief Construct an ECP from BER encoded parameters
/// \param bt BufferedTransformation derived object /// \param bt BufferedTransformation derived object
/// \details This constructor will decode and extract the the fields fieldID and curve of the sequence ECParameters /// \details This constructor will decode and extract the the fields
/// fieldID and curve of the sequence ECParameters
ECP(BufferedTransformation &bt); ECP(BufferedTransformation &bt);
/// \brief Encode the fields fieldID and curve of the sequence ECParameters /// \brief DER Encode
/// \param bt BufferedTransformation derived object /// \param bt BufferedTransformation derived object
/// \details DEREncode encode the fields fieldID and curve of the sequence
/// ECParameters
void DEREncode(BufferedTransformation &bt) const; void DEREncode(BufferedTransformation &bt) const;
/// \brief Compare two points
/// \param P the first point
/// \param Q the second point
/// \returns true if equal, false otherwise
bool Equal(const Point &P, const Point &Q) const; bool Equal(const Point &P, const Point &Q) const;
const Point& Identity() const; const Point& Identity() const;
const Point& Inverse(const Point &P) const; const Point& Inverse(const Point &P) const;
bool InversionIsFast() const {return true;} bool InversionIsFast() const {return true;}

179
elgamal.h
View File

@ -11,14 +11,17 @@
#include "integer.h" #include "integer.h"
#include "gfpcrypt.h" #include "gfpcrypt.h"
#include "pubkey.h" #include "pubkey.h"
#include "dsa.h"
#include "misc.h" #include "misc.h"
#include "oids.h"
#include "dsa.h"
#include "asn.h"
NAMESPACE_BEGIN(CryptoPP) NAMESPACE_BEGIN(CryptoPP)
/// \brief ElGamal key agreement and encryption schemes base class /// \brief ElGamal key agreement and encryption schemes base class
/// \since Crypto++ 1.0 /// \since Crypto++ 1.0
class CRYPTOPP_NO_VTABLE ElGamalBase : public DL_KeyAgreementAlgorithm_DH<Integer, NoCofactorMultiplication>, class CRYPTOPP_NO_VTABLE ElGamalBase :
public DL_KeyAgreementAlgorithm_DH<Integer, NoCofactorMultiplication>,
public DL_KeyDerivationAlgorithm<Integer>, public DL_KeyDerivationAlgorithm<Integer>,
public DL_SymmetricEncryptionAlgorithm public DL_SymmetricEncryptionAlgorithm
{ {
@ -27,7 +30,8 @@ public:
void Derive(const DL_GroupParameters<Integer> &groupParams, byte *derivedKey, size_t derivedLength, const Integer &agreedElement, const Integer &ephemeralPublicKey, const NameValuePairs &derivationParams) const void Derive(const DL_GroupParameters<Integer> &groupParams, byte *derivedKey, size_t derivedLength, const Integer &agreedElement, const Integer &ephemeralPublicKey, const NameValuePairs &derivationParams) const
{ {
CRYPTOPP_UNUSED(groupParams), CRYPTOPP_UNUSED(ephemeralPublicKey), CRYPTOPP_UNUSED(derivationParams); CRYPTOPP_UNUSED(groupParams); CRYPTOPP_UNUSED(ephemeralPublicKey);
CRYPTOPP_UNUSED(derivationParams);
agreedElement.Encode(derivedKey, derivedLength); agreedElement.Encode(derivedKey, derivedLength);
} }
@ -49,6 +53,8 @@ public:
size_t GetMaxSymmetricPlaintextLength(size_t cipherTextLength) const size_t GetMaxSymmetricPlaintextLength(size_t cipherTextLength) const
{ {
unsigned int len = GetGroupParameters().GetModulus().ByteCount(); unsigned int len = GetGroupParameters().GetModulus().ByteCount();
CRYPTOPP_ASSERT(len >= 3);
if (cipherTextLength == len) if (cipherTextLength == len)
return STDMIN(255U, len-3); return STDMIN(255U, len-3);
else else
@ -93,9 +99,14 @@ public:
}; };
/// \brief ElGamal key agreement and encryption schemes default implementation /// \brief ElGamal key agreement and encryption schemes default implementation
/// \tparam BASE Base class implementation
/// \tparam SCHEME_OPTIONS Scheme options
/// \tparam Key ElGamal key classes
/// \since Crypto++ 1.0 /// \since Crypto++ 1.0
template <class BASE, class SCHEME_OPTIONS, class KEY> template <class BASE, class SCHEME_OPTIONS, class KEY>
class ElGamalObjectImpl : public DL_ObjectImplBase<BASE, SCHEME_OPTIONS, KEY>, public ElGamalBase class ElGamalObjectImpl :
public DL_ObjectImplBase<BASE, SCHEME_OPTIONS, KEY>,
public ElGamalBase
{ {
public: public:
virtual ~ElGamalObjectImpl() {} virtual ~ElGamalObjectImpl() {}
@ -114,30 +125,174 @@ protected:
const DL_SymmetricEncryptionAlgorithm & GetSymmetricEncryptionAlgorithm() const {return *this;} const DL_SymmetricEncryptionAlgorithm & GetSymmetricEncryptionAlgorithm() const {return *this;}
}; };
/// \brief ElGamal Public Key adapter
/// \tparam BASE PublicKey derived class
/// \details DL_PublicKey_ElGamal provides an override for GetAlgorithmID()
/// to utilize 1.3.14.7.2.1.1. Prior to DL_PublicKey_ElGamal, the ElGamal
/// keys [mistakenly] used the OID from DSA due to DL_GroupParmaters_GFP().
/// If you need to <tt>Load</tt> an ElGamal key with the wrong OID then
/// see <A HREF="https://www.cryptopp.com/wiki/ElGamal">ElGamal</A> on
/// the Crypto++ wiki.
/// \sa <A HREF="https://github.com/weidai11/cryptopp/issues/876">Issue 876</A>,
/// <A HREF="https://github.com/weidai11/cryptopp/issues/567">Issue 567</A>
/// \since Crypto++ 8.3
template <class BASE>
struct DL_PublicKey_ElGamal : public BASE
{
virtual ~DL_PublicKey_ElGamal() {}
/// \brief Retrieves the OID of the algorithm
/// \returns OID of the algorithm
/// \details DL_PrivateKey_ElGamal provides an override for GetAlgorithmID()
/// to utilize 1.3.14.7.2.1.1. Prior to DL_PrivateKey_ElGamal, the ElGamal
/// keys [mistakenly] used the OID from DSA due to DL_GroupParmaters_GFP().
/// If you need to <tt>Load</tt> an ElGamal key with the wrong OID then
/// see <A HREF="https://www.cryptopp.com/wiki/ElGamal">ElGamal</A> on
/// the Crypto++ wiki.
/// \sa <A HREF="https://github.com/weidai11/cryptopp/issues/876">Issue 876</A>,
/// <A HREF="https://github.com/weidai11/cryptopp/issues/567">Issue 567</A>
virtual OID GetAlgorithmID() const {
return ASN1::elGamal();
}
};
/// \brief ElGamal Private Key adapter
/// \tparam BASE PrivateKey derived class
/// \details DL_PrivateKey_ElGamal provides an override for GetAlgorithmID()
/// to utilize 1.3.14.7.2.1.1. Prior to DL_PrivateKey_ElGamal, the ElGamal
/// keys [mistakenly] used the OID from DSA due to DL_GroupParmaters_GFP().
/// If you need to <tt>Load</tt> an ElGamal key with the wrong OID then
/// see <A HREF="https://www.cryptopp.com/wiki/ElGamal">ElGamal</A> on
/// the Crypto++ wiki.
/// \sa <A HREF="https://github.com/weidai11/cryptopp/issues/876">Issue 876</A>,
/// <A HREF="https://github.com/weidai11/cryptopp/issues/567">Issue 567</A>
/// \since Crypto++ 8.3
template <class BASE>
struct DL_PrivateKey_ElGamal : public BASE
{
virtual ~DL_PrivateKey_ElGamal() {}
/// \brief Retrieves the OID of the algorithm
/// \returns OID of the algorithm
/// \details DL_PrivateKey_ElGamal provides an override for GetAlgorithmID()
/// to utilize 1.3.14.7.2.1.1. Prior to DL_PrivateKey_ElGamal, the ElGamal
/// keys [mistakenly] used the OID from DSA due to DL_GroupParmaters_GFP().
/// If you need to <tt>Load</tt> an ElGamal key with the wrong OID then
/// see <A HREF="https://www.cryptopp.com/wiki/ElGamal">ElGamal</A> on
/// the Crypto++ wiki.
/// \sa <A HREF="https://github.com/weidai11/cryptopp/issues/876">Issue 876</A>,
/// <A HREF="https://github.com/weidai11/cryptopp/issues/567">Issue 567</A>
virtual OID GetAlgorithmID() const {
return ASN1::elGamal();
}
/// \brief Check the key for errors
/// \param rng RandomNumberGenerator for objects which use randomized testing
/// \param level level of thoroughness
/// \return true if the tests succeed, false otherwise
/// \details There are four levels of thoroughness:
/// <ul>
/// <li>0 - using this object won't cause a crash or exception
/// <li>1 - this object will probably function, and encrypt, sign, other
/// operations correctly
/// <li>2 - ensure this object will function correctly, and perform
/// reasonable security checks
/// <li>3 - perform reasonable security checks, and do checks that may
/// take a long time
/// </ul>
/// \details Level 0 does not require a RandomNumberGenerator. A NullRNG() can
/// be used for level 0. Level 1 may not check for weak keys and such.
/// Levels 2 and 3 are recommended.
bool Validate(RandomNumberGenerator &rng, unsigned int level) const
{
// Validate() formerly used DL_PrivateKey_GFP implementation through
// inheritance. However, it would reject keys from other libraries
// like BouncyCastle. The failure was x < q. According to ElGamal's
// paper and the HAC, the private key is selected in over [1,p-1],
// Later Tsiounis and Yung showed the lower limit as [1,q-1] in
// "On the Security of EIGamal Based Encryption". As such, Crypto++
// will generate a key in the range [1,q-1], but accept a key
// in [1,p-1]. Thanks to JPM for finding the reference. Also see
// https://github.com/weidai11/cryptopp/commit/a5a684d92986.
CRYPTOPP_ASSERT(this->GetAbstractGroupParameters().Validate(rng, level));
bool pass = this->GetAbstractGroupParameters().Validate(rng, level);
const Integer &p = this->GetGroupParameters().GetModulus();
const Integer &q = this->GetAbstractGroupParameters().GetSubgroupOrder();
const Integer &x = this->GetPrivateExponent();
// Changed to x < p-1 based on ElGamal's paper and the HAC.
CRYPTOPP_ASSERT(x.IsPositive());
CRYPTOPP_ASSERT(x < p-1);
pass = pass && x.IsPositive() && x < p-1;
if (level >= 1)
{
// Minimum security level due to Tsiounis and Yung.
CRYPTOPP_ASSERT(Integer::Gcd(x, q) == Integer::One());
pass = pass && Integer::Gcd(x, q) == Integer::One();
}
return pass;
}
};
/// \brief ElGamal key agreement and encryption schemes keys /// \brief ElGamal key agreement and encryption schemes keys
/// \details The ElGamalKeys class used DL_PrivateKey_GFP_OldFormat and DL_PublicKey_GFP_OldFormat /// \details ElGamalKeys provide the algorithm implementation ElGamal key
/// for the PrivateKey and PublicKey typedef from about Crypto++ 1.0 through Crypto++ 5.6.5. /// agreement and encryption schemes.
/// At Crypto++ 6.0 the serialization format was cutover to standard PKCS8 and X509 encodings. /// \details The ElGamalKeys class used <tt>DL_PrivateKey_GFP_OldFormat</tt>
/// \sa <A HREF="https://github.com/weidai11/cryptopp/commit/a5a684d92986e8e2">Commit a5a684d92986e8e2</A> /// and <tt>DL_PublicKey_GFP_OldFormat</tt> for the <tt>PrivateKey</tt> and
/// <tt>PublicKey</tt> from about Crypto++ 1.0 through Crypto++ 5.6.5. At
/// Crypto++ 6.0 the serialization format was cutover to standard PKCS8 and
/// X509 encodings.
/// \details The ElGamalKeys class [mistakenly] used the OID for DSA from
/// about Crypto++ 1.0 through Crypto++ 8.2. At Crypto++ 8.3 the OID was
/// fixed and now uses ElGamal encryption, which is 1.3.14.7.2.1.1.
/// If you need to <tt>Load</tt> an ElGamal key with the wrong OID then
/// see <A HREF="https://www.cryptopp.com/wiki/ElGamal">ElGamal</A> on
/// the Crypto++ wiki.
/// \sa <A HREF="https://github.com/weidai11/cryptopp/issues/876">Issue 876</A>,
/// <A HREF="https://github.com/weidai11/cryptopp/issues/567">Issue 567</A>
/// \since Crypto++ 1.0
struct ElGamalKeys struct ElGamalKeys
{ {
/// \brief Implements DL_GroupParameters interface
typedef DL_CryptoKeys_GFP::GroupParameters GroupParameters; typedef DL_CryptoKeys_GFP::GroupParameters GroupParameters;
typedef DL_CryptoKeys_GFP::PrivateKey PrivateKey; /// \brief Implements DL_PrivateKey interface
typedef DL_CryptoKeys_GFP::PublicKey PublicKey; typedef DL_PrivateKey_ElGamal<DL_CryptoKeys_GFP::PrivateKey> PrivateKey;
/// \brief Implements DL_PublicKey interface
typedef DL_PublicKey_ElGamal<DL_CryptoKeys_GFP::PublicKey> PublicKey;
}; };
/// \brief ElGamal encryption scheme with non-standard padding /// \brief ElGamal encryption scheme with non-standard padding
/// \details ElGamal provide the algorithm implementation ElGamal key
/// agreement and encryption schemes.
/// \details The ElGamal class [mistakenly] used the OID for DSA from about
/// Crypto++ 1.0 through Crypto++ 8.2. At Crypto++ 8.3 the OID was fixed
/// and now uses ElGamal encryption, which is 1.3.14.7.2.1.1.
/// If you need to <tt>Load</tt> an ElGamal key with the wrong OID then
/// see <A HREF="https://www.cryptopp.com/wiki/ElGamal">ElGamal</A> on
/// the Crypto++ wiki.
/// \sa <A HREF="https://github.com/weidai11/cryptopp/issues/876">Issue 876</A>,
/// <A HREF="https://github.com/weidai11/cryptopp/issues/567">Issue 567</A>
/// \since Crypto++ 1.0 /// \since Crypto++ 1.0
struct ElGamal struct ElGamal
{ {
typedef DL_CryptoSchemeOptions<ElGamal, ElGamalKeys, int, int, int> SchemeOptions; typedef DL_CryptoSchemeOptions<ElGamal, ElGamalKeys, int, int, int> SchemeOptions;
typedef SchemeOptions::PrivateKey PrivateKey;
typedef SchemeOptions::PublicKey PublicKey;
/// \brief The algorithm name
/// \returns the algorithm name
/// \details StaticAlgorithmName returns the algorithm's name as a static
/// member function.
CRYPTOPP_STATIC_CONSTEXPR const char* StaticAlgorithmName() {return "ElgamalEnc/Crypto++Padding";} CRYPTOPP_STATIC_CONSTEXPR const char* StaticAlgorithmName() {return "ElgamalEnc/Crypto++Padding";}
/// \brief Implements DL_GroupParameters interface
typedef SchemeOptions::GroupParameters GroupParameters; typedef SchemeOptions::GroupParameters GroupParameters;
/// implements PK_Encryptor interface /// \brief Implements PK_Encryptor interface
typedef PK_FinalTemplate<ElGamalObjectImpl<DL_EncryptorBase<Integer>, SchemeOptions, SchemeOptions::PublicKey> > Encryptor; typedef PK_FinalTemplate<ElGamalObjectImpl<DL_EncryptorBase<Integer>, SchemeOptions, SchemeOptions::PublicKey> > Encryptor;
/// implements PK_Decryptor interface /// \brief Implements PK_Encryptor interface
typedef PK_FinalTemplate<ElGamalObjectImpl<DL_DecryptorBase<Integer>, SchemeOptions, SchemeOptions::PrivateKey> > Decryptor; typedef PK_FinalTemplate<ElGamalObjectImpl<DL_DecryptorBase<Integer>, SchemeOptions, SchemeOptions::PrivateKey> > Decryptor;
}; };

215
fhmqv.h
View File

@ -30,30 +30,85 @@ public:
virtual ~FHMQV_Domain() {} virtual ~FHMQV_Domain() {}
FHMQV_Domain(bool clientRole = true): m_role(clientRole ? RoleClient : RoleServer) {} /// \brief Construct a FHMQV domain
/// \param clientRole flag indicating initiator or recipient
/// \details <tt>clientRole = true</tt> indicates initiator, and
/// <tt>clientRole = false</tt> indicates recipient or server.
FHMQV_Domain(bool clientRole = true)
: m_role(clientRole ? RoleClient : RoleServer) {}
/// \brief Construct a FHMQV domain
/// \param params group parameters and options
/// \param clientRole flag indicating initiator or recipient
/// \details <tt>clientRole = true</tt> indicates initiator, and
/// <tt>clientRole = false</tt> indicates recipient or server.
FHMQV_Domain(const GroupParameters &params, bool clientRole = true) FHMQV_Domain(const GroupParameters &params, bool clientRole = true)
: m_role(clientRole ? RoleClient : RoleServer), m_groupParameters(params) {} : m_role(clientRole ? RoleClient : RoleServer), m_groupParameters(params) {}
/// \brief Construct a FHMQV domain
/// \param bt BufferedTransformation with group parameters and options
/// \param clientRole flag indicating initiator or recipient
/// \details <tt>clientRole = true</tt> indicates initiator, and
/// <tt>clientRole = false</tt> indicates recipient or server.
FHMQV_Domain(BufferedTransformation &bt, bool clientRole = true) FHMQV_Domain(BufferedTransformation &bt, bool clientRole = true)
: m_role(clientRole ? RoleClient : RoleServer) : m_role(clientRole ? RoleClient : RoleServer)
{m_groupParameters.BERDecode(bt);} {m_groupParameters.BERDecode(bt);}
/// \brief Construct a FHMQV domain
/// \tparam T1 template parameter used as a constructor parameter
/// \param v1 first parameter
/// \param clientRole flag indicating initiator or recipient
/// \details v1 is passed directly to the GROUP_PARAMETERS object.
/// \details <tt>clientRole = true</tt> indicates initiator, and
/// <tt>clientRole = false</tt> indicates recipient or server.
template <class T1> template <class T1>
FHMQV_Domain(T1 v1, bool clientRole = true) FHMQV_Domain(T1 v1, bool clientRole = true)
: m_role(clientRole ? RoleClient : RoleServer) : m_role(clientRole ? RoleClient : RoleServer)
{m_groupParameters.Initialize(v1);} {m_groupParameters.Initialize(v1);}
/// \brief Construct a FHMQV domain
/// \tparam T1 template parameter used as a constructor parameter
/// \tparam T2 template parameter used as a constructor parameter
/// \param v1 first parameter
/// \param v2 second parameter
/// \param clientRole flag indicating initiator or recipient
/// \details v1 and v2 are passed directly to the GROUP_PARAMETERS object.
/// \details <tt>clientRole = true</tt> indicates initiator, and
/// <tt>clientRole = false</tt> indicates recipient or server.
template <class T1, class T2> template <class T1, class T2>
FHMQV_Domain(T1 v1, T2 v2, bool clientRole = true) FHMQV_Domain(T1 v1, T2 v2, bool clientRole = true)
: m_role(clientRole ? RoleClient : RoleServer) : m_role(clientRole ? RoleClient : RoleServer)
{m_groupParameters.Initialize(v1, v2);} {m_groupParameters.Initialize(v1, v2);}
/// \brief Construct a FHMQV domain
/// \tparam T1 template parameter used as a constructor parameter
/// \tparam T2 template parameter used as a constructor parameter
/// \tparam T3 template parameter used as a constructor parameter
/// \param v1 first parameter
/// \param v2 second parameter
/// \param v3 third parameter
/// \param clientRole flag indicating initiator or recipient
/// \details v1, v2 and v3 are passed directly to the GROUP_PARAMETERS object.
/// \details <tt>clientRole = true</tt> indicates initiator, and
/// <tt>clientRole = false</tt> indicates recipient or server.
template <class T1, class T2, class T3> template <class T1, class T2, class T3>
FHMQV_Domain(T1 v1, T2 v2, T3 v3, bool clientRole = true) FHMQV_Domain(T1 v1, T2 v2, T3 v3, bool clientRole = true)
: m_role(clientRole ? RoleClient : RoleServer) : m_role(clientRole ? RoleClient : RoleServer)
{m_groupParameters.Initialize(v1, v2, v3);} {m_groupParameters.Initialize(v1, v2, v3);}
/// \brief Construct a FHMQV domain
/// \tparam T1 template parameter used as a constructor parameter
/// \tparam T2 template parameter used as a constructor parameter
/// \tparam T3 template parameter used as a constructor parameter
/// \tparam T4 template parameter used as a constructor parameter
/// \param v1 first parameter
/// \param v2 second parameter
/// \param v3 third parameter
/// \param v4 third parameter
/// \param clientRole flag indicating initiator or recipient
/// \details v1, v2, v3 and v4 are passed directly to the GROUP_PARAMETERS object.
/// \details <tt>clientRole = true</tt> indicates initiator, and
/// <tt>clientRole = false</tt> indicates recipient or server.
template <class T1, class T2, class T3, class T4> template <class T1, class T2, class T3, class T4>
FHMQV_Domain(T1 v1, T2 v2, T3 v3, T4 v4, bool clientRole = true) FHMQV_Domain(T1 v1, T2 v2, T3 v3, T4 v4, bool clientRole = true)
: m_role(clientRole ? RoleClient : RoleServer) : m_role(clientRole ? RoleClient : RoleServer)
@ -61,28 +116,62 @@ public:
public: public:
/// \brief Retrieves the group parameters for this domain
/// \return the group parameters for this domain as a const reference
const GroupParameters & GetGroupParameters() const {return m_groupParameters;} const GroupParameters & GetGroupParameters() const {return m_groupParameters;}
/// \brief Retrieves the group parameters for this domain
/// \return the group parameters for this domain as a non-const reference
GroupParameters & AccessGroupParameters() {return m_groupParameters;} GroupParameters & AccessGroupParameters() {return m_groupParameters;}
/// \brief Retrieves the crypto parameters for this domain
/// \return the crypto parameters for this domain as a non-const reference
CryptoParameters & AccessCryptoParameters() {return AccessAbstractGroupParameters();} CryptoParameters & AccessCryptoParameters() {return AccessAbstractGroupParameters();}
/// return length of agreed value produced /// \brief Provides the size of the agreed value
unsigned int AgreedValueLength() const {return GetAbstractGroupParameters().GetEncodedElementSize(false);} /// \return size of agreed value produced in this domain
/// return length of static private keys in this domain /// \details The length is calculated using <tt>GetEncodedElementSize(false)</tt>,
unsigned int StaticPrivateKeyLength() const {return GetAbstractGroupParameters().GetSubgroupOrder().ByteCount();} /// which means the element is encoded in a non-reversible format. A
/// return length of static public keys in this domain /// non-reversible format means its a raw byte array, and it lacks presentation
unsigned int StaticPublicKeyLength() const{return GetAbstractGroupParameters().GetEncodedElementSize(true);} /// format like an ASN.1 BIT_STRING or OCTET_STRING.
unsigned int AgreedValueLength() const
{return GetAbstractGroupParameters().GetEncodedElementSize(false);}
/// generate static private key /// \brief Provides the size of the static private key
/*! \pre size of privateKey == PrivateStaticKeyLength() */ /// \return size of static private keys in this domain
/// \details The length is calculated using the byte count of the subgroup order.
unsigned int StaticPrivateKeyLength() const
{return GetAbstractGroupParameters().GetSubgroupOrder().ByteCount();}
/// \brief Provides the size of the static public key
/// \return size of static public keys in this domain
/// \details The length is calculated using <tt>GetEncodedElementSize(true)</tt>,
/// which means the element is encoded in a reversible format. A reversible
/// format means it has a presentation format, and its an ANS.1 encoded element
/// or point.
unsigned int StaticPublicKeyLength() const
{return GetAbstractGroupParameters().GetEncodedElementSize(true);}
/// \brief Generate static private key in this domain
/// \param rng a RandomNumberGenerator derived class
/// \param privateKey a byte buffer for the generated private key in this domain
/// \details The private key is a random scalar used as an exponent in the range
/// <tt>[1,MaxExponent()]</tt>.
/// \pre <tt>COUNTOF(privateKey) == PrivateStaticKeyLength()</tt>
void GenerateStaticPrivateKey(RandomNumberGenerator &rng, byte *privateKey) const void GenerateStaticPrivateKey(RandomNumberGenerator &rng, byte *privateKey) const
{ {
Integer x(rng, Integer::One(), GetAbstractGroupParameters().GetMaxExponent()); Integer x(rng, Integer::One(), GetAbstractGroupParameters().GetMaxExponent());
x.Encode(privateKey, StaticPrivateKeyLength()); x.Encode(privateKey, StaticPrivateKeyLength());
} }
/// generate static public key /// \brief Generate a static public key from a private key in this domain
/*! \pre size of publicKey == PublicStaticKeyLength() */ /// \param rng a RandomNumberGenerator derived class
/// \param privateKey a byte buffer with the previously generated private key
/// \param publicKey a byte buffer for the generated public key in this domain
/// \details The public key is an element or point on the curve, and its stored
/// in a revrsible format. A reversible format means it has a presentation
/// format, and its an ANS.1 encoded element or point.
/// \pre <tt>COUNTOF(publicKey) == PublicStaticKeyLength()</tt>
void GenerateStaticPublicKey(RandomNumberGenerator &rng, const byte *privateKey, byte *publicKey) const void GenerateStaticPublicKey(RandomNumberGenerator &rng, const byte *privateKey, byte *publicKey) const
{ {
CRYPTOPP_UNUSED(rng); CRYPTOPP_UNUSED(rng);
@ -92,10 +181,22 @@ public:
params.EncodeElement(true, y, publicKey); params.EncodeElement(true, y, publicKey);
} }
/// \brief Provides the size of the ephemeral private key
/// \return size of ephemeral private keys in this domain
/// \details An ephemeral private key is a private key and public key.
/// The serialized size is different than a static private key.
unsigned int EphemeralPrivateKeyLength() const {return StaticPrivateKeyLength() + StaticPublicKeyLength();} unsigned int EphemeralPrivateKeyLength() const {return StaticPrivateKeyLength() + StaticPublicKeyLength();}
/// \brief Provides the size of the ephemeral public key
/// \return size of ephemeral public keys in this domain
/// \details An ephemeral public key is a public key.
/// The serialized size is the same as a static public key.
unsigned int EphemeralPublicKeyLength() const{return StaticPublicKeyLength();} unsigned int EphemeralPublicKeyLength() const{return StaticPublicKeyLength();}
/// return length of ephemeral private keys in this domain /// \brief Generate ephemeral private key in this domain
/// \param rng a RandomNumberGenerator derived class
/// \param privateKey a byte buffer for the generated private key in this domain
/// \pre <tt>COUNTOF(privateKey) == EphemeralPrivateKeyLength()</tt>
void GenerateEphemeralPrivateKey(RandomNumberGenerator &rng, byte *privateKey) const void GenerateEphemeralPrivateKey(RandomNumberGenerator &rng, byte *privateKey) const
{ {
const DL_GroupParameters<Element> &params = GetAbstractGroupParameters(); const DL_GroupParameters<Element> &params = GetAbstractGroupParameters();
@ -105,28 +206,46 @@ public:
params.EncodeElement(true, y, privateKey+StaticPrivateKeyLength()); params.EncodeElement(true, y, privateKey+StaticPrivateKeyLength());
} }
/// return length of ephemeral public keys in this domain /// \brief Generate ephemeral public key from a private key in this domain
/// \param rng a RandomNumberGenerator derived class
/// \param privateKey a byte buffer with the previously generated private key
/// \param publicKey a byte buffer for the generated public key in this domain
/// \pre <tt>COUNTOF(publicKey) == EphemeralPublicKeyLength()</tt>
void GenerateEphemeralPublicKey(RandomNumberGenerator &rng, const byte *privateKey, byte *publicKey) const void GenerateEphemeralPublicKey(RandomNumberGenerator &rng, const byte *privateKey, byte *publicKey) const
{ {
CRYPTOPP_UNUSED(rng); CRYPTOPP_UNUSED(rng);
memcpy(publicKey, privateKey+StaticPrivateKeyLength(), EphemeralPublicKeyLength()); memcpy(publicKey, privateKey+StaticPrivateKeyLength(), EphemeralPublicKeyLength());
} }
/// derive agreed value from your private keys and couterparty's public keys, return false in case of failure /// \brief Derive agreed value or shared secret
/*! \note The ephemeral public key will always be validated. /// \param agreedValue the shared secret
If you have previously validated the static public key, use validateStaticOtherPublicKey=false to save time. /// \param staticPrivateKey your long term private key
\pre size of agreedValue == AgreedValueLength() /// \param ephemeralPrivateKey your ephemeral private key
\pre length of staticPrivateKey == StaticPrivateKeyLength() /// \param staticOtherPublicKey couterparty's long term public key
\pre length of ephemeralPrivateKey == EphemeralPrivateKeyLength() /// \param ephemeralOtherPublicKey couterparty's ephemeral public key
\pre length of staticOtherPublicKey == StaticPublicKeyLength() /// \param validateStaticOtherPublicKey flag indicating validation
\pre length of ephemeralOtherPublicKey == EphemeralPublicKeyLength() /// \return true upon success, false in case of failure
*/ /// \details Agree() performs the authenticated key agreement. Agree()
/// derives a shared secret from your private keys and couterparty's
/// public keys. Each instance or run of the protocol should use a new
/// ephemeral key pair.
/// \details The other's ephemeral public key will always be validated at
/// Level 1 to ensure it is a point on the curve.
/// <tt>validateStaticOtherPublicKey</tt> determines how thoroughly other's
/// static public key is validated. If you have previously validated the
/// couterparty's static public key, then use
/// <tt>validateStaticOtherPublicKey=false</tt> to save time.
/// \pre <tt>COUNTOF(agreedValue) == AgreedValueLength()
/// \pre <tt>COUNTOF(staticPrivateKey) == StaticPrivateKeyLength()</tt>
/// \pre <tt>COUNTOF(ephemeralPrivateKey) == EphemeralPrivateKeyLength()</tt>
/// \pre <tt>COUNTOF(staticOtherPublicKey) == StaticPublicKeyLength()</tt>
/// \pre <tt>COUNTOF(ephemeralOtherPublicKey) == EphemeralPublicKeyLength()</tt>
bool Agree(byte *agreedValue, bool Agree(byte *agreedValue,
const byte *staticPrivateKey, const byte *ephemeralPrivateKey, const byte *staticPrivateKey, const byte *ephemeralPrivateKey,
const byte *staticOtherPublicKey, const byte *ephemeralOtherPublicKey, const byte *staticOtherPublicKey, const byte *ephemeralOtherPublicKey,
bool validateStaticOtherPublicKey=true) const bool validateStaticOtherPublicKey=true) const
{ {
byte *XX = NULLPTR, *YY = NULLPTR, *AA = NULLPTR, *BB = NULLPTR; const byte *XX = NULLPTR, *YY = NULLPTR, *AA = NULLPTR, *BB = NULLPTR;
size_t xxs = 0, yys = 0, aas = 0, bbs = 0; size_t xxs = 0, yys = 0, aas = 0, bbs = 0;
// Depending on the role, this will hold either A's or B's static // Depending on the role, this will hold either A's or B's static
@ -144,60 +263,43 @@ public:
Element B = params.ExponentiateBase(b); Element B = params.ExponentiateBase(b);
params.EncodeElement(true, B, tt); params.EncodeElement(true, B, tt);
XX = const_cast<byte*>(ephemeralOtherPublicKey); XX = ephemeralOtherPublicKey;
xxs = EphemeralPublicKeyLength(); xxs = EphemeralPublicKeyLength();
YY = const_cast<byte*>(ephemeralPrivateKey) + StaticPrivateKeyLength(); YY = ephemeralPrivateKey + StaticPrivateKeyLength();
yys = EphemeralPublicKeyLength(); yys = EphemeralPublicKeyLength();
AA = const_cast<byte*>(staticOtherPublicKey); AA = staticOtherPublicKey;
aas = StaticPublicKeyLength(); aas = StaticPublicKeyLength();
BB = tt.BytePtr(); BB = tt.BytePtr();
bbs = tt.SizeInBytes(); bbs = tt.SizeInBytes();
} }
else if(m_role == RoleClient) else
{ {
Integer a(staticPrivateKey, StaticPrivateKeyLength()); Integer a(staticPrivateKey, StaticPrivateKeyLength());
Element A = params.ExponentiateBase(a); Element A = params.ExponentiateBase(a);
params.EncodeElement(true, A, tt); params.EncodeElement(true, A, tt);
XX = const_cast<byte*>(ephemeralPrivateKey) + StaticPrivateKeyLength(); XX = ephemeralPrivateKey + StaticPrivateKeyLength();
xxs = EphemeralPublicKeyLength(); xxs = EphemeralPublicKeyLength();
YY = const_cast<byte*>(ephemeralOtherPublicKey); YY = ephemeralOtherPublicKey;
yys = EphemeralPublicKeyLength(); yys = EphemeralPublicKeyLength();
AA = tt.BytePtr(); AA = tt.BytePtr();
aas = tt.SizeInBytes(); aas = tt.SizeInBytes();
BB = const_cast<byte*>(staticOtherPublicKey); BB = staticOtherPublicKey;
bbs = StaticPublicKeyLength(); bbs = StaticPublicKeyLength();
} }
else
{
CRYPTOPP_ASSERT(0);
return false;
}
// DecodeElement calls ValidateElement at level 1. Level 1 only calls Element VV1 = params.DecodeElement(staticOtherPublicKey, validateStaticOtherPublicKey);
// VerifyPoint to ensure the element is in G*. If the other's PublicKey is Element VV2 = params.DecodeElement(ephemeralOtherPublicKey, true);
// requested to be validated, we manually call ValidateElement at level 3.
Element VV1 = params.DecodeElement(staticOtherPublicKey, false);
if(!params.ValidateElement(validateStaticOtherPublicKey ? 3 : 1, VV1, NULLPTR))
return false;
// DecodeElement calls ValidateElement at level 1. Level 1 only calls
// VerifyPoint to ensure the element is in G*. Crank it up.
Element VV2 = params.DecodeElement(ephemeralOtherPublicKey, false);
if(!params.ValidateElement(3, VV2, NULLPTR))
return false;
const Integer& q = params.GetSubgroupOrder(); const Integer& q = params.GetSubgroupOrder();
const unsigned int len /*bytes*/ = (((q.BitCount()+1)/2 +7)/8); const unsigned int len /*bytes*/ = (((q.BitCount()+1)/2 +7)/8);
Integer d, e;
SecByteBlock dd(len), ee(len); SecByteBlock dd(len), ee(len);
Hash(NULLPTR, XX, xxs, YY, yys, AA, aas, BB, bbs, dd.BytePtr(), dd.SizeInBytes()); Hash(NULLPTR, XX, xxs, YY, yys, AA, aas, BB, bbs, dd.BytePtr(), dd.SizeInBytes());
d.Decode(dd.BytePtr(), dd.SizeInBytes()); Integer d(dd.BytePtr(), dd.SizeInBytes());
Hash(NULLPTR, YY, yys, XX, xxs, AA, aas, BB, bbs, ee.BytePtr(), ee.SizeInBytes()); Hash(NULLPTR, YY, yys, XX, xxs, AA, aas, BB, bbs, ee.BytePtr(), ee.SizeInBytes());
e.Decode(ee.BytePtr(), ee.SizeInBytes()); Integer e(ee.BytePtr(), ee.SizeInBytes());
Element sigma; Element sigma;
if(m_role == RoleServer) if(m_role == RoleServer)
@ -233,6 +335,7 @@ public:
} }
catch (DL_BadElement &) catch (DL_BadElement &)
{ {
CRYPTOPP_ASSERT(0);
return false; return false;
} }
return true; return true;
@ -251,9 +354,11 @@ protected:
if(sigma) if(sigma)
{ {
Integer x = GetAbstractGroupParameters().ConvertElementToInteger(*sigma); //Integer x = GetAbstractGroupParameters().ConvertElementToInteger(*sigma);
SecByteBlock sbb(x.MinEncodedSize()); //SecByteBlock sbb(x.MinEncodedSize());
x.Encode(sbb.BytePtr(), sbb.SizeInBytes()); //x.Encode(sbb.BytePtr(), sbb.SizeInBytes());
SecByteBlock sbb(GetAbstractGroupParameters().GetEncodedElementSize(false));
GetAbstractGroupParameters().EncodeElement(false, *sigma, sbb);
hash.Update(sbb.BytePtr(), sbb.SizeInBytes()); hash.Update(sbb.BytePtr(), sbb.SizeInBytes());
} }
@ -294,7 +399,7 @@ private:
/// \details This implementation follows Augustin P. Sarr and Philippe ElbazVincent, and JeanClaude Bajard's /// \details This implementation follows Augustin P. Sarr and Philippe ElbazVincent, and JeanClaude Bajard's
/// <a href="http://eprint.iacr.org/2009/408">A Secure and Efficient Authenticated Diffie-Hellman Protocol</a>. /// <a href="http://eprint.iacr.org/2009/408">A Secure and Efficient Authenticated Diffie-Hellman Protocol</a>.
/// Note: this is FHMQV, Protocol 5, from page 11; and not FHMQV-C. /// Note: this is FHMQV, Protocol 5, from page 11; and not FHMQV-C.
/// \sa FHMQV, MQV_Domain, HMQV_Domain, AuthenticatedKeyAgreementDomain /// \sa FHMQV, MQV_Domain, FHMQV_Domain, AuthenticatedKeyAgreementDomain
/// \since Crypto++ 5.6.4 /// \since Crypto++ 5.6.4
typedef FHMQV_Domain<DL_GroupParameters_GFP_DefaultSafePrime> FHMQV; typedef FHMQV_Domain<DL_GroupParameters_GFP_DefaultSafePrime> FHMQV;

View File

@ -595,7 +595,9 @@ StreamTransformationFilter::StreamTransformationFilter(StreamTransformation &c,
m_isSpecial = m_cipher.IsLastBlockSpecial() && m_mandatoryBlockSize > 1; m_isSpecial = m_cipher.IsLastBlockSpecial() && m_mandatoryBlockSize > 1;
m_reservedBufferSize = STDMAX(2*m_mandatoryBlockSize, m_optimalBufferSize); m_reservedBufferSize = STDMAX(2*m_mandatoryBlockSize, m_optimalBufferSize);
IsolatedInitialize(MakeParameters(Name::BlockPaddingScheme(), padding)); FilterWithBufferedInput::IsolatedInitialize(
MakeParameters
(Name::BlockPaddingScheme(), padding));
} }
StreamTransformationFilter::StreamTransformationFilter(StreamTransformation &c, BufferedTransformation *attachment, BlockPaddingScheme padding, bool authenticated) StreamTransformationFilter::StreamTransformationFilter(StreamTransformation &c, BufferedTransformation *attachment, BlockPaddingScheme padding, bool authenticated)
@ -616,7 +618,9 @@ StreamTransformationFilter::StreamTransformationFilter(StreamTransformation &c,
m_isSpecial = m_cipher.IsLastBlockSpecial() && m_mandatoryBlockSize > 1; m_isSpecial = m_cipher.IsLastBlockSpecial() && m_mandatoryBlockSize > 1;
m_reservedBufferSize = STDMAX(2*m_mandatoryBlockSize, m_optimalBufferSize); m_reservedBufferSize = STDMAX(2*m_mandatoryBlockSize, m_optimalBufferSize);
IsolatedInitialize(MakeParameters(Name::BlockPaddingScheme(), padding)); FilterWithBufferedInput::IsolatedInitialize(
MakeParameters
(Name::BlockPaddingScheme(), padding));
} }
size_t StreamTransformationFilter::LastBlockSize(StreamTransformation &c, BlockPaddingScheme padding) size_t StreamTransformationFilter::LastBlockSize(StreamTransformation &c, BlockPaddingScheme padding)
@ -889,7 +893,10 @@ HashVerificationFilter::HashVerificationFilter(HashTransformation &hm, BufferedT
: FilterWithBufferedInput(attachment) : FilterWithBufferedInput(attachment)
, m_hashModule(hm), m_flags(0), m_digestSize(0), m_verified(false) , m_hashModule(hm), m_flags(0), m_digestSize(0), m_verified(false)
{ {
IsolatedInitialize(MakeParameters(Name::HashVerificationFilterFlags(), flags)(Name::TruncatedDigestSize(), truncatedDigestSize)); FilterWithBufferedInput::IsolatedInitialize(
MakeParameters
(Name::HashVerificationFilterFlags(), flags)
(Name::TruncatedDigestSize(), truncatedDigestSize));
} }
void HashVerificationFilter::InitializeDerivedAndReturnNewSizes(const NameValuePairs &parameters, size_t &firstSize, size_t &blockSize, size_t &lastSize) void HashVerificationFilter::InitializeDerivedAndReturnNewSizes(const NameValuePairs &parameters, size_t &firstSize, size_t &blockSize, size_t &lastSize)
@ -994,7 +1001,11 @@ AuthenticatedDecryptionFilter::AuthenticatedDecryptionFilter(AuthenticatedSymmet
, m_streamFilter(c, new OutputProxy(*this, false), padding, true) , m_streamFilter(c, new OutputProxy(*this, false), padding, true)
{ {
CRYPTOPP_ASSERT(!c.IsForwardTransformation() || c.IsSelfInverting()); CRYPTOPP_ASSERT(!c.IsForwardTransformation() || c.IsSelfInverting());
IsolatedInitialize(MakeParameters(Name::BlockPaddingScheme(), padding)(Name::AuthenticatedDecryptionFilterFlags(), flags)(Name::TruncatedDigestSize(), truncatedDigestSize)); FilterWithBufferedInput::IsolatedInitialize(
MakeParameters
(Name::BlockPaddingScheme(), padding)
(Name::AuthenticatedDecryptionFilterFlags(), flags)
(Name::TruncatedDigestSize(), truncatedDigestSize));
} }
void AuthenticatedDecryptionFilter::InitializeDerivedAndReturnNewSizes(const NameValuePairs &parameters, size_t &firstSize, size_t &blockSize, size_t &lastSize) void AuthenticatedDecryptionFilter::InitializeDerivedAndReturnNewSizes(const NameValuePairs &parameters, size_t &firstSize, size_t &blockSize, size_t &lastSize)
@ -1079,7 +1090,9 @@ SignatureVerificationFilter::SignatureVerificationFilter(const PK_Verifier &veri
: FilterWithBufferedInput(attachment) : FilterWithBufferedInput(attachment)
, m_verifier(verifier), m_flags(0), m_verified(0) , m_verifier(verifier), m_flags(0), m_verified(0)
{ {
IsolatedInitialize(MakeParameters(Name::SignatureVerificationFilterFlags(), flags)); FilterWithBufferedInput::IsolatedInitialize(
MakeParameters
(Name::SignatureVerificationFilterFlags(), flags));
} }
void SignatureVerificationFilter::InitializeDerivedAndReturnNewSizes(const NameValuePairs &parameters, size_t &firstSize, size_t &blockSize, size_t &lastSize) void SignatureVerificationFilter::InitializeDerivedAndReturnNewSizes(const NameValuePairs &parameters, size_t &firstSize, size_t &blockSize, size_t &lastSize)

View File

@ -474,7 +474,7 @@ struct BlockPaddingSchemeDef
/// \brief 0's padding added to a block /// \brief 0's padding added to a block
/// \since Crypto++ 5.0 /// \since Crypto++ 5.0
ZEROS_PADDING, ZEROS_PADDING,
/// \brief PKCS #5 padding added to a block /// \brief PKCS padding added to a block
/// \since Crypto++ 5.0 /// \since Crypto++ 5.0
PKCS_PADDING, PKCS_PADDING,
/// \brief 1 and 0's padding added to a block /// \brief 1 and 0's padding added to a block
@ -1100,6 +1100,7 @@ CRYPTOPP_DLL_TEMPLATE_CLASS StringSinkTemplate<std::string>;
/// \brief Append input to a std::vector<byte> object /// \brief Append input to a std::vector<byte> object
/// \details VectorSink is a typedef for StringSinkTemplate<std::vector<byte> >. /// \details VectorSink is a typedef for StringSinkTemplate<std::vector<byte> >.
/// \since Crypto++ 8.0
DOCUMENTED_TYPEDEF(StringSinkTemplate<std::vector<byte> >, VectorSink) DOCUMENTED_TYPEDEF(StringSinkTemplate<std::vector<byte> >, VectorSink)
CRYPTOPP_DLL_TEMPLATE_CLASS StringSinkTemplate<std::vector<byte> >; CRYPTOPP_DLL_TEMPLATE_CLASS StringSinkTemplate<std::vector<byte> >;

View File

@ -47,31 +47,35 @@ bool PowerUpSelfTestInProgressOnThisThread()
{ {
#if CRYPTOPP_ENABLE_COMPLIANCE_WITH_FIPS_140_2 #if CRYPTOPP_ENABLE_COMPLIANCE_WITH_FIPS_140_2
return s_inProgress; return s_inProgress;
#endif #else
return false; return false;
#endif
} }
void SetPowerUpSelfTestInProgressOnThisThread(bool inProgress) void SetPowerUpSelfTestInProgressOnThisThread(bool inProgress)
{ {
CRYPTOPP_UNUSED(inProgress);
#if CRYPTOPP_ENABLE_COMPLIANCE_WITH_FIPS_140_2 #if CRYPTOPP_ENABLE_COMPLIANCE_WITH_FIPS_140_2
s_inProgress = inProgress; s_inProgress = inProgress;
#else
CRYPTOPP_UNUSED(inProgress);
#endif #endif
} }
void EncryptionPairwiseConsistencyTest_FIPS_140_Only(const PK_Encryptor &encryptor, const PK_Decryptor &decryptor) void EncryptionPairwiseConsistencyTest_FIPS_140_Only(const PK_Encryptor &encryptor, const PK_Decryptor &decryptor)
{ {
CRYPTOPP_UNUSED(encryptor), CRYPTOPP_UNUSED(decryptor);
#if CRYPTOPP_ENABLE_COMPLIANCE_WITH_FIPS_140_2 #if CRYPTOPP_ENABLE_COMPLIANCE_WITH_FIPS_140_2
EncryptionPairwiseConsistencyTest(encryptor, decryptor); EncryptionPairwiseConsistencyTest(encryptor, decryptor);
#else
CRYPTOPP_UNUSED(encryptor), CRYPTOPP_UNUSED(decryptor);
#endif #endif
} }
void SignaturePairwiseConsistencyTest_FIPS_140_Only(const PK_Signer &signer, const PK_Verifier &verifier) void SignaturePairwiseConsistencyTest_FIPS_140_Only(const PK_Signer &signer, const PK_Verifier &verifier)
{ {
CRYPTOPP_UNUSED(signer), CRYPTOPP_UNUSED(verifier);
#if CRYPTOPP_ENABLE_COMPLIANCE_WITH_FIPS_140_2 #if CRYPTOPP_ENABLE_COMPLIANCE_WITH_FIPS_140_2
SignaturePairwiseConsistencyTest(signer, verifier); SignaturePairwiseConsistencyTest(signer, verifier);
#else
CRYPTOPP_UNUSED(signer), CRYPTOPP_UNUSED(verifier);
#endif #endif
} }

24
gcm.cpp
View File

@ -44,7 +44,7 @@ NAMESPACE_BEGIN(CryptoPP)
#endif #endif
#endif // CRYPTOPP_BOOL_X86 || CRYPTOPP_BOOL_X32 || CRYPTOPP_BOOL_X64 #endif // CRYPTOPP_BOOL_X86 || CRYPTOPP_BOOL_X32 || CRYPTOPP_BOOL_X64
// Clang __m128i casts, http://bugs.llvm.org/show_bug.cgi?id=20670 // Clang intrinsic casts, http://bugs.llvm.org/show_bug.cgi?id=20670
#define M128_CAST(x) ((__m128i *)(void *)(x)) #define M128_CAST(x) ((__m128i *)(void *)(x))
#define CONST_M128_CAST(x) ((const __m128i *)(const void *)(x)) #define CONST_M128_CAST(x) ((const __m128i *)(const void *)(x))
@ -75,8 +75,8 @@ extern void GCM_Xor16_SSE2(byte *a, const byte *b, const byte *c);
extern void GCM_Xor16_NEON(byte *a, const byte *b, const byte *c); extern void GCM_Xor16_NEON(byte *a, const byte *b, const byte *c);
#endif #endif
#if CRYPTOPP_POWER7_AVAILABLE #if CRYPTOPP_POWER8_AVAILABLE
extern void GCM_Xor16_POWER7(byte *a, const byte *b, const byte *c); extern void GCM_Xor16_POWER8(byte *a, const byte *b, const byte *c);
#endif #endif
#if CRYPTOPP_CLMUL_AVAILABLE #if CRYPTOPP_CLMUL_AVAILABLE
@ -213,11 +213,11 @@ void GCM_Base::SetKeyWithoutResync(const byte *userKey, size_t keylength, const
for (k=1; k<j; k++) for (k=1; k<j; k++)
GCM_Xor16_NEON(mulTable+i*256*16+(j+k)*16, mulTable+i*256*16+j*16, mulTable+i*256*16+k*16); GCM_Xor16_NEON(mulTable+i*256*16+(j+k)*16, mulTable+i*256*16+j*16, mulTable+i*256*16+k*16);
else else
#elif CRYPTOPP_POWER7_AVAILABLE #elif CRYPTOPP_POWER8_AVAILABLE
if (HasPower7()) if (HasPower8())
for (j=2; j<=0x80; j*=2) for (j=2; j<=0x80; j*=2)
for (k=1; k<j; k++) for (k=1; k<j; k++)
GCM_Xor16_POWER7(mulTable+i*256*16+(j+k)*16, mulTable+i*256*16+j*16, mulTable+i*256*16+k*16); GCM_Xor16_POWER8(mulTable+i*256*16+(j+k)*16, mulTable+i*256*16+j*16, mulTable+i*256*16+k*16);
else else
#endif #endif
for (j=2; j<=0x80; j*=2) for (j=2; j<=0x80; j*=2)
@ -277,13 +277,13 @@ void GCM_Base::SetKeyWithoutResync(const byte *userKey, size_t keylength, const
GCM_Xor16_NEON(mulTable+1024+i*256+(j+k)*16, mulTable+1024+i*256+j*16, mulTable+1024+i*256+k*16); GCM_Xor16_NEON(mulTable+1024+i*256+(j+k)*16, mulTable+1024+i*256+j*16, mulTable+1024+i*256+k*16);
} }
else else
#elif CRYPTOPP_POWER7_AVAILABLE #elif CRYPTOPP_POWER8_AVAILABLE
if (HasPower7()) if (HasPower8())
for (j=2; j<=8; j*=2) for (j=2; j<=8; j*=2)
for (k=1; k<j; k++) for (k=1; k<j; k++)
{ {
GCM_Xor16_POWER7(mulTable+i*256+(j+k)*16, mulTable+i*256+j*16, mulTable+i*256+k*16); GCM_Xor16_POWER8(mulTable+i*256+(j+k)*16, mulTable+i*256+j*16, mulTable+i*256+k*16);
GCM_Xor16_POWER7(mulTable+1024+i*256+(j+k)*16, mulTable+1024+i*256+j*16, mulTable+1024+i*256+k*16); GCM_Xor16_POWER8(mulTable+1024+i*256+(j+k)*16, mulTable+1024+i*256+j*16, mulTable+1024+i*256+k*16);
} }
else else
#endif #endif
@ -369,8 +369,8 @@ unsigned int GCM_Base::OptimalDataAlignment() const
HasSSE2() ? 16 : HasSSE2() ? 16 :
#elif CRYPTOPP_ARM_NEON_AVAILABLE #elif CRYPTOPP_ARM_NEON_AVAILABLE
HasNEON() ? 4 : HasNEON() ? 4 :
#elif CRYPTOPP_POWER7_AVAILABLE #elif CRYPTOPP_POWER8_AVAILABLE
HasPower7() ? 16 : HasPower8() ? 16 :
#endif #endif
GetBlockCipher().OptimalDataAlignment(); GetBlockCipher().OptimalDataAlignment();
} }

View File

@ -56,14 +56,10 @@
# define EXCEPTION_EXECUTE_HANDLER 1 # define EXCEPTION_EXECUTE_HANDLER 1
#endif #endif
// Clang __m128i casts, http://bugs.llvm.org/show_bug.cgi?id=20670 // Clang intrinsic casts, http://bugs.llvm.org/show_bug.cgi?id=20670
#define M128_CAST(x) ((__m128i *)(void *)(x)) #define M128_CAST(x) ((__m128i *)(void *)(x))
#define CONST_M128_CAST(x) ((const __m128i *)(const void *)(x)) #define CONST_M128_CAST(x) ((const __m128i *)(const void *)(x))
// GCC cast warning
#define UINT64X2_CAST(x) ((uint64x2_t *)(void *)(x))
#define CONST_UINT64X2_CAST(x) ((const uint64x2_t *)(const void *)(x))
// Squash MS LNK4221 and libtool warnings // Squash MS LNK4221 and libtool warnings
extern const char GCM_SIMD_FNAME[] = __FILE__; extern const char GCM_SIMD_FNAME[] = __FILE__;
@ -219,10 +215,7 @@ bool CPU_ProbePMULL()
#if CRYPTOPP_ARM_NEON_AVAILABLE #if CRYPTOPP_ARM_NEON_AVAILABLE
void GCM_Xor16_NEON(byte *a, const byte *b, const byte *c) void GCM_Xor16_NEON(byte *a, const byte *b, const byte *c)
{ {
CRYPTOPP_ASSERT(IsAlignedOn(a,GetAlignmentOf<uint64x2_t>())); vst1q_u8(a, veorq_u8(vld1q_u8(b), vld1q_u8(c)));
CRYPTOPP_ASSERT(IsAlignedOn(b,GetAlignmentOf<uint64x2_t>()));
CRYPTOPP_ASSERT(IsAlignedOn(c,GetAlignmentOf<uint64x2_t>()));
*UINT64X2_CAST(a) = veorq_u64(*CONST_UINT64X2_CAST(b), *CONST_UINT64X2_CAST(c));
} }
#endif // CRYPTOPP_ARM_NEON_AVAILABLE #endif // CRYPTOPP_ARM_NEON_AVAILABLE
@ -569,12 +562,12 @@ void GCM_ReverseHashBufferIfNeeded_CLMUL(byte *hashBuffer)
// ***************************** POWER8 ***************************** // // ***************************** POWER8 ***************************** //
#if CRYPTOPP_POWER7_AVAILABLE #if CRYPTOPP_POWER8_AVAILABLE
void GCM_Xor16_POWER7(byte *a, const byte *b, const byte *c) void GCM_Xor16_POWER8(byte *a, const byte *b, const byte *c)
{ {
VecStore(VecXor(VecLoad(b), VecLoad(c)), a); VecStore(VecXor(VecLoad(b), VecLoad(c)), a);
} }
#endif // CRYPTOPP_POWER7_AVAILABLE #endif // CRYPTOPP_POWER8_AVAILABLE
#if CRYPTOPP_POWER8_VMULL_AVAILABLE #if CRYPTOPP_POWER8_VMULL_AVAILABLE

View File

@ -21,6 +21,8 @@
#include "pch.h" #include "pch.h"
#include "config.h" #include "config.h"
#ifndef CRYPTOPP_IMPORTS
#include "gf2n.h" #include "gf2n.h"
#if (CRYPTOPP_CLMUL_AVAILABLE) #if (CRYPTOPP_CLMUL_AVAILABLE)
@ -463,36 +465,33 @@ NAMESPACE_BEGIN(CryptoPP)
void void
GF2NT_233_Multiply_Reduce_CLMUL(const word* pA, const word* pB, word* pC) GF2NT_233_Multiply_Reduce_CLMUL(const word* pA, const word* pB, word* pC)
{ {
const __m128i* pAA = reinterpret_cast<const __m128i*>(pA); enum {S=sizeof(__m128i)/sizeof(word)};
const __m128i* pBB = reinterpret_cast<const __m128i*>(pB); __m128i a0 = _mm_loadu_si128(reinterpret_cast<const __m128i*>(pA+0*S));
__m128i a0 = _mm_loadu_si128(pAA+0); __m128i a1 = _mm_loadu_si128(reinterpret_cast<const __m128i*>(pA+1*S));
__m128i a1 = _mm_loadu_si128(pAA+1); __m128i b0 = _mm_loadu_si128(reinterpret_cast<const __m128i*>(pB+0*S));
__m128i b0 = _mm_loadu_si128(pBB+0); __m128i b1 = _mm_loadu_si128(reinterpret_cast<const __m128i*>(pB+1*S));
__m128i b1 = _mm_loadu_si128(pBB+1);
__m128i c0, c1, c2, c3; __m128i c0, c1, c2, c3;
F2N_Multiply_256x256_CLMUL(c3, c2, c1, c0, a1, a0, b1, b0); F2N_Multiply_256x256_CLMUL(c3, c2, c1, c0, a1, a0, b1, b0);
GF2NT_233_Reduce_CLMUL(c3, c2, c1, c0); GF2NT_233_Reduce_CLMUL(c3, c2, c1, c0);
__m128i* pCC = reinterpret_cast<__m128i*>(pC); _mm_storeu_si128(reinterpret_cast<__m128i*>(pC+0*S), c0);
_mm_storeu_si128(pCC+0, c0); _mm_storeu_si128(reinterpret_cast<__m128i*>(pC+1*S), c1);
_mm_storeu_si128(pCC+1, c1);
} }
void void
GF2NT_233_Square_Reduce_CLMUL(const word* pA, word* pC) GF2NT_233_Square_Reduce_CLMUL(const word* pA, word* pC)
{ {
const __m128i* pAA = reinterpret_cast<const __m128i*>(pA); enum {S=sizeof(__m128i)/sizeof(word)};
__m128i a0 = _mm_loadu_si128(pAA+0); __m128i a0 = _mm_loadu_si128(reinterpret_cast<const __m128i*>(pA+0*S));
__m128i a1 = _mm_loadu_si128(pAA+1); __m128i a1 = _mm_loadu_si128(reinterpret_cast<const __m128i*>(pA+1*S));
__m128i c0, c1, c2, c3; __m128i c0, c1, c2, c3;
F2N_Square_256_CLMUL(c3, c2, c1, c0, a1, a0); F2N_Square_256_CLMUL(c3, c2, c1, c0, a1, a0);
GF2NT_233_Reduce_CLMUL(c3, c2, c1, c0); GF2NT_233_Reduce_CLMUL(c3, c2, c1, c0);
__m128i* pCC = reinterpret_cast<__m128i*>(pC); _mm_storeu_si128(reinterpret_cast<__m128i*>(pC+0*S), c0);
_mm_storeu_si128(pCC+0, c0); _mm_storeu_si128(reinterpret_cast<__m128i*>(pC+1*S), c1);
_mm_storeu_si128(pCC+1, c1);
} }
#elif (CRYPTOPP_ARM_PMULL_AVAILABLE) #elif (CRYPTOPP_ARM_PMULL_AVAILABLE)
@ -608,3 +607,5 @@ GF2NT_233_Square_Reduce_POWER8(const word* pA, word* pC)
#endif #endif
NAMESPACE_END NAMESPACE_END
#endif // CRYPTOPP_IMPORTS

View File

@ -133,22 +133,27 @@ void DL_SignatureMessageEncodingMethod_NR::ComputeMessageRepresentative(RandomNu
bool DL_GroupParameters_IntegerBased::ValidateGroup(RandomNumberGenerator &rng, unsigned int level) const bool DL_GroupParameters_IntegerBased::ValidateGroup(RandomNumberGenerator &rng, unsigned int level) const
{ {
const Integer &p = GetModulus(), &q = GetSubgroupOrder(); const Integer &p = GetModulus(), &q = GetSubgroupOrder();
bool pass = true; bool pass = true;
CRYPTOPP_ASSERT(p > Integer::One() && p.IsOdd());
pass = pass && p > Integer::One() && p.IsOdd(); pass = pass && p > Integer::One() && p.IsOdd();
CRYPTOPP_ASSERT(pass);
CRYPTOPP_ASSERT(q > Integer::One() && q.IsOdd());
pass = pass && q > Integer::One() && q.IsOdd(); pass = pass && q > Integer::One() && q.IsOdd();
CRYPTOPP_ASSERT(pass);
if (level >= 1) if (level >= 1)
{ {
CRYPTOPP_ASSERT(GetCofactor() > Integer::One());
CRYPTOPP_ASSERT(GetGroupOrder() % q == Integer::Zero());
pass = pass && GetCofactor() > Integer::One() && GetGroupOrder() % q == Integer::Zero(); pass = pass && GetCofactor() > Integer::One() && GetGroupOrder() % q == Integer::Zero();
CRYPTOPP_ASSERT(pass);
} }
if (level >= 2) if (level >= 2)
{ {
CRYPTOPP_ASSERT(VerifyPrime(rng, q, level-2));
CRYPTOPP_ASSERT(VerifyPrime(rng, p, level-2));
pass = pass && VerifyPrime(rng, q, level-2) && VerifyPrime(rng, p, level-2); pass = pass && VerifyPrime(rng, q, level-2) && VerifyPrime(rng, p, level-2);
CRYPTOPP_ASSERT(pass);
} }
return pass; return pass;
@ -157,28 +162,28 @@ bool DL_GroupParameters_IntegerBased::ValidateGroup(RandomNumberGenerator &rng,
bool DL_GroupParameters_IntegerBased::ValidateElement(unsigned int level, const Integer &g, const DL_FixedBasePrecomputation<Integer> *gpc) const bool DL_GroupParameters_IntegerBased::ValidateElement(unsigned int level, const Integer &g, const DL_FixedBasePrecomputation<Integer> *gpc) const
{ {
const Integer &p = GetModulus(), &q = GetSubgroupOrder(); const Integer &p = GetModulus(), &q = GetSubgroupOrder();
bool pass = true; bool pass = true;
pass = pass && GetFieldType() == 1 ? g.IsPositive() : g.NotNegative();
CRYPTOPP_ASSERT(pass);
CRYPTOPP_ASSERT(GetFieldType() == 1 ? g.IsPositive() : g.NotNegative());
pass = pass && GetFieldType() == 1 ? g.IsPositive() : g.NotNegative();
CRYPTOPP_ASSERT(g < p && !IsIdentity(g));
pass = pass && g < p && !IsIdentity(g); pass = pass && g < p && !IsIdentity(g);
CRYPTOPP_ASSERT(pass);
if (level >= 1) if (level >= 1)
{ {
if (gpc) if (gpc)
{ {
CRYPTOPP_ASSERT(gpc->Exponentiate(GetGroupPrecomputation(), Integer::One()) == g);
pass = pass && gpc->Exponentiate(GetGroupPrecomputation(), Integer::One()) == g; pass = pass && gpc->Exponentiate(GetGroupPrecomputation(), Integer::One()) == g;
CRYPTOPP_ASSERT(pass);
} }
} }
if (level >= 2) if (level >= 2)
{ {
if (GetFieldType() == 2) if (GetFieldType() == 2)
{ {
CRYPTOPP_ASSERT(Jacobi(g*g-4, p)==-1);
pass = pass && Jacobi(g*g-4, p)==-1; pass = pass && Jacobi(g*g-4, p)==-1;
CRYPTOPP_ASSERT(pass);
} }
// verifying that Lucas((p+1)/2, w, p)==2 is omitted because it's too costly // verifying that Lucas((p+1)/2, w, p)==2 is omitted because it's too costly
@ -188,13 +193,13 @@ bool DL_GroupParameters_IntegerBased::ValidateElement(unsigned int level, const
if (fullValidate && pass) if (fullValidate && pass)
{ {
Integer gp = gpc ? gpc->Exponentiate(GetGroupPrecomputation(), q) : ExponentiateElement(g, q); Integer gp = gpc ? gpc->Exponentiate(GetGroupPrecomputation(), q) : ExponentiateElement(g, q);
CRYPTOPP_ASSERT(IsIdentity(gp));
pass = pass && IsIdentity(gp); pass = pass && IsIdentity(gp);
CRYPTOPP_ASSERT(pass);
} }
else if (GetFieldType() == 1) else if (GetFieldType() == 1)
{ {
CRYPTOPP_ASSERT(Jacobi(g, p) == 1);
pass = pass && Jacobi(g, p) == 1; pass = pass && Jacobi(g, p) == 1;
CRYPTOPP_ASSERT(pass);
} }
} }

View File

@ -69,8 +69,13 @@ public:
void BERDecode(BufferedTransformation &bt); void BERDecode(BufferedTransformation &bt);
void DEREncode(BufferedTransformation &bt) const; void DEREncode(BufferedTransformation &bt) const;
// GeneratibleCryptoMaterial interface /// \brief Generate a random key
/*! parameters: (ModulusSize, SubgroupOrderSize (optional)) */ /// \param rng a RandomNumberGenerator to produce keying material
/// \param params additional initialization parameters
/// \details Recognised NameValuePairs are ModulusSize and
/// SubgroupOrderSize (optional)
/// \throws KeyingErr if a key can't be generated or algorithm parameters
/// are invalid
void GenerateRandom(RandomNumberGenerator &rng, const NameValuePairs &alg); void GenerateRandom(RandomNumberGenerator &rng, const NameValuePairs &alg);
bool GetVoidValue(const char *name, const std::type_info &valueType, void *pValue) const; bool GetVoidValue(const char *name, const std::type_info &valueType, void *pValue) const;
void AssignFrom(const NameValuePairs &source); void AssignFrom(const NameValuePairs &source);
@ -80,26 +85,68 @@ public:
Integer GetGroupOrder() const {return GetFieldType() == 1 ? GetModulus()-Integer::One() : GetModulus()+Integer::One();} Integer GetGroupOrder() const {return GetFieldType() == 1 ? GetModulus()-Integer::One() : GetModulus()+Integer::One();}
bool ValidateGroup(RandomNumberGenerator &rng, unsigned int level) const; bool ValidateGroup(RandomNumberGenerator &rng, unsigned int level) const;
bool ValidateElement(unsigned int level, const Integer &element, const DL_FixedBasePrecomputation<Integer> *precomp) const; bool ValidateElement(unsigned int level, const Integer &element, const DL_FixedBasePrecomputation<Integer> *precomp) const;
/// \brief Determine if subgroup membership check is fast
/// \returns true or false
bool FastSubgroupCheckAvailable() const {return GetCofactor() == 2;} bool FastSubgroupCheckAvailable() const {return GetCofactor() == 2;}
// Cygwin i386 crash at -O3; see http://github.com/weidai11/cryptopp/issues/40. /// \brief Encodes the element
/// \param reversible flag indicating the encoding format
/// \param element reference to the element to encode
/// \param encoded destination byte array for the encoded element
/// \details EncodeElement() must be implemented in a derived class.
/// \pre <tt>COUNTOF(encoded) == GetEncodedElementSize()</tt>
/// \sa <A HREF="http://github.com/weidai11/cryptopp/issues/40">Cygwin
/// i386 crash at -O3</A>
void EncodeElement(bool reversible, const Element &element, byte *encoded) const; void EncodeElement(bool reversible, const Element &element, byte *encoded) const;
/// \brief Retrieve the encoded element's size
/// \param reversible flag indicating the encoding format
/// \return encoded element's size, in bytes
/// \details The format of the encoded element varies by the underlying
/// type of the element and the reversible flag.
/// \sa GetEncodedElementSize(), EncodeElement(), DecodeElement()
unsigned int GetEncodedElementSize(bool reversible) const; unsigned int GetEncodedElementSize(bool reversible) const;
/// \brief Decodes the element
/// \param encoded byte array with the encoded element
/// \param checkForGroupMembership flag indicating if the element should be validated
/// \return Element after decoding
/// \details DecodeElement() must be implemented in a derived class.
/// \pre <tt>COUNTOF(encoded) == GetEncodedElementSize()</tt>
Integer DecodeElement(const byte *encoded, bool checkForGroupMembership) const; Integer DecodeElement(const byte *encoded, bool checkForGroupMembership) const;
/// \brief Converts an element to an Integer
/// \param element the element to convert to an Integer
/// \return Element after converting to an Integer
/// \details ConvertElementToInteger() must be implemented in a derived class.
Integer ConvertElementToInteger(const Element &element) const Integer ConvertElementToInteger(const Element &element) const
{return element;} {return element;}
Integer GetMaxExponent() const;
static std::string CRYPTOPP_API StaticAlgorithmNamePrefix() {return "";}
/// \brief Retrieve the maximum exponent for the group
/// \return the maximum exponent for the group
Integer GetMaxExponent() const;
/// \brief Retrieve the OID of the algorithm
/// \returns OID of the algorithm
OID GetAlgorithmID() const; OID GetAlgorithmID() const;
/// \brief Retrieve the modulus for the group
/// \return the modulus for the group
virtual const Integer & GetModulus() const =0; virtual const Integer & GetModulus() const =0;
/// \brief Set group parameters
/// \param p the prime modulus
/// \param g the group generator
virtual void SetModulusAndSubgroupGenerator(const Integer &p, const Integer &g) =0; virtual void SetModulusAndSubgroupGenerator(const Integer &p, const Integer &g) =0;
/// \brief Set subgroup order
/// \param q the subgroup order
void SetSubgroupOrder(const Integer &q) void SetSubgroupOrder(const Integer &q)
{m_q = q; ParametersChanged();} {m_q = q; ParametersChanged();}
static std::string CRYPTOPP_API StaticAlgorithmNamePrefix() {return "";}
protected: protected:
Integer ComputeGroupOrder(const Integer &modulus) const Integer ComputeGroupOrder(const Integer &modulus) const
{return modulus-(GetFieldType() == 1 ? 1 : -1);} {return modulus-(GetFieldType() == 1 ? 1 : -1);}
@ -704,7 +751,7 @@ public:
bool ParameterSupported(const char *name) const {return strcmp(name, Name::EncodingParameters()) == 0;} bool ParameterSupported(const char *name) const {return strcmp(name, Name::EncodingParameters()) == 0;}
size_t GetSymmetricKeyLength(size_t plaintextLength) const size_t GetSymmetricKeyLength(size_t plaintextLength) const
{return plaintextLength + static_cast<size_t>(MAC::DIGESTSIZE);} {return plaintextLength + static_cast<size_t>(MAC::DEFAULT_KEYLENGTH);}
size_t GetSymmetricCiphertextLength(size_t plaintextLength) const size_t GetSymmetricCiphertextLength(size_t plaintextLength) const
{return plaintextLength + static_cast<size_t>(MAC::DIGESTSIZE);} {return plaintextLength + static_cast<size_t>(MAC::DIGESTSIZE);}
size_t GetMaxSymmetricPlaintextLength(size_t ciphertextLength) const size_t GetMaxSymmetricPlaintextLength(size_t ciphertextLength) const

View File

@ -60,7 +60,7 @@ public:
void ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const; void ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const;
}; };
/// \brief Encryption transformation /// \brief Decryption transformation
/// \details Dec provides implementation for decryption transformation. /// \details Dec provides implementation for decryption transformation.
/// \since Crypto++ 8.0 /// \since Crypto++ 8.0
class CRYPTOPP_NO_VTABLE Dec : public Base class CRYPTOPP_NO_VTABLE Dec : public Base

14
hkdf.h
View File

@ -39,7 +39,7 @@ public:
} }
// KeyDerivationFunction interface // KeyDerivationFunction interface
size_t MaxDerivedLength() const { size_t MaxDerivedKeyLength() const {
return static_cast<size_t>(T::DIGESTSIZE) * 255; return static_cast<size_t>(T::DIGESTSIZE) * 255;
} }
@ -60,7 +60,7 @@ public:
/// \param info the additional input buffer /// \param info the additional input buffer
/// \param infoLen the size of the info buffer, in bytes /// \param infoLen the size of the info buffer, in bytes
/// \returns the number of iterations performed /// \returns the number of iterations performed
/// \throws InvalidDerivedLength if <tt>derivedLen</tt> is invalid for the scheme /// \throws InvalidDerivedKeyLength if <tt>derivedLen</tt> is invalid for the scheme
/// \details DeriveKey() provides a standard interface to derive a key from /// \details DeriveKey() provides a standard interface to derive a key from
/// a seed and other parameters. Each class that derives from KeyDerivationFunction /// a seed and other parameters. Each class that derives from KeyDerivationFunction
/// provides an overload that accepts most parameters used by the derivation function. /// provides an overload that accepts most parameters used by the derivation function.
@ -92,8 +92,8 @@ protected:
template <class T> template <class T>
size_t HKDF<T>::GetValidDerivedLength(size_t keylength) const size_t HKDF<T>::GetValidDerivedLength(size_t keylength) const
{ {
if (keylength > MaxDerivedLength()) if (keylength > MaxDerivedKeyLength())
return MaxDerivedLength(); return MaxDerivedKeyLength();
return keylength; return keylength;
} }
@ -103,7 +103,7 @@ size_t HKDF<T>::DeriveKey(byte *derived, size_t derivedLen,
{ {
CRYPTOPP_ASSERT(secret && secretLen); CRYPTOPP_ASSERT(secret && secretLen);
CRYPTOPP_ASSERT(derived && derivedLen); CRYPTOPP_ASSERT(derived && derivedLen);
CRYPTOPP_ASSERT(derivedLen <= MaxDerivedLength()); CRYPTOPP_ASSERT(derivedLen <= MaxDerivedKeyLength());
ConstByteArrayParameter p; ConstByteArrayParameter p;
SecByteBlock salt, info; SecByteBlock salt, info;
@ -127,9 +127,9 @@ size_t HKDF<T>::DeriveKey(byte *derived, size_t derivedLen, const byte *secret,
{ {
CRYPTOPP_ASSERT(secret && secretLen); CRYPTOPP_ASSERT(secret && secretLen);
CRYPTOPP_ASSERT(derived && derivedLen); CRYPTOPP_ASSERT(derived && derivedLen);
CRYPTOPP_ASSERT(derivedLen <= MaxDerivedLength()); CRYPTOPP_ASSERT(derivedLen <= MaxDerivedKeyLength());
ThrowIfInvalidDerivedLength(derivedLen); ThrowIfInvalidDerivedKeyLength(derivedLen);
// HKDF business logic. NULL is different than empty. // HKDF business logic. NULL is different than empty.
if (salt == NULLPTR) if (salt == NULLPTR)

230
hmqv.h
View File

@ -1,5 +1,5 @@
// hmqv.h - written and placed in the public domain by Uri Blumenthal // hmqv.h - written and placed in the public domain by Uri Blumenthal
// Shamelessly based upon Jeffrey Walton's FHMQV and Wei Dai's MQV source files // Shamelessly based upon Wei Dai's MQV source files
#ifndef CRYPTOPP_HMQV_H #ifndef CRYPTOPP_HMQV_H
#define CRYPTOPP_HMQV_H #define CRYPTOPP_HMQV_H
@ -29,30 +29,85 @@ public:
virtual ~HMQV_Domain() {} virtual ~HMQV_Domain() {}
HMQV_Domain(bool clientRole = true): m_role(clientRole ? RoleClient : RoleServer) {} /// \brief Construct a HMQV domain
/// \param clientRole flag indicating initiator or recipient
/// \details <tt>clientRole = true</tt> indicates initiator, and
/// <tt>clientRole = false</tt> indicates recipient or server.
HMQV_Domain(bool clientRole = true)
: m_role(clientRole ? RoleClient : RoleServer) {}
/// \brief Construct a HMQV domain
/// \param params group parameters and options
/// \param clientRole flag indicating initiator or recipient
/// \details <tt>clientRole = true</tt> indicates initiator, and
/// <tt>clientRole = false</tt> indicates recipient or server.
HMQV_Domain(const GroupParameters &params, bool clientRole = true) HMQV_Domain(const GroupParameters &params, bool clientRole = true)
: m_role(clientRole ? RoleClient : RoleServer), m_groupParameters(params) {} : m_role(clientRole ? RoleClient : RoleServer), m_groupParameters(params) {}
/// \brief Construct a HMQV domain
/// \param bt BufferedTransformation with group parameters and options
/// \param clientRole flag indicating initiator or recipient
/// \details <tt>clientRole = true</tt> indicates initiator, and
/// <tt>clientRole = false</tt> indicates recipient or server.
HMQV_Domain(BufferedTransformation &bt, bool clientRole = true) HMQV_Domain(BufferedTransformation &bt, bool clientRole = true)
: m_role(clientRole ? RoleClient : RoleServer) : m_role(clientRole ? RoleClient : RoleServer)
{m_groupParameters.BERDecode(bt);} {m_groupParameters.BERDecode(bt);}
/// \brief Construct a HMQV domain
/// \tparam T1 template parameter used as a constructor parameter
/// \param v1 first parameter
/// \param clientRole flag indicating initiator or recipient
/// \details v1 is passed directly to the GROUP_PARAMETERS object.
/// \details <tt>clientRole = true</tt> indicates initiator, and
/// <tt>clientRole = false</tt> indicates recipient or server.
template <class T1> template <class T1>
HMQV_Domain(T1 v1, bool clientRole = true) HMQV_Domain(T1 v1, bool clientRole = true)
: m_role(clientRole ? RoleClient : RoleServer) : m_role(clientRole ? RoleClient : RoleServer)
{m_groupParameters.Initialize(v1);} {m_groupParameters.Initialize(v1);}
/// \brief Construct a HMQV domain
/// \tparam T1 template parameter used as a constructor parameter
/// \tparam T2 template parameter used as a constructor parameter
/// \param v1 first parameter
/// \param v2 second parameter
/// \param clientRole flag indicating initiator or recipient
/// \details v1 and v2 are passed directly to the GROUP_PARAMETERS object.
/// \details <tt>clientRole = true</tt> indicates initiator, and
/// <tt>clientRole = false</tt> indicates recipient or server.
template <class T1, class T2> template <class T1, class T2>
HMQV_Domain(T1 v1, T2 v2, bool clientRole = true) HMQV_Domain(T1 v1, T2 v2, bool clientRole = true)
: m_role(clientRole ? RoleClient : RoleServer) : m_role(clientRole ? RoleClient : RoleServer)
{m_groupParameters.Initialize(v1, v2);} {m_groupParameters.Initialize(v1, v2);}
/// \brief Construct a HMQV domain
/// \tparam T1 template parameter used as a constructor parameter
/// \tparam T2 template parameter used as a constructor parameter
/// \tparam T3 template parameter used as a constructor parameter
/// \param v1 first parameter
/// \param v2 second parameter
/// \param v3 third parameter
/// \param clientRole flag indicating initiator or recipient
/// \details v1, v2 and v3 are passed directly to the GROUP_PARAMETERS object.
/// \details <tt>clientRole = true</tt> indicates initiator, and
/// <tt>clientRole = false</tt> indicates recipient or server.
template <class T1, class T2, class T3> template <class T1, class T2, class T3>
HMQV_Domain(T1 v1, T2 v2, T3 v3, bool clientRole = true) HMQV_Domain(T1 v1, T2 v2, T3 v3, bool clientRole = true)
: m_role(clientRole ? RoleClient : RoleServer) : m_role(clientRole ? RoleClient : RoleServer)
{m_groupParameters.Initialize(v1, v2, v3);} {m_groupParameters.Initialize(v1, v2, v3);}
/// \brief Construct a HMQV domain
/// \tparam T1 template parameter used as a constructor parameter
/// \tparam T2 template parameter used as a constructor parameter
/// \tparam T3 template parameter used as a constructor parameter
/// \tparam T4 template parameter used as a constructor parameter
/// \param v1 first parameter
/// \param v2 second parameter
/// \param v3 third parameter
/// \param v4 third parameter
/// \param clientRole flag indicating initiator or recipient
/// \details v1, v2, v3 and v4 are passed directly to the GROUP_PARAMETERS object.
/// \details <tt>clientRole = true</tt> indicates initiator, and
/// <tt>clientRole = false</tt> indicates recipient or server.
template <class T1, class T2, class T3, class T4> template <class T1, class T2, class T3, class T4>
HMQV_Domain(T1 v1, T2 v2, T3 v3, T4 v4, bool clientRole = true) HMQV_Domain(T1 v1, T2 v2, T3 v3, T4 v4, bool clientRole = true)
: m_role(clientRole ? RoleClient : RoleServer) : m_role(clientRole ? RoleClient : RoleServer)
@ -60,28 +115,62 @@ public:
public: public:
/// \brief Retrieves the group parameters for this domain
/// \return the group parameters for this domain as a const reference
const GroupParameters & GetGroupParameters() const {return m_groupParameters;} const GroupParameters & GetGroupParameters() const {return m_groupParameters;}
/// \brief Retrieves the group parameters for this domain
/// \return the group parameters for this domain as a non-const reference
GroupParameters & AccessGroupParameters() {return m_groupParameters;} GroupParameters & AccessGroupParameters() {return m_groupParameters;}
/// \brief Retrieves the crypto parameters for this domain
/// \return the crypto parameters for this domain as a non-const reference
CryptoParameters & AccessCryptoParameters() {return AccessAbstractGroupParameters();} CryptoParameters & AccessCryptoParameters() {return AccessAbstractGroupParameters();}
/// return length of agreed value produced /// \brief Provides the size of the agreed value
unsigned int AgreedValueLength() const {return GetAbstractGroupParameters().GetEncodedElementSize(false);} /// \return size of agreed value produced in this domain
/// return length of static private keys in this domain /// \details The length is calculated using <tt>GetEncodedElementSize(false)</tt>,
unsigned int StaticPrivateKeyLength() const {return GetAbstractGroupParameters().GetSubgroupOrder().ByteCount();} /// which means the element is encoded in a non-reversible format. A
/// return length of static public keys in this domain /// non-reversible format means its a raw byte array, and it lacks presentation
unsigned int StaticPublicKeyLength() const{return GetAbstractGroupParameters().GetEncodedElementSize(true);} /// format like an ASN.1 BIT_STRING or OCTET_STRING.
unsigned int AgreedValueLength() const
{return GetAbstractGroupParameters().GetEncodedElementSize(false);}
/// generate static private key /// \brief Provides the size of the static private key
/*! \pre size of privateKey == PrivateStaticKeyLength() */ /// \return size of static private keys in this domain
/// \details The length is calculated using the byte count of the subgroup order.
unsigned int StaticPrivateKeyLength() const
{return GetAbstractGroupParameters().GetSubgroupOrder().ByteCount();}
/// \brief Provides the size of the static public key
/// \return size of static public keys in this domain
/// \details The length is calculated using <tt>GetEncodedElementSize(true)</tt>,
/// which means the element is encoded in a reversible format. A reversible
/// format means it has a presentation format, and its an ANS.1 encoded element
/// or point.
unsigned int StaticPublicKeyLength() const
{return GetAbstractGroupParameters().GetEncodedElementSize(true);}
/// \brief Generate static private key in this domain
/// \param rng a RandomNumberGenerator derived class
/// \param privateKey a byte buffer for the generated private key in this domain
/// \details The private key is a random scalar used as an exponent in the range
/// <tt>[1,MaxExponent()]</tt>.
/// \pre <tt>COUNTOF(privateKey) == PrivateStaticKeyLength()</tt>
void GenerateStaticPrivateKey(RandomNumberGenerator &rng, byte *privateKey) const void GenerateStaticPrivateKey(RandomNumberGenerator &rng, byte *privateKey) const
{ {
Integer x(rng, Integer::One(), GetAbstractGroupParameters().GetMaxExponent()); Integer x(rng, Integer::One(), GetAbstractGroupParameters().GetMaxExponent());
x.Encode(privateKey, StaticPrivateKeyLength()); x.Encode(privateKey, StaticPrivateKeyLength());
} }
/// generate static public key /// \brief Generate a static public key from a private key in this domain
/*! \pre size of publicKey == PublicStaticKeyLength() */ /// \param rng a RandomNumberGenerator derived class
/// \param privateKey a byte buffer with the previously generated private key
/// \param publicKey a byte buffer for the generated public key in this domain
/// \details The public key is an element or point on the curve, and its stored
/// in a revrsible format. A reversible format means it has a presentation
/// format, and its an ANS.1 encoded element or point.
/// \pre <tt>COUNTOF(publicKey) == PublicStaticKeyLength()</tt>
void GenerateStaticPublicKey(RandomNumberGenerator &rng, const byte *privateKey, byte *publicKey) const void GenerateStaticPublicKey(RandomNumberGenerator &rng, const byte *privateKey, byte *publicKey) const
{ {
CRYPTOPP_UNUSED(rng); CRYPTOPP_UNUSED(rng);
@ -91,10 +180,22 @@ public:
params.EncodeElement(true, y, publicKey); params.EncodeElement(true, y, publicKey);
} }
/// \brief Provides the size of the ephemeral private key
/// \return size of ephemeral private keys in this domain
/// \details An ephemeral private key is a private key and public key.
/// The serialized size is different than a static private key.
unsigned int EphemeralPrivateKeyLength() const {return StaticPrivateKeyLength() + StaticPublicKeyLength();} unsigned int EphemeralPrivateKeyLength() const {return StaticPrivateKeyLength() + StaticPublicKeyLength();}
/// \brief Provides the size of the ephemeral public key
/// \return size of ephemeral public keys in this domain
/// \details An ephemeral public key is a public key.
/// The serialized size is the same as a static public key.
unsigned int EphemeralPublicKeyLength() const{return StaticPublicKeyLength();} unsigned int EphemeralPublicKeyLength() const{return StaticPublicKeyLength();}
/// return length of ephemeral private keys in this domain /// \brief Generate ephemeral private key in this domain
/// \param rng a RandomNumberGenerator derived class
/// \param privateKey a byte buffer for the generated private key in this domain
/// \pre <tt>COUNTOF(privateKey) == EphemeralPrivateKeyLength()</tt>
void GenerateEphemeralPrivateKey(RandomNumberGenerator &rng, byte *privateKey) const void GenerateEphemeralPrivateKey(RandomNumberGenerator &rng, byte *privateKey) const
{ {
const DL_GroupParameters<Element> &params = GetAbstractGroupParameters(); const DL_GroupParameters<Element> &params = GetAbstractGroupParameters();
@ -104,28 +205,46 @@ public:
params.EncodeElement(true, y, privateKey+StaticPrivateKeyLength()); params.EncodeElement(true, y, privateKey+StaticPrivateKeyLength());
} }
/// return length of ephemeral public keys in this domain /// \brief Generate ephemeral public key from a private key in this domain
/// \param rng a RandomNumberGenerator derived class
/// \param privateKey a byte buffer with the previously generated private key
/// \param publicKey a byte buffer for the generated public key in this domain
/// \pre <tt>COUNTOF(publicKey) == EphemeralPublicKeyLength()</tt>
void GenerateEphemeralPublicKey(RandomNumberGenerator &rng, const byte *privateKey, byte *publicKey) const void GenerateEphemeralPublicKey(RandomNumberGenerator &rng, const byte *privateKey, byte *publicKey) const
{ {
CRYPTOPP_UNUSED(rng); CRYPTOPP_UNUSED(rng);
memcpy(publicKey, privateKey+StaticPrivateKeyLength(), EphemeralPublicKeyLength()); memcpy(publicKey, privateKey+StaticPrivateKeyLength(), EphemeralPublicKeyLength());
} }
/// derive agreed value from your private keys and couterparty's public keys, return false in case of failure /// \brief Derive agreed value or shared secret
/*! \note The ephemeral public key will always be validated. /// \param agreedValue the shared secret
If you have previously validated the static public key, use validateStaticOtherPublicKey=false to save time. /// \param staticPrivateKey your long term private key
\pre size of agreedValue == AgreedValueLength() /// \param ephemeralPrivateKey your ephemeral private key
\pre length of staticPrivateKey == StaticPrivateKeyLength() /// \param staticOtherPublicKey couterparty's long term public key
\pre length of ephemeralPrivateKey == EphemeralPrivateKeyLength() /// \param ephemeralOtherPublicKey couterparty's ephemeral public key
\pre length of staticOtherPublicKey == StaticPublicKeyLength() /// \param validateStaticOtherPublicKey flag indicating validation
\pre length of ephemeralOtherPublicKey == EphemeralPublicKeyLength() /// \return true upon success, false in case of failure
*/ /// \details Agree() performs the authenticated key agreement. Agree()
/// derives a shared secret from your private keys and couterparty's
/// public keys. Each instance or run of the protocol should use a new
/// ephemeral key pair.
/// \details The other's ephemeral public key will always be validated at
/// Level 1 to ensure it is a point on the curve.
/// <tt>validateStaticOtherPublicKey</tt> determines how thoroughly other's
/// static public key is validated. If you have previously validated the
/// couterparty's static public key, then use
/// <tt>validateStaticOtherPublicKey=false</tt> to save time.
/// \pre <tt>COUNTOF(agreedValue) == AgreedValueLength()
/// \pre <tt>COUNTOF(staticPrivateKey) == StaticPrivateKeyLength()</tt>
/// \pre <tt>COUNTOF(ephemeralPrivateKey) == EphemeralPrivateKeyLength()</tt>
/// \pre <tt>COUNTOF(staticOtherPublicKey) == StaticPublicKeyLength()</tt>
/// \pre <tt>COUNTOF(ephemeralOtherPublicKey) == EphemeralPublicKeyLength()</tt>
bool Agree(byte *agreedValue, bool Agree(byte *agreedValue,
const byte *staticPrivateKey, const byte *ephemeralPrivateKey, const byte *staticPrivateKey, const byte *ephemeralPrivateKey,
const byte *staticOtherPublicKey, const byte *ephemeralOtherPublicKey, const byte *staticOtherPublicKey, const byte *ephemeralOtherPublicKey,
bool validateStaticOtherPublicKey=true) const bool validateStaticOtherPublicKey=true) const
{ {
byte *XX = NULLPTR, *YY = NULLPTR, *AA = NULLPTR, *BB = NULLPTR; const byte *XX = NULLPTR, *YY = NULLPTR, *AA = NULLPTR, *BB = NULLPTR;
size_t xxs = 0, yys = 0, aas = 0, bbs = 0; size_t xxs = 0, yys = 0, aas = 0, bbs = 0;
// Depending on the role, this will hold either A's or B's static // Depending on the role, this will hold either A's or B's static
@ -143,63 +262,45 @@ public:
Element B = params.ExponentiateBase(b); Element B = params.ExponentiateBase(b);
params.EncodeElement(true, B, tt); params.EncodeElement(true, B, tt);
XX = const_cast<byte*>(ephemeralOtherPublicKey); XX = ephemeralOtherPublicKey;
xxs = EphemeralPublicKeyLength(); xxs = EphemeralPublicKeyLength();
YY = const_cast<byte*>(ephemeralPrivateKey) + StaticPrivateKeyLength(); YY = ephemeralPrivateKey + StaticPrivateKeyLength();
yys = EphemeralPublicKeyLength(); yys = EphemeralPublicKeyLength();
AA = const_cast<byte*>(staticOtherPublicKey); AA = staticOtherPublicKey;
aas = StaticPublicKeyLength(); aas = StaticPublicKeyLength();
BB = tt.BytePtr(); BB = tt.BytePtr();
bbs = tt.SizeInBytes(); bbs = tt.SizeInBytes();
} }
else if(m_role == RoleClient) else
{ {
Integer a(staticPrivateKey, StaticPrivateKeyLength()); Integer a(staticPrivateKey, StaticPrivateKeyLength());
Element A = params.ExponentiateBase(a); Element A = params.ExponentiateBase(a);
params.EncodeElement(true, A, tt); params.EncodeElement(true, A, tt);
XX = const_cast<byte*>(ephemeralPrivateKey) + StaticPrivateKeyLength(); XX = ephemeralPrivateKey + StaticPrivateKeyLength();
xxs = EphemeralPublicKeyLength(); xxs = EphemeralPublicKeyLength();
YY = const_cast<byte*>(ephemeralOtherPublicKey); YY = ephemeralOtherPublicKey;
yys = EphemeralPublicKeyLength(); yys = EphemeralPublicKeyLength();
AA = tt.BytePtr(); AA = tt.BytePtr();
aas = tt.SizeInBytes(); aas = tt.SizeInBytes();
BB = const_cast<byte*>(staticOtherPublicKey); BB = staticOtherPublicKey;
bbs = StaticPublicKeyLength(); bbs = StaticPublicKeyLength();
} }
else
{
CRYPTOPP_ASSERT(0);
return false;
}
// DecodeElement calls ValidateElement at level 1. Level 1 only calls Element VV1 = params.DecodeElement(staticOtherPublicKey, validateStaticOtherPublicKey);
// VerifyPoint to ensure the element is in G*. If the other's PublicKey is Element VV2 = params.DecodeElement(ephemeralOtherPublicKey, true);
// requested to be validated, we manually call ValidateElement at level 3.
Element VV1 = params.DecodeElement(staticOtherPublicKey, false);
if(!params.ValidateElement(validateStaticOtherPublicKey ? 3 : 1, VV1, NULLPTR))
return false;
// DecodeElement calls ValidateElement at level 1. Level 1 only calls
// VerifyPoint to ensure the element is in G*. Crank it up.
Element VV2 = params.DecodeElement(ephemeralOtherPublicKey, false);
if(!params.ValidateElement(3, VV2, NULLPTR))
return false;
// const Integer& p = params.GetGroupOrder(); // not used, remove later
const Integer& q = params.GetSubgroupOrder(); const Integer& q = params.GetSubgroupOrder();
const unsigned int len /*bytes*/ = (((q.BitCount()+1)/2 +7)/8); const unsigned int len /*bytes*/ = (((q.BitCount()+1)/2 +7)/8);
Integer d, e;
SecByteBlock dd(len), ee(len); SecByteBlock dd(len), ee(len);
// Compute $d = \hat{H}(X, \hat{B})$ // Compute $d = \hat{H}(X, \hat{B})$
Hash(NULLPTR, XX, xxs, BB, bbs, dd.BytePtr(), dd.SizeInBytes()); Hash(NULLPTR, XX, xxs, BB, bbs, dd.BytePtr(), dd.SizeInBytes());
d.Decode(dd.BytePtr(), dd.SizeInBytes()); Integer d(dd.BytePtr(), dd.SizeInBytes());
// Compute $e = \hat{H}(Y, \hat{A})$ // Compute $e = \hat{H}(Y, \hat{A})$
Hash(NULLPTR, YY, yys, AA, aas, ee.BytePtr(), ee.SizeInBytes()); Hash(NULLPTR, YY, yys, AA, aas, ee.BytePtr(), ee.SizeInBytes());
e.Decode(ee.BytePtr(), ee.SizeInBytes()); Integer e(ee.BytePtr(), ee.SizeInBytes());
Element sigma; Element sigma;
if(m_role == RoleServer) if(m_role == RoleServer)
@ -226,16 +327,17 @@ public:
Element B = params.DecodeElement(BB, false); Element B = params.DecodeElement(BB, false);
Element Y = params.DecodeElement(YY, false); Element Y = params.DecodeElement(YY, false);
Element t1 = params.ExponentiateElement(B, e); Element t3 = params.ExponentiateElement(B, e);
Element t2 = m_groupParameters.MultiplyElements(Y, t1); Element t4 = m_groupParameters.MultiplyElements(Y, t3);
// $\sigma_A}=(Y \cdot B^{e})^{s_A} // $\sigma_A}=(Y \cdot B^{e})^{s_A}
sigma = params.ExponentiateElement(t2, s_A); sigma = params.ExponentiateElement(t4, s_A);
} }
Hash(&sigma, NULLPTR, 0, NULLPTR, 0, agreedValue, AgreedValueLength()); Hash(&sigma, NULLPTR, 0, NULLPTR, 0, agreedValue, AgreedValueLength());
} }
catch (DL_BadElement &) catch (DL_BadElement &)
{ {
CRYPTOPP_ASSERT(0);
return false; return false;
} }
return true; return true;
@ -259,9 +361,11 @@ protected:
if (e1len != 0 || s1len != 0) { if (e1len != 0 || s1len != 0) {
CRYPTOPP_ASSERT(0); CRYPTOPP_ASSERT(0);
} }
Integer x = GetAbstractGroupParameters().ConvertElementToInteger(*sigma); //Integer x = GetAbstractGroupParameters().ConvertElementToInteger(*sigma);
SecByteBlock sbb(x.MinEncodedSize()); //SecByteBlock sbb(x.MinEncodedSize());
x.Encode(sbb.BytePtr(), sbb.SizeInBytes()); //x.Encode(sbb.BytePtr(), sbb.SizeInBytes());
SecByteBlock sbb(GetAbstractGroupParameters().GetEncodedElementSize(false));
GetAbstractGroupParameters().EncodeElement(false, *sigma, sbb);
hash.Update(sbb.BytePtr(), sbb.SizeInBytes()); hash.Update(sbb.BytePtr(), sbb.SizeInBytes());
} else { } else {
if (e1len == 0 || s1len == 0) { if (e1len == 0 || s1len == 0) {
@ -292,8 +396,10 @@ private:
// The paper uses Initiator and Recipient - make it classical. // The paper uses Initiator and Recipient - make it classical.
enum KeyAgreementRole { RoleServer = 1, RoleClient }; enum KeyAgreementRole { RoleServer = 1, RoleClient };
DL_GroupParameters<Element> & AccessAbstractGroupParameters() {return m_groupParameters;} DL_GroupParameters<Element> & AccessAbstractGroupParameters()
const DL_GroupParameters<Element> & GetAbstractGroupParameters() const{return m_groupParameters;} {return m_groupParameters;}
const DL_GroupParameters<Element> & GetAbstractGroupParameters() const
{return m_groupParameters;}
GroupParameters m_groupParameters; GroupParameters m_groupParameters;
KeyAgreementRole m_role; KeyAgreementRole m_role;
@ -302,7 +408,7 @@ private:
/// \brief Hashed Menezes-Qu-Vanstone in GF(p) /// \brief Hashed Menezes-Qu-Vanstone in GF(p)
/// \details This implementation follows Hugo Krawczyk's <a href="http://eprint.iacr.org/2005/176">HMQV: A High-Performance /// \details This implementation follows Hugo Krawczyk's <a href="http://eprint.iacr.org/2005/176">HMQV: A High-Performance
/// Secure Diffie-Hellman Protocol</a>. Note: this implements HMQV only. HMQV-C with Key Confirmation is not provided. /// Secure Diffie-Hellman Protocol</a>. Note: this implements HMQV only. HMQV-C with Key Confirmation is not provided.
/// \sa HMQV, MQV_Domain, FHMQV_Domain, AuthenticatedKeyAgreementDomain /// \sa HMQV, HMQV_Domain, FHMQV_Domain, AuthenticatedKeyAgreementDomain
/// \since Crypto++ 5.6.4 /// \since Crypto++ 5.6.4
typedef HMQV_Domain<DL_GroupParameters_GFP_DefaultSafePrime> HMQV; typedef HMQV_Domain<DL_GroupParameters_GFP_DefaultSafePrime> HMQV;

View File

@ -18,13 +18,13 @@
// For Integer::Zero(), Integer::One() and Integer::Two(), we use one of three // For Integer::Zero(), Integer::One() and Integer::Two(), we use one of three
// strategies. First, if initialization priorities are available then we use // strategies. First, if initialization priorities are available then we use
// them. Initialization priorities are init_priority() on Linux and init_seg() // them. Initialization priorities are init_priority() on Linux and init_seg()
// on Windows. AIX, OS X and several other platforms lack them. Initialization // on Windows. OS X and several other platforms lack them. Initialization
// priorities are platform specific but they are also the most trouble free // priorities are platform specific but they are also the most trouble free
// with determisitic destruction. // with determisitic destruction.
// Second, if C++11 dynamic initialization is available, then we use it. After // Second, if C++11 dynamic initialization is available, then we use it. After
// the std::call_once fiasco we dropped the priority dynamic initialization // the std::call_once fiasco we moved to dynamic initialization to avoid
// to avoid unknown troubles platforms that are tested less frequently. In // unknown troubles platforms that are tested less frequently. In addition
// addition Microsoft platforms mostly do not provide dynamic initialization. // Microsoft platforms mostly do not provide dynamic initialization.
// The MSDN docs claim they do but they don't in practice because we need // The MSDN docs claim they do but they don't in practice because we need
// Visual Studio 2017 and Windows 10 or above. // Visual Studio 2017 and Windows 10 or above.
// Third, we fall back to Wei's original code of a Singleton. Wei's original // Third, we fall back to Wei's original code of a Singleton. Wei's original
@ -45,6 +45,12 @@
// thousands of times during the life of a program. Each load produces a // thousands of times during the life of a program. Each load produces a
// memory leak and they can add up quickly. If they library is being used in // memory leak and they can add up quickly. If they library is being used in
// Java or .Net then Singleton must be avoided at all costs. // Java or .Net then Singleton must be avoided at all costs.
//
// The code below has a path cut-in for BMI2 using mulx and adcx instructions.
// There was a modest speedup of approximately 0.03 ms in public key Integer
// operations. We had to disable BMI2 for the moment because some OS X machines
// were advertising BMI/BMI2 support but caused SIGILL's at runtime. Also see
// https://github.com/weidai11/cryptopp/issues/850.
#include "pch.h" #include "pch.h"
#include "config.h" #include "config.h"
@ -77,7 +83,8 @@
#include <c_asm.h> #include <c_asm.h>
#endif #endif
// "Error: The operand ___LKDB cannot be assigned to", http://github.com/weidai11/cryptopp/issues/188 // "Error: The operand ___LKDB cannot be assigned to",
// http://github.com/weidai11/cryptopp/issues/188
#if (__SUNPRO_CC >= 0x5130) #if (__SUNPRO_CC >= 0x5130)
# define MAYBE_CONST # define MAYBE_CONST
# define MAYBE_UNCONST_CAST(x) const_cast<word*>(x) # define MAYBE_UNCONST_CAST(x) const_cast<word*>(x)
@ -211,6 +218,13 @@ static word AtomicInverseModPower2(word A)
#if defined(__SUNPRO_CC) && __SUNPRO_CC < 0x5100 #if defined(__SUNPRO_CC) && __SUNPRO_CC < 0x5100
// Sun Studio's gcc-style inline assembly is heavily bugged as of version 5.9 Patch 124864-09 2008/12/16, but this one works // Sun Studio's gcc-style inline assembly is heavily bugged as of version 5.9 Patch 124864-09 2008/12/16, but this one works
#define MultiplyWordsLoHi(p0, p1, a, b) asm ("mulq %3" : "=a"(p0), "=d"(p1) : "a"(a), "r"(b) : "cc"); #define MultiplyWordsLoHi(p0, p1, a, b) asm ("mulq %3" : "=a"(p0), "=d"(p1) : "a"(a), "r"(b) : "cc");
#elif defined(__BMI2__) && 0
#define MultiplyWordsLoHi(p0, p1, a, b) asm ("mulxq %3, %0, %1" : "=r"(p0), "=r"(p1) : "d"(a), "r"(b));
#define MulAcc(c, d, a, b) asm ("mulxq %6, %3, %4; addq %3, %0; adcxq %4, %1; adcxq %7, %2;" : "+&r"(c), "+&r"(d##0), "+&r"(d##1), "=&r"(p0), "=&r"(p1) : "d"(a), "r"(b), "r"(W64LIT(0)) : "cc");
#define Double3Words(c, d) asm ("addq %0, %0; adcxq %1, %1; adcxq %2, %2;" : "+r"(c), "+r"(d##0), "+r"(d##1) : : "cc");
#define Acc2WordsBy1(a, b) asm ("addq %2, %0; adcxq %3, %1;" : "+&r"(a##0), "+r"(a##1) : "r"(b), "r"(W64LIT(0)) : "cc");
#define Acc2WordsBy2(a, b) asm ("addq %2, %0; adcxq %3, %1;" : "+r"(a##0), "+r"(a##1) : "r"(b##0), "r"(b##1) : "cc");
#define Acc3WordsBy2(c, d, e) asm ("addq %5, %0; adcxq %6, %1; adcxq %7, %2;" : "+r"(c), "=&r"(e##0), "=&r"(e##1) : "1"(d##0), "2"(d##1), "r"(e##0), "r"(e##1), "r"(W64LIT(0)) : "cc");
#else #else
#define MultiplyWordsLoHi(p0, p1, a, b) asm ("mulq %3" : "=a"(p0), "=d"(p1) : "a"(a), "g"(b) : "cc"); #define MultiplyWordsLoHi(p0, p1, a, b) asm ("mulq %3" : "=a"(p0), "=d"(p1) : "a"(a), "g"(b) : "cc");
#define MulAcc(c, d, a, b) asm ("mulq %6; addq %3, %0; adcq %4, %1; adcq $0, %2;" : "+r"(c), "+r"(d##0), "+r"(d##1), "=a"(p0), "=d"(p1) : "a"(a), "g"(b) : "cc"); #define MulAcc(c, d, a, b) asm ("mulq %6; addq %3, %0; adcq %4, %1; adcq $0, %2;" : "+r"(c), "+r"(d##0), "+r"(d##1), "=a"(p0), "=d"(p1) : "a"(a), "g"(b) : "cc");
@ -3537,9 +3551,9 @@ class KDF2_RNG : public RandomNumberGenerator
{ {
public: public:
KDF2_RNG(const byte *seed, size_t seedSize) KDF2_RNG(const byte *seed, size_t seedSize)
: m_counter(0), m_counterAndSeed(seedSize + 4) : m_counter(0), m_counterAndSeed(ClampSize(seedSize) + 4)
{ {
memcpy(m_counterAndSeed + 4, seed, seedSize); memcpy(m_counterAndSeed + 4, seed, ClampSize(seedSize));
} }
void GenerateBlock(byte *output, size_t size) void GenerateBlock(byte *output, size_t size)
@ -3550,6 +3564,15 @@ public:
P1363_KDF2<SHA1>::DeriveKey(output, size, m_counterAndSeed, m_counterAndSeed.size(), NULLPTR, 0); P1363_KDF2<SHA1>::DeriveKey(output, size, m_counterAndSeed, m_counterAndSeed.size(), NULLPTR, 0);
} }
// UBsan finding, -Wstringop-overflow
inline size_t ClampSize(size_t req) const
{
// Clamp at 16 MB
if (req > 16U*1024*1024)
return 16U*1024*1024;
return req;
}
private: private:
word32 m_counter; word32 m_counter;
SecByteBlock m_counterAndSeed; SecByteBlock m_counterAndSeed;

View File

@ -306,13 +306,16 @@ public:
signed long ConvertToLong() const; signed long ConvertToLong() const;
/// \brief Determines the number of bits required to represent the Integer /// \brief Determines the number of bits required to represent the Integer
/// \returns number of significant bits = floor(log2(abs(*this))) + 1 /// \returns number of significant bits
/// \details BitCount is calculated as <tt>floor(log2(abs(*this))) + 1</tt>.
unsigned int BitCount() const; unsigned int BitCount() const;
/// \brief Determines the number of bytes required to represent the Integer /// \brief Determines the number of bytes required to represent the Integer
/// \returns number of significant bytes = ceiling(BitCount()/8) /// \returns number of significant bytes
/// \details ByteCount is calculated as <tt>ceiling(BitCount()/8)</tt>.
unsigned int ByteCount() const; unsigned int ByteCount() const;
/// \brief Determines the number of words required to represent the Integer /// \brief Determines the number of words required to represent the Integer
/// \returns number of significant words = ceiling(ByteCount()/sizeof(word)) /// \returns number of significant words
/// \details WordCount is calculated as <tt>ceiling(ByteCount()/sizeof(word))</tt>.
unsigned int WordCount() const; unsigned int WordCount() const;
/// \brief Provides the i-th bit of the Integer /// \brief Provides the i-th bit of the Integer
@ -354,29 +357,48 @@ public:
/// \name MANIPULATORS /// \name MANIPULATORS
//@{ //@{
/// \brief Assignment /// \brief Assignment
/// \param t the other Integer
/// \returns the result of assignment
Integer& operator=(const Integer& t); Integer& operator=(const Integer& t);
/// \brief Addition Assignment /// \brief Addition Assignment
/// \param t the other Integer
/// \returns the result of <tt>*this + t</tt>
Integer& operator+=(const Integer& t); Integer& operator+=(const Integer& t);
/// \brief Subtraction Assignment /// \brief Subtraction Assignment
/// \param t the other Integer
/// \returns the result of <tt>*this - t</tt>
Integer& operator-=(const Integer& t); Integer& operator-=(const Integer& t);
/// \brief Multiplication Assignment /// \brief Multiplication Assignment
/// \param t the other Integer
/// \returns the result of <tt>*this * t</tt>
/// \sa a_times_b_mod_c() and a_exp_b_mod_c() /// \sa a_times_b_mod_c() and a_exp_b_mod_c()
Integer& operator*=(const Integer& t) {return *this = Times(t);} Integer& operator*=(const Integer& t) {return *this = Times(t);}
/// \brief Division Assignment /// \brief Division Assignment
/// \param t the other Integer
/// \returns the result of <tt>*this / t</tt>
Integer& operator/=(const Integer& t) {return *this = DividedBy(t);} Integer& operator/=(const Integer& t) {return *this = DividedBy(t);}
/// \brief Remainder Assignment /// \brief Remainder Assignment
/// \param t the other Integer
/// \returns the result of <tt>*this % t</tt>
/// \sa a_times_b_mod_c() and a_exp_b_mod_c() /// \sa a_times_b_mod_c() and a_exp_b_mod_c()
Integer& operator%=(const Integer& t) {return *this = Modulo(t);} Integer& operator%=(const Integer& t) {return *this = Modulo(t);}
/// \brief Division Assignment /// \brief Division Assignment
/// \param t the other word
/// \returns the result of <tt>*this / t</tt>
Integer& operator/=(word t) {return *this = DividedBy(t);} Integer& operator/=(word t) {return *this = DividedBy(t);}
/// \brief Remainder Assignment /// \brief Remainder Assignment
/// \param t the other word
/// \returns the result of <tt>*this % t</tt>
/// \sa a_times_b_mod_c() and a_exp_b_mod_c() /// \sa a_times_b_mod_c() and a_exp_b_mod_c()
Integer& operator%=(word t) {return *this = Integer(POSITIVE, 0, Modulo(t));} Integer& operator%=(word t) {return *this = Integer(POSITIVE, 0, Modulo(t));}
/// \brief Left-shift Assignment /// \brief Left-shift Assignment
/// \param n number of bits to shift
/// \returns reference to this Integer
Integer& operator<<=(size_t n); Integer& operator<<=(size_t n);
/// \brief Right-shift Assignment /// \brief Right-shift Assignment
/// \param n number of bits to shift
/// \returns reference to this Integer
Integer& operator>>=(size_t n); Integer& operator>>=(size_t n);
/// \brief Bitwise AND Assignment /// \brief Bitwise AND Assignment

View File

@ -94,8 +94,6 @@ private:
#if !defined(__BORLANDC__) #if !defined(__BORLANDC__)
// ensure there was no underflow in the math // ensure there was no underflow in the math
CRYPTOPP_COMPILE_ASSERT(BLOCKSIZE < 200); CRYPTOPP_COMPILE_ASSERT(BLOCKSIZE < 200);
// this is a general expectation by HMAC
CRYPTOPP_COMPILE_ASSERT((int)BLOCKSIZE > (int)DIGESTSIZE);
#endif #endif
}; };

View File

@ -12,8 +12,8 @@
// KeccakF1600x2_SSE is ParallelHash128. The SSE2 ParallelHash128 // KeccakF1600x2_SSE is ParallelHash128. The SSE2 ParallelHash128
// implementation was extracted from XKCP using the following command. // implementation was extracted from XKCP using the following command.
// //
// gcc -I lib/common -I lib/low/KeccakP-1600/Optimized \ // gcc -I lib/common -I lib/low/KeccakP-1600/Optimized
// -I lib/low/KeccakP-1600-times2/SIMD128/SSE2ufull \ // -I lib/low/KeccakP-1600-times2/SIMD128/SSE2ufull
// lib/low/KeccakP-1600-times2/SIMD128/KeccakP-1600-times2-SIMD128.c -E // lib/low/KeccakP-1600-times2/SIMD128/KeccakP-1600-times2-SIMD128.c -E
#include "pch.h" #include "pch.h"
@ -23,7 +23,14 @@
#if (CRYPTOPP_SSSE3_AVAILABLE) #if (CRYPTOPP_SSSE3_AVAILABLE)
# include <emmintrin.h> # include <emmintrin.h>
# include <immintrin.h> # include <tmmintrin.h>
#endif
#if defined(__XOP__)
# include <ammintrin.h>
# if defined(__GNUC__)
# include <x86intrin.h>
# endif
#endif #endif
// Squash MS LNK4221 and libtool warnings // Squash MS LNK4221 and libtool warnings
@ -39,16 +46,17 @@ extern void KeccakF1600x2_SSE(word64 *state);
// The F1600 round constants // The F1600 round constants
extern const word64 KeccakF1600Constants[24]; extern const word64 KeccakF1600Constants[24];
const word64 rho8[2] = {0x0605040302010007, 0x0E0D0C0B0A09080F}; CRYPTOPP_ALIGN_DATA(16)
const word64 rho56[2] = {0x0007060504030201, 0x080F0E0D0C0B0A09}; const word64
rho8[2] = {W64LIT(0x0605040302010007), W64LIT(0x0E0D0C0B0A09080F)};
#define V128 __m128i CRYPTOPP_ALIGN_DATA(16)
#define CV128 const __m128i const word64
rho56[2] = {W64LIT(0x0007060504030201), W64LIT(0x080F0E0D0C0B0A09)};
#define CONST128(a) _mm_load_si128((CV128 *)&(a)) // Clang intrinsic casts, http://bugs.llvm.org/show_bug.cgi?id=20670
#define XOREQ128(a, b) a = _mm_xor_si128((a), (b)) #define M128_CAST(x) ((__m128i *)(void *)(x))
#define UNPACKL(a, b) _mm_unpacklo_epi64((a), (b)) #define CONST_M128_CAST(x) ((const __m128i *)(const void *)(x))
#define UNPACKH(a, b) _mm_unpackhi_epi64((a), (b))
#if defined(__XOP__) #if defined(__XOP__)
# define ROL64in128(a, o) _mm_roti_epi64((a), (o)) # define ROL64in128(a, o) _mm_roti_epi64((a), (o))
@ -56,8 +64,8 @@ const word64 rho56[2] = {0x0007060504030201, 0x080F0E0D0C0B0A09};
# define ROL64in128_56(a) ROL64in128((a), 56) # define ROL64in128_56(a) ROL64in128((a), 56)
#else #else
# define ROL64in128(a, o) _mm_or_si128(_mm_slli_epi64((a), (o)), _mm_srli_epi64(a, 64-(o))) # define ROL64in128(a, o) _mm_or_si128(_mm_slli_epi64((a), (o)), _mm_srli_epi64(a, 64-(o)))
# define ROL64in128_8(a) _mm_shuffle_epi8((a), CONST128(rho8)) # define ROL64in128_8(a) _mm_shuffle_epi8((a), _mm_load_si128(CONST_M128_CAST(rho8)))
# define ROL64in128_56(a) _mm_shuffle_epi8((a), CONST128(rho56)) # define ROL64in128_56(a) _mm_shuffle_epi8((a), _mm_load_si128(CONST_M128_CAST(rho56)))
#endif #endif
// Damn Visual Studio is missing too many intrinsics... // Damn Visual Studio is missing too many intrinsics...
@ -74,51 +82,50 @@ inline __m128i SPLAT64(const word64 a)
// The Keccak ParallelHash128 core function // The Keccak ParallelHash128 core function
void KeccakF1600x2_SSE(word64 *state) void KeccakF1600x2_SSE(word64 *state)
{ {
V128 *statesAsLanes = (V128 *)state; __m128i Aba, Abe, Abi, Abo, Abu;
__m128i Aga, Age, Agi, Ago, Agu;
__m128i Aka, Ake, Aki, Ako, Aku;
__m128i Ama, Ame, Ami, Amo, Amu;
__m128i Asa, Ase, Asi, Aso, Asu;
__m128i Bba, Bbe, Bbi, Bbo, Bbu;
__m128i Bga, Bge, Bgi, Bgo, Bgu;
__m128i Bka, Bke, Bki, Bko, Bku;
__m128i Bma, Bme, Bmi, Bmo, Bmu;
__m128i Bsa, Bse, Bsi, Bso, Bsu;
__m128i Ca, Ce, Ci, Co, Cu;
__m128i Da, De, Di, Do, Du;
__m128i Eba, Ebe, Ebi, Ebo, Ebu;
__m128i Ega, Ege, Egi, Ego, Egu;
__m128i Eka, Eke, Eki, Eko, Eku;
__m128i Ema, Eme, Emi, Emo, Emu;
__m128i Esa, Ese, Esi, Eso, Esu;
V128 Aba, Abe, Abi, Abo, Abu; __m128i* lanes = reinterpret_cast<__m128i*>(state);
V128 Aga, Age, Agi, Ago, Agu; Aba = _mm_loadu_si128(CONST_M128_CAST(lanes+ 0));
V128 Aka, Ake, Aki, Ako, Aku; Abe = _mm_loadu_si128(CONST_M128_CAST(lanes+ 1));
V128 Ama, Ame, Ami, Amo, Amu; Abi = _mm_loadu_si128(CONST_M128_CAST(lanes+ 2));
V128 Asa, Ase, Asi, Aso, Asu; Abo = _mm_loadu_si128(CONST_M128_CAST(lanes+ 3));
V128 Bba, Bbe, Bbi, Bbo, Bbu; Abu = _mm_loadu_si128(CONST_M128_CAST(lanes+ 4));
V128 Bga, Bge, Bgi, Bgo, Bgu; Aga = _mm_loadu_si128(CONST_M128_CAST(lanes+ 5));
V128 Bka, Bke, Bki, Bko, Bku; Age = _mm_loadu_si128(CONST_M128_CAST(lanes+ 6));
V128 Bma, Bme, Bmi, Bmo, Bmu; Agi = _mm_loadu_si128(CONST_M128_CAST(lanes+ 7));
V128 Bsa, Bse, Bsi, Bso, Bsu; Ago = _mm_loadu_si128(CONST_M128_CAST(lanes+ 8));
V128 Ca, Ce, Ci, Co, Cu; Agu = _mm_loadu_si128(CONST_M128_CAST(lanes+ 9));
V128 Da, De, Di, Do, Du; Aka = _mm_loadu_si128(CONST_M128_CAST(lanes+10));
V128 Eba, Ebe, Ebi, Ebo, Ebu; Ake = _mm_loadu_si128(CONST_M128_CAST(lanes+11));
V128 Ega, Ege, Egi, Ego, Egu; Aki = _mm_loadu_si128(CONST_M128_CAST(lanes+12));
V128 Eka, Eke, Eki, Eko, Eku; Ako = _mm_loadu_si128(CONST_M128_CAST(lanes+13));
V128 Ema, Eme, Emi, Emo, Emu; Aku = _mm_loadu_si128(CONST_M128_CAST(lanes+14));
V128 Esa, Ese, Esi, Eso, Esu; Ama = _mm_loadu_si128(CONST_M128_CAST(lanes+15));
Ame = _mm_loadu_si128(CONST_M128_CAST(lanes+16));
Aba = _mm_loadu_si128((CV128 *)&(statesAsLanes[ 0])); Ami = _mm_loadu_si128(CONST_M128_CAST(lanes+17));
Abe = _mm_loadu_si128((CV128 *)&(statesAsLanes[ 1])); Amo = _mm_loadu_si128(CONST_M128_CAST(lanes+18));
Abi = _mm_loadu_si128((CV128 *)&(statesAsLanes[ 2])); Amu = _mm_loadu_si128(CONST_M128_CAST(lanes+19));
Abo = _mm_loadu_si128((CV128 *)&(statesAsLanes[ 3])); Asa = _mm_loadu_si128(CONST_M128_CAST(lanes+20));
Abu = _mm_loadu_si128((CV128 *)&(statesAsLanes[ 4])); Ase = _mm_loadu_si128(CONST_M128_CAST(lanes+21));
Aga = _mm_loadu_si128((CV128 *)&(statesAsLanes[ 5])); Asi = _mm_loadu_si128(CONST_M128_CAST(lanes+22));
Age = _mm_loadu_si128((CV128 *)&(statesAsLanes[ 6])); Aso = _mm_loadu_si128(CONST_M128_CAST(lanes+23));
Agi = _mm_loadu_si128((CV128 *)&(statesAsLanes[ 7])); Asu = _mm_loadu_si128(CONST_M128_CAST(lanes+24));
Ago = _mm_loadu_si128((CV128 *)&(statesAsLanes[ 8]));
Agu = _mm_loadu_si128((CV128 *)&(statesAsLanes[ 9]));
Aka = _mm_loadu_si128((CV128 *)&(statesAsLanes[10]));
Ake = _mm_loadu_si128((CV128 *)&(statesAsLanes[11]));
Aki = _mm_loadu_si128((CV128 *)&(statesAsLanes[12]));
Ako = _mm_loadu_si128((CV128 *)&(statesAsLanes[13]));
Aku = _mm_loadu_si128((CV128 *)&(statesAsLanes[14]));
Ama = _mm_loadu_si128((CV128 *)&(statesAsLanes[15]));
Ame = _mm_loadu_si128((CV128 *)&(statesAsLanes[16]));
Ami = _mm_loadu_si128((CV128 *)&(statesAsLanes[17]));
Amo = _mm_loadu_si128((CV128 *)&(statesAsLanes[18]));
Amu = _mm_loadu_si128((CV128 *)&(statesAsLanes[19]));
Asa = _mm_loadu_si128((CV128 *)&(statesAsLanes[20]));
Ase = _mm_loadu_si128((CV128 *)&(statesAsLanes[21]));
Asi = _mm_loadu_si128((CV128 *)&(statesAsLanes[22]));
Aso = _mm_loadu_si128((CV128 *)&(statesAsLanes[23]));
Asu = _mm_loadu_si128((CV128 *)&(statesAsLanes[24]));
Ca = _mm_xor_si128(Aba, _mm_xor_si128(Aga, _mm_xor_si128(Aka, _mm_xor_si128(Ama, Asa)))); Ca = _mm_xor_si128(Aba, _mm_xor_si128(Aga, _mm_xor_si128(Aka, _mm_xor_si128(Ama, Asa))));
Ce = _mm_xor_si128(Abe, _mm_xor_si128(Age, _mm_xor_si128(Ake, _mm_xor_si128(Ame, Ase)))); Ce = _mm_xor_si128(Abe, _mm_xor_si128(Age, _mm_xor_si128(Ake, _mm_xor_si128(Ame, Ase))));
@ -2646,31 +2653,31 @@ void KeccakF1600x2_SSE(word64 *state)
Aso = _mm_xor_si128(Bso, _mm_andnot_si128(Bsu, Bsa)); Aso = _mm_xor_si128(Bso, _mm_andnot_si128(Bsu, Bsa));
Asu = _mm_xor_si128(Bsu, _mm_andnot_si128(Bsa, Bse)); Asu = _mm_xor_si128(Bsu, _mm_andnot_si128(Bsa, Bse));
_mm_storeu_si128((V128 *)&(statesAsLanes[ 0]), Aba); _mm_storeu_si128(M128_CAST(lanes+ 0), Aba);
_mm_storeu_si128((V128 *)&(statesAsLanes[ 1]), Abe); _mm_storeu_si128(M128_CAST(lanes+ 1), Abe);
_mm_storeu_si128((V128 *)&(statesAsLanes[ 2]), Abi); _mm_storeu_si128(M128_CAST(lanes+ 2), Abi);
_mm_storeu_si128((V128 *)&(statesAsLanes[ 3]), Abo); _mm_storeu_si128(M128_CAST(lanes+ 3), Abo);
_mm_storeu_si128((V128 *)&(statesAsLanes[ 4]), Abu); _mm_storeu_si128(M128_CAST(lanes+ 4), Abu);
_mm_storeu_si128((V128 *)&(statesAsLanes[ 5]), Aga); _mm_storeu_si128(M128_CAST(lanes+ 5), Aga);
_mm_storeu_si128((V128 *)&(statesAsLanes[ 6]), Age); _mm_storeu_si128(M128_CAST(lanes+ 6), Age);
_mm_storeu_si128((V128 *)&(statesAsLanes[ 7]), Agi); _mm_storeu_si128(M128_CAST(lanes+ 7), Agi);
_mm_storeu_si128((V128 *)&(statesAsLanes[ 8]), Ago); _mm_storeu_si128(M128_CAST(lanes+ 8), Ago);
_mm_storeu_si128((V128 *)&(statesAsLanes[ 9]), Agu); _mm_storeu_si128(M128_CAST(lanes+ 9), Agu);
_mm_storeu_si128((V128 *)&(statesAsLanes[10]), Aka); _mm_storeu_si128(M128_CAST(lanes+10), Aka);
_mm_storeu_si128((V128 *)&(statesAsLanes[11]), Ake); _mm_storeu_si128(M128_CAST(lanes+11), Ake);
_mm_storeu_si128((V128 *)&(statesAsLanes[12]), Aki); _mm_storeu_si128(M128_CAST(lanes+12), Aki);
_mm_storeu_si128((V128 *)&(statesAsLanes[13]), Ako); _mm_storeu_si128(M128_CAST(lanes+13), Ako);
_mm_storeu_si128((V128 *)&(statesAsLanes[14]), Aku); _mm_storeu_si128(M128_CAST(lanes+14), Aku);
_mm_storeu_si128((V128 *)&(statesAsLanes[15]), Ama); _mm_storeu_si128(M128_CAST(lanes+15), Ama);
_mm_storeu_si128((V128 *)&(statesAsLanes[16]), Ame); _mm_storeu_si128(M128_CAST(lanes+16), Ame);
_mm_storeu_si128((V128 *)&(statesAsLanes[17]), Ami); _mm_storeu_si128(M128_CAST(lanes+17), Ami);
_mm_storeu_si128((V128 *)&(statesAsLanes[18]), Amo); _mm_storeu_si128(M128_CAST(lanes+18), Amo);
_mm_storeu_si128((V128 *)&(statesAsLanes[19]), Amu); _mm_storeu_si128(M128_CAST(lanes+19), Amu);
_mm_storeu_si128((V128 *)&(statesAsLanes[20]), Asa); _mm_storeu_si128(M128_CAST(lanes+20), Asa);
_mm_storeu_si128((V128 *)&(statesAsLanes[21]), Ase); _mm_storeu_si128(M128_CAST(lanes+21), Ase);
_mm_storeu_si128((V128 *)&(statesAsLanes[22]), Asi); _mm_storeu_si128(M128_CAST(lanes+22), Asi);
_mm_storeu_si128((V128 *)&(statesAsLanes[23]), Aso); _mm_storeu_si128(M128_CAST(lanes+23), Aso);
_mm_storeu_si128((V128 *)&(statesAsLanes[24]), Asu); _mm_storeu_si128(M128_CAST(lanes+24), Asu);
} }
#endif #endif

2
lea.h
View File

@ -82,7 +82,7 @@ public:
#endif #endif
}; };
/// \brief Encryption transformation /// \brief Decryption transformation
/// \details Dec provides implementation for decryption transformation. All key and block /// \details Dec provides implementation for decryption transformation. All key and block
/// sizes are supported. /// sizes are supported.
/// \since Crypto++ 8.0 /// \since Crypto++ 8.0

View File

@ -24,6 +24,9 @@
#if defined(__XOP__) #if defined(__XOP__)
# include <ammintrin.h> # include <ammintrin.h>
# if defined(__GNUC__)
# include <x86intrin.h>
# endif
#endif #endif
#if defined(__AVX512F__) #if defined(__AVX512F__)

View File

@ -101,12 +101,12 @@ bool VerifyBufsEqual(const byte *buf, const byte *mask, size_t count)
{ {
CRYPTOPP_ASSERT(buf != NULLPTR); CRYPTOPP_ASSERT(buf != NULLPTR);
CRYPTOPP_ASSERT(mask != NULLPTR); CRYPTOPP_ASSERT(mask != NULLPTR);
CRYPTOPP_ASSERT(count > 0); // CRYPTOPP_ASSERT(count > 0);
size_t i=0; size_t i=0;
byte acc8 = 0; byte acc8 = 0;
if (IsAligned<word32>(buf) && IsAligned<word32>(mask)) if (IsAligned<word32>(buf) && IsAligned<word32>(mask) && count)
{ {
word32 acc32 = 0; word32 acc32 = 0;
if (!CRYPTOPP_BOOL_SLOW_WORD64 && IsAligned<word64>(buf) && IsAligned<word64>(mask)) if (!CRYPTOPP_BOOL_SLOW_WORD64 && IsAligned<word64>(buf) && IsAligned<word64>(mask))

210
misc.h
View File

@ -62,36 +62,66 @@
#include <stdlib.h> #include <stdlib.h>
#endif #endif
#if defined(__GNUC__) && defined(__linux__) #if (defined(__GNUC__) || defined(__clang__)) && defined(__linux__)
#define CRYPTOPP_BYTESWAP_AVAILABLE #define CRYPTOPP_BYTESWAP_AVAILABLE 1
#include <byteswap.h> #include <byteswap.h>
#endif #endif
// Limit to ARM A-32. Aarch64 is failing self tests.
#if defined(__arm__) && (defined(__GNUC__) || defined(__clang__)) && (__ARM_ARCH >= 6)
#define CRYPTOPP_ARM_BYTEREV_AVAILABLE 1
#endif
// Limit to ARM A-32. Aarch64 is failing self tests.
#if defined(__arm__) && (defined(__GNUC__) || defined(__clang__)) && (__ARM_ARCH >= 7)
#define CRYPTOPP_ARM_BITREV_AVAILABLE 1
#endif
#if defined(__BMI__) #if defined(__BMI__)
# include <x86intrin.h> # include <x86intrin.h>
# include <immintrin.h>
#endif // GCC and BMI #endif // GCC and BMI
// More LLVM bullshit. Apple Clang 6.0 does not define them.
// Later version of Clang defines them and results in warnings.
#if defined(__clang__)
# ifndef _blsr_u32
# define _blsr_u32 __blsr_u32
# endif
# ifndef _blsr_u64
# define _blsr_u64 __blsr_u64
# endif
# ifndef _tzcnt_u32
# define _tzcnt_u32 __tzcnt_u32
# endif
# ifndef _tzcnt_u64
# define _tzcnt_u64 __tzcnt_u64
# endif
#endif
#endif // CRYPTOPP_DOXYGEN_PROCESSING #endif // CRYPTOPP_DOXYGEN_PROCESSING
#if CRYPTOPP_DOXYGEN_PROCESSING #if CRYPTOPP_DOXYGEN_PROCESSING
/// \brief The maximum value of a machine word /// \brief The maximum value of a machine word
/// \details SIZE_MAX provides the maximum value of a machine word. The value is /// \details <tt>SIZE_MAX</tt> provides the maximum value of a machine word. The value
/// 0xffffffff on 32-bit machines, and 0xffffffffffffffff on 64-bit machines. /// is <tt>0xffffffff</tt> on 32-bit targets, and <tt>0xffffffffffffffff</tt> on 64-bit
/// Internally, SIZE_MAX is defined as __SIZE_MAX__ if __SIZE_MAX__ is defined. If not /// targets.
/// defined, then SIZE_T_MAX is tried. If neither __SIZE_MAX__ nor SIZE_T_MAX is /// \details If <tt>SIZE_MAX</tt> is not defined, then <tt>__SIZE_MAX__</tt> is used if
/// is defined, the library uses std::numeric_limits<size_t>::max(). The library /// defined. If not defined, then <tt>SIZE_T_MAX</tt> is used if defined. If not defined,
/// prefers __SIZE_MAX__ because its a constexpr that is optimized well /// then the library uses <tt>std::numeric_limits<size_t>::max()</tt>.
/// by all compilers. std::numeric_limits<size_t>::max() is not a constexpr, /// \details The library prefers <tt>__SIZE_MAX__</tt> or <tt>__SIZE_T_MAX__</tt> because
/// and it is not always optimized well. /// they are effectively <tt>constexpr</tt> that is optimized well by all compilers.
/// <tt>std::numeric_limits<size_t>::max()</tt> is not always a <tt>constexpr</tt>, and
/// it is not always optimized well.
# define SIZE_MAX ... # define SIZE_MAX ...
#else #else
// Its amazing portability problems still plague this simple concept in 2015. // Its amazing portability problems still plague this simple concept in 2015.
// http://stackoverflow.com/questions/30472731/which-c-standard-header-defines-size-max // http://stackoverflow.com/questions/30472731/which-c-standard-header-defines-size-max
// Avoid NOMINMAX macro on Windows. http://support.microsoft.com/en-us/kb/143208 // Avoid NOMINMAX macro on Windows. http://support.microsoft.com/en-us/kb/143208
#ifndef SIZE_MAX #ifndef SIZE_MAX
# if defined(__SIZE_MAX__) && (__SIZE_MAX__ > 0) # if defined(__SIZE_MAX__)
# define SIZE_MAX __SIZE_MAX__ # define SIZE_MAX __SIZE_MAX__
# elif defined(SIZE_T_MAX) && (SIZE_T_MAX > 0) # elif defined(SIZE_T_MAX)
# define SIZE_MAX SIZE_T_MAX # define SIZE_MAX SIZE_T_MAX
# elif defined(__SIZE_TYPE__) # elif defined(__SIZE_TYPE__)
# define SIZE_MAX (~(__SIZE_TYPE__)0) # define SIZE_MAX (~(__SIZE_TYPE__)0)
@ -112,8 +142,13 @@ class Integer;
#if CRYPTOPP_DOXYGEN_PROCESSING #if CRYPTOPP_DOXYGEN_PROCESSING
/// \brief Compile time assertion /// \brief Compile time assertion
/// \param expr the expression to evaluate /// \param expr the expression to evaluate
/// \details Asserts the expression expr though a dummy struct. /// \details Asserts the expression <tt>expr</tt> during compile. If C++14 and
/// N3928 are available, then C++14 <tt>static_assert</tt> is used. Otherwise,
/// a <tt>CompileAssert</tt> structure is used. When the structure is used
/// a negative-sized array triggers the assert at compile time.
# define CRYPTOPP_COMPILE_ASSERT(expr) { ... } # define CRYPTOPP_COMPILE_ASSERT(expr) { ... }
#elif defined(CRYPTOPP_CXX14_STATIC_ASSERT)
# define CRYPTOPP_COMPILE_ASSERT(expr) static_assert(expr)
#else // CRYPTOPP_DOXYGEN_PROCESSING #else // CRYPTOPP_DOXYGEN_PROCESSING
template <bool b> template <bool b>
struct CompileAssert struct CompileAssert
@ -122,10 +157,13 @@ struct CompileAssert
}; };
#define CRYPTOPP_COMPILE_ASSERT(assertion) CRYPTOPP_COMPILE_ASSERT_INSTANCE(assertion, __LINE__) #define CRYPTOPP_COMPILE_ASSERT(assertion) CRYPTOPP_COMPILE_ASSERT_INSTANCE(assertion, __LINE__)
#define CRYPTOPP_ASSERT_JOIN(X, Y) CRYPTOPP_DO_ASSERT_JOIN(X, Y)
#define CRYPTOPP_DO_ASSERT_JOIN(X, Y) X##Y
#if defined(CRYPTOPP_EXPORTS) || defined(CRYPTOPP_IMPORTS) #if defined(CRYPTOPP_EXPORTS) || defined(CRYPTOPP_IMPORTS)
# define CRYPTOPP_COMPILE_ASSERT_INSTANCE(assertion, instance) # define CRYPTOPP_COMPILE_ASSERT_INSTANCE(assertion, instance)
#else #else
# if defined(__GNUC__) # if defined(__GNUC__) || defined(__clang__)
# define CRYPTOPP_COMPILE_ASSERT_INSTANCE(assertion, instance) \ # define CRYPTOPP_COMPILE_ASSERT_INSTANCE(assertion, instance) \
static CompileAssert<(assertion)> \ static CompileAssert<(assertion)> \
CRYPTOPP_ASSERT_JOIN(cryptopp_CRYPTOPP_ASSERT_, instance) __attribute__ ((unused)) CRYPTOPP_ASSERT_JOIN(cryptopp_CRYPTOPP_ASSERT_, instance) __attribute__ ((unused))
@ -133,10 +171,8 @@ struct CompileAssert
# define CRYPTOPP_COMPILE_ASSERT_INSTANCE(assertion, instance) \ # define CRYPTOPP_COMPILE_ASSERT_INSTANCE(assertion, instance) \
static CompileAssert<(assertion)> \ static CompileAssert<(assertion)> \
CRYPTOPP_ASSERT_JOIN(cryptopp_CRYPTOPP_ASSERT_, instance) CRYPTOPP_ASSERT_JOIN(cryptopp_CRYPTOPP_ASSERT_, instance)
# endif // __GNUC__ # endif // GCC or Clang
#endif #endif
#define CRYPTOPP_ASSERT_JOIN(X, Y) CRYPTOPP_DO_ASSERT_JOIN(X, Y)
#define CRYPTOPP_DO_ASSERT_JOIN(X, Y) X##Y
#endif // CRYPTOPP_DOXYGEN_PROCESSING #endif // CRYPTOPP_DOXYGEN_PROCESSING
@ -194,16 +230,21 @@ protected:
/// \brief Ensures an object is not copyable /// \brief Ensures an object is not copyable
/// \details NotCopyable ensures an object is not copyable by making the /// \details NotCopyable ensures an object is not copyable by making the
/// copy constructor and assignment operator private. Deleters are not /// copy constructor and assignment operator private. Deleters are used
/// used under C++11. /// under C++11.
/// \sa Clonable class /// \sa Clonable class
class NotCopyable class NotCopyable
{ {
public: public:
NotCopyable() {} NotCopyable() {}
#if CRYPTOPP_CXX11_DELETED_FUNCTIONS
NotCopyable(const NotCopyable &) = delete;
void operator=(const NotCopyable &) = delete;
#else
private: private:
NotCopyable(const NotCopyable &); NotCopyable(const NotCopyable &);
void operator=(const NotCopyable &); void operator=(const NotCopyable &);
#endif
}; };
/// \brief An object factory function /// \brief An object factory function
@ -388,6 +429,38 @@ inline size_t PtrByteDiff(const PTR pointer1, const PTR pointer2)
return (size_t)(reinterpret_cast<uintptr_t>(pointer1) - reinterpret_cast<uintptr_t>(pointer2)); return (size_t)(reinterpret_cast<uintptr_t>(pointer1) - reinterpret_cast<uintptr_t>(pointer2));
} }
/// \brief Pointer to the first element of a string
/// \param str std::string
/// \details BytePtr returns NULL pointer for an empty string.
/// \return Pointer to the first element of a string
inline byte* BytePtr(std::string& str)
{
// Caller wants a writeable pointer
CRYPTOPP_ASSERT(str.empty() == false);
if (str.empty())
return NULLPTR;
return reinterpret_cast<byte*>(&str[0]);
}
/// \brief Const pointer to the first element of a string
/// \param str std::string
/// \details ConstBytePtr returns non-NULL pointer for an empty string.
/// \return Pointer to the first element of a string
inline const byte* ConstBytePtr(const std::string& str)
{
// Use c_str() so a pointer is always available
return reinterpret_cast<const byte*>(str.c_str());
}
/// \brief Size of a string
/// \param str std::string
/// \return size of a string
inline size_t BytePtrSize(const std::string& str)
{
return str.size();
}
#if (!__STDC_WANT_SECURE_LIB__ && !defined(_MEMORY_S_DEFINED)) || defined(CRYPTOPP_WANT_SECURE_LIB) #if (!__STDC_WANT_SECURE_LIB__ && !defined(_MEMORY_S_DEFINED)) || defined(CRYPTOPP_WANT_SECURE_LIB)
/// \brief Bounds checking replacement for memcpy() /// \brief Bounds checking replacement for memcpy()
@ -871,11 +944,12 @@ CRYPTOPP_DLL void CRYPTOPP_API xorbuf(byte *output, const byte *input, const byt
/// \param buf1 the first buffer /// \param buf1 the first buffer
/// \param buf2 the second buffer /// \param buf2 the second buffer
/// \param count the size of the buffers, in bytes /// \param count the size of the buffers, in bytes
/// \details The function effectively performs an XOR of the elements in two equally sized /// \details VerifyBufsEqual performs an XOR of the elements in two equally sized
/// buffers and retruns a result based on the XOR operation. The function is near /// buffers and retruns a result based on the XOR operation. A count of 0 returns
/// constant-time because CPU micro-code timings could affect the "constant-ness". /// true because two empty buffers are considered equal.
/// Calling code is responsible for mitigating timing attacks if the buffers are not /// \details The function is near constant-time because CPU micro-code timings could
/// equally sized. /// affect the "constant-ness". Calling code is responsible for mitigating timing
/// attacks if the buffers are not equally sized.
/// \sa ModPowerOf2 /// \sa ModPowerOf2
CRYPTOPP_DLL bool CRYPTOPP_API VerifyBufsEqual(const byte *buf1, const byte *buf2, size_t count); CRYPTOPP_DLL bool CRYPTOPP_API VerifyBufsEqual(const byte *buf1, const byte *buf2, size_t count);
@ -1193,9 +1267,15 @@ CRYPTOPP_DLL void CRYPTOPP_API CallNewHandler();
/// \note The function is not constant time because it stops processing when the carry is 0. /// \note The function is not constant time because it stops processing when the carry is 0.
inline void IncrementCounterByOne(byte *inout, unsigned int size) inline void IncrementCounterByOne(byte *inout, unsigned int size)
{ {
CRYPTOPP_ASSERT(inout != NULLPTR); CRYPTOPP_ASSERT(size < INT_MAX); CRYPTOPP_ASSERT(inout != NULLPTR);
for (int i=int(size-1), carry=1; i>=0 && carry; i--)
carry = !++inout[i]; unsigned int carry=1;
while (carry && size != 0)
{
// On carry inout[n] equals 0
carry = ! ++inout[size-1];
size--;
}
} }
/// \brief Performs an addition with carry on a block of bytes /// \brief Performs an addition with carry on a block of bytes
@ -1207,12 +1287,22 @@ inline void IncrementCounterByOne(byte *inout, unsigned int size)
/// \details The function is close to near-constant time because it operates on all the bytes in the blocks. /// \details The function is close to near-constant time because it operates on all the bytes in the blocks.
inline void IncrementCounterByOne(byte *output, const byte *input, unsigned int size) inline void IncrementCounterByOne(byte *output, const byte *input, unsigned int size)
{ {
CRYPTOPP_ASSERT(output != NULLPTR); CRYPTOPP_ASSERT(input != NULLPTR); CRYPTOPP_ASSERT(size < INT_MAX); CRYPTOPP_ASSERT(output != NULLPTR);
CRYPTOPP_ASSERT(input != NULLPTR);
int i, carry; unsigned int carry=1;
for (i=int(size-1), carry=1; i>=0 && carry; i--) while (carry && size != 0)
carry = ((output[i] = input[i]+1) == 0); {
memcpy_s(output, size, input, size_t(i)+1); // On carry output[n] equals 0
carry = ! (output[size-1] = input[size-1] + 1);
size--;
}
while (size != 0)
{
output[size-1] = input[size-1];
size--;
}
} }
/// \brief Performs a branchless swap of values a and b if condition c is true /// \brief Performs a branchless swap of values a and b if condition c is true
@ -1936,7 +2026,8 @@ inline unsigned int GetByte(ByteOrder order, T value, unsigned int index)
/// \brief Reverses bytes in a 8-bit value /// \brief Reverses bytes in a 8-bit value
/// \param value the 8-bit value to reverse /// \param value the 8-bit value to reverse
/// \note ByteReverse returns the value passed to it since there is nothing to reverse /// \note ByteReverse returns the value passed to it since there is nothing to
/// reverse.
inline byte ByteReverse(byte value) inline byte ByteReverse(byte value)
{ {
return value; return value;
@ -1944,7 +2035,8 @@ inline byte ByteReverse(byte value)
/// \brief Reverses bytes in a 16-bit value /// \brief Reverses bytes in a 16-bit value
/// \param value the 16-bit value to reverse /// \param value the 16-bit value to reverse
/// \details ByteReverse calls bswap if available. Otherwise the function performs a 8-bit rotate on the word16 /// \details ByteReverse calls bswap if available. Otherwise the function
/// performs a 8-bit rotate on the word16.
inline word16 ByteReverse(word16 value) inline word16 ByteReverse(word16 value)
{ {
#if defined(CRYPTOPP_BYTESWAP_AVAILABLE) #if defined(CRYPTOPP_BYTESWAP_AVAILABLE)
@ -1958,14 +2050,19 @@ inline word16 ByteReverse(word16 value)
/// \brief Reverses bytes in a 32-bit value /// \brief Reverses bytes in a 32-bit value
/// \param value the 32-bit value to reverse /// \param value the 32-bit value to reverse
/// \details ByteReverse calls bswap if available. Otherwise the function uses a combination of rotates on the word32 /// \details ByteReverse calls bswap if available. Otherwise the function uses
/// a combination of rotates on the word32.
inline word32 ByteReverse(word32 value) inline word32 ByteReverse(word32 value)
{ {
#if defined(__GNUC__) && defined(CRYPTOPP_X86_ASM_AVAILABLE) #if defined(CRYPTOPP_BYTESWAP_AVAILABLE)
return bswap_32(value);
#elif defined(CRYPTOPP_ARM_BYTEREV_AVAILABLE)
word32 rvalue;
__asm__ ("rev %0, %1" : "=r" (rvalue) : "r" (value));
return rvalue;
#elif defined(__GNUC__) && defined(CRYPTOPP_X86_ASM_AVAILABLE)
__asm__ ("bswap %0" : "=r" (value) : "0" (value)); __asm__ ("bswap %0" : "=r" (value) : "0" (value));
return value; return value;
#elif defined(CRYPTOPP_BYTESWAP_AVAILABLE)
return bswap_32(value);
#elif defined(__MWERKS__) && TARGET_CPU_PPC #elif defined(__MWERKS__) && TARGET_CPU_PPC
return (word32)__lwbrx(&value,0); return (word32)__lwbrx(&value,0);
#elif (_MSC_VER >= 1400) || (defined(_MSC_VER) && !defined(_DLL)) #elif (_MSC_VER >= 1400) || (defined(_MSC_VER) && !defined(_DLL))
@ -1982,14 +2079,15 @@ inline word32 ByteReverse(word32 value)
/// \brief Reverses bytes in a 64-bit value /// \brief Reverses bytes in a 64-bit value
/// \param value the 64-bit value to reverse /// \param value the 64-bit value to reverse
/// \details ByteReverse calls bswap if available. Otherwise the function uses a combination of rotates on the word64 /// \details ByteReverse calls bswap if available. Otherwise the function uses
/// a combination of rotates on the word64.
inline word64 ByteReverse(word64 value) inline word64 ByteReverse(word64 value)
{ {
#if defined(__GNUC__) && defined(CRYPTOPP_X86_ASM_AVAILABLE) && defined(__x86_64__) #if defined(CRYPTOPP_BYTESWAP_AVAILABLE)
return bswap_64(value);
#elif defined(__GNUC__) && defined(CRYPTOPP_X86_ASM_AVAILABLE) && defined(__x86_64__)
__asm__ ("bswap %0" : "=r" (value) : "0" (value)); __asm__ ("bswap %0" : "=r" (value) : "0" (value));
return value; return value;
#elif defined(CRYPTOPP_BYTESWAP_AVAILABLE)
return bswap_64(value);
#elif (_MSC_VER >= 1400) || (defined(_MSC_VER) && !defined(_DLL)) #elif (_MSC_VER >= 1400) || (defined(_MSC_VER) && !defined(_DLL))
return _byteswap_uint64(value); return _byteswap_uint64(value);
#elif CRYPTOPP_BOOL_SLOW_WORD64 #elif CRYPTOPP_BOOL_SLOW_WORD64
@ -2003,7 +2101,7 @@ inline word64 ByteReverse(word64 value)
/// \brief Reverses bits in a 8-bit value /// \brief Reverses bits in a 8-bit value
/// \param value the 8-bit value to reverse /// \param value the 8-bit value to reverse
/// \details BitReverse performs a combination of shifts on the byte /// \details BitReverse performs a combination of shifts on the byte.
inline byte BitReverse(byte value) inline byte BitReverse(byte value)
{ {
value = byte((value & 0xAA) >> 1) | byte((value & 0x55) << 1); value = byte((value & 0xAA) >> 1) | byte((value & 0x55) << 1);
@ -2013,29 +2111,45 @@ inline byte BitReverse(byte value)
/// \brief Reverses bits in a 16-bit value /// \brief Reverses bits in a 16-bit value
/// \param value the 16-bit value to reverse /// \param value the 16-bit value to reverse
/// \details BitReverse performs a combination of shifts on the word16 /// \details BitReverse performs a combination of shifts on the word16.
inline word16 BitReverse(word16 value) inline word16 BitReverse(word16 value)
{ {
#if defined(CRYPTOPP_ARM_BITREV_AVAILABLE)
// 4 instructions on ARM.
word32 rvalue;
__asm__ ("rbit %0, %1" : "=r" (rvalue) : "r" (value));
return word16(rvalue >> 16);
#else
// 15 instructions on ARM.
value = word16((value & 0xAAAA) >> 1) | word16((value & 0x5555) << 1); value = word16((value & 0xAAAA) >> 1) | word16((value & 0x5555) << 1);
value = word16((value & 0xCCCC) >> 2) | word16((value & 0x3333) << 2); value = word16((value & 0xCCCC) >> 2) | word16((value & 0x3333) << 2);
value = word16((value & 0xF0F0) >> 4) | word16((value & 0x0F0F) << 4); value = word16((value & 0xF0F0) >> 4) | word16((value & 0x0F0F) << 4);
return ByteReverse(value); return ByteReverse(value);
#endif
} }
/// \brief Reverses bits in a 32-bit value /// \brief Reverses bits in a 32-bit value
/// \param value the 32-bit value to reverse /// \param value the 32-bit value to reverse
/// \details BitReverse performs a combination of shifts on the word32 /// \details BitReverse performs a combination of shifts on the word32.
inline word32 BitReverse(word32 value) inline word32 BitReverse(word32 value)
{ {
#if defined(CRYPTOPP_ARM_BITREV_AVAILABLE)
// 2 instructions on ARM.
word32 rvalue;
__asm__ ("rbit %0, %1" : "=r" (rvalue) : "r" (value));
return rvalue;
#else
// 19 instructions on ARM.
value = word32((value & 0xAAAAAAAA) >> 1) | word32((value & 0x55555555) << 1); value = word32((value & 0xAAAAAAAA) >> 1) | word32((value & 0x55555555) << 1);
value = word32((value & 0xCCCCCCCC) >> 2) | word32((value & 0x33333333) << 2); value = word32((value & 0xCCCCCCCC) >> 2) | word32((value & 0x33333333) << 2);
value = word32((value & 0xF0F0F0F0) >> 4) | word32((value & 0x0F0F0F0F) << 4); value = word32((value & 0xF0F0F0F0) >> 4) | word32((value & 0x0F0F0F0F) << 4);
return ByteReverse(value); return ByteReverse(value);
#endif
} }
/// \brief Reverses bits in a 64-bit value /// \brief Reverses bits in a 64-bit value
/// \param value the 64-bit value to reverse /// \param value the 64-bit value to reverse
/// \details BitReverse performs a combination of shifts on the word64 /// \details BitReverse performs a combination of shifts on the word64.
inline word64 BitReverse(word64 value) inline word64 BitReverse(word64 value)
{ {
#if CRYPTOPP_BOOL_SLOW_WORD64 #if CRYPTOPP_BOOL_SLOW_WORD64
@ -2063,9 +2177,11 @@ inline T BitReverse(T value)
return (T)BitReverse((word16)value); return (T)BitReverse((word16)value);
else if (sizeof(T) == 4) else if (sizeof(T) == 4)
return (T)BitReverse((word32)value); return (T)BitReverse((word32)value);
else if (sizeof(T) == 8)
return (T)BitReverse((word64)value);
else else
{ {
CRYPTOPP_ASSERT(sizeof(T) == 8); CRYPTOPP_ASSERT(0);
return (T)BitReverse((word64)value); return (T)BitReverse((word64)value);
} }
} }

Some files were not shown because too many files have changed in this diff Show More