diff options
Diffstat (limited to 'libs/libsodium')
252 files changed, 40303 insertions, 0 deletions
diff --git a/libs/libsodium/docs/AUTHORS b/libs/libsodium/docs/AUTHORS new file mode 100644 index 0000000000..39e55f6288 --- /dev/null +++ b/libs/libsodium/docs/AUTHORS @@ -0,0 +1,135 @@ + +Designers +========= + +argon2 Alex Biryukov + Daniel Dinu + Dmitry Khovratovich + +blake2 Jean-Philippe Aumasson + Christian Winnerlein + Samuel Neves + Zooko Wilcox-O'Hearn + +chacha20 Daniel J. Bernstein + +chacha20poly1305 Adam Langley + Yoav Nir + +curve25519 Daniel J. Bernstein + +curve25519xsalsa20poly1305 Daniel J. Bernstein + +ed25519 Daniel J. Bernstein + Bo-Yin Yang + Niels Duif + Peter Schwabe + Tanja Lange + +poly1305 Daniel J. Bernstein + +salsa20 Daniel J. Bernstein + +scrypt Colin Percival + +siphash Jean-Philippe Aumasson + Daniel J. Bernstein + +Implementors +============ + +crypto_aead/aes256gcm/aesni Romain Dolbeau + Frank Denis + +crypto_aead/chacha20poly1305 Frank Denis + +crypto_aead/xchacha20poly1305 Frank Denis + Jason A. Donenfeld + +crypto_auth/hmacsha256 Colin Percival +crypto_auth/hmacsha512 +crypto_auth/hmacsha512256 + +crypto_box/curve25519xsalsa20poly1305 Daniel J. Bernstein + +crypto_box/curve25519xchacha20poly1305 Frank Denis + +crypto_core/ed25519 Daniel J. Bernstein + Adam Langley + +crypto_core/hchacha20 Frank Denis + +crypto_core/hsalsa20 Daniel J. Bernstein +crypto_core/salsa + +crypto_generichash/blake2b Jean-Philippe Aumasson + Christian Winnerlein + Samuel Neves + Zooko Wilcox-O'Hearn + +crypto_hash/sha256 Colin Percival +crypto_hash/sha512 +crypto_hash/sha512256 + +crypto_kdf Frank Denis + +crypto_kx Frank Denis + +crypto_onetimeauth/poly1305/donna Andrew "floodyberry" Moon +crypto_onetimeauth/poly1305/sse2 + +crypto_pwhash/argon2 Samuel Neves + Dmitry Khovratovich + Jean-Philippe Aumasson + Daniel Dinu + Thomas Pornin + +crypto_pwhash/scryptsalsa208sha256 Colin Percival + Alexander Peslyak + +crypto_scalarmult/curve25519/ref10 Daniel J. Bernstein + +crypto_scalarmult/curve25519/sandy2x Tung Chou + +crypto_scalarmult/ed25519 Frank Denis + +crypto_secretbox/xsalsa20poly1305 Daniel J. Bernstein + +crypto_secretbox/xchacha20poly1305 Frank Denis + +crypto_secretstream/xchacha20poly1305 Frank Denis + +crypto_shorthash/siphash24 Jean-Philippe Aumasson + Daniel J. Bernstein + +crypto_sign/ed25519 Peter Schwabe + Daniel J. Bernstein + Niels Duif + Tanja Lange + Bo-Yin Yang + +crypto_stream/chacha20/ref Daniel J. Bernstein + +crypto_stream/chacha20/dolbeau Romain Dolbeau + Daniel J. Bernstein + +crypto_stream/salsa20/ref Daniel J. Bernstein +crypto_stream/salsa20/xmm6 + +crypto_stream/salsa20/xmm6int Romain Dolbeau + Daniel J. Bernstein + +crypto_stream/salsa2012/ref Daniel J. Bernstein +crypto_stream/salsa2008/ref + +crypto_stream/xchacha20 Frank Denis + +crypto_verify Frank Denis + +sodium/codecs.c Frank Denis + Thomas Pornin + Christian Winnerlein + +sodium/core.c Frank Denis +sodium/runtime.h +sodium/utils.c diff --git a/libs/libsodium/docs/ChangeLog b/libs/libsodium/docs/ChangeLog new file mode 100644 index 0000000000..2c6f7f1777 --- /dev/null +++ b/libs/libsodium/docs/ChangeLog @@ -0,0 +1,505 @@ + +* Version 1.0.16 + - Signatures computations and verifications are now way faster on +64-bit platforms with compilers supporting 128-bit arithmetic (gcc, +clang, icc). This includes the WebAssembly target. + - New low-level APIs for computations over edwards25519: +`crypto_scalarmult_ed25519()`, `crypto_scalarmult_ed25519_base()`, +`crypto_core_ed25519_is_valid_point()`, `crypto_core_ed25519_add()`, +`crypto_core_ed25519_sub()` and `crypto_core_ed25519_from_uniform()` +(elligator representative to point). + - `crypto_sign_open()`, `crypto_sign_verify_detached() and +`crypto_sign_edwards25519sha512batch_open` now reject public keys in +non-canonical form in addition to low-order points. + - The library can be built with `ED25519_NONDETERMINISTIC` defined in +order to use synthetic nonces for EdDSA. This is disabled by default. + - Webassembly: `crypto_pwhash_*()` functions are now included in +non-sumo builds. + - `sodium_stackzero()` was added to wipe content off the stack. + - Android: support new SDKs where unified headers have become the +default. + - The Salsa20-based PRNG example is now thread-safe on platforms with +support for thread-local storage, optionally mixes bits from RDRAND. + - CMAKE: static library detection on Unix systems has been improved +(thanks to @BurningEnlightenment, @nibua-r, @mellery451) + - Argon2 and scrypt are slightly faster on Linux. + +* Version 1.0.15 + - The default password hashing algorithm is now Argon2id. The +`pwhash_str_verify()` function can still verify Argon2i hashes +without any changes, and `pwhash()` can still compute Argon2i hashes +as well. + - The aes128ctr primitive was removed. It was slow, non-standard, not +authenticated, and didn't seem to be used by any opensource project. + - Argon2id required at least 3 passes like Argon2i, despite a minimum +of `1` as defined by the `OPSLIMIT_MIN` constant. This has been fixed. + - The secretstream construction was slightly changed to be consistent +with forthcoming variants. + - The Javascript and Webassembly versions have been merged, and the +module now returns a `.ready` promise that will resolve after the +Webassembly code is loaded and compiled. + - Note that due to these incompatible changes, the library version +major was bumped up. + +* Version 1.0.14 + - iOS binaries should now be compatible with WatchOS and TVOS. + - WebAssembly is now officially supported. Special thanks to +@facekapow and @pepyakin who helped to make it happen. + - Internal consistency checks failing and primitives used with +dangerous/out-of-bounds/invalid parameters used to call abort(3). +Now, a custom handler *that doesn't return* can be set with the +`set_sodium_misuse()` function. It still aborts by default or if the +handler ever returns. This is not a replacement for non-fatal, +expected runtime errors. This handler will be only called in +unexpected situations due to potential bugs in the library or in +language bindings. + - `*_MESSAGEBYTES_MAX` macros (and the corresponding +`_messagebytes_max()` symbols) have been added to represent the +maximum message size that can be safely handled by a primitive. +Language bindings are encouraged to check user inputs against these +maximum lengths. + - The test suite has been extended to cover more edge cases. + - crypto_sign_ed25519_pk_to_curve25519() now rejects points that are +not on the curve, or not in the main subgroup. + - Further changes have been made to ensure that smart compilers will +not optimize out code that we don't want to be optimized. + - Visual Studio solutions are now included in distribution tarballs. + - The `sodium_runtime_has_*` symbols for CPU features detection are +now defined as weak symbols, i.e. they can be replaced with an +application-defined implementation. This can be useful to disable +AVX* when temperature/power consumption is a concern. + - `crypto_kx_*()` now aborts if called with no non-NULL pointers to +store keys to. + - SSE2 implementations of `crypto_verify_*()` have been added. + - Passwords can be hashed using a specific algorithm with the new +`crypto_pwhash_str_alg()` function. + - Due to popular demand, base64 encoding (`sodium_bin2base64()`) and +decoding (`sodium_base642bin()`) have been implemented. + - A new `crypto_secretstream_*()` API was added to safely encrypt files +and multi-part messages. + - The `sodium_pad()` and `sodium_unpad()` helper functions have been +added in order to add & remove padding. + - An AVX512 optimized implementation of Argon2 has been added (written +by Ondrej Mosnáček, thanks!) + - The `crypto_pwhash_str_needs_rehash()` function was added to check if +a password hash string matches the given parameters, or if it needs an +update. + - The library can now be compiled with recent versions of +emscripten/binaryen that don't allow multiple variables declarations +using a single `var` statement. + +* Version 1.0.13 + - Javascript: the sumo builds now include all symbols. They were +previously limited to symbols defined in minimal builds. + - The public `crypto_pwhash_argon2i_MEMLIMIT_MAX` constant was +incorrectly defined on 32-bit platforms. This has been fixed. + - Version 1.0.12 didn't compile on OpenBSD/i386 using the base gcc +compiler. This has been fixed. + - The Android compilation scripts have been updated for NDK r14b. + - armv7s-optimized code was re-added to iOS builds. + - An AVX2 optimized implementation of the Argon2 round function was +added. + - The Argon2id variant of Argon2 has been implemented. The +high-level `crypto_pwhash_str_verify()` function automatically detects +the algorithm and can verify both Argon2i and Argon2id hashed passwords. +The default algorithm for newly hashed passwords remains Argon2i in +this version to avoid breaking compatibility with verifiers running +libsodium <= 1.0.12. + - A `crypto_box_curve25519xchacha20poly1305_seal*()` function set was +implemented. + - scrypt was removed from minimal builds. + - libsodium is now available on NuGet. + +* Version 1.0.12 + - Ed25519ph was implemented, adding a multi-part signature API +(`crypto_sign_init()`, `crypto_sign_update()`, `crypto_sign_final_*()`). + - New constants and related accessors have been added for Scrypt and +Argon2. + - XChaCha20 has been implemented. Like XSalsa20, this construction +extends the ChaCha20 cipher to accept a 192-bit nonce. This makes it safe +to use ChaCha20 with random nonces. + - `crypto_secretbox`, `crypto_box` and `crypto_aead` now offer +variants leveraging XChaCha20. + - SHA-2 is about 20% faster, which also gives a speed boost to +signature and signature verification. + - AVX2 implementations of Salsa20 and ChaCha20 have been added. They +are twice as fast as the SSE2 implementations. The speed gain is +even more significant on Windows, that previously didn't use +vectorized implementations. + - New high-level API: `crypto_kdf`, to easily derive one or more +subkeys from a master key. + - Siphash with a 128-bit output has been implemented, and is +available as `crypto_shorthash_siphashx_*`. + - New `*_keygen()` helpers functions have been added to create secret +keys for all constructions. This improves code clarity and can prevent keys +from being partially initialized. + - A new `randombytes_buf_deterministic()` function was added to +deterministically fill a memory region with pseudorandom data. This +function can especially be useful to write reproducible tests. + - A preliminary `crypto_kx_*()` API was added to compute shared session +keys. + - AVX2 detection is more reliable. + - The pthreads library is not required any more when using MingW. + - `contrib/Findsodium.cmake` was added as an example to include +libsodium in a project using cmake. + - Compatibility with gcc 2.x has been restored. + - Minimal builds can be checked using `sodium_library_minimal()`. + - The `--enable-opt` compilation switch has become compatible with more +platforms. + - Android builds are now using clang on platforms where it is +available. + +* Version 1.0.11 + - `sodium_init()` is now thread-safe, and can be safely called multiple +times. + - Android binaries now properly support 64-bit Android, targeting +platform 24, but without breaking compatibility with platforms 16 and +21. + - Better support for old gcc versions. + - On FreeBSD, core dumps are disabled on regions allocated with +sodium allocation functions. + - AVX2 detection was fixed, resulting in faster Blake2b hashing on +platforms where it was not properly detected. + - The Sandy2x Curve25519 implementation was not as fast as expected +on some platforms. This has been fixed. + - The NativeClient target was improved. Most notably, it now supports +optimized implementations, and uses pepper_49 by default. + - The library can be compiled with recent Emscripten versions. +Changes have been made to produce smaller code, and the default heap +size was reduced in the standard version. + - The code can now be compiled on SLES11 service pack 4. + - Decryption functions can now accept a NULL pointer for the output. +This checks the MAC without writing the decrypted message. + - crypto_generichash_final() now returns -1 if called twice. + - Support for Visual Studio 2008 was improved. + +* Version 1.0.10 + - This release only fixes a compilation issue reported with some older +gcc versions. There are no functional changes over the previous release. + +* Version 1.0.9 + - The Javascript target now includes a `--sumo` option to include all +the symbols of the original C library. + - A detached API was added to the ChaCha20-Poly1305 and AES256-GCM +implementations. + - The Argon2i password hashing function was added, and is accessible +directly and through a new, high-level `crypto_pwhash` API. The scrypt +function remains available as well. + - A speed-record AVX2 implementation of BLAKE2b was added (thanks to +Samuel Neves). + - The library can now be compiled using C++Builder (thanks to @jcolli44) + - Countermeasures for Ed25519 signatures malleability have been added +to match the irtf-cfrg-eddsa draft (note that malleability is irrelevant to +the standard definition of signature security). Signatures with a small-order +`R` point are now also rejected. + - Some implementations are now slightly faster when using the Clang +compiler. + - The HChaCha20 core function was implemented (`crypto_core_hchacha20()`). + - No-op stubs were added for all AES256-GCM public functions even when +compiled on non-Intel platforms. + - `crypt_generichash_blake2b_statebytes()` was added. + - New macros were added for the IETF variant of the ChaCha20-Poly1305 +construction. + - The library can now be compiled on Minix. + - HEASLR is now enabled on MinGW builds. + +* Version 1.0.8 + - Handle the case where the CPU supports AVX, but we are running +on an hypervisor with AVX disabled/not supported. + - Faster (2x) scalarmult_base() when using the ref10 implementation. + +* Version 1.0.7 + - More functions whose return value should be checked have been +tagged with `__attribute__ ((warn_unused_result))`: `crypto_box_easy()`, +`crypto_box_detached()`, `crypto_box_beforenm()`, `crypto_box()`, and +`crypto_scalarmult()`. + - Sandy2x, the fastest Curve25519 implementation ever, has been +merged in, and is automatically used on CPUs supporting the AVX +instructions set. + - An SSE2 optimized implementation of Poly1305 was added, and is +twice as fast as the portable one. + - An SSSE3 optimized implementation of ChaCha20 was added, and is +twice as fast as the portable one. + - Faster `sodium_increment()` for common nonce sizes. + - New helper functions have been added: `sodium_is_zero()` and + `sodium_add()`. + - `sodium_runtime_has_aesni()` now properly detects the CPU flag when + compiled using Visual Studio. + +* Version 1.0.6 + - Optimized implementations of Blake2 have been added for modern +Intel platforms. `crypto_generichash()` is now faster than MD5 and SHA1 +implementations while being far more secure. + - Functions for which the return value should be checked have been +tagged with `__attribute__ ((warn_unused_result))`. This will +intentionally break code compiled with `-Werror` that didn't bother +checking critical return values. + - The `crypto_sign_edwards25519sha512batch_*()` functions have been +tagged as deprecated. + - Undocumented symbols that were exported, but were only useful for +internal purposes have been removed or made private: +`sodium_runtime_get_cpu_features()`, the implementation-specific +`crypto_onetimeauth_poly1305_donna()` symbols, +`crypto_onetimeauth_poly1305_set_implementation()`, +`crypto_onetimeauth_poly1305_implementation_name()` and +`crypto_onetimeauth_pick_best_implementation()`. + - `sodium_compare()` now works as documented, and compares numbers +in little-endian format instead of behaving like `memcmp()`. + - The previous changes should not break actual applications, but to be +safe, the library version major was incremented. + - `sodium_runtime_has_ssse3()` and `sodium_runtime_has_sse41()` have +been added. + - The library can now be compiled with the CompCert compiler. + +* Version 1.0.5 + - Compilation issues on some platforms were fixed: missing alignment +directives were added (required at least on RHEL-6/i386), a workaround +for a VRP bug on gcc/armv7 was added, and the library can now be compiled +with the SunPro compiler. + - Javascript target: io.js is not supported any more. Use nodejs. + +* Version 1.0.4 + - Support for AES256-GCM has been added. This requires +a CPU with the aesni and pclmul extensions, and is accessible via the +crypto_aead_aes256gcm_*() functions. + - The Javascript target doesn't use eval() any more, so that the +library can be used in Chrome packaged applications. + - QNX and CloudABI are now supported. + - Support for NaCl has finally been added. + - ChaCha20 with an extended (96 bit) nonce and a 32-bit counter has +been implemented as crypto_stream_chacha20_ietf(), +crypto_stream_chacha20_ietf_xor() and crypto_stream_chacha20_ietf_xor_ic(). +An IETF-compatible version of ChaCha20Poly1305 is available as +crypto_aead_chacha20poly1305_ietf_npubbytes(), +crypto_aead_chacha20poly1305_ietf_encrypt() and +crypto_aead_chacha20poly1305_ietf_decrypt(). + - The sodium_increment() helper function has been added, to increment +an arbitrary large number (such as a nonce). + - The sodium_compare() helper function has been added, to compare +arbitrary large numbers (such as nonces, in order to prevent replay +attacks). + +* Version 1.0.3 + - In addition to sodium_bin2hex(), sodium_hex2bin() is now a +constant-time function. + - crypto_stream_xsalsa20_ic() has been added. + - crypto_generichash_statebytes(), crypto_auth_*_statebytes() and +crypto_hash_*_statebytes() have been added in order to retrieve the +size of structures keeping states from foreign languages. + - The JavaScript target doesn't require /dev/urandom or an external +randombytes() implementation any more. Other minor Emscripten-related +improvements have been made in order to support libsodium.js + - Custom randombytes implementations do not need to provide their own +implementation of randombytes_uniform() any more. randombytes_stir() +and randombytes_close() can also be NULL pointers if they are not +required. + - On Linux, getrandom(2) is being used instead of directly accessing +/dev/urandom, if the kernel supports this system call. + - crypto_box_seal() and crypto_box_seal_open() have been added. + - Visual Studio 2015 is now supported. + +* Version 1.0.2 + - The _easy and _detached APIs now support precalculated keys; +crypto_box_easy_afternm(), crypto_box_open_easy_afternm(), +crypto_box_detached_afternm() and crypto_box_open_detached_afternm() +have been added as an alternative to the NaCl interface. + - Memory allocation functions can now be used on operating systems with +no memory protection. + - crypto_sign_open() and crypto_sign_edwards25519sha512batch_open() +now accept a NULL pointer instead of a pointer to the message size, if +storing this information is not required. + - The close-on-exec flag is now set on the descriptor returned when +opening /dev/urandom. + - A libsodium-uninstalled.pc file to use pkg-config even when +libsodium is not installed, has been added. + - The iOS target now includes armv7s and arm64 optimized code, as well +as i386 and x86_64 code for the iOS simulator. + - sodium_free() can now be called on regions with PROT_NONE protection. + - The Javascript tests can run on Ubuntu, where the node binary was +renamed nodejs. io.js can also be used instead of node. + +* Version 1.0.1 + - DLL_EXPORT was renamed SODIUM_DLL_EXPORT in order to avoid +collisions with similar macros defined by other libraries. + - sodium_bin2hex() is now constant-time. + - crypto_secretbox_detached() now supports overlapping input and output +regions. + - NaCl's donna_c64 implementation of curve25519 was reading an extra byte +past the end of the buffer containing the base point. This has been +fixed. + +* Version 1.0.0 + - The API and ABI are now stable. New features will be added, but +backward-compatibility is guaranteed through all the 1.x.y releases. + - crypto_sign() properly works with overlapping regions again. Thanks +to @pysiak for reporting this regression introduced in version 0.6.1. + - The test suite has been extended. + +* Version 0.7.1 (1.0 RC2) + - This is the second release candidate of Sodium 1.0. Minor +compilation, readability and portability changes have been made and the +test suite was improved, but the API is the same as the previous release +candidate. + +* Version 0.7.0 (1.0 RC1) + - Allocating memory to store sensitive data can now be done using +sodium_malloc() and sodium_allocarray(). These functions add guard +pages around the protected data to make it less likely to be +accessible in a heartbleed-like scenario. In addition, the protection +for memory regions allocated that way can be changed using +sodium_mprotect_noaccess(), sodium_mprotect_readonly() and +sodium_mprotect_readwrite(). + - ed25519 keys can be converted to curve25519 keys with +crypto_sign_ed25519_pk_to_curve25519() and +crypto_sign_ed25519_sk_to_curve25519(). This allows using the same +keys for signature and encryption. + - The seed and the public key can be extracted from an ed25519 key +using crypto_sign_ed25519_sk_to_seed() and crypto_sign_ed25519_sk_to_pk(). + - aes256 was removed. A timing-attack resistant implementation might +be added later, but not before version 1.0 is tagged. + - The crypto_pwhash_scryptxsalsa208sha256_* compatibility layer was +removed. Use crypto_pwhash_scryptsalsa208sha256_*. + - The compatibility layer for implementation-specific functions was +removed. + - Compilation issues with Mingw64 on MSYS (not MSYS2) were fixed. + - crypto_pwhash_scryptsalsa208sha256_STRPREFIX was added: it contains +the prefix produced by crypto_pwhash_scryptsalsa208sha256_str() + +* Version 0.6.1 + - Important bug fix: when crypto_sign_open() was given a signed +message too short to even contain a signature, it was putting an +unlimited amount of zeros into the target buffer instead of +immediately returning -1. The bug was introduced in version 0.5.0. + - New API: crypto_sign_detached() and crypto_sign_verify_detached() +to produce and verify ed25519 signatures without having to duplicate +the message. + - New ./configure switch: --enable-minimal, to create a smaller +library, with only the functions required for the high-level API. +Mainly useful for the JavaScript target and embedded systems. + - All the symbols are now exported by the Emscripten build script. + - The pkg-config .pc file is now always installed even if the +pkg-config tool is not available during the installation. + +* Version 0.6.0 + - The ChaCha20 stream cipher has been added, as crypto_stream_chacha20_* + - The ChaCha20Poly1305 AEAD construction has been implemented, as +crypto_aead_chacha20poly1305_* + - The _easy API does not require any heap allocations any more and +does not have any overhead over the NaCl API. With the password +hashing function being an obvious exception, the library doesn't +allocate and will not allocate heap memory ever. + - crypto_box and crypto_secretbox have a new _detached API to store +the authentication tag and the encrypted message separately. + - crypto_pwhash_scryptxsalsa208sha256*() functions have been renamed +crypto_pwhash_scryptsalsa208sha256*(). + - The low-level crypto_pwhash_scryptsalsa208sha256_ll() function +allows setting individual parameters of the scrypt function. + - New macros and functions for recommended crypto_pwhash_* parameters +have been added. + - Similarly to crypto_sign_seed_keypair(), crypto_box_seed_keypair() +has been introduced to deterministically generate a key pair from a seed. + - crypto_onetimeauth() now provides a streaming interface. + - crypto_stream_chacha20_xor_ic() and crypto_stream_salsa20_xor_ic() +have been added to use a non-zero initial block counter. + - On Windows, CryptGenRandom() was replaced by RtlGenRandom(), which +doesn't require the Crypt API. + - The high bit in curve25519 is masked instead of processing the key as +a 256-bit value. + - The curve25519 ref implementation was replaced by the latest ref10 +implementation from Supercop. + - sodium_mlock() now prevents memory from being included in coredumps +on Linux 3.4+ + +* Version 0.5.0 + - sodium_mlock()/sodium_munlock() have been introduced to lock pages +in memory before storing sensitive data, and to zero them before +unlocking them. + - High-level wrappers for crypto_box and crypto_secretbox +(crypto_box_easy and crypto_secretbox_easy) can be used to avoid +dealing with the specific memory layout regular functions depend on. + - crypto_pwhash_scryptsalsa208sha256* functions have been added +to derive a key from a password, and for password storage. + - Salsa20 and ed25519 implementations now support overlapping +inputs/keys/outputs (changes imported from supercop-20140505). + - New build scripts for Visual Studio, Emscripten, different Android +architectures and msys2 are available. + - The poly1305-53 implementation has been replaced with Floodyberry's +poly1305-donna32 and poly1305-donna64 implementations. + - sodium_hex2bin() has been added to complement sodium_bin2hex(). + - On OpenBSD and Bitrig, arc4random() is used instead of reading +/dev/urandom. + - crypto_auth_hmac_sha512() has been implemented. + - sha256 and sha512 now have a streaming interface. + - hmacsha256, hmacsha512 and hmacsha512256 now support keys of +arbitrary length, and have a streaming interface. + - crypto_verify_64() has been implemented. + - first-class Visual Studio build system, thanks to @evoskuil + - CPU features are now detected at runtime. + +* Version 0.4.5 + - Restore compatibility with OSX <= 10.6 + +* Version 0.4.4 + - Visual Studio is officially supported (VC 2010 & VC 2013) + - mingw64 is now supported + - big-endian architectures are now supported as well + - The donna_c64 implementation of curve25519_donna_c64 now handles +non-canonical points like the ref implementation + - Missing scalarmult_curve25519 and stream_salsa20 constants are now exported + - A crypto_onetimeauth_poly1305_ref() wrapper has been added + +* Version 0.4.3 + - crypto_sign_seedbytes() and crypto_sign_SEEDBYTES were added. + - crypto_onetimeauth_poly1305_implementation_name() was added. + - poly1305-ref has been replaced by a faster implementation, +Floodyberry's poly1305-donna-unrolled. + - Stackmarkings have been added to assembly code, for Hardened Gentoo. + - pkg-config can now be used in order to retrieve compilations flags for +using libsodium. + - crypto_stream_aes256estream_*() can now deal with unaligned input +on platforms that require word alignment. + - portability improvements. + +* Version 0.4.2 + - All NaCl constants are now also exposed as functions. + - The Android and iOS cross-compilation script have been improved. + - libsodium can now be cross-compiled to Windows from Linux. + - libsodium can now be compiled with emscripten. + - New convenience function (prototyped in utils.h): sodium_bin2hex(). + +* Version 0.4.1 + - sodium_version_*() functions were not exported in version 0.4. They +are now visible as intended. + - sodium_init() now calls randombytes_stir(). + - optimized assembly version of salsa20 is now used on amd64. + - further cleanups and enhanced compatibility with non-C99 compilers. + +* Version 0.4 + - Most constants and operations are now available as actual functions +instead of macros, making it easier to use from other languages. + - New operation: crypto_generichash, featuring a variable key size, a +variable output size, and a streaming API. Currently implemented using +Blake2b. + - The package can be compiled in a separate directory. + - aes128ctr functions are exported. + - Optimized versions of curve25519 (curve25519_donna_c64), poly1305 +(poly1305_53) and ed25519 (ed25519_ref10) are available. Optionally calling +sodium_init() once before using the library makes it pick the fastest +implementation. + - New convenience function: sodium_memzero() in order to securely +wipe a memory area. + - A whole bunch of cleanups and portability enhancements. + - On Windows, a .REF file is generated along with the shared library, +for use with Visual Studio. The installation path for these has become +$prefix/bin as expected by MingW. + +* Version 0.3 + - The crypto_shorthash operation has been added, implemented using +SipHash-2-4. + +* Version 0.2 + - crypto_sign_seed_keypair() has been added + +* Version 0.1 + - Initial release. + diff --git a/libs/libsodium/docs/LICENSE b/libs/libsodium/docs/LICENSE new file mode 100644 index 0000000000..2489a68143 --- /dev/null +++ b/libs/libsodium/docs/LICENSE @@ -0,0 +1,18 @@ +/* + * ISC License + * + * Copyright (c) 2013-2017 + * Frank Denis <j at pureftpd dot org> + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ diff --git a/libs/libsodium/docs/README.markdown b/libs/libsodium/docs/README.markdown new file mode 100644 index 0000000000..815240abea --- /dev/null +++ b/libs/libsodium/docs/README.markdown @@ -0,0 +1,46 @@ +[![Build Status](https://travis-ci.org/jedisct1/libsodium.svg?branch=master)](https://travis-ci.org/jedisct1/libsodium?branch=master) +[![Windows build status](https://ci.appveyor.com/api/projects/status/fu8s2elx25il98hj?svg=true)](https://ci.appveyor.com/project/jedisct1/libsodium) +[![Coverity Scan Build Status](https://scan.coverity.com/projects/2397/badge.svg)](https://scan.coverity.com/projects/2397) + +![libsodium](https://raw.github.com/jedisct1/libsodium/master/logo.png) +============ + +Sodium is a new, easy-to-use software library for encryption, +decryption, signatures, password hashing and more. + +It is a portable, cross-compilable, installable, packageable +fork of [NaCl](http://nacl.cr.yp.to/), with a compatible API, and an +extended API to improve usability even further. + +Its goal is to provide all of the core operations needed to build +higher-level cryptographic tools. + +Sodium supports a variety of compilers and operating systems, +including Windows (with MingW or Visual Studio, x86 and x64), iOS, Android, +as well as Javascript and Webassembly. + +## Documentation + +The documentation is available on Gitbook: + +* [libsodium documentation](https://download.libsodium.org/doc/) - +online, requires Javascript. +* [offline documentation](https://www.gitbook.com/book/jedisct1/libsodium/details) +in PDF, MOBI and ePUB formats. + +## Integrity Checking + +The integrity checking instructions (including the signing key for libsodium) +are available in the [installation](https://download.libsodium.org/doc/installation/index.html#integrity-checking) +section of the documentation. + +## Community + +A mailing-list is available to discuss libsodium. + +In order to join, just send a random mail to `sodium-subscribe` {at} +`pureftpd` {dot} `org`. + +## License + +[ISC license](https://en.wikipedia.org/wiki/ISC_license). diff --git a/libs/libsodium/docs/THANKS b/libs/libsodium/docs/THANKS new file mode 100644 index 0000000000..0d0da788f3 --- /dev/null +++ b/libs/libsodium/docs/THANKS @@ -0,0 +1,91 @@ +Special thanks to people, companies and organizations having written +libsodium bindings for their favorite programming languages: + +@alethia7 +@artemisc +@carblue +@dnaq +@ektrah +@graxrabble +@harleqin +@joshjdevl +@jrmarino +@jshahbazi +@lvh +@neheb + +Adam Caudill (@adamcaudill) +Alexander Morris (@alexpmorris) +Amit Murthy (@amitmurthy) +Andrew Bennett (@potatosalad) +Andrew Lambert (@charonn0) +Bruce Mitchener (@waywardmonkeys) +Bruno Oliveira (@abstractj) +Caolan McMahon (@caolan) +Chris Rebert (@cvrebert) +Christian Hermann (@bitbeans) +Christian Wiese (@morfoh) +Christian Wiese (@morfoh) +Colm MacCárthaigh (@colmmacc) +David Parrish (@dmp1ce) +Donald Stufft (@dstufft) +Douglas Campos (@qmx) +Drew Crawford (@drewcrawford) +Emil Bay (@emilbayes) +Eric Dong (@quantum1423) +Eric Voskuil (@evoskuil) +Farid Hajji (@fhajji) +Frank Siebenlist (@franks42) +Gabriel Handford (@gabriel) +Geo Carncross (@geocar) +Henrik Gassmann (BurningEnlightenment) +Jachym Holecek (@freza) +Jack Wink (@jackwink) +James Ruan (@jamesruan) +Jan de Muijnck-Hughes (@jfdm) +Jason McCampbell (@jasonmccampbell) +Jeroen Habraken (@VeXocide) +Jeroen Ooms (@jeroen) +Jesper Louis Andersen (@jlouis) +Joe Eli McIlvain (@jemc) +Jonathan Stowe (@jonathanstowe) +Joseph Abrahamson (@tel) +Julien Kauffmann (@ereOn) +Kenneth Ballenegger (@kballenegger) +Loic Maury (@loicmaury) +Michael Gorlick (@mgorlick) +Michael Gregorowicz (@mgregoro) +Michał Zieliński (@zielmicha) +Omar Ayub (@electricFeel) +Pedro Paixao (@paixaop) +Project ArteMisc (@artemisc) +Rich FitzJohn (@richfitz) +Ruben De Visscher (@rubendv) +Rudolf Von Krugstein (@rudolfvonkrugstein) +Samuel Neves (@sneves) +Scott Arciszewski (@paragonie-scott) +Stanislav Ovsiannikov (@naphaso) +Stefan Marsiske (@stef) +Stephan Touset (@stouset) +Stephen Chavez (@redragonx) +Steve Gibson (@sggrc) +Tony Arcieri (@bascule) +Tony Garnock-Jones (@tonyg) +Y. T. Chung (@zonyitoo) + +Bytecurry Software +Cryptotronix +Facebook +FSF France +MaidSafe +Paragonie Initiative Enterprises +Python Cryptographic Authority + +(this list may not be complete, if you don't see your name, please +submit a pull request!) + +Also thanks to: + +- Coverity, Inc. to provide static analysis. +- FSF France for providing access to their compilation servers. +- Private Internet Access for having sponsored a complete security audit. diff --git a/libs/libsodium/libsodium.vcxproj b/libs/libsodium/libsodium.vcxproj new file mode 100644 index 0000000000..182ac4184b --- /dev/null +++ b/libs/libsodium/libsodium.vcxproj @@ -0,0 +1,493 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup Label="ProjectConfigurations"> + <ProjectConfiguration Include="Debug|Win32"> + <Configuration>Debug</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Debug|x64"> + <Configuration>Debug</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|Win32"> + <Configuration>Release</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|x64"> + <Configuration>Release</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + </ItemGroup> + <PropertyGroup Label="Globals"> + <ProjectGuid>{A185B162-6CB6-4502-B03F-B56F7699A8D9}</ProjectGuid> + <ProjectName>libsodium</ProjectName> + <RootNamespace>libsodium</RootNamespace> + </PropertyGroup> + <PropertyGroup> + <GenerateManifest>false</GenerateManifest> + <EmbedManifest>false</EmbedManifest> + <ConfigurationType>DynamicLibrary</ConfigurationType> + <OutDir Condition="'$(Platform)'=='Win32'">$(SolutionDir)$(Configuration)\Libs\</OutDir> + <OutDir Condition="'$(Platform)'=='x64'">$(SolutionDir)$(Configuration)64\Libs\</OutDir> + </PropertyGroup> + <Import Project="$(ProjectDir)..\..\build\vc.common\common.props"/> + <PropertyGroup> + <TargetExt>.mir</TargetExt> + <TargetPath>$(OutDir)$(TargetName)$(TargetExt)</TargetPath> + </PropertyGroup> + <ItemDefinitionGroup> + <ClCompile> + <PreprocessorDefinitions>SODIUM_DLL_EXPORT;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <DisableSpecificWarnings>4244;4310;4702;%(DisableSpecificWarnings)</DisableSpecificWarnings> + <AdditionalIncludeDirectories>$(ProjectDir)src\include;$(ProjectDir)src\include\sodium;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + </ClCompile> + </ItemDefinitionGroup> + <ItemGroup> + <ClCompile Include="src\crypto_generichash\crypto_generichash.c"> + <PrecompiledHeader>NotUsing</PrecompiledHeader> + </ClCompile> + <ClCompile Include="src\crypto_generichash\blake2b\generichash_blake2.c"> + <PrecompiledHeader>NotUsing</PrecompiledHeader> + </ClCompile> + <ClCompile Include="src\crypto_generichash\blake2b\ref\blake2b-compress-ref.c"> + <PrecompiledHeader>NotUsing</PrecompiledHeader> + </ClCompile> + <ClCompile Include="src\crypto_generichash\blake2b\ref\blake2b-compress-ssse3.c"> + <PrecompiledHeader>NotUsing</PrecompiledHeader> + </ClCompile> + <ClCompile Include="src\crypto_generichash\blake2b\ref\blake2b-compress-avx2.c"> + <PrecompiledHeader>NotUsing</PrecompiledHeader> + </ClCompile> + <ClCompile Include="src\crypto_generichash\blake2b\ref\blake2b-compress-sse41.c"> + <PrecompiledHeader>NotUsing</PrecompiledHeader> + </ClCompile> + <ClCompile Include="src\crypto_generichash\blake2b\ref\generichash_blake2b.c"> + <PrecompiledHeader>NotUsing</PrecompiledHeader> + </ClCompile> + <ClCompile Include="src\crypto_generichash\blake2b\ref\blake2b-ref.c"> + <PrecompiledHeader>NotUsing</PrecompiledHeader> + </ClCompile> + <ClCompile Include="src\crypto_kx\crypto_kx.c"> + <PrecompiledHeader>NotUsing</PrecompiledHeader> + </ClCompile> + <ClCompile Include="src\crypto_sign\crypto_sign.c"> + <PrecompiledHeader>NotUsing</PrecompiledHeader> + </ClCompile> + <ClCompile Include="src\crypto_sign\ed25519\sign_ed25519.c"> + <PrecompiledHeader>NotUsing</PrecompiledHeader> + </ClCompile> + <ClCompile Include="src\crypto_sign\ed25519\ref10\obsolete.c"> + <PrecompiledHeader>NotUsing</PrecompiledHeader> + </ClCompile> + <ClCompile Include="src\crypto_sign\ed25519\ref10\sign.c"> + <PrecompiledHeader>NotUsing</PrecompiledHeader> + </ClCompile> + <ClCompile Include="src\crypto_sign\ed25519\ref10\keypair.c"> + <PrecompiledHeader>NotUsing</PrecompiledHeader> + </ClCompile> + <ClCompile Include="src\crypto_sign\ed25519\ref10\open.c"> + <PrecompiledHeader>NotUsing</PrecompiledHeader> + </ClCompile> + <ClCompile Include="src\crypto_secretbox\crypto_secretbox.c"> + <PrecompiledHeader>NotUsing</PrecompiledHeader> + </ClCompile> + <ClCompile Include="src\crypto_secretbox\crypto_secretbox_easy.c"> + <PrecompiledHeader>NotUsing</PrecompiledHeader> + </ClCompile> + <ClCompile Include="src\crypto_secretbox\xsalsa20poly1305\secretbox_xsalsa20poly1305.c"> + <PrecompiledHeader>NotUsing</PrecompiledHeader> + </ClCompile> + <ClCompile Include="src\crypto_secretbox\xchacha20poly1305\secretbox_xchacha20poly1305.c"> + <PrecompiledHeader>NotUsing</PrecompiledHeader> + </ClCompile> + <ClCompile Include="src\crypto_pwhash\crypto_pwhash.c"> + <PrecompiledHeader>NotUsing</PrecompiledHeader> + </ClCompile> + <ClCompile Include="src\crypto_pwhash\argon2\blake2b-long.c"> + <PrecompiledHeader>NotUsing</PrecompiledHeader> + </ClCompile> + <ClCompile Include="src\crypto_pwhash\argon2\argon2-core.c"> + <PrecompiledHeader>NotUsing</PrecompiledHeader> + </ClCompile> + <ClCompile Include="src\crypto_pwhash\argon2\argon2-fill-block-avx512f.c"> + <PrecompiledHeader>NotUsing</PrecompiledHeader> + </ClCompile> + <ClCompile Include="src\crypto_pwhash\argon2\argon2-fill-block-ref.c"> + <PrecompiledHeader>NotUsing</PrecompiledHeader> + </ClCompile> + <ClCompile Include="src\crypto_pwhash\argon2\argon2-fill-block-ssse3.c"> + <PrecompiledHeader>NotUsing</PrecompiledHeader> + </ClCompile> + <ClCompile Include="src\crypto_pwhash\argon2\pwhash_argon2i.c"> + <PrecompiledHeader>NotUsing</PrecompiledHeader> + </ClCompile> + <ClCompile Include="src\crypto_pwhash\argon2\pwhash_argon2id.c"> + <PrecompiledHeader>NotUsing</PrecompiledHeader> + </ClCompile> + <ClCompile Include="src\crypto_pwhash\argon2\argon2.c"> + <PrecompiledHeader>NotUsing</PrecompiledHeader> + </ClCompile> + <ClCompile Include="src\crypto_pwhash\argon2\argon2-fill-block-avx2.c"> + <PrecompiledHeader>NotUsing</PrecompiledHeader> + </ClCompile> + <ClCompile Include="src\crypto_pwhash\argon2\argon2-encoding.c"> + <PrecompiledHeader>NotUsing</PrecompiledHeader> + </ClCompile> + <ClCompile Include="src\crypto_pwhash\scryptsalsa208sha256\scrypt_platform.c"> + <PrecompiledHeader>NotUsing</PrecompiledHeader> + </ClCompile> + <ClCompile Include="src\crypto_pwhash\scryptsalsa208sha256\crypto_scrypt-common.c"> + <PrecompiledHeader>NotUsing</PrecompiledHeader> + </ClCompile> + <ClCompile Include="src\crypto_pwhash\scryptsalsa208sha256\pwhash_scryptsalsa208sha256.c"> + <PrecompiledHeader>NotUsing</PrecompiledHeader> + </ClCompile> + <ClCompile Include="src\crypto_pwhash\scryptsalsa208sha256\pbkdf2-sha256.c"> + <PrecompiledHeader>NotUsing</PrecompiledHeader> + </ClCompile> + <ClCompile Include="src\crypto_pwhash\scryptsalsa208sha256\nosse\pwhash_scryptsalsa208sha256_nosse.c"> + <PrecompiledHeader>NotUsing</PrecompiledHeader> + </ClCompile> + <ClCompile Include="src\crypto_pwhash\scryptsalsa208sha256\sse\pwhash_scryptsalsa208sha256_sse.c"> + <PrecompiledHeader>NotUsing</PrecompiledHeader> + </ClCompile> + <ClCompile Include="src\crypto_verify\sodium\verify.c"> + <PrecompiledHeader>NotUsing</PrecompiledHeader> + </ClCompile> + <ClCompile Include="src\crypto_auth\crypto_auth.c"> + <PrecompiledHeader>NotUsing</PrecompiledHeader> + </ClCompile> + <ClCompile Include="src\crypto_auth\hmacsha512\auth_hmacsha512.c"> + <PrecompiledHeader>NotUsing</PrecompiledHeader> + </ClCompile> + <ClCompile Include="src\crypto_auth\hmacsha512256\auth_hmacsha512256.c"> + <PrecompiledHeader>NotUsing</PrecompiledHeader> + </ClCompile> + <ClCompile Include="src\crypto_auth\hmacsha256\auth_hmacsha256.c"> + <PrecompiledHeader>NotUsing</PrecompiledHeader> + </ClCompile> + <ClCompile Include="src\crypto_kdf\crypto_kdf.c"> + <PrecompiledHeader>NotUsing</PrecompiledHeader> + </ClCompile> + <ClCompile Include="src\crypto_kdf\blake2b\kdf_blake2b.c"> + <PrecompiledHeader>NotUsing</PrecompiledHeader> + </ClCompile> + <ClCompile Include="src\crypto_shorthash\crypto_shorthash.c"> + <PrecompiledHeader>NotUsing</PrecompiledHeader> + </ClCompile> + <ClCompile Include="src\crypto_shorthash\siphash24\shorthash_siphash24.c"> + <PrecompiledHeader>NotUsing</PrecompiledHeader> + </ClCompile> + <ClCompile Include="src\crypto_shorthash\siphash24\shorthash_siphashx24.c"> + <PrecompiledHeader>NotUsing</PrecompiledHeader> + </ClCompile> + <ClCompile Include="src\crypto_shorthash\siphash24\ref\shorthash_siphashx24_ref.c"> + <PrecompiledHeader>NotUsing</PrecompiledHeader> + </ClCompile> + <ClCompile Include="src\crypto_shorthash\siphash24\ref\shorthash_siphash24_ref.c"> + <PrecompiledHeader>NotUsing</PrecompiledHeader> + </ClCompile> + <ClCompile Include="src\crypto_scalarmult\crypto_scalarmult.c"> + <PrecompiledHeader>NotUsing</PrecompiledHeader> + </ClCompile> + <ClCompile Include="src\crypto_scalarmult\ed25519\ref10\scalarmult_ed25519_ref10.c"> + <PrecompiledHeader>NotUsing</PrecompiledHeader> + </ClCompile> + <ClCompile Include="src\crypto_scalarmult\curve25519\scalarmult_curve25519.c"> + <PrecompiledHeader>NotUsing</PrecompiledHeader> + </ClCompile> + <ClCompile Include="src\crypto_scalarmult\curve25519\sandy2x\curve25519_sandy2x.c"> + <PrecompiledHeader>NotUsing</PrecompiledHeader> + </ClCompile> + <ClCompile Include="src\crypto_scalarmult\curve25519\sandy2x\fe_frombytes_sandy2x.c"> + <PrecompiledHeader>NotUsing</PrecompiledHeader> + </ClCompile> + <ClCompile Include="src\crypto_scalarmult\curve25519\sandy2x\fe51_invert.c"> + <PrecompiledHeader>NotUsing</PrecompiledHeader> + </ClCompile> + <ClCompile Include="src\crypto_scalarmult\curve25519\ref10\x25519_ref10.c"> + <PrecompiledHeader>NotUsing</PrecompiledHeader> + </ClCompile> + <ClCompile Include="src\crypto_onetimeauth\crypto_onetimeauth.c"> + <PrecompiledHeader>NotUsing</PrecompiledHeader> + </ClCompile> + <ClCompile Include="src\crypto_onetimeauth\poly1305\onetimeauth_poly1305.c"> + <PrecompiledHeader>NotUsing</PrecompiledHeader> + </ClCompile> + <ClCompile Include="src\crypto_onetimeauth\poly1305\donna\poly1305_donna.c"> + <PrecompiledHeader>NotUsing</PrecompiledHeader> + </ClCompile> + <ClCompile Include="src\crypto_onetimeauth\poly1305\sse2\poly1305_sse2.c"> + <PrecompiledHeader>NotUsing</PrecompiledHeader> + </ClCompile> + <ClCompile Include="src\randombytes\randombytes.c"> + <PrecompiledHeader>NotUsing</PrecompiledHeader> + </ClCompile> + <ClCompile Include="src\randombytes\sysrandom\randombytes_sysrandom.c"> + <PrecompiledHeader>NotUsing</PrecompiledHeader> + </ClCompile> + <ClCompile Include="src\randombytes\salsa20\randombytes_salsa20_random.c"> + <PrecompiledHeader>NotUsing</PrecompiledHeader> + </ClCompile> + <ClCompile Include="src\randombytes\nativeclient\randombytes_nativeclient.c"> + <PrecompiledHeader>NotUsing</PrecompiledHeader> + </ClCompile> + <ClCompile Include="src\crypto_box\crypto_box_easy.c"> + <PrecompiledHeader>NotUsing</PrecompiledHeader> + </ClCompile> + <ClCompile Include="src\crypto_box\crypto_box_seal.c"> + <PrecompiledHeader>NotUsing</PrecompiledHeader> + </ClCompile> + <ClCompile Include="src\crypto_box\crypto_box.c"> + <PrecompiledHeader>NotUsing</PrecompiledHeader> + </ClCompile> + <ClCompile Include="src\crypto_box\curve25519xsalsa20poly1305\box_curve25519xsalsa20poly1305.c"> + <PrecompiledHeader>NotUsing</PrecompiledHeader> + </ClCompile> + <ClCompile Include="src\crypto_box\curve25519xchacha20poly1305\box_curve25519xchacha20poly1305.c"> + <PrecompiledHeader>NotUsing</PrecompiledHeader> + </ClCompile> + <ClCompile Include="src\crypto_box\curve25519xchacha20poly1305\box_seal_curve25519xchacha20poly1305.c"> + <PrecompiledHeader>NotUsing</PrecompiledHeader> + </ClCompile> + <ClCompile Include="src\sodium\codecs.c"> + <PrecompiledHeader>NotUsing</PrecompiledHeader> + </ClCompile> + <ClCompile Include="src\sodium\runtime.c"> + <PrecompiledHeader>NotUsing</PrecompiledHeader> + </ClCompile> + <ClCompile Include="src\sodium\core.c"> + <PrecompiledHeader>NotUsing</PrecompiledHeader> + </ClCompile> + <ClCompile Include="src\sodium\utils.c"> + <PrecompiledHeader>NotUsing</PrecompiledHeader> + </ClCompile> + <ClCompile Include="src\sodium\version.c"> + <PrecompiledHeader>NotUsing</PrecompiledHeader> + </ClCompile> + <ClCompile Include="src\crypto_stream\crypto_stream.c"> + <PrecompiledHeader>NotUsing</PrecompiledHeader> + </ClCompile> + <ClCompile Include="src\crypto_stream\xchacha20\stream_xchacha20.c"> + <PrecompiledHeader>NotUsing</PrecompiledHeader> + </ClCompile> + <ClCompile Include="src\crypto_stream\chacha20\stream_chacha20.c"> + <PrecompiledHeader>NotUsing</PrecompiledHeader> + </ClCompile> + <ClCompile Include="src\crypto_stream\chacha20\ref\chacha20_ref.c"> + <PrecompiledHeader>NotUsing</PrecompiledHeader> + </ClCompile> + <ClCompile Include="src\crypto_stream\chacha20\dolbeau\chacha20_dolbeau-avx2.c"> + <PrecompiledHeader>NotUsing</PrecompiledHeader> + </ClCompile> + <ClCompile Include="src\crypto_stream\chacha20\dolbeau\chacha20_dolbeau-ssse3.c"> + <PrecompiledHeader>NotUsing</PrecompiledHeader> + </ClCompile> + <ClCompile Include="src\crypto_stream\salsa20\stream_salsa20.c"> + <PrecompiledHeader>NotUsing</PrecompiledHeader> + </ClCompile> + <ClCompile Include="src\crypto_stream\salsa20\ref\salsa20_ref.c"> + <PrecompiledHeader>NotUsing</PrecompiledHeader> + </ClCompile> + <ClCompile Include="src\crypto_stream\salsa20\xmm6int\salsa20_xmm6int-avx2.c"> + <PrecompiledHeader>NotUsing</PrecompiledHeader> + </ClCompile> + <ClCompile Include="src\crypto_stream\salsa20\xmm6int\salsa20_xmm6int-sse2.c"> + <PrecompiledHeader>NotUsing</PrecompiledHeader> + </ClCompile> + <ClCompile Include="src\crypto_stream\salsa20\xmm6\salsa20_xmm6.c"> + <PrecompiledHeader>NotUsing</PrecompiledHeader> + </ClCompile> + <ClCompile Include="src\crypto_stream\salsa2012\stream_salsa2012.c"> + <PrecompiledHeader>NotUsing</PrecompiledHeader> + </ClCompile> + <ClCompile Include="src\crypto_stream\salsa2012\ref\stream_salsa2012_ref.c"> + <PrecompiledHeader>NotUsing</PrecompiledHeader> + </ClCompile> + <ClCompile Include="src\crypto_stream\salsa208\stream_salsa208.c"> + <PrecompiledHeader>NotUsing</PrecompiledHeader> + </ClCompile> + <ClCompile Include="src\crypto_stream\salsa208\ref\stream_salsa208_ref.c"> + <PrecompiledHeader>NotUsing</PrecompiledHeader> + </ClCompile> + <ClCompile Include="src\crypto_stream\xsalsa20\stream_xsalsa20.c"> + <PrecompiledHeader>NotUsing</PrecompiledHeader> + </ClCompile> + <ClCompile Include="src\crypto_hash\crypto_hash.c"> + <PrecompiledHeader>NotUsing</PrecompiledHeader> + </ClCompile> + <ClCompile Include="src\crypto_hash\sha512\hash_sha512.c"> + <PrecompiledHeader>NotUsing</PrecompiledHeader> + </ClCompile> + <ClCompile Include="src\crypto_hash\sha512\cp\hash_sha512_cp.c"> + <PrecompiledHeader>NotUsing</PrecompiledHeader> + </ClCompile> + <ClCompile Include="src\crypto_hash\sha256\hash_sha256.c"> + <PrecompiledHeader>NotUsing</PrecompiledHeader> + </ClCompile> + <ClCompile Include="src\crypto_hash\sha256\cp\hash_sha256_cp.c"> + <PrecompiledHeader>NotUsing</PrecompiledHeader> + </ClCompile> + <ClCompile Include="src\crypto_aead\xchacha20poly1305\sodium\aead_xchacha20poly1305.c"> + <PrecompiledHeader>NotUsing</PrecompiledHeader> + </ClCompile> + <ClCompile Include="src\crypto_aead\aes256gcm\aesni\aead_aes256gcm_aesni.c"> + <PrecompiledHeader>NotUsing</PrecompiledHeader> + </ClCompile> + <ClCompile Include="src\crypto_aead\chacha20poly1305\sodium\aead_chacha20poly1305.c"> + <PrecompiledHeader>NotUsing</PrecompiledHeader> + </ClCompile> + <ClCompile Include="src\crypto_secretstream\xchacha20poly1305\secretstream_xchacha20poly1305.c"> + <PrecompiledHeader>NotUsing</PrecompiledHeader> + </ClCompile> + <ClCompile Include="src\crypto_core\salsa\ref\core_salsa_ref.c"> + <PrecompiledHeader>NotUsing</PrecompiledHeader> + </ClCompile> + <ClCompile Include="src\crypto_core\hchacha20\core_hchacha20.c"> + <PrecompiledHeader>NotUsing</PrecompiledHeader> + </ClCompile> + <ClCompile Include="src\crypto_core\hsalsa20\core_hsalsa20.c"> + <PrecompiledHeader>NotUsing</PrecompiledHeader> + </ClCompile> + <ClCompile Include="src\crypto_core\hsalsa20\ref2\core_hsalsa20_ref2.c"> + <PrecompiledHeader>NotUsing</PrecompiledHeader> + </ClCompile> + <ClCompile Include="src\crypto_core\ed25519\core_ed25519.c"> + <PrecompiledHeader>NotUsing</PrecompiledHeader> + </ClCompile> + <ClCompile Include="src\crypto_core\ed25519\ref10\ed25519_ref10.c"> + <PrecompiledHeader>NotUsing</PrecompiledHeader> + </ClCompile> + </ItemGroup> + <ItemGroup> + <ClInclude Include="src\crypto_generichash\blake2b\ref\blake2b-load-sse2.h"/> + <ClInclude Include="src\crypto_generichash\blake2b\ref\blake2b-load-avx2.h"/> + <ClInclude Include="src\crypto_generichash\blake2b\ref\blake2.h"/> + <ClInclude Include="src\crypto_generichash\blake2b\ref\blake2b-compress-ssse3.h"/> + <ClInclude Include="src\crypto_generichash\blake2b\ref\blake2b-load-sse41.h"/> + <ClInclude Include="src\crypto_generichash\blake2b\ref\blake2b-compress-avx2.h"/> + <ClInclude Include="src\crypto_generichash\blake2b\ref\blake2b-compress-sse41.h"/> + <ClInclude Include="src\crypto_sign\ed25519\ref10\sign_ed25519_ref10.h"/> + <ClInclude Include="src\include\sodium.h"/> + <ClInclude Include="src\include\sodium\crypto_stream_salsa2012.h"/> + <ClInclude Include="src\include\sodium\crypto_auth.h"/> + <ClInclude Include="src\include\sodium\utils.h"/> + <ClInclude Include="src\include\sodium\crypto_core_hchacha20.h"/> + <ClInclude Include="src\include\sodium\crypto_hash_sha512.h"/> + <ClInclude Include="src\include\sodium\core.h"/> + <ClInclude Include="src\include\sodium\export.h"/> + <ClInclude Include="src\include\sodium\randombytes_salsa20_random.h"/> + <ClInclude Include="src\include\sodium\crypto_core_salsa20.h"/> + <ClInclude Include="src\include\sodium\crypto_shorthash_siphash24.h"/> + <ClInclude Include="src\include\sodium\randombytes.h"/> + <ClInclude Include="src\include\sodium\crypto_hash_sha256.h"/> + <ClInclude Include="src\include\sodium\crypto_stream.h"/> + <ClInclude Include="src\include\sodium\crypto_auth_hmacsha512.h"/> + <ClInclude Include="src\include\sodium\crypto_aead_xchacha20poly1305.h"/> + <ClInclude Include="src\include\sodium\crypto_stream_salsa20.h"/> + <ClInclude Include="src\include\sodium\crypto_onetimeauth_poly1305.h"/> + <ClInclude Include="src\include\sodium\crypto_kx.h"/> + <ClInclude Include="src\include\sodium\crypto_hash.h"/> + <ClInclude Include="src\include\sodium\crypto_sign.h"/> + <ClInclude Include="src\include\sodium\crypto_kdf.h"/> + <ClInclude Include="src\include\sodium\crypto_auth_hmacsha256.h"/> + <ClInclude Include="src\include\sodium\crypto_box.h"/> + <ClInclude Include="src\include\sodium\crypto_verify_32.h"/> + <ClInclude Include="src\include\sodium\crypto_stream_xchacha20.h"/> + <ClInclude Include="src\include\sodium\crypto_core_salsa208.h"/> + <ClInclude Include="src\include\sodium\crypto_auth_hmacsha512256.h"/> + <ClInclude Include="src\include\sodium\crypto_aead_chacha20poly1305.h"/> + <ClInclude Include="src\include\sodium\randombytes_sysrandom.h"/> + <ClInclude Include="src\include\sodium\runtime.h"/> + <ClInclude Include="src\include\sodium\crypto_stream_salsa208.h"/> + <ClInclude Include="src\include\sodium\crypto_aead_aes256gcm.h"/> + <ClInclude Include="src\include\sodium\crypto_core_salsa2012.h"/> + <ClInclude Include="src\include\sodium\crypto_secretbox_xchacha20poly1305.h"/> + <ClInclude Include="src\include\sodium\randombytes_nativeclient.h"/> + <ClInclude Include="src\include\sodium\crypto_scalarmult.h"/> + <ClInclude Include="src\include\sodium\crypto_pwhash.h"/> + <ClInclude Include="src\include\sodium\crypto_verify_16.h"/> + <ClInclude Include="src\include\sodium\crypto_stream_chacha20.h"/> + <ClInclude Include="src\include\sodium\crypto_stream_xsalsa20.h"/> + <ClInclude Include="src\include\sodium\crypto_core_hsalsa20.h"/> + <ClInclude Include="src\include\sodium\crypto_kdf_blake2b.h"/> + <ClInclude Include="src\include\sodium\crypto_scalarmult_curve25519.h"/> + <ClInclude Include="src\include\sodium\crypto_shorthash.h"/> + <ClInclude Include="src\include\sodium\crypto_pwhash_argon2id.h"/> + <ClInclude Include="src\include\sodium\crypto_secretstream_xchacha20poly1305.h"/> + <ClInclude Include="src\include\sodium\crypto_pwhash_scryptsalsa208sha256.h"/> + <ClInclude Include="src\include\sodium\crypto_sign_ed25519.h"/> + <ClInclude Include="src\include\sodium\crypto_onetimeauth.h"/> + <ClInclude Include="src\include\sodium\crypto_verify_64.h"/> + <ClInclude Include="src\include\sodium\crypto_box_curve25519xchacha20poly1305.h"/> + <ClInclude Include="src\include\sodium\crypto_core_ed25519.h"/> + <ClInclude Include="src\include\sodium\crypto_pwhash_argon2i.h"/> + <ClInclude Include="src\include\sodium\crypto_generichash.h"/> + <ClInclude Include="src\include\sodium\crypto_secretbox_xsalsa20poly1305.h"/> + <ClInclude Include="src\include\sodium\crypto_secretbox.h"/> + <ClInclude Include="src\include\sodium\crypto_scalarmult_ed25519.h"/> + <ClInclude Include="src\include\sodium\crypto_box_curve25519xsalsa20poly1305.h"/> + <ClInclude Include="src\include\sodium\crypto_generichash_blake2b.h"/> + <ClInclude Include="src\include\sodium\crypto_sign_edwards25519sha512batch.h"/> + <ClInclude Include="src\include\sodium\version.h"/> + <ClInclude Include="src\include\sodium\private\ed25519_ref10.h"/> + <ClInclude Include="src\include\sodium\private\ed25519_ref10_fe_25_5.h"/> + <ClInclude Include="src\include\sodium\private\ed25519_ref10_fe_51.h"/> + <ClInclude Include="src\include\sodium\private\sse2_64_32.h"/> + <ClInclude Include="src\include\sodium\private\common.h"/> + <ClInclude Include="src\include\sodium\private\mutex.h"/> + <ClInclude Include="src\include\sodium\private\implementations.h"/> + <ClInclude Include="src\crypto_pwhash\argon2\blamka-round-ref.h"/> + <ClInclude Include="src\crypto_pwhash\argon2\blamka-round-avx2.h"/> + <ClInclude Include="src\crypto_pwhash\argon2\argon2.h"/> + <ClInclude Include="src\crypto_pwhash\argon2\blamka-round-ssse3.h"/> + <ClInclude Include="src\crypto_pwhash\argon2\argon2-encoding.h"/> + <ClInclude Include="src\crypto_pwhash\argon2\blake2b-long.h"/> + <ClInclude Include="src\crypto_pwhash\argon2\blamka-round-avx512f.h"/> + <ClInclude Include="src\crypto_pwhash\argon2\argon2-core.h"/> + <ClInclude Include="src\crypto_pwhash\scryptsalsa208sha256\crypto_scrypt.h"/> + <ClInclude Include="src\crypto_pwhash\scryptsalsa208sha256\pbkdf2-sha256.h"/> + <ClInclude Include="src\crypto_shorthash\siphash24\ref\shorthash_siphash_ref.h"/> + <ClInclude Include="src\crypto_scalarmult\curve25519\scalarmult_curve25519.h"/> + <ClInclude Include="src\crypto_scalarmult\curve25519\sandy2x\consts_namespace.h"/> + <ClInclude Include="src\crypto_scalarmult\curve25519\sandy2x\ladder_namespace.h"/> + <ClInclude Include="src\crypto_scalarmult\curve25519\sandy2x\fe.h"/> + <ClInclude Include="src\crypto_scalarmult\curve25519\sandy2x\ladder_base_namespace.h"/> + <ClInclude Include="src\crypto_scalarmult\curve25519\sandy2x\ladder.h"/> + <ClInclude Include="src\crypto_scalarmult\curve25519\sandy2x\fe51.h"/> + <ClInclude Include="src\crypto_scalarmult\curve25519\sandy2x\curve25519_sandy2x.h"/> + <ClInclude Include="src\crypto_scalarmult\curve25519\sandy2x\fe51_namespace.h"/> + <ClInclude Include="src\crypto_scalarmult\curve25519\sandy2x\ladder_base.h"/> + <ClInclude Include="src\crypto_scalarmult\curve25519\ref10\x25519_ref10.h"/> + <ClInclude Include="src\crypto_onetimeauth\poly1305\onetimeauth_poly1305.h"/> + <ClInclude Include="src\crypto_onetimeauth\poly1305\donna\poly1305_donna.h"/> + <ClInclude Include="src\crypto_onetimeauth\poly1305\donna\poly1305_donna64.h"/> + <ClInclude Include="src\crypto_onetimeauth\poly1305\donna\poly1305_donna32.h"/> + <ClInclude Include="src\crypto_onetimeauth\poly1305\sse2\poly1305_sse2.h"/> + <ClInclude Include="src\crypto_stream\chacha20\stream_chacha20.h"/> + <ClInclude Include="src\crypto_stream\chacha20\ref\chacha20_ref.h"/> + <ClInclude Include="src\crypto_stream\chacha20\dolbeau\u4.h"/> + <ClInclude Include="src\crypto_stream\chacha20\dolbeau\chacha20_dolbeau-ssse3.h"/> + <ClInclude Include="src\crypto_stream\chacha20\dolbeau\u0.h"/> + <ClInclude Include="src\crypto_stream\chacha20\dolbeau\u1.h"/> + <ClInclude Include="src\crypto_stream\chacha20\dolbeau\chacha20_dolbeau-avx2.h"/> + <ClInclude Include="src\crypto_stream\chacha20\dolbeau\u8.h"/> + <ClInclude Include="src\crypto_stream\salsa20\stream_salsa20.h"/> + <ClInclude Include="src\crypto_stream\salsa20\ref\salsa20_ref.h"/> + <ClInclude Include="src\crypto_stream\salsa20\xmm6int\u4.h"/> + <ClInclude Include="src\crypto_stream\salsa20\xmm6int\u0.h"/> + <ClInclude Include="src\crypto_stream\salsa20\xmm6int\u1.h"/> + <ClInclude Include="src\crypto_stream\salsa20\xmm6int\salsa20_xmm6int-avx2.h"/> + <ClInclude Include="src\crypto_stream\salsa20\xmm6int\u8.h"/> + <ClInclude Include="src\crypto_stream\salsa20\xmm6int\salsa20_xmm6int-sse2.h"/> + <ClInclude Include="src\crypto_stream\salsa20\xmm6\salsa20_xmm6.h"/> + <ClInclude Include="src\crypto_core\ed25519\ref10\fe_25_5\constants.h"/> + <ClInclude Include="src\crypto_core\ed25519\ref10\fe_25_5\fe.h"/> + <ClInclude Include="src\crypto_core\ed25519\ref10\fe_25_5\base2.h"/> + <ClInclude Include="src\crypto_core\ed25519\ref10\fe_25_5\base.h"/> + <ClInclude Include="src\crypto_core\ed25519\ref10\fe_51\constants.h"/> + <ClInclude Include="src\crypto_core\ed25519\ref10\fe_51\fe.h"/> + <ClInclude Include="src\crypto_core\ed25519\ref10\fe_51\base2.h"/> + <ClInclude Include="src\crypto_core\ed25519\ref10\fe_51\base.h"/> + </ItemGroup> +</Project> diff --git a/libs/libsodium/libsodium.vcxproj.filters b/libs/libsodium/libsodium.vcxproj.filters new file mode 100644 index 0000000000..8f90aeb3d5 --- /dev/null +++ b/libs/libsodium/libsodium.vcxproj.filters @@ -0,0 +1,4 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <Import Project="$(ProjectDir)..\..\build\vc.common\common.filters" /> +</Project> diff --git a/libs/libsodium/src/crypto_aead/aes256gcm/aesni/aead_aes256gcm_aesni.c b/libs/libsodium/src/crypto_aead/aes256gcm/aesni/aead_aes256gcm_aesni.c new file mode 100644 index 0000000000..dc54bca76b --- /dev/null +++ b/libs/libsodium/src/crypto_aead/aes256gcm/aesni/aead_aes256gcm_aesni.c @@ -0,0 +1,1079 @@ + +/* + * AES256-GCM, based on the "Intel Carry-Less Multiplication Instruction and its Usage for Computing + * the GCM Mode" paper and reference code, using the aggregated reduction method. + * Originally adapted by Romain Dolbeau. + */ + +#include <errno.h> +#include <stdint.h> +#include <stdlib.h> +#include <string.h> + +#include "core.h" +#include "crypto_aead_aes256gcm.h" +#include "export.h" +#include "private/common.h" +#include "private/sse2_64_32.h" +#include "randombytes.h" +#include "runtime.h" +#include "utils.h" + +#if defined(HAVE_TMMINTRIN_H) && defined(HAVE_WMMINTRIN_H) + +# ifdef __GNUC__ +# pragma GCC target("ssse3") +# pragma GCC target("aes") +# pragma GCC target("pclmul") +# endif + +#include <tmmintrin.h> +#include <wmmintrin.h> + +#ifndef ENOSYS +# define ENOSYS ENXIO +#endif + +#if defined(__INTEL_COMPILER) || defined(_bswap64) +#elif defined(_MSC_VER) +# define _bswap64(a) _byteswap_uint64(a) +#elif defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 2)) +# define _bswap64(a) __builtin_bswap64(a) +#else +static inline uint64_t +_bswap64(const uint64_t x) +{ + return + ((x << 56) & 0xFF00000000000000UL) | ((x << 40) & 0x00FF000000000000UL) | + ((x << 24) & 0x0000FF0000000000UL) | ((x << 8) & 0x000000FF00000000UL) | + ((x >> 8) & 0x00000000FF000000UL) | ((x >> 24) & 0x0000000000FF0000UL) | + ((x >> 40) & 0x000000000000FF00UL) | ((x >> 56) & 0x00000000000000FFUL); +} +#endif + +typedef struct context { + CRYPTO_ALIGN(16) unsigned char H[16]; + __m128i rkeys[16]; +} context; + +static inline void +aesni_key256_expand(const unsigned char *key, __m128i * const rkeys) +{ + __m128i X0, X1, X2, X3; + int i = 0; + + X0 = _mm_loadu_si128((const __m128i *) &key[0]); + rkeys[i++] = X0; + + X2 = _mm_loadu_si128((const __m128i *) &key[16]); + rkeys[i++] = X2; + +#define EXPAND_KEY_1(S) do { \ + X1 = _mm_shuffle_epi32(_mm_aeskeygenassist_si128(X2, (S)), 0xff); \ + X3 = _mm_castps_si128(_mm_shuffle_ps(_mm_castsi128_ps(X3), _mm_castsi128_ps(X0), 0x10)); \ + X0 = _mm_xor_si128(X0, X3); \ + X3 = _mm_castps_si128(_mm_shuffle_ps(_mm_castsi128_ps(X3), _mm_castsi128_ps(X0), 0x8c)); \ + X0 = _mm_xor_si128(_mm_xor_si128(X0, X3), X1); \ + rkeys[i++] = X0; \ +} while (0) + +#define EXPAND_KEY_2(S) do { \ + X1 = _mm_shuffle_epi32(_mm_aeskeygenassist_si128(X0, (S)), 0xaa); \ + X3 = _mm_castps_si128(_mm_shuffle_ps(_mm_castsi128_ps(X3), _mm_castsi128_ps(X2), 0x10)); \ + X2 = _mm_xor_si128(X2, X3); \ + X3 = _mm_castps_si128(_mm_shuffle_ps(_mm_castsi128_ps(X3), _mm_castsi128_ps(X2), 0x8c)); \ + X2 = _mm_xor_si128(_mm_xor_si128(X2, X3), X1); \ + rkeys[i++] = X2; \ +} while (0) + + X3 = _mm_setzero_si128(); + EXPAND_KEY_1(0x01); EXPAND_KEY_2(0x01); + EXPAND_KEY_1(0x02); EXPAND_KEY_2(0x02); + EXPAND_KEY_1(0x04); EXPAND_KEY_2(0x04); + EXPAND_KEY_1(0x08); EXPAND_KEY_2(0x08); + EXPAND_KEY_1(0x10); EXPAND_KEY_2(0x10); + EXPAND_KEY_1(0x20); EXPAND_KEY_2(0x20); + EXPAND_KEY_1(0x40); +} + +/** single, by-the-book AES encryption with AES-NI */ +static inline void +aesni_encrypt1(unsigned char *out, __m128i nv, const __m128i *rkeys) +{ + __m128i temp = _mm_xor_si128(nv, rkeys[0]); + + temp = _mm_aesenc_si128(temp, rkeys[1]); + temp = _mm_aesenc_si128(temp, rkeys[2]); + temp = _mm_aesenc_si128(temp, rkeys[3]); + temp = _mm_aesenc_si128(temp, rkeys[4]); + temp = _mm_aesenc_si128(temp, rkeys[5]); + temp = _mm_aesenc_si128(temp, rkeys[6]); + temp = _mm_aesenc_si128(temp, rkeys[7]); + temp = _mm_aesenc_si128(temp, rkeys[8]); + temp = _mm_aesenc_si128(temp, rkeys[9]); + temp = _mm_aesenc_si128(temp, rkeys[10]); + temp = _mm_aesenc_si128(temp, rkeys[11]); + temp = _mm_aesenc_si128(temp, rkeys[12]); + temp = _mm_aesenc_si128(temp, rkeys[13]); + + temp = _mm_aesenclast_si128(temp, rkeys[14]); + _mm_storeu_si128((__m128i *) out, temp); +} + +/** multiple-blocks-at-once AES encryption with AES-NI ; + on Haswell, aesenc has a latency of 7 and a throughput of 1 + so the sequence of aesenc should be bubble-free if you + have at least 8 blocks. Let's build an arbitratry-sized + function */ +/* Step 1 : loading the nonce */ +/* load & increment the n vector (non-vectorized, unused for now) */ +#define NVDECLx(a) \ + __m128i nv##a + +#define NVx(a) \ + nv##a = _mm_shuffle_epi8(_mm_load_si128((const __m128i *) n), pt); \ + n[3]++ + +/* Step 2 : define value in round one (xor with subkey #0, aka key) */ +#define TEMPDECLx(a) \ + __m128i temp##a + +#define TEMPx(a) \ + temp##a = _mm_xor_si128(nv##a, rkeys[0]) + +/* Step 3: one round of AES */ +#define AESENCx(a) \ + temp##a = _mm_aesenc_si128(temp##a, rkeys[roundctr]) + +/* Step 4: last round of AES */ +#define AESENCLASTx(a) \ + temp##a = _mm_aesenclast_si128(temp##a, rkeys[14]) + +/* Step 5: store result */ +#define STOREx(a) \ + _mm_storeu_si128((__m128i *) (out + (a * 16)), temp##a) + +/* all the MAKE* macros are for automatic explicit unrolling */ +#define MAKE4(X) \ + X(0); \ + X(1); \ + X(2); \ + X(3) + +#define MAKE8(X) \ + X(0); \ + X(1); \ + X(2); \ + X(3); \ + X(4); \ + X(5); \ + X(6); \ + X(7) + +#define COUNTER_INC2(N) (N)[3] += 2 + +/* create a function of unrolling N ; the MAKEN is the unrolling + macro, defined above. The N in MAKEN must match N, obviously. */ +#define FUNC(N, MAKEN) \ + static inline void aesni_encrypt##N(unsigned char *out, uint32_t *n, const __m128i *rkeys) \ + { \ + const __m128i pt = _mm_set_epi8(12, 13, 14, 15, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \ + int roundctr; \ + MAKEN(NVDECLx); \ + MAKEN(TEMPDECLx); \ + \ + MAKEN(NVx); \ + MAKEN(TEMPx); \ + for (roundctr = 1; roundctr < 14; roundctr++) { \ + MAKEN(AESENCx); \ + } \ + MAKEN(AESENCLASTx); \ + MAKEN(STOREx); \ + } + +FUNC(8, MAKE8) + +/* all GF(2^128) fnctions are by the book, meaning this one: + <https://software.intel.com/sites/default/files/managed/72/cc/clmul-wp-rev-2.02-2014-04-20.pdf> +*/ + +static inline void +addmul(unsigned char *c, const unsigned char *a, unsigned int xlen, const unsigned char *b) +{ + const __m128i rev = _mm_set_epi8(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15); + __m128i A, B, C; + __m128i tmp2, tmp3, tmp4, tmp5, tmp6, tmp7, tmp8, tmp9; + __m128i tmp10, tmp11, tmp12, tmp13, tmp14, tmp15, tmp16, tmp17, tmp18; + __m128i tmp19, tmp20, tmp21, tmp22, tmp23, tmp24, tmp25, tmp26, tmp27; + __m128i tmp28, tmp29, tmp30, tmp31, tmp32, tmp33, tmp34, tmp35, tmp36; + + if (xlen >= 16) { + A = _mm_loadu_si128((const __m128i *) a); + } else { + CRYPTO_ALIGN(16) unsigned char padded[16]; + unsigned int i; + + memset(padded, 0, 16); + for (i = 0; i < xlen; i++) { + padded[i] = a[i]; + } + A = _mm_load_si128((const __m128i *) padded); + } + A = _mm_shuffle_epi8(A, rev); + B = _mm_loadu_si128((const __m128i *) b); + C = _mm_loadu_si128((const __m128i *) c); + A = _mm_xor_si128(A, C); + tmp3 = _mm_clmulepi64_si128(A, B, 0x00); + tmp4 = _mm_clmulepi64_si128(A, B, 0x10); + tmp5 = _mm_clmulepi64_si128(A, B, 0x01); + tmp6 = _mm_clmulepi64_si128(A, B, 0x11); + tmp10 = _mm_xor_si128(tmp4, tmp5); + tmp13 = _mm_slli_si128(tmp10, 8); + tmp11 = _mm_srli_si128(tmp10, 8); + tmp15 = _mm_xor_si128(tmp3, tmp13); + tmp17 = _mm_xor_si128(tmp6, tmp11); + tmp7 = _mm_srli_epi32(tmp15, 31); + tmp8 = _mm_srli_epi32(tmp17, 31); + tmp16 = _mm_slli_epi32(tmp15, 1); + tmp18 = _mm_slli_epi32(tmp17, 1); + tmp9 = _mm_srli_si128(tmp7, 12); + tmp22 = _mm_slli_si128(tmp8, 4); + tmp25 = _mm_slli_si128(tmp7, 4); + tmp29 = _mm_or_si128(tmp16, tmp25); + tmp19 = _mm_or_si128(tmp18, tmp22); + tmp20 = _mm_or_si128(tmp19, tmp9); + tmp26 = _mm_slli_epi32(tmp29, 31); + tmp23 = _mm_slli_epi32(tmp29, 30); + tmp32 = _mm_slli_epi32(tmp29, 25); + tmp27 = _mm_xor_si128(tmp26, tmp23); + tmp28 = _mm_xor_si128(tmp27, tmp32); + tmp24 = _mm_srli_si128(tmp28, 4); + tmp33 = _mm_slli_si128(tmp28, 12); + tmp30 = _mm_xor_si128(tmp29, tmp33); + tmp2 = _mm_srli_epi32(tmp30, 1); + tmp12 = _mm_srli_epi32(tmp30, 2); + tmp14 = _mm_srli_epi32(tmp30, 7); + tmp34 = _mm_xor_si128(tmp2, tmp12); + tmp35 = _mm_xor_si128(tmp34, tmp14); + tmp36 = _mm_xor_si128(tmp35, tmp24); + tmp31 = _mm_xor_si128(tmp30, tmp36); + tmp21 = _mm_xor_si128(tmp20, tmp31); + _mm_storeu_si128((__m128i *) c, tmp21); +} + +/* pure multiplication, for pre-computing powers of H */ +static inline __m128i +mulv(__m128i A, __m128i B) +{ + __m128i tmp3 = _mm_clmulepi64_si128(A, B, 0x00); + __m128i tmp4 = _mm_clmulepi64_si128(A, B, 0x10); + __m128i tmp5 = _mm_clmulepi64_si128(A, B, 0x01); + __m128i tmp6 = _mm_clmulepi64_si128(A, B, 0x11); + __m128i tmp10 = _mm_xor_si128(tmp4, tmp5); + __m128i tmp13 = _mm_slli_si128(tmp10, 8); + __m128i tmp11 = _mm_srli_si128(tmp10, 8); + __m128i tmp15 = _mm_xor_si128(tmp3, tmp13); + __m128i tmp17 = _mm_xor_si128(tmp6, tmp11); + __m128i tmp7 = _mm_srli_epi32(tmp15, 31); + __m128i tmp8 = _mm_srli_epi32(tmp17, 31); + __m128i tmp16 = _mm_slli_epi32(tmp15, 1); + __m128i tmp18 = _mm_slli_epi32(tmp17, 1); + __m128i tmp9 = _mm_srli_si128(tmp7, 12); + __m128i tmp22 = _mm_slli_si128(tmp8, 4); + __m128i tmp25 = _mm_slli_si128(tmp7, 4); + __m128i tmp29 = _mm_or_si128(tmp16, tmp25); + __m128i tmp19 = _mm_or_si128(tmp18, tmp22); + __m128i tmp20 = _mm_or_si128(tmp19, tmp9); + __m128i tmp26 = _mm_slli_epi32(tmp29, 31); + __m128i tmp23 = _mm_slli_epi32(tmp29, 30); + __m128i tmp32 = _mm_slli_epi32(tmp29, 25); + __m128i tmp27 = _mm_xor_si128(tmp26, tmp23); + __m128i tmp28 = _mm_xor_si128(tmp27, tmp32); + __m128i tmp24 = _mm_srli_si128(tmp28, 4); + __m128i tmp33 = _mm_slli_si128(tmp28, 12); + __m128i tmp30 = _mm_xor_si128(tmp29, tmp33); + __m128i tmp2 = _mm_srli_epi32(tmp30, 1); + __m128i tmp12 = _mm_srli_epi32(tmp30, 2); + __m128i tmp14 = _mm_srli_epi32(tmp30, 7); + __m128i tmp34 = _mm_xor_si128(tmp2, tmp12); + __m128i tmp35 = _mm_xor_si128(tmp34, tmp14); + __m128i tmp36 = _mm_xor_si128(tmp35, tmp24); + __m128i tmp31 = _mm_xor_si128(tmp30, tmp36); + __m128i C = _mm_xor_si128(tmp20, tmp31); + + return C; +} + +/* 4 multiply-accumulate at once; again + <https://software.intel.com/sites/default/files/managed/72/cc/clmul-wp-rev-2.02-2014-04-20.pdf> + for the Aggregated Reduction Method & sample code. + Algorithm by Krzysztof Jankowski, Pierre Laurent - Intel */ + +#define RED_DECL(a) __m128i H##a##_X##a##_lo, H##a##_X##a##_hi, tmp##a, tmp##a##B +#define RED_SHUFFLE(a) X##a = _mm_shuffle_epi8(X##a, rev) +#define RED_MUL_LOW(a) H##a##_X##a##_lo = _mm_clmulepi64_si128(H##a, X##a, 0x00) +#define RED_MUL_HIGH(a) H##a##_X##a##_hi = _mm_clmulepi64_si128(H##a, X##a, 0x11) +#define RED_MUL_MID(a) \ + tmp##a = _mm_shuffle_epi32(H##a, 0x4e); \ + tmp##a##B = _mm_shuffle_epi32(X##a, 0x4e); \ + tmp##a = _mm_xor_si128(tmp##a, H##a); \ + tmp##a##B = _mm_xor_si128(tmp##a##B, X##a); \ + tmp##a = _mm_clmulepi64_si128(tmp##a, tmp##a##B, 0x00) + +#define MULREDUCE4(rev, H0_, H1_, H2_, H3_, X0_, X1_, X2_, X3_, accv) \ +do { \ + MAKE4(RED_DECL); \ + __m128i lo, hi; \ + __m128i tmp8, tmp9; \ + __m128i H0 = H0_; \ + __m128i H1 = H1_; \ + __m128i H2 = H2_; \ + __m128i H3 = H3_; \ + __m128i X0 = X0_; \ + __m128i X1 = X1_; \ + __m128i X2 = X2_; \ + __m128i X3 = X3_; \ +\ +/* byte-revert the inputs & xor the first one into the accumulator */ \ +\ + MAKE4(RED_SHUFFLE); \ + X3 = _mm_xor_si128(X3, accv); \ +\ +/* 4 low H*X (x0*h0) */ \ +\ + MAKE4(RED_MUL_LOW); \ + lo = _mm_xor_si128(H0_X0_lo, H1_X1_lo); \ + lo = _mm_xor_si128(lo, H2_X2_lo); \ + lo = _mm_xor_si128(lo, H3_X3_lo); \ +\ +/* 4 high H*X (x1*h1) */ \ +\ + MAKE4(RED_MUL_HIGH); \ + hi = _mm_xor_si128(H0_X0_hi, H1_X1_hi); \ + hi = _mm_xor_si128(hi, H2_X2_hi); \ + hi = _mm_xor_si128(hi, H3_X3_hi); \ +\ +/* 4 middle H*X, using Karatsuba, i.e. \ + x1*h0+x0*h1 =(x1+x0)*(h1+h0)-x1*h1-x0*h0 \ + we already have all x1y1 & x0y0 (accumulated in hi & lo) \ + (0 is low half and 1 is high half) \ + */ \ +/* permute the high and low 64 bits in H1 & X1, \ + so create (h0,h1) from (h1,h0) and (x0,x1) from (x1,x0), \ + then compute (h0+h1,h1+h0) and (x0+x1,x1+x0), \ + and finally multiply \ + */ \ + MAKE4(RED_MUL_MID); \ +\ +/* substracts x1*h1 and x0*h0 */ \ + tmp0 = _mm_xor_si128(tmp0, lo); \ + tmp0 = _mm_xor_si128(tmp0, hi); \ + tmp0 = _mm_xor_si128(tmp1, tmp0); \ + tmp0 = _mm_xor_si128(tmp2, tmp0); \ + tmp0 = _mm_xor_si128(tmp3, tmp0);\ +\ + /* reduction */ \ + tmp0B = _mm_slli_si128(tmp0, 8); \ + tmp0 = _mm_srli_si128(tmp0, 8); \ + lo = _mm_xor_si128(tmp0B, lo); \ + hi = _mm_xor_si128(tmp0, hi); \ + tmp3 = lo; \ + tmp2B = hi; \ + tmp3B = _mm_srli_epi32(tmp3, 31); \ + tmp8 = _mm_srli_epi32(tmp2B, 31); \ + tmp3 = _mm_slli_epi32(tmp3, 1); \ + tmp2B = _mm_slli_epi32(tmp2B, 1); \ + tmp9 = _mm_srli_si128(tmp3B, 12); \ + tmp8 = _mm_slli_si128(tmp8, 4); \ + tmp3B = _mm_slli_si128(tmp3B, 4); \ + tmp3 = _mm_or_si128(tmp3, tmp3B); \ + tmp2B = _mm_or_si128(tmp2B, tmp8); \ + tmp2B = _mm_or_si128(tmp2B, tmp9); \ + tmp3B = _mm_slli_epi32(tmp3, 31); \ + tmp8 = _mm_slli_epi32(tmp3, 30); \ + tmp9 = _mm_slli_epi32(tmp3, 25); \ + tmp3B = _mm_xor_si128(tmp3B, tmp8); \ + tmp3B = _mm_xor_si128(tmp3B, tmp9); \ + tmp8 = _mm_srli_si128(tmp3B, 4); \ + tmp3B = _mm_slli_si128(tmp3B, 12); \ + tmp3 = _mm_xor_si128(tmp3, tmp3B); \ + tmp2 = _mm_srli_epi32(tmp3, 1); \ + tmp0B = _mm_srli_epi32(tmp3, 2); \ + tmp1B = _mm_srli_epi32(tmp3, 7); \ + tmp2 = _mm_xor_si128(tmp2, tmp0B); \ + tmp2 = _mm_xor_si128(tmp2, tmp1B); \ + tmp2 = _mm_xor_si128(tmp2, tmp8); \ + tmp3 = _mm_xor_si128(tmp3, tmp2); \ + tmp2B = _mm_xor_si128(tmp2B, tmp3); \ +\ + accv = tmp2B; \ +} while(0) + +#define XORx(a) \ + temp##a = _mm_xor_si128(temp##a, \ + _mm_loadu_si128((const __m128i *) (in + a * 16))) + +#define LOADx(a) \ + __m128i in##a = _mm_loadu_si128((const __m128i *) (in + a * 16)) + +/* full encrypt & checksum 8 blocks at once */ +#define aesni_encrypt8full(out_, n_, rkeys, in_, accum, hv_, h2v_, h3v_, h4v_, rev) \ +do { \ + unsigned char *out = out_; \ + uint32_t *n = n_; \ + const unsigned char *in = in_; \ + const __m128i hv = hv_; \ + const __m128i h2v = h2v_; \ + const __m128i h3v = h3v_; \ + const __m128i h4v = h4v_; \ + const __m128i pt = _mm_set_epi8(12, 13, 14, 15, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \ + __m128i accv_; \ + int roundctr; \ + \ + MAKE8(NVDECLx); \ + MAKE8(TEMPDECLx); \ + MAKE8(NVx); \ + MAKE8(TEMPx); \ + for (roundctr = 1; roundctr < 14; roundctr++) { \ + MAKE8(AESENCx); \ + } \ + MAKE8(AESENCLASTx); \ + MAKE8(XORx); \ + MAKE8(STOREx); \ + accv_ = _mm_load_si128((const __m128i *) accum); \ + MULREDUCE4(rev, hv, h2v, h3v, h4v, temp3, temp2, temp1, temp0, accv_); \ + MULREDUCE4(rev, hv, h2v, h3v, h4v, temp7, temp6, temp5, temp4, accv_); \ + _mm_store_si128((__m128i *) accum, accv_); \ +} while(0) + +/* checksum 8 blocks at once */ +#define aesni_addmul8full(in_, accum, hv_, h2v_, h3v_, h4v_, rev) \ +do { \ + const unsigned char *in = in_; \ + const __m128i hv = hv_; \ + const __m128i h2v = h2v_; \ + const __m128i h3v = h3v_; \ + const __m128i h4v = h4v_; \ + __m128i accv_; \ + \ + MAKE8(LOADx); \ + accv_ = _mm_load_si128((const __m128i *) accum); \ + MULREDUCE4(rev, hv, h2v, h3v, h4v, in3, in2, in1, in0, accv_); \ + MULREDUCE4(rev, hv, h2v, h3v, h4v, in7, in6, in5, in4, accv_); \ + _mm_store_si128((__m128i *) accum, accv_); \ +} while(0) + +/* decrypt 8 blocks at once */ +#define aesni_decrypt8full(out_, n_, rkeys, in_) \ +do { \ + unsigned char *out = out_; \ + uint32_t *n = n_; \ + const unsigned char *in = in_; \ + const __m128i pt = _mm_set_epi8(12, 13, 14, 15, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \ + int roundctr; \ +\ + MAKE8(NVDECLx); \ + MAKE8(TEMPDECLx); \ + MAKE8(NVx); \ + MAKE8(TEMPx); \ + for (roundctr = 1; roundctr < 14; roundctr++) { \ + MAKE8(AESENCx); \ + } \ + MAKE8(AESENCLASTx); \ + MAKE8(XORx); \ + MAKE8(STOREx); \ +} while(0) + +int +crypto_aead_aes256gcm_beforenm(crypto_aead_aes256gcm_state *ctx_, + const unsigned char *k) +{ + context *ctx = (context *) ctx_; + __m128i *rkeys = ctx->rkeys; + __m128i zero = _mm_setzero_si128(); + unsigned char *H = ctx->H; + + COMPILER_ASSERT((sizeof *ctx_) >= (sizeof *ctx)); + aesni_key256_expand(k, rkeys); + aesni_encrypt1(H, zero, rkeys); + + return 0; +} + +int +crypto_aead_aes256gcm_encrypt_detached_afternm(unsigned char *c, + unsigned char *mac, unsigned long long *maclen_p, + const unsigned char *m, unsigned long long mlen, + const unsigned char *ad, unsigned long long adlen, + const unsigned char *nsec, + const unsigned char *npub, + const crypto_aead_aes256gcm_state *ctx_) +{ + const __m128i rev = _mm_set_epi8(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15); + const context *ctx = (const context *) ctx_; + const __m128i *rkeys = ctx->rkeys; + __m128i Hv, H2v, H3v, H4v, accv; + unsigned long long i, j; + unsigned long long adlen_rnd64 = adlen & ~63ULL; + unsigned long long mlen_rnd128 = mlen & ~127ULL; + CRYPTO_ALIGN(16) uint32_t n2[4]; + CRYPTO_ALIGN(16) unsigned char H[16]; + CRYPTO_ALIGN(16) unsigned char T[16]; + CRYPTO_ALIGN(16) unsigned char accum[16]; + CRYPTO_ALIGN(16) unsigned char fb[16]; + + (void) nsec; + memcpy(H, ctx->H, sizeof H); + if (mlen > crypto_aead_aes256gcm_MESSAGEBYTES_MAX) { + sodium_misuse(); /* LCOV_EXCL_LINE */ + } + memcpy(&n2[0], npub, 3 * 4); + n2[3] = 0x01000000; + aesni_encrypt1(T, _mm_load_si128((const __m128i *) n2), rkeys); + { + uint64_t x; + x = _bswap64((uint64_t) (8 * adlen)); + memcpy(&fb[0], &x, sizeof x); + x = _bswap64((uint64_t) (8 * mlen)); + memcpy(&fb[8], &x, sizeof x); + } + /* we store H (and it's power) byte-reverted once and for all */ + Hv = _mm_shuffle_epi8(_mm_load_si128((const __m128i *) H), rev); + _mm_store_si128((__m128i *) H, Hv); + H2v = mulv(Hv, Hv); + H3v = mulv(H2v, Hv); + H4v = mulv(H3v, Hv); + + accv = _mm_setzero_si128(); + /* unrolled by 4 GCM (by 8 doesn't improve using MULREDUCE4) */ + for (i = 0; i < adlen_rnd64; i += 64) { + __m128i X4_ = _mm_loadu_si128((const __m128i *) (ad + i + 0)); + __m128i X3_ = _mm_loadu_si128((const __m128i *) (ad + i + 16)); + __m128i X2_ = _mm_loadu_si128((const __m128i *) (ad + i + 32)); + __m128i X1_ = _mm_loadu_si128((const __m128i *) (ad + i + 48)); + MULREDUCE4(rev, Hv, H2v, H3v, H4v, X1_, X2_, X3_, X4_, accv); + } + _mm_store_si128((__m128i *) accum, accv); + + /* GCM remainder loop */ + for (i = adlen_rnd64; i < adlen; i += 16) { + unsigned int blocklen = 16; + + if (i + (unsigned long long) blocklen > adlen) { + blocklen = (unsigned int) (adlen - i); + } + addmul(accum, ad + i, blocklen, H); + } + +/* this only does 8 full blocks, so no fancy bounds checking is necessary*/ +#define LOOPRND128 \ + do { \ + const int iter = 8; \ + const int lb = iter * 16; \ + \ + for (i = 0; i < mlen_rnd128; i += lb) { \ + aesni_encrypt8full(c + i, n2, rkeys, m + i, accum, Hv, H2v, H3v, H4v, rev); \ + } \ + } while(0) + +/* remainder loop, with the slower GCM update to accommodate partial blocks */ +#define LOOPRMD128 \ + do { \ + const int iter = 8; \ + const int lb = iter * 16; \ + \ + for (i = mlen_rnd128; i < mlen; i += lb) { \ + CRYPTO_ALIGN(16) unsigned char outni[8 * 16]; \ + unsigned long long mj = lb; \ + \ + aesni_encrypt8(outni, n2, rkeys); \ + if ((i + mj) >= mlen) { \ + mj = mlen - i; \ + } \ + for (j = 0; j < mj; j++) { \ + c[i + j] = m[i + j] ^ outni[j]; \ + } \ + for (j = 0; j < mj; j += 16) { \ + unsigned int bl = 16; \ + \ + if (j + (unsigned long long) bl >= mj) { \ + bl = (unsigned int) (mj - j); \ + } \ + addmul(accum, c + i + j, bl, H); \ + } \ + } \ + } while(0) + + n2[3] &= 0x00ffffff; + COUNTER_INC2(n2); + LOOPRND128; + LOOPRMD128; + + addmul(accum, fb, 16, H); + + for (i = 0; i < 16; ++i) { + mac[i] = T[i] ^ accum[15 - i]; + } + if (maclen_p != NULL) { + *maclen_p = 16; + } + return 0; +} + +int +crypto_aead_aes256gcm_encrypt_afternm(unsigned char *c, unsigned long long *clen_p, + const unsigned char *m, unsigned long long mlen, + const unsigned char *ad, unsigned long long adlen, + const unsigned char *nsec, + const unsigned char *npub, + const crypto_aead_aes256gcm_state *ctx_) +{ + int ret = crypto_aead_aes256gcm_encrypt_detached_afternm(c, + c + mlen, NULL, + m, mlen, + ad, adlen, + nsec, npub, ctx_); + if (clen_p != NULL) { + *clen_p = mlen + crypto_aead_aes256gcm_ABYTES; + } + return ret; +} + +int +crypto_aead_aes256gcm_decrypt_detached_afternm(unsigned char *m, unsigned char *nsec, + const unsigned char *c, unsigned long long clen, + const unsigned char *mac, + const unsigned char *ad, unsigned long long adlen, + const unsigned char *npub, + const crypto_aead_aes256gcm_state *ctx_) +{ + const __m128i rev = _mm_set_epi8(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15); + const context *ctx = (const context *) ctx_; + const __m128i *rkeys = ctx->rkeys; + __m128i Hv, H2v, H3v, H4v, accv; + unsigned long long i, j; + unsigned long long adlen_rnd64 = adlen & ~63ULL; + unsigned long long mlen; + unsigned long long mlen_rnd128; + CRYPTO_ALIGN(16) uint32_t n2[4]; + CRYPTO_ALIGN(16) unsigned char H[16]; + CRYPTO_ALIGN(16) unsigned char T[16]; + CRYPTO_ALIGN(16) unsigned char accum[16]; + CRYPTO_ALIGN(16) unsigned char fb[16]; + + (void) nsec; + if (clen > crypto_aead_aes256gcm_MESSAGEBYTES_MAX) { + sodium_misuse(); /* LCOV_EXCL_LINE */ + } + mlen = clen; + + memcpy(&n2[0], npub, 3 * 4); + n2[3] = 0x01000000; + aesni_encrypt1(T, _mm_load_si128((const __m128i *) n2), rkeys); + + { + uint64_t x; + x = _bswap64((uint64_t)(8 * adlen)); + memcpy(&fb[0], &x, sizeof x); + x = _bswap64((uint64_t)(8 * mlen)); + memcpy(&fb[8], &x, sizeof x); + } + + memcpy(H, ctx->H, sizeof H); + Hv = _mm_shuffle_epi8(_mm_load_si128((const __m128i *) H), rev); + _mm_store_si128((__m128i *) H, Hv); + H2v = mulv(Hv, Hv); + H3v = mulv(H2v, Hv); + H4v = mulv(H3v, Hv); + + accv = _mm_setzero_si128(); + for (i = 0; i < adlen_rnd64; i += 64) { + __m128i X4_ = _mm_loadu_si128((const __m128i *) (ad + i + 0)); + __m128i X3_ = _mm_loadu_si128((const __m128i *) (ad + i + 16)); + __m128i X2_ = _mm_loadu_si128((const __m128i *) (ad + i + 32)); + __m128i X1_ = _mm_loadu_si128((const __m128i *) (ad + i + 48)); + MULREDUCE4(rev, Hv, H2v, H3v, H4v, X1_, X2_, X3_, X4_, accv); + } + _mm_store_si128((__m128i *) accum, accv); + + for (i = adlen_rnd64; i < adlen; i += 16) { + unsigned int blocklen = 16; + if (i + (unsigned long long) blocklen > adlen) { + blocklen = (unsigned int) (adlen - i); + } + addmul(accum, ad + i, blocklen, H); + } + + mlen_rnd128 = mlen & ~127ULL; + +#define LOOPACCUMDRND128 \ + do { \ + const int iter = 8; \ + const int lb = iter * 16; \ + for (i = 0; i < mlen_rnd128; i += lb) { \ + aesni_addmul8full(c + i, accum, Hv, H2v, H3v, H4v, rev); \ + } \ + } while(0) + +#define LOOPDRND128 \ + do { \ + const int iter = 8; \ + const int lb = iter * 16; \ + \ + for (i = 0; i < mlen_rnd128; i += lb) { \ + aesni_decrypt8full(m + i, n2, rkeys, c + i); \ + } \ + } while(0) + +#define LOOPACCUMDRMD128 \ + do { \ + const int iter = 8; \ + const int lb = iter * 16; \ + \ + for (i = mlen_rnd128; i < mlen; i += lb) { \ + unsigned long long mj = lb; \ + \ + if ((i + mj) >= mlen) { \ + mj = mlen - i; \ + } \ + for (j = 0; j < mj; j += 16) { \ + unsigned int bl = 16; \ + \ + if (j + (unsigned long long) bl >= mj) { \ + bl = (unsigned int) (mj - j); \ + } \ + addmul(accum, c + i + j, bl, H); \ + } \ + } \ + } while(0) + +#define LOOPDRMD128 \ + do { \ + const int iter = 8; \ + const int lb = iter * 16; \ + \ + for (i = mlen_rnd128; i < mlen; i += lb) { \ + CRYPTO_ALIGN(16) unsigned char outni[8 * 16]; \ + unsigned long long mj = lb; \ + \ + if ((i + mj) >= mlen) { \ + mj = mlen - i; \ + } \ + aesni_encrypt8(outni, n2, rkeys); \ + for (j = 0; j < mj; j++) { \ + m[i + j] = c[i + j] ^ outni[j]; \ + } \ + } \ + } while(0) + + n2[3] &= 0x00ffffff; + + COUNTER_INC2(n2); + LOOPACCUMDRND128; + LOOPACCUMDRMD128; + addmul(accum, fb, 16, H); + { + unsigned char d = 0; + + for (i = 0; i < 16; i++) { + d |= (mac[i] ^ (T[i] ^ accum[15 - i])); + } + if (d != 0) { + if (m != NULL) { + memset(m, 0, mlen); + } + return -1; + } + if (m == NULL) { + return 0; + } + } + n2[3] = 0U; + COUNTER_INC2(n2); + LOOPDRND128; + LOOPDRMD128; + + return 0; +} + +int +crypto_aead_aes256gcm_decrypt_afternm(unsigned char *m, unsigned long long *mlen_p, + unsigned char *nsec, + const unsigned char *c, unsigned long long clen, + const unsigned char *ad, unsigned long long adlen, + const unsigned char *npub, + const crypto_aead_aes256gcm_state *ctx_) +{ + unsigned long long mlen = 0ULL; + int ret = -1; + + if (clen >= crypto_aead_aes256gcm_ABYTES) { + ret = crypto_aead_aes256gcm_decrypt_detached_afternm + (m, nsec, c, clen - crypto_aead_aes256gcm_ABYTES, + c + clen - crypto_aead_aes256gcm_ABYTES, + ad, adlen, npub, ctx_); + } + if (mlen_p != NULL) { + if (ret == 0) { + mlen = clen - crypto_aead_aes256gcm_ABYTES; + } + *mlen_p = mlen; + } + return ret; +} + +int +crypto_aead_aes256gcm_encrypt_detached(unsigned char *c, + unsigned char *mac, + unsigned long long *maclen_p, + const unsigned char *m, + unsigned long long mlen, + const unsigned char *ad, + unsigned long long adlen, + const unsigned char *nsec, + const unsigned char *npub, + const unsigned char *k) +{ + CRYPTO_ALIGN(16) crypto_aead_aes256gcm_state ctx; + + crypto_aead_aes256gcm_beforenm(&ctx, k); + + return crypto_aead_aes256gcm_encrypt_detached_afternm + (c, mac, maclen_p, m, mlen, ad, adlen, nsec, npub, + (const crypto_aead_aes256gcm_state *) &ctx); +} + +int +crypto_aead_aes256gcm_encrypt(unsigned char *c, + unsigned long long *clen_p, + const unsigned char *m, + unsigned long long mlen, + const unsigned char *ad, + unsigned long long adlen, + const unsigned char *nsec, + const unsigned char *npub, + const unsigned char *k) +{ + CRYPTO_ALIGN(16) crypto_aead_aes256gcm_state ctx; + int ret; + + crypto_aead_aes256gcm_beforenm(&ctx, k); + + ret = crypto_aead_aes256gcm_encrypt_afternm + (c, clen_p, m, mlen, ad, adlen, nsec, npub, + (const crypto_aead_aes256gcm_state *) &ctx); + sodium_memzero(ctx, sizeof ctx); + + return ret; +} + +int +crypto_aead_aes256gcm_decrypt_detached(unsigned char *m, + unsigned char *nsec, + const unsigned char *c, + unsigned long long clen, + const unsigned char *mac, + const unsigned char *ad, + unsigned long long adlen, + const unsigned char *npub, + const unsigned char *k) +{ + CRYPTO_ALIGN(16) crypto_aead_aes256gcm_state ctx; + + crypto_aead_aes256gcm_beforenm(&ctx, k); + + return crypto_aead_aes256gcm_decrypt_detached_afternm + (m, nsec, c, clen, mac, ad, adlen, npub, + (const crypto_aead_aes256gcm_state *) &ctx); +} + +int +crypto_aead_aes256gcm_decrypt(unsigned char *m, + unsigned long long *mlen_p, + unsigned char *nsec, + const unsigned char *c, + unsigned long long clen, + const unsigned char *ad, + unsigned long long adlen, + const unsigned char *npub, + const unsigned char *k) +{ + CRYPTO_ALIGN(16) crypto_aead_aes256gcm_state ctx; + int ret; + + crypto_aead_aes256gcm_beforenm(&ctx, k); + + ret = crypto_aead_aes256gcm_decrypt_afternm + (m, mlen_p, nsec, c, clen, ad, adlen, npub, + (const crypto_aead_aes256gcm_state *) &ctx); + sodium_memzero(ctx, sizeof ctx); + + return ret; +} + +int +crypto_aead_aes256gcm_is_available(void) +{ + return sodium_runtime_has_pclmul() & sodium_runtime_has_aesni(); +} + +#else + +int +crypto_aead_aes256gcm_encrypt_detached(unsigned char *c, + unsigned char *mac, + unsigned long long *maclen_p, + const unsigned char *m, + unsigned long long mlen, + const unsigned char *ad, + unsigned long long adlen, + const unsigned char *nsec, + const unsigned char *npub, + const unsigned char *k) +{ + errno = ENOSYS; + return -1; +} + +int +crypto_aead_aes256gcm_encrypt(unsigned char *c, unsigned long long *clen_p, + const unsigned char *m, unsigned long long mlen, + const unsigned char *ad, unsigned long long adlen, + const unsigned char *nsec, const unsigned char *npub, + const unsigned char *k) +{ + errno = ENOSYS; + return -1; +} + +int +crypto_aead_aes256gcm_decrypt_detached(unsigned char *m, + unsigned char *nsec, + const unsigned char *c, + unsigned long long clen, + const unsigned char *mac, + const unsigned char *ad, + unsigned long long adlen, + const unsigned char *npub, + const unsigned char *k) +{ + errno = ENOSYS; + return -1; +} + +int +crypto_aead_aes256gcm_decrypt(unsigned char *m, unsigned long long *mlen_p, + unsigned char *nsec, const unsigned char *c, + unsigned long long clen, const unsigned char *ad, + unsigned long long adlen, const unsigned char *npub, + const unsigned char *k) +{ + errno = ENOSYS; + return -1; +} + +int +crypto_aead_aes256gcm_beforenm(crypto_aead_aes256gcm_state *ctx_, + const unsigned char *k) +{ + errno = ENOSYS; + return -1; +} + +int +crypto_aead_aes256gcm_encrypt_detached_afternm(unsigned char *c, + unsigned char *mac, unsigned long long *maclen_p, + const unsigned char *m, unsigned long long mlen, + const unsigned char *ad, unsigned long long adlen, + const unsigned char *nsec, + const unsigned char *npub, + const crypto_aead_aes256gcm_state *ctx_) +{ + errno = ENOSYS; + return -1; +} + +int +crypto_aead_aes256gcm_encrypt_afternm(unsigned char *c, unsigned long long *clen_p, + const unsigned char *m, unsigned long long mlen, + const unsigned char *ad, unsigned long long adlen, + const unsigned char *nsec, const unsigned char *npub, + const crypto_aead_aes256gcm_state *ctx_) +{ + errno = ENOSYS; + return -1; +} + +int +crypto_aead_aes256gcm_decrypt_detached_afternm(unsigned char *m, unsigned char *nsec, + const unsigned char *c, unsigned long long clen, + const unsigned char *mac, + const unsigned char *ad, unsigned long long adlen, + const unsigned char *npub, + const crypto_aead_aes256gcm_state *ctx_) +{ + errno = ENOSYS; + return -1; +} + +int +crypto_aead_aes256gcm_decrypt_afternm(unsigned char *m, unsigned long long *mlen_p, + unsigned char *nsec, + const unsigned char *c, unsigned long long clen, + const unsigned char *ad, unsigned long long adlen, + const unsigned char *npub, + const crypto_aead_aes256gcm_state *ctx_) +{ + errno = ENOSYS; + return -1; +} + +int +crypto_aead_aes256gcm_is_available(void) +{ + return 0; +} + +#endif + +size_t +crypto_aead_aes256gcm_keybytes(void) +{ + return crypto_aead_aes256gcm_KEYBYTES; +} + +size_t +crypto_aead_aes256gcm_nsecbytes(void) +{ + return crypto_aead_aes256gcm_NSECBYTES; +} + +size_t +crypto_aead_aes256gcm_npubbytes(void) +{ + return crypto_aead_aes256gcm_NPUBBYTES; +} + +size_t +crypto_aead_aes256gcm_abytes(void) +{ + return crypto_aead_aes256gcm_ABYTES; +} + +size_t +crypto_aead_aes256gcm_statebytes(void) +{ + return (sizeof(crypto_aead_aes256gcm_state) + (size_t) 15U) & ~(size_t) 15U; +} + +size_t +crypto_aead_aes256gcm_messagebytes_max(void) +{ + return crypto_aead_aes256gcm_MESSAGEBYTES_MAX; +} + +void +crypto_aead_aes256gcm_keygen(unsigned char k[crypto_aead_aes256gcm_KEYBYTES]) +{ + randombytes_buf(k, crypto_aead_aes256gcm_KEYBYTES); +} diff --git a/libs/libsodium/src/crypto_aead/chacha20poly1305/sodium/aead_chacha20poly1305.c b/libs/libsodium/src/crypto_aead/chacha20poly1305/sodium/aead_chacha20poly1305.c new file mode 100644 index 0000000000..c79407a185 --- /dev/null +++ b/libs/libsodium/src/crypto_aead/chacha20poly1305/sodium/aead_chacha20poly1305.c @@ -0,0 +1,399 @@ + +#include <stdint.h> +#include <stdlib.h> +#include <limits.h> +#include <string.h> + +#include "core.h" +#include "crypto_aead_chacha20poly1305.h" +#include "crypto_onetimeauth_poly1305.h" +#include "crypto_stream_chacha20.h" +#include "crypto_verify_16.h" +#include "randombytes.h" +#include "utils.h" + +#include "private/common.h" + +static const unsigned char _pad0[16] = { 0 }; + +int +crypto_aead_chacha20poly1305_encrypt_detached(unsigned char *c, + unsigned char *mac, + unsigned long long *maclen_p, + const unsigned char *m, + unsigned long long mlen, + const unsigned char *ad, + unsigned long long adlen, + const unsigned char *nsec, + const unsigned char *npub, + const unsigned char *k) +{ + crypto_onetimeauth_poly1305_state state; + unsigned char block0[64U]; + unsigned char slen[8U]; + + (void) nsec; + crypto_stream_chacha20(block0, sizeof block0, npub, k); + crypto_onetimeauth_poly1305_init(&state, block0); + sodium_memzero(block0, sizeof block0); + + crypto_onetimeauth_poly1305_update(&state, ad, adlen); + STORE64_LE(slen, (uint64_t) adlen); + crypto_onetimeauth_poly1305_update(&state, slen, sizeof slen); + + crypto_stream_chacha20_xor_ic(c, m, mlen, npub, 1U, k); + + crypto_onetimeauth_poly1305_update(&state, c, mlen); + STORE64_LE(slen, (uint64_t) mlen); + crypto_onetimeauth_poly1305_update(&state, slen, sizeof slen); + + crypto_onetimeauth_poly1305_final(&state, mac); + sodium_memzero(&state, sizeof state); + + if (maclen_p != NULL) { + *maclen_p = crypto_aead_chacha20poly1305_ABYTES; + } + return 0; +} + +int +crypto_aead_chacha20poly1305_encrypt(unsigned char *c, + unsigned long long *clen_p, + const unsigned char *m, + unsigned long long mlen, + const unsigned char *ad, + unsigned long long adlen, + const unsigned char *nsec, + const unsigned char *npub, + const unsigned char *k) +{ + unsigned long long clen = 0ULL; + int ret; + + if (mlen > crypto_aead_chacha20poly1305_MESSAGEBYTES_MAX) { + sodium_misuse(); + } + ret = crypto_aead_chacha20poly1305_encrypt_detached(c, + c + mlen, NULL, + m, mlen, + ad, adlen, + nsec, npub, k); + if (clen_p != NULL) { + if (ret == 0) { + clen = mlen + crypto_aead_chacha20poly1305_ABYTES; + } + *clen_p = clen; + } + return ret; +} + +int +crypto_aead_chacha20poly1305_ietf_encrypt_detached(unsigned char *c, + unsigned char *mac, + unsigned long long *maclen_p, + const unsigned char *m, + unsigned long long mlen, + const unsigned char *ad, + unsigned long long adlen, + const unsigned char *nsec, + const unsigned char *npub, + const unsigned char *k) +{ + crypto_onetimeauth_poly1305_state state; + unsigned char block0[64U]; + unsigned char slen[8U]; + + (void) nsec; + crypto_stream_chacha20_ietf(block0, sizeof block0, npub, k); + crypto_onetimeauth_poly1305_init(&state, block0); + sodium_memzero(block0, sizeof block0); + + crypto_onetimeauth_poly1305_update(&state, ad, adlen); + crypto_onetimeauth_poly1305_update(&state, _pad0, (0x10 - adlen) & 0xf); + + crypto_stream_chacha20_ietf_xor_ic(c, m, mlen, npub, 1U, k); + + crypto_onetimeauth_poly1305_update(&state, c, mlen); + crypto_onetimeauth_poly1305_update(&state, _pad0, (0x10 - mlen) & 0xf); + + STORE64_LE(slen, (uint64_t) adlen); + crypto_onetimeauth_poly1305_update(&state, slen, sizeof slen); + + STORE64_LE(slen, (uint64_t) mlen); + crypto_onetimeauth_poly1305_update(&state, slen, sizeof slen); + + crypto_onetimeauth_poly1305_final(&state, mac); + sodium_memzero(&state, sizeof state); + + if (maclen_p != NULL) { + *maclen_p = crypto_aead_chacha20poly1305_ietf_ABYTES; + } + return 0; +} + +int +crypto_aead_chacha20poly1305_ietf_encrypt(unsigned char *c, + unsigned long long *clen_p, + const unsigned char *m, + unsigned long long mlen, + const unsigned char *ad, + unsigned long long adlen, + const unsigned char *nsec, + const unsigned char *npub, + const unsigned char *k) +{ + unsigned long long clen = 0ULL; + int ret; + + if (mlen > crypto_aead_chacha20poly1305_ietf_MESSAGEBYTES_MAX) { + sodium_misuse(); + } + ret = crypto_aead_chacha20poly1305_ietf_encrypt_detached(c, + c + mlen, NULL, + m, mlen, + ad, adlen, + nsec, npub, k); + if (clen_p != NULL) { + if (ret == 0) { + clen = mlen + crypto_aead_chacha20poly1305_ietf_ABYTES; + } + *clen_p = clen; + } + return ret; +} + +int +crypto_aead_chacha20poly1305_decrypt_detached(unsigned char *m, + unsigned char *nsec, + const unsigned char *c, + unsigned long long clen, + const unsigned char *mac, + const unsigned char *ad, + unsigned long long adlen, + const unsigned char *npub, + const unsigned char *k) +{ + crypto_onetimeauth_poly1305_state state; + unsigned char block0[64U]; + unsigned char slen[8U]; + unsigned char computed_mac[crypto_aead_chacha20poly1305_ABYTES]; + unsigned long long mlen; + int ret; + + (void) nsec; + crypto_stream_chacha20(block0, sizeof block0, npub, k); + crypto_onetimeauth_poly1305_init(&state, block0); + sodium_memzero(block0, sizeof block0); + + crypto_onetimeauth_poly1305_update(&state, ad, adlen); + STORE64_LE(slen, (uint64_t) adlen); + crypto_onetimeauth_poly1305_update(&state, slen, sizeof slen); + + mlen = clen; + crypto_onetimeauth_poly1305_update(&state, c, mlen); + STORE64_LE(slen, (uint64_t) mlen); + crypto_onetimeauth_poly1305_update(&state, slen, sizeof slen); + + crypto_onetimeauth_poly1305_final(&state, computed_mac); + sodium_memzero(&state, sizeof state); + + COMPILER_ASSERT(sizeof computed_mac == 16U); + ret = crypto_verify_16(computed_mac, mac); + sodium_memzero(computed_mac, sizeof computed_mac); + if (m == NULL) { + return ret; + } + if (ret != 0) { + memset(m, 0, mlen); + return -1; + } + crypto_stream_chacha20_xor_ic(m, c, mlen, npub, 1U, k); + + return 0; +} + +int +crypto_aead_chacha20poly1305_decrypt(unsigned char *m, + unsigned long long *mlen_p, + unsigned char *nsec, + const unsigned char *c, + unsigned long long clen, + const unsigned char *ad, + unsigned long long adlen, + const unsigned char *npub, + const unsigned char *k) +{ + unsigned long long mlen = 0ULL; + int ret = -1; + + if (clen >= crypto_aead_chacha20poly1305_ABYTES) { + ret = crypto_aead_chacha20poly1305_decrypt_detached + (m, nsec, + c, clen - crypto_aead_chacha20poly1305_ABYTES, + c + clen - crypto_aead_chacha20poly1305_ABYTES, + ad, adlen, npub, k); + } + if (mlen_p != NULL) { + if (ret == 0) { + mlen = clen - crypto_aead_chacha20poly1305_ABYTES; + } + *mlen_p = mlen; + } + return ret; +} + +int +crypto_aead_chacha20poly1305_ietf_decrypt_detached(unsigned char *m, + unsigned char *nsec, + const unsigned char *c, + unsigned long long clen, + const unsigned char *mac, + const unsigned char *ad, + unsigned long long adlen, + const unsigned char *npub, + const unsigned char *k) +{ + crypto_onetimeauth_poly1305_state state; + unsigned char block0[64U]; + unsigned char slen[8U]; + unsigned char computed_mac[crypto_aead_chacha20poly1305_ietf_ABYTES]; + unsigned long long mlen; + int ret; + + (void) nsec; + crypto_stream_chacha20_ietf(block0, sizeof block0, npub, k); + crypto_onetimeauth_poly1305_init(&state, block0); + sodium_memzero(block0, sizeof block0); + + crypto_onetimeauth_poly1305_update(&state, ad, adlen); + crypto_onetimeauth_poly1305_update(&state, _pad0, (0x10 - adlen) & 0xf); + + mlen = clen; + crypto_onetimeauth_poly1305_update(&state, c, mlen); + crypto_onetimeauth_poly1305_update(&state, _pad0, (0x10 - mlen) & 0xf); + + STORE64_LE(slen, (uint64_t) adlen); + crypto_onetimeauth_poly1305_update(&state, slen, sizeof slen); + + STORE64_LE(slen, (uint64_t) mlen); + crypto_onetimeauth_poly1305_update(&state, slen, sizeof slen); + + crypto_onetimeauth_poly1305_final(&state, computed_mac); + sodium_memzero(&state, sizeof state); + + COMPILER_ASSERT(sizeof computed_mac == 16U); + ret = crypto_verify_16(computed_mac, mac); + sodium_memzero(computed_mac, sizeof computed_mac); + if (m == NULL) { + return ret; + } + if (ret != 0) { + memset(m, 0, mlen); + return -1; + } + crypto_stream_chacha20_ietf_xor_ic(m, c, mlen, npub, 1U, k); + + return 0; +} + +int +crypto_aead_chacha20poly1305_ietf_decrypt(unsigned char *m, + unsigned long long *mlen_p, + unsigned char *nsec, + const unsigned char *c, + unsigned long long clen, + const unsigned char *ad, + unsigned long long adlen, + const unsigned char *npub, + const unsigned char *k) +{ + unsigned long long mlen = 0ULL; + int ret = -1; + + if (clen >= crypto_aead_chacha20poly1305_ietf_ABYTES) { + ret = crypto_aead_chacha20poly1305_ietf_decrypt_detached + (m, nsec, + c, clen - crypto_aead_chacha20poly1305_ietf_ABYTES, + c + clen - crypto_aead_chacha20poly1305_ietf_ABYTES, + ad, adlen, npub, k); + } + if (mlen_p != NULL) { + if (ret == 0) { + mlen = clen - crypto_aead_chacha20poly1305_ietf_ABYTES; + } + *mlen_p = mlen; + } + return ret; +} + +size_t +crypto_aead_chacha20poly1305_ietf_keybytes(void) +{ + return crypto_aead_chacha20poly1305_ietf_KEYBYTES; +} + +size_t +crypto_aead_chacha20poly1305_ietf_npubbytes(void) +{ + return crypto_aead_chacha20poly1305_ietf_NPUBBYTES; +} + +size_t +crypto_aead_chacha20poly1305_ietf_nsecbytes(void) +{ + return crypto_aead_chacha20poly1305_ietf_NSECBYTES; +} + +size_t +crypto_aead_chacha20poly1305_ietf_abytes(void) +{ + return crypto_aead_chacha20poly1305_ietf_ABYTES; +} + +size_t +crypto_aead_chacha20poly1305_ietf_messagebytes_max(void) +{ + return crypto_aead_chacha20poly1305_ietf_MESSAGEBYTES_MAX; +} + +void +crypto_aead_chacha20poly1305_ietf_keygen(unsigned char k[crypto_aead_chacha20poly1305_ietf_KEYBYTES]) +{ + randombytes_buf(k, crypto_aead_chacha20poly1305_ietf_KEYBYTES); +} + +size_t +crypto_aead_chacha20poly1305_keybytes(void) +{ + return crypto_aead_chacha20poly1305_KEYBYTES; +} + +size_t +crypto_aead_chacha20poly1305_npubbytes(void) +{ + return crypto_aead_chacha20poly1305_NPUBBYTES; +} + +size_t +crypto_aead_chacha20poly1305_nsecbytes(void) +{ + return crypto_aead_chacha20poly1305_NSECBYTES; +} + +size_t +crypto_aead_chacha20poly1305_abytes(void) +{ + return crypto_aead_chacha20poly1305_ABYTES; +} + +size_t +crypto_aead_chacha20poly1305_messagebytes_max(void) +{ + return crypto_aead_chacha20poly1305_MESSAGEBYTES_MAX; +} + +void +crypto_aead_chacha20poly1305_keygen(unsigned char k[crypto_aead_chacha20poly1305_KEYBYTES]) +{ + randombytes_buf(k, crypto_aead_chacha20poly1305_KEYBYTES); +} diff --git a/libs/libsodium/src/crypto_aead/xchacha20poly1305/sodium/aead_xchacha20poly1305.c b/libs/libsodium/src/crypto_aead/xchacha20poly1305/sodium/aead_xchacha20poly1305.c new file mode 100644 index 0000000000..c18cdf9458 --- /dev/null +++ b/libs/libsodium/src/crypto_aead/xchacha20poly1305/sodium/aead_xchacha20poly1305.c @@ -0,0 +1,160 @@ + +#include <stdint.h> +#include <stdlib.h> +#include <limits.h> +#include <string.h> + +#include "core.h" +#include "crypto_aead_xchacha20poly1305.h" +#include "crypto_aead_chacha20poly1305.h" +#include "crypto_core_hchacha20.h" +#include "randombytes.h" +#include "utils.h" + +#include "private/common.h" + +int +crypto_aead_xchacha20poly1305_ietf_encrypt_detached(unsigned char *c, + unsigned char *mac, + unsigned long long *maclen_p, + const unsigned char *m, + unsigned long long mlen, + const unsigned char *ad, + unsigned long long adlen, + const unsigned char *nsec, + const unsigned char *npub, + const unsigned char *k) +{ + unsigned char k2[crypto_core_hchacha20_OUTPUTBYTES]; + unsigned char npub2[crypto_aead_chacha20poly1305_ietf_NPUBBYTES] = { 0 }; + int ret; + + crypto_core_hchacha20(k2, npub, k, NULL); + memcpy(npub2 + 4, npub + crypto_core_hchacha20_INPUTBYTES, + crypto_aead_chacha20poly1305_ietf_NPUBBYTES - 4); + ret = crypto_aead_chacha20poly1305_ietf_encrypt_detached + (c, mac, maclen_p, m, mlen, ad, adlen, nsec, npub2, k2); + sodium_memzero(k2, crypto_core_hchacha20_OUTPUTBYTES); + + return ret; +} + +int +crypto_aead_xchacha20poly1305_ietf_encrypt(unsigned char *c, + unsigned long long *clen_p, + const unsigned char *m, + unsigned long long mlen, + const unsigned char *ad, + unsigned long long adlen, + const unsigned char *nsec, + const unsigned char *npub, + const unsigned char *k) +{ + unsigned long long clen = 0ULL; + int ret; + + if (mlen > UINT64_MAX - crypto_aead_xchacha20poly1305_ietf_ABYTES) { + sodium_misuse(); + } + ret = crypto_aead_xchacha20poly1305_ietf_encrypt_detached + (c, c + mlen, NULL, m, mlen, ad, adlen, nsec, npub, k); + if (clen_p != NULL) { + if (ret == 0) { + clen = mlen + crypto_aead_xchacha20poly1305_ietf_ABYTES; + } + *clen_p = clen; + } + return ret; +} + +int +crypto_aead_xchacha20poly1305_ietf_decrypt_detached(unsigned char *m, + unsigned char *nsec, + const unsigned char *c, + unsigned long long clen, + const unsigned char *mac, + const unsigned char *ad, + unsigned long long adlen, + const unsigned char *npub, + const unsigned char *k) +{ + unsigned char k2[crypto_core_hchacha20_OUTPUTBYTES]; + unsigned char npub2[crypto_aead_chacha20poly1305_ietf_NPUBBYTES] = { 0 }; + int ret; + + crypto_core_hchacha20(k2, npub, k, NULL); + memcpy(npub2 + 4, npub + crypto_core_hchacha20_INPUTBYTES, + crypto_aead_chacha20poly1305_ietf_NPUBBYTES - 4); + ret = crypto_aead_chacha20poly1305_ietf_decrypt_detached + (m, nsec, c, clen, mac, ad, adlen, npub2, k2); + sodium_memzero(k2, crypto_core_hchacha20_OUTPUTBYTES); + + return ret; + +} + +int +crypto_aead_xchacha20poly1305_ietf_decrypt(unsigned char *m, + unsigned long long *mlen_p, + unsigned char *nsec, + const unsigned char *c, + unsigned long long clen, + const unsigned char *ad, + unsigned long long adlen, + const unsigned char *npub, + const unsigned char *k) +{ + unsigned long long mlen = 0ULL; + int ret = -1; + + if (clen >= crypto_aead_xchacha20poly1305_ietf_ABYTES) { + ret = crypto_aead_xchacha20poly1305_ietf_decrypt_detached + (m, nsec, + c, clen - crypto_aead_xchacha20poly1305_ietf_ABYTES, + c + clen - crypto_aead_xchacha20poly1305_ietf_ABYTES, + ad, adlen, npub, k); + } + if (mlen_p != NULL) { + if (ret == 0) { + mlen = clen - crypto_aead_xchacha20poly1305_ietf_ABYTES; + } + *mlen_p = mlen; + } + return ret; +} + +size_t +crypto_aead_xchacha20poly1305_ietf_keybytes(void) +{ + return crypto_aead_xchacha20poly1305_ietf_KEYBYTES; +} + +size_t +crypto_aead_xchacha20poly1305_ietf_npubbytes(void) +{ + return crypto_aead_xchacha20poly1305_ietf_NPUBBYTES; +} + +size_t +crypto_aead_xchacha20poly1305_ietf_nsecbytes(void) +{ + return crypto_aead_xchacha20poly1305_ietf_NSECBYTES; +} + +size_t +crypto_aead_xchacha20poly1305_ietf_abytes(void) +{ + return crypto_aead_xchacha20poly1305_ietf_ABYTES; +} + +size_t +crypto_aead_xchacha20poly1305_ietf_messagebytes_max(void) +{ + return crypto_aead_xchacha20poly1305_ietf_MESSAGEBYTES_MAX; +} + +void +crypto_aead_xchacha20poly1305_ietf_keygen(unsigned char k[crypto_aead_xchacha20poly1305_ietf_KEYBYTES]) +{ + randombytes_buf(k, crypto_aead_xchacha20poly1305_ietf_KEYBYTES); +} diff --git a/libs/libsodium/src/crypto_auth/crypto_auth.c b/libs/libsodium/src/crypto_auth/crypto_auth.c new file mode 100644 index 0000000000..d061c8c1c5 --- /dev/null +++ b/libs/libsodium/src/crypto_auth/crypto_auth.c @@ -0,0 +1,41 @@ + +#include "crypto_auth.h" +#include "randombytes.h" + +size_t +crypto_auth_bytes(void) +{ + return crypto_auth_BYTES; +} + +size_t +crypto_auth_keybytes(void) +{ + return crypto_auth_KEYBYTES; +} + +const char * +crypto_auth_primitive(void) +{ + return crypto_auth_PRIMITIVE; +} + +int +crypto_auth(unsigned char *out, const unsigned char *in, + unsigned long long inlen, const unsigned char *k) +{ + return crypto_auth_hmacsha512256(out, in, inlen, k); +} + +int +crypto_auth_verify(const unsigned char *h, const unsigned char *in, + unsigned long long inlen,const unsigned char *k) +{ + return crypto_auth_hmacsha512256_verify(h, in, inlen, k); +} + +void +crypto_auth_keygen(unsigned char k[crypto_auth_KEYBYTES]) +{ + randombytes_buf(k, crypto_auth_KEYBYTES); +} diff --git a/libs/libsodium/src/crypto_auth/hmacsha256/auth_hmacsha256.c b/libs/libsodium/src/crypto_auth/hmacsha256/auth_hmacsha256.c new file mode 100644 index 0000000000..a951e932b8 --- /dev/null +++ b/libs/libsodium/src/crypto_auth/hmacsha256/auth_hmacsha256.c @@ -0,0 +1,118 @@ + +#include <stddef.h> +#include <stdint.h> +#include <string.h> + +#include "crypto_auth_hmacsha256.h" +#include "crypto_hash_sha256.h" +#include "crypto_verify_32.h" +#include "randombytes.h" +#include "utils.h" + +size_t +crypto_auth_hmacsha256_bytes(void) +{ + return crypto_auth_hmacsha256_BYTES; +} + +size_t +crypto_auth_hmacsha256_keybytes(void) +{ + return crypto_auth_hmacsha256_KEYBYTES; +} + +size_t +crypto_auth_hmacsha256_statebytes(void) +{ + return sizeof(crypto_auth_hmacsha256_state); +} + +void +crypto_auth_hmacsha256_keygen(unsigned char k[crypto_auth_hmacsha256_KEYBYTES]) +{ + randombytes_buf(k, crypto_auth_hmacsha256_KEYBYTES); +} + +int +crypto_auth_hmacsha256_init(crypto_auth_hmacsha256_state *state, + const unsigned char *key, size_t keylen) +{ + unsigned char pad[64]; + unsigned char khash[32]; + size_t i; + + if (keylen > 64) { + crypto_hash_sha256_init(&state->ictx); + crypto_hash_sha256_update(&state->ictx, key, keylen); + crypto_hash_sha256_final(&state->ictx, khash); + key = khash; + keylen = 32; + } + crypto_hash_sha256_init(&state->ictx); + memset(pad, 0x36, 64); + for (i = 0; i < keylen; i++) { + pad[i] ^= key[i]; + } + crypto_hash_sha256_update(&state->ictx, pad, 64); + + crypto_hash_sha256_init(&state->octx); + memset(pad, 0x5c, 64); + for (i = 0; i < keylen; i++) { + pad[i] ^= key[i]; + } + crypto_hash_sha256_update(&state->octx, pad, 64); + + sodium_memzero((void *) pad, sizeof pad); + sodium_memzero((void *) khash, sizeof khash); + + return 0; +} + +int +crypto_auth_hmacsha256_update(crypto_auth_hmacsha256_state *state, + const unsigned char *in, unsigned long long inlen) +{ + crypto_hash_sha256_update(&state->ictx, in, inlen); + + return 0; +} + +int +crypto_auth_hmacsha256_final(crypto_auth_hmacsha256_state *state, + unsigned char *out) +{ + unsigned char ihash[32]; + + crypto_hash_sha256_final(&state->ictx, ihash); + crypto_hash_sha256_update(&state->octx, ihash, 32); + crypto_hash_sha256_final(&state->octx, out); + + sodium_memzero((void *) ihash, sizeof ihash); + + return 0; +} + +int +crypto_auth_hmacsha256(unsigned char *out, const unsigned char *in, + unsigned long long inlen, const unsigned char *k) +{ + crypto_auth_hmacsha256_state state; + + crypto_auth_hmacsha256_init(&state, k, crypto_auth_hmacsha256_KEYBYTES); + crypto_auth_hmacsha256_update(&state, in, inlen); + crypto_auth_hmacsha256_final(&state, out); + + return 0; +} + +int +crypto_auth_hmacsha256_verify(const unsigned char *h, const unsigned char *in, + unsigned long long inlen, const unsigned char *k) +{ + unsigned char correct[32]; + + crypto_auth_hmacsha256(correct, in, inlen, k); + + return crypto_verify_32(h, correct) | (-(h == correct)) | + sodium_memcmp(correct, h, 32); +} diff --git a/libs/libsodium/src/crypto_auth/hmacsha512/auth_hmacsha512.c b/libs/libsodium/src/crypto_auth/hmacsha512/auth_hmacsha512.c new file mode 100644 index 0000000000..018d7a4e87 --- /dev/null +++ b/libs/libsodium/src/crypto_auth/hmacsha512/auth_hmacsha512.c @@ -0,0 +1,118 @@ + +#include <stddef.h> +#include <stdint.h> +#include <string.h> + +#include "crypto_auth_hmacsha512.h" +#include "crypto_hash_sha512.h" +#include "crypto_verify_64.h" +#include "randombytes.h" +#include "utils.h" + +size_t +crypto_auth_hmacsha512_bytes(void) +{ + return crypto_auth_hmacsha512_BYTES; +} + +size_t +crypto_auth_hmacsha512_keybytes(void) +{ + return crypto_auth_hmacsha512_KEYBYTES; +} + +size_t +crypto_auth_hmacsha512_statebytes(void) +{ + return sizeof(crypto_auth_hmacsha512_state); +} + +void +crypto_auth_hmacsha512_keygen(unsigned char k[crypto_auth_hmacsha512_KEYBYTES]) +{ + randombytes_buf(k, crypto_auth_hmacsha512_KEYBYTES); +} + +int +crypto_auth_hmacsha512_init(crypto_auth_hmacsha512_state *state, + const unsigned char *key, size_t keylen) +{ + unsigned char pad[128]; + unsigned char khash[64]; + size_t i; + + if (keylen > 128) { + crypto_hash_sha512_init(&state->ictx); + crypto_hash_sha512_update(&state->ictx, key, keylen); + crypto_hash_sha512_final(&state->ictx, khash); + key = khash; + keylen = 64; + } + crypto_hash_sha512_init(&state->ictx); + memset(pad, 0x36, 128); + for (i = 0; i < keylen; i++) { + pad[i] ^= key[i]; + } + crypto_hash_sha512_update(&state->ictx, pad, 128); + + crypto_hash_sha512_init(&state->octx); + memset(pad, 0x5c, 128); + for (i = 0; i < keylen; i++) { + pad[i] ^= key[i]; + } + crypto_hash_sha512_update(&state->octx, pad, 128); + + sodium_memzero((void *) pad, sizeof pad); + sodium_memzero((void *) khash, sizeof khash); + + return 0; +} + +int +crypto_auth_hmacsha512_update(crypto_auth_hmacsha512_state *state, + const unsigned char *in, unsigned long long inlen) +{ + crypto_hash_sha512_update(&state->ictx, in, inlen); + + return 0; +} + +int +crypto_auth_hmacsha512_final(crypto_auth_hmacsha512_state *state, + unsigned char *out) +{ + unsigned char ihash[64]; + + crypto_hash_sha512_final(&state->ictx, ihash); + crypto_hash_sha512_update(&state->octx, ihash, 64); + crypto_hash_sha512_final(&state->octx, out); + + sodium_memzero((void *) ihash, sizeof ihash); + + return 0; +} + +int +crypto_auth_hmacsha512(unsigned char *out, const unsigned char *in, + unsigned long long inlen, const unsigned char *k) +{ + crypto_auth_hmacsha512_state state; + + crypto_auth_hmacsha512_init(&state, k, crypto_auth_hmacsha512_KEYBYTES); + crypto_auth_hmacsha512_update(&state, in, inlen); + crypto_auth_hmacsha512_final(&state, out); + + return 0; +} + +int +crypto_auth_hmacsha512_verify(const unsigned char *h, const unsigned char *in, + unsigned long long inlen, const unsigned char *k) +{ + unsigned char correct[64]; + + crypto_auth_hmacsha512(correct, in, inlen, k); + + return crypto_verify_64(h, correct) | (-(h == correct)) | + sodium_memcmp(correct, h, 64); +} diff --git a/libs/libsodium/src/crypto_auth/hmacsha512256/auth_hmacsha512256.c b/libs/libsodium/src/crypto_auth/hmacsha512256/auth_hmacsha512256.c new file mode 100644 index 0000000000..432d6dbee5 --- /dev/null +++ b/libs/libsodium/src/crypto_auth/hmacsha512256/auth_hmacsha512256.c @@ -0,0 +1,93 @@ + +#include <stddef.h> +#include <stdint.h> +#include <string.h> + +#include "crypto_auth_hmacsha512.h" +#include "crypto_auth_hmacsha512256.h" +#include "crypto_hash_sha512.h" +#include "crypto_verify_32.h" +#include "randombytes.h" +#include "utils.h" + +size_t +crypto_auth_hmacsha512256_bytes(void) +{ + return crypto_auth_hmacsha512256_BYTES; +} + +size_t +crypto_auth_hmacsha512256_keybytes(void) +{ + return crypto_auth_hmacsha512256_KEYBYTES; +} + +size_t +crypto_auth_hmacsha512256_statebytes(void) +{ + return sizeof(crypto_auth_hmacsha512256_state); +} + +void +crypto_auth_hmacsha512256_keygen( + unsigned char k[crypto_auth_hmacsha512256_KEYBYTES]) +{ + randombytes_buf(k, crypto_auth_hmacsha512256_KEYBYTES); +} + +int +crypto_auth_hmacsha512256_init(crypto_auth_hmacsha512256_state *state, + const unsigned char *key, size_t keylen) +{ + return crypto_auth_hmacsha512_init((crypto_auth_hmacsha512_state *) state, + key, keylen); +} + +int +crypto_auth_hmacsha512256_update(crypto_auth_hmacsha512256_state *state, + const unsigned char *in, + unsigned long long inlen) +{ + return crypto_auth_hmacsha512_update((crypto_auth_hmacsha512_state *) state, + in, inlen); +} + +int +crypto_auth_hmacsha512256_final(crypto_auth_hmacsha512256_state *state, + unsigned char *out) +{ + unsigned char out0[64]; + + crypto_auth_hmacsha512_final((crypto_auth_hmacsha512_state *) state, out0); + memcpy(out, out0, 32); + + return 0; +} + +int +crypto_auth_hmacsha512256(unsigned char *out, const unsigned char *in, + unsigned long long inlen, const unsigned char *k) +{ + crypto_auth_hmacsha512256_state state; + + crypto_auth_hmacsha512256_init(&state, k, + crypto_auth_hmacsha512256_KEYBYTES); + crypto_auth_hmacsha512256_update(&state, in, inlen); + crypto_auth_hmacsha512256_final(&state, out); + + return 0; +} + +int +crypto_auth_hmacsha512256_verify(const unsigned char *h, + const unsigned char *in, + unsigned long long inlen, + const unsigned char *k) +{ + unsigned char correct[32]; + + crypto_auth_hmacsha512256(correct, in, inlen, k); + + return crypto_verify_32(h, correct) | (-(h == correct)) | + sodium_memcmp(correct, h, 32); +} diff --git a/libs/libsodium/src/crypto_box/crypto_box.c b/libs/libsodium/src/crypto_box/crypto_box.c new file mode 100644 index 0000000000..7e4f00bd15 --- /dev/null +++ b/libs/libsodium/src/crypto_box/crypto_box.c @@ -0,0 +1,114 @@ + +#include "crypto_box.h" + +size_t +crypto_box_seedbytes(void) +{ + return crypto_box_SEEDBYTES; +} + +size_t +crypto_box_publickeybytes(void) +{ + return crypto_box_PUBLICKEYBYTES; +} + +size_t +crypto_box_secretkeybytes(void) +{ + return crypto_box_SECRETKEYBYTES; +} + +size_t +crypto_box_beforenmbytes(void) +{ + return crypto_box_BEFORENMBYTES; +} + +size_t +crypto_box_noncebytes(void) +{ + return crypto_box_NONCEBYTES; +} + +size_t +crypto_box_zerobytes(void) +{ + return crypto_box_ZEROBYTES; +} + +size_t +crypto_box_boxzerobytes(void) +{ + return crypto_box_BOXZEROBYTES; +} + +size_t +crypto_box_macbytes(void) +{ + return crypto_box_MACBYTES; +} + +size_t +crypto_box_messagebytes_max(void) +{ + return crypto_box_MESSAGEBYTES_MAX; +} + +const char * +crypto_box_primitive(void) +{ + return crypto_box_PRIMITIVE; +} + +int +crypto_box_seed_keypair(unsigned char *pk, unsigned char *sk, + const unsigned char *seed) +{ + return crypto_box_curve25519xsalsa20poly1305_seed_keypair(pk, sk, seed); +} + +int +crypto_box_keypair(unsigned char *pk, unsigned char *sk) +{ + return crypto_box_curve25519xsalsa20poly1305_keypair(pk, sk); +} + +int +crypto_box_beforenm(unsigned char *k, const unsigned char *pk, + const unsigned char *sk) +{ + return crypto_box_curve25519xsalsa20poly1305_beforenm(k, pk, sk); +} + +int +crypto_box_afternm(unsigned char *c, const unsigned char *m, + unsigned long long mlen, const unsigned char *n, + const unsigned char *k) +{ + return crypto_box_curve25519xsalsa20poly1305_afternm(c, m, mlen, n, k); +} + +int +crypto_box_open_afternm(unsigned char *m, const unsigned char *c, + unsigned long long clen, const unsigned char *n, + const unsigned char *k) +{ + return crypto_box_curve25519xsalsa20poly1305_open_afternm(m, c, clen, n, k); +} + +int +crypto_box(unsigned char *c, const unsigned char *m, + unsigned long long mlen, const unsigned char *n, + const unsigned char *pk, const unsigned char *sk) +{ + return crypto_box_curve25519xsalsa20poly1305(c, m, mlen, n, pk, sk); +} + +int +crypto_box_open(unsigned char *m, const unsigned char *c, + unsigned long long clen, const unsigned char *n, + const unsigned char *pk, const unsigned char *sk) +{ + return crypto_box_curve25519xsalsa20poly1305_open(m, c, clen, n, pk, sk); +} diff --git a/libs/libsodium/src/crypto_box/crypto_box_easy.c b/libs/libsodium/src/crypto_box/crypto_box_easy.c new file mode 100644 index 0000000000..deb40b4083 --- /dev/null +++ b/libs/libsodium/src/crypto_box/crypto_box_easy.c @@ -0,0 +1,115 @@ + +#include <limits.h> +#include <stdint.h> +#include <stdlib.h> + +#include "core.h" +#include "crypto_box.h" +#include "crypto_secretbox.h" +#include "private/common.h" +#include "utils.h" + +int +crypto_box_detached_afternm(unsigned char *c, unsigned char *mac, + const unsigned char *m, unsigned long long mlen, + const unsigned char *n, const unsigned char *k) +{ + return crypto_secretbox_detached(c, mac, m, mlen, n, k); +} + +int +crypto_box_detached(unsigned char *c, unsigned char *mac, + const unsigned char *m, unsigned long long mlen, + const unsigned char *n, const unsigned char *pk, + const unsigned char *sk) +{ + unsigned char k[crypto_box_BEFORENMBYTES]; + int ret; + + COMPILER_ASSERT(crypto_box_BEFORENMBYTES >= crypto_secretbox_KEYBYTES); + if (crypto_box_beforenm(k, pk, sk) != 0) { + return -1; + } + ret = crypto_box_detached_afternm(c, mac, m, mlen, n, k); + sodium_memzero(k, sizeof k); + + return ret; +} + +int +crypto_box_easy_afternm(unsigned char *c, const unsigned char *m, + unsigned long long mlen, const unsigned char *n, + const unsigned char *k) +{ + if (mlen > crypto_box_MESSAGEBYTES_MAX) { + sodium_misuse(); + } + return crypto_box_detached_afternm(c + crypto_box_MACBYTES, c, m, mlen, n, + k); +} + +int +crypto_box_easy(unsigned char *c, const unsigned char *m, + unsigned long long mlen, const unsigned char *n, + const unsigned char *pk, const unsigned char *sk) +{ + if (mlen > crypto_box_MESSAGEBYTES_MAX) { + sodium_misuse(); + } + return crypto_box_detached(c + crypto_box_MACBYTES, c, m, mlen, n, + pk, sk); +} + +int +crypto_box_open_detached_afternm(unsigned char *m, const unsigned char *c, + const unsigned char *mac, + unsigned long long clen, + const unsigned char *n, + const unsigned char *k) +{ + return crypto_secretbox_open_detached(m, c, mac, clen, n, k); +} + +int +crypto_box_open_detached(unsigned char *m, const unsigned char *c, + const unsigned char *mac, + unsigned long long clen, const unsigned char *n, + const unsigned char *pk, const unsigned char *sk) +{ + unsigned char k[crypto_box_BEFORENMBYTES]; + int ret; + + if (crypto_box_beforenm(k, pk, sk) != 0) { + return -1; + } + ret = crypto_box_open_detached_afternm(m, c, mac, clen, n, k); + sodium_memzero(k, sizeof k); + + return ret; +} + +int +crypto_box_open_easy_afternm(unsigned char *m, const unsigned char *c, + unsigned long long clen, const unsigned char *n, + const unsigned char *k) +{ + if (clen < crypto_box_MACBYTES) { + return -1; + } + return crypto_box_open_detached_afternm(m, c + crypto_box_MACBYTES, c, + clen - crypto_box_MACBYTES, + n, k); +} + +int +crypto_box_open_easy(unsigned char *m, const unsigned char *c, + unsigned long long clen, const unsigned char *n, + const unsigned char *pk, const unsigned char *sk) +{ + if (clen < crypto_box_MACBYTES) { + return -1; + } + return crypto_box_open_detached(m, c + crypto_box_MACBYTES, c, + clen - crypto_box_MACBYTES, + n, pk, sk); +} diff --git a/libs/libsodium/src/crypto_box/crypto_box_seal.c b/libs/libsodium/src/crypto_box/crypto_box_seal.c new file mode 100644 index 0000000000..7181334578 --- /dev/null +++ b/libs/libsodium/src/crypto_box/crypto_box_seal.c @@ -0,0 +1,68 @@ + +#include <string.h> + +#include "crypto_box.h" +#include "crypto_generichash.h" +#include "private/common.h" +#include "utils.h" + +static int +_crypto_box_seal_nonce(unsigned char *nonce, + const unsigned char *pk1, const unsigned char *pk2) +{ + crypto_generichash_state st; + + crypto_generichash_init(&st, NULL, 0U, crypto_box_NONCEBYTES); + crypto_generichash_update(&st, pk1, crypto_box_PUBLICKEYBYTES); + crypto_generichash_update(&st, pk2, crypto_box_PUBLICKEYBYTES); + crypto_generichash_final(&st, nonce, crypto_box_NONCEBYTES); + + return 0; +} + +int +crypto_box_seal(unsigned char *c, const unsigned char *m, + unsigned long long mlen, const unsigned char *pk) +{ + unsigned char nonce[crypto_box_NONCEBYTES]; + unsigned char epk[crypto_box_PUBLICKEYBYTES]; + unsigned char esk[crypto_box_SECRETKEYBYTES]; + int ret; + + if (crypto_box_keypair(epk, esk) != 0) { + return -1; /* LCOV_EXCL_LINE */ + } + memcpy(c, epk, crypto_box_PUBLICKEYBYTES); + _crypto_box_seal_nonce(nonce, epk, pk); + ret = crypto_box_easy(c + crypto_box_PUBLICKEYBYTES, m, mlen, + nonce, pk, esk); + sodium_memzero(esk, sizeof esk); + sodium_memzero(epk, sizeof epk); + sodium_memzero(nonce, sizeof nonce); + + return ret; +} + +int +crypto_box_seal_open(unsigned char *m, const unsigned char *c, + unsigned long long clen, + const unsigned char *pk, const unsigned char *sk) +{ + unsigned char nonce[crypto_box_NONCEBYTES]; + + if (clen < crypto_box_SEALBYTES) { + return -1; + } + _crypto_box_seal_nonce(nonce, c, pk); + + COMPILER_ASSERT(crypto_box_PUBLICKEYBYTES < crypto_box_SEALBYTES); + return crypto_box_open_easy(m, c + crypto_box_PUBLICKEYBYTES, + clen - crypto_box_PUBLICKEYBYTES, + nonce, c, sk); +} + +size_t +crypto_box_sealbytes(void) +{ + return crypto_box_SEALBYTES; +} diff --git a/libs/libsodium/src/crypto_box/curve25519xchacha20poly1305/box_curve25519xchacha20poly1305.c b/libs/libsodium/src/crypto_box/curve25519xchacha20poly1305/box_curve25519xchacha20poly1305.c new file mode 100644 index 0000000000..5e2532eab7 --- /dev/null +++ b/libs/libsodium/src/crypto_box/curve25519xchacha20poly1305/box_curve25519xchacha20poly1305.c @@ -0,0 +1,204 @@ + +#include <limits.h> +#include <stdint.h> +#include <stdlib.h> +#include <string.h> + +#include "core.h" +#include "crypto_box_curve25519xchacha20poly1305.h" +#include "crypto_core_hchacha20.h" +#include "crypto_hash_sha512.h" +#include "crypto_scalarmult_curve25519.h" +#include "crypto_secretbox_xchacha20poly1305.h" +#include "private/common.h" +#include "randombytes.h" +#include "utils.h" + +int +crypto_box_curve25519xchacha20poly1305_seed_keypair(unsigned char *pk, + unsigned char *sk, + const unsigned char *seed) +{ + unsigned char hash[64]; + + crypto_hash_sha512(hash, seed, 32); + memcpy(sk, hash, 32); + sodium_memzero(hash, sizeof hash); + + return crypto_scalarmult_curve25519_base(pk, sk); +} + +int +crypto_box_curve25519xchacha20poly1305_keypair(unsigned char *pk, + unsigned char *sk) +{ + randombytes_buf(sk, 32); + + return crypto_scalarmult_curve25519_base(pk, sk); +} + +int +crypto_box_curve25519xchacha20poly1305_beforenm(unsigned char *k, + const unsigned char *pk, + const unsigned char *sk) +{ + static const unsigned char zero[16] = { 0 }; + unsigned char s[32]; + + if (crypto_scalarmult_curve25519(s, sk, pk) != 0) { + return -1; + } + return crypto_core_hchacha20(k, zero, s, NULL); +} + +int +crypto_box_curve25519xchacha20poly1305_detached_afternm( + unsigned char *c, unsigned char *mac, const unsigned char *m, + unsigned long long mlen, const unsigned char *n, const unsigned char *k) +{ + return crypto_secretbox_xchacha20poly1305_detached(c, mac, m, mlen, n, k); +} + +int +crypto_box_curve25519xchacha20poly1305_detached( + unsigned char *c, unsigned char *mac, const unsigned char *m, + unsigned long long mlen, const unsigned char *n, const unsigned char *pk, + const unsigned char *sk) +{ + unsigned char k[crypto_box_curve25519xchacha20poly1305_BEFORENMBYTES]; + int ret; + + COMPILER_ASSERT(crypto_box_curve25519xchacha20poly1305_BEFORENMBYTES >= + crypto_secretbox_xchacha20poly1305_KEYBYTES); + if (crypto_box_curve25519xchacha20poly1305_beforenm(k, pk, sk) != 0) { + return -1; + } + ret = crypto_box_curve25519xchacha20poly1305_detached_afternm(c, mac, m, + mlen, n, k); + sodium_memzero(k, sizeof k); + + return ret; +} + +int +crypto_box_curve25519xchacha20poly1305_easy_afternm(unsigned char *c, + const unsigned char *m, + unsigned long long mlen, + const unsigned char *n, + const unsigned char *k) +{ + if (mlen > crypto_box_curve25519xchacha20poly1305_MESSAGEBYTES_MAX) { + sodium_misuse(); + } + return crypto_box_curve25519xchacha20poly1305_detached_afternm( + c + crypto_box_curve25519xchacha20poly1305_MACBYTES, c, m, mlen, n, k); +} + +int +crypto_box_curve25519xchacha20poly1305_easy( + unsigned char *c, const unsigned char *m, unsigned long long mlen, + const unsigned char *n, const unsigned char *pk, const unsigned char *sk) +{ + if (mlen > crypto_box_curve25519xchacha20poly1305_MESSAGEBYTES_MAX) { + sodium_misuse(); + } + return crypto_box_curve25519xchacha20poly1305_detached( + c + crypto_box_curve25519xchacha20poly1305_MACBYTES, c, m, mlen, n, pk, + sk); +} + +int +crypto_box_curve25519xchacha20poly1305_open_detached_afternm( + unsigned char *m, const unsigned char *c, const unsigned char *mac, + unsigned long long clen, const unsigned char *n, const unsigned char *k) +{ + return crypto_secretbox_xchacha20poly1305_open_detached(m, c, mac, clen, n, + k); +} + +int +crypto_box_curve25519xchacha20poly1305_open_detached( + unsigned char *m, const unsigned char *c, const unsigned char *mac, + unsigned long long clen, const unsigned char *n, const unsigned char *pk, + const unsigned char *sk) +{ + unsigned char k[crypto_box_curve25519xchacha20poly1305_BEFORENMBYTES]; + int ret; + + if (crypto_box_curve25519xchacha20poly1305_beforenm(k, pk, sk) != 0) { + return -1; + } + ret = crypto_box_curve25519xchacha20poly1305_open_detached_afternm( + m, c, mac, clen, n, k); + sodium_memzero(k, sizeof k); + + return ret; +} + +int +crypto_box_curve25519xchacha20poly1305_open_easy_afternm( + unsigned char *m, const unsigned char *c, unsigned long long clen, + const unsigned char *n, const unsigned char *k) +{ + if (clen < crypto_box_curve25519xchacha20poly1305_MACBYTES) { + return -1; + } + return crypto_box_curve25519xchacha20poly1305_open_detached_afternm( + m, c + crypto_box_curve25519xchacha20poly1305_MACBYTES, c, + clen - crypto_box_curve25519xchacha20poly1305_MACBYTES, n, k); +} + +int +crypto_box_curve25519xchacha20poly1305_open_easy( + unsigned char *m, const unsigned char *c, unsigned long long clen, + const unsigned char *n, const unsigned char *pk, const unsigned char *sk) +{ + if (clen < crypto_box_curve25519xchacha20poly1305_MACBYTES) { + return -1; + } + return crypto_box_curve25519xchacha20poly1305_open_detached( + m, c + crypto_box_curve25519xchacha20poly1305_MACBYTES, c, + clen - crypto_box_curve25519xchacha20poly1305_MACBYTES, n, pk, sk); +} + +size_t +crypto_box_curve25519xchacha20poly1305_seedbytes(void) +{ + return crypto_box_curve25519xchacha20poly1305_SEEDBYTES; +} + +size_t +crypto_box_curve25519xchacha20poly1305_publickeybytes(void) +{ + return crypto_box_curve25519xchacha20poly1305_PUBLICKEYBYTES; +} + +size_t +crypto_box_curve25519xchacha20poly1305_secretkeybytes(void) +{ + return crypto_box_curve25519xchacha20poly1305_SECRETKEYBYTES; +} + +size_t +crypto_box_curve25519xchacha20poly1305_beforenmbytes(void) +{ + return crypto_box_curve25519xchacha20poly1305_BEFORENMBYTES; +} + +size_t +crypto_box_curve25519xchacha20poly1305_noncebytes(void) +{ + return crypto_box_curve25519xchacha20poly1305_NONCEBYTES; +} + +size_t +crypto_box_curve25519xchacha20poly1305_macbytes(void) +{ + return crypto_box_curve25519xchacha20poly1305_MACBYTES; +} + +size_t +crypto_box_curve25519xchacha20poly1305_messagebytes_max(void) +{ + return crypto_box_curve25519xchacha20poly1305_MESSAGEBYTES_MAX; +} diff --git a/libs/libsodium/src/crypto_box/curve25519xchacha20poly1305/box_seal_curve25519xchacha20poly1305.c b/libs/libsodium/src/crypto_box/curve25519xchacha20poly1305/box_seal_curve25519xchacha20poly1305.c new file mode 100644 index 0000000000..9e73a265aa --- /dev/null +++ b/libs/libsodium/src/crypto_box/curve25519xchacha20poly1305/box_seal_curve25519xchacha20poly1305.c @@ -0,0 +1,79 @@ + +#include <string.h> + +#include "crypto_box_curve25519xchacha20poly1305.h" +#include "crypto_generichash.h" +#include "private/common.h" +#include "utils.h" + +static int +_crypto_box_curve25519xchacha20poly1305_seal_nonce(unsigned char *nonce, + const unsigned char *pk1, + const unsigned char *pk2) +{ + crypto_generichash_state st; + + crypto_generichash_init(&st, NULL, 0U, + crypto_box_curve25519xchacha20poly1305_NONCEBYTES); + crypto_generichash_update(&st, pk1, + crypto_box_curve25519xchacha20poly1305_PUBLICKEYBYTES); + crypto_generichash_update(&st, pk2, + crypto_box_curve25519xchacha20poly1305_PUBLICKEYBYTES); + crypto_generichash_final(&st, nonce, + crypto_box_curve25519xchacha20poly1305_NONCEBYTES); + + return 0; +} + +int +crypto_box_curve25519xchacha20poly1305_seal(unsigned char *c, const unsigned char *m, + unsigned long long mlen, + const unsigned char *pk) +{ + unsigned char nonce[crypto_box_curve25519xchacha20poly1305_NONCEBYTES]; + unsigned char epk[crypto_box_curve25519xchacha20poly1305_PUBLICKEYBYTES]; + unsigned char esk[crypto_box_curve25519xchacha20poly1305_SECRETKEYBYTES]; + int ret; + + if (crypto_box_curve25519xchacha20poly1305_keypair(epk, esk) != 0) { + return -1; /* LCOV_EXCL_LINE */ + } + memcpy(c, epk, crypto_box_curve25519xchacha20poly1305_PUBLICKEYBYTES); + _crypto_box_curve25519xchacha20poly1305_seal_nonce(nonce, epk, pk); + ret = crypto_box_curve25519xchacha20poly1305_easy( + c + crypto_box_curve25519xchacha20poly1305_PUBLICKEYBYTES, m, mlen, + nonce, pk, esk); + sodium_memzero(esk, sizeof esk); + sodium_memzero(epk, sizeof epk); + sodium_memzero(nonce, sizeof nonce); + + return ret; +} + +int +crypto_box_curve25519xchacha20poly1305_seal_open(unsigned char *m, const unsigned char *c, + unsigned long long clen, + const unsigned char *pk, + const unsigned char *sk) +{ + unsigned char nonce[crypto_box_curve25519xchacha20poly1305_NONCEBYTES]; + + if (clen < crypto_box_curve25519xchacha20poly1305_SEALBYTES) { + return -1; + } + _crypto_box_curve25519xchacha20poly1305_seal_nonce(nonce, c, pk); + + COMPILER_ASSERT(crypto_box_curve25519xchacha20poly1305_PUBLICKEYBYTES < + crypto_box_curve25519xchacha20poly1305_SEALBYTES); + + return crypto_box_curve25519xchacha20poly1305_open_easy( + m, c + crypto_box_curve25519xchacha20poly1305_PUBLICKEYBYTES, + clen - crypto_box_curve25519xchacha20poly1305_PUBLICKEYBYTES, + nonce, c, sk); +} + +size_t +crypto_box_curve25519xchacha20poly1305_sealbytes(void) +{ + return crypto_box_curve25519xchacha20poly1305_SEALBYTES; +} diff --git a/libs/libsodium/src/crypto_box/curve25519xsalsa20poly1305/box_curve25519xsalsa20poly1305.c b/libs/libsodium/src/crypto_box/curve25519xsalsa20poly1305/box_curve25519xsalsa20poly1305.c new file mode 100644 index 0000000000..4c1d62ed43 --- /dev/null +++ b/libs/libsodium/src/crypto_box/curve25519xsalsa20poly1305/box_curve25519xsalsa20poly1305.c @@ -0,0 +1,156 @@ +#include <string.h> + +#include "crypto_box_curve25519xsalsa20poly1305.h" +#include "crypto_core_hsalsa20.h" +#include "crypto_hash_sha512.h" +#include "crypto_scalarmult_curve25519.h" +#include "crypto_secretbox_xsalsa20poly1305.h" +#include "randombytes.h" +#include "utils.h" + +int +crypto_box_curve25519xsalsa20poly1305_seed_keypair(unsigned char *pk, + unsigned char *sk, + const unsigned char *seed) +{ + unsigned char hash[64]; + + crypto_hash_sha512(hash, seed, 32); + memcpy(sk, hash, 32); + sodium_memzero(hash, sizeof hash); + + return crypto_scalarmult_curve25519_base(pk, sk); +} + +int +crypto_box_curve25519xsalsa20poly1305_keypair(unsigned char *pk, + unsigned char *sk) +{ + randombytes_buf(sk, 32); + + return crypto_scalarmult_curve25519_base(pk, sk); +} + +int +crypto_box_curve25519xsalsa20poly1305_beforenm(unsigned char *k, + const unsigned char *pk, + const unsigned char *sk) +{ + static const unsigned char zero[16] = { 0 }; + unsigned char s[32]; + + if (crypto_scalarmult_curve25519(s, sk, pk) != 0) { + return -1; + } + return crypto_core_hsalsa20(k, zero, s, NULL); +} + +int +crypto_box_curve25519xsalsa20poly1305_afternm(unsigned char *c, + const unsigned char *m, + unsigned long long mlen, + const unsigned char *n, + const unsigned char *k) +{ + return crypto_secretbox_xsalsa20poly1305(c, m, mlen, n, k); +} + +int +crypto_box_curve25519xsalsa20poly1305_open_afternm(unsigned char *m, + const unsigned char *c, + unsigned long long clen, + const unsigned char *n, + const unsigned char *k) +{ + return crypto_secretbox_xsalsa20poly1305_open(m, c, clen, n, k); +} + +int +crypto_box_curve25519xsalsa20poly1305(unsigned char *c, const unsigned char *m, + unsigned long long mlen, + const unsigned char *n, + const unsigned char *pk, + const unsigned char *sk) +{ + unsigned char k[crypto_box_curve25519xsalsa20poly1305_BEFORENMBYTES]; + int ret; + + if (crypto_box_curve25519xsalsa20poly1305_beforenm(k, pk, sk) != 0) { + return -1; + } + ret = crypto_box_curve25519xsalsa20poly1305_afternm(c, m, mlen, n, k); + sodium_memzero(k, sizeof k); + + return ret; +} + +int +crypto_box_curve25519xsalsa20poly1305_open( + unsigned char *m, const unsigned char *c, unsigned long long clen, + const unsigned char *n, const unsigned char *pk, const unsigned char *sk) +{ + unsigned char k[crypto_box_curve25519xsalsa20poly1305_BEFORENMBYTES]; + int ret; + + if (crypto_box_curve25519xsalsa20poly1305_beforenm(k, pk, sk) != 0) { + return -1; + } + ret = crypto_box_curve25519xsalsa20poly1305_open_afternm(m, c, clen, n, k); + sodium_memzero(k, sizeof k); + + return ret; +} + +size_t +crypto_box_curve25519xsalsa20poly1305_seedbytes(void) +{ + return crypto_box_curve25519xsalsa20poly1305_SEEDBYTES; +} + +size_t +crypto_box_curve25519xsalsa20poly1305_publickeybytes(void) +{ + return crypto_box_curve25519xsalsa20poly1305_PUBLICKEYBYTES; +} + +size_t +crypto_box_curve25519xsalsa20poly1305_secretkeybytes(void) +{ + return crypto_box_curve25519xsalsa20poly1305_SECRETKEYBYTES; +} + +size_t +crypto_box_curve25519xsalsa20poly1305_beforenmbytes(void) +{ + return crypto_box_curve25519xsalsa20poly1305_BEFORENMBYTES; +} + +size_t +crypto_box_curve25519xsalsa20poly1305_noncebytes(void) +{ + return crypto_box_curve25519xsalsa20poly1305_NONCEBYTES; +} + +size_t +crypto_box_curve25519xsalsa20poly1305_zerobytes(void) +{ + return crypto_box_curve25519xsalsa20poly1305_ZEROBYTES; +} + +size_t +crypto_box_curve25519xsalsa20poly1305_boxzerobytes(void) +{ + return crypto_box_curve25519xsalsa20poly1305_BOXZEROBYTES; +} + +size_t +crypto_box_curve25519xsalsa20poly1305_macbytes(void) +{ + return crypto_box_curve25519xsalsa20poly1305_MACBYTES; +} + +size_t +crypto_box_curve25519xsalsa20poly1305_messagebytes_max(void) +{ + return crypto_box_curve25519xsalsa20poly1305_MESSAGEBYTES_MAX; +} diff --git a/libs/libsodium/src/crypto_core/ed25519/core_ed25519.c b/libs/libsodium/src/crypto_core/ed25519/core_ed25519.c new file mode 100644 index 0000000000..1bcf5022b1 --- /dev/null +++ b/libs/libsodium/src/crypto_core/ed25519/core_ed25519.c @@ -0,0 +1,79 @@ + +#include "crypto_core_ed25519.h" +#include "private/common.h" +#include "private/ed25519_ref10.h" + +int +crypto_core_ed25519_is_valid_point(const unsigned char *p) +{ + ge25519_p3 p_p3; + + if (ge25519_is_canonical(p) == 0 || + ge25519_has_small_order(p) != 0 || + ge25519_frombytes(&p_p3, p) != 0 || + ge25519_is_on_curve(&p_p3) == 0 || + ge25519_is_on_main_subgroup(&p_p3) == 0) { + return 0; + } + return 1; +} + +int +crypto_core_ed25519_add(unsigned char *r, + const unsigned char *p, const unsigned char *q) +{ + ge25519_p3 p_p3, q_p3, r_p3; + ge25519_p1p1 r_p1p1; + ge25519_cached q_cached; + + if (ge25519_frombytes(&p_p3, p) != 0 || ge25519_is_on_curve(&p_p3) == 0 || + ge25519_frombytes(&q_p3, q) != 0 || ge25519_is_on_curve(&q_p3) == 0) { + return -1; + } + ge25519_p3_to_cached(&q_cached, &q_p3); + ge25519_add(&r_p1p1, &p_p3, &q_cached); + ge25519_p1p1_to_p3(&r_p3, &r_p1p1); + ge25519_p3_tobytes(r, &r_p3); + + return 0; +} + +int +crypto_core_ed25519_sub(unsigned char *r, + const unsigned char *p, const unsigned char *q) +{ + ge25519_p3 p_p3, q_p3, r_p3; + ge25519_p1p1 r_p1p1; + ge25519_cached q_cached; + + if (ge25519_frombytes(&p_p3, p) != 0 || ge25519_is_on_curve(&p_p3) == 0 || + ge25519_frombytes(&q_p3, q) != 0 || ge25519_is_on_curve(&q_p3) == 0) { + return -1; + } + ge25519_p3_to_cached(&q_cached, &q_p3); + ge25519_sub(&r_p1p1, &p_p3, &q_cached); + ge25519_p1p1_to_p3(&r_p3, &r_p1p1); + ge25519_p3_tobytes(r, &r_p3); + + return 0; +} + +int +crypto_core_ed25519_from_uniform(unsigned char *p, const unsigned char *r) +{ + ge25519_from_uniform(p, r); + + return - ge25519_has_small_order(p); +} + +size_t +crypto_core_ed25519_bytes(void) +{ + return crypto_core_ed25519_BYTES; +} + +size_t +crypto_core_ed25519_uniformbytes(void) +{ + return crypto_core_ed25519_UNIFORMBYTES; +} diff --git a/libs/libsodium/src/crypto_core/ed25519/ref10/ed25519_ref10.c b/libs/libsodium/src/crypto_core/ed25519/ref10/ed25519_ref10.c new file mode 100644 index 0000000000..f7b8280685 --- /dev/null +++ b/libs/libsodium/src/crypto_core/ed25519/ref10/ed25519_ref10.c @@ -0,0 +1,2031 @@ +#include <stddef.h> +#include <stdint.h> +#include <stdlib.h> +#include <string.h> + +#include "crypto_verify_32.h" +#include "private/common.h" +#include "private/ed25519_ref10.h" +#include "utils.h" + +static inline uint64_t +load_3(const unsigned char *in) +{ + uint64_t result; + + result = (uint64_t) in[0]; + result |= ((uint64_t) in[1]) << 8; + result |= ((uint64_t) in[2]) << 16; + + return result; +} + +static inline uint64_t +load_4(const unsigned char *in) +{ + uint64_t result; + + result = (uint64_t) in[0]; + result |= ((uint64_t) in[1]) << 8; + result |= ((uint64_t) in[2]) << 16; + result |= ((uint64_t) in[3]) << 24; + + return result; +} + +/* + * Field arithmetic: + * Use 5*51 bit limbs on 64-bit systems with support for 128 bit arithmetic, + * and 10*25.5 bit limbs elsewhere. + * + * Functions used elsewhere that are candidates for inlining are defined + * via "private/curve25519_ref10.h". + */ + +#ifdef HAVE_TI_MODE +# include "fe_51/constants.h" +# include "fe_51/fe.h" +#else +# include "fe_25_5/constants.h" +# include "fe_25_5/fe.h" +#endif + +void +fe25519_invert(fe25519 out, const fe25519 z) +{ + fe25519 t0; + fe25519 t1; + fe25519 t2; + fe25519 t3; + int i; + + fe25519_sq(t0, z); + fe25519_sq(t1, t0); + fe25519_sq(t1, t1); + fe25519_mul(t1, z, t1); + fe25519_mul(t0, t0, t1); + fe25519_sq(t2, t0); + fe25519_mul(t1, t1, t2); + fe25519_sq(t2, t1); + for (i = 1; i < 5; ++i) { + fe25519_sq(t2, t2); + } + fe25519_mul(t1, t2, t1); + fe25519_sq(t2, t1); + for (i = 1; i < 10; ++i) { + fe25519_sq(t2, t2); + } + fe25519_mul(t2, t2, t1); + fe25519_sq(t3, t2); + for (i = 1; i < 20; ++i) { + fe25519_sq(t3, t3); + } + fe25519_mul(t2, t3, t2); + fe25519_sq(t2, t2); + for (i = 1; i < 10; ++i) { + fe25519_sq(t2, t2); + } + fe25519_mul(t1, t2, t1); + fe25519_sq(t2, t1); + for (i = 1; i < 50; ++i) { + fe25519_sq(t2, t2); + } + fe25519_mul(t2, t2, t1); + fe25519_sq(t3, t2); + for (i = 1; i < 100; ++i) { + fe25519_sq(t3, t3); + } + fe25519_mul(t2, t3, t2); + fe25519_sq(t2, t2); + for (i = 1; i < 50; ++i) { + fe25519_sq(t2, t2); + } + fe25519_mul(t1, t2, t1); + fe25519_sq(t1, t1); + for (i = 1; i < 5; ++i) { + fe25519_sq(t1, t1); + } + fe25519_mul(out, t1, t0); +} + +static void +fe25519_pow22523(fe25519 out, const fe25519 z) +{ + fe25519 t0; + fe25519 t1; + fe25519 t2; + int i; + + fe25519_sq(t0, z); + fe25519_sq(t1, t0); + fe25519_sq(t1, t1); + fe25519_mul(t1, z, t1); + fe25519_mul(t0, t0, t1); + fe25519_sq(t0, t0); + fe25519_mul(t0, t1, t0); + fe25519_sq(t1, t0); + for (i = 1; i < 5; ++i) { + fe25519_sq(t1, t1); + } + fe25519_mul(t0, t1, t0); + fe25519_sq(t1, t0); + for (i = 1; i < 10; ++i) { + fe25519_sq(t1, t1); + } + fe25519_mul(t1, t1, t0); + fe25519_sq(t2, t1); + for (i = 1; i < 20; ++i) { + fe25519_sq(t2, t2); + } + fe25519_mul(t1, t2, t1); + fe25519_sq(t1, t1); + for (i = 1; i < 10; ++i) { + fe25519_sq(t1, t1); + } + fe25519_mul(t0, t1, t0); + fe25519_sq(t1, t0); + for (i = 1; i < 50; ++i) { + fe25519_sq(t1, t1); + } + fe25519_mul(t1, t1, t0); + fe25519_sq(t2, t1); + for (i = 1; i < 100; ++i) { + fe25519_sq(t2, t2); + } + fe25519_mul(t1, t2, t1); + fe25519_sq(t1, t1); + for (i = 1; i < 50; ++i) { + fe25519_sq(t1, t1); + } + fe25519_mul(t0, t1, t0); + fe25519_sq(t0, t0); + fe25519_sq(t0, t0); + fe25519_mul(out, t0, z); +} + +/* + r = p + q + */ + +void +ge25519_add(ge25519_p1p1 *r, const ge25519_p3 *p, const ge25519_cached *q) +{ + fe25519 t0; + + fe25519_add(r->X, p->Y, p->X); + fe25519_sub(r->Y, p->Y, p->X); + fe25519_mul(r->Z, r->X, q->YplusX); + fe25519_mul(r->Y, r->Y, q->YminusX); + fe25519_mul(r->T, q->T2d, p->T); + fe25519_mul(r->X, p->Z, q->Z); + fe25519_add(t0, r->X, r->X); + fe25519_sub(r->X, r->Z, r->Y); + fe25519_add(r->Y, r->Z, r->Y); + fe25519_add(r->Z, t0, r->T); + fe25519_sub(r->T, t0, r->T); +} + +static void +slide_vartime(signed char *r, const unsigned char *a) +{ + int i; + int b; + int k; + int ribs; + int cmp; + + for (i = 0; i < 256; ++i) { + r[i] = 1 & (a[i >> 3] >> (i & 7)); + } + for (i = 0; i < 256; ++i) { + if (! r[i]) { + continue; + } + for (b = 1; b <= 6 && i + b < 256; ++b) { + if (! r[i + b]) { + continue; + } + ribs = r[i + b] << b; + cmp = r[i] + ribs; + if (cmp <= 15) { + r[i] = cmp; + r[i + b] = 0; + } else { + cmp = r[i] - ribs; + if (cmp < -15) { + break; + } + r[i] = cmp; + for (k = i + b; k < 256; ++k) { + if (! r[k]) { + r[k] = 1; + break; + } + r[k] = 0; + } + } + } + } +} + +int +ge25519_frombytes(ge25519_p3 *h, const unsigned char *s) +{ + fe25519 u; + fe25519 v; + fe25519 v3; + fe25519 vxx; + fe25519 m_root_check, p_root_check; + fe25519 negx; + fe25519 x_sqrtm1; + int has_m_root, has_p_root; + + fe25519_frombytes(h->Y, s); + fe25519_1(h->Z); + fe25519_sq(u, h->Y); + fe25519_mul(v, u, d); + fe25519_sub(u, u, h->Z); /* u = y^2-1 */ + fe25519_add(v, v, h->Z); /* v = dy^2+1 */ + + fe25519_sq(v3, v); + fe25519_mul(v3, v3, v); /* v3 = v^3 */ + fe25519_sq(h->X, v3); + fe25519_mul(h->X, h->X, v); + fe25519_mul(h->X, h->X, u); /* x = uv^7 */ + + fe25519_pow22523(h->X, h->X); /* x = (uv^7)^((q-5)/8) */ + fe25519_mul(h->X, h->X, v3); + fe25519_mul(h->X, h->X, u); /* x = uv^3(uv^7)^((q-5)/8) */ + + fe25519_sq(vxx, h->X); + fe25519_mul(vxx, vxx, v); + fe25519_sub(m_root_check, vxx, u); /* vx^2-u */ + fe25519_add(p_root_check, vxx, u); /* vx^2+u */ + has_m_root = fe25519_iszero(m_root_check); + has_p_root = fe25519_iszero(p_root_check); + fe25519_mul(x_sqrtm1, h->X, sqrtm1); /* x*sqrt(-1) */ + fe25519_cmov(h->X, x_sqrtm1, 1 - has_m_root); + + fe25519_neg(negx, h->X); + fe25519_cmov(h->X, negx, fe25519_isnegative(h->X) ^ (s[31] >> 7)); + fe25519_mul(h->T, h->X, h->Y); + + return (has_m_root | has_p_root) - 1; +} + +int +ge25519_frombytes_negate_vartime(ge25519_p3 *h, const unsigned char *s) +{ + fe25519 u; + fe25519 v; + fe25519 v3; + fe25519 vxx; + fe25519 m_root_check, p_root_check; + + fe25519_frombytes(h->Y, s); + fe25519_1(h->Z); + fe25519_sq(u, h->Y); + fe25519_mul(v, u, d); + fe25519_sub(u, u, h->Z); /* u = y^2-1 */ + fe25519_add(v, v, h->Z); /* v = dy^2+1 */ + + fe25519_sq(v3, v); + fe25519_mul(v3, v3, v); /* v3 = v^3 */ + fe25519_sq(h->X, v3); + fe25519_mul(h->X, h->X, v); + fe25519_mul(h->X, h->X, u); /* x = uv^7 */ + + fe25519_pow22523(h->X, h->X); /* x = (uv^7)^((q-5)/8) */ + fe25519_mul(h->X, h->X, v3); + fe25519_mul(h->X, h->X, u); /* x = uv^3(uv^7)^((q-5)/8) */ + + fe25519_sq(vxx, h->X); + fe25519_mul(vxx, vxx, v); + fe25519_sub(m_root_check, vxx, u); /* vx^2-u */ + if (fe25519_iszero(m_root_check) == 0) { + fe25519_add(p_root_check, vxx, u); /* vx^2+u */ + if (fe25519_iszero(p_root_check) == 0) { + return -1; + } + fe25519_mul(h->X, h->X, sqrtm1); + } + + if (fe25519_isnegative(h->X) == (s[31] >> 7)) { + fe25519_neg(h->X, h->X); + } + fe25519_mul(h->T, h->X, h->Y); + + return 0; +} + +/* + r = p + q + */ + +static void +ge25519_madd(ge25519_p1p1 *r, const ge25519_p3 *p, const ge25519_precomp *q) +{ + fe25519 t0; + + fe25519_add(r->X, p->Y, p->X); + fe25519_sub(r->Y, p->Y, p->X); + fe25519_mul(r->Z, r->X, q->yplusx); + fe25519_mul(r->Y, r->Y, q->yminusx); + fe25519_mul(r->T, q->xy2d, p->T); + fe25519_add(t0, p->Z, p->Z); + fe25519_sub(r->X, r->Z, r->Y); + fe25519_add(r->Y, r->Z, r->Y); + fe25519_add(r->Z, t0, r->T); + fe25519_sub(r->T, t0, r->T); +} + +/* + r = p - q + */ + +static void +ge25519_msub(ge25519_p1p1 *r, const ge25519_p3 *p, const ge25519_precomp *q) +{ + fe25519 t0; + + fe25519_add(r->X, p->Y, p->X); + fe25519_sub(r->Y, p->Y, p->X); + fe25519_mul(r->Z, r->X, q->yminusx); + fe25519_mul(r->Y, r->Y, q->yplusx); + fe25519_mul(r->T, q->xy2d, p->T); + fe25519_add(t0, p->Z, p->Z); + fe25519_sub(r->X, r->Z, r->Y); + fe25519_add(r->Y, r->Z, r->Y); + fe25519_sub(r->Z, t0, r->T); + fe25519_add(r->T, t0, r->T); +} + +/* + r = p + */ + +void +ge25519_p1p1_to_p2(ge25519_p2 *r, const ge25519_p1p1 *p) +{ + fe25519_mul(r->X, p->X, p->T); + fe25519_mul(r->Y, p->Y, p->Z); + fe25519_mul(r->Z, p->Z, p->T); +} + +/* + r = p + */ + +void +ge25519_p1p1_to_p3(ge25519_p3 *r, const ge25519_p1p1 *p) +{ + fe25519_mul(r->X, p->X, p->T); + fe25519_mul(r->Y, p->Y, p->Z); + fe25519_mul(r->Z, p->Z, p->T); + fe25519_mul(r->T, p->X, p->Y); +} + +static void +ge25519_p2_0(ge25519_p2 *h) +{ + fe25519_0(h->X); + fe25519_1(h->Y); + fe25519_1(h->Z); +} + +/* + r = 2 * p + */ + +static void +ge25519_p2_dbl(ge25519_p1p1 *r, const ge25519_p2 *p) +{ + fe25519 t0; + + fe25519_sq(r->X, p->X); + fe25519_sq(r->Z, p->Y); + fe25519_sq2(r->T, p->Z); + fe25519_add(r->Y, p->X, p->Y); + fe25519_sq(t0, r->Y); + fe25519_add(r->Y, r->Z, r->X); + fe25519_sub(r->Z, r->Z, r->X); + fe25519_sub(r->X, t0, r->Y); + fe25519_sub(r->T, r->T, r->Z); +} + +static void +ge25519_p3_0(ge25519_p3 *h) +{ + fe25519_0(h->X); + fe25519_1(h->Y); + fe25519_1(h->Z); + fe25519_0(h->T); +} + +static void +ge25519_cached_0(ge25519_cached *h) +{ + fe25519_1(h->YplusX); + fe25519_1(h->YminusX); + fe25519_1(h->Z); + fe25519_0(h->T2d); +} + +/* + r = p + */ + +void +ge25519_p3_to_cached(ge25519_cached *r, const ge25519_p3 *p) +{ + fe25519_add(r->YplusX, p->Y, p->X); + fe25519_sub(r->YminusX, p->Y, p->X); + fe25519_copy(r->Z, p->Z); + fe25519_mul(r->T2d, p->T, d2); +} + +static void +ge25519_p3_to_precomp(ge25519_precomp *pi, const ge25519_p3 *p) +{ + fe25519 recip; + fe25519 x; + fe25519 y; + fe25519 xy; + + fe25519_invert(recip, p->Z); + fe25519_mul(x, p->X, recip); + fe25519_mul(y, p->Y, recip); + fe25519_add(pi->yplusx, y, x); + fe25519_sub(pi->yminusx, y, x); + fe25519_mul(xy, x, y); + fe25519_mul(pi->xy2d, xy, d2); +} + +/* + r = p + */ + +static void +ge25519_p3_to_p2(ge25519_p2 *r, const ge25519_p3 *p) +{ + fe25519_copy(r->X, p->X); + fe25519_copy(r->Y, p->Y); + fe25519_copy(r->Z, p->Z); +} + +void +ge25519_p3_tobytes(unsigned char *s, const ge25519_p3 *h) +{ + fe25519 recip; + fe25519 x; + fe25519 y; + + fe25519_invert(recip, h->Z); + fe25519_mul(x, h->X, recip); + fe25519_mul(y, h->Y, recip); + fe25519_tobytes(s, y); + s[31] ^= fe25519_isnegative(x) << 7; +} + +/* + r = 2 * p + */ + +static void +ge25519_p3_dbl(ge25519_p1p1 *r, const ge25519_p3 *p) +{ + ge25519_p2 q; + ge25519_p3_to_p2(&q, p); + ge25519_p2_dbl(r, &q); +} + +static void +ge25519_precomp_0(ge25519_precomp *h) +{ + fe25519_1(h->yplusx); + fe25519_1(h->yminusx); + fe25519_0(h->xy2d); +} + +static unsigned char +equal(signed char b, signed char c) +{ + unsigned char ub = b; + unsigned char uc = c; + unsigned char x = ub ^ uc; /* 0: yes; 1..255: no */ + uint32_t y = x; /* 0: yes; 1..255: no */ + + y -= 1; /* 4294967295: yes; 0..254: no */ + y >>= 31; /* 1: yes; 0: no */ + + return y; +} + +static unsigned char +negative(signed char b) +{ + /* 18446744073709551361..18446744073709551615: yes; 0..255: no */ + uint64_t x = b; + + x >>= 63; /* 1: yes; 0: no */ + + return x; +} + +static void +ge25519_cmov(ge25519_precomp *t, const ge25519_precomp *u, unsigned char b) +{ + fe25519_cmov(t->yplusx, u->yplusx, b); + fe25519_cmov(t->yminusx, u->yminusx, b); + fe25519_cmov(t->xy2d, u->xy2d, b); +} + +static void +ge25519_cmov_cached(ge25519_cached *t, const ge25519_cached *u, unsigned char b) +{ + fe25519_cmov(t->YplusX, u->YplusX, b); + fe25519_cmov(t->YminusX, u->YminusX, b); + fe25519_cmov(t->Z, u->Z, b); + fe25519_cmov(t->T2d, u->T2d, b); +} + +static void +ge25519_select(ge25519_precomp *t, const ge25519_precomp precomp[8], const signed char b) +{ + ge25519_precomp minust; + const unsigned char bnegative = negative(b); + const unsigned char babs = b - (((-bnegative) & b) * ((signed char) 1 << 1)); + + ge25519_precomp_0(t); + ge25519_cmov(t, &precomp[0], equal(babs, 1)); + ge25519_cmov(t, &precomp[1], equal(babs, 2)); + ge25519_cmov(t, &precomp[2], equal(babs, 3)); + ge25519_cmov(t, &precomp[3], equal(babs, 4)); + ge25519_cmov(t, &precomp[4], equal(babs, 5)); + ge25519_cmov(t, &precomp[5], equal(babs, 6)); + ge25519_cmov(t, &precomp[6], equal(babs, 7)); + ge25519_cmov(t, &precomp[7], equal(babs, 8)); + fe25519_copy(minust.yplusx, t->yminusx); + fe25519_copy(minust.yminusx, t->yplusx); + fe25519_neg(minust.xy2d, t->xy2d); + ge25519_cmov(t, &minust, bnegative); +} + +static void +ge25519_select_base(ge25519_precomp *t, const int pos, const signed char b) +{ + static const ge25519_precomp base[32][8] = { /* base[i][j] = (j+1)*256^i*B */ +#ifdef HAVE_TI_MODE +# include "fe_51/base.h" +#else +# include "fe_25_5/base.h" +#endif + }; + ge25519_select(t, base[pos], b); +} + +static void +ge25519_select_cached(ge25519_cached *t, const ge25519_cached cached[8], const signed char b) +{ + ge25519_cached minust; + const unsigned char bnegative = negative(b); + const unsigned char babs = b - (((-bnegative) & b) * ((signed char) 1 << 1)); + + ge25519_cached_0(t); + ge25519_cmov_cached(t, &cached[0], equal(babs, 1)); + ge25519_cmov_cached(t, &cached[1], equal(babs, 2)); + ge25519_cmov_cached(t, &cached[2], equal(babs, 3)); + ge25519_cmov_cached(t, &cached[3], equal(babs, 4)); + ge25519_cmov_cached(t, &cached[4], equal(babs, 5)); + ge25519_cmov_cached(t, &cached[5], equal(babs, 6)); + ge25519_cmov_cached(t, &cached[6], equal(babs, 7)); + ge25519_cmov_cached(t, &cached[7], equal(babs, 8)); + fe25519_copy(minust.YplusX, t->YminusX); + fe25519_copy(minust.YminusX, t->YplusX); + fe25519_copy(minust.Z, t->Z); + fe25519_neg(minust.T2d, t->T2d); + ge25519_cmov_cached(t, &minust, bnegative); +} + +/* + r = p - q + */ + +void +ge25519_sub(ge25519_p1p1 *r, const ge25519_p3 *p, const ge25519_cached *q) +{ + fe25519 t0; + + fe25519_add(r->X, p->Y, p->X); + fe25519_sub(r->Y, p->Y, p->X); + fe25519_mul(r->Z, r->X, q->YminusX); + fe25519_mul(r->Y, r->Y, q->YplusX); + fe25519_mul(r->T, q->T2d, p->T); + fe25519_mul(r->X, p->Z, q->Z); + fe25519_add(t0, r->X, r->X); + fe25519_sub(r->X, r->Z, r->Y); + fe25519_add(r->Y, r->Z, r->Y); + fe25519_sub(r->Z, t0, r->T); + fe25519_add(r->T, t0, r->T); +} + +void +ge25519_tobytes(unsigned char *s, const ge25519_p2 *h) +{ + fe25519 recip; + fe25519 x; + fe25519 y; + + fe25519_invert(recip, h->Z); + fe25519_mul(x, h->X, recip); + fe25519_mul(y, h->Y, recip); + fe25519_tobytes(s, y); + s[31] ^= fe25519_isnegative(x) << 7; +} + +/* + r = a * A + b * B + where a = a[0]+256*a[1]+...+256^31 a[31]. + and b = b[0]+256*b[1]+...+256^31 b[31]. + B is the Ed25519 base point (x,4/5) with x positive. + + Only used for signatures verification. + */ + +void +ge25519_double_scalarmult_vartime(ge25519_p2 *r, const unsigned char *a, + const ge25519_p3 *A, const unsigned char *b) +{ + static const ge25519_precomp Bi[8] = { +#ifdef HAVE_TI_MODE +# include "fe_51/base2.h" +#else +# include "fe_25_5/base2.h" +#endif + }; + signed char aslide[256]; + signed char bslide[256]; + ge25519_cached Ai[8]; /* A,3A,5A,7A,9A,11A,13A,15A */ + ge25519_p1p1 t; + ge25519_p3 u; + ge25519_p3 A2; + int i; + + slide_vartime(aslide, a); + slide_vartime(bslide, b); + + ge25519_p3_to_cached(&Ai[0], A); + + ge25519_p3_dbl(&t, A); + ge25519_p1p1_to_p3(&A2, &t); + + ge25519_add(&t, &A2, &Ai[0]); + ge25519_p1p1_to_p3(&u, &t); + ge25519_p3_to_cached(&Ai[1], &u); + + ge25519_add(&t, &A2, &Ai[1]); + ge25519_p1p1_to_p3(&u, &t); + ge25519_p3_to_cached(&Ai[2], &u); + + ge25519_add(&t, &A2, &Ai[2]); + ge25519_p1p1_to_p3(&u, &t); + ge25519_p3_to_cached(&Ai[3], &u); + + ge25519_add(&t, &A2, &Ai[3]); + ge25519_p1p1_to_p3(&u, &t); + ge25519_p3_to_cached(&Ai[4], &u); + + ge25519_add(&t, &A2, &Ai[4]); + ge25519_p1p1_to_p3(&u, &t); + ge25519_p3_to_cached(&Ai[5], &u); + + ge25519_add(&t, &A2, &Ai[5]); + ge25519_p1p1_to_p3(&u, &t); + ge25519_p3_to_cached(&Ai[6], &u); + + ge25519_add(&t, &A2, &Ai[6]); + ge25519_p1p1_to_p3(&u, &t); + ge25519_p3_to_cached(&Ai[7], &u); + + ge25519_p2_0(r); + + for (i = 255; i >= 0; --i) { + if (aslide[i] || bslide[i]) { + break; + } + } + + for (; i >= 0; --i) { + ge25519_p2_dbl(&t, r); + + if (aslide[i] > 0) { + ge25519_p1p1_to_p3(&u, &t); + ge25519_add(&t, &u, &Ai[aslide[i] / 2]); + } else if (aslide[i] < 0) { + ge25519_p1p1_to_p3(&u, &t); + ge25519_sub(&t, &u, &Ai[(-aslide[i]) / 2]); + } + + if (bslide[i] > 0) { + ge25519_p1p1_to_p3(&u, &t); + ge25519_madd(&t, &u, &Bi[bslide[i] / 2]); + } else if (bslide[i] < 0) { + ge25519_p1p1_to_p3(&u, &t); + ge25519_msub(&t, &u, &Bi[(-bslide[i]) / 2]); + } + + ge25519_p1p1_to_p2(r, &t); + } +} + +/* + h = a * p + where a = a[0]+256*a[1]+...+256^31 a[31] + + Preconditions: + a[31] <= 127 + + p is public + */ + +void +ge25519_scalarmult(ge25519_p3 *h, const unsigned char *a, const ge25519_p3 *p) +{ + signed char e[64]; + signed char carry; + ge25519_p1p1 r; + ge25519_p2 s; + ge25519_p1p1 t2, t3, t4, t5, t6, t7, t8; + ge25519_p3 p2, p3, p4, p5, p6, p7, p8; + ge25519_cached pi[8]; + ge25519_cached t; + int i; + + ge25519_p3_to_cached(&pi[1 - 1], p); /* p */ + + ge25519_p3_dbl(&t2, p); + ge25519_p1p1_to_p3(&p2, &t2); + ge25519_p3_to_cached(&pi[2 - 1], &p2); /* 2p = 2*p */ + + ge25519_add(&t3, p, &pi[2 - 1]); + ge25519_p1p1_to_p3(&p3, &t3); + ge25519_p3_to_cached(&pi[3 - 1], &p3); /* 3p = 2p+p */ + + ge25519_p3_dbl(&t4, &p2); + ge25519_p1p1_to_p3(&p4, &t4); + ge25519_p3_to_cached(&pi[4 - 1], &p4); /* 4p = 2*2p */ + + ge25519_add(&t5, p, &pi[4 - 1]); + ge25519_p1p1_to_p3(&p5, &t5); + ge25519_p3_to_cached(&pi[5 - 1], &p5); /* 5p = 4p+p */ + + ge25519_p3_dbl(&t6, &p3); + ge25519_p1p1_to_p3(&p6, &t6); + ge25519_p3_to_cached(&pi[6 - 1], &p6); /* 6p = 2*3p */ + + ge25519_add(&t7, p, &pi[6 - 1]); + ge25519_p1p1_to_p3(&p7, &t7); + ge25519_p3_to_cached(&pi[7 - 1], &p7); /* 7p = 6p+p */ + + ge25519_p3_dbl(&t8, &p4); + ge25519_p1p1_to_p3(&p8, &t8); + ge25519_p3_to_cached(&pi[8 - 1], &p8); /* 8p = 2*4p */ + + for (i = 0; i < 32; ++i) { + e[2 * i + 0] = (a[i] >> 0) & 15; + e[2 * i + 1] = (a[i] >> 4) & 15; + } + /* each e[i] is between 0 and 15 */ + /* e[63] is between 0 and 7 */ + + carry = 0; + for (i = 0; i < 63; ++i) { + e[i] += carry; + carry = e[i] + 8; + carry >>= 4; + e[i] -= carry * ((signed char) 1 << 4); + } + e[63] += carry; + /* each e[i] is between -8 and 8 */ + + ge25519_p3_0(h); + + for (i = 63; i != 0; i--) { + ge25519_select_cached(&t, pi, e[i]); + ge25519_add(&r, h, &t); + + ge25519_p1p1_to_p2(&s, &r); + ge25519_p2_dbl(&r, &s); + ge25519_p1p1_to_p2(&s, &r); + ge25519_p2_dbl(&r, &s); + ge25519_p1p1_to_p2(&s, &r); + ge25519_p2_dbl(&r, &s); + ge25519_p1p1_to_p2(&s, &r); + ge25519_p2_dbl(&r, &s); + + ge25519_p1p1_to_p3(h, &r); /* *16 */ + } + ge25519_select_cached(&t, pi, e[i]); + ge25519_add(&r, h, &t); + + ge25519_p1p1_to_p3(h, &r); +} + +/* + h = a * B (with precomputation) + where a = a[0]+256*a[1]+...+256^31 a[31] + B is the Ed25519 base point (x,4/5) with x positive + (as bytes: 0x5866666666666666666666666666666666666666666666666666666666666666) + + Preconditions: + a[31] <= 127 + */ + +void +ge25519_scalarmult_base(ge25519_p3 *h, const unsigned char *a) +{ + signed char e[64]; + signed char carry; + ge25519_p1p1 r; + ge25519_p2 s; + ge25519_precomp t; + int i; + + for (i = 0; i < 32; ++i) { + e[2 * i + 0] = (a[i] >> 0) & 15; + e[2 * i + 1] = (a[i] >> 4) & 15; + } + /* each e[i] is between 0 and 15 */ + /* e[63] is between 0 and 7 */ + + carry = 0; + for (i = 0; i < 63; ++i) { + e[i] += carry; + carry = e[i] + 8; + carry >>= 4; + e[i] -= carry * ((signed char) 1 << 4); + } + e[63] += carry; + /* each e[i] is between -8 and 8 */ + + ge25519_p3_0(h); + + for (i = 1; i < 64; i += 2) { + ge25519_select_base(&t, i / 2, e[i]); + ge25519_madd(&r, h, &t); + ge25519_p1p1_to_p3(h, &r); + } + + ge25519_p3_dbl(&r, h); + ge25519_p1p1_to_p2(&s, &r); + ge25519_p2_dbl(&r, &s); + ge25519_p1p1_to_p2(&s, &r); + ge25519_p2_dbl(&r, &s); + ge25519_p1p1_to_p2(&s, &r); + ge25519_p2_dbl(&r, &s); + ge25519_p1p1_to_p3(h, &r); + + for (i = 0; i < 64; i += 2) { + ge25519_select_base(&t, i / 2, e[i]); + ge25519_madd(&r, h, &t); + ge25519_p1p1_to_p3(h, &r); + } +} + +/* multiply by the order of the main subgroup l = 2^252+27742317777372353535851937790883648493 */ +static void +ge25519_mul_l(ge25519_p3 *r, const ge25519_p3 *A) +{ + static const signed char aslide[253] = { + 13, 0, 0, 0, 0, -1, 0, 0, 0, 0, -11, 0, 0, 0, 0, 0, 0, -5, 0, 0, 0, 0, 0, 0, -3, 0, 0, 0, 0, -13, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, -13, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 0, 0, 0, 11, 0, 0, 0, 0, -13, 0, 0, 0, 0, 0, 0, -3, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 3, 0, 0, 0, 0, -11, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, -1, 0, 0, 0, 0, 7, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 + }; + ge25519_cached Ai[8]; + ge25519_p1p1 t; + ge25519_p3 u; + ge25519_p3 A2; + int i; + + ge25519_p3_to_cached(&Ai[0], A); + ge25519_p3_dbl(&t, A); + ge25519_p1p1_to_p3(&A2, &t); + ge25519_add(&t, &A2, &Ai[0]); + ge25519_p1p1_to_p3(&u, &t); + ge25519_p3_to_cached(&Ai[1], &u); + ge25519_add(&t, &A2, &Ai[1]); + ge25519_p1p1_to_p3(&u, &t); + ge25519_p3_to_cached(&Ai[2], &u); + ge25519_add(&t, &A2, &Ai[2]); + ge25519_p1p1_to_p3(&u, &t); + ge25519_p3_to_cached(&Ai[3], &u); + ge25519_add(&t, &A2, &Ai[3]); + ge25519_p1p1_to_p3(&u, &t); + ge25519_p3_to_cached(&Ai[4], &u); + ge25519_add(&t, &A2, &Ai[4]); + ge25519_p1p1_to_p3(&u, &t); + ge25519_p3_to_cached(&Ai[5], &u); + ge25519_add(&t, &A2, &Ai[5]); + ge25519_p1p1_to_p3(&u, &t); + ge25519_p3_to_cached(&Ai[6], &u); + ge25519_add(&t, &A2, &Ai[6]); + ge25519_p1p1_to_p3(&u, &t); + ge25519_p3_to_cached(&Ai[7], &u); + + ge25519_p3_0(r); + + for (i = 252; i >= 0; --i) { + ge25519_p3_dbl(&t, r); + + if (aslide[i] > 0) { + ge25519_p1p1_to_p3(&u, &t); + ge25519_add(&t, &u, &Ai[aslide[i] / 2]); + } else if (aslide[i] < 0) { + ge25519_p1p1_to_p3(&u, &t); + ge25519_sub(&t, &u, &Ai[(-aslide[i]) / 2]); + } + + ge25519_p1p1_to_p3(r, &t); + } +} + +int +ge25519_is_on_curve(const ge25519_p3 *p) +{ + fe25519 x2; + fe25519 y2; + fe25519 z2; + fe25519 z4; + fe25519 t0; + fe25519 t1; + + fe25519_sq(x2, p->X); + fe25519_sq(y2, p->Y); + fe25519_sq(z2, p->Z); + fe25519_sub(t0, y2, x2); + fe25519_mul(t0, t0, z2); + + fe25519_mul(t1, x2, y2); + fe25519_mul(t1, t1, d); + fe25519_sq(z4, z2); + fe25519_add(t1, t1, z4); + fe25519_sub(t0, t0, t1); + + return fe25519_iszero(t0); +} + +int +ge25519_is_on_main_subgroup(const ge25519_p3 *p) +{ + ge25519_p3 pl; + + ge25519_mul_l(&pl, p); + + return fe25519_iszero(pl.X); +} + +int +ge25519_is_canonical(const unsigned char *s) +{ + unsigned char c; + unsigned char d; + unsigned int i; + + c = (s[31] & 0x7f) ^ 0x7f; + for (i = 30; i > 0; i--) { + c |= s[i] ^ 0xff; + } + c = (((unsigned int) c) - 1U) >> 8; + d = (0xed - 1U - (unsigned int) s[0]) >> 8; + + return 1 - (c & d & 1); +} + +int +ge25519_has_small_order(const unsigned char s[32]) +{ + CRYPTO_ALIGN(16) + static const unsigned char blacklist[][32] = { + /* 0 (order 4) */ + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + /* 1 (order 1) */ + { 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + /* 2707385501144840649318225287225658788936804267575313519463743609750303402022 + (order 8) */ + { 0x26, 0xe8, 0x95, 0x8f, 0xc2, 0xb2, 0x27, 0xb0, 0x45, 0xc3, 0xf4, + 0x89, 0xf2, 0xef, 0x98, 0xf0, 0xd5, 0xdf, 0xac, 0x05, 0xd3, 0xc6, + 0x33, 0x39, 0xb1, 0x38, 0x02, 0x88, 0x6d, 0x53, 0xfc, 0x05 }, + /* 55188659117513257062467267217118295137698188065244968500265048394206261417927 + (order 8) */ + { 0xc7, 0x17, 0x6a, 0x70, 0x3d, 0x4d, 0xd8, 0x4f, 0xba, 0x3c, 0x0b, + 0x76, 0x0d, 0x10, 0x67, 0x0f, 0x2a, 0x20, 0x53, 0xfa, 0x2c, 0x39, + 0xcc, 0xc6, 0x4e, 0xc7, 0xfd, 0x77, 0x92, 0xac, 0x03, 0x7a }, + /* p-1 (order 2) */ + { 0xec, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f }, + /* p (=0, order 4) */ + { 0xed, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f }, + /* p+1 (=1, order 1) */ + { 0xee, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f } + }; + unsigned char c[7] = { 0 }; + unsigned int k; + size_t i, j; + + COMPILER_ASSERT(7 == sizeof blacklist / sizeof blacklist[0]); + for (j = 0; j < 31; j++) { + for (i = 0; i < sizeof blacklist / sizeof blacklist[0]; i++) { + c[i] |= s[j] ^ blacklist[i][j]; + } + } + for (i = 0; i < sizeof blacklist / sizeof blacklist[0]; i++) { + c[i] |= (s[j] & 0x7f) ^ blacklist[i][j]; + } + k = 0; + for (i = 0; i < sizeof blacklist / sizeof blacklist[0]; i++) { + k |= (c[i] - 1); + } + return (int) ((k >> 8) & 1); +} + +/* + Input: + a[0]+256*a[1]+...+256^31*a[31] = a + b[0]+256*b[1]+...+256^31*b[31] = b + c[0]+256*c[1]+...+256^31*c[31] = c + * + Output: + s[0]+256*s[1]+...+256^31*s[31] = (ab+c) mod l + where l = 2^252 + 27742317777372353535851937790883648493. + */ + +void +sc25519_muladd(unsigned char *s, const unsigned char *a, + const unsigned char *b, const unsigned char *c) +{ + int64_t a0 = 2097151 & load_3(a); + int64_t a1 = 2097151 & (load_4(a + 2) >> 5); + int64_t a2 = 2097151 & (load_3(a + 5) >> 2); + int64_t a3 = 2097151 & (load_4(a + 7) >> 7); + int64_t a4 = 2097151 & (load_4(a + 10) >> 4); + int64_t a5 = 2097151 & (load_3(a + 13) >> 1); + int64_t a6 = 2097151 & (load_4(a + 15) >> 6); + int64_t a7 = 2097151 & (load_3(a + 18) >> 3); + int64_t a8 = 2097151 & load_3(a + 21); + int64_t a9 = 2097151 & (load_4(a + 23) >> 5); + int64_t a10 = 2097151 & (load_3(a + 26) >> 2); + int64_t a11 = (load_4(a + 28) >> 7); + + int64_t b0 = 2097151 & load_3(b); + int64_t b1 = 2097151 & (load_4(b + 2) >> 5); + int64_t b2 = 2097151 & (load_3(b + 5) >> 2); + int64_t b3 = 2097151 & (load_4(b + 7) >> 7); + int64_t b4 = 2097151 & (load_4(b + 10) >> 4); + int64_t b5 = 2097151 & (load_3(b + 13) >> 1); + int64_t b6 = 2097151 & (load_4(b + 15) >> 6); + int64_t b7 = 2097151 & (load_3(b + 18) >> 3); + int64_t b8 = 2097151 & load_3(b + 21); + int64_t b9 = 2097151 & (load_4(b + 23) >> 5); + int64_t b10 = 2097151 & (load_3(b + 26) >> 2); + int64_t b11 = (load_4(b + 28) >> 7); + + int64_t c0 = 2097151 & load_3(c); + int64_t c1 = 2097151 & (load_4(c + 2) >> 5); + int64_t c2 = 2097151 & (load_3(c + 5) >> 2); + int64_t c3 = 2097151 & (load_4(c + 7) >> 7); + int64_t c4 = 2097151 & (load_4(c + 10) >> 4); + int64_t c5 = 2097151 & (load_3(c + 13) >> 1); + int64_t c6 = 2097151 & (load_4(c + 15) >> 6); + int64_t c7 = 2097151 & (load_3(c + 18) >> 3); + int64_t c8 = 2097151 & load_3(c + 21); + int64_t c9 = 2097151 & (load_4(c + 23) >> 5); + int64_t c10 = 2097151 & (load_3(c + 26) >> 2); + int64_t c11 = (load_4(c + 28) >> 7); + + int64_t s0; + int64_t s1; + int64_t s2; + int64_t s3; + int64_t s4; + int64_t s5; + int64_t s6; + int64_t s7; + int64_t s8; + int64_t s9; + int64_t s10; + int64_t s11; + int64_t s12; + int64_t s13; + int64_t s14; + int64_t s15; + int64_t s16; + int64_t s17; + int64_t s18; + int64_t s19; + int64_t s20; + int64_t s21; + int64_t s22; + int64_t s23; + + int64_t carry0; + int64_t carry1; + int64_t carry2; + int64_t carry3; + int64_t carry4; + int64_t carry5; + int64_t carry6; + int64_t carry7; + int64_t carry8; + int64_t carry9; + int64_t carry10; + int64_t carry11; + int64_t carry12; + int64_t carry13; + int64_t carry14; + int64_t carry15; + int64_t carry16; + int64_t carry17; + int64_t carry18; + int64_t carry19; + int64_t carry20; + int64_t carry21; + int64_t carry22; + + s0 = c0 + a0 * b0; + s1 = c1 + a0 * b1 + a1 * b0; + s2 = c2 + a0 * b2 + a1 * b1 + a2 * b0; + s3 = c3 + a0 * b3 + a1 * b2 + a2 * b1 + a3 * b0; + s4 = c4 + a0 * b4 + a1 * b3 + a2 * b2 + a3 * b1 + a4 * b0; + s5 = c5 + a0 * b5 + a1 * b4 + a2 * b3 + a3 * b2 + a4 * b1 + a5 * b0; + s6 = c6 + a0 * b6 + a1 * b5 + a2 * b4 + a3 * b3 + a4 * b2 + a5 * b1 + + a6 * b0; + s7 = c7 + a0 * b7 + a1 * b6 + a2 * b5 + a3 * b4 + a4 * b3 + a5 * b2 + + a6 * b1 + a7 * b0; + s8 = c8 + a0 * b8 + a1 * b7 + a2 * b6 + a3 * b5 + a4 * b4 + a5 * b3 + + a6 * b2 + a7 * b1 + a8 * b0; + s9 = c9 + a0 * b9 + a1 * b8 + a2 * b7 + a3 * b6 + a4 * b5 + a5 * b4 + + a6 * b3 + a7 * b2 + a8 * b1 + a9 * b0; + s10 = c10 + a0 * b10 + a1 * b9 + a2 * b8 + a3 * b7 + a4 * b6 + a5 * b5 + + a6 * b4 + a7 * b3 + a8 * b2 + a9 * b1 + a10 * b0; + s11 = c11 + a0 * b11 + a1 * b10 + a2 * b9 + a3 * b8 + a4 * b7 + a5 * b6 + + a6 * b5 + a7 * b4 + a8 * b3 + a9 * b2 + a10 * b1 + a11 * b0; + s12 = a1 * b11 + a2 * b10 + a3 * b9 + a4 * b8 + a5 * b7 + a6 * b6 + + a7 * b5 + a8 * b4 + a9 * b3 + a10 * b2 + a11 * b1; + s13 = a2 * b11 + a3 * b10 + a4 * b9 + a5 * b8 + a6 * b7 + a7 * b6 + + a8 * b5 + a9 * b4 + a10 * b3 + a11 * b2; + s14 = a3 * b11 + a4 * b10 + a5 * b9 + a6 * b8 + a7 * b7 + a8 * b6 + + a9 * b5 + a10 * b4 + a11 * b3; + s15 = a4 * b11 + a5 * b10 + a6 * b9 + a7 * b8 + a8 * b7 + a9 * b6 + + a10 * b5 + a11 * b4; + s16 = + a5 * b11 + a6 * b10 + a7 * b9 + a8 * b8 + a9 * b7 + a10 * b6 + a11 * b5; + s17 = a6 * b11 + a7 * b10 + a8 * b9 + a9 * b8 + a10 * b7 + a11 * b6; + s18 = a7 * b11 + a8 * b10 + a9 * b9 + a10 * b8 + a11 * b7; + s19 = a8 * b11 + a9 * b10 + a10 * b9 + a11 * b8; + s20 = a9 * b11 + a10 * b10 + a11 * b9; + s21 = a10 * b11 + a11 * b10; + s22 = a11 * b11; + s23 = 0; + + carry0 = (s0 + (int64_t) (1L << 20)) >> 21; + s1 += carry0; + s0 -= carry0 * ((uint64_t) 1L << 21); + carry2 = (s2 + (int64_t) (1L << 20)) >> 21; + s3 += carry2; + s2 -= carry2 * ((uint64_t) 1L << 21); + carry4 = (s4 + (int64_t) (1L << 20)) >> 21; + s5 += carry4; + s4 -= carry4 * ((uint64_t) 1L << 21); + carry6 = (s6 + (int64_t) (1L << 20)) >> 21; + s7 += carry6; + s6 -= carry6 * ((uint64_t) 1L << 21); + carry8 = (s8 + (int64_t) (1L << 20)) >> 21; + s9 += carry8; + s8 -= carry8 * ((uint64_t) 1L << 21); + carry10 = (s10 + (int64_t) (1L << 20)) >> 21; + s11 += carry10; + s10 -= carry10 * ((uint64_t) 1L << 21); + carry12 = (s12 + (int64_t) (1L << 20)) >> 21; + s13 += carry12; + s12 -= carry12 * ((uint64_t) 1L << 21); + carry14 = (s14 + (int64_t) (1L << 20)) >> 21; + s15 += carry14; + s14 -= carry14 * ((uint64_t) 1L << 21); + carry16 = (s16 + (int64_t) (1L << 20)) >> 21; + s17 += carry16; + s16 -= carry16 * ((uint64_t) 1L << 21); + carry18 = (s18 + (int64_t) (1L << 20)) >> 21; + s19 += carry18; + s18 -= carry18 * ((uint64_t) 1L << 21); + carry20 = (s20 + (int64_t) (1L << 20)) >> 21; + s21 += carry20; + s20 -= carry20 * ((uint64_t) 1L << 21); + carry22 = (s22 + (int64_t) (1L << 20)) >> 21; + s23 += carry22; + s22 -= carry22 * ((uint64_t) 1L << 21); + + carry1 = (s1 + (int64_t) (1L << 20)) >> 21; + s2 += carry1; + s1 -= carry1 * ((uint64_t) 1L << 21); + carry3 = (s3 + (int64_t) (1L << 20)) >> 21; + s4 += carry3; + s3 -= carry3 * ((uint64_t) 1L << 21); + carry5 = (s5 + (int64_t) (1L << 20)) >> 21; + s6 += carry5; + s5 -= carry5 * ((uint64_t) 1L << 21); + carry7 = (s7 + (int64_t) (1L << 20)) >> 21; + s8 += carry7; + s7 -= carry7 * ((uint64_t) 1L << 21); + carry9 = (s9 + (int64_t) (1L << 20)) >> 21; + s10 += carry9; + s9 -= carry9 * ((uint64_t) 1L << 21); + carry11 = (s11 + (int64_t) (1L << 20)) >> 21; + s12 += carry11; + s11 -= carry11 * ((uint64_t) 1L << 21); + carry13 = (s13 + (int64_t) (1L << 20)) >> 21; + s14 += carry13; + s13 -= carry13 * ((uint64_t) 1L << 21); + carry15 = (s15 + (int64_t) (1L << 20)) >> 21; + s16 += carry15; + s15 -= carry15 * ((uint64_t) 1L << 21); + carry17 = (s17 + (int64_t) (1L << 20)) >> 21; + s18 += carry17; + s17 -= carry17 * ((uint64_t) 1L << 21); + carry19 = (s19 + (int64_t) (1L << 20)) >> 21; + s20 += carry19; + s19 -= carry19 * ((uint64_t) 1L << 21); + carry21 = (s21 + (int64_t) (1L << 20)) >> 21; + s22 += carry21; + s21 -= carry21 * ((uint64_t) 1L << 21); + + s11 += s23 * 666643; + s12 += s23 * 470296; + s13 += s23 * 654183; + s14 -= s23 * 997805; + s15 += s23 * 136657; + s16 -= s23 * 683901; + + s10 += s22 * 666643; + s11 += s22 * 470296; + s12 += s22 * 654183; + s13 -= s22 * 997805; + s14 += s22 * 136657; + s15 -= s22 * 683901; + + s9 += s21 * 666643; + s10 += s21 * 470296; + s11 += s21 * 654183; + s12 -= s21 * 997805; + s13 += s21 * 136657; + s14 -= s21 * 683901; + + s8 += s20 * 666643; + s9 += s20 * 470296; + s10 += s20 * 654183; + s11 -= s20 * 997805; + s12 += s20 * 136657; + s13 -= s20 * 683901; + + s7 += s19 * 666643; + s8 += s19 * 470296; + s9 += s19 * 654183; + s10 -= s19 * 997805; + s11 += s19 * 136657; + s12 -= s19 * 683901; + + s6 += s18 * 666643; + s7 += s18 * 470296; + s8 += s18 * 654183; + s9 -= s18 * 997805; + s10 += s18 * 136657; + s11 -= s18 * 683901; + + carry6 = (s6 + (int64_t) (1L << 20)) >> 21; + s7 += carry6; + s6 -= carry6 * ((uint64_t) 1L << 21); + carry8 = (s8 + (int64_t) (1L << 20)) >> 21; + s9 += carry8; + s8 -= carry8 * ((uint64_t) 1L << 21); + carry10 = (s10 + (int64_t) (1L << 20)) >> 21; + s11 += carry10; + s10 -= carry10 * ((uint64_t) 1L << 21); + carry12 = (s12 + (int64_t) (1L << 20)) >> 21; + s13 += carry12; + s12 -= carry12 * ((uint64_t) 1L << 21); + carry14 = (s14 + (int64_t) (1L << 20)) >> 21; + s15 += carry14; + s14 -= carry14 * ((uint64_t) 1L << 21); + carry16 = (s16 + (int64_t) (1L << 20)) >> 21; + s17 += carry16; + s16 -= carry16 * ((uint64_t) 1L << 21); + + carry7 = (s7 + (int64_t) (1L << 20)) >> 21; + s8 += carry7; + s7 -= carry7 * ((uint64_t) 1L << 21); + carry9 = (s9 + (int64_t) (1L << 20)) >> 21; + s10 += carry9; + s9 -= carry9 * ((uint64_t) 1L << 21); + carry11 = (s11 + (int64_t) (1L << 20)) >> 21; + s12 += carry11; + s11 -= carry11 * ((uint64_t) 1L << 21); + carry13 = (s13 + (int64_t) (1L << 20)) >> 21; + s14 += carry13; + s13 -= carry13 * ((uint64_t) 1L << 21); + carry15 = (s15 + (int64_t) (1L << 20)) >> 21; + s16 += carry15; + s15 -= carry15 * ((uint64_t) 1L << 21); + + s5 += s17 * 666643; + s6 += s17 * 470296; + s7 += s17 * 654183; + s8 -= s17 * 997805; + s9 += s17 * 136657; + s10 -= s17 * 683901; + + s4 += s16 * 666643; + s5 += s16 * 470296; + s6 += s16 * 654183; + s7 -= s16 * 997805; + s8 += s16 * 136657; + s9 -= s16 * 683901; + + s3 += s15 * 666643; + s4 += s15 * 470296; + s5 += s15 * 654183; + s6 -= s15 * 997805; + s7 += s15 * 136657; + s8 -= s15 * 683901; + + s2 += s14 * 666643; + s3 += s14 * 470296; + s4 += s14 * 654183; + s5 -= s14 * 997805; + s6 += s14 * 136657; + s7 -= s14 * 683901; + + s1 += s13 * 666643; + s2 += s13 * 470296; + s3 += s13 * 654183; + s4 -= s13 * 997805; + s5 += s13 * 136657; + s6 -= s13 * 683901; + + s0 += s12 * 666643; + s1 += s12 * 470296; + s2 += s12 * 654183; + s3 -= s12 * 997805; + s4 += s12 * 136657; + s5 -= s12 * 683901; + s12 = 0; + + carry0 = (s0 + (int64_t) (1L << 20)) >> 21; + s1 += carry0; + s0 -= carry0 * ((uint64_t) 1L << 21); + carry2 = (s2 + (int64_t) (1L << 20)) >> 21; + s3 += carry2; + s2 -= carry2 * ((uint64_t) 1L << 21); + carry4 = (s4 + (int64_t) (1L << 20)) >> 21; + s5 += carry4; + s4 -= carry4 * ((uint64_t) 1L << 21); + carry6 = (s6 + (int64_t) (1L << 20)) >> 21; + s7 += carry6; + s6 -= carry6 * ((uint64_t) 1L << 21); + carry8 = (s8 + (int64_t) (1L << 20)) >> 21; + s9 += carry8; + s8 -= carry8 * ((uint64_t) 1L << 21); + carry10 = (s10 + (int64_t) (1L << 20)) >> 21; + s11 += carry10; + s10 -= carry10 * ((uint64_t) 1L << 21); + + carry1 = (s1 + (int64_t) (1L << 20)) >> 21; + s2 += carry1; + s1 -= carry1 * ((uint64_t) 1L << 21); + carry3 = (s3 + (int64_t) (1L << 20)) >> 21; + s4 += carry3; + s3 -= carry3 * ((uint64_t) 1L << 21); + carry5 = (s5 + (int64_t) (1L << 20)) >> 21; + s6 += carry5; + s5 -= carry5 * ((uint64_t) 1L << 21); + carry7 = (s7 + (int64_t) (1L << 20)) >> 21; + s8 += carry7; + s7 -= carry7 * ((uint64_t) 1L << 21); + carry9 = (s9 + (int64_t) (1L << 20)) >> 21; + s10 += carry9; + s9 -= carry9 * ((uint64_t) 1L << 21); + carry11 = (s11 + (int64_t) (1L << 20)) >> 21; + s12 += carry11; + s11 -= carry11 * ((uint64_t) 1L << 21); + + s0 += s12 * 666643; + s1 += s12 * 470296; + s2 += s12 * 654183; + s3 -= s12 * 997805; + s4 += s12 * 136657; + s5 -= s12 * 683901; + s12 = 0; + + carry0 = s0 >> 21; + s1 += carry0; + s0 -= carry0 * ((uint64_t) 1L << 21); + carry1 = s1 >> 21; + s2 += carry1; + s1 -= carry1 * ((uint64_t) 1L << 21); + carry2 = s2 >> 21; + s3 += carry2; + s2 -= carry2 * ((uint64_t) 1L << 21); + carry3 = s3 >> 21; + s4 += carry3; + s3 -= carry3 * ((uint64_t) 1L << 21); + carry4 = s4 >> 21; + s5 += carry4; + s4 -= carry4 * ((uint64_t) 1L << 21); + carry5 = s5 >> 21; + s6 += carry5; + s5 -= carry5 * ((uint64_t) 1L << 21); + carry6 = s6 >> 21; + s7 += carry6; + s6 -= carry6 * ((uint64_t) 1L << 21); + carry7 = s7 >> 21; + s8 += carry7; + s7 -= carry7 * ((uint64_t) 1L << 21); + carry8 = s8 >> 21; + s9 += carry8; + s8 -= carry8 * ((uint64_t) 1L << 21); + carry9 = s9 >> 21; + s10 += carry9; + s9 -= carry9 * ((uint64_t) 1L << 21); + carry10 = s10 >> 21; + s11 += carry10; + s10 -= carry10 * ((uint64_t) 1L << 21); + carry11 = s11 >> 21; + s12 += carry11; + s11 -= carry11 * ((uint64_t) 1L << 21); + + s0 += s12 * 666643; + s1 += s12 * 470296; + s2 += s12 * 654183; + s3 -= s12 * 997805; + s4 += s12 * 136657; + s5 -= s12 * 683901; + + carry0 = s0 >> 21; + s1 += carry0; + s0 -= carry0 * ((uint64_t) 1L << 21); + carry1 = s1 >> 21; + s2 += carry1; + s1 -= carry1 * ((uint64_t) 1L << 21); + carry2 = s2 >> 21; + s3 += carry2; + s2 -= carry2 * ((uint64_t) 1L << 21); + carry3 = s3 >> 21; + s4 += carry3; + s3 -= carry3 * ((uint64_t) 1L << 21); + carry4 = s4 >> 21; + s5 += carry4; + s4 -= carry4 * ((uint64_t) 1L << 21); + carry5 = s5 >> 21; + s6 += carry5; + s5 -= carry5 * ((uint64_t) 1L << 21); + carry6 = s6 >> 21; + s7 += carry6; + s6 -= carry6 * ((uint64_t) 1L << 21); + carry7 = s7 >> 21; + s8 += carry7; + s7 -= carry7 * ((uint64_t) 1L << 21); + carry8 = s8 >> 21; + s9 += carry8; + s8 -= carry8 * ((uint64_t) 1L << 21); + carry9 = s9 >> 21; + s10 += carry9; + s9 -= carry9 * ((uint64_t) 1L << 21); + carry10 = s10 >> 21; + s11 += carry10; + s10 -= carry10 * ((uint64_t) 1L << 21); + + s[0] = s0 >> 0; + s[1] = s0 >> 8; + s[2] = (s0 >> 16) | (s1 * ((uint64_t) 1 << 5)); + s[3] = s1 >> 3; + s[4] = s1 >> 11; + s[5] = (s1 >> 19) | (s2 * ((uint64_t) 1 << 2)); + s[6] = s2 >> 6; + s[7] = (s2 >> 14) | (s3 * ((uint64_t) 1 << 7)); + s[8] = s3 >> 1; + s[9] = s3 >> 9; + s[10] = (s3 >> 17) | (s4 * ((uint64_t) 1 << 4)); + s[11] = s4 >> 4; + s[12] = s4 >> 12; + s[13] = (s4 >> 20) | (s5 * ((uint64_t) 1 << 1)); + s[14] = s5 >> 7; + s[15] = (s5 >> 15) | (s6 * ((uint64_t) 1 << 6)); + s[16] = s6 >> 2; + s[17] = s6 >> 10; + s[18] = (s6 >> 18) | (s7 * ((uint64_t) 1 << 3)); + s[19] = s7 >> 5; + s[20] = s7 >> 13; + s[21] = s8 >> 0; + s[22] = s8 >> 8; + s[23] = (s8 >> 16) | (s9 * ((uint64_t) 1 << 5)); + s[24] = s9 >> 3; + s[25] = s9 >> 11; + s[26] = (s9 >> 19) | (s10 * ((uint64_t) 1 << 2)); + s[27] = s10 >> 6; + s[28] = (s10 >> 14) | (s11 * ((uint64_t) 1 << 7)); + s[29] = s11 >> 1; + s[30] = s11 >> 9; + s[31] = s11 >> 17; +} + +/* + Input: + s[0]+256*s[1]+...+256^63*s[63] = s + * + Output: + s[0]+256*s[1]+...+256^31*s[31] = s mod l + where l = 2^252 + 27742317777372353535851937790883648493. + Overwrites s in place. + */ + +void +sc25519_reduce(unsigned char *s) +{ + int64_t s0 = 2097151 & load_3(s); + int64_t s1 = 2097151 & (load_4(s + 2) >> 5); + int64_t s2 = 2097151 & (load_3(s + 5) >> 2); + int64_t s3 = 2097151 & (load_4(s + 7) >> 7); + int64_t s4 = 2097151 & (load_4(s + 10) >> 4); + int64_t s5 = 2097151 & (load_3(s + 13) >> 1); + int64_t s6 = 2097151 & (load_4(s + 15) >> 6); + int64_t s7 = 2097151 & (load_3(s + 18) >> 3); + int64_t s8 = 2097151 & load_3(s + 21); + int64_t s9 = 2097151 & (load_4(s + 23) >> 5); + int64_t s10 = 2097151 & (load_3(s + 26) >> 2); + int64_t s11 = 2097151 & (load_4(s + 28) >> 7); + int64_t s12 = 2097151 & (load_4(s + 31) >> 4); + int64_t s13 = 2097151 & (load_3(s + 34) >> 1); + int64_t s14 = 2097151 & (load_4(s + 36) >> 6); + int64_t s15 = 2097151 & (load_3(s + 39) >> 3); + int64_t s16 = 2097151 & load_3(s + 42); + int64_t s17 = 2097151 & (load_4(s + 44) >> 5); + int64_t s18 = 2097151 & (load_3(s + 47) >> 2); + int64_t s19 = 2097151 & (load_4(s + 49) >> 7); + int64_t s20 = 2097151 & (load_4(s + 52) >> 4); + int64_t s21 = 2097151 & (load_3(s + 55) >> 1); + int64_t s22 = 2097151 & (load_4(s + 57) >> 6); + int64_t s23 = (load_4(s + 60) >> 3); + + int64_t carry0; + int64_t carry1; + int64_t carry2; + int64_t carry3; + int64_t carry4; + int64_t carry5; + int64_t carry6; + int64_t carry7; + int64_t carry8; + int64_t carry9; + int64_t carry10; + int64_t carry11; + int64_t carry12; + int64_t carry13; + int64_t carry14; + int64_t carry15; + int64_t carry16; + + s11 += s23 * 666643; + s12 += s23 * 470296; + s13 += s23 * 654183; + s14 -= s23 * 997805; + s15 += s23 * 136657; + s16 -= s23 * 683901; + + s10 += s22 * 666643; + s11 += s22 * 470296; + s12 += s22 * 654183; + s13 -= s22 * 997805; + s14 += s22 * 136657; + s15 -= s22 * 683901; + + s9 += s21 * 666643; + s10 += s21 * 470296; + s11 += s21 * 654183; + s12 -= s21 * 997805; + s13 += s21 * 136657; + s14 -= s21 * 683901; + + s8 += s20 * 666643; + s9 += s20 * 470296; + s10 += s20 * 654183; + s11 -= s20 * 997805; + s12 += s20 * 136657; + s13 -= s20 * 683901; + + s7 += s19 * 666643; + s8 += s19 * 470296; + s9 += s19 * 654183; + s10 -= s19 * 997805; + s11 += s19 * 136657; + s12 -= s19 * 683901; + + s6 += s18 * 666643; + s7 += s18 * 470296; + s8 += s18 * 654183; + s9 -= s18 * 997805; + s10 += s18 * 136657; + s11 -= s18 * 683901; + + carry6 = (s6 + (int64_t) (1L << 20)) >> 21; + s7 += carry6; + s6 -= carry6 * ((uint64_t) 1L << 21); + carry8 = (s8 + (int64_t) (1L << 20)) >> 21; + s9 += carry8; + s8 -= carry8 * ((uint64_t) 1L << 21); + carry10 = (s10 + (int64_t) (1L << 20)) >> 21; + s11 += carry10; + s10 -= carry10 * ((uint64_t) 1L << 21); + carry12 = (s12 + (int64_t) (1L << 20)) >> 21; + s13 += carry12; + s12 -= carry12 * ((uint64_t) 1L << 21); + carry14 = (s14 + (int64_t) (1L << 20)) >> 21; + s15 += carry14; + s14 -= carry14 * ((uint64_t) 1L << 21); + carry16 = (s16 + (int64_t) (1L << 20)) >> 21; + s17 += carry16; + s16 -= carry16 * ((uint64_t) 1L << 21); + + carry7 = (s7 + (int64_t) (1L << 20)) >> 21; + s8 += carry7; + s7 -= carry7 * ((uint64_t) 1L << 21); + carry9 = (s9 + (int64_t) (1L << 20)) >> 21; + s10 += carry9; + s9 -= carry9 * ((uint64_t) 1L << 21); + carry11 = (s11 + (int64_t) (1L << 20)) >> 21; + s12 += carry11; + s11 -= carry11 * ((uint64_t) 1L << 21); + carry13 = (s13 + (int64_t) (1L << 20)) >> 21; + s14 += carry13; + s13 -= carry13 * ((uint64_t) 1L << 21); + carry15 = (s15 + (int64_t) (1L << 20)) >> 21; + s16 += carry15; + s15 -= carry15 * ((uint64_t) 1L << 21); + + s5 += s17 * 666643; + s6 += s17 * 470296; + s7 += s17 * 654183; + s8 -= s17 * 997805; + s9 += s17 * 136657; + s10 -= s17 * 683901; + + s4 += s16 * 666643; + s5 += s16 * 470296; + s6 += s16 * 654183; + s7 -= s16 * 997805; + s8 += s16 * 136657; + s9 -= s16 * 683901; + + s3 += s15 * 666643; + s4 += s15 * 470296; + s5 += s15 * 654183; + s6 -= s15 * 997805; + s7 += s15 * 136657; + s8 -= s15 * 683901; + + s2 += s14 * 666643; + s3 += s14 * 470296; + s4 += s14 * 654183; + s5 -= s14 * 997805; + s6 += s14 * 136657; + s7 -= s14 * 683901; + + s1 += s13 * 666643; + s2 += s13 * 470296; + s3 += s13 * 654183; + s4 -= s13 * 997805; + s5 += s13 * 136657; + s6 -= s13 * 683901; + + s0 += s12 * 666643; + s1 += s12 * 470296; + s2 += s12 * 654183; + s3 -= s12 * 997805; + s4 += s12 * 136657; + s5 -= s12 * 683901; + s12 = 0; + + carry0 = (s0 + (int64_t) (1L << 20)) >> 21; + s1 += carry0; + s0 -= carry0 * ((uint64_t) 1L << 21); + carry2 = (s2 + (int64_t) (1L << 20)) >> 21; + s3 += carry2; + s2 -= carry2 * ((uint64_t) 1L << 21); + carry4 = (s4 + (int64_t) (1L << 20)) >> 21; + s5 += carry4; + s4 -= carry4 * ((uint64_t) 1L << 21); + carry6 = (s6 + (int64_t) (1L << 20)) >> 21; + s7 += carry6; + s6 -= carry6 * ((uint64_t) 1L << 21); + carry8 = (s8 + (int64_t) (1L << 20)) >> 21; + s9 += carry8; + s8 -= carry8 * ((uint64_t) 1L << 21); + carry10 = (s10 + (int64_t) (1L << 20)) >> 21; + s11 += carry10; + s10 -= carry10 * ((uint64_t) 1L << 21); + + carry1 = (s1 + (int64_t) (1L << 20)) >> 21; + s2 += carry1; + s1 -= carry1 * ((uint64_t) 1L << 21); + carry3 = (s3 + (int64_t) (1L << 20)) >> 21; + s4 += carry3; + s3 -= carry3 * ((uint64_t) 1L << 21); + carry5 = (s5 + (int64_t) (1L << 20)) >> 21; + s6 += carry5; + s5 -= carry5 * ((uint64_t) 1L << 21); + carry7 = (s7 + (int64_t) (1L << 20)) >> 21; + s8 += carry7; + s7 -= carry7 * ((uint64_t) 1L << 21); + carry9 = (s9 + (int64_t) (1L << 20)) >> 21; + s10 += carry9; + s9 -= carry9 * ((uint64_t) 1L << 21); + carry11 = (s11 + (int64_t) (1L << 20)) >> 21; + s12 += carry11; + s11 -= carry11 * ((uint64_t) 1L << 21); + + s0 += s12 * 666643; + s1 += s12 * 470296; + s2 += s12 * 654183; + s3 -= s12 * 997805; + s4 += s12 * 136657; + s5 -= s12 * 683901; + s12 = 0; + + carry0 = s0 >> 21; + s1 += carry0; + s0 -= carry0 * ((uint64_t) 1L << 21); + carry1 = s1 >> 21; + s2 += carry1; + s1 -= carry1 * ((uint64_t) 1L << 21); + carry2 = s2 >> 21; + s3 += carry2; + s2 -= carry2 * ((uint64_t) 1L << 21); + carry3 = s3 >> 21; + s4 += carry3; + s3 -= carry3 * ((uint64_t) 1L << 21); + carry4 = s4 >> 21; + s5 += carry4; + s4 -= carry4 * ((uint64_t) 1L << 21); + carry5 = s5 >> 21; + s6 += carry5; + s5 -= carry5 * ((uint64_t) 1L << 21); + carry6 = s6 >> 21; + s7 += carry6; + s6 -= carry6 * ((uint64_t) 1L << 21); + carry7 = s7 >> 21; + s8 += carry7; + s7 -= carry7 * ((uint64_t) 1L << 21); + carry8 = s8 >> 21; + s9 += carry8; + s8 -= carry8 * ((uint64_t) 1L << 21); + carry9 = s9 >> 21; + s10 += carry9; + s9 -= carry9 * ((uint64_t) 1L << 21); + carry10 = s10 >> 21; + s11 += carry10; + s10 -= carry10 * ((uint64_t) 1L << 21); + carry11 = s11 >> 21; + s12 += carry11; + s11 -= carry11 * ((uint64_t) 1L << 21); + + s0 += s12 * 666643; + s1 += s12 * 470296; + s2 += s12 * 654183; + s3 -= s12 * 997805; + s4 += s12 * 136657; + s5 -= s12 * 683901; + + carry0 = s0 >> 21; + s1 += carry0; + s0 -= carry0 * ((uint64_t) 1L << 21); + carry1 = s1 >> 21; + s2 += carry1; + s1 -= carry1 * ((uint64_t) 1L << 21); + carry2 = s2 >> 21; + s3 += carry2; + s2 -= carry2 * ((uint64_t) 1L << 21); + carry3 = s3 >> 21; + s4 += carry3; + s3 -= carry3 * ((uint64_t) 1L << 21); + carry4 = s4 >> 21; + s5 += carry4; + s4 -= carry4 * ((uint64_t) 1L << 21); + carry5 = s5 >> 21; + s6 += carry5; + s5 -= carry5 * ((uint64_t) 1L << 21); + carry6 = s6 >> 21; + s7 += carry6; + s6 -= carry6 * ((uint64_t) 1L << 21); + carry7 = s7 >> 21; + s8 += carry7; + s7 -= carry7 * ((uint64_t) 1L << 21); + carry8 = s8 >> 21; + s9 += carry8; + s8 -= carry8 * ((uint64_t) 1L << 21); + carry9 = s9 >> 21; + s10 += carry9; + s9 -= carry9 * ((uint64_t) 1L << 21); + carry10 = s10 >> 21; + s11 += carry10; + s10 -= carry10 * ((uint64_t) 1L << 21); + + s[0] = s0 >> 0; + s[1] = s0 >> 8; + s[2] = (s0 >> 16) | (s1 * ((uint64_t) 1 << 5)); + s[3] = s1 >> 3; + s[4] = s1 >> 11; + s[5] = (s1 >> 19) | (s2 * ((uint64_t) 1 << 2)); + s[6] = s2 >> 6; + s[7] = (s2 >> 14) | (s3 * ((uint64_t) 1 << 7)); + s[8] = s3 >> 1; + s[9] = s3 >> 9; + s[10] = (s3 >> 17) | (s4 * ((uint64_t) 1 << 4)); + s[11] = s4 >> 4; + s[12] = s4 >> 12; + s[13] = (s4 >> 20) | (s5 * ((uint64_t) 1 << 1)); + s[14] = s5 >> 7; + s[15] = (s5 >> 15) | (s6 * ((uint64_t) 1 << 6)); + s[16] = s6 >> 2; + s[17] = s6 >> 10; + s[18] = (s6 >> 18) | (s7 * ((uint64_t) 1 << 3)); + s[19] = s7 >> 5; + s[20] = s7 >> 13; + s[21] = s8 >> 0; + s[22] = s8 >> 8; + s[23] = (s8 >> 16) | (s9 * ((uint64_t) 1 << 5)); + s[24] = s9 >> 3; + s[25] = s9 >> 11; + s[26] = (s9 >> 19) | (s10 * ((uint64_t) 1 << 2)); + s[27] = s10 >> 6; + s[28] = (s10 >> 14) | (s11 * ((uint64_t) 1 << 7)); + s[29] = s11 >> 1; + s[30] = s11 >> 9; + s[31] = s11 >> 17; +} + +int +sc25519_is_canonical(const unsigned char *s) +{ + /* 2^252+27742317777372353535851937790883648493 */ + static const unsigned char L[32] = { + 0xed, 0xd3, 0xf5, 0x5c, 0x1a, 0x63, 0x12, 0x58, 0xd6, 0x9c, 0xf7, + 0xa2, 0xde, 0xf9, 0xde, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10 + }; + unsigned char c = 0; + unsigned char n = 1; + unsigned int i = 32; + + do { + i--; + c |= ((s[i] - L[i]) >> 8) & n; + n &= ((s[i] ^ L[i]) - 1) >> 8; + } while (i != 0); + + return (c != 0); +} + +static void +chi25519(fe25519 out, const fe25519 z) +{ + fe25519 t0, t1, t2, t3; + int i; + + fe25519_sq(t0, z); + fe25519_mul(t1, t0, z); + fe25519_sq(t0, t1); + fe25519_sq(t2, t0); + fe25519_sq(t2, t2); + fe25519_mul(t2, t2, t0); + fe25519_mul(t1, t2, z); + fe25519_sq(t2, t1); + + for (i = 1; i < 5; i++) { + fe25519_sq(t2, t2); + } + fe25519_mul(t1, t2, t1); + fe25519_sq(t2, t1); + for (i = 1; i < 10; i++) { + fe25519_sq(t2, t2); + } + fe25519_mul(t2, t2, t1); + fe25519_sq(t3, t2); + for (i = 1; i < 20; i++) { + fe25519_sq(t3, t3); + } + fe25519_mul(t2, t3, t2); + fe25519_sq(t2, t2); + for (i = 1; i < 10; i++) { + fe25519_sq(t2, t2); + } + fe25519_mul(t1, t2, t1); + fe25519_sq(t2, t1); + for (i = 1; i < 50; i++) { + fe25519_sq(t2, t2); + } + fe25519_mul(t2, t2, t1); + fe25519_sq(t3, t2); + for (i = 1; i < 100; i++) { + fe25519_sq(t3, t3); + } + fe25519_mul(t2, t3, t2); + fe25519_sq(t2, t2); + for (i = 1; i < 50; i++) { + fe25519_sq(t2, t2); + } + fe25519_mul(t1, t2, t1); + fe25519_sq(t1, t1); + for (i = 1; i < 4; i++) { + fe25519_sq(t1, t1); + } + fe25519_mul(out, t1, t0); +} + +void +ge25519_from_uniform(unsigned char s[32], const unsigned char r[32]) +{ + fe25519 e; + fe25519 negx; + fe25519 rr2; + fe25519 x, x2, x3; + ge25519_p3 p3; + ge25519_p1p1 p1; + ge25519_p2 p2; + unsigned int e_is_minus_1; + unsigned char x_sign; + + memcpy(s, r, 32); + x_sign = s[31] & 0x80; + s[31] &= 0x7f; + + fe25519_frombytes(rr2, s); + + /* elligator */ + fe25519_sq2(rr2, rr2); + rr2[0]++; + fe25519_invert(rr2, rr2); + fe25519_mul(x, curve25519_A, rr2); + fe25519_neg(x, x); + + fe25519_sq(x2, x); + fe25519_mul(x3, x, x2); + fe25519_add(e, x3, x); + fe25519_mul(x2, x2, curve25519_A); + fe25519_add(e, x2, e); + + chi25519(e, e); + + fe25519_tobytes(s, e); + e_is_minus_1 = s[1] & 1; + fe25519_neg(negx, x); + fe25519_cmov(x, negx, e_is_minus_1); + fe25519_0(x2); + fe25519_cmov(x2, curve25519_A, e_is_minus_1); + fe25519_sub(x, x, x2); + + /* yed = (x-1)/(x+1) */ + { + fe25519 one; + fe25519 x_plus_one; + fe25519 x_plus_one_inv; + fe25519 x_minus_one; + fe25519 yed; + + fe25519_1(one); + fe25519_add(x_plus_one, x, one); + fe25519_sub(x_minus_one, x, one); + fe25519_invert(x_plus_one_inv, x_plus_one); + fe25519_mul(yed, x_minus_one, x_plus_one_inv); + fe25519_tobytes(s, yed); + } + + /* recover x */ + s[31] |= x_sign; + if (ge25519_frombytes(&p3, s) != 0) { + abort(); /* LCOV_EXCL_LINE */ + } + + /* multiply by the cofactor */ + ge25519_p3_dbl(&p1, &p3); + ge25519_p1p1_to_p2(&p2, &p1); + ge25519_p2_dbl(&p1, &p2); + ge25519_p1p1_to_p2(&p2, &p1); + ge25519_p2_dbl(&p1, &p2); + ge25519_p1p1_to_p3(&p3, &p1); + + ge25519_p3_tobytes(s, &p3); +} diff --git a/libs/libsodium/src/crypto_core/ed25519/ref10/fe_25_5/base.h b/libs/libsodium/src/crypto_core/ed25519/ref10/fe_25_5/base.h new file mode 100644 index 0000000000..e18530bbb1 --- /dev/null +++ b/libs/libsodium/src/crypto_core/ed25519/ref10/fe_25_5/base.h @@ -0,0 +1,1344 @@ +{ /* 0/31 */ + { + { 25967493, -14356035, 29566456, 3660896, -12694345, 4014787, 27544626, -11754271, -6079156, 2047605 }, + { -12545711, 934262, -2722910, 3049990, -727428, 9406986, 12720692, 5043384, 19500929, -15469378 }, + { -8738181, 4489570, 9688441, -14785194, 10184609, -12363380, 29287919, 11864899, -24514362, -4438546 } + }, + { + { -12815894, -12976347, -21581243, 11784320, -25355658, -2750717, -11717903, -3814571, -358445, -10211303 }, + { -21703237, 6903825, 27185491, 6451973, -29577724, -9554005, -15616551, 11189268, -26829678, -5319081 }, + { 26966642, 11152617, 32442495, 15396054, 14353839, -12752335, -3128826, -9541118, -15472047, -4166697 } + }, + { + { 15636291, -9688557, 24204773, -7912398, 616977, -16685262, 27787600, -14772189, 28944400, -1550024 }, + { 16568933, 4717097, -11556148, -1102322, 15682896, -11807043, 16354577, -11775962, 7689662, 11199574 }, + { 30464156, -5976125, -11779434, -15670865, 23220365, 15915852, 7512774, 10017326, -17749093, -9920357 } + }, + { + { -17036878, 13921892, 10945806, -6033431, 27105052, -16084379, -28926210, 15006023, 3284568, -6276540 }, + { 23599295, -8306047, -11193664, -7687416, 13236774, 10506355, 7464579, 9656445, 13059162, 10374397 }, + { 7798556, 16710257, 3033922, 2874086, 28997861, 2835604, 32406664, -3839045, -641708, -101325 } + }, + { + { 10861363, 11473154, 27284546, 1981175, -30064349, 12577861, 32867885, 14515107, -15438304, 10819380 }, + { 4708026, 6336745, 20377586, 9066809, -11272109, 6594696, -25653668, 12483688, -12668491, 5581306 }, + { 19563160, 16186464, -29386857, 4097519, 10237984, -4348115, 28542350, 13850243, -23678021, -15815942 } + }, + { + { -15371964, -12862754, 32573250, 4720197, -26436522, 5875511, -19188627, -15224819, -9818940, -12085777 }, + { -8549212, 109983, 15149363, 2178705, 22900618, 4543417, 3044240, -15689887, 1762328, 14866737 }, + { -18199695, -15951423, -10473290, 1707278, -17185920, 3916101, -28236412, 3959421, 27914454, 4383652 } + }, + { + { 5153746, 9909285, 1723747, -2777874, 30523605, 5516873, 19480852, 5230134, -23952439, -15175766 }, + { -30269007, -3463509, 7665486, 10083793, 28475525, 1649722, 20654025, 16520125, 30598449, 7715701 }, + { 28881845, 14381568, 9657904, 3680757, -20181635, 7843316, -31400660, 1370708, 29794553, -1409300 } + }, + { + { 14499471, -2729599, -33191113, -4254652, 28494862, 14271267, 30290735, 10876454, -33154098, 2381726 }, + { -7195431, -2655363, -14730155, 462251, -27724326, 3941372, -6236617, 3696005, -32300832, 15351955 }, + { 27431194, 8222322, 16448760, -3907995, -18707002, 11938355, -32961401, -2970515, 29551813, 10109425 } + } +}, +{ /* 1/31 */ + { + { -13657040, -13155431, -31283750, 11777098, 21447386, 6519384, -2378284, -1627556, 10092783, -4764171 }, + { 27939166, 14210322, 4677035, 16277044, -22964462, -12398139, -32508754, 12005538, -17810127, 12803510 }, + { 17228999, -15661624, -1233527, 300140, -1224870, -11714777, 30364213, -9038194, 18016357, 4397660 } + }, + { + { -10958843, -7690207, 4776341, -14954238, 27850028, -15602212, -26619106, 14544525, -17477504, 982639 }, + { 29253598, 15796703, -2863982, -9908884, 10057023, 3163536, 7332899, -4120128, -21047696, 9934963 }, + { 5793303, 16271923, -24131614, -10116404, 29188560, 1206517, -14747930, 4559895, -30123922, -10897950 } + }, + { + { -27643952, -11493006, 16282657, -11036493, 28414021, -15012264, 24191034, 4541697, -13338309, 5500568 }, + { 12650548, -1497113, 9052871, 11355358, -17680037, -8400164, -17430592, 12264343, 10874051, 13524335 }, + { 25556948, -3045990, 714651, 2510400, 23394682, -10415330, 33119038, 5080568, -22528059, 5376628 } + }, + { + { -26088264, -4011052, -17013699, -3537628, -6726793, 1920897, -22321305, -9447443, 4535768, 1569007 }, + { -2255422, 14606630, -21692440, -8039818, 28430649, 8775819, -30494562, 3044290, 31848280, 12543772 }, + { -22028579, 2943893, -31857513, 6777306, 13784462, -4292203, -27377195, -2062731, 7718482, 14474653 } + }, + { + { 2385315, 2454213, -22631320, 46603, -4437935, -15680415, 656965, -7236665, 24316168, -5253567 }, + { 13741529, 10911568, -33233417, -8603737, -20177830, -1033297, 33040651, -13424532, -20729456, 8321686 }, + { 21060490, -2212744, 15712757, -4336099, 1639040, 10656336, 23845965, -11874838, -9984458, 608372 } + }, + { + { -13672732, -15087586, -10889693, -7557059, -6036909, 11305547, 1123968, -6780577, 27229399, 23887 }, + { -23244140, -294205, -11744728, 14712571, -29465699, -2029617, 12797024, -6440308, -1633405, 16678954 }, + { -29500620, 4770662, -16054387, 14001338, 7830047, 9564805, -1508144, -4795045, -17169265, 4904953 } + }, + { + { 24059557, 14617003, 19037157, -15039908, 19766093, -14906429, 5169211, 16191880, 2128236, -4326833 }, + { -16981152, 4124966, -8540610, -10653797, 30336522, -14105247, -29806336, 916033, -6882542, -2986532 }, + { -22630907, 12419372, -7134229, -7473371, -16478904, 16739175, 285431, 2763829, 15736322, 4143876 } + }, + { + { 2379352, 11839345, -4110402, -5988665, 11274298, 794957, 212801, -14594663, 23527084, -16458268 }, + { 33431127, -11130478, -17838966, -15626900, 8909499, 8376530, -32625340, 4087881, -15188911, -14416214 }, + { 1767683, 7197987, -13205226, -2022635, -13091350, 448826, 5799055, 4357868, -4774191, -16323038 } + } +}, +{ /* 2/31 */ + { + { 6721966, 13833823, -23523388, -1551314, 26354293, -11863321, 23365147, -3949732, 7390890, 2759800 }, + { 4409041, 2052381, 23373853, 10530217, 7676779, -12885954, 21302353, -4264057, 1244380, -12919645 }, + { -4421239, 7169619, 4982368, -2957590, 30256825, -2777540, 14086413, 9208236, 15886429, 16489664 } + }, + { + { 1996075, 10375649, 14346367, 13311202, -6874135, -16438411, -13693198, 398369, -30606455, -712933 }, + { -25307465, 9795880, -2777414, 14878809, -33531835, 14780363, 13348553, 12076947, -30836462, 5113182 }, + { -17770784, 11797796, 31950843, 13929123, -25888302, 12288344, -30341101, -7336386, 13847711, 5387222 } + }, + { + { -18582163, -3416217, 17824843, -2340966, 22744343, -10442611, 8763061, 3617786, -19600662, 10370991 }, + { 20246567, -14369378, 22358229, -543712, 18507283, -10413996, 14554437, -8746092, 32232924, 16763880 }, + { 9648505, 10094563, 26416693, 14745928, -30374318, -6472621, 11094161, 15689506, 3140038, -16510092 } + }, + { + { -16160072, 5472695, 31895588, 4744994, 8823515, 10365685, -27224800, 9448613, -28774454, 366295 }, + { 19153450, 11523972, -11096490, -6503142, -24647631, 5420647, 28344573, 8041113, 719605, 11671788 }, + { 8678025, 2694440, -6808014, 2517372, 4964326, 11152271, -15432916, -15266516, 27000813, -10195553 } + }, + { + { -15157904, 7134312, 8639287, -2814877, -7235688, 10421742, 564065, 5336097, 6750977, -14521026 }, + { 11836410, -3979488, 26297894, 16080799, 23455045, 15735944, 1695823, -8819122, 8169720, 16220347 }, + { -18115838, 8653647, 17578566, -6092619, -8025777, -16012763, -11144307, -2627664, -5990708, -14166033 } + }, + { + { -23308498, -10968312, 15213228, -10081214, -30853605, -11050004, 27884329, 2847284, 2655861, 1738395 }, + { -27537433, -14253021, -25336301, -8002780, -9370762, 8129821, 21651608, -3239336, -19087449, -11005278 }, + { 1533110, 3437855, 23735889, 459276, 29970501, 11335377, 26030092, 5821408, 10478196, 8544890 } + }, + { + { 32173121, -16129311, 24896207, 3921497, 22579056, -3410854, 19270449, 12217473, 17789017, -3395995 }, + { -30552961, -2228401, -15578829, -10147201, 13243889, 517024, 15479401, -3853233, 30460520, 1052596 }, + { -11614875, 13323618, 32618793, 8175907, -15230173, 12596687, 27491595, -4612359, 3179268, -9478891 } + }, + { + { 31947069, -14366651, -4640583, -15339921, -15125977, -6039709, -14756777, -16411740, 19072640, -9511060 }, + { 11685058, 11822410, 3158003, -13952594, 33402194, -4165066, 5977896, -5215017, 473099, 5040608 }, + { -20290863, 8198642, -27410132, 11602123, 1290375, -2799760, 28326862, 1721092, -19558642, -3131606 } + } +}, +{ /* 3/31 */ + { + { 7881532, 10687937, 7578723, 7738378, -18951012, -2553952, 21820786, 8076149, -27868496, 11538389 }, + { -19935666, 3899861, 18283497, -6801568, -15728660, -11249211, 8754525, 7446702, -5676054, 5797016 }, + { -11295600, -3793569, -15782110, -7964573, 12708869, -8456199, 2014099, -9050574, -2369172, -5877341 } + }, + { + { -22472376, -11568741, -27682020, 1146375, 18956691, 16640559, 1192730, -3714199, 15123619, 10811505 }, + { 14352098, -3419715, -18942044, 10822655, 32750596, 4699007, -70363, 15776356, -28886779, -11974553 }, + { -28241164, -8072475, -4978962, -5315317, 29416931, 1847569, -20654173, -16484855, 4714547, -9600655 } + }, + { + { 15200332, 8368572, 19679101, 15970074, -31872674, 1959451, 24611599, -4543832, -11745876, 12340220 }, + { 12876937, -10480056, 33134381, 6590940, -6307776, 14872440, 9613953, 8241152, 15370987, 9608631 }, + { -4143277, -12014408, 8446281, -391603, 4407738, 13629032, -7724868, 15866074, -28210621, -8814099 } + }, + { + { 26660628, -15677655, 8393734, 358047, -7401291, 992988, -23904233, 858697, 20571223, 8420556 }, + { 14620715, 13067227, -15447274, 8264467, 14106269, 15080814, 33531827, 12516406, -21574435, -12476749 }, + { 236881, 10476226, 57258, -14677024, 6472998, 2466984, 17258519, 7256740, 8791136, 15069930 } + }, + { + { 1276410, -9371918, 22949635, -16322807, -23493039, -5702186, 14711875, 4874229, -30663140, -2331391 }, + { 5855666, 4990204, -13711848, 7294284, -7804282, 1924647, -1423175, -7912378, -33069337, 9234253 }, + { 20590503, -9018988, 31529744, -7352666, -2706834, 10650548, 31559055, -11609587, 18979186, 13396066 } + }, + { + { 24474287, 4968103, 22267082, 4407354, 24063882, -8325180, -18816887, 13594782, 33514650, 7021958 }, + { -11566906, -6565505, -21365085, 15928892, -26158305, 4315421, -25948728, -3916677, -21480480, 12868082 }, + { -28635013, 13504661, 19988037, -2132761, 21078225, 6443208, -21446107, 2244500, -12455797, -8089383 } + }, + { + { -30595528, 13793479, -5852820, 319136, -25723172, -6263899, 33086546, 8957937, -15233648, 5540521 }, + { -11630176, -11503902, -8119500, -7643073, 2620056, 1022908, -23710744, -1568984, -16128528, -14962807 }, + { 23152971, 775386, 27395463, 14006635, -9701118, 4649512, 1689819, 892185, -11513277, -15205948 } + }, + { + { 9770129, 9586738, 26496094, 4324120, 1556511, -3550024, 27453819, 4763127, -19179614, 5867134 }, + { -32765025, 1927590, 31726409, -4753295, 23962434, -16019500, 27846559, 5931263, -29749703, -16108455 }, + { 27461885, -2977536, 22380810, 1815854, -23033753, -3031938, 7283490, -15148073, -19526700, 7734629 } + } +}, +{ /* 4/31 */ + { + { -8010264, -9590817, -11120403, 6196038, 29344158, -13430885, 7585295, -3176626, 18549497, 15302069 }, + { -32658337, -6171222, -7672793, -11051681, 6258878, 13504381, 10458790, -6418461, -8872242, 8424746 }, + { 24687205, 8613276, -30667046, -3233545, 1863892, -1830544, 19206234, 7134917, -11284482, -828919 } + }, + { + { 11334899, -9218022, 8025293, 12707519, 17523892, -10476071, 10243738, -14685461, -5066034, 16498837 }, + { 8911542, 6887158, -9584260, -6958590, 11145641, -9543680, 17303925, -14124238, 6536641, 10543906 }, + { -28946384, 15479763, -17466835, 568876, -1497683, 11223454, -2669190, -16625574, -27235709, 8876771 } + }, + { + { -25742899, -12566864, -15649966, -846607, -33026686, -796288, -33481822, 15824474, -604426, -9039817 }, + { 10330056, 70051, 7957388, -9002667, 9764902, 15609756, 27698697, -4890037, 1657394, 3084098 }, + { 10477963, -7470260, 12119566, -13250805, 29016247, -5365589, 31280319, 14396151, -30233575, 15272409 } + }, + { + { -12288309, 3169463, 28813183, 16658753, 25116432, -5630466, -25173957, -12636138, -25014757, 1950504 }, + { -26180358, 9489187, 11053416, -14746161, -31053720, 5825630, -8384306, -8767532, 15341279, 8373727 }, + { 28685821, 7759505, -14378516, -12002860, -31971820, 4079242, 298136, -10232602, -2878207, 15190420 } + }, + { + { -32932876, 13806336, -14337485, -15794431, -24004620, 10940928, 8669718, 2742393, -26033313, -6875003 }, + { -1580388, -11729417, -25979658, -11445023, -17411874, -10912854, 9291594, -16247779, -12154742, 6048605 }, + { -30305315, 14843444, 1539301, 11864366, 20201677, 1900163, 13934231, 5128323, 11213262, 9168384 } + }, + { + { -26280513, 11007847, 19408960, -940758, -18592965, -4328580, -5088060, -11105150, 20470157, -16398701 }, + { -23136053, 9282192, 14855179, -15390078, -7362815, -14408560, -22783952, 14461608, 14042978, 5230683 }, + { 29969567, -2741594, -16711867, -8552442, 9175486, -2468974, 21556951, 3506042, -5933891, -12449708 } + }, + { + { -3144746, 8744661, 19704003, 4581278, -20430686, 6830683, -21284170, 8971513, -28539189, 15326563 }, + { -19464629, 10110288, -17262528, -3503892, -23500387, 1355669, -15523050, 15300988, -20514118, 9168260 }, + { -5353335, 4488613, -23803248, 16314347, 7780487, -15638939, -28948358, 9601605, 33087103, -9011387 } + }, + { + { -19443170, -15512900, -20797467, -12445323, -29824447, 10229461, -27444329, -15000531, -5996870, 15664672 }, + { 23294591, -16632613, -22650781, -8470978, 27844204, 11461195, 13099750, -2460356, 18151676, 13417686 }, + { -24722913, -4176517, -31150679, 5988919, -26858785, 6685065, 1661597, -12551441, 15271676, -15452665 } + } +}, +{ /* 5/31 */ + { + { 11433042, -13228665, 8239631, -5279517, -1985436, -725718, -18698764, 2167544, -6921301, -13440182 }, + { -31436171, 15575146, 30436815, 12192228, -22463353, 9395379, -9917708, -8638997, 12215110, 12028277 }, + { 14098400, 6555944, 23007258, 5757252, -15427832, -12950502, 30123440, 4617780, -16900089, -655628 } + }, + { + { -4026201, -15240835, 11893168, 13718664, -14809462, 1847385, -15819999, 10154009, 23973261, -12684474 }, + { -26531820, -3695990, -1908898, 2534301, -31870557, -16550355, 18341390, -11419951, 32013174, -10103539 }, + { -25479301, 10876443, -11771086, -14625140, -12369567, 1838104, 21911214, 6354752, 4425632, -837822 } + }, + { + { -10433389, -14612966, 22229858, -3091047, -13191166, 776729, -17415375, -12020462, 4725005, 14044970 }, + { 19268650, -7304421, 1555349, 8692754, -21474059, -9910664, 6347390, -1411784, -19522291, -16109756 }, + { -24864089, 12986008, -10898878, -5558584, -11312371, -148526, 19541418, 8180106, 9282262, 10282508 } + }, + { + { -26205082, 4428547, -8661196, -13194263, 4098402, -14165257, 15522535, 8372215, 5542595, -10702683 }, + { -10562541, 14895633, 26814552, -16673850, -17480754, -2489360, -2781891, 6993761, -18093885, 10114655 }, + { -20107055, -929418, 31422704, 10427861, -7110749, 6150669, -29091755, -11529146, 25953725, -106158 } + }, + { + { -4234397, -8039292, -9119125, 3046000, 2101609, -12607294, 19390020, 6094296, -3315279, 12831125 }, + { -15998678, 7578152, 5310217, 14408357, -33548620, -224739, 31575954, 6326196, 7381791, -2421839 }, + { -20902779, 3296811, 24736065, -16328389, 18374254, 7318640, 6295303, 8082724, -15362489, 12339664 } + }, + { + { 27724736, 2291157, 6088201, -14184798, 1792727, 5857634, 13848414, 15768922, 25091167, 14856294 }, + { -18866652, 8331043, 24373479, 8541013, -701998, -9269457, 12927300, -12695493, -22182473, -9012899 }, + { -11423429, -5421590, 11632845, 3405020, 30536730, -11674039, -27260765, 13866390, 30146206, 9142070 } + }, + { + { 3924129, -15307516, -13817122, -10054960, 12291820, -668366, -27702774, 9326384, -8237858, 4171294 }, + { -15921940, 16037937, 6713787, 16606682, -21612135, 2790944, 26396185, 3731949, 345228, -5462949 }, + { -21327538, 13448259, 25284571, 1143661, 20614966, -8849387, 2031539, -12391231, -16253183, -13582083 } + }, + { + { 31016211, -16722429, 26371392, -14451233, -5027349, 14854137, 17477601, 3842657, 28012650, -16405420 }, + { -5075835, 9368966, -8562079, -4600902, -15249953, 6970560, -9189873, 16292057, -8867157, 3507940 }, + { 29439664, 3537914, 23333589, 6997794, -17555561, -11018068, -15209202, -15051267, -9164929, 6580396 } + } +}, +{ /* 6/31 */ + { + { -12185861, -7679788, 16438269, 10826160, -8696817, -6235611, 17860444, -9273846, -2095802, 9304567 }, + { 20714564, -4336911, 29088195, 7406487, 11426967, -5095705, 14792667, -14608617, 5289421, -477127 }, + { -16665533, -10650790, -6160345, -13305760, 9192020, -1802462, 17271490, 12349094, 26939669, -3752294 } + }, + { + { -12889898, 9373458, 31595848, 16374215, 21471720, 13221525, -27283495, -12348559, -3698806, 117887 }, + { 22263325, -6560050, 3984570, -11174646, -15114008, -566785, 28311253, 5358056, -23319780, 541964 }, + { 16259219, 3261970, 2309254, -15534474, -16885711, -4581916, 24134070, -16705829, -13337066, -13552195 } + }, + { + { 9378160, -13140186, -22845982, -12745264, 28198281, -7244098, -2399684, -717351, 690426, 14876244 }, + { 24977353, -314384, -8223969, -13465086, 28432343, -1176353, -13068804, -12297348, -22380984, 6618999 }, + { -1538174, 11685646, 12944378, 13682314, -24389511, -14413193, 8044829, -13817328, 32239829, -5652762 } + }, + { + { -18603066, 4762990, -926250, 8885304, -28412480, -3187315, 9781647, -10350059, 32779359, 5095274 }, + { -33008130, -5214506, -32264887, -3685216, 9460461, -9327423, -24601656, 14506724, 21639561, -2630236 }, + { -16400943, -13112215, 25239338, 15531969, 3987758, -4499318, -1289502, -6863535, 17874574, 558605 } + }, + { + { -13600129, 10240081, 9171883, 16131053, -20869254, 9599700, 33499487, 5080151, 2085892, 5119761 }, + { -22205145, -2519528, -16381601, 414691, -25019550, 2170430, 30634760, -8363614, -31999993, -5759884 }, + { -6845704, 15791202, 8550074, -1312654, 29928809, -12092256, 27534430, -7192145, -22351378, 12961482 } + }, + { + { -24492060, -9570771, 10368194, 11582341, -23397293, -2245287, 16533930, 8206996, -30194652, -5159638 }, + { -11121496, -3382234, 2307366, 6362031, -135455, 8868177, -16835630, 7031275, 7589640, 8945490 }, + { -32152748, 8917967, 6661220, -11677616, -1192060, -15793393, 7251489, -11182180, 24099109, -14456170 } + }, + { + { 5019558, -7907470, 4244127, -14714356, -26933272, 6453165, -19118182, -13289025, -6231896, -10280736 }, + { 10853594, 10721687, 26480089, 5861829, -22995819, 1972175, -1866647, -10557898, -3363451, -6441124 }, + { -17002408, 5906790, 221599, -6563147, 7828208, -13248918, 24362661, -2008168, -13866408, 7421392 } + }, + { + { 8139927, -6546497, 32257646, -5890546, 30375719, 1886181, -21175108, 15441252, 28826358, -4123029 }, + { 6267086, 9695052, 7709135, -16603597, -32869068, -1886135, 14795160, -7840124, 13746021, -1742048 }, + { 28584902, 7787108, -6732942, -15050729, 22846041, -7571236, -3181936, -363524, 4771362, -8419958 } + } +}, +{ /* 7/31 */ + { + { 24949256, 6376279, -27466481, -8174608, -18646154, -9930606, 33543569, -12141695, 3569627, 11342593 }, + { 26514989, 4740088, 27912651, 3697550, 19331575, -11472339, 6809886, 4608608, 7325975, -14801071 }, + { -11618399, -14554430, -24321212, 7655128, -1369274, 5214312, -27400540, 10258390, -17646694, -8186692 } + }, + { + { 11431204, 15823007, 26570245, 14329124, 18029990, 4796082, -31446179, 15580664, 9280358, -3973687 }, + { -160783, -10326257, -22855316, -4304997, -20861367, -13621002, -32810901, -11181622, -15545091, 4387441 }, + { -20799378, 12194512, 3937617, -5805892, -27154820, 9340370, -24513992, 8548137, 20617071, -7482001 } + }, + { + { -938825, -3930586, -8714311, 16124718, 24603125, -6225393, -13775352, -11875822, 24345683, 10325460 }, + { -19855277, -1568885, -22202708, 8714034, 14007766, 6928528, 16318175, -1010689, 4766743, 3552007 }, + { -21751364, -16730916, 1351763, -803421, -4009670, 3950935, 3217514, 14481909, 10988822, -3994762 } + }, + { + { 15564307, -14311570, 3101243, 5684148, 30446780, -8051356, 12677127, -6505343, -8295852, 13296005 }, + { -9442290, 6624296, -30298964, -11913677, -4670981, -2057379, 31521204, 9614054, -30000824, 12074674 }, + { 4771191, -135239, 14290749, -13089852, 27992298, 14998318, -1413936, -1556716, 29832613, -16391035 } + }, + { + { 7064884, -7541174, -19161962, -5067537, -18891269, -2912736, 25825242, 5293297, -27122660, 13101590 }, + { -2298563, 2439670, -7466610, 1719965, -27267541, -16328445, 32512469, -5317593, -30356070, -4190957 }, + { -30006540, 10162316, -33180176, 3981723, -16482138, -13070044, 14413974, 9515896, 19568978, 9628812 } + }, + { + { 33053803, 199357, 15894591, 1583059, 27380243, -4580435, -17838894, -6106839, -6291786, 3437740 }, + { -18978877, 3884493, 19469877, 12726490, 15913552, 13614290, -22961733, 70104, 7463304, 4176122 }, + { -27124001, 10659917, 11482427, -16070381, 12771467, -6635117, -32719404, -5322751, 24216882, 5944158 } + }, + { + { 8894125, 7450974, -2664149, -9765752, -28080517, -12389115, 19345746, 14680796, 11632993, 5847885 }, + { 26942781, -2315317, 9129564, -4906607, 26024105, 11769399, -11518837, 6367194, -9727230, 4782140 }, + { 19916461, -4828410, -22910704, -11414391, 25606324, -5972441, 33253853, 8220911, 6358847, -1873857 } + }, + { + { 801428, -2081702, 16569428, 11065167, 29875704, 96627, 7908388, -4480480, -13538503, 1387155 }, + { 19646058, 5720633, -11416706, 12814209, 11607948, 12749789, 14147075, 15156355, -21866831, 11835260 }, + { 19299512, 1155910, 28703737, 14890794, 2925026, 7269399, 26121523, 15467869, -26560550, 5052483 } + } +}, +{ /* 8/31 */ + { + { -3017432, 10058206, 1980837, 3964243, 22160966, 12322533, -6431123, -12618185, 12228557, -7003677 }, + { 32944382, 14922211, -22844894, 5188528, 21913450, -8719943, 4001465, 13238564, -6114803, 8653815 }, + { 22865569, -4652735, 27603668, -12545395, 14348958, 8234005, 24808405, 5719875, 28483275, 2841751 } + }, + { + { -16420968, -1113305, -327719, -12107856, 21886282, -15552774, -1887966, -315658, 19932058, -12739203 }, + { -11656086, 10087521, -8864888, -5536143, -19278573, -3055912, 3999228, 13239134, -4777469, -13910208 }, + { 1382174, -11694719, 17266790, 9194690, -13324356, 9720081, 20403944, 11284705, -14013818, 3093230 } + }, + { + { 16650921, -11037932, -1064178, 1570629, -8329746, 7352753, -302424, 16271225, -24049421, -6691850 }, + { -21911077, -5927941, -4611316, -5560156, -31744103, -10785293, 24123614, 15193618, -21652117, -16739389 }, + { -9935934, -4289447, -25279823, 4372842, 2087473, 10399484, 31870908, 14690798, 17361620, 11864968 } + }, + { + { -11307610, 6210372, 13206574, 5806320, -29017692, -13967200, -12331205, -7486601, -25578460, -16240689 }, + { 14668462, -12270235, 26039039, 15305210, 25515617, 4542480, 10453892, 6577524, 9145645, -6443880 }, + { 5974874, 3053895, -9433049, -10385191, -31865124, 3225009, -7972642, 3936128, -5652273, -3050304 } + }, + { + { 30625386, -4729400, -25555961, -12792866, -20484575, 7695099, 17097188, -16303496, -27999779, 1803632 }, + { -3553091, 9865099, -5228566, 4272701, -5673832, -16689700, 14911344, 12196514, -21405489, 7047412 }, + { 20093277, 9920966, -11138194, -5343857, 13161587, 12044805, -32856851, 4124601, -32343828, -10257566 } + }, + { + { -20788824, 14084654, -13531713, 7842147, 19119038, -13822605, 4752377, -8714640, -21679658, 2288038 }, + { -26819236, -3283715, 29965059, 3039786, -14473765, 2540457, 29457502, 14625692, -24819617, 12570232 }, + { -1063558, -11551823, 16920318, 12494842, 1278292, -5869109, -21159943, -3498680, -11974704, 4724943 } + }, + { + { 17960970, -11775534, -4140968, -9702530, -8876562, -1410617, -12907383, -8659932, -29576300, 1903856 }, + { 23134274, -14279132, -10681997, -1611936, 20684485, 15770816, -12989750, 3190296, 26955097, 14109738 }, + { 15308788, 5320727, -30113809, -14318877, 22902008, 7767164, 29425325, -11277562, 31960942, 11934971 } + }, + { + { -27395711, 8435796, 4109644, 12222639, -24627868, 14818669, 20638173, 4875028, 10491392, 1379718 }, + { -13159415, 9197841, 3875503, -8936108, -1383712, -5879801, 33518459, 16176658, 21432314, 12180697 }, + { -11787308, 11500838, 13787581, -13832590, -22430679, 10140205, 1465425, 12689540, -10301319, -13872883 } + } +}, +{ /* 9/31 */ + { + { 5414091, -15386041, -21007664, 9643570, 12834970, 1186149, -2622916, -1342231, 26128231, 6032912 }, + { -26337395, -13766162, 32496025, -13653919, 17847801, -12669156, 3604025, 8316894, -25875034, -10437358 }, + { 3296484, 6223048, 24680646, -12246460, -23052020, 5903205, -8862297, -4639164, 12376617, 3188849 } + }, + { + { 29190488, -14659046, 27549113, -1183516, 3520066, -10697301, 32049515, -7309113, -16109234, -9852307 }, + { -14744486, -9309156, 735818, -598978, -20407687, -5057904, 25246078, -15795669, 18640741, -960977 }, + { -6928835, -16430795, 10361374, 5642961, 4910474, 12345252, -31638386, -494430, 10530747, 1053335 } + }, + { + { -29265967, -14186805, -13538216, -12117373, -19457059, -10655384, -31462369, -2948985, 24018831, 15026644 }, + { -22592535, -3145277, -2289276, 5953843, -13440189, 9425631, 25310643, 13003497, -2314791, -15145616 }, + { -27419985, -603321, -8043984, -1669117, -26092265, 13987819, -27297622, 187899, -23166419, -2531735 } + }, + { + { -21744398, -13810475, 1844840, 5021428, -10434399, -15911473, 9716667, 16266922, -5070217, 726099 }, + { 29370922, -6053998, 7334071, -15342259, 9385287, 2247707, -13661962, -4839461, 30007388, -15823341 }, + { -936379, 16086691, 23751945, -543318, -1167538, -5189036, 9137109, 730663, 9835848, 4555336 } + }, + { + { -23376435, 1410446, -22253753, -12899614, 30867635, 15826977, 17693930, 544696, -11985298, 12422646 }, + { 31117226, -12215734, -13502838, 6561947, -9876867, -12757670, -5118685, -4096706, 29120153, 13924425 }, + { -17400879, -14233209, 19675799, -2734756, -11006962, -5858820, -9383939, -11317700, 7240931, -237388 } + }, + { + { -31361739, -11346780, -15007447, -5856218, -22453340, -12152771, 1222336, 4389483, 3293637, -15551743 }, + { -16684801, -14444245, 11038544, 11054958, -13801175, -3338533, -24319580, 7733547, 12796905, -6335822 }, + { -8759414, -10817836, -25418864, 10783769, -30615557, -9746811, -28253339, 3647836, 3222231, -11160462 } + }, + { + { 18606113, 1693100, -25448386, -15170272, 4112353, 10045021, 23603893, -2048234, -7550776, 2484985 }, + { 9255317, -3131197, -12156162, -1004256, 13098013, -9214866, 16377220, -2102812, -19802075, -3034702 }, + { -22729289, 7496160, -5742199, 11329249, 19991973, -3347502, -31718148, 9936966, -30097688, -10618797 } + }, + { + { 21878590, -5001297, 4338336, 13643897, -3036865, 13160960, 19708896, 5415497, -7360503, -4109293 }, + { 27736861, 10103576, 12500508, 8502413, -3413016, -9633558, 10436918, -1550276, -23659143, -8132100 }, + { 19492550, -12104365, -29681976, -852630, -3208171, 12403437, 30066266, 8367329, 13243957, 8709688 } + } +}, +{ /* 10/31 */ + { + { 12015105, 2801261, 28198131, 10151021, 24818120, -4743133, -11194191, -5645734, 5150968, 7274186 }, + { 2831366, -12492146, 1478975, 6122054, 23825128, -12733586, 31097299, 6083058, 31021603, -9793610 }, + { -2529932, -2229646, 445613, 10720828, -13849527, -11505937, -23507731, 16354465, 15067285, -14147707 } + }, + { + { 7840942, 14037873, -33364863, 15934016, -728213, -3642706, 21403988, 1057586, -19379462, -12403220 }, + { 915865, -16469274, 15608285, -8789130, -24357026, 6060030, -17371319, 8410997, -7220461, 16527025 }, + { 32922597, -556987, 20336074, -16184568, 10903705, -5384487, 16957574, 52992, 23834301, 6588044 } + }, + { + { 32752030, 11232950, 3381995, -8714866, 22652988, -10744103, 17159699, 16689107, -20314580, -1305992 }, + { -4689649, 9166776, -25710296, -10847306, 11576752, 12733943, 7924251, -2752281, 1976123, -7249027 }, + { 21251222, 16309901, -2983015, -6783122, 30810597, 12967303, 156041, -3371252, 12331345, -8237197 } + }, + { + { 8651614, -4477032, -16085636, -4996994, 13002507, 2950805, 29054427, -5106970, 10008136, -4667901 }, + { 31486080, 15114593, -14261250, 12951354, 14369431, -7387845, 16347321, -13662089, 8684155, -10532952 }, + { 19443825, 11385320, 24468943, -9659068, -23919258, 2187569, -26263207, -6086921, 31316348, 14219878 } + }, + { + { -28594490, 1193785, 32245219, 11392485, 31092169, 15722801, 27146014, 6992409, 29126555, 9207390 }, + { 32382935, 1110093, 18477781, 11028262, -27411763, -7548111, -4980517, 10843782, -7957600, -14435730 }, + { 2814918, 7836403, 27519878, -7868156, -20894015, -11553689, -21494559, 8550130, 28346258, 1994730 } + }, + { + { -19578299, 8085545, -14000519, -3948622, 2785838, -16231307, -19516951, 7174894, 22628102, 8115180 }, + { -30405132, 955511, -11133838, -15078069, -32447087, -13278079, -25651578, 3317160, -9943017, 930272 }, + { -15303681, -6833769, 28856490, 1357446, 23421993, 1057177, 24091212, -1388970, -22765376, -10650715 } + }, + { + { -22751231, -5303997, -12907607, -12768866, -15811511, -7797053, -14839018, -16554220, -1867018, 8398970 }, + { -31969310, 2106403, -4736360, 1362501, 12813763, 16200670, 22981545, -6291273, 18009408, -15772772 }, + { -17220923, -9545221, -27784654, 14166835, 29815394, 7444469, 29551787, -3727419, 19288549, 1325865 } + }, + { + { 15100157, -15835752, -23923978, -1005098, -26450192, 15509408, 12376730, -3479146, 33166107, -8042750 }, + { 20909231, 13023121, -9209752, 16251778, -5778415, -8094914, 12412151, 10018715, 2213263, -13878373 }, + { 32529814, -11074689, 30361439, -16689753, -9135940, 1513226, 22922121, 6382134, -5766928, 8371348 } + } +}, +{ /* 11/31 */ + { + { 9923462, 11271500, 12616794, 3544722, -29998368, -1721626, 12891687, -8193132, -26442943, 10486144 }, + { -22597207, -7012665, 8587003, -8257861, 4084309, -12970062, 361726, 2610596, -23921530, -11455195 }, + { 5408411, -1136691, -4969122, 10561668, 24145918, 14240566, 31319731, -4235541, 19985175, -3436086 } + }, + { + { -13994457, 16616821, 14549246, 3341099, 32155958, 13648976, -17577068, 8849297, 65030, 8370684 }, + { -8320926, -12049626, 31204563, 5839400, -20627288, -1057277, -19442942, 6922164, 12743482, -9800518 }, + { -2361371, 12678785, 28815050, 4759974, -23893047, 4884717, 23783145, 11038569, 18800704, 255233 } + }, + { + { -5269658, -1773886, 13957886, 7990715, 23132995, 728773, 13393847, 9066957, 19258688, -14753793 }, + { -2936654, -10827535, -10432089, 14516793, -3640786, 4372541, -31934921, 2209390, -1524053, 2055794 }, + { 580882, 16705327, 5468415, -2683018, -30926419, -14696000, -7203346, -8994389, -30021019, 7394435 } + }, + { + { 23838809, 1822728, -15738443, 15242727, 8318092, -3733104, -21672180, -3492205, -4821741, 14799921 }, + { 13345610, 9759151, 3371034, -16137791, 16353039, 8577942, 31129804, 13496856, -9056018, 7402518 }, + { 2286874, -4435931, -20042458, -2008336, -13696227, 5038122, 11006906, -15760352, 8205061, 1607563 } + }, + { + { 14414086, -8002132, 3331830, -3208217, 22249151, -5594188, 18364661, -2906958, 30019587, -9029278 }, + { -27688051, 1585953, -10775053, 931069, -29120221, -11002319, -14410829, 12029093, 9944378, 8024 }, + { 4368715, -3709630, 29874200, -15022983, -20230386, -11410704, -16114594, -999085, -8142388, 5640030 } + }, + { + { 10299610, 13746483, 11661824, 16234854, 7630238, 5998374, 9809887, -16694564, 15219798, -14327783 }, + { 27425505, -5719081, 3055006, 10660664, 23458024, 595578, -15398605, -1173195, -18342183, 9742717 }, + { 6744077, 2427284, 26042789, 2720740, -847906, 1118974, 32324614, 7406442, 12420155, 1994844 } + }, + { + { 14012521, -5024720, -18384453, -9578469, -26485342, -3936439, -13033478, -10909803, 24319929, -6446333 }, + { 16412690, -4507367, 10772641, 15929391, -17068788, -4658621, 10555945, -10484049, -30102368, -4739048 }, + { 22397382, -7767684, -9293161, -12792868, 17166287, -9755136, -27333065, 6199366, 21880021, -12250760 } + }, + { + { -4283307, 5368523, -31117018, 8163389, -30323063, 3209128, 16557151, 8890729, 8840445, 4957760 }, + { -15447727, 709327, -6919446, -10870178, -29777922, 6522332, -21720181, 12130072, -14796503, 5005757 }, + { -2114751, -14308128, 23019042, 15765735, -25269683, 6002752, 10183197, -13239326, -16395286, -2176112 } + } +}, +{ /* 12/31 */ + { + { -19025756, 1632005, 13466291, -7995100, -23640451, 16573537, -32013908, -3057104, 22208662, 2000468 }, + { 3065073, -1412761, -25598674, -361432, -17683065, -5703415, -8164212, 11248527, -3691214, -7414184 }, + { 10379208, -6045554, 8877319, 1473647, -29291284, -12507580, 16690915, 2553332, -3132688, 16400289 } + }, + { + { 15716668, 1254266, -18472690, 7446274, -8448918, 6344164, -22097271, -7285580, 26894937, 9132066 }, + { 24158887, 12938817, 11085297, -8177598, -28063478, -4457083, -30576463, 64452, -6817084, -2692882 }, + { 13488534, 7794716, 22236231, 5989356, 25426474, -12578208, 2350710, -3418511, -4688006, 2364226 } + }, + { + { 16335052, 9132434, 25640582, 6678888, 1725628, 8517937, -11807024, -11697457, 15445875, -7798101 }, + { 29004207, -7867081, 28661402, -640412, -12794003, -7943086, 31863255, -4135540, -278050, -15759279 }, + { -6122061, -14866665, -28614905, 14569919, -10857999, -3591829, 10343412, -6976290, -29828287, -10815811 } + }, + { + { 27081650, 3463984, 14099042, -4517604, 1616303, -6205604, 29542636, 15372179, 17293797, 960709 }, + { 20263915, 11434237, -5765435, 11236810, 13505955, -10857102, -16111345, 6493122, -19384511, 7639714 }, + { -2830798, -14839232, 25403038, -8215196, -8317012, -16173699, 18006287, -16043750, 29994677, -15808121 } + }, + { + { 9769828, 5202651, -24157398, -13631392, -28051003, -11561624, -24613141, -13860782, -31184575, 709464 }, + { 12286395, 13076066, -21775189, -1176622, -25003198, 4057652, -32018128, -8890874, 16102007, 13205847 }, + { 13733362, 5599946, 10557076, 3195751, -5557991, 8536970, -25540170, 8525972, 10151379, 10394400 } + }, + { + { 4024660, -16137551, 22436262, 12276534, -9099015, -2686099, 19698229, 11743039, -33302334, 8934414 }, + { -15879800, -4525240, -8580747, -2934061, 14634845, -698278, -9449077, 3137094, -11536886, 11721158 }, + { 17555939, -5013938, 8268606, 2331751, -22738815, 9761013, 9319229, 8835153, -9205489, -1280045 } + }, + { + { -461409, -7830014, 20614118, 16688288, -7514766, -4807119, 22300304, 505429, 6108462, -6183415 }, + { -5070281, 12367917, -30663534, 3234473, 32617080, -8422642, 29880583, -13483331, -26898490, -7867459 }, + { -31975283, 5726539, 26934134, 10237677, -3173717, -605053, 24199304, 3795095, 7592688, -14992079 } + }, + { + { 21594432, -14964228, 17466408, -4077222, 32537084, 2739898, 6407723, 12018833, -28256052, 4298412 }, + { -20650503, -11961496, -27236275, 570498, 3767144, -1717540, 13891942, -1569194, 13717174, 10805743 }, + { -14676630, -15644296, 15287174, 11927123, 24177847, -8175568, -796431, 14860609, -26938930, -5863836 } + } +}, +{ /* 13/31 */ + { + { 12962541, 5311799, -10060768, 11658280, 18855286, -7954201, 13286263, -12808704, -4381056, 9882022 }, + { 18512079, 11319350, -20123124, 15090309, 18818594, 5271736, -22727904, 3666879, -23967430, -3299429 }, + { -6789020, -3146043, 16192429, 13241070, 15898607, -14206114, -10084880, -6661110, -2403099, 5276065 } + }, + { + { 30169808, -5317648, 26306206, -11750859, 27814964, 7069267, 7152851, 3684982, 1449224, 13082861 }, + { 10342826, 3098505, 2119311, 193222, 25702612, 12233820, 23697382, 15056736, -21016438, -8202000 }, + { -33150110, 3261608, 22745853, 7948688, 19370557, -15177665, -26171976, 6482814, -10300080, -11060101 } + }, + { + { 32869458, -5408545, 25609743, 15678670, -10687769, -15471071, 26112421, 2521008, -22664288, 6904815 }, + { 29506923, 4457497, 3377935, -9796444, -30510046, 12935080, 1561737, 3841096, -29003639, -6657642 }, + { 10340844, -6630377, -18656632, -2278430, 12621151, -13339055, 30878497, -11824370, -25584551, 5181966 } + }, + { + { 25940115, -12658025, 17324188, -10307374, -8671468, 15029094, 24396252, -16450922, -2322852, -12388574 }, + { -21765684, 9916823, -1300409, 4079498, -1028346, 11909559, 1782390, 12641087, 20603771, -6561742 }, + { -18882287, -11673380, 24849422, 11501709, 13161720, -4768874, 1925523, 11914390, 4662781, 7820689 } + }, + { + { 12241050, -425982, 8132691, 9393934, 32846760, -1599620, 29749456, 12172924, 16136752, 15264020 }, + { -10349955, -14680563, -8211979, 2330220, -17662549, -14545780, 10658213, 6671822, 19012087, 3772772 }, + { 3753511, -3421066, 10617074, 2028709, 14841030, -6721664, 28718732, -15762884, 20527771, 12988982 } + }, + { + { -14822485, -5797269, -3707987, 12689773, -898983, -10914866, -24183046, -10564943, 3299665, -12424953 }, + { -16777703, -15253301, -9642417, 4978983, 3308785, 8755439, 6943197, 6461331, -25583147, 8991218 }, + { -17226263, 1816362, -1673288, -6086439, 31783888, -8175991, -32948145, 7417950, -30242287, 1507265 } + }, + { + { 29692663, 6829891, -10498800, 4334896, 20945975, -11906496, -28887608, 8209391, 14606362, -10647073 }, + { -3481570, 8707081, 32188102, 5672294, 22096700, 1711240, -33020695, 9761487, 4170404, -2085325 }, + { -11587470, 14855945, -4127778, -1531857, -26649089, 15084046, 22186522, 16002000, -14276837, -8400798 } + }, + { + { -4811456, 13761029, -31703877, -2483919, -3312471, 7869047, -7113572, -9620092, 13240845, 10965870 }, + { -7742563, -8256762, -14768334, -13656260, -23232383, 12387166, 4498947, 14147411, 29514390, 4302863 }, + { -13413405, -12407859, 20757302, -13801832, 14785143, 8976368, -5061276, -2144373, 17846988, -13971927 } + } +}, +{ /* 14/31 */ + { + { -2244452, -754728, -4597030, -1066309, -6247172, 1455299, -21647728, -9214789, -5222701, 12650267 }, + { -9906797, -16070310, 21134160, 12198166, -27064575, 708126, 387813, 13770293, -19134326, 10958663 }, + { 22470984, 12369526, 23446014, -5441109, -21520802, -9698723, -11772496, -11574455, -25083830, 4271862 } + }, + { + { -25169565, -10053642, -19909332, 15361595, -5984358, 2159192, 75375, -4278529, -32526221, 8469673 }, + { 15854970, 4148314, -8893890, 7259002, 11666551, 13824734, -30531198, 2697372, 24154791, -9460943 }, + { 15446137, -15806644, 29759747, 14019369, 30811221, -9610191, -31582008, 12840104, 24913809, 9815020 } + }, + { + { -4709286, -5614269, -31841498, -12288893, -14443537, 10799414, -9103676, 13438769, 18735128, 9466238 }, + { 11933045, 9281483, 5081055, -5183824, -2628162, -4905629, -7727821, -10896103, -22728655, 16199064 }, + { 14576810, 379472, -26786533, -8317236, -29426508, -10812974, -102766, 1876699, 30801119, 2164795 } + }, + { + { 15995086, 3199873, 13672555, 13712240, -19378835, -4647646, -13081610, -15496269, -13492807, 1268052 }, + { -10290614, -3659039, -3286592, 10948818, 23037027, 3794475, -3470338, -12600221, -17055369, 3565904 }, + { 29210088, -9419337, -5919792, -4952785, 10834811, -13327726, -16512102, -10820713, -27162222, -14030531 } + }, + { + { -13161890, 15508588, 16663704, -8156150, -28349942, 9019123, -29183421, -3769423, 2244111, -14001979 }, + { -5152875, -3800936, -9306475, -6071583, 16243069, 14684434, -25673088, -16180800, 13491506, 4641841 }, + { 10813417, 643330, -19188515, -728916, 30292062, -16600078, 27548447, -7721242, 14476989, -12767431 } + }, + { + { 10292079, 9984945, 6481436, 8279905, -7251514, 7032743, 27282937, -1644259, -27912810, 12651324 }, + { -31185513, -813383, 22271204, 11835308, 10201545, 15351028, 17099662, 3988035, 21721536, -3148940 }, + { 10202177, -6545839, -31373232, -9574638, -32150642, -8119683, -12906320, 3852694, 13216206, 14842320 } + }, + { + { -15815640, -10601066, -6538952, -7258995, -6984659, -6581778, -31500847, 13765824, -27434397, 9900184 }, + { 14465505, -13833331, -32133984, -14738873, -27443187, 12990492, 33046193, 15796406, -7051866, -8040114 }, + { 30924417, -8279620, 6359016, -12816335, 16508377, 9071735, -25488601, 15413635, 9524356, -7018878 } + }, + { + { 12274201, -13175547, 32627641, -1785326, 6736625, 13267305, 5237659, -5109483, 15663516, 4035784 }, + { -2951309, 8903985, 17349946, 601635, -16432815, -4612556, -13732739, -15889334, -22258478, 4659091 }, + { -16916263, -4952973, -30393711, -15158821, 20774812, 15897498, 5736189, 15026997, -2178256, -13455585 } + } +}, +{ /* 15/31 */ + { + { -8858980, -2219056, 28571666, -10155518, -474467, -10105698, -3801496, 278095, 23440562, -290208 }, + { 10226241, -5928702, 15139956, 120818, -14867693, 5218603, 32937275, 11551483, -16571960, -7442864 }, + { 17932739, -12437276, -24039557, 10749060, 11316803, 7535897, 22503767, 5561594, -3646624, 3898661 } + }, + { + { 7749907, -969567, -16339731, -16464, -25018111, 15122143, -1573531, 7152530, 21831162, 1245233 }, + { 26958459, -14658026, 4314586, 8346991, -5677764, 11960072, -32589295, -620035, -30402091, -16716212 }, + { -12165896, 9166947, 33491384, 13673479, 29787085, 13096535, 6280834, 14587357, -22338025, 13987525 } + }, + { + { -24349909, 7778775, 21116000, 15572597, -4833266, -5357778, -4300898, -5124639, -7469781, -2858068 }, + { 9681908, -6737123, -31951644, 13591838, -6883821, 386950, 31622781, 6439245, -14581012, 4091397 }, + { -8426427, 1470727, -28109679, -1596990, 3978627, -5123623, -19622683, 12092163, 29077877, -14741988 } + }, + { + { 5269168, -6859726, -13230211, -8020715, 25932563, 1763552, -5606110, -5505881, -20017847, 2357889 }, + { 32264008, -15407652, -5387735, -1160093, -2091322, -3946900, 23104804, -12869908, 5727338, 189038 }, + { 14609123, -8954470, -6000566, -16622781, -14577387, -7743898, -26745169, 10942115, -25888931, -14884697 } + }, + { + { 20513500, 5557931, -15604613, 7829531, 26413943, -2019404, -21378968, 7471781, 13913677, -5137875 }, + { -25574376, 11967826, 29233242, 12948236, -6754465, 4713227, -8940970, 14059180, 12878652, 8511905 }, + { -25656801, 3393631, -2955415, -7075526, -2250709, 9366908, -30223418, 6812974, 5568676, -3127656 } + }, + { + { 11630004, 12144454, 2116339, 13606037, 27378885, 15676917, -17408753, -13504373, -14395196, 8070818 }, + { 27117696, -10007378, -31282771, -5570088, 1127282, 12772488, -29845906, 10483306, -11552749, -1028714 }, + { 10637467, -5688064, 5674781, 1072708, -26343588, -6982302, -1683975, 9177853, -27493162, 15431203 } + }, + { + { 20525145, 10892566, -12742472, 12779443, -29493034, 16150075, -28240519, 14943142, -15056790, -7935931 }, + { -30024462, 5626926, -551567, -9981087, 753598, 11981191, 25244767, -3239766, -3356550, 9594024 }, + { -23752644, 2636870, -5163910, -10103818, 585134, 7877383, 11345683, -6492290, 13352335, -10977084 } + }, + { + { -1931799, -5407458, 3304649, -12884869, 17015806, -4877091, -29783850, -7752482, -13215537, -319204 }, + { 20239939, 6607058, 6203985, 3483793, -18386976, -779229, -20723742, 15077870, -22750759, 14523817 }, + { 27406042, -6041657, 27423596, -4497394, 4996214, 10002360, -28842031, -4545494, -30172742, -4805667 } + } +}, +{ /* 16/31 */ + { + { 11374242, 12660715, 17861383, -12540833, 10935568, 1099227, -13886076, -9091740, -27727044, 11358504 }, + { -12730809, 10311867, 1510375, 10778093, -2119455, -9145702, 32676003, 11149336, -26123651, 4985768 }, + { -19096303, 341147, -6197485, -239033, 15756973, -8796662, -983043, 13794114, -19414307, -15621255 } + }, + { + { 6490081, 11940286, 25495923, -7726360, 8668373, -8751316, 3367603, 6970005, -1691065, -9004790 }, + { 1656497, 13457317, 15370807, 6364910, 13605745, 8362338, -19174622, -5475723, -16796596, -5031438 }, + { -22273315, -13524424, -64685, -4334223, -18605636, -10921968, -20571065, -7007978, -99853, -10237333 } + }, + { + { 17747465, 10039260, 19368299, -4050591, -20630635, -16041286, 31992683, -15857976, -29260363, -5511971 }, + { 31932027, -4986141, -19612382, 16366580, 22023614, 88450, 11371999, -3744247, 4882242, -10626905 }, + { 29796507, 37186, 19818052, 10115756, -11829032, 3352736, 18551198, 3272828, -5190932, -4162409 } + }, + { + { 12501286, 4044383, -8612957, -13392385, -32430052, 5136599, -19230378, -3529697, 330070, -3659409 }, + { 6384877, 2899513, 17807477, 7663917, -2358888, 12363165, 25366522, -8573892, -271295, 12071499 }, + { -8365515, -4042521, 25133448, -4517355, -6211027, 2265927, -32769618, 1936675, -5159697, 3829363 } + }, + { + { 28425966, -5835433, -577090, -4697198, -14217555, 6870930, 7921550, -6567787, 26333140, 14267664 }, + { -11067219, 11871231, 27385719, -10559544, -4585914, -11189312, 10004786, -8709488, -21761224, 8930324 }, + { -21197785, -16396035, 25654216, -1725397, 12282012, 11008919, 1541940, 4757911, -26491501, -16408940 } + }, + { + { 13537262, -7759490, -20604840, 10961927, -5922820, -13218065, -13156584, 6217254, -15943699, 13814990 }, + { -17422573, 15157790, 18705543, 29619, 24409717, -260476, 27361681, 9257833, -1956526, -1776914 }, + { -25045300, -10191966, 15366585, 15166509, -13105086, 8423556, -29171540, 12361135, -18685978, 4578290 } + }, + { + { 24579768, 3711570, 1342322, -11180126, -27005135, 14124956, -22544529, 14074919, 21964432, 8235257 }, + { -6528613, -2411497, 9442966, -5925588, 12025640, -1487420, -2981514, -1669206, 13006806, 2355433 }, + { -16304899, -13605259, -6632427, -5142349, 16974359, -10911083, 27202044, 1719366, 1141648, -12796236 } + }, + { + { -12863944, -13219986, -8318266, -11018091, -6810145, -4843894, 13475066, -3133972, 32674895, 13715045 }, + { 11423335, -5468059, 32344216, 8962751, 24989809, 9241752, -13265253, 16086212, -28740881, -15642093 }, + { -1409668, 12530728, -6368726, 10847387, 19531186, -14132160, -11709148, 7791794, -27245943, 4383347 } + } +}, +{ /* 17/31 */ + { + { -28970898, 5271447, -1266009, -9736989, -12455236, 16732599, -4862407, -4906449, 27193557, 6245191 }, + { -15193956, 5362278, -1783893, 2695834, 4960227, 12840725, 23061898, 3260492, 22510453, 8577507 }, + { -12632451, 11257346, -32692994, 13548177, -721004, 10879011, 31168030, 13952092, -29571492, -3635906 } + }, + { + { 3877321, -9572739, 32416692, 5405324, -11004407, -13656635, 3759769, 11935320, 5611860, 8164018 }, + { -16275802, 14667797, 15906460, 12155291, -22111149, -9039718, 32003002, -8832289, 5773085, -8422109 }, + { -23788118, -8254300, 1950875, 8937633, 18686727, 16459170, -905725, 12376320, 31632953, 190926 } + }, + { + { -24593607, -16138885, -8423991, 13378746, 14162407, 6901328, -8288749, 4508564, -25341555, -3627528 }, + { 8884438, -5884009, 6023974, 10104341, -6881569, -4941533, 18722941, -14786005, -1672488, 827625 }, + { -32720583, -16289296, -32503547, 7101210, 13354605, 2659080, -1800575, -14108036, -24878478, 1541286 } + }, + { + { 2901347, -1117687, 3880376, -10059388, -17620940, -3612781, -21802117, -3567481, 20456845, -1885033 }, + { 27019610, 12299467, -13658288, -1603234, -12861660, -4861471, -19540150, -5016058, 29439641, 15138866 }, + { 21536104, -6626420, -32447818, -10690208, -22408077, 5175814, -5420040, -16361163, 7779328, 109896 } + }, + { + { 30279744, 14648750, -8044871, 6425558, 13639621, -743509, 28698390, 12180118, 23177719, -554075 }, + { 26572847, 3405927, -31701700, 12890905, -19265668, 5335866, -6493768, 2378492, 4439158, -13279347 }, + { -22716706, 3489070, -9225266, -332753, 18875722, -1140095, 14819434, -12731527, -17717757, -5461437 } + }, + { + { -5056483, 16566551, 15953661, 3767752, -10436499, 15627060, -820954, 2177225, 8550082, -15114165 }, + { -18473302, 16596775, -381660, 15663611, 22860960, 15585581, -27844109, -3582739, -23260460, -8428588 }, + { -32480551, 15707275, -8205912, -5652081, 29464558, 2713815, -22725137, 15860482, -21902570, 1494193 } + }, + { + { -19562091, -14087393, -25583872, -9299552, 13127842, 759709, 21923482, 16529112, 8742704, 12967017 }, + { -28464899, 1553205, 32536856, -10473729, -24691605, -406174, -8914625, -2933896, -29903758, 15553883 }, + { 21877909, 3230008, 9881174, 10539357, -4797115, 2841332, 11543572, 14513274, 19375923, -12647961 } + }, + { + { 8832269, -14495485, 13253511, 5137575, 5037871, 4078777, 24880818, -6222716, 2862653, 9455043 }, + { 29306751, 5123106, 20245049, -14149889, 9592566, 8447059, -2077124, -2990080, 15511449, 4789663 }, + { -20679756, 7004547, 8824831, -9434977, -4045704, -3750736, -5754762, 108893, 23513200, 16652362 } + } +}, +{ /* 18/31 */ + { + { -33256173, 4144782, -4476029, -6579123, 10770039, -7155542, -6650416, -12936300, -18319198, 10212860 }, + { 2756081, 8598110, 7383731, -6859892, 22312759, -1105012, 21179801, 2600940, -9988298, -12506466 }, + { -24645692, 13317462, -30449259, -15653928, 21365574, -10869657, 11344424, 864440, -2499677, -16710063 } + }, + { + { -26432803, 6148329, -17184412, -14474154, 18782929, -275997, -22561534, 211300, 2719757, 4940997 }, + { -1323882, 3911313, -6948744, 14759765, -30027150, 7851207, 21690126, 8518463, 26699843, 5276295 }, + { -13149873, -6429067, 9396249, 365013, 24703301, -10488939, 1321586, 149635, -15452774, 7159369 } + }, + { + { 9987780, -3404759, 17507962, 9505530, 9731535, -2165514, 22356009, 8312176, 22477218, -8403385 }, + { 18155857, -16504990, 19744716, 9006923, 15154154, -10538976, 24256460, -4864995, -22548173, 9334109 }, + { 2986088, -4911893, 10776628, -3473844, 10620590, -7083203, -21413845, 14253545, -22587149, 536906 } + }, + { + { 4377756, 8115836, 24567078, 15495314, 11625074, 13064599, 7390551, 10589625, 10838060, -15420424 }, + { -19342404, 867880, 9277171, -3218459, -14431572, -1986443, 19295826, -15796950, 6378260, 699185 }, + { 7895026, 4057113, -7081772, -13077756, -17886831, -323126, -716039, 15693155, -5045064, -13373962 } + }, + { + { -7737563, -5869402, -14566319, -7406919, 11385654, 13201616, 31730678, -10962840, -3918636, -9669325 }, + { 10188286, -15770834, -7336361, 13427543, 22223443, 14896287, 30743455, 7116568, -21786507, 5427593 }, + { 696102, 13206899, 27047647, -10632082, 15285305, -9853179, 10798490, -4578720, 19236243, 12477404 } + }, + { + { -11229439, 11243796, -17054270, -8040865, -788228, -8167967, -3897669, 11180504, -23169516, 7733644 }, + { 17800790, -14036179, -27000429, -11766671, 23887827, 3149671, 23466177, -10538171, 10322027, 15313801 }, + { 26246234, 11968874, 32263343, -5468728, 6830755, -13323031, -15794704, -101982, -24449242, 10890804 } + }, + { + { -31365647, 10271363, -12660625, -6267268, 16690207, -13062544, -14982212, 16484931, 25180797, -5334884 }, + { -586574, 10376444, -32586414, -11286356, 19801893, 10997610, 2276632, 9482883, 316878, 13820577 }, + { -9882808, -4510367, -2115506, 16457136, -11100081, 11674996, 30756178, -7515054, 30696930, -3712849 } + }, + { + { 32988917, -9603412, 12499366, 7910787, -10617257, -11931514, -7342816, -9985397, -32349517, 7392473 }, + { -8855661, 15927861, 9866406, -3649411, -2396914, -16655781, -30409476, -9134995, 25112947, -2926644 }, + { -2504044, -436966, 25621774, -5678772, 15085042, -5479877, -24884878, -13526194, 5537438, -13914319 } + } +}, +{ /* 19/31 */ + { + { -11225584, 2320285, -9584280, 10149187, -33444663, 5808648, -14876251, -1729667, 31234590, 6090599 }, + { -9633316, 116426, 26083934, 2897444, -6364437, -2688086, 609721, 15878753, -6970405, -9034768 }, + { -27757857, 247744, -15194774, -9002551, 23288161, -10011936, -23869595, 6503646, 20650474, 1804084 } + }, + { + { -27589786, 15456424, 8972517, 8469608, 15640622, 4439847, 3121995, -10329713, 27842616, -202328 }, + { -15306973, 2839644, 22530074, 10026331, 4602058, 5048462, 28248656, 5031932, -11375082, 12714369 }, + { 20807691, -7270825, 29286141, 11421711, -27876523, -13868230, -21227475, 1035546, -19733229, 12796920 } + }, + { + { 12076899, -14301286, -8785001, -11848922, -25012791, 16400684, -17591495, -12899438, 3480665, -15182815 }, + { -32361549, 5457597, 28548107, 7833186, 7303070, -11953545, -24363064, -15921875, -33374054, 2771025 }, + { -21389266, 421932, 26597266, 6860826, 22486084, -6737172, -17137485, -4210226, -24552282, 15673397 } + }, + { + { -20184622, 2338216, 19788685, -9620956, -4001265, -8740893, -20271184, 4733254, 3727144, -12934448 }, + { 6120119, 814863, -11794402, -622716, 6812205, -15747771, 2019594, 7975683, 31123697, -10958981 }, + { 30069250, -11435332, 30434654, 2958439, 18399564, -976289, 12296869, 9204260, -16432438, 9648165 } + }, + { + { 32705432, -1550977, 30705658, 7451065, -11805606, 9631813, 3305266, 5248604, -26008332, -11377501 }, + { 17219865, 2375039, -31570947, -5575615, -19459679, 9219903, 294711, 15298639, 2662509, -16297073 }, + { -1172927, -7558695, -4366770, -4287744, -21346413, -8434326, 32087529, -1222777, 32247248, -14389861 } + }, + { + { 14312628, 1221556, 17395390, -8700143, -4945741, -8684635, -28197744, -9637817, -16027623, -13378845 }, + { -1428825, -9678990, -9235681, 6549687, -7383069, -468664, 23046502, 9803137, 17597934, 2346211 }, + { 18510800, 15337574, 26171504, 981392, -22241552, 7827556, -23491134, -11323352, 3059833, -11782870 } + }, + { + { 10141598, 6082907, 17829293, -1947643, 9830092, 13613136, -25556636, -5544586, -33502212, 3592096 }, + { 33114168, -15889352, -26525686, -13343397, 33076705, 8716171, 1151462, 1521897, -982665, -6837803 }, + { -32939165, -4255815, 23947181, -324178, -33072974, -12305637, -16637686, 3891704, 26353178, 693168 } + }, + { + { 30374239, 1595580, -16884039, 13186931, 4600344, 406904, 9585294, -400668, 31375464, 14369965 }, + { -14370654, -7772529, 1510301, 6434173, -18784789, -6262728, 32732230, -13108839, 17901441, 16011505 }, + { 18171223, -11934626, -12500402, 15197122, -11038147, -15230035, -19172240, -16046376, 8764035, 12309598 } + } +}, +{ /* 20/31 */ + { + { 5975908, -5243188, -19459362, -9681747, -11541277, 14015782, -23665757, 1228319, 17544096, -10593782 }, + { 5811932, -1715293, 3442887, -2269310, -18367348, -8359541, -18044043, -15410127, -5565381, 12348900 }, + { -31399660, 11407555, 25755363, 6891399, -3256938, 14872274, -24849353, 8141295, -10632534, -585479 } + }, + { + { -12675304, 694026, -5076145, 13300344, 14015258, -14451394, -9698672, -11329050, 30944593, 1130208 }, + { 8247766, -6710942, -26562381, -7709309, -14401939, -14648910, 4652152, 2488540, 23550156, -271232 }, + { 17294316, -3788438, 7026748, 15626851, 22990044, 113481, 2267737, -5908146, -408818, -137719 } + }, + { + { 16091085, -16253926, 18599252, 7340678, 2137637, -1221657, -3364161, 14550936, 3260525, -7166271 }, + { -4910104, -13332887, 18550887, 10864893, -16459325, -7291596, -23028869, -13204905, -12748722, 2701326 }, + { -8574695, 16099415, 4629974, -16340524, -20786213, -6005432, -10018363, 9276971, 11329923, 1862132 } + }, + { + { 14763076, -15903608, -30918270, 3689867, 3511892, 10313526, -21951088, 12219231, -9037963, -940300 }, + { 8894987, -3446094, 6150753, 3013931, 301220, 15693451, -31981216, -2909717, -15438168, 11595570 }, + { 15214962, 3537601, -26238722, -14058872, 4418657, -15230761, 13947276, 10730794, -13489462, -4363670 } + }, + { + { -2538306, 7682793, 32759013, 263109, -29984731, -7955452, -22332124, -10188635, 977108, 699994 }, + { -12466472, 4195084, -9211532, 550904, -15565337, 12917920, 19118110, -439841, -30534533, -14337913 }, + { 31788461, -14507657, 4799989, 7372237, 8808585, -14747943, 9408237, -10051775, 12493932, -5409317 } + }, + { + { -25680606, 5260744, -19235809, -6284470, -3695942, 16566087, 27218280, 2607121, 29375955, 6024730 }, + { 842132, -2794693, -4763381, -8722815, 26332018, -12405641, 11831880, 6985184, -9940361, 2854096 }, + { -4847262, -7969331, 2516242, -5847713, 9695691, -7221186, 16512645, 960770, 12121869, 16648078 } + }, + { + { -15218652, 14667096, -13336229, 2013717, 30598287, -464137, -31504922, -7882064, 20237806, 2838411 }, + { -19288047, 4453152, 15298546, -16178388, 22115043, -15972604, 12544294, -13470457, 1068881, -12499905 }, + { -9558883, -16518835, 33238498, 13506958, 30505848, -1114596, -8486907, -2630053, 12521378, 4845654 } + }, + { + { -28198521, 10744108, -2958380, 10199664, 7759311, -13088600, 3409348, -873400, -6482306, -12885870 }, + { -23561822, 6230156, -20382013, 10655314, -24040585, -11621172, 10477734, -1240216, -3113227, 13974498 }, + { 12966261, 15550616, -32038948, -1615346, 21025980, -629444, 5642325, 7188737, 18895762, 12629579 } + } +}, +{ /* 21/31 */ + { + { 14741879, -14946887, 22177208, -11721237, 1279741, 8058600, 11758140, 789443, 32195181, 3895677 }, + { 10758205, 15755439, -4509950, 9243698, -4879422, 6879879, -2204575, -3566119, -8982069, 4429647 }, + { -2453894, 15725973, -20436342, -10410672, -5803908, -11040220, -7135870, -11642895, 18047436, -15281743 } + }, + { + { -25173001, -11307165, 29759956, 11776784, -22262383, -15820455, 10993114, -12850837, -17620701, -9408468 }, + { 21987233, 700364, -24505048, 14972008, -7774265, -5718395, 32155026, 2581431, -29958985, 8773375 }, + { -25568350, 454463, -13211935, 16126715, 25240068, 8594567, 20656846, 12017935, -7874389, -13920155 } + }, + { + { 6028182, 6263078, -31011806, -11301710, -818919, 2461772, -31841174, -5468042, -1721788, -2776725 }, + { -12278994, 16624277, 987579, -5922598, 32908203, 1248608, 7719845, -4166698, 28408820, 6816612 }, + { -10358094, -8237829, 19549651, -12169222, 22082623, 16147817, 20613181, 13982702, -10339570, 5067943 } + }, + { + { -30505967, -3821767, 12074681, 13582412, -19877972, 2443951, -19719286, 12746132, 5331210, -10105944 }, + { 30528811, 3601899, -1957090, 4619785, -27361822, -15436388, 24180793, -12570394, 27679908, -1648928 }, + { 9402404, -13957065, 32834043, 10838634, -26580150, -13237195, 26653274, -8685565, 22611444, -12715406 } + }, + { + { 22190590, 1118029, 22736441, 15130463, -30460692, -5991321, 19189625, -4648942, 4854859, 6622139 }, + { -8310738, -2953450, -8262579, -3388049, -10401731, -271929, 13424426, -3567227, 26404409, 13001963 }, + { -31241838, -15415700, -2994250, 8939346, 11562230, -12840670, -26064365, -11621720, -15405155, 11020693 } + }, + { + { 1866042, -7949489, -7898649, -10301010, 12483315, 13477547, 3175636, -12424163, 28761762, 1406734 }, + { -448555, -1777666, 13018551, 3194501, -9580420, -11161737, 24760585, -4347088, 25577411, -13378680 }, + { -24290378, 4759345, -690653, -1852816, 2066747, 10693769, -29595790, 9884936, -9368926, 4745410 } + }, + { + { -9141284, 6049714, -19531061, -4341411, -31260798, 9944276, -15462008, -11311852, 10931924, -11931931 }, + { -16561513, 14112680, -8012645, 4817318, -8040464, -11414606, -22853429, 10856641, -20470770, 13434654 }, + { 22759489, -10073434, -16766264, -1871422, 13637442, -10168091, 1765144, -12654326, 28445307, -5364710 } + }, + { + { 29875063, 12493613, 2795536, -3786330, 1710620, 15181182, -10195717, -8788675, 9074234, 1167180 }, + { -26205683, 11014233, -9842651, -2635485, -26908120, 7532294, -18716888, -9535498, 3843903, 9367684 }, + { -10969595, -6403711, 9591134, 9582310, 11349256, 108879, 16235123, 8601684, -139197, 4242895 } + } +}, +{ /* 22/31 */ + { + { 22092954, -13191123, -2042793, -11968512, 32186753, -11517388, -6574341, 2470660, -27417366, 16625501 }, + { -11057722, 3042016, 13770083, -9257922, 584236, -544855, -7770857, 2602725, -27351616, 14247413 }, + { 6314175, -10264892, -32772502, 15957557, -10157730, 168750, -8618807, 14290061, 27108877, -1180880 } + }, + { + { -8586597, -7170966, 13241782, 10960156, -32991015, -13794596, 33547976, -11058889, -27148451, 981874 }, + { 22833440, 9293594, -32649448, -13618667, -9136966, 14756819, -22928859, -13970780, -10479804, -16197962 }, + { -7768587, 3326786, -28111797, 10783824, 19178761, 14905060, 22680049, 13906969, -15933690, 3797899 } + }, + { + { 21721356, -4212746, -12206123, 9310182, -3882239, -13653110, 23740224, -2709232, 20491983, -8042152 }, + { 9209270, -15135055, -13256557, -6167798, -731016, 15289673, 25947805, 15286587, 30997318, -6703063 }, + { 7392032, 16618386, 23946583, -8039892, -13265164, -1533858, -14197445, -2321576, 17649998, -250080 } + }, + { + { -9301088, -14193827, 30609526, -3049543, -25175069, -1283752, -15241566, -9525724, -2233253, 7662146 }, + { -17558673, 1763594, -33114336, 15908610, -30040870, -12174295, 7335080, -8472199, -3174674, 3440183 }, + { -19889700, -5977008, -24111293, -9688870, 10799743, -16571957, 40450, -4431835, 4862400, 1133 } + }, + { + { -32856209, -7873957, -5422389, 14860950, -16319031, 7956142, 7258061, 311861, -30594991, -7379421 }, + { -3773428, -1565936, 28985340, 7499440, 24445838, 9325937, 29727763, 16527196, 18278453, 15405622 }, + { -4381906, 8508652, -19898366, -3674424, -5984453, 15149970, -13313598, 843523, -21875062, 13626197 } + }, + { + { 2281448, -13487055, -10915418, -2609910, 1879358, 16164207, -10783882, 3953792, 13340839, 15928663 }, + { 31727126, -7179855, -18437503, -8283652, 2875793, -16390330, -25269894, -7014826, -23452306, 5964753 }, + { 4100420, -5959452, -17179337, 6017714, -18705837, 12227141, -26684835, 11344144, 2538215, -7570755 } + }, + { + { -9433605, 6123113, 11159803, -2156608, 30016280, 14966241, -20474983, 1485421, -629256, -15958862 }, + { -26804558, 4260919, 11851389, 9658551, -32017107, 16367492, -20205425, -13191288, 11659922, -11115118 }, + { 26180396, 10015009, -30844224, -8581293, 5418197, 9480663, 2231568, -10170080, 33100372, -1306171 } + }, + { + { 15121113, -5201871, -10389905, 15427821, -27509937, -15992507, 21670947, 4486675, -5931810, -14466380 }, + { 16166486, -9483733, -11104130, 6023908, -31926798, -1364923, 2340060, -16254968, -10735770, -10039824 }, + { 28042865, -3557089, -12126526, 12259706, -3717498, -6945899, 6766453, -8689599, 18036436, 5803270 } + } +}, +{ /* 23/31 */ + { + { -817581, 6763912, 11803561, 1585585, 10958447, -2671165, 23855391, 4598332, -6159431, -14117438 }, + { -31031306, -14256194, 17332029, -2383520, 31312682, -5967183, 696309, 50292, -20095739, 11763584 }, + { -594563, -2514283, -32234153, 12643980, 12650761, 14811489, 665117, -12613632, -19773211, -10713562 } + }, + { + { 30464590, -11262872, -4127476, -12734478, 19835327, -7105613, -24396175, 2075773, -17020157, 992471 }, + { 18357185, -6994433, 7766382, 16342475, -29324918, 411174, 14578841, 8080033, -11574335, -10601610 }, + { 19598397, 10334610, 12555054, 2555664, 18821899, -10339780, 21873263, 16014234, 26224780, 16452269 } + }, + { + { -30223925, 5145196, 5944548, 16385966, 3976735, 2009897, -11377804, -7618186, -20533829, 3698650 }, + { 14187449, 3448569, -10636236, -10810935, -22663880, -3433596, 7268410, -10890444, 27394301, 12015369 }, + { 19695761, 16087646, 28032085, 12999827, 6817792, 11427614, 20244189, -1312777, -13259127, -3402461 } + }, + { + { 30860103, 12735208, -1888245, -4699734, -16974906, 2256940, -8166013, 12298312, -8550524, -10393462 }, + { -5719826, -11245325, -1910649, 15569035, 26642876, -7587760, -5789354, -15118654, -4976164, 12651793 }, + { -2848395, 9953421, 11531313, -5282879, 26895123, -12697089, -13118820, -16517902, 9768698, -2533218 } + }, + { + { -24719459, 1894651, -287698, -4704085, 15348719, -8156530, 32767513, 12765450, 4940095, 10678226 }, + { 18860224, 15980149, -18987240, -1562570, -26233012, -11071856, -7843882, 13944024, -24372348, 16582019 }, + { -15504260, 4970268, -29893044, 4175593, -20993212, -2199756, -11704054, 15444560, -11003761, 7989037 } + }, + { + { 31490452, 5568061, -2412803, 2182383, -32336847, 4531686, -32078269, 6200206, -19686113, -14800171 }, + { -17308668, -15879940, -31522777, -2831, -32887382, 16375549, 8680158, -16371713, 28550068, -6857132 }, + { -28126887, -5688091, 16837845, -1820458, -6850681, 12700016, -30039981, 4364038, 1155602, 5988841 } + }, + { + { 21890435, -13272907, -12624011, 12154349, -7831873, 15300496, 23148983, -4470481, 24618407, 8283181 }, + { -33136107, -10512751, 9975416, 6841041, -31559793, 16356536, 3070187, -7025928, 1466169, 10740210 }, + { -1509399, -15488185, -13503385, -10655916, 32799044, 909394, -13938903, -5779719, -32164649, -15327040 } + }, + { + { 3960823, -14267803, -28026090, -15918051, -19404858, 13146868, 15567327, 951507, -3260321, -573935 }, + { 24740841, 5052253, -30094131, 8961361, 25877428, 6165135, -24368180, 14397372, -7380369, -6144105 }, + { -28888365, 3510803, -28103278, -1158478, -11238128, -10631454, -15441463, -14453128, -1625486, -6494814 } + } +}, +{ /* 24/31 */ + { + { 793299, -9230478, 8836302, -6235707, -27360908, -2369593, 33152843, -4885251, -9906200, -621852 }, + { 5666233, 525582, 20782575, -8038419, -24538499, 14657740, 16099374, 1468826, -6171428, -15186581 }, + { -4859255, -3779343, -2917758, -6748019, 7778750, 11688288, -30404353, -9871238, -1558923, -9863646 } + }, + { + { 10896332, -7719704, 824275, 472601, -19460308, 3009587, 25248958, 14783338, -30581476, -15757844 }, + { 10566929, 12612572, -31944212, 11118703, -12633376, 12362879, 21752402, 8822496, 24003793, 14264025 }, + { 27713862, -7355973, -11008240, 9227530, 27050101, 2504721, 23886875, -13117525, 13958495, -5732453 } + }, + { + { -23481610, 4867226, -27247128, 3900521, 29838369, -8212291, -31889399, -10041781, 7340521, -15410068 }, + { 4646514, -8011124, -22766023, -11532654, 23184553, 8566613, 31366726, -1381061, -15066784, -10375192 }, + { -17270517, 12723032, -16993061, 14878794, 21619651, -6197576, 27584817, 3093888, -8843694, 3849921 } + }, + { + { -9064912, 2103172, 25561640, -15125738, -5239824, 9582958, 32477045, -9017955, 5002294, -15550259 }, + { -12057553, -11177906, 21115585, -13365155, 8808712, -12030708, 16489530, 13378448, -25845716, 12741426 }, + { -5946367, 10645103, -30911586, 15390284, -3286982, -7118677, 24306472, 15852464, 28834118, -7646072 } + }, + { + { -17335748, -9107057, -24531279, 9434953, -8472084, -583362, -13090771, 455841, 20461858, 5491305 }, + { 13669248, -16095482, -12481974, -10203039, -14569770, -11893198, -24995986, 11293807, -28588204, -9421832 }, + { 28497928, 6272777, -33022994, 14470570, 8906179, -1225630, 18504674, -14165166, 29867745, -8795943 } + }, + { + { -16207023, 13517196, -27799630, -13697798, 24009064, -6373891, -6367600, -13175392, 22853429, -4012011 }, + { 24191378, 16712145, -13931797, 15217831, 14542237, 1646131, 18603514, -11037887, 12876623, -2112447 }, + { 17902668, 4518229, -411702, -2829247, 26878217, 5258055, -12860753, 608397, 16031844, 3723494 } + }, + { + { -28632773, 12763728, -20446446, 7577504, 33001348, -13017745, 17558842, -7872890, 23896954, -4314245 }, + { -20005381, -12011952, 31520464, 605201, 2543521, 5991821, -2945064, 7229064, -9919646, -8826859 }, + { 28816045, 298879, -28165016, -15920938, 19000928, -1665890, -12680833, -2949325, -18051778, -2082915 } + }, + { + { 16000882, -344896, 3493092, -11447198, -29504595, -13159789, 12577740, 16041268, -19715240, 7847707 }, + { 10151868, 10572098, 27312476, 7922682, 14825339, 4723128, -32855931, -6519018, -10020567, 3852848 }, + { -11430470, 15697596, -21121557, -4420647, 5386314, 15063598, 16514493, -15932110, 29330899, -15076224 } + } +}, +{ /* 25/31 */ + { + { -25499735, -4378794, -15222908, -6901211, 16615731, 2051784, 3303702, 15490, -27548796, 12314391 }, + { 15683520, -6003043, 18109120, -9980648, 15337968, -5997823, -16717435, 15921866, 16103996, -3731215 }, + { -23169824, -10781249, 13588192, -1628807, -3798557, -1074929, -19273607, 5402699, -29815713, -9841101 } + }, + { + { 23190676, 2384583, -32714340, 3462154, -29903655, -1529132, -11266856, 8911517, -25205859, 2739713 }, + { 21374101, -3554250, -33524649, 9874411, 15377179, 11831242, -33529904, 6134907, 4931255, 11987849 }, + { -7732, -2978858, -16223486, 7277597, 105524, -322051, -31480539, 13861388, -30076310, 10117930 } + }, + { + { -29501170, -10744872, -26163768, 13051539, -25625564, 5089643, -6325503, 6704079, 12890019, 15728940 }, + { -21972360, -11771379, -951059, -4418840, 14704840, 2695116, 903376, -10428139, 12885167, 8311031 }, + { -17516482, 5352194, 10384213, -13811658, 7506451, 13453191, 26423267, 4384730, 1888765, -5435404 } + }, + { + { -25817338, -3107312, -13494599, -3182506, 30896459, -13921729, -32251644, -12707869, -19464434, -3340243 }, + { -23607977, -2665774, -526091, 4651136, 5765089, 4618330, 6092245, 14845197, 17151279, -9854116 }, + { -24830458, -12733720, -15165978, 10367250, -29530908, -265356, 22825805, -7087279, -16866484, 16176525 } + }, + { + { -23583256, 6564961, 20063689, 3798228, -4740178, 7359225, 2006182, -10363426, -28746253, -10197509 }, + { -10626600, -4486402, -13320562, -5125317, 3432136, -6393229, 23632037, -1940610, 32808310, 1099883 }, + { 15030977, 5768825, -27451236, -2887299, -6427378, -15361371, -15277896, -6809350, 2051441, -15225865 } + }, + { + { -3362323, -7239372, 7517890, 9824992, 23555850, 295369, 5148398, -14154188, -22686354, 16633660 }, + { 4577086, -16752288, 13249841, -15304328, 19958763, -14537274, 18559670, -10759549, 8402478, -9864273 }, + { -28406330, -1051581, -26790155, -907698, -17212414, -11030789, 9453451, -14980072, 17983010, 9967138 } + }, + { + { -25762494, 6524722, 26585488, 9969270, 24709298, 1220360, -1677990, 7806337, 17507396, 3651560 }, + { -10420457, -4118111, 14584639, 15971087, -15768321, 8861010, 26556809, -5574557, -18553322, -11357135 }, + { 2839101, 14284142, 4029895, 3472686, 14402957, 12689363, -26642121, 8459447, -5605463, -7621941 } + }, + { + { -4839289, -3535444, 9744961, 2871048, 25113978, 3187018, -25110813, -849066, 17258084, -7977739 }, + { 18164541, -10595176, -17154882, -1542417, 19237078, -9745295, 23357533, -15217008, 26908270, 12150756 }, + { -30264870, -7647865, 5112249, -7036672, -1499807, -6974257, 43168, -5537701, -32302074, 16215819 } + } +}, +{ /* 26/31 */ + { + { -6898905, 9824394, -12304779, -4401089, -31397141, -6276835, 32574489, 12532905, -7503072, -8675347 }, + { -27343522, -16515468, -27151524, -10722951, 946346, 16291093, 254968, 7168080, 21676107, -1943028 }, + { 21260961, -8424752, -16831886, -11920822, -23677961, 3968121, -3651949, -6215466, -3556191, -7913075 } + }, + { + { 16544754, 13250366, -16804428, 15546242, -4583003, 12757258, -2462308, -8680336, -18907032, -9662799 }, + { -2415239, -15577728, 18312303, 4964443, -15272530, -12653564, 26820651, 16690659, 25459437, -4564609 }, + { -25144690, 11425020, 28423002, -11020557, -6144921, -15826224, 9142795, -2391602, -6432418, -1644817 } + }, + { + { -23104652, 6253476, 16964147, -3768872, -25113972, -12296437, -27457225, -16344658, 6335692, 7249989 }, + { -30333227, 13979675, 7503222, -12368314, -11956721, -4621693, -30272269, 2682242, 25993170, -12478523 }, + { 4364628, 5930691, 32304656, -10044554, -8054781, 15091131, 22857016, -10598955, 31820368, 15075278 } + }, + { + { 31879134, -8918693, 17258761, 90626, -8041836, -4917709, 24162788, -9650886, -17970238, 12833045 }, + { 19073683, 14851414, -24403169, -11860168, 7625278, 11091125, -19619190, 2074449, -9413939, 14905377 }, + { 24483667, -11935567, -2518866, -11547418, -1553130, 15355506, -25282080, 9253129, 27628530, -7555480 } + }, + { + { 17597607, 8340603, 19355617, 552187, 26198470, -3176583, 4593324, -9157582, -14110875, 15297016 }, + { 510886, 14337390, -31785257, 16638632, 6328095, 2713355, -20217417, -11864220, 8683221, 2921426 }, + { 18606791, 11874196, 27155355, -5281482, -24031742, 6265446, -25178240, -1278924, 4674690, 13890525 } + }, + { + { 13609624, 13069022, -27372361, -13055908, 24360586, 9592974, 14977157, 9835105, 4389687, 288396 }, + { 9922506, -519394, 13613107, 5883594, -18758345, -434263, -12304062, 8317628, 23388070, 16052080 }, + { 12720016, 11937594, -31970060, -5028689, 26900120, 8561328, -20155687, -11632979, -14754271, -10812892 } + }, + { + { 15961858, 14150409, 26716931, -665832, -22794328, 13603569, 11829573, 7467844, -28822128, 929275 }, + { 11038231, -11582396, -27310482, -7316562, -10498527, -16307831, -23479533, -9371869, -21393143, 2465074 }, + { 20017163, -4323226, 27915242, 1529148, 12396362, 15675764, 13817261, -9658066, 2463391, -4622140 } + }, + { + { -16358878, -12663911, -12065183, 4996454, -1256422, 1073572, 9583558, 12851107, 4003896, 12673717 }, + { -1731589, -15155870, -3262930, 16143082, 19294135, 13385325, 14741514, -9103726, 7903886, 2348101 }, + { 24536016, -16515207, 12715592, -3862155, 1511293, 10047386, -3842346, -7129159, -28377538, 10048127 } + } +}, +{ /* 27/31 */ + { + { -12622226, -6204820, 30718825, 2591312, -10617028, 12192840, 18873298, -7297090, -32297756, 15221632 }, + { -26478122, -11103864, 11546244, -1852483, 9180880, 7656409, -21343950, 2095755, 29769758, 6593415 }, + { -31994208, -2907461, 4176912, 3264766, 12538965, -868111, 26312345, -6118678, 30958054, 8292160 } + }, + { + { 31429822, -13959116, 29173532, 15632448, 12174511, -2760094, 32808831, 3977186, 26143136, -3148876 }, + { 22648901, 1402143, -22799984, 13746059, 7936347, 365344, -8668633, -1674433, -3758243, -2304625 }, + { -15491917, 8012313, -2514730, -12702462, -23965846, -10254029, -1612713, -1535569, -16664475, 8194478 } + }, + { + { 27338066, -7507420, -7414224, 10140405, -19026427, -6589889, 27277191, 8855376, 28572286, 3005164 }, + { 26287124, 4821776, 25476601, -4145903, -3764513, -15788984, -18008582, 1182479, -26094821, -13079595 }, + { -7171154, 3178080, 23970071, 6201893, -17195577, -4489192, -21876275, -13982627, 32208683, -1198248 } + }, + { + { -16657702, 2817643, -10286362, 14811298, 6024667, 13349505, -27315504, -10497842, -27672585, -11539858 }, + { 15941029, -9405932, -21367050, 8062055, 31876073, -238629, -15278393, -1444429, 15397331, -4130193 }, + { 8934485, -13485467, -23286397, -13423241, -32446090, 14047986, 31170398, -1441021, -27505566, 15087184 } + }, + { + { -18357243, -2156491, 24524913, -16677868, 15520427, -6360776, -15502406, 11461896, 16788528, -5868942 }, + { -1947386, 16013773, 21750665, 3714552, -17401782, -16055433, -3770287, -10323320, 31322514, -11615635 }, + { 21426655, -5650218, -13648287, -5347537, -28812189, -4920970, -18275391, -14621414, 13040862, -12112948 } + }, + { + { 11293895, 12478086, -27136401, 15083750, -29307421, 14748872, 14555558, -13417103, 1613711, 4896935 }, + { -25894883, 15323294, -8489791, -8057900, 25967126, -13425460, 2825960, -4897045, -23971776, -11267415 }, + { -15924766, -5229880, -17443532, 6410664, 3622847, 10243618, 20615400, 12405433, -23753030, -8436416 } + }, + { + { -7091295, 12556208, -20191352, 9025187, -17072479, 4333801, 4378436, 2432030, 23097949, -566018 }, + { 4565804, -16025654, 20084412, -7842817, 1724999, 189254, 24767264, 10103221, -18512313, 2424778 }, + { 366633, -11976806, 8173090, -6890119, 30788634, 5745705, -7168678, 1344109, -3642553, 12412659 } + }, + { + { -24001791, 7690286, 14929416, -168257, -32210835, -13412986, 24162697, -15326504, -3141501, 11179385 }, + { 18289522, -14724954, 8056945, 16430056, -21729724, 7842514, -6001441, -1486897, -18684645, -11443503 }, + { 476239, 6601091, -6152790, -9723375, 17503545, -4863900, 27672959, 13403813, 11052904, 5219329 } + } +}, +{ /* 28/31 */ + { + { 20678546, -8375738, -32671898, 8849123, -5009758, 14574752, 31186971, -3973730, 9014762, -8579056 }, + { -13644050, -10350239, -15962508, 5075808, -1514661, -11534600, -33102500, 9160280, 8473550, -3256838 }, + { 24900749, 14435722, 17209120, -15292541, -22592275, 9878983, -7689309, -16335821, -24568481, 11788948 } + }, + { + { -3118155, -11395194, -13802089, 14797441, 9652448, -6845904, -20037437, 10410733, -24568470, -1458691 }, + { -15659161, 16736706, -22467150, 10215878, -9097177, 7563911, 11871841, -12505194, -18513325, 8464118 }, + { -23400612, 8348507, -14585951, -861714, -3950205, -6373419, 14325289, 8628612, 33313881, -8370517 } + }, + { + { -20186973, -4967935, 22367356, 5271547, -1097117, -4788838, -24805667, -10236854, -8940735, -5818269 }, + { -6948785, -1795212, -32625683, -16021179, 32635414, -7374245, 15989197, -12838188, 28358192, -4253904 }, + { -23561781, -2799059, -32351682, -1661963, -9147719, 10429267, -16637684, 4072016, -5351664, 5596589 } + }, + { + { -28236598, -3390048, 12312896, 6213178, 3117142, 16078565, 29266239, 2557221, 1768301, 15373193 }, + { -7243358, -3246960, -4593467, -7553353, -127927, -912245, -1090902, -4504991, -24660491, 3442910 }, + { -30210571, 5124043, 14181784, 8197961, 18964734, -11939093, 22597931, 7176455, -18585478, 13365930 } + }, + { + { -7877390, -1499958, 8324673, 4690079, 6261860, 890446, 24538107, -8570186, -9689599, -3031667 }, + { 25008904, -10771599, -4305031, -9638010, 16265036, 15721635, 683793, -11823784, 15723479, -15163481 }, + { -9660625, 12374379, -27006999, -7026148, -7724114, -12314514, 11879682, 5400171, 519526, -1235876 } + }, + { + { 22258397, -16332233, -7869817, 14613016, -22520255, -2950923, -20353881, 7315967, 16648397, 7605640 }, + { -8081308, -8464597, -8223311, 9719710, 19259459, -15348212, 23994942, -5281555, -9468848, 4763278 }, + { -21699244, 9220969, -15730624, 1084137, -25476107, -2852390, 31088447, -7764523, -11356529, 728112 } + }, + { + { 26047220, -11751471, -6900323, -16521798, 24092068, 9158119, -4273545, -12555558, -29365436, -5498272 }, + { 17510331, -322857, 5854289, 8403524, 17133918, -3112612, -28111007, 12327945, 10750447, 10014012 }, + { -10312768, 3936952, 9156313, -8897683, 16498692, -994647, -27481051, -666732, 3424691, 7540221 } + }, + { + { 30322361, -6964110, 11361005, -4143317, 7433304, 4989748, -7071422, -16317219, -9244265, 15258046 }, + { 13054562, -2779497, 19155474, 469045, -12482797, 4566042, 5631406, 2711395, 1062915, -5136345 }, + { -19240248, -11254599, -29509029, -7499965, -5835763, 13005411, -6066489, 12194497, 32960380, 1459310 } + } +}, +{ /* 29/31 */ + { + { 19852034, 7027924, 23669353, 10020366, 8586503, -6657907, 394197, -6101885, 18638003, -11174937 }, + { 31395534, 15098109, 26581030, 8030562, -16527914, -5007134, 9012486, -7584354, -6643087, -5442636 }, + { -9192165, -2347377, -1997099, 4529534, 25766844, 607986, -13222, 9677543, -32294889, -6456008 } + }, + { + { -2444496, -149937, 29348902, 8186665, 1873760, 12489863, -30934579, -7839692, -7852844, -8138429 }, + { -15236356, -15433509, 7766470, 746860, 26346930, -10221762, -27333451, 10754588, -9431476, 5203576 }, + { 31834314, 14135496, -770007, 5159118, 20917671, -16768096, -7467973, -7337524, 31809243, 7347066 } + }, + { + { -9606723, -11874240, 20414459, 13033986, 13716524, -11691881, 19797970, -12211255, 15192876, -2087490 }, + { -12663563, -2181719, 1168162, -3804809, 26747877, -14138091, 10609330, 12694420, 33473243, -13382104 }, + { 33184999, 11180355, 15832085, -11385430, -1633671, 225884, 15089336, -11023903, -6135662, 14480053 } + }, + { + { 31308717, -5619998, 31030840, -1897099, 15674547, -6582883, 5496208, 13685227, 27595050, 8737275 }, + { -20318852, -15150239, 10933843, -16178022, 8335352, -7546022, -31008351, -12610604, 26498114, 66511 }, + { 22644454, -8761729, -16671776, 4884562, -3105614, -13559366, 30540766, -4286747, -13327787, -7515095 } + }, + { + { -28017847, 9834845, 18617207, -2681312, -3401956, -13307506, 8205540, 13585437, -17127465, 15115439 }, + { 23711543, -672915, 31206561, -8362711, 6164647, -9709987, -33535882, -1426096, 8236921, 16492939 }, + { -23910559, -13515526, -26299483, -4503841, 25005590, -7687270, 19574902, 10071562, 6708380, -6222424 } + }, + { + { 2101391, -4930054, 19702731, 2367575, -15427167, 1047675, 5301017, 9328700, 29955601, -11678310 }, + { 3096359, 9271816, -21620864, -15521844, -14847996, -7592937, -25892142, -12635595, -9917575, 6216608 }, + { -32615849, 338663, -25195611, 2510422, -29213566, -13820213, 24822830, -6146567, -26767480, 7525079 } + }, + { + { -23066649, -13985623, 16133487, -7896178, -3389565, 778788, -910336, -2782495, -19386633, 11994101 }, + { 21691500, -13624626, -641331, -14367021, 3285881, -3483596, -25064666, 9718258, -7477437, 13381418 }, + { 18445390, -4202236, 14979846, 11622458, -1727110, -3582980, 23111648, -6375247, 28535282, 15779576 } + }, + { + { 30098053, 3089662, -9234387, 16662135, -21306940, 11308411, -14068454, 12021730, 9955285, -16303356 }, + { 9734894, -14576830, -7473633, -9138735, 2060392, 11313496, -18426029, 9924399, 20194861, 13380996 }, + { -26378102, -7965207, -22167821, 15789297, -18055342, -6168792, -1984914, 15707771, 26342023, 10146099 } + } +}, +{ /* 30/31 */ + { + { -26016874, -219943, 21339191, -41388, 19745256, -2878700, -29637280, 2227040, 21612326, -545728 }, + { -13077387, 1184228, 23562814, -5970442, -20351244, -6348714, 25764461, 12243797, -20856566, 11649658 }, + { -10031494, 11262626, 27384172, 2271902, 26947504, -15997771, 39944, 6114064, 33514190, 2333242 } + }, + { + { -21433588, -12421821, 8119782, 7219913, -21830522, -9016134, -6679750, -12670638, 24350578, -13450001 }, + { -4116307, -11271533, -23886186, 4843615, -30088339, 690623, -31536088, -10406836, 8317860, 12352766 }, + { 18200138, -14475911, -33087759, -2696619, -23702521, -9102511, -23552096, -2287550, 20712163, 6719373 } + }, + { + { 26656208, 6075253, -7858556, 1886072, -28344043, 4262326, 11117530, -3763210, 26224235, -3297458 }, + { -17168938, -14854097, -3395676, -16369877, -19954045, 14050420, 21728352, 9493610, 18620611, -16428628 }, + { -13323321, 13325349, 11432106, 5964811, 18609221, 6062965, -5269471, -9725556, -30701573, -16479657 } + }, + { + { -23860538, -11233159, 26961357, 1640861, -32413112, -16737940, 12248509, -5240639, 13735342, 1934062 }, + { 25089769, 6742589, 17081145, -13406266, 21909293, -16067981, -15136294, -3765346, -21277997, 5473616 }, + { 31883677, -7961101, 1083432, -11572403, 22828471, 13290673, -7125085, 12469656, 29111212, -5451014 } + }, + { + { 24244947, -15050407, -26262976, 2791540, -14997599, 16666678, 24367466, 6388839, -10295587, 452383 }, + { -25640782, -3417841, 5217916, 16224624, 19987036, -4082269, -24236251, -5915248, 15766062, 8407814 }, + { -20406999, 13990231, 15495425, 16395525, 5377168, 15166495, -8917023, -4388953, -8067909, 2276718 } + }, + { + { 30157918, 12924066, -17712050, 9245753, 19895028, 3368142, -23827587, 5096219, 22740376, -7303417 }, + { 2041139, -14256350, 7783687, 13876377, -25946985, -13352459, 24051124, 13742383, -15637599, 13295222 }, + { 33338237, -8505733, 12532113, 7977527, 9106186, -1715251, -17720195, -4612972, -4451357, -14669444 } + }, + { + { -20045281, 5454097, -14346548, 6447146, 28862071, 1883651, -2469266, -4141880, 7770569, 9620597 }, + { 23208068, 7979712, 33071466, 8149229, 1758231, -10834995, 30945528, -1694323, -33502340, -14767970 }, + { 1439958, -16270480, -1079989, -793782, 4625402, 10647766, -5043801, 1220118, 30494170, -11440799 } + }, + { + { -5037580, -13028295, -2970559, -3061767, 15640974, -6701666, -26739026, 926050, -1684339, -13333647 }, + { 13908495, -3549272, 30919928, -6273825, -21521863, 7989039, 9021034, 9078865, 3353509, 4033511 }, + { -29663431, -15113610, 32259991, -344482, 24295849, -12912123, 23161163, 8839127, 27485041, 7356032 } + } +}, +{ /* 31/31 */ + { + { 9661027, 705443, 11980065, -5370154, -1628543, 14661173, -6346142, 2625015, 28431036, -16771834 }, + { -23839233, -8311415, -25945511, 7480958, -17681669, -8354183, -22545972, 14150565, 15970762, 4099461 }, + { 29262576, 16756590, 26350592, -8793563, 8529671, -11208050, 13617293, -9937143, 11465739, 8317062 } + }, + { + { -25493081, -6962928, 32500200, -9419051, -23038724, -2302222, 14898637, 3848455, 20969334, -5157516 }, + { -20384450, -14347713, -18336405, 13884722, -33039454, 2842114, -21610826, -3649888, 11177095, 14989547 }, + { -24496721, -11716016, 16959896, 2278463, 12066309, 10137771, 13515641, 2581286, -28487508, 9930240 } + }, + { + { -17751622, -2097826, 16544300, -13009300, -15914807, -14949081, 18345767, -13403753, 16291481, -5314038 }, + { -33229194, 2553288, 32678213, 9875984, 8534129, 6889387, -9676774, 6957617, 4368891, 9788741 }, + { 16660756, 7281060, -10830758, 12911820, 20108584, -8101676, -21722536, -8613148, 16250552, -11111103 } + }, + { + { -19765507, 2390526, -16551031, 14161980, 1905286, 6414907, 4689584, 10604807, -30190403, 4782747 }, + { -1354539, 14736941, -7367442, -13292886, 7710542, -14155590, -9981571, 4383045, 22546403, 437323 }, + { 31665577, -12180464, -16186830, 1491339, -18368625, 3294682, 27343084, 2786261, -30633590, -14097016 } + }, + { + { -14467279, -683715, -33374107, 7448552, 19294360, 14334329, -19690631, 2355319, -19284671, -6114373 }, + { 15121312, -15796162, 6377020, -6031361, -10798111, -12957845, 18952177, 15496498, -29380133, 11754228 }, + { -2637277, -13483075, 8488727, -14303896, 12728761, -1622493, 7141596, 11724556, 22761615, -10134141 } + }, + { + { 16918416, 11729663, -18083579, 3022987, -31015732, -13339659, -28741185, -12227393, 32851222, 11717399 }, + { 11166634, 7338049, -6722523, 4531520, -29468672, -7302055, 31474879, 3483633, -1193175, -4030831 }, + { -185635, 9921305, 31456609, -13536438, -12013818, 13348923, 33142652, 6546660, -19985279, -3948376 } + }, + { + { -32460596, 11266712, -11197107, -7899103, 31703694, 3855903, -8537131, -12833048, -30772034, -15486313 }, + { -18006477, 12709068, 3991746, -6479188, -21491523, -10550425, -31135347, -16049879, 10928917, 3011958 }, + { -6957757, -15594337, 31696059, 334240, 29576716, 14796075, -30831056, -12805180, 18008031, 10258577 } + }, + { + { -22448644, 15655569, 7018479, -4410003, -30314266, -1201591, -1853465, 1367120, 25127874, 6671743 }, + { 29701166, -14373934, -10878120, 9279288, -17568, 13127210, 21382910, 11042292, 25838796, 4642684 }, + { -20430234, 14955537, -24126347, 8124619, -5369288, -5990470, 30468147, -13900640, 18423289, 4177476 } + } +} diff --git a/libs/libsodium/src/crypto_core/ed25519/ref10/fe_25_5/base2.h b/libs/libsodium/src/crypto_core/ed25519/ref10/fe_25_5/base2.h new file mode 100644 index 0000000000..90a1457eab --- /dev/null +++ b/libs/libsodium/src/crypto_core/ed25519/ref10/fe_25_5/base2.h @@ -0,0 +1,40 @@ +{ + { 25967493, -14356035, 29566456, 3660896, -12694345, 4014787, 27544626, -11754271, -6079156, 2047605 }, + { -12545711, 934262, -2722910, 3049990, -727428, 9406986, 12720692, 5043384, 19500929, -15469378 }, + { -8738181, 4489570, 9688441, -14785194, 10184609, -12363380, 29287919, 11864899, -24514362, -4438546 } +}, +{ + { 15636291, -9688557, 24204773, -7912398, 616977, -16685262, 27787600, -14772189, 28944400, -1550024 }, + { 16568933, 4717097, -11556148, -1102322, 15682896, -11807043, 16354577, -11775962, 7689662, 11199574 }, + { 30464156, -5976125, -11779434, -15670865, 23220365, 15915852, 7512774, 10017326, -17749093, -9920357 } +}, +{ + { 10861363, 11473154, 27284546, 1981175, -30064349, 12577861, 32867885, 14515107, -15438304, 10819380 }, + { 4708026, 6336745, 20377586, 9066809, -11272109, 6594696, -25653668, 12483688, -12668491, 5581306 }, + { 19563160, 16186464, -29386857, 4097519, 10237984, -4348115, 28542350, 13850243, -23678021, -15815942 } +}, +{ + { 5153746, 9909285, 1723747, -2777874, 30523605, 5516873, 19480852, 5230134, -23952439, -15175766 }, + { -30269007, -3463509, 7665486, 10083793, 28475525, 1649722, 20654025, 16520125, 30598449, 7715701 }, + { 28881845, 14381568, 9657904, 3680757, -20181635, 7843316, -31400660, 1370708, 29794553, -1409300 } +}, +{ + { -22518993, -6692182, 14201702, -8745502, -23510406, 8844726, 18474211, -1361450, -13062696, 13821877 }, + { -6455177, -7839871, 3374702, -4740862, -27098617, -10571707, 31655028, -7212327, 18853322, -14220951 }, + { 4566830, -12963868, -28974889, -12240689, -7602672, -2830569, -8514358, -10431137, 2207753, -3209784 } +}, +{ + { -25154831, -4185821, 29681144, 7868801, -6854661, -9423865, -12437364, -663000, -31111463, -16132436 }, + { 25576264, -2703214, 7349804, -11814844, 16472782, 9300885, 3844789, 15725684, 171356, 6466918 }, + { 23103977, 13316479, 9739013, -16149481, 817875, -15038942, 8965339, -14088058, -30714912, 16193877 } +}, +{ + { -33521811, 3180713, -2394130, 14003687, -16903474, -16270840, 17238398, 4729455, -18074513, 9256800 }, + { -25182317, -4174131, 32336398, 5036987, -21236817, 11360617, 22616405, 9761698, -19827198, 630305 }, + { -13720693, 2639453, -24237460, -7406481, 9494427, -5774029, -6554551, -15960994, -2449256, -14291300 } +}, +{ + { -3151181, -5046075, 9282714, 6866145, -31907062, -863023, -18940575, 15033784, 25105118, -7894876 }, + { -24326370, 15950226, -31801215, -14592823, -11662737, -5090925, 1573892, -2625887, 2198790, -15804619 }, + { -3099351, 10324967, -2241613, 7453183, -5446979, -2735503, -13812022, -16236442, -32461234, -12290683 } +} diff --git a/libs/libsodium/src/crypto_core/ed25519/ref10/fe_25_5/constants.h b/libs/libsodium/src/crypto_core/ed25519/ref10/fe_25_5/constants.h new file mode 100644 index 0000000000..3dc9156a31 --- /dev/null +++ b/libs/libsodium/src/crypto_core/ed25519/ref10/fe_25_5/constants.h @@ -0,0 +1,20 @@ +/* 37095705934669439343138083508754565189542113879843219016388785533085940283555 */ +static const fe25519 d = { + -10913610, 13857413, -15372611, 6949391, 114729, -8787816, -6275908, -3247719, -18696448, -12055116 +}; + +/* 2 * d = + * 16295367250680780974490674513165176452449235426866156013048779062215315747161 + */ +static const fe25519 d2 = { + -21827239, -5839606, -30745221, 13898782, 229458, 15978800, -12551817, -6495438, 29715968, 9444199 }; + +/* sqrt(-1) */ +static const fe25519 sqrtm1 = { + -32595792, -7943725, 9377950, 3500415, 12389472, -272473, -25146209, -2005654, 326686, 11406482 +}; + +/* A = 486662 */ +static const fe25519 curve25519_A = { + 486662, 0, 0, 0, 0, 0, 0, 0, 0, 0 +}; diff --git a/libs/libsodium/src/crypto_core/ed25519/ref10/fe_25_5/fe.h b/libs/libsodium/src/crypto_core/ed25519/ref10/fe_25_5/fe.h new file mode 100644 index 0000000000..f216669e4e --- /dev/null +++ b/libs/libsodium/src/crypto_core/ed25519/ref10/fe_25_5/fe.h @@ -0,0 +1,220 @@ +/* + Ignores top bit of h. + */ + +void +fe25519_frombytes(fe25519 h, const unsigned char *s) +{ + int64_t h0 = load_4(s); + int64_t h1 = load_3(s + 4) << 6; + int64_t h2 = load_3(s + 7) << 5; + int64_t h3 = load_3(s + 10) << 3; + int64_t h4 = load_3(s + 13) << 2; + int64_t h5 = load_4(s + 16); + int64_t h6 = load_3(s + 20) << 7; + int64_t h7 = load_3(s + 23) << 5; + int64_t h8 = load_3(s + 26) << 4; + int64_t h9 = (load_3(s + 29) & 8388607) << 2; + + int64_t carry0; + int64_t carry1; + int64_t carry2; + int64_t carry3; + int64_t carry4; + int64_t carry5; + int64_t carry6; + int64_t carry7; + int64_t carry8; + int64_t carry9; + + carry9 = (h9 + (int64_t)(1L << 24)) >> 25; + h0 += carry9 * 19; + h9 -= carry9 * ((uint64_t) 1L << 25); + carry1 = (h1 + (int64_t)(1L << 24)) >> 25; + h2 += carry1; + h1 -= carry1 * ((uint64_t) 1L << 25); + carry3 = (h3 + (int64_t)(1L << 24)) >> 25; + h4 += carry3; + h3 -= carry3 * ((uint64_t) 1L << 25); + carry5 = (h5 + (int64_t)(1L << 24)) >> 25; + h6 += carry5; + h5 -= carry5 * ((uint64_t) 1L << 25); + carry7 = (h7 + (int64_t)(1L << 24)) >> 25; + h8 += carry7; + h7 -= carry7 * ((uint64_t) 1L << 25); + + carry0 = (h0 + (int64_t)(1L << 25)) >> 26; + h1 += carry0; + h0 -= carry0 * ((uint64_t) 1L << 26); + carry2 = (h2 + (int64_t)(1L << 25)) >> 26; + h3 += carry2; + h2 -= carry2 * ((uint64_t) 1L << 26); + carry4 = (h4 + (int64_t)(1L << 25)) >> 26; + h5 += carry4; + h4 -= carry4 * ((uint64_t) 1L << 26); + carry6 = (h6 + (int64_t)(1L << 25)) >> 26; + h7 += carry6; + h6 -= carry6 * ((uint64_t) 1L << 26); + carry8 = (h8 + (int64_t)(1L << 25)) >> 26; + h9 += carry8; + h8 -= carry8 * ((uint64_t) 1L << 26); + + h[0] = (int32_t) h0; + h[1] = (int32_t) h1; + h[2] = (int32_t) h2; + h[3] = (int32_t) h3; + h[4] = (int32_t) h4; + h[5] = (int32_t) h5; + h[6] = (int32_t) h6; + h[7] = (int32_t) h7; + h[8] = (int32_t) h8; + h[9] = (int32_t) h9; +} + +/* + Preconditions: + |h| bounded by 1.1*2^26,1.1*2^25,1.1*2^26,1.1*2^25,etc. + + Write p=2^255-19; q=floor(h/p). + Basic claim: q = floor(2^(-255)(h + 19 2^(-25)h9 + 2^(-1))). + + Proof: + Have |h|<=p so |q|<=1 so |19^2 2^(-255) q|<1/4. + Also have |h-2^230 h9|<2^231 so |19 2^(-255)(h-2^230 h9)|<1/4. + + Write y=2^(-1)-19^2 2^(-255)q-19 2^(-255)(h-2^230 h9). + Then 0<y<1. + + Write r=h-pq. + Have 0<=r<=p-1=2^255-20. + Thus 0<=r+19(2^-255)r<r+19(2^-255)2^255<=2^255-1. + + Write x=r+19(2^-255)r+y. + Then 0<x<2^255 so floor(2^(-255)x) = 0 so floor(q+2^(-255)x) = q. + + Have q+2^(-255)x = 2^(-255)(h + 19 2^(-25) h9 + 2^(-1)) + so floor(2^(-255)(h + 19 2^(-25) h9 + 2^(-1))) = q. +*/ + +static void +fe25519_reduce(fe25519 h, const fe25519 f) +{ + int32_t h0 = f[0]; + int32_t h1 = f[1]; + int32_t h2 = f[2]; + int32_t h3 = f[3]; + int32_t h4 = f[4]; + int32_t h5 = f[5]; + int32_t h6 = f[6]; + int32_t h7 = f[7]; + int32_t h8 = f[8]; + int32_t h9 = f[9]; + + int32_t q; + int32_t carry0, carry1, carry2, carry3, carry4, carry5, carry6, carry7, carry8, carry9; + + q = (19 * h9 + ((uint32_t) 1L << 24)) >> 25; + q = (h0 + q) >> 26; + q = (h1 + q) >> 25; + q = (h2 + q) >> 26; + q = (h3 + q) >> 25; + q = (h4 + q) >> 26; + q = (h5 + q) >> 25; + q = (h6 + q) >> 26; + q = (h7 + q) >> 25; + q = (h8 + q) >> 26; + q = (h9 + q) >> 25; + + /* Goal: Output h-(2^255-19)q, which is between 0 and 2^255-20. */ + h0 += 19 * q; + /* Goal: Output h-2^255 q, which is between 0 and 2^255-20. */ + + carry0 = h0 >> 26; + h1 += carry0; + h0 -= carry0 * ((uint32_t) 1L << 26); + carry1 = h1 >> 25; + h2 += carry1; + h1 -= carry1 * ((uint32_t) 1L << 25); + carry2 = h2 >> 26; + h3 += carry2; + h2 -= carry2 * ((uint32_t) 1L << 26); + carry3 = h3 >> 25; + h4 += carry3; + h3 -= carry3 * ((uint32_t) 1L << 25); + carry4 = h4 >> 26; + h5 += carry4; + h4 -= carry4 * ((uint32_t) 1L << 26); + carry5 = h5 >> 25; + h6 += carry5; + h5 -= carry5 * ((uint32_t) 1L << 25); + carry6 = h6 >> 26; + h7 += carry6; + h6 -= carry6 * ((uint32_t) 1L << 26); + carry7 = h7 >> 25; + h8 += carry7; + h7 -= carry7 * ((uint32_t) 1L << 25); + carry8 = h8 >> 26; + h9 += carry8; + h8 -= carry8 * ((uint32_t) 1L << 26); + carry9 = h9 >> 25; + h9 -= carry9 * ((uint32_t) 1L << 25); + + h[0] = h0; + h[1] = h1; + h[2] = h2; + h[3] = h3; + h[4] = h4; + h[5] = h5; + h[6] = h6; + h[7] = h7; + h[8] = h8; + h[9] = h9; +} + +/* + Goal: Output h0+...+2^255 h10-2^255 q, which is between 0 and 2^255-20. + Have h0+...+2^230 h9 between 0 and 2^255-1; + evidently 2^255 h10-2^255 q = 0. + + Goal: Output h0+...+2^230 h9. + */ + +void +fe25519_tobytes(unsigned char *s, const fe25519 h) +{ + fe25519 t; + + fe25519_reduce(t, h); + s[0] = t[0] >> 0; + s[1] = t[0] >> 8; + s[2] = t[0] >> 16; + s[3] = (t[0] >> 24) | (t[1] * ((uint32_t) 1 << 2)); + s[4] = t[1] >> 6; + s[5] = t[1] >> 14; + s[6] = (t[1] >> 22) | (t[2] * ((uint32_t) 1 << 3)); + s[7] = t[2] >> 5; + s[8] = t[2] >> 13; + s[9] = (t[2] >> 21) | (t[3] * ((uint32_t) 1 << 5)); + s[10] = t[3] >> 3; + s[11] = t[3] >> 11; + s[12] = (t[3] >> 19) | (t[4] * ((uint32_t) 1 << 6)); + s[13] = t[4] >> 2; + s[14] = t[4] >> 10; + s[15] = t[4] >> 18; + s[16] = t[5] >> 0; + s[17] = t[5] >> 8; + s[18] = t[5] >> 16; + s[19] = (t[5] >> 24) | (t[6] * ((uint32_t) 1 << 1)); + s[20] = t[6] >> 7; + s[21] = t[6] >> 15; + s[22] = (t[6] >> 23) | (t[7] * ((uint32_t) 1 << 3)); + s[23] = t[7] >> 5; + s[24] = t[7] >> 13; + s[25] = (t[7] >> 21) | (t[8] * ((uint32_t) 1 << 4)); + s[26] = t[8] >> 4; + s[27] = t[8] >> 12; + s[28] = (t[8] >> 20) | (t[9] * ((uint32_t) 1 << 6)); + s[29] = t[9] >> 2; + s[30] = t[9] >> 10; + s[31] = t[9] >> 18; +} diff --git a/libs/libsodium/src/crypto_core/ed25519/ref10/fe_51/base.h b/libs/libsodium/src/crypto_core/ed25519/ref10/fe_51/base.h new file mode 100644 index 0000000000..6b3b833e7a --- /dev/null +++ b/libs/libsodium/src/crypto_core/ed25519/ref10/fe_51/base.h @@ -0,0 +1,1344 @@ +{ /* 0/31 */ + { + { 1288382639258501, 245678601348599, 269427782077623, 1462984067271730, 137412439391563 }, + { 62697248952638, 204681361388450, 631292143396476, 338455783676468, 1213667448819585 }, + { 301289933810280, 1259582250014073, 1422107436869536, 796239922652654, 1953934009299142 } + }, + { + { 1380971894829527, 790832306631236, 2067202295274102, 1995808275510000, 1566530869037010 }, + { 463307831301544, 432984605774163, 1610641361907204, 750899048855000, 1894842303421586 }, + { 748439484463711, 1033211726465151, 1396005112841647, 1611506220286469, 1972177495910992 } + }, + { + { 1601611775252272, 1720807796594148, 1132070835939856, 1260455018889551, 2147779492816911 }, + { 316559037616741, 2177824224946892, 1459442586438991, 1461528397712656, 751590696113597 }, + { 1850748884277385, 1200145853858453, 1068094770532492, 672251375690438, 1586055907191707 } + }, + { + { 934282339813791, 1846903124198670, 1172395437954843, 1007037127761661, 1830588347719256 }, + { 1694390458783935, 1735906047636159, 705069562067493, 648033061693059, 696214010414170 }, + { 1121406372216585, 192876649532226, 190294192191717, 1994165897297032, 2245000007398739 } + }, + { + { 769950342298419, 132954430919746, 844085933195555, 974092374476333, 726076285546016 }, + { 425251763115706, 608463272472562, 442562545713235, 837766094556764, 374555092627893 }, + { 1086255230780037, 274979815921559, 1960002765731872, 929474102396301, 1190409889297339 } + }, + { + { 1388594989461809, 316767091099457, 394298842192982, 1230079486801005, 1440737038838979 }, + { 7380825640100, 146210432690483, 304903576448906, 1198869323871120, 997689833219095 }, + { 1181317918772081, 114573476638901, 262805072233344, 265712217171332, 294181933805782 } + }, + { + { 665000864555967, 2065379846933859, 370231110385876, 350988370788628, 1233371373142985 }, + { 2019367628972465, 676711900706637, 110710997811333, 1108646842542025, 517791959672113 }, + { 965130719900578, 247011430587952, 526356006571389, 91986625355052, 2157223321444601 } + }, + { + { 2068619540119183, 1966274918058806, 957728544705549, 729906502578991, 159834893065166 }, + { 2073601412052185, 31021124762708, 264500969797082, 248034690651703, 1030252227928288 }, + { 551790716293402, 1989538725166328, 801169423371717, 2052451893578887, 678432056995012 } + } +}, +{ /* 1/31 */ + { + { 1368953770187805, 790347636712921, 437508475667162, 2142576377050580, 1932081720066286 }, + { 953638594433374, 1092333936795051, 1419774766716690, 805677984380077, 859228993502513 }, + { 1200766035879111, 20142053207432, 1465634435977050, 1645256912097844, 295121984874596 } + }, + { + { 1735718747031557, 1248237894295956, 1204753118328107, 976066523550493, 65943769534592 }, + { 1060098822528990, 1586825862073490, 212301317240126, 1975302711403555, 666724059764335 }, + { 1091990273418756, 1572899409348578, 80968014455247, 306009358661350, 1520450739132526 } + }, + { + { 1480517209436112, 1511153322193952, 1244343858991172, 304788150493241, 369136856496443 }, + { 2151330273626164, 762045184746182, 1688074332551515, 823046109005759, 907602769079491 }, + { 2047386910586836, 168470092900250, 1552838872594810, 340951180073789, 360819374702533 } + }, + { + { 1982622644432056, 2014393600336956, 128909208804214, 1617792623929191, 105294281913815 }, + { 980234343912898, 1712256739246056, 588935272190264, 204298813091998, 841798321043288 }, + { 197561292938973, 454817274782871, 1963754960082318, 2113372252160468, 971377527342673 } + }, + { + { 164699448829328, 3127451757672, 1199504971548753, 1766155447043652, 1899238924683527 }, + { 732262946680281, 1674412764227063, 2182456405662809, 1350894754474250, 558458873295247 }, + { 2103305098582922, 1960809151316468, 715134605001343, 1454892949167181, 40827143824949 } + }, + { + { 1239289043050212, 1744654158124578, 758702410031698, 1796762995074688, 1603056663766 }, + { 2232056027107988, 987343914584615, 2115594492994461, 1819598072792159, 1119305654014850 }, + { 320153677847348, 939613871605645, 641883205761567, 1930009789398224, 329165806634126 } + }, + { + { 980930490474130, 1242488692177893, 1251446316964684, 1086618677993530, 1961430968465772 }, + { 276821765317453, 1536835591188030, 1305212741412361, 61473904210175, 2051377036983058 }, + { 833449923882501, 1750270368490475, 1123347002068295, 185477424765687, 278090826653186 } + }, + { + { 794524995833413, 1849907304548286, 53348672473145, 1272368559505217, 1147304168324779 }, + { 1504846112759364, 1203096289004681, 562139421471418, 274333017451844, 1284344053775441 }, + { 483048732424432, 2116063063343382, 30120189902313, 292451576741007, 1156379271702225 } + } +}, +{ /* 2/31 */ + { + { 928372153029038, 2147692869914564, 1455665844462196, 1986737809425946, 185207050258089 }, + { 137732961814206, 706670923917341, 1387038086865771, 1965643813686352, 1384777115696347 }, + { 481144981981577, 2053319313589856, 2065402289827512, 617954271490316, 1106602634668125 } + }, + { + { 696298019648792, 893299659040895, 1148636718636009, 26734077349617, 2203955659340681 }, + { 657390353372855, 998499966885562, 991893336905797, 810470207106761, 343139804608786 }, + { 791736669492960, 934767652997115, 824656780392914, 1759463253018643, 361530362383518 } + }, + { + { 2022541353055597, 2094700262587466, 1551008075025686, 242785517418164, 695985404963562 }, + { 1287487199965223, 2215311941380308, 1552928390931986, 1664859529680196, 1125004975265243 }, + { 677434665154918, 989582503122485, 1817429540898386, 1052904935475344, 1143826298169798 } + }, + { + { 367266328308408, 318431188922404, 695629353755355, 634085657580832, 24581612564426 }, + { 773360688841258, 1815381330538070, 363773437667376, 539629987070205, 783280434248437 }, + { 180820816194166, 168937968377394, 748416242794470, 1227281252254508, 1567587861004268 } + }, + { + { 478775558583645, 2062896624554807, 699391259285399, 358099408427873, 1277310261461761 }, + { 1984740906540026, 1079164179400229, 1056021349262661, 1659958556483663, 1088529069025527 }, + { 580736401511151, 1842931091388998, 1177201471228238, 2075460256527244, 1301133425678027 } + }, + { + { 1515728832059182, 1575261009617579, 1510246567196186, 191078022609704, 116661716289141 }, + { 1295295738269652, 1714742313707026, 545583042462581, 2034411676262552, 1513248090013606 }, + { 230710545179830, 30821514358353, 760704303452229, 390668103790604, 573437871383156 } + }, + { + { 1169380107545646, 263167233745614, 2022901299054448, 819900753251120, 2023898464874585 }, + { 2102254323485823, 1570832666216754, 34696906544624, 1993213739807337, 70638552271463 }, + { 894132856735058, 548675863558441, 845349339503395, 1942269668326667, 1615682209874691 } + }, + { + { 1287670217537834, 1222355136884920, 1846481788678694, 1150426571265110, 1613523400722047 }, + { 793388516527298, 1315457083650035, 1972286999342417, 1901825953052455, 338269477222410 }, + { 550201530671806, 778605267108140, 2063911101902983, 115500557286349, 2041641272971022 } + } +}, +{ /* 3/31 */ + { + { 717255318455100, 519313764361315, 2080406977303708, 541981206705521, 774328150311600 }, + { 261715221532238, 1795354330069993, 1496878026850283, 499739720521052, 389031152673770 }, + { 1997217696294013, 1717306351628065, 1684313917746180, 1644426076011410, 1857378133465451 } + }, + { + { 1475434724792648, 76931896285979, 1116729029771667, 2002544139318042, 725547833803938 }, + { 2022306639183567, 726296063571875, 315345054448644, 1058733329149221, 1448201136060677 }, + { 1710065158525665, 1895094923036397, 123988286168546, 1145519900776355, 1607510767693874 } + }, + { + { 561605375422540, 1071733543815037, 131496498800990, 1946868434569999, 828138133964203 }, + { 1548495173745801, 442310529226540, 998072547000384, 553054358385281, 644824326376171 }, + { 1445526537029440, 2225519789662536, 914628859347385, 1064754194555068, 1660295614401091 } + }, + { + { 1199690223111956, 24028135822341, 66638289244341, 57626156285975, 565093967979607 }, + { 876926774220824, 554618976488214, 1012056309841565, 839961821554611, 1414499340307677 }, + { 703047626104145, 1266841406201770, 165556500219173, 486991595001879, 1011325891650656 } + }, + { + { 1622861044480487, 1156394801573634, 1869132565415504, 327103985777730, 2095342781472284 }, + { 334886927423922, 489511099221528, 129160865966726, 1720809113143481, 619700195649254 }, + { 1646545795166119, 1758370782583567, 714746174550637, 1472693650165135, 898994790308209 } + }, + { + { 333403773039279, 295772542452938, 1693106465353610, 912330357530760, 471235657950362 }, + { 1811196219982022, 1068969825533602, 289602974833439, 1988956043611592, 863562343398367 }, + { 906282429780072, 2108672665779781, 432396390473936, 150625823801893, 1708930497638539 } + }, + { + { 925664675702328, 21416848568684, 1831436641861340, 601157008940113, 371818055044496 }, + { 1479786007267725, 1738881859066675, 68646196476567, 2146507056100328, 1247662817535471 }, + { 52035296774456, 939969390708103, 312023458773250, 59873523517659, 1231345905848899 } + }, + { + { 643355106415761, 290186807495774, 2013561737429023, 319648069511546, 393736678496162 }, + { 129358342392716, 1932811617704777, 1176749390799681, 398040349861790, 1170779668090425 }, + { 2051980782668029, 121859921510665, 2048329875753063, 1235229850149665, 519062146124755 } + } +}, +{ /* 4/31 */ + { + { 1608170971973096, 415809060360428, 1350468408164766, 2038620059057678, 1026904485989112 }, + { 1837656083115103, 1510134048812070, 906263674192061, 1821064197805734, 565375124676301 }, + { 578027192365650, 2034800251375322, 2128954087207123, 478816193810521, 2196171989962750 } + }, + { + { 1633188840273139, 852787172373708, 1548762607215796, 1266275218902681, 1107218203325133 }, + { 462189358480054, 1784816734159228, 1611334301651368, 1303938263943540, 707589560319424 }, + { 1038829280972848, 38176604650029, 753193246598573, 1136076426528122, 595709990562434 } + }, + { + { 1408451820859834, 2194984964010833, 2198361797561729, 1061962440055713, 1645147963442934 }, + { 4701053362120, 1647641066302348, 1047553002242085, 1923635013395977, 206970314902065 }, + { 1750479161778571, 1362553355169293, 1891721260220598, 966109370862782, 1024913988299801 } + }, + { + { 212699049131723, 1117950018299775, 1873945661751056, 1403802921984058, 130896082652698 }, + { 636808533673210, 1262201711667560, 390951380330599, 1663420692697294, 561951321757406 }, + { 520731594438141, 1446301499955692, 273753264629267, 1565101517999256, 1019411827004672 } + }, + { + { 926527492029409, 1191853477411379, 734233225181171, 184038887541270, 1790426146325343 }, + { 1464651961852572, 1483737295721717, 1519450561335517, 1161429831763785, 405914998179977 }, + { 996126634382301, 796204125879525, 127517800546509, 344155944689303, 615279846169038 } + }, + { + { 738724080975276, 2188666632415296, 1961313708559162, 1506545807547587, 1151301638969740 }, + { 622917337413835, 1218989177089035, 1284857712846592, 970502061709359, 351025208117090 }, + { 2067814584765580, 1677855129927492, 2086109782475197, 235286517313238, 1416314046739645 } + }, + { + { 586844262630358, 307444381952195, 458399356043426, 602068024507062, 1028548203415243 }, + { 678489922928203, 2016657584724032, 90977383049628, 1026831907234582, 615271492942522 }, + { 301225714012278, 1094837270268560, 1202288391010439, 644352775178361, 1647055902137983 } + }, + { + { 1210746697896478, 1416608304244708, 686487477217856, 1245131191434135, 1051238336855737 }, + { 1135604073198207, 1683322080485474, 769147804376683, 2086688130589414, 900445683120379 }, + { 1971518477615628, 401909519527336, 448627091057375, 1409486868273821, 1214789035034363 } + } +}, +{ /* 5/31 */ + { + { 1364039144731711, 1897497433586190, 2203097701135459, 145461396811251, 1349844460790699 }, + { 1045230323257973, 818206601145807, 630513189076103, 1672046528998132, 807204017562437 }, + { 439961968385997, 386362664488986, 1382706320807688, 309894000125359, 2207801346498567 } + }, + { + { 1229004686397588, 920643968530863, 123975893911178, 681423993215777, 1400559197080973 }, + { 2003766096898049, 170074059235165, 1141124258967971, 1485419893480973, 1573762821028725 }, + { 729905708611432, 1270323270673202, 123353058984288, 426460209632942, 2195574535456672 } + }, + { + { 1271140255321235, 2044363183174497, 52125387634689, 1445120246694705, 942541986339084 }, + { 1761608437466135, 583360847526804, 1586706389685493, 2157056599579261, 1170692369685772 }, + { 871476219910823, 1878769545097794, 2241832391238412, 548957640601001, 690047440233174 } + }, + { + { 297194732135507, 1366347803776820, 1301185512245601, 561849853336294, 1533554921345731 }, + { 999628998628371, 1132836708493400, 2084741674517453, 469343353015612, 678782988708035 }, + { 2189427607417022, 699801937082607, 412764402319267, 1478091893643349, 2244675696854460 } + }, + { + { 1712292055966563, 204413590624874, 1405738637332841, 408981300829763, 861082219276721 }, + { 508561155940631, 966928475686665, 2236717801150132, 424543858577297, 2089272956986143 }, + { 221245220129925, 1156020201681217, 491145634799213, 542422431960839, 828100817819207 } + }, + { + { 153756971240384, 1299874139923977, 393099165260502, 1058234455773022, 996989038681183 }, + { 559086812798481, 573177704212711, 1629737083816402, 1399819713462595, 1646954378266038 }, + { 1887963056288059, 228507035730124, 1468368348640282, 930557653420194, 613513962454686 } + }, + { + { 1224529808187553, 1577022856702685, 2206946542980843, 625883007765001, 279930793512158 }, + { 1076287717051609, 1114455570543035, 187297059715481, 250446884292121, 1885187512550540 }, + { 902497362940219, 76749815795675, 1657927525633846, 1420238379745202, 1340321636548352 } + }, + { + { 1129576631190784, 1281994010027327, 996844254743018, 257876363489249, 1150850742055018 }, + { 628740660038789, 1943038498527841, 467786347793886, 1093341428303375, 235413859513003 }, + { 237425418909360, 469614029179605, 1512389769174935, 1241726368345357, 441602891065214 } + } +}, +{ /* 6/31 */ + { + { 1736417953058555, 726531315520508, 1833335034432527, 1629442561574747, 624418919286085 }, + { 1960754663920689, 497040957888962, 1909832851283095, 1271432136996826, 2219780368020940 }, + { 1537037379417136, 1358865369268262, 2130838645654099, 828733687040705, 1999987652890901 } + }, + { + { 629042105241814, 1098854999137608, 887281544569320, 1423102019874777, 7911258951561 }, + { 1811562332665373, 1501882019007673, 2213763501088999, 359573079719636, 36370565049116 }, + { 218907117361280, 1209298913016966, 1944312619096112, 1130690631451061, 1342327389191701 } + }, + { + { 1369976867854704, 1396479602419169, 1765656654398856, 2203659200586299, 998327836117241 }, + { 2230701885562825, 1348173180338974, 2172856128624598, 1426538746123771, 444193481326151 }, + { 784210426627951, 918204562375674, 1284546780452985, 1324534636134684, 1872449409642708 } + }, + { + { 319638829540294, 596282656808406, 2037902696412608, 1557219121643918, 341938082688094 }, + { 1901860206695915, 2004489122065736, 1625847061568236, 973529743399879, 2075287685312905 }, + { 1371853944110545, 1042332820512553, 1949855697918254, 1791195775521505, 37487364849293 } + }, + { + { 687200189577855, 1082536651125675, 644224940871546, 340923196057951, 343581346747396 }, + { 2082717129583892, 27829425539422, 145655066671970, 1690527209845512, 1865260509673478 }, + { 1059729620568824, 2163709103470266, 1440302280256872, 1769143160546397, 869830310425069 } + }, + { + { 1609516219779025, 777277757338817, 2101121130363987, 550762194946473, 1905542338659364 }, + { 2024821921041576, 426948675450149, 595133284085473, 471860860885970, 600321679413000 }, + { 598474602406721, 1468128276358244, 1191923149557635, 1501376424093216, 1281662691293476 } + }, + { + { 1721138489890707, 1264336102277790, 433064545421287, 1359988423149466, 1561871293409447 }, + { 719520245587143, 393380711632345, 132350400863381, 1543271270810729, 1819543295798660 }, + { 396397949784152, 1811354474471839, 1362679985304303, 2117033964846756, 498041172552279 } + }, + { + { 1812471844975748, 1856491995543149, 126579494584102, 1036244859282620, 1975108050082550 }, + { 650623932407995, 1137551288410575, 2125223403615539, 1725658013221271, 2134892965117796 }, + { 522584000310195, 1241762481390450, 1743702789495384, 2227404127826575, 1686746002148897 } + } +}, +{ /* 7/31 */ + { + { 427904865186312, 1703211129693455, 1585368107547509, 1436984488744336, 761188534613978 }, + { 318101947455002, 248138407995851, 1481904195303927, 309278454311197, 1258516760217879 }, + { 1275068538599310, 513726919533379, 349926553492294, 688428871968420, 1702400196000666 } + }, + { + { 1061864036265233, 961611260325381, 321859632700838, 1045600629959517, 1985130202504038 }, + { 1558816436882417, 1962896332636523, 1337709822062152, 1501413830776938, 294436165831932 }, + { 818359826554971, 1862173000996177, 626821592884859, 573655738872376, 1749691246745455 } + }, + { + { 1988022651432119, 1082111498586040, 1834020786104821, 1454826876423687, 692929915223122 }, + { 2146513703733331, 584788900394667, 464965657279958, 2183973639356127, 238371159456790 }, + { 1129007025494441, 2197883144413266, 265142755578169, 971864464758890, 1983715884903702 } + }, + { + { 1291366624493075, 381456718189114, 1711482489312444, 1815233647702022, 892279782992467 }, + { 444548969917454, 1452286453853356, 2113731441506810, 645188273895859, 810317625309512 }, + { 2242724082797924, 1373354730327868, 1006520110883049, 2147330369940688, 1151816104883620 } + }, + { + { 1745720200383796, 1911723143175317, 2056329390702074, 355227174309849, 879232794371100 }, + { 163723479936298, 115424889803150, 1156016391581227, 1894942220753364, 1970549419986329 }, + { 681981452362484, 267208874112496, 1374683991933094, 638600984916117, 646178654558546 } + }, + { + { 13378654854251, 106237307029567, 1944412051589651, 1841976767925457, 230702819835573 }, + { 260683893467075, 854060306077237, 913639551980112, 4704576840123, 280254810808712 }, + { 715374893080287, 1173334812210491, 1806524662079626, 1894596008000979, 398905715033393 } + }, + { + { 500026409727661, 1596431288195371, 1420380351989370, 985211561521489, 392444930785633 }, + { 2096421546958141, 1922523000950363, 789831022876840, 427295144688779, 320923973161730 }, + { 1927770723575450, 1485792977512719, 1850996108474547, 551696031508956, 2126047405475647 } + }, + { + { 2112099158080148, 742570803909715, 6484558077432, 1951119898618916, 93090382703416 }, + { 383905201636970, 859946997631870, 855623867637644, 1017125780577795, 794250831877809 }, + { 77571826285752, 999304298101753, 487841111777762, 1038031143212339, 339066367948762 } + } +}, +{ /* 8/31 */ + { + { 674994775520533, 266035846330789, 826951213393478, 1405007746162285, 1781791018620876 }, + { 1001412661522686, 348196197067298, 1666614366723946, 888424995032760, 580747687801357 }, + { 1939560076207777, 1409892634407635, 552574736069277, 383854338280405, 190706709864139 } + }, + { + { 2177087163428741, 1439255351721944, 1208070840382793, 2230616362004769, 1396886392021913 }, + { 676962063230039, 1880275537148808, 2046721011602706, 888463247083003, 1318301552024067 }, + { 1466980508178206, 617045217998949, 652303580573628, 757303753529064, 207583137376902 } + }, + { + { 1511056752906902, 105403126891277, 493434892772846, 1091943425335976, 1802717338077427 }, + { 1853982405405128, 1878664056251147, 1528011020803992, 1019626468153565, 1128438412189035 }, + { 1963939888391106, 293456433791664, 697897559513649, 985882796904380, 796244541237972 } + }, + { + { 416770998629779, 389655552427054, 1314476859406756, 1749382513022778, 1161905598739491 }, + { 1428358296490651, 1027115282420478, 304840698058337, 441410174026628, 1819358356278573 }, + { 204943430200135, 1554861433819175, 216426658514651, 264149070665950, 2047097371738319 } + }, + { + { 1934415182909034, 1393285083565062, 516409331772960, 1157690734993892, 121039666594268 }, + { 662035583584445, 286736105093098, 1131773000510616, 818494214211439, 472943792054479 }, + { 665784778135882, 1893179629898606, 808313193813106, 276797254706413, 1563426179676396 } + }, + { + { 945205108984232, 526277562959295, 1324180513733566, 1666970227868664, 153547609289173 }, + { 2031433403516252, 203996615228162, 170487168837083, 981513604791390, 843573964916831 }, + { 1476570093962618, 838514669399805, 1857930577281364, 2017007352225784, 317085545220047 } + }, + { + { 1461557121912842, 1600674043318359, 2157134900399597, 1670641601940616, 127765583803283 }, + { 1293543509393474, 2143624609202546, 1058361566797508, 214097127393994, 946888515472729 }, + { 357067959932916, 1290876214345711, 521245575443703, 1494975468601005, 800942377643885 } + }, + { + { 566116659100033, 820247422481740, 994464017954148, 327157611686365, 92591318111744 }, + { 617256647603209, 1652107761099439, 1857213046645471, 1085597175214970, 817432759830522 }, + { 771808161440705, 1323510426395069, 680497615846440, 851580615547985, 1320806384849017 } + } +}, +{ /* 9/31 */ + { + { 1219260086131915, 647169006596815, 79601124759706, 2161724213426748, 404861897060198 }, + { 1327968293887866, 1335500852943256, 1401587164534264, 558137311952440, 1551360549268902 }, + { 417621685193956, 1429953819744454, 396157358457099, 1940470778873255, 214000046234152 } + }, + { + { 1268047918491973, 2172375426948536, 1533916099229249, 1761293575457130, 1590622667026765 }, + { 1627072914981959, 2211603081280073, 1912369601616504, 1191770436221309, 2187309757525860 }, + { 1149147819689533, 378692712667677, 828475842424202, 2218619146419342, 70688125792186 } + }, + { + { 1299739417079761, 1438616663452759, 1536729078504412, 2053896748919838, 1008421032591246 }, + { 2040723824657366, 399555637875075, 632543375452995, 872649937008051, 1235394727030233 }, + { 2211311599327900, 2139787259888175, 938706616835350, 12609661139114, 2081897930719789 } + }, + { + { 1324994503390450, 336982330582631, 1183998925654177, 1091654665913274, 48727673971319 }, + { 1845522914617879, 1222198248335542, 150841072760134, 1927029069940982, 1189913404498011 }, + { 1079559557592645, 2215338383666441, 1903569501302605, 49033973033940, 305703433934152 } + }, + { + { 94653405416909, 1386121349852999, 1062130477891762, 36553947479274, 833669648948846 }, + { 1432015813136298, 440364795295369, 1395647062821501, 1976874522764578, 934452372723352 }, + { 1296625309219774, 2068273464883862, 1858621048097805, 1492281814208508, 2235868981918946 } + }, + { + { 1490330266465570, 1858795661361448, 1436241134969763, 294573218899647, 1208140011028933 }, + { 1282462923712748, 741885683986255, 2027754642827561, 518989529541027, 1826610009555945 }, + { 1525827120027511, 723686461809551, 1597702369236987, 244802101764964, 1502833890372311 } + }, + { + { 113622036244513, 1233740067745854, 674109952278496, 2114345180342965, 166764512856263 }, + { 2041668749310338, 2184405322203901, 1633400637611036, 2110682505536899, 2048144390084644 }, + { 503058759232932, 760293024620937, 2027152777219493, 666858468148475, 1539184379870952 } + }, + { + { 1916168475367211, 915626432541343, 883217071712575, 363427871374304, 1976029821251593 }, + { 678039535434506, 570587290189340, 1605302676614120, 2147762562875701, 1706063797091704 }, + { 1439489648586438, 2194580753290951, 832380563557396, 561521973970522, 584497280718389 } + } +}, +{ /* 10/31 */ + { + { 187989455492609, 681223515948275, 1933493571072456, 1872921007304880, 488162364135671 }, + { 1413466089534451, 410844090765630, 1397263346404072, 408227143123410, 1594561803147811 }, + { 2102170800973153, 719462588665004, 1479649438510153, 1097529543970028, 1302363283777685 } + }, + { + { 942065717847195, 1069313679352961, 2007341951411051, 70973416446291, 1419433790163706 }, + { 1146565545556377, 1661971299445212, 406681704748893, 564452436406089, 1109109865829139 }, + { 2214421081775077, 1165671861210569, 1890453018796184, 3556249878661, 442116172656317 } + }, + { + { 753830546620811, 1666955059895019, 1530775289309243, 1119987029104146, 2164156153857580 }, + { 615171919212796, 1523849404854568, 854560460547503, 2067097370290715, 1765325848586042 }, + { 1094538949313667, 1796592198908825, 870221004284388, 2025558921863561, 1699010892802384 } + }, + { + { 1951351290725195, 1916457206844795, 198025184438026, 1909076887557595, 1938542290318919 }, + { 1014323197538413, 869150639940606, 1756009942696599, 1334952557375672, 1544945379082874 }, + { 764055910920305, 1603590757375439, 146805246592357, 1843313433854297, 954279890114939 } + }, + { + { 80113526615750, 764536758732259, 1055139345100233, 469252651759390, 617897512431515 }, + { 74497112547268, 740094153192149, 1745254631717581, 727713886503130, 1283034364416928 }, + { 525892105991110, 1723776830270342, 1476444848991936, 573789489857760, 133864092632978 } + }, + { + { 542611720192581, 1986812262899321, 1162535242465837, 481498966143464, 544600533583622 }, + { 64123227344372, 1239927720647794, 1360722983445904, 222610813654661, 62429487187991 }, + { 1793193323953132, 91096687857833, 70945970938921, 2158587638946380, 1537042406482111 } + }, + { + { 1895854577604609, 1394895708949416, 1728548428495944, 1140864900240149, 563645333603061 }, + { 141358280486863, 91435889572504, 1087208572552643, 1829599652522921, 1193307020643647 }, + { 1611230858525381, 950720175540785, 499589887488610, 2001656988495019, 88977313255908 } + }, + { + { 1189080501479658, 2184348804772597, 1040818725742319, 2018318290311834, 1712060030915354 }, + { 873966876953756, 1090638350350440, 1708559325189137, 672344594801910, 1320437969700239 }, + { 1508590048271766, 1131769479776094, 101550868699323, 428297785557897, 561791648661744 } + } +}, +{ /* 11/31 */ + { + { 756417570499462, 237882279232602, 2136263418594016, 1701968045454886, 703713185137472 }, + { 1781187809325462, 1697624151492346, 1381393690939988, 175194132284669, 1483054666415238 }, + { 2175517777364616, 708781536456029, 955668231122942, 1967557500069555, 2021208005604118 } + }, + { + { 1115135966606887, 224217372950782, 915967306279222, 593866251291540, 561747094208006 }, + { 1443163092879439, 391875531646162, 2180847134654632, 464538543018753, 1594098196837178 }, + { 850858855888869, 319436476624586, 327807784938441, 740785849558761, 17128415486016 } + }, + { + { 2132756334090067, 536247820155645, 48907151276867, 608473197600695, 1261689545022784 }, + { 1525176236978354, 974205476721062, 293436255662638, 148269621098039, 137961998433963 }, + { 1121075518299410, 2071745529082111, 1265567917414828, 1648196578317805, 496232102750820 } + }, + { + { 122321229299801, 1022922077493685, 2001275453369484, 2017441881607947, 993205880778002 }, + { 654925550560074, 1168810995576858, 575655959430926, 905758704861388, 496774564663534 }, + { 1954109525779738, 2117022646152485, 338102630417180, 1194140505732026, 107881734943492 } + }, + { + { 1714785840001267, 2036500018681589, 1876380234251966, 2056717182974196, 1645855254384642 }, + { 106431476499341, 62482972120563, 1513446655109411, 807258751769522, 538491469114 }, + { 2002850762893643, 1243624520538135, 1486040410574605, 2184752338181213, 378495998083531 } + }, + { + { 922510868424903, 1089502620807680, 402544072617374, 1131446598479839, 1290278588136533 }, + { 1867998812076769, 715425053580701, 39968586461416, 2173068014586163, 653822651801304 }, + { 162892278589453, 182585796682149, 75093073137630, 497037941226502, 133871727117371 } + }, + { + { 1914596576579670, 1608999621851578, 1987629837704609, 1519655314857977, 1819193753409464 }, + { 1949315551096831, 1069003344994464, 1939165033499916, 1548227205730856, 1933767655861407 }, + { 1730519386931635, 1393284965610134, 1597143735726030, 416032382447158, 1429665248828629 } + }, + { + { 360275475604565, 547835731063078, 215360904187529, 596646739879007, 332709650425085 }, + { 47602113726801, 1522314509708010, 437706261372925, 814035330438027, 335930650933545 }, + { 1291597595523886, 1058020588994081, 402837842324045, 1363323695882781, 2105763393033193 } + } +}, +{ /* 12/31 */ + { + { 109521982566564, 1715257748585139, 1112231216891516, 2046641005101484, 134249157157013 }, + { 2156991030936798, 2227544497153325, 1869050094431622, 754875860479115, 1754242344267058 }, + { 1846089562873800, 98894784984326, 1412430299204844, 171351226625762, 1100604760929008 } + }, + { + { 84172382130492, 499710970700046, 425749630620778, 1762872794206857, 612842602127960 }, + { 868309334532756, 1703010512741873, 1952690008738057, 4325269926064, 2071083554962116 }, + { 523094549451158, 401938899487815, 1407690589076010, 2022387426254453, 158660516411257 } + }, + { + { 612867287630009, 448212612103814, 571629077419196, 1466796750919376, 1728478129663858 }, + { 1723848973783452, 2208822520534681, 1718748322776940, 1974268454121942, 1194212502258141 }, + { 1254114807944608, 977770684047110, 2010756238954993, 1783628927194099, 1525962994408256 } + }, + { + { 232464058235826, 1948628555342434, 1835348780427694, 1031609499437291, 64472106918373 }, + { 767338676040683, 754089548318405, 1523192045639075, 435746025122062, 512692508440385 }, + { 1255955808701983, 1700487367990941, 1166401238800299, 1175121994891534, 1190934801395380 } + }, + { + { 349144008168292, 1337012557669162, 1475912332999108, 1321618454900458, 47611291904320 }, + { 877519947135419, 2172838026132651, 272304391224129, 1655143327559984, 886229406429814 }, + { 375806028254706, 214463229793940, 572906353144089, 572168269875638, 697556386112979 } + }, + { + { 1168827102357844, 823864273033637, 2071538752104697, 788062026895924, 599578340743362 }, + { 1948116082078088, 2054898304487796, 2204939184983900, 210526805152138, 786593586607626 }, + { 1915320147894736, 156481169009469, 655050471180417, 592917090415421, 2165897438660879 } + }, + { + { 1726336468579724, 1119932070398949, 1929199510967666, 33918788322959, 1836837863503150 }, + { 829996854845988, 217061778005138, 1686565909803640, 1346948817219846, 1723823550730181 }, + { 384301494966394, 687038900403062, 2211195391021739, 254684538421383, 1245698430589680 } + }, + { + { 1247567493562688, 1978182094455847, 183871474792955, 806570235643435, 288461518067916 }, + { 1449077384734201, 38285445457996, 2136537659177832, 2146493000841573, 725161151123125 }, + { 1201928866368855, 800415690605445, 1703146756828343, 997278587541744, 1858284414104014 } + } +}, +{ /* 13/31 */ + { + { 356468809648877, 782373916933152, 1718002439402870, 1392222252219254, 663171266061951 }, + { 759628738230460, 1012693474275852, 353780233086498, 246080061387552, 2030378857679162 }, + { 2040672435071076, 888593182036908, 1298443657189359, 1804780278521327, 354070726137060 } + }, + { + { 1894938527423184, 1463213041477277, 474410505497651, 247294963033299, 877975941029128 }, + { 207937160991127, 12966911039119, 820997788283092, 1010440472205286, 1701372890140810 }, + { 218882774543183, 533427444716285, 1233243976733245, 435054256891319, 1509568989549904 } + }, + { + { 1888838535711826, 1052177758340622, 1213553803324135, 169182009127332, 463374268115872 }, + { 299137589460312, 1594371588983567, 868058494039073, 257771590636681, 1805012993142921 }, + { 1806842755664364, 2098896946025095, 1356630998422878, 1458279806348064, 347755825962072 } + }, + { + { 1402334161391744, 1560083671046299, 1008585416617747, 1147797150908892, 1420416683642459 }, + { 665506704253369, 273770475169863, 799236974202630, 848328990077558, 1811448782807931 }, + { 1468412523962641, 771866649897997, 1931766110147832, 799561180078482, 524837559150077 } + }, + { + { 2223212657821850, 630416247363666, 2144451165500328, 816911130947791, 1024351058410032 }, + { 1266603897524861, 156378408858100, 1275649024228779, 447738405888420, 253186462063095 }, + { 2022215964509735, 136144366993649, 1800716593296582, 1193970603800203, 871675847064218 } + }, + { + { 1862751661970328, 851596246739884, 1519315554814041, 1542798466547449, 1417975335901520 }, + { 1228168094547481, 334133883362894, 587567568420081, 433612590281181, 603390400373205 }, + { 121893973206505, 1843345804916664, 1703118377384911, 497810164760654, 101150811654673 } + }, + { + { 458346255946468, 290909935619344, 1452768413850679, 550922875254215, 1537286854336538 }, + { 584322311184395, 380661238802118, 114839394528060, 655082270500073, 2111856026034852 }, + { 996965581008991, 2148998626477022, 1012273164934654, 1073876063914522, 1688031788934939 } + }, + { + { 923487018849600, 2085106799623355, 528082801620136, 1606206360876188, 735907091712524 }, + { 1697697887804317, 1335343703828273, 831288615207040, 949416685250051, 288760277392022 }, + { 1419122478109648, 1325574567803701, 602393874111094, 2107893372601700, 1314159682671307 } + } +}, +{ /* 14/31 */ + { + { 2201150872731804, 2180241023425241, 97663456423163, 1633405770247824, 848945042443986 }, + { 1173339555550611, 818605084277583, 47521504364289, 924108720564965, 735423405754506 }, + { 830104860549448, 1886653193241086, 1600929509383773, 1475051275443631, 286679780900937 } + }, + { + { 1577111294832995, 1030899169768747, 144900916293530, 1964672592979567, 568390100955250 }, + { 278388655910247, 487143369099838, 927762205508727, 181017540174210, 1616886700741287 }, + { 1191033906638969, 940823957346562, 1606870843663445, 861684761499847, 658674867251089 } + }, + { + { 1875032594195546, 1427106132796197, 724736390962158, 901860512044740, 635268497268760 }, + { 622869792298357, 1903919278950367, 1922588621661629, 1520574711600434, 1087100760174640 }, + { 25465949416618, 1693639527318811, 1526153382657203, 125943137857169, 145276964043999 } + }, + { + { 214739857969358, 920212862967915, 1939901550972269, 1211862791775221, 85097515720120 }, + { 2006245852772938, 734762734836159, 254642929763427, 1406213292755966, 239303749517686 }, + { 1619678837192149, 1919424032779215, 1357391272956794, 1525634040073113, 1310226789796241 } + }, + { + { 1040763709762123, 1704449869235352, 605263070456329, 1998838089036355, 1312142911487502 }, + { 1996723311435669, 1844342766567060, 985455700466044, 1165924681400960, 311508689870129 }, + { 43173156290518, 2202883069785309, 1137787467085917, 1733636061944606, 1394992037553852 } + }, + { + { 670078326344559, 555655025059356, 471959386282438, 2141455487356409, 849015953823125 }, + { 2197214573372804, 794254097241315, 1030190060513737, 267632515541902, 2040478049202624 }, + { 1812516004670529, 1609256702920783, 1706897079364493, 258549904773295, 996051247540686 } + }, + { + { 1540374301420584, 1764656898914615, 1810104162020396, 923808779163088, 664390074196579 }, + { 1323460699404750, 1262690757880991, 871777133477900, 1060078894988977, 1712236889662886 }, + { 1696163952057966, 1391710137550823, 608793846867416, 1034391509472039, 1780770894075012 } + }, + { + { 1367603834210841, 2131988646583224, 890353773628144, 1908908219165595, 270836895252891 }, + { 597536315471731, 40375058742586, 1942256403956049, 1185484645495932, 312666282024145 }, + { 1919411405316294, 1234508526402192, 1066863051997083, 1008444703737597, 1348810787701552 } + } +}, +{ /* 15/31 */ + { + { 2102881477513865, 1570274565945361, 1573617900503708, 18662635732583, 2232324307922098 }, + { 1853931367696942, 8107973870707, 350214504129299, 775206934582587, 1752317649166792 }, + { 1417148368003523, 721357181628282, 505725498207811, 373232277872983, 261634707184480 } + }, + { + { 2186733281493267, 2250694917008620, 1014829812957440, 479998161452389, 83566193876474 }, + { 1268116367301224, 560157088142809, 802626839600444, 2210189936605713, 1129993785579988 }, + { 615183387352312, 917611676109240, 878893615973325, 978940963313282, 938686890583575 } + }, + { + { 522024729211672, 1045059315315808, 1892245413707790, 1907891107684253, 2059998109500714 }, + { 1799679152208884, 912132775900387, 25967768040979, 432130448590461, 274568990261996 }, + { 98698809797682, 2144627600856209, 1907959298569602, 811491302610148, 1262481774981493 } + }, + { + { 1791451399743152, 1713538728337276, 118349997257490, 1882306388849954, 158235232210248 }, + { 1217809823321928, 2173947284933160, 1986927836272325, 1388114931125539, 12686131160169 }, + { 1650875518872272, 1136263858253897, 1732115601395988, 734312880662190, 1252904681142109 } + }, + { + { 372986456113865, 525430915458171, 2116279931702135, 501422713587815, 1907002872974925 }, + { 803147181835288, 868941437997146, 316299302989663, 943495589630550, 571224287904572 }, + { 227742695588364, 1776969298667369, 628602552821802, 457210915378118, 2041906378111140 } + }, + { + { 815000523470260, 913085688728307, 1052060118271173, 1345536665214223, 541623413135555 }, + { 1580216071604333, 1877997504342444, 857147161260913, 703522726778478, 2182763974211603 }, + { 1870080310923419, 71988220958492, 1783225432016732, 615915287105016, 1035570475990230 } + }, + { + { 730987750830150, 857613889540280, 1083813157271766, 1002817255970169, 1719228484436074 }, + { 377616581647602, 1581980403078513, 804044118130621, 2034382823044191, 643844048472185 }, + { 176957326463017, 1573744060478586, 528642225008045, 1816109618372371, 1515140189765006 } + }, + { + { 1888911448245718, 1387110895611080, 1924503794066429, 1731539523700949, 2230378382645454 }, + { 443392177002051, 233793396845137, 2199506622312416, 1011858706515937, 974676837063129 }, + { 1846351103143623, 1949984838808427, 671247021915253, 1946756846184401, 1929296930380217 } + } +}, +{ /* 16/31 */ + { + { 849646212452002, 1410198775302919, 73767886183695, 1641663456615812, 762256272452411 }, + { 692017667358279, 723305578826727, 1638042139863265, 748219305990306, 334589200523901 }, + { 22893968530686, 2235758574399251, 1661465835630252, 925707319443452, 1203475116966621 } + }, + { + { 801299035785166, 1733292596726131, 1664508947088596, 467749120991922, 1647498584535623 }, + { 903105258014366, 427141894933047, 561187017169777, 1884330244401954, 1914145708422219 }, + { 1344191060517578, 1960935031767890, 1518838929955259, 1781502350597190, 1564784025565682 } + }, + { + { 673723351748086, 1979969272514923, 1175287312495508, 1187589090978666, 1881897672213940 }, + { 1917185587363432, 1098342571752737, 5935801044414, 2000527662351839, 1538640296181569 }, + { 2495540013192, 678856913479236, 224998292422872, 219635787698590, 1972465269000940 } + }, + { + { 271413961212179, 1353052061471651, 344711291283483, 2014925838520662, 2006221033113941 }, + { 194583029968109, 514316781467765, 829677956235672, 1676415686873082, 810104584395840 }, + { 1980510813313589, 1948645276483975, 152063780665900, 129968026417582, 256984195613935 } + }, + { + { 1860190562533102, 1936576191345085, 461100292705964, 1811043097042830, 957486749306835 }, + { 796664815624365, 1543160838872951, 1500897791837765, 1667315977988401, 599303877030711 }, + { 1151480509533204, 2136010406720455, 738796060240027, 319298003765044, 1150614464349587 } + }, + { + { 1731069268103150, 735642447616087, 1364750481334268, 417232839982871, 927108269127661 }, + { 1017222050227968, 1987716148359, 2234319589635701, 621282683093392, 2132553131763026 }, + { 1567828528453324, 1017807205202360, 565295260895298, 829541698429100, 307243822276582 } + }, + { + { 249079270936248, 1501514259790706, 947909724204848, 944551802437487, 552658763982480 }, + { 2089966982947227, 1854140343916181, 2151980759220007, 2139781292261749, 158070445864917 }, + { 1338766321464554, 1906702607371284, 1519569445519894, 115384726262267, 1393058953390992 } + }, + { + { 1364621558265400, 1512388234908357, 1926731583198686, 2041482526432505, 920401122333774 }, + { 1884844597333588, 601480070269079, 620203503079537, 1079527400117915, 1202076693132015 }, + { 840922919763324, 727955812569642, 1303406629750194, 522898432152867, 294161410441865 } + } +}, +{ /* 17/31 */ + { + { 353760790835310, 1598361541848743, 1122905698202299, 1922533590158905, 419107700666580 }, + { 359856369838236, 180914355488683, 861726472646627, 218807937262986, 575626773232501 }, + { 755467689082474, 909202735047934, 730078068932500, 936309075711518, 2007798262842972 } + }, + { + { 1609384177904073, 362745185608627, 1335318541768201, 800965770436248, 547877979267412 }, + { 984339177776787, 815727786505884, 1645154585713747, 1659074964378553, 1686601651984156 }, + { 1697863093781930, 599794399429786, 1104556219769607, 830560774794755, 12812858601017 } + }, + { + { 1168737550514982, 897832437380552, 463140296333799, 302564600022547, 2008360505135501 }, + { 1856930662813910, 678090852002597, 1920179140755167, 1259527833759868, 55540971895511 }, + { 1158643631044921, 476554103621892, 178447851439725, 1305025542653569, 103433927680625 } + }, + { + { 2176793111709008, 1576725716350391, 2009350167273523, 2012390194631546, 2125297410909580 }, + { 825403285195098, 2144208587560784, 1925552004644643, 1915177840006985, 1015952128947864 }, + { 1807108316634472, 1534392066433717, 347342975407218, 1153820745616376, 7375003497471 } + }, + { + { 983061001799725, 431211889901241, 2201903782961093, 817393911064341, 2214616493042167 }, + { 228567918409756, 865093958780220, 358083886450556, 159617889659320, 1360637926292598 }, + { 234147501399755, 2229469128637390, 2175289352258889, 1397401514549353, 1885288963089922 } + }, + { + { 1111762412951562, 252849572507389, 1048714233823341, 146111095601446, 1237505378776770 }, + { 1113790697840279, 1051167139966244, 1045930658550944, 2011366241542643, 1686166824620755 }, + { 1054097349305049, 1872495070333352, 182121071220717, 1064378906787311, 100273572924182 } + }, + { + { 1306410853171605, 1627717417672447, 50983221088417, 1109249951172250, 870201789081392 }, + { 104233794644221, 1548919791188248, 2224541913267306, 2054909377116478, 1043803389015153 }, + { 216762189468802, 707284285441622, 190678557969733, 973969342604308, 1403009538434867 } + }, + { + { 1279024291038477, 344776835218310, 273722096017199, 1834200436811442, 634517197663804 }, + { 343805853118335, 1302216857414201, 566872543223541, 2051138939539004, 321428858384280 }, + { 470067171324852, 1618629234173951, 2000092177515639, 7307679772789, 1117521120249968 } + } +}, +{ /* 18/31 */ + { + { 278151578291475, 1810282338562947, 1771599529530998, 1383659409671631, 685373414471841 }, + { 577009397403102, 1791440261786291, 2177643735971638, 174546149911960, 1412505077782326 }, + { 893719721537457, 1201282458018197, 1522349501711173, 58011597740583, 1130406465887139 } + }, + { + { 412607348255453, 1280455764199780, 2233277987330768, 14180080401665, 331584698417165 }, + { 262483770854550, 990511055108216, 526885552771698, 571664396646158, 354086190278723 }, + { 1820352417585487, 24495617171480, 1547899057533253, 10041836186225, 480457105094042 } + }, + { + { 2023310314989233, 637905337525881, 2106474638900687, 557820711084072, 1687858215057826 }, + { 1144168702609745, 604444390410187, 1544541121756138, 1925315550126027, 626401428894002 }, + { 1922168257351784, 2018674099908659, 1776454117494445, 956539191509034, 36031129147635 } + }, + { + { 544644538748041, 1039872944430374, 876750409130610, 710657711326551, 1216952687484972 }, + { 58242421545916, 2035812695641843, 2118491866122923, 1191684463816273, 46921517454099 }, + { 272268252444639, 1374166457774292, 2230115177009552, 1053149803909880, 1354288411641016 } + }, + { + { 1857910905368338, 1754729879288912, 885945464109877, 1516096106802166, 1602902393369811 }, + { 1193437069800958, 901107149704790, 999672920611411, 477584824802207, 364239578697845 }, + { 886299989548838, 1538292895758047, 1590564179491896, 1944527126709657, 837344427345298 } + }, + { + { 754558365378305, 1712186480903618, 1703656826337531, 750310918489786, 518996040250900 }, + { 1309847803895382, 1462151862813074, 211370866671570, 1544595152703681, 1027691798954090 }, + { 803217563745370, 1884799722343599, 1357706345069218, 2244955901722095, 730869460037413 } + }, + { + { 689299471295966, 1831210565161071, 1375187341585438, 1106284977546171, 1893781834054269 }, + { 696351368613042, 1494385251239250, 738037133616932, 636385507851544, 927483222611406 }, + { 1949114198209333, 1104419699537997, 783495707664463, 1747473107602770, 2002634765788641 } + }, + { + { 1607325776830197, 530883941415333, 1451089452727895, 1581691157083423, 496100432831154 }, + { 1068900648804224, 2006891997072550, 1134049269345549, 1638760646180091, 2055396084625778 }, + { 2222475519314561, 1870703901472013, 1884051508440561, 1344072275216753, 1318025677799069 } + } +}, +{ /* 19/31 */ + { + { 155711679280656, 681100400509288, 389811735211209, 2135723811340709, 408733211204125 }, + { 7813206966729, 194444201427550, 2071405409526507, 1065605076176312, 1645486789731291 }, + { 16625790644959, 1647648827778410, 1579910185572704, 436452271048548, 121070048451050 } + }, + { + { 1037263028552531, 568385780377829, 297953104144430, 1558584511931211, 2238221839292471 }, + { 190565267697443, 672855706028058, 338796554369226, 337687268493904, 853246848691734 }, + { 1763863028400139, 766498079432444, 1321118624818005, 69494294452268, 858786744165651 } + }, + { + { 1292056768563024, 1456632109855638, 1100631247050184, 1386133165675321, 1232898350193752 }, + { 366253102478259, 525676242508811, 1449610995265438, 1183300845322183, 185960306491545 }, + { 28315355815982, 460422265558930, 1799675876678724, 1969256312504498, 1051823843138725 } + }, + { + { 156914999361983, 1606148405719949, 1665208410108430, 317643278692271, 1383783705665320 }, + { 54684536365732, 2210010038536222, 1194984798155308, 535239027773705, 1516355079301361 }, + { 1484387703771650, 198537510937949, 2186282186359116, 617687444857508, 647477376402122 } + }, + { + { 2147715541830533, 500032538445817, 646380016884826, 352227855331122, 1488268620408052 }, + { 159386186465542, 1877626593362941, 618737197060512, 1026674284330807, 1158121760792685 }, + { 1744544377739822, 1964054180355661, 1685781755873170, 2169740670377448, 1286112621104591 } + }, + { + { 81977249784993, 1667943117713086, 1668983819634866, 1605016835177615, 1353960708075544 }, + { 1602253788689063, 439542044889886, 2220348297664483, 657877410752869, 157451572512238 }, + { 1029287186166717, 65860128430192, 525298368814832, 1491902500801986, 1461064796385400 } + }, + { + { 408216988729246, 2121095722306989, 913562102267595, 1879708920318308, 241061448436731 }, + { 1185483484383269, 1356339572588553, 584932367316448, 102132779946470, 1792922621116791 }, + { 1966196870701923, 2230044620318636, 1425982460745905, 261167817826569, 46517743394330 } + }, + { + { 107077591595359, 884959942172345, 27306869797400, 2224911448949390, 964352058245223 }, + { 1730194207717538, 431790042319772, 1831515233279467, 1372080552768581, 1074513929381760 }, + { 1450880638731607, 1019861580989005, 1229729455116861, 1174945729836143, 826083146840706 } + } +}, +{ /* 20/31 */ + { + { 1899935429242705, 1602068751520477, 940583196550370, 82431069053859, 1540863155745696 }, + { 2136688454840028, 2099509000964294, 1690800495246475, 1217643678575476, 828720645084218 }, + { 765548025667841, 462473984016099, 998061409979798, 546353034089527, 2212508972466858 } + }, + { + { 46575283771160, 892570971573071, 1281983193144090, 1491520128287375, 75847005908304 }, + { 1801436127943107, 1734436817907890, 1268728090345068, 167003097070711, 2233597765834956 }, + { 1997562060465113, 1048700225534011, 7615603985628, 1855310849546841, 2242557647635213 } + }, + { + { 1161017320376250, 492624580169043, 2169815802355237, 976496781732542, 1770879511019629 }, + { 1357044908364776, 729130645262438, 1762469072918979, 1365633616878458, 181282906404941 }, + { 1080413443139865, 1155205815510486, 1848782073549786, 622566975152580, 124965574467971 } + }, + { + { 1184526762066993, 247622751762817, 692129017206356, 820018689412496, 2188697339828085 }, + { 2020536369003019, 202261491735136, 1053169669150884, 2056531979272544, 778165514694311 }, + { 237404399610207, 1308324858405118, 1229680749538400, 720131409105291, 1958958863624906 } + }, + { + { 515583508038846, 17656978857189, 1717918437373989, 1568052070792483, 46975803123923 }, + { 281527309158085, 36970532401524, 866906920877543, 2222282602952734, 1289598729589882 }, + { 1278207464902042, 494742455008756, 1262082121427081, 1577236621659884, 1888786707293291 } + }, + { + { 353042527954210, 1830056151907359, 1111731275799225, 174960955838824, 404312815582675 }, + { 2064251142068628, 1666421603389706, 1419271365315441, 468767774902855, 191535130366583 }, + { 1716987058588002, 1859366439773457, 1767194234188234, 64476199777924, 1117233614485261 } + }, + { + { 984292135520292, 135138246951259, 2220652137473167, 1722843421165029, 190482558012909 }, + { 298845952651262, 1166086588952562, 1179896526238434, 1347812759398693, 1412945390096208 }, + { 1143239552672925, 906436640714209, 2177000572812152, 2075299936108548, 325186347798433 } + }, + { + { 721024854374772, 684487861263316, 1373438744094159, 2193186935276995, 1387043709851261 }, + { 418098668140962, 715065997721283, 1471916138376055, 2168570337288357, 937812682637044 }, + { 1043584187226485, 2143395746619356, 2209558562919611, 482427979307092, 847556718384018 } + } +}, +{ /* 21/31 */ + { + { 1248731221520759, 1465200936117687, 540803492710140, 52978634680892, 261434490176109 }, + { 1057329623869501, 620334067429122, 461700859268034, 2012481616501857, 297268569108938 }, + { 1055352180870759, 1553151421852298, 1510903185371259, 1470458349428097, 1226259419062731 } + }, + { + { 1492988790301668, 790326625573331, 1190107028409745, 1389394752159193, 1620408196604194 }, + { 47000654413729, 1004754424173864, 1868044813557703, 173236934059409, 588771199737015 }, + { 30498470091663, 1082245510489825, 576771653181956, 806509986132686, 1317634017056939 } + }, + { + { 420308055751555, 1493354863316002, 165206721528088, 1884845694919786, 2065456951573059 }, + { 1115636332012334, 1854340990964155, 83792697369514, 1972177451994021, 457455116057587 }, + { 1698968457310898, 1435137169051090, 1083661677032510, 938363267483709, 340103887207182 } + }, + { + { 1995325341336574, 911500251774648, 164010755403692, 855378419194762, 1573601397528842 }, + { 241719380661528, 310028521317150, 1215881323380194, 1408214976493624, 2141142156467363 }, + { 1315157046163473, 727368447885818, 1363466668108618, 1668921439990361, 1398483384337907 } + }, + { + { 75029678299646, 1015388206460473, 1849729037055212, 1939814616452984, 444404230394954 }, + { 2053597130993710, 2024431685856332, 2233550957004860, 2012407275509545, 872546993104440 }, + { 1217269667678610, 599909351968693, 1390077048548598, 1471879360694802, 739586172317596 } + }, + { + { 1718318639380794, 1560510726633958, 904462881159922, 1418028351780052, 94404349451937 }, + { 2132502667405250, 214379346175414, 1502748313768060, 1960071701057800, 1353971822643138 }, + { 319394212043702, 2127459436033571, 717646691535162, 663366796076914, 318459064945314 } + }, + { + { 405989424923593, 1960452633787083, 667349034401665, 1492674260767112, 1451061489880787 }, + { 947085906234007, 323284730494107, 1485778563977200, 728576821512394, 901584347702286 }, + { 1575783124125742, 2126210792434375, 1569430791264065, 1402582372904727, 1891780248341114 } + }, + { + { 838432205560695, 1997703511451664, 1018791879907867, 1662001808174331, 78328132957753 }, + { 739152638255629, 2074935399403557, 505483666745895, 1611883356514088, 628654635394878 }, + { 1822054032121349, 643057948186973, 7306757352712, 577249257962099, 284735863382083 } + } +}, +{ /* 22/31 */ + { + { 1366558556363930, 1448606567552086, 1478881020944768, 165803179355898, 1115718458123498 }, + { 204146226972102, 1630511199034723, 2215235214174763, 174665910283542, 956127674017216 }, + { 1562934578796716, 1070893489712745, 11324610642270, 958989751581897, 2172552325473805 } + }, + { + { 1770564423056027, 735523631664565, 1326060113795289, 1509650369341127, 65892421582684 }, + { 623682558650637, 1337866509471512, 990313350206649, 1314236615762469, 1164772974270275 }, + { 223256821462517, 723690150104139, 1000261663630601, 933280913953265, 254872671543046 } + }, + { + { 1969087237026041, 624795725447124, 1335555107635969, 2069986355593023, 1712100149341902 }, + { 1236103475266979, 1837885883267218, 1026072585230455, 1025865513954973, 1801964901432134 }, + { 1115241013365517, 1712251818829143, 2148864332502771, 2096001471438138, 2235017246626125 } + }, + { + { 1299268198601632, 2047148477845621, 2165648650132450, 1612539282026145, 514197911628890 }, + { 118352772338543, 1067608711804704, 1434796676193498, 1683240170548391, 230866769907437 }, + { 1850689576796636, 1601590730430274, 1139674615958142, 1954384401440257, 76039205311 } + }, + { + { 1723387471374172, 997301467038410, 533927635123657, 20928644693965, 1756575222802513 }, + { 2146711623855116, 503278928021499, 625853062251406, 1109121378393107, 1033853809911861 }, + { 571005965509422, 2005213373292546, 1016697270349626, 56607856974274, 914438579435146 } + }, + { + { 1346698876211176, 2076651707527589, 1084761571110205, 265334478828406, 1068954492309671 }, + { 1769967932677654, 1695893319756416, 1151863389675920, 1781042784397689, 400287774418285 }, + { 1851867764003121, 403841933237558, 820549523771987, 761292590207581, 1743735048551143 } + }, + { + { 410915148140008, 2107072311871739, 1004367461876503, 99684895396761, 1180818713503224 }, + { 285945406881439, 648174397347453, 1098403762631981, 1366547441102991, 1505876883139217 }, + { 672095903120153, 1675918957959872, 636236529315028, 1569297300327696, 2164144194785875 } + }, + { + { 1902708175321798, 1035343530915438, 1178560808893263, 301095684058146, 1280977479761118 }, + { 1615357281742403, 404257611616381, 2160201349780978, 1160947379188955, 1578038619549541 }, + { 2013087639791217, 822734930507457, 1785668418619014, 1668650702946164, 389450875221715 } + } +}, +{ /* 23/31 */ + { + { 453918449698368, 106406819929001, 2072540975937135, 308588860670238, 1304394580755385 }, + { 1295082798350326, 2091844511495996, 1851348972587817, 3375039684596, 789440738712837 }, + { 2083069137186154, 848523102004566, 993982213589257, 1405313299916317, 1532824818698468 } + }, + { + { 1495961298852430, 1397203457344779, 1774950217066942, 139302743555696, 66603584342787 }, + { 1782411379088302, 1096724939964781, 27593390721418, 542241850291353, 1540337798439873 }, + { 693543956581437, 171507720360750, 1557908942697227, 1074697073443438, 1104093109037196 } + }, + { + { 345288228393419, 1099643569747172, 134881908403743, 1740551994106740, 248212179299770 }, + { 231429562203065, 1526290236421172, 2021375064026423, 1520954495658041, 806337791525116 }, + { 1079623667189886, 872403650198613, 766894200588288, 2163700860774109, 2023464507911816 } + }, + { + { 854645372543796, 1936406001954827, 151460662541253, 825325739271555, 1554306377287556 }, + { 1497138821904622, 1044820250515590, 1742593886423484, 1237204112746837, 849047450816987 }, + { 667962773375330, 1897271816877105, 1399712621683474, 1143302161683099, 2081798441209593 } + }, + { + { 127147851567005, 1936114012888110, 1704424366552046, 856674880716312, 716603621335359 }, + { 1072409664800960, 2146937497077528, 1508780108920651, 935767602384853, 1112800433544068 }, + { 333549023751292, 280219272863308, 2104176666454852, 1036466864875785, 536135186520207 } + }, + { + { 373666279883137, 146457241530109, 304116267127857, 416088749147715, 1258577131183391 }, + { 1186115062588401, 2251609796968486, 1098944457878953, 1153112761201374, 1791625503417267 }, + { 1870078460219737, 2129630962183380, 852283639691142, 292865602592851, 401904317342226 } + }, + { + { 1361070124828035, 815664541425524, 1026798897364671, 1951790935390647, 555874891834790 }, + { 1546301003424277, 459094500062839, 1097668518375311, 1780297770129643, 720763293687608 }, + { 1212405311403990, 1536693382542438, 61028431067459, 1863929423417129, 1223219538638038 } + }, + { + { 1294303766540260, 1183557465955093, 882271357233093, 63854569425375, 2213283684565087 }, + { 339050984211414, 601386726509773, 413735232134068, 966191255137228, 1839475899458159 }, + { 235605972169408, 2174055643032978, 1538335001838863, 1281866796917192, 1815940222628465 } + } +}, +{ /* 24/31 */ + { + { 1632352921721536, 1833328609514701, 2092779091951987, 1923956201873226, 2210068022482919 }, + { 35271216625062, 1712350667021807, 983664255668860, 98571260373038, 1232645608559836 }, + { 1998172393429622, 1798947921427073, 784387737563581, 1589352214827263, 1589861734168180 } + }, + { + { 1733739258725305, 31715717059538, 201969945218860, 992093044556990, 1194308773174556 }, + { 846415389605137, 746163495539180, 829658752826080, 592067705956946, 957242537821393 }, + { 1758148849754419, 619249044817679, 168089007997045, 1371497636330523, 1867101418880350 } + }, + { + { 326633984209635, 261759506071016, 1700682323676193, 1577907266349064, 1217647663383016 }, + { 1714182387328607, 1477856482074168, 574895689942184, 2159118410227270, 1555532449716575 }, + { 853828206885131, 998498946036955, 1835887550391235, 207627336608048, 258363815956050 } + }, + { + { 141141474651677, 1236728744905256, 643101419899887, 1646615130509173, 1208239602291765 }, + { 1501663228068911, 1354879465566912, 1444432675498247, 897812463852601, 855062598754348 }, + { 714380763546606, 1032824444965790, 1774073483745338, 1063840874947367, 1738680636537158 } + }, + { + { 1640635546696252, 633168953192112, 2212651044092396, 30590958583852, 368515260889378 }, + { 1171650314802029, 1567085444565577, 1453660792008405, 757914533009261, 1619511342778196 }, + { 420958967093237, 971103481109486, 2169549185607107, 1301191633558497, 1661514101014240 } + }, + { + { 907123651818302, 1332556122804146, 1824055253424487, 1367614217442959, 1982558335973172 }, + { 1121533090144639, 1021251337022187, 110469995947421, 1511059774758394, 2110035908131662 }, + { 303213233384524, 2061932261128138, 352862124777736, 40828818670255, 249879468482660 } + }, + { + { 856559257852200, 508517664949010, 1378193767894916, 1723459126947129, 1962275756614521 }, + { 1445691340537320, 40614383122127, 402104303144865, 485134269878232, 1659439323587426 }, + { 20057458979482, 1183363722525800, 2140003847237215, 2053873950687614, 2112017736174909 } + }, + { + { 2228654250927986, 1483591363415267, 1368661293910956, 1076511285177291, 526650682059608 }, + { 709481497028540, 531682216165724, 316963769431931, 1814315888453765, 258560242424104 }, + { 1053447823660455, 1955135194248683, 1010900954918985, 1182614026976701, 1240051576966610 } + } +}, +{ /* 25/31 */ + { + { 1957943897155497, 1788667368028035, 137692910029106, 1039519607062, 826404763313028 }, + { 1848942433095597, 1582009882530495, 1849292741020143, 1068498323302788, 2001402229799484 }, + { 1528282417624269, 2142492439828191, 2179662545816034, 362568973150328, 1591374675250271 } + }, + { + { 160026679434388, 232341189218716, 2149181472355545, 598041771119831, 183859001910173 }, + { 2013278155187349, 662660471354454, 793981225706267, 411706605985744, 804490933124791 }, + { 2051892037280204, 488391251096321, 2230187337030708, 930221970662692, 679002758255210 } + }, + { + { 1530723630438670, 875873929577927, 341560134269988, 449903119530753, 1055551308214179 }, + { 1461835919309432, 1955256480136428, 180866187813063, 1551979252664528, 557743861963950 }, + { 359179641731115, 1324915145732949, 902828372691474, 294254275669987, 1887036027752957 } + }, + { + { 2043271609454323, 2038225437857464, 1317528426475850, 1398989128982787, 2027639881006861 }, + { 2072902725256516, 312132452743412, 309930885642209, 996244312618453, 1590501300352303 }, + { 1397254305160710, 695734355138021, 2233992044438756, 1776180593969996, 1085588199351115 } + }, + { + { 440567051331029, 254894786356681, 493869224930222, 1556322069683366, 1567456540319218 }, + { 1950722461391320, 1907845598854797, 1822757481635527, 2121567704750244, 73811931471221 }, + { 387139307395758, 2058036430315676, 1220915649965325, 1794832055328951, 1230009312169328 } + }, + { + { 1765973779329517, 659344059446977, 19821901606666, 1301928341311214, 1116266004075885 }, + { 1127572801181483, 1224743760571696, 1276219889847274, 1529738721702581, 1589819666871853 }, + { 2181229378964934, 2190885205260020, 1511536077659137, 1246504208580490, 668883326494241 } + }, + { + { 437866655573314, 669026411194768, 81896997980338, 523874406393178, 245052060935236 }, + { 1975438052228868, 1071801519999806, 594652299224319, 1877697652668809, 1489635366987285 }, + { 958592545673770, 233048016518599, 851568750216589, 567703851596087, 1740300006094761 } + }, + { + { 2014540178270324, 192672779514432, 213877182641530, 2194819933853411, 1716422829364835 }, + { 1540769606609725, 2148289943846077, 1597804156127445, 1230603716683868, 815423458809453 }, + { 1738560251245018, 1779576754536888, 1783765347671392, 1880170990446751, 1088225159617541 } + } +}, +{ /* 26/31 */ + { + { 659303913929492, 1956447718227573, 1830568515922666, 841069049744408, 1669607124206368 }, + { 1143465490433355, 1532194726196059, 1093276745494697, 481041706116088, 2121405433561163 }, + { 1686424298744462, 1451806974487153, 266296068846582, 1834686947542675, 1720762336132256 } + }, + { + { 889217026388959, 1043290623284660, 856125087551909, 1669272323124636, 1603340330827879 }, + { 1206396181488998, 333158148435054, 1402633492821422, 1120091191722026, 1945474114550509 }, + { 766720088232571, 1512222781191002, 1189719893490790, 2091302129467914, 2141418006894941 } + }, + { + { 419663647306612, 1998875112167987, 1426599870253707, 1154928355379510, 486538532138187 }, + { 938160078005954, 1421776319053174, 1941643234741774, 180002183320818, 1414380336750546 }, + { 398001940109652, 1577721237663248, 1012748649830402, 1540516006905144, 1011684812884559 } + }, + { + { 1653276489969630, 6081825167624, 1921777941170836, 1604139841794531, 861211053640641 }, + { 996661541407379, 1455877387952927, 744312806857277, 139213896196746, 1000282908547789 }, + { 1450817495603008, 1476865707053229, 1030490562252053, 620966950353376, 1744760161539058 } + }, + { + { 559728410002599, 37056661641185, 2038622963352006, 1637244893271723, 1026565352238948 }, + { 962165956135846, 1116599660248791, 182090178006815, 1455605467021751, 196053588803284 }, + { 796863823080135, 1897365583584155, 420466939481601, 2165972651724672, 932177357788289 } + }, + { + { 877047233620632, 1375632631944375, 643773611882121, 660022738847877, 19353932331831 }, + { 2216943882299338, 394841323190322, 2222656898319671, 558186553950529, 1077236877025190 }, + { 801118384953213, 1914330175515892, 574541023311511, 1471123787903705, 1526158900256288 } + }, + { + { 949617889087234, 2207116611267331, 912920039141287, 501158539198789, 62362560771472 }, + { 1474518386765335, 1760793622169197, 1157399790472736, 1622864308058898, 165428294422792 }, + { 1961673048027128, 102619413083113, 1051982726768458, 1603657989805485, 1941613251499678 } + }, + { + { 1401939116319266, 335306339903072, 72046196085786, 862423201496006, 850518754531384 }, + { 1234706593321979, 1083343891215917, 898273974314935, 1640859118399498, 157578398571149 }, + { 1143483057726416, 1992614991758919, 674268662140796, 1773370048077526, 674318359920189 } + } +}, +{ /* 27/31 */ + { + { 1835401379538542, 173900035308392, 818247630716732, 1762100412152786, 1021506399448291 }, + { 1506632088156630, 2127481795522179, 513812919490255, 140643715928370, 442476620300318 }, + { 2056683376856736, 219094741662735, 2193541883188309, 1841182310235800, 556477468664293 } + }, + { + { 1315019427910827, 1049075855992603, 2066573052986543, 266904467185534, 2040482348591520 }, + { 94096246544434, 922482381166992, 24517828745563, 2139430508542503, 2097139044231004 }, + { 537697207950515, 1399352016347350, 1563663552106345, 2148749520888918, 549922092988516 } + }, + { + { 1747985413252434, 680511052635695, 1809559829982725, 594274250930054, 201673170745982 }, + { 323583936109569, 1973572998577657, 1192219029966558, 79354804385273, 1374043025560347 }, + { 213277331329947, 416202017849623, 1950535221091783, 1313441578103244, 2171386783823658 } + }, + { + { 189088804229831, 993969372859110, 895870121536987, 1547301535298256, 1477373024911350 }, + { 1620578418245010, 541035331188469, 2235785724453865, 2154865809088198, 1974627268751826 }, + { 1346805451740245, 1350981335690626, 942744349501813, 2155094562545502, 1012483751693409 } + }, + { + { 2107080134091762, 1132567062788208, 1824935377687210, 769194804343737, 1857941799971888 }, + { 1074666112436467, 249279386739593, 1174337926625354, 1559013532006480, 1472287775519121 }, + { 1872620123779532, 1892932666768992, 1921559078394978, 1270573311796160, 1438913646755037 } + }, + { + { 837390187648199, 1012253300223599, 989780015893987, 1351393287739814, 328627746545550 }, + { 1028328827183114, 1711043289969857, 1350832470374933, 1923164689604327, 1495656368846911 }, + { 1900828492104143, 430212361082163, 687437570852799, 832514536673512, 1685641495940794 } + }, + { + { 842632847936398, 605670026766216, 290836444839585, 163210774892356, 2213815011799645 }, + { 1176336383453996, 1725477294339771, 12700622672454, 678015708818208, 162724078519879 }, + { 1448049969043497, 1789411762943521, 385587766217753, 90201620913498, 832999441066823 } + }, + { + { 516086333293313, 2240508292484616, 1351669528166508, 1223255565316488, 750235824427138 }, + { 1263624896582495, 1102602401673328, 526302183714372, 2152015839128799, 1483839308490010 }, + { 442991718646863, 1599275157036458, 1925389027579192, 899514691371390, 350263251085160 } + } +}, +{ /* 28/31 */ + { + { 1689713572022143, 593854559254373, 978095044791970, 1985127338729499, 1676069120347625 }, + { 1557207018622683, 340631692799603, 1477725909476187, 614735951619419, 2033237123746766 }, + { 968764929340557, 1225534776710944, 662967304013036, 1155521416178595, 791142883466590 } + }, + { + { 1487081286167458, 993039441814934, 1792378982844640, 698652444999874, 2153908693179754 }, + { 1123181311102823, 685575944875442, 507605465509927, 1412590462117473, 568017325228626 }, + { 560258797465417, 2193971151466401, 1824086900849026, 579056363542056, 1690063960036441 } + }, + { + { 1918407319222416, 353767553059963, 1930426334528099, 1564816146005724, 1861342381708096 }, + { 2131325168777276, 1176636658428908, 1756922641512981, 1390243617176012, 1966325177038383 }, + { 2063958120364491, 2140267332393533, 699896251574968, 273268351312140, 375580724713232 } + }, + { + { 2024297515263178, 416959329722687, 1079014235017302, 171612225573183, 1031677520051053 }, + { 2033900009388450, 1744902869870788, 2190580087917640, 1949474984254121, 231049754293748 }, + { 343868674606581, 550155864008088, 1450580864229630, 481603765195050, 896972360018042 } + }, + { + { 2151139328380127, 314745882084928, 59756825775204, 1676664391494651, 2048348075599360 }, + { 1528930066340597, 1605003907059576, 1055061081337675, 1458319101947665, 1234195845213142 }, + { 830430507734812, 1780282976102377, 1425386760709037, 362399353095425, 2168861579799910 } + }, + { + { 1155762232730333, 980662895504006, 2053766700883521, 490966214077606, 510405877041357 }, + { 1683750316716132, 652278688286128, 1221798761193539, 1897360681476669, 319658166027343 }, + { 618808732869972, 72755186759744, 2060379135624181, 1730731526741822, 48862757828238 } + }, + { + { 1463171970593505, 1143040711767452, 614590986558883, 1409210575145591, 1882816996436803 }, + { 2230133264691131, 563950955091024, 2042915975426398, 827314356293472, 672028980152815 }, + { 264204366029760, 1654686424479449, 2185050199932931, 2207056159091748, 506015669043634 } + }, + { + { 1784446333136569, 1973746527984364, 334856327359575, 1156769775884610, 1023950124675478 }, + { 2065270940578383, 31477096270353, 306421879113491, 181958643936686, 1907105536686083 }, + { 1496516440779464, 1748485652986458, 872778352227340, 818358834654919, 97932669284220 } + } +}, +{ /* 29/31 */ + { + { 471636015770351, 672455402793577, 1804995246884103, 1842309243470804, 1501862504981682 }, + { 1013216974933691, 538921919682598, 1915776722521558, 1742822441583877, 1886550687916656 }, + { 2094270000643336, 303971879192276, 40801275554748, 649448917027930, 1818544418535447 } + }, + { + { 2241737709499165, 549397817447461, 838180519319392, 1725686958520781, 1705639080897747 }, + { 1216074541925116, 50120933933509, 1565829004133810, 721728156134580, 349206064666188 }, + { 948617110470858, 346222547451945, 1126511960599975, 1759386906004538, 493053284802266 } + }, + { + { 1454933046815146, 874696014266362, 1467170975468588, 1432316382418897, 2111710746366763 }, + { 2105387117364450, 1996463405126433, 1303008614294500, 851908115948209, 1353742049788635 }, + { 750300956351719, 1487736556065813, 15158817002104, 1511998221598392, 971739901354129 } + }, + { + { 1874648163531693, 2124487685930551, 1810030029384882, 918400043048335, 586348627300650 }, + { 1235084464747900, 1166111146432082, 1745394857881591, 1405516473883040, 4463504151617 }, + { 1663810156463827, 327797390285791, 1341846161759410, 1964121122800605, 1747470312055380 } + }, + { + { 660005247548233, 2071860029952887, 1358748199950107, 911703252219107, 1014379923023831 }, + { 2206641276178231, 1690587809721504, 1600173622825126, 2156096097634421, 1106822408548216 }, + { 1344788193552206, 1949552134239140, 1735915881729557, 675891104100469, 1834220014427292 } + }, + { + { 1920949492387964, 158885288387530, 70308263664033, 626038464897817, 1468081726101009 }, + { 622221042073383, 1210146474039168, 1742246422343683, 1403839361379025, 417189490895736 }, + { 22727256592983, 168471543384997, 1324340989803650, 1839310709638189, 504999476432775 } + }, + { + { 1313240518756327, 1721896294296942, 52263574587266, 2065069734239232, 804910473424630 }, + { 1337466662091884, 1287645354669772, 2018019646776184, 652181229374245, 898011753211715 }, + { 1969792547910734, 779969968247557, 2011350094423418, 1823964252907487, 1058949448296945 } + }, + { + { 207343737062002, 1118176942430253, 758894594548164, 806764629546266, 1157700123092949 }, + { 1273565321399022, 1638509681964574, 759235866488935, 666015124346707, 897983460943405 }, + { 1717263794012298, 1059601762860786, 1837819172257618, 1054130665797229, 680893204263559 } + } +}, +{ /* 30/31 */ + { + { 2237039662793603, 2249022333361206, 2058613546633703, 149454094845279, 2215176649164582 }, + { 79472182719605, 1851130257050174, 1825744808933107, 821667333481068, 781795293511946 }, + { 755822026485370, 152464789723500, 1178207602290608, 410307889503239, 156581253571278 } + }, + { + { 1418185496130297, 484520167728613, 1646737281442950, 1401487684670265, 1349185550126961 }, + { 1495380034400429, 325049476417173, 46346894893933, 1553408840354856, 828980101835683 }, + { 1280337889310282, 2070832742866672, 1640940617225222, 2098284908289951, 450929509534434 } + }, + { + { 407703353998781, 126572141483652, 286039827513621, 1999255076709338, 2030511179441770 }, + { 1254958221100483, 1153235960999843, 942907704968834, 637105404087392, 1149293270147267 }, + { 894249020470196, 400291701616810, 406878712230981, 1599128793487393, 1145868722604026 } + }, + { + { 1497955250203334, 110116344653260, 1128535642171976, 1900106496009660, 129792717460909 }, + { 452487513298665, 1352120549024569, 1173495883910956, 1999111705922009, 367328130454226 }, + { 1717539401269642, 1475188995688487, 891921989653942, 836824441505699, 1885988485608364 } + }, + { + { 1241784121422547, 187337051947583, 1118481812236193, 428747751936362, 30358898927325 }, + { 2022432361201842, 1088816090685051, 1977843398539868, 1854834215890724, 564238862029357 }, + { 938868489100585, 1100285072929025, 1017806255688848, 1957262154788833, 152787950560442 } + }, + { + { 867319417678923, 620471962942542, 226032203305716, 342001443957629, 1761675818237336 }, + { 1295072362439987, 931227904689414, 1355731432641687, 922235735834035, 892227229410209 }, + { 1680989767906154, 535362787031440, 2136691276706570, 1942228485381244, 1267350086882274 } + }, + { + { 366018233770527, 432660629755596, 126409707644535, 1973842949591662, 645627343442376 }, + { 535509430575217, 546885533737322, 1524675609547799, 2138095752851703, 1260738089896827 }, + { 1159906385590467, 2198530004321610, 714559485023225, 81880727882151, 1484020820037082 } + }, + { + { 1377485731340769, 2046328105512000, 1802058637158797, 62146136768173, 1356993908853901 }, + { 2013612215646735, 1830770575920375, 536135310219832, 609272325580394, 270684344495013 }, + { 1237542585982777, 2228682050256790, 1385281931622824, 593183794882890, 493654978552689 } + } +}, +{ /* 31/31 */ + { + { 47341488007760, 1891414891220257, 983894663308928, 176161768286818, 1126261115179708 }, + { 1694030170963455, 502038567066200, 1691160065225467, 949628319562187, 275110186693066 }, + { 1124515748676336, 1661673816593408, 1499640319059718, 1584929449166988, 558148594103306 } + }, + { + { 1784525599998356, 1619698033617383, 2097300287550715, 258265458103756, 1905684794832758 }, + { 1288941072872766, 931787902039402, 190731008859042, 2006859954667190, 1005931482221702 }, + { 1465551264822703, 152905080555927, 680334307368453, 173227184634745, 666407097159852 } + }, + { + { 2111017076203943, 1378760485794347, 1248583954016456, 1352289194864422, 1895180776543896 }, + { 171348223915638, 662766099800389, 462338943760497, 466917763340314, 656911292869115 }, + { 488623681976577, 866497561541722, 1708105560937768, 1673781214218839, 1506146329818807 } + }, + { + { 160425464456957, 950394373239689, 430497123340934, 711676555398832, 320964687779005 }, + { 988979367990485, 1359729327576302, 1301834257246029, 294141160829308, 29348272277475 }, + { 1434382743317910, 100082049942065, 221102347892623, 186982837860588, 1305765053501834 } + }, + { + { 2205916462268190, 499863829790820, 961960554686616, 158062762756985, 1841471168298305 }, + { 1191737341426592, 1847042034978363, 1382213545049056, 1039952395710448, 788812858896859 }, + { 1346965964571152, 1291881610839830, 2142916164336056, 786821641205979, 1571709146321039 } + }, + { + { 787164375951248, 202869205373189, 1356590421032140, 1431233331032510, 786341368775957 }, + { 492448143532951, 304105152670757, 1761767168301056, 233782684697790, 1981295323106089 }, + { 665807507761866, 1343384868355425, 895831046139653, 439338948736892, 1986828765695105 } + }, + { + { 756096210874553, 1721699973539149, 258765301727885, 1390588532210645, 1212530909934781 }, + { 852891097972275, 1816988871354562, 1543772755726524, 1174710635522444, 202129090724628 }, + { 1205281565824323, 22430498399418, 992947814485516, 1392458699738672, 688441466734558 } + }, + { + { 1050627428414972, 1955849529137135, 2171162376368357, 91745868298214, 447733118757826 }, + { 1287181461435438, 622722465530711, 880952150571872, 741035693459198, 311565274989772 }, + { 1003649078149734, 545233927396469, 1849786171789880, 1318943684880434, 280345687170552 } + } +} diff --git a/libs/libsodium/src/crypto_core/ed25519/ref10/fe_51/base2.h b/libs/libsodium/src/crypto_core/ed25519/ref10/fe_51/base2.h new file mode 100644 index 0000000000..d088241657 --- /dev/null +++ b/libs/libsodium/src/crypto_core/ed25519/ref10/fe_51/base2.h @@ -0,0 +1,40 @@ +{ + { 1288382639258501, 245678601348599, 269427782077623, 1462984067271730, 137412439391563 }, + { 62697248952638, 204681361388450, 631292143396476, 338455783676468, 1213667448819585 }, + { 301289933810280, 1259582250014073, 1422107436869536, 796239922652654, 1953934009299142 } +}, +{ + { 1601611775252272, 1720807796594148, 1132070835939856, 1260455018889551, 2147779492816911 }, + { 316559037616741, 2177824224946892, 1459442586438991, 1461528397712656, 751590696113597 }, + { 1850748884277385, 1200145853858453, 1068094770532492, 672251375690438, 1586055907191707 } +}, +{ + { 769950342298419, 132954430919746, 844085933195555, 974092374476333, 726076285546016 }, + { 425251763115706, 608463272472562, 442562545713235, 837766094556764, 374555092627893 }, + { 1086255230780037, 274979815921559, 1960002765731872, 929474102396301, 1190409889297339 } +}, +{ + { 665000864555967, 2065379846933859, 370231110385876, 350988370788628, 1233371373142985 }, + { 2019367628972465, 676711900706637, 110710997811333, 1108646842542025, 517791959672113 }, + { 965130719900578, 247011430587952, 526356006571389, 91986625355052, 2157223321444601 } +}, +{ + { 1802695059465007, 1664899123557221, 593559490740857, 2160434469266659, 927570450755031 }, + { 1725674970513508, 1933645953859181, 1542344539275782, 1767788773573747, 1297447965928905 }, + { 1381809363726107, 1430341051343062, 2061843536018959, 1551778050872521, 2036394857967624 } +}, +{ + { 1970894096313054, 528066325833207, 1619374932191227, 2207306624415883, 1169170329061080 }, + { 2070390218572616, 1458919061857835, 624171843017421, 1055332792707765, 433987520732508 }, + { 893653801273833, 1168026499324677, 1242553501121234, 1306366254304474, 1086752658510815 } +}, +{ + { 213454002618221, 939771523987438, 1159882208056014, 317388369627517, 621213314200687 }, + { 1971678598905747, 338026507889165, 762398079972271, 655096486107477, 42299032696322 }, + { 177130678690680, 1754759263300204, 1864311296286618, 1180675631479880, 1292726903152791 } +}, +{ + { 1913163449625248, 460779200291993, 2193883288642314, 1008900146920800, 1721983679009502 }, + { 1070401523076875, 1272492007800961, 1910153608563310, 2075579521696771, 1191169788841221 }, + { 692896803108118, 500174642072499, 2068223309439677, 1162190621851337, 1426986007309901 } +} diff --git a/libs/libsodium/src/crypto_core/ed25519/ref10/fe_51/constants.h b/libs/libsodium/src/crypto_core/ed25519/ref10/fe_51/constants.h new file mode 100644 index 0000000000..53b75c6b45 --- /dev/null +++ b/libs/libsodium/src/crypto_core/ed25519/ref10/fe_51/constants.h @@ -0,0 +1,21 @@ +/* 37095705934669439343138083508754565189542113879843219016388785533085940283555 */ +static const fe25519 d = { + 929955233495203, 466365720129213, 1662059464998953, 2033849074728123, 1442794654840575 +}; + +/* 2 * d = + * 16295367250680780974490674513165176452449235426866156013048779062215315747161 + */ +static const fe25519 d2 = { + 1859910466990425, 932731440258426, 1072319116312658, 1815898335770999, 633789495995903 +}; + +/* sqrt(-1) */ +static const fe25519 sqrtm1 = { + 1718705420411056, 234908883556509, 2233514472574048, 2117202627021982, 765476049583133 +}; + +/* A = 486662 */ +static const fe25519 curve25519_A = { + 486662, 0, 0, 0, 0 +}; diff --git a/libs/libsodium/src/crypto_core/ed25519/ref10/fe_51/fe.h b/libs/libsodium/src/crypto_core/ed25519/ref10/fe_51/fe.h new file mode 100644 index 0000000000..de876264c8 --- /dev/null +++ b/libs/libsodium/src/crypto_core/ed25519/ref10/fe_51/fe.h @@ -0,0 +1,116 @@ +/* + Ignores top bit of h. + */ + +void +fe25519_frombytes(fe25519 h, const unsigned char *s) +{ + const uint64_t mask = 0x7ffffffffffffULL; + uint64_t h0, h1, h2, h3, h4; + + h0 = (LOAD64_LE(s ) ) & mask; + h1 = (LOAD64_LE(s + 6) >> 3) & mask; + h2 = (LOAD64_LE(s + 12) >> 6) & mask; + h3 = (LOAD64_LE(s + 19) >> 1) & mask; + h4 = (LOAD64_LE(s + 24) >> 12) & mask; + + h[0] = h0; + h[1] = h1; + h[2] = h2; + h[3] = h3; + h[4] = h4; +} + +static void +fe25519_reduce(fe25519 h, const fe25519 f) +{ + const uint64_t mask = 0x7ffffffffffffULL; + uint128_t t[5]; + + t[0] = f[0]; + t[1] = f[1]; + t[2] = f[2]; + t[3] = f[3]; + t[4] = f[4]; + + t[1] += t[0] >> 51; + t[0] &= mask; + t[2] += t[1] >> 51; + t[1] &= mask; + t[3] += t[2] >> 51; + t[2] &= mask; + t[4] += t[3] >> 51; + t[3] &= mask; + t[0] += 19 * (t[4] >> 51); + t[4] &= mask; + + t[1] += t[0] >> 51; + t[0] &= mask; + t[2] += t[1] >> 51; + t[1] &= mask; + t[3] += t[2] >> 51; + t[2] &= mask; + t[4] += t[3] >> 51; + t[3] &= mask; + t[0] += 19 * (t[4] >> 51); + t[4] &= mask; + + /* now t is between 0 and 2^255-1, properly carried. */ + /* case 1: between 0 and 2^255-20. case 2: between 2^255-19 and 2^255-1. */ + + t[0] += 19ULL; + + t[1] += t[0] >> 51; + t[0] &= mask; + t[2] += t[1] >> 51; + t[1] &= mask; + t[3] += t[2] >> 51; + t[2] &= mask; + t[4] += t[3] >> 51; + t[3] &= mask; + t[0] += 19ULL * (t[4] >> 51); + t[4] &= mask; + + /* now between 19 and 2^255-1 in both cases, and offset by 19. */ + + t[0] += 0x8000000000000 - 19ULL; + t[1] += 0x8000000000000 - 1ULL; + t[2] += 0x8000000000000 - 1ULL; + t[3] += 0x8000000000000 - 1ULL; + t[4] += 0x8000000000000 - 1ULL; + + /* now between 2^255 and 2^256-20, and offset by 2^255. */ + + t[1] += t[0] >> 51; + t[0] &= mask; + t[2] += t[1] >> 51; + t[1] &= mask; + t[3] += t[2] >> 51; + t[2] &= mask; + t[4] += t[3] >> 51; + t[3] &= mask; + t[4] &= mask; + + h[0] = t[0]; + h[1] = t[1]; + h[2] = t[2]; + h[3] = t[3]; + h[4] = t[4]; +} + +void +fe25519_tobytes(unsigned char *s, const fe25519 h) +{ + fe25519 t; + uint64_t t0, t1, t2, t3; + + fe25519_reduce(t, h); + t0 = t[0] | (t[1] << 51); + t1 = (t[1] >> 13) | (t[2] << 38); + t2 = (t[2] >> 26) | (t[3] << 25); + t3 = (t[3] >> 39) | (t[4] << 12); + STORE64_LE(s + 0, t0); + STORE64_LE(s + 8, t1); + STORE64_LE(s + 16, t2); + STORE64_LE(s + 24, t3); +} diff --git a/libs/libsodium/src/crypto_core/hchacha20/core_hchacha20.c b/libs/libsodium/src/crypto_core/hchacha20/core_hchacha20.c new file mode 100644 index 0000000000..39ab26a6da --- /dev/null +++ b/libs/libsodium/src/crypto_core/hchacha20/core_hchacha20.c @@ -0,0 +1,93 @@ + +#include <stdint.h> +#include <stdlib.h> + +#include "crypto_core_hchacha20.h" +#include "private/common.h" + +#define QUARTERROUND(A, B, C, D) \ + do { \ + A += B; D = ROTL32(D ^ A, 16); \ + C += D; B = ROTL32(B ^ C, 12); \ + A += B; D = ROTL32(D ^ A, 8); \ + C += D; B = ROTL32(B ^ C, 7); \ + } while(0) + +int +crypto_core_hchacha20(unsigned char *out, const unsigned char *in, + const unsigned char *k, const unsigned char *c) +{ + int i; + uint32_t x0, x1, x2, x3, x4, x5, x6, x7; + uint32_t x8, x9, x10, x11, x12, x13, x14, x15; + + if (c == NULL) { + x0 = 0x61707865; + x1 = 0x3320646e; + x2 = 0x79622d32; + x3 = 0x6b206574; + } else { + x0 = LOAD32_LE(c + 0); + x1 = LOAD32_LE(c + 4); + x2 = LOAD32_LE(c + 8); + x3 = LOAD32_LE(c + 12); + } + x4 = LOAD32_LE(k + 0); + x5 = LOAD32_LE(k + 4); + x6 = LOAD32_LE(k + 8); + x7 = LOAD32_LE(k + 12); + x8 = LOAD32_LE(k + 16); + x9 = LOAD32_LE(k + 20); + x10 = LOAD32_LE(k + 24); + x11 = LOAD32_LE(k + 28); + x12 = LOAD32_LE(in + 0); + x13 = LOAD32_LE(in + 4); + x14 = LOAD32_LE(in + 8); + x15 = LOAD32_LE(in + 12); + + for (i = 0; i < 10; i++) { + QUARTERROUND(x0, x4, x8, x12); + QUARTERROUND(x1, x5, x9, x13); + QUARTERROUND(x2, x6, x10, x14); + QUARTERROUND(x3, x7, x11, x15); + QUARTERROUND(x0, x5, x10, x15); + QUARTERROUND(x1, x6, x11, x12); + QUARTERROUND(x2, x7, x8, x13); + QUARTERROUND(x3, x4, x9, x14); + } + + STORE32_LE(out + 0, x0); + STORE32_LE(out + 4, x1); + STORE32_LE(out + 8, x2); + STORE32_LE(out + 12, x3); + STORE32_LE(out + 16, x12); + STORE32_LE(out + 20, x13); + STORE32_LE(out + 24, x14); + STORE32_LE(out + 28, x15); + + return 0; +} + +size_t +crypto_core_hchacha20_outputbytes(void) +{ + return crypto_core_hchacha20_OUTPUTBYTES; +} + +size_t +crypto_core_hchacha20_inputbytes(void) +{ + return crypto_core_hchacha20_INPUTBYTES; +} + +size_t +crypto_core_hchacha20_keybytes(void) +{ + return crypto_core_hchacha20_KEYBYTES; +} + +size_t +crypto_core_hchacha20_constbytes(void) +{ + return crypto_core_hchacha20_CONSTBYTES; +} diff --git a/libs/libsodium/src/crypto_core/hsalsa20/core_hsalsa20.c b/libs/libsodium/src/crypto_core/hsalsa20/core_hsalsa20.c new file mode 100644 index 0000000000..37c4923af6 --- /dev/null +++ b/libs/libsodium/src/crypto_core/hsalsa20/core_hsalsa20.c @@ -0,0 +1,21 @@ +#include "crypto_core_hsalsa20.h" + +size_t +crypto_core_hsalsa20_outputbytes(void) { + return crypto_core_hsalsa20_OUTPUTBYTES; +} + +size_t +crypto_core_hsalsa20_inputbytes(void) { + return crypto_core_hsalsa20_INPUTBYTES; +} + +size_t +crypto_core_hsalsa20_keybytes(void) { + return crypto_core_hsalsa20_KEYBYTES; +} + +size_t +crypto_core_hsalsa20_constbytes(void) { + return crypto_core_hsalsa20_CONSTBYTES; +} diff --git a/libs/libsodium/src/crypto_core/hsalsa20/ref2/core_hsalsa20_ref2.c b/libs/libsodium/src/crypto_core/hsalsa20/ref2/core_hsalsa20_ref2.c new file mode 100644 index 0000000000..1d1220fee2 --- /dev/null +++ b/libs/libsodium/src/crypto_core/hsalsa20/ref2/core_hsalsa20_ref2.c @@ -0,0 +1,95 @@ +/* +version 20080912 +D. J. Bernstein +Public domain. +*/ + +#include <stdint.h> +#include <stdlib.h> + +#include "crypto_core_hsalsa20.h" +#include "private/common.h" + +#define ROUNDS 20 +#define U32C(v) (v##U) + +int +crypto_core_hsalsa20(unsigned char *out, + const unsigned char *in, + const unsigned char *k, + const unsigned char *c) +{ + uint32_t x0, x1, x2, x3, x4, x5, x6, x7, x8, + x9, x10, x11, x12, x13, x14, x15; + int i; + + if (c == NULL) { + x0 = U32C(0x61707865); + x5 = U32C(0x3320646e); + x10 = U32C(0x79622d32); + x15 = U32C(0x6b206574); + } else { + x0 = LOAD32_LE(c + 0); + x5 = LOAD32_LE(c + 4); + x10 = LOAD32_LE(c + 8); + x15 = LOAD32_LE(c + 12); + } + x1 = LOAD32_LE(k + 0); + x2 = LOAD32_LE(k + 4); + x3 = LOAD32_LE(k + 8); + x4 = LOAD32_LE(k + 12); + x11 = LOAD32_LE(k + 16); + x12 = LOAD32_LE(k + 20); + x13 = LOAD32_LE(k + 24); + x14 = LOAD32_LE(k + 28); + x6 = LOAD32_LE(in + 0); + x7 = LOAD32_LE(in + 4); + x8 = LOAD32_LE(in + 8); + x9 = LOAD32_LE(in + 12); + + for (i = ROUNDS; i > 0; i -= 2) { + x4 ^= ROTL32(x0 + x12, 7); + x8 ^= ROTL32(x4 + x0, 9); + x12 ^= ROTL32(x8 + x4, 13); + x0 ^= ROTL32(x12 + x8, 18); + x9 ^= ROTL32(x5 + x1, 7); + x13 ^= ROTL32(x9 + x5, 9); + x1 ^= ROTL32(x13 + x9, 13); + x5 ^= ROTL32(x1 + x13, 18); + x14 ^= ROTL32(x10 + x6, 7); + x2 ^= ROTL32(x14 + x10, 9); + x6 ^= ROTL32(x2 + x14, 13); + x10 ^= ROTL32(x6 + x2, 18); + x3 ^= ROTL32(x15 + x11, 7); + x7 ^= ROTL32(x3 + x15, 9); + x11 ^= ROTL32(x7 + x3, 13); + x15 ^= ROTL32(x11 + x7, 18); + x1 ^= ROTL32(x0 + x3, 7); + x2 ^= ROTL32(x1 + x0, 9); + x3 ^= ROTL32(x2 + x1, 13); + x0 ^= ROTL32(x3 + x2, 18); + x6 ^= ROTL32(x5 + x4, 7); + x7 ^= ROTL32(x6 + x5, 9); + x4 ^= ROTL32(x7 + x6, 13); + x5 ^= ROTL32(x4 + x7, 18); + x11 ^= ROTL32(x10 + x9, 7); + x8 ^= ROTL32(x11 + x10, 9); + x9 ^= ROTL32(x8 + x11, 13); + x10 ^= ROTL32(x9 + x8, 18); + x12 ^= ROTL32(x15 + x14, 7); + x13 ^= ROTL32(x12 + x15, 9); + x14 ^= ROTL32(x13 + x12, 13); + x15 ^= ROTL32(x14 + x13, 18); + } + + STORE32_LE(out + 0, x0); + STORE32_LE(out + 4, x5); + STORE32_LE(out + 8, x10); + STORE32_LE(out + 12, x15); + STORE32_LE(out + 16, x6); + STORE32_LE(out + 20, x7); + STORE32_LE(out + 24, x8); + STORE32_LE(out + 28, x9); + + return 0; +} diff --git a/libs/libsodium/src/crypto_core/salsa/ref/core_salsa_ref.c b/libs/libsodium/src/crypto_core/salsa/ref/core_salsa_ref.c new file mode 100644 index 0000000000..a077d7f4db --- /dev/null +++ b/libs/libsodium/src/crypto_core/salsa/ref/core_salsa_ref.c @@ -0,0 +1,195 @@ + +#include <stdint.h> +#include <stdlib.h> + +#include "crypto_core_salsa20.h" +#include "crypto_core_salsa2012.h" +#include "crypto_core_salsa208.h" +#include "private/common.h" + +static void +crypto_core_salsa(unsigned char *out, const unsigned char *in, + const unsigned char *k, const unsigned char *c, + const int rounds) +{ + uint32_t x0, x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, + x15; + uint32_t j0, j1, j2, j3, j4, j5, j6, j7, j8, j9, j10, j11, j12, j13, j14, + j15; + int i; + + j0 = x0 = 0x61707865; + j5 = x5 = 0x3320646e; + j10 = x10 = 0x79622d32; + j15 = x15 = 0x6b206574; + if (c != NULL) { + j0 = x0 = LOAD32_LE(c + 0); + j5 = x5 = LOAD32_LE(c + 4); + j10 = x10 = LOAD32_LE(c + 8); + j15 = x15 = LOAD32_LE(c + 12); + } + j1 = x1 = LOAD32_LE(k + 0); + j2 = x2 = LOAD32_LE(k + 4); + j3 = x3 = LOAD32_LE(k + 8); + j4 = x4 = LOAD32_LE(k + 12); + j11 = x11 = LOAD32_LE(k + 16); + j12 = x12 = LOAD32_LE(k + 20); + j13 = x13 = LOAD32_LE(k + 24); + j14 = x14 = LOAD32_LE(k + 28); + + j6 = x6 = LOAD32_LE(in + 0); + j7 = x7 = LOAD32_LE(in + 4); + j8 = x8 = LOAD32_LE(in + 8); + j9 = x9 = LOAD32_LE(in + 12); + + for (i = 0; i < rounds; i += 2) { + x4 ^= ROTL32(x0 + x12, 7); + x8 ^= ROTL32(x4 + x0, 9); + x12 ^= ROTL32(x8 + x4, 13); + x0 ^= ROTL32(x12 + x8, 18); + x9 ^= ROTL32(x5 + x1, 7); + x13 ^= ROTL32(x9 + x5, 9); + x1 ^= ROTL32(x13 + x9, 13); + x5 ^= ROTL32(x1 + x13, 18); + x14 ^= ROTL32(x10 + x6, 7); + x2 ^= ROTL32(x14 + x10, 9); + x6 ^= ROTL32(x2 + x14, 13); + x10 ^= ROTL32(x6 + x2, 18); + x3 ^= ROTL32(x15 + x11, 7); + x7 ^= ROTL32(x3 + x15, 9); + x11 ^= ROTL32(x7 + x3, 13); + x15 ^= ROTL32(x11 + x7, 18); + x1 ^= ROTL32(x0 + x3, 7); + x2 ^= ROTL32(x1 + x0, 9); + x3 ^= ROTL32(x2 + x1, 13); + x0 ^= ROTL32(x3 + x2, 18); + x6 ^= ROTL32(x5 + x4, 7); + x7 ^= ROTL32(x6 + x5, 9); + x4 ^= ROTL32(x7 + x6, 13); + x5 ^= ROTL32(x4 + x7, 18); + x11 ^= ROTL32(x10 + x9, 7); + x8 ^= ROTL32(x11 + x10, 9); + x9 ^= ROTL32(x8 + x11, 13); + x10 ^= ROTL32(x9 + x8, 18); + x12 ^= ROTL32(x15 + x14, 7); + x13 ^= ROTL32(x12 + x15, 9); + x14 ^= ROTL32(x13 + x12, 13); + x15 ^= ROTL32(x14 + x13, 18); + } + STORE32_LE(out + 0, x0 + j0); + STORE32_LE(out + 4, x1 + j1); + STORE32_LE(out + 8, x2 + j2); + STORE32_LE(out + 12, x3 + j3); + STORE32_LE(out + 16, x4 + j4); + STORE32_LE(out + 20, x5 + j5); + STORE32_LE(out + 24, x6 + j6); + STORE32_LE(out + 28, x7 + j7); + STORE32_LE(out + 32, x8 + j8); + STORE32_LE(out + 36, x9 + j9); + STORE32_LE(out + 40, x10 + j10); + STORE32_LE(out + 44, x11 + j11); + STORE32_LE(out + 48, x12 + j12); + STORE32_LE(out + 52, x13 + j13); + STORE32_LE(out + 56, x14 + j14); + STORE32_LE(out + 60, x15 + j15); +} + +int +crypto_core_salsa20(unsigned char *out, const unsigned char *in, + const unsigned char *k, const unsigned char *c) +{ + crypto_core_salsa(out, in, k, c, 20); + return 0; +} + +size_t +crypto_core_salsa20_outputbytes(void) +{ + return crypto_core_salsa20_OUTPUTBYTES; +} + +size_t +crypto_core_salsa20_inputbytes(void) +{ + return crypto_core_salsa20_INPUTBYTES; +} + +size_t +crypto_core_salsa20_keybytes(void) +{ + return crypto_core_salsa20_KEYBYTES; +} + +size_t +crypto_core_salsa20_constbytes(void) +{ + return crypto_core_salsa20_CONSTBYTES; +} + +#ifndef MINIMAL + +int +crypto_core_salsa2012(unsigned char *out, const unsigned char *in, + const unsigned char *k, const unsigned char *c) +{ + crypto_core_salsa(out, in, k, c, 12); + return 0; +} + +size_t +crypto_core_salsa2012_outputbytes(void) +{ + return crypto_core_salsa2012_OUTPUTBYTES; +} + +size_t +crypto_core_salsa2012_inputbytes(void) +{ + return crypto_core_salsa2012_INPUTBYTES; +} + +size_t +crypto_core_salsa2012_keybytes(void) +{ + return crypto_core_salsa2012_KEYBYTES; +} + +size_t +crypto_core_salsa2012_constbytes(void) +{ + return crypto_core_salsa2012_CONSTBYTES; +} + +int +crypto_core_salsa208(unsigned char *out, const unsigned char *in, + const unsigned char *k, const unsigned char *c) +{ + crypto_core_salsa(out, in, k, c, 8); + return 0; +} + +size_t +crypto_core_salsa208_outputbytes(void) +{ + return crypto_core_salsa208_OUTPUTBYTES; +} + +size_t +crypto_core_salsa208_inputbytes(void) +{ + return crypto_core_salsa208_INPUTBYTES; +} + +size_t +crypto_core_salsa208_keybytes(void) +{ + return crypto_core_salsa208_KEYBYTES; +} + +size_t +crypto_core_salsa208_constbytes(void) +{ + return crypto_core_salsa208_CONSTBYTES; +} + +#endif diff --git a/libs/libsodium/src/crypto_generichash/blake2b/generichash_blake2.c b/libs/libsodium/src/crypto_generichash/blake2b/generichash_blake2.c new file mode 100644 index 0000000000..781d4c584e --- /dev/null +++ b/libs/libsodium/src/crypto_generichash/blake2b/generichash_blake2.c @@ -0,0 +1,55 @@ +#include "crypto_generichash_blake2b.h" +#include "randombytes.h" + +size_t +crypto_generichash_blake2b_bytes_min(void) { + return crypto_generichash_blake2b_BYTES_MIN; +} + +size_t +crypto_generichash_blake2b_bytes_max(void) { + return crypto_generichash_blake2b_BYTES_MAX; +} + +size_t +crypto_generichash_blake2b_bytes(void) { + return crypto_generichash_blake2b_BYTES; +} + +size_t +crypto_generichash_blake2b_keybytes_min(void) { + return crypto_generichash_blake2b_KEYBYTES_MIN; +} + +size_t +crypto_generichash_blake2b_keybytes_max(void) { + return crypto_generichash_blake2b_KEYBYTES_MAX; +} + +size_t +crypto_generichash_blake2b_keybytes(void) { + return crypto_generichash_blake2b_KEYBYTES; +} + +size_t +crypto_generichash_blake2b_saltbytes(void) { + return crypto_generichash_blake2b_SALTBYTES; +} + +size_t +crypto_generichash_blake2b_personalbytes(void) { + return crypto_generichash_blake2b_PERSONALBYTES; +} + +size_t +crypto_generichash_blake2b_statebytes(void) +{ + return (sizeof(crypto_generichash_blake2b_state) + (size_t) 63U) + & ~(size_t) 63U; +} + +void +crypto_generichash_blake2b_keygen(unsigned char k[crypto_generichash_blake2b_KEYBYTES]) +{ + randombytes_buf(k, crypto_generichash_blake2b_KEYBYTES); +} diff --git a/libs/libsodium/src/crypto_generichash/blake2b/ref/blake2.h b/libs/libsodium/src/crypto_generichash/blake2b/ref/blake2.h new file mode 100644 index 0000000000..c6c4fccbb7 --- /dev/null +++ b/libs/libsodium/src/crypto_generichash/blake2b/ref/blake2.h @@ -0,0 +1,109 @@ +/* + BLAKE2 reference source code package - reference C implementations + + Written in 2012 by Samuel Neves <sneves@dei.uc.pt> + + To the extent possible under law, the author(s) have dedicated all copyright + and related and neighboring rights to this software to the public domain + worldwide. This software is distributed without any warranty. + + All code is triple-licensed under the + [CC0](http://creativecommons.org/publicdomain/zero/1.0), the + [OpenSSL Licence](https://www.openssl.org/source/license.html), or + the [Apache Public License 2.0](http://www.apache.org/licenses/LICENSE-2.0), + at your choosing. + */ + +#ifndef blake2_H +#define blake2_H + +#include <stddef.h> +#include <stdint.h> + +#include "crypto_generichash_blake2b.h" +#include "export.h" + +#define blake2b_init_param crypto_generichash_blake2b__init_param +#define blake2b_init crypto_generichash_blake2b__init +#define blake2b_init_salt_personal \ + crypto_generichash_blake2b__init_salt_personal +#define blake2b_init_key crypto_generichash_blake2b__init_key +#define blake2b_init_key_salt_personal \ + crypto_generichash_blake2b__init_key_salt_personal +#define blake2b_update crypto_generichash_blake2b__update +#define blake2b_final crypto_generichash_blake2b__final +#define blake2b crypto_generichash_blake2b__blake2b +#define blake2b_salt_personal crypto_generichash_blake2b__blake2b_salt_personal +#define blake2b_pick_best_implementation \ + crypto_generichash_blake2b__pick_best_implementation + +enum blake2b_constant { + BLAKE2B_BLOCKBYTES = 128, + BLAKE2B_OUTBYTES = 64, + BLAKE2B_KEYBYTES = 64, + BLAKE2B_SALTBYTES = 16, + BLAKE2B_PERSONALBYTES = 16 +}; + +#if defined(__IBMC__) || defined(__SUNPRO_C) || defined(__SUNPRO_CC) +#pragma pack(1) +#else +#pragma pack(push, 1) +#endif + +typedef struct blake2b_param_ { + uint8_t digest_length; /* 1 */ + uint8_t key_length; /* 2 */ + uint8_t fanout; /* 3 */ + uint8_t depth; /* 4 */ + uint8_t leaf_length[4]; /* 8 */ + uint8_t node_offset[8]; /* 16 */ + uint8_t node_depth; /* 17 */ + uint8_t inner_length; /* 18 */ + uint8_t reserved[14]; /* 32 */ + uint8_t salt[BLAKE2B_SALTBYTES]; /* 48 */ + uint8_t personal[BLAKE2B_PERSONALBYTES]; /* 64 */ +} blake2b_param; + +typedef crypto_generichash_blake2b_state blake2b_state; + +#if defined(__IBMC__) || defined(__SUNPRO_C) || defined(__SUNPRO_CC) +#pragma pack() +#else +#pragma pack(pop) +#endif + +/* Streaming API */ +int blake2b_init(blake2b_state *S, const uint8_t outlen); +int blake2b_init_salt_personal(blake2b_state *S, const uint8_t outlen, + const void *salt, const void *personal); +int blake2b_init_key(blake2b_state *S, const uint8_t outlen, const void *key, + const uint8_t keylen); +int blake2b_init_key_salt_personal(blake2b_state *S, const uint8_t outlen, + const void *key, const uint8_t keylen, + const void *salt, const void *personal); +int blake2b_init_param(blake2b_state *S, const blake2b_param *P); +int blake2b_update(blake2b_state *S, const uint8_t *in, uint64_t inlen); +int blake2b_final(blake2b_state *S, uint8_t *out, uint8_t outlen); + +/* Simple API */ +int blake2b(uint8_t *out, const void *in, const void *key, const uint8_t outlen, + const uint64_t inlen, uint8_t keylen); +int blake2b_salt_personal(uint8_t *out, const void *in, const void *key, + const uint8_t outlen, const uint64_t inlen, + uint8_t keylen, const void *salt, + const void *personal); + +typedef int (*blake2b_compress_fn)(blake2b_state *S, + const uint8_t block[BLAKE2B_BLOCKBYTES]); +int blake2b_pick_best_implementation(void); +int blake2b_compress_ref(blake2b_state *S, + const uint8_t block[BLAKE2B_BLOCKBYTES]); +int blake2b_compress_ssse3(blake2b_state *S, + const uint8_t block[BLAKE2B_BLOCKBYTES]); +int blake2b_compress_sse41(blake2b_state *S, + const uint8_t block[BLAKE2B_BLOCKBYTES]); +int blake2b_compress_avx2(blake2b_state *S, + const uint8_t block[BLAKE2B_BLOCKBYTES]); + +#endif diff --git a/libs/libsodium/src/crypto_generichash/blake2b/ref/blake2b-compress-avx2.c b/libs/libsodium/src/crypto_generichash/blake2b/ref/blake2b-compress-avx2.c new file mode 100644 index 0000000000..7cb41fb6e7 --- /dev/null +++ b/libs/libsodium/src/crypto_generichash/blake2b/ref/blake2b-compress-avx2.c @@ -0,0 +1,49 @@ + +#define BLAKE2_USE_SSSE3 +#define BLAKE2_USE_SSE41 +#define BLAKE2_USE_AVX2 + +#include <stdint.h> +#include <string.h> + +#include "blake2.h" +#include "private/common.h" +#include "private/sse2_64_32.h" + +#if defined(HAVE_AVX2INTRIN_H) && defined(HAVE_EMMINTRIN_H) && \ + defined(HAVE_TMMINTRIN_H) && defined(HAVE_SMMINTRIN_H) + +# ifdef __GNUC__ +# pragma GCC target("sse2") +# pragma GCC target("ssse3") +# pragma GCC target("sse4.1") +# pragma GCC target("avx2") +# endif + +# include <emmintrin.h> +# include <immintrin.h> +# include <smmintrin.h> +# include <tmmintrin.h> + +# include "blake2b-compress-avx2.h" + +CRYPTO_ALIGN(64) +static const uint64_t blake2b_IV[8] = { + 0x6a09e667f3bcc908ULL, 0xbb67ae8584caa73bULL, 0x3c6ef372fe94f82bULL, + 0xa54ff53a5f1d36f1ULL, 0x510e527fade682d1ULL, 0x9b05688c2b3e6c1fULL, + 0x1f83d9abfb41bd6bULL, 0x5be0cd19137e2179ULL +}; + +int +blake2b_compress_avx2(blake2b_state *S, const uint8_t block[BLAKE2B_BLOCKBYTES]) +{ + __m256i a = LOADU(&S->h[0]); + __m256i b = LOADU(&S->h[4]); + BLAKE2B_COMPRESS_V1(a, b, block, S->t[0], S->t[1], S->f[0], S->f[1]); + STOREU(&S->h[0], a); + STOREU(&S->h[4], b); + + return 0; +} + +#endif diff --git a/libs/libsodium/src/crypto_generichash/blake2b/ref/blake2b-compress-avx2.h b/libs/libsodium/src/crypto_generichash/blake2b/ref/blake2b-compress-avx2.h new file mode 100644 index 0000000000..21acb2fa0c --- /dev/null +++ b/libs/libsodium/src/crypto_generichash/blake2b/ref/blake2b-compress-avx2.h @@ -0,0 +1,140 @@ + +#ifndef blake2b_compress_avx2_H +#define blake2b_compress_avx2_H + +#define LOAD128(p) _mm_load_si128((__m128i *) (p)) +#define STORE128(p, r) _mm_store_si128((__m128i *) (p), r) + +#define LOADU128(p) _mm_loadu_si128((__m128i *) (p)) +#define STOREU128(p, r) _mm_storeu_si128((__m128i *) (p), r) + +#define LOAD(p) _mm256_load_si256((__m256i *) (p)) +#define STORE(p, r) _mm256_store_si256((__m256i *) (p), r) + +#define LOADU(p) _mm256_loadu_si256((__m256i *) (p)) +#define STOREU(p, r) _mm256_storeu_si256((__m256i *) (p), r) + +static inline uint64_t +LOADU64(const void *p) +{ + uint64_t v; + memcpy(&v, p, sizeof v); + return v; +} + +#define ROTATE16 \ + _mm256_setr_epi8(2, 3, 4, 5, 6, 7, 0, 1, 10, 11, 12, 13, 14, 15, 8, 9, 2, \ + 3, 4, 5, 6, 7, 0, 1, 10, 11, 12, 13, 14, 15, 8, 9) + +#define ROTATE24 \ + _mm256_setr_epi8(3, 4, 5, 6, 7, 0, 1, 2, 11, 12, 13, 14, 15, 8, 9, 10, 3, \ + 4, 5, 6, 7, 0, 1, 2, 11, 12, 13, 14, 15, 8, 9, 10) + +#define ADD(a, b) _mm256_add_epi64(a, b) +#define SUB(a, b) _mm256_sub_epi64(a, b) + +#define XOR(a, b) _mm256_xor_si256(a, b) +#define AND(a, b) _mm256_and_si256(a, b) +#define OR(a, b) _mm256_or_si256(a, b) + +#define ROT32(x) _mm256_shuffle_epi32((x), _MM_SHUFFLE(2, 3, 0, 1)) +#define ROT24(x) _mm256_shuffle_epi8((x), ROTATE24) +#define ROT16(x) _mm256_shuffle_epi8((x), ROTATE16) +#define ROT63(x) _mm256_or_si256(_mm256_srli_epi64((x), 63), ADD((x), (x))) + +#define BLAKE2B_G1_V1(a, b, c, d, m) \ + do { \ + a = ADD(a, m); \ + a = ADD(a, b); \ + d = XOR(d, a); \ + d = ROT32(d); \ + c = ADD(c, d); \ + b = XOR(b, c); \ + b = ROT24(b); \ + } while (0) + +#define BLAKE2B_G2_V1(a, b, c, d, m) \ + do { \ + a = ADD(a, m); \ + a = ADD(a, b); \ + d = XOR(d, a); \ + d = ROT16(d); \ + c = ADD(c, d); \ + b = XOR(b, c); \ + b = ROT63(b); \ + } while (0) + +#define BLAKE2B_DIAG_V1(a, b, c, d) \ + do { \ + d = _mm256_permute4x64_epi64(d, _MM_SHUFFLE(2, 1, 0, 3)); \ + c = _mm256_permute4x64_epi64(c, _MM_SHUFFLE(1, 0, 3, 2)); \ + b = _mm256_permute4x64_epi64(b, _MM_SHUFFLE(0, 3, 2, 1)); \ + } while (0) + +#define BLAKE2B_UNDIAG_V1(a, b, c, d) \ + do { \ + d = _mm256_permute4x64_epi64(d, _MM_SHUFFLE(0, 3, 2, 1)); \ + c = _mm256_permute4x64_epi64(c, _MM_SHUFFLE(1, 0, 3, 2)); \ + b = _mm256_permute4x64_epi64(b, _MM_SHUFFLE(2, 1, 0, 3)); \ + } while (0) + +#include "blake2b-load-avx2.h" + +#define BLAKE2B_ROUND_V1(a, b, c, d, r, m) \ + do { \ + __m256i b0; \ + BLAKE2B_LOAD_MSG_##r##_1(b0); \ + BLAKE2B_G1_V1(a, b, c, d, b0); \ + BLAKE2B_LOAD_MSG_##r##_2(b0); \ + BLAKE2B_G2_V1(a, b, c, d, b0); \ + BLAKE2B_DIAG_V1(a, b, c, d); \ + BLAKE2B_LOAD_MSG_##r##_3(b0); \ + BLAKE2B_G1_V1(a, b, c, d, b0); \ + BLAKE2B_LOAD_MSG_##r##_4(b0); \ + BLAKE2B_G2_V1(a, b, c, d, b0); \ + BLAKE2B_UNDIAG_V1(a, b, c, d); \ + } while (0) + +#define BLAKE2B_ROUNDS_V1(a, b, c, d, m) \ + do { \ + BLAKE2B_ROUND_V1(a, b, c, d, 0, (m)); \ + BLAKE2B_ROUND_V1(a, b, c, d, 1, (m)); \ + BLAKE2B_ROUND_V1(a, b, c, d, 2, (m)); \ + BLAKE2B_ROUND_V1(a, b, c, d, 3, (m)); \ + BLAKE2B_ROUND_V1(a, b, c, d, 4, (m)); \ + BLAKE2B_ROUND_V1(a, b, c, d, 5, (m)); \ + BLAKE2B_ROUND_V1(a, b, c, d, 6, (m)); \ + BLAKE2B_ROUND_V1(a, b, c, d, 7, (m)); \ + BLAKE2B_ROUND_V1(a, b, c, d, 8, (m)); \ + BLAKE2B_ROUND_V1(a, b, c, d, 9, (m)); \ + BLAKE2B_ROUND_V1(a, b, c, d, 10, (m)); \ + BLAKE2B_ROUND_V1(a, b, c, d, 11, (m)); \ + } while (0) + +#define DECLARE_MESSAGE_WORDS(m) \ + const __m256i m0 = _mm256_broadcastsi128_si256(LOADU128((m) + 0)); \ + const __m256i m1 = _mm256_broadcastsi128_si256(LOADU128((m) + 16)); \ + const __m256i m2 = _mm256_broadcastsi128_si256(LOADU128((m) + 32)); \ + const __m256i m3 = _mm256_broadcastsi128_si256(LOADU128((m) + 48)); \ + const __m256i m4 = _mm256_broadcastsi128_si256(LOADU128((m) + 64)); \ + const __m256i m5 = _mm256_broadcastsi128_si256(LOADU128((m) + 80)); \ + const __m256i m6 = _mm256_broadcastsi128_si256(LOADU128((m) + 96)); \ + const __m256i m7 = _mm256_broadcastsi128_si256(LOADU128((m) + 112)); \ + __m256i t0, t1; + +#define BLAKE2B_COMPRESS_V1(a, b, m, t0, t1, f0, f1) \ + do { \ + DECLARE_MESSAGE_WORDS(m) \ + const __m256i iv0 = a; \ + const __m256i iv1 = b; \ + __m256i c = LOAD(&blake2b_IV[0]); \ + __m256i d = \ + XOR(LOAD(&blake2b_IV[4]), _mm256_set_epi64x(f1, f0, t1, t0)); \ + BLAKE2B_ROUNDS_V1(a, b, c, d, m); \ + a = XOR(a, c); \ + b = XOR(b, d); \ + a = XOR(a, iv0); \ + b = XOR(b, iv1); \ + } while (0) + +#endif diff --git a/libs/libsodium/src/crypto_generichash/blake2b/ref/blake2b-compress-ref.c b/libs/libsodium/src/crypto_generichash/blake2b/ref/blake2b-compress-ref.c new file mode 100644 index 0000000000..614fa34af7 --- /dev/null +++ b/libs/libsodium/src/crypto_generichash/blake2b/ref/blake2b-compress-ref.c @@ -0,0 +1,93 @@ + +#include <stdint.h> +#include <string.h> + +#include "blake2.h" +#include "private/common.h" + +CRYPTO_ALIGN(64) +static const uint64_t blake2b_IV[8] = { + 0x6a09e667f3bcc908ULL, 0xbb67ae8584caa73bULL, 0x3c6ef372fe94f82bULL, + 0xa54ff53a5f1d36f1ULL, 0x510e527fade682d1ULL, 0x9b05688c2b3e6c1fULL, + 0x1f83d9abfb41bd6bULL, 0x5be0cd19137e2179ULL +}; + +static const uint8_t blake2b_sigma[12][16] = { + { 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 }, + { 11, 8, 12, 0, 5, 2, 15, 13, 10, 14, 3, 6, 7, 1, 9, 4 }, + { 7, 9, 3, 1, 13, 12, 11, 14, 2, 6, 5, 10, 4, 0, 15, 8 }, + { 9, 0, 5, 7, 2, 4, 10, 15, 14, 1, 11, 12, 6, 8, 3, 13 }, + { 2, 12, 6, 10, 0, 11, 8, 3, 4, 13, 7, 5, 15, 14, 1, 9 }, + { 12, 5, 1, 15, 14, 13, 4, 10, 0, 7, 6, 3, 9, 2, 8, 11 }, + { 13, 11, 7, 14, 12, 1, 3, 9, 5, 0, 15, 4, 8, 6, 2, 10 }, + { 6, 15, 14, 9, 11, 3, 0, 8, 12, 2, 13, 7, 1, 4, 10, 5 }, + { 10, 2, 8, 4, 7, 6, 1, 5, 15, 11, 9, 14, 3, 12, 13, 0 }, + { 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 } +}; + +int +blake2b_compress_ref(blake2b_state *S, const uint8_t block[BLAKE2B_BLOCKBYTES]) +{ + uint64_t m[16]; + uint64_t v[16]; + int i; + + for (i = 0; i < 16; ++i) + m[i] = LOAD64_LE(block + i * sizeof(m[i])); + + for (i = 0; i < 8; ++i) + v[i] = S->h[i]; + + v[8] = blake2b_IV[0]; + v[9] = blake2b_IV[1]; + v[10] = blake2b_IV[2]; + v[11] = blake2b_IV[3]; + v[12] = S->t[0] ^ blake2b_IV[4]; + v[13] = S->t[1] ^ blake2b_IV[5]; + v[14] = S->f[0] ^ blake2b_IV[6]; + v[15] = S->f[1] ^ blake2b_IV[7]; +#define G(r, i, a, b, c, d) \ + do { \ + a = a + b + m[blake2b_sigma[r][2 * i + 0]]; \ + d = ROTR64(d ^ a, 32); \ + c = c + d; \ + b = ROTR64(b ^ c, 24); \ + a = a + b + m[blake2b_sigma[r][2 * i + 1]]; \ + d = ROTR64(d ^ a, 16); \ + c = c + d; \ + b = ROTR64(b ^ c, 63); \ + } while (0) +#define ROUND(r) \ + do { \ + G(r, 0, v[0], v[4], v[8], v[12]); \ + G(r, 1, v[1], v[5], v[9], v[13]); \ + G(r, 2, v[2], v[6], v[10], v[14]); \ + G(r, 3, v[3], v[7], v[11], v[15]); \ + G(r, 4, v[0], v[5], v[10], v[15]); \ + G(r, 5, v[1], v[6], v[11], v[12]); \ + G(r, 6, v[2], v[7], v[8], v[13]); \ + G(r, 7, v[3], v[4], v[9], v[14]); \ + } while (0) + ROUND(0); + ROUND(1); + ROUND(2); + ROUND(3); + ROUND(4); + ROUND(5); + ROUND(6); + ROUND(7); + ROUND(8); + ROUND(9); + ROUND(10); + ROUND(11); + + for (i = 0; i < 8; ++i) { + S->h[i] = S->h[i] ^ v[i] ^ v[i + 8]; + } + +#undef G +#undef ROUND + return 0; +} diff --git a/libs/libsodium/src/crypto_generichash/blake2b/ref/blake2b-compress-sse41.c b/libs/libsodium/src/crypto_generichash/blake2b/ref/blake2b-compress-sse41.c new file mode 100644 index 0000000000..9e5c0c5081 --- /dev/null +++ b/libs/libsodium/src/crypto_generichash/blake2b/ref/blake2b-compress-sse41.c @@ -0,0 +1,87 @@ + +#define BLAKE2_USE_SSSE3 +#define BLAKE2_USE_SSE41 + +#include <stdint.h> +#include <string.h> + +#include "blake2.h" +#include "private/common.h" +#include "private/sse2_64_32.h" + +#if defined(HAVE_EMMINTRIN_H) && defined(HAVE_TMMINTRIN_H) && \ + defined(HAVE_SMMINTRIN_H) + +# ifdef __GNUC__ +# pragma GCC target("sse2") +# pragma GCC target("ssse3") +# pragma GCC target("sse4.1") +# endif + +# include <emmintrin.h> +# include <smmintrin.h> +# include <tmmintrin.h> + +# include "blake2b-compress-sse41.h" + +CRYPTO_ALIGN(64) +static const uint64_t blake2b_IV[8] = { + 0x6a09e667f3bcc908ULL, 0xbb67ae8584caa73bULL, 0x3c6ef372fe94f82bULL, + 0xa54ff53a5f1d36f1ULL, 0x510e527fade682d1ULL, 0x9b05688c2b3e6c1fULL, + 0x1f83d9abfb41bd6bULL, 0x5be0cd19137e2179ULL +}; + +int +blake2b_compress_sse41(blake2b_state *S, + const uint8_t block[BLAKE2B_BLOCKBYTES]) +{ + __m128i row1l, row1h; + __m128i row2l, row2h; + __m128i row3l, row3h; + __m128i row4l, row4h; + __m128i b0, b1; + __m128i t0, t1; + const __m128i r16 = + _mm_setr_epi8(2, 3, 4, 5, 6, 7, 0, 1, 10, 11, 12, 13, 14, 15, 8, 9); + const __m128i r24 = + _mm_setr_epi8(3, 4, 5, 6, 7, 0, 1, 2, 11, 12, 13, 14, 15, 8, 9, 10); + const __m128i m0 = LOADU(block + 00); + const __m128i m1 = LOADU(block + 16); + const __m128i m2 = LOADU(block + 32); + const __m128i m3 = LOADU(block + 48); + const __m128i m4 = LOADU(block + 64); + const __m128i m5 = LOADU(block + 80); + const __m128i m6 = LOADU(block + 96); + const __m128i m7 = LOADU(block + 112); + row1l = LOADU(&S->h[0]); + row1h = LOADU(&S->h[2]); + row2l = LOADU(&S->h[4]); + row2h = LOADU(&S->h[6]); + row3l = LOADU(&blake2b_IV[0]); + row3h = LOADU(&blake2b_IV[2]); + row4l = _mm_xor_si128(LOADU(&blake2b_IV[4]), LOADU(&S->t[0])); + row4h = _mm_xor_si128(LOADU(&blake2b_IV[6]), LOADU(&S->f[0])); + ROUND(0); + ROUND(1); + ROUND(2); + ROUND(3); + ROUND(4); + ROUND(5); + ROUND(6); + ROUND(7); + ROUND(8); + ROUND(9); + ROUND(10); + ROUND(11); + row1l = _mm_xor_si128(row3l, row1l); + row1h = _mm_xor_si128(row3h, row1h); + STOREU(&S->h[0], _mm_xor_si128(LOADU(&S->h[0]), row1l)); + STOREU(&S->h[2], _mm_xor_si128(LOADU(&S->h[2]), row1h)); + row2l = _mm_xor_si128(row4l, row2l); + row2h = _mm_xor_si128(row4h, row2h); + STOREU(&S->h[4], _mm_xor_si128(LOADU(&S->h[4]), row2l)); + STOREU(&S->h[6], _mm_xor_si128(LOADU(&S->h[6]), row2h)); + return 0; +} + +#endif diff --git a/libs/libsodium/src/crypto_generichash/blake2b/ref/blake2b-compress-sse41.h b/libs/libsodium/src/crypto_generichash/blake2b/ref/blake2b-compress-sse41.h new file mode 100644 index 0000000000..ac78e5bb1e --- /dev/null +++ b/libs/libsodium/src/crypto_generichash/blake2b/ref/blake2b-compress-sse41.h @@ -0,0 +1,103 @@ + +#ifndef blake2b_compress_sse41_H +#define blake2b_compress_sse41_H + +#define LOADU(p) _mm_loadu_si128((const __m128i *) (const void *) (p)) +#define STOREU(p, r) _mm_storeu_si128((__m128i *) (void *) (p), r) + +#define _mm_roti_epi64(x, c) \ + (-(c) == 32) \ + ? _mm_shuffle_epi32((x), _MM_SHUFFLE(2, 3, 0, 1)) \ + : (-(c) == 24) \ + ? _mm_shuffle_epi8((x), r24) \ + : (-(c) == 16) \ + ? _mm_shuffle_epi8((x), r16) \ + : (-(c) == 63) \ + ? _mm_xor_si128(_mm_srli_epi64((x), -(c)), \ + _mm_add_epi64((x), (x))) \ + : _mm_xor_si128(_mm_srli_epi64((x), -(c)), \ + _mm_slli_epi64((x), 64 - (-(c)))) + +#define G1(row1l, row2l, row3l, row4l, row1h, row2h, row3h, row4h, b0, b1) \ + row1l = _mm_add_epi64(_mm_add_epi64(row1l, b0), row2l); \ + row1h = _mm_add_epi64(_mm_add_epi64(row1h, b1), row2h); \ + \ + row4l = _mm_xor_si128(row4l, row1l); \ + row4h = _mm_xor_si128(row4h, row1h); \ + \ + row4l = _mm_roti_epi64(row4l, -32); \ + row4h = _mm_roti_epi64(row4h, -32); \ + \ + row3l = _mm_add_epi64(row3l, row4l); \ + row3h = _mm_add_epi64(row3h, row4h); \ + \ + row2l = _mm_xor_si128(row2l, row3l); \ + row2h = _mm_xor_si128(row2h, row3h); \ + \ + row2l = _mm_roti_epi64(row2l, -24); \ + row2h = _mm_roti_epi64(row2h, -24); + +#define G2(row1l, row2l, row3l, row4l, row1h, row2h, row3h, row4h, b0, b1) \ + row1l = _mm_add_epi64(_mm_add_epi64(row1l, b0), row2l); \ + row1h = _mm_add_epi64(_mm_add_epi64(row1h, b1), row2h); \ + \ + row4l = _mm_xor_si128(row4l, row1l); \ + row4h = _mm_xor_si128(row4h, row1h); \ + \ + row4l = _mm_roti_epi64(row4l, -16); \ + row4h = _mm_roti_epi64(row4h, -16); \ + \ + row3l = _mm_add_epi64(row3l, row4l); \ + row3h = _mm_add_epi64(row3h, row4h); \ + \ + row2l = _mm_xor_si128(row2l, row3l); \ + row2h = _mm_xor_si128(row2h, row3h); \ + \ + row2l = _mm_roti_epi64(row2l, -63); \ + row2h = _mm_roti_epi64(row2h, -63); + +#define DIAGONALIZE(row1l, row2l, row3l, row4l, row1h, row2h, row3h, row4h) \ + t0 = _mm_alignr_epi8(row2h, row2l, 8); \ + t1 = _mm_alignr_epi8(row2l, row2h, 8); \ + row2l = t0; \ + row2h = t1; \ + \ + t0 = row3l; \ + row3l = row3h; \ + row3h = t0; \ + \ + t0 = _mm_alignr_epi8(row4h, row4l, 8); \ + t1 = _mm_alignr_epi8(row4l, row4h, 8); \ + row4l = t1; \ + row4h = t0; + +#define UNDIAGONALIZE(row1l, row2l, row3l, row4l, row1h, row2h, row3h, row4h) \ + t0 = _mm_alignr_epi8(row2l, row2h, 8); \ + t1 = _mm_alignr_epi8(row2h, row2l, 8); \ + row2l = t0; \ + row2h = t1; \ + \ + t0 = row3l; \ + row3l = row3h; \ + row3h = t0; \ + \ + t0 = _mm_alignr_epi8(row4l, row4h, 8); \ + t1 = _mm_alignr_epi8(row4h, row4l, 8); \ + row4l = t1; \ + row4h = t0; + +#include "blake2b-load-sse41.h" + +#define ROUND(r) \ + LOAD_MSG_##r##_1(b0, b1); \ + G1(row1l, row2l, row3l, row4l, row1h, row2h, row3h, row4h, b0, b1); \ + LOAD_MSG_##r##_2(b0, b1); \ + G2(row1l, row2l, row3l, row4l, row1h, row2h, row3h, row4h, b0, b1); \ + DIAGONALIZE(row1l, row2l, row3l, row4l, row1h, row2h, row3h, row4h); \ + LOAD_MSG_##r##_3(b0, b1); \ + G1(row1l, row2l, row3l, row4l, row1h, row2h, row3h, row4h, b0, b1); \ + LOAD_MSG_##r##_4(b0, b1); \ + G2(row1l, row2l, row3l, row4l, row1h, row2h, row3h, row4h, b0, b1); \ + UNDIAGONALIZE(row1l, row2l, row3l, row4l, row1h, row2h, row3h, row4h); + +#endif diff --git a/libs/libsodium/src/crypto_generichash/blake2b/ref/blake2b-compress-ssse3.c b/libs/libsodium/src/crypto_generichash/blake2b/ref/blake2b-compress-ssse3.c new file mode 100644 index 0000000000..a207a64d40 --- /dev/null +++ b/libs/libsodium/src/crypto_generichash/blake2b/ref/blake2b-compress-ssse3.c @@ -0,0 +1,90 @@ + +#include <stdint.h> +#include <string.h> + +#include "blake2.h" +#include "private/common.h" +#include "private/sse2_64_32.h" + +#if defined(HAVE_EMMINTRIN_H) && defined(HAVE_TMMINTRIN_H) + +# ifdef __GNUC__ +# pragma GCC target("sse2") +# pragma GCC target("ssse3") +# endif + +# include <emmintrin.h> +# include <tmmintrin.h> + +# include "blake2b-compress-ssse3.h" + +CRYPTO_ALIGN(64) +static const uint64_t blake2b_IV[8] = { + 0x6a09e667f3bcc908ULL, 0xbb67ae8584caa73bULL, 0x3c6ef372fe94f82bULL, + 0xa54ff53a5f1d36f1ULL, 0x510e527fade682d1ULL, 0x9b05688c2b3e6c1fULL, + 0x1f83d9abfb41bd6bULL, 0x5be0cd19137e2179ULL +}; + +int +blake2b_compress_ssse3(blake2b_state *S, + const uint8_t block[BLAKE2B_BLOCKBYTES]) +{ + __m128i row1l, row1h; + __m128i row2l, row2h; + __m128i row3l, row3h; + __m128i row4l, row4h; + __m128i b0, b1; + __m128i t0, t1; + const __m128i r16 = + _mm_setr_epi8(2, 3, 4, 5, 6, 7, 0, 1, 10, 11, 12, 13, 14, 15, 8, 9); + const __m128i r24 = + _mm_setr_epi8(3, 4, 5, 6, 7, 0, 1, 2, 11, 12, 13, 14, 15, 8, 9, 10); + const uint64_t m0 = ((uint64_t *) block)[0]; + const uint64_t m1 = ((uint64_t *) block)[1]; + const uint64_t m2 = ((uint64_t *) block)[2]; + const uint64_t m3 = ((uint64_t *) block)[3]; + const uint64_t m4 = ((uint64_t *) block)[4]; + const uint64_t m5 = ((uint64_t *) block)[5]; + const uint64_t m6 = ((uint64_t *) block)[6]; + const uint64_t m7 = ((uint64_t *) block)[7]; + const uint64_t m8 = ((uint64_t *) block)[8]; + const uint64_t m9 = ((uint64_t *) block)[9]; + const uint64_t m10 = ((uint64_t *) block)[10]; + const uint64_t m11 = ((uint64_t *) block)[11]; + const uint64_t m12 = ((uint64_t *) block)[12]; + const uint64_t m13 = ((uint64_t *) block)[13]; + const uint64_t m14 = ((uint64_t *) block)[14]; + const uint64_t m15 = ((uint64_t *) block)[15]; + + row1l = LOADU(&S->h[0]); + row1h = LOADU(&S->h[2]); + row2l = LOADU(&S->h[4]); + row2h = LOADU(&S->h[6]); + row3l = LOADU(&blake2b_IV[0]); + row3h = LOADU(&blake2b_IV[2]); + row4l = _mm_xor_si128(LOADU(&blake2b_IV[4]), LOADU(&S->t[0])); + row4h = _mm_xor_si128(LOADU(&blake2b_IV[6]), LOADU(&S->f[0])); + ROUND(0); + ROUND(1); + ROUND(2); + ROUND(3); + ROUND(4); + ROUND(5); + ROUND(6); + ROUND(7); + ROUND(8); + ROUND(9); + ROUND(10); + ROUND(11); + row1l = _mm_xor_si128(row3l, row1l); + row1h = _mm_xor_si128(row3h, row1h); + STOREU(&S->h[0], _mm_xor_si128(LOADU(&S->h[0]), row1l)); + STOREU(&S->h[2], _mm_xor_si128(LOADU(&S->h[2]), row1h)); + row2l = _mm_xor_si128(row4l, row2l); + row2h = _mm_xor_si128(row4h, row2h); + STOREU(&S->h[4], _mm_xor_si128(LOADU(&S->h[4]), row2l)); + STOREU(&S->h[6], _mm_xor_si128(LOADU(&S->h[6]), row2h)); + return 0; +} + +#endif diff --git a/libs/libsodium/src/crypto_generichash/blake2b/ref/blake2b-compress-ssse3.h b/libs/libsodium/src/crypto_generichash/blake2b/ref/blake2b-compress-ssse3.h new file mode 100644 index 0000000000..9a7164fe25 --- /dev/null +++ b/libs/libsodium/src/crypto_generichash/blake2b/ref/blake2b-compress-ssse3.h @@ -0,0 +1,103 @@ + +#ifndef blake2b_compress_ssse3_H +#define blake2b_compress_ssse3_H + +#define LOADU(p) _mm_loadu_si128((const __m128i *) (const void *) (p)) +#define STOREU(p, r) _mm_storeu_si128((__m128i *) (void *) (p), r) + +#define _mm_roti_epi64(x, c) \ + (-(c) == 32) \ + ? _mm_shuffle_epi32((x), _MM_SHUFFLE(2, 3, 0, 1)) \ + : (-(c) == 24) \ + ? _mm_shuffle_epi8((x), r24) \ + : (-(c) == 16) \ + ? _mm_shuffle_epi8((x), r16) \ + : (-(c) == 63) \ + ? _mm_xor_si128(_mm_srli_epi64((x), -(c)), \ + _mm_add_epi64((x), (x))) \ + : _mm_xor_si128(_mm_srli_epi64((x), -(c)), \ + _mm_slli_epi64((x), 64 - (-(c)))) + +#define G1(row1l, row2l, row3l, row4l, row1h, row2h, row3h, row4h, b0, b1) \ + row1l = _mm_add_epi64(_mm_add_epi64(row1l, b0), row2l); \ + row1h = _mm_add_epi64(_mm_add_epi64(row1h, b1), row2h); \ + \ + row4l = _mm_xor_si128(row4l, row1l); \ + row4h = _mm_xor_si128(row4h, row1h); \ + \ + row4l = _mm_roti_epi64(row4l, -32); \ + row4h = _mm_roti_epi64(row4h, -32); \ + \ + row3l = _mm_add_epi64(row3l, row4l); \ + row3h = _mm_add_epi64(row3h, row4h); \ + \ + row2l = _mm_xor_si128(row2l, row3l); \ + row2h = _mm_xor_si128(row2h, row3h); \ + \ + row2l = _mm_roti_epi64(row2l, -24); \ + row2h = _mm_roti_epi64(row2h, -24); + +#define G2(row1l, row2l, row3l, row4l, row1h, row2h, row3h, row4h, b0, b1) \ + row1l = _mm_add_epi64(_mm_add_epi64(row1l, b0), row2l); \ + row1h = _mm_add_epi64(_mm_add_epi64(row1h, b1), row2h); \ + \ + row4l = _mm_xor_si128(row4l, row1l); \ + row4h = _mm_xor_si128(row4h, row1h); \ + \ + row4l = _mm_roti_epi64(row4l, -16); \ + row4h = _mm_roti_epi64(row4h, -16); \ + \ + row3l = _mm_add_epi64(row3l, row4l); \ + row3h = _mm_add_epi64(row3h, row4h); \ + \ + row2l = _mm_xor_si128(row2l, row3l); \ + row2h = _mm_xor_si128(row2h, row3h); \ + \ + row2l = _mm_roti_epi64(row2l, -63); \ + row2h = _mm_roti_epi64(row2h, -63); + +#define DIAGONALIZE(row1l, row2l, row3l, row4l, row1h, row2h, row3h, row4h) \ + t0 = _mm_alignr_epi8(row2h, row2l, 8); \ + t1 = _mm_alignr_epi8(row2l, row2h, 8); \ + row2l = t0; \ + row2h = t1; \ + \ + t0 = row3l; \ + row3l = row3h; \ + row3h = t0; \ + \ + t0 = _mm_alignr_epi8(row4h, row4l, 8); \ + t1 = _mm_alignr_epi8(row4l, row4h, 8); \ + row4l = t1; \ + row4h = t0; + +#define UNDIAGONALIZE(row1l, row2l, row3l, row4l, row1h, row2h, row3h, row4h) \ + t0 = _mm_alignr_epi8(row2l, row2h, 8); \ + t1 = _mm_alignr_epi8(row2h, row2l, 8); \ + row2l = t0; \ + row2h = t1; \ + \ + t0 = row3l; \ + row3l = row3h; \ + row3h = t0; \ + \ + t0 = _mm_alignr_epi8(row4l, row4h, 8); \ + t1 = _mm_alignr_epi8(row4h, row4l, 8); \ + row4l = t1; \ + row4h = t0; + +#include "blake2b-load-sse2.h" + +#define ROUND(r) \ + LOAD_MSG_##r##_1(b0, b1); \ + G1(row1l, row2l, row3l, row4l, row1h, row2h, row3h, row4h, b0, b1); \ + LOAD_MSG_##r##_2(b0, b1); \ + G2(row1l, row2l, row3l, row4l, row1h, row2h, row3h, row4h, b0, b1); \ + DIAGONALIZE(row1l, row2l, row3l, row4l, row1h, row2h, row3h, row4h); \ + LOAD_MSG_##r##_3(b0, b1); \ + G1(row1l, row2l, row3l, row4l, row1h, row2h, row3h, row4h, b0, b1); \ + LOAD_MSG_##r##_4(b0, b1); \ + G2(row1l, row2l, row3l, row4l, row1h, row2h, row3h, row4h, b0, b1); \ + UNDIAGONALIZE(row1l, row2l, row3l, row4l, row1h, row2h, row3h, row4h); + +#endif diff --git a/libs/libsodium/src/crypto_generichash/blake2b/ref/blake2b-load-avx2.h b/libs/libsodium/src/crypto_generichash/blake2b/ref/blake2b-load-avx2.h new file mode 100644 index 0000000000..8c15f177c7 --- /dev/null +++ b/libs/libsodium/src/crypto_generichash/blake2b/ref/blake2b-load-avx2.h @@ -0,0 +1,340 @@ +#ifndef blake2b_load_avx2_H +#define blake2b_load_avx2_H + +#define BLAKE2B_LOAD_MSG_0_1(b0) \ + do { \ + t0 = _mm256_unpacklo_epi64(m0, m1); \ + t1 = _mm256_unpacklo_epi64(m2, m3); \ + b0 = _mm256_blend_epi32(t0, t1, 0xF0); \ + } while (0) + +#define BLAKE2B_LOAD_MSG_0_2(b0) \ + do { \ + t0 = _mm256_unpackhi_epi64(m0, m1); \ + t1 = _mm256_unpackhi_epi64(m2, m3); \ + b0 = _mm256_blend_epi32(t0, t1, 0xF0); \ + } while (0) + +#define BLAKE2B_LOAD_MSG_0_3(b0) \ + do { \ + t0 = _mm256_unpacklo_epi64(m4, m5); \ + t1 = _mm256_unpacklo_epi64(m6, m7); \ + b0 = _mm256_blend_epi32(t0, t1, 0xF0); \ + } while (0) + +#define BLAKE2B_LOAD_MSG_0_4(b0) \ + do { \ + t0 = _mm256_unpackhi_epi64(m4, m5); \ + t1 = _mm256_unpackhi_epi64(m6, m7); \ + b0 = _mm256_blend_epi32(t0, t1, 0xF0); \ + } while (0) + +#define BLAKE2B_LOAD_MSG_1_1(b0) \ + do { \ + t0 = _mm256_unpacklo_epi64(m7, m2); \ + t1 = _mm256_unpackhi_epi64(m4, m6); \ + b0 = _mm256_blend_epi32(t0, t1, 0xF0); \ + } while (0) + +#define BLAKE2B_LOAD_MSG_1_2(b0) \ + do { \ + t0 = _mm256_unpacklo_epi64(m5, m4); \ + t1 = _mm256_alignr_epi8(m3, m7, 8); \ + b0 = _mm256_blend_epi32(t0, t1, 0xF0); \ + } while (0) + +#define BLAKE2B_LOAD_MSG_1_3(b0) \ + do { \ + t0 = _mm256_shuffle_epi32(m0, _MM_SHUFFLE(1, 0, 3, 2)); \ + t1 = _mm256_unpackhi_epi64(m5, m2); \ + b0 = _mm256_blend_epi32(t0, t1, 0xF0); \ + } while (0) + +#define BLAKE2B_LOAD_MSG_1_4(b0) \ + do { \ + t0 = _mm256_unpacklo_epi64(m6, m1); \ + t1 = _mm256_unpackhi_epi64(m3, m1); \ + b0 = _mm256_blend_epi32(t0, t1, 0xF0); \ + } while (0) + +#define BLAKE2B_LOAD_MSG_2_1(b0) \ + do { \ + t0 = _mm256_alignr_epi8(m6, m5, 8); \ + t1 = _mm256_unpackhi_epi64(m2, m7); \ + b0 = _mm256_blend_epi32(t0, t1, 0xF0); \ + } while (0) + +#define BLAKE2B_LOAD_MSG_2_2(b0) \ + do { \ + t0 = _mm256_unpacklo_epi64(m4, m0); \ + t1 = _mm256_blend_epi32(m6, m1, 0x33); \ + b0 = _mm256_blend_epi32(t0, t1, 0xF0); \ + } while (0) + +#define BLAKE2B_LOAD_MSG_2_3(b0) \ + do { \ + t0 = _mm256_blend_epi32(m1, m5, 0x33); \ + t1 = _mm256_unpackhi_epi64(m3, m4); \ + b0 = _mm256_blend_epi32(t0, t1, 0xF0); \ + } while (0) + +#define BLAKE2B_LOAD_MSG_2_4(b0) \ + do { \ + t0 = _mm256_unpacklo_epi64(m7, m3); \ + t1 = _mm256_alignr_epi8(m2, m0, 8); \ + b0 = _mm256_blend_epi32(t0, t1, 0xF0); \ + } while (0) + +#define BLAKE2B_LOAD_MSG_3_1(b0) \ + do { \ + t0 = _mm256_unpackhi_epi64(m3, m1); \ + t1 = _mm256_unpackhi_epi64(m6, m5); \ + b0 = _mm256_blend_epi32(t0, t1, 0xF0); \ + } while (0) + +#define BLAKE2B_LOAD_MSG_3_2(b0) \ + do { \ + t0 = _mm256_unpackhi_epi64(m4, m0); \ + t1 = _mm256_unpacklo_epi64(m6, m7); \ + b0 = _mm256_blend_epi32(t0, t1, 0xF0); \ + } while (0) + +#define BLAKE2B_LOAD_MSG_3_3(b0) \ + do { \ + t0 = _mm256_blend_epi32(m2, m1, 0x33); \ + t1 = _mm256_blend_epi32(m7, m2, 0x33); \ + b0 = _mm256_blend_epi32(t0, t1, 0xF0); \ + } while (0) + +#define BLAKE2B_LOAD_MSG_3_4(b0) \ + do { \ + t0 = _mm256_unpacklo_epi64(m3, m5); \ + t1 = _mm256_unpacklo_epi64(m0, m4); \ + b0 = _mm256_blend_epi32(t0, t1, 0xF0); \ + } while (0) + +#define BLAKE2B_LOAD_MSG_4_1(b0) \ + do { \ + t0 = _mm256_unpackhi_epi64(m4, m2); \ + t1 = _mm256_unpacklo_epi64(m1, m5); \ + b0 = _mm256_blend_epi32(t0, t1, 0xF0); \ + } while (0) + +#define BLAKE2B_LOAD_MSG_4_2(b0) \ + do { \ + t0 = _mm256_blend_epi32(m3, m0, 0x33); \ + t1 = _mm256_blend_epi32(m7, m2, 0x33); \ + b0 = _mm256_blend_epi32(t0, t1, 0xF0); \ + } while (0) + +#define BLAKE2B_LOAD_MSG_4_3(b0) \ + do { \ + t0 = _mm256_blend_epi32(m5, m7, 0x33); \ + t1 = _mm256_blend_epi32(m1, m3, 0x33); \ + b0 = _mm256_blend_epi32(t0, t1, 0xF0); \ + } while (0) + +#define BLAKE2B_LOAD_MSG_4_4(b0) \ + do { \ + t0 = _mm256_alignr_epi8(m6, m0, 8); \ + t1 = _mm256_blend_epi32(m6, m4, 0x33); \ + b0 = _mm256_blend_epi32(t0, t1, 0xF0); \ + } while (0) + +#define BLAKE2B_LOAD_MSG_5_1(b0) \ + do { \ + t0 = _mm256_unpacklo_epi64(m1, m3); \ + t1 = _mm256_unpacklo_epi64(m0, m4); \ + b0 = _mm256_blend_epi32(t0, t1, 0xF0); \ + } while (0) + +#define BLAKE2B_LOAD_MSG_5_2(b0) \ + do { \ + t0 = _mm256_unpacklo_epi64(m6, m5); \ + t1 = _mm256_unpackhi_epi64(m5, m1); \ + b0 = _mm256_blend_epi32(t0, t1, 0xF0); \ + } while (0) + +#define BLAKE2B_LOAD_MSG_5_3(b0) \ + do { \ + t0 = _mm256_blend_epi32(m3, m2, 0x33); \ + t1 = _mm256_unpackhi_epi64(m7, m0); \ + b0 = _mm256_blend_epi32(t0, t1, 0xF0); \ + } while (0) + +#define BLAKE2B_LOAD_MSG_5_4(b0) \ + do { \ + t0 = _mm256_unpackhi_epi64(m6, m2); \ + t1 = _mm256_blend_epi32(m4, m7, 0x33); \ + b0 = _mm256_blend_epi32(t0, t1, 0xF0); \ + } while (0) + +#define BLAKE2B_LOAD_MSG_6_1(b0) \ + do { \ + t0 = _mm256_blend_epi32(m0, m6, 0x33); \ + t1 = _mm256_unpacklo_epi64(m7, m2); \ + b0 = _mm256_blend_epi32(t0, t1, 0xF0); \ + } while (0) + +#define BLAKE2B_LOAD_MSG_6_2(b0) \ + do { \ + t0 = _mm256_unpackhi_epi64(m2, m7); \ + t1 = _mm256_alignr_epi8(m5, m6, 8); \ + b0 = _mm256_blend_epi32(t0, t1, 0xF0); \ + } while (0) + +#define BLAKE2B_LOAD_MSG_6_3(b0) \ + do { \ + t0 = _mm256_unpacklo_epi64(m0, m3); \ + t1 = _mm256_shuffle_epi32(m4, _MM_SHUFFLE(1, 0, 3, 2)); \ + b0 = _mm256_blend_epi32(t0, t1, 0xF0); \ + } while (0) + +#define BLAKE2B_LOAD_MSG_6_4(b0) \ + do { \ + t0 = _mm256_unpackhi_epi64(m3, m1); \ + t1 = _mm256_blend_epi32(m5, m1, 0x33); \ + b0 = _mm256_blend_epi32(t0, t1, 0xF0); \ + } while (0) + +#define BLAKE2B_LOAD_MSG_7_1(b0) \ + do { \ + t0 = _mm256_unpackhi_epi64(m6, m3); \ + t1 = _mm256_blend_epi32(m1, m6, 0x33); \ + b0 = _mm256_blend_epi32(t0, t1, 0xF0); \ + } while (0) + +#define BLAKE2B_LOAD_MSG_7_2(b0) \ + do { \ + t0 = _mm256_alignr_epi8(m7, m5, 8); \ + t1 = _mm256_unpackhi_epi64(m0, m4); \ + b0 = _mm256_blend_epi32(t0, t1, 0xF0); \ + } while (0) + +#define BLAKE2B_LOAD_MSG_7_3(b0) \ + do { \ + t0 = _mm256_unpackhi_epi64(m2, m7); \ + t1 = _mm256_unpacklo_epi64(m4, m1); \ + b0 = _mm256_blend_epi32(t0, t1, 0xF0); \ + } while (0) + +#define BLAKE2B_LOAD_MSG_7_4(b0) \ + do { \ + t0 = _mm256_unpacklo_epi64(m0, m2); \ + t1 = _mm256_unpacklo_epi64(m3, m5); \ + b0 = _mm256_blend_epi32(t0, t1, 0xF0); \ + } while (0) + +#define BLAKE2B_LOAD_MSG_8_1(b0) \ + do { \ + t0 = _mm256_unpacklo_epi64(m3, m7); \ + t1 = _mm256_alignr_epi8(m0, m5, 8); \ + b0 = _mm256_blend_epi32(t0, t1, 0xF0); \ + } while (0) + +#define BLAKE2B_LOAD_MSG_8_2(b0) \ + do { \ + t0 = _mm256_unpackhi_epi64(m7, m4); \ + t1 = _mm256_alignr_epi8(m4, m1, 8); \ + b0 = _mm256_blend_epi32(t0, t1, 0xF0); \ + } while (0) + +#define BLAKE2B_LOAD_MSG_8_3(b0) \ + do { \ + t0 = m6; \ + t1 = _mm256_alignr_epi8(m5, m0, 8); \ + b0 = _mm256_blend_epi32(t0, t1, 0xF0); \ + } while (0) + +#define BLAKE2B_LOAD_MSG_8_4(b0) \ + do { \ + t0 = _mm256_blend_epi32(m3, m1, 0x33); \ + t1 = m2; \ + b0 = _mm256_blend_epi32(t0, t1, 0xF0); \ + } while (0) + +#define BLAKE2B_LOAD_MSG_9_1(b0) \ + do { \ + t0 = _mm256_unpacklo_epi64(m5, m4); \ + t1 = _mm256_unpackhi_epi64(m3, m0); \ + b0 = _mm256_blend_epi32(t0, t1, 0xF0); \ + } while (0) + +#define BLAKE2B_LOAD_MSG_9_2(b0) \ + do { \ + t0 = _mm256_unpacklo_epi64(m1, m2); \ + t1 = _mm256_blend_epi32(m2, m3, 0x33); \ + b0 = _mm256_blend_epi32(t0, t1, 0xF0); \ + } while (0) + +#define BLAKE2B_LOAD_MSG_9_3(b0) \ + do { \ + t0 = _mm256_unpackhi_epi64(m7, m4); \ + t1 = _mm256_unpackhi_epi64(m1, m6); \ + b0 = _mm256_blend_epi32(t0, t1, 0xF0); \ + } while (0) + +#define BLAKE2B_LOAD_MSG_9_4(b0) \ + do { \ + t0 = _mm256_alignr_epi8(m7, m5, 8); \ + t1 = _mm256_unpacklo_epi64(m6, m0); \ + b0 = _mm256_blend_epi32(t0, t1, 0xF0); \ + } while (0) + +#define BLAKE2B_LOAD_MSG_10_1(b0) \ + do { \ + t0 = _mm256_unpacklo_epi64(m0, m1); \ + t1 = _mm256_unpacklo_epi64(m2, m3); \ + b0 = _mm256_blend_epi32(t0, t1, 0xF0); \ + } while (0) + +#define BLAKE2B_LOAD_MSG_10_2(b0) \ + do { \ + t0 = _mm256_unpackhi_epi64(m0, m1); \ + t1 = _mm256_unpackhi_epi64(m2, m3); \ + b0 = _mm256_blend_epi32(t0, t1, 0xF0); \ + } while (0) + +#define BLAKE2B_LOAD_MSG_10_3(b0) \ + do { \ + t0 = _mm256_unpacklo_epi64(m4, m5); \ + t1 = _mm256_unpacklo_epi64(m6, m7); \ + b0 = _mm256_blend_epi32(t0, t1, 0xF0); \ + } while (0) + +#define BLAKE2B_LOAD_MSG_10_4(b0) \ + do { \ + t0 = _mm256_unpackhi_epi64(m4, m5); \ + t1 = _mm256_unpackhi_epi64(m6, m7); \ + b0 = _mm256_blend_epi32(t0, t1, 0xF0); \ + } while (0) + +#define BLAKE2B_LOAD_MSG_11_1(b0) \ + do { \ + t0 = _mm256_unpacklo_epi64(m7, m2); \ + t1 = _mm256_unpackhi_epi64(m4, m6); \ + b0 = _mm256_blend_epi32(t0, t1, 0xF0); \ + } while (0) + +#define BLAKE2B_LOAD_MSG_11_2(b0) \ + do { \ + t0 = _mm256_unpacklo_epi64(m5, m4); \ + t1 = _mm256_alignr_epi8(m3, m7, 8); \ + b0 = _mm256_blend_epi32(t0, t1, 0xF0); \ + } while (0) + +#define BLAKE2B_LOAD_MSG_11_3(b0) \ + do { \ + t0 = _mm256_shuffle_epi32(m0, _MM_SHUFFLE(1, 0, 3, 2)); \ + t1 = _mm256_unpackhi_epi64(m5, m2); \ + b0 = _mm256_blend_epi32(t0, t1, 0xF0); \ + } while (0) + +#define BLAKE2B_LOAD_MSG_11_4(b0) \ + do { \ + t0 = _mm256_unpacklo_epi64(m6, m1); \ + t1 = _mm256_unpackhi_epi64(m3, m1); \ + b0 = _mm256_blend_epi32(t0, t1, 0xF0); \ + } while (0) + +#endif diff --git a/libs/libsodium/src/crypto_generichash/blake2b/ref/blake2b-load-sse2.h b/libs/libsodium/src/crypto_generichash/blake2b/ref/blake2b-load-sse2.h new file mode 100644 index 0000000000..8e67421aca --- /dev/null +++ b/libs/libsodium/src/crypto_generichash/blake2b/ref/blake2b-load-sse2.h @@ -0,0 +1,164 @@ +/* + BLAKE2 reference source code package - optimized C implementations + + Written in 2012 by Samuel Neves <sneves@dei.uc.pt> + + To the extent possible under law, the author(s) have dedicated all copyright + and related and neighboring rights to this software to the public domain + worldwide. This software is distributed without any warranty. + + You should have received a copy of the CC0 Public Domain Dedication along + with + this software. If not, see + <http://creativecommons.org/publicdomain/zero/1.0/>. +*/ + +#ifndef blake2b_load_sse2_H +#define blake2b_load_sse2_H + +#define LOAD_MSG_0_1(b0, b1) \ + b0 = _mm_set_epi64x(m2, m0); \ + b1 = _mm_set_epi64x(m6, m4) +#define LOAD_MSG_0_2(b0, b1) \ + b0 = _mm_set_epi64x(m3, m1); \ + b1 = _mm_set_epi64x(m7, m5) +#define LOAD_MSG_0_3(b0, b1) \ + b0 = _mm_set_epi64x(m10, m8); \ + b1 = _mm_set_epi64x(m14, m12) +#define LOAD_MSG_0_4(b0, b1) \ + b0 = _mm_set_epi64x(m11, m9); \ + b1 = _mm_set_epi64x(m15, m13) +#define LOAD_MSG_1_1(b0, b1) \ + b0 = _mm_set_epi64x(m4, m14); \ + b1 = _mm_set_epi64x(m13, m9) +#define LOAD_MSG_1_2(b0, b1) \ + b0 = _mm_set_epi64x(m8, m10); \ + b1 = _mm_set_epi64x(m6, m15) +#define LOAD_MSG_1_3(b0, b1) \ + b0 = _mm_set_epi64x(m0, m1); \ + b1 = _mm_set_epi64x(m5, m11) +#define LOAD_MSG_1_4(b0, b1) \ + b0 = _mm_set_epi64x(m2, m12); \ + b1 = _mm_set_epi64x(m3, m7) +#define LOAD_MSG_2_1(b0, b1) \ + b0 = _mm_set_epi64x(m12, m11); \ + b1 = _mm_set_epi64x(m15, m5) +#define LOAD_MSG_2_2(b0, b1) \ + b0 = _mm_set_epi64x(m0, m8); \ + b1 = _mm_set_epi64x(m13, m2) +#define LOAD_MSG_2_3(b0, b1) \ + b0 = _mm_set_epi64x(m3, m10); \ + b1 = _mm_set_epi64x(m9, m7) +#define LOAD_MSG_2_4(b0, b1) \ + b0 = _mm_set_epi64x(m6, m14); \ + b1 = _mm_set_epi64x(m4, m1) +#define LOAD_MSG_3_1(b0, b1) \ + b0 = _mm_set_epi64x(m3, m7); \ + b1 = _mm_set_epi64x(m11, m13) +#define LOAD_MSG_3_2(b0, b1) \ + b0 = _mm_set_epi64x(m1, m9); \ + b1 = _mm_set_epi64x(m14, m12) +#define LOAD_MSG_3_3(b0, b1) \ + b0 = _mm_set_epi64x(m5, m2); \ + b1 = _mm_set_epi64x(m15, m4) +#define LOAD_MSG_3_4(b0, b1) \ + b0 = _mm_set_epi64x(m10, m6); \ + b1 = _mm_set_epi64x(m8, m0) +#define LOAD_MSG_4_1(b0, b1) \ + b0 = _mm_set_epi64x(m5, m9); \ + b1 = _mm_set_epi64x(m10, m2) +#define LOAD_MSG_4_2(b0, b1) \ + b0 = _mm_set_epi64x(m7, m0); \ + b1 = _mm_set_epi64x(m15, m4) +#define LOAD_MSG_4_3(b0, b1) \ + b0 = _mm_set_epi64x(m11, m14); \ + b1 = _mm_set_epi64x(m3, m6) +#define LOAD_MSG_4_4(b0, b1) \ + b0 = _mm_set_epi64x(m12, m1); \ + b1 = _mm_set_epi64x(m13, m8) +#define LOAD_MSG_5_1(b0, b1) \ + b0 = _mm_set_epi64x(m6, m2); \ + b1 = _mm_set_epi64x(m8, m0) +#define LOAD_MSG_5_2(b0, b1) \ + b0 = _mm_set_epi64x(m10, m12); \ + b1 = _mm_set_epi64x(m3, m11) +#define LOAD_MSG_5_3(b0, b1) \ + b0 = _mm_set_epi64x(m7, m4); \ + b1 = _mm_set_epi64x(m1, m15) +#define LOAD_MSG_5_4(b0, b1) \ + b0 = _mm_set_epi64x(m5, m13); \ + b1 = _mm_set_epi64x(m9, m14) +#define LOAD_MSG_6_1(b0, b1) \ + b0 = _mm_set_epi64x(m1, m12); \ + b1 = _mm_set_epi64x(m4, m14) +#define LOAD_MSG_6_2(b0, b1) \ + b0 = _mm_set_epi64x(m15, m5); \ + b1 = _mm_set_epi64x(m10, m13) +#define LOAD_MSG_6_3(b0, b1) \ + b0 = _mm_set_epi64x(m6, m0); \ + b1 = _mm_set_epi64x(m8, m9) +#define LOAD_MSG_6_4(b0, b1) \ + b0 = _mm_set_epi64x(m3, m7); \ + b1 = _mm_set_epi64x(m11, m2) +#define LOAD_MSG_7_1(b0, b1) \ + b0 = _mm_set_epi64x(m7, m13); \ + b1 = _mm_set_epi64x(m3, m12) +#define LOAD_MSG_7_2(b0, b1) \ + b0 = _mm_set_epi64x(m14, m11); \ + b1 = _mm_set_epi64x(m9, m1) +#define LOAD_MSG_7_3(b0, b1) \ + b0 = _mm_set_epi64x(m15, m5); \ + b1 = _mm_set_epi64x(m2, m8) +#define LOAD_MSG_7_4(b0, b1) \ + b0 = _mm_set_epi64x(m4, m0); \ + b1 = _mm_set_epi64x(m10, m6) +#define LOAD_MSG_8_1(b0, b1) \ + b0 = _mm_set_epi64x(m14, m6); \ + b1 = _mm_set_epi64x(m0, m11) +#define LOAD_MSG_8_2(b0, b1) \ + b0 = _mm_set_epi64x(m9, m15); \ + b1 = _mm_set_epi64x(m8, m3) +#define LOAD_MSG_8_3(b0, b1) \ + b0 = _mm_set_epi64x(m13, m12); \ + b1 = _mm_set_epi64x(m10, m1) +#define LOAD_MSG_8_4(b0, b1) \ + b0 = _mm_set_epi64x(m7, m2); \ + b1 = _mm_set_epi64x(m5, m4) +#define LOAD_MSG_9_1(b0, b1) \ + b0 = _mm_set_epi64x(m8, m10); \ + b1 = _mm_set_epi64x(m1, m7) +#define LOAD_MSG_9_2(b0, b1) \ + b0 = _mm_set_epi64x(m4, m2); \ + b1 = _mm_set_epi64x(m5, m6) +#define LOAD_MSG_9_3(b0, b1) \ + b0 = _mm_set_epi64x(m9, m15); \ + b1 = _mm_set_epi64x(m13, m3) +#define LOAD_MSG_9_4(b0, b1) \ + b0 = _mm_set_epi64x(m14, m11); \ + b1 = _mm_set_epi64x(m0, m12) +#define LOAD_MSG_10_1(b0, b1) \ + b0 = _mm_set_epi64x(m2, m0); \ + b1 = _mm_set_epi64x(m6, m4) +#define LOAD_MSG_10_2(b0, b1) \ + b0 = _mm_set_epi64x(m3, m1); \ + b1 = _mm_set_epi64x(m7, m5) +#define LOAD_MSG_10_3(b0, b1) \ + b0 = _mm_set_epi64x(m10, m8); \ + b1 = _mm_set_epi64x(m14, m12) +#define LOAD_MSG_10_4(b0, b1) \ + b0 = _mm_set_epi64x(m11, m9); \ + b1 = _mm_set_epi64x(m15, m13) +#define LOAD_MSG_11_1(b0, b1) \ + b0 = _mm_set_epi64x(m4, m14); \ + b1 = _mm_set_epi64x(m13, m9) +#define LOAD_MSG_11_2(b0, b1) \ + b0 = _mm_set_epi64x(m8, m10); \ + b1 = _mm_set_epi64x(m6, m15) +#define LOAD_MSG_11_3(b0, b1) \ + b0 = _mm_set_epi64x(m0, m1); \ + b1 = _mm_set_epi64x(m5, m11) +#define LOAD_MSG_11_4(b0, b1) \ + b0 = _mm_set_epi64x(m2, m12); \ + b1 = _mm_set_epi64x(m3, m7) + +#endif diff --git a/libs/libsodium/src/crypto_generichash/blake2b/ref/blake2b-load-sse41.h b/libs/libsodium/src/crypto_generichash/blake2b/ref/blake2b-load-sse41.h new file mode 100644 index 0000000000..31745fc139 --- /dev/null +++ b/libs/libsodium/src/crypto_generichash/blake2b/ref/blake2b-load-sse41.h @@ -0,0 +1,307 @@ +/* + BLAKE2 reference source code package - optimized C implementations + + Written in 2012 by Samuel Neves <sneves@dei.uc.pt> + + To the extent possible under law, the author(s) have dedicated all copyright + and related and neighboring rights to this software to the public domain + worldwide. This software is distributed without any warranty. + + You should have received a copy of the CC0 Public Domain Dedication along + with + this software. If not, see + <http://creativecommons.org/publicdomain/zero/1.0/>. +*/ + +#ifndef blake2b_load_sse41_H +#define blake2b_load_sse41_H + +#define LOAD_MSG_0_1(b0, b1) \ + do { \ + b0 = _mm_unpacklo_epi64(m0, m1); \ + b1 = _mm_unpacklo_epi64(m2, m3); \ + } while (0) + +#define LOAD_MSG_0_2(b0, b1) \ + do { \ + b0 = _mm_unpackhi_epi64(m0, m1); \ + b1 = _mm_unpackhi_epi64(m2, m3); \ + } while (0) + +#define LOAD_MSG_0_3(b0, b1) \ + do { \ + b0 = _mm_unpacklo_epi64(m4, m5); \ + b1 = _mm_unpacklo_epi64(m6, m7); \ + } while (0) + +#define LOAD_MSG_0_4(b0, b1) \ + do { \ + b0 = _mm_unpackhi_epi64(m4, m5); \ + b1 = _mm_unpackhi_epi64(m6, m7); \ + } while (0) + +#define LOAD_MSG_1_1(b0, b1) \ + do { \ + b0 = _mm_unpacklo_epi64(m7, m2); \ + b1 = _mm_unpackhi_epi64(m4, m6); \ + } while (0) + +#define LOAD_MSG_1_2(b0, b1) \ + do { \ + b0 = _mm_unpacklo_epi64(m5, m4); \ + b1 = _mm_alignr_epi8(m3, m7, 8); \ + } while (0) + +#define LOAD_MSG_1_3(b0, b1) \ + do { \ + b0 = _mm_shuffle_epi32(m0, _MM_SHUFFLE(1, 0, 3, 2)); \ + b1 = _mm_unpackhi_epi64(m5, m2); \ + } while (0) + +#define LOAD_MSG_1_4(b0, b1) \ + do { \ + b0 = _mm_unpacklo_epi64(m6, m1); \ + b1 = _mm_unpackhi_epi64(m3, m1); \ + } while (0) + +#define LOAD_MSG_2_1(b0, b1) \ + do { \ + b0 = _mm_alignr_epi8(m6, m5, 8); \ + b1 = _mm_unpackhi_epi64(m2, m7); \ + } while (0) + +#define LOAD_MSG_2_2(b0, b1) \ + do { \ + b0 = _mm_unpacklo_epi64(m4, m0); \ + b1 = _mm_blend_epi16(m1, m6, 0xF0); \ + } while (0) + +#define LOAD_MSG_2_3(b0, b1) \ + do { \ + b0 = _mm_blend_epi16(m5, m1, 0xF0); \ + b1 = _mm_unpackhi_epi64(m3, m4); \ + } while (0) + +#define LOAD_MSG_2_4(b0, b1) \ + do { \ + b0 = _mm_unpacklo_epi64(m7, m3); \ + b1 = _mm_alignr_epi8(m2, m0, 8); \ + } while (0) + +#define LOAD_MSG_3_1(b0, b1) \ + do { \ + b0 = _mm_unpackhi_epi64(m3, m1); \ + b1 = _mm_unpackhi_epi64(m6, m5); \ + } while (0) + +#define LOAD_MSG_3_2(b0, b1) \ + do { \ + b0 = _mm_unpackhi_epi64(m4, m0); \ + b1 = _mm_unpacklo_epi64(m6, m7); \ + } while (0) + +#define LOAD_MSG_3_3(b0, b1) \ + do { \ + b0 = _mm_blend_epi16(m1, m2, 0xF0); \ + b1 = _mm_blend_epi16(m2, m7, 0xF0); \ + } while (0) + +#define LOAD_MSG_3_4(b0, b1) \ + do { \ + b0 = _mm_unpacklo_epi64(m3, m5); \ + b1 = _mm_unpacklo_epi64(m0, m4); \ + } while (0) + +#define LOAD_MSG_4_1(b0, b1) \ + do { \ + b0 = _mm_unpackhi_epi64(m4, m2); \ + b1 = _mm_unpacklo_epi64(m1, m5); \ + } while (0) + +#define LOAD_MSG_4_2(b0, b1) \ + do { \ + b0 = _mm_blend_epi16(m0, m3, 0xF0); \ + b1 = _mm_blend_epi16(m2, m7, 0xF0); \ + } while (0) + +#define LOAD_MSG_4_3(b0, b1) \ + do { \ + b0 = _mm_blend_epi16(m7, m5, 0xF0); \ + b1 = _mm_blend_epi16(m3, m1, 0xF0); \ + } while (0) + +#define LOAD_MSG_4_4(b0, b1) \ + do { \ + b0 = _mm_alignr_epi8(m6, m0, 8); \ + b1 = _mm_blend_epi16(m4, m6, 0xF0); \ + } while (0) + +#define LOAD_MSG_5_1(b0, b1) \ + do { \ + b0 = _mm_unpacklo_epi64(m1, m3); \ + b1 = _mm_unpacklo_epi64(m0, m4); \ + } while (0) + +#define LOAD_MSG_5_2(b0, b1) \ + do { \ + b0 = _mm_unpacklo_epi64(m6, m5); \ + b1 = _mm_unpackhi_epi64(m5, m1); \ + } while (0) + +#define LOAD_MSG_5_3(b0, b1) \ + do { \ + b0 = _mm_blend_epi16(m2, m3, 0xF0); \ + b1 = _mm_unpackhi_epi64(m7, m0); \ + } while (0) + +#define LOAD_MSG_5_4(b0, b1) \ + do { \ + b0 = _mm_unpackhi_epi64(m6, m2); \ + b1 = _mm_blend_epi16(m7, m4, 0xF0); \ + } while (0) + +#define LOAD_MSG_6_1(b0, b1) \ + do { \ + b0 = _mm_blend_epi16(m6, m0, 0xF0); \ + b1 = _mm_unpacklo_epi64(m7, m2); \ + } while (0) + +#define LOAD_MSG_6_2(b0, b1) \ + do { \ + b0 = _mm_unpackhi_epi64(m2, m7); \ + b1 = _mm_alignr_epi8(m5, m6, 8); \ + } while (0) + +#define LOAD_MSG_6_3(b0, b1) \ + do { \ + b0 = _mm_unpacklo_epi64(m0, m3); \ + b1 = _mm_shuffle_epi32(m4, _MM_SHUFFLE(1, 0, 3, 2)); \ + } while (0) + +#define LOAD_MSG_6_4(b0, b1) \ + do { \ + b0 = _mm_unpackhi_epi64(m3, m1); \ + b1 = _mm_blend_epi16(m1, m5, 0xF0); \ + } while (0) + +#define LOAD_MSG_7_1(b0, b1) \ + do { \ + b0 = _mm_unpackhi_epi64(m6, m3); \ + b1 = _mm_blend_epi16(m6, m1, 0xF0); \ + } while (0) + +#define LOAD_MSG_7_2(b0, b1) \ + do { \ + b0 = _mm_alignr_epi8(m7, m5, 8); \ + b1 = _mm_unpackhi_epi64(m0, m4); \ + } while (0) + +#define LOAD_MSG_7_3(b0, b1) \ + do { \ + b0 = _mm_unpackhi_epi64(m2, m7); \ + b1 = _mm_unpacklo_epi64(m4, m1); \ + } while (0) + +#define LOAD_MSG_7_4(b0, b1) \ + do { \ + b0 = _mm_unpacklo_epi64(m0, m2); \ + b1 = _mm_unpacklo_epi64(m3, m5); \ + } while (0) + +#define LOAD_MSG_8_1(b0, b1) \ + do { \ + b0 = _mm_unpacklo_epi64(m3, m7); \ + b1 = _mm_alignr_epi8(m0, m5, 8); \ + } while (0) + +#define LOAD_MSG_8_2(b0, b1) \ + do { \ + b0 = _mm_unpackhi_epi64(m7, m4); \ + b1 = _mm_alignr_epi8(m4, m1, 8); \ + } while (0) + +#define LOAD_MSG_8_3(b0, b1) \ + do { \ + b0 = m6; \ + b1 = _mm_alignr_epi8(m5, m0, 8); \ + } while (0) + +#define LOAD_MSG_8_4(b0, b1) \ + do { \ + b0 = _mm_blend_epi16(m1, m3, 0xF0); \ + b1 = m2; \ + } while (0) + +#define LOAD_MSG_9_1(b0, b1) \ + do { \ + b0 = _mm_unpacklo_epi64(m5, m4); \ + b1 = _mm_unpackhi_epi64(m3, m0); \ + } while (0) + +#define LOAD_MSG_9_2(b0, b1) \ + do { \ + b0 = _mm_unpacklo_epi64(m1, m2); \ + b1 = _mm_blend_epi16(m3, m2, 0xF0); \ + } while (0) + +#define LOAD_MSG_9_3(b0, b1) \ + do { \ + b0 = _mm_unpackhi_epi64(m7, m4); \ + b1 = _mm_unpackhi_epi64(m1, m6); \ + } while (0) + +#define LOAD_MSG_9_4(b0, b1) \ + do { \ + b0 = _mm_alignr_epi8(m7, m5, 8); \ + b1 = _mm_unpacklo_epi64(m6, m0); \ + } while (0) + +#define LOAD_MSG_10_1(b0, b1) \ + do { \ + b0 = _mm_unpacklo_epi64(m0, m1); \ + b1 = _mm_unpacklo_epi64(m2, m3); \ + } while (0) + +#define LOAD_MSG_10_2(b0, b1) \ + do { \ + b0 = _mm_unpackhi_epi64(m0, m1); \ + b1 = _mm_unpackhi_epi64(m2, m3); \ + } while (0) + +#define LOAD_MSG_10_3(b0, b1) \ + do { \ + b0 = _mm_unpacklo_epi64(m4, m5); \ + b1 = _mm_unpacklo_epi64(m6, m7); \ + } while (0) + +#define LOAD_MSG_10_4(b0, b1) \ + do { \ + b0 = _mm_unpackhi_epi64(m4, m5); \ + b1 = _mm_unpackhi_epi64(m6, m7); \ + } while (0) + +#define LOAD_MSG_11_1(b0, b1) \ + do { \ + b0 = _mm_unpacklo_epi64(m7, m2); \ + b1 = _mm_unpackhi_epi64(m4, m6); \ + } while (0) + +#define LOAD_MSG_11_2(b0, b1) \ + do { \ + b0 = _mm_unpacklo_epi64(m5, m4); \ + b1 = _mm_alignr_epi8(m3, m7, 8); \ + } while (0) + +#define LOAD_MSG_11_3(b0, b1) \ + do { \ + b0 = _mm_shuffle_epi32(m0, _MM_SHUFFLE(1, 0, 3, 2)); \ + b1 = _mm_unpackhi_epi64(m5, m2); \ + } while (0) + +#define LOAD_MSG_11_4(b0, b1) \ + do { \ + b0 = _mm_unpacklo_epi64(m6, m1); \ + b1 = _mm_unpackhi_epi64(m3, m1); \ + } while (0) + +#endif diff --git a/libs/libsodium/src/crypto_generichash/blake2b/ref/blake2b-ref.c b/libs/libsodium/src/crypto_generichash/blake2b/ref/blake2b-ref.c new file mode 100644 index 0000000000..91435a1b16 --- /dev/null +++ b/libs/libsodium/src/crypto_generichash/blake2b/ref/blake2b-ref.c @@ -0,0 +1,436 @@ +/* + BLAKE2 reference source code package - C implementations + + Written in 2012 by Samuel Neves <sneves@dei.uc.pt> + + To the extent possible under law, the author(s) have dedicated all copyright + and related and neighboring rights to this software to the public domain + worldwide. This software is distributed without any warranty. + + You should have received a copy of the CC0 Public Domain Dedication along + with + this software. If not, see + <http://creativecommons.org/publicdomain/zero/1.0/>. +*/ + +#include <assert.h> +#include <stddef.h> +#include <stdint.h> +#include <stdlib.h> +#include <string.h> + +#include "blake2.h" +#include "core.h" +#include "private/common.h" +#include "runtime.h" +#include "utils.h" + +static blake2b_compress_fn blake2b_compress = blake2b_compress_ref; + +static const uint64_t blake2b_IV[8] = { + 0x6a09e667f3bcc908ULL, 0xbb67ae8584caa73bULL, 0x3c6ef372fe94f82bULL, + 0xa54ff53a5f1d36f1ULL, 0x510e527fade682d1ULL, 0x9b05688c2b3e6c1fULL, + 0x1f83d9abfb41bd6bULL, 0x5be0cd19137e2179ULL +}; + +/* LCOV_EXCL_START */ +static inline int +blake2b_set_lastnode(blake2b_state *S) +{ + S->f[1] = -1; + return 0; +} +/* LCOV_EXCL_STOP */ + +static inline int +blake2b_is_lastblock(const blake2b_state *S) +{ + return S->f[0] != 0; +} + +static inline int +blake2b_set_lastblock(blake2b_state *S) +{ + if (S->last_node) + blake2b_set_lastnode(S); + + S->f[0] = -1; + return 0; +} + +static inline int +blake2b_increment_counter(blake2b_state *S, const uint64_t inc) +{ +#ifdef HAVE_TI_MODE + uint128_t t = ((uint128_t) S->t[1] << 64) | S->t[0]; + t += inc; + S->t[0] = (uint64_t)(t >> 0); + S->t[1] = (uint64_t)(t >> 64); +#else + S->t[0] += inc; + S->t[1] += (S->t[0] < inc); +#endif + return 0; +} + +/* Parameter-related functions */ +static inline int +blake2b_param_set_salt(blake2b_param *P, const uint8_t salt[BLAKE2B_SALTBYTES]) +{ + memcpy(P->salt, salt, BLAKE2B_SALTBYTES); + return 0; +} + +static inline int +blake2b_param_set_personal(blake2b_param *P, + const uint8_t personal[BLAKE2B_PERSONALBYTES]) +{ + memcpy(P->personal, personal, BLAKE2B_PERSONALBYTES); + return 0; +} + +static inline int +blake2b_init0(blake2b_state *S) +{ + int i; + + for (i = 0; i < 8; i++) { + S->h[i] = blake2b_IV[i]; + } + memset(S->t, 0, offsetof(blake2b_state, last_node) + sizeof(S->last_node) + - offsetof(blake2b_state, t)); + return 0; +} + +/* init xors IV with input parameter block */ +int +blake2b_init_param(blake2b_state *S, const blake2b_param *P) +{ + size_t i; + const uint8_t *p; + + COMPILER_ASSERT(sizeof *P == 64); + blake2b_init0(S); + p = (const uint8_t *) (P); + + /* IV XOR ParamBlock */ + for (i = 0; i < 8; i++) { + S->h[i] ^= LOAD64_LE(p + sizeof(S->h[i]) * i); + } + return 0; +} + +int +blake2b_init(blake2b_state *S, const uint8_t outlen) +{ + blake2b_param P[1]; + + if ((!outlen) || (outlen > BLAKE2B_OUTBYTES)) { + sodium_misuse(); + } + P->digest_length = outlen; + P->key_length = 0; + P->fanout = 1; + P->depth = 1; + STORE32_LE(P->leaf_length, 0); + STORE64_LE(P->node_offset, 0); + P->node_depth = 0; + P->inner_length = 0; + memset(P->reserved, 0, sizeof(P->reserved)); + memset(P->salt, 0, sizeof(P->salt)); + memset(P->personal, 0, sizeof(P->personal)); + return blake2b_init_param(S, P); +} + +int +blake2b_init_salt_personal(blake2b_state *S, const uint8_t outlen, + const void *salt, const void *personal) +{ + blake2b_param P[1]; + + if ((!outlen) || (outlen > BLAKE2B_OUTBYTES)) { + sodium_misuse(); + } + P->digest_length = outlen; + P->key_length = 0; + P->fanout = 1; + P->depth = 1; + STORE32_LE(P->leaf_length, 0); + STORE64_LE(P->node_offset, 0); + P->node_depth = 0; + P->inner_length = 0; + memset(P->reserved, 0, sizeof(P->reserved)); + if (salt != NULL) { + blake2b_param_set_salt(P, (const uint8_t *) salt); + } else { + memset(P->salt, 0, sizeof(P->salt)); + } + if (personal != NULL) { + blake2b_param_set_personal(P, (const uint8_t *) personal); + } else { + memset(P->personal, 0, sizeof(P->personal)); + } + return blake2b_init_param(S, P); +} + +int +blake2b_init_key(blake2b_state *S, const uint8_t outlen, const void *key, + const uint8_t keylen) +{ + blake2b_param P[1]; + + if ((!outlen) || (outlen > BLAKE2B_OUTBYTES)) { + sodium_misuse(); + } + if (!key || !keylen || keylen > BLAKE2B_KEYBYTES) { + sodium_misuse(); + } + P->digest_length = outlen; + P->key_length = keylen; + P->fanout = 1; + P->depth = 1; + STORE32_LE(P->leaf_length, 0); + STORE64_LE(P->node_offset, 0); + P->node_depth = 0; + P->inner_length = 0; + memset(P->reserved, 0, sizeof(P->reserved)); + memset(P->salt, 0, sizeof(P->salt)); + memset(P->personal, 0, sizeof(P->personal)); + + if (blake2b_init_param(S, P) < 0) { + sodium_misuse(); + } + { + uint8_t block[BLAKE2B_BLOCKBYTES]; + memset(block, 0, BLAKE2B_BLOCKBYTES); + memcpy(block, key, keylen); /* keylen cannot be 0 */ + blake2b_update(S, block, BLAKE2B_BLOCKBYTES); + sodium_memzero(block, BLAKE2B_BLOCKBYTES); /* Burn the key from stack */ + } + return 0; +} + +int +blake2b_init_key_salt_personal(blake2b_state *S, const uint8_t outlen, + const void *key, const uint8_t keylen, + const void *salt, const void *personal) +{ + blake2b_param P[1]; + + if ((!outlen) || (outlen > BLAKE2B_OUTBYTES)) { + sodium_misuse(); + } + if (!key || !keylen || keylen > BLAKE2B_KEYBYTES) { + sodium_misuse(); + } + P->digest_length = outlen; + P->key_length = keylen; + P->fanout = 1; + P->depth = 1; + STORE32_LE(P->leaf_length, 0); + STORE64_LE(P->node_offset, 0); + P->node_depth = 0; + P->inner_length = 0; + memset(P->reserved, 0, sizeof(P->reserved)); + if (salt != NULL) { + blake2b_param_set_salt(P, (const uint8_t *) salt); + } else { + memset(P->salt, 0, sizeof(P->salt)); + } + if (personal != NULL) { + blake2b_param_set_personal(P, (const uint8_t *) personal); + } else { + memset(P->personal, 0, sizeof(P->personal)); + } + + if (blake2b_init_param(S, P) < 0) { + sodium_misuse(); + } + { + uint8_t block[BLAKE2B_BLOCKBYTES]; + memset(block, 0, BLAKE2B_BLOCKBYTES); + memcpy(block, key, keylen); /* keylen cannot be 0 */ + blake2b_update(S, block, BLAKE2B_BLOCKBYTES); + sodium_memzero(block, BLAKE2B_BLOCKBYTES); /* Burn the key from stack */ + } + return 0; +} + +/* inlen now in bytes */ +int +blake2b_update(blake2b_state *S, const uint8_t *in, uint64_t inlen) +{ + while (inlen > 0) { + size_t left = S->buflen; + size_t fill = 2 * BLAKE2B_BLOCKBYTES - left; + + if (inlen > fill) { + memcpy(S->buf + left, in, fill); /* Fill buffer */ + S->buflen += fill; + blake2b_increment_counter(S, BLAKE2B_BLOCKBYTES); + blake2b_compress(S, S->buf); /* Compress */ + memcpy(S->buf, S->buf + BLAKE2B_BLOCKBYTES, + BLAKE2B_BLOCKBYTES); /* Shift buffer left */ + S->buflen -= BLAKE2B_BLOCKBYTES; + in += fill; + inlen -= fill; + } else /* inlen <= fill */ + { + memcpy(S->buf + left, in, inlen); + S->buflen += inlen; /* Be lazy, do not compress */ + in += inlen; + inlen -= inlen; + } + } + + return 0; +} + +int +blake2b_final(blake2b_state *S, uint8_t *out, uint8_t outlen) +{ + unsigned char buffer[BLAKE2B_OUTBYTES]; + + if (!outlen || outlen > BLAKE2B_OUTBYTES) { + sodium_misuse(); + } + if (blake2b_is_lastblock(S)) { + return -1; + } + if (S->buflen > BLAKE2B_BLOCKBYTES) { + blake2b_increment_counter(S, BLAKE2B_BLOCKBYTES); + blake2b_compress(S, S->buf); + S->buflen -= BLAKE2B_BLOCKBYTES; + assert(S->buflen <= BLAKE2B_BLOCKBYTES); + memcpy(S->buf, S->buf + BLAKE2B_BLOCKBYTES, S->buflen); + } + + blake2b_increment_counter(S, S->buflen); + blake2b_set_lastblock(S); + memset(S->buf + S->buflen, 0, + 2 * BLAKE2B_BLOCKBYTES - S->buflen); /* Padding */ + blake2b_compress(S, S->buf); + + COMPILER_ASSERT(sizeof buffer == 64U); + STORE64_LE(buffer + 8 * 0, S->h[0]); + STORE64_LE(buffer + 8 * 1, S->h[1]); + STORE64_LE(buffer + 8 * 2, S->h[2]); + STORE64_LE(buffer + 8 * 3, S->h[3]); + STORE64_LE(buffer + 8 * 4, S->h[4]); + STORE64_LE(buffer + 8 * 5, S->h[5]); + STORE64_LE(buffer + 8 * 6, S->h[6]); + STORE64_LE(buffer + 8 * 7, S->h[7]); + memcpy(out, buffer, outlen); /* outlen <= BLAKE2B_OUTBYTES (64) */ + + sodium_memzero(S->h, sizeof S->h); + sodium_memzero(S->buf, sizeof S->buf); + + return 0; +} + +/* inlen, at least, should be uint64_t. Others can be size_t. */ +int +blake2b(uint8_t *out, const void *in, const void *key, const uint8_t outlen, + const uint64_t inlen, uint8_t keylen) +{ + blake2b_state S[1]; + + /* Verify parameters */ + if (NULL == in && inlen > 0) { + sodium_misuse(); + } + if (NULL == out) { + sodium_misuse(); + } + if (!outlen || outlen > BLAKE2B_OUTBYTES) { + sodium_misuse(); + } + if (NULL == key && keylen > 0) { + sodium_misuse(); + } + if (keylen > BLAKE2B_KEYBYTES) { + sodium_misuse(); + } + if (keylen > 0) { + if (blake2b_init_key(S, outlen, key, keylen) < 0) { + sodium_misuse(); + } + } else { + if (blake2b_init(S, outlen) < 0) { + sodium_misuse(); + } + } + + blake2b_update(S, (const uint8_t *) in, inlen); + blake2b_final(S, out, outlen); + return 0; +} + +int +blake2b_salt_personal(uint8_t *out, const void *in, const void *key, + const uint8_t outlen, const uint64_t inlen, + uint8_t keylen, const void *salt, const void *personal) +{ + blake2b_state S[1]; + + /* Verify parameters */ + if (NULL == in && inlen > 0) { + sodium_misuse(); + } + if (NULL == out) { + sodium_misuse(); + } + if (!outlen || outlen > BLAKE2B_OUTBYTES) { + sodium_misuse(); + } + if (NULL == key && keylen > 0) { + sodium_misuse(); + } + if (keylen > BLAKE2B_KEYBYTES) { + sodium_misuse(); + } + if (keylen > 0) { + if (blake2b_init_key_salt_personal(S, outlen, key, keylen, salt, + personal) < 0) { + sodium_misuse(); + } + } else { + if (blake2b_init_salt_personal(S, outlen, salt, personal) < 0) { + sodium_misuse(); + } + } + + blake2b_update(S, (const uint8_t *) in, inlen); + blake2b_final(S, out, outlen); + return 0; +} + +int +blake2b_pick_best_implementation(void) +{ +/* LCOV_EXCL_START */ +#if defined(HAVE_AVX2INTRIN_H) && defined(HAVE_TMMINTRIN_H) && \ + defined(HAVE_SMMINTRIN_H) + if (sodium_runtime_has_avx2()) { + blake2b_compress = blake2b_compress_avx2; + return 0; + } +#endif +#if defined(HAVE_EMMINTRIN_H) && defined(HAVE_TMMINTRIN_H) && \ + defined(HAVE_SMMINTRIN_H) + if (sodium_runtime_has_sse41()) { + blake2b_compress = blake2b_compress_sse41; + return 0; + } +#endif +#if defined(HAVE_EMMINTRIN_H) && defined(HAVE_TMMINTRIN_H) + if (sodium_runtime_has_ssse3()) { + blake2b_compress = blake2b_compress_ssse3; + return 0; + } +#endif + blake2b_compress = blake2b_compress_ref; + + return 0; + /* LCOV_EXCL_STOP */ +} diff --git a/libs/libsodium/src/crypto_generichash/blake2b/ref/generichash_blake2b.c b/libs/libsodium/src/crypto_generichash/blake2b/ref/generichash_blake2b.c new file mode 100644 index 0000000000..4bd0855006 --- /dev/null +++ b/libs/libsodium/src/crypto_generichash/blake2b/ref/generichash_blake2b.c @@ -0,0 +1,111 @@ + +#include <assert.h> +#include <limits.h> +#include <stdint.h> + +#include "blake2.h" +#include "crypto_generichash_blake2b.h" +#include "private/implementations.h" + +int +crypto_generichash_blake2b(unsigned char *out, size_t outlen, + const unsigned char *in, unsigned long long inlen, + const unsigned char *key, size_t keylen) +{ + if (outlen <= 0U || outlen > BLAKE2B_OUTBYTES || + keylen > BLAKE2B_KEYBYTES || inlen > UINT64_MAX) { + return -1; + } + assert(outlen <= UINT8_MAX); + assert(keylen <= UINT8_MAX); + + return blake2b((uint8_t *) out, in, key, (uint8_t) outlen, (uint64_t) inlen, + (uint8_t) keylen); +} + +int +crypto_generichash_blake2b_salt_personal( + unsigned char *out, size_t outlen, const unsigned char *in, + unsigned long long inlen, const unsigned char *key, size_t keylen, + const unsigned char *salt, const unsigned char *personal) +{ + if (outlen <= 0U || outlen > BLAKE2B_OUTBYTES || + keylen > BLAKE2B_KEYBYTES || inlen > UINT64_MAX) { + return -1; + } + assert(outlen <= UINT8_MAX); + assert(keylen <= UINT8_MAX); + + return blake2b_salt_personal((uint8_t *) out, in, key, (uint8_t) outlen, + (uint64_t) inlen, (uint8_t) keylen, salt, + personal); +} + +int +crypto_generichash_blake2b_init(crypto_generichash_blake2b_state *state, + const unsigned char *key, const size_t keylen, + const size_t outlen) +{ + if (outlen <= 0U || outlen > BLAKE2B_OUTBYTES || + keylen > BLAKE2B_KEYBYTES) { + return -1; + } + assert(outlen <= UINT8_MAX); + assert(keylen <= UINT8_MAX); + if (key == NULL || keylen <= 0U) { + if (blake2b_init(state, (uint8_t) outlen) != 0) { + return -1; /* LCOV_EXCL_LINE */ + } + } else if (blake2b_init_key(state, (uint8_t) outlen, key, + (uint8_t) keylen) != 0) { + return -1; /* LCOV_EXCL_LINE */ + } + return 0; +} + +int +crypto_generichash_blake2b_init_salt_personal( + crypto_generichash_blake2b_state *state, const unsigned char *key, + const size_t keylen, const size_t outlen, const unsigned char *salt, + const unsigned char *personal) +{ + if (outlen <= 0U || outlen > BLAKE2B_OUTBYTES || + keylen > BLAKE2B_KEYBYTES) { + return -1; + } + assert(outlen <= UINT8_MAX); + assert(keylen <= UINT8_MAX); + if (key == NULL || keylen <= 0U) { + if (blake2b_init_salt_personal(state, (uint8_t) outlen, salt, + personal) != 0) { + return -1; /* LCOV_EXCL_LINE */ + } + } else if (blake2b_init_key_salt_personal(state, (uint8_t) outlen, key, + (uint8_t) keylen, salt, + personal) != 0) { + return -1; /* LCOV_EXCL_LINE */ + } + return 0; +} + +int +crypto_generichash_blake2b_update(crypto_generichash_blake2b_state *state, + const unsigned char *in, + unsigned long long inlen) +{ + return blake2b_update(state, (const uint8_t *) in, (uint64_t) inlen); +} + +int +crypto_generichash_blake2b_final(crypto_generichash_blake2b_state *state, + unsigned char *out, const size_t outlen) +{ + assert(outlen <= UINT8_MAX); + return blake2b_final(state, (uint8_t *) out, (uint8_t) outlen); +} + +int +_crypto_generichash_blake2b_pick_best_implementation(void) +{ + return blake2b_pick_best_implementation(); +} diff --git a/libs/libsodium/src/crypto_generichash/crypto_generichash.c b/libs/libsodium/src/crypto_generichash/crypto_generichash.c new file mode 100644 index 0000000000..a9a14e999a --- /dev/null +++ b/libs/libsodium/src/crypto_generichash/crypto_generichash.c @@ -0,0 +1,91 @@ + +#include "crypto_generichash.h" +#include "randombytes.h" + +size_t +crypto_generichash_bytes_min(void) +{ + return crypto_generichash_BYTES_MIN; +} + +size_t +crypto_generichash_bytes_max(void) +{ + return crypto_generichash_BYTES_MAX; +} + +size_t +crypto_generichash_bytes(void) +{ + return crypto_generichash_BYTES; +} + +size_t +crypto_generichash_keybytes_min(void) +{ + return crypto_generichash_KEYBYTES_MIN; +} + +size_t +crypto_generichash_keybytes_max(void) +{ + return crypto_generichash_KEYBYTES_MAX; +} + +size_t +crypto_generichash_keybytes(void) +{ + return crypto_generichash_KEYBYTES; +} + +const char * +crypto_generichash_primitive(void) +{ + return crypto_generichash_PRIMITIVE; +} + +size_t +crypto_generichash_statebytes(void) +{ + return (sizeof(crypto_generichash_state) + (size_t) 63U) & ~(size_t) 63U; +} + +int +crypto_generichash(unsigned char *out, size_t outlen, const unsigned char *in, + unsigned long long inlen, const unsigned char *key, + size_t keylen) +{ + return crypto_generichash_blake2b(out, outlen, in, inlen, key, keylen); +} + +int +crypto_generichash_init(crypto_generichash_state *state, + const unsigned char *key, + const size_t keylen, const size_t outlen) +{ + return crypto_generichash_blake2b_init + ((crypto_generichash_blake2b_state *) state, key, keylen, outlen); +} + +int +crypto_generichash_update(crypto_generichash_state *state, + const unsigned char *in, + unsigned long long inlen) +{ + return crypto_generichash_blake2b_update + ((crypto_generichash_blake2b_state *) state, in, inlen); +} + +int +crypto_generichash_final(crypto_generichash_state *state, + unsigned char *out, const size_t outlen) +{ + return crypto_generichash_blake2b_final + ((crypto_generichash_blake2b_state *) state, out, outlen); +} + +void +crypto_generichash_keygen(unsigned char k[crypto_generichash_KEYBYTES]) +{ + randombytes_buf(k, crypto_generichash_KEYBYTES); +} diff --git a/libs/libsodium/src/crypto_hash/crypto_hash.c b/libs/libsodium/src/crypto_hash/crypto_hash.c new file mode 100644 index 0000000000..855c560ba5 --- /dev/null +++ b/libs/libsodium/src/crypto_hash/crypto_hash.c @@ -0,0 +1,20 @@ + +#include "crypto_hash.h" + +size_t +crypto_hash_bytes(void) +{ + return crypto_hash_BYTES; +} + +int +crypto_hash(unsigned char *out, const unsigned char *in, + unsigned long long inlen) +{ + return crypto_hash_sha512(out, in, inlen); +} + +const char * +crypto_hash_primitive(void) { + return crypto_hash_PRIMITIVE; +} diff --git a/libs/libsodium/src/crypto_hash/sha256/cp/hash_sha256_cp.c b/libs/libsodium/src/crypto_hash/sha256/cp/hash_sha256_cp.c new file mode 100644 index 0000000000..264054f98b --- /dev/null +++ b/libs/libsodium/src/crypto_hash/sha256/cp/hash_sha256_cp.c @@ -0,0 +1,254 @@ + +/*- + * Copyright 2005,2007,2009 Colin Percival + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + */ + +#include <limits.h> +#include <stdint.h> +#include <stdlib.h> +#include <string.h> + +#include <sys/types.h> + +#include "crypto_hash_sha256.h" +#include "private/common.h" +#include "utils.h" + +static void +be32enc_vect(unsigned char *dst, const uint32_t *src, size_t len) +{ + size_t i; + + for (i = 0; i < len / 4; i++) { + STORE32_BE(dst + i * 4, src[i]); + } +} + +static void +be32dec_vect(uint32_t *dst, const unsigned char *src, size_t len) +{ + size_t i; + + for (i = 0; i < len / 4; i++) { + dst[i] = LOAD32_BE(src + i * 4); + } +} + +static const uint32_t Krnd[64] = { + 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, + 0x923f82a4, 0xab1c5ed5, 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, + 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174, 0xe49b69c1, 0xefbe4786, + 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da, + 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147, + 0x06ca6351, 0x14292967, 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, + 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85, 0xa2bfe8a1, 0xa81a664b, + 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070, + 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, + 0x5b9cca4f, 0x682e6ff3, 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, + 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2 +}; + +#define Ch(x, y, z) ((x & (y ^ z)) ^ z) +#define Maj(x, y, z) ((x & (y | z)) | (y & z)) +#define SHR(x, n) (x >> n) +#define ROTR(x, n) ROTR32(x, n) +#define S0(x) (ROTR(x, 2) ^ ROTR(x, 13) ^ ROTR(x, 22)) +#define S1(x) (ROTR(x, 6) ^ ROTR(x, 11) ^ ROTR(x, 25)) +#define s0(x) (ROTR(x, 7) ^ ROTR(x, 18) ^ SHR(x, 3)) +#define s1(x) (ROTR(x, 17) ^ ROTR(x, 19) ^ SHR(x, 10)) + +#define RND(a, b, c, d, e, f, g, h, k) \ + h += S1(e) + Ch(e, f, g) + k; \ + d += h; \ + h += S0(a) + Maj(a, b, c); + +#define RNDr(S, W, i, ii) \ + RND(S[(64 - i) % 8], S[(65 - i) % 8], S[(66 - i) % 8], S[(67 - i) % 8], \ + S[(68 - i) % 8], S[(69 - i) % 8], S[(70 - i) % 8], S[(71 - i) % 8], \ + W[i + ii] + Krnd[i + ii]) + +#define MSCH(W, ii, i) \ + W[i + ii + 16] = \ + s1(W[i + ii + 14]) + W[i + ii + 9] + s0(W[i + ii + 1]) + W[i + ii] + +static void +SHA256_Transform(uint32_t state[8], const uint8_t block[64], uint32_t W[64], + uint32_t S[8]) +{ + int i; + + be32dec_vect(W, block, 64); + memcpy(S, state, 32); + for (i = 0; i < 64; i += 16) { + RNDr(S, W, 0, i); + RNDr(S, W, 1, i); + RNDr(S, W, 2, i); + RNDr(S, W, 3, i); + RNDr(S, W, 4, i); + RNDr(S, W, 5, i); + RNDr(S, W, 6, i); + RNDr(S, W, 7, i); + RNDr(S, W, 8, i); + RNDr(S, W, 9, i); + RNDr(S, W, 10, i); + RNDr(S, W, 11, i); + RNDr(S, W, 12, i); + RNDr(S, W, 13, i); + RNDr(S, W, 14, i); + RNDr(S, W, 15, i); + if (i == 48) { + break; + } + MSCH(W, 0, i); + MSCH(W, 1, i); + MSCH(W, 2, i); + MSCH(W, 3, i); + MSCH(W, 4, i); + MSCH(W, 5, i); + MSCH(W, 6, i); + MSCH(W, 7, i); + MSCH(W, 8, i); + MSCH(W, 9, i); + MSCH(W, 10, i); + MSCH(W, 11, i); + MSCH(W, 12, i); + MSCH(W, 13, i); + MSCH(W, 14, i); + MSCH(W, 15, i); + } + for (i = 0; i < 8; i++) { + state[i] += S[i]; + } +} + +static const uint8_t PAD[64] = { 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; + +static void +SHA256_Pad(crypto_hash_sha256_state *state, uint32_t tmp32[64 + 8]) +{ + unsigned int r; + unsigned int i; + + r = (unsigned int) ((state->count >> 3) & 0x3f); + if (r < 56) { + for (i = 0; i < 56 - r; i++) { + state->buf[r + i] = PAD[i]; + } + } else { + for (i = 0; i < 64 - r; i++) { + state->buf[r + i] = PAD[i]; + } + SHA256_Transform(state->state, state->buf, &tmp32[0], &tmp32[64]); + memset(&state->buf[0], 0, 56); + } + STORE64_BE(&state->buf[56], state->count); + SHA256_Transform(state->state, state->buf, &tmp32[0], &tmp32[64]); +} + +int +crypto_hash_sha256_init(crypto_hash_sha256_state *state) +{ + static const uint32_t sha256_initial_state[8] = { 0x6a09e667, 0xbb67ae85, + 0x3c6ef372, 0xa54ff53a, + 0x510e527f, 0x9b05688c, + 0x1f83d9ab, 0x5be0cd19 }; + + state->count = (uint64_t) 0U; + memcpy(state->state, sha256_initial_state, sizeof sha256_initial_state); + + return 0; +} + +int +crypto_hash_sha256_update(crypto_hash_sha256_state *state, + const unsigned char *in, unsigned long long inlen) +{ + uint32_t tmp32[64 + 8]; + unsigned long long i; + unsigned long long r; + + if (inlen <= 0U) { + return 0; + } + r = (unsigned long long) ((state->count >> 3) & 0x3f); + + state->count += ((uint64_t) inlen) << 3; + if (inlen < 64 - r) { + for (i = 0; i < inlen; i++) { + state->buf[r + i] = in[i]; + } + return 0; + } + for (i = 0; i < 64 - r; i++) { + state->buf[r + i] = in[i]; + } + SHA256_Transform(state->state, state->buf, &tmp32[0], &tmp32[64]); + in += 64 - r; + inlen -= 64 - r; + + while (inlen >= 64) { + SHA256_Transform(state->state, in, &tmp32[0], &tmp32[64]); + in += 64; + inlen -= 64; + } + inlen &= 63; + for (i = 0; i < inlen; i++) { + state->buf[i] = in[i]; + } + sodium_memzero((void *) tmp32, sizeof tmp32); + + return 0; +} + +int +crypto_hash_sha256_final(crypto_hash_sha256_state *state, unsigned char *out) +{ + uint32_t tmp32[64 + 8]; + + SHA256_Pad(state, tmp32); + be32enc_vect(out, state->state, 32); + sodium_memzero((void *) tmp32, sizeof tmp32); + sodium_memzero((void *) state, sizeof *state); + + return 0; +} + +int +crypto_hash_sha256(unsigned char *out, const unsigned char *in, + unsigned long long inlen) +{ + crypto_hash_sha256_state state; + + crypto_hash_sha256_init(&state); + crypto_hash_sha256_update(&state, in, inlen); + crypto_hash_sha256_final(&state, out); + + return 0; +} diff --git a/libs/libsodium/src/crypto_hash/sha256/hash_sha256.c b/libs/libsodium/src/crypto_hash/sha256/hash_sha256.c new file mode 100644 index 0000000000..e729c811e6 --- /dev/null +++ b/libs/libsodium/src/crypto_hash/sha256/hash_sha256.c @@ -0,0 +1,13 @@ +#include "crypto_hash_sha256.h" + +size_t +crypto_hash_sha256_bytes(void) +{ + return crypto_hash_sha256_BYTES; +} + +size_t +crypto_hash_sha256_statebytes(void) +{ + return sizeof(crypto_hash_sha256_state); +} diff --git a/libs/libsodium/src/crypto_hash/sha512/cp/hash_sha512_cp.c b/libs/libsodium/src/crypto_hash/sha512/cp/hash_sha512_cp.c new file mode 100644 index 0000000000..8e0f36fb6b --- /dev/null +++ b/libs/libsodium/src/crypto_hash/sha512/cp/hash_sha512_cp.c @@ -0,0 +1,282 @@ + +/*- + * Copyright 2005,2007,2009 Colin Percival + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + */ + +#include <limits.h> +#include <stdint.h> +#include <stdlib.h> +#include <string.h> + +#include <sys/types.h> + +#include "crypto_hash_sha512.h" +#include "private/common.h" +#include "utils.h" + +static void +be64enc_vect(unsigned char *dst, const uint64_t *src, size_t len) +{ + size_t i; + + for (i = 0; i < len / 8; i++) { + STORE64_BE(dst + i * 8, src[i]); + } +} + +static void +be64dec_vect(uint64_t *dst, const unsigned char *src, size_t len) +{ + size_t i; + + for (i = 0; i < len / 8; i++) { + dst[i] = LOAD64_BE(src + i * 8); + } +} + +static const uint64_t Krnd[80] = { + 0x428a2f98d728ae22ULL, 0x7137449123ef65cdULL, 0xb5c0fbcfec4d3b2fULL, + 0xe9b5dba58189dbbcULL, 0x3956c25bf348b538ULL, 0x59f111f1b605d019ULL, + 0x923f82a4af194f9bULL, 0xab1c5ed5da6d8118ULL, 0xd807aa98a3030242ULL, + 0x12835b0145706fbeULL, 0x243185be4ee4b28cULL, 0x550c7dc3d5ffb4e2ULL, + 0x72be5d74f27b896fULL, 0x80deb1fe3b1696b1ULL, 0x9bdc06a725c71235ULL, + 0xc19bf174cf692694ULL, 0xe49b69c19ef14ad2ULL, 0xefbe4786384f25e3ULL, + 0x0fc19dc68b8cd5b5ULL, 0x240ca1cc77ac9c65ULL, 0x2de92c6f592b0275ULL, + 0x4a7484aa6ea6e483ULL, 0x5cb0a9dcbd41fbd4ULL, 0x76f988da831153b5ULL, + 0x983e5152ee66dfabULL, 0xa831c66d2db43210ULL, 0xb00327c898fb213fULL, + 0xbf597fc7beef0ee4ULL, 0xc6e00bf33da88fc2ULL, 0xd5a79147930aa725ULL, + 0x06ca6351e003826fULL, 0x142929670a0e6e70ULL, 0x27b70a8546d22ffcULL, + 0x2e1b21385c26c926ULL, 0x4d2c6dfc5ac42aedULL, 0x53380d139d95b3dfULL, + 0x650a73548baf63deULL, 0x766a0abb3c77b2a8ULL, 0x81c2c92e47edaee6ULL, + 0x92722c851482353bULL, 0xa2bfe8a14cf10364ULL, 0xa81a664bbc423001ULL, + 0xc24b8b70d0f89791ULL, 0xc76c51a30654be30ULL, 0xd192e819d6ef5218ULL, + 0xd69906245565a910ULL, 0xf40e35855771202aULL, 0x106aa07032bbd1b8ULL, + 0x19a4c116b8d2d0c8ULL, 0x1e376c085141ab53ULL, 0x2748774cdf8eeb99ULL, + 0x34b0bcb5e19b48a8ULL, 0x391c0cb3c5c95a63ULL, 0x4ed8aa4ae3418acbULL, + 0x5b9cca4f7763e373ULL, 0x682e6ff3d6b2b8a3ULL, 0x748f82ee5defb2fcULL, + 0x78a5636f43172f60ULL, 0x84c87814a1f0ab72ULL, 0x8cc702081a6439ecULL, + 0x90befffa23631e28ULL, 0xa4506cebde82bde9ULL, 0xbef9a3f7b2c67915ULL, + 0xc67178f2e372532bULL, 0xca273eceea26619cULL, 0xd186b8c721c0c207ULL, + 0xeada7dd6cde0eb1eULL, 0xf57d4f7fee6ed178ULL, 0x06f067aa72176fbaULL, + 0x0a637dc5a2c898a6ULL, 0x113f9804bef90daeULL, 0x1b710b35131c471bULL, + 0x28db77f523047d84ULL, 0x32caab7b40c72493ULL, 0x3c9ebe0a15c9bebcULL, + 0x431d67c49c100d4cULL, 0x4cc5d4becb3e42b6ULL, 0x597f299cfc657e2aULL, + 0x5fcb6fab3ad6faecULL, 0x6c44198c4a475817ULL +}; + +#define Ch(x, y, z) ((x & (y ^ z)) ^ z) +#define Maj(x, y, z) ((x & (y | z)) | (y & z)) +#define SHR(x, n) (x >> n) +#define ROTR(x, n) ROTR64(x, n) +#define S0(x) (ROTR(x, 28) ^ ROTR(x, 34) ^ ROTR(x, 39)) +#define S1(x) (ROTR(x, 14) ^ ROTR(x, 18) ^ ROTR(x, 41)) +#define s0(x) (ROTR(x, 1) ^ ROTR(x, 8) ^ SHR(x, 7)) +#define s1(x) (ROTR(x, 19) ^ ROTR(x, 61) ^ SHR(x, 6)) + +#define RND(a, b, c, d, e, f, g, h, k) \ + h += S1(e) + Ch(e, f, g) + k; \ + d += h; \ + h += S0(a) + Maj(a, b, c); + +#define RNDr(S, W, i, ii) \ + RND(S[(80 - i) % 8], S[(81 - i) % 8], S[(82 - i) % 8], S[(83 - i) % 8], \ + S[(84 - i) % 8], S[(85 - i) % 8], S[(86 - i) % 8], S[(87 - i) % 8], \ + W[i + ii] + Krnd[i + ii]) + +#define MSCH(W, ii, i) \ + W[i + ii + 16] = \ + s1(W[i + ii + 14]) + W[i + ii + 9] + s0(W[i + ii + 1]) + W[i + ii] + +static void +SHA512_Transform(uint64_t *state, const uint8_t block[128], uint64_t W[80], + uint64_t S[8]) +{ + int i; + + be64dec_vect(W, block, 128); + memcpy(S, state, 64); + for (i = 0; i < 80; i += 16) { + RNDr(S, W, 0, i); + RNDr(S, W, 1, i); + RNDr(S, W, 2, i); + RNDr(S, W, 3, i); + RNDr(S, W, 4, i); + RNDr(S, W, 5, i); + RNDr(S, W, 6, i); + RNDr(S, W, 7, i); + RNDr(S, W, 8, i); + RNDr(S, W, 9, i); + RNDr(S, W, 10, i); + RNDr(S, W, 11, i); + RNDr(S, W, 12, i); + RNDr(S, W, 13, i); + RNDr(S, W, 14, i); + RNDr(S, W, 15, i); + if (i == 64) { + break; + } + MSCH(W, 0, i); + MSCH(W, 1, i); + MSCH(W, 2, i); + MSCH(W, 3, i); + MSCH(W, 4, i); + MSCH(W, 5, i); + MSCH(W, 6, i); + MSCH(W, 7, i); + MSCH(W, 8, i); + MSCH(W, 9, i); + MSCH(W, 10, i); + MSCH(W, 11, i); + MSCH(W, 12, i); + MSCH(W, 13, i); + MSCH(W, 14, i); + MSCH(W, 15, i); + } + for (i = 0; i < 8; i++) { + state[i] += S[i]; + } +} + +static const uint8_t PAD[128] = { + 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 +}; + +static void +SHA512_Pad(crypto_hash_sha512_state *state, uint64_t tmp64[80 + 8]) +{ + unsigned int r; + unsigned int i; + + r = (unsigned int) ((state->count[1] >> 3) & 0x7f); + if (r < 112) { + for (i = 0; i < 112 - r; i++) { + state->buf[r + i] = PAD[i]; + } + } else { + for (i = 0; i < 128 - r; i++) { + state->buf[r + i] = PAD[i]; + } + SHA512_Transform(state->state, state->buf, &tmp64[0], &tmp64[80]); + memset(&state->buf[0], 0, 112); + } + be64enc_vect(&state->buf[112], state->count, 16); + SHA512_Transform(state->state, state->buf, &tmp64[0], &tmp64[80]); +} + +int +crypto_hash_sha512_init(crypto_hash_sha512_state *state) +{ + static const uint64_t sha512_initial_state[8] = { + 0x6a09e667f3bcc908ULL, 0xbb67ae8584caa73bULL, 0x3c6ef372fe94f82bULL, + 0xa54ff53a5f1d36f1ULL, 0x510e527fade682d1ULL, 0x9b05688c2b3e6c1fULL, + 0x1f83d9abfb41bd6bULL, 0x5be0cd19137e2179ULL + }; + + state->count[0] = state->count[1] = (uint64_t) 0U; + memcpy(state->state, sha512_initial_state, sizeof sha512_initial_state); + + return 0; +} + +int +crypto_hash_sha512_update(crypto_hash_sha512_state *state, + const unsigned char *in, unsigned long long inlen) +{ + uint64_t tmp64[80 + 8]; + uint64_t bitlen[2]; + unsigned long long i; + unsigned long long r; + + if (inlen <= 0U) { + return 0; + } + r = (unsigned long long) ((state->count[1] >> 3) & 0x7f); + + bitlen[1] = ((uint64_t) inlen) << 3; + bitlen[0] = ((uint64_t) inlen) >> 61; + /* LCOV_EXCL_START */ + if ((state->count[1] += bitlen[1]) < bitlen[1]) { + state->count[0]++; + } + /* LCOV_EXCL_STOP */ + state->count[0] += bitlen[0]; + if (inlen < 128 - r) { + for (i = 0; i < inlen; i++) { + state->buf[r + i] = in[i]; + } + return 0; + } + for (i = 0; i < 128 - r; i++) { + state->buf[r + i] = in[i]; + } + SHA512_Transform(state->state, state->buf, &tmp64[0], &tmp64[80]); + in += 128 - r; + inlen -= 128 - r; + + while (inlen >= 128) { + SHA512_Transform(state->state, in, &tmp64[0], &tmp64[80]); + in += 128; + inlen -= 128; + } + inlen &= 127; + for (i = 0; i < inlen; i++) { + state->buf[i] = in[i]; + } + sodium_memzero((void *) tmp64, sizeof tmp64); + + return 0; +} + +int +crypto_hash_sha512_final(crypto_hash_sha512_state *state, unsigned char *out) +{ + uint64_t tmp64[80 + 8]; + + SHA512_Pad(state, tmp64); + be64enc_vect(out, state->state, 64); + sodium_memzero((void *) tmp64, sizeof tmp64); + sodium_memzero((void *) state, sizeof *state); + + return 0; +} + +int +crypto_hash_sha512(unsigned char *out, const unsigned char *in, + unsigned long long inlen) +{ + crypto_hash_sha512_state state; + + crypto_hash_sha512_init(&state); + crypto_hash_sha512_update(&state, in, inlen); + crypto_hash_sha512_final(&state, out); + + return 0; +} diff --git a/libs/libsodium/src/crypto_hash/sha512/hash_sha512.c b/libs/libsodium/src/crypto_hash/sha512/hash_sha512.c new file mode 100644 index 0000000000..ba842b8bd4 --- /dev/null +++ b/libs/libsodium/src/crypto_hash/sha512/hash_sha512.c @@ -0,0 +1,13 @@ +#include "crypto_hash_sha512.h" + +size_t +crypto_hash_sha512_bytes(void) +{ + return crypto_hash_sha512_BYTES; +} + +size_t +crypto_hash_sha512_statebytes(void) +{ + return sizeof(crypto_hash_sha512_state); +} diff --git a/libs/libsodium/src/crypto_kdf/blake2b/kdf_blake2b.c b/libs/libsodium/src/crypto_kdf/blake2b/kdf_blake2b.c new file mode 100644 index 0000000000..2a690c9ac8 --- /dev/null +++ b/libs/libsodium/src/crypto_kdf/blake2b/kdf_blake2b.c @@ -0,0 +1,52 @@ +#include <errno.h> + +#include "crypto_kdf_blake2b.h" +#include "crypto_generichash_blake2b.h" +#include "private/common.h" + +size_t +crypto_kdf_blake2b_bytes_min(void) +{ + return crypto_kdf_blake2b_BYTES_MIN; +} + +size_t +crypto_kdf_blake2b_bytes_max(void) +{ + return crypto_kdf_blake2b_BYTES_MAX; +} + +size_t +crypto_kdf_blake2b_contextbytes(void) +{ + return crypto_kdf_blake2b_CONTEXTBYTES; +} + +size_t +crypto_kdf_blake2b_keybytes(void) +{ + return crypto_kdf_blake2b_KEYBYTES; +} + +int crypto_kdf_blake2b_derive_from_key(unsigned char *subkey, size_t subkey_len, + uint64_t subkey_id, + const char ctx[crypto_kdf_blake2b_CONTEXTBYTES], + const unsigned char key[crypto_kdf_blake2b_KEYBYTES]) +{ + unsigned char ctx_padded[crypto_generichash_blake2b_PERSONALBYTES]; + unsigned char salt[crypto_generichash_blake2b_SALTBYTES]; + + memcpy(ctx_padded, ctx, crypto_kdf_blake2b_CONTEXTBYTES); + memset(ctx_padded + crypto_kdf_blake2b_CONTEXTBYTES, 0, sizeof ctx_padded - crypto_kdf_blake2b_CONTEXTBYTES); + STORE64_LE(salt, subkey_id); + memset(salt + 8, 0, (sizeof salt) - 8); + if (subkey_len < crypto_kdf_blake2b_BYTES_MIN || + subkey_len > crypto_kdf_blake2b_BYTES_MAX) { + errno = EINVAL; + return -1; + } + return crypto_generichash_blake2b_salt_personal(subkey, subkey_len, + NULL, 0, + key, crypto_kdf_blake2b_KEYBYTES, + salt, ctx_padded); +} diff --git a/libs/libsodium/src/crypto_kdf/crypto_kdf.c b/libs/libsodium/src/crypto_kdf/crypto_kdf.c new file mode 100644 index 0000000000..b215d99ae6 --- /dev/null +++ b/libs/libsodium/src/crypto_kdf/crypto_kdf.c @@ -0,0 +1,49 @@ + +#include "crypto_kdf.h" +#include "randombytes.h" + +const char * +crypto_kdf_primitive(void) +{ + return crypto_kdf_PRIMITIVE; +} + +size_t +crypto_kdf_bytes_min(void) +{ + return crypto_kdf_BYTES_MIN; +} + +size_t +crypto_kdf_bytes_max(void) +{ + return crypto_kdf_BYTES_MAX; +} + +size_t +crypto_kdf_contextbytes(void) +{ + return crypto_kdf_CONTEXTBYTES; +} + +size_t +crypto_kdf_keybytes(void) +{ + return crypto_kdf_KEYBYTES; +} + +int +crypto_kdf_derive_from_key(unsigned char *subkey, size_t subkey_len, + uint64_t subkey_id, + const char ctx[crypto_kdf_CONTEXTBYTES], + const unsigned char key[crypto_kdf_KEYBYTES]) +{ + return crypto_kdf_blake2b_derive_from_key(subkey, subkey_len, + subkey_id, ctx, key); +} + +void +crypto_kdf_keygen(unsigned char k[crypto_kdf_KEYBYTES]) +{ + randombytes_buf(k, crypto_kdf_KEYBYTES); +} diff --git a/libs/libsodium/src/crypto_kx/crypto_kx.c b/libs/libsodium/src/crypto_kx/crypto_kx.c new file mode 100644 index 0000000000..877ab7ff4a --- /dev/null +++ b/libs/libsodium/src/crypto_kx/crypto_kx.c @@ -0,0 +1,143 @@ + +#include <stddef.h> + +#include "core.h" +#include "crypto_generichash.h" +#include "crypto_kx.h" +#include "crypto_scalarmult.h" +#include "private/common.h" +#include "randombytes.h" +#include "utils.h" + +int +crypto_kx_seed_keypair(unsigned char pk[crypto_kx_PUBLICKEYBYTES], + unsigned char sk[crypto_kx_SECRETKEYBYTES], + const unsigned char seed[crypto_kx_SEEDBYTES]) +{ + crypto_generichash(sk, crypto_kx_SECRETKEYBYTES, + seed, crypto_kx_SEEDBYTES, NULL, 0); + return crypto_scalarmult_base(pk, sk); +} + +int +crypto_kx_keypair(unsigned char pk[crypto_kx_PUBLICKEYBYTES], + unsigned char sk[crypto_kx_SECRETKEYBYTES]) +{ + COMPILER_ASSERT(crypto_kx_SECRETKEYBYTES == crypto_scalarmult_SCALARBYTES); + COMPILER_ASSERT(crypto_kx_PUBLICKEYBYTES == crypto_scalarmult_BYTES); + + randombytes_buf(sk, crypto_kx_SECRETKEYBYTES); + return crypto_scalarmult_base(pk, sk); +} + +int +crypto_kx_client_session_keys(unsigned char rx[crypto_kx_SESSIONKEYBYTES], + unsigned char tx[crypto_kx_SESSIONKEYBYTES], + const unsigned char client_pk[crypto_kx_PUBLICKEYBYTES], + const unsigned char client_sk[crypto_kx_SECRETKEYBYTES], + const unsigned char server_pk[crypto_kx_PUBLICKEYBYTES]) +{ + crypto_generichash_state h; + unsigned char q[crypto_scalarmult_BYTES]; + unsigned char keys[2 * crypto_kx_SESSIONKEYBYTES]; + int i; + + if (rx == NULL) { + rx = tx; + } + if (tx == NULL) { + tx = rx; + } + if (rx == NULL) { + sodium_misuse(); /* LCOV_EXCL_LINE */ + } + if (crypto_scalarmult(q, client_sk, server_pk) != 0) { + return -1; + } + COMPILER_ASSERT(sizeof keys <= crypto_generichash_BYTES_MAX); + crypto_generichash_init(&h, NULL, 0U, sizeof keys); + crypto_generichash_update(&h, q, crypto_scalarmult_BYTES); + sodium_memzero(q, sizeof q); + crypto_generichash_update(&h, client_pk, crypto_kx_PUBLICKEYBYTES); + crypto_generichash_update(&h, server_pk, crypto_kx_PUBLICKEYBYTES); + crypto_generichash_final(&h, keys, sizeof keys); + sodium_memzero(&h, sizeof h); + for (i = 0; i < crypto_kx_SESSIONKEYBYTES; i++) { + rx[i] = keys[i]; + tx[i] = keys[i + crypto_kx_SESSIONKEYBYTES]; + } + sodium_memzero(keys, sizeof keys); + + return 0; +} + +int +crypto_kx_server_session_keys(unsigned char rx[crypto_kx_SESSIONKEYBYTES], + unsigned char tx[crypto_kx_SESSIONKEYBYTES], + const unsigned char server_pk[crypto_kx_PUBLICKEYBYTES], + const unsigned char server_sk[crypto_kx_SECRETKEYBYTES], + const unsigned char client_pk[crypto_kx_PUBLICKEYBYTES]) +{ + crypto_generichash_state h; + unsigned char q[crypto_scalarmult_BYTES]; + unsigned char keys[2 * crypto_kx_SESSIONKEYBYTES]; + int i; + + if (rx == NULL) { + rx = tx; + } + if (tx == NULL) { + tx = rx; + } + if (rx == NULL) { + sodium_misuse(); /* LCOV_EXCL_LINE */ + } + if (crypto_scalarmult(q, server_sk, client_pk) != 0) { + return -1; + } + COMPILER_ASSERT(sizeof keys <= crypto_generichash_BYTES_MAX); + crypto_generichash_init(&h, NULL, 0U, sizeof keys); + crypto_generichash_update(&h, q, crypto_scalarmult_BYTES); + sodium_memzero(q, sizeof q); + crypto_generichash_update(&h, client_pk, crypto_kx_PUBLICKEYBYTES); + crypto_generichash_update(&h, server_pk, crypto_kx_PUBLICKEYBYTES); + crypto_generichash_final(&h, keys, sizeof keys); + sodium_memzero(&h, sizeof h); + for (i = 0; i < crypto_kx_SESSIONKEYBYTES; i++) { + tx[i] = keys[i]; + rx[i] = keys[i + crypto_kx_SESSIONKEYBYTES]; + } + sodium_memzero(keys, sizeof keys); + + return 0; +} + +size_t +crypto_kx_publickeybytes(void) +{ + return crypto_kx_PUBLICKEYBYTES; +} + +size_t +crypto_kx_secretkeybytes(void) +{ + return crypto_kx_SECRETKEYBYTES; +} + +size_t +crypto_kx_seedbytes(void) +{ + return crypto_kx_SEEDBYTES; +} + +size_t +crypto_kx_sessionkeybytes(void) +{ + return crypto_kx_SESSIONKEYBYTES; +} + +const char * +crypto_kx_primitive(void) +{ + return crypto_kx_PRIMITIVE; +} diff --git a/libs/libsodium/src/crypto_onetimeauth/crypto_onetimeauth.c b/libs/libsodium/src/crypto_onetimeauth/crypto_onetimeauth.c new file mode 100644 index 0000000000..93567aae0b --- /dev/null +++ b/libs/libsodium/src/crypto_onetimeauth/crypto_onetimeauth.c @@ -0,0 +1,71 @@ + +#include "crypto_onetimeauth.h" +#include "randombytes.h" + +size_t +crypto_onetimeauth_statebytes(void) +{ + return sizeof(crypto_onetimeauth_state); +} + +size_t +crypto_onetimeauth_bytes(void) +{ + return crypto_onetimeauth_BYTES; +} + +size_t +crypto_onetimeauth_keybytes(void) +{ + return crypto_onetimeauth_KEYBYTES; +} + +int +crypto_onetimeauth(unsigned char *out, const unsigned char *in, + unsigned long long inlen, const unsigned char *k) +{ + return crypto_onetimeauth_poly1305(out, in, inlen, k); +} + +int +crypto_onetimeauth_verify(const unsigned char *h, const unsigned char *in, + unsigned long long inlen, const unsigned char *k) +{ + return crypto_onetimeauth_poly1305_verify(h, in, inlen, k); +} + +int +crypto_onetimeauth_init(crypto_onetimeauth_state *state, + const unsigned char *key) +{ + return crypto_onetimeauth_poly1305_init + ((crypto_onetimeauth_poly1305_state *) state, key); +} + +int +crypto_onetimeauth_update(crypto_onetimeauth_state *state, + const unsigned char *in, + unsigned long long inlen) +{ + return crypto_onetimeauth_poly1305_update + ((crypto_onetimeauth_poly1305_state *) state, in, inlen); +} + +int +crypto_onetimeauth_final(crypto_onetimeauth_state *state, + unsigned char *out) +{ + return crypto_onetimeauth_poly1305_final + ((crypto_onetimeauth_poly1305_state *) state, out); +} + +const char * +crypto_onetimeauth_primitive(void) +{ + return crypto_onetimeauth_PRIMITIVE; +} + +void crypto_onetimeauth_keygen(unsigned char k[crypto_onetimeauth_KEYBYTES]) +{ + randombytes_buf(k, crypto_onetimeauth_KEYBYTES); +} diff --git a/libs/libsodium/src/crypto_onetimeauth/poly1305/donna/poly1305_donna.c b/libs/libsodium/src/crypto_onetimeauth/poly1305/donna/poly1305_donna.c new file mode 100644 index 0000000000..e798072f84 --- /dev/null +++ b/libs/libsodium/src/crypto_onetimeauth/poly1305/donna/poly1305_donna.c @@ -0,0 +1,124 @@ + +#include "poly1305_donna.h" +#include "crypto_verify_16.h" +#include "private/common.h" +#include "utils.h" + +#ifdef HAVE_TI_MODE +#include "poly1305_donna64.h" +#else +#include "poly1305_donna32.h" +#endif +#include "../onetimeauth_poly1305.h" + +static void +poly1305_update(poly1305_state_internal_t *st, const unsigned char *m, + unsigned long long bytes) +{ + unsigned long long i; + + /* handle leftover */ + if (st->leftover) { + unsigned long long want = (poly1305_block_size - st->leftover); + + if (want > bytes) { + want = bytes; + } + for (i = 0; i < want; i++) { + st->buffer[st->leftover + i] = m[i]; + } + bytes -= want; + m += want; + st->leftover += want; + if (st->leftover < poly1305_block_size) { + return; + } + poly1305_blocks(st, st->buffer, poly1305_block_size); + st->leftover = 0; + } + + /* process full blocks */ + if (bytes >= poly1305_block_size) { + unsigned long long want = (bytes & ~(poly1305_block_size - 1)); + + poly1305_blocks(st, m, want); + m += want; + bytes -= want; + } + + /* store leftover */ + if (bytes) { + for (i = 0; i < bytes; i++) { + st->buffer[st->leftover + i] = m[i]; + } + st->leftover += bytes; + } +} + +static int +crypto_onetimeauth_poly1305_donna(unsigned char *out, const unsigned char *m, + unsigned long long inlen, + const unsigned char *key) +{ + CRYPTO_ALIGN(64) poly1305_state_internal_t state; + + poly1305_init(&state, key); + poly1305_update(&state, m, inlen); + poly1305_finish(&state, out); + + return 0; +} + +static int +crypto_onetimeauth_poly1305_donna_init(crypto_onetimeauth_poly1305_state *state, + const unsigned char *key) +{ + COMPILER_ASSERT(sizeof(crypto_onetimeauth_poly1305_state) >= + sizeof(poly1305_state_internal_t)); + poly1305_init((poly1305_state_internal_t *) (void *) state, key); + + return 0; +} + +static int +crypto_onetimeauth_poly1305_donna_update( + crypto_onetimeauth_poly1305_state *state, const unsigned char *in, + unsigned long long inlen) +{ + poly1305_update((poly1305_state_internal_t *) (void *) state, in, inlen); + + return 0; +} + +static int +crypto_onetimeauth_poly1305_donna_final( + crypto_onetimeauth_poly1305_state *state, unsigned char *out) +{ + poly1305_finish((poly1305_state_internal_t *) (void *) state, out); + + return 0; +} + +static int +crypto_onetimeauth_poly1305_donna_verify(const unsigned char *h, + const unsigned char *in, + unsigned long long inlen, + const unsigned char *k) +{ + unsigned char correct[16]; + + crypto_onetimeauth_poly1305_donna(correct, in, inlen, k); + + return crypto_verify_16(h, correct); +} + +struct crypto_onetimeauth_poly1305_implementation + crypto_onetimeauth_poly1305_donna_implementation = { + SODIUM_C99(.onetimeauth =) crypto_onetimeauth_poly1305_donna, + SODIUM_C99(.onetimeauth_verify =) + crypto_onetimeauth_poly1305_donna_verify, + SODIUM_C99(.onetimeauth_init =) crypto_onetimeauth_poly1305_donna_init, + SODIUM_C99(.onetimeauth_update =) + crypto_onetimeauth_poly1305_donna_update, + SODIUM_C99(.onetimeauth_final =) crypto_onetimeauth_poly1305_donna_final + }; diff --git a/libs/libsodium/src/crypto_onetimeauth/poly1305/donna/poly1305_donna.h b/libs/libsodium/src/crypto_onetimeauth/poly1305/donna/poly1305_donna.h new file mode 100644 index 0000000000..d6474b3af4 --- /dev/null +++ b/libs/libsodium/src/crypto_onetimeauth/poly1305/donna/poly1305_donna.h @@ -0,0 +1,12 @@ +#ifndef poly1305_donna_H +#define poly1305_donna_H + +#include <stddef.h> + +#include "../onetimeauth_poly1305.h" +#include "crypto_onetimeauth_poly1305.h" + +extern struct crypto_onetimeauth_poly1305_implementation + crypto_onetimeauth_poly1305_donna_implementation; + +#endif /* poly1305_donna_H */ diff --git a/libs/libsodium/src/crypto_onetimeauth/poly1305/donna/poly1305_donna32.h b/libs/libsodium/src/crypto_onetimeauth/poly1305/donna/poly1305_donna32.h new file mode 100644 index 0000000000..bcf447cd7d --- /dev/null +++ b/libs/libsodium/src/crypto_onetimeauth/poly1305/donna/poly1305_donna32.h @@ -0,0 +1,235 @@ +/* + poly1305 implementation using 32 bit * 32 bit = 64 bit multiplication + and 64 bit addition +*/ + +#if defined(_MSC_VER) +# define POLY1305_NOINLINE __declspec(noinline) +#elif defined(__GNUC__) +# define POLY1305_NOINLINE __attribute__((noinline)) +#else +# define POLY1305_NOINLINE +#endif + +#include "private/common.h" + +#define poly1305_block_size 16 + +/* 17 + sizeof(unsigned long long) + 14*sizeof(unsigned long) */ +typedef struct poly1305_state_internal_t { + unsigned long r[5]; + unsigned long h[5]; + unsigned long pad[4]; + unsigned long long leftover; + unsigned char buffer[poly1305_block_size]; + unsigned char final; +} poly1305_state_internal_t; + +static void +poly1305_init(poly1305_state_internal_t *st, const unsigned char key[32]) +{ + /* r &= 0xffffffc0ffffffc0ffffffc0fffffff - wiped after finalization */ + st->r[0] = (LOAD32_LE(&key[0])) & 0x3ffffff; + st->r[1] = (LOAD32_LE(&key[3]) >> 2) & 0x3ffff03; + st->r[2] = (LOAD32_LE(&key[6]) >> 4) & 0x3ffc0ff; + st->r[3] = (LOAD32_LE(&key[9]) >> 6) & 0x3f03fff; + st->r[4] = (LOAD32_LE(&key[12]) >> 8) & 0x00fffff; + + /* h = 0 */ + st->h[0] = 0; + st->h[1] = 0; + st->h[2] = 0; + st->h[3] = 0; + st->h[4] = 0; + + /* save pad for later */ + st->pad[0] = LOAD32_LE(&key[16]); + st->pad[1] = LOAD32_LE(&key[20]); + st->pad[2] = LOAD32_LE(&key[24]); + st->pad[3] = LOAD32_LE(&key[28]); + + st->leftover = 0; + st->final = 0; +} + +static void +poly1305_blocks(poly1305_state_internal_t *st, const unsigned char *m, + unsigned long long bytes) +{ + const unsigned long hibit = (st->final) ? 0UL : (1UL << 24); /* 1 << 128 */ + unsigned long r0, r1, r2, r3, r4; + unsigned long s1, s2, s3, s4; + unsigned long h0, h1, h2, h3, h4; + unsigned long long d0, d1, d2, d3, d4; + unsigned long c; + + r0 = st->r[0]; + r1 = st->r[1]; + r2 = st->r[2]; + r3 = st->r[3]; + r4 = st->r[4]; + + s1 = r1 * 5; + s2 = r2 * 5; + s3 = r3 * 5; + s4 = r4 * 5; + + h0 = st->h[0]; + h1 = st->h[1]; + h2 = st->h[2]; + h3 = st->h[3]; + h4 = st->h[4]; + + while (bytes >= poly1305_block_size) { + /* h += m[i] */ + h0 += (LOAD32_LE(m + 0)) & 0x3ffffff; + h1 += (LOAD32_LE(m + 3) >> 2) & 0x3ffffff; + h2 += (LOAD32_LE(m + 6) >> 4) & 0x3ffffff; + h3 += (LOAD32_LE(m + 9) >> 6) & 0x3ffffff; + h4 += (LOAD32_LE(m + 12) >> 8) | hibit; + + /* h *= r */ + d0 = ((unsigned long long) h0 * r0) + ((unsigned long long) h1 * s4) + + ((unsigned long long) h2 * s3) + ((unsigned long long) h3 * s2) + + ((unsigned long long) h4 * s1); + d1 = ((unsigned long long) h0 * r1) + ((unsigned long long) h1 * r0) + + ((unsigned long long) h2 * s4) + ((unsigned long long) h3 * s3) + + ((unsigned long long) h4 * s2); + d2 = ((unsigned long long) h0 * r2) + ((unsigned long long) h1 * r1) + + ((unsigned long long) h2 * r0) + ((unsigned long long) h3 * s4) + + ((unsigned long long) h4 * s3); + d3 = ((unsigned long long) h0 * r3) + ((unsigned long long) h1 * r2) + + ((unsigned long long) h2 * r1) + ((unsigned long long) h3 * r0) + + ((unsigned long long) h4 * s4); + d4 = ((unsigned long long) h0 * r4) + ((unsigned long long) h1 * r3) + + ((unsigned long long) h2 * r2) + ((unsigned long long) h3 * r1) + + ((unsigned long long) h4 * r0); + + /* (partial) h %= p */ + c = (unsigned long) (d0 >> 26); + h0 = (unsigned long) d0 & 0x3ffffff; + d1 += c; + c = (unsigned long) (d1 >> 26); + h1 = (unsigned long) d1 & 0x3ffffff; + d2 += c; + c = (unsigned long) (d2 >> 26); + h2 = (unsigned long) d2 & 0x3ffffff; + d3 += c; + c = (unsigned long) (d3 >> 26); + h3 = (unsigned long) d3 & 0x3ffffff; + d4 += c; + c = (unsigned long) (d4 >> 26); + h4 = (unsigned long) d4 & 0x3ffffff; + h0 += c * 5; + c = (h0 >> 26); + h0 = h0 & 0x3ffffff; + h1 += c; + + m += poly1305_block_size; + bytes -= poly1305_block_size; + } + + st->h[0] = h0; + st->h[1] = h1; + st->h[2] = h2; + st->h[3] = h3; + st->h[4] = h4; +} + +static POLY1305_NOINLINE void +poly1305_finish(poly1305_state_internal_t *st, unsigned char mac[16]) +{ + unsigned long h0, h1, h2, h3, h4, c; + unsigned long g0, g1, g2, g3, g4; + unsigned long long f; + unsigned long mask; + + /* process the remaining block */ + if (st->leftover) { + unsigned long long i = st->leftover; + + st->buffer[i++] = 1; + for (; i < poly1305_block_size; i++) { + st->buffer[i] = 0; + } + st->final = 1; + poly1305_blocks(st, st->buffer, poly1305_block_size); + } + + /* fully carry h */ + h0 = st->h[0]; + h1 = st->h[1]; + h2 = st->h[2]; + h3 = st->h[3]; + h4 = st->h[4]; + + c = h1 >> 26; + h1 = h1 & 0x3ffffff; + h2 += c; + c = h2 >> 26; + h2 = h2 & 0x3ffffff; + h3 += c; + c = h3 >> 26; + h3 = h3 & 0x3ffffff; + h4 += c; + c = h4 >> 26; + h4 = h4 & 0x3ffffff; + h0 += c * 5; + c = h0 >> 26; + h0 = h0 & 0x3ffffff; + h1 += c; + + /* compute h + -p */ + g0 = h0 + 5; + c = g0 >> 26; + g0 &= 0x3ffffff; + g1 = h1 + c; + c = g1 >> 26; + g1 &= 0x3ffffff; + g2 = h2 + c; + c = g2 >> 26; + g2 &= 0x3ffffff; + g3 = h3 + c; + c = g3 >> 26; + g3 &= 0x3ffffff; + g4 = h4 + c - (1UL << 26); + + /* select h if h < p, or h + -p if h >= p */ + mask = (g4 >> ((sizeof(unsigned long) * 8) - 1)) - 1; + g0 &= mask; + g1 &= mask; + g2 &= mask; + g3 &= mask; + g4 &= mask; + mask = ~mask; + + h0 = (h0 & mask) | g0; + h1 = (h1 & mask) | g1; + h2 = (h2 & mask) | g2; + h3 = (h3 & mask) | g3; + h4 = (h4 & mask) | g4; + + /* h = h % (2^128) */ + h0 = ((h0) | (h1 << 26)) & 0xffffffff; + h1 = ((h1 >> 6) | (h2 << 20)) & 0xffffffff; + h2 = ((h2 >> 12) | (h3 << 14)) & 0xffffffff; + h3 = ((h3 >> 18) | (h4 << 8)) & 0xffffffff; + + /* mac = (h + pad) % (2^128) */ + f = (unsigned long long) h0 + st->pad[0]; + h0 = (unsigned long) f; + f = (unsigned long long) h1 + st->pad[1] + (f >> 32); + h1 = (unsigned long) f; + f = (unsigned long long) h2 + st->pad[2] + (f >> 32); + h2 = (unsigned long) f; + f = (unsigned long long) h3 + st->pad[3] + (f >> 32); + h3 = (unsigned long) f; + + STORE32_LE(mac + 0, (uint32_t) h0); + STORE32_LE(mac + 4, (uint32_t) h1); + STORE32_LE(mac + 8, (uint32_t) h2); + STORE32_LE(mac + 12, (uint32_t) h3); + + /* zero out the state */ + sodium_memzero((void *) st, sizeof *st); +} diff --git a/libs/libsodium/src/crypto_onetimeauth/poly1305/donna/poly1305_donna64.h b/libs/libsodium/src/crypto_onetimeauth/poly1305/donna/poly1305_donna64.h new file mode 100644 index 0000000000..e0ed754779 --- /dev/null +++ b/libs/libsodium/src/crypto_onetimeauth/poly1305/donna/poly1305_donna64.h @@ -0,0 +1,220 @@ +/* + poly1305 implementation using 64 bit * 64 bit = 128 bit multiplication + and 128 bit addition +*/ + +#include "private/common.h" + +#define MUL(out, x, y) out = ((uint128_t) x * y) +#define ADD(out, in) out += in +#define ADDLO(out, in) out += in +#define SHR(in, shift) (unsigned long long) (in >> (shift)) +#define LO(in) (unsigned long long) (in) + +#if defined(_MSC_VER) +# define POLY1305_NOINLINE __declspec(noinline) +#elif defined(__GNUC__) +# define POLY1305_NOINLINE __attribute__((noinline)) +#else +# define POLY1305_NOINLINE +#endif + +#define poly1305_block_size 16 + +/* 17 + sizeof(unsigned long long) + 8*sizeof(unsigned long long) */ +typedef struct poly1305_state_internal_t { + unsigned long long r[3]; + unsigned long long h[3]; + unsigned long long pad[2]; + unsigned long long leftover; + unsigned char buffer[poly1305_block_size]; + unsigned char final; +} poly1305_state_internal_t; + +static void +poly1305_init(poly1305_state_internal_t *st, const unsigned char key[32]) +{ + unsigned long long t0, t1; + + /* r &= 0xffffffc0ffffffc0ffffffc0fffffff */ + t0 = LOAD64_LE(&key[0]); + t1 = LOAD64_LE(&key[8]); + + /* wiped after finalization */ + st->r[0] = (t0) &0xffc0fffffff; + st->r[1] = ((t0 >> 44) | (t1 << 20)) & 0xfffffc0ffff; + st->r[2] = ((t1 >> 24)) & 0x00ffffffc0f; + + /* h = 0 */ + st->h[0] = 0; + st->h[1] = 0; + st->h[2] = 0; + + /* save pad for later */ + st->pad[0] = LOAD64_LE(&key[16]); + st->pad[1] = LOAD64_LE(&key[24]); + + st->leftover = 0; + st->final = 0; +} + +static void +poly1305_blocks(poly1305_state_internal_t *st, const unsigned char *m, + unsigned long long bytes) +{ + const unsigned long long hibit = + (st->final) ? 0ULL : (1ULL << 40); /* 1 << 128 */ + unsigned long long r0, r1, r2; + unsigned long long s1, s2; + unsigned long long h0, h1, h2; + unsigned long long c; + uint128_t d0, d1, d2, d; + + r0 = st->r[0]; + r1 = st->r[1]; + r2 = st->r[2]; + + h0 = st->h[0]; + h1 = st->h[1]; + h2 = st->h[2]; + + s1 = r1 * (5 << 2); + s2 = r2 * (5 << 2); + + while (bytes >= poly1305_block_size) { + unsigned long long t0, t1; + + /* h += m[i] */ + t0 = LOAD64_LE(&m[0]); + t1 = LOAD64_LE(&m[8]); + + h0 += ((t0) &0xfffffffffff); + h1 += (((t0 >> 44) | (t1 << 20)) & 0xfffffffffff); + h2 += (((t1 >> 24)) & 0x3ffffffffff) | hibit; + + /* h *= r */ + MUL(d0, h0, r0); + MUL(d, h1, s2); + ADD(d0, d); + MUL(d, h2, s1); + ADD(d0, d); + MUL(d1, h0, r1); + MUL(d, h1, r0); + ADD(d1, d); + MUL(d, h2, s2); + ADD(d1, d); + MUL(d2, h0, r2); + MUL(d, h1, r1); + ADD(d2, d); + MUL(d, h2, r0); + ADD(d2, d); + + /* (partial) h %= p */ + c = SHR(d0, 44); + h0 = LO(d0) & 0xfffffffffff; + ADDLO(d1, c); + c = SHR(d1, 44); + h1 = LO(d1) & 0xfffffffffff; + ADDLO(d2, c); + c = SHR(d2, 42); + h2 = LO(d2) & 0x3ffffffffff; + h0 += c * 5; + c = (h0 >> 44); + h0 = h0 & 0xfffffffffff; + h1 += c; + + m += poly1305_block_size; + bytes -= poly1305_block_size; + } + + st->h[0] = h0; + st->h[1] = h1; + st->h[2] = h2; +} + +static POLY1305_NOINLINE void +poly1305_finish(poly1305_state_internal_t *st, unsigned char mac[16]) +{ + unsigned long long h0, h1, h2, c; + unsigned long long g0, g1, g2; + unsigned long long t0, t1; + + /* process the remaining block */ + if (st->leftover) { + unsigned long long i = st->leftover; + + st->buffer[i] = 1; + + for (i = i + 1; i < poly1305_block_size; i++) { + st->buffer[i] = 0; + } + st->final = 1; + poly1305_blocks(st, st->buffer, poly1305_block_size); + } + + /* fully carry h */ + h0 = st->h[0]; + h1 = st->h[1]; + h2 = st->h[2]; + + c = (h1 >> 44); + h1 &= 0xfffffffffff; + h2 += c; + c = (h2 >> 42); + h2 &= 0x3ffffffffff; + h0 += c * 5; + c = (h0 >> 44); + h0 &= 0xfffffffffff; + h1 += c; + c = (h1 >> 44); + h1 &= 0xfffffffffff; + h2 += c; + c = (h2 >> 42); + h2 &= 0x3ffffffffff; + h0 += c * 5; + c = (h0 >> 44); + h0 &= 0xfffffffffff; + h1 += c; + + /* compute h + -p */ + g0 = h0 + 5; + c = (g0 >> 44); + g0 &= 0xfffffffffff; + g1 = h1 + c; + c = (g1 >> 44); + g1 &= 0xfffffffffff; + g2 = h2 + c - (1ULL << 42); + + /* select h if h < p, or h + -p if h >= p */ + c = (g2 >> ((sizeof(unsigned long long) * 8) - 1)) - 1; + g0 &= c; + g1 &= c; + g2 &= c; + c = ~c; + h0 = (h0 & c) | g0; + h1 = (h1 & c) | g1; + h2 = (h2 & c) | g2; + + /* h = (h + pad) */ + t0 = st->pad[0]; + t1 = st->pad[1]; + + h0 += ((t0) &0xfffffffffff); + c = (h0 >> 44); + h0 &= 0xfffffffffff; + h1 += (((t0 >> 44) | (t1 << 20)) & 0xfffffffffff) + c; + c = (h1 >> 44); + h1 &= 0xfffffffffff; + h2 += (((t1 >> 24)) & 0x3ffffffffff) + c; + h2 &= 0x3ffffffffff; + + /* mac = h % (2^128) */ + h0 = ((h0) | (h1 << 44)); + h1 = ((h1 >> 20) | (h2 << 24)); + + STORE64_LE(&mac[0], h0); + STORE64_LE(&mac[8], h1); + + /* zero out the state */ + sodium_memzero((void *) st, sizeof *st); +} diff --git a/libs/libsodium/src/crypto_onetimeauth/poly1305/onetimeauth_poly1305.c b/libs/libsodium/src/crypto_onetimeauth/poly1305/onetimeauth_poly1305.c new file mode 100644 index 0000000000..d5e2efa297 --- /dev/null +++ b/libs/libsodium/src/crypto_onetimeauth/poly1305/onetimeauth_poly1305.c @@ -0,0 +1,90 @@ + +#include "onetimeauth_poly1305.h" +#include "crypto_onetimeauth_poly1305.h" +#include "private/common.h" +#include "private/implementations.h" +#include "randombytes.h" +#include "runtime.h" + +#include "donna/poly1305_donna.h" +#if defined(HAVE_TI_MODE) && defined(HAVE_EMMINTRIN_H) +# include "sse2/poly1305_sse2.h" +#endif + +static const crypto_onetimeauth_poly1305_implementation *implementation = + &crypto_onetimeauth_poly1305_donna_implementation; + +int +crypto_onetimeauth_poly1305(unsigned char *out, const unsigned char *in, + unsigned long long inlen, const unsigned char *k) +{ + return implementation->onetimeauth(out, in, inlen, k); +} + +int +crypto_onetimeauth_poly1305_verify(const unsigned char *h, + const unsigned char *in, + unsigned long long inlen, + const unsigned char *k) +{ + return implementation->onetimeauth_verify(h, in, inlen, k); +} + +int +crypto_onetimeauth_poly1305_init(crypto_onetimeauth_poly1305_state *state, + const unsigned char *key) +{ + return implementation->onetimeauth_init(state, key); +} + +int +crypto_onetimeauth_poly1305_update(crypto_onetimeauth_poly1305_state *state, + const unsigned char *in, + unsigned long long inlen) +{ + return implementation->onetimeauth_update(state, in, inlen); +} + +int +crypto_onetimeauth_poly1305_final(crypto_onetimeauth_poly1305_state *state, + unsigned char *out) +{ + return implementation->onetimeauth_final(state, out); +} + +size_t +crypto_onetimeauth_poly1305_bytes(void) +{ + return crypto_onetimeauth_poly1305_BYTES; +} + +size_t +crypto_onetimeauth_poly1305_keybytes(void) +{ + return crypto_onetimeauth_poly1305_KEYBYTES; +} + +size_t +crypto_onetimeauth_poly1305_statebytes(void) +{ + return sizeof(crypto_onetimeauth_poly1305_state); +} + +void +crypto_onetimeauth_poly1305_keygen( + unsigned char k[crypto_onetimeauth_poly1305_KEYBYTES]) +{ + randombytes_buf(k, crypto_onetimeauth_poly1305_KEYBYTES); +} + +int +_crypto_onetimeauth_poly1305_pick_best_implementation(void) +{ + implementation = &crypto_onetimeauth_poly1305_donna_implementation; +#if defined(HAVE_TI_MODE) && defined(HAVE_EMMINTRIN_H) + if (sodium_runtime_has_sse2()) { + implementation = &crypto_onetimeauth_poly1305_sse2_implementation; + } +#endif + return 0; +} diff --git a/libs/libsodium/src/crypto_onetimeauth/poly1305/onetimeauth_poly1305.h b/libs/libsodium/src/crypto_onetimeauth/poly1305/onetimeauth_poly1305.h new file mode 100644 index 0000000000..243eadd50b --- /dev/null +++ b/libs/libsodium/src/crypto_onetimeauth/poly1305/onetimeauth_poly1305.h @@ -0,0 +1,21 @@ + +#ifndef onetimeauth_poly1305_H +#define onetimeauth_poly1305_H + +#include "crypto_onetimeauth_poly1305.h" + +typedef struct crypto_onetimeauth_poly1305_implementation { + int (*onetimeauth)(unsigned char *out, const unsigned char *in, + unsigned long long inlen, const unsigned char *k); + int (*onetimeauth_verify)(const unsigned char *h, const unsigned char *in, + unsigned long long inlen, const unsigned char *k); + int (*onetimeauth_init)(crypto_onetimeauth_poly1305_state *state, + const unsigned char * key); + int (*onetimeauth_update)(crypto_onetimeauth_poly1305_state *state, + const unsigned char * in, + unsigned long long inlen); + int (*onetimeauth_final)(crypto_onetimeauth_poly1305_state *state, + unsigned char * out); +} crypto_onetimeauth_poly1305_implementation; + +#endif diff --git a/libs/libsodium/src/crypto_onetimeauth/poly1305/sse2/poly1305_sse2.c b/libs/libsodium/src/crypto_onetimeauth/poly1305/sse2/poly1305_sse2.c new file mode 100644 index 0000000000..022f15249b --- /dev/null +++ b/libs/libsodium/src/crypto_onetimeauth/poly1305/sse2/poly1305_sse2.c @@ -0,0 +1,949 @@ + +#include <stdint.h> +#include <string.h> + +#include "../onetimeauth_poly1305.h" +#include "crypto_verify_16.h" +#include "poly1305_sse2.h" +#include "private/common.h" +#include "private/sse2_64_32.h" +#include "utils.h" + +#if defined(HAVE_TI_MODE) && defined(HAVE_EMMINTRIN_H) + +# ifdef __GNUC__ +# pragma GCC target("sse2") +# endif + +# include <emmintrin.h> + +typedef __m128i xmmi; + +# if defined(_MSC_VER) +# define POLY1305_NOINLINE __declspec(noinline) +# elif defined(__GNUC__) +# define POLY1305_NOINLINE __attribute__((noinline)) +# else +# define POLY1305_NOINLINE +# endif + +# define poly1305_block_size 32 + +enum poly1305_state_flags_t { + poly1305_started = 1, + poly1305_final_shift8 = 4, + poly1305_final_shift16 = 8, + poly1305_final_r2_r = 16, /* use [r^2,r] for the final block */ + poly1305_final_r_1 = 32 /* use [r,1] for the final block */ +}; + +typedef struct poly1305_state_internal_t { + union { + uint64_t h[3]; + uint32_t hh[10]; + } H; /* 40 bytes */ + uint32_t R[5]; /* 20 bytes */ + uint32_t R2[5]; /* 20 bytes */ + uint32_t R4[5]; /* 20 bytes */ + uint64_t pad[2]; /* 16 bytes */ + uint64_t flags; /* 8 bytes */ + unsigned long long leftover; /* 8 bytes */ + unsigned char buffer[poly1305_block_size]; /* 32 bytes */ +} poly1305_state_internal_t; /* 164 bytes total */ + +/* + * _mm_loadl_epi64() is turned into a simple MOVQ. So, unaligned accesses are + * totally fine, even though this intrinsic requires a __m128i* input. + * This confuses dynamic analysis, so force alignment, only in debug mode. + */ +# ifdef DEBUG +static xmmi +_fakealign_mm_loadl_epi64(const void *m) +{ + xmmi tmp; + memcpy(&tmp, m, 8); + + return _mm_loadl_epi64(&tmp); +} +# define _mm_loadl_epi64(X) _fakealign_mm_loadl_epi64(X) +#endif + +/* copy 0-31 bytes */ +static inline void +poly1305_block_copy31(unsigned char *dst, const unsigned char *src, + unsigned long long bytes) +{ + if (bytes & 16) { + _mm_store_si128((xmmi *) (void *) dst, + _mm_loadu_si128((const xmmi *) (const void *) src)); + src += 16; + dst += 16; + } + if (bytes & 8) { + memcpy(dst, src, 8); + src += 8; + dst += 8; + } + if (bytes & 4) { + memcpy(dst, src, 4); + src += 4; + dst += 4; + } + if (bytes & 2) { + memcpy(dst, src, 2); + src += 2; + dst += 2; + } + if (bytes & 1) { + *dst = *src; + } +} + +static POLY1305_NOINLINE void +poly1305_init_ext(poly1305_state_internal_t *st, const unsigned char key[32], + unsigned long long bytes) +{ + uint32_t *R; + uint128_t d[3]; + uint64_t r0, r1, r2; + uint64_t rt0, rt1, rt2, st2, c; + uint64_t t0, t1; + unsigned long long i; + + if (!bytes) { + bytes = ~(unsigned long long) 0; + } + /* H = 0 */ + _mm_storeu_si128((xmmi *) (void *) &st->H.hh[0], _mm_setzero_si128()); + _mm_storeu_si128((xmmi *) (void *) &st->H.hh[4], _mm_setzero_si128()); + _mm_storeu_si128((xmmi *) (void *) &st->H.hh[8], _mm_setzero_si128()); + + /* clamp key */ + memcpy(&t0, key, 8); + memcpy(&t1, key + 8, 8); + r0 = t0 & 0xffc0fffffff; + t0 >>= 44; + t0 |= t1 << 20; + r1 = t0 & 0xfffffc0ffff; + t1 >>= 24; + r2 = t1 & 0x00ffffffc0f; + + /* r^1 */ + R = st->R; + R[0] = (uint32_t)(r0) &0x3ffffff; + R[1] = (uint32_t)((r0 >> 26) | (r1 << 18)) & 0x3ffffff; + R[2] = (uint32_t)((r1 >> 8)) & 0x3ffffff; + R[3] = (uint32_t)((r1 >> 34) | (r2 << 10)) & 0x3ffffff; + R[4] = (uint32_t)((r2 >> 16)); + + /* save pad */ + memcpy(&st->pad[0], key + 16, 8); + memcpy(&st->pad[1], key + 24, 8); + + rt0 = r0; + rt1 = r1; + rt2 = r2; + + /* r^2, r^4 */ + for (i = 0; i < 2; i++) { + if (i == 0) { + R = st->R2; + if (bytes <= 16) { + break; + } + } else if (i == 1) { + R = st->R4; + if (bytes < 96) { + break; + } + } + st2 = rt2 * (5 << 2); + + d[0] = ((uint128_t) rt0 * rt0) + ((uint128_t)(rt1 * 2) * st2); + d[1] = ((uint128_t) rt2 * st2) + ((uint128_t)(rt0 * 2) * rt1); + d[2] = ((uint128_t) rt1 * rt1) + ((uint128_t)(rt2 * 2) * rt0); + + rt0 = (uint64_t) d[0] & 0xfffffffffff; + c = (uint64_t)(d[0] >> 44); + d[1] += c; + + rt1 = (uint64_t) d[1] & 0xfffffffffff; + c = (uint64_t)(d[1] >> 44); + d[2] += c; + + rt2 = (uint64_t) d[2] & 0x3ffffffffff; + c = (uint64_t)(d[2] >> 42); + rt0 += c * 5; + c = (rt0 >> 44); + rt0 = rt0 & 0xfffffffffff; + rt1 += c; + c = (rt1 >> 44); + rt1 = rt1 & 0xfffffffffff; + rt2 += c; /* even if rt2 overflows, it will still fit in rp4 safely, and + is safe to multiply with */ + + R[0] = (uint32_t)(rt0) &0x3ffffff; + R[1] = (uint32_t)((rt0 >> 26) | (rt1 << 18)) & 0x3ffffff; + R[2] = (uint32_t)((rt1 >> 8)) & 0x3ffffff; + R[3] = (uint32_t)((rt1 >> 34) | (rt2 << 10)) & 0x3ffffff; + R[4] = (uint32_t)((rt2 >> 16)); + } + st->flags = 0; + st->leftover = 0U; +} + +static POLY1305_NOINLINE void +poly1305_blocks(poly1305_state_internal_t *st, const unsigned char *m, + unsigned long long bytes) +{ + CRYPTO_ALIGN(64) + xmmi HIBIT = + _mm_shuffle_epi32(_mm_cvtsi32_si128(1 << 24), _MM_SHUFFLE(1, 0, 1, 0)); + const xmmi MMASK = _mm_shuffle_epi32(_mm_cvtsi32_si128((1 << 26) - 1), + _MM_SHUFFLE(1, 0, 1, 0)); + const xmmi FIVE = + _mm_shuffle_epi32(_mm_cvtsi32_si128(5), _MM_SHUFFLE(1, 0, 1, 0)); + xmmi H0, H1, H2, H3, H4; + xmmi T0, T1, T2, T3, T4, T5, T6, T7, T8; + xmmi M0, M1, M2, M3, M4; + xmmi M5, M6, M7, M8; + xmmi C1, C2; + xmmi R20, R21, R22, R23, R24, S21, S22, S23, S24; + xmmi R40, R41, R42, R43, R44, S41, S42, S43, S44; + + if (st->flags & poly1305_final_shift8) { + HIBIT = _mm_srli_si128(HIBIT, 8); + } + if (st->flags & poly1305_final_shift16) { + HIBIT = _mm_setzero_si128(); + } + if (!(st->flags & poly1305_started)) { + /* H = [Mx,My] */ + T5 = _mm_unpacklo_epi64( + _mm_loadl_epi64((const xmmi *) (const void *) (m + 0)), + _mm_loadl_epi64((const xmmi *) (const void *) (m + 16))); + T6 = _mm_unpacklo_epi64( + _mm_loadl_epi64((const xmmi *) (const void *) (m + 8)), + _mm_loadl_epi64((const xmmi *) (const void *) (m + 24))); + H0 = _mm_and_si128(MMASK, T5); + H1 = _mm_and_si128(MMASK, _mm_srli_epi64(T5, 26)); + T5 = _mm_or_si128(_mm_srli_epi64(T5, 52), _mm_slli_epi64(T6, 12)); + H2 = _mm_and_si128(MMASK, T5); + H3 = _mm_and_si128(MMASK, _mm_srli_epi64(T5, 26)); + H4 = _mm_srli_epi64(T6, 40); + H4 = _mm_or_si128(H4, HIBIT); + m += 32; + bytes -= 32; + st->flags |= poly1305_started; + } else { + T0 = _mm_loadu_si128((const xmmi *) (const void *) &st->H.hh[0]); + T1 = _mm_loadu_si128((const xmmi *) (const void *) &st->H.hh[4]); + T2 = _mm_loadu_si128((const xmmi *) (const void *) &st->H.hh[8]); + H0 = _mm_shuffle_epi32(T0, _MM_SHUFFLE(1, 1, 0, 0)); + H1 = _mm_shuffle_epi32(T0, _MM_SHUFFLE(3, 3, 2, 2)); + H2 = _mm_shuffle_epi32(T1, _MM_SHUFFLE(1, 1, 0, 0)); + H3 = _mm_shuffle_epi32(T1, _MM_SHUFFLE(3, 3, 2, 2)); + H4 = _mm_shuffle_epi32(T2, _MM_SHUFFLE(1, 1, 0, 0)); + } + if (st->flags & (poly1305_final_r2_r | poly1305_final_r_1)) { + if (st->flags & poly1305_final_r2_r) { + /* use [r^2, r] */ + T2 = _mm_loadu_si128((const xmmi *) (const void *) &st->R[0]); + T3 = _mm_cvtsi32_si128(st->R[4]); + T0 = _mm_loadu_si128((const xmmi *) (const void *) &st->R2[0]); + T1 = _mm_cvtsi32_si128(st->R2[4]); + T4 = _mm_unpacklo_epi32(T0, T2); + T5 = _mm_unpackhi_epi32(T0, T2); + R24 = _mm_unpacklo_epi64(T1, T3); + } else { + /* use [r^1, 1] */ + T0 = _mm_loadu_si128((const xmmi *) (const void *) &st->R[0]); + T1 = _mm_cvtsi32_si128(st->R[4]); + T2 = _mm_cvtsi32_si128(1); + T4 = _mm_unpacklo_epi32(T0, T2); + T5 = _mm_unpackhi_epi32(T0, T2); + R24 = T1; + } + R20 = _mm_shuffle_epi32(T4, _MM_SHUFFLE(1, 1, 0, 0)); + R21 = _mm_shuffle_epi32(T4, _MM_SHUFFLE(3, 3, 2, 2)); + R22 = _mm_shuffle_epi32(T5, _MM_SHUFFLE(1, 1, 0, 0)); + R23 = _mm_shuffle_epi32(T5, _MM_SHUFFLE(3, 3, 2, 2)); + } else { + /* use [r^2, r^2] */ + T0 = _mm_loadu_si128((const xmmi *) (const void *) &st->R2[0]); + T1 = _mm_cvtsi32_si128(st->R2[4]); + R20 = _mm_shuffle_epi32(T0, _MM_SHUFFLE(0, 0, 0, 0)); + R21 = _mm_shuffle_epi32(T0, _MM_SHUFFLE(1, 1, 1, 1)); + R22 = _mm_shuffle_epi32(T0, _MM_SHUFFLE(2, 2, 2, 2)); + R23 = _mm_shuffle_epi32(T0, _MM_SHUFFLE(3, 3, 3, 3)); + R24 = _mm_shuffle_epi32(T1, _MM_SHUFFLE(0, 0, 0, 0)); + } + S21 = _mm_mul_epu32(R21, FIVE); + S22 = _mm_mul_epu32(R22, FIVE); + S23 = _mm_mul_epu32(R23, FIVE); + S24 = _mm_mul_epu32(R24, FIVE); + + if (bytes >= 64) { + T0 = _mm_loadu_si128((const xmmi *) (const void *) &st->R4[0]); + T1 = _mm_cvtsi32_si128(st->R4[4]); + R40 = _mm_shuffle_epi32(T0, _MM_SHUFFLE(0, 0, 0, 0)); + R41 = _mm_shuffle_epi32(T0, _MM_SHUFFLE(1, 1, 1, 1)); + R42 = _mm_shuffle_epi32(T0, _MM_SHUFFLE(2, 2, 2, 2)); + R43 = _mm_shuffle_epi32(T0, _MM_SHUFFLE(3, 3, 3, 3)); + R44 = _mm_shuffle_epi32(T1, _MM_SHUFFLE(0, 0, 0, 0)); + S41 = _mm_mul_epu32(R41, FIVE); + S42 = _mm_mul_epu32(R42, FIVE); + S43 = _mm_mul_epu32(R43, FIVE); + S44 = _mm_mul_epu32(R44, FIVE); + + while (bytes >= 64) { + xmmi v00, v01, v02, v03, v04; + xmmi v10, v11, v12, v13, v14; + xmmi v20, v21, v22, v23, v24; + xmmi v30, v31, v32, v33, v34; + xmmi v40, v41, v42, v43, v44; + xmmi T14, T15; + + /* H *= [r^4,r^4], preload [Mx,My] */ + T15 = S42; + T0 = H4; + T0 = _mm_mul_epu32(T0, S41); + v01 = H3; + v01 = _mm_mul_epu32(v01, T15); + T14 = S43; + T1 = H4; + T1 = _mm_mul_epu32(T1, T15); + v11 = H3; + v11 = _mm_mul_epu32(v11, T14); + T2 = H4; + T2 = _mm_mul_epu32(T2, T14); + T0 = _mm_add_epi64(T0, v01); + T15 = S44; + v02 = H2; + v02 = _mm_mul_epu32(v02, T14); + T3 = H4; + T3 = _mm_mul_epu32(T3, T15); + T1 = _mm_add_epi64(T1, v11); + v03 = H1; + v03 = _mm_mul_epu32(v03, T15); + v12 = H2; + v12 = _mm_mul_epu32(v12, T15); + T0 = _mm_add_epi64(T0, v02); + T14 = R40; + v21 = H3; + v21 = _mm_mul_epu32(v21, T15); + v31 = H3; + v31 = _mm_mul_epu32(v31, T14); + T0 = _mm_add_epi64(T0, v03); + T4 = H4; + T4 = _mm_mul_epu32(T4, T14); + T1 = _mm_add_epi64(T1, v12); + v04 = H0; + v04 = _mm_mul_epu32(v04, T14); + T2 = _mm_add_epi64(T2, v21); + v13 = H1; + v13 = _mm_mul_epu32(v13, T14); + T3 = _mm_add_epi64(T3, v31); + T15 = R41; + v22 = H2; + v22 = _mm_mul_epu32(v22, T14); + v32 = H2; + v32 = _mm_mul_epu32(v32, T15); + T0 = _mm_add_epi64(T0, v04); + v41 = H3; + v41 = _mm_mul_epu32(v41, T15); + T1 = _mm_add_epi64(T1, v13); + v14 = H0; + v14 = _mm_mul_epu32(v14, T15); + T2 = _mm_add_epi64(T2, v22); + T14 = R42; + T5 = _mm_unpacklo_epi64( + _mm_loadl_epi64((const xmmi *) (const void *) (m + 0)), + _mm_loadl_epi64((const xmmi *) (const void *) (m + 16))); + v23 = H1; + v23 = _mm_mul_epu32(v23, T15); + T3 = _mm_add_epi64(T3, v32); + v33 = H1; + v33 = _mm_mul_epu32(v33, T14); + T4 = _mm_add_epi64(T4, v41); + v42 = H2; + v42 = _mm_mul_epu32(v42, T14); + T1 = _mm_add_epi64(T1, v14); + T15 = R43; + T6 = _mm_unpacklo_epi64( + _mm_loadl_epi64((const xmmi *) (const void *) (m + 8)), + _mm_loadl_epi64((const xmmi *) (const void *) (m + 24))); + v24 = H0; + v24 = _mm_mul_epu32(v24, T14); + T2 = _mm_add_epi64(T2, v23); + v34 = H0; + v34 = _mm_mul_epu32(v34, T15); + T3 = _mm_add_epi64(T3, v33); + M0 = _mm_and_si128(MMASK, T5); + v43 = H1; + v43 = _mm_mul_epu32(v43, T15); + T4 = _mm_add_epi64(T4, v42); + M1 = _mm_and_si128(MMASK, _mm_srli_epi64(T5, 26)); + v44 = H0; + v44 = _mm_mul_epu32(v44, R44); + T2 = _mm_add_epi64(T2, v24); + T5 = _mm_or_si128(_mm_srli_epi64(T5, 52), _mm_slli_epi64(T6, 12)); + T3 = _mm_add_epi64(T3, v34); + M3 = _mm_and_si128(MMASK, _mm_srli_epi64(T6, 14)); + T4 = _mm_add_epi64(T4, v43); + M2 = _mm_and_si128(MMASK, T5); + T4 = _mm_add_epi64(T4, v44); + M4 = _mm_or_si128(_mm_srli_epi64(T6, 40), HIBIT); + + /* H += [Mx',My'] */ + T5 = _mm_loadu_si128((const xmmi *) (const void *) (m + 32)); + T6 = _mm_loadu_si128((const xmmi *) (const void *) (m + 48)); + T7 = _mm_unpacklo_epi32(T5, T6); + T8 = _mm_unpackhi_epi32(T5, T6); + M5 = _mm_unpacklo_epi32(T7, _mm_setzero_si128()); + M6 = _mm_unpackhi_epi32(T7, _mm_setzero_si128()); + M7 = _mm_unpacklo_epi32(T8, _mm_setzero_si128()); + M8 = _mm_unpackhi_epi32(T8, _mm_setzero_si128()); + M6 = _mm_slli_epi64(M6, 6); + M7 = _mm_slli_epi64(M7, 12); + M8 = _mm_slli_epi64(M8, 18); + T0 = _mm_add_epi64(T0, M5); + T1 = _mm_add_epi64(T1, M6); + T2 = _mm_add_epi64(T2, M7); + T3 = _mm_add_epi64(T3, M8); + T4 = _mm_add_epi64(T4, HIBIT); + + /* H += [Mx,My]*[r^2,r^2] */ + T15 = S22; + v00 = M4; + v00 = _mm_mul_epu32(v00, S21); + v01 = M3; + v01 = _mm_mul_epu32(v01, T15); + T14 = S23; + v10 = M4; + v10 = _mm_mul_epu32(v10, T15); + v11 = M3; + v11 = _mm_mul_epu32(v11, T14); + T0 = _mm_add_epi64(T0, v00); + v20 = M4; + v20 = _mm_mul_epu32(v20, T14); + T0 = _mm_add_epi64(T0, v01); + T15 = S24; + v02 = M2; + v02 = _mm_mul_epu32(v02, T14); + T1 = _mm_add_epi64(T1, v10); + v30 = M4; + v30 = _mm_mul_epu32(v30, T15); + T1 = _mm_add_epi64(T1, v11); + v03 = M1; + v03 = _mm_mul_epu32(v03, T15); + T2 = _mm_add_epi64(T2, v20); + v12 = M2; + v12 = _mm_mul_epu32(v12, T15); + T0 = _mm_add_epi64(T0, v02); + T14 = R20; + v21 = M3; + v21 = _mm_mul_epu32(v21, T15); + T3 = _mm_add_epi64(T3, v30); + v31 = M3; + v31 = _mm_mul_epu32(v31, T14); + T0 = _mm_add_epi64(T0, v03); + v40 = M4; + v40 = _mm_mul_epu32(v40, T14); + T1 = _mm_add_epi64(T1, v12); + v04 = M0; + v04 = _mm_mul_epu32(v04, T14); + T2 = _mm_add_epi64(T2, v21); + v13 = M1; + v13 = _mm_mul_epu32(v13, T14); + T3 = _mm_add_epi64(T3, v31); + T15 = R21; + v22 = M2; + v22 = _mm_mul_epu32(v22, T14); + T4 = _mm_add_epi64(T4, v40); + v32 = M2; + v32 = _mm_mul_epu32(v32, T15); + T0 = _mm_add_epi64(T0, v04); + v41 = M3; + v41 = _mm_mul_epu32(v41, T15); + T1 = _mm_add_epi64(T1, v13); + v14 = M0; + v14 = _mm_mul_epu32(v14, T15); + T2 = _mm_add_epi64(T2, v22); + T14 = R22; + v23 = M1; + v23 = _mm_mul_epu32(v23, T15); + T3 = _mm_add_epi64(T3, v32); + v33 = M1; + v33 = _mm_mul_epu32(v33, T14); + T4 = _mm_add_epi64(T4, v41); + v42 = M2; + v42 = _mm_mul_epu32(v42, T14); + T1 = _mm_add_epi64(T1, v14); + T15 = R23; + v24 = M0; + v24 = _mm_mul_epu32(v24, T14); + T2 = _mm_add_epi64(T2, v23); + v34 = M0; + v34 = _mm_mul_epu32(v34, T15); + T3 = _mm_add_epi64(T3, v33); + v43 = M1; + v43 = _mm_mul_epu32(v43, T15); + T4 = _mm_add_epi64(T4, v42); + v44 = M0; + v44 = _mm_mul_epu32(v44, R24); + T2 = _mm_add_epi64(T2, v24); + T3 = _mm_add_epi64(T3, v34); + T4 = _mm_add_epi64(T4, v43); + T4 = _mm_add_epi64(T4, v44); + + /* reduce */ + C1 = _mm_srli_epi64(T0, 26); + C2 = _mm_srli_epi64(T3, 26); + T0 = _mm_and_si128(T0, MMASK); + T3 = _mm_and_si128(T3, MMASK); + T1 = _mm_add_epi64(T1, C1); + T4 = _mm_add_epi64(T4, C2); + C1 = _mm_srli_epi64(T1, 26); + C2 = _mm_srli_epi64(T4, 26); + T1 = _mm_and_si128(T1, MMASK); + T4 = _mm_and_si128(T4, MMASK); + T2 = _mm_add_epi64(T2, C1); + T0 = _mm_add_epi64(T0, _mm_mul_epu32(C2, FIVE)); + C1 = _mm_srli_epi64(T2, 26); + C2 = _mm_srli_epi64(T0, 26); + T2 = _mm_and_si128(T2, MMASK); + T0 = _mm_and_si128(T0, MMASK); + T3 = _mm_add_epi64(T3, C1); + T1 = _mm_add_epi64(T1, C2); + C1 = _mm_srli_epi64(T3, 26); + T3 = _mm_and_si128(T3, MMASK); + T4 = _mm_add_epi64(T4, C1); + + /* Final: H = (H*[r^4,r^4] + [Mx,My]*[r^2,r^2] + [Mx',My']) */ + H0 = T0; + H1 = T1; + H2 = T2; + H3 = T3; + H4 = T4; + + m += 64; + bytes -= 64; + } + } + + if (bytes >= 32) { + xmmi v01, v02, v03, v04; + xmmi v11, v12, v13, v14; + xmmi v21, v22, v23, v24; + xmmi v31, v32, v33, v34; + xmmi v41, v42, v43, v44; + xmmi T14, T15; + + /* H *= [r^2,r^2] */ + T15 = S22; + T0 = H4; + T0 = _mm_mul_epu32(T0, S21); + v01 = H3; + v01 = _mm_mul_epu32(v01, T15); + T14 = S23; + T1 = H4; + T1 = _mm_mul_epu32(T1, T15); + v11 = H3; + v11 = _mm_mul_epu32(v11, T14); + T2 = H4; + T2 = _mm_mul_epu32(T2, T14); + T0 = _mm_add_epi64(T0, v01); + T15 = S24; + v02 = H2; + v02 = _mm_mul_epu32(v02, T14); + T3 = H4; + T3 = _mm_mul_epu32(T3, T15); + T1 = _mm_add_epi64(T1, v11); + v03 = H1; + v03 = _mm_mul_epu32(v03, T15); + v12 = H2; + v12 = _mm_mul_epu32(v12, T15); + T0 = _mm_add_epi64(T0, v02); + T14 = R20; + v21 = H3; + v21 = _mm_mul_epu32(v21, T15); + v31 = H3; + v31 = _mm_mul_epu32(v31, T14); + T0 = _mm_add_epi64(T0, v03); + T4 = H4; + T4 = _mm_mul_epu32(T4, T14); + T1 = _mm_add_epi64(T1, v12); + v04 = H0; + v04 = _mm_mul_epu32(v04, T14); + T2 = _mm_add_epi64(T2, v21); + v13 = H1; + v13 = _mm_mul_epu32(v13, T14); + T3 = _mm_add_epi64(T3, v31); + T15 = R21; + v22 = H2; + v22 = _mm_mul_epu32(v22, T14); + v32 = H2; + v32 = _mm_mul_epu32(v32, T15); + T0 = _mm_add_epi64(T0, v04); + v41 = H3; + v41 = _mm_mul_epu32(v41, T15); + T1 = _mm_add_epi64(T1, v13); + v14 = H0; + v14 = _mm_mul_epu32(v14, T15); + T2 = _mm_add_epi64(T2, v22); + T14 = R22; + v23 = H1; + v23 = _mm_mul_epu32(v23, T15); + T3 = _mm_add_epi64(T3, v32); + v33 = H1; + v33 = _mm_mul_epu32(v33, T14); + T4 = _mm_add_epi64(T4, v41); + v42 = H2; + v42 = _mm_mul_epu32(v42, T14); + T1 = _mm_add_epi64(T1, v14); + T15 = R23; + v24 = H0; + v24 = _mm_mul_epu32(v24, T14); + T2 = _mm_add_epi64(T2, v23); + v34 = H0; + v34 = _mm_mul_epu32(v34, T15); + T3 = _mm_add_epi64(T3, v33); + v43 = H1; + v43 = _mm_mul_epu32(v43, T15); + T4 = _mm_add_epi64(T4, v42); + v44 = H0; + v44 = _mm_mul_epu32(v44, R24); + T2 = _mm_add_epi64(T2, v24); + T3 = _mm_add_epi64(T3, v34); + T4 = _mm_add_epi64(T4, v43); + T4 = _mm_add_epi64(T4, v44); + + /* H += [Mx,My] */ + if (m) { + T5 = _mm_loadu_si128((const xmmi *) (const void *) (m + 0)); + T6 = _mm_loadu_si128((const xmmi *) (const void *) (m + 16)); + T7 = _mm_unpacklo_epi32(T5, T6); + T8 = _mm_unpackhi_epi32(T5, T6); + M0 = _mm_unpacklo_epi32(T7, _mm_setzero_si128()); + M1 = _mm_unpackhi_epi32(T7, _mm_setzero_si128()); + M2 = _mm_unpacklo_epi32(T8, _mm_setzero_si128()); + M3 = _mm_unpackhi_epi32(T8, _mm_setzero_si128()); + M1 = _mm_slli_epi64(M1, 6); + M2 = _mm_slli_epi64(M2, 12); + M3 = _mm_slli_epi64(M3, 18); + T0 = _mm_add_epi64(T0, M0); + T1 = _mm_add_epi64(T1, M1); + T2 = _mm_add_epi64(T2, M2); + T3 = _mm_add_epi64(T3, M3); + T4 = _mm_add_epi64(T4, HIBIT); + } + + /* reduce */ + C1 = _mm_srli_epi64(T0, 26); + C2 = _mm_srli_epi64(T3, 26); + T0 = _mm_and_si128(T0, MMASK); + T3 = _mm_and_si128(T3, MMASK); + T1 = _mm_add_epi64(T1, C1); + T4 = _mm_add_epi64(T4, C2); + C1 = _mm_srli_epi64(T1, 26); + C2 = _mm_srli_epi64(T4, 26); + T1 = _mm_and_si128(T1, MMASK); + T4 = _mm_and_si128(T4, MMASK); + T2 = _mm_add_epi64(T2, C1); + T0 = _mm_add_epi64(T0, _mm_mul_epu32(C2, FIVE)); + C1 = _mm_srli_epi64(T2, 26); + C2 = _mm_srli_epi64(T0, 26); + T2 = _mm_and_si128(T2, MMASK); + T0 = _mm_and_si128(T0, MMASK); + T3 = _mm_add_epi64(T3, C1); + T1 = _mm_add_epi64(T1, C2); + C1 = _mm_srli_epi64(T3, 26); + T3 = _mm_and_si128(T3, MMASK); + T4 = _mm_add_epi64(T4, C1); + + /* H = (H*[r^2,r^2] + [Mx,My]) */ + H0 = T0; + H1 = T1; + H2 = T2; + H3 = T3; + H4 = T4; + } + + if (m) { + T0 = _mm_shuffle_epi32(H0, _MM_SHUFFLE(0, 0, 2, 0)); + T1 = _mm_shuffle_epi32(H1, _MM_SHUFFLE(0, 0, 2, 0)); + T2 = _mm_shuffle_epi32(H2, _MM_SHUFFLE(0, 0, 2, 0)); + T3 = _mm_shuffle_epi32(H3, _MM_SHUFFLE(0, 0, 2, 0)); + T4 = _mm_shuffle_epi32(H4, _MM_SHUFFLE(0, 0, 2, 0)); + T0 = _mm_unpacklo_epi64(T0, T1); + T1 = _mm_unpacklo_epi64(T2, T3); + _mm_storeu_si128((xmmi *) (void *) &st->H.hh[0], T0); + _mm_storeu_si128((xmmi *) (void *) &st->H.hh[4], T1); + _mm_storel_epi64((xmmi *) (void *) &st->H.hh[8], T4); + } else { + uint32_t t0, t1, t2, t3, t4, b; + uint64_t h0, h1, h2, g0, g1, g2, c, nc; + + /* H = H[0]+H[1] */ + T0 = H0; + T1 = H1; + T2 = H2; + T3 = H3; + T4 = H4; + + T0 = _mm_add_epi64(T0, _mm_srli_si128(T0, 8)); + T1 = _mm_add_epi64(T1, _mm_srli_si128(T1, 8)); + T2 = _mm_add_epi64(T2, _mm_srli_si128(T2, 8)); + T3 = _mm_add_epi64(T3, _mm_srli_si128(T3, 8)); + T4 = _mm_add_epi64(T4, _mm_srli_si128(T4, 8)); + + t0 = _mm_cvtsi128_si32(T0); + b = (t0 >> 26); + t0 &= 0x3ffffff; + t1 = _mm_cvtsi128_si32(T1) + b; + b = (t1 >> 26); + t1 &= 0x3ffffff; + t2 = _mm_cvtsi128_si32(T2) + b; + b = (t2 >> 26); + t2 &= 0x3ffffff; + t3 = _mm_cvtsi128_si32(T3) + b; + b = (t3 >> 26); + t3 &= 0x3ffffff; + t4 = _mm_cvtsi128_si32(T4) + b; + + /* everything except t4 is in range, so this is all safe */ + h0 = (((uint64_t) t0) | ((uint64_t) t1 << 26)) & 0xfffffffffffull; + h1 = (((uint64_t) t1 >> 18) | ((uint64_t) t2 << 8) | + ((uint64_t) t3 << 34)) & + 0xfffffffffffull; + h2 = (((uint64_t) t3 >> 10) | ((uint64_t) t4 << 16)); + + c = (h2 >> 42); + h2 &= 0x3ffffffffff; + h0 += c * 5; + c = (h0 >> 44); + h0 &= 0xfffffffffff; + h1 += c; + c = (h1 >> 44); + h1 &= 0xfffffffffff; + h2 += c; + c = (h2 >> 42); + h2 &= 0x3ffffffffff; + h0 += c * 5; + c = (h0 >> 44); + h0 &= 0xfffffffffff; + h1 += c; + + g0 = h0 + 5; + c = (g0 >> 44); + g0 &= 0xfffffffffff; + g1 = h1 + c; + c = (g1 >> 44); + g1 &= 0xfffffffffff; + g2 = h2 + c - ((uint64_t) 1 << 42); + + c = (g2 >> 63) - 1; + nc = ~c; + h0 = (h0 & nc) | (g0 & c); + h1 = (h1 & nc) | (g1 & c); + h2 = (h2 & nc) | (g2 & c); + + st->H.h[0] = h0; + st->H.h[1] = h1; + st->H.h[2] = h2; + } +} + +static void +poly1305_update(poly1305_state_internal_t *st, const unsigned char *m, + unsigned long long bytes) +{ + unsigned long long i; + + /* handle leftover */ + if (st->leftover) { + unsigned long long want = (poly1305_block_size - st->leftover); + + if (want > bytes) { + want = bytes; + } + for (i = 0; i < want; i++) { + st->buffer[st->leftover + i] = m[i]; + } + bytes -= want; + m += want; + st->leftover += want; + if (st->leftover < poly1305_block_size) { + return; + } + poly1305_blocks(st, st->buffer, poly1305_block_size); + st->leftover = 0; + } + + /* process full blocks */ + if (bytes >= poly1305_block_size) { + unsigned long long want = (bytes & ~(poly1305_block_size - 1)); + + poly1305_blocks(st, m, want); + m += want; + bytes -= want; + } + + /* store leftover */ + if (bytes) { + for (i = 0; i < bytes; i++) { + st->buffer[st->leftover + i] = m[i]; + } + st->leftover += bytes; + } +} + +static POLY1305_NOINLINE void +poly1305_finish_ext(poly1305_state_internal_t *st, const unsigned char *m, + unsigned long long leftover, unsigned char mac[16]) +{ + uint64_t h0, h1, h2; + + if (leftover) { + CRYPTO_ALIGN(16) unsigned char final[32] = { 0 }; + + poly1305_block_copy31(final, m, leftover); + if (leftover != 16) { + final[leftover] = 1; + } + st->flags |= + (leftover >= 16) ? poly1305_final_shift8 : poly1305_final_shift16; + poly1305_blocks(st, final, 32); + } + + if (st->flags & poly1305_started) { + /* finalize, H *= [r^2,r], or H *= [r,1] */ + if (!leftover || (leftover > 16)) { + st->flags |= poly1305_final_r2_r; + } else { + st->flags |= poly1305_final_r_1; + } + poly1305_blocks(st, NULL, 32); + } + + h0 = st->H.h[0]; + h1 = st->H.h[1]; + h2 = st->H.h[2]; + + /* pad */ + h0 = ((h0) | (h1 << 44)); + h1 = ((h1 >> 20) | (h2 << 24)); +#ifdef HAVE_AMD64_ASM + __asm__ __volatile__( + "addq %2, %0 ;\n" + "adcq %3, %1 ;\n" + : "+r"(h0), "+r"(h1) + : "r"(st->pad[0]), "r"(st->pad[1]) + : "flags", "cc"); +#else + { + uint128_t h; + + memcpy(&h, &st->pad[0], 16); + h += ((uint128_t) h1 << 64) | h0; + h0 = (uint64_t) h; + h1 = (uint64_t)(h >> 64); + } +#endif + _mm_storeu_si128((xmmi *) (void *) st + 0, _mm_setzero_si128()); + _mm_storeu_si128((xmmi *) (void *) st + 1, _mm_setzero_si128()); + _mm_storeu_si128((xmmi *) (void *) st + 2, _mm_setzero_si128()); + _mm_storeu_si128((xmmi *) (void *) st + 3, _mm_setzero_si128()); + _mm_storeu_si128((xmmi *) (void *) st + 4, _mm_setzero_si128()); + _mm_storeu_si128((xmmi *) (void *) st + 5, _mm_setzero_si128()); + _mm_storeu_si128((xmmi *) (void *) st + 6, _mm_setzero_si128()); + _mm_storeu_si128((xmmi *) (void *) st + 7, _mm_setzero_si128()); + + memcpy(&mac[0], &h0, 8); + memcpy(&mac[8], &h1, 8); + + sodium_memzero((void *) st, sizeof *st); +} + +static void +poly1305_finish(poly1305_state_internal_t *st, unsigned char mac[16]) +{ + poly1305_finish_ext(st, st->buffer, st->leftover, mac); +} + +static int +crypto_onetimeauth_poly1305_sse2_init(crypto_onetimeauth_poly1305_state *state, + const unsigned char *key) +{ + COMPILER_ASSERT(sizeof(crypto_onetimeauth_poly1305_state) >= + sizeof(poly1305_state_internal_t)); + poly1305_init_ext((poly1305_state_internal_t *) (void *) state, key, 0U); + + return 0; +} + +static int +crypto_onetimeauth_poly1305_sse2_update( + crypto_onetimeauth_poly1305_state *state, const unsigned char *in, + unsigned long long inlen) +{ + poly1305_update((poly1305_state_internal_t *) (void *) state, in, inlen); + + return 0; +} + +static int +crypto_onetimeauth_poly1305_sse2_final(crypto_onetimeauth_poly1305_state *state, + unsigned char *out) +{ + poly1305_finish((poly1305_state_internal_t *) (void *) state, out); + + return 0; +} + +static int +crypto_onetimeauth_poly1305_sse2(unsigned char *out, const unsigned char *m, + unsigned long long inlen, + const unsigned char *key) +{ + CRYPTO_ALIGN(64) poly1305_state_internal_t st; + unsigned long long blocks; + + poly1305_init_ext(&st, key, inlen); + blocks = inlen & ~31; + if (blocks > 0) { + poly1305_blocks(&st, m, blocks); + m += blocks; + inlen -= blocks; + } + poly1305_finish_ext(&st, m, inlen, out); + + return 0; +} + +static int +crypto_onetimeauth_poly1305_sse2_verify(const unsigned char *h, + const unsigned char *in, + unsigned long long inlen, + const unsigned char *k) +{ + unsigned char correct[16]; + + crypto_onetimeauth_poly1305_sse2(correct, in, inlen, k); + + return crypto_verify_16(h, correct); +} + +struct crypto_onetimeauth_poly1305_implementation + crypto_onetimeauth_poly1305_sse2_implementation = { + SODIUM_C99(.onetimeauth =) crypto_onetimeauth_poly1305_sse2, + SODIUM_C99(.onetimeauth_verify =) + crypto_onetimeauth_poly1305_sse2_verify, + SODIUM_C99(.onetimeauth_init =) crypto_onetimeauth_poly1305_sse2_init, + SODIUM_C99(.onetimeauth_update =) + crypto_onetimeauth_poly1305_sse2_update, + SODIUM_C99(.onetimeauth_final =) crypto_onetimeauth_poly1305_sse2_final + }; + +#endif diff --git a/libs/libsodium/src/crypto_onetimeauth/poly1305/sse2/poly1305_sse2.h b/libs/libsodium/src/crypto_onetimeauth/poly1305/sse2/poly1305_sse2.h new file mode 100644 index 0000000000..9177cad487 --- /dev/null +++ b/libs/libsodium/src/crypto_onetimeauth/poly1305/sse2/poly1305_sse2.h @@ -0,0 +1,12 @@ +#ifndef poly1305_sse2_H +#define poly1305_sse2_H + +#include <stddef.h> + +#include "../onetimeauth_poly1305.h" +#include "crypto_onetimeauth_poly1305.h" + +extern struct crypto_onetimeauth_poly1305_implementation + crypto_onetimeauth_poly1305_sse2_implementation; + +#endif /* poly1305_sse2_H */ diff --git a/libs/libsodium/src/crypto_pwhash/argon2/argon2-core.c b/libs/libsodium/src/crypto_pwhash/argon2/argon2-core.c new file mode 100644 index 0000000000..b52b04d36d --- /dev/null +++ b/libs/libsodium/src/crypto_pwhash/argon2/argon2-core.c @@ -0,0 +1,549 @@ +/* + * Argon2 source code package + * + * Written by Daniel Dinu and Dmitry Khovratovich, 2015 + * + * This work is licensed under a Creative Commons CC0 1.0 License/Waiver. + * + * You should have received a copy of the CC0 Public Domain Dedication along + * with + * this software. If not, see + * <http://creativecommons.org/publicdomain/zero/1.0/>. + */ + +#include <errno.h> +#include <stdint.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#include <sys/types.h> +#ifdef HAVE_SYS_MMAN_H +# include <sys/mman.h> +#endif + +#include "crypto_generichash_blake2b.h" +#include "private/common.h" +#include "private/implementations.h" +#include "runtime.h" +#include "utils.h" + +#include "argon2-core.h" +#include "blake2b-long.h" + +#if !defined(MAP_ANON) && defined(MAP_ANONYMOUS) +# define MAP_ANON MAP_ANONYMOUS +#endif +#ifndef MAP_NOCORE +# define MAP_NOCORE 0 +#endif +#ifndef MAP_POPULATE +# define MAP_POPULATE 0 +#endif + +static fill_segment_fn fill_segment = fill_segment_ref; + +static void +load_block(block *dst, const void *input) +{ + unsigned i; + for (i = 0; i < ARGON2_QWORDS_IN_BLOCK; ++i) { + dst->v[i] = LOAD64_LE((const uint8_t *) input + i * sizeof(dst->v[i])); + } +} + +static void +store_block(void *output, const block *src) +{ + unsigned i; + for (i = 0; i < ARGON2_QWORDS_IN_BLOCK; ++i) { + STORE64_LE((uint8_t *) output + i * sizeof(src->v[i]), src->v[i]); + } +} + +/***************Memory allocators*****************/ +/* Allocates memory to the given pointer + * @param memory pointer to the pointer to the memory + * @param m_cost number of blocks to allocate in the memory + * @return ARGON2_OK if @memory is a valid pointer and memory is allocated + */ +static int allocate_memory(block_region **memory, uint32_t m_cost); + +static int +allocate_memory(block_region **region, uint32_t m_cost) +{ + void * base; + block *memory; + size_t memory_size; + + if (region == NULL) { + return ARGON2_MEMORY_ALLOCATION_ERROR; /* LCOV_EXCL_LINE */ + } + memory_size = sizeof(block) * m_cost; + if (m_cost == 0 || + memory_size / m_cost != + sizeof(block)) { /*1. Check for multiplication overflow*/ + return ARGON2_MEMORY_ALLOCATION_ERROR; /* LCOV_EXCL_LINE */ + } + *region = (block_region *) malloc( + sizeof(block_region)); /*2. Try to allocate region*/ + if (!*region) { + return ARGON2_MEMORY_ALLOCATION_ERROR; /* LCOV_EXCL_LINE */ + } + (*region)->base = (*region)->memory = NULL; + +#if defined(MAP_ANON) && defined(HAVE_MMAP) + if ((base = mmap(NULL, memory_size, PROT_READ | PROT_WRITE, + MAP_ANON | MAP_PRIVATE | MAP_NOCORE | MAP_POPULATE, + -1, 0)) == MAP_FAILED) { + base = NULL; /* LCOV_EXCL_LINE */ + } /* LCOV_EXCL_LINE */ + memcpy(&memory, &base, sizeof memory); +#elif defined(HAVE_POSIX_MEMALIGN) + if ((errno = posix_memalign((void **) &base, 64, memory_size)) != 0) { + base = NULL; + } + memcpy(&memory, &base, sizeof memory); +#else + memory = NULL; + if (memory_size + 63 < memory_size) { + base = NULL; + errno = ENOMEM; + } else if ((base = malloc(memory_size + 63)) != NULL) { + uint8_t *aligned = ((uint8_t *) base) + 63; + aligned -= (uintptr_t) aligned & 63; + memcpy(&memory, &aligned, sizeof memory); + } +#endif + if (base == NULL) { + return ARGON2_MEMORY_ALLOCATION_ERROR; /* LCOV_EXCL_LINE */ + } + (*region)->base = base; + (*region)->memory = memory; + (*region)->size = memory_size; + + return ARGON2_OK; +} + +/*********Memory functions*/ + +/* Clears memory + * @param instance pointer to the current instance + * @param clear_memory indicates if we clear the memory with zeros. + */ +static void clear_memory(argon2_instance_t *instance, int clear); + +static void +clear_memory(argon2_instance_t *instance, int clear) +{ + /* LCOV_EXCL_START */ + if (clear) { + if (instance->region != NULL) { + sodium_memzero(instance->region->memory, + sizeof(block) * instance->memory_blocks); + } + if (instance->pseudo_rands != NULL) { + sodium_memzero(instance->pseudo_rands, + sizeof(uint64_t) * instance->segment_length); + } + } + /* LCOV_EXCL_STOP */ +} + +/* Deallocates memory + * @param memory pointer to the blocks + */ +static void free_memory(block_region *memory); + +static void +free_memory(block_region *region) +{ + if (region && region->base) { +#if defined(MAP_ANON) && defined(HAVE_MMAP) + if (munmap(region->base, region->size)) { + return; /* LCOV_EXCL_LINE */ + } +#else + free(region->base); +#endif + } + free(region); +} + +void +free_instance(argon2_instance_t *instance, int flags) +{ + /* Clear memory */ + clear_memory(instance, flags & ARGON2_FLAG_CLEAR_MEMORY); + + /* Deallocate the memory */ + free(instance->pseudo_rands); + instance->pseudo_rands = NULL; + free_memory(instance->region); + instance->region = NULL; +} + +void +finalize(const argon2_context *context, argon2_instance_t *instance) +{ + if (context != NULL && instance != NULL) { + block blockhash; + uint32_t l; + + copy_block(&blockhash, + instance->region->memory + instance->lane_length - 1); + + /* XOR the last blocks */ + for (l = 1; l < instance->lanes; ++l) { + uint32_t last_block_in_lane = + l * instance->lane_length + (instance->lane_length - 1); + xor_block(&blockhash, + instance->region->memory + last_block_in_lane); + } + + /* Hash the result */ + { + uint8_t blockhash_bytes[ARGON2_BLOCK_SIZE]; + store_block(blockhash_bytes, &blockhash); + blake2b_long(context->out, context->outlen, blockhash_bytes, + ARGON2_BLOCK_SIZE); + sodium_memzero(blockhash.v, + ARGON2_BLOCK_SIZE); /* clear blockhash */ + sodium_memzero(blockhash_bytes, + ARGON2_BLOCK_SIZE); /* clear blockhash_bytes */ + } + + free_instance(instance, context->flags); + } +} + +void +fill_memory_blocks(argon2_instance_t *instance, uint32_t pass) +{ + argon2_position_t position; + uint32_t l; + uint32_t s; + + if (instance == NULL || instance->lanes == 0) { + return; /* LCOV_EXCL_LINE */ + } + + position.pass = pass; + for (s = 0; s < ARGON2_SYNC_POINTS; ++s) { + position.slice = (uint8_t) s; + for (l = 0; l < instance->lanes; ++l) { + position.lane = l; + position.index = 0; + fill_segment(instance, position); + } + } +} + +int +validate_inputs(const argon2_context *context) +{ + /* LCOV_EXCL_START */ + if (NULL == context) { + return ARGON2_INCORRECT_PARAMETER; + } + + if (NULL == context->out) { + return ARGON2_OUTPUT_PTR_NULL; + } + + /* Validate output length */ + if (ARGON2_MIN_OUTLEN > context->outlen) { + return ARGON2_OUTPUT_TOO_SHORT; + } + + if (ARGON2_MAX_OUTLEN < context->outlen) { + return ARGON2_OUTPUT_TOO_LONG; + } + + /* Validate password (required param) */ + if (NULL == context->pwd) { + if (0 != context->pwdlen) { + return ARGON2_PWD_PTR_MISMATCH; + } + } + + if (ARGON2_MIN_PWD_LENGTH > context->pwdlen) { + return ARGON2_PWD_TOO_SHORT; + } + + if (ARGON2_MAX_PWD_LENGTH < context->pwdlen) { + return ARGON2_PWD_TOO_LONG; + } + + /* Validate salt (required param) */ + if (NULL == context->salt) { + if (0 != context->saltlen) { + return ARGON2_SALT_PTR_MISMATCH; + } + } + + if (ARGON2_MIN_SALT_LENGTH > context->saltlen) { + return ARGON2_SALT_TOO_SHORT; + } + + if (ARGON2_MAX_SALT_LENGTH < context->saltlen) { + return ARGON2_SALT_TOO_LONG; + } + + /* Validate secret (optional param) */ + if (NULL == context->secret) { + if (0 != context->secretlen) { + return ARGON2_SECRET_PTR_MISMATCH; + } + } else { + if (ARGON2_MIN_SECRET > context->secretlen) { + return ARGON2_SECRET_TOO_SHORT; + } + + if (ARGON2_MAX_SECRET < context->secretlen) { + return ARGON2_SECRET_TOO_LONG; + } + } + + /* Validate associated data (optional param) */ + if (NULL == context->ad) { + if (0 != context->adlen) { + return ARGON2_AD_PTR_MISMATCH; + } + } else { + if (ARGON2_MIN_AD_LENGTH > context->adlen) { + return ARGON2_AD_TOO_SHORT; + } + + if (ARGON2_MAX_AD_LENGTH < context->adlen) { + return ARGON2_AD_TOO_LONG; + } + } + + /* Validate memory cost */ + if (ARGON2_MIN_MEMORY > context->m_cost) { + return ARGON2_MEMORY_TOO_LITTLE; + } + + if (ARGON2_MAX_MEMORY < context->m_cost) { + return ARGON2_MEMORY_TOO_MUCH; + } + + if (context->m_cost < 8 * context->lanes) { + return ARGON2_MEMORY_TOO_LITTLE; + } + + /* Validate time cost */ + if (ARGON2_MIN_TIME > context->t_cost) { + return ARGON2_TIME_TOO_SMALL; + } + + if (ARGON2_MAX_TIME < context->t_cost) { + return ARGON2_TIME_TOO_LARGE; + } + + /* Validate lanes */ + if (ARGON2_MIN_LANES > context->lanes) { + return ARGON2_LANES_TOO_FEW; + } + + if (ARGON2_MAX_LANES < context->lanes) { + return ARGON2_LANES_TOO_MANY; + } + + /* Validate threads */ + if (ARGON2_MIN_THREADS > context->threads) { + return ARGON2_THREADS_TOO_FEW; + } + + if (ARGON2_MAX_THREADS < context->threads) { + return ARGON2_THREADS_TOO_MANY; + } + /* LCOV_EXCL_STOP */ + + return ARGON2_OK; +} + +void +fill_first_blocks(uint8_t *blockhash, const argon2_instance_t *instance) +{ + uint32_t l; + /* Make the first and second block in each lane as G(H0||i||0) or + G(H0||i||1) */ + uint8_t blockhash_bytes[ARGON2_BLOCK_SIZE]; + for (l = 0; l < instance->lanes; ++l) { + STORE32_LE(blockhash + ARGON2_PREHASH_DIGEST_LENGTH, 0); + STORE32_LE(blockhash + ARGON2_PREHASH_DIGEST_LENGTH + 4, l); + blake2b_long(blockhash_bytes, ARGON2_BLOCK_SIZE, blockhash, + ARGON2_PREHASH_SEED_LENGTH); + load_block(&instance->region->memory[l * instance->lane_length + 0], + blockhash_bytes); + + STORE32_LE(blockhash + ARGON2_PREHASH_DIGEST_LENGTH, 1); + blake2b_long(blockhash_bytes, ARGON2_BLOCK_SIZE, blockhash, + ARGON2_PREHASH_SEED_LENGTH); + load_block(&instance->region->memory[l * instance->lane_length + 1], + blockhash_bytes); + } + sodium_memzero(blockhash_bytes, ARGON2_BLOCK_SIZE); +} + +void +initial_hash(uint8_t *blockhash, argon2_context *context, argon2_type type) +{ + crypto_generichash_blake2b_state BlakeHash; + uint8_t value[4U /* sizeof(uint32_t) */]; + + if (NULL == context || NULL == blockhash) { + return; /* LCOV_EXCL_LINE */ + } + + crypto_generichash_blake2b_init(&BlakeHash, NULL, 0U, + ARGON2_PREHASH_DIGEST_LENGTH); + + STORE32_LE(value, context->lanes); + crypto_generichash_blake2b_update(&BlakeHash, value, sizeof(value)); + + STORE32_LE(value, context->outlen); + crypto_generichash_blake2b_update(&BlakeHash, value, sizeof(value)); + + STORE32_LE(value, context->m_cost); + crypto_generichash_blake2b_update(&BlakeHash, value, sizeof(value)); + + STORE32_LE(value, context->t_cost); + crypto_generichash_blake2b_update(&BlakeHash, value, sizeof(value)); + + STORE32_LE(value, ARGON2_VERSION_NUMBER); + crypto_generichash_blake2b_update(&BlakeHash, value, sizeof(value)); + + STORE32_LE(value, (uint32_t) type); + crypto_generichash_blake2b_update(&BlakeHash, value, sizeof(value)); + + STORE32_LE(value, context->pwdlen); + crypto_generichash_blake2b_update(&BlakeHash, value, sizeof(value)); + + if (context->pwd != NULL) { + crypto_generichash_blake2b_update( + &BlakeHash, (const uint8_t *) context->pwd, context->pwdlen); + + /* LCOV_EXCL_START */ + if (context->flags & ARGON2_FLAG_CLEAR_PASSWORD) { + sodium_memzero(context->pwd, context->pwdlen); + context->pwdlen = 0; + } + /* LCOV_EXCL_STOP */ + } + + STORE32_LE(value, context->saltlen); + crypto_generichash_blake2b_update(&BlakeHash, value, sizeof(value)); + + if (context->salt != NULL) { + crypto_generichash_blake2b_update( + &BlakeHash, (const uint8_t *) context->salt, context->saltlen); + } + + STORE32_LE(value, context->secretlen); + crypto_generichash_blake2b_update(&BlakeHash, value, sizeof(value)); + + /* LCOV_EXCL_START */ + if (context->secret != NULL) { + crypto_generichash_blake2b_update( + &BlakeHash, (const uint8_t *) context->secret, context->secretlen); + + if (context->flags & ARGON2_FLAG_CLEAR_SECRET) { + sodium_memzero(context->secret, context->secretlen); + context->secretlen = 0; + } + } + /* LCOV_EXCL_STOP */ + + STORE32_LE(value, context->adlen); + crypto_generichash_blake2b_update(&BlakeHash, value, sizeof(value)); + + /* LCOV_EXCL_START */ + if (context->ad != NULL) { + crypto_generichash_blake2b_update( + &BlakeHash, (const uint8_t *) context->ad, context->adlen); + } + /* LCOV_EXCL_STOP */ + + crypto_generichash_blake2b_final(&BlakeHash, blockhash, + ARGON2_PREHASH_DIGEST_LENGTH); +} + +int +initialize(argon2_instance_t *instance, argon2_context *context) +{ + uint8_t blockhash[ARGON2_PREHASH_SEED_LENGTH]; + int result = ARGON2_OK; + + if (instance == NULL || context == NULL) { + return ARGON2_INCORRECT_PARAMETER; + } + + /* 1. Memory allocation */ + + if ((instance->pseudo_rands = (uint64_t *) + malloc(sizeof(uint64_t) * instance->segment_length)) == NULL) { + return ARGON2_MEMORY_ALLOCATION_ERROR; + } + + result = allocate_memory(&(instance->region), instance->memory_blocks); + if (ARGON2_OK != result) { + free_instance(instance, context->flags); + return result; + } + + /* 2. Initial hashing */ + /* H_0 + 8 extra bytes to produce the first blocks */ + /* uint8_t blockhash[ARGON2_PREHASH_SEED_LENGTH]; */ + /* Hashing all inputs */ + initial_hash(blockhash, context, instance->type); + /* Zeroing 8 extra bytes */ + sodium_memzero(blockhash + ARGON2_PREHASH_DIGEST_LENGTH, + ARGON2_PREHASH_SEED_LENGTH - ARGON2_PREHASH_DIGEST_LENGTH); + + /* 3. Creating first blocks, we always have at least two blocks in a slice + */ + fill_first_blocks(blockhash, instance); + /* Clearing the hash */ + sodium_memzero(blockhash, ARGON2_PREHASH_SEED_LENGTH); + + return ARGON2_OK; +} + +int +argon2_pick_best_implementation(void) +{ +/* LCOV_EXCL_START */ +#if defined(HAVE_AVX512FINTRIN_H) && defined(HAVE_AVX2INTRIN_H) && \ + defined(HAVE_TMMINTRIN_H) && defined(HAVE_SMMINTRIN_H) + if (sodium_runtime_has_avx512f()) { + fill_segment = fill_segment_avx512f; + return 0; + } +#endif +#if defined(HAVE_AVX2INTRIN_H) && defined(HAVE_TMMINTRIN_H) && \ + defined(HAVE_SMMINTRIN_H) + if (sodium_runtime_has_avx2()) { + fill_segment = fill_segment_avx2; + return 0; + } +#endif +#if defined(HAVE_EMMINTRIN_H) && defined(HAVE_TMMINTRIN_H) + if (sodium_runtime_has_ssse3()) { + fill_segment = fill_segment_ssse3; + return 0; + } +#endif + fill_segment = fill_segment_ref; + + return 0; + /* LCOV_EXCL_STOP */ +} + +int +_crypto_pwhash_argon2_pick_best_implementation(void) +{ + return argon2_pick_best_implementation(); +} diff --git a/libs/libsodium/src/crypto_pwhash/argon2/argon2-core.h b/libs/libsodium/src/crypto_pwhash/argon2/argon2-core.h new file mode 100644 index 0000000000..caab103891 --- /dev/null +++ b/libs/libsodium/src/crypto_pwhash/argon2/argon2-core.h @@ -0,0 +1,297 @@ +/* + * Argon2 source code package + * + * Written by Daniel Dinu and Dmitry Khovratovich, 2015 + * + * This work is licensed under a Creative Commons CC0 1.0 License/Waiver. + * + * You should have received a copy of the CC0 Public Domain Dedication along + * with + * this software. If not, see + * <http://creativecommons.org/publicdomain/zero/1.0/>. + */ + +#ifndef argon2_core_H +#define argon2_core_H + +#include <string.h> + +#include "argon2.h" + +/*************************Argon2 internal + * constants**************************************************/ + +enum argon2_ctx_constants { + /* Version of the algorithm */ + ARGON2_VERSION_NUMBER = 0x13, + + /* Memory block size in bytes */ + ARGON2_BLOCK_SIZE = 1024, + ARGON2_QWORDS_IN_BLOCK = ARGON2_BLOCK_SIZE / 8, + ARGON2_OWORDS_IN_BLOCK = ARGON2_BLOCK_SIZE / 16, + ARGON2_HWORDS_IN_BLOCK = ARGON2_BLOCK_SIZE / 32, + ARGON2_512BIT_WORDS_IN_BLOCK = ARGON2_BLOCK_SIZE / 64, + + /* Number of pseudo-random values generated by one call to Blake in Argon2i + to + generate reference block positions */ + ARGON2_ADDRESSES_IN_BLOCK = 128, + + /* Pre-hashing digest length and its extension*/ + ARGON2_PREHASH_DIGEST_LENGTH = 64, + ARGON2_PREHASH_SEED_LENGTH = 72 +}; + +/*************************Argon2 internal data + * types**************************************************/ + +/* + * Structure for the (1KB) memory block implemented as 128 64-bit words. + * Memory blocks can be copied, XORed. Internal words can be accessed by [] (no + * bounds checking). + */ +typedef struct block_ { + uint64_t v[ARGON2_QWORDS_IN_BLOCK]; +} block; + +typedef struct block_region_ { + void * base; + block *memory; + size_t size; +} block_region; + +/*****************Functions that work with the block******************/ + +/* Initialize each byte of the block with @in */ +static inline void +init_block_value(block *b, uint8_t in) +{ + memset(b->v, in, sizeof(b->v)); +} + +/* Copy block @src to block @dst */ +static inline void +copy_block(block *dst, const block *src) +{ + memcpy(dst->v, src->v, sizeof(uint64_t) * ARGON2_QWORDS_IN_BLOCK); +} + +/* XOR @src onto @dst bytewise */ +static inline void +xor_block(block *dst, const block *src) +{ + int i; + for (i = 0; i < ARGON2_QWORDS_IN_BLOCK; ++i) { + dst->v[i] ^= src->v[i]; + } +} + +/* + * Argon2 instance: memory pointer, number of passes, amount of memory, type, + * and derived values. + * Used to evaluate the number and location of blocks to construct in each + * thread + */ +typedef struct Argon2_instance_t { + block_region *region; /* Memory region pointer */ + uint64_t *pseudo_rands; + uint32_t passes; /* Number of passes */ + uint32_t current_pass; + uint32_t memory_blocks; /* Number of blocks in memory */ + uint32_t segment_length; + uint32_t lane_length; + uint32_t lanes; + uint32_t threads; + argon2_type type; + int print_internals; /* whether to print the memory blocks */ +} argon2_instance_t; + +/* + * Argon2 position: where we construct the block right now. Used to distribute + * work between threads. + */ +typedef struct Argon2_position_t { + uint32_t pass; + uint32_t lane; + uint8_t slice; + uint32_t index; +} argon2_position_t; + +/*Struct that holds the inputs for thread handling FillSegment*/ +typedef struct Argon2_thread_data { + argon2_instance_t *instance_ptr; + argon2_position_t pos; +} argon2_thread_data; + +/*************************Argon2 core + * functions**************************************************/ + +/* + * Computes absolute position of reference block in the lane following a skewed + * distribution and using a pseudo-random value as input + * @param instance Pointer to the current instance + * @param position Pointer to the current position + * @param pseudo_rand 32-bit pseudo-random value used to determine the position + * @param same_lane Indicates if the block will be taken from the current lane. + * If so we can reference the current segment + * @pre All pointers must be valid + */ +static uint32_t index_alpha(const argon2_instance_t *instance, + const argon2_position_t *position, uint32_t pseudo_rand, + int same_lane) +{ + /* + * Pass 0: + * This lane : all already finished segments plus already constructed + * blocks in this segment + * Other lanes : all already finished segments + * Pass 1+: + * This lane : (SYNC_POINTS - 1) last segments plus already constructed + * blocks in this segment + * Other lanes : (SYNC_POINTS - 1) last segments + */ + uint32_t reference_area_size; + uint64_t relative_position; + uint32_t start_position, absolute_position; + + if (position->pass == 0) { + /* First pass */ + if (position->slice == 0) { + /* First slice */ + reference_area_size = + position->index - 1; /* all but the previous */ + } else { + if (same_lane) { + /* The same lane => add current segment */ + reference_area_size = + position->slice * instance->segment_length + + position->index - 1; + } else { + reference_area_size = + position->slice * instance->segment_length + + ((position->index == 0) ? (-1) : 0); + } + } + } else { + /* Second pass */ + if (same_lane) { + reference_area_size = instance->lane_length - + instance->segment_length + position->index - + 1; + } else { + reference_area_size = instance->lane_length - + instance->segment_length + + ((position->index == 0) ? (-1) : 0); + } + } + + /* 1.2.4. Mapping pseudo_rand to 0..<reference_area_size-1> and produce + * relative position */ + relative_position = pseudo_rand; + relative_position = relative_position * relative_position >> 32; + relative_position = reference_area_size - 1 - + (reference_area_size * relative_position >> 32); + + /* 1.2.5 Computing starting position */ + start_position = 0; + + if (position->pass != 0) { + start_position = (position->slice == ARGON2_SYNC_POINTS - 1) + ? 0 + : (position->slice + 1) * instance->segment_length; + } + + /* 1.2.6. Computing absolute position */ + absolute_position = (start_position + relative_position) % + instance->lane_length; /* absolute position */ + return absolute_position; +} + +/* + * Function that validates all inputs against predefined restrictions and return + * an error code + * @param context Pointer to current Argon2 context + * @return ARGON2_OK if everything is all right, otherwise one of error codes + * (all defined in <argon2.h> + */ +int validate_inputs(const argon2_context *context); + +/* + * Hashes all the inputs into @a blockhash[PREHASH_DIGEST_LENGTH], clears + * password and secret if needed + * @param context Pointer to the Argon2 internal structure containing memory + * pointer, and parameters for time and space requirements. + * @param blockhash Buffer for pre-hashing digest + * @param type Argon2 type + * @pre @a blockhash must have at least @a PREHASH_DIGEST_LENGTH bytes + * allocated + */ +void initial_hash(uint8_t *blockhash, argon2_context *context, + argon2_type type); + +/* + * Function creates first 2 blocks per lane + * @param instance Pointer to the current instance + * @param blockhash Pointer to the pre-hashing digest + * @pre blockhash must point to @a PREHASH_SEED_LENGTH allocated values + */ +void fill_first_blocks(uint8_t *blockhash, const argon2_instance_t *instance); + +/* + * Function allocates memory, hashes the inputs with Blake, and creates first + * two blocks. Returns the pointer to the main memory with 2 blocks per lane + * initialized + * @param context Pointer to the Argon2 internal structure containing memory + * pointer, and parameters for time and space requirements. + * @param instance Current Argon2 instance + * @return Zero if successful, -1 if memory failed to allocate. @context->state + * will be modified if successful. + */ +int initialize(argon2_instance_t *instance, argon2_context *context); + +/* + * Deallocates memory. Used on error path. + */ +void free_instance(argon2_instance_t *instance, int flags); + +/* + * XORing the last block of each lane, hashing it, making the tag. Deallocates + * the memory. + * @param context Pointer to current Argon2 context (use only the out parameters + * from it) + * @param instance Pointer to current instance of Argon2 + * @pre instance->state must point to necessary amount of memory + * @pre context->out must point to outlen bytes of memory + * @pre if context->free_cbk is not NULL, it should point to a function that + * deallocates memory + */ +void finalize(const argon2_context *context, argon2_instance_t *instance); + +/* + * Function that fills the segment using previous segments also from other + * threads + * @param instance Pointer to the current instance + * @param position Current position + * @pre all block pointers must be valid + */ +typedef void (*fill_segment_fn)(const argon2_instance_t *instance, + argon2_position_t position); +int argon2_pick_best_implementation(void); +void fill_segment_avx512f(const argon2_instance_t *instance, + argon2_position_t position); +void fill_segment_avx2(const argon2_instance_t *instance, + argon2_position_t position); +void fill_segment_ssse3(const argon2_instance_t *instance, + argon2_position_t position); +void fill_segment_ref(const argon2_instance_t *instance, + argon2_position_t position); + +/* + * Function that fills the entire memory t_cost times based on the first two + * blocks in each lane + * @param instance Pointer to the current instance + * @return Zero if successful, -1 if memory failed to allocate + */ +void fill_memory_blocks(argon2_instance_t *instance, uint32_t pass); + +#endif diff --git a/libs/libsodium/src/crypto_pwhash/argon2/argon2-encoding.c b/libs/libsodium/src/crypto_pwhash/argon2/argon2-encoding.c new file mode 100644 index 0000000000..a08acdda80 --- /dev/null +++ b/libs/libsodium/src/crypto_pwhash/argon2/argon2-encoding.c @@ -0,0 +1,305 @@ +#include "argon2-encoding.h" +#include "argon2-core.h" +#include "utils.h" +#include <limits.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +/* + * Example code for a decoder and encoder of "hash strings", with Argon2 + * parameters. + * + * The code was originally written by Thomas Pornin <pornin@bolet.org>, + * to whom comments and remarks may be sent. It is released under what + * should amount to Public Domain or its closest equivalent; the + * following mantra is supposed to incarnate that fact with all the + * proper legal rituals: + * + * --------------------------------------------------------------------- + * This file is provided under the terms of Creative Commons CC0 1.0 + * Public Domain Dedication. To the extent possible under law, the + * author (Thomas Pornin) has waived all copyright and related or + * neighboring rights to this file. This work is published from: Canada. + * --------------------------------------------------------------------- + * + * Copyright (c) 2015 Thomas Pornin + */ + +/* ==================================================================== */ + +/* + * Decode decimal integer from 'str'; the value is written in '*v'. + * Returned value is a pointer to the next non-decimal character in the + * string. If there is no digit at all, or the value encoding is not + * minimal (extra leading zeros), or the value does not fit in an + * 'unsigned long', then NULL is returned. + */ +static const char * +decode_decimal(const char *str, unsigned long *v) +{ + const char *orig; + unsigned long acc; + + acc = 0; + for (orig = str;; str++) { + int c; + + c = *str; + if (c < '0' || c > '9') { + break; + } + c -= '0'; + if (acc > (ULONG_MAX / 10)) { + return NULL; + } + acc *= 10; + if ((unsigned long) c > (ULONG_MAX - acc)) { + return NULL; + } + acc += (unsigned long) c; + } + if (str == orig || (*orig == '0' && str != (orig + 1))) { + return NULL; + } + *v = acc; + return str; +} + +/* ==================================================================== */ +/* + * Code specific to Argon2. + * + * The code below applies the following format: + * + * $argon2<T>[$v=<num>]$m=<num>,t=<num>,p=<num>$<bin>$<bin> + * + * where <T> is either 'i', <num> is a decimal integer (positive, fits in an + * 'unsigned long') and <bin> is Base64-encoded data (no '=' padding characters, + * no newline or whitespace). + * + * The last two binary chunks (encoded in Base64) are, in that order, + * the salt and the output. Both are required. The binary salt length and the + * output length must be in the allowed ranges defined in argon2.h. + * + * The ctx struct must contain buffers large enough to hold the salt and pwd + * when it is fed into decode_string. + */ + +/* + * Decode an Argon2i hash string into the provided structure 'ctx'. + * Returned value is ARGON2_OK on success. + */ +int +decode_string(argon2_context *ctx, const char *str, argon2_type type) +{ +/* Prefix checking */ +#define CC(prefix) \ + do { \ + size_t cc_len = strlen(prefix); \ + if (strncmp(str, prefix, cc_len) != 0) { \ + return ARGON2_DECODING_FAIL; \ + } \ + str += cc_len; \ + } while ((void) 0, 0) + +/* Optional prefix checking with supplied code */ +#define CC_opt(prefix, code) \ + do { \ + size_t cc_len = strlen(prefix); \ + if (strncmp(str, prefix, cc_len) == 0) { \ + str += cc_len; \ + { \ + code; \ + } \ + } \ + } while ((void) 0, 0) + +/* Decoding prefix into decimal */ +#define DECIMAL(x) \ + do { \ + unsigned long dec_x; \ + str = decode_decimal(str, &dec_x); \ + if (str == NULL) { \ + return ARGON2_DECODING_FAIL; \ + } \ + (x) = dec_x; \ + } while ((void) 0, 0) + +/* Decoding prefix into uint32_t decimal */ +#define DECIMAL_U32(x) \ + do { \ + unsigned long dec_x; \ + str = decode_decimal(str, &dec_x); \ + if (str == NULL || dec_x > UINT32_MAX) { \ + return ARGON2_DECODING_FAIL; \ + } \ + (x) = (uint32_t)dec_x; \ + } while ((void)0, 0) + +/* Decoding base64 into a binary buffer */ +#define BIN(buf, max_len, len) \ + do { \ + size_t bin_len = (max_len); \ + const char *str_end; \ + if (sodium_base642bin((buf), (max_len), str, strlen(str), NULL, \ + &bin_len, &str_end, \ + sodium_base64_VARIANT_ORIGINAL_NO_PADDING) != 0 || \ + bin_len > UINT32_MAX) { \ + return ARGON2_DECODING_FAIL; \ + } \ + (len) = (uint32_t) bin_len; \ + str = str_end; \ + } while ((void) 0, 0) + + size_t maxsaltlen = ctx->saltlen; + size_t maxoutlen = ctx->outlen; + int validation_result; + uint32_t version = 0; + + ctx->saltlen = 0; + ctx->outlen = 0; + + if (type == Argon2_id) { + CC("$argon2id"); + } else if (type == Argon2_i) { + CC("$argon2i"); + } else { + return ARGON2_INCORRECT_TYPE; + } + CC("$v="); + DECIMAL_U32(version); + if (version != ARGON2_VERSION_NUMBER) { + return ARGON2_INCORRECT_TYPE; + } + CC("$m="); + DECIMAL_U32(ctx->m_cost); + if (ctx->m_cost > UINT32_MAX) { + return ARGON2_INCORRECT_TYPE; + } + CC(",t="); + DECIMAL_U32(ctx->t_cost); + if (ctx->t_cost > UINT32_MAX) { + return ARGON2_INCORRECT_TYPE; + } + CC(",p="); + DECIMAL_U32(ctx->lanes); + if (ctx->lanes > UINT32_MAX) { + return ARGON2_INCORRECT_TYPE; + } + ctx->threads = ctx->lanes; + + CC("$"); + BIN(ctx->salt, maxsaltlen, ctx->saltlen); + CC("$"); + BIN(ctx->out, maxoutlen, ctx->outlen); + validation_result = validate_inputs(ctx); + if (validation_result != ARGON2_OK) { + return validation_result; + } + if (*str == 0) { + return ARGON2_OK; + } + return ARGON2_DECODING_FAIL; + +#undef CC +#undef CC_opt +#undef DECIMAL +#undef BIN +} + +#define U32_STR_MAXSIZE 11U + +static void +u32_to_string(char *str, uint32_t x) +{ + char tmp[U32_STR_MAXSIZE - 1U]; + size_t i; + + i = sizeof tmp; + do { + tmp[--i] = (x % (uint32_t) 10U) + '0'; + x /= (uint32_t) 10U; + } while (x != 0U && i != 0U); + memcpy(str, &tmp[i], (sizeof tmp) - i); + str[(sizeof tmp) - i] = 0; +} + +/* + * Encode an argon2i hash string into the provided buffer. 'dst_len' + * contains the size, in characters, of the 'dst' buffer; if 'dst_len' + * is less than the number of required characters (including the + * terminating 0), then this function returns 0. + * + * If pp->output_len is 0, then the hash string will be a salt string + * (no output). if pp->salt_len is also 0, then the string will be a + * parameter-only string (no salt and no output). + * + * On success, ARGON2_OK is returned. + */ +int +encode_string(char *dst, size_t dst_len, argon2_context *ctx, argon2_type type) +{ +#define SS(str) \ + do { \ + size_t pp_len = strlen(str); \ + if (pp_len >= dst_len) { \ + return ARGON2_ENCODING_FAIL; \ + } \ + memcpy(dst, str, pp_len + 1); \ + dst += pp_len; \ + dst_len -= pp_len; \ + } while ((void) 0, 0) + +#define SX(x) \ + do { \ + char tmp[U32_STR_MAXSIZE]; \ + u32_to_string(tmp, x); \ + SS(tmp); \ + } while ((void) 0, 0) + +#define SB(buf, len) \ + do { \ + size_t sb_len; \ + if (sodium_bin2base64(dst, dst_len, (buf), (len), \ + sodium_base64_VARIANT_ORIGINAL_NO_PADDING) == NULL) { \ + return ARGON2_ENCODING_FAIL; \ + } \ + sb_len = strlen(dst); \ + dst += sb_len; \ + dst_len -= sb_len; \ + } while ((void) 0, 0) + + int validation_result; + + switch (type) { + case Argon2_id: + SS("$argon2id$v="); break; + case Argon2_i: + SS("$argon2i$v="); break; + default: + return ARGON2_ENCODING_FAIL; + } + validation_result = validate_inputs(ctx); + if (validation_result != ARGON2_OK) { + return validation_result; + } + SX(ARGON2_VERSION_NUMBER); + SS("$m="); + SX(ctx->m_cost); + SS(",t="); + SX(ctx->t_cost); + SS(",p="); + SX(ctx->lanes); + + SS("$"); + SB(ctx->salt, ctx->saltlen); + + SS("$"); + SB(ctx->out, ctx->outlen); + return ARGON2_OK; + +#undef SS +#undef SX +#undef SB +} diff --git a/libs/libsodium/src/crypto_pwhash/argon2/argon2-encoding.h b/libs/libsodium/src/crypto_pwhash/argon2/argon2-encoding.h new file mode 100644 index 0000000000..e929b31dc3 --- /dev/null +++ b/libs/libsodium/src/crypto_pwhash/argon2/argon2-encoding.h @@ -0,0 +1,33 @@ +#ifndef argon2_encoding_H +#define argon2_encoding_H + +#include "argon2.h" + +/* + * encode an Argon2 hash string into the provided buffer. 'dst_len' + * contains the size, in characters, of the 'dst' buffer; if 'dst_len' + * is less than the number of required characters (including the + * terminating 0), then this function returns 0. + * + * if ctx->outlen is 0, then the hash string will be a salt string + * (no output). if ctx->saltlen is also 0, then the string will be a + * parameter-only string (no salt and no output). + * + * On success, ARGON2_OK is returned. + * + * No other parameters are checked + */ +int encode_string(char *dst, size_t dst_len, argon2_context *ctx, + argon2_type type); + +/* + * Decodes an Argon2 hash string into the provided structure 'ctx'. + * The fields ctx.saltlen, ctx.adlen, ctx.outlen set the maximal salt, ad, out + * length values + * that are allowed; invalid input string causes an error + * + * Returned value is ARGON2_OK on success. + */ +int decode_string(argon2_context *ctx, const char *str, argon2_type type); + +#endif diff --git a/libs/libsodium/src/crypto_pwhash/argon2/argon2-fill-block-avx2.c b/libs/libsodium/src/crypto_pwhash/argon2/argon2-fill-block-avx2.c new file mode 100644 index 0000000000..8acb42ca4d --- /dev/null +++ b/libs/libsodium/src/crypto_pwhash/argon2/argon2-fill-block-avx2.c @@ -0,0 +1,239 @@ +/* + * Argon2 source code package + * + * Written by Daniel Dinu and Dmitry Khovratovich, 2015 + * + * This work is licensed under a Creative Commons CC0 1.0 License/Waiver. + * + * You should have received a copy of the CC0 Public Domain Dedication along + * with + * this software. If not, see + * <http://creativecommons.org/publicdomain/zero/1.0/>. + */ + +#include <stdint.h> +#include <stdlib.h> +#include <string.h> + +#include "argon2-core.h" +#include "argon2.h" +#include "private/common.h" +#include "private/sse2_64_32.h" + +#if defined(HAVE_AVX2INTRIN_H) && defined(HAVE_EMMINTRIN_H) && \ + defined(HAVE_TMMINTRIN_H) && defined(HAVE_SMMINTRIN_H) + +# ifdef __GNUC__ +# pragma GCC target("sse2") +# pragma GCC target("ssse3") +# pragma GCC target("sse4.1") +# pragma GCC target("avx2") +# endif + +# ifdef _MSC_VER +# include <intrin.h> /* for _mm_set_epi64x */ +# endif +#include <emmintrin.h> +#include <immintrin.h> +#include <smmintrin.h> +#include <tmmintrin.h> + +# include "blamka-round-avx2.h" + +static void +fill_block(__m256i *state, const uint8_t *ref_block, uint8_t *next_block) +{ + __m256i block_XY[ARGON2_HWORDS_IN_BLOCK]; + uint32_t i; + + for (i = 0; i < ARGON2_HWORDS_IN_BLOCK; i++) { + block_XY[i] = state[i] = _mm256_xor_si256( + state[i], _mm256_loadu_si256((__m256i const *) (&ref_block[32 * i]))); + } + + for (i = 0; i < 4; ++i) { + BLAKE2_ROUND_1(state[8 * i + 0], state[8 * i + 4], state[8 * i + 1], state[8 * i + 5], + state[8 * i + 2], state[8 * i + 6], state[8 * i + 3], state[8 * i + 7]); + } + + for (i = 0; i < 4; ++i) { + BLAKE2_ROUND_2(state[ 0 + i], state[ 4 + i], state[ 8 + i], state[12 + i], + state[16 + i], state[20 + i], state[24 + i], state[28 + i]); + } + + for (i = 0; i < ARGON2_HWORDS_IN_BLOCK; i++) { + state[i] = _mm256_xor_si256(state[i], block_XY[i]); + _mm256_storeu_si256((__m256i *) (&next_block[32 * i]), state[i]); + } +} + +static void +fill_block_with_xor(__m256i *state, const uint8_t *ref_block, + uint8_t *next_block) +{ + __m256i block_XY[ARGON2_HWORDS_IN_BLOCK]; + uint32_t i; + + for (i = 0; i < ARGON2_HWORDS_IN_BLOCK; i++) { + state[i] = _mm256_xor_si256( + state[i], _mm256_loadu_si256((__m256i const *) (&ref_block[32 * i]))); + block_XY[i] = _mm256_xor_si256( + state[i], _mm256_loadu_si256((__m256i const *) (&next_block[32 * i]))); + } + + for (i = 0; i < 4; ++i) { + BLAKE2_ROUND_1(state[8 * i + 0], state[8 * i + 4], state[8 * i + 1], state[8 * i + 5], + state[8 * i + 2], state[8 * i + 6], state[8 * i + 3], state[8 * i + 7]); + } + + for (i = 0; i < 4; ++i) { + BLAKE2_ROUND_2(state[ 0 + i], state[ 4 + i], state[ 8 + i], state[12 + i], + state[16 + i], state[20 + i], state[24 + i], state[28 + i]); + } + + for (i = 0; i < ARGON2_HWORDS_IN_BLOCK; i++) { + state[i] = _mm256_xor_si256(state[i], block_XY[i]); + _mm256_storeu_si256((__m256i *) (&next_block[32 * i]), state[i]); + } +} + +static void +generate_addresses(const argon2_instance_t *instance, + const argon2_position_t *position, uint64_t *pseudo_rands) +{ + block address_block, input_block, tmp_block; + uint32_t i; + + init_block_value(&address_block, 0); + init_block_value(&input_block, 0); + + if (instance != NULL && position != NULL) { + input_block.v[0] = position->pass; + input_block.v[1] = position->lane; + input_block.v[2] = position->slice; + input_block.v[3] = instance->memory_blocks; + input_block.v[4] = instance->passes; + input_block.v[5] = instance->type; + + for (i = 0; i < instance->segment_length; ++i) { + if (i % ARGON2_ADDRESSES_IN_BLOCK == 0) { + /* Temporary zero-initialized blocks */ + __m256i zero_block[ARGON2_HWORDS_IN_BLOCK]; + __m256i zero2_block[ARGON2_HWORDS_IN_BLOCK]; + + memset(zero_block, 0, sizeof(zero_block)); + memset(zero2_block, 0, sizeof(zero2_block)); + init_block_value(&address_block, 0); + init_block_value(&tmp_block, 0); + /* Increasing index counter */ + input_block.v[6]++; + /* First iteration of G */ + fill_block_with_xor(zero_block, (uint8_t *) &input_block.v, + (uint8_t *) &tmp_block.v); + /* Second iteration of G */ + fill_block_with_xor(zero2_block, (uint8_t *) &tmp_block.v, + (uint8_t *) &address_block.v); + } + + pseudo_rands[i] = address_block.v[i % ARGON2_ADDRESSES_IN_BLOCK]; + } + } +} + +void +fill_segment_avx2(const argon2_instance_t *instance, + argon2_position_t position) +{ + block *ref_block = NULL, *curr_block = NULL; + uint64_t pseudo_rand, ref_index, ref_lane; + uint32_t prev_offset, curr_offset; + uint32_t starting_index, i; + __m256i state[ARGON2_HWORDS_IN_BLOCK]; + int data_independent_addressing = 1; + + /* Pseudo-random values that determine the reference block position */ + uint64_t *pseudo_rands = NULL; + + if (instance == NULL) { + return; + } + + if (instance->type == Argon2_id && + (position.pass != 0 || position.slice >= ARGON2_SYNC_POINTS / 2)) { + data_independent_addressing = 0; + } + + pseudo_rands = instance->pseudo_rands; + + if (data_independent_addressing) { + generate_addresses(instance, &position, pseudo_rands); + } + + starting_index = 0; + + if ((0 == position.pass) && (0 == position.slice)) { + starting_index = 2; /* we have already generated the first two blocks */ + } + + /* Offset of the current block */ + curr_offset = position.lane * instance->lane_length + + position.slice * instance->segment_length + starting_index; + + if (0 == curr_offset % instance->lane_length) { + /* Last block in this lane */ + prev_offset = curr_offset + instance->lane_length - 1; + } else { + /* Previous block */ + prev_offset = curr_offset - 1; + } + + memcpy(state, ((instance->region->memory + prev_offset)->v), + ARGON2_BLOCK_SIZE); + + for (i = starting_index; i < instance->segment_length; + ++i, ++curr_offset, ++prev_offset) { + /*1.1 Rotating prev_offset if needed */ + if (curr_offset % instance->lane_length == 1) { + prev_offset = curr_offset - 1; + } + + /* 1.2 Computing the index of the reference block */ + /* 1.2.1 Taking pseudo-random value from the previous block */ + if (data_independent_addressing) { +#pragma warning(push) +#pragma warning(disable : 6385) + pseudo_rand = pseudo_rands[i]; +#pragma warning(pop) + } else { + pseudo_rand = instance->region->memory[prev_offset].v[0]; + } + + /* 1.2.2 Computing the lane of the reference block */ + ref_lane = ((pseudo_rand >> 32)) % instance->lanes; + + if ((position.pass == 0) && (position.slice == 0)) { + /* Can not reference other lanes yet */ + ref_lane = position.lane; + } + + /* 1.2.3 Computing the number of possible reference block within the + * lane. + */ + position.index = i; + ref_index = index_alpha(instance, &position, pseudo_rand & 0xFFFFFFFF, + ref_lane == position.lane); + + /* 2 Creating a new block */ + ref_block = instance->region->memory + + instance->lane_length * ref_lane + ref_index; + curr_block = instance->region->memory + curr_offset; + if (position.pass != 0) { + fill_block_with_xor(state, (uint8_t *) ref_block->v, + (uint8_t *) curr_block->v); + } else { + fill_block(state, (uint8_t *) ref_block->v, + (uint8_t *) curr_block->v); + } + } +} +#endif diff --git a/libs/libsodium/src/crypto_pwhash/argon2/argon2-fill-block-avx512f.c b/libs/libsodium/src/crypto_pwhash/argon2/argon2-fill-block-avx512f.c new file mode 100644 index 0000000000..1f1ec8b3b4 --- /dev/null +++ b/libs/libsodium/src/crypto_pwhash/argon2/argon2-fill-block-avx512f.c @@ -0,0 +1,244 @@ +/* + * Argon2 source code package + * + * Written by Daniel Dinu and Dmitry Khovratovich, 2015 + * + * This work is licensed under a Creative Commons CC0 1.0 License/Waiver. + * + * You should have received a copy of the CC0 Public Domain Dedication along + * with + * this software. If not, see + * <http://creativecommons.org/publicdomain/zero/1.0/>. + */ + +#include <stdint.h> +#include <stdlib.h> +#include <string.h> + +#include "argon2-core.h" +#include "argon2.h" +#include "private/common.h" +#include "private/sse2_64_32.h" + +#if defined(HAVE_AVX512FINTRIN_H) && defined(HAVE_AVX2INTRIN_H) && \ + defined(HAVE_EMMINTRIN_H) && defined(HAVE_TMMINTRIN_H) && defined(HAVE_SMMINTRIN_H) + +# ifdef __GNUC__ +# pragma GCC target("sse2") +# pragma GCC target("ssse3") +# pragma GCC target("sse4.1") +# pragma GCC target("avx2") +# pragma GCC target("avx512f") +# endif + +# ifdef _MSC_VER +# include <intrin.h> /* for _mm_set_epi64x */ +# endif +#include <emmintrin.h> +#include <immintrin.h> +#include <smmintrin.h> +#include <tmmintrin.h> + +# include "blamka-round-avx512f.h" + +static void +fill_block(__m512i *state, const uint8_t *ref_block, uint8_t *next_block) +{ + __m512i block_XY[ARGON2_512BIT_WORDS_IN_BLOCK]; + uint32_t i; + + for (i = 0; i < ARGON2_512BIT_WORDS_IN_BLOCK; i++) { + block_XY[i] = state[i] = _mm512_xor_si512( + state[i], _mm512_loadu_si512((__m512i const *) (&ref_block[64 * i]))); + } + + for (i = 0; i < 2; ++i) { + BLAKE2_ROUND_1( + state[8 * i + 0], state[8 * i + 1], state[8 * i + 2], state[8 * i + 3], + state[8 * i + 4], state[8 * i + 5], state[8 * i + 6], state[8 * i + 7]); + } + + for (i = 0; i < 2; ++i) { + BLAKE2_ROUND_2( + state[2 * 0 + i], state[2 * 1 + i], state[2 * 2 + i], state[2 * 3 + i], + state[2 * 4 + i], state[2 * 5 + i], state[2 * 6 + i], state[2 * 7 + i]); + } + + for (i = 0; i < ARGON2_512BIT_WORDS_IN_BLOCK; i++) { + state[i] = _mm512_xor_si512(state[i], block_XY[i]); + _mm512_storeu_si512((__m512i *) (&next_block[64 * i]), state[i]); + } +} + +static void +fill_block_with_xor(__m512i *state, const uint8_t *ref_block, + uint8_t *next_block) +{ + __m512i block_XY[ARGON2_512BIT_WORDS_IN_BLOCK]; + uint32_t i; + + for (i = 0; i < ARGON2_512BIT_WORDS_IN_BLOCK; i++) { + state[i] = _mm512_xor_si512( + state[i], _mm512_loadu_si512((__m512i const *) (&ref_block[64 * i]))); + block_XY[i] = _mm512_xor_si512( + state[i], _mm512_loadu_si512((__m512i const *) (&next_block[64 * i]))); + } + + for (i = 0; i < 2; ++i) { + BLAKE2_ROUND_1( + state[8 * i + 0], state[8 * i + 1], state[8 * i + 2], state[8 * i + 3], + state[8 * i + 4], state[8 * i + 5], state[8 * i + 6], state[8 * i + 7]); + } + + for (i = 0; i < 2; ++i) { + BLAKE2_ROUND_2( + state[2 * 0 + i], state[2 * 1 + i], state[2 * 2 + i], state[2 * 3 + i], + state[2 * 4 + i], state[2 * 5 + i], state[2 * 6 + i], state[2 * 7 + i]); + } + + for (i = 0; i < ARGON2_512BIT_WORDS_IN_BLOCK; i++) { + state[i] = _mm512_xor_si512(state[i], block_XY[i]); + _mm512_storeu_si512((__m512i *) (&next_block[64 * i]), state[i]); + } +} + +static void +generate_addresses(const argon2_instance_t *instance, + const argon2_position_t *position, uint64_t *pseudo_rands) +{ + block address_block, input_block, tmp_block; + uint32_t i; + + init_block_value(&address_block, 0); + init_block_value(&input_block, 0); + + if (instance != NULL && position != NULL) { + input_block.v[0] = position->pass; + input_block.v[1] = position->lane; + input_block.v[2] = position->slice; + input_block.v[3] = instance->memory_blocks; + input_block.v[4] = instance->passes; + input_block.v[5] = instance->type; + + for (i = 0; i < instance->segment_length; ++i) { + if (i % ARGON2_ADDRESSES_IN_BLOCK == 0) { + /* Temporary zero-initialized blocks */ + __m512i zero_block[ARGON2_512BIT_WORDS_IN_BLOCK]; + __m512i zero2_block[ARGON2_512BIT_WORDS_IN_BLOCK]; + + memset(zero_block, 0, sizeof(zero_block)); + memset(zero2_block, 0, sizeof(zero2_block)); + init_block_value(&address_block, 0); + init_block_value(&tmp_block, 0); + /* Increasing index counter */ + input_block.v[6]++; + /* First iteration of G */ + fill_block_with_xor(zero_block, (uint8_t *) &input_block.v, + (uint8_t *) &tmp_block.v); + /* Second iteration of G */ + fill_block_with_xor(zero2_block, (uint8_t *) &tmp_block.v, + (uint8_t *) &address_block.v); + } + + pseudo_rands[i] = address_block.v[i % ARGON2_ADDRESSES_IN_BLOCK]; + } + } +} + +void +fill_segment_avx512f(const argon2_instance_t *instance, + argon2_position_t position) +{ + block *ref_block = NULL, *curr_block = NULL; + uint64_t pseudo_rand, ref_index, ref_lane; + uint32_t prev_offset, curr_offset; + uint32_t starting_index, i; + __m512i state[ARGON2_512BIT_WORDS_IN_BLOCK]; + int data_independent_addressing = 1; + + /* Pseudo-random values that determine the reference block position */ + uint64_t *pseudo_rands = NULL; + + if (instance == NULL) { + return; + } + + if (instance->type == Argon2_id && + (position.pass != 0 || position.slice >= ARGON2_SYNC_POINTS / 2)) { + data_independent_addressing = 0; + } + + pseudo_rands = instance->pseudo_rands; + + if (data_independent_addressing) { + generate_addresses(instance, &position, pseudo_rands); + } + + starting_index = 0; + + if ((0 == position.pass) && (0 == position.slice)) { + starting_index = 2; /* we have already generated the first two blocks */ + } + + /* Offset of the current block */ + curr_offset = position.lane * instance->lane_length + + position.slice * instance->segment_length + starting_index; + + if (0 == curr_offset % instance->lane_length) { + /* Last block in this lane */ + prev_offset = curr_offset + instance->lane_length - 1; + } else { + /* Previous block */ + prev_offset = curr_offset - 1; + } + + memcpy(state, ((instance->region->memory + prev_offset)->v), + ARGON2_BLOCK_SIZE); + + for (i = starting_index; i < instance->segment_length; + ++i, ++curr_offset, ++prev_offset) { + /*1.1 Rotating prev_offset if needed */ + if (curr_offset % instance->lane_length == 1) { + prev_offset = curr_offset - 1; + } + + /* 1.2 Computing the index of the reference block */ + /* 1.2.1 Taking pseudo-random value from the previous block */ + if (data_independent_addressing) { +#pragma warning(push) +#pragma warning(disable : 6385) + pseudo_rand = pseudo_rands[i]; +#pragma warning(pop) + } else { + pseudo_rand = instance->region->memory[prev_offset].v[0]; + } + + /* 1.2.2 Computing the lane of the reference block */ + ref_lane = ((pseudo_rand >> 32)) % instance->lanes; + + if ((position.pass == 0) && (position.slice == 0)) { + /* Can not reference other lanes yet */ + ref_lane = position.lane; + } + + /* 1.2.3 Computing the number of possible reference block within the + * lane. + */ + position.index = i; + ref_index = index_alpha(instance, &position, pseudo_rand & 0xFFFFFFFF, + ref_lane == position.lane); + + /* 2 Creating a new block */ + ref_block = instance->region->memory + + instance->lane_length * ref_lane + ref_index; + curr_block = instance->region->memory + curr_offset; + if (position.pass != 0) { + fill_block_with_xor(state, (uint8_t *) ref_block->v, + (uint8_t *) curr_block->v); + } else { + fill_block(state, (uint8_t *) ref_block->v, + (uint8_t *) curr_block->v); + } + } +} +#endif diff --git a/libs/libsodium/src/crypto_pwhash/argon2/argon2-fill-block-ref.c b/libs/libsodium/src/crypto_pwhash/argon2/argon2-fill-block-ref.c new file mode 100644 index 0000000000..75e8d8f5ea --- /dev/null +++ b/libs/libsodium/src/crypto_pwhash/argon2/argon2-fill-block-ref.c @@ -0,0 +1,233 @@ +/* + * Argon2 source code package + * + * Written by Daniel Dinu and Dmitry Khovratovich, 2015 + * + * This work is licensed under a Creative Commons CC0 1.0 License/Waiver. + * + * You should have received a copy of the CC0 Public Domain Dedication along + * with + * this software. If not, see + * <http://creativecommons.org/publicdomain/zero/1.0/>. + */ + +#include <stdint.h> +#include <stdlib.h> +#include <string.h> + +#include "argon2-core.h" +#include "argon2.h" +#include "blamka-round-ref.h" +#include "private/common.h" + +static void +fill_block(const block *prev_block, const block *ref_block, block *next_block) +{ + block blockR, block_tmp; + unsigned i; + + copy_block(&blockR, ref_block); + xor_block(&blockR, prev_block); + copy_block(&block_tmp, &blockR); + /* Now blockR = ref_block + prev_block and bloc_tmp = ref_block + prev_block + Apply Blake2 on columns of 64-bit words: (0,1,...,15), then + (16,17,..31)... finally (112,113,...127) */ + for (i = 0; i < 8; ++i) { + BLAKE2_ROUND_NOMSG( + blockR.v[16 * i], blockR.v[16 * i + 1], blockR.v[16 * i + 2], + blockR.v[16 * i + 3], blockR.v[16 * i + 4], blockR.v[16 * i + 5], + blockR.v[16 * i + 6], blockR.v[16 * i + 7], blockR.v[16 * i + 8], + blockR.v[16 * i + 9], blockR.v[16 * i + 10], blockR.v[16 * i + 11], + blockR.v[16 * i + 12], blockR.v[16 * i + 13], blockR.v[16 * i + 14], + blockR.v[16 * i + 15]); + } + + /* Apply Blake2 on rows of 64-bit words: (0,1,16,17,...112,113), then + (2,3,18,19,...,114,115).. finally (14,15,30,31,...,126,127) */ + for (i = 0; i < 8; i++) { + BLAKE2_ROUND_NOMSG( + blockR.v[2 * i], blockR.v[2 * i + 1], blockR.v[2 * i + 16], + blockR.v[2 * i + 17], blockR.v[2 * i + 32], blockR.v[2 * i + 33], + blockR.v[2 * i + 48], blockR.v[2 * i + 49], blockR.v[2 * i + 64], + blockR.v[2 * i + 65], blockR.v[2 * i + 80], blockR.v[2 * i + 81], + blockR.v[2 * i + 96], blockR.v[2 * i + 97], blockR.v[2 * i + 112], + blockR.v[2 * i + 113]); + } + + copy_block(next_block, &block_tmp); + xor_block(next_block, &blockR); +} + +static void +fill_block_with_xor(const block *prev_block, const block *ref_block, + block *next_block) +{ + block blockR, block_tmp; + unsigned i; + + copy_block(&blockR, ref_block); + xor_block(&blockR, prev_block); + copy_block(&block_tmp, &blockR); + xor_block(&block_tmp, + next_block); /* Saving the next block contents for XOR over */ + /* Now blockR = ref_block + prev_block and bloc_tmp = ref_block + prev_block + * + next_block */ + /* Apply Blake2 on columns of 64-bit words: (0,1,...,15) , then + (16,17,..31)... finally (112,113,...127) */ + for (i = 0; i < 8; ++i) { + BLAKE2_ROUND_NOMSG( + blockR.v[16 * i], blockR.v[16 * i + 1], blockR.v[16 * i + 2], + blockR.v[16 * i + 3], blockR.v[16 * i + 4], blockR.v[16 * i + 5], + blockR.v[16 * i + 6], blockR.v[16 * i + 7], blockR.v[16 * i + 8], + blockR.v[16 * i + 9], blockR.v[16 * i + 10], blockR.v[16 * i + 11], + blockR.v[16 * i + 12], blockR.v[16 * i + 13], blockR.v[16 * i + 14], + blockR.v[16 * i + 15]); + } + + /* Apply Blake2 on rows of 64-bit words: (0,1,16,17,...112,113), then + (2,3,18,19,...,114,115).. finally (14,15,30,31,...,126,127) */ + for (i = 0; i < 8; i++) { + BLAKE2_ROUND_NOMSG( + blockR.v[2 * i], blockR.v[2 * i + 1], blockR.v[2 * i + 16], + blockR.v[2 * i + 17], blockR.v[2 * i + 32], blockR.v[2 * i + 33], + blockR.v[2 * i + 48], blockR.v[2 * i + 49], blockR.v[2 * i + 64], + blockR.v[2 * i + 65], blockR.v[2 * i + 80], blockR.v[2 * i + 81], + blockR.v[2 * i + 96], blockR.v[2 * i + 97], blockR.v[2 * i + 112], + blockR.v[2 * i + 113]); + } + + copy_block(next_block, &block_tmp); + xor_block(next_block, &blockR); +} + +/* + * Generate pseudo-random values to reference blocks in the segment and puts + * them into the array + * @param instance Pointer to the current instance + * @param position Pointer to the current position + * @param pseudo_rands Pointer to the array of 64-bit values + * @pre pseudo_rands must point to @a instance->segment_length allocated values + */ +static void +generate_addresses(const argon2_instance_t *instance, + const argon2_position_t *position, uint64_t *pseudo_rands) +{ + block zero_block, input_block, address_block, tmp_block; + uint32_t i; + + init_block_value(&zero_block, 0); + init_block_value(&input_block, 0); + + if (instance != NULL && position != NULL) { + input_block.v[0] = position->pass; + input_block.v[1] = position->lane; + input_block.v[2] = position->slice; + input_block.v[3] = instance->memory_blocks; + input_block.v[4] = instance->passes; + input_block.v[5] = instance->type; + + for (i = 0; i < instance->segment_length; ++i) { + if (i % ARGON2_ADDRESSES_IN_BLOCK == 0) { + input_block.v[6]++; + init_block_value(&tmp_block, 0); + init_block_value(&address_block, 0); + fill_block_with_xor(&zero_block, &input_block, &tmp_block); + fill_block_with_xor(&zero_block, &tmp_block, &address_block); + } + + pseudo_rands[i] = address_block.v[i % ARGON2_ADDRESSES_IN_BLOCK]; + } + } +} + +void +fill_segment_ref(const argon2_instance_t *instance, argon2_position_t position) +{ + block *ref_block = NULL, *curr_block = NULL; + /* Pseudo-random values that determine the reference block position */ + uint64_t *pseudo_rands = NULL; + uint64_t pseudo_rand, ref_index, ref_lane; + uint32_t prev_offset, curr_offset; + uint32_t starting_index; + uint32_t i; + int data_independent_addressing = 1; + + if (instance == NULL) { + return; + } + + if (instance->type == Argon2_id && + (position.pass != 0 || position.slice >= ARGON2_SYNC_POINTS / 2)) { + data_independent_addressing = 0; + } + + pseudo_rands = instance->pseudo_rands; + + if (data_independent_addressing) { + generate_addresses(instance, &position, pseudo_rands); + } + + starting_index = 0; + + if ((0 == position.pass) && (0 == position.slice)) { + starting_index = 2; /* we have already generated the first two blocks */ + } + + /* Offset of the current block */ + curr_offset = position.lane * instance->lane_length + + position.slice * instance->segment_length + starting_index; + + if (0 == curr_offset % instance->lane_length) { + /* Last block in this lane */ + prev_offset = curr_offset + instance->lane_length - 1; + } else { + /* Previous block */ + prev_offset = curr_offset - 1; + } + + for (i = starting_index; i < instance->segment_length; + ++i, ++curr_offset, ++prev_offset) { + /*1.1 Rotating prev_offset if needed */ + if (curr_offset % instance->lane_length == 1) { + prev_offset = curr_offset - 1; + } + + /* 1.2 Computing the index of the reference block */ + /* 1.2.1 Taking pseudo-random value from the previous block */ + if (data_independent_addressing) { +#pragma warning(push) +#pragma warning(disable : 6385) + pseudo_rand = pseudo_rands[i]; +#pragma warning(pop) + } else { + pseudo_rand = instance->region->memory[prev_offset].v[0]; + } + + /* 1.2.2 Computing the lane of the reference block */ + ref_lane = ((pseudo_rand >> 32)) % instance->lanes; + + if ((position.pass == 0) && (position.slice == 0)) { + /* Can not reference other lanes yet */ + ref_lane = position.lane; + } + + /* 1.2.3 Computing the number of possible reference block within the + * lane. + */ + position.index = i; + ref_index = index_alpha(instance, &position, pseudo_rand & 0xFFFFFFFF, + ref_lane == position.lane); + + /* 2 Creating a new block */ + ref_block = instance->region->memory + + instance->lane_length * ref_lane + ref_index; + curr_block = instance->region->memory + curr_offset; + if (position.pass != 0) { + fill_block_with_xor(instance->region->memory + prev_offset, + ref_block, curr_block); + } else { + fill_block(instance->region->memory + prev_offset, ref_block, + curr_block); + } + } +} diff --git a/libs/libsodium/src/crypto_pwhash/argon2/argon2-fill-block-ssse3.c b/libs/libsodium/src/crypto_pwhash/argon2/argon2-fill-block-ssse3.c new file mode 100644 index 0000000000..796c445560 --- /dev/null +++ b/libs/libsodium/src/crypto_pwhash/argon2/argon2-fill-block-ssse3.c @@ -0,0 +1,238 @@ +/* + * Argon2 source code package + * + * Written by Daniel Dinu and Dmitry Khovratovich, 2015 + * + * This work is licensed under a Creative Commons CC0 1.0 License/Waiver. + * + * You should have received a copy of the CC0 Public Domain Dedication along + * with + * this software. If not, see + * <http://creativecommons.org/publicdomain/zero/1.0/>. + */ + +#include <stdint.h> +#include <stdlib.h> +#include <string.h> + +#include "argon2-core.h" +#include "argon2.h" +#include "private/common.h" +#include "private/sse2_64_32.h" + +#if defined(HAVE_EMMINTRIN_H) && defined(HAVE_TMMINTRIN_H) + +# ifdef __GNUC__ +# pragma GCC target("sse2") +# pragma GCC target("ssse3") +# endif + +# ifdef _MSC_VER +# include <intrin.h> /* for _mm_set_epi64x */ +# endif +# include <emmintrin.h> +# include <tmmintrin.h> + +# include "blamka-round-ssse3.h" + +static void +fill_block(__m128i *state, const uint8_t *ref_block, uint8_t *next_block) +{ + __m128i block_XY[ARGON2_OWORDS_IN_BLOCK]; + uint32_t i; + + for (i = 0; i < ARGON2_OWORDS_IN_BLOCK; i++) { + block_XY[i] = state[i] = _mm_xor_si128( + state[i], _mm_loadu_si128((__m128i const *) (&ref_block[16 * i]))); + } + + for (i = 0; i < 8; ++i) { + BLAKE2_ROUND(state[8 * i + 0], state[8 * i + 1], state[8 * i + 2], + state[8 * i + 3], state[8 * i + 4], state[8 * i + 5], + state[8 * i + 6], state[8 * i + 7]); + } + + for (i = 0; i < 8; ++i) { + BLAKE2_ROUND(state[8 * 0 + i], state[8 * 1 + i], state[8 * 2 + i], + state[8 * 3 + i], state[8 * 4 + i], state[8 * 5 + i], + state[8 * 6 + i], state[8 * 7 + i]); + } + + for (i = 0; i < ARGON2_OWORDS_IN_BLOCK; i++) { + state[i] = _mm_xor_si128(state[i], block_XY[i]); + _mm_storeu_si128((__m128i *) (&next_block[16 * i]), state[i]); + } +} + +static void +fill_block_with_xor(__m128i *state, const uint8_t *ref_block, + uint8_t *next_block) +{ + __m128i block_XY[ARGON2_OWORDS_IN_BLOCK]; + uint32_t i; + + for (i = 0; i < ARGON2_OWORDS_IN_BLOCK; i++) { + state[i] = _mm_xor_si128( + state[i], _mm_loadu_si128((__m128i const *) (&ref_block[16 * i]))); + block_XY[i] = _mm_xor_si128( + state[i], _mm_loadu_si128((__m128i const *) (&next_block[16 * i]))); + } + + for (i = 0; i < 8; ++i) { + BLAKE2_ROUND(state[8 * i + 0], state[8 * i + 1], state[8 * i + 2], + state[8 * i + 3], state[8 * i + 4], state[8 * i + 5], + state[8 * i + 6], state[8 * i + 7]); + } + + for (i = 0; i < 8; ++i) { + BLAKE2_ROUND(state[8 * 0 + i], state[8 * 1 + i], state[8 * 2 + i], + state[8 * 3 + i], state[8 * 4 + i], state[8 * 5 + i], + state[8 * 6 + i], state[8 * 7 + i]); + } + + for (i = 0; i < ARGON2_OWORDS_IN_BLOCK; i++) { + state[i] = _mm_xor_si128(state[i], block_XY[i]); + _mm_storeu_si128((__m128i *) (&next_block[16 * i]), state[i]); + } +} + +static void +generate_addresses(const argon2_instance_t *instance, + const argon2_position_t *position, uint64_t *pseudo_rands) +{ + block address_block, input_block, tmp_block; + uint32_t i; + + init_block_value(&address_block, 0); + init_block_value(&input_block, 0); + + if (instance != NULL && position != NULL) { + input_block.v[0] = position->pass; + input_block.v[1] = position->lane; + input_block.v[2] = position->slice; + input_block.v[3] = instance->memory_blocks; + input_block.v[4] = instance->passes; + input_block.v[5] = instance->type; + + for (i = 0; i < instance->segment_length; ++i) { + if (i % ARGON2_ADDRESSES_IN_BLOCK == 0) { + /* Temporary zero-initialized blocks */ + __m128i zero_block[ARGON2_OWORDS_IN_BLOCK]; + __m128i zero2_block[ARGON2_OWORDS_IN_BLOCK]; + + memset(zero_block, 0, sizeof(zero_block)); + memset(zero2_block, 0, sizeof(zero2_block)); + init_block_value(&address_block, 0); + init_block_value(&tmp_block, 0); + /* Increasing index counter */ + input_block.v[6]++; + /* First iteration of G */ + fill_block_with_xor(zero_block, (uint8_t *) &input_block.v, + (uint8_t *) &tmp_block.v); + /* Second iteration of G */ + fill_block_with_xor(zero2_block, (uint8_t *) &tmp_block.v, + (uint8_t *) &address_block.v); + } + + pseudo_rands[i] = address_block.v[i % ARGON2_ADDRESSES_IN_BLOCK]; + } + } +} + +void +fill_segment_ssse3(const argon2_instance_t *instance, + argon2_position_t position) +{ + block *ref_block = NULL, *curr_block = NULL; + uint64_t pseudo_rand, ref_index, ref_lane; + uint32_t prev_offset, curr_offset; + uint32_t starting_index, i; + __m128i state[ARGON2_OWORDS_IN_BLOCK]; + int data_independent_addressing = 1; + + /* Pseudo-random values that determine the reference block position */ + uint64_t *pseudo_rands = NULL; + + if (instance == NULL) { + return; + } + + if (instance->type == Argon2_id && + (position.pass != 0 || position.slice >= ARGON2_SYNC_POINTS / 2)) { + data_independent_addressing = 0; + } + + pseudo_rands = instance->pseudo_rands; + + if (data_independent_addressing) { + generate_addresses(instance, &position, pseudo_rands); + } + + starting_index = 0; + + if ((0 == position.pass) && (0 == position.slice)) { + starting_index = 2; /* we have already generated the first two blocks */ + } + + /* Offset of the current block */ + curr_offset = position.lane * instance->lane_length + + position.slice * instance->segment_length + starting_index; + + if (0 == curr_offset % instance->lane_length) { + /* Last block in this lane */ + prev_offset = curr_offset + instance->lane_length - 1; + } else { + /* Previous block */ + prev_offset = curr_offset - 1; + } + + memcpy(state, ((instance->region->memory + prev_offset)->v), + ARGON2_BLOCK_SIZE); + + for (i = starting_index; i < instance->segment_length; + ++i, ++curr_offset, ++prev_offset) { + /*1.1 Rotating prev_offset if needed */ + if (curr_offset % instance->lane_length == 1) { + prev_offset = curr_offset - 1; + } + + /* 1.2 Computing the index of the reference block */ + /* 1.2.1 Taking pseudo-random value from the previous block */ + if (data_independent_addressing) { +#pragma warning(push) +#pragma warning(disable : 6385) + pseudo_rand = pseudo_rands[i]; +#pragma warning(pop) + } else { + pseudo_rand = instance->region->memory[prev_offset].v[0]; + } + + /* 1.2.2 Computing the lane of the reference block */ + ref_lane = ((pseudo_rand >> 32)) % instance->lanes; + + if ((position.pass == 0) && (position.slice == 0)) { + /* Can not reference other lanes yet */ + ref_lane = position.lane; + } + + /* 1.2.3 Computing the number of possible reference block within the + * lane. + */ + position.index = i; + ref_index = index_alpha(instance, &position, pseudo_rand & 0xFFFFFFFF, + ref_lane == position.lane); + + /* 2 Creating a new block */ + ref_block = instance->region->memory + + instance->lane_length * ref_lane + ref_index; + curr_block = instance->region->memory + curr_offset; + if (position.pass != 0) { + fill_block_with_xor(state, (uint8_t *) ref_block->v, + (uint8_t *) curr_block->v); + } else { + fill_block(state, (uint8_t *) ref_block->v, + (uint8_t *) curr_block->v); + } + } +} +#endif diff --git a/libs/libsodium/src/crypto_pwhash/argon2/argon2.c b/libs/libsodium/src/crypto_pwhash/argon2/argon2.c new file mode 100644 index 0000000000..ac1628c991 --- /dev/null +++ b/libs/libsodium/src/crypto_pwhash/argon2/argon2.c @@ -0,0 +1,277 @@ +/* + * Argon2 source code package + * + * Written by Daniel Dinu and Dmitry Khovratovich, 2015 + * + * This work is licensed under a Creative Commons CC0 1.0 License/Waiver. + * + * You should have received a copy of the CC0 Public Domain Dedication along + * with + * this software. If not, see + * <http://creativecommons.org/publicdomain/zero/1.0/>. + */ + +#include <limits.h> +#include <stdint.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#include "utils.h" + +#include "argon2-core.h" +#include "argon2-encoding.h" +#include "argon2.h" + +int +argon2_ctx(argon2_context *context, argon2_type type) +{ + /* 1. Validate all inputs */ + int result = validate_inputs(context); + uint32_t memory_blocks, segment_length; + uint32_t pass; + argon2_instance_t instance; + + if (ARGON2_OK != result) { + return result; + } + + if (type != Argon2_id && type != Argon2_i) { + return ARGON2_INCORRECT_TYPE; + } + + /* 2. Align memory size */ + /* Minimum memory_blocks = 8L blocks, where L is the number of lanes */ + memory_blocks = context->m_cost; + + if (memory_blocks < 2 * ARGON2_SYNC_POINTS * context->lanes) { + memory_blocks = 2 * ARGON2_SYNC_POINTS * context->lanes; + } + + segment_length = memory_blocks / (context->lanes * ARGON2_SYNC_POINTS); + /* Ensure that all segments have equal length */ + memory_blocks = segment_length * (context->lanes * ARGON2_SYNC_POINTS); + + instance.region = NULL; + instance.passes = context->t_cost; + instance.current_pass = ~ 0U; + instance.memory_blocks = memory_blocks; + instance.segment_length = segment_length; + instance.lane_length = segment_length * ARGON2_SYNC_POINTS; + instance.lanes = context->lanes; + instance.threads = context->threads; + instance.type = type; + + /* 3. Initialization: Hashing inputs, allocating memory, filling first + * blocks + */ + result = initialize(&instance, context); + + if (ARGON2_OK != result) { + return result; + } + + /* 4. Filling memory */ + for (pass = 0; pass < instance.passes; pass++) { + fill_memory_blocks(&instance, pass); + } + + /* 5. Finalization */ + finalize(context, &instance); + + return ARGON2_OK; +} + +int +argon2_hash(const uint32_t t_cost, const uint32_t m_cost, + const uint32_t parallelism, const void *pwd, const size_t pwdlen, + const void *salt, const size_t saltlen, void *hash, + const size_t hashlen, char *encoded, const size_t encodedlen, + argon2_type type) +{ + argon2_context context; + int result; + uint8_t *out; + + if (pwdlen > ARGON2_MAX_PWD_LENGTH) { + return ARGON2_PWD_TOO_LONG; + } + + if (hashlen > ARGON2_MAX_OUTLEN) { + return ARGON2_OUTPUT_TOO_LONG; + } + + if (saltlen > ARGON2_MAX_SALT_LENGTH) { + return ARGON2_SALT_TOO_LONG; + } + + out = (uint8_t *) malloc(hashlen); + if (!out) { + return ARGON2_MEMORY_ALLOCATION_ERROR; + } + + context.out = (uint8_t *) out; + context.outlen = (uint32_t) hashlen; + context.pwd = (uint8_t *) pwd; + context.pwdlen = (uint32_t) pwdlen; + context.salt = (uint8_t *) salt; + context.saltlen = (uint32_t) saltlen; + context.secret = NULL; + context.secretlen = 0; + context.ad = NULL; + context.adlen = 0; + context.t_cost = t_cost; + context.m_cost = m_cost; + context.lanes = parallelism; + context.threads = parallelism; + context.flags = ARGON2_DEFAULT_FLAGS; + + result = argon2_ctx(&context, type); + + if (result != ARGON2_OK) { + sodium_memzero(out, hashlen); + free(out); + return result; + } + + /* if raw hash requested, write it */ + if (hash) { + memcpy(hash, out, hashlen); + } + + /* if encoding requested, write it */ + if (encoded && encodedlen) { + if (encode_string(encoded, encodedlen, &context, type) != ARGON2_OK) { + sodium_memzero(out, hashlen); + sodium_memzero(encoded, encodedlen); + free(out); + return ARGON2_ENCODING_FAIL; + } + } + + sodium_memzero(out, hashlen); + free(out); + + return ARGON2_OK; +} + +int +argon2i_hash_encoded(const uint32_t t_cost, const uint32_t m_cost, + const uint32_t parallelism, const void *pwd, + const size_t pwdlen, const void *salt, + const size_t saltlen, const size_t hashlen, char *encoded, + const size_t encodedlen) +{ + return argon2_hash(t_cost, m_cost, parallelism, pwd, pwdlen, salt, saltlen, + NULL, hashlen, encoded, encodedlen, Argon2_i); +} + +int +argon2i_hash_raw(const uint32_t t_cost, const uint32_t m_cost, + const uint32_t parallelism, const void *pwd, + const size_t pwdlen, const void *salt, const size_t saltlen, + void *hash, const size_t hashlen) +{ + return argon2_hash(t_cost, m_cost, parallelism, pwd, pwdlen, salt, saltlen, + hash, hashlen, NULL, 0, Argon2_i); +} + +int +argon2id_hash_encoded(const uint32_t t_cost, const uint32_t m_cost, + const uint32_t parallelism, const void *pwd, + const size_t pwdlen, const void *salt, + const size_t saltlen, const size_t hashlen, char *encoded, + const size_t encodedlen) +{ + return argon2_hash(t_cost, m_cost, parallelism, pwd, pwdlen, salt, saltlen, + NULL, hashlen, encoded, encodedlen, Argon2_id); +} + +int +argon2id_hash_raw(const uint32_t t_cost, const uint32_t m_cost, + const uint32_t parallelism, const void *pwd, + const size_t pwdlen, const void *salt, const size_t saltlen, + void *hash, const size_t hashlen) +{ + return argon2_hash(t_cost, m_cost, parallelism, pwd, pwdlen, salt, saltlen, + hash, hashlen, NULL, 0, Argon2_id); +} + +int +argon2_verify(const char *encoded, const void *pwd, const size_t pwdlen, + argon2_type type) +{ + argon2_context ctx; + uint8_t *out; + int decode_result; + int ret; + size_t encoded_len; + + memset(&ctx, 0, sizeof ctx); + + ctx.pwd = NULL; + ctx.pwdlen = 0; + ctx.secret = NULL; + ctx.secretlen = 0; + + /* max values, to be updated in decode_string */ + encoded_len = strlen(encoded); + if (encoded_len > UINT32_MAX) { + return ARGON2_DECODING_LENGTH_FAIL; + } + ctx.adlen = (uint32_t) encoded_len; + ctx.saltlen = (uint32_t) encoded_len; + ctx.outlen = (uint32_t) encoded_len; + + ctx.ad = (uint8_t *) malloc(ctx.adlen); + ctx.salt = (uint8_t *) malloc(ctx.saltlen); + ctx.out = (uint8_t *) malloc(ctx.outlen); + if (!ctx.out || !ctx.salt || !ctx.ad) { + free(ctx.ad); + free(ctx.salt); + free(ctx.out); + return ARGON2_MEMORY_ALLOCATION_ERROR; + } + out = (uint8_t *) malloc(ctx.outlen); + if (!out) { + free(ctx.ad); + free(ctx.salt); + free(ctx.out); + return ARGON2_MEMORY_ALLOCATION_ERROR; + } + + decode_result = decode_string(&ctx, encoded, type); + if (decode_result != ARGON2_OK) { + free(ctx.ad); + free(ctx.salt); + free(ctx.out); + free(out); + return decode_result; + } + + ret = argon2_hash(ctx.t_cost, ctx.m_cost, ctx.threads, pwd, pwdlen, + ctx.salt, ctx.saltlen, out, ctx.outlen, NULL, 0, type); + + free(ctx.ad); + free(ctx.salt); + + if (ret != ARGON2_OK || sodium_memcmp(out, ctx.out, ctx.outlen) != 0) { + ret = ARGON2_VERIFY_MISMATCH; + } + free(out); + free(ctx.out); + + return ret; +} + +int +argon2i_verify(const char *encoded, const void *pwd, const size_t pwdlen) +{ + return argon2_verify(encoded, pwd, pwdlen, Argon2_i); +} + +int +argon2id_verify(const char *encoded, const void *pwd, const size_t pwdlen) +{ + return argon2_verify(encoded, pwd, pwdlen, Argon2_id); +} diff --git a/libs/libsodium/src/crypto_pwhash/argon2/argon2.h b/libs/libsodium/src/crypto_pwhash/argon2/argon2.h new file mode 100644 index 0000000000..85ca4dd373 --- /dev/null +++ b/libs/libsodium/src/crypto_pwhash/argon2/argon2.h @@ -0,0 +1,305 @@ +/* + * Argon2 source code package + * + * Written by Daniel Dinu and Dmitry Khovratovich, 2015 + * + * This work is licensed under a Creative Commons CC0 1.0 License/Waiver. + * + * You should have received a copy of the CC0 Public Domain Dedication along + * with this software. If not, see + * <http://creativecommons.org/publicdomain/zero/1.0/>. + */ +#ifndef argon2_H +#define argon2_H + +#include <limits.h> +#include <stddef.h> +#include <stdint.h> + +/* + * Argon2 input parameter restrictions + */ + +/* Minimum and maximum number of lanes (degree of parallelism) */ +#define ARGON2_MIN_LANES UINT32_C(1) +#define ARGON2_MAX_LANES UINT32_C(0xFFFFFF) + +/* Minimum and maximum number of threads */ +#define ARGON2_MIN_THREADS UINT32_C(1) +#define ARGON2_MAX_THREADS UINT32_C(0xFFFFFF) + +/* Number of synchronization points between lanes per pass */ +#define ARGON2_SYNC_POINTS UINT32_C(4) + +/* Minimum and maximum digest size in bytes */ +#define ARGON2_MIN_OUTLEN UINT32_C(16) +#define ARGON2_MAX_OUTLEN UINT32_C(0xFFFFFFFF) + +/* Minimum and maximum number of memory blocks (each of BLOCK_SIZE bytes) */ +#define ARGON2_MIN_MEMORY (2 * ARGON2_SYNC_POINTS) /* 2 blocks per slice */ + +#define ARGON2_MIN(a, b) ((a) < (b) ? (a) : (b)) +/* Max memory size is half the addressing space, topping at 2^32 blocks (4 TB) + */ +#define ARGON2_MAX_MEMORY_BITS \ + ARGON2_MIN(UINT32_C(32), (sizeof(void *) * CHAR_BIT - 10 - 1)) +#define ARGON2_MAX_MEMORY \ + ARGON2_MIN(UINT32_C(0xFFFFFFFF), UINT64_C(1) << ARGON2_MAX_MEMORY_BITS) + +/* Minimum and maximum number of passes */ +#define ARGON2_MIN_TIME UINT32_C(1) +#define ARGON2_MAX_TIME UINT32_C(0xFFFFFFFF) + +/* Minimum and maximum password length in bytes */ +#define ARGON2_MIN_PWD_LENGTH UINT32_C(0) +#define ARGON2_MAX_PWD_LENGTH UINT32_C(0xFFFFFFFF) + +/* Minimum and maximum associated data length in bytes */ +#define ARGON2_MIN_AD_LENGTH UINT32_C(0) +#define ARGON2_MAX_AD_LENGTH UINT32_C(0xFFFFFFFF) + +/* Minimum and maximum salt length in bytes */ +#define ARGON2_MIN_SALT_LENGTH UINT32_C(8) +#define ARGON2_MAX_SALT_LENGTH UINT32_C(0xFFFFFFFF) + +/* Minimum and maximum key length in bytes */ +#define ARGON2_MIN_SECRET UINT32_C(0) +#define ARGON2_MAX_SECRET UINT32_C(0xFFFFFFFF) + +#define ARGON2_FLAG_CLEAR_PASSWORD (UINT32_C(1) << 0) +#define ARGON2_FLAG_CLEAR_SECRET (UINT32_C(1) << 1) +#define ARGON2_FLAG_CLEAR_MEMORY (UINT32_C(1) << 2) +#define ARGON2_DEFAULT_FLAGS (UINT32_C(0)) + +/* Error codes */ +typedef enum Argon2_ErrorCodes { + ARGON2_OK = 0, + + ARGON2_OUTPUT_PTR_NULL = -1, + + ARGON2_OUTPUT_TOO_SHORT = -2, + ARGON2_OUTPUT_TOO_LONG = -3, + + ARGON2_PWD_TOO_SHORT = -4, + ARGON2_PWD_TOO_LONG = -5, + + ARGON2_SALT_TOO_SHORT = -6, + ARGON2_SALT_TOO_LONG = -7, + + ARGON2_AD_TOO_SHORT = -8, + ARGON2_AD_TOO_LONG = -9, + + ARGON2_SECRET_TOO_SHORT = -10, + ARGON2_SECRET_TOO_LONG = -11, + + ARGON2_TIME_TOO_SMALL = -12, + ARGON2_TIME_TOO_LARGE = -13, + + ARGON2_MEMORY_TOO_LITTLE = -14, + ARGON2_MEMORY_TOO_MUCH = -15, + + ARGON2_LANES_TOO_FEW = -16, + ARGON2_LANES_TOO_MANY = -17, + + ARGON2_PWD_PTR_MISMATCH = -18, /* NULL ptr with non-zero length */ + ARGON2_SALT_PTR_MISMATCH = -19, /* NULL ptr with non-zero length */ + ARGON2_SECRET_PTR_MISMATCH = -20, /* NULL ptr with non-zero length */ + ARGON2_AD_PTR_MISMATCH = -21, /* NULL ptr with non-zero length */ + + ARGON2_MEMORY_ALLOCATION_ERROR = -22, + + ARGON2_FREE_MEMORY_CBK_NULL = -23, + ARGON2_ALLOCATE_MEMORY_CBK_NULL = -24, + + ARGON2_INCORRECT_PARAMETER = -25, + ARGON2_INCORRECT_TYPE = -26, + + ARGON2_OUT_PTR_MISMATCH = -27, + + ARGON2_THREADS_TOO_FEW = -28, + ARGON2_THREADS_TOO_MANY = -29, + + ARGON2_MISSING_ARGS = -30, + + ARGON2_ENCODING_FAIL = -31, + + ARGON2_DECODING_FAIL = -32, + + ARGON2_THREAD_FAIL = -33, + + ARGON2_DECODING_LENGTH_FAIL = -34, + + ARGON2_VERIFY_MISMATCH = -35 +} argon2_error_codes; + +/* Argon2 external data structures */ + +/* + * Context: structure to hold Argon2 inputs: + * output array and its length, + * password and its length, + * salt and its length, + * secret and its length, + * associated data and its length, + * number of passes, amount of used memory (in KBytes, can be rounded up a bit) + * number of parallel threads that will be run. + * All the parameters above affect the output hash value. + * Additionally, two function pointers can be provided to allocate and + * deallocate the memory (if NULL, memory will be allocated internally). + * Also, three flags indicate whether to erase password, secret as soon as they + * are pre-hashed (and thus not needed anymore), and the entire memory + ***** + * Simplest situation: you have output array out[8], password is stored in + * pwd[32], salt is stored in salt[16], you do not have keys nor associated + *data. + * You need to spend 1 GB of RAM and you run 5 passes of Argon2 with 4 parallel + *lanes. + * You want to erase the password, but you're OK with last pass not being + *erased. + * You want to use the default memory allocator. + * Then you initialize: + * Argon2_Context(out,8,pwd,32,salt,16,NULL,0,NULL,0,5,1<<20,4,4,NULL,NULL,true,false,false,false). + */ +typedef struct Argon2_Context { + uint8_t *out; /* output array */ + uint32_t outlen; /* digest length */ + + uint8_t *pwd; /* password array */ + uint32_t pwdlen; /* password length */ + + uint8_t *salt; /* salt array */ + uint32_t saltlen; /* salt length */ + + uint8_t *secret; /* key array */ + uint32_t secretlen; /* key length */ + + uint8_t *ad; /* associated data array */ + uint32_t adlen; /* associated data length */ + + uint32_t t_cost; /* number of passes */ + uint32_t m_cost; /* amount of memory requested (KB) */ + uint32_t lanes; /* number of lanes */ + uint32_t threads; /* maximum number of threads */ + + uint32_t flags; /* array of bool options */ +} argon2_context; + +/* Argon2 primitive type */ +typedef enum Argon2_type { Argon2_i = 1, Argon2_id = 2 } argon2_type; + +/* + * Function that performs memory-hard hashing with certain degree of parallelism + * @param context Pointer to the Argon2 internal structure + * @return Error code if smth is wrong, ARGON2_OK otherwise + */ +int argon2_ctx(argon2_context *context, argon2_type type); + +/** + * Hashes a password with Argon2i, producing an encoded hash + * @param t_cost Number of iterations + * @param m_cost Sets memory usage to m_cost kibibytes + * @param parallelism Number of threads and compute lanes + * @param pwd Pointer to password + * @param pwdlen Password size in bytes + * @param salt Pointer to salt + * @param saltlen Salt size in bytes + * @param hashlen Desired length of the hash in bytes + * @param encoded Buffer where to write the encoded hash + * @param encodedlen Size of the buffer (thus max size of the encoded hash) + * @pre Different parallelism levels will give different results + * @pre Returns ARGON2_OK if successful + */ +int argon2i_hash_encoded(const uint32_t t_cost, const uint32_t m_cost, + const uint32_t parallelism, const void *pwd, + const size_t pwdlen, const void *salt, + const size_t saltlen, const size_t hashlen, + char *encoded, const size_t encodedlen); + +/** + * Hashes a password with Argon2id, producing an encoded hash + * @param t_cost Number of iterations + * @param m_cost Sets memory usage to m_cost kibibytes + * @param parallelism Number of threads and compute lanes + * @param pwd Pointer to password + * @param pwdlen Password size in bytes + * @param salt Pointer to salt + * @param saltlen Salt size in bytes + * @param hashlen Desired length of the hash in bytes + * @param encoded Buffer where to write the encoded hash + * @param encodedlen Size of the buffer (thus max size of the encoded hash) + * @pre Different parallelism levels will give different results + * @pre Returns ARGON2_OK if successful + */ +int argon2id_hash_encoded(const uint32_t t_cost, const uint32_t m_cost, + const uint32_t parallelism, const void *pwd, + const size_t pwdlen, const void *salt, + const size_t saltlen, const size_t hashlen, + char *encoded, const size_t encodedlen); + +/** + * Hashes a password with Argon2i, producing a raw hash + * @param t_cost Number of iterations + * @param m_cost Sets memory usage to m_cost kibibytes + * @param parallelism Number of threads and compute lanes + * @param pwd Pointer to password + * @param pwdlen Password size in bytes + * @param salt Pointer to salt + * @param saltlen Salt size in bytes + * @param hash Buffer where to write the raw hash + * @param hashlen Desired length of the hash in bytes + * @pre Different parallelism levels will give different results + * @pre Returns ARGON2_OK if successful + */ +int argon2i_hash_raw(const uint32_t t_cost, const uint32_t m_cost, + const uint32_t parallelism, const void *pwd, + const size_t pwdlen, const void *salt, + const size_t saltlen, void *hash, const size_t hashlen); + +/** + * Hashes a password with Argon2id, producing a raw hash + * @param t_cost Number of iterations + * @param m_cost Sets memory usage to m_cost kibibytes + * @param parallelism Number of threads and compute lanes + * @param pwd Pointer to password + * @param pwdlen Password size in bytes + * @param salt Pointer to salt + * @param saltlen Salt size in bytes + * @param hash Buffer where to write the raw hash + * @param hashlen Desired length of the hash in bytes + * @pre Different parallelism levels will give different results + * @pre Returns ARGON2_OK if successful + */ +int argon2id_hash_raw(const uint32_t t_cost, const uint32_t m_cost, + const uint32_t parallelism, const void *pwd, + const size_t pwdlen, const void *salt, + const size_t saltlen, void *hash, const size_t hashlen); + +/* generic function underlying the above ones */ +int argon2_hash(const uint32_t t_cost, const uint32_t m_cost, + const uint32_t parallelism, const void *pwd, + const size_t pwdlen, const void *salt, const size_t saltlen, + void *hash, const size_t hashlen, char *encoded, + const size_t encodedlen, argon2_type type); + +/** + * Verifies a password against an encoded string + * Encoded string is restricted as in validate_inputs() + * @param encoded String encoding parameters, salt, hash + * @param pwd Pointer to password + * @pre Returns ARGON2_OK if successful + */ +int argon2i_verify(const char *encoded, const void *pwd, const size_t pwdlen); + +/** + * Verifies a password against an encoded string + * Encoded string is restricted as in validate_inputs() + * @param encoded String encoding parameters, salt, hash + * @param pwd Pointer to password + * @pre Returns ARGON2_OK if successful + */ +int argon2id_verify(const char *encoded, const void *pwd, const size_t pwdlen); + +/* generic function underlying the above ones */ +int argon2_verify(const char *encoded, const void *pwd, const size_t pwdlen, + argon2_type type); +#endif diff --git a/libs/libsodium/src/crypto_pwhash/argon2/blake2b-long.c b/libs/libsodium/src/crypto_pwhash/argon2/blake2b-long.c new file mode 100644 index 0000000000..f0364aca87 --- /dev/null +++ b/libs/libsodium/src/crypto_pwhash/argon2/blake2b-long.c @@ -0,0 +1,79 @@ +#include <limits.h> +#include <stdint.h> +#include <stdlib.h> +#include <string.h> + +#include "crypto_generichash_blake2b.h" +#include "private/common.h" +#include "utils.h" + +#include "blake2b-long.h" + +int +blake2b_long(void *pout, size_t outlen, const void *in, size_t inlen) +{ + uint8_t *out = (uint8_t *) pout; + crypto_generichash_blake2b_state blake_state; + uint8_t outlen_bytes[4 /* sizeof(uint32_t) */] = { 0 }; + int ret = -1; + + if (outlen > UINT32_MAX) { + goto fail; /* LCOV_EXCL_LINE */ + } + + /* Ensure little-endian byte order! */ + STORE32_LE(outlen_bytes, (uint32_t) outlen); + +#define TRY(statement) \ + do { \ + ret = statement; \ + if (ret < 0) { \ + goto fail; \ + } \ + } while ((void) 0, 0) + + if (outlen <= crypto_generichash_blake2b_BYTES_MAX) { + TRY(crypto_generichash_blake2b_init(&blake_state, NULL, 0U, outlen)); + TRY(crypto_generichash_blake2b_update(&blake_state, outlen_bytes, + sizeof(outlen_bytes))); + TRY(crypto_generichash_blake2b_update( + &blake_state, (const unsigned char *) in, inlen)); + TRY(crypto_generichash_blake2b_final(&blake_state, out, outlen)); + } else { + uint32_t toproduce; + uint8_t out_buffer[crypto_generichash_blake2b_BYTES_MAX]; + uint8_t in_buffer[crypto_generichash_blake2b_BYTES_MAX]; + TRY(crypto_generichash_blake2b_init( + &blake_state, NULL, 0U, crypto_generichash_blake2b_BYTES_MAX)); + TRY(crypto_generichash_blake2b_update(&blake_state, outlen_bytes, + sizeof(outlen_bytes))); + TRY(crypto_generichash_blake2b_update( + &blake_state, (const unsigned char *) in, inlen)); + TRY(crypto_generichash_blake2b_final( + &blake_state, out_buffer, crypto_generichash_blake2b_BYTES_MAX)); + memcpy(out, out_buffer, crypto_generichash_blake2b_BYTES_MAX / 2); + out += crypto_generichash_blake2b_BYTES_MAX / 2; + toproduce = + (uint32_t) outlen - crypto_generichash_blake2b_BYTES_MAX / 2; + + while (toproduce > crypto_generichash_blake2b_BYTES_MAX) { + memcpy(in_buffer, out_buffer, crypto_generichash_blake2b_BYTES_MAX); + TRY(crypto_generichash_blake2b( + out_buffer, crypto_generichash_blake2b_BYTES_MAX, in_buffer, + crypto_generichash_blake2b_BYTES_MAX, NULL, 0U)); + memcpy(out, out_buffer, crypto_generichash_blake2b_BYTES_MAX / 2); + out += crypto_generichash_blake2b_BYTES_MAX / 2; + toproduce -= crypto_generichash_blake2b_BYTES_MAX / 2; + } + + memcpy(in_buffer, out_buffer, crypto_generichash_blake2b_BYTES_MAX); + TRY(crypto_generichash_blake2b(out_buffer, toproduce, in_buffer, + crypto_generichash_blake2b_BYTES_MAX, + NULL, 0U)); + memcpy(out, out_buffer, toproduce); + } +fail: + sodium_memzero(&blake_state, sizeof(blake_state)); + return ret; +#undef TRY +} diff --git a/libs/libsodium/src/crypto_pwhash/argon2/blake2b-long.h b/libs/libsodium/src/crypto_pwhash/argon2/blake2b-long.h new file mode 100644 index 0000000000..3d6d775521 --- /dev/null +++ b/libs/libsodium/src/crypto_pwhash/argon2/blake2b-long.h @@ -0,0 +1,8 @@ +#ifndef blake2b_long_H +#define blake2b_long_H + +#include <stddef.h> + +int blake2b_long(void *pout, size_t outlen, const void *in, size_t inlen); + +#endif diff --git a/libs/libsodium/src/crypto_pwhash/argon2/blamka-round-avx2.h b/libs/libsodium/src/crypto_pwhash/argon2/blamka-round-avx2.h new file mode 100644 index 0000000000..f3dfa0f506 --- /dev/null +++ b/libs/libsodium/src/crypto_pwhash/argon2/blamka-round-avx2.h @@ -0,0 +1,150 @@ +#ifndef blamka_round_avx2_H +#define blamka_round_avx2_H + +#include "private/common.h" +#include "private/sse2_64_32.h" + +#define rotr32(x) _mm256_shuffle_epi32(x, _MM_SHUFFLE(2, 3, 0, 1)) +#define rotr24(x) _mm256_shuffle_epi8(x, _mm256_setr_epi8(3, 4, 5, 6, 7, 0, 1, 2, 11, 12, 13, 14, 15, 8, 9, 10, 3, 4, 5, 6, 7, 0, 1, 2, 11, 12, 13, 14, 15, 8, 9, 10)) +#define rotr16(x) _mm256_shuffle_epi8(x, _mm256_setr_epi8(2, 3, 4, 5, 6, 7, 0, 1, 10, 11, 12, 13, 14, 15, 8, 9, 2, 3, 4, 5, 6, 7, 0, 1, 10, 11, 12, 13, 14, 15, 8, 9)) +#define rotr63(x) _mm256_xor_si256(_mm256_srli_epi64((x), 63), _mm256_add_epi64((x), (x))) + +#define G1_AVX2(A0, A1, B0, B1, C0, C1, D0, D1) \ + do { \ + __m256i ml = _mm256_mul_epu32(A0, B0); \ + ml = _mm256_add_epi64(ml, ml); \ + A0 = _mm256_add_epi64(A0, _mm256_add_epi64(B0, ml)); \ + D0 = _mm256_xor_si256(D0, A0); \ + D0 = rotr32(D0); \ + \ + ml = _mm256_mul_epu32(C0, D0); \ + ml = _mm256_add_epi64(ml, ml); \ + C0 = _mm256_add_epi64(C0, _mm256_add_epi64(D0, ml)); \ + \ + B0 = _mm256_xor_si256(B0, C0); \ + B0 = rotr24(B0); \ + \ + ml = _mm256_mul_epu32(A1, B1); \ + ml = _mm256_add_epi64(ml, ml); \ + A1 = _mm256_add_epi64(A1, _mm256_add_epi64(B1, ml)); \ + D1 = _mm256_xor_si256(D1, A1); \ + D1 = rotr32(D1); \ + \ + ml = _mm256_mul_epu32(C1, D1); \ + ml = _mm256_add_epi64(ml, ml); \ + C1 = _mm256_add_epi64(C1, _mm256_add_epi64(D1, ml)); \ + \ + B1 = _mm256_xor_si256(B1, C1); \ + B1 = rotr24(B1); \ + } while((void)0, 0); + +#define G2_AVX2(A0, A1, B0, B1, C0, C1, D0, D1) \ + do { \ + __m256i ml = _mm256_mul_epu32(A0, B0); \ + ml = _mm256_add_epi64(ml, ml); \ + A0 = _mm256_add_epi64(A0, _mm256_add_epi64(B0, ml)); \ + D0 = _mm256_xor_si256(D0, A0); \ + D0 = rotr16(D0); \ + \ + ml = _mm256_mul_epu32(C0, D0); \ + ml = _mm256_add_epi64(ml, ml); \ + C0 = _mm256_add_epi64(C0, _mm256_add_epi64(D0, ml)); \ + B0 = _mm256_xor_si256(B0, C0); \ + B0 = rotr63(B0); \ + \ + ml = _mm256_mul_epu32(A1, B1); \ + ml = _mm256_add_epi64(ml, ml); \ + A1 = _mm256_add_epi64(A1, _mm256_add_epi64(B1, ml)); \ + D1 = _mm256_xor_si256(D1, A1); \ + D1 = rotr16(D1); \ + \ + ml = _mm256_mul_epu32(C1, D1); \ + ml = _mm256_add_epi64(ml, ml); \ + C1 = _mm256_add_epi64(C1, _mm256_add_epi64(D1, ml)); \ + B1 = _mm256_xor_si256(B1, C1); \ + B1 = rotr63(B1); \ + } while((void)0, 0); + +#define DIAGONALIZE_1(A0, B0, C0, D0, A1, B1, C1, D1) \ + do { \ + B0 = _mm256_permute4x64_epi64(B0, _MM_SHUFFLE(0, 3, 2, 1)); \ + C0 = _mm256_permute4x64_epi64(C0, _MM_SHUFFLE(1, 0, 3, 2)); \ + D0 = _mm256_permute4x64_epi64(D0, _MM_SHUFFLE(2, 1, 0, 3)); \ + \ + B1 = _mm256_permute4x64_epi64(B1, _MM_SHUFFLE(0, 3, 2, 1)); \ + C1 = _mm256_permute4x64_epi64(C1, _MM_SHUFFLE(1, 0, 3, 2)); \ + D1 = _mm256_permute4x64_epi64(D1, _MM_SHUFFLE(2, 1, 0, 3)); \ + } while((void)0, 0); + +#define DIAGONALIZE_2(A0, A1, B0, B1, C0, C1, D0, D1) \ + do { \ + __m256i tmp1 = _mm256_blend_epi32(B0, B1, 0xCC); \ + __m256i tmp2 = _mm256_blend_epi32(B0, B1, 0x33); \ + B1 = _mm256_permute4x64_epi64(tmp1, _MM_SHUFFLE(2,3,0,1)); \ + B0 = _mm256_permute4x64_epi64(tmp2, _MM_SHUFFLE(2,3,0,1)); \ + \ + tmp1 = C0; \ + C0 = C1; \ + C1 = tmp1; \ + \ + tmp1 = _mm256_blend_epi32(D0, D1, 0xCC); \ + tmp2 = _mm256_blend_epi32(D0, D1, 0x33); \ + D0 = _mm256_permute4x64_epi64(tmp1, _MM_SHUFFLE(2,3,0,1)); \ + D1 = _mm256_permute4x64_epi64(tmp2, _MM_SHUFFLE(2,3,0,1)); \ + } while(0); + +#define UNDIAGONALIZE_1(A0, B0, C0, D0, A1, B1, C1, D1) \ + do { \ + B0 = _mm256_permute4x64_epi64(B0, _MM_SHUFFLE(2, 1, 0, 3)); \ + C0 = _mm256_permute4x64_epi64(C0, _MM_SHUFFLE(1, 0, 3, 2)); \ + D0 = _mm256_permute4x64_epi64(D0, _MM_SHUFFLE(0, 3, 2, 1)); \ + \ + B1 = _mm256_permute4x64_epi64(B1, _MM_SHUFFLE(2, 1, 0, 3)); \ + C1 = _mm256_permute4x64_epi64(C1, _MM_SHUFFLE(1, 0, 3, 2)); \ + D1 = _mm256_permute4x64_epi64(D1, _MM_SHUFFLE(0, 3, 2, 1)); \ + } while((void)0, 0); + +#define UNDIAGONALIZE_2(A0, A1, B0, B1, C0, C1, D0, D1) \ + do { \ + __m256i tmp1 = _mm256_blend_epi32(B0, B1, 0xCC); \ + __m256i tmp2 = _mm256_blend_epi32(B0, B1, 0x33); \ + B0 = _mm256_permute4x64_epi64(tmp1, _MM_SHUFFLE(2,3,0,1)); \ + B1 = _mm256_permute4x64_epi64(tmp2, _MM_SHUFFLE(2,3,0,1)); \ + \ + tmp1 = C0; \ + C0 = C1; \ + C1 = tmp1; \ + \ + tmp1 = _mm256_blend_epi32(D0, D1, 0x33); \ + tmp2 = _mm256_blend_epi32(D0, D1, 0xCC); \ + D0 = _mm256_permute4x64_epi64(tmp1, _MM_SHUFFLE(2,3,0,1)); \ + D1 = _mm256_permute4x64_epi64(tmp2, _MM_SHUFFLE(2,3,0,1)); \ + } while((void)0, 0); + +#define BLAKE2_ROUND_1(A0, A1, B0, B1, C0, C1, D0, D1) \ + do{ \ + G1_AVX2(A0, A1, B0, B1, C0, C1, D0, D1) \ + G2_AVX2(A0, A1, B0, B1, C0, C1, D0, D1) \ + \ + DIAGONALIZE_1(A0, B0, C0, D0, A1, B1, C1, D1) \ + \ + G1_AVX2(A0, A1, B0, B1, C0, C1, D0, D1) \ + G2_AVX2(A0, A1, B0, B1, C0, C1, D0, D1) \ + \ + UNDIAGONALIZE_1(A0, B0, C0, D0, A1, B1, C1, D1) \ + } while((void)0, 0); + +#define BLAKE2_ROUND_2(A0, A1, B0, B1, C0, C1, D0, D1) \ + do{ \ + G1_AVX2(A0, A1, B0, B1, C0, C1, D0, D1) \ + G2_AVX2(A0, A1, B0, B1, C0, C1, D0, D1) \ + \ + DIAGONALIZE_2(A0, A1, B0, B1, C0, C1, D0, D1) \ + \ + G1_AVX2(A0, A1, B0, B1, C0, C1, D0, D1) \ + G2_AVX2(A0, A1, B0, B1, C0, C1, D0, D1) \ + \ + UNDIAGONALIZE_2(A0, A1, B0, B1, C0, C1, D0, D1) \ + } while((void)0, 0); + +#endif diff --git a/libs/libsodium/src/crypto_pwhash/argon2/blamka-round-avx512f.h b/libs/libsodium/src/crypto_pwhash/argon2/blamka-round-avx512f.h new file mode 100644 index 0000000000..9a822402d8 --- /dev/null +++ b/libs/libsodium/src/crypto_pwhash/argon2/blamka-round-avx512f.h @@ -0,0 +1,145 @@ +#ifndef blamka_round_avx512f_H +#define blamka_round_avx512f_H + +#include "private/common.h" +#include "private/sse2_64_32.h" + +#define ror64(x, n) _mm512_ror_epi64((x), (n)) + +static inline __m512i +muladd(__m512i x, __m512i y) +{ + __m512i z = _mm512_mul_epu32(x, y); + + return _mm512_add_epi64(_mm512_add_epi64(x, y), _mm512_add_epi64(z, z)); +} + +#define G1_AVX512F(A0, B0, C0, D0, A1, B1, C1, D1) \ + do { \ + A0 = muladd(A0, B0); \ + A1 = muladd(A1, B1); \ + \ + D0 = _mm512_xor_si512(D0, A0); \ + D1 = _mm512_xor_si512(D1, A1); \ + \ + D0 = ror64(D0, 32); \ + D1 = ror64(D1, 32); \ + \ + C0 = muladd(C0, D0); \ + C1 = muladd(C1, D1); \ + \ + B0 = _mm512_xor_si512(B0, C0); \ + B1 = _mm512_xor_si512(B1, C1); \ + \ + B0 = ror64(B0, 24); \ + B1 = ror64(B1, 24); \ + } while ((void)0, 0) + +#define G2_AVX512F(A0, B0, C0, D0, A1, B1, C1, D1) \ + do { \ + A0 = muladd(A0, B0); \ + A1 = muladd(A1, B1); \ + \ + D0 = _mm512_xor_si512(D0, A0); \ + D1 = _mm512_xor_si512(D1, A1); \ + \ + D0 = ror64(D0, 16); \ + D1 = ror64(D1, 16); \ + \ + C0 = muladd(C0, D0); \ + C1 = muladd(C1, D1); \ + \ + B0 = _mm512_xor_si512(B0, C0); \ + B1 = _mm512_xor_si512(B1, C1); \ + \ + B0 = ror64(B0, 63); \ + B1 = ror64(B1, 63); \ + } while ((void)0, 0) + +#define DIAGONALIZE(A0, B0, C0, D0, A1, B1, C1, D1) \ + do { \ + B0 = _mm512_permutex_epi64(B0, _MM_SHUFFLE(0, 3, 2, 1)); \ + B1 = _mm512_permutex_epi64(B1, _MM_SHUFFLE(0, 3, 2, 1)); \ + \ + C0 = _mm512_permutex_epi64(C0, _MM_SHUFFLE(1, 0, 3, 2)); \ + C1 = _mm512_permutex_epi64(C1, _MM_SHUFFLE(1, 0, 3, 2)); \ + \ + D0 = _mm512_permutex_epi64(D0, _MM_SHUFFLE(2, 1, 0, 3)); \ + D1 = _mm512_permutex_epi64(D1, _MM_SHUFFLE(2, 1, 0, 3)); \ + } while ((void)0, 0) + +#define UNDIAGONALIZE(A0, B0, C0, D0, A1, B1, C1, D1) \ + do { \ + B0 = _mm512_permutex_epi64(B0, _MM_SHUFFLE(2, 1, 0, 3)); \ + B1 = _mm512_permutex_epi64(B1, _MM_SHUFFLE(2, 1, 0, 3)); \ + \ + C0 = _mm512_permutex_epi64(C0, _MM_SHUFFLE(1, 0, 3, 2)); \ + C1 = _mm512_permutex_epi64(C1, _MM_SHUFFLE(1, 0, 3, 2)); \ + \ + D0 = _mm512_permutex_epi64(D0, _MM_SHUFFLE(0, 3, 2, 1)); \ + D1 = _mm512_permutex_epi64(D1, _MM_SHUFFLE(0, 3, 2, 1)); \ + } while ((void)0, 0) + +#define BLAKE2_ROUND(A0, B0, C0, D0, A1, B1, C1, D1) \ + do { \ + G1_AVX512F(A0, B0, C0, D0, A1, B1, C1, D1); \ + G2_AVX512F(A0, B0, C0, D0, A1, B1, C1, D1); \ + \ + DIAGONALIZE(A0, B0, C0, D0, A1, B1, C1, D1); \ + \ + G1_AVX512F(A0, B0, C0, D0, A1, B1, C1, D1); \ + G2_AVX512F(A0, B0, C0, D0, A1, B1, C1, D1); \ + \ + UNDIAGONALIZE(A0, B0, C0, D0, A1, B1, C1, D1); \ + } while ((void)0, 0) + +#define SWAP_HALVES(A0, A1) \ + do { \ + __m512i t0, t1; \ + t0 = _mm512_shuffle_i64x2(A0, A1, _MM_SHUFFLE(1, 0, 1, 0)); \ + t1 = _mm512_shuffle_i64x2(A0, A1, _MM_SHUFFLE(3, 2, 3, 2)); \ + A0 = t0; \ + A1 = t1; \ + } while((void)0, 0) + +#define SWAP_QUARTERS(A0, A1) \ + do { \ + SWAP_HALVES(A0, A1); \ + A0 = _mm512_permutexvar_epi64(_mm512_setr_epi64(0, 1, 4, 5, 2, 3, 6, 7), A0); \ + A1 = _mm512_permutexvar_epi64(_mm512_setr_epi64(0, 1, 4, 5, 2, 3, 6, 7), A1); \ + } while((void)0, 0) + +#define UNSWAP_QUARTERS(A0, A1) \ + do { \ + A0 = _mm512_permutexvar_epi64(_mm512_setr_epi64(0, 1, 4, 5, 2, 3, 6, 7), A0); \ + A1 = _mm512_permutexvar_epi64(_mm512_setr_epi64(0, 1, 4, 5, 2, 3, 6, 7), A1); \ + SWAP_HALVES(A0, A1); \ + } while((void)0, 0) + +#define BLAKE2_ROUND_1(A0, C0, B0, D0, A1, C1, B1, D1) \ + do { \ + SWAP_HALVES(A0, B0); \ + SWAP_HALVES(C0, D0); \ + SWAP_HALVES(A1, B1); \ + SWAP_HALVES(C1, D1); \ + BLAKE2_ROUND(A0, B0, C0, D0, A1, B1, C1, D1); \ + SWAP_HALVES(A0, B0); \ + SWAP_HALVES(C0, D0); \ + SWAP_HALVES(A1, B1); \ + SWAP_HALVES(C1, D1); \ + } while ((void)0, 0) + +#define BLAKE2_ROUND_2(A0, A1, B0, B1, C0, C1, D0, D1) \ + do { \ + SWAP_QUARTERS(A0, A1); \ + SWAP_QUARTERS(B0, B1); \ + SWAP_QUARTERS(C0, C1); \ + SWAP_QUARTERS(D0, D1); \ + BLAKE2_ROUND(A0, B0, C0, D0, A1, B1, C1, D1); \ + UNSWAP_QUARTERS(A0, A1); \ + UNSWAP_QUARTERS(B0, B1); \ + UNSWAP_QUARTERS(C0, C1); \ + UNSWAP_QUARTERS(D0, D1); \ + } while ((void)0, 0) + +#endif diff --git a/libs/libsodium/src/crypto_pwhash/argon2/blamka-round-ref.h b/libs/libsodium/src/crypto_pwhash/argon2/blamka-round-ref.h new file mode 100644 index 0000000000..7a2c6eb20e --- /dev/null +++ b/libs/libsodium/src/crypto_pwhash/argon2/blamka-round-ref.h @@ -0,0 +1,40 @@ +#ifndef blamka_round_ref_H +#define blamka_round_ref_H + +#include "private/common.h" + +/*designed by the Lyra PHC team */ +static inline uint64_t +fBlaMka(uint64_t x, uint64_t y) +{ + const uint64_t m = UINT64_C(0xFFFFFFFF); + const uint64_t xy = (x & m) * (y & m); + return x + y + 2 * xy; +} + +#define G(a, b, c, d) \ + do { \ + a = fBlaMka(a, b); \ + d = ROTR64(d ^ a, 32); \ + c = fBlaMka(c, d); \ + b = ROTR64(b ^ c, 24); \ + a = fBlaMka(a, b); \ + d = ROTR64(d ^ a, 16); \ + c = fBlaMka(c, d); \ + b = ROTR64(b ^ c, 63); \ + } while ((void) 0, 0) + +#define BLAKE2_ROUND_NOMSG(v0, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, \ + v12, v13, v14, v15) \ + do { \ + G(v0, v4, v8, v12); \ + G(v1, v5, v9, v13); \ + G(v2, v6, v10, v14); \ + G(v3, v7, v11, v15); \ + G(v0, v5, v10, v15); \ + G(v1, v6, v11, v12); \ + G(v2, v7, v8, v13); \ + G(v3, v4, v9, v14); \ + } while ((void) 0, 0) + +#endif diff --git a/libs/libsodium/src/crypto_pwhash/argon2/blamka-round-ssse3.h b/libs/libsodium/src/crypto_pwhash/argon2/blamka-round-ssse3.h new file mode 100644 index 0000000000..98a47b93f8 --- /dev/null +++ b/libs/libsodium/src/crypto_pwhash/argon2/blamka-round-ssse3.h @@ -0,0 +1,120 @@ +#ifndef blamka_round_ssse3_H +#define blamka_round_ssse3_H + +#include "private/common.h" +#include "private/sse2_64_32.h" + +#define r16 \ + (_mm_setr_epi8(2, 3, 4, 5, 6, 7, 0, 1, 10, 11, 12, 13, 14, 15, 8, 9)) +#define r24 \ + (_mm_setr_epi8(3, 4, 5, 6, 7, 0, 1, 2, 11, 12, 13, 14, 15, 8, 9, 10)) +#define _mm_roti_epi64(x, c) \ + (-(c) == 32) \ + ? _mm_shuffle_epi32((x), _MM_SHUFFLE(2, 3, 0, 1)) \ + : (-(c) == 24) \ + ? _mm_shuffle_epi8((x), r24) \ + : (-(c) == 16) \ + ? _mm_shuffle_epi8((x), r16) \ + : (-(c) == 63) \ + ? _mm_xor_si128(_mm_srli_epi64((x), -(c)), \ + _mm_add_epi64((x), (x))) \ + : _mm_xor_si128(_mm_srli_epi64((x), -(c)), \ + _mm_slli_epi64((x), 64 - (-(c)))) + +static inline __m128i +fBlaMka(__m128i x, __m128i y) +{ + const __m128i z = _mm_mul_epu32(x, y); + return _mm_add_epi64(_mm_add_epi64(x, y), _mm_add_epi64(z, z)); +} + +#define G1(A0, B0, C0, D0, A1, B1, C1, D1) \ + do { \ + A0 = fBlaMka(A0, B0); \ + A1 = fBlaMka(A1, B1); \ + \ + D0 = _mm_xor_si128(D0, A0); \ + D1 = _mm_xor_si128(D1, A1); \ + \ + D0 = _mm_roti_epi64(D0, -32); \ + D1 = _mm_roti_epi64(D1, -32); \ + \ + C0 = fBlaMka(C0, D0); \ + C1 = fBlaMka(C1, D1); \ + \ + B0 = _mm_xor_si128(B0, C0); \ + B1 = _mm_xor_si128(B1, C1); \ + \ + B0 = _mm_roti_epi64(B0, -24); \ + B1 = _mm_roti_epi64(B1, -24); \ + } while ((void) 0, 0) + +#define G2(A0, B0, C0, D0, A1, B1, C1, D1) \ + do { \ + A0 = fBlaMka(A0, B0); \ + A1 = fBlaMka(A1, B1); \ + \ + D0 = _mm_xor_si128(D0, A0); \ + D1 = _mm_xor_si128(D1, A1); \ + \ + D0 = _mm_roti_epi64(D0, -16); \ + D1 = _mm_roti_epi64(D1, -16); \ + \ + C0 = fBlaMka(C0, D0); \ + C1 = fBlaMka(C1, D1); \ + \ + B0 = _mm_xor_si128(B0, C0); \ + B1 = _mm_xor_si128(B1, C1); \ + \ + B0 = _mm_roti_epi64(B0, -63); \ + B1 = _mm_roti_epi64(B1, -63); \ + } while ((void) 0, 0) + +#define DIAGONALIZE(A0, B0, C0, D0, A1, B1, C1, D1) \ + do { \ + __m128i t0 = _mm_alignr_epi8(B1, B0, 8); \ + __m128i t1 = _mm_alignr_epi8(B0, B1, 8); \ + B0 = t0; \ + B1 = t1; \ + \ + t0 = C0; \ + C0 = C1; \ + C1 = t0; \ + \ + t0 = _mm_alignr_epi8(D1, D0, 8); \ + t1 = _mm_alignr_epi8(D0, D1, 8); \ + D0 = t1; \ + D1 = t0; \ + } while ((void) 0, 0) + +#define UNDIAGONALIZE(A0, B0, C0, D0, A1, B1, C1, D1) \ + do { \ + __m128i t0 = _mm_alignr_epi8(B0, B1, 8); \ + __m128i t1 = _mm_alignr_epi8(B1, B0, 8); \ + B0 = t0; \ + B1 = t1; \ + \ + t0 = C0; \ + C0 = C1; \ + C1 = t0; \ + \ + t0 = _mm_alignr_epi8(D0, D1, 8); \ + t1 = _mm_alignr_epi8(D1, D0, 8); \ + D0 = t1; \ + D1 = t0; \ + } while ((void) 0, 0) + +#define BLAKE2_ROUND(A0, A1, B0, B1, C0, C1, D0, D1) \ + do { \ + G1(A0, B0, C0, D0, A1, B1, C1, D1); \ + G2(A0, B0, C0, D0, A1, B1, C1, D1); \ + \ + DIAGONALIZE(A0, B0, C0, D0, A1, B1, C1, D1); \ + \ + G1(A0, B0, C0, D0, A1, B1, C1, D1); \ + G2(A0, B0, C0, D0, A1, B1, C1, D1); \ + \ + UNDIAGONALIZE(A0, B0, C0, D0, A1, B1, C1, D1); \ + } while ((void) 0, 0) + +#endif diff --git a/libs/libsodium/src/crypto_pwhash/argon2/pwhash_argon2i.c b/libs/libsodium/src/crypto_pwhash/argon2/pwhash_argon2i.c new file mode 100644 index 0000000000..0515bd6135 --- /dev/null +++ b/libs/libsodium/src/crypto_pwhash/argon2/pwhash_argon2i.c @@ -0,0 +1,290 @@ + +#include <errno.h> +#include <limits.h> +#include <stddef.h> +#include <stdint.h> +#include <stdlib.h> +#include <string.h> + +#include "argon2-core.h" +#include "argon2-encoding.h" +#include "argon2.h" +#include "crypto_pwhash.h" +#include "crypto_pwhash_argon2i.h" +#include "crypto_pwhash_argon2id.h" +#include "private/common.h" +#include "randombytes.h" +#include "utils.h" + +#define STR_HASHBYTES 32U + +int +crypto_pwhash_argon2i_alg_argon2i13(void) +{ + return crypto_pwhash_argon2i_ALG_ARGON2I13; +} + +size_t +crypto_pwhash_argon2i_bytes_min(void) +{ + COMPILER_ASSERT(crypto_pwhash_argon2i_BYTES_MIN >= ARGON2_MIN_OUTLEN); + return crypto_pwhash_argon2i_BYTES_MIN; +} + +size_t +crypto_pwhash_argon2i_bytes_max(void) +{ + COMPILER_ASSERT(crypto_pwhash_argon2i_BYTES_MAX <= ARGON2_MAX_OUTLEN); + return crypto_pwhash_argon2i_BYTES_MAX; +} + +size_t +crypto_pwhash_argon2i_passwd_min(void) +{ + COMPILER_ASSERT(crypto_pwhash_argon2i_PASSWD_MIN >= ARGON2_MIN_PWD_LENGTH); + return crypto_pwhash_argon2i_PASSWD_MIN; +} + +size_t +crypto_pwhash_argon2i_passwd_max(void) +{ + COMPILER_ASSERT(crypto_pwhash_argon2i_PASSWD_MAX <= ARGON2_MAX_PWD_LENGTH); + return crypto_pwhash_argon2i_PASSWD_MAX; +} + +size_t +crypto_pwhash_argon2i_saltbytes(void) +{ + COMPILER_ASSERT(crypto_pwhash_argon2i_SALTBYTES >= ARGON2_MIN_SALT_LENGTH); + COMPILER_ASSERT(crypto_pwhash_argon2i_SALTBYTES <= ARGON2_MAX_SALT_LENGTH); + return crypto_pwhash_argon2i_SALTBYTES; +} + +size_t +crypto_pwhash_argon2i_strbytes(void) +{ + return crypto_pwhash_argon2i_STRBYTES; +} + +const char* +crypto_pwhash_argon2i_strprefix(void) +{ + return crypto_pwhash_argon2i_STRPREFIX; +} + +size_t +crypto_pwhash_argon2i_opslimit_min(void) +{ + COMPILER_ASSERT(crypto_pwhash_argon2i_OPSLIMIT_MIN >= ARGON2_MIN_TIME); + return crypto_pwhash_argon2i_OPSLIMIT_MIN; +} + +size_t +crypto_pwhash_argon2i_opslimit_max(void) +{ + COMPILER_ASSERT(crypto_pwhash_argon2i_OPSLIMIT_MAX <= ARGON2_MAX_TIME); + return crypto_pwhash_argon2i_OPSLIMIT_MAX; +} + +size_t +crypto_pwhash_argon2i_memlimit_min(void) +{ + COMPILER_ASSERT((crypto_pwhash_argon2i_MEMLIMIT_MIN / 1024U) >= ARGON2_MIN_MEMORY); + return crypto_pwhash_argon2i_MEMLIMIT_MIN; +} + +size_t +crypto_pwhash_argon2i_memlimit_max(void) +{ + COMPILER_ASSERT((crypto_pwhash_argon2i_MEMLIMIT_MAX / 1024U) <= ARGON2_MAX_MEMORY); + return crypto_pwhash_argon2i_MEMLIMIT_MAX; +} + +size_t +crypto_pwhash_argon2i_opslimit_interactive(void) +{ + return crypto_pwhash_argon2i_OPSLIMIT_INTERACTIVE; +} + +size_t +crypto_pwhash_argon2i_memlimit_interactive(void) +{ + return crypto_pwhash_argon2i_MEMLIMIT_INTERACTIVE; +} + +size_t +crypto_pwhash_argon2i_opslimit_moderate(void) +{ + return crypto_pwhash_argon2i_OPSLIMIT_MODERATE; +} + +size_t +crypto_pwhash_argon2i_memlimit_moderate(void) +{ + return crypto_pwhash_argon2i_MEMLIMIT_MODERATE; +} + +size_t +crypto_pwhash_argon2i_opslimit_sensitive(void) +{ + return crypto_pwhash_argon2i_OPSLIMIT_SENSITIVE; +} + +size_t +crypto_pwhash_argon2i_memlimit_sensitive(void) +{ + return crypto_pwhash_argon2i_MEMLIMIT_SENSITIVE; +} + +int +crypto_pwhash_argon2i(unsigned char *const out, unsigned long long outlen, + const char *const passwd, unsigned long long passwdlen, + const unsigned char *const salt, + unsigned long long opslimit, size_t memlimit, int alg) +{ + memset(out, 0, outlen); + if (outlen > crypto_pwhash_argon2i_BYTES_MAX) { + errno = EFBIG; + return -1; + } + if (outlen < crypto_pwhash_argon2i_BYTES_MIN) { + errno = EINVAL; + return -1; + } + if (passwdlen > crypto_pwhash_argon2i_PASSWD_MAX || + opslimit > crypto_pwhash_argon2i_OPSLIMIT_MAX || + memlimit > crypto_pwhash_argon2i_MEMLIMIT_MAX) { + errno = EFBIG; + return -1; + } + if (passwdlen < crypto_pwhash_argon2i_PASSWD_MIN || + opslimit < crypto_pwhash_argon2i_OPSLIMIT_MIN || + memlimit < crypto_pwhash_argon2i_MEMLIMIT_MIN) { + errno = EINVAL; + return -1; + } + switch (alg) { + case crypto_pwhash_argon2i_ALG_ARGON2I13: + if (argon2i_hash_raw((uint32_t) opslimit, (uint32_t) (memlimit / 1024U), + (uint32_t) 1U, passwd, (size_t) passwdlen, salt, + (size_t) crypto_pwhash_argon2i_SALTBYTES, out, + (size_t) outlen) != ARGON2_OK) { + return -1; /* LCOV_EXCL_LINE */ + } + return 0; + default: + errno = EINVAL; + return -1; + } +} + +int +crypto_pwhash_argon2i_str(char out[crypto_pwhash_argon2i_STRBYTES], + const char *const passwd, + unsigned long long passwdlen, + unsigned long long opslimit, size_t memlimit) +{ + unsigned char salt[crypto_pwhash_argon2i_SALTBYTES]; + + memset(out, 0, crypto_pwhash_argon2i_STRBYTES); + if (passwdlen > crypto_pwhash_argon2i_PASSWD_MAX || + opslimit > crypto_pwhash_argon2i_OPSLIMIT_MAX || + memlimit > crypto_pwhash_argon2i_MEMLIMIT_MAX) { + errno = EFBIG; + return -1; + } + if (passwdlen < crypto_pwhash_argon2i_PASSWD_MIN || + opslimit < crypto_pwhash_argon2i_OPSLIMIT_MIN || + memlimit < crypto_pwhash_argon2i_MEMLIMIT_MIN) { + errno = EINVAL; + return -1; + } + randombytes_buf(salt, sizeof salt); + if (argon2i_hash_encoded((uint32_t) opslimit, (uint32_t) (memlimit / 1024U), + (uint32_t) 1U, passwd, (size_t) passwdlen, salt, + sizeof salt, STR_HASHBYTES, out, + crypto_pwhash_argon2i_STRBYTES) != ARGON2_OK) { + return -1; /* LCOV_EXCL_LINE */ + } + return 0; +} + +int +crypto_pwhash_argon2i_str_verify(const char str[crypto_pwhash_argon2i_STRBYTES], + const char *const passwd, + unsigned long long passwdlen) +{ + int verify_ret; + + if (passwdlen > crypto_pwhash_argon2i_PASSWD_MAX) { + errno = EFBIG; + return -1; + } + /* LCOV_EXCL_START */ + if (passwdlen < crypto_pwhash_argon2i_PASSWD_MIN) { + errno = EINVAL; + return -1; + } + /* LCOV_EXCL_STOP */ + + verify_ret = argon2i_verify(str, passwd, (size_t) passwdlen); + if (verify_ret == ARGON2_OK) { + return 0; + } + if (verify_ret == ARGON2_VERIFY_MISMATCH) { + errno = EINVAL; + } + return -1; +} + +static int +_needs_rehash(const char *str, unsigned long long opslimit, size_t memlimit, + argon2_type type) +{ + unsigned char *fodder; + argon2_context ctx; + size_t fodder_len; + int ret = -1; + + fodder_len = strlen(str); + memlimit /= 1024U; + if (opslimit > UINT32_MAX || memlimit > UINT32_MAX || + fodder_len >= crypto_pwhash_STRBYTES) { + errno = EINVAL; + return -1; + } + memset(&ctx, 0, sizeof ctx); + if ((fodder = (unsigned char *) calloc(fodder_len, 1U)) == NULL) { + return -1; /* LCOV_EXCL_LINE */ + } + ctx.out = ctx.pwd = ctx.salt = fodder; + ctx.outlen = ctx.pwdlen = ctx.saltlen = (uint32_t) fodder_len; + ctx.ad = ctx.secret = NULL; + ctx.adlen = ctx.secretlen = 0U; + if (decode_string(&ctx, str, type) != 0) { + errno = EINVAL; + ret = -1; + } else if (ctx.t_cost != (uint32_t) opslimit || + ctx.m_cost != (uint32_t) memlimit) { + ret = 1; + } else { + ret = 0; + } + free(fodder); + + return ret; +} + +int +crypto_pwhash_argon2i_str_needs_rehash(const char str[crypto_pwhash_argon2i_STRBYTES], + unsigned long long opslimit, size_t memlimit) +{ + return _needs_rehash(str, opslimit, memlimit, Argon2_i); +} + +int +crypto_pwhash_argon2id_str_needs_rehash(const char str[crypto_pwhash_argon2id_STRBYTES], + unsigned long long opslimit, size_t memlimit) +{ + return _needs_rehash(str, opslimit, memlimit, Argon2_id); +} diff --git a/libs/libsodium/src/crypto_pwhash/argon2/pwhash_argon2id.c b/libs/libsodium/src/crypto_pwhash/argon2/pwhash_argon2id.c new file mode 100644 index 0000000000..99d3e219bf --- /dev/null +++ b/libs/libsodium/src/crypto_pwhash/argon2/pwhash_argon2id.c @@ -0,0 +1,234 @@ + +#include <errno.h> +#include <limits.h> +#include <stddef.h> +#include <stdint.h> +#include <string.h> + +#include "argon2-core.h" +#include "argon2.h" +#include "crypto_pwhash_argon2id.h" +#include "private/common.h" +#include "randombytes.h" +#include "utils.h" + +#define STR_HASHBYTES 32U + +int +crypto_pwhash_argon2id_alg_argon2id13(void) +{ + return crypto_pwhash_argon2id_ALG_ARGON2ID13; +} + +size_t +crypto_pwhash_argon2id_bytes_min(void) +{ + COMPILER_ASSERT(crypto_pwhash_argon2id_BYTES_MIN >= ARGON2_MIN_OUTLEN); + return crypto_pwhash_argon2id_BYTES_MIN; +} + +size_t +crypto_pwhash_argon2id_bytes_max(void) +{ + COMPILER_ASSERT(crypto_pwhash_argon2id_BYTES_MAX <= ARGON2_MAX_OUTLEN); + return crypto_pwhash_argon2id_BYTES_MAX; +} + +size_t +crypto_pwhash_argon2id_passwd_min(void) +{ + COMPILER_ASSERT(crypto_pwhash_argon2id_PASSWD_MIN >= ARGON2_MIN_PWD_LENGTH); + return crypto_pwhash_argon2id_PASSWD_MIN; +} + +size_t +crypto_pwhash_argon2id_passwd_max(void) +{ + COMPILER_ASSERT(crypto_pwhash_argon2id_PASSWD_MAX <= ARGON2_MAX_PWD_LENGTH); + return crypto_pwhash_argon2id_PASSWD_MAX; +} + +size_t +crypto_pwhash_argon2id_saltbytes(void) +{ + COMPILER_ASSERT(crypto_pwhash_argon2id_SALTBYTES >= ARGON2_MIN_SALT_LENGTH); + COMPILER_ASSERT(crypto_pwhash_argon2id_SALTBYTES <= ARGON2_MAX_SALT_LENGTH); + return crypto_pwhash_argon2id_SALTBYTES; +} + +size_t +crypto_pwhash_argon2id_strbytes(void) +{ + return crypto_pwhash_argon2id_STRBYTES; +} + +const char* +crypto_pwhash_argon2id_strprefix(void) +{ + return crypto_pwhash_argon2id_STRPREFIX; +} + +size_t +crypto_pwhash_argon2id_opslimit_min(void) +{ + COMPILER_ASSERT(crypto_pwhash_argon2id_OPSLIMIT_MIN >= ARGON2_MIN_TIME); + return crypto_pwhash_argon2id_OPSLIMIT_MIN; +} + +size_t +crypto_pwhash_argon2id_opslimit_max(void) +{ + COMPILER_ASSERT(crypto_pwhash_argon2id_OPSLIMIT_MAX <= ARGON2_MAX_TIME); + return crypto_pwhash_argon2id_OPSLIMIT_MAX; +} + +size_t +crypto_pwhash_argon2id_memlimit_min(void) +{ + COMPILER_ASSERT((crypto_pwhash_argon2id_MEMLIMIT_MIN / 1024U) >= ARGON2_MIN_MEMORY); + return crypto_pwhash_argon2id_MEMLIMIT_MIN; +} + +size_t +crypto_pwhash_argon2id_memlimit_max(void) +{ + COMPILER_ASSERT((crypto_pwhash_argon2id_MEMLIMIT_MAX / 1024U) <= ARGON2_MAX_MEMORY); + return crypto_pwhash_argon2id_MEMLIMIT_MAX; +} + +size_t +crypto_pwhash_argon2id_opslimit_interactive(void) +{ + return crypto_pwhash_argon2id_OPSLIMIT_INTERACTIVE; +} + +size_t +crypto_pwhash_argon2id_memlimit_interactive(void) +{ + return crypto_pwhash_argon2id_MEMLIMIT_INTERACTIVE; +} + +size_t +crypto_pwhash_argon2id_opslimit_moderate(void) +{ + return crypto_pwhash_argon2id_OPSLIMIT_MODERATE; +} + +size_t +crypto_pwhash_argon2id_memlimit_moderate(void) +{ + return crypto_pwhash_argon2id_MEMLIMIT_MODERATE; +} + +size_t +crypto_pwhash_argon2id_opslimit_sensitive(void) +{ + return crypto_pwhash_argon2id_OPSLIMIT_SENSITIVE; +} + +size_t +crypto_pwhash_argon2id_memlimit_sensitive(void) +{ + return crypto_pwhash_argon2id_MEMLIMIT_SENSITIVE; +} + +int +crypto_pwhash_argon2id(unsigned char *const out, unsigned long long outlen, + const char *const passwd, unsigned long long passwdlen, + const unsigned char *const salt, + unsigned long long opslimit, size_t memlimit, int alg) +{ + memset(out, 0, outlen); + if (outlen > crypto_pwhash_argon2id_BYTES_MAX) { + errno = EFBIG; + return -1; + } + if (outlen < crypto_pwhash_argon2id_BYTES_MIN) { + errno = EINVAL; + return -1; + } + if (passwdlen > crypto_pwhash_argon2id_PASSWD_MAX || + opslimit > crypto_pwhash_argon2id_OPSLIMIT_MAX || + memlimit > crypto_pwhash_argon2id_MEMLIMIT_MAX) { + errno = EFBIG; + return -1; + } + if (passwdlen < crypto_pwhash_argon2id_PASSWD_MIN || + opslimit < crypto_pwhash_argon2id_OPSLIMIT_MIN || + memlimit < crypto_pwhash_argon2id_MEMLIMIT_MIN) { + errno = EINVAL; + return -1; + } + switch (alg) { + case crypto_pwhash_argon2id_ALG_ARGON2ID13: + if (argon2id_hash_raw((uint32_t) opslimit, (uint32_t) (memlimit / 1024U), + (uint32_t) 1U, passwd, (size_t) passwdlen, salt, + (size_t) crypto_pwhash_argon2id_SALTBYTES, out, + (size_t) outlen) != ARGON2_OK) { + return -1; /* LCOV_EXCL_LINE */ + } + return 0; + default: + errno = EINVAL; + return -1; + } +} + +int +crypto_pwhash_argon2id_str(char out[crypto_pwhash_argon2id_STRBYTES], + const char *const passwd, + unsigned long long passwdlen, + unsigned long long opslimit, size_t memlimit) +{ + unsigned char salt[crypto_pwhash_argon2id_SALTBYTES]; + + memset(out, 0, crypto_pwhash_argon2id_STRBYTES); + if (passwdlen > crypto_pwhash_argon2id_PASSWD_MAX || + opslimit > crypto_pwhash_argon2id_OPSLIMIT_MAX || + memlimit > crypto_pwhash_argon2id_MEMLIMIT_MAX) { + errno = EFBIG; + return -1; + } + if (passwdlen < crypto_pwhash_argon2id_PASSWD_MIN || + opslimit < crypto_pwhash_argon2id_OPSLIMIT_MIN || + memlimit < crypto_pwhash_argon2id_MEMLIMIT_MIN) { + errno = EINVAL; + return -1; + } + randombytes_buf(salt, sizeof salt); + if (argon2id_hash_encoded((uint32_t) opslimit, (uint32_t) (memlimit / 1024U), + (uint32_t) 1U, passwd, (size_t) passwdlen, salt, + sizeof salt, STR_HASHBYTES, out, + crypto_pwhash_argon2id_STRBYTES) != ARGON2_OK) { + return -1; /* LCOV_EXCL_LINE */ + } + return 0; +} + +int +crypto_pwhash_argon2id_str_verify(const char str[crypto_pwhash_argon2id_STRBYTES], + const char *const passwd, + unsigned long long passwdlen) +{ + int verify_ret; + + if (passwdlen > crypto_pwhash_argon2id_PASSWD_MAX) { + errno = EFBIG; + return -1; + } + /* LCOV_EXCL_START */ + if (passwdlen < crypto_pwhash_argon2id_PASSWD_MIN) { + errno = EINVAL; + return -1; + } + /* LCOV_EXCL_STOP */ + + verify_ret = argon2id_verify(str, passwd, (size_t) passwdlen); + if (verify_ret == ARGON2_OK) { + return 0; + } + if (verify_ret == ARGON2_VERIFY_MISMATCH) { + errno = EINVAL; + } + return -1; +} diff --git a/libs/libsodium/src/crypto_pwhash/crypto_pwhash.c b/libs/libsodium/src/crypto_pwhash/crypto_pwhash.c new file mode 100644 index 0000000000..8168f96216 --- /dev/null +++ b/libs/libsodium/src/crypto_pwhash/crypto_pwhash.c @@ -0,0 +1,211 @@ + +#include <errno.h> +#include <string.h> + +#include "core.h" +#include "crypto_pwhash.h" + +int +crypto_pwhash_alg_argon2i13(void) +{ + return crypto_pwhash_ALG_ARGON2I13; +} + +int +crypto_pwhash_alg_argon2id13(void) +{ + return crypto_pwhash_ALG_ARGON2ID13; +} + +int +crypto_pwhash_alg_default(void) +{ + return crypto_pwhash_ALG_DEFAULT; +} + +size_t +crypto_pwhash_bytes_min(void) +{ + return crypto_pwhash_BYTES_MIN; +} + +size_t +crypto_pwhash_bytes_max(void) +{ + return crypto_pwhash_BYTES_MAX; +} + +size_t +crypto_pwhash_passwd_min(void) +{ + return crypto_pwhash_PASSWD_MIN; +} + +size_t +crypto_pwhash_passwd_max(void) +{ + return crypto_pwhash_PASSWD_MAX; +} + +size_t +crypto_pwhash_saltbytes(void) +{ + return crypto_pwhash_SALTBYTES; +} + +size_t +crypto_pwhash_strbytes(void) +{ + return crypto_pwhash_STRBYTES; +} + +const char * +crypto_pwhash_strprefix(void) +{ + return crypto_pwhash_STRPREFIX; +} + +size_t +crypto_pwhash_opslimit_min(void) +{ + return crypto_pwhash_OPSLIMIT_MIN; +} + +size_t +crypto_pwhash_opslimit_max(void) +{ + return crypto_pwhash_OPSLIMIT_MAX; +} + +size_t +crypto_pwhash_memlimit_min(void) +{ + return crypto_pwhash_MEMLIMIT_MIN; +} + +size_t +crypto_pwhash_memlimit_max(void) +{ + return crypto_pwhash_MEMLIMIT_MAX; +} + +size_t +crypto_pwhash_opslimit_interactive(void) +{ + return crypto_pwhash_OPSLIMIT_INTERACTIVE; +} + +size_t +crypto_pwhash_memlimit_interactive(void) +{ + return crypto_pwhash_MEMLIMIT_INTERACTIVE; +} + +size_t +crypto_pwhash_opslimit_moderate(void) +{ + return crypto_pwhash_OPSLIMIT_MODERATE; +} + +size_t +crypto_pwhash_memlimit_moderate(void) +{ + return crypto_pwhash_MEMLIMIT_MODERATE; +} + +size_t +crypto_pwhash_opslimit_sensitive(void) +{ + return crypto_pwhash_OPSLIMIT_SENSITIVE; +} + +size_t +crypto_pwhash_memlimit_sensitive(void) +{ + return crypto_pwhash_MEMLIMIT_SENSITIVE; +} + +int +crypto_pwhash(unsigned char * const out, unsigned long long outlen, + const char * const passwd, unsigned long long passwdlen, + const unsigned char * const salt, + unsigned long long opslimit, size_t memlimit, int alg) +{ + switch (alg) { + case crypto_pwhash_ALG_ARGON2I13: + return crypto_pwhash_argon2i(out, outlen, passwd, passwdlen, salt, + opslimit, memlimit, alg); + case crypto_pwhash_ALG_ARGON2ID13: + return crypto_pwhash_argon2id(out, outlen, passwd, passwdlen, salt, + opslimit, memlimit, alg); + default: + errno = EINVAL; + return -1; + } +} + +int +crypto_pwhash_str(char out[crypto_pwhash_STRBYTES], + const char * const passwd, unsigned long long passwdlen, + unsigned long long opslimit, size_t memlimit) +{ + return crypto_pwhash_argon2id_str(out, passwd, passwdlen, + opslimit, memlimit); +} + +int +crypto_pwhash_str_alg(char out[crypto_pwhash_STRBYTES], + const char * const passwd, unsigned long long passwdlen, + unsigned long long opslimit, size_t memlimit, int alg) +{ + switch (alg) { + case crypto_pwhash_ALG_ARGON2I13: + return crypto_pwhash_argon2i_str(out, passwd, passwdlen, + opslimit, memlimit); + case crypto_pwhash_ALG_ARGON2ID13: + return crypto_pwhash_argon2id_str(out, passwd, passwdlen, + opslimit, memlimit); + } + sodium_misuse(); + /* NOTREACHED */ +} + +int +crypto_pwhash_str_verify(const char str[crypto_pwhash_STRBYTES], + const char * const passwd, + unsigned long long passwdlen) +{ + if (strncmp(str, crypto_pwhash_argon2id_STRPREFIX, + sizeof crypto_pwhash_argon2id_STRPREFIX - 1) == 0) { + return crypto_pwhash_argon2id_str_verify(str, passwd, passwdlen); + } + if (strncmp(str, crypto_pwhash_argon2i_STRPREFIX, + sizeof crypto_pwhash_argon2i_STRPREFIX - 1) == 0) { + return crypto_pwhash_argon2i_str_verify(str, passwd, passwdlen); + } + errno = EINVAL; + + return -1; +} + +int +crypto_pwhash_str_needs_rehash(const char str[crypto_pwhash_STRBYTES], + unsigned long long opslimit, size_t memlimit) +{ + if (strncmp(str, crypto_pwhash_argon2id_STRPREFIX, + sizeof crypto_pwhash_argon2id_STRPREFIX - 1) == 0) { + return crypto_pwhash_argon2id_str_needs_rehash(str, opslimit, memlimit); + } + if (strncmp(str, crypto_pwhash_argon2i_STRPREFIX, + sizeof crypto_pwhash_argon2i_STRPREFIX - 1) == 0) { + return crypto_pwhash_argon2i_str_needs_rehash(str, opslimit, memlimit); + } + errno = EINVAL; + + return -1; +} + +const char * +crypto_pwhash_primitive(void) { + return crypto_pwhash_PRIMITIVE; +} diff --git a/libs/libsodium/src/crypto_pwhash/scryptsalsa208sha256/crypto_scrypt-common.c b/libs/libsodium/src/crypto_pwhash/scryptsalsa208sha256/crypto_scrypt-common.c new file mode 100644 index 0000000000..e15e12b294 --- /dev/null +++ b/libs/libsodium/src/crypto_pwhash/scryptsalsa208sha256/crypto_scrypt-common.c @@ -0,0 +1,263 @@ +/*- + * Copyright 2013 Alexander Peslyak + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include <stdint.h> +#include <string.h> + +#include "crypto_pwhash_scryptsalsa208sha256.h" +#include "crypto_scrypt.h" +#include "private/common.h" +#include "runtime.h" +#include "utils.h" + +static const char *const itoa64 = + "./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"; + +static uint8_t * +encode64_uint32(uint8_t *dst, size_t dstlen, uint32_t src, uint32_t srcbits) +{ + uint32_t bit; + + for (bit = 0; bit < srcbits; bit += 6) { + if (dstlen < 1) { + return NULL; /* LCOV_EXCL_LINE */ + } + *dst++ = itoa64[src & 0x3f]; + dstlen--; + src >>= 6; + } + return dst; +} + +static uint8_t * +encode64(uint8_t *dst, size_t dstlen, const uint8_t *src, size_t srclen) +{ + size_t i; + + for (i = 0; i < srclen;) { + uint8_t *dnext; + uint32_t value = 0, bits = 0; + + do { + value |= (uint32_t) src[i++] << bits; + bits += 8; + } while (bits < 24 && i < srclen); + + dnext = encode64_uint32(dst, dstlen, value, bits); + if (!dnext) { + return NULL; /* LCOV_EXCL_LINE */ + } + dstlen -= dnext - dst; + dst = dnext; + } + return dst; +} + +static int +decode64_one(uint32_t *dst, uint8_t src) +{ + const char *ptr = strchr(itoa64, src); + + if (ptr) { + *dst = (uint32_t)(ptr - itoa64); + return 0; + } + *dst = 0; + + return -1; +} + +static const uint8_t * +decode64_uint32(uint32_t *dst, uint32_t dstbits, const uint8_t *src) +{ + uint32_t bit; + uint32_t value; + + value = 0; + for (bit = 0; bit < dstbits; bit += 6) { + uint32_t one; + if (decode64_one(&one, *src)) { + *dst = 0; + return NULL; + } + src++; + value |= one << bit; + } + *dst = value; + + return src; +} + +const uint8_t * +escrypt_parse_setting(const uint8_t *setting, + uint32_t *N_log2_p, uint32_t *r_p, uint32_t *p_p) +{ + const uint8_t *src; + + if (setting[0] != '$' || setting[1] != '7' || setting[2] != '$') { + return NULL; + } + src = setting + 3; + + if (decode64_one(N_log2_p, *src)) { + return NULL; + } + src++; + + src = decode64_uint32(r_p, 30, src); + if (!src) { + return NULL; + } + + src = decode64_uint32(p_p, 30, src); + if (!src) { + return NULL; + } + return src; +} + +uint8_t * +escrypt_r(escrypt_local_t *local, const uint8_t *passwd, size_t passwdlen, + const uint8_t *setting, uint8_t *buf, size_t buflen) +{ + uint8_t hash[crypto_pwhash_scryptsalsa208sha256_STRHASHBYTES]; + escrypt_kdf_t escrypt_kdf; + const uint8_t *src; + const uint8_t *salt; + uint8_t *dst; + size_t prefixlen; + size_t saltlen; + size_t need; + uint64_t N; + uint32_t N_log2; + uint32_t r; + uint32_t p; + + src = escrypt_parse_setting(setting, &N_log2, &r, &p); + if (!src) { + return NULL; + } + N = (uint64_t) 1 << N_log2; + prefixlen = src - setting; + + salt = src; + src = (uint8_t *) strrchr((char *) salt, '$'); + if (src) { + saltlen = src - salt; + } else { + saltlen = strlen((char *) salt); + } + need = prefixlen + saltlen + 1 + + crypto_pwhash_scryptsalsa208sha256_STRHASHBYTES_ENCODED + 1; + if (need > buflen || need < saltlen) { + return NULL; + } +#ifdef HAVE_EMMINTRIN_H + escrypt_kdf = + sodium_runtime_has_sse2() ? escrypt_kdf_sse : escrypt_kdf_nosse; +#else + escrypt_kdf = escrypt_kdf_nosse; +#endif + if (escrypt_kdf(local, passwd, passwdlen, salt, saltlen, N, r, p, hash, + sizeof(hash))) { + return NULL; + } + dst = buf; + memcpy(dst, setting, prefixlen + saltlen); + dst += prefixlen + saltlen; + *dst++ = '$'; + + dst = encode64(dst, buflen - (dst - buf), hash, sizeof(hash)); + sodium_memzero(hash, sizeof hash); + if (!dst || dst >= buf + buflen) { + return NULL; /* Can't happen LCOV_EXCL_LINE */ + } + *dst = 0; /* NUL termination */ + + return buf; +} + +uint8_t * +escrypt_gensalt_r(uint32_t N_log2, uint32_t r, uint32_t p, const uint8_t *src, + size_t srclen, uint8_t *buf, size_t buflen) +{ + uint8_t *dst; + size_t prefixlen = + (sizeof "$7$" - 1U) + (1U /* N_log2 */) + (5U /* r */) + (5U /* p */); + size_t saltlen = BYTES2CHARS(srclen); + size_t need; + + need = prefixlen + saltlen + 1; + if (need > buflen || need < saltlen || saltlen < srclen) { + return NULL; /* LCOV_EXCL_LINE */ + } + if (N_log2 > 63 || ((uint64_t) r * (uint64_t) p >= (1U << 30))) { + return NULL; /* LCOV_EXCL_LINE */ + } + dst = buf; + *dst++ = '$'; + *dst++ = '7'; + *dst++ = '$'; + + *dst++ = itoa64[N_log2]; + + dst = encode64_uint32(dst, buflen - (dst - buf), r, 30); + if (!dst) { + return NULL; /* Can't happen LCOV_EXCL_LINE */ + } + dst = encode64_uint32(dst, buflen - (dst - buf), p, 30); + if (!dst) { + return NULL; /* Can't happen LCOV_EXCL_LINE */ + } + dst = encode64(dst, buflen - (dst - buf), src, srclen); + if (!dst || dst >= buf + buflen) { + return NULL; /* Can't happen LCOV_EXCL_LINE */ + } + *dst = 0; /* NUL termination */ + + return buf; +} + +int +crypto_pwhash_scryptsalsa208sha256_ll(const uint8_t *passwd, size_t passwdlen, + const uint8_t *salt, size_t saltlen, + uint64_t N, uint32_t r, uint32_t p, + uint8_t *buf, size_t buflen) +{ + escrypt_kdf_t escrypt_kdf; + escrypt_local_t local; + int retval; + + if (escrypt_init_local(&local)) { + return -1; /* LCOV_EXCL_LINE */ + } +#if defined(HAVE_EMMINTRIN_H) + escrypt_kdf = + sodium_runtime_has_sse2() ? escrypt_kdf_sse : escrypt_kdf_nosse; +#else + escrypt_kdf = escrypt_kdf_nosse; +#endif + retval = escrypt_kdf(&local, passwd, passwdlen, salt, saltlen, N, r, p, buf, + buflen); + if (escrypt_free_local(&local)) { + return -1; /* LCOV_EXCL_LINE */ + } + return retval; +} diff --git a/libs/libsodium/src/crypto_pwhash/scryptsalsa208sha256/crypto_scrypt.h b/libs/libsodium/src/crypto_pwhash/scryptsalsa208sha256/crypto_scrypt.h new file mode 100644 index 0000000000..83101967c3 --- /dev/null +++ b/libs/libsodium/src/crypto_pwhash/scryptsalsa208sha256/crypto_scrypt.h @@ -0,0 +1,98 @@ +/*- + * Copyright 2009 Colin Percival + * Copyright 2013 Alexander Peslyak + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file was originally written by Colin Percival as part of the Tarsnap + * online backup system. + */ +#ifndef crypto_scrypt_H +#define crypto_scrypt_H + +#include <limits.h> +#include <stddef.h> +#include <stdint.h> + +#if SIZE_MAX > 0xffffffffULL +#define ARCH_BITS 64 +#else +#define ARCH_BITS 32 +#endif + +#define crypto_pwhash_scryptsalsa208sha256_STRPREFIXBYTES 14 +#define crypto_pwhash_scryptsalsa208sha256_STRSETTINGBYTES 57 +#define crypto_pwhash_scryptsalsa208sha256_STRSALTBYTES 32 +#define crypto_pwhash_scryptsalsa208sha256_STRSALTBYTES_ENCODED 43 +#define crypto_pwhash_scryptsalsa208sha256_STRHASHBYTES 32 +#define crypto_pwhash_scryptsalsa208sha256_STRHASHBYTES_ENCODED 43 + +#define BYTES2CHARS(bytes) ((((bytes) *8) + 5) / 6) + +typedef struct { + void * base, *aligned; + size_t size; +} escrypt_region_t; + +typedef union { + uint64_t d[8]; + uint32_t w[16]; +} escrypt_block_t; + +typedef escrypt_region_t escrypt_local_t; + +extern int escrypt_init_local(escrypt_local_t *__local); + +extern int escrypt_free_local(escrypt_local_t *__local); + +extern void *alloc_region(escrypt_region_t *region, size_t size); +extern int free_region(escrypt_region_t *region); + +typedef int (*escrypt_kdf_t)(escrypt_local_t *__local, const uint8_t *__passwd, + size_t __passwdlen, const uint8_t *__salt, + size_t __saltlen, uint64_t __N, uint32_t __r, + uint32_t __p, uint8_t *__buf, size_t __buflen); + +extern int escrypt_kdf_nosse(escrypt_local_t *__local, const uint8_t *__passwd, + size_t __passwdlen, const uint8_t *__salt, + size_t __saltlen, uint64_t __N, uint32_t __r, + uint32_t __p, uint8_t *__buf, size_t __buflen); + +extern int escrypt_kdf_sse(escrypt_local_t *__local, const uint8_t *__passwd, + size_t __passwdlen, const uint8_t *__salt, + size_t __saltlen, uint64_t __N, uint32_t __r, + uint32_t __p, uint8_t *__buf, size_t __buflen); + +extern uint8_t *escrypt_r(escrypt_local_t *__local, const uint8_t *__passwd, + size_t __passwdlen, const uint8_t *__setting, + uint8_t *__buf, size_t __buflen); + +extern uint8_t *escrypt_gensalt_r(uint32_t __N_log2, uint32_t __r, uint32_t __p, + const uint8_t *__src, size_t __srclen, + uint8_t *__buf, size_t __buflen); + +extern const uint8_t *escrypt_parse_setting(const uint8_t *setting, + uint32_t *N_log2_p, uint32_t *r_p, + uint32_t *p_p); + +#endif /* !_CRYPTO_SCRYPT_H_ */ diff --git a/libs/libsodium/src/crypto_pwhash/scryptsalsa208sha256/nosse/pwhash_scryptsalsa208sha256_nosse.c b/libs/libsodium/src/crypto_pwhash/scryptsalsa208sha256/nosse/pwhash_scryptsalsa208sha256_nosse.c new file mode 100644 index 0000000000..9e31352dc2 --- /dev/null +++ b/libs/libsodium/src/crypto_pwhash/scryptsalsa208sha256/nosse/pwhash_scryptsalsa208sha256_nosse.c @@ -0,0 +1,375 @@ +/*- + * Copyright 2009 Colin Percival + * Copyright 2013 Alexander Peslyak + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file was originally written by Colin Percival as part of the Tarsnap + * online backup system. + */ + +#include <errno.h> +#include <limits.h> +#include <stdint.h> +#include <stdlib.h> +#include <string.h> + +#include "../crypto_scrypt.h" +#include "../pbkdf2-sha256.h" +#include "private/common.h" + +static inline void +blkcpy_64(escrypt_block_t *dest, const escrypt_block_t *src) +{ + int i; + +#if (ARCH_BITS == 32) + for (i = 0; i < 16; ++i) { + dest->w[i] = src->w[i]; + } +#else + for (i = 0; i < 8; ++i) { + dest->d[i] = src->d[i]; + } +#endif +} + +static inline void +blkxor_64(escrypt_block_t *dest, const escrypt_block_t *src) +{ + int i; + +#if (ARCH_BITS == 32) + for (i = 0; i < 16; ++i) { + dest->w[i] ^= src->w[i]; + } +#else + for (i = 0; i < 8; ++i) { + dest->d[i] ^= src->d[i]; + } +#endif +} + +static inline void +blkcpy(escrypt_block_t *dest, const escrypt_block_t *src, size_t len) +{ + size_t i, L; + +#if (ARCH_BITS == 32) + L = (len >> 2); + for (i = 0; i < L; ++i) { + dest->w[i] = src->w[i]; + } +#else + L = (len >> 3); + for (i = 0; i < L; ++i) { + dest->d[i] = src->d[i]; + } +#endif +} + +static inline void +blkxor(escrypt_block_t *dest, const escrypt_block_t *src, size_t len) +{ + size_t i, L; + +#if (ARCH_BITS == 32) + L = (len >> 2); + for (i = 0; i < L; ++i) { + dest->w[i] ^= src->w[i]; + } +#else + L = (len >> 3); + for (i = 0; i < L; ++i) { + dest->d[i] ^= src->d[i]; + } +#endif +} + +/** + * salsa20_8(B): + * Apply the salsa20/8 core to the provided block. + */ +static void +salsa20_8(uint32_t B[16]) +{ + escrypt_block_t X; + uint32_t *x = X.w; + size_t i; + + blkcpy_64(&X, (escrypt_block_t *) B); + for (i = 0; i < 8; i += 2) { +#define R(a, b) (((a) << (b)) | ((a) >> (32 - (b)))) + /* Operate on columns. */ + x[4] ^= R(x[0] + x[12], 7); + x[8] ^= R(x[4] + x[0], 9); + x[12] ^= R(x[8] + x[4], 13); + x[0] ^= R(x[12] + x[8], 18); + + x[9] ^= R(x[5] + x[1], 7); + x[13] ^= R(x[9] + x[5], 9); + x[1] ^= R(x[13] + x[9], 13); + x[5] ^= R(x[1] + x[13], 18); + + x[14] ^= R(x[10] + x[6], 7); + x[2] ^= R(x[14] + x[10], 9); + x[6] ^= R(x[2] + x[14], 13); + x[10] ^= R(x[6] + x[2], 18); + + x[3] ^= R(x[15] + x[11], 7); + x[7] ^= R(x[3] + x[15], 9); + x[11] ^= R(x[7] + x[3], 13); + x[15] ^= R(x[11] + x[7], 18); + + /* Operate on rows. */ + x[1] ^= R(x[0] + x[3], 7); + x[2] ^= R(x[1] + x[0], 9); + x[3] ^= R(x[2] + x[1], 13); + x[0] ^= R(x[3] + x[2], 18); + + x[6] ^= R(x[5] + x[4], 7); + x[7] ^= R(x[6] + x[5], 9); + x[4] ^= R(x[7] + x[6], 13); + x[5] ^= R(x[4] + x[7], 18); + + x[11] ^= R(x[10] + x[9], 7); + x[8] ^= R(x[11] + x[10], 9); + x[9] ^= R(x[8] + x[11], 13); + x[10] ^= R(x[9] + x[8], 18); + + x[12] ^= R(x[15] + x[14], 7); + x[13] ^= R(x[12] + x[15], 9); + x[14] ^= R(x[13] + x[12], 13); + x[15] ^= R(x[14] + x[13], 18); +#undef R + } + for (i = 0; i < 16; i++) + B[i] += x[i]; +} + +/** + * blockmix_salsa8(Bin, Bout, X, r): + * Compute Bout = BlockMix_{salsa20/8, r}(Bin). The input Bin must be 128r + * bytes in length; the output Bout must also be the same size. The + * temporary space X must be 64 bytes. + */ +static void +blockmix_salsa8(const uint32_t *Bin, uint32_t *Bout, uint32_t *X, size_t r) +{ + size_t i; + + /* 1: X <-- B_{2r - 1} */ + blkcpy_64((escrypt_block_t *) X, + (escrypt_block_t *) &Bin[(2 * r - 1) * 16]); + + /* 2: for i = 0 to 2r - 1 do */ + for (i = 0; i < 2 * r; i += 2) { + /* 3: X <-- H(X \xor B_i) */ + blkxor_64((escrypt_block_t *) X, (escrypt_block_t *) &Bin[i * 16]); + salsa20_8(X); + + /* 4: Y_i <-- X */ + /* 6: B' <-- (Y_0, Y_2 ... Y_{2r-2}, Y_1, Y_3 ... Y_{2r-1}) */ + blkcpy_64((escrypt_block_t *) &Bout[i * 8], (escrypt_block_t *) X); + + /* 3: X <-- H(X \xor B_i) */ + blkxor_64((escrypt_block_t *) X, (escrypt_block_t *) &Bin[i * 16 + 16]); + salsa20_8(X); + + /* 4: Y_i <-- X */ + /* 6: B' <-- (Y_0, Y_2 ... Y_{2r-2}, Y_1, Y_3 ... Y_{2r-1}) */ + blkcpy_64((escrypt_block_t *) &Bout[i * 8 + r * 16], + (escrypt_block_t *) X); + } +} + +/** + * integerify(B, r): + * Return the result of parsing B_{2r-1} as a little-endian integer. + */ +static inline uint64_t +integerify(const void *B, size_t r) +{ + const uint32_t *X = (const uint32_t *) ((uintptr_t)(B) + (2 * r - 1) * 64); + + return (((uint64_t)(X[1]) << 32) + X[0]); +} + +/** + * smix(B, r, N, V, XY): + * Compute B = SMix_r(B, N). The input B must be 128r bytes in length; + * the temporary storage V must be 128rN bytes in length; the temporary + * storage XY must be 256r + 64 bytes in length. The value N must be a + * power of 2 greater than 1. The arrays B, V, and XY must be aligned to a + * multiple of 64 bytes. + */ +static void +smix(uint8_t *B, size_t r, uint64_t N, uint32_t *V, uint32_t *XY) +{ + uint32_t *X = XY; + uint32_t *Y = &XY[32 * r]; + uint32_t *Z = &XY[64 * r]; + uint64_t i; + uint64_t j; + size_t k; + + /* 1: X <-- B */ + for (k = 0; k < 32 * r; k++) { + X[k] = LOAD32_LE(&B[4 * k]); + } + /* 2: for i = 0 to N - 1 do */ + for (i = 0; i < N; i += 2) { + /* 3: V_i <-- X */ + blkcpy((escrypt_block_t *) &V[i * (32 * r)], (escrypt_block_t *) X, + 128 * r); + + /* 4: X <-- H(X) */ + blockmix_salsa8(X, Y, Z, r); + + /* 3: V_i <-- X */ + blkcpy((escrypt_block_t *) &V[(i + 1) * (32 * r)], + (escrypt_block_t *) Y, 128 * r); + + /* 4: X <-- H(X) */ + blockmix_salsa8(Y, X, Z, r); + } + + /* 6: for i = 0 to N - 1 do */ + for (i = 0; i < N; i += 2) { + /* 7: j <-- Integerify(X) mod N */ + j = integerify(X, r) & (N - 1); + + /* 8: X <-- H(X \xor V_j) */ + blkxor((escrypt_block_t *) X, (escrypt_block_t *) &V[j * (32 * r)], + 128 * r); + blockmix_salsa8(X, Y, Z, r); + + /* 7: j <-- Integerify(X) mod N */ + j = integerify(Y, r) & (N - 1); + + /* 8: X <-- H(X \xor V_j) */ + blkxor((escrypt_block_t *) Y, (escrypt_block_t *) &V[j * (32 * r)], + 128 * r); + blockmix_salsa8(Y, X, Z, r); + } + /* 10: B' <-- X */ + for (k = 0; k < 32 * r; k++) { + STORE32_LE(&B[4 * k], X[k]); + } +} + +/** + * escrypt_kdf(local, passwd, passwdlen, salt, saltlen, + * N, r, p, buf, buflen): + * Compute scrypt(passwd[0 .. passwdlen - 1], salt[0 .. saltlen - 1], N, r, + * p, buflen) and write the result into buf. The parameters r, p, and buflen + * must satisfy r * p < 2^30 and buflen <= (2^32 - 1) * 32. The parameter N + * must be a power of 2 greater than 1. + * + * Return 0 on success; or -1 on error. + */ +int +escrypt_kdf_nosse(escrypt_local_t *local, const uint8_t *passwd, + size_t passwdlen, const uint8_t *salt, size_t saltlen, + uint64_t N, uint32_t _r, uint32_t _p, uint8_t *buf, + size_t buflen) +{ + size_t B_size, V_size, XY_size, need; + uint8_t * B; + uint32_t *V, *XY; + size_t r = _r, p = _p; + uint32_t i; + +/* Sanity-check parameters. */ +#if SIZE_MAX > UINT32_MAX + if (buflen > (((uint64_t)(1) << 32) - 1) * 32) { + errno = EFBIG; + return -1; + } +#endif + if ((uint64_t)(r) * (uint64_t)(p) >= ((uint64_t) 1 << 30)) { + errno = EFBIG; + return -1; + } + if (N > UINT32_MAX) { + errno = EFBIG; + return -1; + } + if (((N & (N - 1)) != 0) || (N < 2)) { + errno = EINVAL; + return -1; + } + if (r == 0 || p == 0) { + errno = EINVAL; + return -1; + } + if ((r > SIZE_MAX / 128 / p) || +#if SIZE_MAX / 256 <= UINT32_MAX + (r > SIZE_MAX / 256) || +#endif + (N > SIZE_MAX / 128 / r)) { + errno = ENOMEM; + return -1; + } + + /* Allocate memory. */ + B_size = (size_t) 128 * r * p; + V_size = (size_t) 128 * r * (size_t) N; + need = B_size + V_size; + if (need < V_size) { + errno = ENOMEM; + return -1; + } + XY_size = (size_t) 256 * r + 64; + need += XY_size; + if (need < XY_size) { + errno = ENOMEM; + return -1; + } + if (local->size < need) { + if (free_region(local)) { + return -1; + } + if (!alloc_region(local, need)) { + return -1; + } + } + B = (uint8_t *) local->aligned; + V = (uint32_t *) ((uint8_t *) B + B_size); + XY = (uint32_t *) ((uint8_t *) V + V_size); + + /* 1: (B_0 ... B_{p-1}) <-- PBKDF2(P, S, 1, p * MFLen) */ + PBKDF2_SHA256(passwd, passwdlen, salt, saltlen, 1, B, B_size); + + /* 2: for i = 0 to p - 1 do */ + for (i = 0; i < p; i++) { + /* 3: B_i <-- MF(B_i, N) */ + smix(&B[(size_t) 128 * i * r], r, N, V, XY); + } + + /* 5: DK <-- PBKDF2(P, B, 1, dkLen) */ + PBKDF2_SHA256(passwd, passwdlen, B, B_size, 1, buf, buflen); + + /* Success! */ + return 0; +} diff --git a/libs/libsodium/src/crypto_pwhash/scryptsalsa208sha256/pbkdf2-sha256.c b/libs/libsodium/src/crypto_pwhash/scryptsalsa208sha256/pbkdf2-sha256.c new file mode 100644 index 0000000000..42cab61fe2 --- /dev/null +++ b/libs/libsodium/src/crypto_pwhash/scryptsalsa208sha256/pbkdf2-sha256.c @@ -0,0 +1,95 @@ +/*- + * Copyright 2005,2007,2009 Colin Percival + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include <limits.h> +#include <stdint.h> +#include <stdlib.h> +#include <string.h> + +#include <sys/types.h> + +#include "core.h" +#include "crypto_auth_hmacsha256.h" +#include "crypto_pwhash_scryptsalsa208sha256.h" +#include "pbkdf2-sha256.h" +#include "private/common.h" +#include "utils.h" + +/** + * PBKDF2_SHA256(passwd, passwdlen, salt, saltlen, c, buf, dkLen): + * Compute PBKDF2(passwd, salt, c, dkLen) using HMAC-SHA256 as the PRF, and + * write the output to buf. The value dkLen must be at most 32 * (2^32 - 1). + */ +void +PBKDF2_SHA256(const uint8_t *passwd, size_t passwdlen, const uint8_t *salt, + size_t saltlen, uint64_t c, uint8_t *buf, size_t dkLen) +{ + crypto_auth_hmacsha256_state PShctx, hctx; + size_t i; + uint8_t ivec[4]; + uint8_t U[32]; + uint8_t T[32]; + uint64_t j; + int k; + size_t clen; + +#if SIZE_MAX > 0x1fffffffe0ULL + COMPILER_ASSERT(crypto_pwhash_scryptsalsa208sha256_BYTES_MAX + <= 0x1fffffffe0ULL); + if (dkLen > 0x1fffffffe0ULL) { + sodium_misuse(); /* LCOV_EXCL_LINE */ + } +#endif + crypto_auth_hmacsha256_init(&PShctx, passwd, passwdlen); + crypto_auth_hmacsha256_update(&PShctx, salt, saltlen); + + for (i = 0; i * 32 < dkLen; i++) { + STORE32_BE(ivec, (uint32_t)(i + 1)); + memcpy(&hctx, &PShctx, sizeof(crypto_auth_hmacsha256_state)); + crypto_auth_hmacsha256_update(&hctx, ivec, 4); + crypto_auth_hmacsha256_final(&hctx, U); + + memcpy(T, U, 32); + /* LCOV_EXCL_START */ + for (j = 2; j <= c; j++) { + crypto_auth_hmacsha256_init(&hctx, passwd, passwdlen); + crypto_auth_hmacsha256_update(&hctx, U, 32); + crypto_auth_hmacsha256_final(&hctx, U); + + for (k = 0; k < 32; k++) { + T[k] ^= U[k]; + } + } + /* LCOV_EXCL_STOP */ + + clen = dkLen - i * 32; + if (clen > 32) { + clen = 32; + } + memcpy(&buf[i * 32], T, clen); + } + sodium_memzero((void *) &PShctx, sizeof PShctx); +} diff --git a/libs/libsodium/src/crypto_pwhash/scryptsalsa208sha256/pbkdf2-sha256.h b/libs/libsodium/src/crypto_pwhash/scryptsalsa208sha256/pbkdf2-sha256.h new file mode 100644 index 0000000000..f9598c87aa --- /dev/null +++ b/libs/libsodium/src/crypto_pwhash/scryptsalsa208sha256/pbkdf2-sha256.h @@ -0,0 +1,45 @@ +/*- + * Copyright 2005,2007,2009 Colin Percival + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + */ + +#ifndef pbkdf2_sha256_H +#define pbkdf2_sha256_H + +#include <stdint.h> + +#include <sys/types.h> + +#include "crypto_auth_hmacsha256.h" + +/** + * PBKDF2_SHA256(passwd, passwdlen, salt, saltlen, c, buf, dkLen): + * Compute PBKDF2(passwd, salt, c, dkLen) using HMAC-SHA256 as the PRF, and + * write the output to buf. The value dkLen must be at most 32 * (2^32 - 1). + */ +void PBKDF2_SHA256(const uint8_t *, size_t, const uint8_t *, size_t, uint64_t, + uint8_t *, size_t); + +#endif /* !_SHA256_H_ */ diff --git a/libs/libsodium/src/crypto_pwhash/scryptsalsa208sha256/pwhash_scryptsalsa208sha256.c b/libs/libsodium/src/crypto_pwhash/scryptsalsa208sha256/pwhash_scryptsalsa208sha256.c new file mode 100644 index 0000000000..d1afd91afe --- /dev/null +++ b/libs/libsodium/src/crypto_pwhash/scryptsalsa208sha256/pwhash_scryptsalsa208sha256.c @@ -0,0 +1,285 @@ + +#include <errno.h> +#include <limits.h> +#include <stddef.h> +#include <stdint.h> +#include <string.h> + +#include "crypto_pwhash_scryptsalsa208sha256.h" +#include "crypto_scrypt.h" +#include "private/common.h" +#include "randombytes.h" +#include "utils.h" + +#define SETTING_SIZE(saltbytes) \ + ((sizeof "$7$" - 1U) + (1U /* N_log2 */) + (5U /* r */) + (5U /* p */) + \ + BYTES2CHARS(saltbytes)) + +static int +pickparams(unsigned long long opslimit, const size_t memlimit, + uint32_t *const N_log2, uint32_t *const p, uint32_t *const r) +{ + unsigned long long maxN; + unsigned long long maxrp; + + if (opslimit < 32768) { + opslimit = 32768; + } + *r = 8; + if (opslimit < memlimit / 32) { + *p = 1; + maxN = opslimit / (*r * 4); + for (*N_log2 = 1; *N_log2 < 63; *N_log2 += 1) { + if ((uint64_t)(1) << *N_log2 > maxN / 2) { + break; + } + } + } else { + maxN = memlimit / ((size_t) *r * 128); + for (*N_log2 = 1; *N_log2 < 63; *N_log2 += 1) { + if ((uint64_t)(1) << *N_log2 > maxN / 2) { + break; + } + } + maxrp = (opslimit / 4) / ((uint64_t)(1) << *N_log2); + /* LCOV_EXCL_START */ + if (maxrp > 0x3fffffff) { + maxrp = 0x3fffffff; + } + /* LCOV_EXCL_STOP */ + *p = (uint32_t)(maxrp) / *r; + } + return 0; +} + +size_t +crypto_pwhash_scryptsalsa208sha256_bytes_min(void) +{ + return crypto_pwhash_scryptsalsa208sha256_BYTES_MIN; +} + +size_t +crypto_pwhash_scryptsalsa208sha256_bytes_max(void) +{ + return crypto_pwhash_scryptsalsa208sha256_BYTES_MAX; +} + +size_t +crypto_pwhash_scryptsalsa208sha256_passwd_min(void) +{ + return crypto_pwhash_scryptsalsa208sha256_PASSWD_MIN; +} + +size_t +crypto_pwhash_scryptsalsa208sha256_passwd_max(void) +{ + return crypto_pwhash_scryptsalsa208sha256_PASSWD_MAX; +} + +size_t +crypto_pwhash_scryptsalsa208sha256_saltbytes(void) +{ + return crypto_pwhash_scryptsalsa208sha256_SALTBYTES; +} + +size_t +crypto_pwhash_scryptsalsa208sha256_strbytes(void) +{ + return crypto_pwhash_scryptsalsa208sha256_STRBYTES; +} + +const char * +crypto_pwhash_scryptsalsa208sha256_strprefix(void) +{ + return crypto_pwhash_scryptsalsa208sha256_STRPREFIX; +} + +size_t +crypto_pwhash_scryptsalsa208sha256_opslimit_min(void) +{ + return crypto_pwhash_scryptsalsa208sha256_OPSLIMIT_MIN; +} + +size_t +crypto_pwhash_scryptsalsa208sha256_opslimit_max(void) +{ + return crypto_pwhash_scryptsalsa208sha256_OPSLIMIT_MAX; +} + +size_t +crypto_pwhash_scryptsalsa208sha256_memlimit_min(void) +{ + return crypto_pwhash_scryptsalsa208sha256_MEMLIMIT_MIN; +} + +size_t +crypto_pwhash_scryptsalsa208sha256_memlimit_max(void) +{ + return crypto_pwhash_scryptsalsa208sha256_MEMLIMIT_MAX; +} + +size_t +crypto_pwhash_scryptsalsa208sha256_opslimit_interactive(void) +{ + return crypto_pwhash_scryptsalsa208sha256_OPSLIMIT_INTERACTIVE; +} + +size_t +crypto_pwhash_scryptsalsa208sha256_memlimit_interactive(void) +{ + return crypto_pwhash_scryptsalsa208sha256_MEMLIMIT_INTERACTIVE; +} + +size_t +crypto_pwhash_scryptsalsa208sha256_opslimit_sensitive(void) +{ + return crypto_pwhash_scryptsalsa208sha256_OPSLIMIT_SENSITIVE; +} + +size_t +crypto_pwhash_scryptsalsa208sha256_memlimit_sensitive(void) +{ + return crypto_pwhash_scryptsalsa208sha256_MEMLIMIT_SENSITIVE; +} + +int +crypto_pwhash_scryptsalsa208sha256(unsigned char *const out, + unsigned long long outlen, + const char *const passwd, + unsigned long long passwdlen, + const unsigned char *const salt, + unsigned long long opslimit, size_t memlimit) +{ + uint32_t N_log2; + uint32_t p; + uint32_t r; + + memset(out, 0, outlen); + if (passwdlen > crypto_pwhash_scryptsalsa208sha256_PASSWD_MAX || + outlen > crypto_pwhash_scryptsalsa208sha256_BYTES_MAX) { + errno = EFBIG; /* LCOV_EXCL_LINE */ + return -1; /* LCOV_EXCL_LINE */ + } + if (outlen < crypto_pwhash_scryptsalsa208sha256_BYTES_MIN || + pickparams(opslimit, memlimit, &N_log2, &p, &r) != 0) { + errno = EINVAL; /* LCOV_EXCL_LINE */ + return -1; /* LCOV_EXCL_LINE */ + } + return crypto_pwhash_scryptsalsa208sha256_ll( + (const uint8_t *) passwd, (size_t) passwdlen, (const uint8_t *) salt, + crypto_pwhash_scryptsalsa208sha256_SALTBYTES, (uint64_t)(1) << N_log2, + r, p, out, (size_t) outlen); +} + +int +crypto_pwhash_scryptsalsa208sha256_str( + char out[crypto_pwhash_scryptsalsa208sha256_STRBYTES], + const char *const passwd, unsigned long long passwdlen, + unsigned long long opslimit, size_t memlimit) +{ + uint8_t salt[crypto_pwhash_scryptsalsa208sha256_STRSALTBYTES]; + char setting[crypto_pwhash_scryptsalsa208sha256_STRSETTINGBYTES + 1U]; + escrypt_local_t escrypt_local; + uint32_t N_log2; + uint32_t p; + uint32_t r; + + memset(out, 0, crypto_pwhash_scryptsalsa208sha256_STRBYTES); + if (passwdlen > crypto_pwhash_scryptsalsa208sha256_PASSWD_MAX) { + errno = EFBIG; /* LCOV_EXCL_LINE */ + return -1; /* LCOV_EXCL_LINE */ + } + if (passwdlen < crypto_pwhash_scryptsalsa208sha256_PASSWD_MIN || + pickparams(opslimit, memlimit, &N_log2, &p, &r) != 0) { + errno = EINVAL; /* LCOV_EXCL_LINE */ + return -1; /* LCOV_EXCL_LINE */ + } + randombytes_buf(salt, sizeof salt); + if (escrypt_gensalt_r(N_log2, r, p, salt, sizeof salt, (uint8_t *) setting, + sizeof setting) == NULL) { + errno = EINVAL; /* LCOV_EXCL_LINE */ + return -1; /* LCOV_EXCL_LINE */ + } + if (escrypt_init_local(&escrypt_local) != 0) { + return -1; /* LCOV_EXCL_LINE */ + } + if (escrypt_r(&escrypt_local, (const uint8_t *) passwd, (size_t) passwdlen, + (const uint8_t *) setting, (uint8_t *) out, + crypto_pwhash_scryptsalsa208sha256_STRBYTES) == NULL) { + /* LCOV_EXCL_START */ + escrypt_free_local(&escrypt_local); + errno = EINVAL; + return -1; + /* LCOV_EXCL_STOP */ + } + escrypt_free_local(&escrypt_local); + + COMPILER_ASSERT( + SETTING_SIZE(crypto_pwhash_scryptsalsa208sha256_STRSALTBYTES) == + crypto_pwhash_scryptsalsa208sha256_STRSETTINGBYTES); + COMPILER_ASSERT( + crypto_pwhash_scryptsalsa208sha256_STRSETTINGBYTES + 1U + + crypto_pwhash_scryptsalsa208sha256_STRHASHBYTES_ENCODED + 1U == + crypto_pwhash_scryptsalsa208sha256_STRBYTES); + + return 0; +} + +int +crypto_pwhash_scryptsalsa208sha256_str_verify( + const char str[crypto_pwhash_scryptsalsa208sha256_STRBYTES], + const char *const passwd, unsigned long long passwdlen) +{ + char wanted[crypto_pwhash_scryptsalsa208sha256_STRBYTES]; + escrypt_local_t escrypt_local; + int ret = -1; + + if (memchr(str, 0, crypto_pwhash_scryptsalsa208sha256_STRBYTES) != + &str[crypto_pwhash_scryptsalsa208sha256_STRBYTES - 1U]) { + return -1; + } + if (escrypt_init_local(&escrypt_local) != 0) { + return -1; /* LCOV_EXCL_LINE */ + } + memset(wanted, 0, sizeof wanted); + if (escrypt_r(&escrypt_local, (const uint8_t *) passwd, (size_t) passwdlen, + (const uint8_t *) str, (uint8_t *) wanted, + sizeof wanted) == NULL) { + escrypt_free_local(&escrypt_local); + return -1; + } + escrypt_free_local(&escrypt_local); + ret = sodium_memcmp(wanted, str, sizeof wanted); + sodium_memzero(wanted, sizeof wanted); + + return ret; +} + +int +crypto_pwhash_scryptsalsa208sha256_str_needs_rehash( + const char str[crypto_pwhash_scryptsalsa208sha256_STRBYTES], + unsigned long long opslimit, size_t memlimit) +{ + uint32_t N_log2, N_log2_; + uint32_t p, p_; + uint32_t r, r_; + + if (pickparams(opslimit, memlimit, &N_log2, &p, &r) != 0) { + errno = EINVAL; + return -1; + } + if (memchr(str, 0, crypto_pwhash_scryptsalsa208sha256_STRBYTES) != + &str[crypto_pwhash_scryptsalsa208sha256_STRBYTES - 1U]) { + errno = EINVAL; + return -1; + } + if (escrypt_parse_setting((const uint8_t *) str, + &N_log2_, &r_, &p_) == NULL) { + errno = EINVAL; + return -1; + } + if (N_log2 != N_log2_ || r != r_ || p != p_) { + return 1; + } + return 0; +} diff --git a/libs/libsodium/src/crypto_pwhash/scryptsalsa208sha256/scrypt_platform.c b/libs/libsodium/src/crypto_pwhash/scryptsalsa208sha256/scrypt_platform.c new file mode 100644 index 0000000000..139a7df286 --- /dev/null +++ b/libs/libsodium/src/crypto_pwhash/scryptsalsa208sha256/scrypt_platform.c @@ -0,0 +1,108 @@ +/*- + * Copyright 2013 Alexander Peslyak + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifdef HAVE_SYS_MMAN_H +#include <sys/mman.h> +#endif +#include <errno.h> +#include <stdlib.h> + +#include "crypto_scrypt.h" +#include "runtime.h" + +#if !defined(MAP_ANON) && defined(MAP_ANONYMOUS) +# define MAP_ANON MAP_ANONYMOUS +#endif +#ifndef MAP_NOCORE +# define MAP_NOCORE 0 +#endif +#ifndef MAP_POPULATE +# define MAP_POPULATE 0 +#endif + +void * +alloc_region(escrypt_region_t *region, size_t size) +{ + uint8_t *base, *aligned; +#if defined(MAP_ANON) && defined(HAVE_MMAP) + if ((base = (uint8_t *) mmap(NULL, size, PROT_READ | PROT_WRITE, + MAP_ANON | MAP_PRIVATE | MAP_NOCORE | MAP_POPULATE, + -1, 0)) == MAP_FAILED) { + base = NULL; /* LCOV_EXCL_LINE */ + } /* LCOV_EXCL_LINE */ + aligned = base; +#elif defined(HAVE_POSIX_MEMALIGN) + if ((errno = posix_memalign((void **) &base, 64, size)) != 0) { + base = NULL; + } + aligned = base; +#else + base = aligned = NULL; + if (size + 63 < size) + errno = ENOMEM; + else if ((base = (uint8_t *) malloc(size + 63)) != NULL) { + aligned = base + 63; + aligned -= (uintptr_t) aligned & 63; + } +#endif + region->base = base; + region->aligned = aligned; + region->size = base ? size : 0; + + return aligned; +} + +static inline void +init_region(escrypt_region_t *region) +{ + region->base = region->aligned = NULL; + region->size = 0; +} + +int +free_region(escrypt_region_t *region) +{ + if (region->base) { +#if defined(MAP_ANON) && defined(HAVE_MMAP) + if (munmap(region->base, region->size)) { + return -1; /* LCOV_EXCL_LINE */ + } +#else + free(region->base); +#endif + } + init_region(region); + + return 0; +} + +int +escrypt_init_local(escrypt_local_t *local) +{ + init_region(local); + + return 0; +} + +int +escrypt_free_local(escrypt_local_t *local) +{ + return free_region(local); +} diff --git a/libs/libsodium/src/crypto_pwhash/scryptsalsa208sha256/sse/pwhash_scryptsalsa208sha256_sse.c b/libs/libsodium/src/crypto_pwhash/scryptsalsa208sha256/sse/pwhash_scryptsalsa208sha256_sse.c new file mode 100644 index 0000000000..754a19fdb8 --- /dev/null +++ b/libs/libsodium/src/crypto_pwhash/scryptsalsa208sha256/sse/pwhash_scryptsalsa208sha256_sse.c @@ -0,0 +1,400 @@ +/*- + * Copyright 2009 Colin Percival + * Copyright 2012,2013 Alexander Peslyak + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file was originally written by Colin Percival as part of the Tarsnap + * online backup system. + */ + +#include <errno.h> +#include <limits.h> +#include <stdint.h> +#include <stdlib.h> +#include <string.h> + +#include "private/common.h" +#include "private/sse2_64_32.h" + +#ifdef HAVE_EMMINTRIN_H + +# ifdef __GNUC__ +# pragma GCC target("sse2") +# endif +# include <emmintrin.h> +# if defined(__XOP__) && defined(DISABLED) +# include <x86intrin.h> +# endif + +# include "../crypto_scrypt.h" +# include "../pbkdf2-sha256.h" + +# if defined(__XOP__) && defined(DISABLED) +# define ARX(out, in1, in2, s) \ + out = _mm_xor_si128(out, _mm_roti_epi32(_mm_add_epi32(in1, in2), s)); +# else +# define ARX(out, in1, in2, s) \ + { \ + __m128i T = _mm_add_epi32(in1, in2); \ + out = _mm_xor_si128(out, _mm_slli_epi32(T, s)); \ + out = _mm_xor_si128(out, _mm_srli_epi32(T, 32 - s)); \ + } +# endif + +# define SALSA20_2ROUNDS \ + /* Operate on "columns". */ \ + ARX(X1, X0, X3, 7) \ + ARX(X2, X1, X0, 9) \ + ARX(X3, X2, X1, 13) \ + ARX(X0, X3, X2, 18) \ + \ + /* Rearrange data. */ \ + X1 = _mm_shuffle_epi32(X1, 0x93); \ + X2 = _mm_shuffle_epi32(X2, 0x4E); \ + X3 = _mm_shuffle_epi32(X3, 0x39); \ + \ + /* Operate on "rows". */ \ + ARX(X3, X0, X1, 7) \ + ARX(X2, X3, X0, 9) \ + ARX(X1, X2, X3, 13) \ + ARX(X0, X1, X2, 18) \ + \ + /* Rearrange data. */ \ + X1 = _mm_shuffle_epi32(X1, 0x39); \ + X2 = _mm_shuffle_epi32(X2, 0x4E); \ + X3 = _mm_shuffle_epi32(X3, 0x93); + +/** + * Apply the salsa20/8 core to the block provided in (X0 ... X3) ^ (Z0 ... Z3). + */ +# define SALSA20_8_XOR(in, out) \ + { \ + __m128i Y0 = X0 = _mm_xor_si128(X0, (in)[0]); \ + __m128i Y1 = X1 = _mm_xor_si128(X1, (in)[1]); \ + __m128i Y2 = X2 = _mm_xor_si128(X2, (in)[2]); \ + __m128i Y3 = X3 = _mm_xor_si128(X3, (in)[3]); \ + SALSA20_2ROUNDS \ + SALSA20_2ROUNDS \ + SALSA20_2ROUNDS \ + SALSA20_2ROUNDS(out)[0] = X0 = _mm_add_epi32(X0, Y0); \ + (out)[1] = X1 = _mm_add_epi32(X1, Y1); \ + (out)[2] = X2 = _mm_add_epi32(X2, Y2); \ + (out)[3] = X3 = _mm_add_epi32(X3, Y3); \ + } + +/** + * blockmix_salsa8(Bin, Bout, r): + * Compute Bout = BlockMix_{salsa20/8, r}(Bin). The input Bin must be 128r + * bytes in length; the output Bout must also be the same size. + */ +static inline void +blockmix_salsa8(const __m128i *Bin, __m128i *Bout, size_t r) +{ + __m128i X0, X1, X2, X3; + size_t i; + + /* 1: X <-- B_{2r - 1} */ + X0 = Bin[8 * r - 4]; + X1 = Bin[8 * r - 3]; + X2 = Bin[8 * r - 2]; + X3 = Bin[8 * r - 1]; + + /* 3: X <-- H(X \xor B_i) */ + /* 4: Y_i <-- X */ + /* 6: B' <-- (Y_0, Y_2 ... Y_{2r-2}, Y_1, Y_3 ... Y_{2r-1}) */ + SALSA20_8_XOR(Bin, Bout) + + /* 2: for i = 0 to 2r - 1 do */ + r--; + for (i = 0; i < r;) { + /* 3: X <-- H(X \xor B_i) */ + /* 4: Y_i <-- X */ + /* 6: B' <-- (Y_0, Y_2 ... Y_{2r-2}, Y_1, Y_3 ... Y_{2r-1}) */ + SALSA20_8_XOR(&Bin[i * 8 + 4], &Bout[(r + i) * 4 + 4]) + + i++; + + /* 3: X <-- H(X \xor B_i) */ + /* 4: Y_i <-- X */ + /* 6: B' <-- (Y_0, Y_2 ... Y_{2r-2}, Y_1, Y_3 ... Y_{2r-1}) */ + SALSA20_8_XOR(&Bin[i * 8], &Bout[i * 4]) + } + + /* 3: X <-- H(X \xor B_i) */ + /* 4: Y_i <-- X */ + /* 6: B' <-- (Y_0, Y_2 ... Y_{2r-2}, Y_1, Y_3 ... Y_{2r-1}) */ + SALSA20_8_XOR(&Bin[i * 8 + 4], &Bout[(r + i) * 4 + 4]) +} + +# define XOR4(in) \ + X0 = _mm_xor_si128(X0, (in)[0]); \ + X1 = _mm_xor_si128(X1, (in)[1]); \ + X2 = _mm_xor_si128(X2, (in)[2]); \ + X3 = _mm_xor_si128(X3, (in)[3]); + +# define XOR4_2(in1, in2) \ + X0 = _mm_xor_si128((in1)[0], (in2)[0]); \ + X1 = _mm_xor_si128((in1)[1], (in2)[1]); \ + X2 = _mm_xor_si128((in1)[2], (in2)[2]); \ + X3 = _mm_xor_si128((in1)[3], (in2)[3]); + +static inline uint32_t +blockmix_salsa8_xor(const __m128i *Bin1, const __m128i *Bin2, __m128i *Bout, + size_t r) +{ + __m128i X0, X1, X2, X3; + size_t i; + + /* 1: X <-- B_{2r - 1} */ + XOR4_2(&Bin1[8 * r - 4], &Bin2[8 * r - 4]) + + /* 3: X <-- H(X \xor B_i) */ + /* 4: Y_i <-- X */ + /* 6: B' <-- (Y_0, Y_2 ... Y_{2r-2}, Y_1, Y_3 ... Y_{2r-1}) */ + XOR4(Bin1) + SALSA20_8_XOR(Bin2, Bout) + + /* 2: for i = 0 to 2r - 1 do */ + r--; + for (i = 0; i < r;) { + /* 3: X <-- H(X \xor B_i) */ + /* 4: Y_i <-- X */ + /* 6: B' <-- (Y_0, Y_2 ... Y_{2r-2}, Y_1, Y_3 ... Y_{2r-1}) */ + XOR4(&Bin1[i * 8 + 4]) + SALSA20_8_XOR(&Bin2[i * 8 + 4], &Bout[(r + i) * 4 + 4]) + + i++; + + /* 3: X <-- H(X \xor B_i) */ + /* 4: Y_i <-- X */ + /* 6: B' <-- (Y_0, Y_2 ... Y_{2r-2}, Y_1, Y_3 ... Y_{2r-1}) */ + XOR4(&Bin1[i * 8]) + SALSA20_8_XOR(&Bin2[i * 8], &Bout[i * 4]) + } + + /* 3: X <-- H(X \xor B_i) */ + /* 4: Y_i <-- X */ + /* 6: B' <-- (Y_0, Y_2 ... Y_{2r-2}, Y_1, Y_3 ... Y_{2r-1}) */ + XOR4(&Bin1[i * 8 + 4]) + SALSA20_8_XOR(&Bin2[i * 8 + 4], &Bout[(r + i) * 4 + 4]) + + return _mm_cvtsi128_si32(X0); +} + +# undef ARX +# undef SALSA20_2ROUNDS +# undef SALSA20_8_XOR +# undef XOR4 +# undef XOR4_2 + +/** + * integerify(B, r): + * Return the result of parsing B_{2r-1} as a little-endian integer. + * Note that B's layout is permuted compared to the generic implementation. + */ +static inline uint32_t +integerify(const void *B, size_t r) +{ + return *(const uint32_t *) ((uintptr_t)(B) + (2 * r - 1) * 64); +} + +/** + * smix(B, r, N, V, XY): + * Compute B = SMix_r(B, N). The input B must be 128r bytes in length; + * the temporary storage V must be 128rN bytes in length; the temporary + * storage XY must be 256r + 64 bytes in length. The value N must be a + * power of 2 greater than 1. The arrays B, V, and XY must be aligned to a + * multiple of 64 bytes. + */ +static void +smix(uint8_t *B, size_t r, uint32_t N, void *V, void *XY) +{ + size_t s = 128 * r; + __m128i * X = (__m128i *) V, *Y; + uint32_t *X32 = (uint32_t *) V; + uint32_t i, j; + size_t k; + + /* 1: X <-- B */ + /* 3: V_i <-- X */ + for (k = 0; k < 2 * r; k++) { + for (i = 0; i < 16; i++) { + X32[k * 16 + i] = LOAD32_LE(&B[(k * 16 + (i * 5 % 16)) * 4]); + } + } + + /* 2: for i = 0 to N - 1 do */ + for (i = 1; i < N - 1; i += 2) { + /* 4: X <-- H(X) */ + /* 3: V_i <-- X */ + Y = (__m128i *) ((uintptr_t)(V) + i * s); + blockmix_salsa8(X, Y, r); + + /* 4: X <-- H(X) */ + /* 3: V_i <-- X */ + X = (__m128i *) ((uintptr_t)(V) + (i + 1) * s); + blockmix_salsa8(Y, X, r); + } + + /* 4: X <-- H(X) */ + /* 3: V_i <-- X */ + Y = (__m128i *) ((uintptr_t)(V) + i * s); + blockmix_salsa8(X, Y, r); + + /* 4: X <-- H(X) */ + /* 3: V_i <-- X */ + X = (__m128i *) XY; + blockmix_salsa8(Y, X, r); + + X32 = (uint32_t *) XY; + Y = (__m128i *) ((uintptr_t)(XY) + s); + + /* 7: j <-- Integerify(X) mod N */ + j = integerify(X, r) & (N - 1); + + /* 6: for i = 0 to N - 1 do */ + for (i = 0; i < N; i += 2) { + __m128i *V_j = (__m128i *) ((uintptr_t)(V) + j * s); + + /* 8: X <-- H(X \xor V_j) */ + /* 7: j <-- Integerify(X) mod N */ + j = blockmix_salsa8_xor(X, V_j, Y, r) & (N - 1); + V_j = (__m128i *) ((uintptr_t)(V) + j * s); + + /* 8: X <-- H(X \xor V_j) */ + /* 7: j <-- Integerify(X) mod N */ + j = blockmix_salsa8_xor(Y, V_j, X, r) & (N - 1); + } + + /* 10: B' <-- X */ + for (k = 0; k < 2 * r; k++) { + for (i = 0; i < 16; i++) { + STORE32_LE(&B[(k * 16 + (i * 5 % 16)) * 4], X32[k * 16 + i]); + } + } +} + +/** + * escrypt_kdf(local, passwd, passwdlen, salt, saltlen, + * N, r, p, buf, buflen): + * Compute scrypt(passwd[0 .. passwdlen - 1], salt[0 .. saltlen - 1], N, r, + * p, buflen) and write the result into buf. The parameters r, p, and buflen + * must satisfy r * p < 2^30 and buflen <= (2^32 - 1) * 32. The parameter N + * must be a power of 2 greater than 1. + * + * Return 0 on success; or -1 on error. + */ +int +escrypt_kdf_sse(escrypt_local_t *local, const uint8_t *passwd, size_t passwdlen, + const uint8_t *salt, size_t saltlen, uint64_t N, uint32_t _r, + uint32_t _p, uint8_t *buf, size_t buflen) +{ + size_t B_size, V_size, XY_size, need; + uint8_t * B; + uint32_t *V, *XY; + size_t r = _r, p = _p; + uint32_t i; + +/* Sanity-check parameters. */ +# if SIZE_MAX > UINT32_MAX +/* LCOV_EXCL_START */ + if (buflen > (((uint64_t)(1) << 32) - 1) * 32) { + errno = EFBIG; + return -1; + } +/* LCOV_EXCL_END */ +# endif + if ((uint64_t)(r) * (uint64_t)(p) >= ((uint64_t) 1 << 30)) { + errno = EFBIG; + return -1; + } + if (N > UINT32_MAX) { + errno = EFBIG; + return -1; + } + if (((N & (N - 1)) != 0) || (N < 2)) { + errno = EINVAL; + return -1; + } + if (r == 0 || p == 0) { + errno = EINVAL; + return -1; + } +/* LCOV_EXCL_START */ + if ((r > SIZE_MAX / 128 / p) || +# if SIZE_MAX / 256 <= UINT32_MAX + (r > SIZE_MAX / 256) || +# endif + (N > SIZE_MAX / 128 / r)) { + errno = ENOMEM; + return -1; + } +/* LCOV_EXCL_END */ + + /* Allocate memory. */ + B_size = (size_t) 128 * r * p; + V_size = (size_t) 128 * r * N; + need = B_size + V_size; +/* LCOV_EXCL_START */ + if (need < V_size) { + errno = ENOMEM; + return -1; + } +/* LCOV_EXCL_END */ + XY_size = (size_t) 256 * r + 64; + need += XY_size; +/* LCOV_EXCL_START */ + if (need < XY_size) { + errno = ENOMEM; + return -1; + } +/* LCOV_EXCL_END */ + if (local->size < need) { + if (free_region(local)) { + return -1; /* LCOV_EXCL_LINE */ + } + if (!alloc_region(local, need)) { + return -1; /* LCOV_EXCL_LINE */ + } + } + B = (uint8_t *) local->aligned; + V = (uint32_t *) ((uint8_t *) B + B_size); + XY = (uint32_t *) ((uint8_t *) V + V_size); + + /* 1: (B_0 ... B_{p-1}) <-- PBKDF2(P, S, 1, p * MFLen) */ + PBKDF2_SHA256(passwd, passwdlen, salt, saltlen, 1, B, B_size); + + /* 2: for i = 0 to p - 1 do */ + for (i = 0; i < p; i++) { + /* 3: B_i <-- MF(B_i, N) */ + smix(&B[(size_t) 128 * i * r], r, (uint32_t) N, V, XY); + } + + /* 5: DK <-- PBKDF2(P, B, 1, dkLen) */ + PBKDF2_SHA256(passwd, passwdlen, B, B_size, 1, buf, buflen); + + /* Success! */ + return 0; +} +#endif diff --git a/libs/libsodium/src/crypto_scalarmult/crypto_scalarmult.c b/libs/libsodium/src/crypto_scalarmult/crypto_scalarmult.c new file mode 100644 index 0000000000..9afffce8a9 --- /dev/null +++ b/libs/libsodium/src/crypto_scalarmult/crypto_scalarmult.c @@ -0,0 +1,33 @@ + +#include "crypto_scalarmult.h" + +const char * +crypto_scalarmult_primitive(void) +{ + return crypto_scalarmult_PRIMITIVE; +} + +int +crypto_scalarmult_base(unsigned char *q, const unsigned char *n) +{ + return crypto_scalarmult_curve25519_base(q, n); +} + +int +crypto_scalarmult(unsigned char *q, const unsigned char *n, + const unsigned char *p) +{ + return crypto_scalarmult_curve25519(q, n, p); +} + +size_t +crypto_scalarmult_bytes(void) +{ + return crypto_scalarmult_BYTES; +} + +size_t +crypto_scalarmult_scalarbytes(void) +{ + return crypto_scalarmult_SCALARBYTES; +} diff --git a/libs/libsodium/src/crypto_scalarmult/curve25519/ref10/x25519_ref10.c b/libs/libsodium/src/crypto_scalarmult/curve25519/ref10/x25519_ref10.c new file mode 100644 index 0000000000..7b93a7247b --- /dev/null +++ b/libs/libsodium/src/crypto_scalarmult/curve25519/ref10/x25519_ref10.c @@ -0,0 +1,159 @@ + +#include <stddef.h> +#include <stdint.h> + +#include "../scalarmult_curve25519.h" +#include "export.h" +#include "private/ed25519_ref10.h" +#include "utils.h" +#include "x25519_ref10.h" + +/* + * Reject small order points early to mitigate the implications of + * unexpected optimizations that would affect the ref10 code. + * See https://eprint.iacr.org/2017/806.pdf for reference. + */ +static int +has_small_order(const unsigned char s[32]) +{ + CRYPTO_ALIGN(16) + static const unsigned char blacklist[][32] = { + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0xe0, 0xeb, 0x7a, 0x7c, 0x3b, 0x41, 0xb8, 0xae, 0x16, 0x56, 0xe3, 0xfa, 0xf1, 0x9f, 0xc4, 0x6a, 0xda, 0x09, 0x8d, 0xeb, 0x9c, 0x32, 0xb1, 0xfd, 0x86, 0x62, 0x05, 0x16, 0x5f, 0x49, 0xb8, 0x00 }, + { 0x5f, 0x9c, 0x95, 0xbc, 0xa3, 0x50, 0x8c, 0x24, 0xb1, 0xd0, 0xb1, 0x55, 0x9c, 0x83, 0xef, 0x5b, 0x04, 0x44, 0x5c, 0xc4, 0x58, 0x1c, 0x8e, 0x86, 0xd8, 0x22, 0x4e, 0xdd, 0xd0, 0x9f, 0x11, 0x57 }, + { 0xec, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f }, + { 0xed, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f }, + { 0xee, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f }, + { 0xcd, 0xeb, 0x7a, 0x7c, 0x3b, 0x41, 0xb8, 0xae, 0x16, 0x56, 0xe3, 0xfa, 0xf1, 0x9f, 0xc4, 0x6a, 0xda, 0x09, 0x8d, 0xeb, 0x9c, 0x32, 0xb1, 0xfd, 0x86, 0x62, 0x05, 0x16, 0x5f, 0x49, 0xb8, 0x80 }, + { 0x4c, 0x9c, 0x95, 0xbc, 0xa3, 0x50, 0x8c, 0x24, 0xb1, 0xd0, 0xb1, 0x55, 0x9c, 0x83, 0xef, 0x5b, 0x04, 0x44, 0x5c, 0xc4, 0x58, 0x1c, 0x8e, 0x86, 0xd8, 0x22, 0x4e, 0xdd, 0xd0, 0x9f, 0x11, 0xd7 }, + { 0xd9, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }, + { 0xda, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }, + { 0xdb, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff } + }; + unsigned char c[12] = { 0 }; + unsigned int k; + size_t i, j; + + COMPILER_ASSERT(12 == sizeof blacklist / sizeof blacklist[0]); + for (j = 0; j < 32; j++) { + for (i = 0; i < sizeof blacklist / sizeof blacklist[0]; i++) { + c[i] |= s[j] ^ blacklist[i][j]; + } + } + k = 0; + for (i = 0; i < sizeof blacklist / sizeof blacklist[0]; i++) { + k |= (c[i] - 1); + } + return (int) ((k >> 8) & 1); +} + +static int +crypto_scalarmult_curve25519_ref10(unsigned char *q, + const unsigned char *n, + const unsigned char *p) +{ + unsigned char *t = q; + unsigned int i; + fe25519 x1; + fe25519 x2; + fe25519 z2; + fe25519 x3; + fe25519 z3; + fe25519 tmp0; + fe25519 tmp1; + int pos; + unsigned int swap; + unsigned int b; + + if (has_small_order(p)) { + return -1; + } + for (i = 0; i < 32; i++) { + t[i] = n[i]; + } + t[0] &= 248; + t[31] &= 127; + t[31] |= 64; + fe25519_frombytes(x1, p); + fe25519_1(x2); + fe25519_0(z2); + fe25519_copy(x3, x1); + fe25519_1(z3); + + swap = 0; + for (pos = 254; pos >= 0; --pos) { + b = t[pos / 8] >> (pos & 7); + b &= 1; + swap ^= b; + fe25519_cswap(x2, x3, swap); + fe25519_cswap(z2, z3, swap); + swap = b; + fe25519_sub(tmp0, x3, z3); + fe25519_sub(tmp1, x2, z2); + fe25519_add(x2, x2, z2); + fe25519_add(z2, x3, z3); + fe25519_mul(z3, tmp0, x2); + fe25519_mul(z2, z2, tmp1); + fe25519_sq(tmp0, tmp1); + fe25519_sq(tmp1, x2); + fe25519_add(x3, z3, z2); + fe25519_sub(z2, z3, z2); + fe25519_mul(x2, tmp1, tmp0); + fe25519_sub(tmp1, tmp1, tmp0); + fe25519_sq(z2, z2); + fe25519_scalar_product(z3, tmp1, 121666); + fe25519_sq(x3, x3); + fe25519_add(tmp0, tmp0, z3); + fe25519_mul(z3, x1, z2); + fe25519_mul(z2, tmp1, tmp0); + } + fe25519_cswap(x2, x3, swap); + fe25519_cswap(z2, z3, swap); + + fe25519_invert(z2, z2); + fe25519_mul(x2, x2, z2); + fe25519_tobytes(q, x2); + + return 0; +} + +static void +edwards_to_montgomery(fe25519 montgomeryX, const fe25519 edwardsY, const fe25519 edwardsZ) +{ + fe25519 tempX; + fe25519 tempZ; + + fe25519_add(tempX, edwardsZ, edwardsY); + fe25519_sub(tempZ, edwardsZ, edwardsY); + fe25519_invert(tempZ, tempZ); + fe25519_mul(montgomeryX, tempX, tempZ); +} + +static int +crypto_scalarmult_curve25519_ref10_base(unsigned char *q, + const unsigned char *n) +{ + unsigned char *t = q; + ge25519_p3 A; + fe25519 pk; + unsigned int i; + + for (i = 0; i < 32; i++) { + t[i] = n[i]; + } + t[0] &= 248; + t[31] &= 127; + t[31] |= 64; + ge25519_scalarmult_base(&A, t); + edwards_to_montgomery(pk, A.Y, A.Z); + fe25519_tobytes(q, pk); + + return 0; +} + +struct crypto_scalarmult_curve25519_implementation + crypto_scalarmult_curve25519_ref10_implementation = { + SODIUM_C99(.mult =) crypto_scalarmult_curve25519_ref10, + SODIUM_C99(.mult_base =) crypto_scalarmult_curve25519_ref10_base + }; diff --git a/libs/libsodium/src/crypto_scalarmult/curve25519/ref10/x25519_ref10.h b/libs/libsodium/src/crypto_scalarmult/curve25519/ref10/x25519_ref10.h new file mode 100644 index 0000000000..ea52a62a69 --- /dev/null +++ b/libs/libsodium/src/crypto_scalarmult/curve25519/ref10/x25519_ref10.h @@ -0,0 +1,10 @@ +#ifndef x25519_ref10_H +#define x25519_ref10_H + +#include "crypto_scalarmult_curve25519.h" +#include "../scalarmult_curve25519.h" + +extern struct crypto_scalarmult_curve25519_implementation + crypto_scalarmult_curve25519_ref10_implementation; + +#endif diff --git a/libs/libsodium/src/crypto_scalarmult/curve25519/sandy2x/consts.S b/libs/libsodium/src/crypto_scalarmult/curve25519/sandy2x/consts.S new file mode 100644 index 0000000000..67f1f0183e --- /dev/null +++ b/libs/libsodium/src/crypto_scalarmult/curve25519/sandy2x/consts.S @@ -0,0 +1,25 @@ +#ifdef IN_SANDY2X + +/* + REDMASK51 is from amd64-51/consts.s. +*/ + +#include "consts_namespace.h" +.data +.p2align 4 +v0_0: .quad 0, 0 +v1_0: .quad 1, 0 +v2_1: .quad 2, 1 +v9_0: .quad 9, 0 +v9_9: .quad 9, 9 +v19_19: .quad 19, 19 +v38_1: .quad 38, 1 +v38_38: .quad 38, 38 +v121666_121666: .quad 121666, 121666 +m25: .quad 33554431, 33554431 +m26: .quad 67108863, 67108863 +subc0: .quad 0x07FFFFDA, 0x03FFFFFE +subc2: .quad 0x07FFFFFE, 0x03FFFFFE +REDMASK51: .quad 0x0007FFFFFFFFFFFF + +#endif diff --git a/libs/libsodium/src/crypto_scalarmult/curve25519/sandy2x/consts_namespace.h b/libs/libsodium/src/crypto_scalarmult/curve25519/sandy2x/consts_namespace.h new file mode 100644 index 0000000000..9f81fa61c4 --- /dev/null +++ b/libs/libsodium/src/crypto_scalarmult/curve25519/sandy2x/consts_namespace.h @@ -0,0 +1,20 @@ +#ifndef consts_namespace_H +#define consts_namespace_H + +#define v0_0 crypto_scalarmult_curve25519_sandy2x_v0_0 +#define v1_0 crypto_scalarmult_curve25519_sandy2x_v1_0 +#define v2_1 crypto_scalarmult_curve25519_sandy2x_v2_1 +#define v9_0 crypto_scalarmult_curve25519_sandy2x_v9_0 +#define v9_9 crypto_scalarmult_curve25519_sandy2x_v9_9 +#define v19_19 crypto_scalarmult_curve25519_sandy2x_v19_19 +#define v38_1 crypto_scalarmult_curve25519_sandy2x_v38_1 +#define v38_38 crypto_scalarmult_curve25519_sandy2x_v38_38 +#define v121666_121666 crypto_scalarmult_curve25519_sandy2x_v121666_121666 +#define m25 crypto_scalarmult_curve25519_sandy2x_m25 +#define m26 crypto_scalarmult_curve25519_sandy2x_m26 +#define subc0 crypto_scalarmult_curve25519_sandy2x_subc0 +#define subc2 crypto_scalarmult_curve25519_sandy2x_subc2 +#define REDMASK51 crypto_scalarmult_curve25519_sandy2x_REDMASK51 + +#endif /* ifndef consts_namespace_H */ + diff --git a/libs/libsodium/src/crypto_scalarmult/curve25519/sandy2x/curve25519_sandy2x.c b/libs/libsodium/src/crypto_scalarmult/curve25519/sandy2x/curve25519_sandy2x.c new file mode 100644 index 0000000000..98b7cf79e5 --- /dev/null +++ b/libs/libsodium/src/crypto_scalarmult/curve25519/sandy2x/curve25519_sandy2x.c @@ -0,0 +1,114 @@ +/* + This file is adapted from ref10/scalarmult.c: + The code for Mongomery ladder is replace by the ladder assembly function; + Inversion is done in the same way as amd64-51/. + (fe is first converted into fe51 after Mongomery ladder) +*/ + +#include <stddef.h> + +#ifdef HAVE_AVX_ASM + +#include "utils.h" +#include "curve25519_sandy2x.h" +#include "../scalarmult_curve25519.h" +#include "fe.h" +#include "fe51.h" +#include "ladder.h" +#include "ladder_base.h" + +#define x1 var[0] +#define x2 var[1] +#define z2 var[2] + +static int +crypto_scalarmult_curve25519_sandy2x(unsigned char *q, const unsigned char *n, + const unsigned char *p) +{ + unsigned char *t = q; + fe var[3]; + fe51 x_51; + fe51 z_51; + unsigned int i; + + for (i = 0; i < 32; i++) { + t[i] = n[i]; + } + t[0] &= 248; + t[31] &= 127; + t[31] |= 64; + + fe_frombytes(x1, p); + + ladder(var, t); + + z_51.v[0] = (z2[1] << 26) + z2[0]; + z_51.v[1] = (z2[3] << 26) + z2[2]; + z_51.v[2] = (z2[5] << 26) + z2[4]; + z_51.v[3] = (z2[7] << 26) + z2[6]; + z_51.v[4] = (z2[9] << 26) + z2[8]; + + x_51.v[0] = (x2[1] << 26) + x2[0]; + x_51.v[1] = (x2[3] << 26) + x2[2]; + x_51.v[2] = (x2[5] << 26) + x2[4]; + x_51.v[3] = (x2[7] << 26) + x2[6]; + x_51.v[4] = (x2[9] << 26) + x2[8]; + + fe51_invert(&z_51, &z_51); + fe51_mul(&x_51, &x_51, &z_51); + fe51_pack(q, &x_51); + + return 0; +} + +#undef x2 +#undef z2 + +#define x2 var[0] +#define z2 var[1] + +static int +crypto_scalarmult_curve25519_sandy2x_base(unsigned char *q, + const unsigned char *n) +{ + unsigned char *t = q; + fe var[3]; + fe51 x_51; + fe51 z_51; + unsigned int i; + + for (i = 0;i < 32; i++) { + t[i] = n[i]; + } + t[0] &= 248; + t[31] &= 127; + t[31] |= 64; + + ladder_base(var, t); + + z_51.v[0] = (z2[1] << 26) + z2[0]; + z_51.v[1] = (z2[3] << 26) + z2[2]; + z_51.v[2] = (z2[5] << 26) + z2[4]; + z_51.v[3] = (z2[7] << 26) + z2[6]; + z_51.v[4] = (z2[9] << 26) + z2[8]; + + x_51.v[0] = (x2[1] << 26) + x2[0]; + x_51.v[1] = (x2[3] << 26) + x2[2]; + x_51.v[2] = (x2[5] << 26) + x2[4]; + x_51.v[3] = (x2[7] << 26) + x2[6]; + x_51.v[4] = (x2[9] << 26) + x2[8]; + + fe51_invert(&z_51, &z_51); + fe51_mul(&x_51, &x_51, &z_51); + fe51_pack(q, &x_51); + + return 0; +} + +struct crypto_scalarmult_curve25519_implementation +crypto_scalarmult_curve25519_sandy2x_implementation = { + SODIUM_C99(.mult = ) crypto_scalarmult_curve25519_sandy2x, + SODIUM_C99(.mult_base = ) crypto_scalarmult_curve25519_sandy2x_base +}; + +#endif diff --git a/libs/libsodium/src/crypto_scalarmult/curve25519/sandy2x/curve25519_sandy2x.h b/libs/libsodium/src/crypto_scalarmult/curve25519/sandy2x/curve25519_sandy2x.h new file mode 100644 index 0000000000..f02d980187 --- /dev/null +++ b/libs/libsodium/src/crypto_scalarmult/curve25519/sandy2x/curve25519_sandy2x.h @@ -0,0 +1,9 @@ +#ifndef curve25519_sandy2x_H +#define curve25519_sandy2x_H + +#include "crypto_scalarmult_curve25519.h" + +extern struct crypto_scalarmult_curve25519_implementation + crypto_scalarmult_curve25519_sandy2x_implementation; + +#endif diff --git a/libs/libsodium/src/crypto_scalarmult/curve25519/sandy2x/fe.h b/libs/libsodium/src/crypto_scalarmult/curve25519/sandy2x/fe.h new file mode 100644 index 0000000000..b1115f8691 --- /dev/null +++ b/libs/libsodium/src/crypto_scalarmult/curve25519/sandy2x/fe.h @@ -0,0 +1,26 @@ +/* + This file is adapted from ref10/fe.h: + All the redundant functions are removed. +*/ + +#ifndef fe_H +#define fe_H + +#include <stdint.h> +#include <stdlib.h> + +typedef uint64_t fe[10]; + +/* +fe means field element. +Here the field is \Z/(2^255-19). +An element t, entries t[0]...t[9], represents the integer +t[0]+2^26 t[1]+2^51 t[2]+2^77 t[3]+2^102 t[4]+...+2^230 t[9]. +Bounds on each t[i] vary depending on context. +*/ + +#define fe_frombytes crypto_scalarmult_curve25519_sandy2x_fe_frombytes + +extern void fe_frombytes(fe, const unsigned char *); + +#endif diff --git a/libs/libsodium/src/crypto_scalarmult/curve25519/sandy2x/fe51.h b/libs/libsodium/src/crypto_scalarmult/curve25519/sandy2x/fe51.h new file mode 100644 index 0000000000..8e3f199b24 --- /dev/null +++ b/libs/libsodium/src/crypto_scalarmult/curve25519/sandy2x/fe51.h @@ -0,0 +1,35 @@ +/* + This file is adapted from amd64-51/fe25519.h: + 'fe25519' is renamed as 'fe51'; + All the redundant functions are removed; + New function fe51_nsquare is introduced. +*/ + +#ifndef fe51_H +#define fe51_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include <stdint.h> +#include <stdlib.h> + +#include "fe51_namespace.h" + +typedef struct +{ + uint64_t v[5]; +} +fe51; + +extern void fe51_pack(unsigned char *, const fe51 *); +extern void fe51_mul(fe51 *, const fe51 *, const fe51 *); +extern void fe51_nsquare(fe51 *, const fe51 *, int); +extern void fe51_invert(fe51 *, const fe51 *); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/libs/libsodium/src/crypto_scalarmult/curve25519/sandy2x/fe51_invert.c b/libs/libsodium/src/crypto_scalarmult/curve25519/sandy2x/fe51_invert.c new file mode 100644 index 0000000000..ec9bb1a91f --- /dev/null +++ b/libs/libsodium/src/crypto_scalarmult/curve25519/sandy2x/fe51_invert.c @@ -0,0 +1,58 @@ +/* + This file is adapted from amd64-51/fe25519_invert.c: + Loops of squares are replaced by nsquares for better performance. +*/ + +#include "fe51.h" + +#ifdef HAVE_AVX_ASM + +#define fe51_square(x, y) fe51_nsquare(x, y, 1) + +void +fe51_invert(fe51 *r, const fe51 *x) +{ + fe51 z2; + fe51 z9; + fe51 z11; + fe51 z2_5_0; + fe51 z2_10_0; + fe51 z2_20_0; + fe51 z2_50_0; + fe51 z2_100_0; + fe51 t; + + /* 2 */ fe51_square(&z2,x); + /* 4 */ fe51_square(&t,&z2); + /* 8 */ fe51_square(&t,&t); + /* 9 */ fe51_mul(&z9,&t,x); + /* 11 */ fe51_mul(&z11,&z9,&z2); + /* 22 */ fe51_square(&t,&z11); + /* 2^5 - 2^0 = 31 */ fe51_mul(&z2_5_0,&t,&z9); + + /* 2^10 - 2^5 */ fe51_nsquare(&t,&z2_5_0, 5); + /* 2^10 - 2^0 */ fe51_mul(&z2_10_0,&t,&z2_5_0); + + /* 2^20 - 2^10 */ fe51_nsquare(&t,&z2_10_0, 10); + /* 2^20 - 2^0 */ fe51_mul(&z2_20_0,&t,&z2_10_0); + + /* 2^40 - 2^20 */ fe51_nsquare(&t,&z2_20_0, 20); + /* 2^40 - 2^0 */ fe51_mul(&t,&t,&z2_20_0); + + /* 2^50 - 2^10 */ fe51_nsquare(&t,&t,10); + /* 2^50 - 2^0 */ fe51_mul(&z2_50_0,&t,&z2_10_0); + + /* 2^100 - 2^50 */ fe51_nsquare(&t,&z2_50_0, 50); + /* 2^100 - 2^0 */ fe51_mul(&z2_100_0,&t,&z2_50_0); + + /* 2^200 - 2^100 */ fe51_nsquare(&t,&z2_100_0, 100); + /* 2^200 - 2^0 */ fe51_mul(&t,&t,&z2_100_0); + + /* 2^250 - 2^50 */ fe51_nsquare(&t,&t, 50); + /* 2^250 - 2^0 */ fe51_mul(&t,&t,&z2_50_0); + + /* 2^255 - 2^5 */ fe51_nsquare(&t,&t,5); + /* 2^255 - 21 */ fe51_mul(r,&t,&z11); +} + +#endif diff --git a/libs/libsodium/src/crypto_scalarmult/curve25519/sandy2x/fe51_mul.S b/libs/libsodium/src/crypto_scalarmult/curve25519/sandy2x/fe51_mul.S new file mode 100644 index 0000000000..83501b0395 --- /dev/null +++ b/libs/libsodium/src/crypto_scalarmult/curve25519/sandy2x/fe51_mul.S @@ -0,0 +1,197 @@ +#ifdef IN_SANDY2X + +/* + This file is basically amd64-51/fe25519_mul.s. +*/ +#include "fe51_namespace.h" +#include "consts_namespace.h" +.text +.p2align 5 +#ifdef ASM_HIDE_SYMBOL +ASM_HIDE_SYMBOL fe51_mul +ASM_HIDE_SYMBOL _fe51_mul +#endif +.globl fe51_mul +.globl _fe51_mul +#ifdef __ELF__ +.type fe51_mul, @function +.type _fe51_mul, @function +#endif +fe51_mul: +_fe51_mul: +mov %rsp,%r11 +and $31,%r11 +add $96,%r11 +sub %r11,%rsp +movq %r11,0(%rsp) +movq %r12,8(%rsp) +movq %r13,16(%rsp) +movq %r14,24(%rsp) +movq %r15,32(%rsp) +movq %rbx,40(%rsp) +movq %rbp,48(%rsp) +movq %rdi,56(%rsp) +mov %rdx,%rcx +movq 24(%rsi),%rdx +imulq $19,%rdx,%rax +movq %rax,64(%rsp) +mulq 16(%rcx) +mov %rax,%r8 +mov %rdx,%r9 +movq 32(%rsi),%rdx +imulq $19,%rdx,%rax +movq %rax,72(%rsp) +mulq 8(%rcx) +add %rax,%r8 +adc %rdx,%r9 +movq 0(%rsi),%rax +mulq 0(%rcx) +add %rax,%r8 +adc %rdx,%r9 +movq 0(%rsi),%rax +mulq 8(%rcx) +mov %rax,%r10 +mov %rdx,%r11 +movq 0(%rsi),%rax +mulq 16(%rcx) +mov %rax,%r12 +mov %rdx,%r13 +movq 0(%rsi),%rax +mulq 24(%rcx) +mov %rax,%r14 +mov %rdx,%r15 +movq 0(%rsi),%rax +mulq 32(%rcx) +mov %rax,%rbx +mov %rdx,%rbp +movq 8(%rsi),%rax +mulq 0(%rcx) +add %rax,%r10 +adc %rdx,%r11 +movq 8(%rsi),%rax +mulq 8(%rcx) +add %rax,%r12 +adc %rdx,%r13 +movq 8(%rsi),%rax +mulq 16(%rcx) +add %rax,%r14 +adc %rdx,%r15 +movq 8(%rsi),%rax +mulq 24(%rcx) +add %rax,%rbx +adc %rdx,%rbp +movq 8(%rsi),%rdx +imulq $19,%rdx,%rax +mulq 32(%rcx) +add %rax,%r8 +adc %rdx,%r9 +movq 16(%rsi),%rax +mulq 0(%rcx) +add %rax,%r12 +adc %rdx,%r13 +movq 16(%rsi),%rax +mulq 8(%rcx) +add %rax,%r14 +adc %rdx,%r15 +movq 16(%rsi),%rax +mulq 16(%rcx) +add %rax,%rbx +adc %rdx,%rbp +movq 16(%rsi),%rdx +imulq $19,%rdx,%rax +mulq 24(%rcx) +add %rax,%r8 +adc %rdx,%r9 +movq 16(%rsi),%rdx +imulq $19,%rdx,%rax +mulq 32(%rcx) +add %rax,%r10 +adc %rdx,%r11 +movq 24(%rsi),%rax +mulq 0(%rcx) +add %rax,%r14 +adc %rdx,%r15 +movq 24(%rsi),%rax +mulq 8(%rcx) +add %rax,%rbx +adc %rdx,%rbp +movq 64(%rsp),%rax +mulq 24(%rcx) +add %rax,%r10 +adc %rdx,%r11 +movq 64(%rsp),%rax +mulq 32(%rcx) +add %rax,%r12 +adc %rdx,%r13 +movq 32(%rsi),%rax +mulq 0(%rcx) +add %rax,%rbx +adc %rdx,%rbp +movq 72(%rsp),%rax +mulq 16(%rcx) +add %rax,%r10 +adc %rdx,%r11 +movq 72(%rsp),%rax +mulq 24(%rcx) +add %rax,%r12 +adc %rdx,%r13 +movq 72(%rsp),%rax +mulq 32(%rcx) +add %rax,%r14 +adc %rdx,%r15 +movq REDMASK51(%rip),%rsi +shld $13,%r8,%r9 +and %rsi,%r8 +shld $13,%r10,%r11 +and %rsi,%r10 +add %r9,%r10 +shld $13,%r12,%r13 +and %rsi,%r12 +add %r11,%r12 +shld $13,%r14,%r15 +and %rsi,%r14 +add %r13,%r14 +shld $13,%rbx,%rbp +and %rsi,%rbx +add %r15,%rbx +imulq $19,%rbp,%rdx +add %rdx,%r8 +mov %r8,%rdx +shr $51,%rdx +add %r10,%rdx +mov %rdx,%rcx +shr $51,%rdx +and %rsi,%r8 +add %r12,%rdx +mov %rdx,%r9 +shr $51,%rdx +and %rsi,%rcx +add %r14,%rdx +mov %rdx,%rax +shr $51,%rdx +and %rsi,%r9 +add %rbx,%rdx +mov %rdx,%r10 +shr $51,%rdx +and %rsi,%rax +imulq $19,%rdx,%rdx +add %rdx,%r8 +and %rsi,%r10 +movq %r8,0(%rdi) +movq %rcx,8(%rdi) +movq %r9,16(%rdi) +movq %rax,24(%rdi) +movq %r10,32(%rdi) +movq 0(%rsp),%r11 +movq 8(%rsp),%r12 +movq 16(%rsp),%r13 +movq 24(%rsp),%r14 +movq 32(%rsp),%r15 +movq 40(%rsp),%rbx +movq 48(%rsp),%rbp +add %r11,%rsp +mov %rdi,%rax +mov %rsi,%rdx +ret + +#endif diff --git a/libs/libsodium/src/crypto_scalarmult/curve25519/sandy2x/fe51_namespace.h b/libs/libsodium/src/crypto_scalarmult/curve25519/sandy2x/fe51_namespace.h new file mode 100644 index 0000000000..057f242ca1 --- /dev/null +++ b/libs/libsodium/src/crypto_scalarmult/curve25519/sandy2x/fe51_namespace.h @@ -0,0 +1,16 @@ +#ifndef fe51_namespace_H +#define fe51_namespace_H + +#define fe51 crypto_scalarmult_curve25519_sandy2x_fe51 +#define _fe51 _crypto_scalarmult_curve25519_sandy2x_fe51 +#define fe51_pack crypto_scalarmult_curve25519_sandy2x_fe51_pack +#define _fe51_pack _crypto_scalarmult_curve25519_sandy2x_fe51_pack +#define fe51_mul crypto_scalarmult_curve25519_sandy2x_fe51_mul +#define _fe51_mul _crypto_scalarmult_curve25519_sandy2x_fe51_mul +#define fe51_nsquare crypto_scalarmult_curve25519_sandy2x_fe51_nsquare +#define _fe51_nsquare _crypto_scalarmult_curve25519_sandy2x_fe51_nsquare + +#define fe51_invert crypto_scalarmult_curve25519_sandy2x_fe51_invert + +#endif /* ifndef fe51_namespace_H */ + diff --git a/libs/libsodium/src/crypto_scalarmult/curve25519/sandy2x/fe51_nsquare.S b/libs/libsodium/src/crypto_scalarmult/curve25519/sandy2x/fe51_nsquare.S new file mode 100644 index 0000000000..41c3054805 --- /dev/null +++ b/libs/libsodium/src/crypto_scalarmult/curve25519/sandy2x/fe51_nsquare.S @@ -0,0 +1,172 @@ +#ifdef IN_SANDY2X + +/* + This file is adapted from amd64-51/fe25519_square.s: + Adding loop to perform n squares. +*/ +#include "fe51_namespace.h" +#include "consts_namespace.h" +.p2align 5 + +#ifdef ASM_HIDE_SYMBOL +ASM_HIDE_SYMBOL fe51_nsquare +ASM_HIDE_SYMBOL _fe51_nsquare +#endif +.globl fe51_nsquare +.globl _fe51_nsquare +#ifdef __ELF__ +.type fe51_nsquare, @function +.type _fe51_nsquare, @function +#endif +fe51_nsquare: +_fe51_nsquare: + +mov %rsp,%r11 +and $31,%r11 +add $64,%r11 +sub %r11,%rsp +movq %r11,0(%rsp) +movq %r12,8(%rsp) +movq %r13,16(%rsp) +movq %r14,24(%rsp) +movq %r15,32(%rsp) +movq %rbx,40(%rsp) +movq %rbp,48(%rsp) +movq 0(%rsi),%rcx +movq 8(%rsi),%r8 +movq 16(%rsi),%r9 +movq 24(%rsi),%rax +movq 32(%rsi),%rsi +movq %r9,16(%rdi) +movq %rax,24(%rdi) +movq %rsi,32(%rdi) +mov %rdx,%rsi + +.p2align 4 +._loop: +sub $1,%rsi +mov %rcx,%rax +mul %rcx +add %rcx,%rcx +mov %rax,%r9 +mov %rdx,%r10 +mov %rcx,%rax +mul %r8 +mov %rax,%r11 +mov %rdx,%r12 +mov %rcx,%rax +mulq 16(%rdi) +mov %rax,%r13 +mov %rdx,%r14 +mov %rcx,%rax +mulq 24(%rdi) +mov %rax,%r15 +mov %rdx,%rbx +mov %rcx,%rax +mulq 32(%rdi) +mov %rax,%rcx +mov %rdx,%rbp +mov %r8,%rax +mul %r8 +add %r8,%r8 +add %rax,%r13 +adc %rdx,%r14 +mov %r8,%rax +mulq 16(%rdi) +add %rax,%r15 +adc %rdx,%rbx +mov %r8,%rax +imulq $19, %r8,%r8 +mulq 24(%rdi) +add %rax,%rcx +adc %rdx,%rbp +mov %r8,%rax +mulq 32(%rdi) +add %rax,%r9 +adc %rdx,%r10 +movq 16(%rdi),%rax +mulq 16(%rdi) +add %rax,%rcx +adc %rdx,%rbp +shld $13,%rcx,%rbp +movq 16(%rdi),%rax +imulq $38, %rax,%rax +mulq 24(%rdi) +add %rax,%r9 +adc %rdx,%r10 +shld $13,%r9,%r10 +movq 16(%rdi),%rax +imulq $38, %rax,%rax +mulq 32(%rdi) +add %rax,%r11 +adc %rdx,%r12 +movq 24(%rdi),%rax +imulq $19, %rax,%rax +mulq 24(%rdi) +add %rax,%r11 +adc %rdx,%r12 +shld $13,%r11,%r12 +movq 24(%rdi),%rax +imulq $38, %rax,%rax +mulq 32(%rdi) +add %rax,%r13 +adc %rdx,%r14 +shld $13,%r13,%r14 +movq 32(%rdi),%rax +imulq $19, %rax,%rax +mulq 32(%rdi) +add %rax,%r15 +adc %rdx,%rbx +shld $13,%r15,%rbx +movq REDMASK51(%rip),%rdx +and %rdx,%rcx +add %rbx,%rcx +and %rdx,%r9 +and %rdx,%r11 +add %r10,%r11 +and %rdx,%r13 +add %r12,%r13 +and %rdx,%r15 +add %r14,%r15 +imulq $19, %rbp,%rbp +lea (%r9,%rbp),%r9 +mov %r9,%rax +shr $51,%r9 +add %r11,%r9 +and %rdx,%rax +mov %r9,%r8 +shr $51,%r9 +add %r13,%r9 +and %rdx,%r8 +mov %r9,%r10 +shr $51,%r9 +add %r15,%r9 +and %rdx,%r10 +movq %r10,16(%rdi) +mov %r9,%r10 +shr $51,%r9 +add %rcx,%r9 +and %rdx,%r10 +movq %r10,24(%rdi) +mov %r9,%r10 +shr $51,%r9 +imulq $19, %r9,%r9 +lea (%rax,%r9),%rcx +and %rdx,%r10 +movq %r10,32(%rdi) +cmp $0,%rsi +jne ._loop + +movq %rcx,0(%rdi) +movq %r8,8(%rdi) +movq 0(%rsp),%r11 +movq 8(%rsp),%r12 +movq 16(%rsp),%r13 +movq 24(%rsp),%r14 +movq 32(%rsp),%r15 +movq 40(%rsp),%rbx +movq 48(%rsp),%rbp +add %r11,%rsp +ret + +#endif diff --git a/libs/libsodium/src/crypto_scalarmult/curve25519/sandy2x/fe51_pack.S b/libs/libsodium/src/crypto_scalarmult/curve25519/sandy2x/fe51_pack.S new file mode 100644 index 0000000000..500c858476 --- /dev/null +++ b/libs/libsodium/src/crypto_scalarmult/curve25519/sandy2x/fe51_pack.S @@ -0,0 +1,226 @@ +#ifdef IN_SANDY2X + +/* + This file is the result of merging + amd64-51/fe25519_pack.c and amd64-51/fe25519_freeze.s. +*/ +#include "fe51_namespace.h" +#include "consts_namespace.h" +.p2align 5 + +#ifdef ASM_HIDE_SYMBOL +ASM_HIDE_SYMBOL fe51_pack +ASM_HIDE_SYMBOL _fe51_pack +#endif +.globl fe51_pack +.globl _fe51_pack +#ifdef __ELF__ +.type fe51_pack, @function +.type _fe51_pack, @function +#endif +fe51_pack: +_fe51_pack: + +mov %rsp,%r11 +and $31,%r11 +add $32,%r11 +sub %r11,%rsp +movq %r11,0(%rsp) +movq %r12,8(%rsp) +movq 0(%rsi),%rdx +movq 8(%rsi),%rcx +movq 16(%rsi),%r8 +movq 24(%rsi),%r9 +movq 32(%rsi),%rsi +movq REDMASK51(%rip),%rax +lea -18(%rax),%r10 +mov $3,%r11 + +.p2align 4 +._reduceloop: +mov %rdx,%r12 +shr $51,%r12 +and %rax,%rdx +add %r12,%rcx +mov %rcx,%r12 +shr $51,%r12 +and %rax,%rcx +add %r12,%r8 +mov %r8,%r12 +shr $51,%r12 +and %rax,%r8 +add %r12,%r9 +mov %r9,%r12 +shr $51,%r12 +and %rax,%r9 +add %r12,%rsi +mov %rsi,%r12 +shr $51,%r12 +and %rax,%rsi +imulq $19, %r12,%r12 +add %r12,%rdx +sub $1,%r11 +ja ._reduceloop + +mov $1,%r12 +cmp %r10,%rdx +cmovl %r11,%r12 +cmp %rax,%rcx +cmovne %r11,%r12 +cmp %rax,%r8 +cmovne %r11,%r12 +cmp %rax,%r9 +cmovne %r11,%r12 +cmp %rax,%rsi +cmovne %r11,%r12 +neg %r12 +and %r12,%rax +and %r12,%r10 +sub %r10,%rdx +sub %rax,%rcx +sub %rax,%r8 +sub %rax,%r9 +sub %rax,%rsi +mov %rdx,%rax +and $0xFF,%eax +movb %al,0(%rdi) +mov %rdx,%rax +shr $8,%rax +and $0xFF,%eax +movb %al,1(%rdi) +mov %rdx,%rax +shr $16,%rax +and $0xFF,%eax +movb %al,2(%rdi) +mov %rdx,%rax +shr $24,%rax +and $0xFF,%eax +movb %al,3(%rdi) +mov %rdx,%rax +shr $32,%rax +and $0xFF,%eax +movb %al,4(%rdi) +mov %rdx,%rax +shr $40,%rax +and $0xFF,%eax +movb %al,5(%rdi) +mov %rdx,%rdx +shr $48,%rdx +mov %rcx,%rax +shl $3,%rax +and $0xF8,%eax +xor %rdx,%rax +movb %al,6(%rdi) +mov %rcx,%rdx +shr $5,%rdx +and $0xFF,%edx +movb %dl,7(%rdi) +mov %rcx,%rdx +shr $13,%rdx +and $0xFF,%edx +movb %dl,8(%rdi) +mov %rcx,%rdx +shr $21,%rdx +and $0xFF,%edx +movb %dl,9(%rdi) +mov %rcx,%rdx +shr $29,%rdx +and $0xFF,%edx +movb %dl,10(%rdi) +mov %rcx,%rdx +shr $37,%rdx +and $0xFF,%edx +movb %dl,11(%rdi) +mov %rcx,%rdx +shr $45,%rdx +mov %r8,%rcx +shl $6,%rcx +and $0xC0,%ecx +xor %rdx,%rcx +movb %cl,12(%rdi) +mov %r8,%rdx +shr $2,%rdx +and $0xFF,%edx +movb %dl,13(%rdi) +mov %r8,%rdx +shr $10,%rdx +and $0xFF,%edx +movb %dl,14(%rdi) +mov %r8,%rdx +shr $18,%rdx +and $0xFF,%edx +movb %dl,15(%rdi) +mov %r8,%rdx +shr $26,%rdx +and $0xFF,%edx +movb %dl,16(%rdi) +mov %r8,%rdx +shr $34,%rdx +and $0xFF,%edx +movb %dl,17(%rdi) +mov %r8,%rdx +shr $42,%rdx +movb %dl,18(%rdi) +mov %r8,%rdx +shr $50,%rdx +mov %r9,%rcx +shl $1,%rcx +and $0xFE,%ecx +xor %rdx,%rcx +movb %cl,19(%rdi) +mov %r9,%rdx +shr $7,%rdx +and $0xFF,%edx +movb %dl,20(%rdi) +mov %r9,%rdx +shr $15,%rdx +and $0xFF,%edx +movb %dl,21(%rdi) +mov %r9,%rdx +shr $23,%rdx +and $0xFF,%edx +movb %dl,22(%rdi) +mov %r9,%rdx +shr $31,%rdx +and $0xFF,%edx +movb %dl,23(%rdi) +mov %r9,%rdx +shr $39,%rdx +and $0xFF,%edx +movb %dl,24(%rdi) +mov %r9,%rdx +shr $47,%rdx +mov %rsi,%rcx +shl $4,%rcx +and $0xF0,%ecx +xor %rdx,%rcx +movb %cl,25(%rdi) +mov %rsi,%rdx +shr $4,%rdx +and $0xFF,%edx +movb %dl,26(%rdi) +mov %rsi,%rdx +shr $12,%rdx +and $0xFF,%edx +movb %dl,27(%rdi) +mov %rsi,%rdx +shr $20,%rdx +and $0xFF,%edx +movb %dl,28(%rdi) +mov %rsi,%rdx +shr $28,%rdx +and $0xFF,%edx +movb %dl,29(%rdi) +mov %rsi,%rdx +shr $36,%rdx +and $0xFF,%edx +movb %dl,30(%rdi) +mov %rsi,%rsi +shr $44,%rsi +movb %sil,31(%rdi) +movq 0(%rsp),%r11 +movq 8(%rsp),%r12 +add %r11,%rsp +ret + +#endif diff --git a/libs/libsodium/src/crypto_scalarmult/curve25519/sandy2x/fe_frombytes_sandy2x.c b/libs/libsodium/src/crypto_scalarmult/curve25519/sandy2x/fe_frombytes_sandy2x.c new file mode 100644 index 0000000000..2fe081ee2a --- /dev/null +++ b/libs/libsodium/src/crypto_scalarmult/curve25519/sandy2x/fe_frombytes_sandy2x.c @@ -0,0 +1,78 @@ +/* + This file is basically ref10/fe_frombytes.h. +*/ + +#include "fe.h" + +#ifdef HAVE_AVX_ASM + +static uint64_t +load_3(const unsigned char *in) +{ + uint64_t result; + result = (uint64_t) in[0]; + result |= ((uint64_t) in[1]) << 8; + result |= ((uint64_t) in[2]) << 16; + return result; +} + +static uint64_t +load_4(const unsigned char *in) +{ + uint64_t result; + result = (uint64_t) in[0]; + result |= ((uint64_t) in[1]) << 8; + result |= ((uint64_t) in[2]) << 16; + result |= ((uint64_t) in[3]) << 24; + return result; +} + +void +fe_frombytes(fe h, const unsigned char *s) +{ + uint64_t h0 = load_4(s); + uint64_t h1 = load_3(s + 4) << 6; + uint64_t h2 = load_3(s + 7) << 5; + uint64_t h3 = load_3(s + 10) << 3; + uint64_t h4 = load_3(s + 13) << 2; + uint64_t h5 = load_4(s + 16); + uint64_t h6 = load_3(s + 20) << 7; + uint64_t h7 = load_3(s + 23) << 5; + uint64_t h8 = load_3(s + 26) << 4; + uint64_t h9 = (load_3(s + 29) & 8388607) << 2; + uint64_t carry0; + uint64_t carry1; + uint64_t carry2; + uint64_t carry3; + uint64_t carry4; + uint64_t carry5; + uint64_t carry6; + uint64_t carry7; + uint64_t carry8; + uint64_t carry9; + + carry9 = h9 >> 25; h0 += carry9 * 19; h9 &= 0x1FFFFFF; + carry1 = h1 >> 25; h2 += carry1; h1 &= 0x1FFFFFF; + carry3 = h3 >> 25; h4 += carry3; h3 &= 0x1FFFFFF; + carry5 = h5 >> 25; h6 += carry5; h5 &= 0x1FFFFFF; + carry7 = h7 >> 25; h8 += carry7; h7 &= 0x1FFFFFF; + + carry0 = h0 >> 26; h1 += carry0; h0 &= 0x3FFFFFF; + carry2 = h2 >> 26; h3 += carry2; h2 &= 0x3FFFFFF; + carry4 = h4 >> 26; h5 += carry4; h4 &= 0x3FFFFFF; + carry6 = h6 >> 26; h7 += carry6; h6 &= 0x3FFFFFF; + carry8 = h8 >> 26; h9 += carry8; h8 &= 0x3FFFFFF; + + h[0] = h0; + h[1] = h1; + h[2] = h2; + h[3] = h3; + h[4] = h4; + h[5] = h5; + h[6] = h6; + h[7] = h7; + h[8] = h8; + h[9] = h9; +} + +#endif diff --git a/libs/libsodium/src/crypto_scalarmult/curve25519/sandy2x/ladder.S b/libs/libsodium/src/crypto_scalarmult/curve25519/sandy2x/ladder.S new file mode 100644 index 0000000000..c5c06021d8 --- /dev/null +++ b/libs/libsodium/src/crypto_scalarmult/curve25519/sandy2x/ladder.S @@ -0,0 +1,1440 @@ +#ifdef IN_SANDY2X + +#include "ladder_namespace.h" +#include "consts_namespace.h" +.p2align 5 + +#ifdef ASM_HIDE_SYMBOL +ASM_HIDE_SYMBOL ladder +ASM_HIDE_SYMBOL _ladder +#endif +.globl ladder +.globl _ladder +#ifdef __ELF__ +.type ladder, @function +.type _ladder, @function +#endif +ladder: +_ladder: + +mov %rsp,%r11 +and $31,%r11 +add $1856,%r11 +sub %r11,%rsp +movq %r11,1824(%rsp) +movq %r12,1832(%rsp) +movq %r13,1840(%rsp) +movq %r14,1848(%rsp) +vmovdqa v0_0(%rip),%xmm0 +vmovdqa v1_0(%rip),%xmm1 +vmovdqu 0(%rdi),%xmm2 +vmovdqa %xmm2,0(%rsp) +vmovdqu 16(%rdi),%xmm2 +vmovdqa %xmm2,16(%rsp) +vmovdqu 32(%rdi),%xmm2 +vmovdqa %xmm2,32(%rsp) +vmovdqu 48(%rdi),%xmm2 +vmovdqa %xmm2,48(%rsp) +vmovdqu 64(%rdi),%xmm2 +vmovdqa %xmm2,64(%rsp) +vmovdqa %xmm1,80(%rsp) +vmovdqa %xmm0,96(%rsp) +vmovdqa %xmm0,112(%rsp) +vmovdqa %xmm0,128(%rsp) +vmovdqa %xmm0,144(%rsp) +vmovdqa %xmm1,%xmm0 +vpxor %xmm1,%xmm1,%xmm1 +vpxor %xmm2,%xmm2,%xmm2 +vpxor %xmm3,%xmm3,%xmm3 +vpxor %xmm4,%xmm4,%xmm4 +vpxor %xmm5,%xmm5,%xmm5 +vpxor %xmm6,%xmm6,%xmm6 +vpxor %xmm7,%xmm7,%xmm7 +vpxor %xmm8,%xmm8,%xmm8 +vpxor %xmm9,%xmm9,%xmm9 +vmovdqu 0(%rdi),%xmm10 +vmovdqa %xmm10,160(%rsp) +vmovdqu 16(%rdi),%xmm10 +vmovdqa %xmm10,176(%rsp) +vpmuludq v19_19(%rip),%xmm10,%xmm10 +vmovdqa %xmm10,192(%rsp) +vmovdqu 32(%rdi),%xmm10 +vmovdqa %xmm10,208(%rsp) +vpmuludq v19_19(%rip),%xmm10,%xmm10 +vmovdqa %xmm10,224(%rsp) +vmovdqu 48(%rdi),%xmm10 +vmovdqa %xmm10,240(%rsp) +vpmuludq v19_19(%rip),%xmm10,%xmm10 +vmovdqa %xmm10,256(%rsp) +vmovdqu 64(%rdi),%xmm10 +vmovdqa %xmm10,272(%rsp) +vpmuludq v19_19(%rip),%xmm10,%xmm10 +vmovdqa %xmm10,288(%rsp) +vmovdqu 8(%rdi),%xmm10 +vpmuludq v2_1(%rip),%xmm10,%xmm10 +vmovdqa %xmm10,304(%rsp) +vpmuludq v19_19(%rip),%xmm10,%xmm10 +vmovdqa %xmm10,320(%rsp) +vmovdqu 24(%rdi),%xmm10 +vpmuludq v2_1(%rip),%xmm10,%xmm10 +vmovdqa %xmm10,336(%rsp) +vpmuludq v19_19(%rip),%xmm10,%xmm10 +vmovdqa %xmm10,352(%rsp) +vmovdqu 40(%rdi),%xmm10 +vpmuludq v2_1(%rip),%xmm10,%xmm10 +vmovdqa %xmm10,368(%rsp) +vpmuludq v19_19(%rip),%xmm10,%xmm10 +vmovdqa %xmm10,384(%rsp) +vmovdqu 56(%rdi),%xmm10 +vpmuludq v2_1(%rip),%xmm10,%xmm10 +vmovdqa %xmm10,400(%rsp) +vpmuludq v19_19(%rip),%xmm10,%xmm10 +vmovdqa %xmm10,416(%rsp) +vmovdqu 0(%rdi),%xmm10 +vmovdqu 64(%rdi),%xmm11 +vblendps $12, %xmm11, %xmm10, %xmm10 +vpshufd $2,%xmm10,%xmm10 +vpmuludq v38_1(%rip),%xmm10,%xmm10 +vmovdqa %xmm10,432(%rsp) +movq 0(%rsi),%rdx +movq 8(%rsi),%rcx +movq 16(%rsi),%r8 +movq 24(%rsi),%r9 +shrd $1,%rcx,%rdx +shrd $1,%r8,%rcx +shrd $1,%r9,%r8 +shr $1,%r9 +xorq 0(%rsi),%rdx +xorq 8(%rsi),%rcx +xorq 16(%rsi),%r8 +xorq 24(%rsi),%r9 +leaq 800(%rsp),%rsi +mov $64,%rax + +.p2align 4 +._ladder_small_loop: +mov %rdx,%r10 +mov %rcx,%r11 +mov %r8,%r12 +mov %r9,%r13 +shr $1,%rdx +shr $1,%rcx +shr $1,%r8 +shr $1,%r9 +and $1,%r10d +and $1,%r11d +and $1,%r12d +and $1,%r13d +neg %r10 +neg %r11 +neg %r12 +neg %r13 +movl %r10d,0(%rsi) +movl %r11d,256(%rsi) +movl %r12d,512(%rsi) +movl %r13d,768(%rsi) +add $4,%rsi +sub $1,%rax +jne ._ladder_small_loop +mov $255,%rdx +add $760,%rsi + +.p2align 4 +._ladder_loop: +sub $1,%rdx +vbroadcastss 0(%rsi),%xmm10 +sub $4,%rsi +vmovdqa 0(%rsp),%xmm11 +vmovdqa 80(%rsp),%xmm12 +vpxor %xmm11,%xmm0,%xmm13 +vpand %xmm10,%xmm13,%xmm13 +vpxor %xmm13,%xmm0,%xmm0 +vpxor %xmm13,%xmm11,%xmm11 +vpxor %xmm12,%xmm1,%xmm13 +vpand %xmm10,%xmm13,%xmm13 +vpxor %xmm13,%xmm1,%xmm1 +vpxor %xmm13,%xmm12,%xmm12 +vmovdqa 16(%rsp),%xmm13 +vmovdqa 96(%rsp),%xmm14 +vpxor %xmm13,%xmm2,%xmm15 +vpand %xmm10,%xmm15,%xmm15 +vpxor %xmm15,%xmm2,%xmm2 +vpxor %xmm15,%xmm13,%xmm13 +vpxor %xmm14,%xmm3,%xmm15 +vpand %xmm10,%xmm15,%xmm15 +vpxor %xmm15,%xmm3,%xmm3 +vpxor %xmm15,%xmm14,%xmm14 +vmovdqa %xmm13,0(%rsp) +vmovdqa %xmm14,16(%rsp) +vmovdqa 32(%rsp),%xmm13 +vmovdqa 112(%rsp),%xmm14 +vpxor %xmm13,%xmm4,%xmm15 +vpand %xmm10,%xmm15,%xmm15 +vpxor %xmm15,%xmm4,%xmm4 +vpxor %xmm15,%xmm13,%xmm13 +vpxor %xmm14,%xmm5,%xmm15 +vpand %xmm10,%xmm15,%xmm15 +vpxor %xmm15,%xmm5,%xmm5 +vpxor %xmm15,%xmm14,%xmm14 +vmovdqa %xmm13,32(%rsp) +vmovdqa %xmm14,80(%rsp) +vmovdqa 48(%rsp),%xmm13 +vmovdqa 128(%rsp),%xmm14 +vpxor %xmm13,%xmm6,%xmm15 +vpand %xmm10,%xmm15,%xmm15 +vpxor %xmm15,%xmm6,%xmm6 +vpxor %xmm15,%xmm13,%xmm13 +vpxor %xmm14,%xmm7,%xmm15 +vpand %xmm10,%xmm15,%xmm15 +vpxor %xmm15,%xmm7,%xmm7 +vpxor %xmm15,%xmm14,%xmm14 +vmovdqa %xmm13,48(%rsp) +vmovdqa %xmm14,96(%rsp) +vmovdqa 64(%rsp),%xmm13 +vmovdqa 144(%rsp),%xmm14 +vpxor %xmm13,%xmm8,%xmm15 +vpand %xmm10,%xmm15,%xmm15 +vpxor %xmm15,%xmm8,%xmm8 +vpxor %xmm15,%xmm13,%xmm13 +vpxor %xmm14,%xmm9,%xmm15 +vpand %xmm10,%xmm15,%xmm15 +vpxor %xmm15,%xmm9,%xmm9 +vpxor %xmm15,%xmm14,%xmm14 +vmovdqa %xmm13,64(%rsp) +vmovdqa %xmm14,112(%rsp) +vpaddq subc0(%rip),%xmm11,%xmm10 +vpsubq %xmm12,%xmm10,%xmm10 +vpaddq %xmm12,%xmm11,%xmm11 +vpunpckhqdq %xmm10,%xmm11,%xmm12 +vpunpcklqdq %xmm10,%xmm11,%xmm10 +vpaddq %xmm1,%xmm0,%xmm11 +vpaddq subc0(%rip),%xmm0,%xmm0 +vpsubq %xmm1,%xmm0,%xmm0 +vpunpckhqdq %xmm11,%xmm0,%xmm1 +vpunpcklqdq %xmm11,%xmm0,%xmm0 +vpmuludq %xmm0,%xmm10,%xmm11 +vpmuludq %xmm1,%xmm10,%xmm13 +vmovdqa %xmm1,128(%rsp) +vpaddq %xmm1,%xmm1,%xmm1 +vpmuludq %xmm0,%xmm12,%xmm14 +vmovdqa %xmm0,144(%rsp) +vpaddq %xmm14,%xmm13,%xmm13 +vpmuludq %xmm1,%xmm12,%xmm0 +vmovdqa %xmm1,448(%rsp) +vpaddq %xmm3,%xmm2,%xmm1 +vpaddq subc2(%rip),%xmm2,%xmm2 +vpsubq %xmm3,%xmm2,%xmm2 +vpunpckhqdq %xmm1,%xmm2,%xmm3 +vpunpcklqdq %xmm1,%xmm2,%xmm1 +vpmuludq %xmm1,%xmm10,%xmm2 +vpaddq %xmm2,%xmm0,%xmm0 +vpmuludq %xmm3,%xmm10,%xmm2 +vmovdqa %xmm3,464(%rsp) +vpaddq %xmm3,%xmm3,%xmm3 +vpmuludq %xmm1,%xmm12,%xmm14 +vmovdqa %xmm1,480(%rsp) +vpaddq %xmm14,%xmm2,%xmm2 +vpmuludq %xmm3,%xmm12,%xmm1 +vmovdqa %xmm3,496(%rsp) +vpaddq %xmm5,%xmm4,%xmm3 +vpaddq subc2(%rip),%xmm4,%xmm4 +vpsubq %xmm5,%xmm4,%xmm4 +vpunpckhqdq %xmm3,%xmm4,%xmm5 +vpunpcklqdq %xmm3,%xmm4,%xmm3 +vpmuludq %xmm3,%xmm10,%xmm4 +vpaddq %xmm4,%xmm1,%xmm1 +vpmuludq %xmm5,%xmm10,%xmm4 +vmovdqa %xmm5,512(%rsp) +vpaddq %xmm5,%xmm5,%xmm5 +vpmuludq %xmm3,%xmm12,%xmm14 +vmovdqa %xmm3,528(%rsp) +vpaddq %xmm14,%xmm4,%xmm4 +vpaddq %xmm7,%xmm6,%xmm3 +vpaddq subc2(%rip),%xmm6,%xmm6 +vpsubq %xmm7,%xmm6,%xmm6 +vpunpckhqdq %xmm3,%xmm6,%xmm7 +vpunpcklqdq %xmm3,%xmm6,%xmm3 +vpmuludq %xmm3,%xmm10,%xmm6 +vpmuludq %xmm5,%xmm12,%xmm14 +vmovdqa %xmm5,544(%rsp) +vpmuludq v19_19(%rip),%xmm5,%xmm5 +vmovdqa %xmm5,560(%rsp) +vpaddq %xmm14,%xmm6,%xmm6 +vpmuludq %xmm7,%xmm10,%xmm5 +vmovdqa %xmm7,576(%rsp) +vpaddq %xmm7,%xmm7,%xmm7 +vpmuludq %xmm3,%xmm12,%xmm14 +vmovdqa %xmm3,592(%rsp) +vpaddq %xmm14,%xmm5,%xmm5 +vpmuludq v19_19(%rip),%xmm3,%xmm3 +vmovdqa %xmm3,608(%rsp) +vpaddq %xmm9,%xmm8,%xmm3 +vpaddq subc2(%rip),%xmm8,%xmm8 +vpsubq %xmm9,%xmm8,%xmm8 +vpunpckhqdq %xmm3,%xmm8,%xmm9 +vpunpcklqdq %xmm3,%xmm8,%xmm3 +vmovdqa %xmm3,624(%rsp) +vpmuludq %xmm7,%xmm12,%xmm8 +vmovdqa %xmm7,640(%rsp) +vpmuludq v19_19(%rip),%xmm7,%xmm7 +vmovdqa %xmm7,656(%rsp) +vpmuludq %xmm3,%xmm10,%xmm7 +vpaddq %xmm7,%xmm8,%xmm8 +vpmuludq %xmm9,%xmm10,%xmm7 +vmovdqa %xmm9,672(%rsp) +vpaddq %xmm9,%xmm9,%xmm9 +vpmuludq %xmm3,%xmm12,%xmm10 +vpaddq %xmm10,%xmm7,%xmm7 +vpmuludq v19_19(%rip),%xmm3,%xmm3 +vmovdqa %xmm3,688(%rsp) +vpmuludq v19_19(%rip),%xmm12,%xmm12 +vpmuludq %xmm9,%xmm12,%xmm3 +vmovdqa %xmm9,704(%rsp) +vpaddq %xmm3,%xmm11,%xmm11 +vmovdqa 0(%rsp),%xmm3 +vmovdqa 16(%rsp),%xmm9 +vpaddq subc2(%rip),%xmm3,%xmm10 +vpsubq %xmm9,%xmm10,%xmm10 +vpaddq %xmm9,%xmm3,%xmm3 +vpunpckhqdq %xmm10,%xmm3,%xmm9 +vpunpcklqdq %xmm10,%xmm3,%xmm3 +vpmuludq 144(%rsp),%xmm3,%xmm10 +vpaddq %xmm10,%xmm0,%xmm0 +vpmuludq 128(%rsp),%xmm3,%xmm10 +vpaddq %xmm10,%xmm2,%xmm2 +vpmuludq 480(%rsp),%xmm3,%xmm10 +vpaddq %xmm10,%xmm1,%xmm1 +vpmuludq 464(%rsp),%xmm3,%xmm10 +vpaddq %xmm10,%xmm4,%xmm4 +vpmuludq 528(%rsp),%xmm3,%xmm10 +vpaddq %xmm10,%xmm6,%xmm6 +vpmuludq 512(%rsp),%xmm3,%xmm10 +vpaddq %xmm10,%xmm5,%xmm5 +vpmuludq 592(%rsp),%xmm3,%xmm10 +vpaddq %xmm10,%xmm8,%xmm8 +vpmuludq 576(%rsp),%xmm3,%xmm10 +vpaddq %xmm10,%xmm7,%xmm7 +vpmuludq v19_19(%rip),%xmm3,%xmm3 +vpmuludq 624(%rsp),%xmm3,%xmm10 +vpaddq %xmm10,%xmm11,%xmm11 +vpmuludq 672(%rsp),%xmm3,%xmm3 +vpaddq %xmm3,%xmm13,%xmm13 +vpmuludq 144(%rsp),%xmm9,%xmm3 +vpaddq %xmm3,%xmm2,%xmm2 +vpmuludq 448(%rsp),%xmm9,%xmm3 +vpaddq %xmm3,%xmm1,%xmm1 +vpmuludq 480(%rsp),%xmm9,%xmm3 +vpaddq %xmm3,%xmm4,%xmm4 +vpmuludq 496(%rsp),%xmm9,%xmm3 +vpaddq %xmm3,%xmm6,%xmm6 +vpmuludq 528(%rsp),%xmm9,%xmm3 +vpaddq %xmm3,%xmm5,%xmm5 +vpmuludq 544(%rsp),%xmm9,%xmm3 +vpaddq %xmm3,%xmm8,%xmm8 +vpmuludq 592(%rsp),%xmm9,%xmm3 +vpaddq %xmm3,%xmm7,%xmm7 +vpmuludq v19_19(%rip),%xmm9,%xmm9 +vpmuludq 640(%rsp),%xmm9,%xmm3 +vpaddq %xmm3,%xmm11,%xmm11 +vpmuludq 624(%rsp),%xmm9,%xmm3 +vpaddq %xmm3,%xmm13,%xmm13 +vpmuludq 704(%rsp),%xmm9,%xmm9 +vpaddq %xmm9,%xmm0,%xmm0 +vmovdqa 32(%rsp),%xmm3 +vmovdqa 80(%rsp),%xmm9 +vpaddq subc2(%rip),%xmm3,%xmm10 +vpsubq %xmm9,%xmm10,%xmm10 +vpaddq %xmm9,%xmm3,%xmm3 +vpunpckhqdq %xmm10,%xmm3,%xmm9 +vpunpcklqdq %xmm10,%xmm3,%xmm3 +vpmuludq 144(%rsp),%xmm3,%xmm10 +vpaddq %xmm10,%xmm1,%xmm1 +vpmuludq 128(%rsp),%xmm3,%xmm10 +vpaddq %xmm10,%xmm4,%xmm4 +vpmuludq 480(%rsp),%xmm3,%xmm10 +vpaddq %xmm10,%xmm6,%xmm6 +vpmuludq 464(%rsp),%xmm3,%xmm10 +vpaddq %xmm10,%xmm5,%xmm5 +vpmuludq 528(%rsp),%xmm3,%xmm10 +vpaddq %xmm10,%xmm8,%xmm8 +vpmuludq 512(%rsp),%xmm3,%xmm10 +vpaddq %xmm10,%xmm7,%xmm7 +vpmuludq v19_19(%rip),%xmm3,%xmm3 +vpmuludq 592(%rsp),%xmm3,%xmm10 +vpaddq %xmm10,%xmm11,%xmm11 +vpmuludq 576(%rsp),%xmm3,%xmm10 +vpaddq %xmm10,%xmm13,%xmm13 +vpmuludq 624(%rsp),%xmm3,%xmm10 +vpaddq %xmm10,%xmm0,%xmm0 +vpmuludq 672(%rsp),%xmm3,%xmm3 +vpaddq %xmm3,%xmm2,%xmm2 +vpmuludq 144(%rsp),%xmm9,%xmm3 +vpaddq %xmm3,%xmm4,%xmm4 +vpmuludq 448(%rsp),%xmm9,%xmm3 +vpaddq %xmm3,%xmm6,%xmm6 +vpmuludq 480(%rsp),%xmm9,%xmm3 +vpaddq %xmm3,%xmm5,%xmm5 +vpmuludq 496(%rsp),%xmm9,%xmm3 +vpaddq %xmm3,%xmm8,%xmm8 +vpmuludq 528(%rsp),%xmm9,%xmm3 +vpaddq %xmm3,%xmm7,%xmm7 +vpmuludq v19_19(%rip),%xmm9,%xmm9 +vpmuludq 544(%rsp),%xmm9,%xmm3 +vpaddq %xmm3,%xmm11,%xmm11 +vpmuludq 592(%rsp),%xmm9,%xmm3 +vpaddq %xmm3,%xmm13,%xmm13 +vpmuludq 640(%rsp),%xmm9,%xmm3 +vpaddq %xmm3,%xmm0,%xmm0 +vpmuludq 624(%rsp),%xmm9,%xmm3 +vpaddq %xmm3,%xmm2,%xmm2 +vpmuludq 704(%rsp),%xmm9,%xmm9 +vpaddq %xmm9,%xmm1,%xmm1 +vmovdqa 48(%rsp),%xmm3 +vmovdqa 96(%rsp),%xmm9 +vpaddq subc2(%rip),%xmm3,%xmm10 +vpsubq %xmm9,%xmm10,%xmm10 +vpaddq %xmm9,%xmm3,%xmm3 +vpunpckhqdq %xmm10,%xmm3,%xmm9 +vpunpcklqdq %xmm10,%xmm3,%xmm3 +vpmuludq 144(%rsp),%xmm3,%xmm10 +vpaddq %xmm10,%xmm6,%xmm6 +vpmuludq 128(%rsp),%xmm3,%xmm10 +vpaddq %xmm10,%xmm5,%xmm5 +vpmuludq 480(%rsp),%xmm3,%xmm10 +vpaddq %xmm10,%xmm8,%xmm8 +vpmuludq 464(%rsp),%xmm3,%xmm10 +vpaddq %xmm10,%xmm7,%xmm7 +vpmuludq v19_19(%rip),%xmm3,%xmm3 +vpmuludq 528(%rsp),%xmm3,%xmm10 +vpaddq %xmm10,%xmm11,%xmm11 +vpmuludq 512(%rsp),%xmm3,%xmm10 +vpaddq %xmm10,%xmm13,%xmm13 +vpmuludq 592(%rsp),%xmm3,%xmm10 +vpaddq %xmm10,%xmm0,%xmm0 +vpmuludq 576(%rsp),%xmm3,%xmm10 +vpaddq %xmm10,%xmm2,%xmm2 +vpmuludq 624(%rsp),%xmm3,%xmm10 +vpaddq %xmm10,%xmm1,%xmm1 +vpmuludq 672(%rsp),%xmm3,%xmm3 +vpaddq %xmm3,%xmm4,%xmm4 +vpmuludq 144(%rsp),%xmm9,%xmm3 +vpaddq %xmm3,%xmm5,%xmm5 +vpmuludq 448(%rsp),%xmm9,%xmm3 +vpaddq %xmm3,%xmm8,%xmm8 +vpmuludq 480(%rsp),%xmm9,%xmm3 +vpaddq %xmm3,%xmm7,%xmm7 +vpmuludq v19_19(%rip),%xmm9,%xmm9 +vpmuludq 496(%rsp),%xmm9,%xmm3 +vpaddq %xmm3,%xmm11,%xmm11 +vpmuludq 528(%rsp),%xmm9,%xmm3 +vpaddq %xmm3,%xmm13,%xmm13 +vpmuludq 544(%rsp),%xmm9,%xmm3 +vpaddq %xmm3,%xmm0,%xmm0 +vpmuludq 592(%rsp),%xmm9,%xmm3 +vpaddq %xmm3,%xmm2,%xmm2 +vpmuludq 640(%rsp),%xmm9,%xmm3 +vpaddq %xmm3,%xmm1,%xmm1 +vpmuludq 624(%rsp),%xmm9,%xmm3 +vpaddq %xmm3,%xmm4,%xmm4 +vpmuludq 704(%rsp),%xmm9,%xmm9 +vpaddq %xmm9,%xmm6,%xmm6 +vmovdqa 64(%rsp),%xmm3 +vmovdqa 112(%rsp),%xmm9 +vpaddq subc2(%rip),%xmm3,%xmm10 +vpsubq %xmm9,%xmm10,%xmm10 +vpaddq %xmm9,%xmm3,%xmm3 +vpunpckhqdq %xmm10,%xmm3,%xmm9 +vpunpcklqdq %xmm10,%xmm3,%xmm3 +vpmuludq 144(%rsp),%xmm3,%xmm10 +vpaddq %xmm10,%xmm8,%xmm8 +vpmuludq 128(%rsp),%xmm3,%xmm10 +vpaddq %xmm10,%xmm7,%xmm7 +vpmuludq v19_19(%rip),%xmm3,%xmm3 +vpmuludq 480(%rsp),%xmm3,%xmm10 +vpaddq %xmm10,%xmm11,%xmm11 +vpmuludq 464(%rsp),%xmm3,%xmm10 +vpaddq %xmm10,%xmm13,%xmm13 +vpmuludq 528(%rsp),%xmm3,%xmm10 +vpaddq %xmm10,%xmm0,%xmm0 +vpmuludq 512(%rsp),%xmm3,%xmm10 +vpaddq %xmm10,%xmm2,%xmm2 +vpmuludq 592(%rsp),%xmm3,%xmm10 +vpaddq %xmm10,%xmm1,%xmm1 +vpmuludq 576(%rsp),%xmm3,%xmm10 +vpaddq %xmm10,%xmm4,%xmm4 +vpmuludq 624(%rsp),%xmm3,%xmm10 +vpaddq %xmm10,%xmm6,%xmm6 +vpmuludq 672(%rsp),%xmm3,%xmm3 +vpaddq %xmm3,%xmm5,%xmm5 +vpmuludq 144(%rsp),%xmm9,%xmm3 +vpaddq %xmm3,%xmm7,%xmm7 +vpmuludq v19_19(%rip),%xmm9,%xmm9 +vpmuludq 448(%rsp),%xmm9,%xmm3 +vpaddq %xmm3,%xmm11,%xmm11 +vpmuludq 480(%rsp),%xmm9,%xmm3 +vpaddq %xmm3,%xmm13,%xmm13 +vpmuludq 496(%rsp),%xmm9,%xmm3 +vpaddq %xmm3,%xmm0,%xmm0 +vpmuludq 528(%rsp),%xmm9,%xmm3 +vpaddq %xmm3,%xmm2,%xmm2 +vpmuludq 544(%rsp),%xmm9,%xmm3 +vpaddq %xmm3,%xmm1,%xmm1 +vpmuludq 592(%rsp),%xmm9,%xmm3 +vpaddq %xmm3,%xmm4,%xmm4 +vpmuludq 640(%rsp),%xmm9,%xmm3 +vpaddq %xmm3,%xmm6,%xmm6 +vpmuludq 624(%rsp),%xmm9,%xmm3 +vpaddq %xmm3,%xmm5,%xmm5 +vpmuludq 704(%rsp),%xmm9,%xmm9 +vpaddq %xmm9,%xmm8,%xmm8 +vpsrlq $25,%xmm4,%xmm3 +vpaddq %xmm3,%xmm6,%xmm6 +vpand m25(%rip),%xmm4,%xmm4 +vpsrlq $26,%xmm11,%xmm3 +vpaddq %xmm3,%xmm13,%xmm13 +vpand m26(%rip),%xmm11,%xmm11 +vpsrlq $26,%xmm6,%xmm3 +vpaddq %xmm3,%xmm5,%xmm5 +vpand m26(%rip),%xmm6,%xmm6 +vpsrlq $25,%xmm13,%xmm3 +vpaddq %xmm3,%xmm0,%xmm0 +vpand m25(%rip),%xmm13,%xmm13 +vpsrlq $25,%xmm5,%xmm3 +vpaddq %xmm3,%xmm8,%xmm8 +vpand m25(%rip),%xmm5,%xmm5 +vpsrlq $26,%xmm0,%xmm3 +vpaddq %xmm3,%xmm2,%xmm2 +vpand m26(%rip),%xmm0,%xmm0 +vpsrlq $26,%xmm8,%xmm3 +vpaddq %xmm3,%xmm7,%xmm7 +vpand m26(%rip),%xmm8,%xmm8 +vpsrlq $25,%xmm2,%xmm3 +vpaddq %xmm3,%xmm1,%xmm1 +vpand m25(%rip),%xmm2,%xmm2 +vpsrlq $25,%xmm7,%xmm3 +vpsllq $4,%xmm3,%xmm9 +vpaddq %xmm3,%xmm11,%xmm11 +vpsllq $1,%xmm3,%xmm3 +vpaddq %xmm3,%xmm9,%xmm9 +vpaddq %xmm9,%xmm11,%xmm11 +vpand m25(%rip),%xmm7,%xmm7 +vpsrlq $26,%xmm1,%xmm3 +vpaddq %xmm3,%xmm4,%xmm4 +vpand m26(%rip),%xmm1,%xmm1 +vpsrlq $26,%xmm11,%xmm3 +vpaddq %xmm3,%xmm13,%xmm13 +vpand m26(%rip),%xmm11,%xmm11 +vpsrlq $25,%xmm4,%xmm3 +vpaddq %xmm3,%xmm6,%xmm6 +vpand m25(%rip),%xmm4,%xmm4 +vpunpcklqdq %xmm13,%xmm11,%xmm3 +vpunpckhqdq %xmm13,%xmm11,%xmm9 +vpaddq subc0(%rip),%xmm9,%xmm10 +vpsubq %xmm3,%xmm10,%xmm10 +vpaddq %xmm9,%xmm3,%xmm3 +vpunpckhqdq %xmm3,%xmm10,%xmm9 +vpunpcklqdq %xmm3,%xmm10,%xmm10 +vpmuludq %xmm10,%xmm10,%xmm3 +vpaddq %xmm10,%xmm10,%xmm10 +vpmuludq %xmm9,%xmm10,%xmm11 +vpunpcklqdq %xmm2,%xmm0,%xmm12 +vpunpckhqdq %xmm2,%xmm0,%xmm0 +vpaddq subc2(%rip),%xmm0,%xmm2 +vpsubq %xmm12,%xmm2,%xmm2 +vpaddq %xmm0,%xmm12,%xmm12 +vpunpckhqdq %xmm12,%xmm2,%xmm0 +vpunpcklqdq %xmm12,%xmm2,%xmm2 +vpmuludq %xmm2,%xmm10,%xmm12 +vpaddq %xmm9,%xmm9,%xmm13 +vpmuludq %xmm13,%xmm9,%xmm9 +vpaddq %xmm9,%xmm12,%xmm12 +vpmuludq %xmm0,%xmm10,%xmm9 +vpmuludq %xmm2,%xmm13,%xmm14 +vpaddq %xmm14,%xmm9,%xmm9 +vpunpcklqdq %xmm4,%xmm1,%xmm14 +vpunpckhqdq %xmm4,%xmm1,%xmm1 +vpaddq subc2(%rip),%xmm1,%xmm4 +vpsubq %xmm14,%xmm4,%xmm4 +vpaddq %xmm1,%xmm14,%xmm14 +vpunpckhqdq %xmm14,%xmm4,%xmm1 +vpunpcklqdq %xmm14,%xmm4,%xmm4 +vmovdqa %xmm1,0(%rsp) +vpaddq %xmm1,%xmm1,%xmm1 +vmovdqa %xmm1,16(%rsp) +vpmuludq v19_19(%rip),%xmm1,%xmm1 +vmovdqa %xmm1,32(%rsp) +vpmuludq %xmm4,%xmm10,%xmm1 +vpmuludq %xmm2,%xmm2,%xmm14 +vpaddq %xmm14,%xmm1,%xmm1 +vpmuludq 0(%rsp),%xmm10,%xmm14 +vpmuludq %xmm4,%xmm13,%xmm15 +vpaddq %xmm15,%xmm14,%xmm14 +vpunpcklqdq %xmm5,%xmm6,%xmm15 +vpunpckhqdq %xmm5,%xmm6,%xmm5 +vpaddq subc2(%rip),%xmm5,%xmm6 +vpsubq %xmm15,%xmm6,%xmm6 +vpaddq %xmm5,%xmm15,%xmm15 +vpunpckhqdq %xmm15,%xmm6,%xmm5 +vpunpcklqdq %xmm15,%xmm6,%xmm6 +vmovdqa %xmm6,48(%rsp) +vpmuludq v19_19(%rip),%xmm6,%xmm6 +vmovdqa %xmm6,64(%rsp) +vmovdqa %xmm5,80(%rsp) +vpmuludq v38_38(%rip),%xmm5,%xmm5 +vmovdqa %xmm5,96(%rsp) +vpmuludq 48(%rsp),%xmm10,%xmm5 +vpaddq %xmm0,%xmm0,%xmm6 +vpmuludq %xmm6,%xmm0,%xmm0 +vpaddq %xmm0,%xmm5,%xmm5 +vpmuludq 80(%rsp),%xmm10,%xmm0 +vpmuludq %xmm4,%xmm6,%xmm15 +vpaddq %xmm15,%xmm0,%xmm0 +vpmuludq %xmm6,%xmm13,%xmm15 +vpaddq %xmm15,%xmm1,%xmm1 +vpmuludq %xmm6,%xmm2,%xmm15 +vpaddq %xmm15,%xmm14,%xmm14 +vpunpcklqdq %xmm7,%xmm8,%xmm15 +vpunpckhqdq %xmm7,%xmm8,%xmm7 +vpaddq subc2(%rip),%xmm7,%xmm8 +vpsubq %xmm15,%xmm8,%xmm8 +vpaddq %xmm7,%xmm15,%xmm15 +vpunpckhqdq %xmm15,%xmm8,%xmm7 +vpunpcklqdq %xmm15,%xmm8,%xmm8 +vmovdqa %xmm8,112(%rsp) +vpmuludq v19_19(%rip),%xmm8,%xmm8 +vmovdqa %xmm8,448(%rsp) +vpmuludq 112(%rsp),%xmm10,%xmm8 +vpmuludq %xmm7,%xmm10,%xmm10 +vpmuludq v38_38(%rip),%xmm7,%xmm15 +vpmuludq %xmm15,%xmm7,%xmm7 +vpaddq %xmm7,%xmm8,%xmm8 +vpmuludq %xmm15,%xmm13,%xmm7 +vpaddq %xmm7,%xmm3,%xmm3 +vpmuludq %xmm15,%xmm2,%xmm7 +vpaddq %xmm7,%xmm11,%xmm11 +vpmuludq 80(%rsp),%xmm13,%xmm7 +vpaddq %xmm7,%xmm7,%xmm7 +vpaddq %xmm7,%xmm8,%xmm8 +vpmuludq 16(%rsp),%xmm13,%xmm7 +vpaddq %xmm7,%xmm5,%xmm5 +vpmuludq 48(%rsp),%xmm13,%xmm7 +vpaddq %xmm7,%xmm0,%xmm0 +vpmuludq 112(%rsp),%xmm13,%xmm7 +vpaddq %xmm7,%xmm10,%xmm10 +vpmuludq %xmm15,%xmm6,%xmm7 +vpaddq %xmm7,%xmm12,%xmm12 +vpmuludq %xmm15,%xmm4,%xmm7 +vpaddq %xmm7,%xmm9,%xmm9 +vpaddq %xmm2,%xmm2,%xmm2 +vpmuludq %xmm4,%xmm2,%xmm7 +vpaddq %xmm7,%xmm5,%xmm5 +vpmuludq 448(%rsp),%xmm2,%xmm7 +vpaddq %xmm7,%xmm3,%xmm3 +vpmuludq 448(%rsp),%xmm6,%xmm7 +vpaddq %xmm7,%xmm11,%xmm11 +vpmuludq 0(%rsp),%xmm2,%xmm7 +vpaddq %xmm7,%xmm0,%xmm0 +vpmuludq 48(%rsp),%xmm2,%xmm7 +vpaddq %xmm7,%xmm8,%xmm8 +vpmuludq 80(%rsp),%xmm2,%xmm2 +vpaddq %xmm2,%xmm10,%xmm10 +vpmuludq 96(%rsp),%xmm4,%xmm2 +vpaddq %xmm2,%xmm11,%xmm11 +vpmuludq %xmm4,%xmm4,%xmm2 +vpaddq %xmm2,%xmm8,%xmm8 +vpaddq %xmm4,%xmm4,%xmm2 +vpmuludq 448(%rsp),%xmm2,%xmm4 +vpaddq %xmm4,%xmm12,%xmm12 +vpmuludq 16(%rsp),%xmm15,%xmm4 +vpaddq %xmm4,%xmm1,%xmm1 +vpmuludq 48(%rsp),%xmm15,%xmm4 +vpaddq %xmm4,%xmm14,%xmm14 +vpmuludq 96(%rsp),%xmm6,%xmm4 +vpaddq %xmm4,%xmm3,%xmm3 +vmovdqa 16(%rsp),%xmm4 +vpmuludq 448(%rsp),%xmm4,%xmm4 +vpaddq %xmm4,%xmm9,%xmm9 +vpmuludq 16(%rsp),%xmm6,%xmm4 +vpaddq %xmm4,%xmm8,%xmm8 +vpmuludq 48(%rsp),%xmm6,%xmm4 +vpaddq %xmm4,%xmm10,%xmm10 +vpmuludq 80(%rsp),%xmm15,%xmm4 +vpaddq %xmm4,%xmm4,%xmm4 +vpaddq %xmm4,%xmm5,%xmm5 +vpmuludq 112(%rsp),%xmm15,%xmm4 +vpaddq %xmm4,%xmm0,%xmm0 +vmovdqa 48(%rsp),%xmm4 +vpaddq %xmm4,%xmm4,%xmm4 +vpmuludq 448(%rsp),%xmm4,%xmm4 +vpaddq %xmm4,%xmm1,%xmm1 +vmovdqa 80(%rsp),%xmm4 +vpaddq %xmm4,%xmm4,%xmm4 +vpmuludq 448(%rsp),%xmm4,%xmm4 +vpaddq %xmm4,%xmm14,%xmm14 +vpmuludq 64(%rsp),%xmm2,%xmm4 +vpaddq %xmm4,%xmm3,%xmm3 +vmovdqa 16(%rsp),%xmm4 +vpmuludq 64(%rsp),%xmm4,%xmm4 +vpaddq %xmm4,%xmm11,%xmm11 +vmovdqa 16(%rsp),%xmm4 +vpmuludq 96(%rsp),%xmm4,%xmm4 +vpaddq %xmm4,%xmm12,%xmm12 +vmovdqa 48(%rsp),%xmm4 +vpmuludq 96(%rsp),%xmm4,%xmm4 +vpaddq %xmm4,%xmm9,%xmm9 +vpmuludq 0(%rsp),%xmm2,%xmm2 +vpaddq %xmm2,%xmm10,%xmm10 +vmovdqa 32(%rsp),%xmm2 +vpmuludq 0(%rsp),%xmm2,%xmm2 +vpaddq %xmm2,%xmm3,%xmm3 +vmovdqa 64(%rsp),%xmm2 +vpmuludq 48(%rsp),%xmm2,%xmm2 +vpaddq %xmm2,%xmm12,%xmm12 +vmovdqa 96(%rsp),%xmm2 +vpmuludq 80(%rsp),%xmm2,%xmm2 +vpaddq %xmm2,%xmm1,%xmm1 +vmovdqa 448(%rsp),%xmm2 +vpmuludq 112(%rsp),%xmm2,%xmm2 +vpaddq %xmm2,%xmm5,%xmm5 +vpsrlq $26,%xmm3,%xmm2 +vpaddq %xmm2,%xmm11,%xmm11 +vpand m26(%rip),%xmm3,%xmm3 +vpsrlq $25,%xmm14,%xmm2 +vpaddq %xmm2,%xmm5,%xmm5 +vpand m25(%rip),%xmm14,%xmm14 +vpsrlq $25,%xmm11,%xmm2 +vpaddq %xmm2,%xmm12,%xmm12 +vpand m25(%rip),%xmm11,%xmm11 +vpsrlq $26,%xmm5,%xmm2 +vpaddq %xmm2,%xmm0,%xmm0 +vpand m26(%rip),%xmm5,%xmm5 +vpsrlq $26,%xmm12,%xmm2 +vpaddq %xmm2,%xmm9,%xmm9 +vpand m26(%rip),%xmm12,%xmm12 +vpsrlq $25,%xmm0,%xmm2 +vpaddq %xmm2,%xmm8,%xmm8 +vpand m25(%rip),%xmm0,%xmm0 +vpsrlq $25,%xmm9,%xmm2 +vpaddq %xmm2,%xmm1,%xmm1 +vpand m25(%rip),%xmm9,%xmm9 +vpsrlq $26,%xmm8,%xmm2 +vpaddq %xmm2,%xmm10,%xmm10 +vpand m26(%rip),%xmm8,%xmm8 +vpsrlq $26,%xmm1,%xmm2 +vpaddq %xmm2,%xmm14,%xmm14 +vpand m26(%rip),%xmm1,%xmm1 +vpsrlq $25,%xmm10,%xmm2 +vpsllq $4,%xmm2,%xmm4 +vpaddq %xmm2,%xmm3,%xmm3 +vpsllq $1,%xmm2,%xmm2 +vpaddq %xmm2,%xmm4,%xmm4 +vpaddq %xmm4,%xmm3,%xmm3 +vpand m25(%rip),%xmm10,%xmm10 +vpsrlq $25,%xmm14,%xmm2 +vpaddq %xmm2,%xmm5,%xmm5 +vpand m25(%rip),%xmm14,%xmm14 +vpsrlq $26,%xmm3,%xmm2 +vpaddq %xmm2,%xmm11,%xmm11 +vpand m26(%rip),%xmm3,%xmm3 +vpunpckhqdq %xmm11,%xmm3,%xmm2 +vmovdqa %xmm2,0(%rsp) +vpshufd $0,%xmm3,%xmm2 +vpshufd $0,%xmm11,%xmm3 +vpmuludq 160(%rsp),%xmm2,%xmm4 +vpmuludq 432(%rsp),%xmm3,%xmm6 +vpaddq %xmm6,%xmm4,%xmm4 +vpmuludq 176(%rsp),%xmm2,%xmm6 +vpmuludq 304(%rsp),%xmm3,%xmm7 +vpaddq %xmm7,%xmm6,%xmm6 +vpmuludq 208(%rsp),%xmm2,%xmm7 +vpmuludq 336(%rsp),%xmm3,%xmm11 +vpaddq %xmm11,%xmm7,%xmm7 +vpmuludq 240(%rsp),%xmm2,%xmm11 +vpmuludq 368(%rsp),%xmm3,%xmm13 +vpaddq %xmm13,%xmm11,%xmm11 +vpmuludq 272(%rsp),%xmm2,%xmm2 +vpmuludq 400(%rsp),%xmm3,%xmm3 +vpaddq %xmm3,%xmm2,%xmm2 +vpunpckhqdq %xmm9,%xmm12,%xmm3 +vmovdqa %xmm3,16(%rsp) +vpshufd $0,%xmm12,%xmm3 +vpshufd $0,%xmm9,%xmm9 +vpmuludq 288(%rsp),%xmm3,%xmm12 +vpaddq %xmm12,%xmm4,%xmm4 +vpmuludq 416(%rsp),%xmm9,%xmm12 +vpaddq %xmm12,%xmm4,%xmm4 +vpmuludq 160(%rsp),%xmm3,%xmm12 +vpaddq %xmm12,%xmm6,%xmm6 +vpmuludq 432(%rsp),%xmm9,%xmm12 +vpaddq %xmm12,%xmm6,%xmm6 +vpmuludq 176(%rsp),%xmm3,%xmm12 +vpaddq %xmm12,%xmm7,%xmm7 +vpmuludq 304(%rsp),%xmm9,%xmm12 +vpaddq %xmm12,%xmm7,%xmm7 +vpmuludq 208(%rsp),%xmm3,%xmm12 +vpaddq %xmm12,%xmm11,%xmm11 +vpmuludq 336(%rsp),%xmm9,%xmm12 +vpaddq %xmm12,%xmm11,%xmm11 +vpmuludq 240(%rsp),%xmm3,%xmm3 +vpaddq %xmm3,%xmm2,%xmm2 +vpmuludq 368(%rsp),%xmm9,%xmm3 +vpaddq %xmm3,%xmm2,%xmm2 +vpunpckhqdq %xmm14,%xmm1,%xmm3 +vmovdqa %xmm3,32(%rsp) +vpshufd $0,%xmm1,%xmm1 +vpshufd $0,%xmm14,%xmm3 +vpmuludq 256(%rsp),%xmm1,%xmm9 +vpaddq %xmm9,%xmm4,%xmm4 +vpmuludq 384(%rsp),%xmm3,%xmm9 +vpaddq %xmm9,%xmm4,%xmm4 +vpmuludq 288(%rsp),%xmm1,%xmm9 +vpaddq %xmm9,%xmm6,%xmm6 +vpmuludq 416(%rsp),%xmm3,%xmm9 +vpaddq %xmm9,%xmm6,%xmm6 +vpmuludq 160(%rsp),%xmm1,%xmm9 +vpaddq %xmm9,%xmm7,%xmm7 +vpmuludq 432(%rsp),%xmm3,%xmm9 +vpaddq %xmm9,%xmm7,%xmm7 +vpmuludq 176(%rsp),%xmm1,%xmm9 +vpaddq %xmm9,%xmm11,%xmm11 +vpmuludq 304(%rsp),%xmm3,%xmm9 +vpaddq %xmm9,%xmm11,%xmm11 +vpmuludq 208(%rsp),%xmm1,%xmm1 +vpaddq %xmm1,%xmm2,%xmm2 +vpmuludq 336(%rsp),%xmm3,%xmm1 +vpaddq %xmm1,%xmm2,%xmm2 +vpunpckhqdq %xmm0,%xmm5,%xmm1 +vmovdqa %xmm1,48(%rsp) +vpshufd $0,%xmm5,%xmm1 +vpshufd $0,%xmm0,%xmm0 +vpmuludq 224(%rsp),%xmm1,%xmm3 +vpaddq %xmm3,%xmm4,%xmm4 +vpmuludq 352(%rsp),%xmm0,%xmm3 +vpaddq %xmm3,%xmm4,%xmm4 +vpmuludq 256(%rsp),%xmm1,%xmm3 +vpaddq %xmm3,%xmm6,%xmm6 +vpmuludq 384(%rsp),%xmm0,%xmm3 +vpaddq %xmm3,%xmm6,%xmm6 +vpmuludq 288(%rsp),%xmm1,%xmm3 +vpaddq %xmm3,%xmm7,%xmm7 +vpmuludq 416(%rsp),%xmm0,%xmm3 +vpaddq %xmm3,%xmm7,%xmm7 +vpmuludq 160(%rsp),%xmm1,%xmm3 +vpaddq %xmm3,%xmm11,%xmm11 +vpmuludq 432(%rsp),%xmm0,%xmm3 +vpaddq %xmm3,%xmm11,%xmm11 +vpmuludq 176(%rsp),%xmm1,%xmm1 +vpaddq %xmm1,%xmm2,%xmm2 +vpmuludq 304(%rsp),%xmm0,%xmm0 +vpaddq %xmm0,%xmm2,%xmm2 +vpunpckhqdq %xmm10,%xmm8,%xmm0 +vmovdqa %xmm0,64(%rsp) +vpshufd $0,%xmm8,%xmm0 +vpshufd $0,%xmm10,%xmm1 +vpmuludq 192(%rsp),%xmm0,%xmm3 +vpaddq %xmm3,%xmm4,%xmm4 +vpmuludq 320(%rsp),%xmm1,%xmm3 +vpaddq %xmm3,%xmm4,%xmm4 +vpmuludq 224(%rsp),%xmm0,%xmm3 +vpaddq %xmm3,%xmm6,%xmm6 +vpmuludq 352(%rsp),%xmm1,%xmm3 +vpaddq %xmm3,%xmm6,%xmm6 +vpmuludq 256(%rsp),%xmm0,%xmm3 +vpaddq %xmm3,%xmm7,%xmm7 +vpmuludq 384(%rsp),%xmm1,%xmm3 +vpaddq %xmm3,%xmm7,%xmm7 +vpmuludq 288(%rsp),%xmm0,%xmm3 +vpaddq %xmm3,%xmm11,%xmm11 +vpmuludq 416(%rsp),%xmm1,%xmm3 +vpaddq %xmm3,%xmm11,%xmm11 +vpmuludq 160(%rsp),%xmm0,%xmm0 +vpaddq %xmm0,%xmm2,%xmm2 +vpmuludq 432(%rsp),%xmm1,%xmm0 +vpaddq %xmm0,%xmm2,%xmm2 +vmovdqa %xmm4,80(%rsp) +vmovdqa %xmm6,96(%rsp) +vmovdqa %xmm7,112(%rsp) +vmovdqa %xmm11,448(%rsp) +vmovdqa %xmm2,496(%rsp) +vmovdqa 144(%rsp),%xmm0 +vpmuludq %xmm0,%xmm0,%xmm1 +vpaddq %xmm0,%xmm0,%xmm0 +vmovdqa 128(%rsp),%xmm2 +vpmuludq %xmm2,%xmm0,%xmm3 +vmovdqa 480(%rsp),%xmm4 +vpmuludq %xmm4,%xmm0,%xmm5 +vmovdqa 464(%rsp),%xmm6 +vpmuludq %xmm6,%xmm0,%xmm7 +vmovdqa 528(%rsp),%xmm8 +vpmuludq %xmm8,%xmm0,%xmm9 +vpmuludq 512(%rsp),%xmm0,%xmm10 +vpmuludq 592(%rsp),%xmm0,%xmm11 +vpmuludq 576(%rsp),%xmm0,%xmm12 +vpmuludq 624(%rsp),%xmm0,%xmm13 +vmovdqa 672(%rsp),%xmm14 +vpmuludq %xmm14,%xmm0,%xmm0 +vpmuludq v38_38(%rip),%xmm14,%xmm15 +vpmuludq %xmm15,%xmm14,%xmm14 +vpaddq %xmm14,%xmm13,%xmm13 +vpaddq %xmm6,%xmm6,%xmm14 +vpmuludq %xmm14,%xmm6,%xmm6 +vpaddq %xmm6,%xmm11,%xmm11 +vpaddq %xmm2,%xmm2,%xmm6 +vpmuludq %xmm6,%xmm2,%xmm2 +vpaddq %xmm2,%xmm5,%xmm5 +vpmuludq %xmm15,%xmm6,%xmm2 +vpaddq %xmm2,%xmm1,%xmm1 +vpmuludq %xmm15,%xmm4,%xmm2 +vpaddq %xmm2,%xmm3,%xmm3 +vpmuludq 544(%rsp),%xmm6,%xmm2 +vpaddq %xmm2,%xmm11,%xmm11 +vpmuludq 592(%rsp),%xmm6,%xmm2 +vpaddq %xmm2,%xmm12,%xmm12 +vpmuludq 640(%rsp),%xmm6,%xmm2 +vpaddq %xmm2,%xmm13,%xmm13 +vpmuludq 624(%rsp),%xmm6,%xmm2 +vpaddq %xmm2,%xmm0,%xmm0 +vpmuludq %xmm4,%xmm6,%xmm2 +vpaddq %xmm2,%xmm7,%xmm7 +vpmuludq %xmm14,%xmm6,%xmm2 +vpaddq %xmm2,%xmm9,%xmm9 +vpmuludq %xmm8,%xmm6,%xmm2 +vpaddq %xmm2,%xmm10,%xmm10 +vpmuludq %xmm15,%xmm14,%xmm2 +vpaddq %xmm2,%xmm5,%xmm5 +vpmuludq %xmm15,%xmm8,%xmm2 +vpaddq %xmm2,%xmm7,%xmm7 +vpmuludq %xmm4,%xmm4,%xmm2 +vpaddq %xmm2,%xmm9,%xmm9 +vpmuludq %xmm14,%xmm4,%xmm2 +vpaddq %xmm2,%xmm10,%xmm10 +vpaddq %xmm4,%xmm4,%xmm2 +vpmuludq %xmm8,%xmm2,%xmm4 +vpaddq %xmm4,%xmm11,%xmm11 +vpmuludq 688(%rsp),%xmm2,%xmm4 +vpaddq %xmm4,%xmm1,%xmm1 +vpmuludq 688(%rsp),%xmm14,%xmm4 +vpaddq %xmm4,%xmm3,%xmm3 +vpmuludq 512(%rsp),%xmm2,%xmm4 +vpaddq %xmm4,%xmm12,%xmm12 +vpmuludq 592(%rsp),%xmm2,%xmm4 +vpaddq %xmm4,%xmm13,%xmm13 +vpmuludq 576(%rsp),%xmm2,%xmm2 +vpaddq %xmm2,%xmm0,%xmm0 +vpmuludq 656(%rsp),%xmm8,%xmm2 +vpaddq %xmm2,%xmm3,%xmm3 +vpmuludq %xmm8,%xmm14,%xmm2 +vpaddq %xmm2,%xmm12,%xmm12 +vpmuludq %xmm8,%xmm8,%xmm2 +vpaddq %xmm2,%xmm13,%xmm13 +vpaddq %xmm8,%xmm8,%xmm2 +vpmuludq 688(%rsp),%xmm2,%xmm4 +vpaddq %xmm4,%xmm5,%xmm5 +vpmuludq 544(%rsp),%xmm15,%xmm4 +vpaddq %xmm4,%xmm9,%xmm9 +vpmuludq 592(%rsp),%xmm15,%xmm4 +vpaddq %xmm4,%xmm10,%xmm10 +vpmuludq 656(%rsp),%xmm14,%xmm4 +vpaddq %xmm4,%xmm1,%xmm1 +vmovdqa 544(%rsp),%xmm4 +vpmuludq 688(%rsp),%xmm4,%xmm4 +vpaddq %xmm4,%xmm7,%xmm7 +vpmuludq 544(%rsp),%xmm14,%xmm4 +vpaddq %xmm4,%xmm13,%xmm13 +vpmuludq 592(%rsp),%xmm14,%xmm4 +vpaddq %xmm4,%xmm0,%xmm0 +vpmuludq 640(%rsp),%xmm15,%xmm4 +vpaddq %xmm4,%xmm11,%xmm11 +vpmuludq 624(%rsp),%xmm15,%xmm4 +vpaddq %xmm4,%xmm12,%xmm12 +vmovdqa 592(%rsp),%xmm4 +vpaddq %xmm4,%xmm4,%xmm4 +vpmuludq 688(%rsp),%xmm4,%xmm4 +vpaddq %xmm4,%xmm9,%xmm9 +vpmuludq 608(%rsp),%xmm2,%xmm4 +vpaddq %xmm4,%xmm1,%xmm1 +vmovdqa 544(%rsp),%xmm4 +vpmuludq 608(%rsp),%xmm4,%xmm4 +vpaddq %xmm4,%xmm3,%xmm3 +vmovdqa 544(%rsp),%xmm4 +vpmuludq 656(%rsp),%xmm4,%xmm4 +vpaddq %xmm4,%xmm5,%xmm5 +vmovdqa 592(%rsp),%xmm4 +vpmuludq 656(%rsp),%xmm4,%xmm4 +vpaddq %xmm4,%xmm7,%xmm7 +vmovdqa 640(%rsp),%xmm4 +vpmuludq 688(%rsp),%xmm4,%xmm4 +vpaddq %xmm4,%xmm10,%xmm10 +vpmuludq 512(%rsp),%xmm2,%xmm2 +vpaddq %xmm2,%xmm0,%xmm0 +vmovdqa 560(%rsp),%xmm2 +vpmuludq 512(%rsp),%xmm2,%xmm2 +vpaddq %xmm2,%xmm1,%xmm1 +vmovdqa 608(%rsp),%xmm2 +vpmuludq 592(%rsp),%xmm2,%xmm2 +vpaddq %xmm2,%xmm5,%xmm5 +vmovdqa 656(%rsp),%xmm2 +vpmuludq 576(%rsp),%xmm2,%xmm2 +vpaddq %xmm2,%xmm9,%xmm9 +vmovdqa 688(%rsp),%xmm2 +vpmuludq 624(%rsp),%xmm2,%xmm2 +vpaddq %xmm2,%xmm11,%xmm11 +vpsrlq $26,%xmm1,%xmm2 +vpaddq %xmm2,%xmm3,%xmm3 +vpand m26(%rip),%xmm1,%xmm1 +vpsrlq $25,%xmm10,%xmm2 +vpaddq %xmm2,%xmm11,%xmm11 +vpand m25(%rip),%xmm10,%xmm10 +vpsrlq $25,%xmm3,%xmm2 +vpaddq %xmm2,%xmm5,%xmm5 +vpand m25(%rip),%xmm3,%xmm3 +vpsrlq $26,%xmm11,%xmm2 +vpaddq %xmm2,%xmm12,%xmm12 +vpand m26(%rip),%xmm11,%xmm11 +vpsrlq $26,%xmm5,%xmm2 +vpaddq %xmm2,%xmm7,%xmm7 +vpand m26(%rip),%xmm5,%xmm5 +vpsrlq $25,%xmm12,%xmm2 +vpaddq %xmm2,%xmm13,%xmm13 +vpand m25(%rip),%xmm12,%xmm12 +vpsrlq $25,%xmm7,%xmm2 +vpaddq %xmm2,%xmm9,%xmm9 +vpand m25(%rip),%xmm7,%xmm7 +vpsrlq $26,%xmm13,%xmm2 +vpaddq %xmm2,%xmm0,%xmm0 +vpand m26(%rip),%xmm13,%xmm13 +vpsrlq $26,%xmm9,%xmm2 +vpaddq %xmm2,%xmm10,%xmm10 +vpand m26(%rip),%xmm9,%xmm9 +vpsrlq $25,%xmm0,%xmm2 +vpsllq $4,%xmm2,%xmm4 +vpaddq %xmm2,%xmm1,%xmm1 +vpsllq $1,%xmm2,%xmm2 +vpaddq %xmm2,%xmm4,%xmm4 +vpaddq %xmm4,%xmm1,%xmm1 +vpand m25(%rip),%xmm0,%xmm0 +vpsrlq $25,%xmm10,%xmm2 +vpaddq %xmm2,%xmm11,%xmm11 +vpand m25(%rip),%xmm10,%xmm10 +vpsrlq $26,%xmm1,%xmm2 +vpaddq %xmm2,%xmm3,%xmm3 +vpand m26(%rip),%xmm1,%xmm1 +vpunpckhqdq %xmm3,%xmm1,%xmm2 +vpunpcklqdq %xmm3,%xmm1,%xmm1 +vmovdqa %xmm1,464(%rsp) +vpaddq subc0(%rip),%xmm2,%xmm3 +vpsubq %xmm1,%xmm3,%xmm3 +vpunpckhqdq %xmm3,%xmm2,%xmm1 +vpunpcklqdq %xmm3,%xmm2,%xmm2 +vmovdqa %xmm2,480(%rsp) +vmovdqa %xmm1,512(%rsp) +vpsllq $1,%xmm1,%xmm1 +vmovdqa %xmm1,528(%rsp) +vpmuludq v121666_121666(%rip),%xmm3,%xmm3 +vmovdqa 80(%rsp),%xmm1 +vpunpcklqdq %xmm1,%xmm3,%xmm2 +vpunpckhqdq %xmm1,%xmm3,%xmm1 +vpunpckhqdq %xmm7,%xmm5,%xmm3 +vpunpcklqdq %xmm7,%xmm5,%xmm4 +vmovdqa %xmm4,544(%rsp) +vpaddq subc2(%rip),%xmm3,%xmm5 +vpsubq %xmm4,%xmm5,%xmm5 +vpunpckhqdq %xmm5,%xmm3,%xmm4 +vpunpcklqdq %xmm5,%xmm3,%xmm3 +vmovdqa %xmm3,560(%rsp) +vmovdqa %xmm4,576(%rsp) +vpsllq $1,%xmm4,%xmm4 +vmovdqa %xmm4,592(%rsp) +vpmuludq v121666_121666(%rip),%xmm5,%xmm5 +vmovdqa 96(%rsp),%xmm3 +vpunpcklqdq %xmm3,%xmm5,%xmm4 +vpunpckhqdq %xmm3,%xmm5,%xmm3 +vpunpckhqdq %xmm10,%xmm9,%xmm5 +vpunpcklqdq %xmm10,%xmm9,%xmm6 +vmovdqa %xmm6,608(%rsp) +vpaddq subc2(%rip),%xmm5,%xmm7 +vpsubq %xmm6,%xmm7,%xmm7 +vpunpckhqdq %xmm7,%xmm5,%xmm6 +vpunpcklqdq %xmm7,%xmm5,%xmm5 +vmovdqa %xmm5,624(%rsp) +vmovdqa %xmm6,640(%rsp) +vpsllq $1,%xmm6,%xmm6 +vmovdqa %xmm6,656(%rsp) +vpmuludq v121666_121666(%rip),%xmm7,%xmm7 +vmovdqa 112(%rsp),%xmm5 +vpunpcklqdq %xmm5,%xmm7,%xmm6 +vpunpckhqdq %xmm5,%xmm7,%xmm5 +vpunpckhqdq %xmm12,%xmm11,%xmm7 +vpunpcklqdq %xmm12,%xmm11,%xmm8 +vmovdqa %xmm8,672(%rsp) +vpaddq subc2(%rip),%xmm7,%xmm9 +vpsubq %xmm8,%xmm9,%xmm9 +vpunpckhqdq %xmm9,%xmm7,%xmm8 +vpunpcklqdq %xmm9,%xmm7,%xmm7 +vmovdqa %xmm7,688(%rsp) +vmovdqa %xmm8,704(%rsp) +vpsllq $1,%xmm8,%xmm8 +vmovdqa %xmm8,720(%rsp) +vpmuludq v121666_121666(%rip),%xmm9,%xmm9 +vmovdqa 448(%rsp),%xmm7 +vpunpcklqdq %xmm7,%xmm9,%xmm8 +vpunpckhqdq %xmm7,%xmm9,%xmm7 +vpunpckhqdq %xmm0,%xmm13,%xmm9 +vpunpcklqdq %xmm0,%xmm13,%xmm0 +vmovdqa %xmm0,448(%rsp) +vpaddq subc2(%rip),%xmm9,%xmm10 +vpsubq %xmm0,%xmm10,%xmm10 +vpunpckhqdq %xmm10,%xmm9,%xmm0 +vpunpcklqdq %xmm10,%xmm9,%xmm9 +vmovdqa %xmm9,736(%rsp) +vmovdqa %xmm0,752(%rsp) +vpsllq $1,%xmm0,%xmm0 +vmovdqa %xmm0,768(%rsp) +vpmuludq v121666_121666(%rip),%xmm10,%xmm10 +vmovdqa 496(%rsp),%xmm0 +vpunpcklqdq %xmm0,%xmm10,%xmm9 +vpunpckhqdq %xmm0,%xmm10,%xmm0 +vpsrlq $26,%xmm2,%xmm10 +vpaddq %xmm10,%xmm1,%xmm1 +vpand m26(%rip),%xmm2,%xmm2 +vpsrlq $25,%xmm5,%xmm10 +vpaddq %xmm10,%xmm8,%xmm8 +vpand m25(%rip),%xmm5,%xmm5 +vpsrlq $25,%xmm1,%xmm10 +vpaddq %xmm10,%xmm4,%xmm4 +vpand m25(%rip),%xmm1,%xmm1 +vpsrlq $26,%xmm8,%xmm10 +vpaddq %xmm10,%xmm7,%xmm7 +vpand m26(%rip),%xmm8,%xmm8 +vpsrlq $26,%xmm4,%xmm10 +vpaddq %xmm10,%xmm3,%xmm3 +vpand m26(%rip),%xmm4,%xmm4 +vpsrlq $25,%xmm7,%xmm10 +vpaddq %xmm10,%xmm9,%xmm9 +vpand m25(%rip),%xmm7,%xmm7 +vpsrlq $25,%xmm3,%xmm10 +vpaddq %xmm10,%xmm6,%xmm6 +vpand m25(%rip),%xmm3,%xmm3 +vpsrlq $26,%xmm9,%xmm10 +vpaddq %xmm10,%xmm0,%xmm0 +vpand m26(%rip),%xmm9,%xmm9 +vpsrlq $26,%xmm6,%xmm10 +vpaddq %xmm10,%xmm5,%xmm5 +vpand m26(%rip),%xmm6,%xmm6 +vpsrlq $25,%xmm0,%xmm10 +vpsllq $4,%xmm10,%xmm11 +vpaddq %xmm10,%xmm2,%xmm2 +vpsllq $1,%xmm10,%xmm10 +vpaddq %xmm10,%xmm11,%xmm11 +vpaddq %xmm11,%xmm2,%xmm2 +vpand m25(%rip),%xmm0,%xmm0 +vpsrlq $25,%xmm5,%xmm10 +vpaddq %xmm10,%xmm8,%xmm8 +vpand m25(%rip),%xmm5,%xmm5 +vpsrlq $26,%xmm2,%xmm10 +vpaddq %xmm10,%xmm1,%xmm1 +vpand m26(%rip),%xmm2,%xmm2 +vpunpckhqdq %xmm1,%xmm2,%xmm10 +vmovdqa %xmm10,80(%rsp) +vpunpcklqdq %xmm1,%xmm2,%xmm1 +vpunpckhqdq %xmm3,%xmm4,%xmm2 +vmovdqa %xmm2,96(%rsp) +vpunpcklqdq %xmm3,%xmm4,%xmm2 +vpunpckhqdq %xmm5,%xmm6,%xmm3 +vmovdqa %xmm3,112(%rsp) +vpunpcklqdq %xmm5,%xmm6,%xmm3 +vpunpckhqdq %xmm7,%xmm8,%xmm4 +vmovdqa %xmm4,128(%rsp) +vpunpcklqdq %xmm7,%xmm8,%xmm4 +vpunpckhqdq %xmm0,%xmm9,%xmm5 +vmovdqa %xmm5,144(%rsp) +vpunpcklqdq %xmm0,%xmm9,%xmm0 +vmovdqa 464(%rsp),%xmm5 +vpaddq %xmm5,%xmm1,%xmm1 +vpunpcklqdq %xmm1,%xmm5,%xmm6 +vpunpckhqdq %xmm1,%xmm5,%xmm1 +vpmuludq 512(%rsp),%xmm6,%xmm5 +vpmuludq 480(%rsp),%xmm1,%xmm7 +vpaddq %xmm7,%xmm5,%xmm5 +vpmuludq 560(%rsp),%xmm6,%xmm7 +vpmuludq 528(%rsp),%xmm1,%xmm8 +vpaddq %xmm8,%xmm7,%xmm7 +vpmuludq 576(%rsp),%xmm6,%xmm8 +vpmuludq 560(%rsp),%xmm1,%xmm9 +vpaddq %xmm9,%xmm8,%xmm8 +vpmuludq 624(%rsp),%xmm6,%xmm9 +vpmuludq 592(%rsp),%xmm1,%xmm10 +vpaddq %xmm10,%xmm9,%xmm9 +vpmuludq 640(%rsp),%xmm6,%xmm10 +vpmuludq 624(%rsp),%xmm1,%xmm11 +vpaddq %xmm11,%xmm10,%xmm10 +vpmuludq 688(%rsp),%xmm6,%xmm11 +vpmuludq 656(%rsp),%xmm1,%xmm12 +vpaddq %xmm12,%xmm11,%xmm11 +vpmuludq 704(%rsp),%xmm6,%xmm12 +vpmuludq 688(%rsp),%xmm1,%xmm13 +vpaddq %xmm13,%xmm12,%xmm12 +vpmuludq 736(%rsp),%xmm6,%xmm13 +vpmuludq 720(%rsp),%xmm1,%xmm14 +vpaddq %xmm14,%xmm13,%xmm13 +vpmuludq 752(%rsp),%xmm6,%xmm14 +vpmuludq 736(%rsp),%xmm1,%xmm15 +vpaddq %xmm15,%xmm14,%xmm14 +vpmuludq 480(%rsp),%xmm6,%xmm6 +vpmuludq v19_19(%rip),%xmm1,%xmm1 +vpmuludq 768(%rsp),%xmm1,%xmm1 +vpaddq %xmm1,%xmm6,%xmm6 +vmovdqa 544(%rsp),%xmm1 +vpaddq %xmm1,%xmm2,%xmm2 +vpunpcklqdq %xmm2,%xmm1,%xmm15 +vpunpckhqdq %xmm2,%xmm1,%xmm1 +vpmuludq 480(%rsp),%xmm15,%xmm2 +vpaddq %xmm2,%xmm7,%xmm7 +vpmuludq 512(%rsp),%xmm15,%xmm2 +vpaddq %xmm2,%xmm8,%xmm8 +vpmuludq 560(%rsp),%xmm15,%xmm2 +vpaddq %xmm2,%xmm9,%xmm9 +vpmuludq 576(%rsp),%xmm15,%xmm2 +vpaddq %xmm2,%xmm10,%xmm10 +vpmuludq 624(%rsp),%xmm15,%xmm2 +vpaddq %xmm2,%xmm11,%xmm11 +vpmuludq 640(%rsp),%xmm15,%xmm2 +vpaddq %xmm2,%xmm12,%xmm12 +vpmuludq 688(%rsp),%xmm15,%xmm2 +vpaddq %xmm2,%xmm13,%xmm13 +vpmuludq 704(%rsp),%xmm15,%xmm2 +vpaddq %xmm2,%xmm14,%xmm14 +vpmuludq v19_19(%rip),%xmm15,%xmm15 +vpmuludq 736(%rsp),%xmm15,%xmm2 +vpaddq %xmm2,%xmm6,%xmm6 +vpmuludq 752(%rsp),%xmm15,%xmm15 +vpaddq %xmm15,%xmm5,%xmm5 +vpmuludq 480(%rsp),%xmm1,%xmm2 +vpaddq %xmm2,%xmm8,%xmm8 +vpmuludq 528(%rsp),%xmm1,%xmm2 +vpaddq %xmm2,%xmm9,%xmm9 +vpmuludq 560(%rsp),%xmm1,%xmm2 +vpaddq %xmm2,%xmm10,%xmm10 +vpmuludq 592(%rsp),%xmm1,%xmm2 +vpaddq %xmm2,%xmm11,%xmm11 +vpmuludq 624(%rsp),%xmm1,%xmm2 +vpaddq %xmm2,%xmm12,%xmm12 +vpmuludq 656(%rsp),%xmm1,%xmm2 +vpaddq %xmm2,%xmm13,%xmm13 +vpmuludq 688(%rsp),%xmm1,%xmm2 +vpaddq %xmm2,%xmm14,%xmm14 +vpmuludq v19_19(%rip),%xmm1,%xmm1 +vpmuludq 720(%rsp),%xmm1,%xmm2 +vpaddq %xmm2,%xmm6,%xmm6 +vpmuludq 736(%rsp),%xmm1,%xmm2 +vpaddq %xmm2,%xmm5,%xmm5 +vpmuludq 768(%rsp),%xmm1,%xmm1 +vpaddq %xmm1,%xmm7,%xmm7 +vmovdqa 608(%rsp),%xmm1 +vpaddq %xmm1,%xmm3,%xmm3 +vpunpcklqdq %xmm3,%xmm1,%xmm2 +vpunpckhqdq %xmm3,%xmm1,%xmm1 +vpmuludq 480(%rsp),%xmm2,%xmm3 +vpaddq %xmm3,%xmm9,%xmm9 +vpmuludq 512(%rsp),%xmm2,%xmm3 +vpaddq %xmm3,%xmm10,%xmm10 +vpmuludq 560(%rsp),%xmm2,%xmm3 +vpaddq %xmm3,%xmm11,%xmm11 +vpmuludq 576(%rsp),%xmm2,%xmm3 +vpaddq %xmm3,%xmm12,%xmm12 +vpmuludq 624(%rsp),%xmm2,%xmm3 +vpaddq %xmm3,%xmm13,%xmm13 +vpmuludq 640(%rsp),%xmm2,%xmm3 +vpaddq %xmm3,%xmm14,%xmm14 +vpmuludq v19_19(%rip),%xmm2,%xmm2 +vpmuludq 688(%rsp),%xmm2,%xmm3 +vpaddq %xmm3,%xmm6,%xmm6 +vpmuludq 704(%rsp),%xmm2,%xmm3 +vpaddq %xmm3,%xmm5,%xmm5 +vpmuludq 736(%rsp),%xmm2,%xmm3 +vpaddq %xmm3,%xmm7,%xmm7 +vpmuludq 752(%rsp),%xmm2,%xmm2 +vpaddq %xmm2,%xmm8,%xmm8 +vpmuludq 480(%rsp),%xmm1,%xmm2 +vpaddq %xmm2,%xmm10,%xmm10 +vpmuludq 528(%rsp),%xmm1,%xmm2 +vpaddq %xmm2,%xmm11,%xmm11 +vpmuludq 560(%rsp),%xmm1,%xmm2 +vpaddq %xmm2,%xmm12,%xmm12 +vpmuludq 592(%rsp),%xmm1,%xmm2 +vpaddq %xmm2,%xmm13,%xmm13 +vpmuludq 624(%rsp),%xmm1,%xmm2 +vpaddq %xmm2,%xmm14,%xmm14 +vpmuludq v19_19(%rip),%xmm1,%xmm1 +vpmuludq 656(%rsp),%xmm1,%xmm2 +vpaddq %xmm2,%xmm6,%xmm6 +vpmuludq 688(%rsp),%xmm1,%xmm2 +vpaddq %xmm2,%xmm5,%xmm5 +vpmuludq 720(%rsp),%xmm1,%xmm2 +vpaddq %xmm2,%xmm7,%xmm7 +vpmuludq 736(%rsp),%xmm1,%xmm2 +vpaddq %xmm2,%xmm8,%xmm8 +vpmuludq 768(%rsp),%xmm1,%xmm1 +vpaddq %xmm1,%xmm9,%xmm9 +vmovdqa 672(%rsp),%xmm1 +vpaddq %xmm1,%xmm4,%xmm4 +vpunpcklqdq %xmm4,%xmm1,%xmm2 +vpunpckhqdq %xmm4,%xmm1,%xmm1 +vpmuludq 480(%rsp),%xmm2,%xmm3 +vpaddq %xmm3,%xmm11,%xmm11 +vpmuludq 512(%rsp),%xmm2,%xmm3 +vpaddq %xmm3,%xmm12,%xmm12 +vpmuludq 560(%rsp),%xmm2,%xmm3 +vpaddq %xmm3,%xmm13,%xmm13 +vpmuludq 576(%rsp),%xmm2,%xmm3 +vpaddq %xmm3,%xmm14,%xmm14 +vpmuludq v19_19(%rip),%xmm2,%xmm2 +vpmuludq 624(%rsp),%xmm2,%xmm3 +vpaddq %xmm3,%xmm6,%xmm6 +vpmuludq 640(%rsp),%xmm2,%xmm3 +vpaddq %xmm3,%xmm5,%xmm5 +vpmuludq 688(%rsp),%xmm2,%xmm3 +vpaddq %xmm3,%xmm7,%xmm7 +vpmuludq 704(%rsp),%xmm2,%xmm3 +vpaddq %xmm3,%xmm8,%xmm8 +vpmuludq 736(%rsp),%xmm2,%xmm3 +vpaddq %xmm3,%xmm9,%xmm9 +vpmuludq 752(%rsp),%xmm2,%xmm2 +vpaddq %xmm2,%xmm10,%xmm10 +vpmuludq 480(%rsp),%xmm1,%xmm2 +vpaddq %xmm2,%xmm12,%xmm12 +vpmuludq 528(%rsp),%xmm1,%xmm2 +vpaddq %xmm2,%xmm13,%xmm13 +vpmuludq 560(%rsp),%xmm1,%xmm2 +vpaddq %xmm2,%xmm14,%xmm14 +vpmuludq v19_19(%rip),%xmm1,%xmm1 +vpmuludq 592(%rsp),%xmm1,%xmm2 +vpaddq %xmm2,%xmm6,%xmm6 +vpmuludq 624(%rsp),%xmm1,%xmm2 +vpaddq %xmm2,%xmm5,%xmm5 +vpmuludq 656(%rsp),%xmm1,%xmm2 +vpaddq %xmm2,%xmm7,%xmm7 +vpmuludq 688(%rsp),%xmm1,%xmm2 +vpaddq %xmm2,%xmm8,%xmm8 +vpmuludq 720(%rsp),%xmm1,%xmm2 +vpaddq %xmm2,%xmm9,%xmm9 +vpmuludq 736(%rsp),%xmm1,%xmm2 +vpaddq %xmm2,%xmm10,%xmm10 +vpmuludq 768(%rsp),%xmm1,%xmm1 +vpaddq %xmm1,%xmm11,%xmm11 +vmovdqa 448(%rsp),%xmm1 +vpaddq %xmm1,%xmm0,%xmm0 +vpunpcklqdq %xmm0,%xmm1,%xmm2 +vpunpckhqdq %xmm0,%xmm1,%xmm0 +vpmuludq 480(%rsp),%xmm2,%xmm1 +vpaddq %xmm1,%xmm13,%xmm13 +vpmuludq 512(%rsp),%xmm2,%xmm1 +vpaddq %xmm1,%xmm14,%xmm14 +vpmuludq v19_19(%rip),%xmm2,%xmm2 +vpmuludq 560(%rsp),%xmm2,%xmm1 +vpaddq %xmm1,%xmm6,%xmm6 +vpmuludq 576(%rsp),%xmm2,%xmm1 +vpaddq %xmm1,%xmm5,%xmm5 +vpmuludq 624(%rsp),%xmm2,%xmm1 +vpaddq %xmm1,%xmm7,%xmm7 +vpmuludq 640(%rsp),%xmm2,%xmm1 +vpaddq %xmm1,%xmm8,%xmm8 +vpmuludq 688(%rsp),%xmm2,%xmm1 +vpaddq %xmm1,%xmm9,%xmm9 +vpmuludq 704(%rsp),%xmm2,%xmm1 +vpaddq %xmm1,%xmm10,%xmm10 +vpmuludq 736(%rsp),%xmm2,%xmm1 +vpaddq %xmm1,%xmm11,%xmm11 +vpmuludq 752(%rsp),%xmm2,%xmm2 +vpaddq %xmm2,%xmm12,%xmm12 +vpmuludq 480(%rsp),%xmm0,%xmm1 +vpaddq %xmm1,%xmm14,%xmm14 +vpmuludq v19_19(%rip),%xmm0,%xmm0 +vpmuludq 528(%rsp),%xmm0,%xmm1 +vpaddq %xmm1,%xmm6,%xmm6 +vpmuludq 560(%rsp),%xmm0,%xmm1 +vpaddq %xmm1,%xmm5,%xmm5 +vpmuludq 592(%rsp),%xmm0,%xmm1 +vpaddq %xmm1,%xmm7,%xmm7 +vpmuludq 624(%rsp),%xmm0,%xmm1 +vpaddq %xmm1,%xmm8,%xmm8 +vpmuludq 656(%rsp),%xmm0,%xmm1 +vpaddq %xmm1,%xmm9,%xmm9 +vpmuludq 688(%rsp),%xmm0,%xmm1 +vpaddq %xmm1,%xmm10,%xmm10 +vpmuludq 720(%rsp),%xmm0,%xmm1 +vpaddq %xmm1,%xmm11,%xmm11 +vpmuludq 736(%rsp),%xmm0,%xmm1 +vpaddq %xmm1,%xmm12,%xmm12 +vpmuludq 768(%rsp),%xmm0,%xmm0 +vpaddq %xmm0,%xmm13,%xmm13 +vpsrlq $26,%xmm6,%xmm0 +vpaddq %xmm0,%xmm5,%xmm5 +vpand m26(%rip),%xmm6,%xmm6 +vpsrlq $25,%xmm10,%xmm0 +vpaddq %xmm0,%xmm11,%xmm11 +vpand m25(%rip),%xmm10,%xmm10 +vpsrlq $25,%xmm5,%xmm0 +vpaddq %xmm0,%xmm7,%xmm7 +vpand m25(%rip),%xmm5,%xmm5 +vpsrlq $26,%xmm11,%xmm0 +vpaddq %xmm0,%xmm12,%xmm12 +vpand m26(%rip),%xmm11,%xmm11 +vpsrlq $26,%xmm7,%xmm0 +vpaddq %xmm0,%xmm8,%xmm8 +vpand m26(%rip),%xmm7,%xmm7 +vpsrlq $25,%xmm12,%xmm0 +vpaddq %xmm0,%xmm13,%xmm13 +vpand m25(%rip),%xmm12,%xmm12 +vpsrlq $25,%xmm8,%xmm0 +vpaddq %xmm0,%xmm9,%xmm9 +vpand m25(%rip),%xmm8,%xmm8 +vpsrlq $26,%xmm13,%xmm0 +vpaddq %xmm0,%xmm14,%xmm14 +vpand m26(%rip),%xmm13,%xmm13 +vpsrlq $26,%xmm9,%xmm0 +vpaddq %xmm0,%xmm10,%xmm10 +vpand m26(%rip),%xmm9,%xmm9 +vpsrlq $25,%xmm14,%xmm0 +vpsllq $4,%xmm0,%xmm1 +vpaddq %xmm0,%xmm6,%xmm6 +vpsllq $1,%xmm0,%xmm0 +vpaddq %xmm0,%xmm1,%xmm1 +vpaddq %xmm1,%xmm6,%xmm6 +vpand m25(%rip),%xmm14,%xmm14 +vpsrlq $25,%xmm10,%xmm0 +vpaddq %xmm0,%xmm11,%xmm11 +vpand m25(%rip),%xmm10,%xmm10 +vpsrlq $26,%xmm6,%xmm0 +vpaddq %xmm0,%xmm5,%xmm5 +vpand m26(%rip),%xmm6,%xmm6 +vpunpckhqdq %xmm5,%xmm6,%xmm1 +vpunpcklqdq %xmm5,%xmm6,%xmm0 +vpunpckhqdq %xmm8,%xmm7,%xmm3 +vpunpcklqdq %xmm8,%xmm7,%xmm2 +vpunpckhqdq %xmm10,%xmm9,%xmm5 +vpunpcklqdq %xmm10,%xmm9,%xmm4 +vpunpckhqdq %xmm12,%xmm11,%xmm7 +vpunpcklqdq %xmm12,%xmm11,%xmm6 +vpunpckhqdq %xmm14,%xmm13,%xmm9 +vpunpcklqdq %xmm14,%xmm13,%xmm8 +cmp $0,%rdx +jne ._ladder_loop +vmovdqu %xmm1,160(%rdi) +vmovdqu %xmm0,80(%rdi) +vmovdqu %xmm3,176(%rdi) +vmovdqu %xmm2,96(%rdi) +vmovdqu %xmm5,192(%rdi) +vmovdqu %xmm4,112(%rdi) +vmovdqu %xmm7,208(%rdi) +vmovdqu %xmm6,128(%rdi) +vmovdqu %xmm9,224(%rdi) +vmovdqu %xmm8,144(%rdi) +movq 1824(%rsp),%r11 +movq 1832(%rsp),%r12 +movq 1840(%rsp),%r13 +movq 1848(%rsp),%r14 +add %r11,%rsp +ret + +#endif diff --git a/libs/libsodium/src/crypto_scalarmult/curve25519/sandy2x/ladder.h b/libs/libsodium/src/crypto_scalarmult/curve25519/sandy2x/ladder.h new file mode 100644 index 0000000000..ccf4ecaecd --- /dev/null +++ b/libs/libsodium/src/crypto_scalarmult/curve25519/sandy2x/ladder.h @@ -0,0 +1,18 @@ +#ifndef ladder_H +#define ladder_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include "fe.h" +#include "ladder_namespace.h" + +extern void ladder(fe *, const unsigned char *); + +#ifdef __cplusplus +} +#endif + +#endif /* ifndef ladder_H */ + diff --git a/libs/libsodium/src/crypto_scalarmult/curve25519/sandy2x/ladder_base.S b/libs/libsodium/src/crypto_scalarmult/curve25519/sandy2x/ladder_base.S new file mode 100644 index 0000000000..f290d2565e --- /dev/null +++ b/libs/libsodium/src/crypto_scalarmult/curve25519/sandy2x/ladder_base.S @@ -0,0 +1,1295 @@ +#ifdef IN_SANDY2X + +#include "ladder_base_namespace.h" +#include "consts_namespace.h" +.p2align 5 + +#ifdef ASM_HIDE_SYMBOL +ASM_HIDE_SYMBOL ladder_base +ASM_HIDE_SYMBOL _ladder_base +#endif +.globl ladder_base +.globl _ladder_base +#ifdef __ELF__ +.type ladder_base, @function +.type _ladder_base, @function +#endif +ladder_base: +_ladder_base: + +mov %rsp,%r11 +and $31,%r11 +add $1568,%r11 +sub %r11,%rsp +movq %r11,1536(%rsp) +movq %r12,1544(%rsp) +movq %r13,1552(%rsp) +vmovdqa v0_0(%rip),%xmm0 +vmovdqa v1_0(%rip),%xmm1 +vmovdqa v9_0(%rip),%xmm2 +vmovdqa %xmm2,0(%rsp) +vmovdqa %xmm0,16(%rsp) +vmovdqa %xmm0,32(%rsp) +vmovdqa %xmm0,48(%rsp) +vmovdqa %xmm0,64(%rsp) +vmovdqa %xmm1,80(%rsp) +vmovdqa %xmm0,96(%rsp) +vmovdqa %xmm0,112(%rsp) +vmovdqa %xmm0,128(%rsp) +vmovdqa %xmm0,144(%rsp) +vmovdqa %xmm1,%xmm0 +vpxor %xmm1,%xmm1,%xmm1 +vpxor %xmm2,%xmm2,%xmm2 +vpxor %xmm3,%xmm3,%xmm3 +vpxor %xmm4,%xmm4,%xmm4 +vpxor %xmm5,%xmm5,%xmm5 +vpxor %xmm6,%xmm6,%xmm6 +vpxor %xmm7,%xmm7,%xmm7 +vpxor %xmm8,%xmm8,%xmm8 +vpxor %xmm9,%xmm9,%xmm9 +movq 0(%rsi),%rdx +movq 8(%rsi),%rcx +movq 16(%rsi),%r8 +movq 24(%rsi),%r9 +shrd $1,%rcx,%rdx +shrd $1,%r8,%rcx +shrd $1,%r9,%r8 +shr $1,%r9 +xorq 0(%rsi),%rdx +xorq 8(%rsi),%rcx +xorq 16(%rsi),%r8 +xorq 24(%rsi),%r9 +leaq 512(%rsp),%rsi +mov $64,%rax + +.p2align 4 +._ladder_base_small_loop: +mov %rdx,%r10 +mov %rcx,%r11 +mov %r8,%r12 +mov %r9,%r13 +shr $1,%rdx +shr $1,%rcx +shr $1,%r8 +shr $1,%r9 +and $1,%r10d +and $1,%r11d +and $1,%r12d +and $1,%r13d +neg %r10 +neg %r11 +neg %r12 +neg %r13 +movl %r10d,0(%rsi) +movl %r11d,256(%rsi) +movl %r12d,512(%rsi) +movl %r13d,768(%rsi) +add $4,%rsi +sub $1,%rax +jne ._ladder_base_small_loop +mov $255,%rdx +add $760,%rsi + +.p2align 4 +._ladder_base_loop: +sub $1,%rdx +vbroadcastss 0(%rsi),%xmm10 +sub $4,%rsi +vmovdqa 0(%rsp),%xmm11 +vmovdqa 80(%rsp),%xmm12 +vpxor %xmm11,%xmm0,%xmm13 +vpand %xmm10,%xmm13,%xmm13 +vpxor %xmm13,%xmm0,%xmm0 +vpxor %xmm13,%xmm11,%xmm11 +vpxor %xmm12,%xmm1,%xmm13 +vpand %xmm10,%xmm13,%xmm13 +vpxor %xmm13,%xmm1,%xmm1 +vpxor %xmm13,%xmm12,%xmm12 +vmovdqa 16(%rsp),%xmm13 +vmovdqa 96(%rsp),%xmm14 +vpxor %xmm13,%xmm2,%xmm15 +vpand %xmm10,%xmm15,%xmm15 +vpxor %xmm15,%xmm2,%xmm2 +vpxor %xmm15,%xmm13,%xmm13 +vpxor %xmm14,%xmm3,%xmm15 +vpand %xmm10,%xmm15,%xmm15 +vpxor %xmm15,%xmm3,%xmm3 +vpxor %xmm15,%xmm14,%xmm14 +vmovdqa %xmm13,0(%rsp) +vmovdqa %xmm14,16(%rsp) +vmovdqa 32(%rsp),%xmm13 +vmovdqa 112(%rsp),%xmm14 +vpxor %xmm13,%xmm4,%xmm15 +vpand %xmm10,%xmm15,%xmm15 +vpxor %xmm15,%xmm4,%xmm4 +vpxor %xmm15,%xmm13,%xmm13 +vpxor %xmm14,%xmm5,%xmm15 +vpand %xmm10,%xmm15,%xmm15 +vpxor %xmm15,%xmm5,%xmm5 +vpxor %xmm15,%xmm14,%xmm14 +vmovdqa %xmm13,32(%rsp) +vmovdqa %xmm14,80(%rsp) +vmovdqa 48(%rsp),%xmm13 +vmovdqa 128(%rsp),%xmm14 +vpxor %xmm13,%xmm6,%xmm15 +vpand %xmm10,%xmm15,%xmm15 +vpxor %xmm15,%xmm6,%xmm6 +vpxor %xmm15,%xmm13,%xmm13 +vpxor %xmm14,%xmm7,%xmm15 +vpand %xmm10,%xmm15,%xmm15 +vpxor %xmm15,%xmm7,%xmm7 +vpxor %xmm15,%xmm14,%xmm14 +vmovdqa %xmm13,48(%rsp) +vmovdqa %xmm14,96(%rsp) +vmovdqa 64(%rsp),%xmm13 +vmovdqa 144(%rsp),%xmm14 +vpxor %xmm13,%xmm8,%xmm15 +vpand %xmm10,%xmm15,%xmm15 +vpxor %xmm15,%xmm8,%xmm8 +vpxor %xmm15,%xmm13,%xmm13 +vpxor %xmm14,%xmm9,%xmm15 +vpand %xmm10,%xmm15,%xmm15 +vpxor %xmm15,%xmm9,%xmm9 +vpxor %xmm15,%xmm14,%xmm14 +vmovdqa %xmm13,64(%rsp) +vmovdqa %xmm14,112(%rsp) +vpaddq subc0(%rip),%xmm11,%xmm10 +vpsubq %xmm12,%xmm10,%xmm10 +vpaddq %xmm12,%xmm11,%xmm11 +vpunpckhqdq %xmm10,%xmm11,%xmm12 +vpunpcklqdq %xmm10,%xmm11,%xmm10 +vpaddq %xmm1,%xmm0,%xmm11 +vpaddq subc0(%rip),%xmm0,%xmm0 +vpsubq %xmm1,%xmm0,%xmm0 +vpunpckhqdq %xmm11,%xmm0,%xmm1 +vpunpcklqdq %xmm11,%xmm0,%xmm0 +vpmuludq %xmm0,%xmm10,%xmm11 +vpmuludq %xmm1,%xmm10,%xmm13 +vmovdqa %xmm1,128(%rsp) +vpaddq %xmm1,%xmm1,%xmm1 +vpmuludq %xmm0,%xmm12,%xmm14 +vmovdqa %xmm0,144(%rsp) +vpaddq %xmm14,%xmm13,%xmm13 +vpmuludq %xmm1,%xmm12,%xmm0 +vmovdqa %xmm1,160(%rsp) +vpaddq %xmm3,%xmm2,%xmm1 +vpaddq subc2(%rip),%xmm2,%xmm2 +vpsubq %xmm3,%xmm2,%xmm2 +vpunpckhqdq %xmm1,%xmm2,%xmm3 +vpunpcklqdq %xmm1,%xmm2,%xmm1 +vpmuludq %xmm1,%xmm10,%xmm2 +vpaddq %xmm2,%xmm0,%xmm0 +vpmuludq %xmm3,%xmm10,%xmm2 +vmovdqa %xmm3,176(%rsp) +vpaddq %xmm3,%xmm3,%xmm3 +vpmuludq %xmm1,%xmm12,%xmm14 +vmovdqa %xmm1,192(%rsp) +vpaddq %xmm14,%xmm2,%xmm2 +vpmuludq %xmm3,%xmm12,%xmm1 +vmovdqa %xmm3,208(%rsp) +vpaddq %xmm5,%xmm4,%xmm3 +vpaddq subc2(%rip),%xmm4,%xmm4 +vpsubq %xmm5,%xmm4,%xmm4 +vpunpckhqdq %xmm3,%xmm4,%xmm5 +vpunpcklqdq %xmm3,%xmm4,%xmm3 +vpmuludq %xmm3,%xmm10,%xmm4 +vpaddq %xmm4,%xmm1,%xmm1 +vpmuludq %xmm5,%xmm10,%xmm4 +vmovdqa %xmm5,224(%rsp) +vpaddq %xmm5,%xmm5,%xmm5 +vpmuludq %xmm3,%xmm12,%xmm14 +vmovdqa %xmm3,240(%rsp) +vpaddq %xmm14,%xmm4,%xmm4 +vpaddq %xmm7,%xmm6,%xmm3 +vpaddq subc2(%rip),%xmm6,%xmm6 +vpsubq %xmm7,%xmm6,%xmm6 +vpunpckhqdq %xmm3,%xmm6,%xmm7 +vpunpcklqdq %xmm3,%xmm6,%xmm3 +vpmuludq %xmm3,%xmm10,%xmm6 +vpmuludq %xmm5,%xmm12,%xmm14 +vmovdqa %xmm5,256(%rsp) +vpmuludq v19_19(%rip),%xmm5,%xmm5 +vmovdqa %xmm5,272(%rsp) +vpaddq %xmm14,%xmm6,%xmm6 +vpmuludq %xmm7,%xmm10,%xmm5 +vmovdqa %xmm7,288(%rsp) +vpaddq %xmm7,%xmm7,%xmm7 +vpmuludq %xmm3,%xmm12,%xmm14 +vmovdqa %xmm3,304(%rsp) +vpaddq %xmm14,%xmm5,%xmm5 +vpmuludq v19_19(%rip),%xmm3,%xmm3 +vmovdqa %xmm3,320(%rsp) +vpaddq %xmm9,%xmm8,%xmm3 +vpaddq subc2(%rip),%xmm8,%xmm8 +vpsubq %xmm9,%xmm8,%xmm8 +vpunpckhqdq %xmm3,%xmm8,%xmm9 +vpunpcklqdq %xmm3,%xmm8,%xmm3 +vmovdqa %xmm3,336(%rsp) +vpmuludq %xmm7,%xmm12,%xmm8 +vmovdqa %xmm7,352(%rsp) +vpmuludq v19_19(%rip),%xmm7,%xmm7 +vmovdqa %xmm7,368(%rsp) +vpmuludq %xmm3,%xmm10,%xmm7 +vpaddq %xmm7,%xmm8,%xmm8 +vpmuludq %xmm9,%xmm10,%xmm7 +vmovdqa %xmm9,384(%rsp) +vpaddq %xmm9,%xmm9,%xmm9 +vpmuludq %xmm3,%xmm12,%xmm10 +vpaddq %xmm10,%xmm7,%xmm7 +vpmuludq v19_19(%rip),%xmm3,%xmm3 +vmovdqa %xmm3,400(%rsp) +vpmuludq v19_19(%rip),%xmm12,%xmm12 +vpmuludq %xmm9,%xmm12,%xmm3 +vmovdqa %xmm9,416(%rsp) +vpaddq %xmm3,%xmm11,%xmm11 +vmovdqa 0(%rsp),%xmm3 +vmovdqa 16(%rsp),%xmm9 +vpaddq subc2(%rip),%xmm3,%xmm10 +vpsubq %xmm9,%xmm10,%xmm10 +vpaddq %xmm9,%xmm3,%xmm3 +vpunpckhqdq %xmm10,%xmm3,%xmm9 +vpunpcklqdq %xmm10,%xmm3,%xmm3 +vpmuludq 144(%rsp),%xmm3,%xmm10 +vpaddq %xmm10,%xmm0,%xmm0 +vpmuludq 128(%rsp),%xmm3,%xmm10 +vpaddq %xmm10,%xmm2,%xmm2 +vpmuludq 192(%rsp),%xmm3,%xmm10 +vpaddq %xmm10,%xmm1,%xmm1 +vpmuludq 176(%rsp),%xmm3,%xmm10 +vpaddq %xmm10,%xmm4,%xmm4 +vpmuludq 240(%rsp),%xmm3,%xmm10 +vpaddq %xmm10,%xmm6,%xmm6 +vpmuludq 224(%rsp),%xmm3,%xmm10 +vpaddq %xmm10,%xmm5,%xmm5 +vpmuludq 304(%rsp),%xmm3,%xmm10 +vpaddq %xmm10,%xmm8,%xmm8 +vpmuludq 288(%rsp),%xmm3,%xmm10 +vpaddq %xmm10,%xmm7,%xmm7 +vpmuludq v19_19(%rip),%xmm3,%xmm3 +vpmuludq 336(%rsp),%xmm3,%xmm10 +vpaddq %xmm10,%xmm11,%xmm11 +vpmuludq 384(%rsp),%xmm3,%xmm3 +vpaddq %xmm3,%xmm13,%xmm13 +vpmuludq 144(%rsp),%xmm9,%xmm3 +vpaddq %xmm3,%xmm2,%xmm2 +vpmuludq 160(%rsp),%xmm9,%xmm3 +vpaddq %xmm3,%xmm1,%xmm1 +vpmuludq 192(%rsp),%xmm9,%xmm3 +vpaddq %xmm3,%xmm4,%xmm4 +vpmuludq 208(%rsp),%xmm9,%xmm3 +vpaddq %xmm3,%xmm6,%xmm6 +vpmuludq 240(%rsp),%xmm9,%xmm3 +vpaddq %xmm3,%xmm5,%xmm5 +vpmuludq 256(%rsp),%xmm9,%xmm3 +vpaddq %xmm3,%xmm8,%xmm8 +vpmuludq 304(%rsp),%xmm9,%xmm3 +vpaddq %xmm3,%xmm7,%xmm7 +vpmuludq v19_19(%rip),%xmm9,%xmm9 +vpmuludq 352(%rsp),%xmm9,%xmm3 +vpaddq %xmm3,%xmm11,%xmm11 +vpmuludq 336(%rsp),%xmm9,%xmm3 +vpaddq %xmm3,%xmm13,%xmm13 +vpmuludq 416(%rsp),%xmm9,%xmm9 +vpaddq %xmm9,%xmm0,%xmm0 +vmovdqa 32(%rsp),%xmm3 +vmovdqa 80(%rsp),%xmm9 +vpaddq subc2(%rip),%xmm3,%xmm10 +vpsubq %xmm9,%xmm10,%xmm10 +vpaddq %xmm9,%xmm3,%xmm3 +vpunpckhqdq %xmm10,%xmm3,%xmm9 +vpunpcklqdq %xmm10,%xmm3,%xmm3 +vpmuludq 144(%rsp),%xmm3,%xmm10 +vpaddq %xmm10,%xmm1,%xmm1 +vpmuludq 128(%rsp),%xmm3,%xmm10 +vpaddq %xmm10,%xmm4,%xmm4 +vpmuludq 192(%rsp),%xmm3,%xmm10 +vpaddq %xmm10,%xmm6,%xmm6 +vpmuludq 176(%rsp),%xmm3,%xmm10 +vpaddq %xmm10,%xmm5,%xmm5 +vpmuludq 240(%rsp),%xmm3,%xmm10 +vpaddq %xmm10,%xmm8,%xmm8 +vpmuludq 224(%rsp),%xmm3,%xmm10 +vpaddq %xmm10,%xmm7,%xmm7 +vpmuludq v19_19(%rip),%xmm3,%xmm3 +vpmuludq 304(%rsp),%xmm3,%xmm10 +vpaddq %xmm10,%xmm11,%xmm11 +vpmuludq 288(%rsp),%xmm3,%xmm10 +vpaddq %xmm10,%xmm13,%xmm13 +vpmuludq 336(%rsp),%xmm3,%xmm10 +vpaddq %xmm10,%xmm0,%xmm0 +vpmuludq 384(%rsp),%xmm3,%xmm3 +vpaddq %xmm3,%xmm2,%xmm2 +vpmuludq 144(%rsp),%xmm9,%xmm3 +vpaddq %xmm3,%xmm4,%xmm4 +vpmuludq 160(%rsp),%xmm9,%xmm3 +vpaddq %xmm3,%xmm6,%xmm6 +vpmuludq 192(%rsp),%xmm9,%xmm3 +vpaddq %xmm3,%xmm5,%xmm5 +vpmuludq 208(%rsp),%xmm9,%xmm3 +vpaddq %xmm3,%xmm8,%xmm8 +vpmuludq 240(%rsp),%xmm9,%xmm3 +vpaddq %xmm3,%xmm7,%xmm7 +vpmuludq v19_19(%rip),%xmm9,%xmm9 +vpmuludq 256(%rsp),%xmm9,%xmm3 +vpaddq %xmm3,%xmm11,%xmm11 +vpmuludq 304(%rsp),%xmm9,%xmm3 +vpaddq %xmm3,%xmm13,%xmm13 +vpmuludq 352(%rsp),%xmm9,%xmm3 +vpaddq %xmm3,%xmm0,%xmm0 +vpmuludq 336(%rsp),%xmm9,%xmm3 +vpaddq %xmm3,%xmm2,%xmm2 +vpmuludq 416(%rsp),%xmm9,%xmm9 +vpaddq %xmm9,%xmm1,%xmm1 +vmovdqa 48(%rsp),%xmm3 +vmovdqa 96(%rsp),%xmm9 +vpaddq subc2(%rip),%xmm3,%xmm10 +vpsubq %xmm9,%xmm10,%xmm10 +vpaddq %xmm9,%xmm3,%xmm3 +vpunpckhqdq %xmm10,%xmm3,%xmm9 +vpunpcklqdq %xmm10,%xmm3,%xmm3 +vpmuludq 144(%rsp),%xmm3,%xmm10 +vpaddq %xmm10,%xmm6,%xmm6 +vpmuludq 128(%rsp),%xmm3,%xmm10 +vpaddq %xmm10,%xmm5,%xmm5 +vpmuludq 192(%rsp),%xmm3,%xmm10 +vpaddq %xmm10,%xmm8,%xmm8 +vpmuludq 176(%rsp),%xmm3,%xmm10 +vpaddq %xmm10,%xmm7,%xmm7 +vpmuludq v19_19(%rip),%xmm3,%xmm3 +vpmuludq 240(%rsp),%xmm3,%xmm10 +vpaddq %xmm10,%xmm11,%xmm11 +vpmuludq 224(%rsp),%xmm3,%xmm10 +vpaddq %xmm10,%xmm13,%xmm13 +vpmuludq 304(%rsp),%xmm3,%xmm10 +vpaddq %xmm10,%xmm0,%xmm0 +vpmuludq 288(%rsp),%xmm3,%xmm10 +vpaddq %xmm10,%xmm2,%xmm2 +vpmuludq 336(%rsp),%xmm3,%xmm10 +vpaddq %xmm10,%xmm1,%xmm1 +vpmuludq 384(%rsp),%xmm3,%xmm3 +vpaddq %xmm3,%xmm4,%xmm4 +vpmuludq 144(%rsp),%xmm9,%xmm3 +vpaddq %xmm3,%xmm5,%xmm5 +vpmuludq 160(%rsp),%xmm9,%xmm3 +vpaddq %xmm3,%xmm8,%xmm8 +vpmuludq 192(%rsp),%xmm9,%xmm3 +vpaddq %xmm3,%xmm7,%xmm7 +vpmuludq v19_19(%rip),%xmm9,%xmm9 +vpmuludq 208(%rsp),%xmm9,%xmm3 +vpaddq %xmm3,%xmm11,%xmm11 +vpmuludq 240(%rsp),%xmm9,%xmm3 +vpaddq %xmm3,%xmm13,%xmm13 +vpmuludq 256(%rsp),%xmm9,%xmm3 +vpaddq %xmm3,%xmm0,%xmm0 +vpmuludq 304(%rsp),%xmm9,%xmm3 +vpaddq %xmm3,%xmm2,%xmm2 +vpmuludq 352(%rsp),%xmm9,%xmm3 +vpaddq %xmm3,%xmm1,%xmm1 +vpmuludq 336(%rsp),%xmm9,%xmm3 +vpaddq %xmm3,%xmm4,%xmm4 +vpmuludq 416(%rsp),%xmm9,%xmm9 +vpaddq %xmm9,%xmm6,%xmm6 +vmovdqa 64(%rsp),%xmm3 +vmovdqa 112(%rsp),%xmm9 +vpaddq subc2(%rip),%xmm3,%xmm10 +vpsubq %xmm9,%xmm10,%xmm10 +vpaddq %xmm9,%xmm3,%xmm3 +vpunpckhqdq %xmm10,%xmm3,%xmm9 +vpunpcklqdq %xmm10,%xmm3,%xmm3 +vpmuludq 144(%rsp),%xmm3,%xmm10 +vpaddq %xmm10,%xmm8,%xmm8 +vpmuludq 128(%rsp),%xmm3,%xmm10 +vpaddq %xmm10,%xmm7,%xmm7 +vpmuludq v19_19(%rip),%xmm3,%xmm3 +vpmuludq 192(%rsp),%xmm3,%xmm10 +vpaddq %xmm10,%xmm11,%xmm11 +vpmuludq 176(%rsp),%xmm3,%xmm10 +vpaddq %xmm10,%xmm13,%xmm13 +vpmuludq 240(%rsp),%xmm3,%xmm10 +vpaddq %xmm10,%xmm0,%xmm0 +vpmuludq 224(%rsp),%xmm3,%xmm10 +vpaddq %xmm10,%xmm2,%xmm2 +vpmuludq 304(%rsp),%xmm3,%xmm10 +vpaddq %xmm10,%xmm1,%xmm1 +vpmuludq 288(%rsp),%xmm3,%xmm10 +vpaddq %xmm10,%xmm4,%xmm4 +vpmuludq 336(%rsp),%xmm3,%xmm10 +vpaddq %xmm10,%xmm6,%xmm6 +vpmuludq 384(%rsp),%xmm3,%xmm3 +vpaddq %xmm3,%xmm5,%xmm5 +vpmuludq 144(%rsp),%xmm9,%xmm3 +vpaddq %xmm3,%xmm7,%xmm7 +vpmuludq v19_19(%rip),%xmm9,%xmm9 +vpmuludq 160(%rsp),%xmm9,%xmm3 +vpaddq %xmm3,%xmm11,%xmm11 +vpmuludq 192(%rsp),%xmm9,%xmm3 +vpaddq %xmm3,%xmm13,%xmm13 +vpmuludq 208(%rsp),%xmm9,%xmm3 +vpaddq %xmm3,%xmm0,%xmm0 +vpmuludq 240(%rsp),%xmm9,%xmm3 +vpaddq %xmm3,%xmm2,%xmm2 +vpmuludq 256(%rsp),%xmm9,%xmm3 +vpaddq %xmm3,%xmm1,%xmm1 +vpmuludq 304(%rsp),%xmm9,%xmm3 +vpaddq %xmm3,%xmm4,%xmm4 +vpmuludq 352(%rsp),%xmm9,%xmm3 +vpaddq %xmm3,%xmm6,%xmm6 +vpmuludq 336(%rsp),%xmm9,%xmm3 +vpaddq %xmm3,%xmm5,%xmm5 +vpmuludq 416(%rsp),%xmm9,%xmm9 +vpaddq %xmm9,%xmm8,%xmm8 +vpsrlq $25,%xmm4,%xmm3 +vpaddq %xmm3,%xmm6,%xmm6 +vpand m25(%rip),%xmm4,%xmm4 +vpsrlq $26,%xmm11,%xmm3 +vpaddq %xmm3,%xmm13,%xmm13 +vpand m26(%rip),%xmm11,%xmm11 +vpsrlq $26,%xmm6,%xmm3 +vpaddq %xmm3,%xmm5,%xmm5 +vpand m26(%rip),%xmm6,%xmm6 +vpsrlq $25,%xmm13,%xmm3 +vpaddq %xmm3,%xmm0,%xmm0 +vpand m25(%rip),%xmm13,%xmm13 +vpsrlq $25,%xmm5,%xmm3 +vpaddq %xmm3,%xmm8,%xmm8 +vpand m25(%rip),%xmm5,%xmm5 +vpsrlq $26,%xmm0,%xmm3 +vpaddq %xmm3,%xmm2,%xmm2 +vpand m26(%rip),%xmm0,%xmm0 +vpsrlq $26,%xmm8,%xmm3 +vpaddq %xmm3,%xmm7,%xmm7 +vpand m26(%rip),%xmm8,%xmm8 +vpsrlq $25,%xmm2,%xmm3 +vpaddq %xmm3,%xmm1,%xmm1 +vpand m25(%rip),%xmm2,%xmm2 +vpsrlq $25,%xmm7,%xmm3 +vpsllq $4,%xmm3,%xmm9 +vpaddq %xmm3,%xmm11,%xmm11 +vpsllq $1,%xmm3,%xmm3 +vpaddq %xmm3,%xmm9,%xmm9 +vpaddq %xmm9,%xmm11,%xmm11 +vpand m25(%rip),%xmm7,%xmm7 +vpsrlq $26,%xmm1,%xmm3 +vpaddq %xmm3,%xmm4,%xmm4 +vpand m26(%rip),%xmm1,%xmm1 +vpsrlq $26,%xmm11,%xmm3 +vpaddq %xmm3,%xmm13,%xmm13 +vpand m26(%rip),%xmm11,%xmm11 +vpsrlq $25,%xmm4,%xmm3 +vpaddq %xmm3,%xmm6,%xmm6 +vpand m25(%rip),%xmm4,%xmm4 +vpunpcklqdq %xmm13,%xmm11,%xmm3 +vpunpckhqdq %xmm13,%xmm11,%xmm9 +vpaddq subc0(%rip),%xmm9,%xmm10 +vpsubq %xmm3,%xmm10,%xmm10 +vpaddq %xmm9,%xmm3,%xmm3 +vpunpckhqdq %xmm3,%xmm10,%xmm9 +vpunpcklqdq %xmm3,%xmm10,%xmm10 +vpmuludq %xmm10,%xmm10,%xmm3 +vpaddq %xmm10,%xmm10,%xmm10 +vpmuludq %xmm9,%xmm10,%xmm11 +vpunpcklqdq %xmm2,%xmm0,%xmm12 +vpunpckhqdq %xmm2,%xmm0,%xmm0 +vpaddq subc2(%rip),%xmm0,%xmm2 +vpsubq %xmm12,%xmm2,%xmm2 +vpaddq %xmm0,%xmm12,%xmm12 +vpunpckhqdq %xmm12,%xmm2,%xmm0 +vpunpcklqdq %xmm12,%xmm2,%xmm2 +vpmuludq %xmm2,%xmm10,%xmm12 +vpaddq %xmm9,%xmm9,%xmm13 +vpmuludq %xmm13,%xmm9,%xmm9 +vpaddq %xmm9,%xmm12,%xmm12 +vpmuludq %xmm0,%xmm10,%xmm9 +vpmuludq %xmm2,%xmm13,%xmm14 +vpaddq %xmm14,%xmm9,%xmm9 +vpunpcklqdq %xmm4,%xmm1,%xmm14 +vpunpckhqdq %xmm4,%xmm1,%xmm1 +vpaddq subc2(%rip),%xmm1,%xmm4 +vpsubq %xmm14,%xmm4,%xmm4 +vpaddq %xmm1,%xmm14,%xmm14 +vpunpckhqdq %xmm14,%xmm4,%xmm1 +vpunpcklqdq %xmm14,%xmm4,%xmm4 +vmovdqa %xmm1,0(%rsp) +vpaddq %xmm1,%xmm1,%xmm1 +vmovdqa %xmm1,16(%rsp) +vpmuludq v19_19(%rip),%xmm1,%xmm1 +vmovdqa %xmm1,32(%rsp) +vpmuludq %xmm4,%xmm10,%xmm1 +vpmuludq %xmm2,%xmm2,%xmm14 +vpaddq %xmm14,%xmm1,%xmm1 +vpmuludq 0(%rsp),%xmm10,%xmm14 +vpmuludq %xmm4,%xmm13,%xmm15 +vpaddq %xmm15,%xmm14,%xmm14 +vpunpcklqdq %xmm5,%xmm6,%xmm15 +vpunpckhqdq %xmm5,%xmm6,%xmm5 +vpaddq subc2(%rip),%xmm5,%xmm6 +vpsubq %xmm15,%xmm6,%xmm6 +vpaddq %xmm5,%xmm15,%xmm15 +vpunpckhqdq %xmm15,%xmm6,%xmm5 +vpunpcklqdq %xmm15,%xmm6,%xmm6 +vmovdqa %xmm6,48(%rsp) +vpmuludq v19_19(%rip),%xmm6,%xmm6 +vmovdqa %xmm6,64(%rsp) +vmovdqa %xmm5,80(%rsp) +vpmuludq v38_38(%rip),%xmm5,%xmm5 +vmovdqa %xmm5,96(%rsp) +vpmuludq 48(%rsp),%xmm10,%xmm5 +vpaddq %xmm0,%xmm0,%xmm6 +vpmuludq %xmm6,%xmm0,%xmm0 +vpaddq %xmm0,%xmm5,%xmm5 +vpmuludq 80(%rsp),%xmm10,%xmm0 +vpmuludq %xmm4,%xmm6,%xmm15 +vpaddq %xmm15,%xmm0,%xmm0 +vpmuludq %xmm6,%xmm13,%xmm15 +vpaddq %xmm15,%xmm1,%xmm1 +vpmuludq %xmm6,%xmm2,%xmm15 +vpaddq %xmm15,%xmm14,%xmm14 +vpunpcklqdq %xmm7,%xmm8,%xmm15 +vpunpckhqdq %xmm7,%xmm8,%xmm7 +vpaddq subc2(%rip),%xmm7,%xmm8 +vpsubq %xmm15,%xmm8,%xmm8 +vpaddq %xmm7,%xmm15,%xmm15 +vpunpckhqdq %xmm15,%xmm8,%xmm7 +vpunpcklqdq %xmm15,%xmm8,%xmm8 +vmovdqa %xmm8,112(%rsp) +vpmuludq v19_19(%rip),%xmm8,%xmm8 +vmovdqa %xmm8,160(%rsp) +vpmuludq 112(%rsp),%xmm10,%xmm8 +vpmuludq %xmm7,%xmm10,%xmm10 +vpmuludq v38_38(%rip),%xmm7,%xmm15 +vpmuludq %xmm15,%xmm7,%xmm7 +vpaddq %xmm7,%xmm8,%xmm8 +vpmuludq %xmm15,%xmm13,%xmm7 +vpaddq %xmm7,%xmm3,%xmm3 +vpmuludq %xmm15,%xmm2,%xmm7 +vpaddq %xmm7,%xmm11,%xmm11 +vpmuludq 80(%rsp),%xmm13,%xmm7 +vpaddq %xmm7,%xmm7,%xmm7 +vpaddq %xmm7,%xmm8,%xmm8 +vpmuludq 16(%rsp),%xmm13,%xmm7 +vpaddq %xmm7,%xmm5,%xmm5 +vpmuludq 48(%rsp),%xmm13,%xmm7 +vpaddq %xmm7,%xmm0,%xmm0 +vpmuludq 112(%rsp),%xmm13,%xmm7 +vpaddq %xmm7,%xmm10,%xmm10 +vpmuludq %xmm15,%xmm6,%xmm7 +vpaddq %xmm7,%xmm12,%xmm12 +vpmuludq %xmm15,%xmm4,%xmm7 +vpaddq %xmm7,%xmm9,%xmm9 +vpaddq %xmm2,%xmm2,%xmm2 +vpmuludq %xmm4,%xmm2,%xmm7 +vpaddq %xmm7,%xmm5,%xmm5 +vpmuludq 160(%rsp),%xmm2,%xmm7 +vpaddq %xmm7,%xmm3,%xmm3 +vpmuludq 160(%rsp),%xmm6,%xmm7 +vpaddq %xmm7,%xmm11,%xmm11 +vpmuludq 0(%rsp),%xmm2,%xmm7 +vpaddq %xmm7,%xmm0,%xmm0 +vpmuludq 48(%rsp),%xmm2,%xmm7 +vpaddq %xmm7,%xmm8,%xmm8 +vpmuludq 80(%rsp),%xmm2,%xmm2 +vpaddq %xmm2,%xmm10,%xmm10 +vpmuludq 96(%rsp),%xmm4,%xmm2 +vpaddq %xmm2,%xmm11,%xmm11 +vpmuludq %xmm4,%xmm4,%xmm2 +vpaddq %xmm2,%xmm8,%xmm8 +vpaddq %xmm4,%xmm4,%xmm2 +vpmuludq 160(%rsp),%xmm2,%xmm4 +vpaddq %xmm4,%xmm12,%xmm12 +vpmuludq 16(%rsp),%xmm15,%xmm4 +vpaddq %xmm4,%xmm1,%xmm1 +vpmuludq 48(%rsp),%xmm15,%xmm4 +vpaddq %xmm4,%xmm14,%xmm14 +vpmuludq 96(%rsp),%xmm6,%xmm4 +vpaddq %xmm4,%xmm3,%xmm3 +vmovdqa 16(%rsp),%xmm4 +vpmuludq 160(%rsp),%xmm4,%xmm4 +vpaddq %xmm4,%xmm9,%xmm9 +vpmuludq 16(%rsp),%xmm6,%xmm4 +vpaddq %xmm4,%xmm8,%xmm8 +vpmuludq 48(%rsp),%xmm6,%xmm4 +vpaddq %xmm4,%xmm10,%xmm10 +vpmuludq 80(%rsp),%xmm15,%xmm4 +vpaddq %xmm4,%xmm4,%xmm4 +vpaddq %xmm4,%xmm5,%xmm5 +vpmuludq 112(%rsp),%xmm15,%xmm4 +vpaddq %xmm4,%xmm0,%xmm0 +vmovdqa 48(%rsp),%xmm4 +vpaddq %xmm4,%xmm4,%xmm4 +vpmuludq 160(%rsp),%xmm4,%xmm4 +vpaddq %xmm4,%xmm1,%xmm1 +vmovdqa 80(%rsp),%xmm4 +vpaddq %xmm4,%xmm4,%xmm4 +vpmuludq 160(%rsp),%xmm4,%xmm4 +vpaddq %xmm4,%xmm14,%xmm14 +vpmuludq 64(%rsp),%xmm2,%xmm4 +vpaddq %xmm4,%xmm3,%xmm3 +vmovdqa 16(%rsp),%xmm4 +vpmuludq 64(%rsp),%xmm4,%xmm4 +vpaddq %xmm4,%xmm11,%xmm11 +vmovdqa 16(%rsp),%xmm4 +vpmuludq 96(%rsp),%xmm4,%xmm4 +vpaddq %xmm4,%xmm12,%xmm12 +vmovdqa 48(%rsp),%xmm4 +vpmuludq 96(%rsp),%xmm4,%xmm4 +vpaddq %xmm4,%xmm9,%xmm9 +vpmuludq 0(%rsp),%xmm2,%xmm2 +vpaddq %xmm2,%xmm10,%xmm10 +vmovdqa 32(%rsp),%xmm2 +vpmuludq 0(%rsp),%xmm2,%xmm2 +vpaddq %xmm2,%xmm3,%xmm3 +vmovdqa 64(%rsp),%xmm2 +vpmuludq 48(%rsp),%xmm2,%xmm2 +vpaddq %xmm2,%xmm12,%xmm12 +vmovdqa 96(%rsp),%xmm2 +vpmuludq 80(%rsp),%xmm2,%xmm2 +vpaddq %xmm2,%xmm1,%xmm1 +vmovdqa 160(%rsp),%xmm2 +vpmuludq 112(%rsp),%xmm2,%xmm2 +vpaddq %xmm2,%xmm5,%xmm5 +vpsrlq $26,%xmm3,%xmm2 +vpaddq %xmm2,%xmm11,%xmm11 +vpand m26(%rip),%xmm3,%xmm3 +vpsrlq $25,%xmm14,%xmm2 +vpaddq %xmm2,%xmm5,%xmm5 +vpand m25(%rip),%xmm14,%xmm14 +vpsrlq $25,%xmm11,%xmm2 +vpaddq %xmm2,%xmm12,%xmm12 +vpand m25(%rip),%xmm11,%xmm11 +vpsrlq $26,%xmm5,%xmm2 +vpaddq %xmm2,%xmm0,%xmm0 +vpand m26(%rip),%xmm5,%xmm5 +vpsrlq $26,%xmm12,%xmm2 +vpaddq %xmm2,%xmm9,%xmm9 +vpand m26(%rip),%xmm12,%xmm12 +vpsrlq $25,%xmm0,%xmm2 +vpaddq %xmm2,%xmm8,%xmm8 +vpand m25(%rip),%xmm0,%xmm0 +vpsrlq $25,%xmm9,%xmm2 +vpaddq %xmm2,%xmm1,%xmm1 +vpand m25(%rip),%xmm9,%xmm9 +vpsrlq $26,%xmm8,%xmm2 +vpaddq %xmm2,%xmm10,%xmm10 +vpand m26(%rip),%xmm8,%xmm8 +vpsrlq $26,%xmm1,%xmm2 +vpaddq %xmm2,%xmm14,%xmm14 +vpand m26(%rip),%xmm1,%xmm1 +vpsrlq $25,%xmm10,%xmm2 +vpsllq $4,%xmm2,%xmm4 +vpaddq %xmm2,%xmm3,%xmm3 +vpsllq $1,%xmm2,%xmm2 +vpaddq %xmm2,%xmm4,%xmm4 +vpaddq %xmm4,%xmm3,%xmm3 +vpand m25(%rip),%xmm10,%xmm10 +vpsrlq $25,%xmm14,%xmm2 +vpaddq %xmm2,%xmm5,%xmm5 +vpand m25(%rip),%xmm14,%xmm14 +vpsrlq $26,%xmm3,%xmm2 +vpaddq %xmm2,%xmm11,%xmm11 +vpand m26(%rip),%xmm3,%xmm3 +vpunpckhqdq %xmm11,%xmm3,%xmm2 +vmovdqa %xmm2,0(%rsp) +vpunpcklqdq %xmm11,%xmm3,%xmm2 +vpmuludq v9_9(%rip),%xmm2,%xmm2 +vmovdqa %xmm2,80(%rsp) +vpunpckhqdq %xmm9,%xmm12,%xmm2 +vmovdqa %xmm2,16(%rsp) +vpunpcklqdq %xmm9,%xmm12,%xmm2 +vpmuludq v9_9(%rip),%xmm2,%xmm2 +vmovdqa %xmm2,96(%rsp) +vpunpckhqdq %xmm14,%xmm1,%xmm2 +vmovdqa %xmm2,32(%rsp) +vpunpcklqdq %xmm14,%xmm1,%xmm1 +vpmuludq v9_9(%rip),%xmm1,%xmm1 +vmovdqa %xmm1,112(%rsp) +vpunpckhqdq %xmm0,%xmm5,%xmm1 +vmovdqa %xmm1,48(%rsp) +vpunpcklqdq %xmm0,%xmm5,%xmm0 +vpmuludq v9_9(%rip),%xmm0,%xmm0 +vmovdqa %xmm0,160(%rsp) +vpunpckhqdq %xmm10,%xmm8,%xmm0 +vmovdqa %xmm0,64(%rsp) +vpunpcklqdq %xmm10,%xmm8,%xmm0 +vpmuludq v9_9(%rip),%xmm0,%xmm0 +vmovdqa %xmm0,208(%rsp) +vmovdqa 144(%rsp),%xmm0 +vpmuludq %xmm0,%xmm0,%xmm1 +vpaddq %xmm0,%xmm0,%xmm0 +vmovdqa 128(%rsp),%xmm2 +vpmuludq %xmm2,%xmm0,%xmm3 +vmovdqa 192(%rsp),%xmm4 +vpmuludq %xmm4,%xmm0,%xmm5 +vmovdqa 176(%rsp),%xmm6 +vpmuludq %xmm6,%xmm0,%xmm7 +vmovdqa 240(%rsp),%xmm8 +vpmuludq %xmm8,%xmm0,%xmm9 +vpmuludq 224(%rsp),%xmm0,%xmm10 +vpmuludq 304(%rsp),%xmm0,%xmm11 +vpmuludq 288(%rsp),%xmm0,%xmm12 +vpmuludq 336(%rsp),%xmm0,%xmm13 +vmovdqa 384(%rsp),%xmm14 +vpmuludq %xmm14,%xmm0,%xmm0 +vpmuludq v38_38(%rip),%xmm14,%xmm15 +vpmuludq %xmm15,%xmm14,%xmm14 +vpaddq %xmm14,%xmm13,%xmm13 +vpaddq %xmm6,%xmm6,%xmm14 +vpmuludq %xmm14,%xmm6,%xmm6 +vpaddq %xmm6,%xmm11,%xmm11 +vpaddq %xmm2,%xmm2,%xmm6 +vpmuludq %xmm6,%xmm2,%xmm2 +vpaddq %xmm2,%xmm5,%xmm5 +vpmuludq %xmm15,%xmm6,%xmm2 +vpaddq %xmm2,%xmm1,%xmm1 +vpmuludq %xmm15,%xmm4,%xmm2 +vpaddq %xmm2,%xmm3,%xmm3 +vpmuludq 256(%rsp),%xmm6,%xmm2 +vpaddq %xmm2,%xmm11,%xmm11 +vpmuludq 304(%rsp),%xmm6,%xmm2 +vpaddq %xmm2,%xmm12,%xmm12 +vpmuludq 352(%rsp),%xmm6,%xmm2 +vpaddq %xmm2,%xmm13,%xmm13 +vpmuludq 336(%rsp),%xmm6,%xmm2 +vpaddq %xmm2,%xmm0,%xmm0 +vpmuludq %xmm4,%xmm6,%xmm2 +vpaddq %xmm2,%xmm7,%xmm7 +vpmuludq %xmm14,%xmm6,%xmm2 +vpaddq %xmm2,%xmm9,%xmm9 +vpmuludq %xmm8,%xmm6,%xmm2 +vpaddq %xmm2,%xmm10,%xmm10 +vpmuludq %xmm15,%xmm14,%xmm2 +vpaddq %xmm2,%xmm5,%xmm5 +vpmuludq %xmm15,%xmm8,%xmm2 +vpaddq %xmm2,%xmm7,%xmm7 +vpmuludq %xmm4,%xmm4,%xmm2 +vpaddq %xmm2,%xmm9,%xmm9 +vpmuludq %xmm14,%xmm4,%xmm2 +vpaddq %xmm2,%xmm10,%xmm10 +vpaddq %xmm4,%xmm4,%xmm2 +vpmuludq %xmm8,%xmm2,%xmm4 +vpaddq %xmm4,%xmm11,%xmm11 +vpmuludq 400(%rsp),%xmm2,%xmm4 +vpaddq %xmm4,%xmm1,%xmm1 +vpmuludq 400(%rsp),%xmm14,%xmm4 +vpaddq %xmm4,%xmm3,%xmm3 +vpmuludq 224(%rsp),%xmm2,%xmm4 +vpaddq %xmm4,%xmm12,%xmm12 +vpmuludq 304(%rsp),%xmm2,%xmm4 +vpaddq %xmm4,%xmm13,%xmm13 +vpmuludq 288(%rsp),%xmm2,%xmm2 +vpaddq %xmm2,%xmm0,%xmm0 +vpmuludq 368(%rsp),%xmm8,%xmm2 +vpaddq %xmm2,%xmm3,%xmm3 +vpmuludq %xmm8,%xmm14,%xmm2 +vpaddq %xmm2,%xmm12,%xmm12 +vpmuludq %xmm8,%xmm8,%xmm2 +vpaddq %xmm2,%xmm13,%xmm13 +vpaddq %xmm8,%xmm8,%xmm2 +vpmuludq 400(%rsp),%xmm2,%xmm4 +vpaddq %xmm4,%xmm5,%xmm5 +vpmuludq 256(%rsp),%xmm15,%xmm4 +vpaddq %xmm4,%xmm9,%xmm9 +vpmuludq 304(%rsp),%xmm15,%xmm4 +vpaddq %xmm4,%xmm10,%xmm10 +vpmuludq 368(%rsp),%xmm14,%xmm4 +vpaddq %xmm4,%xmm1,%xmm1 +vmovdqa 256(%rsp),%xmm4 +vpmuludq 400(%rsp),%xmm4,%xmm4 +vpaddq %xmm4,%xmm7,%xmm7 +vpmuludq 256(%rsp),%xmm14,%xmm4 +vpaddq %xmm4,%xmm13,%xmm13 +vpmuludq 304(%rsp),%xmm14,%xmm4 +vpaddq %xmm4,%xmm0,%xmm0 +vpmuludq 352(%rsp),%xmm15,%xmm4 +vpaddq %xmm4,%xmm11,%xmm11 +vpmuludq 336(%rsp),%xmm15,%xmm4 +vpaddq %xmm4,%xmm12,%xmm12 +vmovdqa 304(%rsp),%xmm4 +vpaddq %xmm4,%xmm4,%xmm4 +vpmuludq 400(%rsp),%xmm4,%xmm4 +vpaddq %xmm4,%xmm9,%xmm9 +vpmuludq 320(%rsp),%xmm2,%xmm4 +vpaddq %xmm4,%xmm1,%xmm1 +vmovdqa 256(%rsp),%xmm4 +vpmuludq 320(%rsp),%xmm4,%xmm4 +vpaddq %xmm4,%xmm3,%xmm3 +vmovdqa 256(%rsp),%xmm4 +vpmuludq 368(%rsp),%xmm4,%xmm4 +vpaddq %xmm4,%xmm5,%xmm5 +vmovdqa 304(%rsp),%xmm4 +vpmuludq 368(%rsp),%xmm4,%xmm4 +vpaddq %xmm4,%xmm7,%xmm7 +vmovdqa 352(%rsp),%xmm4 +vpmuludq 400(%rsp),%xmm4,%xmm4 +vpaddq %xmm4,%xmm10,%xmm10 +vpmuludq 224(%rsp),%xmm2,%xmm2 +vpaddq %xmm2,%xmm0,%xmm0 +vmovdqa 272(%rsp),%xmm2 +vpmuludq 224(%rsp),%xmm2,%xmm2 +vpaddq %xmm2,%xmm1,%xmm1 +vmovdqa 320(%rsp),%xmm2 +vpmuludq 304(%rsp),%xmm2,%xmm2 +vpaddq %xmm2,%xmm5,%xmm5 +vmovdqa 368(%rsp),%xmm2 +vpmuludq 288(%rsp),%xmm2,%xmm2 +vpaddq %xmm2,%xmm9,%xmm9 +vmovdqa 400(%rsp),%xmm2 +vpmuludq 336(%rsp),%xmm2,%xmm2 +vpaddq %xmm2,%xmm11,%xmm11 +vpsrlq $26,%xmm1,%xmm2 +vpaddq %xmm2,%xmm3,%xmm3 +vpand m26(%rip),%xmm1,%xmm1 +vpsrlq $25,%xmm10,%xmm2 +vpaddq %xmm2,%xmm11,%xmm11 +vpand m25(%rip),%xmm10,%xmm10 +vpsrlq $25,%xmm3,%xmm2 +vpaddq %xmm2,%xmm5,%xmm5 +vpand m25(%rip),%xmm3,%xmm3 +vpsrlq $26,%xmm11,%xmm2 +vpaddq %xmm2,%xmm12,%xmm12 +vpand m26(%rip),%xmm11,%xmm11 +vpsrlq $26,%xmm5,%xmm2 +vpaddq %xmm2,%xmm7,%xmm7 +vpand m26(%rip),%xmm5,%xmm5 +vpsrlq $25,%xmm12,%xmm2 +vpaddq %xmm2,%xmm13,%xmm13 +vpand m25(%rip),%xmm12,%xmm12 +vpsrlq $25,%xmm7,%xmm2 +vpaddq %xmm2,%xmm9,%xmm9 +vpand m25(%rip),%xmm7,%xmm7 +vpsrlq $26,%xmm13,%xmm2 +vpaddq %xmm2,%xmm0,%xmm0 +vpand m26(%rip),%xmm13,%xmm13 +vpsrlq $26,%xmm9,%xmm2 +vpaddq %xmm2,%xmm10,%xmm10 +vpand m26(%rip),%xmm9,%xmm9 +vpsrlq $25,%xmm0,%xmm2 +vpsllq $4,%xmm2,%xmm4 +vpaddq %xmm2,%xmm1,%xmm1 +vpsllq $1,%xmm2,%xmm2 +vpaddq %xmm2,%xmm4,%xmm4 +vpaddq %xmm4,%xmm1,%xmm1 +vpand m25(%rip),%xmm0,%xmm0 +vpsrlq $25,%xmm10,%xmm2 +vpaddq %xmm2,%xmm11,%xmm11 +vpand m25(%rip),%xmm10,%xmm10 +vpsrlq $26,%xmm1,%xmm2 +vpaddq %xmm2,%xmm3,%xmm3 +vpand m26(%rip),%xmm1,%xmm1 +vpunpckhqdq %xmm3,%xmm1,%xmm2 +vpunpcklqdq %xmm3,%xmm1,%xmm1 +vmovdqa %xmm1,176(%rsp) +vpaddq subc0(%rip),%xmm2,%xmm3 +vpsubq %xmm1,%xmm3,%xmm3 +vpunpckhqdq %xmm3,%xmm2,%xmm1 +vpunpcklqdq %xmm3,%xmm2,%xmm2 +vmovdqa %xmm2,192(%rsp) +vmovdqa %xmm1,224(%rsp) +vpsllq $1,%xmm1,%xmm1 +vmovdqa %xmm1,240(%rsp) +vpmuludq v121666_121666(%rip),%xmm3,%xmm3 +vmovdqa 80(%rsp),%xmm1 +vpunpcklqdq %xmm1,%xmm3,%xmm2 +vpunpckhqdq %xmm1,%xmm3,%xmm1 +vpunpckhqdq %xmm7,%xmm5,%xmm3 +vpunpcklqdq %xmm7,%xmm5,%xmm4 +vmovdqa %xmm4,256(%rsp) +vpaddq subc2(%rip),%xmm3,%xmm5 +vpsubq %xmm4,%xmm5,%xmm5 +vpunpckhqdq %xmm5,%xmm3,%xmm4 +vpunpcklqdq %xmm5,%xmm3,%xmm3 +vmovdqa %xmm3,272(%rsp) +vmovdqa %xmm4,288(%rsp) +vpsllq $1,%xmm4,%xmm4 +vmovdqa %xmm4,304(%rsp) +vpmuludq v121666_121666(%rip),%xmm5,%xmm5 +vmovdqa 96(%rsp),%xmm3 +vpunpcklqdq %xmm3,%xmm5,%xmm4 +vpunpckhqdq %xmm3,%xmm5,%xmm3 +vpunpckhqdq %xmm10,%xmm9,%xmm5 +vpunpcklqdq %xmm10,%xmm9,%xmm6 +vmovdqa %xmm6,320(%rsp) +vpaddq subc2(%rip),%xmm5,%xmm7 +vpsubq %xmm6,%xmm7,%xmm7 +vpunpckhqdq %xmm7,%xmm5,%xmm6 +vpunpcklqdq %xmm7,%xmm5,%xmm5 +vmovdqa %xmm5,336(%rsp) +vmovdqa %xmm6,352(%rsp) +vpsllq $1,%xmm6,%xmm6 +vmovdqa %xmm6,368(%rsp) +vpmuludq v121666_121666(%rip),%xmm7,%xmm7 +vmovdqa 112(%rsp),%xmm5 +vpunpcklqdq %xmm5,%xmm7,%xmm6 +vpunpckhqdq %xmm5,%xmm7,%xmm5 +vpunpckhqdq %xmm12,%xmm11,%xmm7 +vpunpcklqdq %xmm12,%xmm11,%xmm8 +vmovdqa %xmm8,384(%rsp) +vpaddq subc2(%rip),%xmm7,%xmm9 +vpsubq %xmm8,%xmm9,%xmm9 +vpunpckhqdq %xmm9,%xmm7,%xmm8 +vpunpcklqdq %xmm9,%xmm7,%xmm7 +vmovdqa %xmm7,400(%rsp) +vmovdqa %xmm8,416(%rsp) +vpsllq $1,%xmm8,%xmm8 +vmovdqa %xmm8,432(%rsp) +vpmuludq v121666_121666(%rip),%xmm9,%xmm9 +vmovdqa 160(%rsp),%xmm7 +vpunpcklqdq %xmm7,%xmm9,%xmm8 +vpunpckhqdq %xmm7,%xmm9,%xmm7 +vpunpckhqdq %xmm0,%xmm13,%xmm9 +vpunpcklqdq %xmm0,%xmm13,%xmm0 +vmovdqa %xmm0,160(%rsp) +vpaddq subc2(%rip),%xmm9,%xmm10 +vpsubq %xmm0,%xmm10,%xmm10 +vpunpckhqdq %xmm10,%xmm9,%xmm0 +vpunpcklqdq %xmm10,%xmm9,%xmm9 +vmovdqa %xmm9,448(%rsp) +vmovdqa %xmm0,464(%rsp) +vpsllq $1,%xmm0,%xmm0 +vmovdqa %xmm0,480(%rsp) +vpmuludq v121666_121666(%rip),%xmm10,%xmm10 +vmovdqa 208(%rsp),%xmm0 +vpunpcklqdq %xmm0,%xmm10,%xmm9 +vpunpckhqdq %xmm0,%xmm10,%xmm0 +vpsrlq $26,%xmm2,%xmm10 +vpaddq %xmm10,%xmm1,%xmm1 +vpand m26(%rip),%xmm2,%xmm2 +vpsrlq $25,%xmm5,%xmm10 +vpaddq %xmm10,%xmm8,%xmm8 +vpand m25(%rip),%xmm5,%xmm5 +vpsrlq $25,%xmm1,%xmm10 +vpaddq %xmm10,%xmm4,%xmm4 +vpand m25(%rip),%xmm1,%xmm1 +vpsrlq $26,%xmm8,%xmm10 +vpaddq %xmm10,%xmm7,%xmm7 +vpand m26(%rip),%xmm8,%xmm8 +vpsrlq $26,%xmm4,%xmm10 +vpaddq %xmm10,%xmm3,%xmm3 +vpand m26(%rip),%xmm4,%xmm4 +vpsrlq $25,%xmm7,%xmm10 +vpaddq %xmm10,%xmm9,%xmm9 +vpand m25(%rip),%xmm7,%xmm7 +vpsrlq $25,%xmm3,%xmm10 +vpaddq %xmm10,%xmm6,%xmm6 +vpand m25(%rip),%xmm3,%xmm3 +vpsrlq $26,%xmm9,%xmm10 +vpaddq %xmm10,%xmm0,%xmm0 +vpand m26(%rip),%xmm9,%xmm9 +vpsrlq $26,%xmm6,%xmm10 +vpaddq %xmm10,%xmm5,%xmm5 +vpand m26(%rip),%xmm6,%xmm6 +vpsrlq $25,%xmm0,%xmm10 +vpsllq $4,%xmm10,%xmm11 +vpaddq %xmm10,%xmm2,%xmm2 +vpsllq $1,%xmm10,%xmm10 +vpaddq %xmm10,%xmm11,%xmm11 +vpaddq %xmm11,%xmm2,%xmm2 +vpand m25(%rip),%xmm0,%xmm0 +vpsrlq $25,%xmm5,%xmm10 +vpaddq %xmm10,%xmm8,%xmm8 +vpand m25(%rip),%xmm5,%xmm5 +vpsrlq $26,%xmm2,%xmm10 +vpaddq %xmm10,%xmm1,%xmm1 +vpand m26(%rip),%xmm2,%xmm2 +vpunpckhqdq %xmm1,%xmm2,%xmm10 +vmovdqa %xmm10,80(%rsp) +vpunpcklqdq %xmm1,%xmm2,%xmm1 +vpunpckhqdq %xmm3,%xmm4,%xmm2 +vmovdqa %xmm2,96(%rsp) +vpunpcklqdq %xmm3,%xmm4,%xmm2 +vpunpckhqdq %xmm5,%xmm6,%xmm3 +vmovdqa %xmm3,112(%rsp) +vpunpcklqdq %xmm5,%xmm6,%xmm3 +vpunpckhqdq %xmm7,%xmm8,%xmm4 +vmovdqa %xmm4,128(%rsp) +vpunpcklqdq %xmm7,%xmm8,%xmm4 +vpunpckhqdq %xmm0,%xmm9,%xmm5 +vmovdqa %xmm5,144(%rsp) +vpunpcklqdq %xmm0,%xmm9,%xmm0 +vmovdqa 176(%rsp),%xmm5 +vpaddq %xmm5,%xmm1,%xmm1 +vpunpcklqdq %xmm1,%xmm5,%xmm6 +vpunpckhqdq %xmm1,%xmm5,%xmm1 +vpmuludq 224(%rsp),%xmm6,%xmm5 +vpmuludq 192(%rsp),%xmm1,%xmm7 +vpaddq %xmm7,%xmm5,%xmm5 +vpmuludq 272(%rsp),%xmm6,%xmm7 +vpmuludq 240(%rsp),%xmm1,%xmm8 +vpaddq %xmm8,%xmm7,%xmm7 +vpmuludq 288(%rsp),%xmm6,%xmm8 +vpmuludq 272(%rsp),%xmm1,%xmm9 +vpaddq %xmm9,%xmm8,%xmm8 +vpmuludq 336(%rsp),%xmm6,%xmm9 +vpmuludq 304(%rsp),%xmm1,%xmm10 +vpaddq %xmm10,%xmm9,%xmm9 +vpmuludq 352(%rsp),%xmm6,%xmm10 +vpmuludq 336(%rsp),%xmm1,%xmm11 +vpaddq %xmm11,%xmm10,%xmm10 +vpmuludq 400(%rsp),%xmm6,%xmm11 +vpmuludq 368(%rsp),%xmm1,%xmm12 +vpaddq %xmm12,%xmm11,%xmm11 +vpmuludq 416(%rsp),%xmm6,%xmm12 +vpmuludq 400(%rsp),%xmm1,%xmm13 +vpaddq %xmm13,%xmm12,%xmm12 +vpmuludq 448(%rsp),%xmm6,%xmm13 +vpmuludq 432(%rsp),%xmm1,%xmm14 +vpaddq %xmm14,%xmm13,%xmm13 +vpmuludq 464(%rsp),%xmm6,%xmm14 +vpmuludq 448(%rsp),%xmm1,%xmm15 +vpaddq %xmm15,%xmm14,%xmm14 +vpmuludq 192(%rsp),%xmm6,%xmm6 +vpmuludq v19_19(%rip),%xmm1,%xmm1 +vpmuludq 480(%rsp),%xmm1,%xmm1 +vpaddq %xmm1,%xmm6,%xmm6 +vmovdqa 256(%rsp),%xmm1 +vpaddq %xmm1,%xmm2,%xmm2 +vpunpcklqdq %xmm2,%xmm1,%xmm15 +vpunpckhqdq %xmm2,%xmm1,%xmm1 +vpmuludq 192(%rsp),%xmm15,%xmm2 +vpaddq %xmm2,%xmm7,%xmm7 +vpmuludq 224(%rsp),%xmm15,%xmm2 +vpaddq %xmm2,%xmm8,%xmm8 +vpmuludq 272(%rsp),%xmm15,%xmm2 +vpaddq %xmm2,%xmm9,%xmm9 +vpmuludq 288(%rsp),%xmm15,%xmm2 +vpaddq %xmm2,%xmm10,%xmm10 +vpmuludq 336(%rsp),%xmm15,%xmm2 +vpaddq %xmm2,%xmm11,%xmm11 +vpmuludq 352(%rsp),%xmm15,%xmm2 +vpaddq %xmm2,%xmm12,%xmm12 +vpmuludq 400(%rsp),%xmm15,%xmm2 +vpaddq %xmm2,%xmm13,%xmm13 +vpmuludq 416(%rsp),%xmm15,%xmm2 +vpaddq %xmm2,%xmm14,%xmm14 +vpmuludq v19_19(%rip),%xmm15,%xmm15 +vpmuludq 448(%rsp),%xmm15,%xmm2 +vpaddq %xmm2,%xmm6,%xmm6 +vpmuludq 464(%rsp),%xmm15,%xmm15 +vpaddq %xmm15,%xmm5,%xmm5 +vpmuludq 192(%rsp),%xmm1,%xmm2 +vpaddq %xmm2,%xmm8,%xmm8 +vpmuludq 240(%rsp),%xmm1,%xmm2 +vpaddq %xmm2,%xmm9,%xmm9 +vpmuludq 272(%rsp),%xmm1,%xmm2 +vpaddq %xmm2,%xmm10,%xmm10 +vpmuludq 304(%rsp),%xmm1,%xmm2 +vpaddq %xmm2,%xmm11,%xmm11 +vpmuludq 336(%rsp),%xmm1,%xmm2 +vpaddq %xmm2,%xmm12,%xmm12 +vpmuludq 368(%rsp),%xmm1,%xmm2 +vpaddq %xmm2,%xmm13,%xmm13 +vpmuludq 400(%rsp),%xmm1,%xmm2 +vpaddq %xmm2,%xmm14,%xmm14 +vpmuludq v19_19(%rip),%xmm1,%xmm1 +vpmuludq 432(%rsp),%xmm1,%xmm2 +vpaddq %xmm2,%xmm6,%xmm6 +vpmuludq 448(%rsp),%xmm1,%xmm2 +vpaddq %xmm2,%xmm5,%xmm5 +vpmuludq 480(%rsp),%xmm1,%xmm1 +vpaddq %xmm1,%xmm7,%xmm7 +vmovdqa 320(%rsp),%xmm1 +vpaddq %xmm1,%xmm3,%xmm3 +vpunpcklqdq %xmm3,%xmm1,%xmm2 +vpunpckhqdq %xmm3,%xmm1,%xmm1 +vpmuludq 192(%rsp),%xmm2,%xmm3 +vpaddq %xmm3,%xmm9,%xmm9 +vpmuludq 224(%rsp),%xmm2,%xmm3 +vpaddq %xmm3,%xmm10,%xmm10 +vpmuludq 272(%rsp),%xmm2,%xmm3 +vpaddq %xmm3,%xmm11,%xmm11 +vpmuludq 288(%rsp),%xmm2,%xmm3 +vpaddq %xmm3,%xmm12,%xmm12 +vpmuludq 336(%rsp),%xmm2,%xmm3 +vpaddq %xmm3,%xmm13,%xmm13 +vpmuludq 352(%rsp),%xmm2,%xmm3 +vpaddq %xmm3,%xmm14,%xmm14 +vpmuludq v19_19(%rip),%xmm2,%xmm2 +vpmuludq 400(%rsp),%xmm2,%xmm3 +vpaddq %xmm3,%xmm6,%xmm6 +vpmuludq 416(%rsp),%xmm2,%xmm3 +vpaddq %xmm3,%xmm5,%xmm5 +vpmuludq 448(%rsp),%xmm2,%xmm3 +vpaddq %xmm3,%xmm7,%xmm7 +vpmuludq 464(%rsp),%xmm2,%xmm2 +vpaddq %xmm2,%xmm8,%xmm8 +vpmuludq 192(%rsp),%xmm1,%xmm2 +vpaddq %xmm2,%xmm10,%xmm10 +vpmuludq 240(%rsp),%xmm1,%xmm2 +vpaddq %xmm2,%xmm11,%xmm11 +vpmuludq 272(%rsp),%xmm1,%xmm2 +vpaddq %xmm2,%xmm12,%xmm12 +vpmuludq 304(%rsp),%xmm1,%xmm2 +vpaddq %xmm2,%xmm13,%xmm13 +vpmuludq 336(%rsp),%xmm1,%xmm2 +vpaddq %xmm2,%xmm14,%xmm14 +vpmuludq v19_19(%rip),%xmm1,%xmm1 +vpmuludq 368(%rsp),%xmm1,%xmm2 +vpaddq %xmm2,%xmm6,%xmm6 +vpmuludq 400(%rsp),%xmm1,%xmm2 +vpaddq %xmm2,%xmm5,%xmm5 +vpmuludq 432(%rsp),%xmm1,%xmm2 +vpaddq %xmm2,%xmm7,%xmm7 +vpmuludq 448(%rsp),%xmm1,%xmm2 +vpaddq %xmm2,%xmm8,%xmm8 +vpmuludq 480(%rsp),%xmm1,%xmm1 +vpaddq %xmm1,%xmm9,%xmm9 +vmovdqa 384(%rsp),%xmm1 +vpaddq %xmm1,%xmm4,%xmm4 +vpunpcklqdq %xmm4,%xmm1,%xmm2 +vpunpckhqdq %xmm4,%xmm1,%xmm1 +vpmuludq 192(%rsp),%xmm2,%xmm3 +vpaddq %xmm3,%xmm11,%xmm11 +vpmuludq 224(%rsp),%xmm2,%xmm3 +vpaddq %xmm3,%xmm12,%xmm12 +vpmuludq 272(%rsp),%xmm2,%xmm3 +vpaddq %xmm3,%xmm13,%xmm13 +vpmuludq 288(%rsp),%xmm2,%xmm3 +vpaddq %xmm3,%xmm14,%xmm14 +vpmuludq v19_19(%rip),%xmm2,%xmm2 +vpmuludq 336(%rsp),%xmm2,%xmm3 +vpaddq %xmm3,%xmm6,%xmm6 +vpmuludq 352(%rsp),%xmm2,%xmm3 +vpaddq %xmm3,%xmm5,%xmm5 +vpmuludq 400(%rsp),%xmm2,%xmm3 +vpaddq %xmm3,%xmm7,%xmm7 +vpmuludq 416(%rsp),%xmm2,%xmm3 +vpaddq %xmm3,%xmm8,%xmm8 +vpmuludq 448(%rsp),%xmm2,%xmm3 +vpaddq %xmm3,%xmm9,%xmm9 +vpmuludq 464(%rsp),%xmm2,%xmm2 +vpaddq %xmm2,%xmm10,%xmm10 +vpmuludq 192(%rsp),%xmm1,%xmm2 +vpaddq %xmm2,%xmm12,%xmm12 +vpmuludq 240(%rsp),%xmm1,%xmm2 +vpaddq %xmm2,%xmm13,%xmm13 +vpmuludq 272(%rsp),%xmm1,%xmm2 +vpaddq %xmm2,%xmm14,%xmm14 +vpmuludq v19_19(%rip),%xmm1,%xmm1 +vpmuludq 304(%rsp),%xmm1,%xmm2 +vpaddq %xmm2,%xmm6,%xmm6 +vpmuludq 336(%rsp),%xmm1,%xmm2 +vpaddq %xmm2,%xmm5,%xmm5 +vpmuludq 368(%rsp),%xmm1,%xmm2 +vpaddq %xmm2,%xmm7,%xmm7 +vpmuludq 400(%rsp),%xmm1,%xmm2 +vpaddq %xmm2,%xmm8,%xmm8 +vpmuludq 432(%rsp),%xmm1,%xmm2 +vpaddq %xmm2,%xmm9,%xmm9 +vpmuludq 448(%rsp),%xmm1,%xmm2 +vpaddq %xmm2,%xmm10,%xmm10 +vpmuludq 480(%rsp),%xmm1,%xmm1 +vpaddq %xmm1,%xmm11,%xmm11 +vmovdqa 160(%rsp),%xmm1 +vpaddq %xmm1,%xmm0,%xmm0 +vpunpcklqdq %xmm0,%xmm1,%xmm2 +vpunpckhqdq %xmm0,%xmm1,%xmm0 +vpmuludq 192(%rsp),%xmm2,%xmm1 +vpaddq %xmm1,%xmm13,%xmm13 +vpmuludq 224(%rsp),%xmm2,%xmm1 +vpaddq %xmm1,%xmm14,%xmm14 +vpmuludq v19_19(%rip),%xmm2,%xmm2 +vpmuludq 272(%rsp),%xmm2,%xmm1 +vpaddq %xmm1,%xmm6,%xmm6 +vpmuludq 288(%rsp),%xmm2,%xmm1 +vpaddq %xmm1,%xmm5,%xmm5 +vpmuludq 336(%rsp),%xmm2,%xmm1 +vpaddq %xmm1,%xmm7,%xmm7 +vpmuludq 352(%rsp),%xmm2,%xmm1 +vpaddq %xmm1,%xmm8,%xmm8 +vpmuludq 400(%rsp),%xmm2,%xmm1 +vpaddq %xmm1,%xmm9,%xmm9 +vpmuludq 416(%rsp),%xmm2,%xmm1 +vpaddq %xmm1,%xmm10,%xmm10 +vpmuludq 448(%rsp),%xmm2,%xmm1 +vpaddq %xmm1,%xmm11,%xmm11 +vpmuludq 464(%rsp),%xmm2,%xmm2 +vpaddq %xmm2,%xmm12,%xmm12 +vpmuludq 192(%rsp),%xmm0,%xmm1 +vpaddq %xmm1,%xmm14,%xmm14 +vpmuludq v19_19(%rip),%xmm0,%xmm0 +vpmuludq 240(%rsp),%xmm0,%xmm1 +vpaddq %xmm1,%xmm6,%xmm6 +vpmuludq 272(%rsp),%xmm0,%xmm1 +vpaddq %xmm1,%xmm5,%xmm5 +vpmuludq 304(%rsp),%xmm0,%xmm1 +vpaddq %xmm1,%xmm7,%xmm7 +vpmuludq 336(%rsp),%xmm0,%xmm1 +vpaddq %xmm1,%xmm8,%xmm8 +vpmuludq 368(%rsp),%xmm0,%xmm1 +vpaddq %xmm1,%xmm9,%xmm9 +vpmuludq 400(%rsp),%xmm0,%xmm1 +vpaddq %xmm1,%xmm10,%xmm10 +vpmuludq 432(%rsp),%xmm0,%xmm1 +vpaddq %xmm1,%xmm11,%xmm11 +vpmuludq 448(%rsp),%xmm0,%xmm1 +vpaddq %xmm1,%xmm12,%xmm12 +vpmuludq 480(%rsp),%xmm0,%xmm0 +vpaddq %xmm0,%xmm13,%xmm13 +vpsrlq $26,%xmm6,%xmm0 +vpaddq %xmm0,%xmm5,%xmm5 +vpand m26(%rip),%xmm6,%xmm6 +vpsrlq $25,%xmm10,%xmm0 +vpaddq %xmm0,%xmm11,%xmm11 +vpand m25(%rip),%xmm10,%xmm10 +vpsrlq $25,%xmm5,%xmm0 +vpaddq %xmm0,%xmm7,%xmm7 +vpand m25(%rip),%xmm5,%xmm5 +vpsrlq $26,%xmm11,%xmm0 +vpaddq %xmm0,%xmm12,%xmm12 +vpand m26(%rip),%xmm11,%xmm11 +vpsrlq $26,%xmm7,%xmm0 +vpaddq %xmm0,%xmm8,%xmm8 +vpand m26(%rip),%xmm7,%xmm7 +vpsrlq $25,%xmm12,%xmm0 +vpaddq %xmm0,%xmm13,%xmm13 +vpand m25(%rip),%xmm12,%xmm12 +vpsrlq $25,%xmm8,%xmm0 +vpaddq %xmm0,%xmm9,%xmm9 +vpand m25(%rip),%xmm8,%xmm8 +vpsrlq $26,%xmm13,%xmm0 +vpaddq %xmm0,%xmm14,%xmm14 +vpand m26(%rip),%xmm13,%xmm13 +vpsrlq $26,%xmm9,%xmm0 +vpaddq %xmm0,%xmm10,%xmm10 +vpand m26(%rip),%xmm9,%xmm9 +vpsrlq $25,%xmm14,%xmm0 +vpsllq $4,%xmm0,%xmm1 +vpaddq %xmm0,%xmm6,%xmm6 +vpsllq $1,%xmm0,%xmm0 +vpaddq %xmm0,%xmm1,%xmm1 +vpaddq %xmm1,%xmm6,%xmm6 +vpand m25(%rip),%xmm14,%xmm14 +vpsrlq $25,%xmm10,%xmm0 +vpaddq %xmm0,%xmm11,%xmm11 +vpand m25(%rip),%xmm10,%xmm10 +vpsrlq $26,%xmm6,%xmm0 +vpaddq %xmm0,%xmm5,%xmm5 +vpand m26(%rip),%xmm6,%xmm6 +vpunpckhqdq %xmm5,%xmm6,%xmm1 +vpunpcklqdq %xmm5,%xmm6,%xmm0 +vpunpckhqdq %xmm8,%xmm7,%xmm3 +vpunpcklqdq %xmm8,%xmm7,%xmm2 +vpunpckhqdq %xmm10,%xmm9,%xmm5 +vpunpcklqdq %xmm10,%xmm9,%xmm4 +vpunpckhqdq %xmm12,%xmm11,%xmm7 +vpunpcklqdq %xmm12,%xmm11,%xmm6 +vpunpckhqdq %xmm14,%xmm13,%xmm9 +vpunpcklqdq %xmm14,%xmm13,%xmm8 +cmp $0,%rdx +jne ._ladder_base_loop +vmovdqu %xmm1,80(%rdi) +vmovdqu %xmm0,0(%rdi) +vmovdqu %xmm3,96(%rdi) +vmovdqu %xmm2,16(%rdi) +vmovdqu %xmm5,112(%rdi) +vmovdqu %xmm4,32(%rdi) +vmovdqu %xmm7,128(%rdi) +vmovdqu %xmm6,48(%rdi) +vmovdqu %xmm9,144(%rdi) +vmovdqu %xmm8,64(%rdi) +movq 1536(%rsp),%r11 +movq 1544(%rsp),%r12 +movq 1552(%rsp),%r13 +add %r11,%rsp +ret + +#endif diff --git a/libs/libsodium/src/crypto_scalarmult/curve25519/sandy2x/ladder_base.h b/libs/libsodium/src/crypto_scalarmult/curve25519/sandy2x/ladder_base.h new file mode 100644 index 0000000000..a69be13f0d --- /dev/null +++ b/libs/libsodium/src/crypto_scalarmult/curve25519/sandy2x/ladder_base.h @@ -0,0 +1,18 @@ +#ifndef ladder_base_H +#define ladder_base_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include "fe.h" +#include "ladder_base_namespace.h" + +extern void ladder_base(fe *, const unsigned char *); + +#ifdef __cplusplus +} +#endif + +#endif /* ifndef ladder_base_H */ + diff --git a/libs/libsodium/src/crypto_scalarmult/curve25519/sandy2x/ladder_base_namespace.h b/libs/libsodium/src/crypto_scalarmult/curve25519/sandy2x/ladder_base_namespace.h new file mode 100644 index 0000000000..304546a185 --- /dev/null +++ b/libs/libsodium/src/crypto_scalarmult/curve25519/sandy2x/ladder_base_namespace.h @@ -0,0 +1,8 @@ +#ifndef ladder_base_namespace_H +#define ladder_base_namespace_H + +#define ladder_base crypto_scalarmult_curve25519_sandy2x_ladder_base +#define _ladder_base _crypto_scalarmult_curve25519_sandy2x_ladder_base + +#endif /* ifndef ladder_base_namespace_H */ + diff --git a/libs/libsodium/src/crypto_scalarmult/curve25519/sandy2x/ladder_namespace.h b/libs/libsodium/src/crypto_scalarmult/curve25519/sandy2x/ladder_namespace.h new file mode 100644 index 0000000000..6637074bec --- /dev/null +++ b/libs/libsodium/src/crypto_scalarmult/curve25519/sandy2x/ladder_namespace.h @@ -0,0 +1,8 @@ +#ifndef ladder_namespace_H +#define ladder_namespace_H + +#define ladder crypto_scalarmult_curve25519_sandy2x_ladder +#define _ladder _crypto_scalarmult_curve25519_sandy2x_ladder + +#endif /* ifndef ladder_namespace_H */ + diff --git a/libs/libsodium/src/crypto_scalarmult/curve25519/sandy2x/sandy2x.S b/libs/libsodium/src/crypto_scalarmult/curve25519/sandy2x/sandy2x.S new file mode 100644 index 0000000000..1fd632057b --- /dev/null +++ b/libs/libsodium/src/crypto_scalarmult/curve25519/sandy2x/sandy2x.S @@ -0,0 +1,17 @@ + +#ifdef HAVE_AVX_ASM + +#define IN_SANDY2X + +#include "consts.S" +#include "fe51_mul.S" +#include "fe51_nsquare.S" +#include "fe51_pack.S" +#include "ladder.S" +#include "ladder_base.S" + +#if defined(__linux__) && defined(__ELF__) +.section .note.GNU-stack,"",%progbits +#endif + +#endif diff --git a/libs/libsodium/src/crypto_scalarmult/curve25519/scalarmult_curve25519.c b/libs/libsodium/src/crypto_scalarmult/curve25519/scalarmult_curve25519.c new file mode 100644 index 0000000000..2d3ffc0563 --- /dev/null +++ b/libs/libsodium/src/crypto_scalarmult/curve25519/scalarmult_curve25519.c @@ -0,0 +1,59 @@ + +#include "crypto_scalarmult_curve25519.h" +#include "private/implementations.h" +#include "scalarmult_curve25519.h" +#include "runtime.h" + +#ifdef HAVE_AVX_ASM +# include "sandy2x/curve25519_sandy2x.h" +#endif +#include "ref10/x25519_ref10.h" +static const crypto_scalarmult_curve25519_implementation *implementation = + &crypto_scalarmult_curve25519_ref10_implementation; + +int +crypto_scalarmult_curve25519(unsigned char *q, const unsigned char *n, + const unsigned char *p) +{ + size_t i; + volatile unsigned char d = 0; + + if (implementation->mult(q, n, p) != 0) { + return -1; /* LCOV_EXCL_LINE */ + } + for (i = 0; i < crypto_scalarmult_curve25519_BYTES; i++) { + d |= q[i]; + } + return -(1 & ((d - 1) >> 8)); +} + +int +crypto_scalarmult_curve25519_base(unsigned char *q, const unsigned char *n) +{ + return implementation->mult_base(q, n); +} + +size_t +crypto_scalarmult_curve25519_bytes(void) +{ + return crypto_scalarmult_curve25519_BYTES; +} + +size_t +crypto_scalarmult_curve25519_scalarbytes(void) +{ + return crypto_scalarmult_curve25519_SCALARBYTES; +} + +int +_crypto_scalarmult_curve25519_pick_best_implementation(void) +{ + implementation = &crypto_scalarmult_curve25519_ref10_implementation; + +#ifdef HAVE_AVX_ASM + if (sodium_runtime_has_avx()) { + implementation = &crypto_scalarmult_curve25519_sandy2x_implementation; + } +#endif + return 0; +} diff --git a/libs/libsodium/src/crypto_scalarmult/curve25519/scalarmult_curve25519.h b/libs/libsodium/src/crypto_scalarmult/curve25519/scalarmult_curve25519.h new file mode 100644 index 0000000000..66edbf6a8a --- /dev/null +++ b/libs/libsodium/src/crypto_scalarmult/curve25519/scalarmult_curve25519.h @@ -0,0 +1,11 @@ + +#ifndef scalarmult_poly1305_H +#define scalarmult_poly1305_H + +typedef struct crypto_scalarmult_curve25519_implementation { + int (*mult)(unsigned char *q, const unsigned char *n, + const unsigned char *p); + int (*mult_base)(unsigned char *q, const unsigned char *n); +} crypto_scalarmult_curve25519_implementation; + +#endif diff --git a/libs/libsodium/src/crypto_scalarmult/ed25519/ref10/scalarmult_ed25519_ref10.c b/libs/libsodium/src/crypto_scalarmult/ed25519/ref10/scalarmult_ed25519_ref10.c new file mode 100644 index 0000000000..0e317cf7cc --- /dev/null +++ b/libs/libsodium/src/crypto_scalarmult/ed25519/ref10/scalarmult_ed25519_ref10.c @@ -0,0 +1,86 @@ + +#include <string.h> + +#include "crypto_scalarmult_ed25519.h" +#include "private/ed25519_ref10.h" +#include "utils.h" + +static int +_crypto_scalarmult_ed25519_is_inf(const unsigned char s[32]) +{ + unsigned char c; + unsigned int i; + + c = s[0] ^ 0x01; + for (i = 1; i < 31; i++) { + c |= s[i]; + } + c |= s[31] & 0x7f; + + return ((((unsigned int) c) - 1U) >> 8) & 1; +} + +static inline void +_crypto_scalarmult_ed25519_clamp(unsigned char k[32]) +{ + k[0] &= 248; + k[31] &= 127; + k[31] |= 64; +} + +int +crypto_scalarmult_ed25519(unsigned char *q, const unsigned char *n, + const unsigned char *p) +{ + unsigned char *t = q; + ge25519_p3 Q; + ge25519_p3 P; + unsigned int i; + + if (ge25519_is_canonical(p) == 0 || ge25519_has_small_order(p) != 0 || + ge25519_frombytes(&P, p) != 0 || ge25519_is_on_main_subgroup(&P) == 0) { + return -1; + } + for (i = 0; i < 32; ++i) { + t[i] = n[i]; + } + _crypto_scalarmult_ed25519_clamp(t); + ge25519_scalarmult(&Q, t, &P); + ge25519_p3_tobytes(q, &Q); + if (_crypto_scalarmult_ed25519_is_inf(q) != 0 || sodium_is_zero(n, 32)) { + return -1; + } + return 0; +} + +int +crypto_scalarmult_ed25519_base(unsigned char *q, + const unsigned char *n) +{ + unsigned char *t = q; + ge25519_p3 Q; + unsigned int i; + + for (i = 0; i < 32; ++i) { + t[i] = n[i]; + } + _crypto_scalarmult_ed25519_clamp(t); + ge25519_scalarmult_base(&Q, t); + ge25519_p3_tobytes(q, &Q); + if (sodium_is_zero(n, 32) != 0) { + return -1; + } + return 0; +} + +size_t +crypto_scalarmult_ed25519_bytes(void) +{ + return crypto_scalarmult_ed25519_BYTES; +} + +size_t +crypto_scalarmult_ed25519_scalarbytes(void) +{ + return crypto_scalarmult_ed25519_SCALARBYTES; +} diff --git a/libs/libsodium/src/crypto_secretbox/crypto_secretbox.c b/libs/libsodium/src/crypto_secretbox/crypto_secretbox.c new file mode 100644 index 0000000000..45f678ecdf --- /dev/null +++ b/libs/libsodium/src/crypto_secretbox/crypto_secretbox.c @@ -0,0 +1,67 @@ + +#include "crypto_secretbox.h" +#include "randombytes.h" + +size_t +crypto_secretbox_keybytes(void) +{ + return crypto_secretbox_KEYBYTES; +} + +size_t +crypto_secretbox_noncebytes(void) +{ + return crypto_secretbox_NONCEBYTES; +} + +size_t +crypto_secretbox_zerobytes(void) +{ + return crypto_secretbox_ZEROBYTES; +} + +size_t +crypto_secretbox_boxzerobytes(void) +{ + return crypto_secretbox_BOXZEROBYTES; +} + +size_t +crypto_secretbox_macbytes(void) +{ + return crypto_secretbox_MACBYTES; +} + +size_t +crypto_secretbox_messagebytes_max(void) +{ + return crypto_secretbox_MESSAGEBYTES_MAX; +} + +const char * +crypto_secretbox_primitive(void) +{ + return crypto_secretbox_PRIMITIVE; +} + +int +crypto_secretbox(unsigned char *c, const unsigned char *m, + unsigned long long mlen, const unsigned char *n, + const unsigned char *k) +{ + return crypto_secretbox_xsalsa20poly1305(c, m, mlen, n, k); +} + +int +crypto_secretbox_open(unsigned char *m, const unsigned char *c, + unsigned long long clen, const unsigned char *n, + const unsigned char *k) +{ + return crypto_secretbox_xsalsa20poly1305_open(m, c, clen, n, k); +} + +void +crypto_secretbox_keygen(unsigned char k[crypto_secretbox_KEYBYTES]) +{ + randombytes_buf(k, crypto_secretbox_KEYBYTES); +} diff --git a/libs/libsodium/src/crypto_secretbox/crypto_secretbox_easy.c b/libs/libsodium/src/crypto_secretbox/crypto_secretbox_easy.c new file mode 100644 index 0000000000..b1203849f2 --- /dev/null +++ b/libs/libsodium/src/crypto_secretbox/crypto_secretbox_easy.c @@ -0,0 +1,144 @@ + +#include <assert.h> +#include <limits.h> +#include <stdint.h> +#include <stdlib.h> +#include <string.h> + +#include "core.h" +#include "crypto_core_hsalsa20.h" +#include "crypto_onetimeauth_poly1305.h" +#include "crypto_secretbox.h" +#include "crypto_stream_salsa20.h" +#include "private/common.h" +#include "utils.h" + +int +crypto_secretbox_detached(unsigned char *c, unsigned char *mac, + const unsigned char *m, + unsigned long long mlen, const unsigned char *n, + const unsigned char *k) +{ + crypto_onetimeauth_poly1305_state state; + unsigned char block0[64U]; + unsigned char subkey[crypto_stream_salsa20_KEYBYTES]; + unsigned long long i; + unsigned long long mlen0; + + crypto_core_hsalsa20(subkey, n, k, NULL); + + if (((uintptr_t) c > (uintptr_t) m && + (uintptr_t) c - (uintptr_t) m < mlen) || + ((uintptr_t) m > (uintptr_t) c && + (uintptr_t) m - (uintptr_t) c < mlen)) { /* LCOV_EXCL_LINE */ + memmove(c, m, mlen); + m = c; + } + memset(block0, 0U, crypto_secretbox_ZEROBYTES); + COMPILER_ASSERT(64U >= crypto_secretbox_ZEROBYTES); + mlen0 = mlen; + if (mlen0 > 64U - crypto_secretbox_ZEROBYTES) { + mlen0 = 64U - crypto_secretbox_ZEROBYTES; + } + for (i = 0U; i < mlen0; i++) { + block0[i + crypto_secretbox_ZEROBYTES] = m[i]; + } + crypto_stream_salsa20_xor(block0, block0, + mlen0 + crypto_secretbox_ZEROBYTES, + n + 16, subkey); + COMPILER_ASSERT(crypto_secretbox_ZEROBYTES >= + crypto_onetimeauth_poly1305_KEYBYTES); + crypto_onetimeauth_poly1305_init(&state, block0); + + for (i = 0U; i < mlen0; i++) { + c[i] = block0[crypto_secretbox_ZEROBYTES + i]; + } + sodium_memzero(block0, sizeof block0); + if (mlen > mlen0) { + crypto_stream_salsa20_xor_ic(c + mlen0, m + mlen0, mlen - mlen0, + n + 16, 1U, subkey); + } + sodium_memzero(subkey, sizeof subkey); + + crypto_onetimeauth_poly1305_update(&state, c, mlen); + crypto_onetimeauth_poly1305_final(&state, mac); + sodium_memzero(&state, sizeof state); + + return 0; +} + +int +crypto_secretbox_easy(unsigned char *c, const unsigned char *m, + unsigned long long mlen, const unsigned char *n, + const unsigned char *k) +{ + if (mlen > crypto_secretbox_MESSAGEBYTES_MAX) { + sodium_misuse(); + } + return crypto_secretbox_detached(c + crypto_secretbox_MACBYTES, + c, m, mlen, n, k); +} + +int +crypto_secretbox_open_detached(unsigned char *m, const unsigned char *c, + const unsigned char *mac, + unsigned long long clen, + const unsigned char *n, + const unsigned char *k) +{ + unsigned char block0[64U]; + unsigned char subkey[crypto_stream_salsa20_KEYBYTES]; + unsigned long long i; + unsigned long long mlen0; + + crypto_core_hsalsa20(subkey, n, k, NULL); + crypto_stream_salsa20(block0, crypto_stream_salsa20_KEYBYTES, + n + 16, subkey); + if (crypto_onetimeauth_poly1305_verify(mac, c, clen, block0) != 0) { + sodium_memzero(subkey, sizeof subkey); + return -1; + } + if (m == NULL) { + return 0; + } + if (((uintptr_t) c >= (uintptr_t) m && + (uintptr_t) c - (uintptr_t) m < clen) || + ((uintptr_t) m >= (uintptr_t) c && + (uintptr_t) m - (uintptr_t) c < clen)) { /* LCOV_EXCL_LINE */ + memmove(m, c, clen); + c = m; + } + mlen0 = clen; + if (mlen0 > 64U - crypto_secretbox_ZEROBYTES) { + mlen0 = 64U - crypto_secretbox_ZEROBYTES; + } + for (i = 0U; i < mlen0; i++) { + block0[crypto_secretbox_ZEROBYTES + i] = c[i]; + } + crypto_stream_salsa20_xor(block0, block0, + crypto_secretbox_ZEROBYTES + mlen0, + n + 16, subkey); + for (i = 0U; i < mlen0; i++) { + m[i] = block0[i + crypto_secretbox_ZEROBYTES]; + } + if (clen > mlen0) { + crypto_stream_salsa20_xor_ic(m + mlen0, c + mlen0, clen - mlen0, + n + 16, 1U, subkey); + } + sodium_memzero(subkey, sizeof subkey); + + return 0; +} + +int +crypto_secretbox_open_easy(unsigned char *m, const unsigned char *c, + unsigned long long clen, const unsigned char *n, + const unsigned char *k) +{ + if (clen < crypto_secretbox_MACBYTES) { + return -1; + } + return crypto_secretbox_open_detached(m, c + crypto_secretbox_MACBYTES, c, + clen - crypto_secretbox_MACBYTES, + n, k); +} diff --git a/libs/libsodium/src/crypto_secretbox/xchacha20poly1305/secretbox_xchacha20poly1305.c b/libs/libsodium/src/crypto_secretbox/xchacha20poly1305/secretbox_xchacha20poly1305.c new file mode 100644 index 0000000000..e76167d2ee --- /dev/null +++ b/libs/libsodium/src/crypto_secretbox/xchacha20poly1305/secretbox_xchacha20poly1305.c @@ -0,0 +1,177 @@ + +#include <assert.h> +#include <limits.h> +#include <stdint.h> +#include <stdlib.h> +#include <string.h> + +#include "core.h" +#include "crypto_core_hchacha20.h" +#include "crypto_onetimeauth_poly1305.h" +#include "crypto_secretbox_xchacha20poly1305.h" +#include "crypto_stream_chacha20.h" +#include "private/common.h" +#include "utils.h" + +#define crypto_secretbox_xchacha20poly1305_ZEROBYTES 32U + +int +crypto_secretbox_xchacha20poly1305_detached(unsigned char *c, + unsigned char *mac, + const unsigned char *m, + unsigned long long mlen, + const unsigned char *n, + const unsigned char *k) +{ + crypto_onetimeauth_poly1305_state state; + unsigned char block0[64U]; + unsigned char subkey[crypto_stream_chacha20_KEYBYTES]; + unsigned long long i; + unsigned long long mlen0; + + crypto_core_hchacha20(subkey, n, k, NULL); + + if (((uintptr_t) c > (uintptr_t) m && + (uintptr_t) c - (uintptr_t) m < mlen) || + ((uintptr_t) m > (uintptr_t) c && + (uintptr_t) m - (uintptr_t) c < mlen)) { /* LCOV_EXCL_LINE */ + memmove(c, m, mlen); + m = c; + } + memset(block0, 0U, crypto_secretbox_xchacha20poly1305_ZEROBYTES); + COMPILER_ASSERT(64U >= crypto_secretbox_xchacha20poly1305_ZEROBYTES); + mlen0 = mlen; + if (mlen0 > 64U - crypto_secretbox_xchacha20poly1305_ZEROBYTES) { + mlen0 = 64U - crypto_secretbox_xchacha20poly1305_ZEROBYTES; + } + for (i = 0U; i < mlen0; i++) { + block0[i + crypto_secretbox_xchacha20poly1305_ZEROBYTES] = m[i]; + } + crypto_stream_chacha20_xor(block0, block0, + mlen0 + crypto_secretbox_xchacha20poly1305_ZEROBYTES, + n + 16, subkey); + COMPILER_ASSERT(crypto_secretbox_xchacha20poly1305_ZEROBYTES >= + crypto_onetimeauth_poly1305_KEYBYTES); + crypto_onetimeauth_poly1305_init(&state, block0); + + for (i = 0U; i < mlen0; i++) { + c[i] = block0[crypto_secretbox_xchacha20poly1305_ZEROBYTES + i]; + } + sodium_memzero(block0, sizeof block0); + if (mlen > mlen0) { + crypto_stream_chacha20_xor_ic(c + mlen0, m + mlen0, mlen - mlen0, + n + 16, 1U, subkey); + } + sodium_memzero(subkey, sizeof subkey); + + crypto_onetimeauth_poly1305_update(&state, c, mlen); + crypto_onetimeauth_poly1305_final(&state, mac); + sodium_memzero(&state, sizeof state); + + return 0; +} + +int +crypto_secretbox_xchacha20poly1305_easy(unsigned char *c, + const unsigned char *m, + unsigned long long mlen, + const unsigned char *n, + const unsigned char *k) +{ + if (mlen > crypto_secretbox_xchacha20poly1305_MESSAGEBYTES_MAX) { + sodium_misuse(); + } + return crypto_secretbox_xchacha20poly1305_detached + (c + crypto_secretbox_xchacha20poly1305_MACBYTES, c, m, mlen, n, k); +} + +int +crypto_secretbox_xchacha20poly1305_open_detached(unsigned char *m, + const unsigned char *c, + const unsigned char *mac, + unsigned long long clen, + const unsigned char *n, + const unsigned char *k) +{ + unsigned char block0[64U]; + unsigned char subkey[crypto_stream_chacha20_KEYBYTES]; + unsigned long long i; + unsigned long long mlen0; + + crypto_core_hchacha20(subkey, n, k, NULL); + crypto_stream_chacha20(block0, crypto_stream_chacha20_KEYBYTES, + n + 16, subkey); + if (crypto_onetimeauth_poly1305_verify(mac, c, clen, block0) != 0) { + sodium_memzero(subkey, sizeof subkey); + return -1; + } + if (m == NULL) { + return 0; + } + if (((uintptr_t) c >= (uintptr_t) m && + (uintptr_t) c - (uintptr_t) m < clen) || + ((uintptr_t) m >= (uintptr_t) c && + (uintptr_t) m - (uintptr_t) c < clen)) { /* LCOV_EXCL_LINE */ + memmove(m, c, clen); + c = m; + } + mlen0 = clen; + if (mlen0 > 64U - crypto_secretbox_xchacha20poly1305_ZEROBYTES) { + mlen0 = 64U - crypto_secretbox_xchacha20poly1305_ZEROBYTES; + } + for (i = 0U; i < mlen0; i++) { + block0[crypto_secretbox_xchacha20poly1305_ZEROBYTES + i] = c[i]; + } + crypto_stream_chacha20_xor(block0, block0, + crypto_secretbox_xchacha20poly1305_ZEROBYTES + mlen0, + n + 16, subkey); + for (i = 0U; i < mlen0; i++) { + m[i] = block0[i + crypto_secretbox_xchacha20poly1305_ZEROBYTES]; + } + if (clen > mlen0) { + crypto_stream_chacha20_xor_ic(m + mlen0, c + mlen0, clen - mlen0, + n + 16, 1U, subkey); + } + sodium_memzero(subkey, sizeof subkey); + + return 0; +} + +int +crypto_secretbox_xchacha20poly1305_open_easy(unsigned char *m, + const unsigned char *c, + unsigned long long clen, + const unsigned char *n, + const unsigned char *k) +{ + if (clen < crypto_secretbox_xchacha20poly1305_MACBYTES) { + return -1; + } + return crypto_secretbox_xchacha20poly1305_open_detached + (m, c + crypto_secretbox_xchacha20poly1305_MACBYTES, c, + clen - crypto_secretbox_xchacha20poly1305_MACBYTES, n, k); +} + +size_t +crypto_secretbox_xchacha20poly1305_keybytes(void) +{ + return crypto_secretbox_xchacha20poly1305_KEYBYTES; +} + +size_t +crypto_secretbox_xchacha20poly1305_noncebytes(void) +{ + return crypto_secretbox_xchacha20poly1305_NONCEBYTES; +} + +size_t +crypto_secretbox_xchacha20poly1305_macbytes(void) +{ + return crypto_secretbox_xchacha20poly1305_MACBYTES; +} + +size_t +crypto_secretbox_xchacha20poly1305_messagebytes_max(void) +{ + return crypto_secretbox_xchacha20poly1305_MESSAGEBYTES_MAX; +} diff --git a/libs/libsodium/src/crypto_secretbox/xsalsa20poly1305/secretbox_xsalsa20poly1305.c b/libs/libsodium/src/crypto_secretbox/xsalsa20poly1305/secretbox_xsalsa20poly1305.c new file mode 100644 index 0000000000..7240050dfd --- /dev/null +++ b/libs/libsodium/src/crypto_secretbox/xsalsa20poly1305/secretbox_xsalsa20poly1305.c @@ -0,0 +1,89 @@ +#include "crypto_onetimeauth_poly1305.h" +#include "crypto_secretbox_xsalsa20poly1305.h" +#include "crypto_stream_xsalsa20.h" +#include "randombytes.h" + +int +crypto_secretbox_xsalsa20poly1305(unsigned char *c, const unsigned char *m, + unsigned long long mlen, + const unsigned char *n, + const unsigned char *k) +{ + int i; + + if (mlen < 32) { + return -1; + } + crypto_stream_xsalsa20_xor(c, m, mlen, n, k); + crypto_onetimeauth_poly1305(c + 16, c + 32, mlen - 32, c); + for (i = 0; i < 16; ++i) { + c[i] = 0; + } + return 0; +} + +int +crypto_secretbox_xsalsa20poly1305_open(unsigned char *m, const unsigned char *c, + unsigned long long clen, + const unsigned char *n, + const unsigned char *k) +{ + unsigned char subkey[32]; + int i; + + if (clen < 32) { + return -1; + } + crypto_stream_xsalsa20(subkey, 32, n, k); + if (crypto_onetimeauth_poly1305_verify(c + 16, c + 32, + clen - 32, subkey) != 0) { + return -1; + } + crypto_stream_xsalsa20_xor(m, c, clen, n, k); + for (i = 0; i < 32; ++i) { + m[i] = 0; + } + return 0; +} + +size_t +crypto_secretbox_xsalsa20poly1305_keybytes(void) +{ + return crypto_secretbox_xsalsa20poly1305_KEYBYTES; +} + +size_t +crypto_secretbox_xsalsa20poly1305_noncebytes(void) +{ + return crypto_secretbox_xsalsa20poly1305_NONCEBYTES; +} + +size_t +crypto_secretbox_xsalsa20poly1305_zerobytes(void) +{ + return crypto_secretbox_xsalsa20poly1305_ZEROBYTES; +} + +size_t +crypto_secretbox_xsalsa20poly1305_boxzerobytes(void) +{ + return crypto_secretbox_xsalsa20poly1305_BOXZEROBYTES; +} + +size_t +crypto_secretbox_xsalsa20poly1305_macbytes(void) +{ + return crypto_secretbox_xsalsa20poly1305_MACBYTES; +} + +size_t +crypto_secretbox_xsalsa20poly1305_messagebytes_max(void) +{ + return crypto_secretbox_xsalsa20poly1305_MESSAGEBYTES_MAX; +} + +void +crypto_secretbox_xsalsa20poly1305_keygen(unsigned char k[crypto_secretbox_xsalsa20poly1305_KEYBYTES]) +{ + randombytes_buf(k, crypto_secretbox_xsalsa20poly1305_KEYBYTES); +} diff --git a/libs/libsodium/src/crypto_secretstream/xchacha20poly1305/secretstream_xchacha20poly1305.c b/libs/libsodium/src/crypto_secretstream/xchacha20poly1305/secretstream_xchacha20poly1305.c new file mode 100644 index 0000000000..ef000d16c7 --- /dev/null +++ b/libs/libsodium/src/crypto_secretstream/xchacha20poly1305/secretstream_xchacha20poly1305.c @@ -0,0 +1,311 @@ +#include <stdint.h> +#include <stdlib.h> +#include <limits.h> +#include <string.h> + +#include "core.h" +#include "crypto_aead_chacha20poly1305.h" +#include "crypto_aead_xchacha20poly1305.h" +#include "crypto_core_hchacha20.h" +#include "crypto_onetimeauth_poly1305.h" +#include "crypto_secretstream_xchacha20poly1305.h" +#include "randombytes.h" +#include "utils.h" + +#include "private/common.h" + +#define crypto_secretstream_xchacha20poly1305_COUNTERBYTES 4U +#define crypto_secretstream_xchacha20poly1305_INONCEBYTES 8U + +#define STATE_COUNTER(STATE) ((STATE)->nonce) +#define STATE_INONCE(STATE) ((STATE)->nonce + \ + crypto_secretstream_xchacha20poly1305_COUNTERBYTES) + +static const unsigned char _pad0[16] = { 0 }; + +static inline void +_crypto_secretstream_xchacha20poly1305_counter_reset + (crypto_secretstream_xchacha20poly1305_state *state) +{ + memset(STATE_COUNTER(state), 0, + crypto_secretstream_xchacha20poly1305_COUNTERBYTES); + STATE_COUNTER(state)[0] = 1; +} + +void +crypto_secretstream_xchacha20poly1305_keygen + (unsigned char k[crypto_secretstream_xchacha20poly1305_KEYBYTES]) +{ + randombytes_buf(k, crypto_secretstream_xchacha20poly1305_KEYBYTES); +} + +int +crypto_secretstream_xchacha20poly1305_init_push + (crypto_secretstream_xchacha20poly1305_state *state, + unsigned char out[crypto_secretstream_xchacha20poly1305_HEADERBYTES], + const unsigned char k[crypto_secretstream_xchacha20poly1305_KEYBYTES]) +{ + COMPILER_ASSERT(crypto_secretstream_xchacha20poly1305_HEADERBYTES == + crypto_core_hchacha20_INPUTBYTES + + crypto_secretstream_xchacha20poly1305_INONCEBYTES); + COMPILER_ASSERT(crypto_secretstream_xchacha20poly1305_HEADERBYTES == + crypto_aead_xchacha20poly1305_ietf_NPUBBYTES); + COMPILER_ASSERT(sizeof state->nonce == + crypto_secretstream_xchacha20poly1305_INONCEBYTES + + crypto_secretstream_xchacha20poly1305_COUNTERBYTES); + + randombytes_buf(out, crypto_secretstream_xchacha20poly1305_HEADERBYTES); + crypto_core_hchacha20(state->k, out, k, NULL); + _crypto_secretstream_xchacha20poly1305_counter_reset(state); + memcpy(STATE_INONCE(state), out + crypto_core_hchacha20_INPUTBYTES, + crypto_secretstream_xchacha20poly1305_INONCEBYTES); + memset(state->_pad, 0, sizeof state->_pad); + + return 0; +} + +int +crypto_secretstream_xchacha20poly1305_init_pull + (crypto_secretstream_xchacha20poly1305_state *state, + const unsigned char in[crypto_secretstream_xchacha20poly1305_HEADERBYTES], + const unsigned char k[crypto_secretstream_xchacha20poly1305_KEYBYTES]) +{ + crypto_core_hchacha20(state->k, in, k, NULL); + _crypto_secretstream_xchacha20poly1305_counter_reset(state); + memcpy(STATE_INONCE(state), in + crypto_core_hchacha20_INPUTBYTES, + crypto_secretstream_xchacha20poly1305_INONCEBYTES); + memset(state->_pad, 0, sizeof state->_pad); + + return 0; +} + +void +crypto_secretstream_xchacha20poly1305_rekey + (crypto_secretstream_xchacha20poly1305_state *state) +{ + unsigned char new_key_and_inonce[crypto_stream_chacha20_ietf_KEYBYTES + + crypto_secretstream_xchacha20poly1305_INONCEBYTES]; + size_t i; + + for (i = 0U; i < crypto_stream_chacha20_ietf_KEYBYTES; i++) { + new_key_and_inonce[i] = state->k[i]; + } + for (i = 0U; i < crypto_secretstream_xchacha20poly1305_INONCEBYTES; i++) { + new_key_and_inonce[crypto_stream_chacha20_ietf_KEYBYTES + i] = + STATE_INONCE(state)[i]; + } + crypto_stream_chacha20_ietf_xor(new_key_and_inonce, new_key_and_inonce, + sizeof new_key_and_inonce, + state->nonce, state->k); + for (i = 0U; i < crypto_stream_chacha20_ietf_KEYBYTES; i++) { + state->k[i] = new_key_and_inonce[i]; + } + for (i = 0U; i < crypto_secretstream_xchacha20poly1305_INONCEBYTES; i++) { + STATE_INONCE(state)[i] = + new_key_and_inonce[crypto_stream_chacha20_ietf_KEYBYTES + i]; + } + _crypto_secretstream_xchacha20poly1305_counter_reset(state); +} + +int +crypto_secretstream_xchacha20poly1305_push + (crypto_secretstream_xchacha20poly1305_state *state, + unsigned char *out, unsigned long long *outlen_p, + const unsigned char *m, unsigned long long mlen, + const unsigned char *ad, unsigned long long adlen, unsigned char tag) +{ + crypto_onetimeauth_poly1305_state poly1305_state; + unsigned char block[64U]; + unsigned char slen[8U]; + unsigned char *c; + unsigned char *mac; + + if (outlen_p != NULL) { + *outlen_p = 0U; + } + if (mlen > crypto_secretstream_xchacha20poly1305_MESSAGEBYTES_MAX) { + sodium_misuse(); + } + crypto_stream_chacha20_ietf(block, sizeof block, state->nonce, state->k); + crypto_onetimeauth_poly1305_init(&poly1305_state, block); + sodium_memzero(block, sizeof block); + + crypto_onetimeauth_poly1305_update(&poly1305_state, ad, adlen); + crypto_onetimeauth_poly1305_update(&poly1305_state, _pad0, + (0x10 - adlen) & 0xf); + memset(block, 0, sizeof block); + block[0] = tag; + + crypto_stream_chacha20_ietf_xor_ic(block, block, sizeof block, + state->nonce, 1U, state->k); + crypto_onetimeauth_poly1305_update(&poly1305_state, block, sizeof block); + out[0] = block[0]; + + c = out + (sizeof tag); + crypto_stream_chacha20_ietf_xor_ic(c, m, mlen, state->nonce, 2U, state->k); + crypto_onetimeauth_poly1305_update(&poly1305_state, c, mlen); + crypto_onetimeauth_poly1305_update + (&poly1305_state, _pad0, (0x10 - (sizeof block) + mlen) & 0xf); + + STORE64_LE(slen, (uint64_t) adlen); + crypto_onetimeauth_poly1305_update(&poly1305_state, slen, sizeof slen); + STORE64_LE(slen, (sizeof block) + mlen); + crypto_onetimeauth_poly1305_update(&poly1305_state, slen, sizeof slen); + + mac = c + mlen; + crypto_onetimeauth_poly1305_final(&poly1305_state, mac); + sodium_memzero(&poly1305_state, sizeof poly1305_state); + + COMPILER_ASSERT(crypto_onetimeauth_poly1305_BYTES >= + crypto_secretstream_xchacha20poly1305_INONCEBYTES); + XOR_BUF(STATE_INONCE(state), mac, + crypto_secretstream_xchacha20poly1305_INONCEBYTES); + sodium_increment(STATE_COUNTER(state), + crypto_secretstream_xchacha20poly1305_COUNTERBYTES); + if ((tag & crypto_secretstream_xchacha20poly1305_TAG_REKEY) != 0 || + sodium_is_zero(STATE_COUNTER(state), + crypto_secretstream_xchacha20poly1305_COUNTERBYTES)) { + crypto_secretstream_xchacha20poly1305_rekey(state); + } + if (outlen_p != NULL) { + *outlen_p = crypto_secretstream_xchacha20poly1305_ABYTES + mlen; + } + return 0; +} + +int +crypto_secretstream_xchacha20poly1305_pull + (crypto_secretstream_xchacha20poly1305_state *state, + unsigned char *m, unsigned long long *mlen_p, unsigned char *tag_p, + const unsigned char *in, unsigned long long inlen, + const unsigned char *ad, unsigned long long adlen) +{ + crypto_onetimeauth_poly1305_state poly1305_state; + unsigned char block[64U]; + unsigned char slen[8U]; + unsigned char mac[crypto_onetimeauth_poly1305_BYTES]; + const unsigned char *c; + const unsigned char *stored_mac; + unsigned long long mlen; + unsigned char tag; + + if (mlen_p != NULL) { + *mlen_p = 0U; + } + if (tag_p != NULL) { + *tag_p = 0xff; + } + if (inlen < crypto_secretstream_xchacha20poly1305_ABYTES) { + return -1; + } + mlen = inlen - crypto_secretstream_xchacha20poly1305_ABYTES; + if (mlen > crypto_secretstream_xchacha20poly1305_MESSAGEBYTES_MAX) { + sodium_misuse(); + } + crypto_stream_chacha20_ietf(block, sizeof block, state->nonce, state->k); + crypto_onetimeauth_poly1305_init(&poly1305_state, block); + sodium_memzero(block, sizeof block); + + crypto_onetimeauth_poly1305_update(&poly1305_state, ad, adlen); + crypto_onetimeauth_poly1305_update(&poly1305_state, _pad0, + (0x10 - adlen) & 0xf); + + memset(block, 0, sizeof block); + block[0] = in[0]; + crypto_stream_chacha20_ietf_xor_ic(block, block, sizeof block, + state->nonce, 1U, state->k); + tag = block[0]; + block[0] = in[0]; + crypto_onetimeauth_poly1305_update(&poly1305_state, block, sizeof block); + + c = in + (sizeof tag); + crypto_onetimeauth_poly1305_update(&poly1305_state, c, mlen); + crypto_onetimeauth_poly1305_update + (&poly1305_state, _pad0, (0x10 - (sizeof block) + mlen) & 0xf); + + STORE64_LE(slen, (uint64_t) adlen); + crypto_onetimeauth_poly1305_update(&poly1305_state, slen, sizeof slen); + STORE64_LE(slen, (sizeof block) + mlen); + crypto_onetimeauth_poly1305_update(&poly1305_state, slen, sizeof slen); + + crypto_onetimeauth_poly1305_final(&poly1305_state, mac); + sodium_memzero(&poly1305_state, sizeof poly1305_state); + + stored_mac = c + mlen; + if (sodium_memcmp(mac, stored_mac, sizeof mac) != 0) { + sodium_memzero(mac, sizeof mac); + return -1; + } + + crypto_stream_chacha20_ietf_xor_ic(m, c, mlen, state->nonce, 2U, state->k); + XOR_BUF(STATE_INONCE(state), mac, + crypto_secretstream_xchacha20poly1305_INONCEBYTES); + sodium_increment(STATE_COUNTER(state), + crypto_secretstream_xchacha20poly1305_COUNTERBYTES); + if ((tag & crypto_secretstream_xchacha20poly1305_TAG_REKEY) != 0 || + sodium_is_zero(STATE_COUNTER(state), + crypto_secretstream_xchacha20poly1305_COUNTERBYTES)) { + crypto_secretstream_xchacha20poly1305_rekey(state); + } + if (mlen_p != NULL) { + *mlen_p = mlen; + } + if (tag_p != NULL) { + *tag_p = tag; + } + return 0; +} + +size_t +crypto_secretstream_xchacha20poly1305_statebytes(void) +{ + return sizeof(crypto_secretstream_xchacha20poly1305_state); +} + +size_t +crypto_secretstream_xchacha20poly1305_abytes(void) +{ + return crypto_secretstream_xchacha20poly1305_ABYTES; +} + +size_t +crypto_secretstream_xchacha20poly1305_headerbytes(void) +{ + return crypto_secretstream_xchacha20poly1305_HEADERBYTES; +} + +size_t +crypto_secretstream_xchacha20poly1305_keybytes(void) +{ + return crypto_secretstream_xchacha20poly1305_KEYBYTES; +} + +size_t +crypto_secretstream_xchacha20poly1305_messagebytes_max(void) +{ + return crypto_secretstream_xchacha20poly1305_MESSAGEBYTES_MAX; +} + +unsigned char +crypto_secretstream_xchacha20poly1305_tag_message(void) +{ + return crypto_secretstream_xchacha20poly1305_TAG_MESSAGE; +} + +unsigned char +crypto_secretstream_xchacha20poly1305_tag_push(void) +{ + return crypto_secretstream_xchacha20poly1305_TAG_PUSH; +} + +unsigned char +crypto_secretstream_xchacha20poly1305_tag_rekey(void) +{ + return crypto_secretstream_xchacha20poly1305_TAG_REKEY; +} + +unsigned char +crypto_secretstream_xchacha20poly1305_tag_final(void) +{ + return crypto_secretstream_xchacha20poly1305_TAG_FINAL; +} diff --git a/libs/libsodium/src/crypto_shorthash/crypto_shorthash.c b/libs/libsodium/src/crypto_shorthash/crypto_shorthash.c new file mode 100644 index 0000000000..95f52f83ba --- /dev/null +++ b/libs/libsodium/src/crypto_shorthash/crypto_shorthash.c @@ -0,0 +1,34 @@ + +#include "crypto_shorthash.h" +#include "randombytes.h" + +size_t +crypto_shorthash_bytes(void) +{ + return crypto_shorthash_BYTES; +} + +size_t +crypto_shorthash_keybytes(void) +{ + return crypto_shorthash_KEYBYTES; +} + +const char * +crypto_shorthash_primitive(void) +{ + return crypto_shorthash_PRIMITIVE; +} + +int +crypto_shorthash(unsigned char *out, const unsigned char *in, + unsigned long long inlen, const unsigned char *k) +{ + return crypto_shorthash_siphash24(out, in, inlen, k); +} + +void +crypto_shorthash_keygen(unsigned char k[crypto_shorthash_KEYBYTES]) +{ + randombytes_buf(k, crypto_shorthash_KEYBYTES); +} diff --git a/libs/libsodium/src/crypto_shorthash/siphash24/ref/shorthash_siphash24_ref.c b/libs/libsodium/src/crypto_shorthash/siphash24/ref/shorthash_siphash24_ref.c new file mode 100644 index 0000000000..0c173d4c89 --- /dev/null +++ b/libs/libsodium/src/crypto_shorthash/siphash24/ref/shorthash_siphash24_ref.c @@ -0,0 +1,65 @@ +#include "crypto_shorthash_siphash24.h" +#include "private/common.h" +#include "shorthash_siphash_ref.h" + +int +crypto_shorthash_siphash24(unsigned char *out, const unsigned char *in, + unsigned long long inlen, const unsigned char *k) +{ + /* "somepseudorandomlygeneratedbytes" */ + uint64_t v0 = 0x736f6d6570736575ULL; + uint64_t v1 = 0x646f72616e646f6dULL; + uint64_t v2 = 0x6c7967656e657261ULL; + uint64_t v3 = 0x7465646279746573ULL; + uint64_t b; + uint64_t k0 = LOAD64_LE(k); + uint64_t k1 = LOAD64_LE(k + 8); + uint64_t m; + const uint8_t *end = in + inlen - (inlen % sizeof(uint64_t)); + const int left = inlen & 7; + + b = ((uint64_t) inlen) << 56; + v3 ^= k1; + v2 ^= k0; + v1 ^= k1; + v0 ^= k0; + for (; in != end; in += 8) { + m = LOAD64_LE(in); + v3 ^= m; + SIPROUND; + SIPROUND; + v0 ^= m; + } + switch (left) { + case 7: + b |= ((uint64_t) in[6]) << 48; + case 6: + b |= ((uint64_t) in[5]) << 40; + case 5: + b |= ((uint64_t) in[4]) << 32; + case 4: + b |= ((uint64_t) in[3]) << 24; + case 3: + b |= ((uint64_t) in[2]) << 16; + case 2: + b |= ((uint64_t) in[1]) << 8; + case 1: + b |= ((uint64_t) in[0]); + break; + case 0: + break; + } + v3 ^= b; + SIPROUND; + SIPROUND; + v0 ^= b; + v2 ^= 0xff; + SIPROUND; + SIPROUND; + SIPROUND; + SIPROUND; + b = v0 ^ v1 ^ v2 ^ v3; + STORE64_LE(out, b); + + return 0; +} diff --git a/libs/libsodium/src/crypto_shorthash/siphash24/ref/shorthash_siphash_ref.h b/libs/libsodium/src/crypto_shorthash/siphash24/ref/shorthash_siphash_ref.h new file mode 100644 index 0000000000..3f9a38b510 --- /dev/null +++ b/libs/libsodium/src/crypto_shorthash/siphash24/ref/shorthash_siphash_ref.h @@ -0,0 +1,24 @@ +#ifndef shorthash_siphash_H +#define shorthash_siphash_H + +#include "private/common.h" + +#define SIPROUND \ + do { \ + v0 += v1; \ + v1 = ROTL64(v1, 13); \ + v1 ^= v0; \ + v0 = ROTL64(v0, 32); \ + v2 += v3; \ + v3 = ROTL64(v3, 16); \ + v3 ^= v2; \ + v0 += v3; \ + v3 = ROTL64(v3, 21); \ + v3 ^= v0; \ + v2 += v1; \ + v1 = ROTL64(v1, 17); \ + v1 ^= v2; \ + v2 = ROTL64(v2, 32); \ + } while (0) + +#endif diff --git a/libs/libsodium/src/crypto_shorthash/siphash24/ref/shorthash_siphashx24_ref.c b/libs/libsodium/src/crypto_shorthash/siphash24/ref/shorthash_siphashx24_ref.c new file mode 100644 index 0000000000..20480d0d5f --- /dev/null +++ b/libs/libsodium/src/crypto_shorthash/siphash24/ref/shorthash_siphashx24_ref.c @@ -0,0 +1,71 @@ +#include "crypto_shorthash_siphash24.h" +#include "private/common.h" +#include "shorthash_siphash_ref.h" + +int +crypto_shorthash_siphashx24(unsigned char *out, const unsigned char *in, + unsigned long long inlen, const unsigned char *k) +{ + uint64_t v0 = 0x736f6d6570736575ULL; + uint64_t v1 = 0x646f72616e646f83ULL; + uint64_t v2 = 0x6c7967656e657261ULL; + uint64_t v3 = 0x7465646279746573ULL; + uint64_t b; + uint64_t k0 = LOAD64_LE(k); + uint64_t k1 = LOAD64_LE(k + 8); + uint64_t m; + const uint8_t *end = in + inlen - (inlen % sizeof(uint64_t)); + const int left = inlen & 7; + + b = ((uint64_t) inlen) << 56; + v3 ^= k1; + v2 ^= k0; + v1 ^= k1; + v0 ^= k0; + for (; in != end; in += 8) { + m = LOAD64_LE(in); + v3 ^= m; + SIPROUND; + SIPROUND; + v0 ^= m; + } + switch (left) { + case 7: + b |= ((uint64_t) in[6]) << 48; + case 6: + b |= ((uint64_t) in[5]) << 40; + case 5: + b |= ((uint64_t) in[4]) << 32; + case 4: + b |= ((uint64_t) in[3]) << 24; + case 3: + b |= ((uint64_t) in[2]) << 16; + case 2: + b |= ((uint64_t) in[1]) << 8; + case 1: + b |= ((uint64_t) in[0]); + break; + case 0: + break; + } + v3 ^= b; + SIPROUND; + SIPROUND; + v0 ^= b; + v2 ^= 0xee; + SIPROUND; + SIPROUND; + SIPROUND; + SIPROUND; + b = v0 ^ v1 ^ v2 ^ v3; + STORE64_LE(out, b); + v1 ^= 0xdd; + SIPROUND; + SIPROUND; + SIPROUND; + SIPROUND; + b = v0 ^ v1 ^ v2 ^ v3; + STORE64_LE(out + 8, b); + + return 0; +} diff --git a/libs/libsodium/src/crypto_shorthash/siphash24/shorthash_siphash24.c b/libs/libsodium/src/crypto_shorthash/siphash24/shorthash_siphash24.c new file mode 100644 index 0000000000..e2cea7761e --- /dev/null +++ b/libs/libsodium/src/crypto_shorthash/siphash24/shorthash_siphash24.c @@ -0,0 +1,11 @@ +#include "crypto_shorthash_siphash24.h" + +size_t +crypto_shorthash_siphash24_bytes(void) { + return crypto_shorthash_siphash24_BYTES; +} + +size_t +crypto_shorthash_siphash24_keybytes(void) { + return crypto_shorthash_siphash24_KEYBYTES; +} diff --git a/libs/libsodium/src/crypto_shorthash/siphash24/shorthash_siphashx24.c b/libs/libsodium/src/crypto_shorthash/siphash24/shorthash_siphashx24.c new file mode 100644 index 0000000000..2d487dbb6f --- /dev/null +++ b/libs/libsodium/src/crypto_shorthash/siphash24/shorthash_siphashx24.c @@ -0,0 +1,11 @@ +#include "crypto_shorthash_siphash24.h" + +size_t +crypto_shorthash_siphashx24_bytes(void) { + return crypto_shorthash_siphashx24_BYTES; +} + +size_t +crypto_shorthash_siphashx24_keybytes(void) { + return crypto_shorthash_siphashx24_KEYBYTES; +} diff --git a/libs/libsodium/src/crypto_sign/crypto_sign.c b/libs/libsodium/src/crypto_sign/crypto_sign.c new file mode 100644 index 0000000000..127072f726 --- /dev/null +++ b/libs/libsodium/src/crypto_sign/crypto_sign.c @@ -0,0 +1,115 @@ + +#include "crypto_sign.h" + +size_t +crypto_sign_statebytes(void) +{ + return sizeof(crypto_sign_state); +} + +size_t +crypto_sign_bytes(void) +{ + return crypto_sign_BYTES; +} + +size_t +crypto_sign_seedbytes(void) +{ + return crypto_sign_SEEDBYTES; +} + +size_t +crypto_sign_publickeybytes(void) +{ + return crypto_sign_PUBLICKEYBYTES; +} + +size_t +crypto_sign_secretkeybytes(void) +{ + return crypto_sign_SECRETKEYBYTES; +} + +size_t +crypto_sign_messagebytes_max(void) +{ + return crypto_sign_MESSAGEBYTES_MAX; +} + +const char * +crypto_sign_primitive(void) +{ + return crypto_sign_PRIMITIVE; +} + +int +crypto_sign_seed_keypair(unsigned char *pk, unsigned char *sk, + const unsigned char *seed) +{ + return crypto_sign_ed25519_seed_keypair(pk, sk, seed); +} + +int +crypto_sign_keypair(unsigned char *pk, unsigned char *sk) +{ + return crypto_sign_ed25519_keypair(pk, sk); +} + +int +crypto_sign(unsigned char *sm, unsigned long long *smlen_p, + const unsigned char *m, unsigned long long mlen, + const unsigned char *sk) +{ + return crypto_sign_ed25519(sm, smlen_p, m, mlen, sk); +} + +int +crypto_sign_open(unsigned char *m, unsigned long long *mlen_p, + const unsigned char *sm, unsigned long long smlen, + const unsigned char *pk) +{ + return crypto_sign_ed25519_open(m, mlen_p, sm, smlen, pk); +} + +int +crypto_sign_detached(unsigned char *sig, unsigned long long *siglen_p, + const unsigned char *m, unsigned long long mlen, + const unsigned char *sk) +{ + return crypto_sign_ed25519_detached(sig, siglen_p, m, mlen, sk); +} + +int +crypto_sign_verify_detached(const unsigned char *sig, const unsigned char *m, + unsigned long long mlen, const unsigned char *pk) +{ + return crypto_sign_ed25519_verify_detached(sig, m, mlen, pk); +} + +int +crypto_sign_init(crypto_sign_state *state) +{ + return crypto_sign_ed25519ph_init(state); +} + +int +crypto_sign_update(crypto_sign_state *state, const unsigned char *m, + unsigned long long mlen) +{ + return crypto_sign_ed25519ph_update(state, m, mlen); +} + +int +crypto_sign_final_create(crypto_sign_state *state, unsigned char *sig, + unsigned long long *siglen_p, const unsigned char *sk) +{ + return crypto_sign_ed25519ph_final_create(state, sig, siglen_p, sk); +} + +int +crypto_sign_final_verify(crypto_sign_state *state, unsigned char *sig, + const unsigned char *pk) +{ + return crypto_sign_ed25519ph_final_verify(state, sig, pk); +} diff --git a/libs/libsodium/src/crypto_sign/ed25519/ref10/keypair.c b/libs/libsodium/src/crypto_sign/ed25519/ref10/keypair.c new file mode 100644 index 0000000000..8bf3cec8fd --- /dev/null +++ b/libs/libsodium/src/crypto_sign/ed25519/ref10/keypair.c @@ -0,0 +1,91 @@ + +#include <string.h> + +#include "crypto_hash_sha512.h" +#include "crypto_scalarmult_curve25519.h" +#include "crypto_sign_ed25519.h" +#include "sign_ed25519_ref10.h" +#include "private/ed25519_ref10.h" +#include "randombytes.h" +#include "utils.h" + +int +crypto_sign_ed25519_seed_keypair(unsigned char *pk, unsigned char *sk, + const unsigned char *seed) +{ + ge25519_p3 A; + +#ifdef ED25519_NONDETERMINISTIC + memmove(sk, seed, 32); +#else + crypto_hash_sha512(sk, seed, 32); +#endif + sk[0] &= 248; + sk[31] &= 127; + sk[31] |= 64; + + ge25519_scalarmult_base(&A, sk); + ge25519_p3_tobytes(pk, &A); + + memmove(sk, seed, 32); + memmove(sk + 32, pk, 32); + + return 0; +} + +int +crypto_sign_ed25519_keypair(unsigned char *pk, unsigned char *sk) +{ + unsigned char seed[32]; + int ret; + + randombytes_buf(seed, sizeof seed); + ret = crypto_sign_ed25519_seed_keypair(pk, sk, seed); + sodium_memzero(seed, sizeof seed); + + return ret; +} + +int +crypto_sign_ed25519_pk_to_curve25519(unsigned char *curve25519_pk, + const unsigned char *ed25519_pk) +{ + ge25519_p3 A; + fe25519 x; + fe25519 one_minus_y; + + if (ge25519_has_small_order(ed25519_pk) != 0 || + ge25519_frombytes_negate_vartime(&A, ed25519_pk) != 0 || + ge25519_is_on_main_subgroup(&A) == 0) { + return -1; + } + fe25519_1(one_minus_y); + fe25519_sub(one_minus_y, one_minus_y, A.Y); + fe25519_invert(one_minus_y, one_minus_y); + fe25519_1(x); + fe25519_add(x, x, A.Y); + fe25519_mul(x, x, one_minus_y); + fe25519_tobytes(curve25519_pk, x); + + return 0; +} + +int +crypto_sign_ed25519_sk_to_curve25519(unsigned char *curve25519_sk, + const unsigned char *ed25519_sk) +{ + unsigned char h[crypto_hash_sha512_BYTES]; + +#ifdef ED25519_NONDETERMINISTIC + memcpy(h, ed25519_sk, 32); +#else + crypto_hash_sha512(h, ed25519_sk, 32); +#endif + h[0] &= 248; + h[31] &= 127; + h[31] |= 64; + memcpy(curve25519_sk, h, crypto_scalarmult_curve25519_BYTES); + sodium_memzero(h, sizeof h); + + return 0; +} diff --git a/libs/libsodium/src/crypto_sign/ed25519/ref10/obsolete.c b/libs/libsodium/src/crypto_sign/ed25519/ref10/obsolete.c new file mode 100644 index 0000000000..03440cfa75 --- /dev/null +++ b/libs/libsodium/src/crypto_sign/ed25519/ref10/obsolete.c @@ -0,0 +1,116 @@ + +#include <limits.h> +#include <stdint.h> +#include <string.h> + +#include "crypto_hash_sha512.h" +#include "crypto_sign_edwards25519sha512batch.h" +#include "crypto_verify_32.h" +#include "private/ed25519_ref10.h" +#include "randombytes.h" +#include "utils.h" + +int +crypto_sign_edwards25519sha512batch_keypair(unsigned char *pk, + unsigned char *sk) +{ + ge25519_p3 A; + + randombytes_buf(sk, 32); + crypto_hash_sha512(sk, sk, 32); + sk[0] &= 248; + sk[31] &= 127; + sk[31] |= 64; + ge25519_scalarmult_base(&A, sk); + ge25519_p3_tobytes(pk, &A); + + return 0; +} + +int +crypto_sign_edwards25519sha512batch(unsigned char *sm, + unsigned long long *smlen_p, + const unsigned char *m, + unsigned long long mlen, + const unsigned char *sk) +{ + crypto_hash_sha512_state hs; + unsigned char nonce[64]; + unsigned char hram[64]; + unsigned char sig[64]; + ge25519_p3 A; + ge25519_p3 R; + + crypto_hash_sha512_init(&hs); + crypto_hash_sha512_update(&hs, sk + 32, 32); + crypto_hash_sha512_update(&hs, m, mlen); + crypto_hash_sha512_final(&hs, nonce); + ge25519_scalarmult_base(&A, sk); + ge25519_p3_tobytes(sig + 32, &A); + sc25519_reduce(nonce); + ge25519_scalarmult_base(&R, nonce); + ge25519_p3_tobytes(sig, &R); + crypto_hash_sha512_init(&hs); + crypto_hash_sha512_update(&hs, sig, 32); + crypto_hash_sha512_update(&hs, m, mlen); + crypto_hash_sha512_final(&hs, hram); + sc25519_reduce(hram); + sc25519_muladd(sig + 32, hram, nonce, sk); + sodium_memzero(hram, sizeof hram); + memmove(sm + 32, m, (size_t) mlen); + memcpy(sm, sig, 32); + memcpy(sm + 32 + mlen, sig + 32, 32); + *smlen_p = mlen + 64U; + + return 0; +} + +int +crypto_sign_edwards25519sha512batch_open(unsigned char *m, + unsigned long long *mlen_p, + const unsigned char *sm, + unsigned long long smlen, + const unsigned char *pk) +{ + unsigned char h[64]; + unsigned char t1[32], t2[32]; + unsigned long long mlen; + ge25519_cached Ai; + ge25519_p1p1 csa; + ge25519_p2 cs; + ge25519_p3 A; + ge25519_p3 R; + ge25519_p3 cs3; + + *mlen_p = 0; + if (smlen < 64 || smlen - 64 > crypto_sign_edwards25519sha512batch_MESSAGEBYTES_MAX) { + return -1; + } + mlen = smlen - 64; + if (sm[smlen - 1] & 224) { + return -1; + } + if (ge25519_has_small_order(pk) != 0 || + ge25519_frombytes_negate_vartime(&A, pk) != 0 || + ge25519_has_small_order(sm) != 0 || + ge25519_frombytes_negate_vartime(&R, sm) != 0) { + return -1; + } + ge25519_p3_to_cached(&Ai, &A); + crypto_hash_sha512(h, sm, mlen + 32); + sc25519_reduce(h); + ge25519_scalarmult(&cs3, h, &R); + ge25519_add(&csa, &cs3, &Ai); + ge25519_p1p1_to_p2(&cs, &csa); + ge25519_tobytes(t1, &cs); + t1[31] ^= 1 << 7; + ge25519_scalarmult_base(&R, sm + 32 + mlen); + ge25519_p3_tobytes(t2, &R); + if (crypto_verify_32(t1, t2) != 0) { + return -1; + } + *mlen_p = mlen; + memmove(m, sm + 32, mlen); + + return 0; +} diff --git a/libs/libsodium/src/crypto_sign/ed25519/ref10/open.c b/libs/libsodium/src/crypto_sign/ed25519/ref10/open.c new file mode 100644 index 0000000000..c9e8843c1e --- /dev/null +++ b/libs/libsodium/src/crypto_sign/ed25519/ref10/open.c @@ -0,0 +1,93 @@ + +#include <limits.h> +#include <stdint.h> +#include <string.h> + +#include "crypto_hash_sha512.h" +#include "crypto_sign_ed25519.h" +#include "crypto_verify_32.h" +#include "sign_ed25519_ref10.h" +#include "private/ed25519_ref10.h" +#include "utils.h" + +int +_crypto_sign_ed25519_verify_detached(const unsigned char *sig, + const unsigned char *m, + unsigned long long mlen, + const unsigned char *pk, + int prehashed) +{ + crypto_hash_sha512_state hs; + unsigned char h[64]; + unsigned char rcheck[32]; + ge25519_p3 A; + ge25519_p2 R; + +#ifndef ED25519_COMPAT + if (sc25519_is_canonical(sig + 32) == 0 || + ge25519_has_small_order(sig) != 0) { + return -1; + } + if (ge25519_is_canonical(pk) == 0) { + return -1; + } +#else + if (sig[63] & 224) { + return -1; + } +#endif + if (ge25519_has_small_order(pk) != 0 || + ge25519_frombytes_negate_vartime(&A, pk) != 0) { + return -1; + } + _crypto_sign_ed25519_ref10_hinit(&hs, prehashed); + crypto_hash_sha512_update(&hs, sig, 32); + crypto_hash_sha512_update(&hs, pk, 32); + crypto_hash_sha512_update(&hs, m, mlen); + crypto_hash_sha512_final(&hs, h); + sc25519_reduce(h); + + ge25519_double_scalarmult_vartime(&R, h, &A, sig + 32); + ge25519_tobytes(rcheck, &R); + + return crypto_verify_32(rcheck, sig) | (-(rcheck == sig)) | + sodium_memcmp(sig, rcheck, 32); +} + +int +crypto_sign_ed25519_verify_detached(const unsigned char *sig, + const unsigned char *m, + unsigned long long mlen, + const unsigned char *pk) +{ + return _crypto_sign_ed25519_verify_detached(sig, m, mlen, pk, 0); +} + +int +crypto_sign_ed25519_open(unsigned char *m, unsigned long long *mlen_p, + const unsigned char *sm, unsigned long long smlen, + const unsigned char *pk) +{ + unsigned long long mlen; + + if (smlen < 64 || smlen - 64 > crypto_sign_ed25519_MESSAGEBYTES_MAX) { + goto badsig; + } + mlen = smlen - 64; + if (crypto_sign_ed25519_verify_detached(sm, sm + 64, mlen, pk) != 0) { + memset(m, 0, mlen); + goto badsig; + } + if (mlen_p != NULL) { + *mlen_p = mlen; + } + memmove(m, sm + 64, mlen); + + return 0; + +badsig: + if (mlen_p != NULL) { + *mlen_p = 0; + } + return -1; +} diff --git a/libs/libsodium/src/crypto_sign/ed25519/ref10/sign.c b/libs/libsodium/src/crypto_sign/ed25519/ref10/sign.c new file mode 100644 index 0000000000..4df90bddd9 --- /dev/null +++ b/libs/libsodium/src/crypto_sign/ed25519/ref10/sign.c @@ -0,0 +1,144 @@ + +#include <string.h> + +#include "crypto_hash_sha512.h" +#include "crypto_sign_ed25519.h" +#include "sign_ed25519_ref10.h" +#include "private/ed25519_ref10.h" +#include "randombytes.h" +#include "utils.h" + +void +_crypto_sign_ed25519_ref10_hinit(crypto_hash_sha512_state *hs, int prehashed) +{ + static const unsigned char DOM2PREFIX[32 + 2] = { + 'S', 'i', 'g', 'E', 'd', '2', '5', '5', '1', '9', ' ', + 'n', 'o', ' ', + 'E', 'd', '2', '5', '5', '1', '9', ' ', + 'c', 'o', 'l', 'l', 'i', 's', 'i', 'o', 'n', 's', 1, 0 + }; + + crypto_hash_sha512_init(hs); + if (prehashed) { + crypto_hash_sha512_update(hs, DOM2PREFIX, sizeof DOM2PREFIX); + } +} + +static inline void +_crypto_sign_ed25519_clamp(unsigned char k[32]) +{ + k[0] &= 248; + k[31] &= 127; + k[31] |= 64; +} + +#ifdef ED25519_NONDETERMINISTIC +/* r = hash(B || empty_labelset || Z || pad1 || k || pad2 || empty_labelset || K || extra || M) (mod q) */ +static void +_crypto_sign_ed25519_synthetic_r_hv(crypto_hash_sha512_state *hs, + unsigned char Z[32], + const unsigned char sk[64]) +{ + static const unsigned char B[32] = { + 0x58, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, + 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, + 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, + 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, + }; + static const unsigned char zeros[128] = { 0x00 }; + static const unsigned char empty_labelset[3] = { 0x02, 0x00, 0x00 }; + + crypto_hash_sha512_update(hs, B, 32); + crypto_hash_sha512_update(hs, empty_labelset, 3); + randombytes_buf(Z, 32); + crypto_hash_sha512_update(hs, Z, 32); + crypto_hash_sha512_update(hs, zeros, 128 - (32 + 3 + 32) % 128); + crypto_hash_sha512_update(hs, sk, 32); + crypto_hash_sha512_update(hs, zeros, 128 - 32 % 128); + crypto_hash_sha512_update(hs, empty_labelset, 3); + crypto_hash_sha512_update(hs, sk + 32, 32); + /* empty extra */ +} +#endif + +int +_crypto_sign_ed25519_detached(unsigned char *sig, unsigned long long *siglen_p, + const unsigned char *m, unsigned long long mlen, + const unsigned char *sk, int prehashed) +{ + crypto_hash_sha512_state hs; + unsigned char az[64]; + unsigned char nonce[64]; + unsigned char hram[64]; + ge25519_p3 R; + + _crypto_sign_ed25519_ref10_hinit(&hs, prehashed); + +#ifdef ED25519_NONDETERMINISTIC + memcpy(az, sk, 32); + _crypto_sign_ed25519_synthetic_r_hv(&hs, nonce, az); +#else + crypto_hash_sha512(az, sk, 32); + crypto_hash_sha512_update(&hs, az + 32, 32); +#endif + + crypto_hash_sha512_update(&hs, m, mlen); + crypto_hash_sha512_final(&hs, nonce); + + memmove(sig + 32, sk + 32, 32); + + sc25519_reduce(nonce); + ge25519_scalarmult_base(&R, nonce); + ge25519_p3_tobytes(sig, &R); + + _crypto_sign_ed25519_ref10_hinit(&hs, prehashed); + crypto_hash_sha512_update(&hs, sig, 64); + crypto_hash_sha512_update(&hs, m, mlen); + crypto_hash_sha512_final(&hs, hram); + + sc25519_reduce(hram); + _crypto_sign_ed25519_clamp(az); + sc25519_muladd(sig + 32, hram, az, nonce); + + sodium_memzero(az, sizeof az); + sodium_memzero(nonce, sizeof nonce); + + if (siglen_p != NULL) { + *siglen_p = 64U; + } + return 0; +} + +int +crypto_sign_ed25519_detached(unsigned char *sig, unsigned long long *siglen_p, + const unsigned char *m, unsigned long long mlen, + const unsigned char *sk) +{ + return _crypto_sign_ed25519_detached(sig, siglen_p, m, mlen, sk, 0); +} + +int +crypto_sign_ed25519(unsigned char *sm, unsigned long long *smlen_p, + const unsigned char *m, unsigned long long mlen, + const unsigned char *sk) +{ + unsigned long long siglen; + + memmove(sm + crypto_sign_ed25519_BYTES, m, mlen); + /* LCOV_EXCL_START */ + if (crypto_sign_ed25519_detached( + sm, &siglen, sm + crypto_sign_ed25519_BYTES, mlen, sk) != 0 || + siglen != crypto_sign_ed25519_BYTES) { + if (smlen_p != NULL) { + *smlen_p = 0; + } + memset(sm, 0, mlen + crypto_sign_ed25519_BYTES); + return -1; + } + /* LCOV_EXCL_STOP */ + + if (smlen_p != NULL) { + *smlen_p = mlen + siglen; + } + return 0; +} diff --git a/libs/libsodium/src/crypto_sign/ed25519/ref10/sign_ed25519_ref10.h b/libs/libsodium/src/crypto_sign/ed25519/ref10/sign_ed25519_ref10.h new file mode 100644 index 0000000000..29f45a8544 --- /dev/null +++ b/libs/libsodium/src/crypto_sign/ed25519/ref10/sign_ed25519_ref10.h @@ -0,0 +1,18 @@ +#ifndef sign_ed25519_ref10_H +#define sign_ed25519_ref10_H + +void _crypto_sign_ed25519_ref10_hinit(crypto_hash_sha512_state *hs, + int prehashed); + +int _crypto_sign_ed25519_detached(unsigned char *sig, + unsigned long long *siglen_p, + const unsigned char *m, + unsigned long long mlen, + const unsigned char *sk, int prehashed); + +int _crypto_sign_ed25519_verify_detached(const unsigned char *sig, + const unsigned char *m, + unsigned long long mlen, + const unsigned char *pk, + int prehashed); +#endif diff --git a/libs/libsodium/src/crypto_sign/ed25519/sign_ed25519.c b/libs/libsodium/src/crypto_sign/ed25519/sign_ed25519.c new file mode 100644 index 0000000000..8a69513ede --- /dev/null +++ b/libs/libsodium/src/crypto_sign/ed25519/sign_ed25519.c @@ -0,0 +1,97 @@ + +#include <string.h> + +#include "crypto_hash_sha512.h" +#include "crypto_sign_ed25519.h" +#include "ref10/sign_ed25519_ref10.h" + +size_t +crypto_sign_ed25519ph_statebytes(void) +{ + return sizeof(crypto_sign_ed25519ph_state); +} + +size_t +crypto_sign_ed25519_bytes(void) +{ + return crypto_sign_ed25519_BYTES; +} + +size_t +crypto_sign_ed25519_seedbytes(void) +{ + return crypto_sign_ed25519_SEEDBYTES; +} + +size_t +crypto_sign_ed25519_publickeybytes(void) +{ + return crypto_sign_ed25519_PUBLICKEYBYTES; +} + +size_t +crypto_sign_ed25519_secretkeybytes(void) +{ + return crypto_sign_ed25519_SECRETKEYBYTES; +} + +size_t +crypto_sign_ed25519_messagebytes_max(void) +{ + return crypto_sign_ed25519_MESSAGEBYTES_MAX; +} + +int +crypto_sign_ed25519_sk_to_seed(unsigned char *seed, const unsigned char *sk) +{ + memmove(seed, sk, crypto_sign_ed25519_SEEDBYTES); + + return 0; +} + +int +crypto_sign_ed25519_sk_to_pk(unsigned char *pk, const unsigned char *sk) +{ + memmove(pk, sk + crypto_sign_ed25519_SEEDBYTES, + crypto_sign_ed25519_PUBLICKEYBYTES); + return 0; +} + +int +crypto_sign_ed25519ph_init(crypto_sign_ed25519ph_state *state) +{ + crypto_hash_sha512_init(&state->hs); + return 0; +} + +int +crypto_sign_ed25519ph_update(crypto_sign_ed25519ph_state *state, + const unsigned char *m, unsigned long long mlen) +{ + return crypto_hash_sha512_update(&state->hs, m, mlen); +} + +int +crypto_sign_ed25519ph_final_create(crypto_sign_ed25519ph_state *state, + unsigned char *sig, + unsigned long long *siglen_p, + const unsigned char *sk) +{ + unsigned char ph[crypto_hash_sha512_BYTES]; + + crypto_hash_sha512_final(&state->hs, ph); + + return _crypto_sign_ed25519_detached(sig, siglen_p, ph, sizeof ph, sk, 1); +} + +int +crypto_sign_ed25519ph_final_verify(crypto_sign_ed25519ph_state *state, + unsigned char *sig, + const unsigned char *pk) +{ + unsigned char ph[crypto_hash_sha512_BYTES]; + + crypto_hash_sha512_final(&state->hs, ph); + + return _crypto_sign_ed25519_verify_detached(sig, ph, sizeof ph, pk, 1); +} diff --git a/libs/libsodium/src/crypto_stream/chacha20/dolbeau/chacha20_dolbeau-avx2.c b/libs/libsodium/src/crypto_stream/chacha20/dolbeau/chacha20_dolbeau-avx2.c new file mode 100644 index 0000000000..6149af3942 --- /dev/null +++ b/libs/libsodium/src/crypto_stream/chacha20/dolbeau/chacha20_dolbeau-avx2.c @@ -0,0 +1,180 @@ + +#include <stdint.h> +#include <stdlib.h> +#include <string.h> + +#include "core.h" +#include "crypto_stream_chacha20.h" +#include "private/common.h" +#include "private/sse2_64_32.h" +#include "utils.h" + +#if defined(HAVE_AVX2INTRIN_H) && defined(HAVE_EMMINTRIN_H) && \ + defined(HAVE_TMMINTRIN_H) && defined(HAVE_SMMINTRIN_H) + +# ifdef __GNUC__ +# pragma GCC target("sse2") +# pragma GCC target("ssse3") +# pragma GCC target("sse4.1") +# pragma GCC target("avx2") +# endif + +# include <emmintrin.h> +# include <immintrin.h> +# include <smmintrin.h> +# include <tmmintrin.h> + +# include "../stream_chacha20.h" +# include "chacha20_dolbeau-avx2.h" + +# define ROUNDS 20 + +typedef struct chacha_ctx { + uint32_t input[16]; +} chacha_ctx; + +static void +chacha_keysetup(chacha_ctx *ctx, const uint8_t *k) +{ + ctx->input[0] = 0x61707865; + ctx->input[1] = 0x3320646e; + ctx->input[2] = 0x79622d32; + ctx->input[3] = 0x6b206574; + ctx->input[4] = LOAD32_LE(k + 0); + ctx->input[5] = LOAD32_LE(k + 4); + ctx->input[6] = LOAD32_LE(k + 8); + ctx->input[7] = LOAD32_LE(k + 12); + ctx->input[8] = LOAD32_LE(k + 16); + ctx->input[9] = LOAD32_LE(k + 20); + ctx->input[10] = LOAD32_LE(k + 24); + ctx->input[11] = LOAD32_LE(k + 28); +} + +static void +chacha_ivsetup(chacha_ctx *ctx, const uint8_t *iv, const uint8_t *counter) +{ + ctx->input[12] = counter == NULL ? 0 : LOAD32_LE(counter + 0); + ctx->input[13] = counter == NULL ? 0 : LOAD32_LE(counter + 4); + ctx->input[14] = LOAD32_LE(iv + 0); + ctx->input[15] = LOAD32_LE(iv + 4); +} + +static void +chacha_ietf_ivsetup(chacha_ctx *ctx, const uint8_t *iv, const uint8_t *counter) +{ + ctx->input[12] = counter == NULL ? 0 : LOAD32_LE(counter); + ctx->input[13] = LOAD32_LE(iv + 0); + ctx->input[14] = LOAD32_LE(iv + 4); + ctx->input[15] = LOAD32_LE(iv + 8); +} + +static void +chacha20_encrypt_bytes(chacha_ctx *ctx, const uint8_t *m, uint8_t *c, + unsigned long long bytes) +{ + uint32_t * const x = &ctx->input[0]; + + if (!bytes) { + return; /* LCOV_EXCL_LINE */ + } + if (bytes > crypto_stream_chacha20_MESSAGEBYTES_MAX) { + sodium_misuse(); + } +# include "u8.h" +# include "u4.h" +# include "u1.h" +# include "u0.h" +} + +static int +stream_ref(unsigned char *c, unsigned long long clen, const unsigned char *n, + const unsigned char *k) +{ + struct chacha_ctx ctx; + + if (!clen) { + return 0; + } + COMPILER_ASSERT(crypto_stream_chacha20_KEYBYTES == 256 / 8); + chacha_keysetup(&ctx, k); + chacha_ivsetup(&ctx, n, NULL); + memset(c, 0, clen); + chacha20_encrypt_bytes(&ctx, c, c, clen); + sodium_memzero(&ctx, sizeof ctx); + + return 0; +} + +static int +stream_ietf_ref(unsigned char *c, unsigned long long clen, + const unsigned char *n, const unsigned char *k) +{ + struct chacha_ctx ctx; + + if (!clen) { + return 0; + } + COMPILER_ASSERT(crypto_stream_chacha20_KEYBYTES == 256 / 8); + chacha_keysetup(&ctx, k); + chacha_ietf_ivsetup(&ctx, n, NULL); + memset(c, 0, clen); + chacha20_encrypt_bytes(&ctx, c, c, clen); + sodium_memzero(&ctx, sizeof ctx); + + return 0; +} + +static int +stream_ref_xor_ic(unsigned char *c, const unsigned char *m, + unsigned long long mlen, const unsigned char *n, uint64_t ic, + const unsigned char *k) +{ + struct chacha_ctx ctx; + uint8_t ic_bytes[8]; + uint32_t ic_high; + uint32_t ic_low; + + if (!mlen) { + return 0; + } + ic_high = (uint32_t) (ic >> 32); + ic_low = (uint32_t) ic; + STORE32_LE(&ic_bytes[0], ic_low); + STORE32_LE(&ic_bytes[4], ic_high); + chacha_keysetup(&ctx, k); + chacha_ivsetup(&ctx, n, ic_bytes); + chacha20_encrypt_bytes(&ctx, m, c, mlen); + sodium_memzero(&ctx, sizeof ctx); + + return 0; +} + +static int +stream_ietf_ref_xor_ic(unsigned char *c, const unsigned char *m, + unsigned long long mlen, const unsigned char *n, + uint32_t ic, const unsigned char *k) +{ + struct chacha_ctx ctx; + uint8_t ic_bytes[4]; + + if (!mlen) { + return 0; + } + STORE32_LE(ic_bytes, ic); + chacha_keysetup(&ctx, k); + chacha_ietf_ivsetup(&ctx, n, ic_bytes); + chacha20_encrypt_bytes(&ctx, m, c, mlen); + sodium_memzero(&ctx, sizeof ctx); + + return 0; +} + +struct crypto_stream_chacha20_implementation + crypto_stream_chacha20_dolbeau_avx2_implementation = { + SODIUM_C99(.stream =) stream_ref, + SODIUM_C99(.stream_ietf =) stream_ietf_ref, + SODIUM_C99(.stream_xor_ic =) stream_ref_xor_ic, + SODIUM_C99(.stream_ietf_xor_ic =) stream_ietf_ref_xor_ic + }; + +#endif diff --git a/libs/libsodium/src/crypto_stream/chacha20/dolbeau/chacha20_dolbeau-avx2.h b/libs/libsodium/src/crypto_stream/chacha20/dolbeau/chacha20_dolbeau-avx2.h new file mode 100644 index 0000000000..45eb98d797 --- /dev/null +++ b/libs/libsodium/src/crypto_stream/chacha20/dolbeau/chacha20_dolbeau-avx2.h @@ -0,0 +1,8 @@ + +#include <stdint.h> + +#include "../stream_chacha20.h" +#include "crypto_stream_chacha20.h" + +extern struct crypto_stream_chacha20_implementation + crypto_stream_chacha20_dolbeau_avx2_implementation; diff --git a/libs/libsodium/src/crypto_stream/chacha20/dolbeau/chacha20_dolbeau-ssse3.c b/libs/libsodium/src/crypto_stream/chacha20/dolbeau/chacha20_dolbeau-ssse3.c new file mode 100644 index 0000000000..b7b9aa4ad3 --- /dev/null +++ b/libs/libsodium/src/crypto_stream/chacha20/dolbeau/chacha20_dolbeau-ssse3.c @@ -0,0 +1,174 @@ + +#include <stdint.h> +#include <stdlib.h> +#include <string.h> + +#include "core.h" +#include "crypto_stream_chacha20.h" +#include "private/common.h" +#include "private/sse2_64_32.h" +#include "utils.h" + +#if defined(HAVE_EMMINTRIN_H) && defined(HAVE_TMMINTRIN_H) + +# ifdef __GNUC__ +# pragma GCC target("sse2") +# pragma GCC target("ssse3") +# endif + +# include <emmintrin.h> +# include <tmmintrin.h> + +# include "../stream_chacha20.h" +# include "chacha20_dolbeau-ssse3.h" + +# define ROUNDS 20 + +typedef struct chacha_ctx { + uint32_t input[16]; +} chacha_ctx; + +static void +chacha_keysetup(chacha_ctx *ctx, const uint8_t *k) +{ + ctx->input[0] = 0x61707865; + ctx->input[1] = 0x3320646e; + ctx->input[2] = 0x79622d32; + ctx->input[3] = 0x6b206574; + ctx->input[4] = LOAD32_LE(k + 0); + ctx->input[5] = LOAD32_LE(k + 4); + ctx->input[6] = LOAD32_LE(k + 8); + ctx->input[7] = LOAD32_LE(k + 12); + ctx->input[8] = LOAD32_LE(k + 16); + ctx->input[9] = LOAD32_LE(k + 20); + ctx->input[10] = LOAD32_LE(k + 24); + ctx->input[11] = LOAD32_LE(k + 28); +} + +static void +chacha_ivsetup(chacha_ctx *ctx, const uint8_t *iv, const uint8_t *counter) +{ + ctx->input[12] = counter == NULL ? 0 : LOAD32_LE(counter + 0); + ctx->input[13] = counter == NULL ? 0 : LOAD32_LE(counter + 4); + ctx->input[14] = LOAD32_LE(iv + 0); + ctx->input[15] = LOAD32_LE(iv + 4); +} + +static void +chacha_ietf_ivsetup(chacha_ctx *ctx, const uint8_t *iv, const uint8_t *counter) +{ + ctx->input[12] = counter == NULL ? 0 : LOAD32_LE(counter); + ctx->input[13] = LOAD32_LE(iv + 0); + ctx->input[14] = LOAD32_LE(iv + 4); + ctx->input[15] = LOAD32_LE(iv + 8); +} + +static void +chacha20_encrypt_bytes(chacha_ctx *ctx, const uint8_t *m, uint8_t *c, + unsigned long long bytes) +{ + uint32_t * const x = &ctx->input[0]; + + if (!bytes) { + return; /* LCOV_EXCL_LINE */ + } + if (bytes > crypto_stream_chacha20_MESSAGEBYTES_MAX) { + sodium_misuse(); + } +# include "u4.h" +# include "u1.h" +# include "u0.h" +} + +static int +stream_ref(unsigned char *c, unsigned long long clen, const unsigned char *n, + const unsigned char *k) +{ + struct chacha_ctx ctx; + + if (!clen) { + return 0; + } + COMPILER_ASSERT(crypto_stream_chacha20_KEYBYTES == 256 / 8); + chacha_keysetup(&ctx, k); + chacha_ivsetup(&ctx, n, NULL); + memset(c, 0, clen); + chacha20_encrypt_bytes(&ctx, c, c, clen); + sodium_memzero(&ctx, sizeof ctx); + + return 0; +} + +static int +stream_ietf_ref(unsigned char *c, unsigned long long clen, + const unsigned char *n, const unsigned char *k) +{ + struct chacha_ctx ctx; + + if (!clen) { + return 0; + } + COMPILER_ASSERT(crypto_stream_chacha20_KEYBYTES == 256 / 8); + chacha_keysetup(&ctx, k); + chacha_ietf_ivsetup(&ctx, n, NULL); + memset(c, 0, clen); + chacha20_encrypt_bytes(&ctx, c, c, clen); + sodium_memzero(&ctx, sizeof ctx); + + return 0; +} + +static int +stream_ref_xor_ic(unsigned char *c, const unsigned char *m, + unsigned long long mlen, const unsigned char *n, uint64_t ic, + const unsigned char *k) +{ + struct chacha_ctx ctx; + uint8_t ic_bytes[8]; + uint32_t ic_high; + uint32_t ic_low; + + if (!mlen) { + return 0; + } + ic_high = (uint32_t) (ic >> 32); + ic_low = (uint32_t) ic; + STORE32_LE(&ic_bytes[0], ic_low); + STORE32_LE(&ic_bytes[4], ic_high); + chacha_keysetup(&ctx, k); + chacha_ivsetup(&ctx, n, ic_bytes); + chacha20_encrypt_bytes(&ctx, m, c, mlen); + sodium_memzero(&ctx, sizeof ctx); + + return 0; +} + +static int +stream_ietf_ref_xor_ic(unsigned char *c, const unsigned char *m, + unsigned long long mlen, const unsigned char *n, + uint32_t ic, const unsigned char *k) +{ + struct chacha_ctx ctx; + uint8_t ic_bytes[4]; + + if (!mlen) { + return 0; + } + STORE32_LE(ic_bytes, ic); + chacha_keysetup(&ctx, k); + chacha_ietf_ivsetup(&ctx, n, ic_bytes); + chacha20_encrypt_bytes(&ctx, m, c, mlen); + sodium_memzero(&ctx, sizeof ctx); + + return 0; +} + +struct crypto_stream_chacha20_implementation + crypto_stream_chacha20_dolbeau_ssse3_implementation = { + SODIUM_C99(.stream =) stream_ref, + SODIUM_C99(.stream_ietf =) stream_ietf_ref, + SODIUM_C99(.stream_xor_ic =) stream_ref_xor_ic, + SODIUM_C99(.stream_ietf_xor_ic =) stream_ietf_ref_xor_ic + }; + +#endif diff --git a/libs/libsodium/src/crypto_stream/chacha20/dolbeau/chacha20_dolbeau-ssse3.h b/libs/libsodium/src/crypto_stream/chacha20/dolbeau/chacha20_dolbeau-ssse3.h new file mode 100644 index 0000000000..d67630f6a9 --- /dev/null +++ b/libs/libsodium/src/crypto_stream/chacha20/dolbeau/chacha20_dolbeau-ssse3.h @@ -0,0 +1,8 @@ + +#include <stdint.h> + +#include "../stream_chacha20.h" +#include "crypto_stream_chacha20.h" + +extern struct crypto_stream_chacha20_implementation + crypto_stream_chacha20_dolbeau_ssse3_implementation; diff --git a/libs/libsodium/src/crypto_stream/chacha20/dolbeau/u0.h b/libs/libsodium/src/crypto_stream/chacha20/dolbeau/u0.h new file mode 100644 index 0000000000..17c3ff8e08 --- /dev/null +++ b/libs/libsodium/src/crypto_stream/chacha20/dolbeau/u0.h @@ -0,0 +1,86 @@ +if (bytes > 0) { + __m128i x_0, x_1, x_2, x_3; + __m128i t_1; + const __m128i rot16 = + _mm_set_epi8(13, 12, 15, 14, 9, 8, 11, 10, 5, 4, 7, 6, 1, 0, 3, 2); + const __m128i rot8 = + _mm_set_epi8(14, 13, 12, 15, 10, 9, 8, 11, 6, 5, 4, 7, 2, 1, 0, 3); + uint8_t partialblock[64]; + + unsigned int i; + + x_0 = _mm_loadu_si128((__m128i*) (x + 0)); + x_1 = _mm_loadu_si128((__m128i*) (x + 4)); + x_2 = _mm_loadu_si128((__m128i*) (x + 8)); + x_3 = _mm_loadu_si128((__m128i*) (x + 12)); + + for (i = 0; i < ROUNDS; i += 2) { + x_0 = _mm_add_epi32(x_0, x_1); + x_3 = _mm_xor_si128(x_3, x_0); + x_3 = _mm_shuffle_epi8(x_3, rot16); + + x_2 = _mm_add_epi32(x_2, x_3); + x_1 = _mm_xor_si128(x_1, x_2); + + t_1 = x_1; + x_1 = _mm_slli_epi32(x_1, 12); + t_1 = _mm_srli_epi32(t_1, 20); + x_1 = _mm_xor_si128(x_1, t_1); + + x_0 = _mm_add_epi32(x_0, x_1); + x_3 = _mm_xor_si128(x_3, x_0); + x_0 = _mm_shuffle_epi32(x_0, 0x93); + x_3 = _mm_shuffle_epi8(x_3, rot8); + + x_2 = _mm_add_epi32(x_2, x_3); + x_3 = _mm_shuffle_epi32(x_3, 0x4e); + x_1 = _mm_xor_si128(x_1, x_2); + x_2 = _mm_shuffle_epi32(x_2, 0x39); + + t_1 = x_1; + x_1 = _mm_slli_epi32(x_1, 7); + t_1 = _mm_srli_epi32(t_1, 25); + x_1 = _mm_xor_si128(x_1, t_1); + + x_0 = _mm_add_epi32(x_0, x_1); + x_3 = _mm_xor_si128(x_3, x_0); + x_3 = _mm_shuffle_epi8(x_3, rot16); + + x_2 = _mm_add_epi32(x_2, x_3); + x_1 = _mm_xor_si128(x_1, x_2); + + t_1 = x_1; + x_1 = _mm_slli_epi32(x_1, 12); + t_1 = _mm_srli_epi32(t_1, 20); + x_1 = _mm_xor_si128(x_1, t_1); + + x_0 = _mm_add_epi32(x_0, x_1); + x_3 = _mm_xor_si128(x_3, x_0); + x_0 = _mm_shuffle_epi32(x_0, 0x39); + x_3 = _mm_shuffle_epi8(x_3, rot8); + + x_2 = _mm_add_epi32(x_2, x_3); + x_3 = _mm_shuffle_epi32(x_3, 0x4e); + x_1 = _mm_xor_si128(x_1, x_2); + x_2 = _mm_shuffle_epi32(x_2, 0x93); + + t_1 = x_1; + x_1 = _mm_slli_epi32(x_1, 7); + t_1 = _mm_srli_epi32(t_1, 25); + x_1 = _mm_xor_si128(x_1, t_1); + } + x_0 = _mm_add_epi32(x_0, _mm_loadu_si128((__m128i*) (x + 0))); + x_1 = _mm_add_epi32(x_1, _mm_loadu_si128((__m128i*) (x + 4))); + x_2 = _mm_add_epi32(x_2, _mm_loadu_si128((__m128i*) (x + 8))); + x_3 = _mm_add_epi32(x_3, _mm_loadu_si128((__m128i*) (x + 12))); + _mm_storeu_si128((__m128i*) (partialblock + 0), x_0); + _mm_storeu_si128((__m128i*) (partialblock + 16), x_1); + _mm_storeu_si128((__m128i*) (partialblock + 32), x_2); + _mm_storeu_si128((__m128i*) (partialblock + 48), x_3); + + for (i = 0; i < bytes; i++) { + c[i] = m[i] ^ partialblock[i]; + } + + sodium_memzero(partialblock, sizeof partialblock); +} diff --git a/libs/libsodium/src/crypto_stream/chacha20/dolbeau/u1.h b/libs/libsodium/src/crypto_stream/chacha20/dolbeau/u1.h new file mode 100644 index 0000000000..867b44bcf2 --- /dev/null +++ b/libs/libsodium/src/crypto_stream/chacha20/dolbeau/u1.h @@ -0,0 +1,98 @@ +while (bytes >= 64) { + __m128i x_0, x_1, x_2, x_3; + __m128i t_1; + const __m128i rot16 = + _mm_set_epi8(13, 12, 15, 14, 9, 8, 11, 10, 5, 4, 7, 6, 1, 0, 3, 2); + const __m128i rot8 = + _mm_set_epi8(14, 13, 12, 15, 10, 9, 8, 11, 6, 5, 4, 7, 2, 1, 0, 3); + + uint32_t in12; + uint32_t in13; + int i; + + x_0 = _mm_loadu_si128((__m128i*) (x + 0)); + x_1 = _mm_loadu_si128((__m128i*) (x + 4)); + x_2 = _mm_loadu_si128((__m128i*) (x + 8)); + x_3 = _mm_loadu_si128((__m128i*) (x + 12)); + + for (i = 0; i < ROUNDS; i += 2) { + x_0 = _mm_add_epi32(x_0, x_1); + x_3 = _mm_xor_si128(x_3, x_0); + x_3 = _mm_shuffle_epi8(x_3, rot16); + + x_2 = _mm_add_epi32(x_2, x_3); + x_1 = _mm_xor_si128(x_1, x_2); + + t_1 = x_1; + x_1 = _mm_slli_epi32(x_1, 12); + t_1 = _mm_srli_epi32(t_1, 20); + x_1 = _mm_xor_si128(x_1, t_1); + + x_0 = _mm_add_epi32(x_0, x_1); + x_3 = _mm_xor_si128(x_3, x_0); + x_0 = _mm_shuffle_epi32(x_0, 0x93); + x_3 = _mm_shuffle_epi8(x_3, rot8); + + x_2 = _mm_add_epi32(x_2, x_3); + x_3 = _mm_shuffle_epi32(x_3, 0x4e); + x_1 = _mm_xor_si128(x_1, x_2); + x_2 = _mm_shuffle_epi32(x_2, 0x39); + + t_1 = x_1; + x_1 = _mm_slli_epi32(x_1, 7); + t_1 = _mm_srli_epi32(t_1, 25); + x_1 = _mm_xor_si128(x_1, t_1); + + x_0 = _mm_add_epi32(x_0, x_1); + x_3 = _mm_xor_si128(x_3, x_0); + x_3 = _mm_shuffle_epi8(x_3, rot16); + + x_2 = _mm_add_epi32(x_2, x_3); + x_1 = _mm_xor_si128(x_1, x_2); + + t_1 = x_1; + x_1 = _mm_slli_epi32(x_1, 12); + t_1 = _mm_srli_epi32(t_1, 20); + x_1 = _mm_xor_si128(x_1, t_1); + + x_0 = _mm_add_epi32(x_0, x_1); + x_3 = _mm_xor_si128(x_3, x_0); + x_0 = _mm_shuffle_epi32(x_0, 0x39); + x_3 = _mm_shuffle_epi8(x_3, rot8); + + x_2 = _mm_add_epi32(x_2, x_3); + x_3 = _mm_shuffle_epi32(x_3, 0x4e); + x_1 = _mm_xor_si128(x_1, x_2); + x_2 = _mm_shuffle_epi32(x_2, 0x93); + + t_1 = x_1; + x_1 = _mm_slli_epi32(x_1, 7); + t_1 = _mm_srli_epi32(t_1, 25); + x_1 = _mm_xor_si128(x_1, t_1); + } + x_0 = _mm_add_epi32(x_0, _mm_loadu_si128((__m128i*) (x + 0))); + x_1 = _mm_add_epi32(x_1, _mm_loadu_si128((__m128i*) (x + 4))); + x_2 = _mm_add_epi32(x_2, _mm_loadu_si128((__m128i*) (x + 8))); + x_3 = _mm_add_epi32(x_3, _mm_loadu_si128((__m128i*) (x + 12))); + x_0 = _mm_xor_si128(x_0, _mm_loadu_si128((__m128i*) (m + 0))); + x_1 = _mm_xor_si128(x_1, _mm_loadu_si128((__m128i*) (m + 16))); + x_2 = _mm_xor_si128(x_2, _mm_loadu_si128((__m128i*) (m + 32))); + x_3 = _mm_xor_si128(x_3, _mm_loadu_si128((__m128i*) (m + 48))); + _mm_storeu_si128((__m128i*) (c + 0), x_0); + _mm_storeu_si128((__m128i*) (c + 16), x_1); + _mm_storeu_si128((__m128i*) (c + 32), x_2); + _mm_storeu_si128((__m128i*) (c + 48), x_3); + + in12 = x[12]; + in13 = x[13]; + in12++; + if (in12 == 0) { + in13++; + } + x[12] = in12; + x[13] = in13; + + bytes -= 64; + c += 64; + m += 64; +} diff --git a/libs/libsodium/src/crypto_stream/chacha20/dolbeau/u4.h b/libs/libsodium/src/crypto_stream/chacha20/dolbeau/u4.h new file mode 100644 index 0000000000..3ff8342609 --- /dev/null +++ b/libs/libsodium/src/crypto_stream/chacha20/dolbeau/u4.h @@ -0,0 +1,175 @@ + +#define VEC4_ROT(A, IMM) \ + _mm_or_si128(_mm_slli_epi32(A, IMM), _mm_srli_epi32(A, (32 - IMM))) + +/* same, but replace 2 of the shift/shift/or "rotation" by byte shuffles (8 & + * 16) (better) */ +#define VEC4_QUARTERROUND_SHUFFLE(A, B, C, D) \ + x_##A = _mm_add_epi32(x_##A, x_##B); \ + t_##A = _mm_xor_si128(x_##D, x_##A); \ + x_##D = _mm_shuffle_epi8(t_##A, rot16); \ + x_##C = _mm_add_epi32(x_##C, x_##D); \ + t_##C = _mm_xor_si128(x_##B, x_##C); \ + x_##B = VEC4_ROT(t_##C, 12); \ + x_##A = _mm_add_epi32(x_##A, x_##B); \ + t_##A = _mm_xor_si128(x_##D, x_##A); \ + x_##D = _mm_shuffle_epi8(t_##A, rot8); \ + x_##C = _mm_add_epi32(x_##C, x_##D); \ + t_##C = _mm_xor_si128(x_##B, x_##C); \ + x_##B = VEC4_ROT(t_##C, 7) + +#define VEC4_QUARTERROUND(A, B, C, D) VEC4_QUARTERROUND_SHUFFLE(A, B, C, D) + +if (bytes >= 256) { + /* constant for shuffling bytes (replacing multiple-of-8 rotates) */ + __m128i rot16 = + _mm_set_epi8(13, 12, 15, 14, 9, 8, 11, 10, 5, 4, 7, 6, 1, 0, 3, 2); + __m128i rot8 = + _mm_set_epi8(14, 13, 12, 15, 10, 9, 8, 11, 6, 5, 4, 7, 2, 1, 0, 3); + + __m128i x_0 = _mm_set1_epi32(x[0]); + __m128i x_1 = _mm_set1_epi32(x[1]); + __m128i x_2 = _mm_set1_epi32(x[2]); + __m128i x_3 = _mm_set1_epi32(x[3]); + __m128i x_4 = _mm_set1_epi32(x[4]); + __m128i x_5 = _mm_set1_epi32(x[5]); + __m128i x_6 = _mm_set1_epi32(x[6]); + __m128i x_7 = _mm_set1_epi32(x[7]); + __m128i x_8 = _mm_set1_epi32(x[8]); + __m128i x_9 = _mm_set1_epi32(x[9]); + __m128i x_10 = _mm_set1_epi32(x[10]); + __m128i x_11 = _mm_set1_epi32(x[11]); + __m128i x_12; + __m128i x_13; + __m128i x_14 = _mm_set1_epi32(x[14]); + __m128i x_15 = _mm_set1_epi32(x[15]); + __m128i orig0 = x_0; + __m128i orig1 = x_1; + __m128i orig2 = x_2; + __m128i orig3 = x_3; + __m128i orig4 = x_4; + __m128i orig5 = x_5; + __m128i orig6 = x_6; + __m128i orig7 = x_7; + __m128i orig8 = x_8; + __m128i orig9 = x_9; + __m128i orig10 = x_10; + __m128i orig11 = x_11; + __m128i orig12; + __m128i orig13; + __m128i orig14 = x_14; + __m128i orig15 = x_15; + __m128i t_0, t_1, t_2, t_3, t_4, t_5, t_6, t_7, t_8, t_9, t_10, t_11, t_12, + t_13, t_14, t_15; + + uint32_t in12, in13; + int i; + + while (bytes >= 256) { + const __m128i addv12 = _mm_set_epi64x(1, 0); + const __m128i addv13 = _mm_set_epi64x(3, 2); + __m128i t12, t13; + uint64_t in1213; + + x_0 = orig0; + x_1 = orig1; + x_2 = orig2; + x_3 = orig3; + x_4 = orig4; + x_5 = orig5; + x_6 = orig6; + x_7 = orig7; + x_8 = orig8; + x_9 = orig9; + x_10 = orig10; + x_11 = orig11; + x_14 = orig14; + x_15 = orig15; + + in12 = x[12]; + in13 = x[13]; + in1213 = ((uint64_t) in12) | (((uint64_t) in13) << 32); + t12 = _mm_set1_epi64x(in1213); + t13 = _mm_set1_epi64x(in1213); + + x_12 = _mm_add_epi64(addv12, t12); + x_13 = _mm_add_epi64(addv13, t13); + + t12 = _mm_unpacklo_epi32(x_12, x_13); + t13 = _mm_unpackhi_epi32(x_12, x_13); + + x_12 = _mm_unpacklo_epi32(t12, t13); + x_13 = _mm_unpackhi_epi32(t12, t13); + + orig12 = x_12; + orig13 = x_13; + + in1213 += 4; + + x[12] = in1213 & 0xFFFFFFFF; + x[13] = (in1213 >> 32) & 0xFFFFFFFF; + + for (i = 0; i < ROUNDS; i += 2) { + VEC4_QUARTERROUND(0, 4, 8, 12); + VEC4_QUARTERROUND(1, 5, 9, 13); + VEC4_QUARTERROUND(2, 6, 10, 14); + VEC4_QUARTERROUND(3, 7, 11, 15); + VEC4_QUARTERROUND(0, 5, 10, 15); + VEC4_QUARTERROUND(1, 6, 11, 12); + VEC4_QUARTERROUND(2, 7, 8, 13); + VEC4_QUARTERROUND(3, 4, 9, 14); + } + +#define ONEQUAD_TRANSPOSE(A, B, C, D) \ + { \ + __m128i t0, t1, t2, t3; \ + \ + x_##A = _mm_add_epi32(x_##A, orig##A); \ + x_##B = _mm_add_epi32(x_##B, orig##B); \ + x_##C = _mm_add_epi32(x_##C, orig##C); \ + x_##D = _mm_add_epi32(x_##D, orig##D); \ + t_##A = _mm_unpacklo_epi32(x_##A, x_##B); \ + t_##B = _mm_unpacklo_epi32(x_##C, x_##D); \ + t_##C = _mm_unpackhi_epi32(x_##A, x_##B); \ + t_##D = _mm_unpackhi_epi32(x_##C, x_##D); \ + x_##A = _mm_unpacklo_epi64(t_##A, t_##B); \ + x_##B = _mm_unpackhi_epi64(t_##A, t_##B); \ + x_##C = _mm_unpacklo_epi64(t_##C, t_##D); \ + x_##D = _mm_unpackhi_epi64(t_##C, t_##D); \ + \ + t0 = _mm_xor_si128(x_##A, _mm_loadu_si128((__m128i*) (m + 0))); \ + _mm_storeu_si128((__m128i*) (c + 0), t0); \ + t1 = _mm_xor_si128(x_##B, _mm_loadu_si128((__m128i*) (m + 64))); \ + _mm_storeu_si128((__m128i*) (c + 64), t1); \ + t2 = _mm_xor_si128(x_##C, _mm_loadu_si128((__m128i*) (m + 128))); \ + _mm_storeu_si128((__m128i*) (c + 128), t2); \ + t3 = _mm_xor_si128(x_##D, _mm_loadu_si128((__m128i*) (m + 192))); \ + _mm_storeu_si128((__m128i*) (c + 192), t3); \ + } + +#define ONEQUAD(A, B, C, D) ONEQUAD_TRANSPOSE(A, B, C, D) + + ONEQUAD(0, 1, 2, 3); + m += 16; + c += 16; + ONEQUAD(4, 5, 6, 7); + m += 16; + c += 16; + ONEQUAD(8, 9, 10, 11); + m += 16; + c += 16; + ONEQUAD(12, 13, 14, 15); + m -= 48; + c -= 48; + +#undef ONEQUAD +#undef ONEQUAD_TRANSPOSE + + bytes -= 256; + c += 256; + m += 256; + } +} +#undef VEC4_ROT +#undef VEC4_QUARTERROUND +#undef VEC4_QUARTERROUND_SHUFFLE diff --git a/libs/libsodium/src/crypto_stream/chacha20/dolbeau/u8.h b/libs/libsodium/src/crypto_stream/chacha20/dolbeau/u8.h new file mode 100644 index 0000000000..22bf9fcfa1 --- /dev/null +++ b/libs/libsodium/src/crypto_stream/chacha20/dolbeau/u8.h @@ -0,0 +1,357 @@ + +#define VEC8_ROT(A, IMM) \ + _mm256_or_si256(_mm256_slli_epi32(A, IMM), _mm256_srli_epi32(A, (32 - IMM))) + +/* implements a vector quarter round by-the-book (naive!) */ +#define VEC8_QUARTERROUND_NAIVE(A, B, C, D) \ + x_##A = _mm256_add_epi32(x_##A, x_##B); \ + t_##A = _mm256_xor_si256(x_##D, x_##A); \ + x_##D = VEC8_ROT(t_##A, 16); \ + x_##C = _mm256_add_epi32(x_##C, x_##D); \ + t_##C = _mm256_xor_si256(x_##B, x_##C); \ + x_##B = VEC8_ROT(t_##C, 12); \ + x_##A = _mm256_add_epi32(x_##A, x_##B); \ + t_##A = _mm256_xor_si256(x_##D, x_##A); \ + x_##D = VEC8_ROT(t_##A, 8); \ + x_##C = _mm256_add_epi32(x_##C, x_##D); \ + t_##C = _mm256_xor_si256(x_##B, x_##C); \ + x_##B = VEC8_ROT(t_##C, 7) + +/* same, but replace 2 of the shift/shift/or "rotation" by byte shuffles (8 & + * 16) (better) */ +#define VEC8_QUARTERROUND_SHUFFLE(A, B, C, D) \ + x_##A = _mm256_add_epi32(x_##A, x_##B); \ + t_##A = _mm256_xor_si256(x_##D, x_##A); \ + x_##D = _mm256_shuffle_epi8(t_##A, rot16); \ + x_##C = _mm256_add_epi32(x_##C, x_##D); \ + t_##C = _mm256_xor_si256(x_##B, x_##C); \ + x_##B = VEC8_ROT(t_##C, 12); \ + x_##A = _mm256_add_epi32(x_##A, x_##B); \ + t_##A = _mm256_xor_si256(x_##D, x_##A); \ + x_##D = _mm256_shuffle_epi8(t_##A, rot8); \ + x_##C = _mm256_add_epi32(x_##C, x_##D); \ + t_##C = _mm256_xor_si256(x_##B, x_##C); \ + x_##B = VEC8_ROT(t_##C, 7) + +/* same, but replace 2 of the shift/shift/or "rotation" by byte & word shuffles + * (8 & 16) (not as good as previous) */ +#define VEC8_QUARTERROUND_SHUFFLE2(A, B, C, D) \ + x_##A = _mm256_add_epi32(x_##A, x_##B); \ + t_##A = _mm256_xor_si256(x_##D, x_##A); \ + x_##D = _mm256_shufflehi_epi16(_mm256_shufflelo_epi16(t_##A, 0xb1), 0xb1); \ + x_##C = _mm256_add_epi32(x_##C, x_##D); \ + t_##C = _mm256_xor_si256(x_##B, x_##C); \ + x_##B = VEC8_ROT(t_##C, 12); \ + x_##A = _mm256_add_epi32(x_##A, x_##B); \ + t_##A = _mm256_xor_si256(x_##D, x_##A); \ + x_##D = _mm256_shuffle_epi8(t_##A, rot8); \ + x_##C = _mm256_add_epi32(x_##C, x_##D); \ + t_##C = _mm256_xor_si256(x_##B, x_##C); \ + x_##B = VEC8_ROT(t_##C, 7) + +#define VEC8_QUARTERROUND(A, B, C, D) VEC8_QUARTERROUND_SHUFFLE(A, B, C, D) + +#define VEC8_LINE1(A, B, C, D) \ + x_##A = _mm256_add_epi32(x_##A, x_##B); \ + x_##D = _mm256_shuffle_epi8(_mm256_xor_si256(x_##D, x_##A), rot16) +#define VEC8_LINE2(A, B, C, D) \ + x_##C = _mm256_add_epi32(x_##C, x_##D); \ + x_##B = VEC8_ROT(_mm256_xor_si256(x_##B, x_##C), 12) +#define VEC8_LINE3(A, B, C, D) \ + x_##A = _mm256_add_epi32(x_##A, x_##B); \ + x_##D = _mm256_shuffle_epi8(_mm256_xor_si256(x_##D, x_##A), rot8) +#define VEC8_LINE4(A, B, C, D) \ + x_##C = _mm256_add_epi32(x_##C, x_##D); \ + x_##B = VEC8_ROT(_mm256_xor_si256(x_##B, x_##C), 7) + +#define VEC8_ROUND_SEQ(A1, B1, C1, D1, A2, B2, C2, D2, A3, B3, C3, D3, A4, B4, \ + C4, D4) \ + VEC8_LINE1(A1, B1, C1, D1); \ + VEC8_LINE1(A2, B2, C2, D2); \ + VEC8_LINE1(A3, B3, C3, D3); \ + VEC8_LINE1(A4, B4, C4, D4); \ + VEC8_LINE2(A1, B1, C1, D1); \ + VEC8_LINE2(A2, B2, C2, D2); \ + VEC8_LINE2(A3, B3, C3, D3); \ + VEC8_LINE2(A4, B4, C4, D4); \ + VEC8_LINE3(A1, B1, C1, D1); \ + VEC8_LINE3(A2, B2, C2, D2); \ + VEC8_LINE3(A3, B3, C3, D3); \ + VEC8_LINE3(A4, B4, C4, D4); \ + VEC8_LINE4(A1, B1, C1, D1); \ + VEC8_LINE4(A2, B2, C2, D2); \ + VEC8_LINE4(A3, B3, C3, D3); \ + VEC8_LINE4(A4, B4, C4, D4) + +#define VEC8_ROUND_HALF(A1, B1, C1, D1, A2, B2, C2, D2, A3, B3, C3, D3, A4, \ + B4, C4, D4) \ + VEC8_LINE1(A1, B1, C1, D1); \ + VEC8_LINE1(A2, B2, C2, D2); \ + VEC8_LINE2(A1, B1, C1, D1); \ + VEC8_LINE2(A2, B2, C2, D2); \ + VEC8_LINE3(A1, B1, C1, D1); \ + VEC8_LINE3(A2, B2, C2, D2); \ + VEC8_LINE4(A1, B1, C1, D1); \ + VEC8_LINE4(A2, B2, C2, D2); \ + VEC8_LINE1(A3, B3, C3, D3); \ + VEC8_LINE1(A4, B4, C4, D4); \ + VEC8_LINE2(A3, B3, C3, D3); \ + VEC8_LINE2(A4, B4, C4, D4); \ + VEC8_LINE3(A3, B3, C3, D3); \ + VEC8_LINE3(A4, B4, C4, D4); \ + VEC8_LINE4(A3, B3, C3, D3); \ + VEC8_LINE4(A4, B4, C4, D4) + +#define VEC8_ROUND_HALFANDHALF(A1, B1, C1, D1, A2, B2, C2, D2, A3, B3, C3, D3, \ + A4, B4, C4, D4) \ + VEC8_LINE1(A1, B1, C1, D1); \ + VEC8_LINE1(A2, B2, C2, D2); \ + VEC8_LINE2(A1, B1, C1, D1); \ + VEC8_LINE2(A2, B2, C2, D2); \ + VEC8_LINE1(A3, B3, C3, D3); \ + VEC8_LINE1(A4, B4, C4, D4); \ + VEC8_LINE2(A3, B3, C3, D3); \ + VEC8_LINE2(A4, B4, C4, D4); \ + VEC8_LINE3(A1, B1, C1, D1); \ + VEC8_LINE3(A2, B2, C2, D2); \ + VEC8_LINE4(A1, B1, C1, D1); \ + VEC8_LINE4(A2, B2, C2, D2); \ + VEC8_LINE3(A3, B3, C3, D3); \ + VEC8_LINE3(A4, B4, C4, D4); \ + VEC8_LINE4(A3, B3, C3, D3); \ + VEC8_LINE4(A4, B4, C4, D4) + +#define VEC8_ROUND(A1, B1, C1, D1, A2, B2, C2, D2, A3, B3, C3, D3, A4, B4, C4, \ + D4) \ + VEC8_ROUND_SEQ(A1, B1, C1, D1, A2, B2, C2, D2, A3, B3, C3, D3, A4, B4, C4, \ + D4) + +if (bytes >= 512) { + /* constant for shuffling bytes (replacing multiple-of-8 rotates) */ + __m256i rot16 = + _mm256_set_epi8(13, 12, 15, 14, 9, 8, 11, 10, 5, 4, 7, 6, 1, 0, 3, 2, + 13, 12, 15, 14, 9, 8, 11, 10, 5, 4, 7, 6, 1, 0, 3, 2); + __m256i rot8 = + _mm256_set_epi8(14, 13, 12, 15, 10, 9, 8, 11, 6, 5, 4, 7, 2, 1, 0, 3, + 14, 13, 12, 15, 10, 9, 8, 11, 6, 5, 4, 7, 2, 1, 0, 3); + uint32_t in12, in13; + + /* the naive way seems as fast (if not a bit faster) than the vector way */ + __m256i x_0 = _mm256_set1_epi32(x[0]); + __m256i x_1 = _mm256_set1_epi32(x[1]); + __m256i x_2 = _mm256_set1_epi32(x[2]); + __m256i x_3 = _mm256_set1_epi32(x[3]); + __m256i x_4 = _mm256_set1_epi32(x[4]); + __m256i x_5 = _mm256_set1_epi32(x[5]); + __m256i x_6 = _mm256_set1_epi32(x[6]); + __m256i x_7 = _mm256_set1_epi32(x[7]); + __m256i x_8 = _mm256_set1_epi32(x[8]); + __m256i x_9 = _mm256_set1_epi32(x[9]); + __m256i x_10 = _mm256_set1_epi32(x[10]); + __m256i x_11 = _mm256_set1_epi32(x[11]); + __m256i x_12; + __m256i x_13; + __m256i x_14 = _mm256_set1_epi32(x[14]); + __m256i x_15 = _mm256_set1_epi32(x[15]); + + __m256i orig0 = x_0; + __m256i orig1 = x_1; + __m256i orig2 = x_2; + __m256i orig3 = x_3; + __m256i orig4 = x_4; + __m256i orig5 = x_5; + __m256i orig6 = x_6; + __m256i orig7 = x_7; + __m256i orig8 = x_8; + __m256i orig9 = x_9; + __m256i orig10 = x_10; + __m256i orig11 = x_11; + __m256i orig12; + __m256i orig13; + __m256i orig14 = x_14; + __m256i orig15 = x_15; + __m256i t_0, t_1, t_2, t_3, t_4, t_5, t_6, t_7, t_8, t_9, t_10, t_11, t_12, + t_13, t_14, t_15; + + while (bytes >= 512) { + const __m256i addv12 = _mm256_set_epi64x(3, 2, 1, 0); + const __m256i addv13 = _mm256_set_epi64x(7, 6, 5, 4); + const __m256i permute = _mm256_set_epi32(7, 6, 3, 2, 5, 4, 1, 0); + __m256i t12, t13; + + uint64_t in1213; + int i; + + x_0 = orig0; + x_1 = orig1; + x_2 = orig2; + x_3 = orig3; + x_4 = orig4; + x_5 = orig5; + x_6 = orig6; + x_7 = orig7; + x_8 = orig8; + x_9 = orig9; + x_10 = orig10; + x_11 = orig11; + x_14 = orig14; + x_15 = orig15; + + in12 = x[12]; + in13 = x[13]; + in1213 = ((uint64_t) in12) | (((uint64_t) in13) << 32); + x_12 = x_13 = _mm256_broadcastq_epi64(_mm_cvtsi64_si128(in1213)); + + t12 = _mm256_add_epi64(addv12, x_12); + t13 = _mm256_add_epi64(addv13, x_13); + + x_12 = _mm256_unpacklo_epi32(t12, t13); + x_13 = _mm256_unpackhi_epi32(t12, t13); + + t12 = _mm256_unpacklo_epi32(x_12, x_13); + t13 = _mm256_unpackhi_epi32(x_12, x_13); + + /* required because unpack* are intra-lane */ + x_12 = _mm256_permutevar8x32_epi32(t12, permute); + x_13 = _mm256_permutevar8x32_epi32(t13, permute); + + orig12 = x_12; + orig13 = x_13; + + in1213 += 8; + + x[12] = in1213 & 0xFFFFFFFF; + x[13] = (in1213 >> 32) & 0xFFFFFFFF; + + for (i = 0; i < ROUNDS; i += 2) { + VEC8_ROUND(0, 4, 8, 12, 1, 5, 9, 13, 2, 6, 10, 14, 3, 7, 11, 15); + VEC8_ROUND(0, 5, 10, 15, 1, 6, 11, 12, 2, 7, 8, 13, 3, 4, 9, 14); + } + +#define ONEQUAD_TRANSPOSE(A, B, C, D) \ + { \ + __m128i t0, t1, t2, t3; \ + x_##A = _mm256_add_epi32(x_##A, orig##A); \ + x_##B = _mm256_add_epi32(x_##B, orig##B); \ + x_##C = _mm256_add_epi32(x_##C, orig##C); \ + x_##D = _mm256_add_epi32(x_##D, orig##D); \ + t_##A = _mm256_unpacklo_epi32(x_##A, x_##B); \ + t_##B = _mm256_unpacklo_epi32(x_##C, x_##D); \ + t_##C = _mm256_unpackhi_epi32(x_##A, x_##B); \ + t_##D = _mm256_unpackhi_epi32(x_##C, x_##D); \ + x_##A = _mm256_unpacklo_epi64(t_##A, t_##B); \ + x_##B = _mm256_unpackhi_epi64(t_##A, t_##B); \ + x_##C = _mm256_unpacklo_epi64(t_##C, t_##D); \ + x_##D = _mm256_unpackhi_epi64(t_##C, t_##D); \ + t0 = _mm_xor_si128(_mm256_extracti128_si256(x_##A, 0), \ + _mm_loadu_si128((__m128i*) (m + 0))); \ + _mm_storeu_si128((__m128i*) (c + 0), t0); \ + t1 = _mm_xor_si128(_mm256_extracti128_si256(x_##B, 0), \ + _mm_loadu_si128((__m128i*) (m + 64))); \ + _mm_storeu_si128((__m128i*) (c + 64), t1); \ + t2 = _mm_xor_si128(_mm256_extracti128_si256(x_##C, 0), \ + _mm_loadu_si128((__m128i*) (m + 128))); \ + _mm_storeu_si128((__m128i*) (c + 128), t2); \ + t3 = _mm_xor_si128(_mm256_extracti128_si256(x_##D, 0), \ + _mm_loadu_si128((__m128i*) (m + 192))); \ + _mm_storeu_si128((__m128i*) (c + 192), t3); \ + t0 = _mm_xor_si128(_mm256_extracti128_si256(x_##A, 1), \ + _mm_loadu_si128((__m128i*) (m + 256))); \ + _mm_storeu_si128((__m128i*) (c + 256), t0); \ + t1 = _mm_xor_si128(_mm256_extracti128_si256(x_##B, 1), \ + _mm_loadu_si128((__m128i*) (m + 320))); \ + _mm_storeu_si128((__m128i*) (c + 320), t1); \ + t2 = _mm_xor_si128(_mm256_extracti128_si256(x_##C, 1), \ + _mm_loadu_si128((__m128i*) (m + 384))); \ + _mm_storeu_si128((__m128i*) (c + 384), t2); \ + t3 = _mm_xor_si128(_mm256_extracti128_si256(x_##D, 1), \ + _mm_loadu_si128((__m128i*) (m + 448))); \ + _mm_storeu_si128((__m128i*) (c + 448), t3); \ + } + +#define ONEQUAD(A, B, C, D) ONEQUAD_TRANSPOSE(A, B, C, D) + +#define ONEQUAD_UNPCK(A, B, C, D) \ + { \ + x_##A = _mm256_add_epi32(x_##A, orig##A); \ + x_##B = _mm256_add_epi32(x_##B, orig##B); \ + x_##C = _mm256_add_epi32(x_##C, orig##C); \ + x_##D = _mm256_add_epi32(x_##D, orig##D); \ + t_##A = _mm256_unpacklo_epi32(x_##A, x_##B); \ + t_##B = _mm256_unpacklo_epi32(x_##C, x_##D); \ + t_##C = _mm256_unpackhi_epi32(x_##A, x_##B); \ + t_##D = _mm256_unpackhi_epi32(x_##C, x_##D); \ + x_##A = _mm256_unpacklo_epi64(t_##A, t_##B); \ + x_##B = _mm256_unpackhi_epi64(t_##A, t_##B); \ + x_##C = _mm256_unpacklo_epi64(t_##C, t_##D); \ + x_##D = _mm256_unpackhi_epi64(t_##C, t_##D); \ + } + +#define ONEOCTO(A, B, C, D, A2, B2, C2, D2) \ + { \ + ONEQUAD_UNPCK(A, B, C, D); \ + ONEQUAD_UNPCK(A2, B2, C2, D2); \ + t_##A = _mm256_permute2x128_si256(x_##A, x_##A2, 0x20); \ + t_##A2 = _mm256_permute2x128_si256(x_##A, x_##A2, 0x31); \ + t_##B = _mm256_permute2x128_si256(x_##B, x_##B2, 0x20); \ + t_##B2 = _mm256_permute2x128_si256(x_##B, x_##B2, 0x31); \ + t_##C = _mm256_permute2x128_si256(x_##C, x_##C2, 0x20); \ + t_##C2 = _mm256_permute2x128_si256(x_##C, x_##C2, 0x31); \ + t_##D = _mm256_permute2x128_si256(x_##D, x_##D2, 0x20); \ + t_##D2 = _mm256_permute2x128_si256(x_##D, x_##D2, 0x31); \ + t_##A = \ + _mm256_xor_si256(t_##A, _mm256_loadu_si256((__m256i*) (m + 0))); \ + t_##B = \ + _mm256_xor_si256(t_##B, _mm256_loadu_si256((__m256i*) (m + 64))); \ + t_##C = \ + _mm256_xor_si256(t_##C, _mm256_loadu_si256((__m256i*) (m + 128))); \ + t_##D = \ + _mm256_xor_si256(t_##D, _mm256_loadu_si256((__m256i*) (m + 192))); \ + t_##A2 = _mm256_xor_si256(t_##A2, \ + _mm256_loadu_si256((__m256i*) (m + 256))); \ + t_##B2 = _mm256_xor_si256(t_##B2, \ + _mm256_loadu_si256((__m256i*) (m + 320))); \ + t_##C2 = _mm256_xor_si256(t_##C2, \ + _mm256_loadu_si256((__m256i*) (m + 384))); \ + t_##D2 = _mm256_xor_si256(t_##D2, \ + _mm256_loadu_si256((__m256i*) (m + 448))); \ + _mm256_storeu_si256((__m256i*) (c + 0), t_##A); \ + _mm256_storeu_si256((__m256i*) (c + 64), t_##B); \ + _mm256_storeu_si256((__m256i*) (c + 128), t_##C); \ + _mm256_storeu_si256((__m256i*) (c + 192), t_##D); \ + _mm256_storeu_si256((__m256i*) (c + 256), t_##A2); \ + _mm256_storeu_si256((__m256i*) (c + 320), t_##B2); \ + _mm256_storeu_si256((__m256i*) (c + 384), t_##C2); \ + _mm256_storeu_si256((__m256i*) (c + 448), t_##D2); \ + } + + ONEOCTO(0, 1, 2, 3, 4, 5, 6, 7); + m += 32; + c += 32; + ONEOCTO(8, 9, 10, 11, 12, 13, 14, 15); + m -= 32; + c -= 32; + +#undef ONEQUAD +#undef ONEQUAD_TRANSPOSE +#undef ONEQUAD_UNPCK +#undef ONEOCTO + + bytes -= 512; + c += 512; + m += 512; + } +} +#undef VEC8_ROT +#undef VEC8_QUARTERROUND +#undef VEC8_QUARTERROUND_NAIVE +#undef VEC8_QUARTERROUND_SHUFFLE +#undef VEC8_QUARTERROUND_SHUFFLE2 +#undef VEC8_LINE1 +#undef VEC8_LINE2 +#undef VEC8_LINE3 +#undef VEC8_LINE4 +#undef VEC8_ROUND +#undef VEC8_ROUND_SEQ +#undef VEC8_ROUND_HALF +#undef VEC8_ROUND_HALFANDHALF diff --git a/libs/libsodium/src/crypto_stream/chacha20/ref/chacha20_ref.c b/libs/libsodium/src/crypto_stream/chacha20/ref/chacha20_ref.c new file mode 100644 index 0000000000..f88a99dbdf --- /dev/null +++ b/libs/libsodium/src/crypto_stream/chacha20/ref/chacha20_ref.c @@ -0,0 +1,315 @@ + +/* + chacha-merged.c version 20080118 + D. J. Bernstein + Public domain. + */ + +#include <stdint.h> +#include <stdlib.h> +#include <string.h> + +#include "core.h" +#include "crypto_stream_chacha20.h" +#include "private/common.h" +#include "utils.h" + +#include "../stream_chacha20.h" +#include "chacha20_ref.h" + +struct chacha_ctx { + uint32_t input[16]; +}; + +typedef struct chacha_ctx chacha_ctx; + +#define U32C(v) (v##U) + +#define U32V(v) ((uint32_t)(v) &U32C(0xFFFFFFFF)) + +#define ROTATE(v, c) (ROTL32(v, c)) +#define XOR(v, w) ((v) ^ (w)) +#define PLUS(v, w) (U32V((v) + (w))) +#define PLUSONE(v) (PLUS((v), 1)) + +#define QUARTERROUND(a, b, c, d) \ + a = PLUS(a, b); \ + d = ROTATE(XOR(d, a), 16); \ + c = PLUS(c, d); \ + b = ROTATE(XOR(b, c), 12); \ + a = PLUS(a, b); \ + d = ROTATE(XOR(d, a), 8); \ + c = PLUS(c, d); \ + b = ROTATE(XOR(b, c), 7); + +static void +chacha_keysetup(chacha_ctx *ctx, const uint8_t *k) +{ + ctx->input[0] = U32C(0x61707865); + ctx->input[1] = U32C(0x3320646e); + ctx->input[2] = U32C(0x79622d32); + ctx->input[3] = U32C(0x6b206574); + ctx->input[4] = LOAD32_LE(k + 0); + ctx->input[5] = LOAD32_LE(k + 4); + ctx->input[6] = LOAD32_LE(k + 8); + ctx->input[7] = LOAD32_LE(k + 12); + ctx->input[8] = LOAD32_LE(k + 16); + ctx->input[9] = LOAD32_LE(k + 20); + ctx->input[10] = LOAD32_LE(k + 24); + ctx->input[11] = LOAD32_LE(k + 28); +} + +static void +chacha_ivsetup(chacha_ctx *ctx, const uint8_t *iv, const uint8_t *counter) +{ + ctx->input[12] = counter == NULL ? 0 : LOAD32_LE(counter + 0); + ctx->input[13] = counter == NULL ? 0 : LOAD32_LE(counter + 4); + ctx->input[14] = LOAD32_LE(iv + 0); + ctx->input[15] = LOAD32_LE(iv + 4); +} + +static void +chacha_ietf_ivsetup(chacha_ctx *ctx, const uint8_t *iv, const uint8_t *counter) +{ + ctx->input[12] = counter == NULL ? 0 : LOAD32_LE(counter); + ctx->input[13] = LOAD32_LE(iv + 0); + ctx->input[14] = LOAD32_LE(iv + 4); + ctx->input[15] = LOAD32_LE(iv + 8); +} + +static void +chacha20_encrypt_bytes(chacha_ctx *ctx, const uint8_t *m, uint8_t *c, + unsigned long long bytes) +{ + uint32_t x0, x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, + x15; + uint32_t j0, j1, j2, j3, j4, j5, j6, j7, j8, j9, j10, j11, j12, j13, j14, + j15; + uint8_t *ctarget = NULL; + uint8_t tmp[64]; + unsigned int i; + + if (!bytes) { + return; /* LCOV_EXCL_LINE */ + } + if (bytes > crypto_stream_chacha20_MESSAGEBYTES_MAX) { + sodium_misuse(); + } + j0 = ctx->input[0]; + j1 = ctx->input[1]; + j2 = ctx->input[2]; + j3 = ctx->input[3]; + j4 = ctx->input[4]; + j5 = ctx->input[5]; + j6 = ctx->input[6]; + j7 = ctx->input[7]; + j8 = ctx->input[8]; + j9 = ctx->input[9]; + j10 = ctx->input[10]; + j11 = ctx->input[11]; + j12 = ctx->input[12]; + j13 = ctx->input[13]; + j14 = ctx->input[14]; + j15 = ctx->input[15]; + + for (;;) { + if (bytes < 64) { + memset(tmp, 0, 64); + for (i = 0; i < bytes; ++i) { + tmp[i] = m[i]; + } + m = tmp; + ctarget = c; + c = tmp; + } + x0 = j0; + x1 = j1; + x2 = j2; + x3 = j3; + x4 = j4; + x5 = j5; + x6 = j6; + x7 = j7; + x8 = j8; + x9 = j9; + x10 = j10; + x11 = j11; + x12 = j12; + x13 = j13; + x14 = j14; + x15 = j15; + for (i = 20; i > 0; i -= 2) { + QUARTERROUND(x0, x4, x8, x12) + QUARTERROUND(x1, x5, x9, x13) + QUARTERROUND(x2, x6, x10, x14) + QUARTERROUND(x3, x7, x11, x15) + QUARTERROUND(x0, x5, x10, x15) + QUARTERROUND(x1, x6, x11, x12) + QUARTERROUND(x2, x7, x8, x13) + QUARTERROUND(x3, x4, x9, x14) + } + x0 = PLUS(x0, j0); + x1 = PLUS(x1, j1); + x2 = PLUS(x2, j2); + x3 = PLUS(x3, j3); + x4 = PLUS(x4, j4); + x5 = PLUS(x5, j5); + x6 = PLUS(x6, j6); + x7 = PLUS(x7, j7); + x8 = PLUS(x8, j8); + x9 = PLUS(x9, j9); + x10 = PLUS(x10, j10); + x11 = PLUS(x11, j11); + x12 = PLUS(x12, j12); + x13 = PLUS(x13, j13); + x14 = PLUS(x14, j14); + x15 = PLUS(x15, j15); + + x0 = XOR(x0, LOAD32_LE(m + 0)); + x1 = XOR(x1, LOAD32_LE(m + 4)); + x2 = XOR(x2, LOAD32_LE(m + 8)); + x3 = XOR(x3, LOAD32_LE(m + 12)); + x4 = XOR(x4, LOAD32_LE(m + 16)); + x5 = XOR(x5, LOAD32_LE(m + 20)); + x6 = XOR(x6, LOAD32_LE(m + 24)); + x7 = XOR(x7, LOAD32_LE(m + 28)); + x8 = XOR(x8, LOAD32_LE(m + 32)); + x9 = XOR(x9, LOAD32_LE(m + 36)); + x10 = XOR(x10, LOAD32_LE(m + 40)); + x11 = XOR(x11, LOAD32_LE(m + 44)); + x12 = XOR(x12, LOAD32_LE(m + 48)); + x13 = XOR(x13, LOAD32_LE(m + 52)); + x14 = XOR(x14, LOAD32_LE(m + 56)); + x15 = XOR(x15, LOAD32_LE(m + 60)); + + j12 = PLUSONE(j12); + /* LCOV_EXCL_START */ + if (!j12) { + j13 = PLUSONE(j13); + } + /* LCOV_EXCL_STOP */ + + STORE32_LE(c + 0, x0); + STORE32_LE(c + 4, x1); + STORE32_LE(c + 8, x2); + STORE32_LE(c + 12, x3); + STORE32_LE(c + 16, x4); + STORE32_LE(c + 20, x5); + STORE32_LE(c + 24, x6); + STORE32_LE(c + 28, x7); + STORE32_LE(c + 32, x8); + STORE32_LE(c + 36, x9); + STORE32_LE(c + 40, x10); + STORE32_LE(c + 44, x11); + STORE32_LE(c + 48, x12); + STORE32_LE(c + 52, x13); + STORE32_LE(c + 56, x14); + STORE32_LE(c + 60, x15); + + if (bytes <= 64) { + if (bytes < 64) { + for (i = 0; i < (unsigned int) bytes; ++i) { + ctarget[i] = c[i]; /* ctarget cannot be NULL */ + } + } + ctx->input[12] = j12; + ctx->input[13] = j13; + + return; + } + bytes -= 64; + c += 64; + m += 64; + } +} + +static int +stream_ref(unsigned char *c, unsigned long long clen, const unsigned char *n, + const unsigned char *k) +{ + struct chacha_ctx ctx; + + if (!clen) { + return 0; + } + COMPILER_ASSERT(crypto_stream_chacha20_KEYBYTES == 256 / 8); + chacha_keysetup(&ctx, k); + chacha_ivsetup(&ctx, n, NULL); + memset(c, 0, clen); + chacha20_encrypt_bytes(&ctx, c, c, clen); + sodium_memzero(&ctx, sizeof ctx); + + return 0; +} + +static int +stream_ietf_ref(unsigned char *c, unsigned long long clen, + const unsigned char *n, const unsigned char *k) +{ + struct chacha_ctx ctx; + + if (!clen) { + return 0; + } + COMPILER_ASSERT(crypto_stream_chacha20_KEYBYTES == 256 / 8); + chacha_keysetup(&ctx, k); + chacha_ietf_ivsetup(&ctx, n, NULL); + memset(c, 0, clen); + chacha20_encrypt_bytes(&ctx, c, c, clen); + sodium_memzero(&ctx, sizeof ctx); + + return 0; +} + +static int +stream_ref_xor_ic(unsigned char *c, const unsigned char *m, + unsigned long long mlen, const unsigned char *n, uint64_t ic, + const unsigned char *k) +{ + struct chacha_ctx ctx; + uint8_t ic_bytes[8]; + uint32_t ic_high; + uint32_t ic_low; + + if (!mlen) { + return 0; + } + ic_high = U32V(ic >> 32); + ic_low = U32V(ic); + STORE32_LE(&ic_bytes[0], ic_low); + STORE32_LE(&ic_bytes[4], ic_high); + chacha_keysetup(&ctx, k); + chacha_ivsetup(&ctx, n, ic_bytes); + chacha20_encrypt_bytes(&ctx, m, c, mlen); + sodium_memzero(&ctx, sizeof ctx); + + return 0; +} + +static int +stream_ietf_ref_xor_ic(unsigned char *c, const unsigned char *m, + unsigned long long mlen, const unsigned char *n, + uint32_t ic, const unsigned char *k) +{ + struct chacha_ctx ctx; + uint8_t ic_bytes[4]; + + if (!mlen) { + return 0; + } + STORE32_LE(ic_bytes, ic); + chacha_keysetup(&ctx, k); + chacha_ietf_ivsetup(&ctx, n, ic_bytes); + chacha20_encrypt_bytes(&ctx, m, c, mlen); + sodium_memzero(&ctx, sizeof ctx); + + return 0; +} + +struct crypto_stream_chacha20_implementation + crypto_stream_chacha20_ref_implementation = { + SODIUM_C99(.stream =) stream_ref, + SODIUM_C99(.stream_ietf =) stream_ietf_ref, + SODIUM_C99(.stream_xor_ic =) stream_ref_xor_ic, + SODIUM_C99(.stream_ietf_xor_ic =) stream_ietf_ref_xor_ic + }; diff --git a/libs/libsodium/src/crypto_stream/chacha20/ref/chacha20_ref.h b/libs/libsodium/src/crypto_stream/chacha20/ref/chacha20_ref.h new file mode 100644 index 0000000000..6ac4807554 --- /dev/null +++ b/libs/libsodium/src/crypto_stream/chacha20/ref/chacha20_ref.h @@ -0,0 +1,8 @@ + +#include <stdint.h> + +#include "../stream_chacha20.h" +#include "crypto_stream_chacha20.h" + +extern struct crypto_stream_chacha20_implementation + crypto_stream_chacha20_ref_implementation; diff --git a/libs/libsodium/src/crypto_stream/chacha20/stream_chacha20.c b/libs/libsodium/src/crypto_stream/chacha20/stream_chacha20.c new file mode 100644 index 0000000000..3b0895112c --- /dev/null +++ b/libs/libsodium/src/crypto_stream/chacha20/stream_chacha20.c @@ -0,0 +1,130 @@ +#include "crypto_stream_chacha20.h" +#include "private/common.h" +#include "private/implementations.h" +#include "randombytes.h" +#include "runtime.h" +#include "stream_chacha20.h" + +#include "ref/chacha20_ref.h" +#if defined(HAVE_AVX2INTRIN_H) && defined(HAVE_EMMINTRIN_H) && \ + defined(HAVE_TMMINTRIN_H) && defined(HAVE_SMMINTRIN_H) +# include "dolbeau/chacha20_dolbeau-avx2.h" +#endif +#if defined(HAVE_EMMINTRIN_H) && defined(HAVE_TMMINTRIN_H) +# include "dolbeau/chacha20_dolbeau-ssse3.h" +#endif + +static const crypto_stream_chacha20_implementation *implementation = + &crypto_stream_chacha20_ref_implementation; + +size_t +crypto_stream_chacha20_keybytes(void) { + return crypto_stream_chacha20_KEYBYTES; +} + +size_t +crypto_stream_chacha20_noncebytes(void) { + return crypto_stream_chacha20_NONCEBYTES; +} + +size_t +crypto_stream_chacha20_messagebytes_max(void) +{ + return crypto_stream_chacha20_MESSAGEBYTES_MAX; +} + +size_t +crypto_stream_chacha20_ietf_keybytes(void) { + return crypto_stream_chacha20_ietf_KEYBYTES; +} + +size_t +crypto_stream_chacha20_ietf_noncebytes(void) { + return crypto_stream_chacha20_ietf_NONCEBYTES; +} + +size_t +crypto_stream_chacha20_ietf_messagebytes_max(void) +{ + return crypto_stream_chacha20_ietf_MESSAGEBYTES_MAX; +} + +int +crypto_stream_chacha20(unsigned char *c, unsigned long long clen, + const unsigned char *n, const unsigned char *k) +{ + return implementation->stream(c, clen, n, k); +} + +int +crypto_stream_chacha20_ietf(unsigned char *c, unsigned long long clen, + const unsigned char *n, const unsigned char *k) +{ + return implementation->stream_ietf(c, clen, n, k); +} + +int +crypto_stream_chacha20_xor_ic(unsigned char *c, const unsigned char *m, + unsigned long long mlen, + const unsigned char *n, uint64_t ic, + const unsigned char *k) +{ + return implementation->stream_xor_ic(c, m, mlen, n, ic, k); +} + +int +crypto_stream_chacha20_ietf_xor_ic(unsigned char *c, const unsigned char *m, + unsigned long long mlen, + const unsigned char *n, uint32_t ic, + const unsigned char *k) +{ + return implementation->stream_ietf_xor_ic(c, m, mlen, n, ic, k); +} + +int +crypto_stream_chacha20_xor(unsigned char *c, const unsigned char *m, + unsigned long long mlen, const unsigned char *n, + const unsigned char *k) +{ + return implementation->stream_xor_ic(c, m, mlen, n, 0U, k); +} + +int +crypto_stream_chacha20_ietf_xor(unsigned char *c, const unsigned char *m, + unsigned long long mlen, const unsigned char *n, + const unsigned char *k) +{ + return implementation->stream_ietf_xor_ic(c, m, mlen, n, 0U, k); +} + +void +crypto_stream_chacha20_ietf_keygen(unsigned char k[crypto_stream_chacha20_ietf_KEYBYTES]) +{ + randombytes_buf(k, crypto_stream_chacha20_ietf_KEYBYTES); +} + +void +crypto_stream_chacha20_keygen(unsigned char k[crypto_stream_chacha20_KEYBYTES]) +{ + randombytes_buf(k, crypto_stream_chacha20_KEYBYTES); +} + +int +_crypto_stream_chacha20_pick_best_implementation(void) +{ + implementation = &crypto_stream_chacha20_ref_implementation; +#if defined(HAVE_AVX2INTRIN_H) && defined(HAVE_EMMINTRIN_H) && \ + defined(HAVE_TMMINTRIN_H) && defined(HAVE_SMMINTRIN_H) + if (sodium_runtime_has_avx2()) { + implementation = &crypto_stream_chacha20_dolbeau_avx2_implementation; + return 0; + } +#endif +#if defined(HAVE_EMMINTRIN_H) && defined(HAVE_TMMINTRIN_H) + if (sodium_runtime_has_ssse3()) { + implementation = &crypto_stream_chacha20_dolbeau_ssse3_implementation; + return 0; + } +#endif + return 0; +} diff --git a/libs/libsodium/src/crypto_stream/chacha20/stream_chacha20.h b/libs/libsodium/src/crypto_stream/chacha20/stream_chacha20.h new file mode 100644 index 0000000000..d6b71c5e0d --- /dev/null +++ b/libs/libsodium/src/crypto_stream/chacha20/stream_chacha20.h @@ -0,0 +1,22 @@ + +#ifndef stream_chacha20_H +#define stream_chacha20_H + +#include <stdint.h> + +typedef struct crypto_stream_chacha20_implementation { + int (*stream)(unsigned char *c, unsigned long long clen, + const unsigned char *n, const unsigned char *k); + int (*stream_ietf)(unsigned char *c, unsigned long long clen, + const unsigned char *n, const unsigned char *k); + int (*stream_xor_ic)(unsigned char *c, const unsigned char *m, + unsigned long long mlen, + const unsigned char *n, uint64_t ic, + const unsigned char *k); + int (*stream_ietf_xor_ic)(unsigned char *c, const unsigned char *m, + unsigned long long mlen, + const unsigned char *n, uint32_t ic, + const unsigned char *k); +} crypto_stream_chacha20_implementation; + +#endif diff --git a/libs/libsodium/src/crypto_stream/crypto_stream.c b/libs/libsodium/src/crypto_stream/crypto_stream.c new file mode 100644 index 0000000000..58d25381ab --- /dev/null +++ b/libs/libsodium/src/crypto_stream/crypto_stream.c @@ -0,0 +1,49 @@ + +#include "crypto_stream.h" +#include "randombytes.h" + +size_t +crypto_stream_keybytes(void) +{ + return crypto_stream_KEYBYTES; +} + +size_t +crypto_stream_noncebytes(void) +{ + return crypto_stream_NONCEBYTES; +} + +size_t +crypto_stream_messagebytes_max(void) +{ + return crypto_stream_MESSAGEBYTES_MAX; +} + +const char * +crypto_stream_primitive(void) +{ + return crypto_stream_PRIMITIVE; +} + +int +crypto_stream(unsigned char *c, unsigned long long clen, + const unsigned char *n, const unsigned char *k) +{ + return crypto_stream_xsalsa20(c, clen, n, k); +} + + +int +crypto_stream_xor(unsigned char *c, const unsigned char *m, + unsigned long long mlen, const unsigned char *n, + const unsigned char *k) +{ + return crypto_stream_xsalsa20_xor(c, m, mlen, n, k); +} + +void +crypto_stream_keygen(unsigned char k[crypto_stream_KEYBYTES]) +{ + randombytes_buf(k, crypto_stream_KEYBYTES); +} diff --git a/libs/libsodium/src/crypto_stream/salsa20/ref/salsa20_ref.c b/libs/libsodium/src/crypto_stream/salsa20/ref/salsa20_ref.c new file mode 100644 index 0000000000..f0854ebf7e --- /dev/null +++ b/libs/libsodium/src/crypto_stream/salsa20/ref/salsa20_ref.c @@ -0,0 +1,120 @@ +/* +version 20140420 +D. J. Bernstein +Public domain. +*/ + +#include <stdint.h> + +#include "crypto_core_salsa20.h" +#include "crypto_stream_salsa20.h" +#include "utils.h" + +#include "../stream_salsa20.h" +#include "salsa20_ref.h" + +#ifndef HAVE_AMD64_ASM + +static int +stream_ref(unsigned char *c, unsigned long long clen, const unsigned char *n, + const unsigned char *k) +{ + unsigned char in[16]; + unsigned char block[64]; + unsigned char kcopy[32]; + unsigned int i; + unsigned int u; + + if (!clen) { + return 0; + } + for (i = 0; i < 32; i++) { + kcopy[i] = k[i]; + } + for (i = 0; i < 8; i++) { + in[i] = n[i]; + } + for (i = 8; i < 16; i++) { + in[i] = 0; + } + while (clen >= 64) { + crypto_core_salsa20(c, in, kcopy, NULL); + u = 1; + for (i = 8; i < 16; i++) { + u += (unsigned int) in[i]; + in[i] = u; + u >>= 8; + } + clen -= 64; + c += 64; + } + if (clen) { + crypto_core_salsa20(block, in, kcopy, NULL); + for (i = 0; i < (unsigned int) clen; i++) { + c[i] = block[i]; + } + } + sodium_memzero(block, sizeof block); + sodium_memzero(kcopy, sizeof kcopy); + + return 0; +} + +static int +stream_ref_xor_ic(unsigned char *c, const unsigned char *m, + unsigned long long mlen, const unsigned char *n, uint64_t ic, + const unsigned char *k) +{ + unsigned char in[16]; + unsigned char block[64]; + unsigned char kcopy[32]; + unsigned int i; + unsigned int u; + + if (!mlen) { + return 0; + } + for (i = 0; i < 32; i++) { + kcopy[i] = k[i]; + } + for (i = 0; i < 8; i++) { + in[i] = n[i]; + } + for (i = 8; i < 16; i++) { + in[i] = (unsigned char) (ic & 0xff); + ic >>= 8; + } + while (mlen >= 64) { + crypto_core_salsa20(block, in, kcopy, NULL); + for (i = 0; i < 64; i++) { + c[i] = m[i] ^ block[i]; + } + u = 1; + for (i = 8; i < 16; i++) { + u += (unsigned int) in[i]; + in[i] = u; + u >>= 8; + } + mlen -= 64; + c += 64; + m += 64; + } + if (mlen) { + crypto_core_salsa20(block, in, kcopy, NULL); + for (i = 0; i < (unsigned int) mlen; i++) { + c[i] = m[i] ^ block[i]; + } + } + sodium_memzero(block, sizeof block); + sodium_memzero(kcopy, sizeof kcopy); + + return 0; +} + +struct crypto_stream_salsa20_implementation + crypto_stream_salsa20_ref_implementation = { + SODIUM_C99(.stream =) stream_ref, + SODIUM_C99(.stream_xor_ic =) stream_ref_xor_ic, + }; + +#endif diff --git a/libs/libsodium/src/crypto_stream/salsa20/ref/salsa20_ref.h b/libs/libsodium/src/crypto_stream/salsa20/ref/salsa20_ref.h new file mode 100644 index 0000000000..8716cb4048 --- /dev/null +++ b/libs/libsodium/src/crypto_stream/salsa20/ref/salsa20_ref.h @@ -0,0 +1,8 @@ + +#include <stdint.h> + +#include "../stream_salsa20.h" +#include "crypto_stream_salsa20.h" + +extern struct crypto_stream_salsa20_implementation + crypto_stream_salsa20_ref_implementation; diff --git a/libs/libsodium/src/crypto_stream/salsa20/stream_salsa20.c b/libs/libsodium/src/crypto_stream/salsa20/stream_salsa20.c new file mode 100644 index 0000000000..4529850136 --- /dev/null +++ b/libs/libsodium/src/crypto_stream/salsa20/stream_salsa20.c @@ -0,0 +1,100 @@ +#include "crypto_stream_salsa20.h" +#include "private/common.h" +#include "private/implementations.h" +#include "randombytes.h" +#include "runtime.h" +#include "stream_salsa20.h" + +#ifdef HAVE_AMD64_ASM +# include "xmm6/salsa20_xmm6.h" +#else +# include "ref/salsa20_ref.h" +#endif +#if !defined(HAVE_AMD64_ASM) && defined(HAVE_EMMINTRIN_H) +# include "xmm6int/salsa20_xmm6int-sse2.h" +#endif +#if defined(HAVE_AVX2INTRIN_H) && defined(HAVE_EMMINTRIN_H) && \ + defined(HAVE_TMMINTRIN_H) && defined(HAVE_SMMINTRIN_H) +# include "xmm6int/salsa20_xmm6int-avx2.h" +#endif + +#if HAVE_AMD64_ASM +static const crypto_stream_salsa20_implementation *implementation = + &crypto_stream_salsa20_xmm6_implementation; +#else +static const crypto_stream_salsa20_implementation *implementation = + &crypto_stream_salsa20_ref_implementation; +#endif + +size_t +crypto_stream_salsa20_keybytes(void) +{ + return crypto_stream_salsa20_KEYBYTES; +} + +size_t +crypto_stream_salsa20_noncebytes(void) +{ + return crypto_stream_salsa20_NONCEBYTES; +} + +size_t +crypto_stream_salsa20_messagebytes_max(void) +{ + return crypto_stream_salsa20_MESSAGEBYTES_MAX; +} + +int +crypto_stream_salsa20(unsigned char *c, unsigned long long clen, + const unsigned char *n, const unsigned char *k) +{ + return implementation->stream(c, clen, n, k); +} + +int +crypto_stream_salsa20_xor_ic(unsigned char *c, const unsigned char *m, + unsigned long long mlen, + const unsigned char *n, uint64_t ic, + const unsigned char *k) +{ + return implementation->stream_xor_ic(c, m, mlen, n, ic, k); +} + +int +crypto_stream_salsa20_xor(unsigned char *c, const unsigned char *m, + unsigned long long mlen, const unsigned char *n, + const unsigned char *k) +{ + return implementation->stream_xor_ic(c, m, mlen, n, 0U, k); +} + +void +crypto_stream_salsa20_keygen(unsigned char k[crypto_stream_salsa20_KEYBYTES]) +{ + randombytes_buf(k, crypto_stream_salsa20_KEYBYTES); +} + +int +_crypto_stream_salsa20_pick_best_implementation(void) +{ +#ifdef HAVE_AMD64_ASM + implementation = &crypto_stream_salsa20_xmm6_implementation; +#else + implementation = &crypto_stream_salsa20_ref_implementation; +#endif + +#if defined(HAVE_AVX2INTRIN_H) && defined(HAVE_EMMINTRIN_H) && \ + defined(HAVE_TMMINTRIN_H) && defined(HAVE_SMMINTRIN_H) + if (sodium_runtime_has_avx2()) { + implementation = &crypto_stream_salsa20_xmm6int_avx2_implementation; + return 0; + } +#endif +#if !defined(HAVE_AMD64_ASM) && defined(HAVE_EMMINTRIN_H) + if (sodium_runtime_has_sse2()) { + implementation = &crypto_stream_salsa20_xmm6int_sse2_implementation; + return 0; + } +#endif + return 0; /* LCOV_EXCL_LINE */ +} diff --git a/libs/libsodium/src/crypto_stream/salsa20/stream_salsa20.h b/libs/libsodium/src/crypto_stream/salsa20/stream_salsa20.h new file mode 100644 index 0000000000..1949d38113 --- /dev/null +++ b/libs/libsodium/src/crypto_stream/salsa20/stream_salsa20.h @@ -0,0 +1,16 @@ + +#ifndef stream_salsa20_H +#define stream_salsa20_H + +#include <stdint.h> + +typedef struct crypto_stream_salsa20_implementation { + int (*stream)(unsigned char *c, unsigned long long clen, + const unsigned char *n, const unsigned char *k); + int (*stream_xor_ic)(unsigned char *c, const unsigned char *m, + unsigned long long mlen, + const unsigned char *n, uint64_t ic, + const unsigned char *k); +} crypto_stream_salsa20_implementation; + +#endif diff --git a/libs/libsodium/src/crypto_stream/salsa20/xmm6/salsa20_xmm6-asm.S b/libs/libsodium/src/crypto_stream/salsa20/xmm6/salsa20_xmm6-asm.S new file mode 100644 index 0000000000..6d9f354e10 --- /dev/null +++ b/libs/libsodium/src/crypto_stream/salsa20/xmm6/salsa20_xmm6-asm.S @@ -0,0 +1,960 @@ +#ifdef HAVE_AMD64_ASM + +.text +.p2align 5 + +#ifdef ASM_HIDE_SYMBOL +ASM_HIDE_SYMBOL stream_salsa20_xmm6 +ASM_HIDE_SYMBOL _stream_salsa20_xmm6 +#endif +.globl stream_salsa20_xmm6 +.globl _stream_salsa20_xmm6 +#ifdef __ELF__ +.type stream_salsa20_xmm6, @function +.type _stream_salsa20_xmm6, @function +#endif +stream_salsa20_xmm6: +_stream_salsa20_xmm6: +mov %rsp,%r11 +and $31,%r11 +add $512,%r11 +sub %r11,%rsp +movq %r11,416(%rsp) +movq %r12,424(%rsp) +movq %r13,432(%rsp) +movq %r14,440(%rsp) +movq %r15,448(%rsp) +movq %rbx,456(%rsp) +movq %rbp,464(%rsp) +mov %rsi,%r9 +mov %rdi,%rdi +mov %rdi,%rsi +mov %rdx,%rdx +mov %rcx,%r10 +cmp $0,%r9 +jbe ._done +mov $0,%rax +mov %r9,%rcx +rep stosb +sub %r9,%rdi +movq $0,472(%rsp) +jmp ._start + +.text +.p2align 5 + +#ifdef ASM_HIDE_SYMBOL +ASM_HIDE_SYMBOL stream_salsa20_xmm6_xor_ic +ASM_HIDE_SYMBOL _stream_salsa20_xmm6_xor_ic +#endif +.globl stream_salsa20_xmm6_xor_ic +.globl _stream_salsa20_xmm6_xor_ic +#ifdef __ELF__ +.type stream_salsa20_xmm6_xor_ic, @function +.type _stream_salsa20_xmm6_xor_ic, @function +#endif +stream_salsa20_xmm6_xor_ic: +_stream_salsa20_xmm6_xor_ic: + +mov %rsp,%r11 +and $31,%r11 +add $512,%r11 +sub %r11,%rsp +movq %r11,416(%rsp) +movq %r12,424(%rsp) +movq %r13,432(%rsp) +movq %r14,440(%rsp) +movq %r15,448(%rsp) +movq %rbx,456(%rsp) +movq %rbp,464(%rsp) +mov %rdi,%rdi +mov %rsi,%rsi +mov %r9,%r10 +movq %r8,472(%rsp) +mov %rdx,%r9 +mov %rcx,%rdx +cmp $0,%r9 +jbe ._done + +._start: +movl 20(%r10),%ecx +movl 0(%r10),%r8d +movl 0(%rdx),%eax +movl 16(%r10),%r11d +movl %ecx,64(%rsp) +movl %r8d,4+64(%rsp) +movl %eax,8+64(%rsp) +movl %r11d,12+64(%rsp) +movl 24(%r10),%r8d +movl 4(%r10),%eax +movl 4(%rdx),%edx +movq 472(%rsp),%rcx +movl %ecx,80(%rsp) +movl %r8d,4+80(%rsp) +movl %eax,8+80(%rsp) +movl %edx,12+80(%rsp) +movl 12(%r10),%edx +shr $32,%rcx +movl 28(%r10),%r8d +movl 8(%r10),%eax +movl %edx,96(%rsp) +movl %ecx,4+96(%rsp) +movl %r8d,8+96(%rsp) +movl %eax,12+96(%rsp) +mov $1634760805,%rdx +mov $857760878,%rcx +mov $2036477234,%r8 +mov $1797285236,%rax +movl %edx,112(%rsp) +movl %ecx,4+112(%rsp) +movl %r8d,8+112(%rsp) +movl %eax,12+112(%rsp) +cmp $256,%r9 +jb ._bytesbetween1and255 +movdqa 112(%rsp),%xmm0 +pshufd $0x55,%xmm0,%xmm1 +pshufd $0xaa,%xmm0,%xmm2 +pshufd $0xff,%xmm0,%xmm3 +pshufd $0x00,%xmm0,%xmm0 +movdqa %xmm1,128(%rsp) +movdqa %xmm2,144(%rsp) +movdqa %xmm3,160(%rsp) +movdqa %xmm0,176(%rsp) +movdqa 64(%rsp),%xmm0 +pshufd $0xaa,%xmm0,%xmm1 +pshufd $0xff,%xmm0,%xmm2 +pshufd $0x00,%xmm0,%xmm3 +pshufd $0x55,%xmm0,%xmm0 +movdqa %xmm1,192(%rsp) +movdqa %xmm2,208(%rsp) +movdqa %xmm3,224(%rsp) +movdqa %xmm0,240(%rsp) +movdqa 80(%rsp),%xmm0 +pshufd $0xff,%xmm0,%xmm1 +pshufd $0x55,%xmm0,%xmm2 +pshufd $0xaa,%xmm0,%xmm0 +movdqa %xmm1,256(%rsp) +movdqa %xmm2,272(%rsp) +movdqa %xmm0,288(%rsp) +movdqa 96(%rsp),%xmm0 +pshufd $0x00,%xmm0,%xmm1 +pshufd $0xaa,%xmm0,%xmm2 +pshufd $0xff,%xmm0,%xmm0 +movdqa %xmm1,304(%rsp) +movdqa %xmm2,320(%rsp) +movdqa %xmm0,336(%rsp) + +.p2align 4 +._bytesatleast256: +movq 472(%rsp),%rdx +mov %rdx,%rcx +shr $32,%rcx +movl %edx,352(%rsp) +movl %ecx,368(%rsp) +add $1,%rdx +mov %rdx,%rcx +shr $32,%rcx +movl %edx,4+352(%rsp) +movl %ecx,4+368(%rsp) +add $1,%rdx +mov %rdx,%rcx +shr $32,%rcx +movl %edx,8+352(%rsp) +movl %ecx,8+368(%rsp) +add $1,%rdx +mov %rdx,%rcx +shr $32,%rcx +movl %edx,12+352(%rsp) +movl %ecx,12+368(%rsp) +add $1,%rdx +mov %rdx,%rcx +shr $32,%rcx +movl %edx,80(%rsp) +movl %ecx,4+96(%rsp) +movq %rdx,472(%rsp) +movq %r9,480(%rsp) +mov $20,%rdx +movdqa 128(%rsp),%xmm0 +movdqa 144(%rsp),%xmm1 +movdqa 160(%rsp),%xmm2 +movdqa 320(%rsp),%xmm3 +movdqa 336(%rsp),%xmm4 +movdqa 192(%rsp),%xmm5 +movdqa 208(%rsp),%xmm6 +movdqa 240(%rsp),%xmm7 +movdqa 256(%rsp),%xmm8 +movdqa 272(%rsp),%xmm9 +movdqa 288(%rsp),%xmm10 +movdqa 368(%rsp),%xmm11 +movdqa 176(%rsp),%xmm12 +movdqa 224(%rsp),%xmm13 +movdqa 304(%rsp),%xmm14 +movdqa 352(%rsp),%xmm15 + +.p2align 4 +._mainloop1: +movdqa %xmm1,384(%rsp) +movdqa %xmm2,400(%rsp) +movdqa %xmm13,%xmm1 +paddd %xmm12,%xmm1 +movdqa %xmm1,%xmm2 +pslld $7,%xmm1 +pxor %xmm1,%xmm14 +psrld $25,%xmm2 +pxor %xmm2,%xmm14 +movdqa %xmm7,%xmm1 +paddd %xmm0,%xmm1 +movdqa %xmm1,%xmm2 +pslld $7,%xmm1 +pxor %xmm1,%xmm11 +psrld $25,%xmm2 +pxor %xmm2,%xmm11 +movdqa %xmm12,%xmm1 +paddd %xmm14,%xmm1 +movdqa %xmm1,%xmm2 +pslld $9,%xmm1 +pxor %xmm1,%xmm15 +psrld $23,%xmm2 +pxor %xmm2,%xmm15 +movdqa %xmm0,%xmm1 +paddd %xmm11,%xmm1 +movdqa %xmm1,%xmm2 +pslld $9,%xmm1 +pxor %xmm1,%xmm9 +psrld $23,%xmm2 +pxor %xmm2,%xmm9 +movdqa %xmm14,%xmm1 +paddd %xmm15,%xmm1 +movdqa %xmm1,%xmm2 +pslld $13,%xmm1 +pxor %xmm1,%xmm13 +psrld $19,%xmm2 +pxor %xmm2,%xmm13 +movdqa %xmm11,%xmm1 +paddd %xmm9,%xmm1 +movdqa %xmm1,%xmm2 +pslld $13,%xmm1 +pxor %xmm1,%xmm7 +psrld $19,%xmm2 +pxor %xmm2,%xmm7 +movdqa %xmm15,%xmm1 +paddd %xmm13,%xmm1 +movdqa %xmm1,%xmm2 +pslld $18,%xmm1 +pxor %xmm1,%xmm12 +psrld $14,%xmm2 +pxor %xmm2,%xmm12 +movdqa 384(%rsp),%xmm1 +movdqa %xmm12,384(%rsp) +movdqa %xmm9,%xmm2 +paddd %xmm7,%xmm2 +movdqa %xmm2,%xmm12 +pslld $18,%xmm2 +pxor %xmm2,%xmm0 +psrld $14,%xmm12 +pxor %xmm12,%xmm0 +movdqa %xmm5,%xmm2 +paddd %xmm1,%xmm2 +movdqa %xmm2,%xmm12 +pslld $7,%xmm2 +pxor %xmm2,%xmm3 +psrld $25,%xmm12 +pxor %xmm12,%xmm3 +movdqa 400(%rsp),%xmm2 +movdqa %xmm0,400(%rsp) +movdqa %xmm6,%xmm0 +paddd %xmm2,%xmm0 +movdqa %xmm0,%xmm12 +pslld $7,%xmm0 +pxor %xmm0,%xmm4 +psrld $25,%xmm12 +pxor %xmm12,%xmm4 +movdqa %xmm1,%xmm0 +paddd %xmm3,%xmm0 +movdqa %xmm0,%xmm12 +pslld $9,%xmm0 +pxor %xmm0,%xmm10 +psrld $23,%xmm12 +pxor %xmm12,%xmm10 +movdqa %xmm2,%xmm0 +paddd %xmm4,%xmm0 +movdqa %xmm0,%xmm12 +pslld $9,%xmm0 +pxor %xmm0,%xmm8 +psrld $23,%xmm12 +pxor %xmm12,%xmm8 +movdqa %xmm3,%xmm0 +paddd %xmm10,%xmm0 +movdqa %xmm0,%xmm12 +pslld $13,%xmm0 +pxor %xmm0,%xmm5 +psrld $19,%xmm12 +pxor %xmm12,%xmm5 +movdqa %xmm4,%xmm0 +paddd %xmm8,%xmm0 +movdqa %xmm0,%xmm12 +pslld $13,%xmm0 +pxor %xmm0,%xmm6 +psrld $19,%xmm12 +pxor %xmm12,%xmm6 +movdqa %xmm10,%xmm0 +paddd %xmm5,%xmm0 +movdqa %xmm0,%xmm12 +pslld $18,%xmm0 +pxor %xmm0,%xmm1 +psrld $14,%xmm12 +pxor %xmm12,%xmm1 +movdqa 384(%rsp),%xmm0 +movdqa %xmm1,384(%rsp) +movdqa %xmm4,%xmm1 +paddd %xmm0,%xmm1 +movdqa %xmm1,%xmm12 +pslld $7,%xmm1 +pxor %xmm1,%xmm7 +psrld $25,%xmm12 +pxor %xmm12,%xmm7 +movdqa %xmm8,%xmm1 +paddd %xmm6,%xmm1 +movdqa %xmm1,%xmm12 +pslld $18,%xmm1 +pxor %xmm1,%xmm2 +psrld $14,%xmm12 +pxor %xmm12,%xmm2 +movdqa 400(%rsp),%xmm12 +movdqa %xmm2,400(%rsp) +movdqa %xmm14,%xmm1 +paddd %xmm12,%xmm1 +movdqa %xmm1,%xmm2 +pslld $7,%xmm1 +pxor %xmm1,%xmm5 +psrld $25,%xmm2 +pxor %xmm2,%xmm5 +movdqa %xmm0,%xmm1 +paddd %xmm7,%xmm1 +movdqa %xmm1,%xmm2 +pslld $9,%xmm1 +pxor %xmm1,%xmm10 +psrld $23,%xmm2 +pxor %xmm2,%xmm10 +movdqa %xmm12,%xmm1 +paddd %xmm5,%xmm1 +movdqa %xmm1,%xmm2 +pslld $9,%xmm1 +pxor %xmm1,%xmm8 +psrld $23,%xmm2 +pxor %xmm2,%xmm8 +movdqa %xmm7,%xmm1 +paddd %xmm10,%xmm1 +movdqa %xmm1,%xmm2 +pslld $13,%xmm1 +pxor %xmm1,%xmm4 +psrld $19,%xmm2 +pxor %xmm2,%xmm4 +movdqa %xmm5,%xmm1 +paddd %xmm8,%xmm1 +movdqa %xmm1,%xmm2 +pslld $13,%xmm1 +pxor %xmm1,%xmm14 +psrld $19,%xmm2 +pxor %xmm2,%xmm14 +movdqa %xmm10,%xmm1 +paddd %xmm4,%xmm1 +movdqa %xmm1,%xmm2 +pslld $18,%xmm1 +pxor %xmm1,%xmm0 +psrld $14,%xmm2 +pxor %xmm2,%xmm0 +movdqa 384(%rsp),%xmm1 +movdqa %xmm0,384(%rsp) +movdqa %xmm8,%xmm0 +paddd %xmm14,%xmm0 +movdqa %xmm0,%xmm2 +pslld $18,%xmm0 +pxor %xmm0,%xmm12 +psrld $14,%xmm2 +pxor %xmm2,%xmm12 +movdqa %xmm11,%xmm0 +paddd %xmm1,%xmm0 +movdqa %xmm0,%xmm2 +pslld $7,%xmm0 +pxor %xmm0,%xmm6 +psrld $25,%xmm2 +pxor %xmm2,%xmm6 +movdqa 400(%rsp),%xmm2 +movdqa %xmm12,400(%rsp) +movdqa %xmm3,%xmm0 +paddd %xmm2,%xmm0 +movdqa %xmm0,%xmm12 +pslld $7,%xmm0 +pxor %xmm0,%xmm13 +psrld $25,%xmm12 +pxor %xmm12,%xmm13 +movdqa %xmm1,%xmm0 +paddd %xmm6,%xmm0 +movdqa %xmm0,%xmm12 +pslld $9,%xmm0 +pxor %xmm0,%xmm15 +psrld $23,%xmm12 +pxor %xmm12,%xmm15 +movdqa %xmm2,%xmm0 +paddd %xmm13,%xmm0 +movdqa %xmm0,%xmm12 +pslld $9,%xmm0 +pxor %xmm0,%xmm9 +psrld $23,%xmm12 +pxor %xmm12,%xmm9 +movdqa %xmm6,%xmm0 +paddd %xmm15,%xmm0 +movdqa %xmm0,%xmm12 +pslld $13,%xmm0 +pxor %xmm0,%xmm11 +psrld $19,%xmm12 +pxor %xmm12,%xmm11 +movdqa %xmm13,%xmm0 +paddd %xmm9,%xmm0 +movdqa %xmm0,%xmm12 +pslld $13,%xmm0 +pxor %xmm0,%xmm3 +psrld $19,%xmm12 +pxor %xmm12,%xmm3 +movdqa %xmm15,%xmm0 +paddd %xmm11,%xmm0 +movdqa %xmm0,%xmm12 +pslld $18,%xmm0 +pxor %xmm0,%xmm1 +psrld $14,%xmm12 +pxor %xmm12,%xmm1 +movdqa %xmm9,%xmm0 +paddd %xmm3,%xmm0 +movdqa %xmm0,%xmm12 +pslld $18,%xmm0 +pxor %xmm0,%xmm2 +psrld $14,%xmm12 +pxor %xmm12,%xmm2 +movdqa 384(%rsp),%xmm12 +movdqa 400(%rsp),%xmm0 +sub $2,%rdx +ja ._mainloop1 + +paddd 176(%rsp),%xmm12 +paddd 240(%rsp),%xmm7 +paddd 288(%rsp),%xmm10 +paddd 336(%rsp),%xmm4 +movd %xmm12,%rdx +movd %xmm7,%rcx +movd %xmm10,%r8 +movd %xmm4,%r9 +pshufd $0x39,%xmm12,%xmm12 +pshufd $0x39,%xmm7,%xmm7 +pshufd $0x39,%xmm10,%xmm10 +pshufd $0x39,%xmm4,%xmm4 +xorl 0(%rsi),%edx +xorl 4(%rsi),%ecx +xorl 8(%rsi),%r8d +xorl 12(%rsi),%r9d +movl %edx,0(%rdi) +movl %ecx,4(%rdi) +movl %r8d,8(%rdi) +movl %r9d,12(%rdi) +movd %xmm12,%rdx +movd %xmm7,%rcx +movd %xmm10,%r8 +movd %xmm4,%r9 +pshufd $0x39,%xmm12,%xmm12 +pshufd $0x39,%xmm7,%xmm7 +pshufd $0x39,%xmm10,%xmm10 +pshufd $0x39,%xmm4,%xmm4 +xorl 64(%rsi),%edx +xorl 68(%rsi),%ecx +xorl 72(%rsi),%r8d +xorl 76(%rsi),%r9d +movl %edx,64(%rdi) +movl %ecx,68(%rdi) +movl %r8d,72(%rdi) +movl %r9d,76(%rdi) +movd %xmm12,%rdx +movd %xmm7,%rcx +movd %xmm10,%r8 +movd %xmm4,%r9 +pshufd $0x39,%xmm12,%xmm12 +pshufd $0x39,%xmm7,%xmm7 +pshufd $0x39,%xmm10,%xmm10 +pshufd $0x39,%xmm4,%xmm4 +xorl 128(%rsi),%edx +xorl 132(%rsi),%ecx +xorl 136(%rsi),%r8d +xorl 140(%rsi),%r9d +movl %edx,128(%rdi) +movl %ecx,132(%rdi) +movl %r8d,136(%rdi) +movl %r9d,140(%rdi) +movd %xmm12,%rdx +movd %xmm7,%rcx +movd %xmm10,%r8 +movd %xmm4,%r9 +xorl 192(%rsi),%edx +xorl 196(%rsi),%ecx +xorl 200(%rsi),%r8d +xorl 204(%rsi),%r9d +movl %edx,192(%rdi) +movl %ecx,196(%rdi) +movl %r8d,200(%rdi) +movl %r9d,204(%rdi) +paddd 304(%rsp),%xmm14 +paddd 128(%rsp),%xmm0 +paddd 192(%rsp),%xmm5 +paddd 256(%rsp),%xmm8 +movd %xmm14,%rdx +movd %xmm0,%rcx +movd %xmm5,%r8 +movd %xmm8,%r9 +pshufd $0x39,%xmm14,%xmm14 +pshufd $0x39,%xmm0,%xmm0 +pshufd $0x39,%xmm5,%xmm5 +pshufd $0x39,%xmm8,%xmm8 +xorl 16(%rsi),%edx +xorl 20(%rsi),%ecx +xorl 24(%rsi),%r8d +xorl 28(%rsi),%r9d +movl %edx,16(%rdi) +movl %ecx,20(%rdi) +movl %r8d,24(%rdi) +movl %r9d,28(%rdi) +movd %xmm14,%rdx +movd %xmm0,%rcx +movd %xmm5,%r8 +movd %xmm8,%r9 +pshufd $0x39,%xmm14,%xmm14 +pshufd $0x39,%xmm0,%xmm0 +pshufd $0x39,%xmm5,%xmm5 +pshufd $0x39,%xmm8,%xmm8 +xorl 80(%rsi),%edx +xorl 84(%rsi),%ecx +xorl 88(%rsi),%r8d +xorl 92(%rsi),%r9d +movl %edx,80(%rdi) +movl %ecx,84(%rdi) +movl %r8d,88(%rdi) +movl %r9d,92(%rdi) +movd %xmm14,%rdx +movd %xmm0,%rcx +movd %xmm5,%r8 +movd %xmm8,%r9 +pshufd $0x39,%xmm14,%xmm14 +pshufd $0x39,%xmm0,%xmm0 +pshufd $0x39,%xmm5,%xmm5 +pshufd $0x39,%xmm8,%xmm8 +xorl 144(%rsi),%edx +xorl 148(%rsi),%ecx +xorl 152(%rsi),%r8d +xorl 156(%rsi),%r9d +movl %edx,144(%rdi) +movl %ecx,148(%rdi) +movl %r8d,152(%rdi) +movl %r9d,156(%rdi) +movd %xmm14,%rdx +movd %xmm0,%rcx +movd %xmm5,%r8 +movd %xmm8,%r9 +xorl 208(%rsi),%edx +xorl 212(%rsi),%ecx +xorl 216(%rsi),%r8d +xorl 220(%rsi),%r9d +movl %edx,208(%rdi) +movl %ecx,212(%rdi) +movl %r8d,216(%rdi) +movl %r9d,220(%rdi) +paddd 352(%rsp),%xmm15 +paddd 368(%rsp),%xmm11 +paddd 144(%rsp),%xmm1 +paddd 208(%rsp),%xmm6 +movd %xmm15,%rdx +movd %xmm11,%rcx +movd %xmm1,%r8 +movd %xmm6,%r9 +pshufd $0x39,%xmm15,%xmm15 +pshufd $0x39,%xmm11,%xmm11 +pshufd $0x39,%xmm1,%xmm1 +pshufd $0x39,%xmm6,%xmm6 +xorl 32(%rsi),%edx +xorl 36(%rsi),%ecx +xorl 40(%rsi),%r8d +xorl 44(%rsi),%r9d +movl %edx,32(%rdi) +movl %ecx,36(%rdi) +movl %r8d,40(%rdi) +movl %r9d,44(%rdi) +movd %xmm15,%rdx +movd %xmm11,%rcx +movd %xmm1,%r8 +movd %xmm6,%r9 +pshufd $0x39,%xmm15,%xmm15 +pshufd $0x39,%xmm11,%xmm11 +pshufd $0x39,%xmm1,%xmm1 +pshufd $0x39,%xmm6,%xmm6 +xorl 96(%rsi),%edx +xorl 100(%rsi),%ecx +xorl 104(%rsi),%r8d +xorl 108(%rsi),%r9d +movl %edx,96(%rdi) +movl %ecx,100(%rdi) +movl %r8d,104(%rdi) +movl %r9d,108(%rdi) +movd %xmm15,%rdx +movd %xmm11,%rcx +movd %xmm1,%r8 +movd %xmm6,%r9 +pshufd $0x39,%xmm15,%xmm15 +pshufd $0x39,%xmm11,%xmm11 +pshufd $0x39,%xmm1,%xmm1 +pshufd $0x39,%xmm6,%xmm6 +xorl 160(%rsi),%edx +xorl 164(%rsi),%ecx +xorl 168(%rsi),%r8d +xorl 172(%rsi),%r9d +movl %edx,160(%rdi) +movl %ecx,164(%rdi) +movl %r8d,168(%rdi) +movl %r9d,172(%rdi) +movd %xmm15,%rdx +movd %xmm11,%rcx +movd %xmm1,%r8 +movd %xmm6,%r9 +xorl 224(%rsi),%edx +xorl 228(%rsi),%ecx +xorl 232(%rsi),%r8d +xorl 236(%rsi),%r9d +movl %edx,224(%rdi) +movl %ecx,228(%rdi) +movl %r8d,232(%rdi) +movl %r9d,236(%rdi) +paddd 224(%rsp),%xmm13 +paddd 272(%rsp),%xmm9 +paddd 320(%rsp),%xmm3 +paddd 160(%rsp),%xmm2 +movd %xmm13,%rdx +movd %xmm9,%rcx +movd %xmm3,%r8 +movd %xmm2,%r9 +pshufd $0x39,%xmm13,%xmm13 +pshufd $0x39,%xmm9,%xmm9 +pshufd $0x39,%xmm3,%xmm3 +pshufd $0x39,%xmm2,%xmm2 +xorl 48(%rsi),%edx +xorl 52(%rsi),%ecx +xorl 56(%rsi),%r8d +xorl 60(%rsi),%r9d +movl %edx,48(%rdi) +movl %ecx,52(%rdi) +movl %r8d,56(%rdi) +movl %r9d,60(%rdi) +movd %xmm13,%rdx +movd %xmm9,%rcx +movd %xmm3,%r8 +movd %xmm2,%r9 +pshufd $0x39,%xmm13,%xmm13 +pshufd $0x39,%xmm9,%xmm9 +pshufd $0x39,%xmm3,%xmm3 +pshufd $0x39,%xmm2,%xmm2 +xorl 112(%rsi),%edx +xorl 116(%rsi),%ecx +xorl 120(%rsi),%r8d +xorl 124(%rsi),%r9d +movl %edx,112(%rdi) +movl %ecx,116(%rdi) +movl %r8d,120(%rdi) +movl %r9d,124(%rdi) +movd %xmm13,%rdx +movd %xmm9,%rcx +movd %xmm3,%r8 +movd %xmm2,%r9 +pshufd $0x39,%xmm13,%xmm13 +pshufd $0x39,%xmm9,%xmm9 +pshufd $0x39,%xmm3,%xmm3 +pshufd $0x39,%xmm2,%xmm2 +xorl 176(%rsi),%edx +xorl 180(%rsi),%ecx +xorl 184(%rsi),%r8d +xorl 188(%rsi),%r9d +movl %edx,176(%rdi) +movl %ecx,180(%rdi) +movl %r8d,184(%rdi) +movl %r9d,188(%rdi) +movd %xmm13,%rdx +movd %xmm9,%rcx +movd %xmm3,%r8 +movd %xmm2,%r9 +xorl 240(%rsi),%edx +xorl 244(%rsi),%ecx +xorl 248(%rsi),%r8d +xorl 252(%rsi),%r9d +movl %edx,240(%rdi) +movl %ecx,244(%rdi) +movl %r8d,248(%rdi) +movl %r9d,252(%rdi) +movq 480(%rsp),%r9 +sub $256,%r9 +add $256,%rsi +add $256,%rdi +cmp $256,%r9 +jae ._bytesatleast256 + +cmp $0,%r9 +jbe ._done + +._bytesbetween1and255: +cmp $64,%r9 +jae ._nocopy + +mov %rdi,%rdx +leaq 0(%rsp),%rdi +mov %r9,%rcx +rep movsb +leaq 0(%rsp),%rdi +leaq 0(%rsp),%rsi + +._nocopy: +movq %r9,480(%rsp) +movdqa 112(%rsp),%xmm0 +movdqa 64(%rsp),%xmm1 +movdqa 80(%rsp),%xmm2 +movdqa 96(%rsp),%xmm3 +movdqa %xmm1,%xmm4 +mov $20,%rcx + +.p2align 4 +._mainloop2: +paddd %xmm0,%xmm4 +movdqa %xmm0,%xmm5 +movdqa %xmm4,%xmm6 +pslld $7,%xmm4 +psrld $25,%xmm6 +pxor %xmm4,%xmm3 +pxor %xmm6,%xmm3 +paddd %xmm3,%xmm5 +movdqa %xmm3,%xmm4 +movdqa %xmm5,%xmm6 +pslld $9,%xmm5 +psrld $23,%xmm6 +pxor %xmm5,%xmm2 +pshufd $0x93,%xmm3,%xmm3 +pxor %xmm6,%xmm2 +paddd %xmm2,%xmm4 +movdqa %xmm2,%xmm5 +movdqa %xmm4,%xmm6 +pslld $13,%xmm4 +psrld $19,%xmm6 +pxor %xmm4,%xmm1 +pshufd $0x4e,%xmm2,%xmm2 +pxor %xmm6,%xmm1 +paddd %xmm1,%xmm5 +movdqa %xmm3,%xmm4 +movdqa %xmm5,%xmm6 +pslld $18,%xmm5 +psrld $14,%xmm6 +pxor %xmm5,%xmm0 +pshufd $0x39,%xmm1,%xmm1 +pxor %xmm6,%xmm0 +paddd %xmm0,%xmm4 +movdqa %xmm0,%xmm5 +movdqa %xmm4,%xmm6 +pslld $7,%xmm4 +psrld $25,%xmm6 +pxor %xmm4,%xmm1 +pxor %xmm6,%xmm1 +paddd %xmm1,%xmm5 +movdqa %xmm1,%xmm4 +movdqa %xmm5,%xmm6 +pslld $9,%xmm5 +psrld $23,%xmm6 +pxor %xmm5,%xmm2 +pshufd $0x93,%xmm1,%xmm1 +pxor %xmm6,%xmm2 +paddd %xmm2,%xmm4 +movdqa %xmm2,%xmm5 +movdqa %xmm4,%xmm6 +pslld $13,%xmm4 +psrld $19,%xmm6 +pxor %xmm4,%xmm3 +pshufd $0x4e,%xmm2,%xmm2 +pxor %xmm6,%xmm3 +paddd %xmm3,%xmm5 +movdqa %xmm1,%xmm4 +movdqa %xmm5,%xmm6 +pslld $18,%xmm5 +psrld $14,%xmm6 +pxor %xmm5,%xmm0 +pshufd $0x39,%xmm3,%xmm3 +pxor %xmm6,%xmm0 +paddd %xmm0,%xmm4 +movdqa %xmm0,%xmm5 +movdqa %xmm4,%xmm6 +pslld $7,%xmm4 +psrld $25,%xmm6 +pxor %xmm4,%xmm3 +pxor %xmm6,%xmm3 +paddd %xmm3,%xmm5 +movdqa %xmm3,%xmm4 +movdqa %xmm5,%xmm6 +pslld $9,%xmm5 +psrld $23,%xmm6 +pxor %xmm5,%xmm2 +pshufd $0x93,%xmm3,%xmm3 +pxor %xmm6,%xmm2 +paddd %xmm2,%xmm4 +movdqa %xmm2,%xmm5 +movdqa %xmm4,%xmm6 +pslld $13,%xmm4 +psrld $19,%xmm6 +pxor %xmm4,%xmm1 +pshufd $0x4e,%xmm2,%xmm2 +pxor %xmm6,%xmm1 +paddd %xmm1,%xmm5 +movdqa %xmm3,%xmm4 +movdqa %xmm5,%xmm6 +pslld $18,%xmm5 +psrld $14,%xmm6 +pxor %xmm5,%xmm0 +pshufd $0x39,%xmm1,%xmm1 +pxor %xmm6,%xmm0 +paddd %xmm0,%xmm4 +movdqa %xmm0,%xmm5 +movdqa %xmm4,%xmm6 +pslld $7,%xmm4 +psrld $25,%xmm6 +pxor %xmm4,%xmm1 +pxor %xmm6,%xmm1 +paddd %xmm1,%xmm5 +movdqa %xmm1,%xmm4 +movdqa %xmm5,%xmm6 +pslld $9,%xmm5 +psrld $23,%xmm6 +pxor %xmm5,%xmm2 +pshufd $0x93,%xmm1,%xmm1 +pxor %xmm6,%xmm2 +paddd %xmm2,%xmm4 +movdqa %xmm2,%xmm5 +movdqa %xmm4,%xmm6 +pslld $13,%xmm4 +psrld $19,%xmm6 +pxor %xmm4,%xmm3 +pshufd $0x4e,%xmm2,%xmm2 +pxor %xmm6,%xmm3 +sub $4,%rcx +paddd %xmm3,%xmm5 +movdqa %xmm1,%xmm4 +movdqa %xmm5,%xmm6 +pslld $18,%xmm5 +pxor %xmm7,%xmm7 +psrld $14,%xmm6 +pxor %xmm5,%xmm0 +pshufd $0x39,%xmm3,%xmm3 +pxor %xmm6,%xmm0 +ja ._mainloop2 + +paddd 112(%rsp),%xmm0 +paddd 64(%rsp),%xmm1 +paddd 80(%rsp),%xmm2 +paddd 96(%rsp),%xmm3 +movd %xmm0,%rcx +movd %xmm1,%r8 +movd %xmm2,%r9 +movd %xmm3,%rax +pshufd $0x39,%xmm0,%xmm0 +pshufd $0x39,%xmm1,%xmm1 +pshufd $0x39,%xmm2,%xmm2 +pshufd $0x39,%xmm3,%xmm3 +xorl 0(%rsi),%ecx +xorl 48(%rsi),%r8d +xorl 32(%rsi),%r9d +xorl 16(%rsi),%eax +movl %ecx,0(%rdi) +movl %r8d,48(%rdi) +movl %r9d,32(%rdi) +movl %eax,16(%rdi) +movd %xmm0,%rcx +movd %xmm1,%r8 +movd %xmm2,%r9 +movd %xmm3,%rax +pshufd $0x39,%xmm0,%xmm0 +pshufd $0x39,%xmm1,%xmm1 +pshufd $0x39,%xmm2,%xmm2 +pshufd $0x39,%xmm3,%xmm3 +xorl 20(%rsi),%ecx +xorl 4(%rsi),%r8d +xorl 52(%rsi),%r9d +xorl 36(%rsi),%eax +movl %ecx,20(%rdi) +movl %r8d,4(%rdi) +movl %r9d,52(%rdi) +movl %eax,36(%rdi) +movd %xmm0,%rcx +movd %xmm1,%r8 +movd %xmm2,%r9 +movd %xmm3,%rax +pshufd $0x39,%xmm0,%xmm0 +pshufd $0x39,%xmm1,%xmm1 +pshufd $0x39,%xmm2,%xmm2 +pshufd $0x39,%xmm3,%xmm3 +xorl 40(%rsi),%ecx +xorl 24(%rsi),%r8d +xorl 8(%rsi),%r9d +xorl 56(%rsi),%eax +movl %ecx,40(%rdi) +movl %r8d,24(%rdi) +movl %r9d,8(%rdi) +movl %eax,56(%rdi) +movd %xmm0,%rcx +movd %xmm1,%r8 +movd %xmm2,%r9 +movd %xmm3,%rax +xorl 60(%rsi),%ecx +xorl 44(%rsi),%r8d +xorl 28(%rsi),%r9d +xorl 12(%rsi),%eax +movl %ecx,60(%rdi) +movl %r8d,44(%rdi) +movl %r9d,28(%rdi) +movl %eax,12(%rdi) +movq 480(%rsp),%r9 +movq 472(%rsp),%rcx +add $1,%rcx +mov %rcx,%r8 +shr $32,%r8 +movl %ecx,80(%rsp) +movl %r8d,4+96(%rsp) +movq %rcx,472(%rsp) +cmp $64,%r9 +ja ._bytesatleast65 +jae ._bytesatleast64 + +mov %rdi,%rsi +mov %rdx,%rdi +mov %r9,%rcx +rep movsb + +._bytesatleast64: +._done: +movq 416(%rsp),%r11 +movq 424(%rsp),%r12 +movq 432(%rsp),%r13 +movq 440(%rsp),%r14 +movq 448(%rsp),%r15 +movq 456(%rsp),%rbx +movq 464(%rsp),%rbp +add %r11,%rsp +xor %rax,%rax +mov %rsi,%rdx +ret + +._bytesatleast65: +sub $64,%r9 +add $64,%rdi +add $64,%rsi +jmp ._bytesbetween1and255 + +#endif + +#if defined(__linux__) && defined(__ELF__) +.section .note.GNU-stack,"",%progbits +#endif diff --git a/libs/libsodium/src/crypto_stream/salsa20/xmm6/salsa20_xmm6.c b/libs/libsodium/src/crypto_stream/salsa20/xmm6/salsa20_xmm6.c new file mode 100644 index 0000000000..0a6fee0f3e --- /dev/null +++ b/libs/libsodium/src/crypto_stream/salsa20/xmm6/salsa20_xmm6.c @@ -0,0 +1,31 @@ + +#include <stdint.h> + +#include "utils.h" + +#include "../stream_salsa20.h" +#include "salsa20_xmm6.h" + +#ifdef HAVE_AMD64_ASM + +#ifdef __cplusplus +extern "C" { +#endif +extern int stream_salsa20_xmm6(unsigned char *c, unsigned long long clen, + const unsigned char *n, const unsigned char *k); + +extern int stream_salsa20_xmm6_xor_ic(unsigned char *c, const unsigned char *m, + unsigned long long mlen, + const unsigned char *n, + uint64_t ic, const unsigned char *k); +#ifdef __cplusplus +} +#endif + +struct crypto_stream_salsa20_implementation + crypto_stream_salsa20_xmm6_implementation = { + SODIUM_C99(.stream =) stream_salsa20_xmm6, + SODIUM_C99(.stream_xor_ic =) stream_salsa20_xmm6_xor_ic, + }; + +#endif diff --git a/libs/libsodium/src/crypto_stream/salsa20/xmm6/salsa20_xmm6.h b/libs/libsodium/src/crypto_stream/salsa20/xmm6/salsa20_xmm6.h new file mode 100644 index 0000000000..d38473a9ff --- /dev/null +++ b/libs/libsodium/src/crypto_stream/salsa20/xmm6/salsa20_xmm6.h @@ -0,0 +1,8 @@ + +#include <stdint.h> + +#include "../stream_salsa20.h" +#include "crypto_stream_salsa20.h" + +extern struct crypto_stream_salsa20_implementation + crypto_stream_salsa20_xmm6_implementation; diff --git a/libs/libsodium/src/crypto_stream/salsa20/xmm6int/salsa20_xmm6int-avx2.c b/libs/libsodium/src/crypto_stream/salsa20/xmm6int/salsa20_xmm6int-avx2.c new file mode 100644 index 0000000000..18d4773ec9 --- /dev/null +++ b/libs/libsodium/src/crypto_stream/salsa20/xmm6int/salsa20_xmm6int-avx2.c @@ -0,0 +1,131 @@ + +#include <stdint.h> +#include <stdlib.h> +#include <string.h> + +#include "crypto_stream_salsa20.h" +#include "private/common.h" +#include "private/sse2_64_32.h" +#include "utils.h" + +#if defined(HAVE_AVX2INTRIN_H) && defined(HAVE_EMMINTRIN_H) && \ + defined(HAVE_TMMINTRIN_H) && defined(HAVE_SMMINTRIN_H) + +# ifdef __GNUC__ +# pragma GCC target("sse2") +# pragma GCC target("ssse3") +# pragma GCC target("sse4.1") +# pragma GCC target("avx2") +# endif + +#include <emmintrin.h> +#include <immintrin.h> +#include <smmintrin.h> +#include <tmmintrin.h> + +# include "../stream_salsa20.h" +# include "salsa20_xmm6int-avx2.h" + +# define ROUNDS 20 + +typedef struct salsa_ctx { + uint32_t input[16]; +} salsa_ctx; + +static const int TR[16] = { + 0, 5, 10, 15, 12, 1, 6, 11, 8, 13, 2, 7, 4, 9, 14, 3 +}; + +static void +salsa_keysetup(salsa_ctx *ctx, const uint8_t *k) +{ + ctx->input[TR[1]] = LOAD32_LE(k + 0); + ctx->input[TR[2]] = LOAD32_LE(k + 4); + ctx->input[TR[3]] = LOAD32_LE(k + 8); + ctx->input[TR[4]] = LOAD32_LE(k + 12); + ctx->input[TR[11]] = LOAD32_LE(k + 16); + ctx->input[TR[12]] = LOAD32_LE(k + 20); + ctx->input[TR[13]] = LOAD32_LE(k + 24); + ctx->input[TR[14]] = LOAD32_LE(k + 28); + ctx->input[TR[0]] = 0x61707865; + ctx->input[TR[5]] = 0x3320646e; + ctx->input[TR[10]] = 0x79622d32; + ctx->input[TR[15]] = 0x6b206574; +} + +static void +salsa_ivsetup(salsa_ctx *ctx, const uint8_t *iv, const uint8_t *counter) +{ + ctx->input[TR[6]] = LOAD32_LE(iv + 0); + ctx->input[TR[7]] = LOAD32_LE(iv + 4); + ctx->input[TR[8]] = counter == NULL ? 0 : LOAD32_LE(counter + 0); + ctx->input[TR[9]] = counter == NULL ? 0 : LOAD32_LE(counter + 4); +} + +static void +salsa20_encrypt_bytes(salsa_ctx *ctx, const uint8_t *m, uint8_t *c, + unsigned long long bytes) +{ + uint32_t * const x = &ctx->input[0]; + + if (!bytes) { + return; /* LCOV_EXCL_LINE */ + } + +#include "u8.h" +#include "u4.h" +#include "u1.h" +#include "u0.h" +} + +static int +stream_avx2(unsigned char *c, unsigned long long clen, const unsigned char *n, + const unsigned char *k) +{ + struct salsa_ctx ctx; + + if (!clen) { + return 0; + } + COMPILER_ASSERT(crypto_stream_salsa20_KEYBYTES == 256 / 8); + salsa_keysetup(&ctx, k); + salsa_ivsetup(&ctx, n, NULL); + memset(c, 0, clen); + salsa20_encrypt_bytes(&ctx, c, c, clen); + sodium_memzero(&ctx, sizeof ctx); + + return 0; +} + +static int +stream_avx2_xor_ic(unsigned char *c, const unsigned char *m, + unsigned long long mlen, const unsigned char *n, uint64_t ic, + const unsigned char *k) +{ + struct salsa_ctx ctx; + uint8_t ic_bytes[8]; + uint32_t ic_high; + uint32_t ic_low; + + if (!mlen) { + return 0; + } + ic_high = (uint32_t) (ic >> 32); + ic_low = (uint32_t) ic; + STORE32_LE(&ic_bytes[0], ic_low); + STORE32_LE(&ic_bytes[4], ic_high); + salsa_keysetup(&ctx, k); + salsa_ivsetup(&ctx, n, ic_bytes); + salsa20_encrypt_bytes(&ctx, m, c, mlen); + sodium_memzero(&ctx, sizeof ctx); + + return 0; +} + +struct crypto_stream_salsa20_implementation + crypto_stream_salsa20_xmm6int_avx2_implementation = { + SODIUM_C99(.stream =) stream_avx2, + SODIUM_C99(.stream_xor_ic =) stream_avx2_xor_ic + }; + +#endif diff --git a/libs/libsodium/src/crypto_stream/salsa20/xmm6int/salsa20_xmm6int-avx2.h b/libs/libsodium/src/crypto_stream/salsa20/xmm6int/salsa20_xmm6int-avx2.h new file mode 100644 index 0000000000..0924e9baff --- /dev/null +++ b/libs/libsodium/src/crypto_stream/salsa20/xmm6int/salsa20_xmm6int-avx2.h @@ -0,0 +1,8 @@ + +#include <stdint.h> + +#include "../stream_salsa20.h" +#include "crypto_stream_salsa20.h" + +extern struct crypto_stream_salsa20_implementation + crypto_stream_salsa20_xmm6int_avx2_implementation; diff --git a/libs/libsodium/src/crypto_stream/salsa20/xmm6int/salsa20_xmm6int-sse2.c b/libs/libsodium/src/crypto_stream/salsa20/xmm6int/salsa20_xmm6int-sse2.c new file mode 100644 index 0000000000..d8e53a6554 --- /dev/null +++ b/libs/libsodium/src/crypto_stream/salsa20/xmm6int/salsa20_xmm6int-sse2.c @@ -0,0 +1,122 @@ + +#include <stdint.h> +#include <stdlib.h> +#include <string.h> + +#include "crypto_stream_salsa20.h" +#include "private/common.h" +#include "private/sse2_64_32.h" +#include "utils.h" + +#ifdef HAVE_EMMINTRIN_H + +# ifdef __GNUC__ +# pragma GCC target("sse2") +# endif +# include <emmintrin.h> + +# include "../stream_salsa20.h" +# include "salsa20_xmm6int-sse2.h" + +# define ROUNDS 20 + +typedef struct salsa_ctx { + uint32_t input[16]; +} salsa_ctx; + +static const int TR[16] = { + 0, 5, 10, 15, 12, 1, 6, 11, 8, 13, 2, 7, 4, 9, 14, 3 +}; + +static void +salsa_keysetup(salsa_ctx *ctx, const uint8_t *k) +{ + ctx->input[TR[1]] = LOAD32_LE(k + 0); + ctx->input[TR[2]] = LOAD32_LE(k + 4); + ctx->input[TR[3]] = LOAD32_LE(k + 8); + ctx->input[TR[4]] = LOAD32_LE(k + 12); + ctx->input[TR[11]] = LOAD32_LE(k + 16); + ctx->input[TR[12]] = LOAD32_LE(k + 20); + ctx->input[TR[13]] = LOAD32_LE(k + 24); + ctx->input[TR[14]] = LOAD32_LE(k + 28); + ctx->input[TR[0]] = 0x61707865; + ctx->input[TR[5]] = 0x3320646e; + ctx->input[TR[10]] = 0x79622d32; + ctx->input[TR[15]] = 0x6b206574; +} + +static void +salsa_ivsetup(salsa_ctx *ctx, const uint8_t *iv, const uint8_t *counter) +{ + ctx->input[TR[6]] = LOAD32_LE(iv + 0); + ctx->input[TR[7]] = LOAD32_LE(iv + 4); + ctx->input[TR[8]] = counter == NULL ? 0 : LOAD32_LE(counter + 0); + ctx->input[TR[9]] = counter == NULL ? 0 : LOAD32_LE(counter + 4); +} + +static void +salsa20_encrypt_bytes(salsa_ctx *ctx, const uint8_t *m, uint8_t *c, + unsigned long long bytes) +{ + uint32_t * const x = &ctx->input[0]; + + if (!bytes) { + return; /* LCOV_EXCL_LINE */ + } + +#include "u4.h" +#include "u1.h" +#include "u0.h" +} + +static int +stream_sse2(unsigned char *c, unsigned long long clen, const unsigned char *n, + const unsigned char *k) +{ + struct salsa_ctx ctx; + + if (!clen) { + return 0; + } + COMPILER_ASSERT(crypto_stream_salsa20_KEYBYTES == 256 / 8); + salsa_keysetup(&ctx, k); + salsa_ivsetup(&ctx, n, NULL); + memset(c, 0, clen); + salsa20_encrypt_bytes(&ctx, c, c, clen); + sodium_memzero(&ctx, sizeof ctx); + + return 0; +} + +static int +stream_sse2_xor_ic(unsigned char *c, const unsigned char *m, + unsigned long long mlen, const unsigned char *n, uint64_t ic, + const unsigned char *k) +{ + struct salsa_ctx ctx; + uint8_t ic_bytes[8]; + uint32_t ic_high; + uint32_t ic_low; + + if (!mlen) { + return 0; + } + ic_high = (uint32_t) (ic >> 32); + ic_low = (uint32_t) (ic); + STORE32_LE(&ic_bytes[0], ic_low); + STORE32_LE(&ic_bytes[4], ic_high); + salsa_keysetup(&ctx, k); + salsa_ivsetup(&ctx, n, ic_bytes); + salsa20_encrypt_bytes(&ctx, m, c, mlen); + sodium_memzero(&ctx, sizeof ctx); + + return 0; +} + +struct crypto_stream_salsa20_implementation + crypto_stream_salsa20_xmm6int_sse2_implementation = { + SODIUM_C99(.stream =) stream_sse2, + SODIUM_C99(.stream_xor_ic =) stream_sse2_xor_ic + }; + +#endif diff --git a/libs/libsodium/src/crypto_stream/salsa20/xmm6int/salsa20_xmm6int-sse2.h b/libs/libsodium/src/crypto_stream/salsa20/xmm6int/salsa20_xmm6int-sse2.h new file mode 100644 index 0000000000..ed52a8bcbe --- /dev/null +++ b/libs/libsodium/src/crypto_stream/salsa20/xmm6int/salsa20_xmm6int-sse2.h @@ -0,0 +1,8 @@ + +#include <stdint.h> + +#include "../stream_salsa20.h" +#include "crypto_stream_salsa20.h" + +extern struct crypto_stream_salsa20_implementation + crypto_stream_salsa20_xmm6int_sse2_implementation; diff --git a/libs/libsodium/src/crypto_stream/salsa20/xmm6int/u0.h b/libs/libsodium/src/crypto_stream/salsa20/xmm6int/u0.h new file mode 100644 index 0000000000..b2d4168058 --- /dev/null +++ b/libs/libsodium/src/crypto_stream/salsa20/xmm6int/u0.h @@ -0,0 +1,195 @@ +if (bytes > 0) { + __m128i diag0 = _mm_loadu_si128((__m128i *) (x + 0)); + __m128i diag1 = _mm_loadu_si128((__m128i *) (x + 4)); + __m128i diag2 = _mm_loadu_si128((__m128i *) (x + 8)); + __m128i diag3 = _mm_loadu_si128((__m128i *) (x + 12)); + __m128i a0, a1, a2, a3, a4, a5, a6, a7; + __m128i b0, b1, b2, b3, b4, b5, b6, b7; + uint8_t partialblock[64]; + + unsigned int i; + + a0 = diag1; + for (i = 0; i < ROUNDS; i += 4) { + a0 = _mm_add_epi32(a0, diag0); + a1 = diag0; + b0 = a0; + a0 = _mm_slli_epi32(a0, 7); + b0 = _mm_srli_epi32(b0, 25); + diag3 = _mm_xor_si128(diag3, a0); + + diag3 = _mm_xor_si128(diag3, b0); + + a1 = _mm_add_epi32(a1, diag3); + a2 = diag3; + b1 = a1; + a1 = _mm_slli_epi32(a1, 9); + b1 = _mm_srli_epi32(b1, 23); + diag2 = _mm_xor_si128(diag2, a1); + diag3 = _mm_shuffle_epi32(diag3, 0x93); + diag2 = _mm_xor_si128(diag2, b1); + + a2 = _mm_add_epi32(a2, diag2); + a3 = diag2; + b2 = a2; + a2 = _mm_slli_epi32(a2, 13); + b2 = _mm_srli_epi32(b2, 19); + diag1 = _mm_xor_si128(diag1, a2); + diag2 = _mm_shuffle_epi32(diag2, 0x4e); + diag1 = _mm_xor_si128(diag1, b2); + + a3 = _mm_add_epi32(a3, diag1); + a4 = diag3; + b3 = a3; + a3 = _mm_slli_epi32(a3, 18); + b3 = _mm_srli_epi32(b3, 14); + diag0 = _mm_xor_si128(diag0, a3); + diag1 = _mm_shuffle_epi32(diag1, 0x39); + diag0 = _mm_xor_si128(diag0, b3); + + a4 = _mm_add_epi32(a4, diag0); + a5 = diag0; + b4 = a4; + a4 = _mm_slli_epi32(a4, 7); + b4 = _mm_srli_epi32(b4, 25); + diag1 = _mm_xor_si128(diag1, a4); + + diag1 = _mm_xor_si128(diag1, b4); + + a5 = _mm_add_epi32(a5, diag1); + a6 = diag1; + b5 = a5; + a5 = _mm_slli_epi32(a5, 9); + b5 = _mm_srli_epi32(b5, 23); + diag2 = _mm_xor_si128(diag2, a5); + diag1 = _mm_shuffle_epi32(diag1, 0x93); + diag2 = _mm_xor_si128(diag2, b5); + + a6 = _mm_add_epi32(a6, diag2); + a7 = diag2; + b6 = a6; + a6 = _mm_slli_epi32(a6, 13); + b6 = _mm_srli_epi32(b6, 19); + diag3 = _mm_xor_si128(diag3, a6); + diag2 = _mm_shuffle_epi32(diag2, 0x4e); + diag3 = _mm_xor_si128(diag3, b6); + + a7 = _mm_add_epi32(a7, diag3); + a0 = diag1; + b7 = a7; + a7 = _mm_slli_epi32(a7, 18); + b7 = _mm_srli_epi32(b7, 14); + diag0 = _mm_xor_si128(diag0, a7); + diag3 = _mm_shuffle_epi32(diag3, 0x39); + diag0 = _mm_xor_si128(diag0, b7); + + a0 = _mm_add_epi32(a0, diag0); + a1 = diag0; + b0 = a0; + a0 = _mm_slli_epi32(a0, 7); + b0 = _mm_srli_epi32(b0, 25); + diag3 = _mm_xor_si128(diag3, a0); + + diag3 = _mm_xor_si128(diag3, b0); + + a1 = _mm_add_epi32(a1, diag3); + a2 = diag3; + b1 = a1; + a1 = _mm_slli_epi32(a1, 9); + b1 = _mm_srli_epi32(b1, 23); + diag2 = _mm_xor_si128(diag2, a1); + diag3 = _mm_shuffle_epi32(diag3, 0x93); + diag2 = _mm_xor_si128(diag2, b1); + + a2 = _mm_add_epi32(a2, diag2); + a3 = diag2; + b2 = a2; + a2 = _mm_slli_epi32(a2, 13); + b2 = _mm_srli_epi32(b2, 19); + diag1 = _mm_xor_si128(diag1, a2); + diag2 = _mm_shuffle_epi32(diag2, 0x4e); + diag1 = _mm_xor_si128(diag1, b2); + + a3 = _mm_add_epi32(a3, diag1); + a4 = diag3; + b3 = a3; + a3 = _mm_slli_epi32(a3, 18); + b3 = _mm_srli_epi32(b3, 14); + diag0 = _mm_xor_si128(diag0, a3); + diag1 = _mm_shuffle_epi32(diag1, 0x39); + diag0 = _mm_xor_si128(diag0, b3); + + a4 = _mm_add_epi32(a4, diag0); + a5 = diag0; + b4 = a4; + a4 = _mm_slli_epi32(a4, 7); + b4 = _mm_srli_epi32(b4, 25); + diag1 = _mm_xor_si128(diag1, a4); + + diag1 = _mm_xor_si128(diag1, b4); + + a5 = _mm_add_epi32(a5, diag1); + a6 = diag1; + b5 = a5; + a5 = _mm_slli_epi32(a5, 9); + b5 = _mm_srli_epi32(b5, 23); + diag2 = _mm_xor_si128(diag2, a5); + diag1 = _mm_shuffle_epi32(diag1, 0x93); + diag2 = _mm_xor_si128(diag2, b5); + + a6 = _mm_add_epi32(a6, diag2); + a7 = diag2; + b6 = a6; + a6 = _mm_slli_epi32(a6, 13); + b6 = _mm_srli_epi32(b6, 19); + diag3 = _mm_xor_si128(diag3, a6); + diag2 = _mm_shuffle_epi32(diag2, 0x4e); + diag3 = _mm_xor_si128(diag3, b6); + + a7 = _mm_add_epi32(a7, diag3); + a0 = diag1; + b7 = a7; + a7 = _mm_slli_epi32(a7, 18); + b7 = _mm_srli_epi32(b7, 14); + diag0 = _mm_xor_si128(diag0, a7); + diag3 = _mm_shuffle_epi32(diag3, 0x39); + diag0 = _mm_xor_si128(diag0, b7); + } + + diag0 = _mm_add_epi32(diag0, _mm_loadu_si128((__m128i *) (x + 0))); + diag1 = _mm_add_epi32(diag1, _mm_loadu_si128((__m128i *) (x + 4))); + diag2 = _mm_add_epi32(diag2, _mm_loadu_si128((__m128i *) (x + 8))); + diag3 = _mm_add_epi32(diag3, _mm_loadu_si128((__m128i *) (x + 12))); + +#define ONEQUAD_SHUFFLE(A, B, C, D) \ + do { \ + uint32_t in##A = _mm_cvtsi128_si32(diag0); \ + uint32_t in##B = _mm_cvtsi128_si32(diag1); \ + uint32_t in##C = _mm_cvtsi128_si32(diag2); \ + uint32_t in##D = _mm_cvtsi128_si32(diag3); \ + diag0 = _mm_shuffle_epi32(diag0, 0x39); \ + diag1 = _mm_shuffle_epi32(diag1, 0x39); \ + diag2 = _mm_shuffle_epi32(diag2, 0x39); \ + diag3 = _mm_shuffle_epi32(diag3, 0x39); \ + *(uint32_t *) (partialblock + (A * 4)) = in##A; \ + *(uint32_t *) (partialblock + (B * 4)) = in##B; \ + *(uint32_t *) (partialblock + (C * 4)) = in##C; \ + *(uint32_t *) (partialblock + (D * 4)) = in##D; \ + } while (0) + +#define ONEQUAD(A, B, C, D) ONEQUAD_SHUFFLE(A, B, C, D) + + ONEQUAD(0, 12, 8, 4); + ONEQUAD(5, 1, 13, 9); + ONEQUAD(10, 6, 2, 14); + ONEQUAD(15, 11, 7, 3); + +#undef ONEQUAD +#undef ONEQUAD_SHUFFLE + + for (i = 0; i < bytes; i++) { + c[i] = m[i] ^ partialblock[i]; + } + + sodium_memzero(partialblock, sizeof partialblock); +} diff --git a/libs/libsodium/src/crypto_stream/salsa20/xmm6int/u1.h b/libs/libsodium/src/crypto_stream/salsa20/xmm6int/u1.h new file mode 100644 index 0000000000..c245d9565f --- /dev/null +++ b/libs/libsodium/src/crypto_stream/salsa20/xmm6int/u1.h @@ -0,0 +1,207 @@ +while (bytes >= 64) { + __m128i diag0 = _mm_loadu_si128((__m128i *) (x + 0)); + __m128i diag1 = _mm_loadu_si128((__m128i *) (x + 4)); + __m128i diag2 = _mm_loadu_si128((__m128i *) (x + 8)); + __m128i diag3 = _mm_loadu_si128((__m128i *) (x + 12)); + __m128i a0, a1, a2, a3, a4, a5, a6, a7; + __m128i b0, b1, b2, b3, b4, b5, b6, b7; + + uint32_t in8; + uint32_t in9; + int i; + + a0 = diag1; + for (i = 0; i < ROUNDS; i += 4) { + a0 = _mm_add_epi32(a0, diag0); + a1 = diag0; + b0 = a0; + a0 = _mm_slli_epi32(a0, 7); + b0 = _mm_srli_epi32(b0, 25); + diag3 = _mm_xor_si128(diag3, a0); + + diag3 = _mm_xor_si128(diag3, b0); + + a1 = _mm_add_epi32(a1, diag3); + a2 = diag3; + b1 = a1; + a1 = _mm_slli_epi32(a1, 9); + b1 = _mm_srli_epi32(b1, 23); + diag2 = _mm_xor_si128(diag2, a1); + diag3 = _mm_shuffle_epi32(diag3, 0x93); + diag2 = _mm_xor_si128(diag2, b1); + + a2 = _mm_add_epi32(a2, diag2); + a3 = diag2; + b2 = a2; + a2 = _mm_slli_epi32(a2, 13); + b2 = _mm_srli_epi32(b2, 19); + diag1 = _mm_xor_si128(diag1, a2); + diag2 = _mm_shuffle_epi32(diag2, 0x4e); + diag1 = _mm_xor_si128(diag1, b2); + + a3 = _mm_add_epi32(a3, diag1); + a4 = diag3; + b3 = a3; + a3 = _mm_slli_epi32(a3, 18); + b3 = _mm_srli_epi32(b3, 14); + diag0 = _mm_xor_si128(diag0, a3); + diag1 = _mm_shuffle_epi32(diag1, 0x39); + diag0 = _mm_xor_si128(diag0, b3); + + a4 = _mm_add_epi32(a4, diag0); + a5 = diag0; + b4 = a4; + a4 = _mm_slli_epi32(a4, 7); + b4 = _mm_srli_epi32(b4, 25); + diag1 = _mm_xor_si128(diag1, a4); + + diag1 = _mm_xor_si128(diag1, b4); + + a5 = _mm_add_epi32(a5, diag1); + a6 = diag1; + b5 = a5; + a5 = _mm_slli_epi32(a5, 9); + b5 = _mm_srli_epi32(b5, 23); + diag2 = _mm_xor_si128(diag2, a5); + diag1 = _mm_shuffle_epi32(diag1, 0x93); + diag2 = _mm_xor_si128(diag2, b5); + + a6 = _mm_add_epi32(a6, diag2); + a7 = diag2; + b6 = a6; + a6 = _mm_slli_epi32(a6, 13); + b6 = _mm_srli_epi32(b6, 19); + diag3 = _mm_xor_si128(diag3, a6); + diag2 = _mm_shuffle_epi32(diag2, 0x4e); + diag3 = _mm_xor_si128(diag3, b6); + + a7 = _mm_add_epi32(a7, diag3); + a0 = diag1; + b7 = a7; + a7 = _mm_slli_epi32(a7, 18); + b7 = _mm_srli_epi32(b7, 14); + diag0 = _mm_xor_si128(diag0, a7); + diag3 = _mm_shuffle_epi32(diag3, 0x39); + diag0 = _mm_xor_si128(diag0, b7); + + a0 = _mm_add_epi32(a0, diag0); + a1 = diag0; + b0 = a0; + a0 = _mm_slli_epi32(a0, 7); + b0 = _mm_srli_epi32(b0, 25); + diag3 = _mm_xor_si128(diag3, a0); + + diag3 = _mm_xor_si128(diag3, b0); + + a1 = _mm_add_epi32(a1, diag3); + a2 = diag3; + b1 = a1; + a1 = _mm_slli_epi32(a1, 9); + b1 = _mm_srli_epi32(b1, 23); + diag2 = _mm_xor_si128(diag2, a1); + diag3 = _mm_shuffle_epi32(diag3, 0x93); + diag2 = _mm_xor_si128(diag2, b1); + + a2 = _mm_add_epi32(a2, diag2); + a3 = diag2; + b2 = a2; + a2 = _mm_slli_epi32(a2, 13); + b2 = _mm_srli_epi32(b2, 19); + diag1 = _mm_xor_si128(diag1, a2); + diag2 = _mm_shuffle_epi32(diag2, 0x4e); + diag1 = _mm_xor_si128(diag1, b2); + + a3 = _mm_add_epi32(a3, diag1); + a4 = diag3; + b3 = a3; + a3 = _mm_slli_epi32(a3, 18); + b3 = _mm_srli_epi32(b3, 14); + diag0 = _mm_xor_si128(diag0, a3); + diag1 = _mm_shuffle_epi32(diag1, 0x39); + diag0 = _mm_xor_si128(diag0, b3); + + a4 = _mm_add_epi32(a4, diag0); + a5 = diag0; + b4 = a4; + a4 = _mm_slli_epi32(a4, 7); + b4 = _mm_srli_epi32(b4, 25); + diag1 = _mm_xor_si128(diag1, a4); + + diag1 = _mm_xor_si128(diag1, b4); + + a5 = _mm_add_epi32(a5, diag1); + a6 = diag1; + b5 = a5; + a5 = _mm_slli_epi32(a5, 9); + b5 = _mm_srli_epi32(b5, 23); + diag2 = _mm_xor_si128(diag2, a5); + diag1 = _mm_shuffle_epi32(diag1, 0x93); + diag2 = _mm_xor_si128(diag2, b5); + + a6 = _mm_add_epi32(a6, diag2); + a7 = diag2; + b6 = a6; + a6 = _mm_slli_epi32(a6, 13); + b6 = _mm_srli_epi32(b6, 19); + diag3 = _mm_xor_si128(diag3, a6); + diag2 = _mm_shuffle_epi32(diag2, 0x4e); + diag3 = _mm_xor_si128(diag3, b6); + + a7 = _mm_add_epi32(a7, diag3); + a0 = diag1; + b7 = a7; + a7 = _mm_slli_epi32(a7, 18); + b7 = _mm_srli_epi32(b7, 14); + diag0 = _mm_xor_si128(diag0, a7); + diag3 = _mm_shuffle_epi32(diag3, 0x39); + diag0 = _mm_xor_si128(diag0, b7); + } + + diag0 = _mm_add_epi32(diag0, _mm_loadu_si128((__m128i *) (x + 0))); + diag1 = _mm_add_epi32(diag1, _mm_loadu_si128((__m128i *) (x + 4))); + diag2 = _mm_add_epi32(diag2, _mm_loadu_si128((__m128i *) (x + 8))); + diag3 = _mm_add_epi32(diag3, _mm_loadu_si128((__m128i *) (x + 12))); + +#define ONEQUAD_SHUFFLE(A, B, C, D) \ + do { \ + uint32_t in##A = _mm_cvtsi128_si32(diag0); \ + uint32_t in##B = _mm_cvtsi128_si32(diag1); \ + uint32_t in##C = _mm_cvtsi128_si32(diag2); \ + uint32_t in##D = _mm_cvtsi128_si32(diag3); \ + diag0 = _mm_shuffle_epi32(diag0, 0x39); \ + diag1 = _mm_shuffle_epi32(diag1, 0x39); \ + diag2 = _mm_shuffle_epi32(diag2, 0x39); \ + diag3 = _mm_shuffle_epi32(diag3, 0x39); \ + in##A ^= *(uint32_t *) (m + (A * 4)); \ + in##B ^= *(uint32_t *) (m + (B * 4)); \ + in##C ^= *(uint32_t *) (m + (C * 4)); \ + in##D ^= *(uint32_t *) (m + (D * 4)); \ + *(uint32_t *) (c + (A * 4)) = in##A; \ + *(uint32_t *) (c + (B * 4)) = in##B; \ + *(uint32_t *) (c + (C * 4)) = in##C; \ + *(uint32_t *) (c + (D * 4)) = in##D; \ + } while (0) + +#define ONEQUAD(A, B, C, D) ONEQUAD_SHUFFLE(A, B, C, D) + + ONEQUAD(0, 12, 8, 4); + ONEQUAD(5, 1, 13, 9); + ONEQUAD(10, 6, 2, 14); + ONEQUAD(15, 11, 7, 3); + +#undef ONEQUAD +#undef ONEQUAD_SHUFFLE + + in8 = x[8]; + in9 = x[13]; + in8++; + if (in8 == 0) { + in9++; + } + x[8] = in8; + x[13] = in9; + + c += 64; + m += 64; + bytes -= 64; +} diff --git a/libs/libsodium/src/crypto_stream/salsa20/xmm6int/u4.h b/libs/libsodium/src/crypto_stream/salsa20/xmm6int/u4.h new file mode 100644 index 0000000000..61d935fc90 --- /dev/null +++ b/libs/libsodium/src/crypto_stream/salsa20/xmm6int/u4.h @@ -0,0 +1,547 @@ +if (bytes >= 256) { + __m128i y0, y1, y2, y3, y4, y5, y6, y7, y8, y9, y10, y11, y12, y13, y14, + y15; + __m128i z0, z1, z2, z3, z4, z5, z6, z7, z8, z9, z10, z11, z12, z13, z14, + z15; + __m128i orig0, orig1, orig2, orig3, orig4, orig5, orig6, orig7, orig8, + orig9, orig10, orig11, orig12, orig13, orig14, orig15; + + uint32_t in8; + uint32_t in9; + int i; + + /* element broadcast immediate for _mm_shuffle_epi32 are in order: + 0x00, 0x55, 0xaa, 0xff */ + z0 = _mm_loadu_si128((__m128i *) (x + 0)); + z5 = _mm_shuffle_epi32(z0, 0x55); + z10 = _mm_shuffle_epi32(z0, 0xaa); + z15 = _mm_shuffle_epi32(z0, 0xff); + z0 = _mm_shuffle_epi32(z0, 0x00); + z1 = _mm_loadu_si128((__m128i *) (x + 4)); + z6 = _mm_shuffle_epi32(z1, 0xaa); + z11 = _mm_shuffle_epi32(z1, 0xff); + z12 = _mm_shuffle_epi32(z1, 0x00); + z1 = _mm_shuffle_epi32(z1, 0x55); + z2 = _mm_loadu_si128((__m128i *) (x + 8)); + z7 = _mm_shuffle_epi32(z2, 0xff); + z13 = _mm_shuffle_epi32(z2, 0x55); + z2 = _mm_shuffle_epi32(z2, 0xaa); + /* no z8 -> first half of the nonce, will fill later */ + z3 = _mm_loadu_si128((__m128i *) (x + 12)); + z4 = _mm_shuffle_epi32(z3, 0x00); + z14 = _mm_shuffle_epi32(z3, 0xaa); + z3 = _mm_shuffle_epi32(z3, 0xff); + /* no z9 -> second half of the nonce, will fill later */ + orig0 = z0; + orig1 = z1; + orig2 = z2; + orig3 = z3; + orig4 = z4; + orig5 = z5; + orig6 = z6; + orig7 = z7; + orig10 = z10; + orig11 = z11; + orig12 = z12; + orig13 = z13; + orig14 = z14; + orig15 = z15; + + while (bytes >= 256) { + /* vector implementation for z8 and z9 */ + /* not sure if it helps for only 4 blocks */ + const __m128i addv8 = _mm_set_epi64x(1, 0); + const __m128i addv9 = _mm_set_epi64x(3, 2); + __m128i t8, t9; + uint64_t in89; + + in8 = x[8]; + in9 = x[13]; + in89 = ((uint64_t) in8) | (((uint64_t) in9) << 32); + t8 = _mm_set1_epi64x(in89); + t9 = _mm_set1_epi64x(in89); + + z8 = _mm_add_epi64(addv8, t8); + z9 = _mm_add_epi64(addv9, t9); + + t8 = _mm_unpacklo_epi32(z8, z9); + t9 = _mm_unpackhi_epi32(z8, z9); + + z8 = _mm_unpacklo_epi32(t8, t9); + z9 = _mm_unpackhi_epi32(t8, t9); + + orig8 = z8; + orig9 = z9; + + in89 += 4; + + x[8] = in89 & 0xFFFFFFFF; + x[13] = (in89 >> 32) & 0xFFFFFFFF; + + z5 = orig5; + z10 = orig10; + z15 = orig15; + z14 = orig14; + z3 = orig3; + z6 = orig6; + z11 = orig11; + z1 = orig1; + + z7 = orig7; + z13 = orig13; + z2 = orig2; + z9 = orig9; + z0 = orig0; + z12 = orig12; + z4 = orig4; + z8 = orig8; + + for (i = 0; i < ROUNDS; i += 2) { + /* the inner loop is a direct translation (regexp search/replace) + * from the amd64-xmm6 ASM */ + __m128i r0, r1, r2, r3, r4, r5, r6, r7, r8, r9, r10, r11, r12, r13, + r14, r15; + + y4 = z12; + y4 = _mm_add_epi32(y4, z0); + r4 = y4; + y4 = _mm_slli_epi32(y4, 7); + z4 = _mm_xor_si128(z4, y4); + r4 = _mm_srli_epi32(r4, 25); + z4 = _mm_xor_si128(z4, r4); + + y9 = z1; + y9 = _mm_add_epi32(y9, z5); + r9 = y9; + y9 = _mm_slli_epi32(y9, 7); + z9 = _mm_xor_si128(z9, y9); + r9 = _mm_srli_epi32(r9, 25); + z9 = _mm_xor_si128(z9, r9); + + y8 = z0; + y8 = _mm_add_epi32(y8, z4); + r8 = y8; + y8 = _mm_slli_epi32(y8, 9); + z8 = _mm_xor_si128(z8, y8); + r8 = _mm_srli_epi32(r8, 23); + z8 = _mm_xor_si128(z8, r8); + + y13 = z5; + y13 = _mm_add_epi32(y13, z9); + r13 = y13; + y13 = _mm_slli_epi32(y13, 9); + z13 = _mm_xor_si128(z13, y13); + r13 = _mm_srli_epi32(r13, 23); + z13 = _mm_xor_si128(z13, r13); + + y12 = z4; + y12 = _mm_add_epi32(y12, z8); + r12 = y12; + y12 = _mm_slli_epi32(y12, 13); + z12 = _mm_xor_si128(z12, y12); + r12 = _mm_srli_epi32(r12, 19); + z12 = _mm_xor_si128(z12, r12); + + y1 = z9; + y1 = _mm_add_epi32(y1, z13); + r1 = y1; + y1 = _mm_slli_epi32(y1, 13); + z1 = _mm_xor_si128(z1, y1); + r1 = _mm_srli_epi32(r1, 19); + z1 = _mm_xor_si128(z1, r1); + + y0 = z8; + y0 = _mm_add_epi32(y0, z12); + r0 = y0; + y0 = _mm_slli_epi32(y0, 18); + z0 = _mm_xor_si128(z0, y0); + r0 = _mm_srli_epi32(r0, 14); + z0 = _mm_xor_si128(z0, r0); + + y5 = z13; + y5 = _mm_add_epi32(y5, z1); + r5 = y5; + y5 = _mm_slli_epi32(y5, 18); + z5 = _mm_xor_si128(z5, y5); + r5 = _mm_srli_epi32(r5, 14); + z5 = _mm_xor_si128(z5, r5); + + y14 = z6; + y14 = _mm_add_epi32(y14, z10); + r14 = y14; + y14 = _mm_slli_epi32(y14, 7); + z14 = _mm_xor_si128(z14, y14); + r14 = _mm_srli_epi32(r14, 25); + z14 = _mm_xor_si128(z14, r14); + + y3 = z11; + y3 = _mm_add_epi32(y3, z15); + r3 = y3; + y3 = _mm_slli_epi32(y3, 7); + z3 = _mm_xor_si128(z3, y3); + r3 = _mm_srli_epi32(r3, 25); + z3 = _mm_xor_si128(z3, r3); + + y2 = z10; + y2 = _mm_add_epi32(y2, z14); + r2 = y2; + y2 = _mm_slli_epi32(y2, 9); + z2 = _mm_xor_si128(z2, y2); + r2 = _mm_srli_epi32(r2, 23); + z2 = _mm_xor_si128(z2, r2); + + y7 = z15; + y7 = _mm_add_epi32(y7, z3); + r7 = y7; + y7 = _mm_slli_epi32(y7, 9); + z7 = _mm_xor_si128(z7, y7); + r7 = _mm_srli_epi32(r7, 23); + z7 = _mm_xor_si128(z7, r7); + + y6 = z14; + y6 = _mm_add_epi32(y6, z2); + r6 = y6; + y6 = _mm_slli_epi32(y6, 13); + z6 = _mm_xor_si128(z6, y6); + r6 = _mm_srli_epi32(r6, 19); + z6 = _mm_xor_si128(z6, r6); + + y11 = z3; + y11 = _mm_add_epi32(y11, z7); + r11 = y11; + y11 = _mm_slli_epi32(y11, 13); + z11 = _mm_xor_si128(z11, y11); + r11 = _mm_srli_epi32(r11, 19); + z11 = _mm_xor_si128(z11, r11); + + y10 = z2; + y10 = _mm_add_epi32(y10, z6); + r10 = y10; + y10 = _mm_slli_epi32(y10, 18); + z10 = _mm_xor_si128(z10, y10); + r10 = _mm_srli_epi32(r10, 14); + z10 = _mm_xor_si128(z10, r10); + + y1 = z3; + y1 = _mm_add_epi32(y1, z0); + r1 = y1; + y1 = _mm_slli_epi32(y1, 7); + z1 = _mm_xor_si128(z1, y1); + r1 = _mm_srli_epi32(r1, 25); + z1 = _mm_xor_si128(z1, r1); + + y15 = z7; + y15 = _mm_add_epi32(y15, z11); + r15 = y15; + y15 = _mm_slli_epi32(y15, 18); + z15 = _mm_xor_si128(z15, y15); + r15 = _mm_srli_epi32(r15, 14); + z15 = _mm_xor_si128(z15, r15); + + y6 = z4; + y6 = _mm_add_epi32(y6, z5); + r6 = y6; + y6 = _mm_slli_epi32(y6, 7); + z6 = _mm_xor_si128(z6, y6); + r6 = _mm_srli_epi32(r6, 25); + z6 = _mm_xor_si128(z6, r6); + + y2 = z0; + y2 = _mm_add_epi32(y2, z1); + r2 = y2; + y2 = _mm_slli_epi32(y2, 9); + z2 = _mm_xor_si128(z2, y2); + r2 = _mm_srli_epi32(r2, 23); + z2 = _mm_xor_si128(z2, r2); + + y7 = z5; + y7 = _mm_add_epi32(y7, z6); + r7 = y7; + y7 = _mm_slli_epi32(y7, 9); + z7 = _mm_xor_si128(z7, y7); + r7 = _mm_srli_epi32(r7, 23); + z7 = _mm_xor_si128(z7, r7); + + y3 = z1; + y3 = _mm_add_epi32(y3, z2); + r3 = y3; + y3 = _mm_slli_epi32(y3, 13); + z3 = _mm_xor_si128(z3, y3); + r3 = _mm_srli_epi32(r3, 19); + z3 = _mm_xor_si128(z3, r3); + + y4 = z6; + y4 = _mm_add_epi32(y4, z7); + r4 = y4; + y4 = _mm_slli_epi32(y4, 13); + z4 = _mm_xor_si128(z4, y4); + r4 = _mm_srli_epi32(r4, 19); + z4 = _mm_xor_si128(z4, r4); + + y0 = z2; + y0 = _mm_add_epi32(y0, z3); + r0 = y0; + y0 = _mm_slli_epi32(y0, 18); + z0 = _mm_xor_si128(z0, y0); + r0 = _mm_srli_epi32(r0, 14); + z0 = _mm_xor_si128(z0, r0); + + y5 = z7; + y5 = _mm_add_epi32(y5, z4); + r5 = y5; + y5 = _mm_slli_epi32(y5, 18); + z5 = _mm_xor_si128(z5, y5); + r5 = _mm_srli_epi32(r5, 14); + z5 = _mm_xor_si128(z5, r5); + + y11 = z9; + y11 = _mm_add_epi32(y11, z10); + r11 = y11; + y11 = _mm_slli_epi32(y11, 7); + z11 = _mm_xor_si128(z11, y11); + r11 = _mm_srli_epi32(r11, 25); + z11 = _mm_xor_si128(z11, r11); + + y12 = z14; + y12 = _mm_add_epi32(y12, z15); + r12 = y12; + y12 = _mm_slli_epi32(y12, 7); + z12 = _mm_xor_si128(z12, y12); + r12 = _mm_srli_epi32(r12, 25); + z12 = _mm_xor_si128(z12, r12); + + y8 = z10; + y8 = _mm_add_epi32(y8, z11); + r8 = y8; + y8 = _mm_slli_epi32(y8, 9); + z8 = _mm_xor_si128(z8, y8); + r8 = _mm_srli_epi32(r8, 23); + z8 = _mm_xor_si128(z8, r8); + + y13 = z15; + y13 = _mm_add_epi32(y13, z12); + r13 = y13; + y13 = _mm_slli_epi32(y13, 9); + z13 = _mm_xor_si128(z13, y13); + r13 = _mm_srli_epi32(r13, 23); + z13 = _mm_xor_si128(z13, r13); + + y9 = z11; + y9 = _mm_add_epi32(y9, z8); + r9 = y9; + y9 = _mm_slli_epi32(y9, 13); + z9 = _mm_xor_si128(z9, y9); + r9 = _mm_srli_epi32(r9, 19); + z9 = _mm_xor_si128(z9, r9); + + y14 = z12; + y14 = _mm_add_epi32(y14, z13); + r14 = y14; + y14 = _mm_slli_epi32(y14, 13); + z14 = _mm_xor_si128(z14, y14); + r14 = _mm_srli_epi32(r14, 19); + z14 = _mm_xor_si128(z14, r14); + + y10 = z8; + y10 = _mm_add_epi32(y10, z9); + r10 = y10; + y10 = _mm_slli_epi32(y10, 18); + z10 = _mm_xor_si128(z10, y10); + r10 = _mm_srli_epi32(r10, 14); + z10 = _mm_xor_si128(z10, r10); + + y15 = z13; + y15 = _mm_add_epi32(y15, z14); + r15 = y15; + y15 = _mm_slli_epi32(y15, 18); + z15 = _mm_xor_si128(z15, y15); + r15 = _mm_srli_epi32(r15, 14); + z15 = _mm_xor_si128(z15, r15); + } + +/* store data ; this macro replicates the original amd64-xmm6 code */ +#define ONEQUAD_SHUFFLE(A, B, C, D) \ + z##A = _mm_add_epi32(z##A, orig##A); \ + z##B = _mm_add_epi32(z##B, orig##B); \ + z##C = _mm_add_epi32(z##C, orig##C); \ + z##D = _mm_add_epi32(z##D, orig##D); \ + in##A = _mm_cvtsi128_si32(z##A); \ + in##B = _mm_cvtsi128_si32(z##B); \ + in##C = _mm_cvtsi128_si32(z##C); \ + in##D = _mm_cvtsi128_si32(z##D); \ + z##A = _mm_shuffle_epi32(z##A, 0x39); \ + z##B = _mm_shuffle_epi32(z##B, 0x39); \ + z##C = _mm_shuffle_epi32(z##C, 0x39); \ + z##D = _mm_shuffle_epi32(z##D, 0x39); \ + \ + in##A ^= *(uint32_t *) (m + 0); \ + in##B ^= *(uint32_t *) (m + 4); \ + in##C ^= *(uint32_t *) (m + 8); \ + in##D ^= *(uint32_t *) (m + 12); \ + \ + *(uint32_t *) (c + 0) = in##A; \ + *(uint32_t *) (c + 4) = in##B; \ + *(uint32_t *) (c + 8) = in##C; \ + *(uint32_t *) (c + 12) = in##D; \ + \ + in##A = _mm_cvtsi128_si32(z##A); \ + in##B = _mm_cvtsi128_si32(z##B); \ + in##C = _mm_cvtsi128_si32(z##C); \ + in##D = _mm_cvtsi128_si32(z##D); \ + z##A = _mm_shuffle_epi32(z##A, 0x39); \ + z##B = _mm_shuffle_epi32(z##B, 0x39); \ + z##C = _mm_shuffle_epi32(z##C, 0x39); \ + z##D = _mm_shuffle_epi32(z##D, 0x39); \ + \ + in##A ^= *(uint32_t *) (m + 64); \ + in##B ^= *(uint32_t *) (m + 68); \ + in##C ^= *(uint32_t *) (m + 72); \ + in##D ^= *(uint32_t *) (m + 76); \ + *(uint32_t *) (c + 64) = in##A; \ + *(uint32_t *) (c + 68) = in##B; \ + *(uint32_t *) (c + 72) = in##C; \ + *(uint32_t *) (c + 76) = in##D; \ + \ + in##A = _mm_cvtsi128_si32(z##A); \ + in##B = _mm_cvtsi128_si32(z##B); \ + in##C = _mm_cvtsi128_si32(z##C); \ + in##D = _mm_cvtsi128_si32(z##D); \ + z##A = _mm_shuffle_epi32(z##A, 0x39); \ + z##B = _mm_shuffle_epi32(z##B, 0x39); \ + z##C = _mm_shuffle_epi32(z##C, 0x39); \ + z##D = _mm_shuffle_epi32(z##D, 0x39); \ + \ + in##A ^= *(uint32_t *) (m + 128); \ + in##B ^= *(uint32_t *) (m + 132); \ + in##C ^= *(uint32_t *) (m + 136); \ + in##D ^= *(uint32_t *) (m + 140); \ + *(uint32_t *) (c + 128) = in##A; \ + *(uint32_t *) (c + 132) = in##B; \ + *(uint32_t *) (c + 136) = in##C; \ + *(uint32_t *) (c + 140) = in##D; \ + \ + in##A = _mm_cvtsi128_si32(z##A); \ + in##B = _mm_cvtsi128_si32(z##B); \ + in##C = _mm_cvtsi128_si32(z##C); \ + in##D = _mm_cvtsi128_si32(z##D); \ + \ + in##A ^= *(uint32_t *) (m + 192); \ + in##B ^= *(uint32_t *) (m + 196); \ + in##C ^= *(uint32_t *) (m + 200); \ + in##D ^= *(uint32_t *) (m + 204); \ + *(uint32_t *) (c + 192) = in##A; \ + *(uint32_t *) (c + 196) = in##B; \ + *(uint32_t *) (c + 200) = in##C; \ + *(uint32_t *) (c + 204) = in##D + +/* store data ; this macro replaces shuffle+mov by a direct extract; not much + * difference */ +#define ONEQUAD_EXTRACT(A, B, C, D) \ + z##A = _mm_add_epi32(z##A, orig##A); \ + z##B = _mm_add_epi32(z##B, orig##B); \ + z##C = _mm_add_epi32(z##C, orig##C); \ + z##D = _mm_add_epi32(z##D, orig##D); \ + in##A = _mm_cvtsi128_si32(z##A); \ + in##B = _mm_cvtsi128_si32(z##B); \ + in##C = _mm_cvtsi128_si32(z##C); \ + in##D = _mm_cvtsi128_si32(z##D); \ + in##A ^= *(uint32_t *) (m + 0); \ + in##B ^= *(uint32_t *) (m + 4); \ + in##C ^= *(uint32_t *) (m + 8); \ + in##D ^= *(uint32_t *) (m + 12); \ + *(uint32_t *) (c + 0) = in##A; \ + *(uint32_t *) (c + 4) = in##B; \ + *(uint32_t *) (c + 8) = in##C; \ + *(uint32_t *) (c + 12) = in##D; \ + \ + in##A = _mm_extract_epi32(z##A, 1); \ + in##B = _mm_extract_epi32(z##B, 1); \ + in##C = _mm_extract_epi32(z##C, 1); \ + in##D = _mm_extract_epi32(z##D, 1); \ + \ + in##A ^= *(uint32_t *) (m + 64); \ + in##B ^= *(uint32_t *) (m + 68); \ + in##C ^= *(uint32_t *) (m + 72); \ + in##D ^= *(uint32_t *) (m + 76); \ + *(uint32_t *) (c + 64) = in##A; \ + *(uint32_t *) (c + 68) = in##B; \ + *(uint32_t *) (c + 72) = in##C; \ + *(uint32_t *) (c + 76) = in##D; \ + \ + in##A = _mm_extract_epi32(z##A, 2); \ + in##B = _mm_extract_epi32(z##B, 2); \ + in##C = _mm_extract_epi32(z##C, 2); \ + in##D = _mm_extract_epi32(z##D, 2); \ + \ + in##A ^= *(uint32_t *) (m + 128); \ + in##B ^= *(uint32_t *) (m + 132); \ + in##C ^= *(uint32_t *) (m + 136); \ + in##D ^= *(uint32_t *) (m + 140); \ + *(uint32_t *) (c + 128) = in##A; \ + *(uint32_t *) (c + 132) = in##B; \ + *(uint32_t *) (c + 136) = in##C; \ + *(uint32_t *) (c + 140) = in##D; \ + \ + in##A = _mm_extract_epi32(z##A, 3); \ + in##B = _mm_extract_epi32(z##B, 3); \ + in##C = _mm_extract_epi32(z##C, 3); \ + in##D = _mm_extract_epi32(z##D, 3); \ + \ + in##A ^= *(uint32_t *) (m + 192); \ + in##B ^= *(uint32_t *) (m + 196); \ + in##C ^= *(uint32_t *) (m + 200); \ + in##D ^= *(uint32_t *) (m + 204); \ + *(uint32_t *) (c + 192) = in##A; \ + *(uint32_t *) (c + 196) = in##B; \ + *(uint32_t *) (c + 200) = in##C; \ + *(uint32_t *) (c + 204) = in##D + +/* store data ; this macro first transpose data in-registers, and then store + * them in memory. much faster with icc. */ +#define ONEQUAD_TRANSPOSE(A, B, C, D) \ + z##A = _mm_add_epi32(z##A, orig##A); \ + z##B = _mm_add_epi32(z##B, orig##B); \ + z##C = _mm_add_epi32(z##C, orig##C); \ + z##D = _mm_add_epi32(z##D, orig##D); \ + y##A = _mm_unpacklo_epi32(z##A, z##B); \ + y##B = _mm_unpacklo_epi32(z##C, z##D); \ + y##C = _mm_unpackhi_epi32(z##A, z##B); \ + y##D = _mm_unpackhi_epi32(z##C, z##D); \ + z##A = _mm_unpacklo_epi64(y##A, y##B); \ + z##B = _mm_unpackhi_epi64(y##A, y##B); \ + z##C = _mm_unpacklo_epi64(y##C, y##D); \ + z##D = _mm_unpackhi_epi64(y##C, y##D); \ + y##A = _mm_xor_si128(z##A, _mm_loadu_si128((__m128i *) (m + 0))); \ + _mm_storeu_si128((__m128i *) (c + 0), y##A); \ + y##B = _mm_xor_si128(z##B, _mm_loadu_si128((__m128i *) (m + 64))); \ + _mm_storeu_si128((__m128i *) (c + 64), y##B); \ + y##C = _mm_xor_si128(z##C, _mm_loadu_si128((__m128i *) (m + 128))); \ + _mm_storeu_si128((__m128i *) (c + 128), y##C); \ + y##D = _mm_xor_si128(z##D, _mm_loadu_si128((__m128i *) (m + 192))); \ + _mm_storeu_si128((__m128i *) (c + 192), y##D) + +#define ONEQUAD(A, B, C, D) ONEQUAD_TRANSPOSE(A, B, C, D) + + ONEQUAD(0, 1, 2, 3); + m += 16; + c += 16; + ONEQUAD(4, 5, 6, 7); + m += 16; + c += 16; + ONEQUAD(8, 9, 10, 11); + m += 16; + c += 16; + ONEQUAD(12, 13, 14, 15); + m -= 48; + c -= 48; + +#undef ONEQUAD +#undef ONEQUAD_TRANSPOSE +#undef ONEQUAD_EXTRACT +#undef ONEQUAD_SHUFFLE + + bytes -= 256; + c += 256; + m += 256; + } +} diff --git a/libs/libsodium/src/crypto_stream/salsa20/xmm6int/u8.h b/libs/libsodium/src/crypto_stream/salsa20/xmm6int/u8.h new file mode 100644 index 0000000000..467a961299 --- /dev/null +++ b/libs/libsodium/src/crypto_stream/salsa20/xmm6int/u8.h @@ -0,0 +1,476 @@ +if (bytes >= 512) { + __m256i y0, y1, y2, y3, y4, y5, y6, y7, y8, y9, y10, y11, y12, y13, y14, + y15; + + /* the naive way seems as fast (if not a bit faster) than the vector way */ + __m256i z0 = _mm256_set1_epi32(x[0]); + __m256i z5 = _mm256_set1_epi32(x[1]); + __m256i z10 = _mm256_set1_epi32(x[2]); + __m256i z15 = _mm256_set1_epi32(x[3]); + __m256i z12 = _mm256_set1_epi32(x[4]); + __m256i z1 = _mm256_set1_epi32(x[5]); + __m256i z6 = _mm256_set1_epi32(x[6]); + __m256i z11 = _mm256_set1_epi32(x[7]); + __m256i z8; /* useless */ + __m256i z13 = _mm256_set1_epi32(x[9]); + __m256i z2 = _mm256_set1_epi32(x[10]); + __m256i z7 = _mm256_set1_epi32(x[11]); + __m256i z4 = _mm256_set1_epi32(x[12]); + __m256i z9; /* useless */ + __m256i z14 = _mm256_set1_epi32(x[14]); + __m256i z3 = _mm256_set1_epi32(x[15]); + + __m256i orig0 = z0; + __m256i orig1 = z1; + __m256i orig2 = z2; + __m256i orig3 = z3; + __m256i orig4 = z4; + __m256i orig5 = z5; + __m256i orig6 = z6; + __m256i orig7 = z7; + __m256i orig8; + __m256i orig9; + __m256i orig10 = z10; + __m256i orig11 = z11; + __m256i orig12 = z12; + __m256i orig13 = z13; + __m256i orig14 = z14; + __m256i orig15 = z15; + + uint32_t in8; + uint32_t in9; + int i; + + while (bytes >= 512) { + /* vector implementation for z8 and z9 */ + /* faster than the naive version for 8 blocks */ + const __m256i addv8 = _mm256_set_epi64x(3, 2, 1, 0); + const __m256i addv9 = _mm256_set_epi64x(7, 6, 5, 4); + const __m256i permute = _mm256_set_epi32(7, 6, 3, 2, 5, 4, 1, 0); + + __m256i t8, t9; + uint64_t in89; + + in8 = x[8]; + in9 = x[13]; /* see arrays above for the address translation */ + in89 = ((uint64_t) in8) | (((uint64_t) in9) << 32); + + z8 = z9 = _mm256_broadcastq_epi64(_mm_cvtsi64_si128(in89)); + + t8 = _mm256_add_epi64(addv8, z8); + t9 = _mm256_add_epi64(addv9, z9); + + z8 = _mm256_unpacklo_epi32(t8, t9); + z9 = _mm256_unpackhi_epi32(t8, t9); + + t8 = _mm256_unpacklo_epi32(z8, z9); + t9 = _mm256_unpackhi_epi32(z8, z9); + + /* required because unpack* are intra-lane */ + z8 = _mm256_permutevar8x32_epi32(t8, permute); + z9 = _mm256_permutevar8x32_epi32(t9, permute); + + orig8 = z8; + orig9 = z9; + + in89 += 8; + + x[8] = in89 & 0xFFFFFFFF; + x[13] = (in89 >> 32) & 0xFFFFFFFF; + + z5 = orig5; + z10 = orig10; + z15 = orig15; + z14 = orig14; + z3 = orig3; + z6 = orig6; + z11 = orig11; + z1 = orig1; + + z7 = orig7; + z13 = orig13; + z2 = orig2; + z9 = orig9; + z0 = orig0; + z12 = orig12; + z4 = orig4; + z8 = orig8; + + for (i = 0; i < ROUNDS; i += 2) { + /* the inner loop is a direct translation (regexp search/replace) + * from the amd64-xmm6 ASM */ + __m256i r0, r1, r2, r3, r4, r5, r6, r7, r8, r9, r10, r11, r12, r13, + r14, r15; + + y4 = z12; + y4 = _mm256_add_epi32(y4, z0); + r4 = y4; + y4 = _mm256_slli_epi32(y4, 7); + z4 = _mm256_xor_si256(z4, y4); + r4 = _mm256_srli_epi32(r4, 25); + z4 = _mm256_xor_si256(z4, r4); + + y9 = z1; + y9 = _mm256_add_epi32(y9, z5); + r9 = y9; + y9 = _mm256_slli_epi32(y9, 7); + z9 = _mm256_xor_si256(z9, y9); + r9 = _mm256_srli_epi32(r9, 25); + z9 = _mm256_xor_si256(z9, r9); + + y8 = z0; + y8 = _mm256_add_epi32(y8, z4); + r8 = y8; + y8 = _mm256_slli_epi32(y8, 9); + z8 = _mm256_xor_si256(z8, y8); + r8 = _mm256_srli_epi32(r8, 23); + z8 = _mm256_xor_si256(z8, r8); + + y13 = z5; + y13 = _mm256_add_epi32(y13, z9); + r13 = y13; + y13 = _mm256_slli_epi32(y13, 9); + z13 = _mm256_xor_si256(z13, y13); + r13 = _mm256_srli_epi32(r13, 23); + z13 = _mm256_xor_si256(z13, r13); + + y12 = z4; + y12 = _mm256_add_epi32(y12, z8); + r12 = y12; + y12 = _mm256_slli_epi32(y12, 13); + z12 = _mm256_xor_si256(z12, y12); + r12 = _mm256_srli_epi32(r12, 19); + z12 = _mm256_xor_si256(z12, r12); + + y1 = z9; + y1 = _mm256_add_epi32(y1, z13); + r1 = y1; + y1 = _mm256_slli_epi32(y1, 13); + z1 = _mm256_xor_si256(z1, y1); + r1 = _mm256_srli_epi32(r1, 19); + z1 = _mm256_xor_si256(z1, r1); + + y0 = z8; + y0 = _mm256_add_epi32(y0, z12); + r0 = y0; + y0 = _mm256_slli_epi32(y0, 18); + z0 = _mm256_xor_si256(z0, y0); + r0 = _mm256_srli_epi32(r0, 14); + z0 = _mm256_xor_si256(z0, r0); + + y5 = z13; + y5 = _mm256_add_epi32(y5, z1); + r5 = y5; + y5 = _mm256_slli_epi32(y5, 18); + z5 = _mm256_xor_si256(z5, y5); + r5 = _mm256_srli_epi32(r5, 14); + z5 = _mm256_xor_si256(z5, r5); + + y14 = z6; + y14 = _mm256_add_epi32(y14, z10); + r14 = y14; + y14 = _mm256_slli_epi32(y14, 7); + z14 = _mm256_xor_si256(z14, y14); + r14 = _mm256_srli_epi32(r14, 25); + z14 = _mm256_xor_si256(z14, r14); + + y3 = z11; + y3 = _mm256_add_epi32(y3, z15); + r3 = y3; + y3 = _mm256_slli_epi32(y3, 7); + z3 = _mm256_xor_si256(z3, y3); + r3 = _mm256_srli_epi32(r3, 25); + z3 = _mm256_xor_si256(z3, r3); + + y2 = z10; + y2 = _mm256_add_epi32(y2, z14); + r2 = y2; + y2 = _mm256_slli_epi32(y2, 9); + z2 = _mm256_xor_si256(z2, y2); + r2 = _mm256_srli_epi32(r2, 23); + z2 = _mm256_xor_si256(z2, r2); + + y7 = z15; + y7 = _mm256_add_epi32(y7, z3); + r7 = y7; + y7 = _mm256_slli_epi32(y7, 9); + z7 = _mm256_xor_si256(z7, y7); + r7 = _mm256_srli_epi32(r7, 23); + z7 = _mm256_xor_si256(z7, r7); + + y6 = z14; + y6 = _mm256_add_epi32(y6, z2); + r6 = y6; + y6 = _mm256_slli_epi32(y6, 13); + z6 = _mm256_xor_si256(z6, y6); + r6 = _mm256_srli_epi32(r6, 19); + z6 = _mm256_xor_si256(z6, r6); + + y11 = z3; + y11 = _mm256_add_epi32(y11, z7); + r11 = y11; + y11 = _mm256_slli_epi32(y11, 13); + z11 = _mm256_xor_si256(z11, y11); + r11 = _mm256_srli_epi32(r11, 19); + z11 = _mm256_xor_si256(z11, r11); + + y10 = z2; + y10 = _mm256_add_epi32(y10, z6); + r10 = y10; + y10 = _mm256_slli_epi32(y10, 18); + z10 = _mm256_xor_si256(z10, y10); + r10 = _mm256_srli_epi32(r10, 14); + z10 = _mm256_xor_si256(z10, r10); + + y1 = z3; + y1 = _mm256_add_epi32(y1, z0); + r1 = y1; + y1 = _mm256_slli_epi32(y1, 7); + z1 = _mm256_xor_si256(z1, y1); + r1 = _mm256_srli_epi32(r1, 25); + z1 = _mm256_xor_si256(z1, r1); + + y15 = z7; + y15 = _mm256_add_epi32(y15, z11); + r15 = y15; + y15 = _mm256_slli_epi32(y15, 18); + z15 = _mm256_xor_si256(z15, y15); + r15 = _mm256_srli_epi32(r15, 14); + z15 = _mm256_xor_si256(z15, r15); + + y6 = z4; + y6 = _mm256_add_epi32(y6, z5); + r6 = y6; + y6 = _mm256_slli_epi32(y6, 7); + z6 = _mm256_xor_si256(z6, y6); + r6 = _mm256_srli_epi32(r6, 25); + z6 = _mm256_xor_si256(z6, r6); + + y2 = z0; + y2 = _mm256_add_epi32(y2, z1); + r2 = y2; + y2 = _mm256_slli_epi32(y2, 9); + z2 = _mm256_xor_si256(z2, y2); + r2 = _mm256_srli_epi32(r2, 23); + z2 = _mm256_xor_si256(z2, r2); + + y7 = z5; + y7 = _mm256_add_epi32(y7, z6); + r7 = y7; + y7 = _mm256_slli_epi32(y7, 9); + z7 = _mm256_xor_si256(z7, y7); + r7 = _mm256_srli_epi32(r7, 23); + z7 = _mm256_xor_si256(z7, r7); + + y3 = z1; + y3 = _mm256_add_epi32(y3, z2); + r3 = y3; + y3 = _mm256_slli_epi32(y3, 13); + z3 = _mm256_xor_si256(z3, y3); + r3 = _mm256_srli_epi32(r3, 19); + z3 = _mm256_xor_si256(z3, r3); + + y4 = z6; + y4 = _mm256_add_epi32(y4, z7); + r4 = y4; + y4 = _mm256_slli_epi32(y4, 13); + z4 = _mm256_xor_si256(z4, y4); + r4 = _mm256_srli_epi32(r4, 19); + z4 = _mm256_xor_si256(z4, r4); + + y0 = z2; + y0 = _mm256_add_epi32(y0, z3); + r0 = y0; + y0 = _mm256_slli_epi32(y0, 18); + z0 = _mm256_xor_si256(z0, y0); + r0 = _mm256_srli_epi32(r0, 14); + z0 = _mm256_xor_si256(z0, r0); + + y5 = z7; + y5 = _mm256_add_epi32(y5, z4); + r5 = y5; + y5 = _mm256_slli_epi32(y5, 18); + z5 = _mm256_xor_si256(z5, y5); + r5 = _mm256_srli_epi32(r5, 14); + z5 = _mm256_xor_si256(z5, r5); + + y11 = z9; + y11 = _mm256_add_epi32(y11, z10); + r11 = y11; + y11 = _mm256_slli_epi32(y11, 7); + z11 = _mm256_xor_si256(z11, y11); + r11 = _mm256_srli_epi32(r11, 25); + z11 = _mm256_xor_si256(z11, r11); + + y12 = z14; + y12 = _mm256_add_epi32(y12, z15); + r12 = y12; + y12 = _mm256_slli_epi32(y12, 7); + z12 = _mm256_xor_si256(z12, y12); + r12 = _mm256_srli_epi32(r12, 25); + z12 = _mm256_xor_si256(z12, r12); + + y8 = z10; + y8 = _mm256_add_epi32(y8, z11); + r8 = y8; + y8 = _mm256_slli_epi32(y8, 9); + z8 = _mm256_xor_si256(z8, y8); + r8 = _mm256_srli_epi32(r8, 23); + z8 = _mm256_xor_si256(z8, r8); + + y13 = z15; + y13 = _mm256_add_epi32(y13, z12); + r13 = y13; + y13 = _mm256_slli_epi32(y13, 9); + z13 = _mm256_xor_si256(z13, y13); + r13 = _mm256_srli_epi32(r13, 23); + z13 = _mm256_xor_si256(z13, r13); + + y9 = z11; + y9 = _mm256_add_epi32(y9, z8); + r9 = y9; + y9 = _mm256_slli_epi32(y9, 13); + z9 = _mm256_xor_si256(z9, y9); + r9 = _mm256_srli_epi32(r9, 19); + z9 = _mm256_xor_si256(z9, r9); + + y14 = z12; + y14 = _mm256_add_epi32(y14, z13); + r14 = y14; + y14 = _mm256_slli_epi32(y14, 13); + z14 = _mm256_xor_si256(z14, y14); + r14 = _mm256_srli_epi32(r14, 19); + z14 = _mm256_xor_si256(z14, r14); + + y10 = z8; + y10 = _mm256_add_epi32(y10, z9); + r10 = y10; + y10 = _mm256_slli_epi32(y10, 18); + z10 = _mm256_xor_si256(z10, y10); + r10 = _mm256_srli_epi32(r10, 14); + z10 = _mm256_xor_si256(z10, r10); + + y15 = z13; + y15 = _mm256_add_epi32(y15, z14); + r15 = y15; + y15 = _mm256_slli_epi32(y15, 18); + z15 = _mm256_xor_si256(z15, y15); + r15 = _mm256_srli_epi32(r15, 14); + z15 = _mm256_xor_si256(z15, r15); + } + +/* store data ; this macro first transpose data in-registers, and then store + * them in memory. much faster with icc. */ +#define ONEQUAD_TRANSPOSE(A, B, C, D) \ + { \ + __m128i t0, t1, t2, t3; \ + z##A = _mm256_add_epi32(z##A, orig##A); \ + z##B = _mm256_add_epi32(z##B, orig##B); \ + z##C = _mm256_add_epi32(z##C, orig##C); \ + z##D = _mm256_add_epi32(z##D, orig##D); \ + y##A = _mm256_unpacklo_epi32(z##A, z##B); \ + y##B = _mm256_unpacklo_epi32(z##C, z##D); \ + y##C = _mm256_unpackhi_epi32(z##A, z##B); \ + y##D = _mm256_unpackhi_epi32(z##C, z##D); \ + z##A = _mm256_unpacklo_epi64(y##A, y##B); \ + z##B = _mm256_unpackhi_epi64(y##A, y##B); \ + z##C = _mm256_unpacklo_epi64(y##C, y##D); \ + z##D = _mm256_unpackhi_epi64(y##C, y##D); \ + t0 = _mm_xor_si128(_mm256_extracti128_si256(z##A, 0), \ + _mm_loadu_si128((__m128i*) (m + 0))); \ + _mm_storeu_si128((__m128i*) (c + 0), t0); \ + t1 = _mm_xor_si128(_mm256_extracti128_si256(z##B, 0), \ + _mm_loadu_si128((__m128i*) (m + 64))); \ + _mm_storeu_si128((__m128i*) (c + 64), t1); \ + t2 = _mm_xor_si128(_mm256_extracti128_si256(z##C, 0), \ + _mm_loadu_si128((__m128i*) (m + 128))); \ + _mm_storeu_si128((__m128i*) (c + 128), t2); \ + t3 = _mm_xor_si128(_mm256_extracti128_si256(z##D, 0), \ + _mm_loadu_si128((__m128i*) (m + 192))); \ + _mm_storeu_si128((__m128i*) (c + 192), t3); \ + t0 = _mm_xor_si128(_mm256_extracti128_si256(z##A, 1), \ + _mm_loadu_si128((__m128i*) (m + 256))); \ + _mm_storeu_si128((__m128i*) (c + 256), t0); \ + t1 = _mm_xor_si128(_mm256_extracti128_si256(z##B, 1), \ + _mm_loadu_si128((__m128i*) (m + 320))); \ + _mm_storeu_si128((__m128i*) (c + 320), t1); \ + t2 = _mm_xor_si128(_mm256_extracti128_si256(z##C, 1), \ + _mm_loadu_si128((__m128i*) (m + 384))); \ + _mm_storeu_si128((__m128i*) (c + 384), t2); \ + t3 = _mm_xor_si128(_mm256_extracti128_si256(z##D, 1), \ + _mm_loadu_si128((__m128i*) (m + 448))); \ + _mm_storeu_si128((__m128i*) (c + 448), t3); \ + } + +#define ONEQUAD(A, B, C, D) ONEQUAD_TRANSPOSE(A, B, C, D) + +#define ONEQUAD_UNPCK(A, B, C, D) \ + { \ + z##A = _mm256_add_epi32(z##A, orig##A); \ + z##B = _mm256_add_epi32(z##B, orig##B); \ + z##C = _mm256_add_epi32(z##C, orig##C); \ + z##D = _mm256_add_epi32(z##D, orig##D); \ + y##A = _mm256_unpacklo_epi32(z##A, z##B); \ + y##B = _mm256_unpacklo_epi32(z##C, z##D); \ + y##C = _mm256_unpackhi_epi32(z##A, z##B); \ + y##D = _mm256_unpackhi_epi32(z##C, z##D); \ + z##A = _mm256_unpacklo_epi64(y##A, y##B); \ + z##B = _mm256_unpackhi_epi64(y##A, y##B); \ + z##C = _mm256_unpacklo_epi64(y##C, y##D); \ + z##D = _mm256_unpackhi_epi64(y##C, y##D); \ + } + +#define ONEOCTO(A, B, C, D, A2, B2, C2, D2) \ + { \ + ONEQUAD_UNPCK(A, B, C, D); \ + ONEQUAD_UNPCK(A2, B2, C2, D2); \ + y##A = _mm256_permute2x128_si256(z##A, z##A2, 0x20); \ + y##A2 = _mm256_permute2x128_si256(z##A, z##A2, 0x31); \ + y##B = _mm256_permute2x128_si256(z##B, z##B2, 0x20); \ + y##B2 = _mm256_permute2x128_si256(z##B, z##B2, 0x31); \ + y##C = _mm256_permute2x128_si256(z##C, z##C2, 0x20); \ + y##C2 = _mm256_permute2x128_si256(z##C, z##C2, 0x31); \ + y##D = _mm256_permute2x128_si256(z##D, z##D2, 0x20); \ + y##D2 = _mm256_permute2x128_si256(z##D, z##D2, 0x31); \ + y##A = _mm256_xor_si256(y##A, _mm256_loadu_si256((__m256i*) (m + 0))); \ + y##B = \ + _mm256_xor_si256(y##B, _mm256_loadu_si256((__m256i*) (m + 64))); \ + y##C = \ + _mm256_xor_si256(y##C, _mm256_loadu_si256((__m256i*) (m + 128))); \ + y##D = \ + _mm256_xor_si256(y##D, _mm256_loadu_si256((__m256i*) (m + 192))); \ + y##A2 = \ + _mm256_xor_si256(y##A2, _mm256_loadu_si256((__m256i*) (m + 256))); \ + y##B2 = \ + _mm256_xor_si256(y##B2, _mm256_loadu_si256((__m256i*) (m + 320))); \ + y##C2 = \ + _mm256_xor_si256(y##C2, _mm256_loadu_si256((__m256i*) (m + 384))); \ + y##D2 = \ + _mm256_xor_si256(y##D2, _mm256_loadu_si256((__m256i*) (m + 448))); \ + _mm256_storeu_si256((__m256i*) (c + 0), y##A); \ + _mm256_storeu_si256((__m256i*) (c + 64), y##B); \ + _mm256_storeu_si256((__m256i*) (c + 128), y##C); \ + _mm256_storeu_si256((__m256i*) (c + 192), y##D); \ + _mm256_storeu_si256((__m256i*) (c + 256), y##A2); \ + _mm256_storeu_si256((__m256i*) (c + 320), y##B2); \ + _mm256_storeu_si256((__m256i*) (c + 384), y##C2); \ + _mm256_storeu_si256((__m256i*) (c + 448), y##D2); \ + } + + ONEOCTO(0, 1, 2, 3, 4, 5, 6, 7); + m += 32; + c += 32; + ONEOCTO(8, 9, 10, 11, 12, 13, 14, 15); + m -= 32; + c -= 32; + +#undef ONEQUAD +#undef ONEQUAD_TRANSPOSE +#undef ONEQUAD_UNPCK +#undef ONEOCTO + + bytes -= 512; + c += 512; + m += 512; + } +} diff --git a/libs/libsodium/src/crypto_stream/salsa2012/ref/stream_salsa2012_ref.c b/libs/libsodium/src/crypto_stream/salsa2012/ref/stream_salsa2012_ref.c new file mode 100644 index 0000000000..bfdfeedba3 --- /dev/null +++ b/libs/libsodium/src/crypto_stream/salsa2012/ref/stream_salsa2012_ref.c @@ -0,0 +1,106 @@ +/* +version 20140420 +D. J. Bernstein +Public domain. +*/ + +#include <stdint.h> + +#include "crypto_core_salsa2012.h" +#include "crypto_stream_salsa2012.h" +#include "utils.h" + +int +crypto_stream_salsa2012(unsigned char *c, unsigned long long clen, + const unsigned char *n, const unsigned char *k) +{ + unsigned char in[16]; + unsigned char block[64]; + unsigned char kcopy[32]; + unsigned int i; + unsigned int u; + + if (!clen) { + return 0; + } + for (i = 0; i < 32; ++i) { + kcopy[i] = k[i]; + } + for (i = 0; i < 8; ++i) { + in[i] = n[i]; + } + for (i = 8; i < 16; ++i) { + in[i] = 0; + } + while (clen >= 64) { + crypto_core_salsa2012(c, in, kcopy, NULL); + u = 1; + for (i = 8; i < 16; ++i) { + u += (unsigned int)in[i]; + in[i] = u; + u >>= 8; + } + clen -= 64; + c += 64; + } + if (clen) { + crypto_core_salsa2012(block, in, kcopy, NULL); + for (i = 0; i < (unsigned int)clen; ++i) { + c[i] = block[i]; + } + } + sodium_memzero(block, sizeof block); + sodium_memzero(kcopy, sizeof kcopy); + + return 0; +} + +int +crypto_stream_salsa2012_xor(unsigned char *c, const unsigned char *m, + unsigned long long mlen, const unsigned char *n, + const unsigned char *k) +{ + unsigned char in[16]; + unsigned char block[64]; + unsigned char kcopy[32]; + unsigned int i; + unsigned int u; + + if (!mlen) { + return 0; + } + for (i = 0; i < 32; ++i) { + kcopy[i] = k[i]; + } + for (i = 0; i < 8; ++i) { + in[i] = n[i]; + } + for (i = 8; i < 16; ++i) { + in[i] = 0; + } + while (mlen >= 64) { + crypto_core_salsa2012(block, in, kcopy, NULL); + for (i = 0; i < 64; ++i) { + c[i] = m[i] ^ block[i]; + } + u = 1; + for (i = 8; i < 16; ++i) { + u += (unsigned int)in[i]; + in[i] = u; + u >>= 8; + } + mlen -= 64; + c += 64; + m += 64; + } + if (mlen) { + crypto_core_salsa2012(block, in, kcopy, NULL); + for (i = 0; i < (unsigned int)mlen; ++i) { + c[i] = m[i] ^ block[i]; + } + } + sodium_memzero(block, sizeof block); + sodium_memzero(kcopy, sizeof kcopy); + + return 0; +} diff --git a/libs/libsodium/src/crypto_stream/salsa2012/stream_salsa2012.c b/libs/libsodium/src/crypto_stream/salsa2012/stream_salsa2012.c new file mode 100644 index 0000000000..d0cc0f68ee --- /dev/null +++ b/libs/libsodium/src/crypto_stream/salsa2012/stream_salsa2012.c @@ -0,0 +1,26 @@ +#include "crypto_stream_salsa2012.h" +#include "randombytes.h" + +size_t +crypto_stream_salsa2012_keybytes(void) +{ + return crypto_stream_salsa2012_KEYBYTES; +} + +size_t +crypto_stream_salsa2012_noncebytes(void) +{ + return crypto_stream_salsa2012_NONCEBYTES; +} + +size_t +crypto_stream_salsa2012_messagebytes_max(void) +{ + return crypto_stream_salsa2012_MESSAGEBYTES_MAX; +} + +void +crypto_stream_salsa2012_keygen(unsigned char k[crypto_stream_salsa2012_KEYBYTES]) +{ + randombytes_buf(k, crypto_stream_salsa2012_KEYBYTES); +} diff --git a/libs/libsodium/src/crypto_stream/salsa208/ref/stream_salsa208_ref.c b/libs/libsodium/src/crypto_stream/salsa208/ref/stream_salsa208_ref.c new file mode 100644 index 0000000000..7ec0c4e78e --- /dev/null +++ b/libs/libsodium/src/crypto_stream/salsa208/ref/stream_salsa208_ref.c @@ -0,0 +1,106 @@ +/* +version 20140420 +D. J. Bernstein +Public domain. +*/ + +#include <stdint.h> + +#include "crypto_core_salsa208.h" +#include "crypto_stream_salsa208.h" +#include "utils.h" + +int +crypto_stream_salsa208(unsigned char *c, unsigned long long clen, + const unsigned char *n, const unsigned char *k) +{ + unsigned char in[16]; + unsigned char block[64]; + unsigned char kcopy[32]; + unsigned int i; + unsigned int u; + + if (!clen) { + return 0; + } + for (i = 0; i < 32; ++i) { + kcopy[i] = k[i]; + } + for (i = 0; i < 8; ++i) { + in[i] = n[i]; + } + for (i = 8; i < 16; ++i) { + in[i] = 0; + } + while (clen >= 64) { + crypto_core_salsa208(c, in, kcopy, NULL); + u = 1; + for (i = 8; i < 16; ++i) { + u += (unsigned int)in[i]; + in[i] = u; + u >>= 8; + } + clen -= 64; + c += 64; + } + if (clen) { + crypto_core_salsa208(block, in, kcopy, NULL); + for (i = 0; i < (unsigned int)clen; ++i) { + c[i] = block[i]; + } + } + sodium_memzero(block, sizeof block); + sodium_memzero(kcopy, sizeof kcopy); + + return 0; +} + +int +crypto_stream_salsa208_xor(unsigned char *c, const unsigned char *m, + unsigned long long mlen, const unsigned char *n, + const unsigned char *k) +{ + unsigned char in[16]; + unsigned char block[64]; + unsigned char kcopy[32]; + unsigned int i; + unsigned int u; + + if (!mlen) { + return 0; + } + for (i = 0; i < 32; ++i) { + kcopy[i] = k[i]; + } + for (i = 0; i < 8; ++i) { + in[i] = n[i]; + } + for (i = 8; i < 16; ++i) { + in[i] = 0; + } + while (mlen >= 64) { + crypto_core_salsa208(block, in, kcopy, NULL); + for (i = 0; i < 64; ++i) { + c[i] = m[i] ^ block[i]; + } + u = 1; + for (i = 8; i < 16; ++i) { + u += (unsigned int)in[i]; + in[i] = u; + u >>= 8; + } + mlen -= 64; + c += 64; + m += 64; + } + if (mlen) { + crypto_core_salsa208(block, in, kcopy, NULL); + for (i = 0; i < (unsigned int)mlen; ++i) { + c[i] = m[i] ^ block[i]; + } + } + sodium_memzero(block, sizeof block); + sodium_memzero(kcopy, sizeof kcopy); + + return 0; +} diff --git a/libs/libsodium/src/crypto_stream/salsa208/stream_salsa208.c b/libs/libsodium/src/crypto_stream/salsa208/stream_salsa208.c new file mode 100644 index 0000000000..b79bda5ec2 --- /dev/null +++ b/libs/libsodium/src/crypto_stream/salsa208/stream_salsa208.c @@ -0,0 +1,26 @@ +#include "crypto_stream_salsa208.h" +#include "randombytes.h" + +size_t +crypto_stream_salsa208_keybytes(void) +{ + return crypto_stream_salsa208_KEYBYTES; +} + +size_t +crypto_stream_salsa208_noncebytes(void) +{ + return crypto_stream_salsa208_NONCEBYTES; +} + +size_t +crypto_stream_salsa208_messagebytes_max(void) +{ + return crypto_stream_salsa208_MESSAGEBYTES_MAX; +} + +void +crypto_stream_salsa208_keygen(unsigned char k[crypto_stream_salsa208_KEYBYTES]) +{ + randombytes_buf(k, crypto_stream_salsa208_KEYBYTES); +} diff --git a/libs/libsodium/src/crypto_stream/xchacha20/stream_xchacha20.c b/libs/libsodium/src/crypto_stream/xchacha20/stream_xchacha20.c new file mode 100644 index 0000000000..8b1bc09abd --- /dev/null +++ b/libs/libsodium/src/crypto_stream/xchacha20/stream_xchacha20.c @@ -0,0 +1,69 @@ + +#include <stdlib.h> + +#include "crypto_core_hchacha20.h" +#include "crypto_stream_chacha20.h" +#include "crypto_stream_xchacha20.h" +#include "private/common.h" +#include "randombytes.h" + +size_t +crypto_stream_xchacha20_keybytes(void) +{ + return crypto_stream_xchacha20_KEYBYTES; +} + +size_t +crypto_stream_xchacha20_noncebytes(void) +{ + return crypto_stream_xchacha20_NONCEBYTES; +} + +size_t +crypto_stream_xchacha20_messagebytes_max(void) +{ + return crypto_stream_xchacha20_MESSAGEBYTES_MAX; +} + +int +crypto_stream_xchacha20(unsigned char *c, unsigned long long clen, + const unsigned char *n, const unsigned char *k) +{ + unsigned char k2[crypto_core_hchacha20_OUTPUTBYTES]; + + crypto_core_hchacha20(k2, n, k, NULL); + COMPILER_ASSERT(crypto_stream_chacha20_KEYBYTES <= sizeof k2); + COMPILER_ASSERT(crypto_stream_chacha20_NONCEBYTES == + crypto_stream_xchacha20_NONCEBYTES - + crypto_core_hchacha20_INPUTBYTES); + + return crypto_stream_chacha20(c, clen, n + crypto_core_hchacha20_INPUTBYTES, + k2); +} + +int +crypto_stream_xchacha20_xor_ic(unsigned char *c, const unsigned char *m, + unsigned long long mlen, const unsigned char *n, + uint64_t ic, const unsigned char *k) +{ + unsigned char k2[crypto_core_hchacha20_OUTPUTBYTES]; + + crypto_core_hchacha20(k2, n, k, NULL); + return crypto_stream_chacha20_xor_ic( + c, m, mlen, n + crypto_core_hchacha20_INPUTBYTES, ic, k2); +} + +int +crypto_stream_xchacha20_xor(unsigned char *c, const unsigned char *m, + unsigned long long mlen, const unsigned char *n, + const unsigned char *k) +{ + return crypto_stream_xchacha20_xor_ic(c, m, mlen, n, 0U, k); +} + +void +crypto_stream_xchacha20_keygen( + unsigned char k[crypto_stream_xchacha20_KEYBYTES]) +{ + randombytes_buf(k, crypto_stream_xchacha20_KEYBYTES); +} diff --git a/libs/libsodium/src/crypto_stream/xsalsa20/stream_xsalsa20.c b/libs/libsodium/src/crypto_stream/xsalsa20/stream_xsalsa20.c new file mode 100644 index 0000000000..dc831a94d8 --- /dev/null +++ b/libs/libsodium/src/crypto_stream/xsalsa20/stream_xsalsa20.c @@ -0,0 +1,66 @@ +#include "crypto_core_hsalsa20.h" +#include "crypto_stream_salsa20.h" +#include "crypto_stream_xsalsa20.h" +#include "randombytes.h" +#include "utils.h" + +int +crypto_stream_xsalsa20(unsigned char *c, unsigned long long clen, + const unsigned char *n, const unsigned char *k) +{ + unsigned char subkey[32]; + int ret; + + crypto_core_hsalsa20(subkey, n, k, NULL); + ret = crypto_stream_salsa20(c, clen, n + 16, subkey); + sodium_memzero(subkey, sizeof subkey); + + return ret; +} + +int +crypto_stream_xsalsa20_xor_ic(unsigned char *c, const unsigned char *m, + unsigned long long mlen, const unsigned char *n, + uint64_t ic, const unsigned char *k) +{ + unsigned char subkey[32]; + int ret; + + crypto_core_hsalsa20(subkey, n, k, NULL); + ret = crypto_stream_salsa20_xor_ic(c, m, mlen, n + 16, ic, subkey); + sodium_memzero(subkey, sizeof subkey); + + return ret; +} + +int +crypto_stream_xsalsa20_xor(unsigned char *c, const unsigned char *m, + unsigned long long mlen, const unsigned char *n, + const unsigned char *k) +{ + return crypto_stream_xsalsa20_xor_ic(c, m, mlen, n, 0ULL, k); +} + +size_t +crypto_stream_xsalsa20_keybytes(void) +{ + return crypto_stream_xsalsa20_KEYBYTES; +} + +size_t +crypto_stream_xsalsa20_noncebytes(void) +{ + return crypto_stream_xsalsa20_NONCEBYTES; +} + +size_t +crypto_stream_xsalsa20_messagebytes_max(void) +{ + return crypto_stream_xsalsa20_MESSAGEBYTES_MAX; +} + +void +crypto_stream_xsalsa20_keygen(unsigned char k[crypto_stream_xsalsa20_KEYBYTES]) +{ + randombytes_buf(k, crypto_stream_xsalsa20_KEYBYTES); +} diff --git a/libs/libsodium/src/crypto_verify/sodium/verify.c b/libs/libsodium/src/crypto_verify/sodium/verify.c new file mode 100644 index 0000000000..ffebf220a0 --- /dev/null +++ b/libs/libsodium/src/crypto_verify/sodium/verify.c @@ -0,0 +1,98 @@ + +#include <stddef.h> +#include <stdint.h> + +#include "crypto_verify_16.h" +#include "crypto_verify_32.h" +#include "crypto_verify_64.h" + +size_t +crypto_verify_16_bytes(void) +{ + return crypto_verify_16_BYTES; +} + +size_t +crypto_verify_32_bytes(void) +{ + return crypto_verify_32_BYTES; +} + +size_t +crypto_verify_64_bytes(void) +{ + return crypto_verify_64_BYTES; +} + +#if defined(HAVE_EMMINTRIN_H) && defined(__SSE2__) + +# ifdef __GNUC__ +# pragma GCC target("sse2") +# endif +# include <emmintrin.h> + +static inline int +crypto_verify_n(const unsigned char *x_, const unsigned char *y_, + const int n) +{ + const __m128i zero = _mm_setzero_si128(); + volatile __m128i v1, v2, z; + volatile int m; + int i; + + const volatile __m128i *volatile x = + (const volatile __m128i *volatile) (const void *) x_; + const volatile __m128i *volatile y = + (const volatile __m128i *volatile) (const void *) y_; + v1 = _mm_loadu_si128((const __m128i *) &x[0]); + v2 = _mm_loadu_si128((const __m128i *) &y[0]); + z = _mm_xor_si128(v1, v2); + for (i = 1; i < n / 16; i++) { + v1 = _mm_loadu_si128((const __m128i *) &x[i]); + v2 = _mm_loadu_si128((const __m128i *) &y[i]); + z = _mm_or_si128(z, _mm_xor_si128(v1, v2)); + } + m = _mm_movemask_epi8(_mm_cmpeq_epi32(z, zero)); + v1 = zero; v2 = zero; z = zero; + + return (int) (((uint32_t) m + 1U) >> 16) - 1; +} + +#else + +static inline int +crypto_verify_n(const unsigned char *x_, const unsigned char *y_, + const int n) +{ + const volatile unsigned char *volatile x = + (const volatile unsigned char *volatile) x_; + const volatile unsigned char *volatile y = + (const volatile unsigned char *volatile) y_; + volatile uint_fast16_t d = 0U; + int i; + + for (i = 0; i < n; i++) { + d |= x[i] ^ y[i]; + } + return (1 & ((d - 1) >> 8)) - 1; +} + +#endif + +int +crypto_verify_16(const unsigned char *x, const unsigned char *y) +{ + return crypto_verify_n(x, y, crypto_verify_16_BYTES); +} + +int +crypto_verify_32(const unsigned char *x, const unsigned char *y) +{ + return crypto_verify_n(x, y, crypto_verify_32_BYTES); +} + +int +crypto_verify_64(const unsigned char *x, const unsigned char *y) +{ + return crypto_verify_n(x, y, crypto_verify_64_BYTES); +} diff --git a/libs/libsodium/src/include/Makefile.am b/libs/libsodium/src/include/Makefile.am new file mode 100644 index 0000000000..b70c22b39b --- /dev/null +++ b/libs/libsodium/src/include/Makefile.am @@ -0,0 +1,75 @@ + +SODIUM_EXPORT = \ + sodium.h \ + sodium/core.h \ + sodium/crypto_aead_aes256gcm.h \ + sodium/crypto_aead_chacha20poly1305.h \ + sodium/crypto_aead_xchacha20poly1305.h \ + sodium/crypto_auth.h \ + sodium/crypto_auth_hmacsha256.h \ + sodium/crypto_auth_hmacsha512.h \ + sodium/crypto_auth_hmacsha512256.h \ + sodium/crypto_box.h \ + sodium/crypto_box_curve25519xchacha20poly1305.h \ + sodium/crypto_box_curve25519xsalsa20poly1305.h \ + sodium/crypto_core_ed25519.h \ + sodium/crypto_core_hchacha20.h \ + sodium/crypto_core_hsalsa20.h \ + sodium/crypto_core_salsa20.h \ + sodium/crypto_core_salsa2012.h \ + sodium/crypto_core_salsa208.h \ + sodium/crypto_generichash.h \ + sodium/crypto_generichash_blake2b.h \ + sodium/crypto_hash.h \ + sodium/crypto_hash_sha256.h \ + sodium/crypto_hash_sha512.h \ + sodium/crypto_kdf.h \ + sodium/crypto_kdf_blake2b.h \ + sodium/crypto_kx.h \ + sodium/crypto_onetimeauth.h \ + sodium/crypto_onetimeauth_poly1305.h \ + sodium/crypto_pwhash.h \ + sodium/crypto_pwhash_argon2i.h \ + sodium/crypto_pwhash_argon2id.h \ + sodium/crypto_pwhash_scryptsalsa208sha256.h \ + sodium/crypto_scalarmult.h \ + sodium/crypto_scalarmult_curve25519.h \ + sodium/crypto_scalarmult_ed25519.h \ + sodium/crypto_secretbox.h \ + sodium/crypto_secretbox_xchacha20poly1305.h \ + sodium/crypto_secretbox_xsalsa20poly1305.h \ + sodium/crypto_secretstream_xchacha20poly1305.h \ + sodium/crypto_shorthash.h \ + sodium/crypto_shorthash_siphash24.h \ + sodium/crypto_sign.h \ + sodium/crypto_sign_ed25519.h \ + sodium/crypto_sign_edwards25519sha512batch.h \ + sodium/crypto_stream.h \ + sodium/crypto_stream_chacha20.h \ + sodium/crypto_stream_salsa20.h \ + sodium/crypto_stream_salsa2012.h \ + sodium/crypto_stream_salsa208.h \ + sodium/crypto_stream_xchacha20.h \ + sodium/crypto_stream_xsalsa20.h \ + sodium/crypto_verify_16.h \ + sodium/crypto_verify_32.h \ + sodium/crypto_verify_64.h \ + sodium/export.h \ + sodium/randombytes.h \ + sodium/randombytes_salsa20_random.h \ + sodium/randombytes_sysrandom.h \ + sodium/runtime.h \ + sodium/utils.h + +if NATIVECLIENT +SODIUM_EXPORT += \ + sodium/randombytes_nativeclient.h +endif + +EXTRA_SRC = $(SODIUM_EXPORT) \ + sodium/version.h.in + +nobase_include_HEADERS = $(SODIUM_EXPORT) + +nobase_nodist_include_HEADERS = \ + sodium/version.h diff --git a/libs/libsodium/src/include/sodium.h b/libs/libsodium/src/include/sodium.h new file mode 100644 index 0000000000..e7b1af46f0 --- /dev/null +++ b/libs/libsodium/src/include/sodium.h @@ -0,0 +1,70 @@ + +#ifndef sodium_H +#define sodium_H + +#include "sodium/version.h" + +#include "sodium/core.h" +#include "sodium/crypto_aead_aes256gcm.h" +#include "sodium/crypto_aead_chacha20poly1305.h" +#include "sodium/crypto_aead_xchacha20poly1305.h" +#include "sodium/crypto_auth.h" +#include "sodium/crypto_auth_hmacsha256.h" +#include "sodium/crypto_auth_hmacsha512.h" +#include "sodium/crypto_auth_hmacsha512256.h" +#include "sodium/crypto_box.h" +#include "sodium/crypto_box_curve25519xsalsa20poly1305.h" +#include "sodium/crypto_core_hsalsa20.h" +#include "sodium/crypto_core_hchacha20.h" +#include "sodium/crypto_core_salsa20.h" +#include "sodium/crypto_core_salsa2012.h" +#include "sodium/crypto_core_salsa208.h" +#include "sodium/crypto_generichash.h" +#include "sodium/crypto_generichash_blake2b.h" +#include "sodium/crypto_hash.h" +#include "sodium/crypto_hash_sha256.h" +#include "sodium/crypto_hash_sha512.h" +#include "sodium/crypto_kdf.h" +#include "sodium/crypto_kdf_blake2b.h" +#include "sodium/crypto_kx.h" +#include "sodium/crypto_onetimeauth.h" +#include "sodium/crypto_onetimeauth_poly1305.h" +#include "sodium/crypto_pwhash.h" +#include "sodium/crypto_pwhash_argon2i.h" +#include "sodium/crypto_scalarmult.h" +#include "sodium/crypto_scalarmult_curve25519.h" +#include "sodium/crypto_secretbox.h" +#include "sodium/crypto_secretbox_xsalsa20poly1305.h" +#include "sodium/crypto_secretstream_xchacha20poly1305.h" +#include "sodium/crypto_shorthash.h" +#include "sodium/crypto_shorthash_siphash24.h" +#include "sodium/crypto_sign.h" +#include "sodium/crypto_sign_ed25519.h" +#include "sodium/crypto_stream.h" +#include "sodium/crypto_stream_chacha20.h" +#include "sodium/crypto_stream_salsa20.h" +#include "sodium/crypto_stream_xsalsa20.h" +#include "sodium/crypto_verify_16.h" +#include "sodium/crypto_verify_32.h" +#include "sodium/crypto_verify_64.h" +#include "sodium/randombytes.h" +#ifdef __native_client__ +# include "sodium/randombytes_nativeclient.h" +#endif +#include "sodium/randombytes_salsa20_random.h" +#include "sodium/randombytes_sysrandom.h" +#include "sodium/runtime.h" +#include "sodium/utils.h" + +#ifndef SODIUM_LIBRARY_MINIMAL +# include "sodium/crypto_box_curve25519xchacha20poly1305.h" +# include "sodium/crypto_core_ed25519.h" +# include "sodium/crypto_scalarmult_ed25519.h" +# include "sodium/crypto_secretbox_xchacha20poly1305.h" +# include "sodium/crypto_pwhash_scryptsalsa208sha256.h" +# include "sodium/crypto_stream_salsa2012.h" +# include "sodium/crypto_stream_salsa208.h" +# include "sodium/crypto_stream_xchacha20.h" +#endif + +#endif diff --git a/libs/libsodium/src/include/sodium/core.h b/libs/libsodium/src/include/sodium/core.h new file mode 100644 index 0000000000..dd088d2cae --- /dev/null +++ b/libs/libsodium/src/include/sodium/core.h @@ -0,0 +1,28 @@ + +#ifndef sodium_core_H +#define sodium_core_H + +#include "export.h" + +#ifdef __cplusplus +extern "C" { +#endif + +SODIUM_EXPORT +int sodium_init(void) + __attribute__ ((warn_unused_result)); + +/* ---- */ + +SODIUM_EXPORT +int sodium_set_misuse_handler(void (*handler)(void)); + +SODIUM_EXPORT +void sodium_misuse(void) + __attribute__ ((noreturn)); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/libs/libsodium/src/include/sodium/crypto_aead_aes256gcm.h b/libs/libsodium/src/include/sodium/crypto_aead_aes256gcm.h new file mode 100644 index 0000000000..46a3800f37 --- /dev/null +++ b/libs/libsodium/src/include/sodium/crypto_aead_aes256gcm.h @@ -0,0 +1,171 @@ +#ifndef crypto_aead_aes256gcm_H +#define crypto_aead_aes256gcm_H + +/* + * WARNING: Despite being the most popular AEAD construction due to its + * use in TLS, safely using AES-GCM in a different context is tricky. + * + * No more than ~ 350 GB of input data should be encrypted with a given key. + * This is for ~ 16 KB messages -- Actual figures vary according to + * message sizes. + * + * In addition, nonces are short and repeated nonces would totally destroy + * the security of this scheme. + * + * Nonces should thus come from atomic counters, which can be difficult to + * set up in a distributed environment. + * + * Unless you absolutely need AES-GCM, use crypto_aead_xchacha20poly1305_ietf_*() + * instead. It doesn't have any of these limitations. + * Or, if you don't need to authenticate additional data, just stick to + * crypto_secretbox(). + */ + +#include <stddef.h> +#include "export.h" + +#ifdef __cplusplus +# ifdef __GNUC__ +# pragma GCC diagnostic ignored "-Wlong-long" +# endif +extern "C" { +#endif + +SODIUM_EXPORT +int crypto_aead_aes256gcm_is_available(void); + +#define crypto_aead_aes256gcm_KEYBYTES 32U +SODIUM_EXPORT +size_t crypto_aead_aes256gcm_keybytes(void); + +#define crypto_aead_aes256gcm_NSECBYTES 0U +SODIUM_EXPORT +size_t crypto_aead_aes256gcm_nsecbytes(void); + +#define crypto_aead_aes256gcm_NPUBBYTES 12U +SODIUM_EXPORT +size_t crypto_aead_aes256gcm_npubbytes(void); + +#define crypto_aead_aes256gcm_ABYTES 16U +SODIUM_EXPORT +size_t crypto_aead_aes256gcm_abytes(void); + +#define crypto_aead_aes256gcm_MESSAGEBYTES_MAX \ + SODIUM_MIN(SODIUM_SIZE_MAX - crypto_aead_aes256gcm_ABYTES, \ + (16ULL * ((1ULL << 32) - 2ULL)) - crypto_aead_aes256gcm_ABYTES) +SODIUM_EXPORT +size_t crypto_aead_aes256gcm_messagebytes_max(void); + +typedef CRYPTO_ALIGN(16) unsigned char crypto_aead_aes256gcm_state[512]; + +SODIUM_EXPORT +size_t crypto_aead_aes256gcm_statebytes(void); + +SODIUM_EXPORT +int crypto_aead_aes256gcm_encrypt(unsigned char *c, + unsigned long long *clen_p, + const unsigned char *m, + unsigned long long mlen, + const unsigned char *ad, + unsigned long long adlen, + const unsigned char *nsec, + const unsigned char *npub, + const unsigned char *k); + +SODIUM_EXPORT +int crypto_aead_aes256gcm_decrypt(unsigned char *m, + unsigned long long *mlen_p, + unsigned char *nsec, + const unsigned char *c, + unsigned long long clen, + const unsigned char *ad, + unsigned long long adlen, + const unsigned char *npub, + const unsigned char *k) + __attribute__ ((warn_unused_result)); + +SODIUM_EXPORT +int crypto_aead_aes256gcm_encrypt_detached(unsigned char *c, + unsigned char *mac, + unsigned long long *maclen_p, + const unsigned char *m, + unsigned long long mlen, + const unsigned char *ad, + unsigned long long adlen, + const unsigned char *nsec, + const unsigned char *npub, + const unsigned char *k); + +SODIUM_EXPORT +int crypto_aead_aes256gcm_decrypt_detached(unsigned char *m, + unsigned char *nsec, + const unsigned char *c, + unsigned long long clen, + const unsigned char *mac, + const unsigned char *ad, + unsigned long long adlen, + const unsigned char *npub, + const unsigned char *k) + __attribute__ ((warn_unused_result)); + +/* -- Precomputation interface -- */ + +SODIUM_EXPORT +int crypto_aead_aes256gcm_beforenm(crypto_aead_aes256gcm_state *ctx_, + const unsigned char *k); + +SODIUM_EXPORT +int crypto_aead_aes256gcm_encrypt_afternm(unsigned char *c, + unsigned long long *clen_p, + const unsigned char *m, + unsigned long long mlen, + const unsigned char *ad, + unsigned long long adlen, + const unsigned char *nsec, + const unsigned char *npub, + const crypto_aead_aes256gcm_state *ctx_); + +SODIUM_EXPORT +int crypto_aead_aes256gcm_decrypt_afternm(unsigned char *m, + unsigned long long *mlen_p, + unsigned char *nsec, + const unsigned char *c, + unsigned long long clen, + const unsigned char *ad, + unsigned long long adlen, + const unsigned char *npub, + const crypto_aead_aes256gcm_state *ctx_) + __attribute__ ((warn_unused_result)); + +SODIUM_EXPORT +int crypto_aead_aes256gcm_encrypt_detached_afternm(unsigned char *c, + unsigned char *mac, + unsigned long long *maclen_p, + const unsigned char *m, + unsigned long long mlen, + const unsigned char *ad, + unsigned long long adlen, + const unsigned char *nsec, + const unsigned char *npub, + const crypto_aead_aes256gcm_state *ctx_); + +SODIUM_EXPORT +int crypto_aead_aes256gcm_decrypt_detached_afternm(unsigned char *m, + unsigned char *nsec, + const unsigned char *c, + unsigned long long clen, + const unsigned char *mac, + const unsigned char *ad, + unsigned long long adlen, + const unsigned char *npub, + const crypto_aead_aes256gcm_state *ctx_) + __attribute__ ((warn_unused_result)); + +SODIUM_EXPORT +void crypto_aead_aes256gcm_keygen(unsigned char k[crypto_aead_aes256gcm_KEYBYTES]); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/libs/libsodium/src/include/sodium/crypto_aead_chacha20poly1305.h b/libs/libsodium/src/include/sodium/crypto_aead_chacha20poly1305.h new file mode 100644 index 0000000000..a575ec7173 --- /dev/null +++ b/libs/libsodium/src/include/sodium/crypto_aead_chacha20poly1305.h @@ -0,0 +1,174 @@ +#ifndef crypto_aead_chacha20poly1305_H +#define crypto_aead_chacha20poly1305_H + +#include <stddef.h> +#include "export.h" + +#ifdef __cplusplus +# ifdef __GNUC__ +# pragma GCC diagnostic ignored "-Wlong-long" +# endif +extern "C" { +#endif + +/* -- IETF ChaCha20-Poly1305 construction with a 96-bit nonce and a 32-bit internal counter -- */ + +#define crypto_aead_chacha20poly1305_ietf_KEYBYTES 32U +SODIUM_EXPORT +size_t crypto_aead_chacha20poly1305_ietf_keybytes(void); + +#define crypto_aead_chacha20poly1305_ietf_NSECBYTES 0U +SODIUM_EXPORT +size_t crypto_aead_chacha20poly1305_ietf_nsecbytes(void); + +#define crypto_aead_chacha20poly1305_ietf_NPUBBYTES 12U + +SODIUM_EXPORT +size_t crypto_aead_chacha20poly1305_ietf_npubbytes(void); + +#define crypto_aead_chacha20poly1305_ietf_ABYTES 16U +SODIUM_EXPORT +size_t crypto_aead_chacha20poly1305_ietf_abytes(void); + +#define crypto_aead_chacha20poly1305_ietf_MESSAGEBYTES_MAX \ + SODIUM_MIN(SODIUM_SIZE_MAX - crypto_aead_chacha20poly1305_ietf_ABYTES, \ + (64ULL * (1ULL << 32) - 64ULL) - crypto_aead_chacha20poly1305_ietf_ABYTES) +SODIUM_EXPORT +size_t crypto_aead_chacha20poly1305_ietf_messagebytes_max(void); + +SODIUM_EXPORT +int crypto_aead_chacha20poly1305_ietf_encrypt(unsigned char *c, + unsigned long long *clen_p, + const unsigned char *m, + unsigned long long mlen, + const unsigned char *ad, + unsigned long long adlen, + const unsigned char *nsec, + const unsigned char *npub, + const unsigned char *k); + +SODIUM_EXPORT +int crypto_aead_chacha20poly1305_ietf_decrypt(unsigned char *m, + unsigned long long *mlen_p, + unsigned char *nsec, + const unsigned char *c, + unsigned long long clen, + const unsigned char *ad, + unsigned long long adlen, + const unsigned char *npub, + const unsigned char *k) + __attribute__ ((warn_unused_result)); + +SODIUM_EXPORT +int crypto_aead_chacha20poly1305_ietf_encrypt_detached(unsigned char *c, + unsigned char *mac, + unsigned long long *maclen_p, + const unsigned char *m, + unsigned long long mlen, + const unsigned char *ad, + unsigned long long adlen, + const unsigned char *nsec, + const unsigned char *npub, + const unsigned char *k); + +SODIUM_EXPORT +int crypto_aead_chacha20poly1305_ietf_decrypt_detached(unsigned char *m, + unsigned char *nsec, + const unsigned char *c, + unsigned long long clen, + const unsigned char *mac, + const unsigned char *ad, + unsigned long long adlen, + const unsigned char *npub, + const unsigned char *k) + __attribute__ ((warn_unused_result)); + +SODIUM_EXPORT +void crypto_aead_chacha20poly1305_ietf_keygen(unsigned char k[crypto_aead_chacha20poly1305_ietf_KEYBYTES]); + +/* -- Original ChaCha20-Poly1305 construction with a 64-bit nonce and a 64-bit internal counter -- */ + +#define crypto_aead_chacha20poly1305_KEYBYTES 32U +SODIUM_EXPORT +size_t crypto_aead_chacha20poly1305_keybytes(void); + +#define crypto_aead_chacha20poly1305_NSECBYTES 0U +SODIUM_EXPORT +size_t crypto_aead_chacha20poly1305_nsecbytes(void); + +#define crypto_aead_chacha20poly1305_NPUBBYTES 8U +SODIUM_EXPORT +size_t crypto_aead_chacha20poly1305_npubbytes(void); + +#define crypto_aead_chacha20poly1305_ABYTES 16U +SODIUM_EXPORT +size_t crypto_aead_chacha20poly1305_abytes(void); + +#define crypto_aead_chacha20poly1305_MESSAGEBYTES_MAX \ + (SODIUM_SIZE_MAX - crypto_aead_chacha20poly1305_ABYTES) +SODIUM_EXPORT +size_t crypto_aead_chacha20poly1305_messagebytes_max(void); + +SODIUM_EXPORT +int crypto_aead_chacha20poly1305_encrypt(unsigned char *c, + unsigned long long *clen_p, + const unsigned char *m, + unsigned long long mlen, + const unsigned char *ad, + unsigned long long adlen, + const unsigned char *nsec, + const unsigned char *npub, + const unsigned char *k); + +SODIUM_EXPORT +int crypto_aead_chacha20poly1305_decrypt(unsigned char *m, + unsigned long long *mlen_p, + unsigned char *nsec, + const unsigned char *c, + unsigned long long clen, + const unsigned char *ad, + unsigned long long adlen, + const unsigned char *npub, + const unsigned char *k) + __attribute__ ((warn_unused_result)); + +SODIUM_EXPORT +int crypto_aead_chacha20poly1305_encrypt_detached(unsigned char *c, + unsigned char *mac, + unsigned long long *maclen_p, + const unsigned char *m, + unsigned long long mlen, + const unsigned char *ad, + unsigned long long adlen, + const unsigned char *nsec, + const unsigned char *npub, + const unsigned char *k); + +SODIUM_EXPORT +int crypto_aead_chacha20poly1305_decrypt_detached(unsigned char *m, + unsigned char *nsec, + const unsigned char *c, + unsigned long long clen, + const unsigned char *mac, + const unsigned char *ad, + unsigned long long adlen, + const unsigned char *npub, + const unsigned char *k) + __attribute__ ((warn_unused_result)); + +SODIUM_EXPORT +void crypto_aead_chacha20poly1305_keygen(unsigned char k[crypto_aead_chacha20poly1305_KEYBYTES]); + +/* Aliases */ + +#define crypto_aead_chacha20poly1305_IETF_KEYBYTES crypto_aead_chacha20poly1305_ietf_KEYBYTES +#define crypto_aead_chacha20poly1305_IETF_NSECBYTES crypto_aead_chacha20poly1305_ietf_NSECBYTES +#define crypto_aead_chacha20poly1305_IETF_NPUBBYTES crypto_aead_chacha20poly1305_ietf_NPUBBYTES +#define crypto_aead_chacha20poly1305_IETF_ABYTES crypto_aead_chacha20poly1305_ietf_ABYTES +#define crypto_aead_chacha20poly1305_IETF_MESSAGEBYTES_MAX crypto_aead_chacha20poly1305_ietf_MESSAGEBYTES_MAX + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/libs/libsodium/src/include/sodium/crypto_aead_xchacha20poly1305.h b/libs/libsodium/src/include/sodium/crypto_aead_xchacha20poly1305.h new file mode 100644 index 0000000000..99692aae9a --- /dev/null +++ b/libs/libsodium/src/include/sodium/crypto_aead_xchacha20poly1305.h @@ -0,0 +1,97 @@ +#ifndef crypto_aead_xchacha20poly1305_H +#define crypto_aead_xchacha20poly1305_H + +#include <stddef.h> +#include "export.h" + +#ifdef __cplusplus +# ifdef __GNUC__ +# pragma GCC diagnostic ignored "-Wlong-long" +# endif +extern "C" { +#endif + +#define crypto_aead_xchacha20poly1305_ietf_KEYBYTES 32U +SODIUM_EXPORT +size_t crypto_aead_xchacha20poly1305_ietf_keybytes(void); + +#define crypto_aead_xchacha20poly1305_ietf_NSECBYTES 0U +SODIUM_EXPORT +size_t crypto_aead_xchacha20poly1305_ietf_nsecbytes(void); + +#define crypto_aead_xchacha20poly1305_ietf_NPUBBYTES 24U +SODIUM_EXPORT +size_t crypto_aead_xchacha20poly1305_ietf_npubbytes(void); + +#define crypto_aead_xchacha20poly1305_ietf_ABYTES 16U +SODIUM_EXPORT +size_t crypto_aead_xchacha20poly1305_ietf_abytes(void); + +#define crypto_aead_xchacha20poly1305_ietf_MESSAGEBYTES_MAX \ + (SODIUM_SIZE_MAX - crypto_aead_xchacha20poly1305_ietf_ABYTES) +SODIUM_EXPORT +size_t crypto_aead_xchacha20poly1305_ietf_messagebytes_max(void); + +SODIUM_EXPORT +int crypto_aead_xchacha20poly1305_ietf_encrypt(unsigned char *c, + unsigned long long *clen_p, + const unsigned char *m, + unsigned long long mlen, + const unsigned char *ad, + unsigned long long adlen, + const unsigned char *nsec, + const unsigned char *npub, + const unsigned char *k); + +SODIUM_EXPORT +int crypto_aead_xchacha20poly1305_ietf_decrypt(unsigned char *m, + unsigned long long *mlen_p, + unsigned char *nsec, + const unsigned char *c, + unsigned long long clen, + const unsigned char *ad, + unsigned long long adlen, + const unsigned char *npub, + const unsigned char *k) + __attribute__ ((warn_unused_result)); + +SODIUM_EXPORT +int crypto_aead_xchacha20poly1305_ietf_encrypt_detached(unsigned char *c, + unsigned char *mac, + unsigned long long *maclen_p, + const unsigned char *m, + unsigned long long mlen, + const unsigned char *ad, + unsigned long long adlen, + const unsigned char *nsec, + const unsigned char *npub, + const unsigned char *k); + +SODIUM_EXPORT +int crypto_aead_xchacha20poly1305_ietf_decrypt_detached(unsigned char *m, + unsigned char *nsec, + const unsigned char *c, + unsigned long long clen, + const unsigned char *mac, + const unsigned char *ad, + unsigned long long adlen, + const unsigned char *npub, + const unsigned char *k) + __attribute__ ((warn_unused_result)); + +SODIUM_EXPORT +void crypto_aead_xchacha20poly1305_ietf_keygen(unsigned char k[crypto_aead_xchacha20poly1305_ietf_KEYBYTES]); + +/* Aliases */ + +#define crypto_aead_xchacha20poly1305_IETF_KEYBYTES crypto_aead_xchacha20poly1305_ietf_KEYBYTES +#define crypto_aead_xchacha20poly1305_IETF_NSECBYTES crypto_aead_xchacha20poly1305_ietf_NSECBYTES +#define crypto_aead_xchacha20poly1305_IETF_NPUBBYTES crypto_aead_xchacha20poly1305_ietf_NPUBBYTES +#define crypto_aead_xchacha20poly1305_IETF_ABYTES crypto_aead_xchacha20poly1305_ietf_ABYTES +#define crypto_aead_xchacha20poly1305_IETF_MESSAGEBYTES_MAX crypto_aead_xchacha20poly1305_ietf_MESSAGEBYTES_MAX + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/libs/libsodium/src/include/sodium/crypto_auth.h b/libs/libsodium/src/include/sodium/crypto_auth.h new file mode 100644 index 0000000000..7174e7bced --- /dev/null +++ b/libs/libsodium/src/include/sodium/crypto_auth.h @@ -0,0 +1,44 @@ +#ifndef crypto_auth_H +#define crypto_auth_H + +#include <stddef.h> + +#include "crypto_auth_hmacsha512256.h" +#include "export.h" + +#ifdef __cplusplus +# ifdef __GNUC__ +# pragma GCC diagnostic ignored "-Wlong-long" +# endif +extern "C" { +#endif + +#define crypto_auth_BYTES crypto_auth_hmacsha512256_BYTES +SODIUM_EXPORT +size_t crypto_auth_bytes(void); + +#define crypto_auth_KEYBYTES crypto_auth_hmacsha512256_KEYBYTES +SODIUM_EXPORT +size_t crypto_auth_keybytes(void); + +#define crypto_auth_PRIMITIVE "hmacsha512256" +SODIUM_EXPORT +const char *crypto_auth_primitive(void); + +SODIUM_EXPORT +int crypto_auth(unsigned char *out, const unsigned char *in, + unsigned long long inlen, const unsigned char *k); + +SODIUM_EXPORT +int crypto_auth_verify(const unsigned char *h, const unsigned char *in, + unsigned long long inlen, const unsigned char *k) + __attribute__ ((warn_unused_result)); + +SODIUM_EXPORT +void crypto_auth_keygen(unsigned char k[crypto_auth_KEYBYTES]); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/libs/libsodium/src/include/sodium/crypto_auth_hmacsha256.h b/libs/libsodium/src/include/sodium/crypto_auth_hmacsha256.h new file mode 100644 index 0000000000..deec5266e6 --- /dev/null +++ b/libs/libsodium/src/include/sodium/crypto_auth_hmacsha256.h @@ -0,0 +1,68 @@ +#ifndef crypto_auth_hmacsha256_H +#define crypto_auth_hmacsha256_H + +#include <stddef.h> +#include "crypto_hash_sha256.h" +#include "export.h" + +#ifdef __cplusplus +# ifdef __GNUC__ +# pragma GCC diagnostic ignored "-Wlong-long" +# endif +extern "C" { +#endif + +#define crypto_auth_hmacsha256_BYTES 32U +SODIUM_EXPORT +size_t crypto_auth_hmacsha256_bytes(void); + +#define crypto_auth_hmacsha256_KEYBYTES 32U +SODIUM_EXPORT +size_t crypto_auth_hmacsha256_keybytes(void); + +SODIUM_EXPORT +int crypto_auth_hmacsha256(unsigned char *out, + const unsigned char *in, + unsigned long long inlen, + const unsigned char *k); + +SODIUM_EXPORT +int crypto_auth_hmacsha256_verify(const unsigned char *h, + const unsigned char *in, + unsigned long long inlen, + const unsigned char *k) + __attribute__ ((warn_unused_result)); + +/* ------------------------------------------------------------------------- */ + +typedef struct crypto_auth_hmacsha256_state { + crypto_hash_sha256_state ictx; + crypto_hash_sha256_state octx; +} crypto_auth_hmacsha256_state; + +SODIUM_EXPORT +size_t crypto_auth_hmacsha256_statebytes(void); + +SODIUM_EXPORT +int crypto_auth_hmacsha256_init(crypto_auth_hmacsha256_state *state, + const unsigned char *key, + size_t keylen); + +SODIUM_EXPORT +int crypto_auth_hmacsha256_update(crypto_auth_hmacsha256_state *state, + const unsigned char *in, + unsigned long long inlen); + +SODIUM_EXPORT +int crypto_auth_hmacsha256_final(crypto_auth_hmacsha256_state *state, + unsigned char *out); + + +SODIUM_EXPORT +void crypto_auth_hmacsha256_keygen(unsigned char k[crypto_auth_hmacsha256_KEYBYTES]); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/libs/libsodium/src/include/sodium/crypto_auth_hmacsha512.h b/libs/libsodium/src/include/sodium/crypto_auth_hmacsha512.h new file mode 100644 index 0000000000..77a55fbc00 --- /dev/null +++ b/libs/libsodium/src/include/sodium/crypto_auth_hmacsha512.h @@ -0,0 +1,67 @@ +#ifndef crypto_auth_hmacsha512_H +#define crypto_auth_hmacsha512_H + +#include <stddef.h> +#include "crypto_hash_sha512.h" +#include "export.h" + +#ifdef __cplusplus +# ifdef __GNUC__ +# pragma GCC diagnostic ignored "-Wlong-long" +# endif +extern "C" { +#endif + +#define crypto_auth_hmacsha512_BYTES 64U +SODIUM_EXPORT +size_t crypto_auth_hmacsha512_bytes(void); + +#define crypto_auth_hmacsha512_KEYBYTES 32U +SODIUM_EXPORT +size_t crypto_auth_hmacsha512_keybytes(void); + +SODIUM_EXPORT +int crypto_auth_hmacsha512(unsigned char *out, + const unsigned char *in, + unsigned long long inlen, + const unsigned char *k); + +SODIUM_EXPORT +int crypto_auth_hmacsha512_verify(const unsigned char *h, + const unsigned char *in, + unsigned long long inlen, + const unsigned char *k) + __attribute__ ((warn_unused_result)); + +/* ------------------------------------------------------------------------- */ + +typedef struct crypto_auth_hmacsha512_state { + crypto_hash_sha512_state ictx; + crypto_hash_sha512_state octx; +} crypto_auth_hmacsha512_state; + +SODIUM_EXPORT +size_t crypto_auth_hmacsha512_statebytes(void); + +SODIUM_EXPORT +int crypto_auth_hmacsha512_init(crypto_auth_hmacsha512_state *state, + const unsigned char *key, + size_t keylen); + +SODIUM_EXPORT +int crypto_auth_hmacsha512_update(crypto_auth_hmacsha512_state *state, + const unsigned char *in, + unsigned long long inlen); + +SODIUM_EXPORT +int crypto_auth_hmacsha512_final(crypto_auth_hmacsha512_state *state, + unsigned char *out); + +SODIUM_EXPORT +void crypto_auth_hmacsha512_keygen(unsigned char k[crypto_auth_hmacsha512_KEYBYTES]); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/libs/libsodium/src/include/sodium/crypto_auth_hmacsha512256.h b/libs/libsodium/src/include/sodium/crypto_auth_hmacsha512256.h new file mode 100644 index 0000000000..4842f3debc --- /dev/null +++ b/libs/libsodium/src/include/sodium/crypto_auth_hmacsha512256.h @@ -0,0 +1,62 @@ +#ifndef crypto_auth_hmacsha512256_H +#define crypto_auth_hmacsha512256_H + +#include <stddef.h> +#include "crypto_auth_hmacsha512.h" +#include "export.h" + +#ifdef __cplusplus +# ifdef __GNUC__ +# pragma GCC diagnostic ignored "-Wlong-long" +# endif +extern "C" { +#endif + +#define crypto_auth_hmacsha512256_BYTES 32U +SODIUM_EXPORT +size_t crypto_auth_hmacsha512256_bytes(void); + +#define crypto_auth_hmacsha512256_KEYBYTES 32U +SODIUM_EXPORT +size_t crypto_auth_hmacsha512256_keybytes(void); + +SODIUM_EXPORT +int crypto_auth_hmacsha512256(unsigned char *out, const unsigned char *in, + unsigned long long inlen,const unsigned char *k); + +SODIUM_EXPORT +int crypto_auth_hmacsha512256_verify(const unsigned char *h, + const unsigned char *in, + unsigned long long inlen, + const unsigned char *k) + __attribute__ ((warn_unused_result)); + +/* ------------------------------------------------------------------------- */ + +typedef crypto_auth_hmacsha512_state crypto_auth_hmacsha512256_state; + +SODIUM_EXPORT +size_t crypto_auth_hmacsha512256_statebytes(void); + +SODIUM_EXPORT +int crypto_auth_hmacsha512256_init(crypto_auth_hmacsha512256_state *state, + const unsigned char *key, + size_t keylen); + +SODIUM_EXPORT +int crypto_auth_hmacsha512256_update(crypto_auth_hmacsha512256_state *state, + const unsigned char *in, + unsigned long long inlen); + +SODIUM_EXPORT +int crypto_auth_hmacsha512256_final(crypto_auth_hmacsha512256_state *state, + unsigned char *out); + +SODIUM_EXPORT +void crypto_auth_hmacsha512256_keygen(unsigned char k[crypto_auth_hmacsha512256_KEYBYTES]); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/libs/libsodium/src/include/sodium/crypto_box.h b/libs/libsodium/src/include/sodium/crypto_box.h new file mode 100644 index 0000000000..99ee19a8f6 --- /dev/null +++ b/libs/libsodium/src/include/sodium/crypto_box.h @@ -0,0 +1,173 @@ +#ifndef crypto_box_H +#define crypto_box_H + +/* + * THREAD SAFETY: crypto_box_keypair() is thread-safe, + * provided that sodium_init() was called before. + * + * Other functions are always thread-safe. + */ + +#include <stddef.h> + +#include "crypto_box_curve25519xsalsa20poly1305.h" +#include "export.h" + +#ifdef __cplusplus +# ifdef __GNUC__ +# pragma GCC diagnostic ignored "-Wlong-long" +# endif +extern "C" { +#endif + +#define crypto_box_SEEDBYTES crypto_box_curve25519xsalsa20poly1305_SEEDBYTES +SODIUM_EXPORT +size_t crypto_box_seedbytes(void); + +#define crypto_box_PUBLICKEYBYTES crypto_box_curve25519xsalsa20poly1305_PUBLICKEYBYTES +SODIUM_EXPORT +size_t crypto_box_publickeybytes(void); + +#define crypto_box_SECRETKEYBYTES crypto_box_curve25519xsalsa20poly1305_SECRETKEYBYTES +SODIUM_EXPORT +size_t crypto_box_secretkeybytes(void); + +#define crypto_box_NONCEBYTES crypto_box_curve25519xsalsa20poly1305_NONCEBYTES +SODIUM_EXPORT +size_t crypto_box_noncebytes(void); + +#define crypto_box_MACBYTES crypto_box_curve25519xsalsa20poly1305_MACBYTES +SODIUM_EXPORT +size_t crypto_box_macbytes(void); + +#define crypto_box_MESSAGEBYTES_MAX crypto_box_curve25519xsalsa20poly1305_MESSAGEBYTES_MAX +SODIUM_EXPORT +size_t crypto_box_messagebytes_max(void); + +#define crypto_box_PRIMITIVE "curve25519xsalsa20poly1305" +SODIUM_EXPORT +const char *crypto_box_primitive(void); + +SODIUM_EXPORT +int crypto_box_seed_keypair(unsigned char *pk, unsigned char *sk, + const unsigned char *seed); + +SODIUM_EXPORT +int crypto_box_keypair(unsigned char *pk, unsigned char *sk); + +SODIUM_EXPORT +int crypto_box_easy(unsigned char *c, const unsigned char *m, + unsigned long long mlen, const unsigned char *n, + const unsigned char *pk, const unsigned char *sk) + __attribute__ ((warn_unused_result)); + +SODIUM_EXPORT +int crypto_box_open_easy(unsigned char *m, const unsigned char *c, + unsigned long long clen, const unsigned char *n, + const unsigned char *pk, const unsigned char *sk) + __attribute__ ((warn_unused_result)); + +SODIUM_EXPORT +int crypto_box_detached(unsigned char *c, unsigned char *mac, + const unsigned char *m, unsigned long long mlen, + const unsigned char *n, const unsigned char *pk, + const unsigned char *sk) + __attribute__ ((warn_unused_result)); + +SODIUM_EXPORT +int crypto_box_open_detached(unsigned char *m, const unsigned char *c, + const unsigned char *mac, + unsigned long long clen, + const unsigned char *n, + const unsigned char *pk, + const unsigned char *sk) + __attribute__ ((warn_unused_result)); + +/* -- Precomputation interface -- */ + +#define crypto_box_BEFORENMBYTES crypto_box_curve25519xsalsa20poly1305_BEFORENMBYTES +SODIUM_EXPORT +size_t crypto_box_beforenmbytes(void); + +SODIUM_EXPORT +int crypto_box_beforenm(unsigned char *k, const unsigned char *pk, + const unsigned char *sk) + __attribute__ ((warn_unused_result)); + +SODIUM_EXPORT +int crypto_box_easy_afternm(unsigned char *c, const unsigned char *m, + unsigned long long mlen, const unsigned char *n, + const unsigned char *k); + +SODIUM_EXPORT +int crypto_box_open_easy_afternm(unsigned char *m, const unsigned char *c, + unsigned long long clen, const unsigned char *n, + const unsigned char *k) + __attribute__ ((warn_unused_result)); + +SODIUM_EXPORT +int crypto_box_detached_afternm(unsigned char *c, unsigned char *mac, + const unsigned char *m, unsigned long long mlen, + const unsigned char *n, const unsigned char *k); + +SODIUM_EXPORT +int crypto_box_open_detached_afternm(unsigned char *m, const unsigned char *c, + const unsigned char *mac, + unsigned long long clen, const unsigned char *n, + const unsigned char *k) + __attribute__ ((warn_unused_result)); + +/* -- Ephemeral SK interface -- */ + +#define crypto_box_SEALBYTES (crypto_box_PUBLICKEYBYTES + crypto_box_MACBYTES) +SODIUM_EXPORT +size_t crypto_box_sealbytes(void); + +SODIUM_EXPORT +int crypto_box_seal(unsigned char *c, const unsigned char *m, + unsigned long long mlen, const unsigned char *pk); + +SODIUM_EXPORT +int crypto_box_seal_open(unsigned char *m, const unsigned char *c, + unsigned long long clen, + const unsigned char *pk, const unsigned char *sk) + __attribute__ ((warn_unused_result)); + +/* -- NaCl compatibility interface ; Requires padding -- */ + +#define crypto_box_ZEROBYTES crypto_box_curve25519xsalsa20poly1305_ZEROBYTES +SODIUM_EXPORT +size_t crypto_box_zerobytes(void); + +#define crypto_box_BOXZEROBYTES crypto_box_curve25519xsalsa20poly1305_BOXZEROBYTES +SODIUM_EXPORT +size_t crypto_box_boxzerobytes(void); + +SODIUM_EXPORT +int crypto_box(unsigned char *c, const unsigned char *m, + unsigned long long mlen, const unsigned char *n, + const unsigned char *pk, const unsigned char *sk) + __attribute__ ((warn_unused_result)); + +SODIUM_EXPORT +int crypto_box_open(unsigned char *m, const unsigned char *c, + unsigned long long clen, const unsigned char *n, + const unsigned char *pk, const unsigned char *sk) + __attribute__ ((warn_unused_result)); + +SODIUM_EXPORT +int crypto_box_afternm(unsigned char *c, const unsigned char *m, + unsigned long long mlen, const unsigned char *n, + const unsigned char *k); + +SODIUM_EXPORT +int crypto_box_open_afternm(unsigned char *m, const unsigned char *c, + unsigned long long clen, const unsigned char *n, + const unsigned char *k) + __attribute__ ((warn_unused_result)); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/libs/libsodium/src/include/sodium/crypto_box_curve25519xchacha20poly1305.h b/libs/libsodium/src/include/sodium/crypto_box_curve25519xchacha20poly1305.h new file mode 100644 index 0000000000..c1cf756687 --- /dev/null +++ b/libs/libsodium/src/include/sodium/crypto_box_curve25519xchacha20poly1305.h @@ -0,0 +1,159 @@ + +#ifndef crypto_box_curve25519xchacha20poly1305_H +#define crypto_box_curve25519xchacha20poly1305_H + +#include <stddef.h> +#include "crypto_stream_xchacha20.h" +#include "export.h" + +#ifdef __cplusplus +# ifdef __GNUC__ +# pragma GCC diagnostic ignored "-Wlong-long" +# endif +extern "C" { +#endif + +#define crypto_box_curve25519xchacha20poly1305_SEEDBYTES 32U +SODIUM_EXPORT +size_t crypto_box_curve25519xchacha20poly1305_seedbytes(void); + +#define crypto_box_curve25519xchacha20poly1305_PUBLICKEYBYTES 32U +SODIUM_EXPORT +size_t crypto_box_curve25519xchacha20poly1305_publickeybytes(void); + +#define crypto_box_curve25519xchacha20poly1305_SECRETKEYBYTES 32U +SODIUM_EXPORT +size_t crypto_box_curve25519xchacha20poly1305_secretkeybytes(void); + +#define crypto_box_curve25519xchacha20poly1305_BEFORENMBYTES 32U +SODIUM_EXPORT +size_t crypto_box_curve25519xchacha20poly1305_beforenmbytes(void); + +#define crypto_box_curve25519xchacha20poly1305_NONCEBYTES 24U +SODIUM_EXPORT +size_t crypto_box_curve25519xchacha20poly1305_noncebytes(void); + +#define crypto_box_curve25519xchacha20poly1305_MACBYTES 16U +SODIUM_EXPORT +size_t crypto_box_curve25519xchacha20poly1305_macbytes(void); + +#define crypto_box_curve25519xchacha20poly1305_MESSAGEBYTES_MAX \ + (crypto_stream_xchacha20_MESSAGEBYTES_MAX - crypto_box_curve25519xchacha20poly1305_MACBYTES) +SODIUM_EXPORT +size_t crypto_box_curve25519xchacha20poly1305_messagebytes_max(void); + +SODIUM_EXPORT +int crypto_box_curve25519xchacha20poly1305_seed_keypair(unsigned char *pk, + unsigned char *sk, + const unsigned char *seed); + +SODIUM_EXPORT +int crypto_box_curve25519xchacha20poly1305_keypair(unsigned char *pk, + unsigned char *sk); + +SODIUM_EXPORT +int crypto_box_curve25519xchacha20poly1305_easy(unsigned char *c, + const unsigned char *m, + unsigned long long mlen, + const unsigned char *n, + const unsigned char *pk, + const unsigned char *sk) + __attribute__ ((warn_unused_result)); + +SODIUM_EXPORT +int crypto_box_curve25519xchacha20poly1305_open_easy(unsigned char *m, + const unsigned char *c, + unsigned long long clen, + const unsigned char *n, + const unsigned char *pk, + const unsigned char *sk) + __attribute__ ((warn_unused_result)); + +SODIUM_EXPORT +int crypto_box_curve25519xchacha20poly1305_detached(unsigned char *c, + unsigned char *mac, + const unsigned char *m, + unsigned long long mlen, + const unsigned char *n, + const unsigned char *pk, + const unsigned char *sk) + __attribute__ ((warn_unused_result)); + +SODIUM_EXPORT +int crypto_box_curve25519xchacha20poly1305_open_detached(unsigned char *m, + const unsigned char *c, + const unsigned char *mac, + unsigned long long clen, + const unsigned char *n, + const unsigned char *pk, + const unsigned char *sk) + __attribute__ ((warn_unused_result)); + +/* -- Precomputation interface -- */ + +SODIUM_EXPORT +int crypto_box_curve25519xchacha20poly1305_beforenm(unsigned char *k, + const unsigned char *pk, + const unsigned char *sk) + __attribute__ ((warn_unused_result)); + +SODIUM_EXPORT +int crypto_box_curve25519xchacha20poly1305_easy_afternm(unsigned char *c, + const unsigned char *m, + unsigned long long mlen, + const unsigned char *n, + const unsigned char *k); + +SODIUM_EXPORT +int crypto_box_curve25519xchacha20poly1305_open_easy_afternm(unsigned char *m, + const unsigned char *c, + unsigned long long clen, + const unsigned char *n, + const unsigned char *k) + __attribute__ ((warn_unused_result)); + +SODIUM_EXPORT +int crypto_box_curve25519xchacha20poly1305_detached_afternm(unsigned char *c, + unsigned char *mac, + const unsigned char *m, + unsigned long long mlen, + const unsigned char *n, + const unsigned char *k); + +SODIUM_EXPORT +int crypto_box_curve25519xchacha20poly1305_open_detached_afternm(unsigned char *m, + const unsigned char *c, + const unsigned char *mac, + unsigned long long clen, + const unsigned char *n, + const unsigned char *k) + __attribute__ ((warn_unused_result)); + +/* -- Ephemeral SK interface -- */ + +#define crypto_box_curve25519xchacha20poly1305_SEALBYTES \ + (crypto_box_curve25519xchacha20poly1305_PUBLICKEYBYTES + \ + crypto_box_curve25519xchacha20poly1305_MACBYTES) + +SODIUM_EXPORT +size_t crypto_box_curve25519xchacha20poly1305_sealbytes(void); + +SODIUM_EXPORT +int crypto_box_curve25519xchacha20poly1305_seal(unsigned char *c, + const unsigned char *m, + unsigned long long mlen, + const unsigned char *pk); + +SODIUM_EXPORT +int crypto_box_curve25519xchacha20poly1305_seal_open(unsigned char *m, + const unsigned char *c, + unsigned long long clen, + const unsigned char *pk, + const unsigned char *sk) + __attribute__ ((warn_unused_result)); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/libs/libsodium/src/include/sodium/crypto_box_curve25519xsalsa20poly1305.h b/libs/libsodium/src/include/sodium/crypto_box_curve25519xsalsa20poly1305.h new file mode 100644 index 0000000000..c5b15f42e4 --- /dev/null +++ b/libs/libsodium/src/include/sodium/crypto_box_curve25519xsalsa20poly1305.h @@ -0,0 +1,109 @@ +#ifndef crypto_box_curve25519xsalsa20poly1305_H +#define crypto_box_curve25519xsalsa20poly1305_H + +#include <stddef.h> +#include "crypto_stream_xsalsa20.h" +#include "export.h" + +#ifdef __cplusplus +# ifdef __GNUC__ +# pragma GCC diagnostic ignored "-Wlong-long" +# endif +extern "C" { +#endif + +#define crypto_box_curve25519xsalsa20poly1305_SEEDBYTES 32U +SODIUM_EXPORT +size_t crypto_box_curve25519xsalsa20poly1305_seedbytes(void); + +#define crypto_box_curve25519xsalsa20poly1305_PUBLICKEYBYTES 32U +SODIUM_EXPORT +size_t crypto_box_curve25519xsalsa20poly1305_publickeybytes(void); + +#define crypto_box_curve25519xsalsa20poly1305_SECRETKEYBYTES 32U +SODIUM_EXPORT +size_t crypto_box_curve25519xsalsa20poly1305_secretkeybytes(void); + +#define crypto_box_curve25519xsalsa20poly1305_BEFORENMBYTES 32U +SODIUM_EXPORT +size_t crypto_box_curve25519xsalsa20poly1305_beforenmbytes(void); + +#define crypto_box_curve25519xsalsa20poly1305_NONCEBYTES 24U +SODIUM_EXPORT +size_t crypto_box_curve25519xsalsa20poly1305_noncebytes(void); + +#define crypto_box_curve25519xsalsa20poly1305_MACBYTES 16U +SODIUM_EXPORT +size_t crypto_box_curve25519xsalsa20poly1305_macbytes(void); + +/* Only for the libsodium API - The NaCl compatibility API would require BOXZEROBYTES extra bytes */ +#define crypto_box_curve25519xsalsa20poly1305_MESSAGEBYTES_MAX \ + (crypto_stream_xsalsa20_MESSAGEBYTES_MAX - crypto_box_curve25519xsalsa20poly1305_MACBYTES) +SODIUM_EXPORT +size_t crypto_box_curve25519xsalsa20poly1305_messagebytes_max(void); + +SODIUM_EXPORT +int crypto_box_curve25519xsalsa20poly1305_seed_keypair(unsigned char *pk, + unsigned char *sk, + const unsigned char *seed); + +SODIUM_EXPORT +int crypto_box_curve25519xsalsa20poly1305_keypair(unsigned char *pk, + unsigned char *sk); + +SODIUM_EXPORT +int crypto_box_curve25519xsalsa20poly1305_beforenm(unsigned char *k, + const unsigned char *pk, + const unsigned char *sk) + __attribute__ ((warn_unused_result)); + +/* -- NaCl compatibility interface ; Requires padding -- */ + +#define crypto_box_curve25519xsalsa20poly1305_BOXZEROBYTES 16U +SODIUM_EXPORT +size_t crypto_box_curve25519xsalsa20poly1305_boxzerobytes(void); + +#define crypto_box_curve25519xsalsa20poly1305_ZEROBYTES \ + (crypto_box_curve25519xsalsa20poly1305_BOXZEROBYTES + \ + crypto_box_curve25519xsalsa20poly1305_MACBYTES) +SODIUM_EXPORT +size_t crypto_box_curve25519xsalsa20poly1305_zerobytes(void); + +SODIUM_EXPORT +int crypto_box_curve25519xsalsa20poly1305(unsigned char *c, + const unsigned char *m, + unsigned long long mlen, + const unsigned char *n, + const unsigned char *pk, + const unsigned char *sk) + __attribute__ ((warn_unused_result)); + +SODIUM_EXPORT +int crypto_box_curve25519xsalsa20poly1305_open(unsigned char *m, + const unsigned char *c, + unsigned long long clen, + const unsigned char *n, + const unsigned char *pk, + const unsigned char *sk) + __attribute__ ((warn_unused_result)); + +SODIUM_EXPORT +int crypto_box_curve25519xsalsa20poly1305_afternm(unsigned char *c, + const unsigned char *m, + unsigned long long mlen, + const unsigned char *n, + const unsigned char *k); + +SODIUM_EXPORT +int crypto_box_curve25519xsalsa20poly1305_open_afternm(unsigned char *m, + const unsigned char *c, + unsigned long long clen, + const unsigned char *n, + const unsigned char *k) + __attribute__ ((warn_unused_result)); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/libs/libsodium/src/include/sodium/crypto_core_ed25519.h b/libs/libsodium/src/include/sodium/crypto_core_ed25519.h new file mode 100644 index 0000000000..1536294b21 --- /dev/null +++ b/libs/libsodium/src/include/sodium/crypto_core_ed25519.h @@ -0,0 +1,37 @@ +#ifndef crypto_core_ed25519_H +#define crypto_core_ed25519_H + +#include <stddef.h> +#include "export.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define crypto_core_ed25519_BYTES 32 +SODIUM_EXPORT +size_t crypto_core_ed25519_bytes(void); + +#define crypto_core_ed25519_UNIFORMBYTES 32 +SODIUM_EXPORT +size_t crypto_core_ed25519_uniformbytes(void); + +SODIUM_EXPORT +int crypto_core_ed25519_is_valid_point(const unsigned char *p); + +SODIUM_EXPORT +int crypto_core_ed25519_add(unsigned char *r, + const unsigned char *p, const unsigned char *q); + +SODIUM_EXPORT +int crypto_core_ed25519_sub(unsigned char *r, + const unsigned char *p, const unsigned char *q); + +SODIUM_EXPORT +int crypto_core_ed25519_from_uniform(unsigned char *p, const unsigned char *r); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/libs/libsodium/src/include/sodium/crypto_core_hchacha20.h b/libs/libsodium/src/include/sodium/crypto_core_hchacha20.h new file mode 100644 index 0000000000..05e5670c10 --- /dev/null +++ b/libs/libsodium/src/include/sodium/crypto_core_hchacha20.h @@ -0,0 +1,35 @@ +#ifndef crypto_core_hchacha20_H +#define crypto_core_hchacha20_H + +#include <stddef.h> +#include "export.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define crypto_core_hchacha20_OUTPUTBYTES 32U +SODIUM_EXPORT +size_t crypto_core_hchacha20_outputbytes(void); + +#define crypto_core_hchacha20_INPUTBYTES 16U +SODIUM_EXPORT +size_t crypto_core_hchacha20_inputbytes(void); + +#define crypto_core_hchacha20_KEYBYTES 32U +SODIUM_EXPORT +size_t crypto_core_hchacha20_keybytes(void); + +#define crypto_core_hchacha20_CONSTBYTES 16U +SODIUM_EXPORT +size_t crypto_core_hchacha20_constbytes(void); + +SODIUM_EXPORT +int crypto_core_hchacha20(unsigned char *out, const unsigned char *in, + const unsigned char *k, const unsigned char *c); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/libs/libsodium/src/include/sodium/crypto_core_hsalsa20.h b/libs/libsodium/src/include/sodium/crypto_core_hsalsa20.h new file mode 100644 index 0000000000..82e475b8f6 --- /dev/null +++ b/libs/libsodium/src/include/sodium/crypto_core_hsalsa20.h @@ -0,0 +1,35 @@ +#ifndef crypto_core_hsalsa20_H +#define crypto_core_hsalsa20_H + +#include <stddef.h> +#include "export.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define crypto_core_hsalsa20_OUTPUTBYTES 32U +SODIUM_EXPORT +size_t crypto_core_hsalsa20_outputbytes(void); + +#define crypto_core_hsalsa20_INPUTBYTES 16U +SODIUM_EXPORT +size_t crypto_core_hsalsa20_inputbytes(void); + +#define crypto_core_hsalsa20_KEYBYTES 32U +SODIUM_EXPORT +size_t crypto_core_hsalsa20_keybytes(void); + +#define crypto_core_hsalsa20_CONSTBYTES 16U +SODIUM_EXPORT +size_t crypto_core_hsalsa20_constbytes(void); + +SODIUM_EXPORT +int crypto_core_hsalsa20(unsigned char *out, const unsigned char *in, + const unsigned char *k, const unsigned char *c); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/libs/libsodium/src/include/sodium/crypto_core_salsa20.h b/libs/libsodium/src/include/sodium/crypto_core_salsa20.h new file mode 100644 index 0000000000..160cc56d2c --- /dev/null +++ b/libs/libsodium/src/include/sodium/crypto_core_salsa20.h @@ -0,0 +1,35 @@ +#ifndef crypto_core_salsa20_H +#define crypto_core_salsa20_H + +#include <stddef.h> +#include "export.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define crypto_core_salsa20_OUTPUTBYTES 64U +SODIUM_EXPORT +size_t crypto_core_salsa20_outputbytes(void); + +#define crypto_core_salsa20_INPUTBYTES 16U +SODIUM_EXPORT +size_t crypto_core_salsa20_inputbytes(void); + +#define crypto_core_salsa20_KEYBYTES 32U +SODIUM_EXPORT +size_t crypto_core_salsa20_keybytes(void); + +#define crypto_core_salsa20_CONSTBYTES 16U +SODIUM_EXPORT +size_t crypto_core_salsa20_constbytes(void); + +SODIUM_EXPORT +int crypto_core_salsa20(unsigned char *out, const unsigned char *in, + const unsigned char *k, const unsigned char *c); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/libs/libsodium/src/include/sodium/crypto_core_salsa2012.h b/libs/libsodium/src/include/sodium/crypto_core_salsa2012.h new file mode 100644 index 0000000000..bdd5f9fdbb --- /dev/null +++ b/libs/libsodium/src/include/sodium/crypto_core_salsa2012.h @@ -0,0 +1,35 @@ +#ifndef crypto_core_salsa2012_H +#define crypto_core_salsa2012_H + +#include <stddef.h> +#include "export.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define crypto_core_salsa2012_OUTPUTBYTES 64U +SODIUM_EXPORT +size_t crypto_core_salsa2012_outputbytes(void); + +#define crypto_core_salsa2012_INPUTBYTES 16U +SODIUM_EXPORT +size_t crypto_core_salsa2012_inputbytes(void); + +#define crypto_core_salsa2012_KEYBYTES 32U +SODIUM_EXPORT +size_t crypto_core_salsa2012_keybytes(void); + +#define crypto_core_salsa2012_CONSTBYTES 16U +SODIUM_EXPORT +size_t crypto_core_salsa2012_constbytes(void); + +SODIUM_EXPORT +int crypto_core_salsa2012(unsigned char *out, const unsigned char *in, + const unsigned char *k, const unsigned char *c); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/libs/libsodium/src/include/sodium/crypto_core_salsa208.h b/libs/libsodium/src/include/sodium/crypto_core_salsa208.h new file mode 100644 index 0000000000..876bda8936 --- /dev/null +++ b/libs/libsodium/src/include/sodium/crypto_core_salsa208.h @@ -0,0 +1,39 @@ +#ifndef crypto_core_salsa208_H +#define crypto_core_salsa208_H + +#include <stddef.h> +#include "export.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define crypto_core_salsa208_OUTPUTBYTES 64U +SODIUM_EXPORT +size_t crypto_core_salsa208_outputbytes(void) + __attribute__ ((deprecated)); + +#define crypto_core_salsa208_INPUTBYTES 16U +SODIUM_EXPORT +size_t crypto_core_salsa208_inputbytes(void) + __attribute__ ((deprecated)); + +#define crypto_core_salsa208_KEYBYTES 32U +SODIUM_EXPORT +size_t crypto_core_salsa208_keybytes(void) + __attribute__ ((deprecated)); + +#define crypto_core_salsa208_CONSTBYTES 16U +SODIUM_EXPORT +size_t crypto_core_salsa208_constbytes(void) + __attribute__ ((deprecated)); + +SODIUM_EXPORT +int crypto_core_salsa208(unsigned char *out, const unsigned char *in, + const unsigned char *k, const unsigned char *c); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/libs/libsodium/src/include/sodium/crypto_generichash.h b/libs/libsodium/src/include/sodium/crypto_generichash.h new file mode 100644 index 0000000000..2398fb9dbb --- /dev/null +++ b/libs/libsodium/src/include/sodium/crypto_generichash.h @@ -0,0 +1,75 @@ +#ifndef crypto_generichash_H +#define crypto_generichash_H + +#include <stddef.h> + +#include "crypto_generichash_blake2b.h" +#include "export.h" + +#ifdef __cplusplus +# ifdef __GNUC__ +# pragma GCC diagnostic ignored "-Wlong-long" +# endif +extern "C" { +#endif + +#define crypto_generichash_BYTES_MIN crypto_generichash_blake2b_BYTES_MIN +SODIUM_EXPORT +size_t crypto_generichash_bytes_min(void); + +#define crypto_generichash_BYTES_MAX crypto_generichash_blake2b_BYTES_MAX +SODIUM_EXPORT +size_t crypto_generichash_bytes_max(void); + +#define crypto_generichash_BYTES crypto_generichash_blake2b_BYTES +SODIUM_EXPORT +size_t crypto_generichash_bytes(void); + +#define crypto_generichash_KEYBYTES_MIN crypto_generichash_blake2b_KEYBYTES_MIN +SODIUM_EXPORT +size_t crypto_generichash_keybytes_min(void); + +#define crypto_generichash_KEYBYTES_MAX crypto_generichash_blake2b_KEYBYTES_MAX +SODIUM_EXPORT +size_t crypto_generichash_keybytes_max(void); + +#define crypto_generichash_KEYBYTES crypto_generichash_blake2b_KEYBYTES +SODIUM_EXPORT +size_t crypto_generichash_keybytes(void); + +#define crypto_generichash_PRIMITIVE "blake2b" +SODIUM_EXPORT +const char *crypto_generichash_primitive(void); + +typedef crypto_generichash_blake2b_state crypto_generichash_state; + +SODIUM_EXPORT +size_t crypto_generichash_statebytes(void); + +SODIUM_EXPORT +int crypto_generichash(unsigned char *out, size_t outlen, + const unsigned char *in, unsigned long long inlen, + const unsigned char *key, size_t keylen); + +SODIUM_EXPORT +int crypto_generichash_init(crypto_generichash_state *state, + const unsigned char *key, + const size_t keylen, const size_t outlen); + +SODIUM_EXPORT +int crypto_generichash_update(crypto_generichash_state *state, + const unsigned char *in, + unsigned long long inlen); + +SODIUM_EXPORT +int crypto_generichash_final(crypto_generichash_state *state, + unsigned char *out, const size_t outlen); + +SODIUM_EXPORT +void crypto_generichash_keygen(unsigned char k[crypto_generichash_KEYBYTES]); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/libs/libsodium/src/include/sodium/crypto_generichash_blake2b.h b/libs/libsodium/src/include/sodium/crypto_generichash_blake2b.h new file mode 100644 index 0000000000..9326a04ad1 --- /dev/null +++ b/libs/libsodium/src/include/sodium/crypto_generichash_blake2b.h @@ -0,0 +1,117 @@ +#ifndef crypto_generichash_blake2b_H +#define crypto_generichash_blake2b_H + +#include <stddef.h> +#include <stdint.h> +#include <stdlib.h> + +#include "export.h" + +#ifdef __cplusplus +# ifdef __GNUC__ +# pragma GCC diagnostic ignored "-Wlong-long" +# endif +extern "C" { +#endif + +#if defined(__IBMC__) || defined(__SUNPRO_C) || defined(__SUNPRO_CC) +# pragma pack(1) +#else +# pragma pack(push, 1) +#endif + +typedef struct CRYPTO_ALIGN(64) crypto_generichash_blake2b_state { + uint64_t h[8]; + uint64_t t[2]; + uint64_t f[2]; + uint8_t buf[2 * 128]; + size_t buflen; + uint8_t last_node; +} crypto_generichash_blake2b_state; + +#if defined(__IBMC__) || defined(__SUNPRO_C) || defined(__SUNPRO_CC) +# pragma pack() +#else +# pragma pack(pop) +#endif + +#define crypto_generichash_blake2b_BYTES_MIN 16U +SODIUM_EXPORT +size_t crypto_generichash_blake2b_bytes_min(void); + +#define crypto_generichash_blake2b_BYTES_MAX 64U +SODIUM_EXPORT +size_t crypto_generichash_blake2b_bytes_max(void); + +#define crypto_generichash_blake2b_BYTES 32U +SODIUM_EXPORT +size_t crypto_generichash_blake2b_bytes(void); + +#define crypto_generichash_blake2b_KEYBYTES_MIN 16U +SODIUM_EXPORT +size_t crypto_generichash_blake2b_keybytes_min(void); + +#define crypto_generichash_blake2b_KEYBYTES_MAX 64U +SODIUM_EXPORT +size_t crypto_generichash_blake2b_keybytes_max(void); + +#define crypto_generichash_blake2b_KEYBYTES 32U +SODIUM_EXPORT +size_t crypto_generichash_blake2b_keybytes(void); + +#define crypto_generichash_blake2b_SALTBYTES 16U +SODIUM_EXPORT +size_t crypto_generichash_blake2b_saltbytes(void); + +#define crypto_generichash_blake2b_PERSONALBYTES 16U +SODIUM_EXPORT +size_t crypto_generichash_blake2b_personalbytes(void); + +SODIUM_EXPORT +size_t crypto_generichash_blake2b_statebytes(void); + +SODIUM_EXPORT +int crypto_generichash_blake2b(unsigned char *out, size_t outlen, + const unsigned char *in, + unsigned long long inlen, + const unsigned char *key, size_t keylen); + +SODIUM_EXPORT +int crypto_generichash_blake2b_salt_personal(unsigned char *out, size_t outlen, + const unsigned char *in, + unsigned long long inlen, + const unsigned char *key, + size_t keylen, + const unsigned char *salt, + const unsigned char *personal); + +SODIUM_EXPORT +int crypto_generichash_blake2b_init(crypto_generichash_blake2b_state *state, + const unsigned char *key, + const size_t keylen, const size_t outlen); + +SODIUM_EXPORT +int crypto_generichash_blake2b_init_salt_personal(crypto_generichash_blake2b_state *state, + const unsigned char *key, + const size_t keylen, const size_t outlen, + const unsigned char *salt, + const unsigned char *personal); + +SODIUM_EXPORT +int crypto_generichash_blake2b_update(crypto_generichash_blake2b_state *state, + const unsigned char *in, + unsigned long long inlen); + +SODIUM_EXPORT +int crypto_generichash_blake2b_final(crypto_generichash_blake2b_state *state, + unsigned char *out, + const size_t outlen); + +SODIUM_EXPORT +void crypto_generichash_blake2b_keygen(unsigned char k[crypto_generichash_blake2b_KEYBYTES]); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/libs/libsodium/src/include/sodium/crypto_hash.h b/libs/libsodium/src/include/sodium/crypto_hash.h new file mode 100644 index 0000000000..302ed5c5ea --- /dev/null +++ b/libs/libsodium/src/include/sodium/crypto_hash.h @@ -0,0 +1,40 @@ +#ifndef crypto_hash_H +#define crypto_hash_H + +/* + * WARNING: Unless you absolutely need to use SHA512 for interoperatibility, + * purposes, you might want to consider crypto_generichash() instead. + * Unlike SHA512, crypto_generichash() is not vulnerable to length + * extension attacks. + */ + +#include <stddef.h> + +#include "crypto_hash_sha512.h" +#include "export.h" + +#ifdef __cplusplus +# ifdef __GNUC__ +# pragma GCC diagnostic ignored "-Wlong-long" +# endif +extern "C" { +#endif + +#define crypto_hash_BYTES crypto_hash_sha512_BYTES +SODIUM_EXPORT +size_t crypto_hash_bytes(void); + +SODIUM_EXPORT +int crypto_hash(unsigned char *out, const unsigned char *in, + unsigned long long inlen); + +#define crypto_hash_PRIMITIVE "sha512" +SODIUM_EXPORT +const char *crypto_hash_primitive(void) + __attribute__ ((warn_unused_result)); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/libs/libsodium/src/include/sodium/crypto_hash_sha256.h b/libs/libsodium/src/include/sodium/crypto_hash_sha256.h new file mode 100644 index 0000000000..f64d16e0e5 --- /dev/null +++ b/libs/libsodium/src/include/sodium/crypto_hash_sha256.h @@ -0,0 +1,57 @@ +#ifndef crypto_hash_sha256_H +#define crypto_hash_sha256_H + +/* + * WARNING: Unless you absolutely need to use SHA256 for interoperatibility, + * purposes, you might want to consider crypto_generichash() instead. + * Unlike SHA256, crypto_generichash() is not vulnerable to length + * extension attacks. + */ + +#include <stddef.h> +#include <stdint.h> +#include <stdlib.h> + +#include "export.h" + +#ifdef __cplusplus +# ifdef __GNUC__ +# pragma GCC diagnostic ignored "-Wlong-long" +# endif +extern "C" { +#endif + +typedef struct crypto_hash_sha256_state { + uint32_t state[8]; + uint64_t count; + uint8_t buf[64]; +} crypto_hash_sha256_state; + +SODIUM_EXPORT +size_t crypto_hash_sha256_statebytes(void); + +#define crypto_hash_sha256_BYTES 32U +SODIUM_EXPORT +size_t crypto_hash_sha256_bytes(void); + +SODIUM_EXPORT +int crypto_hash_sha256(unsigned char *out, const unsigned char *in, + unsigned long long inlen); + +SODIUM_EXPORT +int crypto_hash_sha256_init(crypto_hash_sha256_state *state); + +SODIUM_EXPORT +int crypto_hash_sha256_update(crypto_hash_sha256_state *state, + const unsigned char *in, + unsigned long long inlen); + +SODIUM_EXPORT +int crypto_hash_sha256_final(crypto_hash_sha256_state *state, + unsigned char *out); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/libs/libsodium/src/include/sodium/crypto_hash_sha512.h b/libs/libsodium/src/include/sodium/crypto_hash_sha512.h new file mode 100644 index 0000000000..6b0330f14f --- /dev/null +++ b/libs/libsodium/src/include/sodium/crypto_hash_sha512.h @@ -0,0 +1,57 @@ +#ifndef crypto_hash_sha512_H +#define crypto_hash_sha512_H + +/* + * WARNING: Unless you absolutely need to use SHA512 for interoperatibility, + * purposes, you might want to consider crypto_generichash() instead. + * Unlike SHA512, crypto_generichash() is not vulnerable to length + * extension attacks. + */ + +#include <stddef.h> +#include <stdint.h> +#include <stdlib.h> + +#include "export.h" + +#ifdef __cplusplus +# ifdef __GNUC__ +# pragma GCC diagnostic ignored "-Wlong-long" +# endif +extern "C" { +#endif + +typedef struct crypto_hash_sha512_state { + uint64_t state[8]; + uint64_t count[2]; + uint8_t buf[128]; +} crypto_hash_sha512_state; + +SODIUM_EXPORT +size_t crypto_hash_sha512_statebytes(void); + +#define crypto_hash_sha512_BYTES 64U +SODIUM_EXPORT +size_t crypto_hash_sha512_bytes(void); + +SODIUM_EXPORT +int crypto_hash_sha512(unsigned char *out, const unsigned char *in, + unsigned long long inlen); + +SODIUM_EXPORT +int crypto_hash_sha512_init(crypto_hash_sha512_state *state); + +SODIUM_EXPORT +int crypto_hash_sha512_update(crypto_hash_sha512_state *state, + const unsigned char *in, + unsigned long long inlen); + +SODIUM_EXPORT +int crypto_hash_sha512_final(crypto_hash_sha512_state *state, + unsigned char *out); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/libs/libsodium/src/include/sodium/crypto_kdf.h b/libs/libsodium/src/include/sodium/crypto_kdf.h new file mode 100644 index 0000000000..52e496a744 --- /dev/null +++ b/libs/libsodium/src/include/sodium/crypto_kdf.h @@ -0,0 +1,51 @@ +#ifndef crypto_kdf_H +#define crypto_kdf_H + +#include <stddef.h> +#include <stdint.h> + +#include "crypto_kdf_blake2b.h" +#include "export.h" + +#ifdef __cplusplus +# ifdef __GNUC__ +# pragma GCC diagnostic ignored "-Wlong-long" +# endif +extern "C" { +#endif + +#define crypto_kdf_BYTES_MIN crypto_kdf_blake2b_BYTES_MIN +SODIUM_EXPORT +size_t crypto_kdf_bytes_min(void); + +#define crypto_kdf_BYTES_MAX crypto_kdf_blake2b_BYTES_MAX +SODIUM_EXPORT +size_t crypto_kdf_bytes_max(void); + +#define crypto_kdf_CONTEXTBYTES crypto_kdf_blake2b_CONTEXTBYTES +SODIUM_EXPORT +size_t crypto_kdf_contextbytes(void); + +#define crypto_kdf_KEYBYTES crypto_kdf_blake2b_KEYBYTES +SODIUM_EXPORT +size_t crypto_kdf_keybytes(void); + +#define crypto_kdf_PRIMITIVE "blake2b" +SODIUM_EXPORT +const char *crypto_kdf_primitive(void) + __attribute__ ((warn_unused_result)); + +SODIUM_EXPORT +int crypto_kdf_derive_from_key(unsigned char *subkey, size_t subkey_len, + uint64_t subkey_id, + const char ctx[crypto_kdf_CONTEXTBYTES], + const unsigned char key[crypto_kdf_KEYBYTES]); + +SODIUM_EXPORT +void crypto_kdf_keygen(unsigned char k[crypto_kdf_KEYBYTES]); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/libs/libsodium/src/include/sodium/crypto_kdf_blake2b.h b/libs/libsodium/src/include/sodium/crypto_kdf_blake2b.h new file mode 100644 index 0000000000..5480ebe82f --- /dev/null +++ b/libs/libsodium/src/include/sodium/crypto_kdf_blake2b.h @@ -0,0 +1,42 @@ +#ifndef crypto_kdf_blake2b_H +#define crypto_kdf_blake2b_H + +#include <stddef.h> +#include <stdint.h> + +#include "crypto_kdf_blake2b.h" +#include "export.h" + +#ifdef __cplusplus +# ifdef __GNUC__ +# pragma GCC diagnostic ignored "-Wlong-long" +# endif +extern "C" { +#endif + +#define crypto_kdf_blake2b_BYTES_MIN 16 +SODIUM_EXPORT +size_t crypto_kdf_blake2b_bytes_min(void); + +#define crypto_kdf_blake2b_BYTES_MAX 64 +SODIUM_EXPORT +size_t crypto_kdf_blake2b_bytes_max(void); + +#define crypto_kdf_blake2b_CONTEXTBYTES 8 +SODIUM_EXPORT +size_t crypto_kdf_blake2b_contextbytes(void); + +#define crypto_kdf_blake2b_KEYBYTES 32 +SODIUM_EXPORT +size_t crypto_kdf_blake2b_keybytes(void); + +SODIUM_EXPORT +int crypto_kdf_blake2b_derive_from_key(unsigned char *subkey, size_t subkey_len, + uint64_t subkey_id, + const char ctx[crypto_kdf_blake2b_CONTEXTBYTES], + const unsigned char key[crypto_kdf_blake2b_KEYBYTES]); +#ifdef __cplusplus +} +#endif + +#endif diff --git a/libs/libsodium/src/include/sodium/crypto_kx.h b/libs/libsodium/src/include/sodium/crypto_kx.h new file mode 100644 index 0000000000..d1fce90da5 --- /dev/null +++ b/libs/libsodium/src/include/sodium/crypto_kx.h @@ -0,0 +1,64 @@ +#ifndef crypto_kx_H +#define crypto_kx_H + +#include <stddef.h> + +#include "export.h" + +#ifdef __cplusplus +# ifdef __GNUC__ +# pragma GCC diagnostic ignored "-Wlong-long" +# endif +extern "C" { +#endif + +#define crypto_kx_PUBLICKEYBYTES 32 +SODIUM_EXPORT +size_t crypto_kx_publickeybytes(void); + +#define crypto_kx_SECRETKEYBYTES 32 +SODIUM_EXPORT +size_t crypto_kx_secretkeybytes(void); + +#define crypto_kx_SEEDBYTES 32 +SODIUM_EXPORT +size_t crypto_kx_seedbytes(void); + +#define crypto_kx_SESSIONKEYBYTES 32 +SODIUM_EXPORT +size_t crypto_kx_sessionkeybytes(void); + +#define crypto_kx_PRIMITIVE "x25519blake2b" +SODIUM_EXPORT +const char *crypto_kx_primitive(void); + +SODIUM_EXPORT +int crypto_kx_seed_keypair(unsigned char pk[crypto_kx_PUBLICKEYBYTES], + unsigned char sk[crypto_kx_SECRETKEYBYTES], + const unsigned char seed[crypto_kx_SEEDBYTES]); + +SODIUM_EXPORT +int crypto_kx_keypair(unsigned char pk[crypto_kx_PUBLICKEYBYTES], + unsigned char sk[crypto_kx_SECRETKEYBYTES]); + +SODIUM_EXPORT +int crypto_kx_client_session_keys(unsigned char rx[crypto_kx_SESSIONKEYBYTES], + unsigned char tx[crypto_kx_SESSIONKEYBYTES], + const unsigned char client_pk[crypto_kx_PUBLICKEYBYTES], + const unsigned char client_sk[crypto_kx_SECRETKEYBYTES], + const unsigned char server_pk[crypto_kx_PUBLICKEYBYTES]) + __attribute__ ((warn_unused_result)); + +SODIUM_EXPORT +int crypto_kx_server_session_keys(unsigned char rx[crypto_kx_SESSIONKEYBYTES], + unsigned char tx[crypto_kx_SESSIONKEYBYTES], + const unsigned char server_pk[crypto_kx_PUBLICKEYBYTES], + const unsigned char server_sk[crypto_kx_SECRETKEYBYTES], + const unsigned char client_pk[crypto_kx_PUBLICKEYBYTES]) + __attribute__ ((warn_unused_result)); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/libs/libsodium/src/include/sodium/crypto_onetimeauth.h b/libs/libsodium/src/include/sodium/crypto_onetimeauth.h new file mode 100644 index 0000000000..5951c5b82d --- /dev/null +++ b/libs/libsodium/src/include/sodium/crypto_onetimeauth.h @@ -0,0 +1,62 @@ +#ifndef crypto_onetimeauth_H +#define crypto_onetimeauth_H + +#include <stddef.h> + +#include "crypto_onetimeauth_poly1305.h" +#include "export.h" + +#ifdef __cplusplus +# ifdef __GNUC__ +# pragma GCC diagnostic ignored "-Wlong-long" +# endif +extern "C" { +#endif + +typedef crypto_onetimeauth_poly1305_state crypto_onetimeauth_state; + +SODIUM_EXPORT +size_t crypto_onetimeauth_statebytes(void); + +#define crypto_onetimeauth_BYTES crypto_onetimeauth_poly1305_BYTES +SODIUM_EXPORT +size_t crypto_onetimeauth_bytes(void); + +#define crypto_onetimeauth_KEYBYTES crypto_onetimeauth_poly1305_KEYBYTES +SODIUM_EXPORT +size_t crypto_onetimeauth_keybytes(void); + +#define crypto_onetimeauth_PRIMITIVE "poly1305" +SODIUM_EXPORT +const char *crypto_onetimeauth_primitive(void); + +SODIUM_EXPORT +int crypto_onetimeauth(unsigned char *out, const unsigned char *in, + unsigned long long inlen, const unsigned char *k); + +SODIUM_EXPORT +int crypto_onetimeauth_verify(const unsigned char *h, const unsigned char *in, + unsigned long long inlen, const unsigned char *k) + __attribute__ ((warn_unused_result)); + +SODIUM_EXPORT +int crypto_onetimeauth_init(crypto_onetimeauth_state *state, + const unsigned char *key); + +SODIUM_EXPORT +int crypto_onetimeauth_update(crypto_onetimeauth_state *state, + const unsigned char *in, + unsigned long long inlen); + +SODIUM_EXPORT +int crypto_onetimeauth_final(crypto_onetimeauth_state *state, + unsigned char *out); + +SODIUM_EXPORT +void crypto_onetimeauth_keygen(unsigned char k[crypto_onetimeauth_KEYBYTES]); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/libs/libsodium/src/include/sodium/crypto_onetimeauth_poly1305.h b/libs/libsodium/src/include/sodium/crypto_onetimeauth_poly1305.h new file mode 100644 index 0000000000..4b89c4f019 --- /dev/null +++ b/libs/libsodium/src/include/sodium/crypto_onetimeauth_poly1305.h @@ -0,0 +1,67 @@ +#ifndef crypto_onetimeauth_poly1305_H +#define crypto_onetimeauth_poly1305_H + +#ifdef __cplusplus +# ifdef __GNUC__ +# pragma GCC diagnostic ignored "-Wlong-long" +# endif +extern "C" { +#endif + +#include <stdint.h> +#include <stdio.h> +#include <stdlib.h> + +#include <sys/types.h> + +#include "export.h" + +typedef struct CRYPTO_ALIGN(16) crypto_onetimeauth_poly1305_state { + unsigned char opaque[256]; +} crypto_onetimeauth_poly1305_state; + +SODIUM_EXPORT +size_t crypto_onetimeauth_poly1305_statebytes(void); + +#define crypto_onetimeauth_poly1305_BYTES 16U +SODIUM_EXPORT +size_t crypto_onetimeauth_poly1305_bytes(void); + +#define crypto_onetimeauth_poly1305_KEYBYTES 32U +SODIUM_EXPORT +size_t crypto_onetimeauth_poly1305_keybytes(void); + +SODIUM_EXPORT +int crypto_onetimeauth_poly1305(unsigned char *out, + const unsigned char *in, + unsigned long long inlen, + const unsigned char *k); + +SODIUM_EXPORT +int crypto_onetimeauth_poly1305_verify(const unsigned char *h, + const unsigned char *in, + unsigned long long inlen, + const unsigned char *k) + __attribute__ ((warn_unused_result)); + +SODIUM_EXPORT +int crypto_onetimeauth_poly1305_init(crypto_onetimeauth_poly1305_state *state, + const unsigned char *key); + +SODIUM_EXPORT +int crypto_onetimeauth_poly1305_update(crypto_onetimeauth_poly1305_state *state, + const unsigned char *in, + unsigned long long inlen); + +SODIUM_EXPORT +int crypto_onetimeauth_poly1305_final(crypto_onetimeauth_poly1305_state *state, + unsigned char *out); + +SODIUM_EXPORT +void crypto_onetimeauth_poly1305_keygen(unsigned char k[crypto_onetimeauth_poly1305_KEYBYTES]); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/libs/libsodium/src/include/sodium/crypto_pwhash.h b/libs/libsodium/src/include/sodium/crypto_pwhash.h new file mode 100644 index 0000000000..2c76461f44 --- /dev/null +++ b/libs/libsodium/src/include/sodium/crypto_pwhash.h @@ -0,0 +1,147 @@ +#ifndef crypto_pwhash_H +#define crypto_pwhash_H + +#include <stddef.h> + +#include "crypto_pwhash_argon2i.h" +#include "crypto_pwhash_argon2id.h" +#include "export.h" + +#ifdef __cplusplus +# ifdef __GNUC__ +# pragma GCC diagnostic ignored "-Wlong-long" +# endif +extern "C" { +#endif + +#define crypto_pwhash_ALG_ARGON2I13 crypto_pwhash_argon2i_ALG_ARGON2I13 +SODIUM_EXPORT +int crypto_pwhash_alg_argon2i13(void); + +#define crypto_pwhash_ALG_ARGON2ID13 crypto_pwhash_argon2id_ALG_ARGON2ID13 +SODIUM_EXPORT +int crypto_pwhash_alg_argon2id13(void); + +#define crypto_pwhash_ALG_DEFAULT crypto_pwhash_ALG_ARGON2ID13 +SODIUM_EXPORT +int crypto_pwhash_alg_default(void); + +#define crypto_pwhash_BYTES_MIN crypto_pwhash_argon2id_BYTES_MIN +SODIUM_EXPORT +size_t crypto_pwhash_bytes_min(void); + +#define crypto_pwhash_BYTES_MAX crypto_pwhash_argon2id_BYTES_MAX +SODIUM_EXPORT +size_t crypto_pwhash_bytes_max(void); + +#define crypto_pwhash_PASSWD_MIN crypto_pwhash_argon2id_PASSWD_MIN +SODIUM_EXPORT +size_t crypto_pwhash_passwd_min(void); + +#define crypto_pwhash_PASSWD_MAX crypto_pwhash_argon2id_PASSWD_MAX +SODIUM_EXPORT +size_t crypto_pwhash_passwd_max(void); + +#define crypto_pwhash_SALTBYTES crypto_pwhash_argon2id_SALTBYTES +SODIUM_EXPORT +size_t crypto_pwhash_saltbytes(void); + +#define crypto_pwhash_STRBYTES crypto_pwhash_argon2id_STRBYTES +SODIUM_EXPORT +size_t crypto_pwhash_strbytes(void); + +#define crypto_pwhash_STRPREFIX crypto_pwhash_argon2id_STRPREFIX +SODIUM_EXPORT +const char *crypto_pwhash_strprefix(void); + +#define crypto_pwhash_OPSLIMIT_MIN crypto_pwhash_argon2id_OPSLIMIT_MIN +SODIUM_EXPORT +size_t crypto_pwhash_opslimit_min(void); + +#define crypto_pwhash_OPSLIMIT_MAX crypto_pwhash_argon2id_OPSLIMIT_MAX +SODIUM_EXPORT +size_t crypto_pwhash_opslimit_max(void); + +#define crypto_pwhash_MEMLIMIT_MIN crypto_pwhash_argon2id_MEMLIMIT_MIN +SODIUM_EXPORT +size_t crypto_pwhash_memlimit_min(void); + +#define crypto_pwhash_MEMLIMIT_MAX crypto_pwhash_argon2id_MEMLIMIT_MAX +SODIUM_EXPORT +size_t crypto_pwhash_memlimit_max(void); + +#define crypto_pwhash_OPSLIMIT_INTERACTIVE crypto_pwhash_argon2id_OPSLIMIT_INTERACTIVE +SODIUM_EXPORT +size_t crypto_pwhash_opslimit_interactive(void); + +#define crypto_pwhash_MEMLIMIT_INTERACTIVE crypto_pwhash_argon2id_MEMLIMIT_INTERACTIVE +SODIUM_EXPORT +size_t crypto_pwhash_memlimit_interactive(void); + +#define crypto_pwhash_OPSLIMIT_MODERATE crypto_pwhash_argon2id_OPSLIMIT_MODERATE +SODIUM_EXPORT +size_t crypto_pwhash_opslimit_moderate(void); + +#define crypto_pwhash_MEMLIMIT_MODERATE crypto_pwhash_argon2id_MEMLIMIT_MODERATE +SODIUM_EXPORT +size_t crypto_pwhash_memlimit_moderate(void); + +#define crypto_pwhash_OPSLIMIT_SENSITIVE crypto_pwhash_argon2id_OPSLIMIT_SENSITIVE +SODIUM_EXPORT +size_t crypto_pwhash_opslimit_sensitive(void); + +#define crypto_pwhash_MEMLIMIT_SENSITIVE crypto_pwhash_argon2id_MEMLIMIT_SENSITIVE +SODIUM_EXPORT +size_t crypto_pwhash_memlimit_sensitive(void); + +/* + * With this function, do not forget to store all parameters, including the + * algorithm identifier in order to produce deterministic output. + * The crypto_pwhash_* definitions, including crypto_pwhash_ALG_DEFAULT, + * may change. + */ +SODIUM_EXPORT +int crypto_pwhash(unsigned char * const out, unsigned long long outlen, + const char * const passwd, unsigned long long passwdlen, + const unsigned char * const salt, + unsigned long long opslimit, size_t memlimit, int alg) + __attribute__ ((warn_unused_result)); + +/* + * The output string already includes all the required parameters, including + * the algorithm identifier. The string is all that has to be stored in + * order to verify a password. + */ +SODIUM_EXPORT +int crypto_pwhash_str(char out[crypto_pwhash_STRBYTES], + const char * const passwd, unsigned long long passwdlen, + unsigned long long opslimit, size_t memlimit) + __attribute__ ((warn_unused_result)); + +SODIUM_EXPORT +int crypto_pwhash_str_alg(char out[crypto_pwhash_STRBYTES], + const char * const passwd, unsigned long long passwdlen, + unsigned long long opslimit, size_t memlimit, int alg) + __attribute__ ((warn_unused_result)); + +SODIUM_EXPORT +int crypto_pwhash_str_verify(const char str[crypto_pwhash_STRBYTES], + const char * const passwd, + unsigned long long passwdlen) + __attribute__ ((warn_unused_result)); + +SODIUM_EXPORT +int crypto_pwhash_str_needs_rehash(const char str[crypto_pwhash_STRBYTES], + unsigned long long opslimit, size_t memlimit) + __attribute__ ((warn_unused_result)); + +#define crypto_pwhash_PRIMITIVE "argon2i" +SODIUM_EXPORT +const char *crypto_pwhash_primitive(void) + __attribute__ ((warn_unused_result)); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/libs/libsodium/src/include/sodium/crypto_pwhash_argon2i.h b/libs/libsodium/src/include/sodium/crypto_pwhash_argon2i.h new file mode 100644 index 0000000000..8e4c1c3531 --- /dev/null +++ b/libs/libsodium/src/include/sodium/crypto_pwhash_argon2i.h @@ -0,0 +1,122 @@ +#ifndef crypto_pwhash_argon2i_H +#define crypto_pwhash_argon2i_H + +#include <limits.h> +#include <stddef.h> +#include <stdint.h> + +#include "export.h" + +#ifdef __cplusplus +# ifdef __GNUC__ +# pragma GCC diagnostic ignored "-Wlong-long" +# endif +extern "C" { +#endif + +#define crypto_pwhash_argon2i_ALG_ARGON2I13 1 +SODIUM_EXPORT +int crypto_pwhash_argon2i_alg_argon2i13(void); + +#define crypto_pwhash_argon2i_BYTES_MIN 16U +SODIUM_EXPORT +size_t crypto_pwhash_argon2i_bytes_min(void); + +#define crypto_pwhash_argon2i_BYTES_MAX SODIUM_MIN(SODIUM_SIZE_MAX, 4294967295U) +SODIUM_EXPORT +size_t crypto_pwhash_argon2i_bytes_max(void); + +#define crypto_pwhash_argon2i_PASSWD_MIN 0U +SODIUM_EXPORT +size_t crypto_pwhash_argon2i_passwd_min(void); + +#define crypto_pwhash_argon2i_PASSWD_MAX 4294967295U +SODIUM_EXPORT +size_t crypto_pwhash_argon2i_passwd_max(void); + +#define crypto_pwhash_argon2i_SALTBYTES 16U +SODIUM_EXPORT +size_t crypto_pwhash_argon2i_saltbytes(void); + +#define crypto_pwhash_argon2i_STRBYTES 128U +SODIUM_EXPORT +size_t crypto_pwhash_argon2i_strbytes(void); + +#define crypto_pwhash_argon2i_STRPREFIX "$argon2i$" +SODIUM_EXPORT +const char *crypto_pwhash_argon2i_strprefix(void); + +#define crypto_pwhash_argon2i_OPSLIMIT_MIN 3U +SODIUM_EXPORT +size_t crypto_pwhash_argon2i_opslimit_min(void); + +#define crypto_pwhash_argon2i_OPSLIMIT_MAX 4294967295U +SODIUM_EXPORT +size_t crypto_pwhash_argon2i_opslimit_max(void); + +#define crypto_pwhash_argon2i_MEMLIMIT_MIN 8192U +SODIUM_EXPORT +size_t crypto_pwhash_argon2i_memlimit_min(void); + +#define crypto_pwhash_argon2i_MEMLIMIT_MAX \ + ((SIZE_MAX >= 4398046510080U) ? 4398046510080U : (SIZE_MAX >= 2147483648U) ? 2147483648U : 32768U) +SODIUM_EXPORT +size_t crypto_pwhash_argon2i_memlimit_max(void); + +#define crypto_pwhash_argon2i_OPSLIMIT_INTERACTIVE 4U +SODIUM_EXPORT +size_t crypto_pwhash_argon2i_opslimit_interactive(void); + +#define crypto_pwhash_argon2i_MEMLIMIT_INTERACTIVE 33554432U +SODIUM_EXPORT +size_t crypto_pwhash_argon2i_memlimit_interactive(void); + +#define crypto_pwhash_argon2i_OPSLIMIT_MODERATE 6U +SODIUM_EXPORT +size_t crypto_pwhash_argon2i_opslimit_moderate(void); + +#define crypto_pwhash_argon2i_MEMLIMIT_MODERATE 134217728U +SODIUM_EXPORT +size_t crypto_pwhash_argon2i_memlimit_moderate(void); + +#define crypto_pwhash_argon2i_OPSLIMIT_SENSITIVE 8U +SODIUM_EXPORT +size_t crypto_pwhash_argon2i_opslimit_sensitive(void); + +#define crypto_pwhash_argon2i_MEMLIMIT_SENSITIVE 536870912U +SODIUM_EXPORT +size_t crypto_pwhash_argon2i_memlimit_sensitive(void); + +SODIUM_EXPORT +int crypto_pwhash_argon2i(unsigned char * const out, + unsigned long long outlen, + const char * const passwd, + unsigned long long passwdlen, + const unsigned char * const salt, + unsigned long long opslimit, size_t memlimit, + int alg) + __attribute__ ((warn_unused_result)); + +SODIUM_EXPORT +int crypto_pwhash_argon2i_str(char out[crypto_pwhash_argon2i_STRBYTES], + const char * const passwd, + unsigned long long passwdlen, + unsigned long long opslimit, size_t memlimit) + __attribute__ ((warn_unused_result)); + +SODIUM_EXPORT +int crypto_pwhash_argon2i_str_verify(const char str[crypto_pwhash_argon2i_STRBYTES], + const char * const passwd, + unsigned long long passwdlen) + __attribute__ ((warn_unused_result)); + +SODIUM_EXPORT +int crypto_pwhash_argon2i_str_needs_rehash(const char str[crypto_pwhash_argon2i_STRBYTES], + unsigned long long opslimit, size_t memlimit) + __attribute__ ((warn_unused_result)); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/libs/libsodium/src/include/sodium/crypto_pwhash_argon2id.h b/libs/libsodium/src/include/sodium/crypto_pwhash_argon2id.h new file mode 100644 index 0000000000..51b17aa8e3 --- /dev/null +++ b/libs/libsodium/src/include/sodium/crypto_pwhash_argon2id.h @@ -0,0 +1,122 @@ +#ifndef crypto_pwhash_argon2id_H +#define crypto_pwhash_argon2id_H + +#include <limits.h> +#include <stddef.h> +#include <stdint.h> + +#include "export.h" + +#ifdef __cplusplus +# ifdef __GNUC__ +# pragma GCC diagnostic ignored "-Wlong-long" +# endif +extern "C" { +#endif + +#define crypto_pwhash_argon2id_ALG_ARGON2ID13 2 +SODIUM_EXPORT +int crypto_pwhash_argon2id_alg_argon2id13(void); + +#define crypto_pwhash_argon2id_BYTES_MIN 16U +SODIUM_EXPORT +size_t crypto_pwhash_argon2id_bytes_min(void); + +#define crypto_pwhash_argon2id_BYTES_MAX SODIUM_MIN(SODIUM_SIZE_MAX, 4294967295U) +SODIUM_EXPORT +size_t crypto_pwhash_argon2id_bytes_max(void); + +#define crypto_pwhash_argon2id_PASSWD_MIN 0U +SODIUM_EXPORT +size_t crypto_pwhash_argon2id_passwd_min(void); + +#define crypto_pwhash_argon2id_PASSWD_MAX 4294967295U +SODIUM_EXPORT +size_t crypto_pwhash_argon2id_passwd_max(void); + +#define crypto_pwhash_argon2id_SALTBYTES 16U +SODIUM_EXPORT +size_t crypto_pwhash_argon2id_saltbytes(void); + +#define crypto_pwhash_argon2id_STRBYTES 128U +SODIUM_EXPORT +size_t crypto_pwhash_argon2id_strbytes(void); + +#define crypto_pwhash_argon2id_STRPREFIX "$argon2id$" +SODIUM_EXPORT +const char *crypto_pwhash_argon2id_strprefix(void); + +#define crypto_pwhash_argon2id_OPSLIMIT_MIN 1U +SODIUM_EXPORT +size_t crypto_pwhash_argon2id_opslimit_min(void); + +#define crypto_pwhash_argon2id_OPSLIMIT_MAX 4294967295U +SODIUM_EXPORT +size_t crypto_pwhash_argon2id_opslimit_max(void); + +#define crypto_pwhash_argon2id_MEMLIMIT_MIN 8192U +SODIUM_EXPORT +size_t crypto_pwhash_argon2id_memlimit_min(void); + +#define crypto_pwhash_argon2id_MEMLIMIT_MAX \ + ((SIZE_MAX >= 4398046510080U) ? 4398046510080U : (SIZE_MAX >= 2147483648U) ? 2147483648U : 32768U) +SODIUM_EXPORT +size_t crypto_pwhash_argon2id_memlimit_max(void); + +#define crypto_pwhash_argon2id_OPSLIMIT_INTERACTIVE 2U +SODIUM_EXPORT +size_t crypto_pwhash_argon2id_opslimit_interactive(void); + +#define crypto_pwhash_argon2id_MEMLIMIT_INTERACTIVE 67108864U +SODIUM_EXPORT +size_t crypto_pwhash_argon2id_memlimit_interactive(void); + +#define crypto_pwhash_argon2id_OPSLIMIT_MODERATE 3U +SODIUM_EXPORT +size_t crypto_pwhash_argon2id_opslimit_moderate(void); + +#define crypto_pwhash_argon2id_MEMLIMIT_MODERATE 268435456U +SODIUM_EXPORT +size_t crypto_pwhash_argon2id_memlimit_moderate(void); + +#define crypto_pwhash_argon2id_OPSLIMIT_SENSITIVE 4U +SODIUM_EXPORT +size_t crypto_pwhash_argon2id_opslimit_sensitive(void); + +#define crypto_pwhash_argon2id_MEMLIMIT_SENSITIVE 1073741824U +SODIUM_EXPORT +size_t crypto_pwhash_argon2id_memlimit_sensitive(void); + +SODIUM_EXPORT +int crypto_pwhash_argon2id(unsigned char * const out, + unsigned long long outlen, + const char * const passwd, + unsigned long long passwdlen, + const unsigned char * const salt, + unsigned long long opslimit, size_t memlimit, + int alg) + __attribute__ ((warn_unused_result)); + +SODIUM_EXPORT +int crypto_pwhash_argon2id_str(char out[crypto_pwhash_argon2id_STRBYTES], + const char * const passwd, + unsigned long long passwdlen, + unsigned long long opslimit, size_t memlimit) + __attribute__ ((warn_unused_result)); + +SODIUM_EXPORT +int crypto_pwhash_argon2id_str_verify(const char str[crypto_pwhash_argon2id_STRBYTES], + const char * const passwd, + unsigned long long passwdlen) + __attribute__ ((warn_unused_result)); + +SODIUM_EXPORT +int crypto_pwhash_argon2id_str_needs_rehash(const char str[crypto_pwhash_argon2id_STRBYTES], + unsigned long long opslimit, size_t memlimit) + __attribute__ ((warn_unused_result)); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/libs/libsodium/src/include/sodium/crypto_pwhash_scryptsalsa208sha256.h b/libs/libsodium/src/include/sodium/crypto_pwhash_scryptsalsa208sha256.h new file mode 100644 index 0000000000..951b87b962 --- /dev/null +++ b/libs/libsodium/src/include/sodium/crypto_pwhash_scryptsalsa208sha256.h @@ -0,0 +1,120 @@ +#ifndef crypto_pwhash_scryptsalsa208sha256_H +#define crypto_pwhash_scryptsalsa208sha256_H + +#include <limits.h> +#include <stddef.h> +#include <stdint.h> + +#include "export.h" + +#ifdef __cplusplus +# ifdef __GNUC__ +# pragma GCC diagnostic ignored "-Wlong-long" +# endif +extern "C" { +#endif + +#define crypto_pwhash_scryptsalsa208sha256_BYTES_MIN 16U +SODIUM_EXPORT +size_t crypto_pwhash_scryptsalsa208sha256_bytes_min(void); + +#define crypto_pwhash_scryptsalsa208sha256_BYTES_MAX \ + SODIUM_MIN(SODIUM_SIZE_MAX, 0x1fffffffe0ULL) +SODIUM_EXPORT +size_t crypto_pwhash_scryptsalsa208sha256_bytes_max(void); + +#define crypto_pwhash_scryptsalsa208sha256_PASSWD_MIN 0U +SODIUM_EXPORT +size_t crypto_pwhash_scryptsalsa208sha256_passwd_min(void); + +#define crypto_pwhash_scryptsalsa208sha256_PASSWD_MAX SODIUM_SIZE_MAX +SODIUM_EXPORT +size_t crypto_pwhash_scryptsalsa208sha256_passwd_max(void); + +#define crypto_pwhash_scryptsalsa208sha256_SALTBYTES 32U +SODIUM_EXPORT +size_t crypto_pwhash_scryptsalsa208sha256_saltbytes(void); + +#define crypto_pwhash_scryptsalsa208sha256_STRBYTES 102U +SODIUM_EXPORT +size_t crypto_pwhash_scryptsalsa208sha256_strbytes(void); + +#define crypto_pwhash_scryptsalsa208sha256_STRPREFIX "$7$" +SODIUM_EXPORT +const char *crypto_pwhash_scryptsalsa208sha256_strprefix(void); + +#define crypto_pwhash_scryptsalsa208sha256_OPSLIMIT_MIN 32768U +SODIUM_EXPORT +size_t crypto_pwhash_scryptsalsa208sha256_opslimit_min(void); + +#define crypto_pwhash_scryptsalsa208sha256_OPSLIMIT_MAX 4294967295U +SODIUM_EXPORT +size_t crypto_pwhash_scryptsalsa208sha256_opslimit_max(void); + +#define crypto_pwhash_scryptsalsa208sha256_MEMLIMIT_MIN 16777216U +SODIUM_EXPORT +size_t crypto_pwhash_scryptsalsa208sha256_memlimit_min(void); + +#define crypto_pwhash_scryptsalsa208sha256_MEMLIMIT_MAX \ + SODIUM_MIN(SIZE_MAX, 68719476736ULL) +SODIUM_EXPORT +size_t crypto_pwhash_scryptsalsa208sha256_memlimit_max(void); + +#define crypto_pwhash_scryptsalsa208sha256_OPSLIMIT_INTERACTIVE 524288U +SODIUM_EXPORT +size_t crypto_pwhash_scryptsalsa208sha256_opslimit_interactive(void); + +#define crypto_pwhash_scryptsalsa208sha256_MEMLIMIT_INTERACTIVE 16777216U +SODIUM_EXPORT +size_t crypto_pwhash_scryptsalsa208sha256_memlimit_interactive(void); + +#define crypto_pwhash_scryptsalsa208sha256_OPSLIMIT_SENSITIVE 33554432U +SODIUM_EXPORT +size_t crypto_pwhash_scryptsalsa208sha256_opslimit_sensitive(void); + +#define crypto_pwhash_scryptsalsa208sha256_MEMLIMIT_SENSITIVE 1073741824U +SODIUM_EXPORT +size_t crypto_pwhash_scryptsalsa208sha256_memlimit_sensitive(void); + +SODIUM_EXPORT +int crypto_pwhash_scryptsalsa208sha256(unsigned char * const out, + unsigned long long outlen, + const char * const passwd, + unsigned long long passwdlen, + const unsigned char * const salt, + unsigned long long opslimit, + size_t memlimit) + __attribute__ ((warn_unused_result)); + +SODIUM_EXPORT +int crypto_pwhash_scryptsalsa208sha256_str(char out[crypto_pwhash_scryptsalsa208sha256_STRBYTES], + const char * const passwd, + unsigned long long passwdlen, + unsigned long long opslimit, + size_t memlimit) + __attribute__ ((warn_unused_result)); + +SODIUM_EXPORT +int crypto_pwhash_scryptsalsa208sha256_str_verify(const char str[crypto_pwhash_scryptsalsa208sha256_STRBYTES], + const char * const passwd, + unsigned long long passwdlen) + __attribute__ ((warn_unused_result)); + +SODIUM_EXPORT +int crypto_pwhash_scryptsalsa208sha256_ll(const uint8_t * passwd, size_t passwdlen, + const uint8_t * salt, size_t saltlen, + uint64_t N, uint32_t r, uint32_t p, + uint8_t * buf, size_t buflen) + __attribute__ ((warn_unused_result)); + +SODIUM_EXPORT +int crypto_pwhash_scryptsalsa208sha256_str_needs_rehash(const char str[crypto_pwhash_scryptsalsa208sha256_STRBYTES], + unsigned long long opslimit, + size_t memlimit) + __attribute__ ((warn_unused_result)); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/libs/libsodium/src/include/sodium/crypto_scalarmult.h b/libs/libsodium/src/include/sodium/crypto_scalarmult.h new file mode 100644 index 0000000000..f7fa6f8f39 --- /dev/null +++ b/libs/libsodium/src/include/sodium/crypto_scalarmult.h @@ -0,0 +1,45 @@ +#ifndef crypto_scalarmult_H +#define crypto_scalarmult_H + +#include <stddef.h> + +#include "crypto_scalarmult_curve25519.h" +#include "export.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define crypto_scalarmult_BYTES crypto_scalarmult_curve25519_BYTES +SODIUM_EXPORT +size_t crypto_scalarmult_bytes(void); + +#define crypto_scalarmult_SCALARBYTES crypto_scalarmult_curve25519_SCALARBYTES +SODIUM_EXPORT +size_t crypto_scalarmult_scalarbytes(void); + +#define crypto_scalarmult_PRIMITIVE "curve25519" +SODIUM_EXPORT +const char *crypto_scalarmult_primitive(void); + +SODIUM_EXPORT +int crypto_scalarmult_base(unsigned char *q, const unsigned char *n); + +/* + * NOTE: Do not use the result of this function directly. + * + * Hash the result with the public keys in order to compute a shared + * secret key: H(q || client_pk || server_pk) + * + * Or unless this is not an option, use the crypto_kx() API instead. + */ +SODIUM_EXPORT +int crypto_scalarmult(unsigned char *q, const unsigned char *n, + const unsigned char *p) + __attribute__ ((warn_unused_result)); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/libs/libsodium/src/include/sodium/crypto_scalarmult_curve25519.h b/libs/libsodium/src/include/sodium/crypto_scalarmult_curve25519.h new file mode 100644 index 0000000000..ae85eadc22 --- /dev/null +++ b/libs/libsodium/src/include/sodium/crypto_scalarmult_curve25519.h @@ -0,0 +1,40 @@ +#ifndef crypto_scalarmult_curve25519_H +#define crypto_scalarmult_curve25519_H + +#include <stddef.h> + +#include "export.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define crypto_scalarmult_curve25519_BYTES 32U +SODIUM_EXPORT +size_t crypto_scalarmult_curve25519_bytes(void); + +#define crypto_scalarmult_curve25519_SCALARBYTES 32U +SODIUM_EXPORT +size_t crypto_scalarmult_curve25519_scalarbytes(void); + +/* + * NOTE: Do not use the result of this function directly. + * + * Hash the result with the public keys in order to compute a shared + * secret key: H(q || client_pk || server_pk) + * + * Or unless this is not an option, use the crypto_kx() API instead. + */ +SODIUM_EXPORT +int crypto_scalarmult_curve25519(unsigned char *q, const unsigned char *n, + const unsigned char *p) + __attribute__ ((warn_unused_result)); + +SODIUM_EXPORT +int crypto_scalarmult_curve25519_base(unsigned char *q, const unsigned char *n); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/libs/libsodium/src/include/sodium/crypto_scalarmult_ed25519.h b/libs/libsodium/src/include/sodium/crypto_scalarmult_ed25519.h new file mode 100644 index 0000000000..3d51235112 --- /dev/null +++ b/libs/libsodium/src/include/sodium/crypto_scalarmult_ed25519.h @@ -0,0 +1,41 @@ + +#ifndef crypto_scalarmult_ed25519_H +#define crypto_scalarmult_ed25519_H + +#include <stddef.h> + +#include "export.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define crypto_scalarmult_ed25519_BYTES 32U +SODIUM_EXPORT +size_t crypto_scalarmult_ed25519_bytes(void); + +#define crypto_scalarmult_ed25519_SCALARBYTES 32U +SODIUM_EXPORT +size_t crypto_scalarmult_ed25519_scalarbytes(void); + +/* + * NOTE: Do not use the result of this function directly. + * + * Hash the result with the public keys in order to compute a shared + * secret key: H(q || client_pk || server_pk) + * + * Or unless this is not an option, use the crypto_kx() API instead. + */ +SODIUM_EXPORT +int crypto_scalarmult_ed25519(unsigned char *q, const unsigned char *n, + const unsigned char *p) + __attribute__ ((warn_unused_result)); + +SODIUM_EXPORT +int crypto_scalarmult_ed25519_base(unsigned char *q, const unsigned char *n); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/libs/libsodium/src/include/sodium/crypto_secretbox.h b/libs/libsodium/src/include/sodium/crypto_secretbox.h new file mode 100644 index 0000000000..55e94a0292 --- /dev/null +++ b/libs/libsodium/src/include/sodium/crypto_secretbox.h @@ -0,0 +1,91 @@ +#ifndef crypto_secretbox_H +#define crypto_secretbox_H + +#include <stddef.h> + +#include "crypto_secretbox_xsalsa20poly1305.h" +#include "export.h" + +#ifdef __cplusplus +# ifdef __GNUC__ +# pragma GCC diagnostic ignored "-Wlong-long" +# endif +extern "C" { +#endif + +#define crypto_secretbox_KEYBYTES crypto_secretbox_xsalsa20poly1305_KEYBYTES +SODIUM_EXPORT +size_t crypto_secretbox_keybytes(void); + +#define crypto_secretbox_NONCEBYTES crypto_secretbox_xsalsa20poly1305_NONCEBYTES +SODIUM_EXPORT +size_t crypto_secretbox_noncebytes(void); + +#define crypto_secretbox_MACBYTES crypto_secretbox_xsalsa20poly1305_MACBYTES +SODIUM_EXPORT +size_t crypto_secretbox_macbytes(void); + +#define crypto_secretbox_PRIMITIVE "xsalsa20poly1305" +SODIUM_EXPORT +const char *crypto_secretbox_primitive(void); + +#define crypto_secretbox_MESSAGEBYTES_MAX crypto_secretbox_xsalsa20poly1305_MESSAGEBYTES_MAX +SODIUM_EXPORT +size_t crypto_secretbox_messagebytes_max(void); + +SODIUM_EXPORT +int crypto_secretbox_easy(unsigned char *c, const unsigned char *m, + unsigned long long mlen, const unsigned char *n, + const unsigned char *k); + +SODIUM_EXPORT +int crypto_secretbox_open_easy(unsigned char *m, const unsigned char *c, + unsigned long long clen, const unsigned char *n, + const unsigned char *k) + __attribute__ ((warn_unused_result)); + +SODIUM_EXPORT +int crypto_secretbox_detached(unsigned char *c, unsigned char *mac, + const unsigned char *m, + unsigned long long mlen, + const unsigned char *n, + const unsigned char *k); + +SODIUM_EXPORT +int crypto_secretbox_open_detached(unsigned char *m, + const unsigned char *c, + const unsigned char *mac, + unsigned long long clen, + const unsigned char *n, + const unsigned char *k) + __attribute__ ((warn_unused_result)); + +SODIUM_EXPORT +void crypto_secretbox_keygen(unsigned char k[crypto_secretbox_KEYBYTES]); + +/* -- NaCl compatibility interface ; Requires padding -- */ + +#define crypto_secretbox_ZEROBYTES crypto_secretbox_xsalsa20poly1305_ZEROBYTES +SODIUM_EXPORT +size_t crypto_secretbox_zerobytes(void); + +#define crypto_secretbox_BOXZEROBYTES crypto_secretbox_xsalsa20poly1305_BOXZEROBYTES +SODIUM_EXPORT +size_t crypto_secretbox_boxzerobytes(void); + +SODIUM_EXPORT +int crypto_secretbox(unsigned char *c, const unsigned char *m, + unsigned long long mlen, const unsigned char *n, + const unsigned char *k); + +SODIUM_EXPORT +int crypto_secretbox_open(unsigned char *m, const unsigned char *c, + unsigned long long clen, const unsigned char *n, + const unsigned char *k) + __attribute__ ((warn_unused_result)); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/libs/libsodium/src/include/sodium/crypto_secretbox_xchacha20poly1305.h b/libs/libsodium/src/include/sodium/crypto_secretbox_xchacha20poly1305.h new file mode 100644 index 0000000000..2919da161c --- /dev/null +++ b/libs/libsodium/src/include/sodium/crypto_secretbox_xchacha20poly1305.h @@ -0,0 +1,68 @@ +#ifndef crypto_secretbox_xchacha20poly1305_H +#define crypto_secretbox_xchacha20poly1305_H + +#include <stddef.h> +#include "crypto_stream_xchacha20.h" +#include "export.h" + +#ifdef __cplusplus +# ifdef __GNUC__ +# pragma GCC diagnostic ignored "-Wlong-long" +# endif +extern "C" { +#endif + +#define crypto_secretbox_xchacha20poly1305_KEYBYTES 32U +SODIUM_EXPORT +size_t crypto_secretbox_xchacha20poly1305_keybytes(void); + +#define crypto_secretbox_xchacha20poly1305_NONCEBYTES 24U +SODIUM_EXPORT +size_t crypto_secretbox_xchacha20poly1305_noncebytes(void); + +#define crypto_secretbox_xchacha20poly1305_MACBYTES 16U +SODIUM_EXPORT +size_t crypto_secretbox_xchacha20poly1305_macbytes(void); + +#define crypto_secretbox_xchacha20poly1305_MESSAGEBYTES_MAX \ + (crypto_stream_xchacha20_MESSAGEBYTES_MAX - crypto_secretbox_xchacha20poly1305_MACBYTES) +SODIUM_EXPORT +size_t crypto_secretbox_xchacha20poly1305_messagebytes_max(void); + +SODIUM_EXPORT +int crypto_secretbox_xchacha20poly1305_easy(unsigned char *c, + const unsigned char *m, + unsigned long long mlen, + const unsigned char *n, + const unsigned char *k); + +SODIUM_EXPORT +int crypto_secretbox_xchacha20poly1305_open_easy(unsigned char *m, + const unsigned char *c, + unsigned long long clen, + const unsigned char *n, + const unsigned char *k) + __attribute__ ((warn_unused_result)); + +SODIUM_EXPORT +int crypto_secretbox_xchacha20poly1305_detached(unsigned char *c, + unsigned char *mac, + const unsigned char *m, + unsigned long long mlen, + const unsigned char *n, + const unsigned char *k); + +SODIUM_EXPORT +int crypto_secretbox_xchacha20poly1305_open_detached(unsigned char *m, + const unsigned char *c, + const unsigned char *mac, + unsigned long long clen, + const unsigned char *n, + const unsigned char *k) + __attribute__ ((warn_unused_result)); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/libs/libsodium/src/include/sodium/crypto_secretbox_xsalsa20poly1305.h b/libs/libsodium/src/include/sodium/crypto_secretbox_xsalsa20poly1305.h new file mode 100644 index 0000000000..4b8c7c8ea2 --- /dev/null +++ b/libs/libsodium/src/include/sodium/crypto_secretbox_xsalsa20poly1305.h @@ -0,0 +1,67 @@ +#ifndef crypto_secretbox_xsalsa20poly1305_H +#define crypto_secretbox_xsalsa20poly1305_H + +#include <stddef.h> +#include "crypto_stream_xsalsa20.h" +#include "export.h" + +#ifdef __cplusplus +# ifdef __GNUC__ +# pragma GCC diagnostic ignored "-Wlong-long" +# endif +extern "C" { +#endif + +#define crypto_secretbox_xsalsa20poly1305_KEYBYTES 32U +SODIUM_EXPORT +size_t crypto_secretbox_xsalsa20poly1305_keybytes(void); + +#define crypto_secretbox_xsalsa20poly1305_NONCEBYTES 24U +SODIUM_EXPORT +size_t crypto_secretbox_xsalsa20poly1305_noncebytes(void); + +#define crypto_secretbox_xsalsa20poly1305_MACBYTES 16U +SODIUM_EXPORT +size_t crypto_secretbox_xsalsa20poly1305_macbytes(void); + +/* Only for the libsodium API - The NaCl compatibility API would require BOXZEROBYTES extra bytes */ +#define crypto_secretbox_xsalsa20poly1305_MESSAGEBYTES_MAX \ + (crypto_stream_xsalsa20_MESSAGEBYTES_MAX - crypto_secretbox_xsalsa20poly1305_MACBYTES) +SODIUM_EXPORT +size_t crypto_secretbox_xsalsa20poly1305_messagebytes_max(void); + +SODIUM_EXPORT +int crypto_secretbox_xsalsa20poly1305(unsigned char *c, + const unsigned char *m, + unsigned long long mlen, + const unsigned char *n, + const unsigned char *k); + +SODIUM_EXPORT +int crypto_secretbox_xsalsa20poly1305_open(unsigned char *m, + const unsigned char *c, + unsigned long long clen, + const unsigned char *n, + const unsigned char *k) + __attribute__ ((warn_unused_result)); + +SODIUM_EXPORT +void crypto_secretbox_xsalsa20poly1305_keygen(unsigned char k[crypto_secretbox_xsalsa20poly1305_KEYBYTES]); + +/* -- NaCl compatibility interface ; Requires padding -- */ + +#define crypto_secretbox_xsalsa20poly1305_BOXZEROBYTES 16U +SODIUM_EXPORT +size_t crypto_secretbox_xsalsa20poly1305_boxzerobytes(void); + +#define crypto_secretbox_xsalsa20poly1305_ZEROBYTES \ + (crypto_secretbox_xsalsa20poly1305_BOXZEROBYTES + \ + crypto_secretbox_xsalsa20poly1305_MACBYTES) +SODIUM_EXPORT +size_t crypto_secretbox_xsalsa20poly1305_zerobytes(void); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/libs/libsodium/src/include/sodium/crypto_secretstream_xchacha20poly1305.h b/libs/libsodium/src/include/sodium/crypto_secretstream_xchacha20poly1305.h new file mode 100644 index 0000000000..7d3fa2a9e3 --- /dev/null +++ b/libs/libsodium/src/include/sodium/crypto_secretstream_xchacha20poly1305.h @@ -0,0 +1,102 @@ +#ifndef crypto_secretstream_xchacha20poly1305_H +#define crypto_secretstream_xchacha20poly1305_H + +#include <stddef.h> + +#include "crypto_aead_xchacha20poly1305.h" +#include "crypto_stream_chacha20.h" +#include "export.h" + +#ifdef __cplusplus +# ifdef __GNUC__ +# pragma GCC diagnostic ignored "-Wlong-long" +# endif +extern "C" { +#endif + +#define crypto_secretstream_xchacha20poly1305_ABYTES \ + (1U + crypto_aead_xchacha20poly1305_ietf_ABYTES) +SODIUM_EXPORT +size_t crypto_secretstream_xchacha20poly1305_abytes(void); + +#define crypto_secretstream_xchacha20poly1305_HEADERBYTES \ + crypto_aead_xchacha20poly1305_ietf_NPUBBYTES +SODIUM_EXPORT +size_t crypto_secretstream_xchacha20poly1305_headerbytes(void); + +#define crypto_secretstream_xchacha20poly1305_KEYBYTES \ + crypto_aead_xchacha20poly1305_ietf_KEYBYTES +SODIUM_EXPORT +size_t crypto_secretstream_xchacha20poly1305_keybytes(void); + +#define crypto_secretstream_xchacha20poly1305_MESSAGEBYTES_MAX \ + SODIUM_MIN(SODIUM_SIZE_MAX, ((1ULL << 32) - 2ULL) * 64ULL) +SODIUM_EXPORT +size_t crypto_secretstream_xchacha20poly1305_messagebytes_max(void); + +#define crypto_secretstream_xchacha20poly1305_TAG_MESSAGE 0x00 +SODIUM_EXPORT +unsigned char crypto_secretstream_xchacha20poly1305_tag_message(void); + +#define crypto_secretstream_xchacha20poly1305_TAG_PUSH 0x01 +SODIUM_EXPORT +unsigned char crypto_secretstream_xchacha20poly1305_tag_push(void); + +#define crypto_secretstream_xchacha20poly1305_TAG_REKEY 0x02 +SODIUM_EXPORT +unsigned char crypto_secretstream_xchacha20poly1305_tag_rekey(void); + +#define crypto_secretstream_xchacha20poly1305_TAG_FINAL \ + (crypto_secretstream_xchacha20poly1305_TAG_PUSH | \ + crypto_secretstream_xchacha20poly1305_TAG_REKEY) +SODIUM_EXPORT +unsigned char crypto_secretstream_xchacha20poly1305_tag_final(void); + +typedef struct crypto_secretstream_xchacha20poly1305_state { + unsigned char k[crypto_stream_chacha20_ietf_KEYBYTES]; + unsigned char nonce[crypto_stream_chacha20_ietf_NONCEBYTES]; + unsigned char _pad[8]; +} crypto_secretstream_xchacha20poly1305_state; + +SODIUM_EXPORT +size_t crypto_secretstream_xchacha20poly1305_statebytes(void); + +SODIUM_EXPORT +void crypto_secretstream_xchacha20poly1305_keygen + (unsigned char k[crypto_secretstream_xchacha20poly1305_KEYBYTES]); + +SODIUM_EXPORT +int crypto_secretstream_xchacha20poly1305_init_push + (crypto_secretstream_xchacha20poly1305_state *state, + unsigned char header[crypto_secretstream_xchacha20poly1305_HEADERBYTES], + const unsigned char k[crypto_secretstream_xchacha20poly1305_KEYBYTES]); + +SODIUM_EXPORT +int crypto_secretstream_xchacha20poly1305_push + (crypto_secretstream_xchacha20poly1305_state *state, + unsigned char *c, unsigned long long *clen_p, + const unsigned char *m, unsigned long long mlen, + const unsigned char *ad, unsigned long long adlen, unsigned char tag); + +SODIUM_EXPORT +int crypto_secretstream_xchacha20poly1305_init_pull + (crypto_secretstream_xchacha20poly1305_state *state, + const unsigned char header[crypto_secretstream_xchacha20poly1305_HEADERBYTES], + const unsigned char k[crypto_secretstream_xchacha20poly1305_KEYBYTES]); + +SODIUM_EXPORT +int crypto_secretstream_xchacha20poly1305_pull + (crypto_secretstream_xchacha20poly1305_state *state, + unsigned char *m, unsigned long long *mlen_p, unsigned char *tag_p, + const unsigned char *c, unsigned long long clen, + const unsigned char *ad, unsigned long long adlen); + +SODIUM_EXPORT +void crypto_secretstream_xchacha20poly1305_rekey + (crypto_secretstream_xchacha20poly1305_state *state); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/libs/libsodium/src/include/sodium/crypto_shorthash.h b/libs/libsodium/src/include/sodium/crypto_shorthash.h new file mode 100644 index 0000000000..a498808247 --- /dev/null +++ b/libs/libsodium/src/include/sodium/crypto_shorthash.h @@ -0,0 +1,39 @@ +#ifndef crypto_shorthash_H +#define crypto_shorthash_H + +#include <stddef.h> + +#include "crypto_shorthash_siphash24.h" +#include "export.h" + +#ifdef __cplusplus +# ifdef __GNUC__ +# pragma GCC diagnostic ignored "-Wlong-long" +# endif +extern "C" { +#endif + +#define crypto_shorthash_BYTES crypto_shorthash_siphash24_BYTES +SODIUM_EXPORT +size_t crypto_shorthash_bytes(void); + +#define crypto_shorthash_KEYBYTES crypto_shorthash_siphash24_KEYBYTES +SODIUM_EXPORT +size_t crypto_shorthash_keybytes(void); + +#define crypto_shorthash_PRIMITIVE "siphash24" +SODIUM_EXPORT +const char *crypto_shorthash_primitive(void); + +SODIUM_EXPORT +int crypto_shorthash(unsigned char *out, const unsigned char *in, + unsigned long long inlen, const unsigned char *k); + +SODIUM_EXPORT +void crypto_shorthash_keygen(unsigned char k[crypto_shorthash_KEYBYTES]); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/libs/libsodium/src/include/sodium/crypto_shorthash_siphash24.h b/libs/libsodium/src/include/sodium/crypto_shorthash_siphash24.h new file mode 100644 index 0000000000..745ed48fae --- /dev/null +++ b/libs/libsodium/src/include/sodium/crypto_shorthash_siphash24.h @@ -0,0 +1,48 @@ +#ifndef crypto_shorthash_siphash24_H +#define crypto_shorthash_siphash24_H + +#include <stddef.h> +#include "export.h" + +#ifdef __cplusplus +# ifdef __GNUC__ +# pragma GCC diagnostic ignored "-Wlong-long" +# endif +extern "C" { +#endif + +/* -- 64-bit output -- */ + +#define crypto_shorthash_siphash24_BYTES 8U +SODIUM_EXPORT +size_t crypto_shorthash_siphash24_bytes(void); + +#define crypto_shorthash_siphash24_KEYBYTES 16U +SODIUM_EXPORT +size_t crypto_shorthash_siphash24_keybytes(void); + +SODIUM_EXPORT +int crypto_shorthash_siphash24(unsigned char *out, const unsigned char *in, + unsigned long long inlen, const unsigned char *k); + +#ifndef SODIUM_LIBRARY_MINIMAL +/* -- 128-bit output -- */ + +#define crypto_shorthash_siphashx24_BYTES 16U +SODIUM_EXPORT +size_t crypto_shorthash_siphashx24_bytes(void); + +#define crypto_shorthash_siphashx24_KEYBYTES 16U +SODIUM_EXPORT +size_t crypto_shorthash_siphashx24_keybytes(void); + +SODIUM_EXPORT +int crypto_shorthash_siphashx24(unsigned char *out, const unsigned char *in, + unsigned long long inlen, const unsigned char *k); +#endif + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/libs/libsodium/src/include/sodium/crypto_sign.h b/libs/libsodium/src/include/sodium/crypto_sign.h new file mode 100644 index 0000000000..85aff0c9db --- /dev/null +++ b/libs/libsodium/src/include/sodium/crypto_sign.h @@ -0,0 +1,103 @@ +#ifndef crypto_sign_H +#define crypto_sign_H + +/* + * THREAD SAFETY: crypto_sign_keypair() is thread-safe, + * provided that sodium_init() was called before. + * + * Other functions, including crypto_sign_seed_keypair() are always thread-safe. + */ + +#include <stddef.h> + +#include "crypto_sign_ed25519.h" +#include "export.h" + +#ifdef __cplusplus +# ifdef __GNUC__ +# pragma GCC diagnostic ignored "-Wlong-long" +# endif +extern "C" { +#endif + +typedef crypto_sign_ed25519ph_state crypto_sign_state; + +SODIUM_EXPORT +size_t crypto_sign_statebytes(void); + +#define crypto_sign_BYTES crypto_sign_ed25519_BYTES +SODIUM_EXPORT +size_t crypto_sign_bytes(void); + +#define crypto_sign_SEEDBYTES crypto_sign_ed25519_SEEDBYTES +SODIUM_EXPORT +size_t crypto_sign_seedbytes(void); + +#define crypto_sign_PUBLICKEYBYTES crypto_sign_ed25519_PUBLICKEYBYTES +SODIUM_EXPORT +size_t crypto_sign_publickeybytes(void); + +#define crypto_sign_SECRETKEYBYTES crypto_sign_ed25519_SECRETKEYBYTES +SODIUM_EXPORT +size_t crypto_sign_secretkeybytes(void); + +#define crypto_sign_MESSAGEBYTES_MAX crypto_sign_ed25519_MESSAGEBYTES_MAX +SODIUM_EXPORT +size_t crypto_sign_messagebytes_max(void); + +#define crypto_sign_PRIMITIVE "ed25519" +SODIUM_EXPORT +const char *crypto_sign_primitive(void); + +SODIUM_EXPORT +int crypto_sign_seed_keypair(unsigned char *pk, unsigned char *sk, + const unsigned char *seed); + +SODIUM_EXPORT +int crypto_sign_keypair(unsigned char *pk, unsigned char *sk); + +SODIUM_EXPORT +int crypto_sign(unsigned char *sm, unsigned long long *smlen_p, + const unsigned char *m, unsigned long long mlen, + const unsigned char *sk); + +SODIUM_EXPORT +int crypto_sign_open(unsigned char *m, unsigned long long *mlen_p, + const unsigned char *sm, unsigned long long smlen, + const unsigned char *pk) + __attribute__ ((warn_unused_result)); + +SODIUM_EXPORT +int crypto_sign_detached(unsigned char *sig, unsigned long long *siglen_p, + const unsigned char *m, unsigned long long mlen, + const unsigned char *sk); + +SODIUM_EXPORT +int crypto_sign_verify_detached(const unsigned char *sig, + const unsigned char *m, + unsigned long long mlen, + const unsigned char *pk) + __attribute__ ((warn_unused_result)); + +SODIUM_EXPORT +int crypto_sign_init(crypto_sign_state *state); + +SODIUM_EXPORT +int crypto_sign_update(crypto_sign_state *state, + const unsigned char *m, unsigned long long mlen); + +SODIUM_EXPORT +int crypto_sign_final_create(crypto_sign_state *state, unsigned char *sig, + unsigned long long *siglen_p, + const unsigned char *sk); + +SODIUM_EXPORT +int crypto_sign_final_verify(crypto_sign_state *state, unsigned char *sig, + const unsigned char *pk) + __attribute__ ((warn_unused_result)); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/libs/libsodium/src/include/sodium/crypto_sign_ed25519.h b/libs/libsodium/src/include/sodium/crypto_sign_ed25519.h new file mode 100644 index 0000000000..38d2b9dd63 --- /dev/null +++ b/libs/libsodium/src/include/sodium/crypto_sign_ed25519.h @@ -0,0 +1,114 @@ +#ifndef crypto_sign_ed25519_H +#define crypto_sign_ed25519_H + +#include <stddef.h> +#include "crypto_hash_sha512.h" +#include "export.h" + +#ifdef __cplusplus +# ifdef __GNUC__ +# pragma GCC diagnostic ignored "-Wlong-long" +# endif +extern "C" { +#endif + +typedef struct crypto_sign_ed25519ph_state { + crypto_hash_sha512_state hs; +} crypto_sign_ed25519ph_state; + +SODIUM_EXPORT +size_t crypto_sign_ed25519ph_statebytes(void); + +#define crypto_sign_ed25519_BYTES 64U +SODIUM_EXPORT +size_t crypto_sign_ed25519_bytes(void); + +#define crypto_sign_ed25519_SEEDBYTES 32U +SODIUM_EXPORT +size_t crypto_sign_ed25519_seedbytes(void); + +#define crypto_sign_ed25519_PUBLICKEYBYTES 32U +SODIUM_EXPORT +size_t crypto_sign_ed25519_publickeybytes(void); + +#define crypto_sign_ed25519_SECRETKEYBYTES (32U + 32U) +SODIUM_EXPORT +size_t crypto_sign_ed25519_secretkeybytes(void); + +#define crypto_sign_ed25519_MESSAGEBYTES_MAX (SODIUM_SIZE_MAX - crypto_sign_ed25519_BYTES) +SODIUM_EXPORT +size_t crypto_sign_ed25519_messagebytes_max(void); + +SODIUM_EXPORT +int crypto_sign_ed25519(unsigned char *sm, unsigned long long *smlen_p, + const unsigned char *m, unsigned long long mlen, + const unsigned char *sk); + +SODIUM_EXPORT +int crypto_sign_ed25519_open(unsigned char *m, unsigned long long *mlen_p, + const unsigned char *sm, unsigned long long smlen, + const unsigned char *pk) + __attribute__ ((warn_unused_result)); + +SODIUM_EXPORT +int crypto_sign_ed25519_detached(unsigned char *sig, + unsigned long long *siglen_p, + const unsigned char *m, + unsigned long long mlen, + const unsigned char *sk); + +SODIUM_EXPORT +int crypto_sign_ed25519_verify_detached(const unsigned char *sig, + const unsigned char *m, + unsigned long long mlen, + const unsigned char *pk) + __attribute__ ((warn_unused_result)); + +SODIUM_EXPORT +int crypto_sign_ed25519_keypair(unsigned char *pk, unsigned char *sk); + +SODIUM_EXPORT +int crypto_sign_ed25519_seed_keypair(unsigned char *pk, unsigned char *sk, + const unsigned char *seed); + +SODIUM_EXPORT +int crypto_sign_ed25519_pk_to_curve25519(unsigned char *curve25519_pk, + const unsigned char *ed25519_pk) + __attribute__ ((warn_unused_result)); + +SODIUM_EXPORT +int crypto_sign_ed25519_sk_to_curve25519(unsigned char *curve25519_sk, + const unsigned char *ed25519_sk); + +SODIUM_EXPORT +int crypto_sign_ed25519_sk_to_seed(unsigned char *seed, + const unsigned char *sk); + +SODIUM_EXPORT +int crypto_sign_ed25519_sk_to_pk(unsigned char *pk, const unsigned char *sk); + +SODIUM_EXPORT +int crypto_sign_ed25519ph_init(crypto_sign_ed25519ph_state *state); + +SODIUM_EXPORT +int crypto_sign_ed25519ph_update(crypto_sign_ed25519ph_state *state, + const unsigned char *m, + unsigned long long mlen); + +SODIUM_EXPORT +int crypto_sign_ed25519ph_final_create(crypto_sign_ed25519ph_state *state, + unsigned char *sig, + unsigned long long *siglen_p, + const unsigned char *sk); + +SODIUM_EXPORT +int crypto_sign_ed25519ph_final_verify(crypto_sign_ed25519ph_state *state, + unsigned char *sig, + const unsigned char *pk) + __attribute__ ((warn_unused_result)); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/libs/libsodium/src/include/sodium/crypto_sign_edwards25519sha512batch.h b/libs/libsodium/src/include/sodium/crypto_sign_edwards25519sha512batch.h new file mode 100644 index 0000000000..4bb9192470 --- /dev/null +++ b/libs/libsodium/src/include/sodium/crypto_sign_edwards25519sha512batch.h @@ -0,0 +1,55 @@ +#ifndef crypto_sign_edwards25519sha512batch_H +#define crypto_sign_edwards25519sha512batch_H + +/* + * WARNING: This construction was a prototype, which should not be used + * any more in new projects. + * + * crypto_sign_edwards25519sha512batch is provided for applications + * initially built with NaCl, but as recommended by the author of this + * construction, new applications should use ed25519 instead. + * + * In Sodium, you should use the high-level crypto_sign_*() functions instead. + */ + +#include <stddef.h> +#include "export.h" + +#ifdef __cplusplus +# ifdef __GNUC__ +# pragma GCC diagnostic ignored "-Wlong-long" +# endif +extern "C" { +#endif + +#define crypto_sign_edwards25519sha512batch_BYTES 64U +#define crypto_sign_edwards25519sha512batch_PUBLICKEYBYTES 32U +#define crypto_sign_edwards25519sha512batch_SECRETKEYBYTES (32U + 32U) +#define crypto_sign_edwards25519sha512batch_MESSAGEBYTES_MAX (SODIUM_SIZE_MAX - crypto_sign_edwards25519sha512batch_BYTES) + +SODIUM_EXPORT +int crypto_sign_edwards25519sha512batch(unsigned char *sm, + unsigned long long *smlen_p, + const unsigned char *m, + unsigned long long mlen, + const unsigned char *sk) + __attribute__ ((deprecated)); + +SODIUM_EXPORT +int crypto_sign_edwards25519sha512batch_open(unsigned char *m, + unsigned long long *mlen_p, + const unsigned char *sm, + unsigned long long smlen, + const unsigned char *pk) + __attribute__ ((deprecated)); + +SODIUM_EXPORT +int crypto_sign_edwards25519sha512batch_keypair(unsigned char *pk, + unsigned char *sk) + __attribute__ ((deprecated)); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/libs/libsodium/src/include/sodium/crypto_stream.h b/libs/libsodium/src/include/sodium/crypto_stream.h new file mode 100644 index 0000000000..d288f0b6dd --- /dev/null +++ b/libs/libsodium/src/include/sodium/crypto_stream.h @@ -0,0 +1,56 @@ +#ifndef crypto_stream_H +#define crypto_stream_H + +/* + * WARNING: This is just a stream cipher. It is NOT authenticated encryption. + * While it provides some protection against eavesdropping, it does NOT + * provide any security against active attacks. + * Unless you know what you're doing, what you are looking for is probably + * the crypto_box functions. + */ + +#include <stddef.h> + +#include "crypto_stream_xsalsa20.h" +#include "export.h" + +#ifdef __cplusplus +# ifdef __GNUC__ +# pragma GCC diagnostic ignored "-Wlong-long" +# endif +extern "C" { +#endif + +#define crypto_stream_KEYBYTES crypto_stream_xsalsa20_KEYBYTES +SODIUM_EXPORT +size_t crypto_stream_keybytes(void); + +#define crypto_stream_NONCEBYTES crypto_stream_xsalsa20_NONCEBYTES +SODIUM_EXPORT +size_t crypto_stream_noncebytes(void); + +#define crypto_stream_MESSAGEBYTES_MAX crypto_stream_xsalsa20_MESSAGEBYTES_MAX +SODIUM_EXPORT +size_t crypto_stream_messagebytes_max(void); + +#define crypto_stream_PRIMITIVE "xsalsa20" +SODIUM_EXPORT +const char *crypto_stream_primitive(void); + +SODIUM_EXPORT +int crypto_stream(unsigned char *c, unsigned long long clen, + const unsigned char *n, const unsigned char *k); + +SODIUM_EXPORT +int crypto_stream_xor(unsigned char *c, const unsigned char *m, + unsigned long long mlen, const unsigned char *n, + const unsigned char *k); + +SODIUM_EXPORT +void crypto_stream_keygen(unsigned char k[crypto_stream_KEYBYTES]); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/libs/libsodium/src/include/sodium/crypto_stream_chacha20.h b/libs/libsodium/src/include/sodium/crypto_stream_chacha20.h new file mode 100644 index 0000000000..d3e2b234ef --- /dev/null +++ b/libs/libsodium/src/include/sodium/crypto_stream_chacha20.h @@ -0,0 +1,98 @@ +#ifndef crypto_stream_chacha20_H +#define crypto_stream_chacha20_H + +/* + * WARNING: This is just a stream cipher. It is NOT authenticated encryption. + * While it provides some protection against eavesdropping, it does NOT + * provide any security against active attacks. + * Unless you know what you're doing, what you are looking for is probably + * the crypto_box functions. + */ + +#include <stddef.h> +#include <stdint.h> +#include "export.h" + +#ifdef __cplusplus +# ifdef __GNUC__ +# pragma GCC diagnostic ignored "-Wlong-long" +# endif +extern "C" { +#endif + +#define crypto_stream_chacha20_KEYBYTES 32U +SODIUM_EXPORT +size_t crypto_stream_chacha20_keybytes(void); + +#define crypto_stream_chacha20_NONCEBYTES 8U +SODIUM_EXPORT +size_t crypto_stream_chacha20_noncebytes(void); + +#define crypto_stream_chacha20_MESSAGEBYTES_MAX SODIUM_SIZE_MAX +SODIUM_EXPORT +size_t crypto_stream_chacha20_messagebytes_max(void); + +/* ChaCha20 with a 64-bit nonce and a 64-bit counter, as originally designed */ + +SODIUM_EXPORT +int crypto_stream_chacha20(unsigned char *c, unsigned long long clen, + const unsigned char *n, const unsigned char *k); + +SODIUM_EXPORT +int crypto_stream_chacha20_xor(unsigned char *c, const unsigned char *m, + unsigned long long mlen, const unsigned char *n, + const unsigned char *k); + +SODIUM_EXPORT +int crypto_stream_chacha20_xor_ic(unsigned char *c, const unsigned char *m, + unsigned long long mlen, + const unsigned char *n, uint64_t ic, + const unsigned char *k); + +SODIUM_EXPORT +void crypto_stream_chacha20_keygen(unsigned char k[crypto_stream_chacha20_KEYBYTES]); + +/* ChaCha20 with a 96-bit nonce and a 32-bit counter (IETF) */ + +#define crypto_stream_chacha20_ietf_KEYBYTES 32U +SODIUM_EXPORT +size_t crypto_stream_chacha20_ietf_keybytes(void); + +#define crypto_stream_chacha20_ietf_NONCEBYTES 12U +SODIUM_EXPORT +size_t crypto_stream_chacha20_ietf_noncebytes(void); + +#define crypto_stream_chacha20_ietf_MESSAGEBYTES_MAX \ + SODIUM_MIN(SODIUM_SIZE_MAX, 64ULL * (1ULL << 32)) +SODIUM_EXPORT +size_t crypto_stream_chacha20_ietf_messagebytes_max(void); + +SODIUM_EXPORT +int crypto_stream_chacha20_ietf(unsigned char *c, unsigned long long clen, + const unsigned char *n, const unsigned char *k); + +SODIUM_EXPORT +int crypto_stream_chacha20_ietf_xor(unsigned char *c, const unsigned char *m, + unsigned long long mlen, const unsigned char *n, + const unsigned char *k); + +SODIUM_EXPORT +int crypto_stream_chacha20_ietf_xor_ic(unsigned char *c, const unsigned char *m, + unsigned long long mlen, + const unsigned char *n, uint32_t ic, + const unsigned char *k); + +SODIUM_EXPORT +void crypto_stream_chacha20_ietf_keygen(unsigned char k[crypto_stream_chacha20_ietf_KEYBYTES]); + +/* Aliases */ + +#define crypto_stream_chacha20_IETF_KEYBYTES crypto_stream_chacha20_ietf_KEYBYTES +#define crypto_stream_chacha20_IETF_NONCEBYTES crypto_stream_chacha20_ietf_NONCEBYTES +#define crypto_stream_chacha20_IETF_MESSAGEBYTES_MAX crypto_stream_chacha20_ietf_MESSAGEBYTES_MAX + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/libs/libsodium/src/include/sodium/crypto_stream_salsa20.h b/libs/libsodium/src/include/sodium/crypto_stream_salsa20.h new file mode 100644 index 0000000000..0c7688c736 --- /dev/null +++ b/libs/libsodium/src/include/sodium/crypto_stream_salsa20.h @@ -0,0 +1,57 @@ +#ifndef crypto_stream_salsa20_H +#define crypto_stream_salsa20_H + +/* + * WARNING: This is just a stream cipher. It is NOT authenticated encryption. + * While it provides some protection against eavesdropping, it does NOT + * provide any security against active attacks. + * Unless you know what you're doing, what you are looking for is probably + * the crypto_box functions. + */ + +#include <stddef.h> +#include <stdint.h> +#include "export.h" + +#ifdef __cplusplus +# ifdef __GNUC__ +# pragma GCC diagnostic ignored "-Wlong-long" +# endif +extern "C" { +#endif + +#define crypto_stream_salsa20_KEYBYTES 32U +SODIUM_EXPORT +size_t crypto_stream_salsa20_keybytes(void); + +#define crypto_stream_salsa20_NONCEBYTES 8U +SODIUM_EXPORT +size_t crypto_stream_salsa20_noncebytes(void); + +#define crypto_stream_salsa20_MESSAGEBYTES_MAX SODIUM_SIZE_MAX +SODIUM_EXPORT +size_t crypto_stream_salsa20_messagebytes_max(void); + +SODIUM_EXPORT +int crypto_stream_salsa20(unsigned char *c, unsigned long long clen, + const unsigned char *n, const unsigned char *k); + +SODIUM_EXPORT +int crypto_stream_salsa20_xor(unsigned char *c, const unsigned char *m, + unsigned long long mlen, const unsigned char *n, + const unsigned char *k); + +SODIUM_EXPORT +int crypto_stream_salsa20_xor_ic(unsigned char *c, const unsigned char *m, + unsigned long long mlen, + const unsigned char *n, uint64_t ic, + const unsigned char *k); + +SODIUM_EXPORT +void crypto_stream_salsa20_keygen(unsigned char k[crypto_stream_salsa20_KEYBYTES]); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/libs/libsodium/src/include/sodium/crypto_stream_salsa2012.h b/libs/libsodium/src/include/sodium/crypto_stream_salsa2012.h new file mode 100644 index 0000000000..c93d1c81f8 --- /dev/null +++ b/libs/libsodium/src/include/sodium/crypto_stream_salsa2012.h @@ -0,0 +1,50 @@ +#ifndef crypto_stream_salsa2012_H +#define crypto_stream_salsa2012_H + +/* + * WARNING: This is just a stream cipher. It is NOT authenticated encryption. + * While it provides some protection against eavesdropping, it does NOT + * provide any security against active attacks. + * Unless you know what you're doing, what you are looking for is probably + * the crypto_box functions. + */ + +#include <stddef.h> +#include "export.h" + +#ifdef __cplusplus +# ifdef __GNUC__ +# pragma GCC diagnostic ignored "-Wlong-long" +# endif +extern "C" { +#endif + +#define crypto_stream_salsa2012_KEYBYTES 32U +SODIUM_EXPORT +size_t crypto_stream_salsa2012_keybytes(void); + +#define crypto_stream_salsa2012_NONCEBYTES 8U +SODIUM_EXPORT +size_t crypto_stream_salsa2012_noncebytes(void); + +#define crypto_stream_salsa2012_MESSAGEBYTES_MAX SODIUM_SIZE_MAX +SODIUM_EXPORT +size_t crypto_stream_salsa2012_messagebytes_max(void); + +SODIUM_EXPORT +int crypto_stream_salsa2012(unsigned char *c, unsigned long long clen, + const unsigned char *n, const unsigned char *k); + +SODIUM_EXPORT +int crypto_stream_salsa2012_xor(unsigned char *c, const unsigned char *m, + unsigned long long mlen, const unsigned char *n, + const unsigned char *k); + +SODIUM_EXPORT +void crypto_stream_salsa2012_keygen(unsigned char k[crypto_stream_salsa2012_KEYBYTES]); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/libs/libsodium/src/include/sodium/crypto_stream_salsa208.h b/libs/libsodium/src/include/sodium/crypto_stream_salsa208.h new file mode 100644 index 0000000000..653f6504bd --- /dev/null +++ b/libs/libsodium/src/include/sodium/crypto_stream_salsa208.h @@ -0,0 +1,56 @@ +#ifndef crypto_stream_salsa208_H +#define crypto_stream_salsa208_H + +/* + * WARNING: This is just a stream cipher. It is NOT authenticated encryption. + * While it provides some protection against eavesdropping, it does NOT + * provide any security against active attacks. + * Unless you know what you're doing, what you are looking for is probably + * the crypto_box functions. + */ + +#include <stddef.h> +#include "export.h" + +#ifdef __cplusplus +# ifdef __GNUC__ +# pragma GCC diagnostic ignored "-Wlong-long" +# endif +extern "C" { +#endif + +#define crypto_stream_salsa208_KEYBYTES 32U +SODIUM_EXPORT +size_t crypto_stream_salsa208_keybytes(void) + __attribute__ ((deprecated)); + +#define crypto_stream_salsa208_NONCEBYTES 8U +SODIUM_EXPORT +size_t crypto_stream_salsa208_noncebytes(void) + __attribute__ ((deprecated)); + +#define crypto_stream_salsa208_MESSAGEBYTES_MAX SODIUM_SIZE_MAX + SODIUM_EXPORT +size_t crypto_stream_salsa208_messagebytes_max(void) + __attribute__ ((deprecated)); + +SODIUM_EXPORT +int crypto_stream_salsa208(unsigned char *c, unsigned long long clen, + const unsigned char *n, const unsigned char *k) + __attribute__ ((deprecated)); + +SODIUM_EXPORT +int crypto_stream_salsa208_xor(unsigned char *c, const unsigned char *m, + unsigned long long mlen, const unsigned char *n, + const unsigned char *k) + __attribute__ ((deprecated)); + +SODIUM_EXPORT +void crypto_stream_salsa208_keygen(unsigned char k[crypto_stream_salsa208_KEYBYTES]) + __attribute__ ((deprecated)); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/libs/libsodium/src/include/sodium/crypto_stream_xchacha20.h b/libs/libsodium/src/include/sodium/crypto_stream_xchacha20.h new file mode 100644 index 0000000000..cf0407ffa7 --- /dev/null +++ b/libs/libsodium/src/include/sodium/crypto_stream_xchacha20.h @@ -0,0 +1,57 @@ +#ifndef crypto_stream_xchacha20_H +#define crypto_stream_xchacha20_H + +/* + * WARNING: This is just a stream cipher. It is NOT authenticated encryption. + * While it provides some protection against eavesdropping, it does NOT + * provide any security against active attacks. + * Unless you know what you're doing, what you are looking for is probably + * the crypto_box functions. + */ + +#include <stddef.h> +#include <stdint.h> +#include "export.h" + +#ifdef __cplusplus +# ifdef __GNUC__ +# pragma GCC diagnostic ignored "-Wlong-long" +# endif +extern "C" { +#endif + +#define crypto_stream_xchacha20_KEYBYTES 32U +SODIUM_EXPORT +size_t crypto_stream_xchacha20_keybytes(void); + +#define crypto_stream_xchacha20_NONCEBYTES 24U +SODIUM_EXPORT +size_t crypto_stream_xchacha20_noncebytes(void); + +#define crypto_stream_xchacha20_MESSAGEBYTES_MAX SODIUM_SIZE_MAX +SODIUM_EXPORT +size_t crypto_stream_xchacha20_messagebytes_max(void); + +SODIUM_EXPORT +int crypto_stream_xchacha20(unsigned char *c, unsigned long long clen, + const unsigned char *n, const unsigned char *k); + +SODIUM_EXPORT +int crypto_stream_xchacha20_xor(unsigned char *c, const unsigned char *m, + unsigned long long mlen, const unsigned char *n, + const unsigned char *k); + +SODIUM_EXPORT +int crypto_stream_xchacha20_xor_ic(unsigned char *c, const unsigned char *m, + unsigned long long mlen, + const unsigned char *n, uint64_t ic, + const unsigned char *k); + +SODIUM_EXPORT +void crypto_stream_xchacha20_keygen(unsigned char k[crypto_stream_xchacha20_KEYBYTES]); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/libs/libsodium/src/include/sodium/crypto_stream_xsalsa20.h b/libs/libsodium/src/include/sodium/crypto_stream_xsalsa20.h new file mode 100644 index 0000000000..cb4c44a8b8 --- /dev/null +++ b/libs/libsodium/src/include/sodium/crypto_stream_xsalsa20.h @@ -0,0 +1,57 @@ +#ifndef crypto_stream_xsalsa20_H +#define crypto_stream_xsalsa20_H + +/* + * WARNING: This is just a stream cipher. It is NOT authenticated encryption. + * While it provides some protection against eavesdropping, it does NOT + * provide any security against active attacks. + * Unless you know what you're doing, what you are looking for is probably + * the crypto_box functions. + */ + +#include <stddef.h> +#include <stdint.h> +#include "export.h" + +#ifdef __cplusplus +# ifdef __GNUC__ +# pragma GCC diagnostic ignored "-Wlong-long" +# endif +extern "C" { +#endif + +#define crypto_stream_xsalsa20_KEYBYTES 32U +SODIUM_EXPORT +size_t crypto_stream_xsalsa20_keybytes(void); + +#define crypto_stream_xsalsa20_NONCEBYTES 24U +SODIUM_EXPORT +size_t crypto_stream_xsalsa20_noncebytes(void); + +#define crypto_stream_xsalsa20_MESSAGEBYTES_MAX SODIUM_SIZE_MAX +SODIUM_EXPORT +size_t crypto_stream_xsalsa20_messagebytes_max(void); + +SODIUM_EXPORT +int crypto_stream_xsalsa20(unsigned char *c, unsigned long long clen, + const unsigned char *n, const unsigned char *k); + +SODIUM_EXPORT +int crypto_stream_xsalsa20_xor(unsigned char *c, const unsigned char *m, + unsigned long long mlen, const unsigned char *n, + const unsigned char *k); + +SODIUM_EXPORT +int crypto_stream_xsalsa20_xor_ic(unsigned char *c, const unsigned char *m, + unsigned long long mlen, + const unsigned char *n, uint64_t ic, + const unsigned char *k); + +SODIUM_EXPORT +void crypto_stream_xsalsa20_keygen(unsigned char k[crypto_stream_xsalsa20_KEYBYTES]); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/libs/libsodium/src/include/sodium/crypto_verify_16.h b/libs/libsodium/src/include/sodium/crypto_verify_16.h new file mode 100644 index 0000000000..5e9eeabee8 --- /dev/null +++ b/libs/libsodium/src/include/sodium/crypto_verify_16.h @@ -0,0 +1,23 @@ +#ifndef crypto_verify_16_H +#define crypto_verify_16_H + +#include <stddef.h> +#include "export.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define crypto_verify_16_BYTES 16U +SODIUM_EXPORT +size_t crypto_verify_16_bytes(void); + +SODIUM_EXPORT +int crypto_verify_16(const unsigned char *x, const unsigned char *y) + __attribute__ ((warn_unused_result)); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/libs/libsodium/src/include/sodium/crypto_verify_32.h b/libs/libsodium/src/include/sodium/crypto_verify_32.h new file mode 100644 index 0000000000..281b5a1bb7 --- /dev/null +++ b/libs/libsodium/src/include/sodium/crypto_verify_32.h @@ -0,0 +1,23 @@ +#ifndef crypto_verify_32_H +#define crypto_verify_32_H + +#include <stddef.h> +#include "export.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define crypto_verify_32_BYTES 32U +SODIUM_EXPORT +size_t crypto_verify_32_bytes(void); + +SODIUM_EXPORT +int crypto_verify_32(const unsigned char *x, const unsigned char *y) + __attribute__ ((warn_unused_result)); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/libs/libsodium/src/include/sodium/crypto_verify_64.h b/libs/libsodium/src/include/sodium/crypto_verify_64.h new file mode 100644 index 0000000000..0dc7c304a9 --- /dev/null +++ b/libs/libsodium/src/include/sodium/crypto_verify_64.h @@ -0,0 +1,23 @@ +#ifndef crypto_verify_64_H +#define crypto_verify_64_H + +#include <stddef.h> +#include "export.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define crypto_verify_64_BYTES 64U +SODIUM_EXPORT +size_t crypto_verify_64_bytes(void); + +SODIUM_EXPORT +int crypto_verify_64(const unsigned char *x, const unsigned char *y) + __attribute__ ((warn_unused_result)); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/libs/libsodium/src/include/sodium/export.h b/libs/libsodium/src/include/sodium/export.h new file mode 100644 index 0000000000..0f624ae3c5 --- /dev/null +++ b/libs/libsodium/src/include/sodium/export.h @@ -0,0 +1,53 @@ + +#ifndef sodium_export_H +#define sodium_export_H + +#ifndef __GNUC__ +# ifdef __attribute__ +# undef __attribute__ +# endif +# define __attribute__(a) +#endif + +#ifdef SODIUM_STATIC +# define SODIUM_EXPORT +# define SODIUM_EXPORT_WEAK +#else +# if defined(_MSC_VER) +# ifdef SODIUM_DLL_EXPORT +# define SODIUM_EXPORT __declspec(dllexport) +# else +# define SODIUM_EXPORT __declspec(dllimport) +# endif +# else +# if defined(__SUNPRO_C) +# ifndef __GNU_C__ +# define SODIUM_EXPORT __attribute__ (visibility(__global)) +# else +# define SODIUM_EXPORT __attribute__ __global +# endif +# elif defined(_MSG_VER) +# define SODIUM_EXPORT extern __declspec(dllexport) +# else +# define SODIUM_EXPORT __attribute__ ((visibility ("default"))) +# endif +# endif +# if defined(__ELF__) && !defined(SODIUM_DISABLE_WEAK_FUNCTIONS) +# define SODIUM_EXPORT_WEAK SODIUM_EXPORT __attribute__((weak)) +# else +# define SODIUM_EXPORT_WEAK SODIUM_EXPORT +# endif +#endif + +#ifndef CRYPTO_ALIGN +# if defined(__INTEL_COMPILER) || defined(_MSC_VER) +# define CRYPTO_ALIGN(x) __declspec(align(x)) +# else +# define CRYPTO_ALIGN(x) __attribute__ ((aligned(x))) +# endif +#endif + +#define SODIUM_MIN(A, B) ((A) < (B) ? (A) : (B)) +#define SODIUM_SIZE_MAX SODIUM_MIN(UINT64_MAX, SIZE_MAX) + +#endif diff --git a/libs/libsodium/src/include/sodium/private/common.h b/libs/libsodium/src/include/sodium/private/common.h new file mode 100644 index 0000000000..954d02ccd7 --- /dev/null +++ b/libs/libsodium/src/include/sodium/private/common.h @@ -0,0 +1,246 @@ +#ifndef common_H +#define common_H 1 + +#include <stdint.h> +#include <stdlib.h> +#include <string.h> + +#define COMPILER_ASSERT(X) (void) sizeof(char[(X) ? 1 : -1]) + +#ifdef HAVE_TI_MODE +# if defined(__SIZEOF_INT128__) +typedef unsigned __int128 uint128_t; +# else +typedef unsigned uint128_t __attribute__((mode(TI))); +# endif +#endif + +#define ROTL32(X, B) rotl32((X), (B)) +static inline uint32_t +rotl32(const uint32_t x, const int b) +{ + return (x << b) | (x >> (32 - b)); +} + +#define ROTL64(X, B) rotl64((X), (B)) +static inline uint64_t +rotl64(const uint64_t x, const int b) +{ + return (x << b) | (x >> (64 - b)); +} + +#define ROTR32(X, B) rotr32((X), (B)) +static inline uint32_t +rotr32(const uint32_t x, const int b) +{ + return (x >> b) | (x << (32 - b)); +} + +#define ROTR64(X, B) rotr64((X), (B)) +static inline uint64_t +rotr64(const uint64_t x, const int b) +{ + return (x >> b) | (x << (64 - b)); +} + +#define LOAD64_LE(SRC) load64_le(SRC) +static inline uint64_t +load64_le(const uint8_t src[8]) +{ +#ifdef NATIVE_LITTLE_ENDIAN + uint64_t w; + memcpy(&w, src, sizeof w); + return w; +#else + uint64_t w = (uint64_t) src[0]; + w |= (uint64_t) src[1] << 8; + w |= (uint64_t) src[2] << 16; + w |= (uint64_t) src[3] << 24; + w |= (uint64_t) src[4] << 32; + w |= (uint64_t) src[5] << 40; + w |= (uint64_t) src[6] << 48; + w |= (uint64_t) src[7] << 56; + return w; +#endif +} + +#define STORE64_LE(DST, W) store64_le((DST), (W)) +static inline void +store64_le(uint8_t dst[8], uint64_t w) +{ +#ifdef NATIVE_LITTLE_ENDIAN + memcpy(dst, &w, sizeof w); +#else + dst[0] = (uint8_t) w; w >>= 8; + dst[1] = (uint8_t) w; w >>= 8; + dst[2] = (uint8_t) w; w >>= 8; + dst[3] = (uint8_t) w; w >>= 8; + dst[4] = (uint8_t) w; w >>= 8; + dst[5] = (uint8_t) w; w >>= 8; + dst[6] = (uint8_t) w; w >>= 8; + dst[7] = (uint8_t) w; +#endif +} + +#define LOAD32_LE(SRC) load32_le(SRC) +static inline uint32_t +load32_le(const uint8_t src[4]) +{ +#ifdef NATIVE_LITTLE_ENDIAN + uint32_t w; + memcpy(&w, src, sizeof w); + return w; +#else + uint32_t w = (uint32_t) src[0]; + w |= (uint32_t) src[1] << 8; + w |= (uint32_t) src[2] << 16; + w |= (uint32_t) src[3] << 24; + return w; +#endif +} + +#define STORE32_LE(DST, W) store32_le((DST), (W)) +static inline void +store32_le(uint8_t dst[4], uint32_t w) +{ +#ifdef NATIVE_LITTLE_ENDIAN + memcpy(dst, &w, sizeof w); +#else + dst[0] = (uint8_t) w; w >>= 8; + dst[1] = (uint8_t) w; w >>= 8; + dst[2] = (uint8_t) w; w >>= 8; + dst[3] = (uint8_t) w; +#endif +} + +/* ----- */ + +#define LOAD64_BE(SRC) load64_be(SRC) +static inline uint64_t +load64_be(const uint8_t src[8]) +{ +#ifdef NATIVE_BIG_ENDIAN + uint64_t w; + memcpy(&w, src, sizeof w); + return w; +#else + uint64_t w = (uint64_t) src[7]; + w |= (uint64_t) src[6] << 8; + w |= (uint64_t) src[5] << 16; + w |= (uint64_t) src[4] << 24; + w |= (uint64_t) src[3] << 32; + w |= (uint64_t) src[2] << 40; + w |= (uint64_t) src[1] << 48; + w |= (uint64_t) src[0] << 56; + return w; +#endif +} + +#define STORE64_BE(DST, W) store64_be((DST), (W)) +static inline void +store64_be(uint8_t dst[8], uint64_t w) +{ +#ifdef NATIVE_BIG_ENDIAN + memcpy(dst, &w, sizeof w); +#else + dst[7] = (uint8_t) w; w >>= 8; + dst[6] = (uint8_t) w; w >>= 8; + dst[5] = (uint8_t) w; w >>= 8; + dst[4] = (uint8_t) w; w >>= 8; + dst[3] = (uint8_t) w; w >>= 8; + dst[2] = (uint8_t) w; w >>= 8; + dst[1] = (uint8_t) w; w >>= 8; + dst[0] = (uint8_t) w; +#endif +} + +#define LOAD32_BE(SRC) load32_be(SRC) +static inline uint32_t +load32_be(const uint8_t src[4]) +{ +#ifdef NATIVE_BIG_ENDIAN + uint32_t w; + memcpy(&w, src, sizeof w); + return w; +#else + uint32_t w = (uint32_t) src[3]; + w |= (uint32_t) src[2] << 8; + w |= (uint32_t) src[1] << 16; + w |= (uint32_t) src[0] << 24; + return w; +#endif +} + +#define STORE32_BE(DST, W) store32_be((DST), (W)) +static inline void +store32_be(uint8_t dst[4], uint32_t w) +{ +#ifdef NATIVE_BIG_ENDIAN + memcpy(dst, &w, sizeof w); +#else + dst[3] = (uint8_t) w; w >>= 8; + dst[2] = (uint8_t) w; w >>= 8; + dst[1] = (uint8_t) w; w >>= 8; + dst[0] = (uint8_t) w; +#endif +} + +#define XOR_BUF(OUT, IN, N) xor_buf((OUT), (IN), (N)) +static inline void +xor_buf(unsigned char *out, const unsigned char *in, size_t n) +{ + size_t i; + + for (i = 0; i < n; i++) { + out[i] ^= in[i]; + } +} + +#ifndef __GNUC__ +# ifdef __attribute__ +# undef __attribute__ +# endif +# define __attribute__(a) +#endif + +#ifndef CRYPTO_ALIGN +# if defined(__INTEL_COMPILER) || defined(_MSC_VER) +# define CRYPTO_ALIGN(x) __declspec(align(x)) +# else +# define CRYPTO_ALIGN(x) __attribute__ ((aligned(x))) +# endif +#endif + +#if defined(_MSC_VER) && \ + (defined(_M_X64) || defined(_M_AMD64) || defined(_M_IX86)) + +# include <intrin.h> + +# define HAVE_INTRIN_H 1 +# define HAVE_MMINTRIN_H 1 +# define HAVE_EMMINTRIN_H 1 +# define HAVE_PMMINTRIN_H 1 +# define HAVE_TMMINTRIN_H 1 +# define HAVE_SMMINTRIN_H 1 +# define HAVE_AVXINTRIN_H 1 +# if _MSC_VER >= 1600 +# define HAVE_WMMINTRIN_H 1 +# endif +# if _MSC_VER >= 1700 && defined(_M_X64) +# define HAVE_AVX2INTRIN_H 1 +# endif +#elif defined(HAVE_INTRIN_H) +# include <intrin.h> +#endif + +#ifdef HAVE_LIBCTGRIND +extern void ct_poison (const void *, size_t); +extern void ct_unpoison(const void *, size_t); +# define POISON(X, L) ct_poison((X), (L)) +# define UNPOISON(X, L) ct_unpoison((X), (L)) +#else +# define POISON(X, L) (void) 0 +# define UNPOISON(X, L) (void) 0 +#endif + +#endif diff --git a/libs/libsodium/src/include/sodium/private/ed25519_ref10.h b/libs/libsodium/src/include/sodium/private/ed25519_ref10.h new file mode 100644 index 0000000000..42fcd98139 --- /dev/null +++ b/libs/libsodium/src/include/sodium/private/ed25519_ref10.h @@ -0,0 +1,125 @@ +#ifndef ed25519_ref10_H +#define ed25519_ref10_H + +#include <stddef.h> +#include <stdint.h> + +/* + fe means field element. + Here the field is \Z/(2^255-19). + */ + +#ifdef HAVE_TI_MODE +typedef uint64_t fe25519[5]; +#else +typedef int32_t fe25519[10]; +#endif + +void fe25519_invert(fe25519 out, const fe25519 z); +void fe25519_frombytes(fe25519 h, const unsigned char *s); +void fe25519_tobytes(unsigned char *s, const fe25519 h); + +#ifdef HAVE_TI_MODE +# include "ed25519_ref10_fe_51.h" +#else +# include "ed25519_ref10_fe_25_5.h" +#endif + + +/* + ge means group element. + + Here the group is the set of pairs (x,y) of field elements + satisfying -x^2 + y^2 = 1 + d x^2y^2 + where d = -121665/121666. + + Representations: + ge25519_p2 (projective): (X:Y:Z) satisfying x=X/Z, y=Y/Z + ge25519_p3 (extended): (X:Y:Z:T) satisfying x=X/Z, y=Y/Z, XY=ZT + ge25519_p1p1 (completed): ((X:Z),(Y:T)) satisfying x=X/Z, y=Y/T + ge25519_precomp (Duif): (y+x,y-x,2dxy) + */ + +typedef struct { + fe25519 X; + fe25519 Y; + fe25519 Z; +} ge25519_p2; + +typedef struct { + fe25519 X; + fe25519 Y; + fe25519 Z; + fe25519 T; +} ge25519_p3; + +typedef struct { + fe25519 X; + fe25519 Y; + fe25519 Z; + fe25519 T; +} ge25519_p1p1; + +typedef struct { + fe25519 yplusx; + fe25519 yminusx; + fe25519 xy2d; +} ge25519_precomp; + +typedef struct { + fe25519 YplusX; + fe25519 YminusX; + fe25519 Z; + fe25519 T2d; +} ge25519_cached; + +void ge25519_tobytes(unsigned char *s, const ge25519_p2 *h); + +void ge25519_p3_tobytes(unsigned char *s, const ge25519_p3 *h); + +int ge25519_frombytes(ge25519_p3 *h, const unsigned char *s); + +int ge25519_frombytes_negate_vartime(ge25519_p3 *h, const unsigned char *s); + +void ge25519_p3_to_cached(ge25519_cached *r, const ge25519_p3 *p); + +void ge25519_p1p1_to_p2(ge25519_p2 *r, const ge25519_p1p1 *p); + +void ge25519_p1p1_to_p3(ge25519_p3 *r, const ge25519_p1p1 *p); + +void ge25519_add(ge25519_p1p1 *r, const ge25519_p3 *p, const ge25519_cached *q); + +void ge25519_sub(ge25519_p1p1 *r, const ge25519_p3 *p, const ge25519_cached *q); + +void ge25519_scalarmult_base(ge25519_p3 *h, const unsigned char *a); + +void ge25519_double_scalarmult_vartime(ge25519_p2 *r, const unsigned char *a, + const ge25519_p3 *A, + const unsigned char *b); + +void ge25519_scalarmult(ge25519_p3 *h, const unsigned char *a, + const ge25519_p3 *p); + +int ge25519_is_canonical(const unsigned char *s); + +int ge25519_is_on_curve(const ge25519_p3 *p); + +int ge25519_is_on_main_subgroup(const ge25519_p3 *p); + +int ge25519_has_small_order(const unsigned char s[32]); + +void ge25519_from_uniform(unsigned char s[32], const unsigned char r[32]); + +/* + The set of scalars is \Z/l + where l = 2^252 + 27742317777372353535851937790883648493. + */ + +void sc25519_reduce(unsigned char *s); + +void sc25519_muladd(unsigned char *s, const unsigned char *a, + const unsigned char *b, const unsigned char *c); + +int sc25519_is_canonical(const unsigned char *s); + +#endif diff --git a/libs/libsodium/src/include/sodium/private/ed25519_ref10_fe_25_5.h b/libs/libsodium/src/include/sodium/private/ed25519_ref10_fe_25_5.h new file mode 100644 index 0000000000..5a0b6148b7 --- /dev/null +++ b/libs/libsodium/src/include/sodium/private/ed25519_ref10_fe_25_5.h @@ -0,0 +1,1050 @@ +#include <string.h> + +#include "private/common.h" +#include "utils.h" + +/* + h = 0 + */ + +static inline void +fe25519_0(fe25519 h) +{ + memset(&h[0], 0, 10 * sizeof h[0]); +} + +/* + h = 1 + */ + +static inline void +fe25519_1(fe25519 h) +{ + h[0] = 1; + h[1] = 0; + memset(&h[2], 0, 8 * sizeof h[0]); +} + +/* + h = f + g + Can overlap h with f or g. + * + Preconditions: + |f| bounded by 1.1*2^25,1.1*2^24,1.1*2^25,1.1*2^24,etc. + |g| bounded by 1.1*2^25,1.1*2^24,1.1*2^25,1.1*2^24,etc. + * + Postconditions: + |h| bounded by 1.1*2^26,1.1*2^25,1.1*2^26,1.1*2^25,etc. + */ + +static inline void +fe25519_add(fe25519 h, const fe25519 f, const fe25519 g) +{ + int32_t h0 = f[0] + g[0]; + int32_t h1 = f[1] + g[1]; + int32_t h2 = f[2] + g[2]; + int32_t h3 = f[3] + g[3]; + int32_t h4 = f[4] + g[4]; + int32_t h5 = f[5] + g[5]; + int32_t h6 = f[6] + g[6]; + int32_t h7 = f[7] + g[7]; + int32_t h8 = f[8] + g[8]; + int32_t h9 = f[9] + g[9]; + + h[0] = h0; + h[1] = h1; + h[2] = h2; + h[3] = h3; + h[4] = h4; + h[5] = h5; + h[6] = h6; + h[7] = h7; + h[8] = h8; + h[9] = h9; +} + +/* + h = f - g + Can overlap h with f or g. + * + Preconditions: + |f| bounded by 1.1*2^25,1.1*2^24,1.1*2^25,1.1*2^24,etc. + |g| bounded by 1.1*2^25,1.1*2^24,1.1*2^25,1.1*2^24,etc. + * + Postconditions: + |h| bounded by 1.1*2^26,1.1*2^25,1.1*2^26,1.1*2^25,etc. + */ + +static void +fe25519_sub(fe25519 h, const fe25519 f, const fe25519 g) +{ + int32_t h0 = f[0] - g[0]; + int32_t h1 = f[1] - g[1]; + int32_t h2 = f[2] - g[2]; + int32_t h3 = f[3] - g[3]; + int32_t h4 = f[4] - g[4]; + int32_t h5 = f[5] - g[5]; + int32_t h6 = f[6] - g[6]; + int32_t h7 = f[7] - g[7]; + int32_t h8 = f[8] - g[8]; + int32_t h9 = f[9] - g[9]; + + h[0] = h0; + h[1] = h1; + h[2] = h2; + h[3] = h3; + h[4] = h4; + h[5] = h5; + h[6] = h6; + h[7] = h7; + h[8] = h8; + h[9] = h9; +} + +/* + h = -f + * + Preconditions: + |f| bounded by 1.1*2^25,1.1*2^24,1.1*2^25,1.1*2^24,etc. + * + Postconditions: + |h| bounded by 1.1*2^25,1.1*2^24,1.1*2^25,1.1*2^24,etc. + */ + +static inline void +fe25519_neg(fe25519 h, const fe25519 f) +{ + int32_t h0 = -f[0]; + int32_t h1 = -f[1]; + int32_t h2 = -f[2]; + int32_t h3 = -f[3]; + int32_t h4 = -f[4]; + int32_t h5 = -f[5]; + int32_t h6 = -f[6]; + int32_t h7 = -f[7]; + int32_t h8 = -f[8]; + int32_t h9 = -f[9]; + + h[0] = h0; + h[1] = h1; + h[2] = h2; + h[3] = h3; + h[4] = h4; + h[5] = h5; + h[6] = h6; + h[7] = h7; + h[8] = h8; + h[9] = h9; +} + +/* + Replace (f,g) with (g,g) if b == 1; + replace (f,g) with (f,g) if b == 0. + * + Preconditions: b in {0,1}. + */ + +static void +fe25519_cmov(fe25519 f, const fe25519 g, unsigned int b) +{ + const uint32_t mask = (uint32_t) (-(int32_t) b); + + int32_t f0 = f[0]; + int32_t f1 = f[1]; + int32_t f2 = f[2]; + int32_t f3 = f[3]; + int32_t f4 = f[4]; + int32_t f5 = f[5]; + int32_t f6 = f[6]; + int32_t f7 = f[7]; + int32_t f8 = f[8]; + int32_t f9 = f[9]; + + int32_t x0 = f0 ^ g[0]; + int32_t x1 = f1 ^ g[1]; + int32_t x2 = f2 ^ g[2]; + int32_t x3 = f3 ^ g[3]; + int32_t x4 = f4 ^ g[4]; + int32_t x5 = f5 ^ g[5]; + int32_t x6 = f6 ^ g[6]; + int32_t x7 = f7 ^ g[7]; + int32_t x8 = f8 ^ g[8]; + int32_t x9 = f9 ^ g[9]; + + x0 &= mask; + x1 &= mask; + x2 &= mask; + x3 &= mask; + x4 &= mask; + x5 &= mask; + x6 &= mask; + x7 &= mask; + x8 &= mask; + x9 &= mask; + + f[0] = f0 ^ x0; + f[1] = f1 ^ x1; + f[2] = f2 ^ x2; + f[3] = f3 ^ x3; + f[4] = f4 ^ x4; + f[5] = f5 ^ x5; + f[6] = f6 ^ x6; + f[7] = f7 ^ x7; + f[8] = f8 ^ x8; + f[9] = f9 ^ x9; +} + +static void +fe25519_cswap(fe25519 f, fe25519 g, unsigned int b) +{ + const uint32_t mask = (uint32_t) (-(int64_t) b); + + int32_t f0 = f[0]; + int32_t f1 = f[1]; + int32_t f2 = f[2]; + int32_t f3 = f[3]; + int32_t f4 = f[4]; + int32_t f5 = f[5]; + int32_t f6 = f[6]; + int32_t f7 = f[7]; + int32_t f8 = f[8]; + int32_t f9 = f[9]; + + int32_t g0 = g[0]; + int32_t g1 = g[1]; + int32_t g2 = g[2]; + int32_t g3 = g[3]; + int32_t g4 = g[4]; + int32_t g5 = g[5]; + int32_t g6 = g[6]; + int32_t g7 = g[7]; + int32_t g8 = g[8]; + int32_t g9 = g[9]; + + int32_t x0 = f0 ^ g0; + int32_t x1 = f1 ^ g1; + int32_t x2 = f2 ^ g2; + int32_t x3 = f3 ^ g3; + int32_t x4 = f4 ^ g4; + int32_t x5 = f5 ^ g5; + int32_t x6 = f6 ^ g6; + int32_t x7 = f7 ^ g7; + int32_t x8 = f8 ^ g8; + int32_t x9 = f9 ^ g9; + + x0 &= mask; + x1 &= mask; + x2 &= mask; + x3 &= mask; + x4 &= mask; + x5 &= mask; + x6 &= mask; + x7 &= mask; + x8 &= mask; + x9 &= mask; + + f[0] = f0 ^ x0; + f[1] = f1 ^ x1; + f[2] = f2 ^ x2; + f[3] = f3 ^ x3; + f[4] = f4 ^ x4; + f[5] = f5 ^ x5; + f[6] = f6 ^ x6; + f[7] = f7 ^ x7; + f[8] = f8 ^ x8; + f[9] = f9 ^ x9; + + g[0] = g0 ^ x0; + g[1] = g1 ^ x1; + g[2] = g2 ^ x2; + g[3] = g3 ^ x3; + g[4] = g4 ^ x4; + g[5] = g5 ^ x5; + g[6] = g6 ^ x6; + g[7] = g7 ^ x7; + g[8] = g8 ^ x8; + g[9] = g9 ^ x9; +} + +/* + h = f + */ + +static inline void +fe25519_copy(fe25519 h, const fe25519 f) +{ + int32_t f0 = f[0]; + int32_t f1 = f[1]; + int32_t f2 = f[2]; + int32_t f3 = f[3]; + int32_t f4 = f[4]; + int32_t f5 = f[5]; + int32_t f6 = f[6]; + int32_t f7 = f[7]; + int32_t f8 = f[8]; + int32_t f9 = f[9]; + + h[0] = f0; + h[1] = f1; + h[2] = f2; + h[3] = f3; + h[4] = f4; + h[5] = f5; + h[6] = f6; + h[7] = f7; + h[8] = f8; + h[9] = f9; +} + +/* + return 1 if f is in {1,3,5,...,q-2} + return 0 if f is in {0,2,4,...,q-1} + + Preconditions: + |f| bounded by 1.1*2^26,1.1*2^25,1.1*2^26,1.1*2^25,etc. + */ + +static inline int +fe25519_isnegative(const fe25519 f) +{ + unsigned char s[32]; + + fe25519_tobytes(s, f); + + return s[0] & 1; +} + +/* + return 1 if f == 0 + return 0 if f != 0 + + Preconditions: + |f| bounded by 1.1*2^26,1.1*2^25,1.1*2^26,1.1*2^25,etc. + */ + +static inline int +fe25519_iszero(const fe25519 f) +{ + unsigned char s[32]; + + fe25519_tobytes(s, f); + + return sodium_is_zero(s, 32); +} + +/* + h = f * g + Can overlap h with f or g. + * + Preconditions: + |f| bounded by 1.65*2^26,1.65*2^25,1.65*2^26,1.65*2^25,etc. + |g| bounded by 1.65*2^26,1.65*2^25,1.65*2^26,1.65*2^25,etc. + * + Postconditions: + |h| bounded by 1.01*2^25,1.01*2^24,1.01*2^25,1.01*2^24,etc. + */ + +/* + Notes on implementation strategy: + * + Using schoolbook multiplication. + Karatsuba would save a little in some cost models. + * + Most multiplications by 2 and 19 are 32-bit precomputations; + cheaper than 64-bit postcomputations. + * + There is one remaining multiplication by 19 in the carry chain; + one *19 precomputation can be merged into this, + but the resulting data flow is considerably less clean. + * + There are 12 carries below. + 10 of them are 2-way parallelizable and vectorizable. + Can get away with 11 carries, but then data flow is much deeper. + * + With tighter constraints on inputs can squeeze carries into int32. + */ + +static void +fe25519_mul(fe25519 h, const fe25519 f, const fe25519 g) +{ + int32_t f0 = f[0]; + int32_t f1 = f[1]; + int32_t f2 = f[2]; + int32_t f3 = f[3]; + int32_t f4 = f[4]; + int32_t f5 = f[5]; + int32_t f6 = f[6]; + int32_t f7 = f[7]; + int32_t f8 = f[8]; + int32_t f9 = f[9]; + + int32_t g0 = g[0]; + int32_t g1 = g[1]; + int32_t g2 = g[2]; + int32_t g3 = g[3]; + int32_t g4 = g[4]; + int32_t g5 = g[5]; + int32_t g6 = g[6]; + int32_t g7 = g[7]; + int32_t g8 = g[8]; + int32_t g9 = g[9]; + + int32_t g1_19 = 19 * g1; /* 1.959375*2^29 */ + int32_t g2_19 = 19 * g2; /* 1.959375*2^30; still ok */ + int32_t g3_19 = 19 * g3; + int32_t g4_19 = 19 * g4; + int32_t g5_19 = 19 * g5; + int32_t g6_19 = 19 * g6; + int32_t g7_19 = 19 * g7; + int32_t g8_19 = 19 * g8; + int32_t g9_19 = 19 * g9; + int32_t f1_2 = 2 * f1; + int32_t f3_2 = 2 * f3; + int32_t f5_2 = 2 * f5; + int32_t f7_2 = 2 * f7; + int32_t f9_2 = 2 * f9; + + int64_t f0g0 = f0 * (int64_t) g0; + int64_t f0g1 = f0 * (int64_t) g1; + int64_t f0g2 = f0 * (int64_t) g2; + int64_t f0g3 = f0 * (int64_t) g3; + int64_t f0g4 = f0 * (int64_t) g4; + int64_t f0g5 = f0 * (int64_t) g5; + int64_t f0g6 = f0 * (int64_t) g6; + int64_t f0g7 = f0 * (int64_t) g7; + int64_t f0g8 = f0 * (int64_t) g8; + int64_t f0g9 = f0 * (int64_t) g9; + int64_t f1g0 = f1 * (int64_t) g0; + int64_t f1g1_2 = f1_2 * (int64_t) g1; + int64_t f1g2 = f1 * (int64_t) g2; + int64_t f1g3_2 = f1_2 * (int64_t) g3; + int64_t f1g4 = f1 * (int64_t) g4; + int64_t f1g5_2 = f1_2 * (int64_t) g5; + int64_t f1g6 = f1 * (int64_t) g6; + int64_t f1g7_2 = f1_2 * (int64_t) g7; + int64_t f1g8 = f1 * (int64_t) g8; + int64_t f1g9_38 = f1_2 * (int64_t) g9_19; + int64_t f2g0 = f2 * (int64_t) g0; + int64_t f2g1 = f2 * (int64_t) g1; + int64_t f2g2 = f2 * (int64_t) g2; + int64_t f2g3 = f2 * (int64_t) g3; + int64_t f2g4 = f2 * (int64_t) g4; + int64_t f2g5 = f2 * (int64_t) g5; + int64_t f2g6 = f2 * (int64_t) g6; + int64_t f2g7 = f2 * (int64_t) g7; + int64_t f2g8_19 = f2 * (int64_t) g8_19; + int64_t f2g9_19 = f2 * (int64_t) g9_19; + int64_t f3g0 = f3 * (int64_t) g0; + int64_t f3g1_2 = f3_2 * (int64_t) g1; + int64_t f3g2 = f3 * (int64_t) g2; + int64_t f3g3_2 = f3_2 * (int64_t) g3; + int64_t f3g4 = f3 * (int64_t) g4; + int64_t f3g5_2 = f3_2 * (int64_t) g5; + int64_t f3g6 = f3 * (int64_t) g6; + int64_t f3g7_38 = f3_2 * (int64_t) g7_19; + int64_t f3g8_19 = f3 * (int64_t) g8_19; + int64_t f3g9_38 = f3_2 * (int64_t) g9_19; + int64_t f4g0 = f4 * (int64_t) g0; + int64_t f4g1 = f4 * (int64_t) g1; + int64_t f4g2 = f4 * (int64_t) g2; + int64_t f4g3 = f4 * (int64_t) g3; + int64_t f4g4 = f4 * (int64_t) g4; + int64_t f4g5 = f4 * (int64_t) g5; + int64_t f4g6_19 = f4 * (int64_t) g6_19; + int64_t f4g7_19 = f4 * (int64_t) g7_19; + int64_t f4g8_19 = f4 * (int64_t) g8_19; + int64_t f4g9_19 = f4 * (int64_t) g9_19; + int64_t f5g0 = f5 * (int64_t) g0; + int64_t f5g1_2 = f5_2 * (int64_t) g1; + int64_t f5g2 = f5 * (int64_t) g2; + int64_t f5g3_2 = f5_2 * (int64_t) g3; + int64_t f5g4 = f5 * (int64_t) g4; + int64_t f5g5_38 = f5_2 * (int64_t) g5_19; + int64_t f5g6_19 = f5 * (int64_t) g6_19; + int64_t f5g7_38 = f5_2 * (int64_t) g7_19; + int64_t f5g8_19 = f5 * (int64_t) g8_19; + int64_t f5g9_38 = f5_2 * (int64_t) g9_19; + int64_t f6g0 = f6 * (int64_t) g0; + int64_t f6g1 = f6 * (int64_t) g1; + int64_t f6g2 = f6 * (int64_t) g2; + int64_t f6g3 = f6 * (int64_t) g3; + int64_t f6g4_19 = f6 * (int64_t) g4_19; + int64_t f6g5_19 = f6 * (int64_t) g5_19; + int64_t f6g6_19 = f6 * (int64_t) g6_19; + int64_t f6g7_19 = f6 * (int64_t) g7_19; + int64_t f6g8_19 = f6 * (int64_t) g8_19; + int64_t f6g9_19 = f6 * (int64_t) g9_19; + int64_t f7g0 = f7 * (int64_t) g0; + int64_t f7g1_2 = f7_2 * (int64_t) g1; + int64_t f7g2 = f7 * (int64_t) g2; + int64_t f7g3_38 = f7_2 * (int64_t) g3_19; + int64_t f7g4_19 = f7 * (int64_t) g4_19; + int64_t f7g5_38 = f7_2 * (int64_t) g5_19; + int64_t f7g6_19 = f7 * (int64_t) g6_19; + int64_t f7g7_38 = f7_2 * (int64_t) g7_19; + int64_t f7g8_19 = f7 * (int64_t) g8_19; + int64_t f7g9_38 = f7_2 * (int64_t) g9_19; + int64_t f8g0 = f8 * (int64_t) g0; + int64_t f8g1 = f8 * (int64_t) g1; + int64_t f8g2_19 = f8 * (int64_t) g2_19; + int64_t f8g3_19 = f8 * (int64_t) g3_19; + int64_t f8g4_19 = f8 * (int64_t) g4_19; + int64_t f8g5_19 = f8 * (int64_t) g5_19; + int64_t f8g6_19 = f8 * (int64_t) g6_19; + int64_t f8g7_19 = f8 * (int64_t) g7_19; + int64_t f8g8_19 = f8 * (int64_t) g8_19; + int64_t f8g9_19 = f8 * (int64_t) g9_19; + int64_t f9g0 = f9 * (int64_t) g0; + int64_t f9g1_38 = f9_2 * (int64_t) g1_19; + int64_t f9g2_19 = f9 * (int64_t) g2_19; + int64_t f9g3_38 = f9_2 * (int64_t) g3_19; + int64_t f9g4_19 = f9 * (int64_t) g4_19; + int64_t f9g5_38 = f9_2 * (int64_t) g5_19; + int64_t f9g6_19 = f9 * (int64_t) g6_19; + int64_t f9g7_38 = f9_2 * (int64_t) g7_19; + int64_t f9g8_19 = f9 * (int64_t) g8_19; + int64_t f9g9_38 = f9_2 * (int64_t) g9_19; + + int64_t h0 = f0g0 + f1g9_38 + f2g8_19 + f3g7_38 + f4g6_19 + f5g5_38 + + f6g4_19 + f7g3_38 + f8g2_19 + f9g1_38; + int64_t h1 = f0g1 + f1g0 + f2g9_19 + f3g8_19 + f4g7_19 + f5g6_19 + f6g5_19 + + f7g4_19 + f8g3_19 + f9g2_19; + int64_t h2 = f0g2 + f1g1_2 + f2g0 + f3g9_38 + f4g8_19 + f5g7_38 + f6g6_19 + + f7g5_38 + f8g4_19 + f9g3_38; + int64_t h3 = f0g3 + f1g2 + f2g1 + f3g0 + f4g9_19 + f5g8_19 + f6g7_19 + + f7g6_19 + f8g5_19 + f9g4_19; + int64_t h4 = f0g4 + f1g3_2 + f2g2 + f3g1_2 + f4g0 + f5g9_38 + f6g8_19 + + f7g7_38 + f8g6_19 + f9g5_38; + int64_t h5 = f0g5 + f1g4 + f2g3 + f3g2 + f4g1 + f5g0 + f6g9_19 + f7g8_19 + + f8g7_19 + f9g6_19; + int64_t h6 = f0g6 + f1g5_2 + f2g4 + f3g3_2 + f4g2 + f5g1_2 + f6g0 + + f7g9_38 + f8g8_19 + f9g7_38; + int64_t h7 = f0g7 + f1g6 + f2g5 + f3g4 + f4g3 + f5g2 + f6g1 + f7g0 + + f8g9_19 + f9g8_19; + int64_t h8 = f0g8 + f1g7_2 + f2g6 + f3g5_2 + f4g4 + f5g3_2 + f6g2 + f7g1_2 + + f8g0 + f9g9_38; + int64_t h9 = + f0g9 + f1g8 + f2g7 + f3g6 + f4g5 + f5g4 + f6g3 + f7g2 + f8g1 + f9g0; + + int64_t carry0; + int64_t carry1; + int64_t carry2; + int64_t carry3; + int64_t carry4; + int64_t carry5; + int64_t carry6; + int64_t carry7; + int64_t carry8; + int64_t carry9; + + /* + |h0| <= (1.65*1.65*2^52*(1+19+19+19+19)+1.65*1.65*2^50*(38+38+38+38+38)) + i.e. |h0| <= 1.4*2^60; narrower ranges for h2, h4, h6, h8 + |h1| <= (1.65*1.65*2^51*(1+1+19+19+19+19+19+19+19+19)) + i.e. |h1| <= 1.7*2^59; narrower ranges for h3, h5, h7, h9 + */ + + carry0 = (h0 + (int64_t)(1L << 25)) >> 26; + h1 += carry0; + h0 -= carry0 * ((uint64_t) 1L << 26); + carry4 = (h4 + (int64_t)(1L << 25)) >> 26; + h5 += carry4; + h4 -= carry4 * ((uint64_t) 1L << 26); + /* |h0| <= 2^25 */ + /* |h4| <= 2^25 */ + /* |h1| <= 1.71*2^59 */ + /* |h5| <= 1.71*2^59 */ + + carry1 = (h1 + (int64_t)(1L << 24)) >> 25; + h2 += carry1; + h1 -= carry1 * ((uint64_t) 1L << 25); + carry5 = (h5 + (int64_t)(1L << 24)) >> 25; + h6 += carry5; + h5 -= carry5 * ((uint64_t) 1L << 25); + /* |h1| <= 2^24; from now on fits into int32 */ + /* |h5| <= 2^24; from now on fits into int32 */ + /* |h2| <= 1.41*2^60 */ + /* |h6| <= 1.41*2^60 */ + + carry2 = (h2 + (int64_t)(1L << 25)) >> 26; + h3 += carry2; + h2 -= carry2 * ((uint64_t) 1L << 26); + carry6 = (h6 + (int64_t)(1L << 25)) >> 26; + h7 += carry6; + h6 -= carry6 * ((uint64_t) 1L << 26); + /* |h2| <= 2^25; from now on fits into int32 unchanged */ + /* |h6| <= 2^25; from now on fits into int32 unchanged */ + /* |h3| <= 1.71*2^59 */ + /* |h7| <= 1.71*2^59 */ + + carry3 = (h3 + (int64_t)(1L << 24)) >> 25; + h4 += carry3; + h3 -= carry3 * ((uint64_t) 1L << 25); + carry7 = (h7 + (int64_t)(1L << 24)) >> 25; + h8 += carry7; + h7 -= carry7 * ((uint64_t) 1L << 25); + /* |h3| <= 2^24; from now on fits into int32 unchanged */ + /* |h7| <= 2^24; from now on fits into int32 unchanged */ + /* |h4| <= 1.72*2^34 */ + /* |h8| <= 1.41*2^60 */ + + carry4 = (h4 + (int64_t)(1L << 25)) >> 26; + h5 += carry4; + h4 -= carry4 * ((uint64_t) 1L << 26); + carry8 = (h8 + (int64_t)(1L << 25)) >> 26; + h9 += carry8; + h8 -= carry8 * ((uint64_t) 1L << 26); + /* |h4| <= 2^25; from now on fits into int32 unchanged */ + /* |h8| <= 2^25; from now on fits into int32 unchanged */ + /* |h5| <= 1.01*2^24 */ + /* |h9| <= 1.71*2^59 */ + + carry9 = (h9 + (int64_t)(1L << 24)) >> 25; + h0 += carry9 * 19; + h9 -= carry9 * ((uint64_t) 1L << 25); + /* |h9| <= 2^24; from now on fits into int32 unchanged */ + /* |h0| <= 1.1*2^39 */ + + carry0 = (h0 + (int64_t)(1L << 25)) >> 26; + h1 += carry0; + h0 -= carry0 * ((uint64_t) 1L << 26); + /* |h0| <= 2^25; from now on fits into int32 unchanged */ + /* |h1| <= 1.01*2^24 */ + + h[0] = (int32_t) h0; + h[1] = (int32_t) h1; + h[2] = (int32_t) h2; + h[3] = (int32_t) h3; + h[4] = (int32_t) h4; + h[5] = (int32_t) h5; + h[6] = (int32_t) h6; + h[7] = (int32_t) h7; + h[8] = (int32_t) h8; + h[9] = (int32_t) h9; +} + +/* + h = f * f + Can overlap h with f. + * + Preconditions: + |f| bounded by 1.65*2^26,1.65*2^25,1.65*2^26,1.65*2^25,etc. + * + Postconditions: + |h| bounded by 1.01*2^25,1.01*2^24,1.01*2^25,1.01*2^24,etc. + */ + +static void +fe25519_sq(fe25519 h, const fe25519 f) +{ + int32_t f0 = f[0]; + int32_t f1 = f[1]; + int32_t f2 = f[2]; + int32_t f3 = f[3]; + int32_t f4 = f[4]; + int32_t f5 = f[5]; + int32_t f6 = f[6]; + int32_t f7 = f[7]; + int32_t f8 = f[8]; + int32_t f9 = f[9]; + + int32_t f0_2 = 2 * f0; + int32_t f1_2 = 2 * f1; + int32_t f2_2 = 2 * f2; + int32_t f3_2 = 2 * f3; + int32_t f4_2 = 2 * f4; + int32_t f5_2 = 2 * f5; + int32_t f6_2 = 2 * f6; + int32_t f7_2 = 2 * f7; + int32_t f5_38 = 38 * f5; /* 1.959375*2^30 */ + int32_t f6_19 = 19 * f6; /* 1.959375*2^30 */ + int32_t f7_38 = 38 * f7; /* 1.959375*2^30 */ + int32_t f8_19 = 19 * f8; /* 1.959375*2^30 */ + int32_t f9_38 = 38 * f9; /* 1.959375*2^30 */ + + int64_t f0f0 = f0 * (int64_t) f0; + int64_t f0f1_2 = f0_2 * (int64_t) f1; + int64_t f0f2_2 = f0_2 * (int64_t) f2; + int64_t f0f3_2 = f0_2 * (int64_t) f3; + int64_t f0f4_2 = f0_2 * (int64_t) f4; + int64_t f0f5_2 = f0_2 * (int64_t) f5; + int64_t f0f6_2 = f0_2 * (int64_t) f6; + int64_t f0f7_2 = f0_2 * (int64_t) f7; + int64_t f0f8_2 = f0_2 * (int64_t) f8; + int64_t f0f9_2 = f0_2 * (int64_t) f9; + int64_t f1f1_2 = f1_2 * (int64_t) f1; + int64_t f1f2_2 = f1_2 * (int64_t) f2; + int64_t f1f3_4 = f1_2 * (int64_t) f3_2; + int64_t f1f4_2 = f1_2 * (int64_t) f4; + int64_t f1f5_4 = f1_2 * (int64_t) f5_2; + int64_t f1f6_2 = f1_2 * (int64_t) f6; + int64_t f1f7_4 = f1_2 * (int64_t) f7_2; + int64_t f1f8_2 = f1_2 * (int64_t) f8; + int64_t f1f9_76 = f1_2 * (int64_t) f9_38; + int64_t f2f2 = f2 * (int64_t) f2; + int64_t f2f3_2 = f2_2 * (int64_t) f3; + int64_t f2f4_2 = f2_2 * (int64_t) f4; + int64_t f2f5_2 = f2_2 * (int64_t) f5; + int64_t f2f6_2 = f2_2 * (int64_t) f6; + int64_t f2f7_2 = f2_2 * (int64_t) f7; + int64_t f2f8_38 = f2_2 * (int64_t) f8_19; + int64_t f2f9_38 = f2 * (int64_t) f9_38; + int64_t f3f3_2 = f3_2 * (int64_t) f3; + int64_t f3f4_2 = f3_2 * (int64_t) f4; + int64_t f3f5_4 = f3_2 * (int64_t) f5_2; + int64_t f3f6_2 = f3_2 * (int64_t) f6; + int64_t f3f7_76 = f3_2 * (int64_t) f7_38; + int64_t f3f8_38 = f3_2 * (int64_t) f8_19; + int64_t f3f9_76 = f3_2 * (int64_t) f9_38; + int64_t f4f4 = f4 * (int64_t) f4; + int64_t f4f5_2 = f4_2 * (int64_t) f5; + int64_t f4f6_38 = f4_2 * (int64_t) f6_19; + int64_t f4f7_38 = f4 * (int64_t) f7_38; + int64_t f4f8_38 = f4_2 * (int64_t) f8_19; + int64_t f4f9_38 = f4 * (int64_t) f9_38; + int64_t f5f5_38 = f5 * (int64_t) f5_38; + int64_t f5f6_38 = f5_2 * (int64_t) f6_19; + int64_t f5f7_76 = f5_2 * (int64_t) f7_38; + int64_t f5f8_38 = f5_2 * (int64_t) f8_19; + int64_t f5f9_76 = f5_2 * (int64_t) f9_38; + int64_t f6f6_19 = f6 * (int64_t) f6_19; + int64_t f6f7_38 = f6 * (int64_t) f7_38; + int64_t f6f8_38 = f6_2 * (int64_t) f8_19; + int64_t f6f9_38 = f6 * (int64_t) f9_38; + int64_t f7f7_38 = f7 * (int64_t) f7_38; + int64_t f7f8_38 = f7_2 * (int64_t) f8_19; + int64_t f7f9_76 = f7_2 * (int64_t) f9_38; + int64_t f8f8_19 = f8 * (int64_t) f8_19; + int64_t f8f9_38 = f8 * (int64_t) f9_38; + int64_t f9f9_38 = f9 * (int64_t) f9_38; + + int64_t h0 = f0f0 + f1f9_76 + f2f8_38 + f3f7_76 + f4f6_38 + f5f5_38; + int64_t h1 = f0f1_2 + f2f9_38 + f3f8_38 + f4f7_38 + f5f6_38; + int64_t h2 = f0f2_2 + f1f1_2 + f3f9_76 + f4f8_38 + f5f7_76 + f6f6_19; + int64_t h3 = f0f3_2 + f1f2_2 + f4f9_38 + f5f8_38 + f6f7_38; + int64_t h4 = f0f4_2 + f1f3_4 + f2f2 + f5f9_76 + f6f8_38 + f7f7_38; + int64_t h5 = f0f5_2 + f1f4_2 + f2f3_2 + f6f9_38 + f7f8_38; + int64_t h6 = f0f6_2 + f1f5_4 + f2f4_2 + f3f3_2 + f7f9_76 + f8f8_19; + int64_t h7 = f0f7_2 + f1f6_2 + f2f5_2 + f3f4_2 + f8f9_38; + int64_t h8 = f0f8_2 + f1f7_4 + f2f6_2 + f3f5_4 + f4f4 + f9f9_38; + int64_t h9 = f0f9_2 + f1f8_2 + f2f7_2 + f3f6_2 + f4f5_2; + + int64_t carry0; + int64_t carry1; + int64_t carry2; + int64_t carry3; + int64_t carry4; + int64_t carry5; + int64_t carry6; + int64_t carry7; + int64_t carry8; + int64_t carry9; + + carry0 = (h0 + (int64_t)(1L << 25)) >> 26; + h1 += carry0; + h0 -= carry0 * ((uint64_t) 1L << 26); + carry4 = (h4 + (int64_t)(1L << 25)) >> 26; + h5 += carry4; + h4 -= carry4 * ((uint64_t) 1L << 26); + + carry1 = (h1 + (int64_t)(1L << 24)) >> 25; + h2 += carry1; + h1 -= carry1 * ((uint64_t) 1L << 25); + carry5 = (h5 + (int64_t)(1L << 24)) >> 25; + h6 += carry5; + h5 -= carry5 * ((uint64_t) 1L << 25); + + carry2 = (h2 + (int64_t)(1L << 25)) >> 26; + h3 += carry2; + h2 -= carry2 * ((uint64_t) 1L << 26); + carry6 = (h6 + (int64_t)(1L << 25)) >> 26; + h7 += carry6; + h6 -= carry6 * ((uint64_t) 1L << 26); + + carry3 = (h3 + (int64_t)(1L << 24)) >> 25; + h4 += carry3; + h3 -= carry3 * ((uint64_t) 1L << 25); + carry7 = (h7 + (int64_t)(1L << 24)) >> 25; + h8 += carry7; + h7 -= carry7 * ((uint64_t) 1L << 25); + + carry4 = (h4 + (int64_t)(1L << 25)) >> 26; + h5 += carry4; + h4 -= carry4 * ((uint64_t) 1L << 26); + carry8 = (h8 + (int64_t)(1L << 25)) >> 26; + h9 += carry8; + h8 -= carry8 * ((uint64_t) 1L << 26); + + carry9 = (h9 + (int64_t)(1L << 24)) >> 25; + h0 += carry9 * 19; + h9 -= carry9 * ((uint64_t) 1L << 25); + + carry0 = (h0 + (int64_t)(1L << 25)) >> 26; + h1 += carry0; + h0 -= carry0 * ((uint64_t) 1L << 26); + + h[0] = (int32_t) h0; + h[1] = (int32_t) h1; + h[2] = (int32_t) h2; + h[3] = (int32_t) h3; + h[4] = (int32_t) h4; + h[5] = (int32_t) h5; + h[6] = (int32_t) h6; + h[7] = (int32_t) h7; + h[8] = (int32_t) h8; + h[9] = (int32_t) h9; +} + +/* + h = 2 * f * f + Can overlap h with f. + * + Preconditions: + |f| bounded by 1.65*2^26,1.65*2^25,1.65*2^26,1.65*2^25,etc. + * + Postconditions: + |h| bounded by 1.01*2^25,1.01*2^24,1.01*2^25,1.01*2^24,etc. + */ + +static void +fe25519_sq2(fe25519 h, const fe25519 f) +{ + int32_t f0 = f[0]; + int32_t f1 = f[1]; + int32_t f2 = f[2]; + int32_t f3 = f[3]; + int32_t f4 = f[4]; + int32_t f5 = f[5]; + int32_t f6 = f[6]; + int32_t f7 = f[7]; + int32_t f8 = f[8]; + int32_t f9 = f[9]; + + int32_t f0_2 = 2 * f0; + int32_t f1_2 = 2 * f1; + int32_t f2_2 = 2 * f2; + int32_t f3_2 = 2 * f3; + int32_t f4_2 = 2 * f4; + int32_t f5_2 = 2 * f5; + int32_t f6_2 = 2 * f6; + int32_t f7_2 = 2 * f7; + int32_t f5_38 = 38 * f5; /* 1.959375*2^30 */ + int32_t f6_19 = 19 * f6; /* 1.959375*2^30 */ + int32_t f7_38 = 38 * f7; /* 1.959375*2^30 */ + int32_t f8_19 = 19 * f8; /* 1.959375*2^30 */ + int32_t f9_38 = 38 * f9; /* 1.959375*2^30 */ + + int64_t f0f0 = f0 * (int64_t) f0; + int64_t f0f1_2 = f0_2 * (int64_t) f1; + int64_t f0f2_2 = f0_2 * (int64_t) f2; + int64_t f0f3_2 = f0_2 * (int64_t) f3; + int64_t f0f4_2 = f0_2 * (int64_t) f4; + int64_t f0f5_2 = f0_2 * (int64_t) f5; + int64_t f0f6_2 = f0_2 * (int64_t) f6; + int64_t f0f7_2 = f0_2 * (int64_t) f7; + int64_t f0f8_2 = f0_2 * (int64_t) f8; + int64_t f0f9_2 = f0_2 * (int64_t) f9; + int64_t f1f1_2 = f1_2 * (int64_t) f1; + int64_t f1f2_2 = f1_2 * (int64_t) f2; + int64_t f1f3_4 = f1_2 * (int64_t) f3_2; + int64_t f1f4_2 = f1_2 * (int64_t) f4; + int64_t f1f5_4 = f1_2 * (int64_t) f5_2; + int64_t f1f6_2 = f1_2 * (int64_t) f6; + int64_t f1f7_4 = f1_2 * (int64_t) f7_2; + int64_t f1f8_2 = f1_2 * (int64_t) f8; + int64_t f1f9_76 = f1_2 * (int64_t) f9_38; + int64_t f2f2 = f2 * (int64_t) f2; + int64_t f2f3_2 = f2_2 * (int64_t) f3; + int64_t f2f4_2 = f2_2 * (int64_t) f4; + int64_t f2f5_2 = f2_2 * (int64_t) f5; + int64_t f2f6_2 = f2_2 * (int64_t) f6; + int64_t f2f7_2 = f2_2 * (int64_t) f7; + int64_t f2f8_38 = f2_2 * (int64_t) f8_19; + int64_t f2f9_38 = f2 * (int64_t) f9_38; + int64_t f3f3_2 = f3_2 * (int64_t) f3; + int64_t f3f4_2 = f3_2 * (int64_t) f4; + int64_t f3f5_4 = f3_2 * (int64_t) f5_2; + int64_t f3f6_2 = f3_2 * (int64_t) f6; + int64_t f3f7_76 = f3_2 * (int64_t) f7_38; + int64_t f3f8_38 = f3_2 * (int64_t) f8_19; + int64_t f3f9_76 = f3_2 * (int64_t) f9_38; + int64_t f4f4 = f4 * (int64_t) f4; + int64_t f4f5_2 = f4_2 * (int64_t) f5; + int64_t f4f6_38 = f4_2 * (int64_t) f6_19; + int64_t f4f7_38 = f4 * (int64_t) f7_38; + int64_t f4f8_38 = f4_2 * (int64_t) f8_19; + int64_t f4f9_38 = f4 * (int64_t) f9_38; + int64_t f5f5_38 = f5 * (int64_t) f5_38; + int64_t f5f6_38 = f5_2 * (int64_t) f6_19; + int64_t f5f7_76 = f5_2 * (int64_t) f7_38; + int64_t f5f8_38 = f5_2 * (int64_t) f8_19; + int64_t f5f9_76 = f5_2 * (int64_t) f9_38; + int64_t f6f6_19 = f6 * (int64_t) f6_19; + int64_t f6f7_38 = f6 * (int64_t) f7_38; + int64_t f6f8_38 = f6_2 * (int64_t) f8_19; + int64_t f6f9_38 = f6 * (int64_t) f9_38; + int64_t f7f7_38 = f7 * (int64_t) f7_38; + int64_t f7f8_38 = f7_2 * (int64_t) f8_19; + int64_t f7f9_76 = f7_2 * (int64_t) f9_38; + int64_t f8f8_19 = f8 * (int64_t) f8_19; + int64_t f8f9_38 = f8 * (int64_t) f9_38; + int64_t f9f9_38 = f9 * (int64_t) f9_38; + + int64_t h0 = f0f0 + f1f9_76 + f2f8_38 + f3f7_76 + f4f6_38 + f5f5_38; + int64_t h1 = f0f1_2 + f2f9_38 + f3f8_38 + f4f7_38 + f5f6_38; + int64_t h2 = f0f2_2 + f1f1_2 + f3f9_76 + f4f8_38 + f5f7_76 + f6f6_19; + int64_t h3 = f0f3_2 + f1f2_2 + f4f9_38 + f5f8_38 + f6f7_38; + int64_t h4 = f0f4_2 + f1f3_4 + f2f2 + f5f9_76 + f6f8_38 + f7f7_38; + int64_t h5 = f0f5_2 + f1f4_2 + f2f3_2 + f6f9_38 + f7f8_38; + int64_t h6 = f0f6_2 + f1f5_4 + f2f4_2 + f3f3_2 + f7f9_76 + f8f8_19; + int64_t h7 = f0f7_2 + f1f6_2 + f2f5_2 + f3f4_2 + f8f9_38; + int64_t h8 = f0f8_2 + f1f7_4 + f2f6_2 + f3f5_4 + f4f4 + f9f9_38; + int64_t h9 = f0f9_2 + f1f8_2 + f2f7_2 + f3f6_2 + f4f5_2; + + int64_t carry0; + int64_t carry1; + int64_t carry2; + int64_t carry3; + int64_t carry4; + int64_t carry5; + int64_t carry6; + int64_t carry7; + int64_t carry8; + int64_t carry9; + + h0 += h0; + h1 += h1; + h2 += h2; + h3 += h3; + h4 += h4; + h5 += h5; + h6 += h6; + h7 += h7; + h8 += h8; + h9 += h9; + + carry0 = (h0 + (int64_t)(1L << 25)) >> 26; + h1 += carry0; + h0 -= carry0 * ((uint64_t) 1L << 26); + carry4 = (h4 + (int64_t)(1L << 25)) >> 26; + h5 += carry4; + h4 -= carry4 * ((uint64_t) 1L << 26); + + carry1 = (h1 + (int64_t)(1L << 24)) >> 25; + h2 += carry1; + h1 -= carry1 * ((uint64_t) 1L << 25); + carry5 = (h5 + (int64_t)(1L << 24)) >> 25; + h6 += carry5; + h5 -= carry5 * ((uint64_t) 1L << 25); + + carry2 = (h2 + (int64_t)(1L << 25)) >> 26; + h3 += carry2; + h2 -= carry2 * ((uint64_t) 1L << 26); + carry6 = (h6 + (int64_t)(1L << 25)) >> 26; + h7 += carry6; + h6 -= carry6 * ((uint64_t) 1L << 26); + + carry3 = (h3 + (int64_t)(1L << 24)) >> 25; + h4 += carry3; + h3 -= carry3 * ((uint64_t) 1L << 25); + carry7 = (h7 + (int64_t)(1L << 24)) >> 25; + h8 += carry7; + h7 -= carry7 * ((uint64_t) 1L << 25); + + carry4 = (h4 + (int64_t)(1L << 25)) >> 26; + h5 += carry4; + h4 -= carry4 * ((uint64_t) 1L << 26); + carry8 = (h8 + (int64_t)(1L << 25)) >> 26; + h9 += carry8; + h8 -= carry8 * ((uint64_t) 1L << 26); + + carry9 = (h9 + (int64_t)(1L << 24)) >> 25; + h0 += carry9 * 19; + h9 -= carry9 * ((uint64_t) 1L << 25); + + carry0 = (h0 + (int64_t)(1L << 25)) >> 26; + h1 += carry0; + h0 -= carry0 * ((uint64_t) 1L << 26); + + h[0] = (int32_t) h0; + h[1] = (int32_t) h1; + h[2] = (int32_t) h2; + h[3] = (int32_t) h3; + h[4] = (int32_t) h4; + h[5] = (int32_t) h5; + h[6] = (int32_t) h6; + h[7] = (int32_t) h7; + h[8] = (int32_t) h8; + h[9] = (int32_t) h9; +} + +static void +fe25519_scalar_product(fe25519 h, const fe25519 f, uint32_t n) +{ + int64_t sn = (int64_t) n; + int32_t f0 = f[0]; + int32_t f1 = f[1]; + int32_t f2 = f[2]; + int32_t f3 = f[3]; + int32_t f4 = f[4]; + int32_t f5 = f[5]; + int32_t f6 = f[6]; + int32_t f7 = f[7]; + int32_t f8 = f[8]; + int32_t f9 = f[9]; + int64_t h0 = f0 * sn; + int64_t h1 = f1 * sn; + int64_t h2 = f2 * sn; + int64_t h3 = f3 * sn; + int64_t h4 = f4 * sn; + int64_t h5 = f5 * sn; + int64_t h6 = f6 * sn; + int64_t h7 = f7 * sn; + int64_t h8 = f8 * sn; + int64_t h9 = f9 * sn; + int64_t carry0, carry1, carry2, carry3, carry4, carry5, carry6, carry7, + carry8, carry9; + + carry9 = (h9 + ((int64_t) 1 << 24)) >> 25; + h0 += carry9 * 19; + h9 -= carry9 * ((int64_t) 1 << 25); + carry1 = (h1 + ((int64_t) 1 << 24)) >> 25; + h2 += carry1; + h1 -= carry1 * ((int64_t) 1 << 25); + carry3 = (h3 + ((int64_t) 1 << 24)) >> 25; + h4 += carry3; + h3 -= carry3 * ((int64_t) 1 << 25); + carry5 = (h5 + ((int64_t) 1 << 24)) >> 25; + h6 += carry5; + h5 -= carry5 * ((int64_t) 1 << 25); + carry7 = (h7 + ((int64_t) 1 << 24)) >> 25; + h8 += carry7; + h7 -= carry7 * ((int64_t) 1 << 25); + + carry0 = (h0 + ((int64_t) 1 << 25)) >> 26; + h1 += carry0; + h0 -= carry0 * ((int64_t) 1 << 26); + carry2 = (h2 + ((int64_t) 1 << 25)) >> 26; + h3 += carry2; + h2 -= carry2 * ((int64_t) 1 << 26); + carry4 = (h4 + ((int64_t) 1 << 25)) >> 26; + h5 += carry4; + h4 -= carry4 * ((int64_t) 1 << 26); + carry6 = (h6 + ((int64_t) 1 << 25)) >> 26; + h7 += carry6; + h6 -= carry6 * ((int64_t) 1 << 26); + carry8 = (h8 + ((int64_t) 1 << 25)) >> 26; + h9 += carry8; + h8 -= carry8 * ((int64_t) 1 << 26); + + h[0] = (int32_t) h0; + h[1] = (int32_t) h1; + h[2] = (int32_t) h2; + h[3] = (int32_t) h3; + h[4] = (int32_t) h4; + h[5] = (int32_t) h5; + h[6] = (int32_t) h6; + h[7] = (int32_t) h7; + h[8] = (int32_t) h8; + h[9] = (int32_t) h9; +} diff --git a/libs/libsodium/src/include/sodium/private/ed25519_ref10_fe_51.h b/libs/libsodium/src/include/sodium/private/ed25519_ref10_fe_51.h new file mode 100644 index 0000000000..3a30f30148 --- /dev/null +++ b/libs/libsodium/src/include/sodium/private/ed25519_ref10_fe_51.h @@ -0,0 +1,518 @@ +#include <string.h> + +#include "private/common.h" +#include "utils.h" + +/* + h = 0 + */ + +static inline void +fe25519_0(fe25519 h) +{ + memset(&h[0], 0, 5 * sizeof h[0]); +} + +/* + h = 1 + */ + +static inline void +fe25519_1(fe25519 h) +{ + h[0] = 1; + memset(&h[1], 0, 4 * sizeof h[0]); +} + +/* + h = f + g + Can overlap h with f or g. + */ + +static inline void +fe25519_add(fe25519 h, const fe25519 f, const fe25519 g) +{ + uint64_t h0 = f[0] + g[0]; + uint64_t h1 = f[1] + g[1]; + uint64_t h2 = f[2] + g[2]; + uint64_t h3 = f[3] + g[3]; + uint64_t h4 = f[4] + g[4]; + + h[0] = h0; + h[1] = h1; + h[2] = h2; + h[3] = h3; + h[4] = h4; +} + +/* + h = f - g + */ + +static void +fe25519_sub(fe25519 h, const fe25519 f, const fe25519 g) +{ + const uint64_t mask = 0x7ffffffffffffULL; + uint64_t h0, h1, h2, h3, h4; + + h0 = g[0]; + h1 = g[1]; + h2 = g[2]; + h3 = g[3]; + h4 = g[4]; + + h1 += h0 >> 51; + h0 &= mask; + h2 += h1 >> 51; + h1 &= mask; + h3 += h2 >> 51; + h2 &= mask; + h4 += h3 >> 51; + h3 &= mask; + h0 += 19ULL * (h4 >> 51); + h4 &= mask; + + h0 = (f[0] + 0xfffffffffffdaULL) - h0; + h1 = (f[1] + 0xffffffffffffeULL) - h1; + h2 = (f[2] + 0xffffffffffffeULL) - h2; + h3 = (f[3] + 0xffffffffffffeULL) - h3; + h4 = (f[4] + 0xffffffffffffeULL) - h4; + + h[0] = h0; + h[1] = h1; + h[2] = h2; + h[3] = h3; + h[4] = h4; +} + +/* + h = -f + */ + +static inline void +fe25519_neg(fe25519 h, const fe25519 f) +{ + fe25519 zero; + + fe25519_0(zero); + fe25519_sub(h, zero, f); +} + +/* + Replace (f,g) with (g,g) if b == 1; + replace (f,g) with (f,g) if b == 0. + * + Preconditions: b in {0,1}. + */ + +static void +fe25519_cmov(fe25519 f, const fe25519 g, unsigned int b) +{ + const uint64_t mask = (uint64_t) (-(int64_t) b); + + uint64_t f0 = f[0]; + uint64_t f1 = f[1]; + uint64_t f2 = f[2]; + uint64_t f3 = f[3]; + uint64_t f4 = f[4]; + + uint64_t x0 = f0 ^ g[0]; + uint64_t x1 = f1 ^ g[1]; + uint64_t x2 = f2 ^ g[2]; + uint64_t x3 = f3 ^ g[3]; + uint64_t x4 = f4 ^ g[4]; + + x0 &= mask; + x1 &= mask; + x2 &= mask; + x3 &= mask; + x4 &= mask; + + f[0] = f0 ^ x0; + f[1] = f1 ^ x1; + f[2] = f2 ^ x2; + f[3] = f3 ^ x3; + f[4] = f4 ^ x4; +} + +/* +Replace (f,g) with (g,f) if b == 1; +replace (f,g) with (f,g) if b == 0. + +Preconditions: b in {0,1}. +*/ + +static void +fe25519_cswap(fe25519 f, fe25519 g, unsigned int b) +{ + const uint64_t mask = (uint64_t) (-(int64_t) b); + + uint64_t f0 = f[0]; + uint64_t f1 = f[1]; + uint64_t f2 = f[2]; + uint64_t f3 = f[3]; + uint64_t f4 = f[4]; + + uint64_t g0 = g[0]; + uint64_t g1 = g[1]; + uint64_t g2 = g[2]; + uint64_t g3 = g[3]; + uint64_t g4 = g[4]; + + uint64_t x0 = f0 ^ g0; + uint64_t x1 = f1 ^ g1; + uint64_t x2 = f2 ^ g2; + uint64_t x3 = f3 ^ g3; + uint64_t x4 = f4 ^ g4; + + x0 &= mask; + x1 &= mask; + x2 &= mask; + x3 &= mask; + x4 &= mask; + + f[0] = f0 ^ x0; + f[1] = f1 ^ x1; + f[2] = f2 ^ x2; + f[3] = f3 ^ x3; + f[4] = f4 ^ x4; + + g[0] = g0 ^ x0; + g[1] = g1 ^ x1; + g[2] = g2 ^ x2; + g[3] = g3 ^ x3; + g[4] = g4 ^ x4; +} + +/* + h = f + */ + +static inline void +fe25519_copy(fe25519 h, const fe25519 f) +{ + uint64_t f0 = f[0]; + uint64_t f1 = f[1]; + uint64_t f2 = f[2]; + uint64_t f3 = f[3]; + uint64_t f4 = f[4]; + + h[0] = f0; + h[1] = f1; + h[2] = f2; + h[3] = f3; + h[4] = f4; +} + +/* + return 1 if f is in {1,3,5,...,q-2} + return 0 if f is in {0,2,4,...,q-1} + */ + +static inline int +fe25519_isnegative(const fe25519 f) +{ + unsigned char s[32]; + + fe25519_tobytes(s, f); + + return s[0] & 1; +} + +/* + return 1 if f == 0 + return 0 if f != 0 + */ + +static inline int +fe25519_iszero(const fe25519 f) +{ + unsigned char s[32]; + + fe25519_tobytes(s, f); + + return sodium_is_zero(s, 32); +} + +/* + h = f * g + Can overlap h with f or g. + */ + +static void +fe25519_mul(fe25519 h, const fe25519 f, const fe25519 g) +{ + const uint64_t mask = 0x7ffffffffffffULL; + uint128_t r0, r1, r2, r3, r4, carry; + uint64_t f0, f1, f2, f3, f4; + uint64_t f1_19, f2_19, f3_19, f4_19; + uint64_t g0, g1, g2, g3, g4; + uint64_t r00, r01, r02, r03, r04; + + f0 = f[0]; + f1 = f[1]; + f2 = f[2]; + f3 = f[3]; + f4 = f[4]; + + g0 = g[0]; + g1 = g[1]; + g2 = g[2]; + g3 = g[3]; + g4 = g[4]; + + f1_19 = 19ULL * f1; + f2_19 = 19ULL * f2; + f3_19 = 19ULL * f3; + f4_19 = 19ULL * f4; + + r0 = ((uint128_t) f0 ) * ((uint128_t) g0); + r0 += ((uint128_t) f1_19) * ((uint128_t) g4); + r0 += ((uint128_t) f2_19) * ((uint128_t) g3); + r0 += ((uint128_t) f3_19) * ((uint128_t) g2); + r0 += ((uint128_t) f4_19) * ((uint128_t) g1); + + r1 = ((uint128_t) f0 ) * ((uint128_t) g1); + r1 += ((uint128_t) f1 ) * ((uint128_t) g0); + r1 += ((uint128_t) f2_19) * ((uint128_t) g4); + r1 += ((uint128_t) f3_19) * ((uint128_t) g3); + r1 += ((uint128_t) f4_19) * ((uint128_t) g2); + + r2 = ((uint128_t) f0 ) * ((uint128_t) g2); + r2 += ((uint128_t) f1 ) * ((uint128_t) g1); + r2 += ((uint128_t) f2 ) * ((uint128_t) g0); + r2 += ((uint128_t) f3_19) * ((uint128_t) g4); + r2 += ((uint128_t) f4_19) * ((uint128_t) g3); + + r3 = ((uint128_t) f0 ) * ((uint128_t) g3); + r3 += ((uint128_t) f1 ) * ((uint128_t) g2); + r3 += ((uint128_t) f2 ) * ((uint128_t) g1); + r3 += ((uint128_t) f3 ) * ((uint128_t) g0); + r3 += ((uint128_t) f4_19) * ((uint128_t) g4); + + r4 = ((uint128_t) f0 ) * ((uint128_t) g4); + r4 += ((uint128_t) f1 ) * ((uint128_t) g3); + r4 += ((uint128_t) f2 ) * ((uint128_t) g2); + r4 += ((uint128_t) f3 ) * ((uint128_t) g1); + r4 += ((uint128_t) f4 ) * ((uint128_t) g0); + + r00 = ((uint64_t) r0) & mask; + carry = r0 >> 51; + r1 += carry; + r01 = ((uint64_t) r1) & mask; + carry = r1 >> 51; + r2 += carry; + r02 = ((uint64_t) r2) & mask; + carry = r2 >> 51; + r3 += carry; + r03 = ((uint64_t) r3) & mask; + carry = r3 >> 51; + r4 += carry; + r04 = ((uint64_t) r4) & mask; + carry = r4 >> 51; + r00 += 19ULL * (uint64_t) carry; + carry = r00 >> 51; + r00 &= mask; + r01 += (uint64_t) carry; + carry = r01 >> 51; + r01 &= mask; + r02 += (uint64_t) carry; + + h[0] = r00; + h[1] = r01; + h[2] = r02; + h[3] = r03; + h[4] = r04; +} + +/* + h = f * f + Can overlap h with f. + */ + +static void +fe25519_sq(fe25519 h, const fe25519 f) +{ + const uint64_t mask = 0x7ffffffffffffULL; + uint128_t r0, r1, r2, r3, r4, carry; + uint64_t f0, f1, f2, f3, f4; + uint64_t f0_2, f1_2, f1_38, f2_38, f3_38, f3_19, f4_19; + uint64_t r00, r01, r02, r03, r04; + + f0 = f[0]; + f1 = f[1]; + f2 = f[2]; + f3 = f[3]; + f4 = f[4]; + + f0_2 = f0 << 1; + f1_2 = f1 << 1; + + f1_38 = 38ULL * f1; + f2_38 = 38ULL * f2; + f3_38 = 38ULL * f3; + + f3_19 = 19ULL * f3; + f4_19 = 19ULL * f4; + + r0 = ((uint128_t) f0 ) * ((uint128_t) f0); + r0 += ((uint128_t) f1_38) * ((uint128_t) f4); + r0 += ((uint128_t) f2_38) * ((uint128_t) f3); + + r1 = ((uint128_t) f0_2 ) * ((uint128_t) f1); + r1 += ((uint128_t) f2_38) * ((uint128_t) f4); + r1 += ((uint128_t) f3_19) * ((uint128_t) f3); + + r2 = ((uint128_t) f0_2 ) * ((uint128_t) f2); + r2 += ((uint128_t) f1 ) * ((uint128_t) f1); + r2 += ((uint128_t) f3_38) * ((uint128_t) f4); + + r3 = ((uint128_t) f0_2 ) * ((uint128_t) f3); + r3 += ((uint128_t) f1_2 ) * ((uint128_t) f2); + r3 += ((uint128_t) f4_19) * ((uint128_t) f4); + + r4 = ((uint128_t) f0_2 ) * ((uint128_t) f4); + r4 += ((uint128_t) f1_2 ) * ((uint128_t) f3); + r4 += ((uint128_t) f2 ) * ((uint128_t) f2); + + r00 = ((uint64_t) r0) & mask; + carry = r0 >> 51; + r1 += carry; + r01 = ((uint64_t) r1) & mask; + carry = r1 >> 51; + r2 += carry; + r02 = ((uint64_t) r2) & mask; + carry = r2 >> 51; + r3 += carry; + r03 = ((uint64_t) r3) & mask; + carry = r3 >> 51; + r4 += carry; + r04 = ((uint64_t) r4) & mask; + carry = r4 >> 51; + r00 += 19ULL * (uint64_t) carry; + carry = r00 >> 51; + r00 &= mask; + r01 += (uint64_t) carry; + carry = r01 >> 51; + r01 &= mask; + r02 += (uint64_t) carry; + + h[0] = r00; + h[1] = r01; + h[2] = r02; + h[3] = r03; + h[4] = r04; +} + +/* + h = 2 * f * f + Can overlap h with f. +*/ + +static void +fe25519_sq2(fe25519 h, const fe25519 f) +{ + const uint64_t mask = 0x7ffffffffffffULL; + uint128_t r0, r1, r2, r3, r4, carry; + uint64_t f0, f1, f2, f3, f4; + uint64_t f0_2, f1_2, f1_38, f2_38, f3_38, f3_19, f4_19; + uint64_t r00, r01, r02, r03, r04; + + f0 = f[0]; + f1 = f[1]; + f2 = f[2]; + f3 = f[3]; + f4 = f[4]; + + f0_2 = f0 << 1; + f1_2 = f1 << 1; + + f1_38 = 38ULL * f1; + f2_38 = 38ULL * f2; + f3_38 = 38ULL * f3; + + f3_19 = 19ULL * f3; + f4_19 = 19ULL * f4; + + r0 = ((uint128_t) f0 ) * ((uint128_t) f0); + r0 += ((uint128_t) f1_38) * ((uint128_t) f4); + r0 += ((uint128_t) f2_38) * ((uint128_t) f3); + + r1 = ((uint128_t) f0_2 ) * ((uint128_t) f1); + r1 += ((uint128_t) f2_38) * ((uint128_t) f4); + r1 += ((uint128_t) f3_19) * ((uint128_t) f3); + + r2 = ((uint128_t) f0_2 ) * ((uint128_t) f2); + r2 += ((uint128_t) f1 ) * ((uint128_t) f1); + r2 += ((uint128_t) f3_38) * ((uint128_t) f4); + + r3 = ((uint128_t) f0_2 ) * ((uint128_t) f3); + r3 += ((uint128_t) f1_2 ) * ((uint128_t) f2); + r3 += ((uint128_t) f4_19) * ((uint128_t) f4); + + r4 = ((uint128_t) f0_2 ) * ((uint128_t) f4); + r4 += ((uint128_t) f1_2 ) * ((uint128_t) f3); + r4 += ((uint128_t) f2 ) * ((uint128_t) f2); + + r0 <<= 1; + r1 <<= 1; + r2 <<= 1; + r3 <<= 1; + r4 <<= 1; + + r00 = ((uint64_t) r0) & mask; + carry = r0 >> 51; + r1 += carry; + r01 = ((uint64_t) r1) & mask; + carry = r1 >> 51; + r2 += carry; + r02 = ((uint64_t) r2) & mask; + carry = r2 >> 51; + r3 += carry; + r03 = ((uint64_t) r3) & mask; + carry = r3 >> 51; + r4 += carry; + r04 = ((uint64_t) r4) & mask; + carry = r4 >> 51; + r00 += 19ULL * (uint64_t) carry; + carry = r00 >> 51; + r00 &= mask; + r01 += (uint64_t) carry; + carry = r01 >> 51; + r01 &= mask; + r02 += (uint64_t) carry; + + h[0] = r00; + h[1] = r01; + h[2] = r02; + h[3] = r03; + h[4] = r04; +} + +static void +fe25519_scalar_product(fe25519 h, const fe25519 f, uint32_t n) +{ + const uint64_t mask = 0x7ffffffffffffULL; + uint128_t a; + uint128_t sn = (uint128_t) n; + uint64_t h0, h1, h2, h3, h4; + + a = f[0] * sn; + h0 = ((uint64_t) a) & mask; + a = f[1] * sn + ((uint64_t) (a >> 51)); + h1 = ((uint64_t) a) & mask; + a = f[2] * sn + ((uint64_t) (a >> 51)); + h2 = ((uint64_t) a) & mask; + a = f[3] * sn + ((uint64_t) (a >> 51)); + h3 = ((uint64_t) a) & mask; + a = f[4] * sn + ((uint64_t) (a >> 51)); + h4 = ((uint64_t) a) & mask; + + h0 += (a >> 51) * 19ULL; + + h[0] = h0; + h[1] = h1; + h[2] = h2; + h[3] = h3; + h[4] = h4; +} diff --git a/libs/libsodium/src/include/sodium/private/implementations.h b/libs/libsodium/src/include/sodium/private/implementations.h new file mode 100644 index 0000000000..c7237f851d --- /dev/null +++ b/libs/libsodium/src/include/sodium/private/implementations.h @@ -0,0 +1,11 @@ +#ifndef implementations_H +#define implementations_H + +int _crypto_generichash_blake2b_pick_best_implementation(void); +int _crypto_onetimeauth_poly1305_pick_best_implementation(void); +int _crypto_pwhash_argon2_pick_best_implementation(void); +int _crypto_scalarmult_curve25519_pick_best_implementation(void); +int _crypto_stream_chacha20_pick_best_implementation(void); +int _crypto_stream_salsa20_pick_best_implementation(void); + +#endif diff --git a/libs/libsodium/src/include/sodium/private/mutex.h b/libs/libsodium/src/include/sodium/private/mutex.h new file mode 100644 index 0000000000..322b6742b2 --- /dev/null +++ b/libs/libsodium/src/include/sodium/private/mutex.h @@ -0,0 +1,7 @@ +#ifndef mutex_H +#define mutex_H 1 + +extern int sodium_crit_enter(void); +extern int sodium_crit_leave(void); + +#endif diff --git a/libs/libsodium/src/include/sodium/private/sse2_64_32.h b/libs/libsodium/src/include/sodium/private/sse2_64_32.h new file mode 100644 index 0000000000..d0455b41b4 --- /dev/null +++ b/libs/libsodium/src/include/sodium/private/sse2_64_32.h @@ -0,0 +1,50 @@ +#ifndef sse2_64_32_H +#define sse2_64_32_H 1 + +#include "common.h" + +#ifdef HAVE_INTRIN_H +# include <intrin.h> +#endif + +#if defined(HAVE_EMMINTRIN_H) && \ + !(defined(__amd64) || defined(__amd64__) || defined(__x86_64__) || \ + defined(_M_X64) || defined(_M_AMD64)) + +# include <emmintrin.h> +# include <stdint.h> + +# ifndef _mm_set_epi64x +# define _mm_set_epi64x(Q0, Q1) sodium__mm_set_epi64x((Q0), (Q1)) +static inline __m128i +sodium__mm_set_epi64x(int64_t q1, int64_t q0) +{ + union { int64_t as64; int32_t as32[2]; } x0, x1; + x0.as64 = q0; x1.as64 = q1; + return _mm_set_epi32(x1.as32[1], x1.as32[0], x0.as32[1], x0.as32[0]); +} +# endif + +# ifndef _mm_set1_epi64x +# define _mm_set1_epi64x(Q) sodium__mm_set1_epi64x(Q) +static inline __m128i +sodium__mm_set1_epi64x(int64_t q) +{ + return _mm_set_epi64x(q, q); +} +# endif + +# ifndef _mm_cvtsi64_si128 +# define _mm_cvtsi64_si128(Q) sodium__mm_cvtsi64_si128(Q) +static inline __m128i +sodium__mm_cvtsi64_si128(int64_t q) +{ + union { int64_t as64; int32_t as32[2]; } x; + x.as64 = q; + return _mm_setr_epi32(x.as32[0], x.as32[1], 0, 0); +} +# endif + +#endif + +#endif diff --git a/libs/libsodium/src/include/sodium/randombytes.h b/libs/libsodium/src/include/sodium/randombytes.h new file mode 100644 index 0000000000..d19f684ed6 --- /dev/null +++ b/libs/libsodium/src/include/sodium/randombytes.h @@ -0,0 +1,68 @@ + +#ifndef randombytes_H +#define randombytes_H + +#include <stddef.h> +#include <stdint.h> + +#include <sys/types.h> + +#include "export.h" + +#ifdef __cplusplus +# ifdef __GNUC__ +# pragma GCC diagnostic ignored "-Wlong-long" +# endif +extern "C" { +#endif + +typedef struct randombytes_implementation { + const char *(*implementation_name)(void); /* required */ + uint32_t (*random)(void); /* required */ + void (*stir)(void); /* optional */ + uint32_t (*uniform)(const uint32_t upper_bound); /* optional, a default implementation will be used if NULL */ + void (*buf)(void * const buf, const size_t size); /* required */ + int (*close)(void); /* optional */ +} randombytes_implementation; + +#define randombytes_BYTES_MAX SODIUM_MIN(SODIUM_SIZE_MAX, 0xffffffffUL) + +#define randombytes_SEEDBYTES 32U +SODIUM_EXPORT +size_t randombytes_seedbytes(void); + +SODIUM_EXPORT +void randombytes_buf(void * const buf, const size_t size); + +SODIUM_EXPORT +void randombytes_buf_deterministic(void * const buf, const size_t size, + const unsigned char seed[randombytes_SEEDBYTES]); + +SODIUM_EXPORT +uint32_t randombytes_random(void); + +SODIUM_EXPORT +uint32_t randombytes_uniform(const uint32_t upper_bound); + +SODIUM_EXPORT +void randombytes_stir(void); + +SODIUM_EXPORT +int randombytes_close(void); + +SODIUM_EXPORT +int randombytes_set_implementation(randombytes_implementation *impl); + +SODIUM_EXPORT +const char *randombytes_implementation_name(void); + +/* -- NaCl compatibility interface -- */ + +SODIUM_EXPORT +void randombytes(unsigned char * const buf, const unsigned long long buf_len); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/libs/libsodium/src/include/sodium/randombytes_nativeclient.h b/libs/libsodium/src/include/sodium/randombytes_nativeclient.h new file mode 100644 index 0000000000..5158d8c3c3 --- /dev/null +++ b/libs/libsodium/src/include/sodium/randombytes_nativeclient.h @@ -0,0 +1,23 @@ + +#ifndef randombytes_nativeclient_H +#define randombytes_nativeclient_H + +#ifdef __native_client__ + +# include "export.h" +# include "randombytes.h" + +# ifdef __cplusplus +extern "C" { +# endif + +SODIUM_EXPORT +extern struct randombytes_implementation randombytes_nativeclient_implementation; + +# ifdef __cplusplus +} +# endif + +#endif + +#endif diff --git a/libs/libsodium/src/include/sodium/randombytes_salsa20_random.h b/libs/libsodium/src/include/sodium/randombytes_salsa20_random.h new file mode 100644 index 0000000000..4deae15b6d --- /dev/null +++ b/libs/libsodium/src/include/sodium/randombytes_salsa20_random.h @@ -0,0 +1,19 @@ + +#ifndef randombytes_salsa20_random_H +#define randombytes_salsa20_random_H + +#include "export.h" +#include "randombytes.h" + +#ifdef __cplusplus +extern "C" { +#endif + +SODIUM_EXPORT +extern struct randombytes_implementation randombytes_salsa20_implementation; + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/libs/libsodium/src/include/sodium/randombytes_sysrandom.h b/libs/libsodium/src/include/sodium/randombytes_sysrandom.h new file mode 100644 index 0000000000..9e27b674c7 --- /dev/null +++ b/libs/libsodium/src/include/sodium/randombytes_sysrandom.h @@ -0,0 +1,19 @@ + +#ifndef randombytes_sysrandom_H +#define randombytes_sysrandom_H + +#include "export.h" +#include "randombytes.h" + +#ifdef __cplusplus +extern "C" { +#endif + +SODIUM_EXPORT +extern struct randombytes_implementation randombytes_sysrandom_implementation; + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/libs/libsodium/src/include/sodium/runtime.h b/libs/libsodium/src/include/sodium/runtime.h new file mode 100644 index 0000000000..7f15d58e7c --- /dev/null +++ b/libs/libsodium/src/include/sodium/runtime.h @@ -0,0 +1,52 @@ + +#ifndef sodium_runtime_H +#define sodium_runtime_H + +#include "export.h" + +#ifdef __cplusplus +extern "C" { +#endif + +SODIUM_EXPORT_WEAK +int sodium_runtime_has_neon(void); + +SODIUM_EXPORT_WEAK +int sodium_runtime_has_sse2(void); + +SODIUM_EXPORT_WEAK +int sodium_runtime_has_sse3(void); + +SODIUM_EXPORT_WEAK +int sodium_runtime_has_ssse3(void); + +SODIUM_EXPORT_WEAK +int sodium_runtime_has_sse41(void); + +SODIUM_EXPORT_WEAK +int sodium_runtime_has_avx(void); + +SODIUM_EXPORT_WEAK +int sodium_runtime_has_avx2(void); + +SODIUM_EXPORT_WEAK +int sodium_runtime_has_avx512f(void); + +SODIUM_EXPORT_WEAK +int sodium_runtime_has_pclmul(void); + +SODIUM_EXPORT_WEAK +int sodium_runtime_has_aesni(void); + +SODIUM_EXPORT_WEAK +int sodium_runtime_has_rdrand(void); + +/* ------------------------------------------------------------------------- */ + +int _sodium_runtime_get_cpu_features(void); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/libs/libsodium/src/include/sodium/utils.h b/libs/libsodium/src/include/sodium/utils.h new file mode 100644 index 0000000000..46eb331cfd --- /dev/null +++ b/libs/libsodium/src/include/sodium/utils.h @@ -0,0 +1,170 @@ + +#ifndef sodium_utils_H +#define sodium_utils_H + +#include <stddef.h> + +#include "export.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef SODIUM_C99 +# if defined(__cplusplus) || !defined(__STDC_VERSION__) || __STDC_VERSION__ < 199901L +# define SODIUM_C99(X) +# else +# define SODIUM_C99(X) X +# endif +#endif + +SODIUM_EXPORT +void sodium_memzero(void * const pnt, const size_t len); + +SODIUM_EXPORT +void sodium_stackzero(const size_t len); + +/* + * WARNING: sodium_memcmp() must be used to verify if two secret keys + * are equal, in constant time. + * It returns 0 if the keys are equal, and -1 if they differ. + * This function is not designed for lexicographical comparisons. + */ +SODIUM_EXPORT +int sodium_memcmp(const void * const b1_, const void * const b2_, size_t len) + __attribute__ ((warn_unused_result)); + +/* + * sodium_compare() returns -1 if b1_ < b2_, 1 if b1_ > b2_ and 0 if b1_ == b2_ + * It is suitable for lexicographical comparisons, or to compare nonces + * and counters stored in little-endian format. + * However, it is slower than sodium_memcmp(). + */ +SODIUM_EXPORT +int sodium_compare(const unsigned char *b1_, const unsigned char *b2_, + size_t len) + __attribute__ ((warn_unused_result)); + +SODIUM_EXPORT +int sodium_is_zero(const unsigned char *n, const size_t nlen); + +SODIUM_EXPORT +void sodium_increment(unsigned char *n, const size_t nlen); + +SODIUM_EXPORT +void sodium_add(unsigned char *a, const unsigned char *b, const size_t len); + +SODIUM_EXPORT +char *sodium_bin2hex(char * const hex, const size_t hex_maxlen, + const unsigned char * const bin, const size_t bin_len); + +SODIUM_EXPORT +int sodium_hex2bin(unsigned char * const bin, const size_t bin_maxlen, + const char * const hex, const size_t hex_len, + const char * const ignore, size_t * const bin_len, + const char ** const hex_end); + +#define sodium_base64_VARIANT_ORIGINAL 1 +#define sodium_base64_VARIANT_ORIGINAL_NO_PADDING 3 +#define sodium_base64_VARIANT_URLSAFE 5 +#define sodium_base64_VARIANT_URLSAFE_NO_PADDING 7 + +/* + * Computes the required length to encode BIN_LEN bytes as a base64 string + * using the given variant. The computed length includes a trailing \0. + */ +#define sodium_base64_ENCODED_LEN(BIN_LEN, VARIANT) \ + (((BIN_LEN) / 3U) * 4U + \ + ((((BIN_LEN) - ((BIN_LEN) / 3U) * 3U) | (((BIN_LEN) - ((BIN_LEN) / 3U) * 3U) >> 1)) & 1U) * \ + (4U - (~((((VARIANT) & 2U) >> 1) - 1U) & (3U - ((BIN_LEN) - ((BIN_LEN) / 3U) * 3U)))) + 1U) + +SODIUM_EXPORT +size_t sodium_base64_encoded_len(const size_t bin_len, const int variant); + +SODIUM_EXPORT +char *sodium_bin2base64(char * const b64, const size_t b64_maxlen, + const unsigned char * const bin, const size_t bin_len, + const int variant); + +SODIUM_EXPORT +int sodium_base642bin(unsigned char * const bin, const size_t bin_maxlen, + const char * const b64, const size_t b64_len, + const char * const ignore, size_t * const bin_len, + const char ** const b64_end, const int variant); + +SODIUM_EXPORT +int sodium_mlock(void * const addr, const size_t len); + +SODIUM_EXPORT +int sodium_munlock(void * const addr, const size_t len); + +/* WARNING: sodium_malloc() and sodium_allocarray() are not general-purpose + * allocation functions. + * + * They return a pointer to a region filled with 0xd0 bytes, immediately + * followed by a guard page. + * As a result, accessing a single byte after the requested allocation size + * will intentionally trigger a segmentation fault. + * + * A canary and an additional guard page placed before the beginning of the + * region may also kill the process if a buffer underflow is detected. + * + * The memory layout is: + * [unprotected region size (read only)][guard page (no access)][unprotected pages (read/write)][guard page (no access)] + * With the layout of the unprotected pages being: + * [optional padding][16-bytes canary][user region] + * + * However: + * - These functions are significantly slower than standard functions + * - Each allocation requires 3 or 4 additional pages + * - The returned address will not be aligned if the allocation size is not + * a multiple of the required alignment. For this reason, these functions + * are designed to store data, such as secret keys and messages. + * + * sodium_malloc() can be used to allocate any libsodium data structure. + * + * The crypto_generichash_state structure is packed and its length is + * either 357 or 361 bytes. For this reason, when using sodium_malloc() to + * allocate a crypto_generichash_state structure, padding must be added in + * order to ensure proper alignment. crypto_generichash_statebytes() + * returns the rounded up structure size, and should be prefered to sizeof(): + * state = sodium_malloc(crypto_generichash_statebytes()); + */ + +SODIUM_EXPORT +void *sodium_malloc(const size_t size) + __attribute__ ((malloc)); + +SODIUM_EXPORT +void *sodium_allocarray(size_t count, size_t size) + __attribute__ ((malloc)); + +SODIUM_EXPORT +void sodium_free(void *ptr); + +SODIUM_EXPORT +int sodium_mprotect_noaccess(void *ptr); + +SODIUM_EXPORT +int sodium_mprotect_readonly(void *ptr); + +SODIUM_EXPORT +int sodium_mprotect_readwrite(void *ptr); + +SODIUM_EXPORT +int sodium_pad(size_t *padded_buflen_p, unsigned char *buf, + size_t unpadded_buflen, size_t blocksize, size_t max_buflen); + +SODIUM_EXPORT +int sodium_unpad(size_t *unpadded_buflen_p, const unsigned char *buf, + size_t padded_buflen, size_t blocksize); + +/* -------- */ + +int _sodium_alloc_init(void); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/libs/libsodium/src/include/sodium/version.h b/libs/libsodium/src/include/sodium/version.h new file mode 100644 index 0000000000..56ec2b9550 --- /dev/null +++ b/libs/libsodium/src/include/sodium/version.h @@ -0,0 +1,32 @@ + +#ifndef sodium_version_H +#define sodium_version_H + +#include "export.h" + +#define SODIUM_VERSION_STRING "1.0.16" + +#define SODIUM_LIBRARY_VERSION_MAJOR 10 +#define SODIUM_LIBRARY_VERSION_MINOR 1 + +#ifdef __cplusplus +extern "C" { +#endif + +SODIUM_EXPORT +const char *sodium_version_string(void); + +SODIUM_EXPORT +int sodium_library_version_major(void); + +SODIUM_EXPORT +int sodium_library_version_minor(void); + +SODIUM_EXPORT +int sodium_library_minimal(void); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/libs/libsodium/src/randombytes/nativeclient/randombytes_nativeclient.c b/libs/libsodium/src/randombytes/nativeclient/randombytes_nativeclient.c new file mode 100644 index 0000000000..85ffa9b29b --- /dev/null +++ b/libs/libsodium/src/randombytes/nativeclient/randombytes_nativeclient.c @@ -0,0 +1,61 @@ + +#include <assert.h> +#include <stdint.h> +#include <stdlib.h> + +#ifdef __native_client__ +# include <irt.h> + +# include "core.h" +# include "utils.h" +# include "randombytes.h" +# include "randombytes_nativeclient.h" + +static void +randombytes_nativeclient_buf(void * const buf, const size_t size) +{ + unsigned char *buf_ = (unsigned char *) buf; + struct nacl_irt_random rand_intf; + size_t readnb = (size_t) 0U; + size_t toread = size; + + if (nacl_interface_query(NACL_IRT_RANDOM_v0_1, &rand_intf, + sizeof rand_intf) != sizeof rand_intf) { + sodium_misuse(); + } + while (toread > (size_t) 0U) { + if (rand_intf.get_random_bytes(buf_, size, &readnb) != 0 || + readnb > size) { + sodium_misuse(); + } + toread -= readnb; + buf_ += readnb; + } +} + +static uint32_t +randombytes_nativeclient_random(void) +{ + uint32_t r; + + randombytes_nativeclient_buf(&r, sizeof r); + + return r; +} + +static const char * +randombytes_nativeclient_implementation_name(void) +{ + return "nativeclient"; +} + +struct randombytes_implementation randombytes_nativeclient_implementation = { + SODIUM_C99(.implementation_name =) randombytes_nativeclient_implementation_name, + SODIUM_C99(.random =) randombytes_nativeclient_random, + SODIUM_C99(.stir =) NULL, + SODIUM_C99(.uniform =) NULL, + SODIUM_C99(.buf =) randombytes_nativeclient_buf, + SODIUM_C99(.close =) NULL +}; + +#endif diff --git a/libs/libsodium/src/randombytes/randombytes.c b/libs/libsodium/src/randombytes/randombytes.c new file mode 100644 index 0000000000..708616b8aa --- /dev/null +++ b/libs/libsodium/src/randombytes/randombytes.c @@ -0,0 +1,206 @@ + +#include <assert.h> +#include <limits.h> +#include <stdint.h> +#include <stdlib.h> + +#include <sys/types.h> + +#ifdef __EMSCRIPTEN__ +# include <emscripten.h> +#endif + +#include "core.h" +#include "crypto_stream_chacha20.h" +#include "randombytes.h" +#ifdef RANDOMBYTES_DEFAULT_IMPLEMENTATION +# include "randombytes_default.h" +#else +# ifdef __native_client__ +# include "randombytes_nativeclient.h" +# else +# include "randombytes_sysrandom.h" +# endif +#endif +#include "private/common.h" + +/* C++Builder defines a "random" macro */ +#undef random + +static const randombytes_implementation *implementation; + +#ifndef RANDOMBYTES_DEFAULT_IMPLEMENTATION +# ifdef __EMSCRIPTEN__ +# define RANDOMBYTES_DEFAULT_IMPLEMENTATION NULL +# else +# ifdef __native_client__ +# define RANDOMBYTES_DEFAULT_IMPLEMENTATION &randombytes_nativeclient_implementation; +# else +# define RANDOMBYTES_DEFAULT_IMPLEMENTATION &randombytes_sysrandom_implementation; +# endif +# endif +#endif + +static void +randombytes_init_if_needed(void) +{ + if (implementation == NULL) { + implementation = RANDOMBYTES_DEFAULT_IMPLEMENTATION; + randombytes_stir(); + } +} + +int +randombytes_set_implementation(randombytes_implementation *impl) +{ + implementation = impl; + + return 0; +} + +const char * +randombytes_implementation_name(void) +{ +#ifndef __EMSCRIPTEN__ + randombytes_init_if_needed(); + return implementation->implementation_name(); +#else + return "js"; +#endif +} + +uint32_t +randombytes_random(void) +{ +#ifndef __EMSCRIPTEN__ + randombytes_init_if_needed(); + return implementation->random(); +#else + return EM_ASM_INT_V({ + return Module.getRandomValue(); + }); +#endif +} + +void +randombytes_stir(void) +{ +#ifndef __EMSCRIPTEN__ + randombytes_init_if_needed(); + if (implementation->stir != NULL) { + implementation->stir(); + } +#else + EM_ASM({ + if (Module.getRandomValue === undefined) { + try { + var window_ = 'object' === typeof window ? window : self; + var crypto_ = typeof window_.crypto !== 'undefined' ? window_.crypto : window_.msCrypto; + var randomValuesStandard = function() { + var buf = new Uint32Array(1); + crypto_.getRandomValues(buf); + return buf[0] >>> 0; + }; + randomValuesStandard(); + Module.getRandomValue = randomValuesStandard; + } catch (e) { + try { + var crypto = require('crypto'); + var randomValueNodeJS = function() { + var buf = crypto.randomBytes(4); + return (buf[0] << 24 | buf[1] << 16 | buf[2] << 8 | buf[3]) >>> 0; + }; + randomValueNodeJS(); + Module.getRandomValue = randomValueNodeJS; + } catch (e) { + throw 'No secure random number generator found'; + } + } + } + }); +#endif +} + +uint32_t +randombytes_uniform(const uint32_t upper_bound) +{ + uint32_t min; + uint32_t r; + +#ifndef __EMSCRIPTEN__ + randombytes_init_if_needed(); + if (implementation->uniform != NULL) { + return implementation->uniform(upper_bound); + } +#endif + if (upper_bound < 2) { + return 0; + } + min = (1U + ~upper_bound) % upper_bound; /* = 2**32 mod upper_bound */ + do { + r = randombytes_random(); + } while (r < min); + /* r is now clamped to a set whose size mod upper_bound == 0 + * the worst case (2**31+1) requires ~ 2 attempts */ + + return r % upper_bound; +} + +void +randombytes_buf(void * const buf, const size_t size) +{ +#ifndef __EMSCRIPTEN__ + randombytes_init_if_needed(); + if (size > (size_t) 0U) { + implementation->buf(buf, size); + } +#else + unsigned char *p = (unsigned char *) buf; + size_t i; + + for (i = (size_t) 0U; i < size; i++) { + p[i] = (unsigned char) randombytes_random(); + } +#endif +} + +void +randombytes_buf_deterministic(void * const buf, const size_t size, + const unsigned char seed[randombytes_SEEDBYTES]) +{ + static const unsigned char nonce[crypto_stream_chacha20_ietf_NONCEBYTES] = { + 'L', 'i', 'b', 's', 'o', 'd', 'i', 'u', 'm', 'D', 'R', 'G' + }; + + COMPILER_ASSERT(randombytes_SEEDBYTES == crypto_stream_chacha20_ietf_KEYBYTES); +#if SIZE_MAX > 0x4000000000ULL + COMPILER_ASSERT(randombytes_BYTES_MAX <= 0x4000000000ULL); + if (size > 0x4000000000ULL) { + sodium_misuse(); + } +#endif + crypto_stream_chacha20_ietf((unsigned char *) buf, (unsigned long long) size, + nonce, seed); +} + +size_t +randombytes_seedbytes(void) +{ + return randombytes_SEEDBYTES; +} + +int +randombytes_close(void) +{ + if (implementation != NULL && implementation->close != NULL) { + return implementation->close(); + } + return 0; +} + +void +randombytes(unsigned char * const buf, const unsigned long long buf_len) +{ + assert(buf_len <= SIZE_MAX); + randombytes_buf(buf, (size_t) buf_len); +} diff --git a/libs/libsodium/src/randombytes/salsa20/randombytes_salsa20_random.c b/libs/libsodium/src/randombytes/salsa20/randombytes_salsa20_random.c new file mode 100644 index 0000000000..79916eabc0 --- /dev/null +++ b/libs/libsodium/src/randombytes/salsa20/randombytes_salsa20_random.c @@ -0,0 +1,564 @@ + +#include <assert.h> +#include <errno.h> +#include <fcntl.h> +#include <limits.h> +#include <stdint.h> +#include <stdlib.h> +#include <stdlib.h> +#include <string.h> +#if !defined(_MSC_VER) && !defined(__BORLANDC__) +# include <unistd.h> +#endif + +#include <sys/types.h> +#ifndef _WIN32 +# include <sys/stat.h> +# include <sys/time.h> +#endif +#ifdef __linux__ +# ifdef __dietlibc__ +# define _LINUX_SOURCE +# else +# include <sys/syscall.h> +# endif +# include <poll.h> +#endif +#ifdef HAVE_RDRAND +# pragma GCC target("rdrnd") +# include <immintrin.h> +#endif + +#include "core.h" +#include "crypto_core_salsa20.h" +#include "crypto_stream_salsa20.h" +#include "private/common.h" +#include "randombytes.h" +#include "randombytes_salsa20_random.h" +#include "runtime.h" +#include "utils.h" + +#ifdef _WIN32 +# include <windows.h> +# include <sys/timeb.h> +# define RtlGenRandom SystemFunction036 +# if defined(__cplusplus) +extern "C" +# endif +BOOLEAN NTAPI RtlGenRandom(PVOID RandomBuffer, ULONG RandomBufferLength); +# pragma comment(lib, "advapi32.lib") +# ifdef __BORLANDC__ +# define _ftime ftime +# define _timeb timeb +# endif +#endif + +#define SALSA20_RANDOM_BLOCK_SIZE crypto_core_salsa20_OUTPUTBYTES + +#if defined(__OpenBSD__) || defined(__CloudABI__) +# define HAVE_SAFE_ARC4RANDOM 1 +#endif + +#ifndef SSIZE_MAX +# define SSIZE_MAX (SIZE_MAX / 2 - 1) +#endif +#ifndef S_ISNAM +# ifdef __COMPCERT__ +# define S_ISNAM(X) 1 +# else +# define S_ISNAM(X) 0 +# endif +#endif + +#ifndef TLS +# ifdef _WIN32 +# define TLS __declspec(thread) +# else +# define TLS +# endif +#endif + +typedef struct Salsa20RandomGlobal_ { + int initialized; + int random_data_source_fd; + int getrandom_available; + int rdrand_available; +#ifdef HAVE_GETPID + pid_t pid; +#endif +} Salsa20RandomGlobal; + +typedef struct Salsa20Random_ { + int initialized; + size_t rnd32_outleft; + unsigned char key[crypto_stream_salsa20_KEYBYTES]; + unsigned char rnd32[16U * SALSA20_RANDOM_BLOCK_SIZE]; + uint64_t nonce; +} Salsa20Random; + +static Salsa20RandomGlobal global = { + SODIUM_C99(.initialized =) 0, + SODIUM_C99(.random_data_source_fd =) -1 +}; + +static TLS Salsa20Random stream = { + SODIUM_C99(.initialized =) 0, + SODIUM_C99(.rnd32_outleft =) (size_t) 0U +}; + + +/* + * Get a high-resolution timestamp, as a uint64_t value + */ + +#ifdef _WIN32 +static uint64_t +sodium_hrtime(void) +{ + struct _timeb tb; +# pragma warning(push) +# pragma warning(disable: 4996) + _ftime(&tb); +# pragma warning(pop) + return ((uint64_t) tb.time) * 1000000U + ((uint64_t) tb.millitm) * 1000U; +} + +#else /* _WIN32 */ + +static uint64_t +sodium_hrtime(void) +{ + struct timeval tv; + + if (gettimeofday(&tv, NULL) != 0) { + sodium_misuse(); /* LCOV_EXCL_LINE */ + } + return ((uint64_t) tv.tv_sec) * 1000000U + (uint64_t) tv.tv_usec; +} +#endif + +/* + * Initialize the entropy source + */ + +#ifdef _WIN32 + +static void +randombytes_salsa20_random_init(void) +{ + stream.nonce = sodium_hrtime(); + assert(stream.nonce != (uint64_t) 0U); + global.rdrand_available = sodium_runtime_has_rdrand(); +} + +#else /* _WIN32 */ + +static ssize_t +safe_read(const int fd, void * const buf_, size_t size) +{ + unsigned char *buf = (unsigned char *) buf_; + ssize_t readnb; + + assert(size > (size_t) 0U); + assert(size <= SSIZE_MAX); + do { + while ((readnb = read(fd, buf, size)) < (ssize_t) 0 && + (errno == EINTR || errno == EAGAIN)); /* LCOV_EXCL_LINE */ + if (readnb < (ssize_t) 0) { + return readnb; /* LCOV_EXCL_LINE */ + } + if (readnb == (ssize_t) 0) { + break; /* LCOV_EXCL_LINE */ + } + size -= (size_t) readnb; + buf += readnb; + } while (size > (ssize_t) 0); + + return (ssize_t) (buf - (unsigned char *) buf_); +} + +# if defined(__linux__) && !defined(USE_BLOCKING_RANDOM) && !defined(NO_BLOCKING_RANDOM_POLL) +static int +randombytes_block_on_dev_random(void) +{ + struct pollfd pfd; + int fd; + int pret; + + fd = open("/dev/random", O_RDONLY); + if (fd == -1) { + return 0; + } + pfd.fd = fd; + pfd.events = POLLIN; + pfd.revents = 0; + do { + pret = poll(&pfd, 1, -1); + } while (pret < 0 && (errno == EINTR || errno == EAGAIN)); + if (pret != 1) { + (void) close(fd); + errno = EIO; + return -1; + } + return close(fd); +} +# endif + +# ifndef HAVE_SAFE_ARC4RANDOM +static int +randombytes_salsa20_random_random_dev_open(void) +{ +/* LCOV_EXCL_START */ + struct stat st; + static const char *devices[] = { +# ifndef USE_BLOCKING_RANDOM + "/dev/urandom", +# endif + "/dev/random", NULL + }; + const char **device = devices; + int fd; + +# if defined(__linux__) && !defined(USE_BLOCKING_RANDOM) && !defined(NO_BLOCKING_RANDOM_POLL) + if (randombytes_block_on_dev_random() != 0) { + return -1; + } +# endif + do { + fd = open(*device, O_RDONLY); + if (fd != -1) { + if (fstat(fd, &st) == 0 && (S_ISNAM(st.st_mode) || S_ISCHR(st.st_mode))) { +# if defined(F_SETFD) && defined(FD_CLOEXEC) + (void) fcntl(fd, F_SETFD, fcntl(fd, F_GETFD) | FD_CLOEXEC); +# endif + return fd; + } + (void) close(fd); + } else if (errno == EINTR) { + continue; + } + device++; + } while (*device != NULL); + + errno = EIO; + return -1; +/* LCOV_EXCL_STOP */ +} +# endif + +# if defined(__dietlibc__) || (defined(SYS_getrandom) && defined(__NR_getrandom)) +static int +_randombytes_linux_getrandom(void * const buf, const size_t size) +{ + int readnb; + + assert(size <= 256U); + do { +# ifdef __dietlibc__ + readnb = getrandom(buf, size, 0); +# else + readnb = syscall(SYS_getrandom, buf, (int) size, 0); +# endif + } while (readnb < 0 && (errno == EINTR || errno == EAGAIN)); + + return (readnb == (int) size) - 1; +} + +static int +randombytes_linux_getrandom(void * const buf_, size_t size) +{ + unsigned char *buf = (unsigned char *) buf_; + size_t chunk_size = 256U; + + do { + if (size < chunk_size) { + chunk_size = size; + assert(chunk_size > (size_t) 0U); + } + if (_randombytes_linux_getrandom(buf, chunk_size) != 0) { + return -1; + } + size -= chunk_size; + buf += chunk_size; + } while (size > (size_t) 0U); + + return 0; +} +# endif + +static void +randombytes_salsa20_random_init(void) +{ + const int errno_save = errno; + + stream.nonce = sodium_hrtime(); + global.rdrand_available = sodium_runtime_has_rdrand(); + assert(stream.nonce != (uint64_t) 0U); + +# ifdef HAVE_SAFE_ARC4RANDOM + errno = errno_save; +# else + +# if defined(SYS_getrandom) && defined(__NR_getrandom) + { + unsigned char fodder[16]; + + if (randombytes_linux_getrandom(fodder, sizeof fodder) == 0) { + global.getrandom_available = 1; + errno = errno_save; + return; + } + global.getrandom_available = 0; + } +# endif /* SYS_getrandom */ + + if ((global.random_data_source_fd = + randombytes_salsa20_random_random_dev_open()) == -1) { + sodium_misuse(); /* LCOV_EXCL_LINE */ + } + errno = errno_save; +# endif /* HAVE_SAFE_ARC4RANDOM */ +} + +#endif /* _WIN32 */ + +/* + * (Re)seed the generator using the entropy source + */ + +static void +randombytes_salsa20_random_stir(void) +{ + unsigned char m0[crypto_stream_salsa20_KEYBYTES + + crypto_stream_salsa20_NONCEBYTES]; + + memset(stream.rnd32, 0, sizeof stream.rnd32); + stream.rnd32_outleft = (size_t) 0U; + if (global.initialized == 0) { + randombytes_salsa20_random_init(); + global.initialized = 1; + } +#ifdef HAVE_GETPID + global.pid = getpid(); +#endif + +#ifndef _WIN32 + +# ifdef HAVE_SAFE_ARC4RANDOM + arc4random_buf(m0, sizeof m0); +# elif defined(SYS_getrandom) && defined(__NR_getrandom) + if (global.getrandom_available != 0) { + if (randombytes_linux_getrandom(m0, sizeof m0) != 0) { + sodium_misuse(); /* LCOV_EXCL_LINE */ + } + } else if (global.random_data_source_fd == -1 || + safe_read(global.random_data_source_fd, m0, + sizeof m0) != (ssize_t) sizeof m0) { + sodium_misuse(); /* LCOV_EXCL_LINE */ + } +# else + if (global.random_data_source_fd == -1 || + safe_read(global.random_data_source_fd, m0, + sizeof m0) != (ssize_t) sizeof m0) { + sodium_misuse(); /* LCOV_EXCL_LINE */ + } +# endif + +#else /* _WIN32 */ + if (! RtlGenRandom((PVOID) m0, (ULONG) sizeof m0)) { + sodium_misuse(); /* LCOV_EXCL_LINE */ + } +#endif + + crypto_stream_salsa20(stream.key, sizeof stream.key, + m0 + crypto_stream_salsa20_KEYBYTES, m0); + sodium_memzero(m0, sizeof m0); + stream.initialized = 1; +} + +/* + * Reseed the generator if it hasn't been initialized yet + */ + +static void +randombytes_salsa20_random_stir_if_needed(void) +{ +#ifdef HAVE_GETPID + if (stream.initialized == 0) { + randombytes_salsa20_random_stir(); + } else if (global.pid != getpid()) { + sodium_misuse(); /* LCOV_EXCL_LINE */ + } +#else + if (stream.initialized == 0) { + randombytes_salsa20_random_stir(); + } +#endif +} + +/* + * Close the stream, free global resources + */ + +#ifdef _WIN32 +static int +randombytes_salsa20_random_close(void) +{ + int ret = -1; + + if (global.initialized != 0) { + global.initialized = 0; + ret = 0; + } + sodium_memzero(&stream, sizeof stream); + + return ret; +} +#else +static int +randombytes_salsa20_random_close(void) +{ + int ret = -1; + + if (global.random_data_source_fd != -1 && + close(global.random_data_source_fd) == 0) { + global.random_data_source_fd = -1; + global.initialized = 0; +# ifdef HAVE_GETPID + global.pid = (pid_t) 0; +# endif + ret = 0; + } + +# ifdef HAVE_SAFE_ARC4RANDOM + ret = 0; +# endif + +# if defined(SYS_getrandom) && defined(__NR_getrandom) + if (global.getrandom_available != 0) { + ret = 0; + } +# endif + + sodium_memzero(&stream, sizeof stream); + + return ret; +} +#endif + +/* + * RDRAND is only used to mitigate prediction if a key is compromised + */ + +static void +randombytes_salsa20_random_xorhwrand(void) +{ +/* LCOV_EXCL_START */ +#ifdef HAVE_RDRAND + unsigned int r; + + if (global.rdrand_available == 0) { + return; + } + (void) _rdrand32_step(&r); + * (uint32_t *) (void *) + &stream.key[crypto_stream_salsa20_KEYBYTES - 4] ^= (uint32_t) r; +#endif +/* LCOV_EXCL_STOP */ +} + +/* + * XOR the key with another same-length secret + */ + +static inline void +randombytes_salsa20_random_xorkey(const unsigned char * const mix) +{ + unsigned char *key = stream.key; + size_t i; + + for (i = (size_t) 0U; i < sizeof stream.key; i++) { + key[i] ^= mix[i]; + } +} + +/* + * Put `size` random bytes into `buf` and overwrite the key + */ + +static void +randombytes_salsa20_random_buf(void * const buf, const size_t size) +{ + size_t i; + int ret; + + randombytes_salsa20_random_stir_if_needed(); + COMPILER_ASSERT(sizeof stream.nonce == crypto_stream_salsa20_NONCEBYTES); +#if defined(ULONG_LONG_MAX) && defined(SIZE_MAX) +# if SIZE_MAX > ULONG_LONG_MAX + /* coverity[result_independent_of_operands] */ + assert(size <= ULONG_LONG_MAX); +# endif +#endif + ret = crypto_stream_salsa20((unsigned char *) buf, (unsigned long long) size, + (unsigned char *) &stream.nonce, stream.key); + assert(ret == 0); + for (i = 0U; i < sizeof size; i++) { + stream.key[i] ^= ((const unsigned char *) (const void *) &size)[i]; + } + randombytes_salsa20_random_xorhwrand(); + stream.nonce++; + crypto_stream_salsa20_xor(stream.key, stream.key, sizeof stream.key, + (unsigned char *) &stream.nonce, stream.key); +} + +/* + * Pop a 32-bit value from the random pool + * + * Overwrite the key after the pool gets refilled. + */ + +static uint32_t +randombytes_salsa20_random(void) +{ + uint32_t val; + int ret; + + COMPILER_ASSERT(sizeof stream.rnd32 >= (sizeof stream.key) + (sizeof val)); + COMPILER_ASSERT(((sizeof stream.rnd32) - (sizeof stream.key)) + % sizeof val == (size_t) 0U); + if (stream.rnd32_outleft <= (size_t) 0U) { + randombytes_salsa20_random_stir_if_needed(); + COMPILER_ASSERT(sizeof stream.nonce == crypto_stream_salsa20_NONCEBYTES); + ret = crypto_stream_salsa20((unsigned char *) stream.rnd32, + (unsigned long long) sizeof stream.rnd32, + (unsigned char *) &stream.nonce, + stream.key); + assert(ret == 0); + stream.rnd32_outleft = (sizeof stream.rnd32) - (sizeof stream.key); + randombytes_salsa20_random_xorhwrand(); + randombytes_salsa20_random_xorkey(&stream.rnd32[stream.rnd32_outleft]); + memset(&stream.rnd32[stream.rnd32_outleft], 0, sizeof stream.key); + stream.nonce++; + } + stream.rnd32_outleft -= sizeof val; + memcpy(&val, &stream.rnd32[stream.rnd32_outleft], sizeof val); + memset(&stream.rnd32[stream.rnd32_outleft], 0, sizeof val); + + return val; +} + +static const char * +randombytes_salsa20_implementation_name(void) +{ + return "salsa20"; +} + +struct randombytes_implementation randombytes_salsa20_implementation = { + SODIUM_C99(.implementation_name =) randombytes_salsa20_implementation_name, + SODIUM_C99(.random =) randombytes_salsa20_random, + SODIUM_C99(.stir =) randombytes_salsa20_random_stir, + SODIUM_C99(.uniform =) NULL, + SODIUM_C99(.buf =) randombytes_salsa20_random_buf, + SODIUM_C99(.close =) randombytes_salsa20_random_close +}; diff --git a/libs/libsodium/src/randombytes/sysrandom/randombytes_sysrandom.c b/libs/libsodium/src/randombytes/sysrandom/randombytes_sysrandom.c new file mode 100644 index 0000000000..f4dec08f5b --- /dev/null +++ b/libs/libsodium/src/randombytes/sysrandom/randombytes_sysrandom.c @@ -0,0 +1,382 @@ + +#include <assert.h> +#include <errno.h> +#include <fcntl.h> +#include <limits.h> +#include <stdint.h> +#include <string.h> +#ifndef _WIN32 +# include <unistd.h> +#endif + +#include <stdlib.h> +#include <sys/types.h> +#ifndef _WIN32 +# include <sys/stat.h> +# include <sys/time.h> +#endif +#ifdef __linux__ +# ifdef __dietlibc__ +# define _LINUX_SOURCE +# else +# include <sys/syscall.h> +# endif +# include <poll.h> +#endif + +#include "core.h" +#include "private/common.h" +#include "randombytes.h" +#include "randombytes_sysrandom.h" +#include "utils.h" + +#ifdef _WIN32 +/* `RtlGenRandom` is used over `CryptGenRandom` on Microsoft Windows based systems: + * - `CryptGenRandom` requires pulling in `CryptoAPI` which causes unnecessary + * memory overhead if this API is not being used for other purposes + * - `RtlGenRandom` is thus called directly instead. A detailed explanation + * can be found here: https://blogs.msdn.microsoft.com/michael_howard/2005/01/14/cryptographically-secure-random-number-on-windows-without-using-cryptoapi/ + * + * In spite of the disclaimer on the `RtlGenRandom` documentation page that was + * written back in the Windows XP days, this function is here to stay. The CRT + * function `rand_s()` directly depends on it, so touching it would break many + * applications released since Windows XP. + * + * Also note that Rust, Firefox and BoringSSL (thus, Google Chrome and everything + * based on Chromium) also depend on it, and that libsodium allows the RNG to be + * replaced without patching nor recompiling the library. + */ +# include <windows.h> +# define RtlGenRandom SystemFunction036 +# if defined(__cplusplus) +extern "C" +# endif +BOOLEAN NTAPI RtlGenRandom(PVOID RandomBuffer, ULONG RandomBufferLength); +# pragma comment(lib, "advapi32.lib") +#endif + +#if defined(__OpenBSD__) || defined(__CloudABI__) +# define HAVE_SAFE_ARC4RANDOM 1 +#endif + +#ifndef SSIZE_MAX +# define SSIZE_MAX (SIZE_MAX / 2 - 1) +#endif + +#ifdef HAVE_SAFE_ARC4RANDOM + +static uint32_t +randombytes_sysrandom(void) +{ + return arc4random(); +} + +static void +randombytes_sysrandom_stir(void) +{ +} + +static void +randombytes_sysrandom_buf(void * const buf, const size_t size) +{ + arc4random_buf(buf, size); +} + +static int +randombytes_sysrandom_close(void) +{ + return 0; +} + +#else /* __OpenBSD__ */ + +typedef struct SysRandom_ { + int random_data_source_fd; + int initialized; + int getrandom_available; +} SysRandom; + +static SysRandom stream = { + SODIUM_C99(.random_data_source_fd =) -1, + SODIUM_C99(.initialized =) 0, + SODIUM_C99(.getrandom_available =) 0 +}; + +#ifndef _WIN32 +static ssize_t +safe_read(const int fd, void * const buf_, size_t size) +{ + unsigned char *buf = (unsigned char *) buf_; + ssize_t readnb; + + assert(size > (size_t) 0U); + assert(size <= SSIZE_MAX); + do { + while ((readnb = read(fd, buf, size)) < (ssize_t) 0 && + (errno == EINTR || errno == EAGAIN)); /* LCOV_EXCL_LINE */ + if (readnb < (ssize_t) 0) { + return readnb; /* LCOV_EXCL_LINE */ + } + if (readnb == (ssize_t) 0) { + break; /* LCOV_EXCL_LINE */ + } + size -= (size_t) readnb; + buf += readnb; + } while (size > (ssize_t) 0); + + return (ssize_t) (buf - (unsigned char *) buf_); +} +#endif + +#ifndef _WIN32 +# if defined(__linux__) && !defined(USE_BLOCKING_RANDOM) && !defined(NO_BLOCKING_RANDOM_POLL) +static int +randombytes_block_on_dev_random(void) +{ + struct pollfd pfd; + int fd; + int pret; + + fd = open("/dev/random", O_RDONLY); + if (fd == -1) { + return 0; + } + pfd.fd = fd; + pfd.events = POLLIN; + pfd.revents = 0; + do { + pret = poll(&pfd, 1, -1); + } while (pret < 0 && (errno == EINTR || errno == EAGAIN)); + if (pret != 1) { + (void) close(fd); + errno = EIO; + return -1; + } + return close(fd); +} +# endif + +static int +randombytes_sysrandom_random_dev_open(void) +{ +/* LCOV_EXCL_START */ + struct stat st; + static const char *devices[] = { +# ifndef USE_BLOCKING_RANDOM + "/dev/urandom", +# endif + "/dev/random", NULL + }; + const char **device = devices; + int fd; + +# if defined(__linux__) && !defined(USE_BLOCKING_RANDOM) && !defined(NO_BLOCKING_RANDOM_POLL) + if (randombytes_block_on_dev_random() != 0) { + return -1; + } +# endif + do { + fd = open(*device, O_RDONLY); + if (fd != -1) { + if (fstat(fd, &st) == 0 && +# ifdef __COMPCERT__ + 1 +# elif defined(S_ISNAM) + (S_ISNAM(st.st_mode) || S_ISCHR(st.st_mode)) +# else + S_ISCHR(st.st_mode) +# endif + ) { +# if defined(F_SETFD) && defined(FD_CLOEXEC) + (void) fcntl(fd, F_SETFD, fcntl(fd, F_GETFD) | FD_CLOEXEC); +# endif + return fd; + } + (void) close(fd); + } else if (errno == EINTR) { + continue; + } + device++; + } while (*device != NULL); + + errno = EIO; + return -1; +/* LCOV_EXCL_STOP */ +} + +# if defined(__dietlibc__) || (defined(SYS_getrandom) && defined(__NR_getrandom)) +static int +_randombytes_linux_getrandom(void * const buf, const size_t size) +{ + int readnb; + + assert(size <= 256U); + do { +# ifdef __dietlibc__ + readnb = getrandom(buf, size, 0); +# else + readnb = syscall(SYS_getrandom, buf, (int) size, 0); +# endif + } while (readnb < 0 && (errno == EINTR || errno == EAGAIN)); + + return (readnb == (int) size) - 1; +} + +static int +randombytes_linux_getrandom(void * const buf_, size_t size) +{ + unsigned char *buf = (unsigned char *) buf_; + size_t chunk_size = 256U; + + do { + if (size < chunk_size) { + chunk_size = size; + assert(chunk_size > (size_t) 0U); + } + if (_randombytes_linux_getrandom(buf, chunk_size) != 0) { + return -1; + } + size -= chunk_size; + buf += chunk_size; + } while (size > (size_t) 0U); + + return 0; +} +# endif + +static void +randombytes_sysrandom_init(void) +{ + const int errno_save = errno; + +# if defined(SYS_getrandom) && defined(__NR_getrandom) + { + unsigned char fodder[16]; + + if (randombytes_linux_getrandom(fodder, sizeof fodder) == 0) { + stream.getrandom_available = 1; + errno = errno_save; + return; + } + stream.getrandom_available = 0; + } +# endif + + if ((stream.random_data_source_fd = + randombytes_sysrandom_random_dev_open()) == -1) { + sodium_misuse(); /* LCOV_EXCL_LINE */ + } + errno = errno_save; +} + +#else /* _WIN32 */ + +static void +randombytes_sysrandom_init(void) +{ +} +#endif + +static void +randombytes_sysrandom_stir(void) +{ + if (stream.initialized == 0) { + randombytes_sysrandom_init(); + stream.initialized = 1; + } +} + +static void +randombytes_sysrandom_stir_if_needed(void) +{ + if (stream.initialized == 0) { + randombytes_sysrandom_stir(); + } +} + +static int +randombytes_sysrandom_close(void) +{ + int ret = -1; + +#ifndef _WIN32 + if (stream.random_data_source_fd != -1 && + close(stream.random_data_source_fd) == 0) { + stream.random_data_source_fd = -1; + stream.initialized = 0; + ret = 0; + } +# if defined(SYS_getrandom) && defined(__NR_getrandom) + if (stream.getrandom_available != 0) { + ret = 0; + } +# endif +#else /* _WIN32 */ + if (stream.initialized != 0) { + stream.initialized = 0; + ret = 0; + } +#endif + return ret; +} + +static void +randombytes_sysrandom_buf(void * const buf, const size_t size) +{ + randombytes_sysrandom_stir_if_needed(); +#if defined(ULONG_LONG_MAX) && defined(SIZE_MAX) +# if SIZE_MAX > ULONG_LONG_MAX + /* coverity[result_independent_of_operands] */ + assert(size <= ULONG_LONG_MAX); +# endif +#endif +#ifndef _WIN32 +# if defined(SYS_getrandom) && defined(__NR_getrandom) + if (stream.getrandom_available != 0) { + if (randombytes_linux_getrandom(buf, size) != 0) { + sodium_misuse(); /* LCOV_EXCL_LINE */ + } + return; + } +# endif + if (stream.random_data_source_fd == -1 || + safe_read(stream.random_data_source_fd, buf, size) != (ssize_t) size) { + sodium_misuse(); /* LCOV_EXCL_LINE */ + } +#else + COMPILER_ASSERT(randombytes_BYTES_MAX <= 0xffffffffUL); + if (size > (size_t) 0xffffffffUL) { + sodium_misuse(); /* LCOV_EXCL_LINE */ + } + if (! RtlGenRandom((PVOID) buf, (ULONG) size)) { + sodium_misuse(); /* LCOV_EXCL_LINE */ + } +#endif +} + +static uint32_t +randombytes_sysrandom(void) +{ + uint32_t r; + + randombytes_sysrandom_buf(&r, sizeof r); + + return r; +} + +#endif /* __OpenBSD__ */ + +static const char * +randombytes_sysrandom_implementation_name(void) +{ + return "sysrandom"; +} + +struct randombytes_implementation randombytes_sysrandom_implementation = { + SODIUM_C99(.implementation_name =) randombytes_sysrandom_implementation_name, + SODIUM_C99(.random =) randombytes_sysrandom, + SODIUM_C99(.stir =) randombytes_sysrandom_stir, + SODIUM_C99(.uniform =) NULL, + SODIUM_C99(.buf =) randombytes_sysrandom_buf, + SODIUM_C99(.close =) randombytes_sysrandom_close +}; diff --git a/libs/libsodium/src/sodium/codecs.c b/libs/libsodium/src/sodium/codecs.c new file mode 100644 index 0000000000..77fa464cc4 --- /dev/null +++ b/libs/libsodium/src/sodium/codecs.c @@ -0,0 +1,333 @@ +#include <assert.h> +#include <errno.h> +#include <limits.h> +#include <stddef.h> +#include <stdint.h> +#include <stdlib.h> +#include <string.h> + +#include "core.h" +#include "utils.h" + +/* Derived from original code by CodesInChaos */ +char * +sodium_bin2hex(char *const hex, const size_t hex_maxlen, + const unsigned char *const bin, const size_t bin_len) +{ + size_t i = (size_t) 0U; + unsigned int x; + int b; + int c; + + if (bin_len >= SIZE_MAX / 2 || hex_maxlen <= bin_len * 2U) { + sodium_misuse(); /* LCOV_EXCL_LINE */ + } + while (i < bin_len) { + c = bin[i] & 0xf; + b = bin[i] >> 4; + x = (unsigned char) (87U + c + (((c - 10U) >> 8) & ~38U)) << 8 | + (unsigned char) (87U + b + (((b - 10U) >> 8) & ~38U)); + hex[i * 2U] = (char) x; + x >>= 8; + hex[i * 2U + 1U] = (char) x; + i++; + } + hex[i * 2U] = 0U; + + return hex; +} + +int +sodium_hex2bin(unsigned char *const bin, const size_t bin_maxlen, + const char *const hex, const size_t hex_len, + const char *const ignore, size_t *const bin_len, + const char **const hex_end) +{ + size_t bin_pos = (size_t) 0U; + size_t hex_pos = (size_t) 0U; + int ret = 0; + unsigned char c; + unsigned char c_acc = 0U; + unsigned char c_alpha0, c_alpha; + unsigned char c_num0, c_num; + unsigned char c_val; + unsigned char state = 0U; + + while (hex_pos < hex_len) { + c = (unsigned char) hex[hex_pos]; + c_num = c ^ 48U; + c_num0 = (c_num - 10U) >> 8; + c_alpha = (c & ~32U) - 55U; + c_alpha0 = ((c_alpha - 10U) ^ (c_alpha - 16U)) >> 8; + if ((c_num0 | c_alpha0) == 0U) { + if (ignore != NULL && state == 0U && strchr(ignore, c) != NULL) { + hex_pos++; + continue; + } + break; + } + c_val = (c_num0 & c_num) | (c_alpha0 & c_alpha); + if (bin_pos >= bin_maxlen) { + ret = -1; + errno = ERANGE; + break; + } + if (state == 0U) { + c_acc = c_val * 16U; + } else { + bin[bin_pos++] = c_acc | c_val; + } + state = ~state; + hex_pos++; + } + if (state != 0U) { + hex_pos--; + errno = EINVAL; + ret = -1; + } + if (ret != 0) { + bin_pos = (size_t) 0U; + } + if (hex_end != NULL) { + *hex_end = &hex[hex_pos]; + } else if (hex_pos != hex_len) { + errno = EINVAL; + ret = -1; + } + if (bin_len != NULL) { + *bin_len = bin_pos; + } + return ret; +} + +/* + * Some macros for constant-time comparisons. These work over values in + * the 0..255 range. Returned value is 0x00 on "false", 0xFF on "true". + * + * Original code by Thomas Pornin. + */ +#define EQ(x, y) \ + ((((0U - ((unsigned int) (x) ^ (unsigned int) (y))) >> 8) & 0xFF) ^ 0xFF) +#define GT(x, y) ((((unsigned int) (y) - (unsigned int) (x)) >> 8) & 0xFF) +#define GE(x, y) (GT(y, x) ^ 0xFF) +#define LT(x, y) GT(y, x) +#define LE(x, y) GE(y, x) + +static int +b64_byte_to_char(unsigned int x) +{ + return (LT(x, 26) & (x + 'A')) | + (GE(x, 26) & LT(x, 52) & (x + ('a' - 26))) | + (GE(x, 52) & LT(x, 62) & (x + ('0' - 52))) | (EQ(x, 62) & '+') | + (EQ(x, 63) & '/'); +} + +static unsigned int +b64_char_to_byte(int c) +{ + const unsigned int x = + (GE(c, 'A') & LE(c, 'Z') & (c - 'A')) | + (GE(c, 'a') & LE(c, 'z') & (c - ('a' - 26))) | + (GE(c, '0') & LE(c, '9') & (c - ('0' - 52))) | (EQ(c, '+') & 62) | + (EQ(c, '/') & 63); + + return x | (EQ(x, 0) & (EQ(c, 'A') ^ 0xFF)); +} + +static int +b64_byte_to_urlsafe_char(unsigned int x) +{ + return (LT(x, 26) & (x + 'A')) | + (GE(x, 26) & LT(x, 52) & (x + ('a' - 26))) | + (GE(x, 52) & LT(x, 62) & (x + ('0' - 52))) | (EQ(x, 62) & '-') | + (EQ(x, 63) & '_'); +} + +static unsigned int +b64_urlsafe_char_to_byte(int c) +{ + const unsigned x = + (GE(c, 'A') & LE(c, 'Z') & (c - 'A')) | + (GE(c, 'a') & LE(c, 'z') & (c - ('a' - 26))) | + (GE(c, '0') & LE(c, '9') & (c - ('0' - 52))) | (EQ(c, '-') & 62) | + (EQ(c, '_') & 63); + + return x | (EQ(x, 0) & (EQ(c, 'A') ^ 0xFF)); +} + + +#define VARIANT_NO_PADDING_MASK 0x2U +#define VARIANT_URLSAFE_MASK 0x4U + +static void +sodium_base64_check_variant(const int variant) +{ + if ((((unsigned int) variant) & ~ 0x6U) != 0x1U) { + sodium_misuse(); + } +} + +size_t +sodium_base64_encoded_len(const size_t bin_len, const int variant) +{ + sodium_base64_check_variant(variant); + + return sodium_base64_ENCODED_LEN(bin_len, variant); +} + +char * +sodium_bin2base64(char * const b64, const size_t b64_maxlen, + const unsigned char * const bin, const size_t bin_len, + const int variant) +{ + size_t acc_len = (size_t) 0; + size_t b64_len; + size_t b64_pos = (size_t) 0; + size_t bin_pos = (size_t) 0; + size_t nibbles; + size_t remainder; + unsigned int acc = 0U; + + sodium_base64_check_variant(variant); + nibbles = bin_len / 3; + remainder = bin_len - 3 * nibbles; + b64_len = nibbles * 4; + if (remainder != 0) { + if ((((unsigned int) variant) & VARIANT_NO_PADDING_MASK) == 0U) { + b64_len += 4; + } else { + b64_len += 2 + (remainder >> 1); + } + } + if (b64_maxlen <= b64_len) { + sodium_misuse(); + } + if ((((unsigned int) variant) & VARIANT_URLSAFE_MASK) != 0U) { + while (bin_pos < bin_len) { + acc = (acc << 8) + bin[bin_pos++]; + acc_len += 8; + while (acc_len >= 6) { + acc_len -= 6; + b64[b64_pos++] = (char) b64_byte_to_urlsafe_char((acc >> acc_len) & 0x3F); + } + } + if (acc_len > 0) { + b64[b64_pos++] = (char) b64_byte_to_urlsafe_char((acc << (6 - acc_len)) & 0x3F); + } + } else { + while (bin_pos < bin_len) { + acc = (acc << 8) + bin[bin_pos++]; + acc_len += 8; + while (acc_len >= 6) { + acc_len -= 6; + b64[b64_pos++] = (char) b64_byte_to_char((acc >> acc_len) & 0x3F); + } + } + if (acc_len > 0) { + b64[b64_pos++] = (char) b64_byte_to_char((acc << (6 - acc_len)) & 0x3F); + } + } + assert(b64_pos <= b64_len); + while (b64_pos < b64_len) { + b64[b64_pos++] = '='; + } + do { + b64[b64_pos++] = 0U; + } while (b64_pos < b64_maxlen); + + return b64; +} + +static int +_sodium_base642bin_skip_padding(const char * const b64, const size_t b64_len, + size_t * const b64_pos_p, + const char * const ignore, size_t padding_len) +{ + int c; + + while (padding_len > 0) { + if (*b64_pos_p >= b64_len) { + errno = ERANGE; + return -1; + } + c = b64[*b64_pos_p]; + if (c == '=') { + padding_len--; + } else if (ignore == NULL || strchr(ignore, c) == NULL) { + errno = EINVAL; + return -1; + } + (*b64_pos_p)++; + } + return 0; +} + +int +sodium_base642bin(unsigned char * const bin, const size_t bin_maxlen, + const char * const b64, const size_t b64_len, + const char * const ignore, size_t * const bin_len, + const char ** const b64_end, const int variant) +{ + size_t acc_len = (size_t) 0; + size_t b64_pos = (size_t) 0; + size_t bin_pos = (size_t) 0; + int is_urlsafe; + int ret = 0; + unsigned int acc = 0U; + unsigned int d; + char c; + + sodium_base64_check_variant(variant); + is_urlsafe = ((unsigned int) variant) & VARIANT_URLSAFE_MASK; + while (b64_pos < b64_len) { + c = b64[b64_pos]; + if (is_urlsafe) { + d = b64_urlsafe_char_to_byte(c); + } else { + d = b64_char_to_byte(c); + } + if (d == 0xFF) { + if (ignore != NULL && strchr(ignore, c) != NULL) { + b64_pos++; + continue; + } + break; + } + acc = (acc << 6) + d; + acc_len += 6; + if (acc_len >= 8) { + acc_len -= 8; + if (bin_pos >= bin_maxlen) { + errno = ERANGE; + ret = -1; + break; + } + bin[bin_pos++] = (acc >> acc_len) & 0xFF; + } + b64_pos++; + } + if (acc_len > 4U || (acc & ((1U << acc_len) - 1U)) != 0U) { + ret = -1; + } else if (ret == 0 && + (((unsigned int) variant) & VARIANT_NO_PADDING_MASK) == 0U) { + ret = _sodium_base642bin_skip_padding(b64, b64_len, &b64_pos, ignore, + acc_len / 2); + } + if (ret != 0) { + bin_pos = (size_t) 0U; + } else if (ignore != NULL) { + while (b64_pos < b64_len && strchr(ignore, b64[b64_pos]) != NULL) { + b64_pos++; + } + } + if (b64_end != NULL) { + *b64_end = &b64[b64_pos]; + } else if (b64_pos != b64_len) { + errno = EINVAL; + ret = -1; + } + if (bin_len != NULL) { + *bin_len = bin_pos; + } + return ret; +} diff --git a/libs/libsodium/src/sodium/core.c b/libs/libsodium/src/sodium/core.c new file mode 100644 index 0000000000..1ac29d09c8 --- /dev/null +++ b/libs/libsodium/src/sodium/core.c @@ -0,0 +1,231 @@ + +#include <assert.h> +#include <stdlib.h> +#include <string.h> +#include <time.h> +#ifdef _WIN32 +# include <windows.h> +#elif defined(HAVE_PTHREAD) +# include <pthread.h> +#endif + +#include "core.h" +#include "crypto_generichash.h" +#include "crypto_onetimeauth.h" +#include "crypto_scalarmult.h" +#include "crypto_stream_chacha20.h" +#include "crypto_stream_salsa20.h" +#include "randombytes.h" +#include "runtime.h" +#include "utils.h" +#include "private/implementations.h" +#include "private/mutex.h" + +#if !defined(_MSC_VER) && 0 +# warning *** This is unstable, untested, development code. +# warning It might not compile. It might not work as expected. +# warning It might be totally insecure. +# warning Do not use this in production. +# warning Use releases available at https://download.libsodium.org/libsodium/releases/ instead. +# warning Alternatively, use the "stable" branch in the git repository. +#endif + +#if !defined(_MSC_VER) && (!defined(CONFIGURED) || CONFIGURED != 1) +# warning *** The library is being compiled using an undocumented method. +# warning This is not supported. It has not been tested, it might not +# warning work as expected, and performance is likely to be suboptimal. +#endif + +static volatile int initialized; +static volatile int locked; + +int +sodium_init(void) +{ + if (sodium_crit_enter() != 0) { + return -1; /* LCOV_EXCL_LINE */ + } + if (initialized != 0) { + if (sodium_crit_leave() != 0) { + return -1; /* LCOV_EXCL_LINE */ + } + return 1; + } + _sodium_runtime_get_cpu_features(); + randombytes_stir(); + _sodium_alloc_init(); + _crypto_pwhash_argon2_pick_best_implementation(); + _crypto_generichash_blake2b_pick_best_implementation(); + _crypto_onetimeauth_poly1305_pick_best_implementation(); + _crypto_scalarmult_curve25519_pick_best_implementation(); + _crypto_stream_chacha20_pick_best_implementation(); + _crypto_stream_salsa20_pick_best_implementation(); + initialized = 1; + if (sodium_crit_leave() != 0) { + return -1; /* LCOV_EXCL_LINE */ + } + return 0; +} + +#ifdef _WIN32 + +static CRITICAL_SECTION _sodium_lock; +static volatile LONG _sodium_lock_initialized; + +int +_sodium_crit_init(void) +{ + LONG status = 0L; + + while ((status = InterlockedCompareExchange(&_sodium_lock_initialized, + 1L, 0L)) == 1L) { + Sleep(0); + } + + switch (status) { + case 0L: + InitializeCriticalSection(&_sodium_lock); + return InterlockedExchange(&_sodium_lock_initialized, 2L) == 1L ? 0 : -1; + case 2L: + return 0; + default: /* should never be reached */ + return -1; + } +} + +int +sodium_crit_enter(void) +{ + if (_sodium_crit_init() != 0) { + return -1; /* LCOV_EXCL_LINE */ + } + EnterCriticalSection(&_sodium_lock); + assert(locked == 0); + locked = 1; + + return 0; +} + +int +sodium_crit_leave(void) +{ + if (locked == 0) { +# ifdef EPERM + errno = EPERM; +# endif + return -1; + } + locked = 0; + LeaveCriticalSection(&_sodium_lock); + + return 0; +} + +#elif defined(HAVE_PTHREAD) && !defined(__EMSCRIPTEN__) + +static pthread_mutex_t _sodium_lock = PTHREAD_MUTEX_INITIALIZER; + +int +sodium_crit_enter(void) +{ + int ret; + + if ((ret = pthread_mutex_lock(&_sodium_lock)) == 0) { + assert(locked == 0); + locked = 1; + } + return ret; +} + +int +sodium_crit_leave(void) +{ + int ret; + + if (locked == 0) { +# ifdef EPERM + errno = EPERM; +# endif + return -1; + } + locked = 0; + + return pthread_mutex_unlock(&_sodium_lock); +} + +#elif defined(HAVE_ATOMIC_OPS) && !defined(__EMSCRIPTEN__) && !defined(__native_client__) + +static volatile int _sodium_lock; + +int +sodium_crit_enter(void) +{ +# ifdef HAVE_NANOSLEEP + struct timespec q; + memset(&q, 0, sizeof q); +# endif + while (__sync_lock_test_and_set(&_sodium_lock, 1) != 0) { +# ifdef HAVE_NANOSLEEP + (void) nanosleep(&q, NULL); +# elif defined(__x86_64__) || defined(__i386__) + __asm__ __volatile__ ("pause"); +# endif + } + return 0; +} + +int +sodium_crit_leave(void) +{ + __sync_lock_release(&_sodium_lock); + + return 0; +} + +#else + +int +sodium_crit_enter(void) +{ + return 0; +} + +int +sodium_crit_leave(void) +{ + return 0; +} + +#endif + +static void (*_misuse_handler)(void); + +void +sodium_misuse(void) +{ + void (*handler)(void); + + (void) sodium_crit_leave(); + if (sodium_crit_enter() == 0) { + handler = _misuse_handler; + if (handler != NULL) { + handler(); + } + } +/* LCOV_EXCL_START */ + abort(); +} +/* LCOV_EXCL_STOP */ + +int +sodium_set_misuse_handler(void (*handler)(void)) +{ + if (sodium_crit_enter() != 0) { + return -1; /* LCOV_EXCL_LINE */ + } + _misuse_handler = handler; + if (sodium_crit_leave() != 0) { + return -1; /* LCOV_EXCL_LINE */ + } + return 0; +} diff --git a/libs/libsodium/src/sodium/runtime.c b/libs/libsodium/src/sodium/runtime.c new file mode 100644 index 0000000000..ba1000f4dc --- /dev/null +++ b/libs/libsodium/src/sodium/runtime.c @@ -0,0 +1,286 @@ +#include <stddef.h> +#include <stdint.h> +#ifdef HAVE_ANDROID_GETCPUFEATURES +# include <cpu-features.h> +#endif + +#include "private/common.h" +#include "runtime.h" + +typedef struct CPUFeatures_ { + int initialized; + int has_neon; + int has_sse2; + int has_sse3; + int has_ssse3; + int has_sse41; + int has_avx; + int has_avx2; + int has_avx512f; + int has_pclmul; + int has_aesni; + int has_rdrand; +} CPUFeatures; + +static CPUFeatures _cpu_features; + +#define CPUID_EBX_AVX2 0x00000020 +#define CPUID_EBX_AVX512F 0x00010000 + +#define CPUID_ECX_SSE3 0x00000001 +#define CPUID_ECX_PCLMUL 0x00000002 +#define CPUID_ECX_SSSE3 0x00000200 +#define CPUID_ECX_SSE41 0x00080000 +#define CPUID_ECX_AESNI 0x02000000 +#define CPUID_ECX_XSAVE 0x04000000 +#define CPUID_ECX_OSXSAVE 0x08000000 +#define CPUID_ECX_AVX 0x10000000 +#define CPUID_ECX_RDRAND 0x40000000 + +#define CPUID_EDX_SSE2 0x04000000 + +#define XCR0_SSE 0x00000002 +#define XCR0_AVX 0x00000004 + +static int +_sodium_runtime_arm_cpu_features(CPUFeatures * const cpu_features) +{ +#ifndef __arm__ + cpu_features->has_neon = 0; + return -1; +#else +# ifdef __APPLE__ +# ifdef __ARM_NEON__ + cpu_features->has_neon = 1; +# else + cpu_features->has_neon = 0; +# endif +# elif defined(HAVE_ANDROID_GETCPUFEATURES) && \ + defined(ANDROID_CPU_ARM_FEATURE_NEON) + cpu_features->has_neon = + (android_getCpuFeatures() & ANDROID_CPU_ARM_FEATURE_NEON) != 0x0; +# else + cpu_features->has_neon = 0; +# endif + return 0; +#endif +} + +static void +_cpuid(unsigned int cpu_info[4U], const unsigned int cpu_info_type) +{ +#if defined(_MSC_VER) && \ + (defined(_M_X64) || defined(_M_AMD64) || defined(_M_IX86)) + __cpuid((int *) cpu_info, cpu_info_type); +#elif defined(HAVE_CPUID) + cpu_info[0] = cpu_info[1] = cpu_info[2] = cpu_info[3] = 0; +# ifdef __i386__ + __asm__ __volatile__( + "pushfl; pushfl; " + "popl %0; " + "movl %0, %1; xorl %2, %0; " + "pushl %0; " + "popfl; pushfl; popl %0; popfl" + : "=&r"(cpu_info[0]), "=&r"(cpu_info[1]) + : "i"(0x200000)); + if (((cpu_info[0] ^ cpu_info[1]) & 0x200000) == 0x0) { + return; /* LCOV_EXCL_LINE */ + } +# endif +# ifdef __i386__ + __asm__ __volatile__("xchgl %%ebx, %k1; cpuid; xchgl %%ebx, %k1" + : "=a"(cpu_info[0]), "=&r"(cpu_info[1]), + "=c"(cpu_info[2]), "=d"(cpu_info[3]) + : "0"(cpu_info_type), "2"(0U)); +# elif defined(__x86_64__) + __asm__ __volatile__("xchgq %%rbx, %q1; cpuid; xchgq %%rbx, %q1" + : "=a"(cpu_info[0]), "=&r"(cpu_info[1]), + "=c"(cpu_info[2]), "=d"(cpu_info[3]) + : "0"(cpu_info_type), "2"(0U)); +# else + __asm__ __volatile__("cpuid" + : "=a"(cpu_info[0]), "=b"(cpu_info[1]), + "=c"(cpu_info[2]), "=d"(cpu_info[3]) + : "0"(cpu_info_type), "2"(0U)); +# endif +#else + (void) cpu_info_type; + cpu_info[0] = cpu_info[1] = cpu_info[2] = cpu_info[3] = 0; +#endif +} + +static int +_sodium_runtime_intel_cpu_features(CPUFeatures * const cpu_features) +{ + unsigned int cpu_info[4]; + unsigned int id; + + _cpuid(cpu_info, 0x0); + if ((id = cpu_info[0]) == 0U) { + return -1; /* LCOV_EXCL_LINE */ + } + _cpuid(cpu_info, 0x00000001); +#ifdef HAVE_EMMINTRIN_H + cpu_features->has_sse2 = ((cpu_info[3] & CPUID_EDX_SSE2) != 0x0); +#else + cpu_features->has_sse2 = 0; +#endif + +#ifdef HAVE_PMMINTRIN_H + cpu_features->has_sse3 = ((cpu_info[2] & CPUID_ECX_SSE3) != 0x0); +#else + cpu_features->has_sse3 = 0; +#endif + +#ifdef HAVE_TMMINTRIN_H + cpu_features->has_ssse3 = ((cpu_info[2] & CPUID_ECX_SSSE3) != 0x0); +#else + cpu_features->has_ssse3 = 0; +#endif + +#ifdef HAVE_SMMINTRIN_H + cpu_features->has_sse41 = ((cpu_info[2] & CPUID_ECX_SSE41) != 0x0); +#else + cpu_features->has_sse41 = 0; +#endif + + cpu_features->has_avx = 0; +#ifdef HAVE_AVXINTRIN_H + if ((cpu_info[2] & (CPUID_ECX_AVX | CPUID_ECX_XSAVE | CPUID_ECX_OSXSAVE)) == + (CPUID_ECX_AVX | CPUID_ECX_XSAVE | CPUID_ECX_OSXSAVE)) { + uint32_t xcr0 = 0U; +# if defined(HAVE__XGETBV) || \ + (defined(_MSC_VER) && defined(_XCR_XFEATURE_ENABLED_MASK) && _MSC_FULL_VER >= 160040219) + xcr0 = (uint32_t) _xgetbv(0); +# elif defined(_MSC_VER) && defined(_M_IX86) + __asm { + xor ecx, ecx + _asm _emit 0x0f _asm _emit 0x01 _asm _emit 0xd0 + mov xcr0, eax + } +# elif defined(HAVE_AVX_ASM) + __asm__ __volatile__(".byte 0x0f, 0x01, 0xd0" /* XGETBV */ + : "=a"(xcr0) + : "c"((uint32_t) 0U) + : "%edx"); +# endif + if ((xcr0 & (XCR0_SSE | XCR0_AVX)) == (XCR0_SSE | XCR0_AVX)) { + cpu_features->has_avx = 1; + } + } +#endif + + cpu_features->has_avx2 = 0; +#ifdef HAVE_AVX2INTRIN_H + if (cpu_features->has_avx) { + unsigned int cpu_info7[4]; + + _cpuid(cpu_info7, 0x00000007); + cpu_features->has_avx2 = ((cpu_info7[1] & CPUID_EBX_AVX2) != 0x0); + } +#endif + + cpu_features->has_avx512f = 0; +#ifdef HAVE_AVX512FINTRIN_H + if (cpu_features->has_avx2) { + unsigned int cpu_info7[4]; + + _cpuid(cpu_info7, 0x00000007); + cpu_features->has_avx512f = ((cpu_info7[1] & CPUID_EBX_AVX512F) != 0x0); + } +#endif + +#ifdef HAVE_WMMINTRIN_H + cpu_features->has_pclmul = ((cpu_info[2] & CPUID_ECX_PCLMUL) != 0x0); + cpu_features->has_aesni = ((cpu_info[2] & CPUID_ECX_AESNI) != 0x0); +#else + cpu_features->has_pclmul = 0; + cpu_features->has_aesni = 0; +#endif + +#ifdef HAVE_RDRAND + cpu_features->has_rdrand = ((cpu_info[2] & CPUID_ECX_RDRAND) != 0x0); +#else + cpu_features->has_rdrand = 0; +#endif + + return 0; +} + +int +_sodium_runtime_get_cpu_features(void) +{ + int ret = -1; + + ret &= _sodium_runtime_arm_cpu_features(&_cpu_features); + ret &= _sodium_runtime_intel_cpu_features(&_cpu_features); + _cpu_features.initialized = 1; + + return ret; +} + +int +sodium_runtime_has_neon(void) +{ + return _cpu_features.has_neon; +} + +int +sodium_runtime_has_sse2(void) +{ + return _cpu_features.has_sse2; +} + +int +sodium_runtime_has_sse3(void) +{ + return _cpu_features.has_sse3; +} + +int +sodium_runtime_has_ssse3(void) +{ + return _cpu_features.has_ssse3; +} + +int +sodium_runtime_has_sse41(void) +{ + return _cpu_features.has_sse41; +} + +int +sodium_runtime_has_avx(void) +{ + return _cpu_features.has_avx; +} + +int +sodium_runtime_has_avx2(void) +{ + return _cpu_features.has_avx2; +} + +int +sodium_runtime_has_avx512f(void) +{ + return _cpu_features.has_avx512f; +} + +int +sodium_runtime_has_pclmul(void) +{ + return _cpu_features.has_pclmul; +} + +int +sodium_runtime_has_aesni(void) +{ + return _cpu_features.has_aesni; +} + +int +sodium_runtime_has_rdrand(void) +{ + return _cpu_features.has_rdrand; +} diff --git a/libs/libsodium/src/sodium/utils.c b/libs/libsodium/src/sodium/utils.c new file mode 100644 index 0000000000..85aad29200 --- /dev/null +++ b/libs/libsodium/src/sodium/utils.c @@ -0,0 +1,737 @@ +#ifndef __STDC_WANT_LIB_EXT1__ +# define __STDC_WANT_LIB_EXT1__ 1 +#endif +#include <assert.h> +#include <errno.h> +#include <limits.h> +#include <signal.h> +#include <stddef.h> +#include <stdint.h> +#include <stdlib.h> +#include <string.h> + +#ifdef HAVE_SYS_MMAN_H +# include <sys/mman.h> +#endif + +#ifdef _WIN32 +# include <windows.h> +# include <wincrypt.h> +#else +# include <unistd.h> +#endif + +#ifndef HAVE_C_VARARRAYS +# ifdef HAVE_ALLOCA_H +# include <alloca.h> +# elif !defined(alloca) +# if defined(__GNUC__) +# define alloca __builtin_alloca +# elif defined _AIX +# define alloca __alloca +# elif defined _MSC_VER +# include <malloc.h> +# define alloca _alloca +# else +# include <stddef.h> +# ifdef __cplusplus +extern "C" +# endif +void *alloca (size_t); +# endif +# endif +#endif + +#include "core.h" +#include "randombytes.h" +#include "utils.h" + +#ifndef ENOSYS +# define ENOSYS ENXIO +#endif + +#if defined(_WIN32) && \ + (!defined(WINAPI_FAMILY) || WINAPI_FAMILY == WINAPI_FAMILY_DESKTOP_APP) +# define WINAPI_DESKTOP +#endif + +#define CANARY_SIZE 16U +#define GARBAGE_VALUE 0xdb + +#ifndef MAP_NOCORE +# define MAP_NOCORE 0 +#endif +#if !defined(MAP_ANON) && defined(MAP_ANONYMOUS) +# define MAP_ANON MAP_ANONYMOUS +#endif +#if defined(WINAPI_DESKTOP) || (defined(MAP_ANON) && defined(HAVE_MMAP)) || \ + defined(HAVE_POSIX_MEMALIGN) +# define HAVE_ALIGNED_MALLOC +#endif +#if defined(HAVE_MPROTECT) && \ + !(defined(PROT_NONE) && defined(PROT_READ) && defined(PROT_WRITE)) +# undef HAVE_MPROTECT +#endif +#if defined(HAVE_ALIGNED_MALLOC) && \ + (defined(WINAPI_DESKTOP) || defined(HAVE_MPROTECT)) +# define HAVE_PAGE_PROTECTION +#endif +#if !defined(MADV_DODUMP) && defined(MADV_CORE) +# define MADV_DODUMP MADV_CORE +# define MADV_DONTDUMP MADV_NOCORE +#endif + +static size_t page_size; +static unsigned char canary[CANARY_SIZE]; + +/* LCOV_EXCL_START */ +#ifdef HAVE_WEAK_SYMBOLS +__attribute__((weak)) void +_sodium_dummy_symbol_to_prevent_memzero_lto(void *const pnt, + const size_t len); +__attribute__((weak)) void +_sodium_dummy_symbol_to_prevent_memzero_lto(void *const pnt, + const size_t len) +{ + (void) pnt; /* LCOV_EXCL_LINE */ + (void) len; /* LCOV_EXCL_LINE */ +} +#endif +/* LCOV_EXCL_STOP */ + +void +sodium_memzero(void *const pnt, const size_t len) +{ +#ifdef _WIN32 + SecureZeroMemory(pnt, len); +#elif defined(HAVE_MEMSET_S) + if (len > 0U && memset_s(pnt, (rsize_t) len, 0, (rsize_t) len) != 0) { + sodium_misuse(); /* LCOV_EXCL_LINE */ + } +#elif defined(HAVE_EXPLICIT_BZERO) + explicit_bzero(pnt, len); +#elif HAVE_WEAK_SYMBOLS + memset(pnt, 0, len); + _sodium_dummy_symbol_to_prevent_memzero_lto(pnt, len); +# ifdef HAVE_AMD64_ASM + __asm__ __volatile__ ("" : : "p"(pnt)); +# endif +#else + volatile unsigned char *volatile pnt_ = + (volatile unsigned char *volatile) pnt; + size_t i = (size_t) 0U; + + while (i < len) { + pnt_[i++] = 0U; + } +#endif +} + +void +sodium_stackzero(const size_t len) +{ +#ifdef HAVE_C_VARARRAYS + unsigned char fodder[len]; + sodium_memzero(fodder, len); +#elif HAVE_ALLOCA + sodium_memzero(alloca(len), len); +#endif +} + +#ifdef HAVE_WEAK_SYMBOLS +__attribute__((weak)) void +_sodium_dummy_symbol_to_prevent_memcmp_lto(const unsigned char *b1, + const unsigned char *b2, + const size_t len); +__attribute__((weak)) void +_sodium_dummy_symbol_to_prevent_memcmp_lto(const unsigned char *b1, + const unsigned char *b2, + const size_t len) +{ + (void) b1; + (void) b2; + (void) len; +} +#endif + +int +sodium_memcmp(const void *const b1_, const void *const b2_, size_t len) +{ +#ifdef HAVE_WEAK_SYMBOLS + const unsigned char *b1 = (const unsigned char *) b1_; + const unsigned char *b2 = (const unsigned char *) b2_; +#else + const volatile unsigned char *volatile b1 = + (const volatile unsigned char *volatile) b1_; + const volatile unsigned char *volatile b2 = + (const volatile unsigned char *volatile) b2_; +#endif + size_t i; + volatile unsigned char d = 0U; + +#if HAVE_WEAK_SYMBOLS + _sodium_dummy_symbol_to_prevent_memcmp_lto(b1, b2, len); +#endif + for (i = 0U; i < len; i++) { + d |= b1[i] ^ b2[i]; + } + return (1 & ((d - 1) >> 8)) - 1; +} + +#ifdef HAVE_WEAK_SYMBOLS +__attribute__((weak)) void +_sodium_dummy_symbol_to_prevent_compare_lto(const unsigned char *b1, + const unsigned char *b2, + const size_t len); +__attribute__((weak)) void +_sodium_dummy_symbol_to_prevent_compare_lto(const unsigned char *b1, + const unsigned char *b2, + const size_t len) +{ + (void) b1; + (void) b2; + (void) len; +} +#endif + +int +sodium_compare(const unsigned char *b1_, const unsigned char *b2_, size_t len) +{ +#ifdef HAVE_WEAK_SYMBOLS + const unsigned char *b1 = b1_; + const unsigned char *b2 = b2_; +#else + const volatile unsigned char *volatile b1 = + (const volatile unsigned char *volatile) b1_; + const volatile unsigned char *volatile b2 = + (const volatile unsigned char *volatile) b2_; +#endif + size_t i; + volatile unsigned char gt = 0U; + volatile unsigned char eq = 1U; + uint16_t x1, x2; + +#if HAVE_WEAK_SYMBOLS + _sodium_dummy_symbol_to_prevent_compare_lto(b1, b2, len); +#endif + i = len; + while (i != 0U) { + i--; + x1 = b1[i]; + x2 = b2[i]; + gt |= ((x2 - x1) >> 8) & eq; + eq &= ((x2 ^ x1) - 1) >> 8; + } + return (int) (gt + gt + eq) - 1; +} + +int +sodium_is_zero(const unsigned char *n, const size_t nlen) +{ + size_t i; + volatile unsigned char d = 0U; + + for (i = 0U; i < nlen; i++) { + d |= n[i]; + } + return 1 & ((d - 1) >> 8); +} + +void +sodium_increment(unsigned char *n, const size_t nlen) +{ + size_t i = 0U; + uint_fast16_t c = 1U; + +#ifdef HAVE_AMD64_ASM + uint64_t t64, t64_2; + uint32_t t32; + + if (nlen == 12U) { + __asm__ __volatile__( + "xorq %[t64], %[t64] \n" + "xorl %[t32], %[t32] \n" + "stc \n" + "adcq %[t64], (%[out]) \n" + "adcl %[t32], 8(%[out]) \n" + : [t64] "=&r"(t64), [t32] "=&r"(t32) + : [out] "D"(n) + : "memory", "flags", "cc"); + return; + } else if (nlen == 24U) { + __asm__ __volatile__( + "movq $1, %[t64] \n" + "xorq %[t64_2], %[t64_2] \n" + "addq %[t64], (%[out]) \n" + "adcq %[t64_2], 8(%[out]) \n" + "adcq %[t64_2], 16(%[out]) \n" + : [t64] "=&r"(t64), [t64_2] "=&r"(t64_2) + : [out] "D"(n) + : "memory", "flags", "cc"); + return; + } else if (nlen == 8U) { + __asm__ __volatile__("incq (%[out]) \n" + : + : [out] "D"(n) + : "memory", "flags", "cc"); + return; + } +#endif + for (; i < nlen; i++) { + c += (uint_fast16_t) n[i]; + n[i] = (unsigned char) c; + c >>= 8; + } +} + +void +sodium_add(unsigned char *a, const unsigned char *b, const size_t len) +{ + size_t i = 0U; + uint_fast16_t c = 0U; + +#ifdef HAVE_AMD64_ASM + uint64_t t64, t64_2, t64_3; + uint32_t t32; + + if (len == 12U) { + __asm__ __volatile__( + "movq (%[in]), %[t64] \n" + "movl 8(%[in]), %[t32] \n" + "addq %[t64], (%[out]) \n" + "adcl %[t32], 8(%[out]) \n" + : [t64] "=&r"(t64), [t32] "=&r"(t32) + : [in] "S"(b), [out] "D"(a) + : "memory", "flags", "cc"); + return; + } else if (len == 24U) { + __asm__ __volatile__( + "movq (%[in]), %[t64] \n" + "movq 8(%[in]), %[t64_2] \n" + "movq 16(%[in]), %[t64_3] \n" + "addq %[t64], (%[out]) \n" + "adcq %[t64_2], 8(%[out]) \n" + "adcq %[t64_3], 16(%[out]) \n" + : [t64] "=&r"(t64), [t64_2] "=&r"(t64_2), [t64_3] "=&r"(t64_3) + : [in] "S"(b), [out] "D"(a) + : "memory", "flags", "cc"); + return; + } else if (len == 8U) { + __asm__ __volatile__( + "movq (%[in]), %[t64] \n" + "addq %[t64], (%[out]) \n" + : [t64] "=&r"(t64) + : [in] "S"(b), [out] "D"(a) + : "memory", "flags", "cc"); + return; + } +#endif + for (; i < len; i++) { + c += (uint_fast16_t) a[i] + (uint_fast16_t) b[i]; + a[i] = (unsigned char) c; + c >>= 8; + } +} + +int +_sodium_alloc_init(void) +{ +#ifdef HAVE_ALIGNED_MALLOC +# if defined(_SC_PAGESIZE) + long page_size_ = sysconf(_SC_PAGESIZE); + if (page_size_ > 0L) { + page_size = (size_t) page_size_; + } +# elif defined(WINAPI_DESKTOP) + SYSTEM_INFO si; + GetSystemInfo(&si); + page_size = (size_t) si.dwPageSize; +# endif + if (page_size < CANARY_SIZE || page_size < sizeof(size_t)) { + sodium_misuse(); /* LCOV_EXCL_LINE */ + } +#endif + randombytes_buf(canary, sizeof canary); + + return 0; +} + +int +sodium_mlock(void *const addr, const size_t len) +{ +#if defined(MADV_DONTDUMP) && defined(HAVE_MADVISE) + (void) madvise(addr, len, MADV_DONTDUMP); +#endif +#ifdef HAVE_MLOCK + return mlock(addr, len); +#elif defined(WINAPI_DESKTOP) + return -(VirtualLock(addr, len) == 0); +#else + errno = ENOSYS; + return -1; +#endif +} + +int +sodium_munlock(void *const addr, const size_t len) +{ + sodium_memzero(addr, len); +#if defined(MADV_DODUMP) && defined(HAVE_MADVISE) + (void) madvise(addr, len, MADV_DODUMP); +#endif +#ifdef HAVE_MLOCK + return munlock(addr, len); +#elif defined(WINAPI_DESKTOP) + return -(VirtualUnlock(addr, len) == 0); +#else + errno = ENOSYS; + return -1; +#endif +} + +static int +_mprotect_noaccess(void *ptr, size_t size) +{ +#ifdef HAVE_MPROTECT + return mprotect(ptr, size, PROT_NONE); +#elif defined(WINAPI_DESKTOP) + DWORD old; + return -(VirtualProtect(ptr, size, PAGE_NOACCESS, &old) == 0); +#else + errno = ENOSYS; + return -1; +#endif +} + +static int +_mprotect_readonly(void *ptr, size_t size) +{ +#ifdef HAVE_MPROTECT + return mprotect(ptr, size, PROT_READ); +#elif defined(WINAPI_DESKTOP) + DWORD old; + return -(VirtualProtect(ptr, size, PAGE_READONLY, &old) == 0); +#else + errno = ENOSYS; + return -1; +#endif +} + +static int +_mprotect_readwrite(void *ptr, size_t size) +{ +#ifdef HAVE_MPROTECT + return mprotect(ptr, size, PROT_READ | PROT_WRITE); +#elif defined(WINAPI_DESKTOP) + DWORD old; + return -(VirtualProtect(ptr, size, PAGE_READWRITE, &old) == 0); +#else + errno = ENOSYS; + return -1; +#endif +} + +#ifdef HAVE_ALIGNED_MALLOC + +__attribute__((noreturn)) static void +_out_of_bounds(void) +{ +# ifdef SIGSEGV + raise(SIGSEGV); +# elif defined(SIGKILL) + raise(SIGKILL); +# endif + abort(); /* not something we want any higher-level API to catch */ +} /* LCOV_EXCL_LINE */ + +static inline size_t +_page_round(const size_t size) +{ + const size_t page_mask = page_size - 1U; + + return (size + page_mask) & ~page_mask; +} + +static __attribute__((malloc)) unsigned char * +_alloc_aligned(const size_t size) +{ + void *ptr; + +# if defined(MAP_ANON) && defined(HAVE_MMAP) + if ((ptr = mmap(NULL, size, PROT_READ | PROT_WRITE, + MAP_ANON | MAP_PRIVATE | MAP_NOCORE, -1, 0)) == + MAP_FAILED) { + ptr = NULL; /* LCOV_EXCL_LINE */ + } /* LCOV_EXCL_LINE */ +# elif defined(HAVE_POSIX_MEMALIGN) + if (posix_memalign(&ptr, page_size, size) != 0) { + ptr = NULL; /* LCOV_EXCL_LINE */ + } /* LCOV_EXCL_LINE */ +# elif defined(WINAPI_DESKTOP) + ptr = VirtualAlloc(NULL, size, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE); +# else +# error Bug +# endif + return (unsigned char *) ptr; +} + +static void +_free_aligned(unsigned char *const ptr, const size_t size) +{ +# if defined(MAP_ANON) && defined(HAVE_MMAP) + (void) munmap(ptr, size); +# elif defined(HAVE_POSIX_MEMALIGN) + free(ptr); +# elif defined(WINAPI_DESKTOP) + VirtualFree(ptr, 0U, MEM_RELEASE); +# else +# error Bug +#endif +} + +static unsigned char * +_unprotected_ptr_from_user_ptr(void *const ptr) +{ + uintptr_t unprotected_ptr_u; + unsigned char *canary_ptr; + size_t page_mask; + + canary_ptr = ((unsigned char *) ptr) - sizeof canary; + page_mask = page_size - 1U; + unprotected_ptr_u = ((uintptr_t) canary_ptr & (uintptr_t) ~page_mask); + if (unprotected_ptr_u <= page_size * 2U) { + sodium_misuse(); /* LCOV_EXCL_LINE */ + } + return (unsigned char *) unprotected_ptr_u; +} + +#endif /* HAVE_ALIGNED_MALLOC */ + +#ifndef HAVE_ALIGNED_MALLOC +static __attribute__((malloc)) void * +_sodium_malloc(const size_t size) +{ + return malloc(size > (size_t) 0U ? size : (size_t) 1U); +} +#else +static __attribute__((malloc)) void * +_sodium_malloc(const size_t size) +{ + void *user_ptr; + unsigned char *base_ptr; + unsigned char *canary_ptr; + unsigned char *unprotected_ptr; + size_t size_with_canary; + size_t total_size; + size_t unprotected_size; + + if (size >= (size_t) SIZE_MAX - page_size * 4U) { + errno = ENOMEM; + return NULL; + } + if (page_size <= sizeof canary || page_size < sizeof unprotected_size) { + sodium_misuse(); /* LCOV_EXCL_LINE */ + } + size_with_canary = (sizeof canary) + size; + unprotected_size = _page_round(size_with_canary); + total_size = page_size + page_size + unprotected_size + page_size; + if ((base_ptr = _alloc_aligned(total_size)) == NULL) { + return NULL; /* LCOV_EXCL_LINE */ + } + unprotected_ptr = base_ptr + page_size * 2U; + _mprotect_noaccess(base_ptr + page_size, page_size); +# ifndef HAVE_PAGE_PROTECTION + memcpy(unprotected_ptr + unprotected_size, canary, sizeof canary); +# endif + _mprotect_noaccess(unprotected_ptr + unprotected_size, page_size); + sodium_mlock(unprotected_ptr, unprotected_size); + canary_ptr = + unprotected_ptr + _page_round(size_with_canary) - size_with_canary; + user_ptr = canary_ptr + sizeof canary; + memcpy(canary_ptr, canary, sizeof canary); + memcpy(base_ptr, &unprotected_size, sizeof unprotected_size); + _mprotect_readonly(base_ptr, page_size); + assert(_unprotected_ptr_from_user_ptr(user_ptr) == unprotected_ptr); + + return user_ptr; +} +#endif /* !HAVE_ALIGNED_MALLOC */ + +__attribute__((malloc)) void * +sodium_malloc(const size_t size) +{ + void *ptr; + + if ((ptr = _sodium_malloc(size)) == NULL) { + return NULL; + } + memset(ptr, (int) GARBAGE_VALUE, size); + + return ptr; +} + +__attribute__((malloc)) void * +sodium_allocarray(size_t count, size_t size) +{ + size_t total_size; + + if (count > (size_t) 0U && size >= (size_t) SIZE_MAX / count) { + errno = ENOMEM; + return NULL; + } + total_size = count * size; + + return sodium_malloc(total_size); +} + +#ifndef HAVE_ALIGNED_MALLOC +void +sodium_free(void *ptr) +{ + free(ptr); +} +#else +void +sodium_free(void *ptr) +{ + unsigned char *base_ptr; + unsigned char *canary_ptr; + unsigned char *unprotected_ptr; + size_t total_size; + size_t unprotected_size; + + if (ptr == NULL) { + return; + } + canary_ptr = ((unsigned char *) ptr) - sizeof canary; + unprotected_ptr = _unprotected_ptr_from_user_ptr(ptr); + base_ptr = unprotected_ptr - page_size * 2U; + memcpy(&unprotected_size, base_ptr, sizeof unprotected_size); + total_size = page_size + page_size + unprotected_size + page_size; + _mprotect_readwrite(base_ptr, total_size); + if (sodium_memcmp(canary_ptr, canary, sizeof canary) != 0) { + _out_of_bounds(); + } +# ifndef HAVE_PAGE_PROTECTION + if (sodium_memcmp(unprotected_ptr + unprotected_size, canary, + sizeof canary) != 0) { + _out_of_bounds(); + } +# endif + sodium_munlock(unprotected_ptr, unprotected_size); + _free_aligned(base_ptr, total_size); +} +#endif /* HAVE_ALIGNED_MALLOC */ + +#ifndef HAVE_PAGE_PROTECTION +static int +_sodium_mprotect(void *ptr, int (*cb)(void *ptr, size_t size)) +{ + (void) ptr; + (void) cb; + errno = ENOSYS; + return -1; +} +#else +static int +_sodium_mprotect(void *ptr, int (*cb)(void *ptr, size_t size)) +{ + unsigned char *base_ptr; + unsigned char *unprotected_ptr; + size_t unprotected_size; + + unprotected_ptr = _unprotected_ptr_from_user_ptr(ptr); + base_ptr = unprotected_ptr - page_size * 2U; + memcpy(&unprotected_size, base_ptr, sizeof unprotected_size); + + return cb(unprotected_ptr, unprotected_size); +} +#endif + +int +sodium_mprotect_noaccess(void *ptr) +{ + return _sodium_mprotect(ptr, _mprotect_noaccess); +} + +int +sodium_mprotect_readonly(void *ptr) +{ + return _sodium_mprotect(ptr, _mprotect_readonly); +} + +int +sodium_mprotect_readwrite(void *ptr) +{ + return _sodium_mprotect(ptr, _mprotect_readwrite); +} + +int +sodium_pad(size_t *padded_buflen_p, unsigned char *buf, + size_t unpadded_buflen, size_t blocksize, size_t max_buflen) +{ + unsigned char *tail; + size_t i; + size_t xpadlen; + size_t xpadded_len; + volatile unsigned char mask; + unsigned char barrier_mask; + + if (blocksize <= 0U) { + return -1; + } + xpadlen = blocksize - 1U; + if ((blocksize & (blocksize - 1U)) == 0U) { + xpadlen -= unpadded_buflen & (blocksize - 1U); + } else { + xpadlen -= unpadded_buflen % blocksize; + } + if ((size_t) SIZE_MAX - unpadded_buflen <= xpadlen) { + sodium_misuse(); + } + xpadded_len = unpadded_buflen + xpadlen; + if (xpadded_len >= max_buflen) { + return -1; + } + tail = &buf[xpadded_len]; + if (padded_buflen_p != NULL) { + *padded_buflen_p = xpadded_len + 1U; + } + mask = 0U; + for (i = 0; i < blocksize; i++) { + barrier_mask = (unsigned char) (((i ^ xpadlen) - 1U) >> 8); + tail[-i] = (tail[-i] & mask) | (0x80 & barrier_mask); + mask |= barrier_mask; + } + return 0; +} + +int +sodium_unpad(size_t *unpadded_buflen_p, const unsigned char *buf, + size_t padded_buflen, size_t blocksize) +{ + const unsigned char *tail; + unsigned char acc = 0U; + unsigned char c; + unsigned char valid = 0U; + volatile size_t pad_len = 0U; + size_t i; + size_t is_barrier; + + if (padded_buflen < blocksize || blocksize <= 0U) { + return -1; + } + tail = &buf[padded_buflen - 1U]; + + for (i = 0U; i < blocksize; i++) { + c = tail[-i]; + is_barrier = + (( (acc - 1U) & (pad_len - 1U) & ((c ^ 0x80) - 1U) ) >> 8) & 1U; + acc |= c; + pad_len |= i & (1U + ~is_barrier); + valid |= (unsigned char) is_barrier; + } + *unpadded_buflen_p = padded_buflen - 1U - pad_len; + + return (int) (valid - 1U); +} diff --git a/libs/libsodium/src/sodium/version.c b/libs/libsodium/src/sodium/version.c new file mode 100644 index 0000000000..4e584a6ea0 --- /dev/null +++ b/libs/libsodium/src/sodium/version.c @@ -0,0 +1,30 @@ + +#include "version.h" + +const char * +sodium_version_string(void) +{ + return SODIUM_VERSION_STRING; +} + +int +sodium_library_version_major(void) +{ + return SODIUM_LIBRARY_VERSION_MAJOR; +} + +int +sodium_library_version_minor(void) +{ + return SODIUM_LIBRARY_VERSION_MINOR; +} + +int +sodium_library_minimal(void) +{ +#ifdef SODIUM_LIBRARY_MINIMAL + return 1; +#else + return 0; +#endif +} diff --git a/libs/libsodium/src/stdafx.cxx b/libs/libsodium/src/stdafx.cxx new file mode 100644 index 0000000000..1647228cd0 --- /dev/null +++ b/libs/libsodium/src/stdafx.cxx @@ -0,0 +1,2 @@ + +#include "stdafx.h"
\ No newline at end of file diff --git a/libs/libsodium/src/stdafx.h b/libs/libsodium/src/stdafx.h new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/libs/libsodium/src/stdafx.h |