aboutsummaryrefslogtreecommitdiff
path: root/lib/Utils.Cryptography/monocypher
diff options
context:
space:
mode:
Diffstat (limited to 'lib/Utils.Cryptography/monocypher')
-rw-r--r--lib/Utils.Cryptography/monocypher/CMakeLists.txt105
-rw-r--r--lib/Utils.Cryptography/monocypher/LICENSE293
-rw-r--r--lib/Utils.Cryptography/monocypher/Taskfile.yaml105
-rw-r--r--lib/Utils.Cryptography/monocypher/argon2.c102
-rw-r--r--lib/Utils.Cryptography/monocypher/argon2.h135
-rw-r--r--lib/Utils.Cryptography/monocypher/blake2b.c90
-rw-r--r--lib/Utils.Cryptography/monocypher/blake2b.h43
-rw-r--r--lib/Utils.Cryptography/monocypher/build.readme.txt0
-rw-r--r--lib/Utils.Cryptography/monocypher/package.json10
-rw-r--r--lib/Utils.Cryptography/monocypher/readme.md17
-rw-r--r--lib/Utils.Cryptography/monocypher/util.h77
-rw-r--r--lib/Utils.Cryptography/monocypher/vendor/.editorconfig16
-rw-r--r--lib/Utils.Cryptography/monocypher/vendor/.gitignore29
-rw-r--r--lib/Utils.Cryptography/monocypher/vendor/AUTHORS.md63
-rw-r--r--lib/Utils.Cryptography/monocypher/vendor/CHANGELOG.md295
-rw-r--r--lib/Utils.Cryptography/monocypher/vendor/CMakeLists.txt82
-rw-r--r--lib/Utils.Cryptography/monocypher/vendor/LICENCE.md173
-rw-r--r--lib/Utils.Cryptography/monocypher/vendor/README.md196
-rw-r--r--lib/Utils.Cryptography/monocypher/vendor/change-prefix.sh70
-rw-r--r--lib/Utils.Cryptography/monocypher/vendor/dist.sh119
-rw-r--r--lib/Utils.Cryptography/monocypher/vendor/dist_ignore36
-rw-r--r--lib/Utils.Cryptography/monocypher/vendor/doc/crypto_aead_lock.3monocypher507
-rw-r--r--lib/Utils.Cryptography/monocypher/vendor/doc/crypto_argon2.3monocypher400
-rw-r--r--lib/Utils.Cryptography/monocypher/vendor/doc/crypto_blake2b.3monocypher544
-rw-r--r--lib/Utils.Cryptography/monocypher/vendor/doc/crypto_chacha20_djb.3monocypher447
-rw-r--r--lib/Utils.Cryptography/monocypher/vendor/doc/crypto_ed25519_sign.3monocypher189
-rw-r--r--lib/Utils.Cryptography/monocypher/vendor/doc/crypto_eddsa_sign.3monocypher522
-rw-r--r--lib/Utils.Cryptography/monocypher/vendor/doc/crypto_elligator_map.3monocypher316
-rw-r--r--lib/Utils.Cryptography/monocypher/vendor/doc/crypto_poly1305.3monocypher279
-rw-r--r--lib/Utils.Cryptography/monocypher/vendor/doc/crypto_sha512.3monocypher578
-rw-r--r--lib/Utils.Cryptography/monocypher/vendor/doc/crypto_verify16.3monocypher132
-rw-r--r--lib/Utils.Cryptography/monocypher/vendor/doc/crypto_wipe.3monocypher116
-rw-r--r--lib/Utils.Cryptography/monocypher/vendor/doc/crypto_x25519.3monocypher329
-rw-r--r--lib/Utils.Cryptography/monocypher/vendor/doc/doc_check.py138
-rw-r--r--lib/Utils.Cryptography/monocypher/vendor/doc/doc_extract_examples.sh78
-rw-r--r--lib/Utils.Cryptography/monocypher/vendor/doc/doc_gen.sh93
-rw-r--r--lib/Utils.Cryptography/monocypher/vendor/doc/intro.3monocypher335
-rw-r--r--lib/Utils.Cryptography/monocypher/vendor/doc/style.css292
-rw-r--r--lib/Utils.Cryptography/monocypher/vendor/makefile211
-rw-r--r--lib/Utils.Cryptography/monocypher/vendor/monocypher.pc11
-rw-r--r--lib/Utils.Cryptography/monocypher/vendor/src/monocypher.c2956
-rw-r--r--lib/Utils.Cryptography/monocypher/vendor/src/monocypher.h321
-rw-r--r--lib/Utils.Cryptography/monocypher/vendor/src/optional/monocypher-ed25519.c500
-rw-r--r--lib/Utils.Cryptography/monocypher/vendor/src/optional/monocypher-ed25519.h140
-rw-r--r--lib/Utils.Cryptography/monocypher/vendor/tests/coverage.sh59
-rw-r--r--lib/Utils.Cryptography/monocypher/vendor/tests/ctgrind.c330
-rw-r--r--lib/Utils.Cryptography/monocypher/vendor/tests/externals/c25519/.gitignore5
-rw-r--r--lib/Utils.Cryptography/monocypher/vendor/tests/externals/c25519/AUTHORS.md5
-rw-r--r--lib/Utils.Cryptography/monocypher/vendor/tests/externals/c25519/c25519.c124
-rw-r--r--lib/Utils.Cryptography/monocypher/vendor/tests/externals/c25519/c25519.h48
-rw-r--r--lib/Utils.Cryptography/monocypher/vendor/tests/externals/c25519/ed25519.c320
-rw-r--r--lib/Utils.Cryptography/monocypher/vendor/tests/externals/c25519/ed25519.h82
-rw-r--r--lib/Utils.Cryptography/monocypher/vendor/tests/externals/c25519/edsign.c168
-rw-r--r--lib/Utils.Cryptography/monocypher/vendor/tests/externals/c25519/edsign.h51
-rw-r--r--lib/Utils.Cryptography/monocypher/vendor/tests/externals/c25519/f25519.c324
-rw-r--r--lib/Utils.Cryptography/monocypher/vendor/tests/externals/c25519/f25519.h92
-rw-r--r--lib/Utils.Cryptography/monocypher/vendor/tests/externals/c25519/fprime.c215
-rw-r--r--lib/Utils.Cryptography/monocypher/vendor/tests/externals/c25519/fprime.h70
-rw-r--r--lib/Utils.Cryptography/monocypher/vendor/tests/externals/c25519/morph25519.c87
-rw-r--r--lib/Utils.Cryptography/monocypher/vendor/tests/externals/c25519/morph25519.h29
-rw-r--r--lib/Utils.Cryptography/monocypher/vendor/tests/externals/c25519/sha512.c228
-rw-r--r--lib/Utils.Cryptography/monocypher/vendor/tests/externals/c25519/sha512.h52
-rw-r--r--lib/Utils.Cryptography/monocypher/vendor/tests/externals/ed25519-donna/AUTHORS.md42
-rw-r--r--lib/Utils.Cryptography/monocypher/vendor/tests/externals/ed25519-donna/curve25519-donna-32bit.h579
-rw-r--r--lib/Utils.Cryptography/monocypher/vendor/tests/externals/ed25519-donna/curve25519-donna-helpers.h67
-rw-r--r--lib/Utils.Cryptography/monocypher/vendor/tests/externals/ed25519-donna/ed25519-donna-32bit-tables.h61
-rw-r--r--lib/Utils.Cryptography/monocypher/vendor/tests/externals/ed25519-donna/ed25519-donna-basepoint-table.h259
-rw-r--r--lib/Utils.Cryptography/monocypher/vendor/tests/externals/ed25519-donna/ed25519-donna-batchverify.h275
-rw-r--r--lib/Utils.Cryptography/monocypher/vendor/tests/externals/ed25519-donna/ed25519-donna-impl-base.h364
-rw-r--r--lib/Utils.Cryptography/monocypher/vendor/tests/externals/ed25519-donna/ed25519-donna-portable-identify.h103
-rw-r--r--lib/Utils.Cryptography/monocypher/vendor/tests/externals/ed25519-donna/ed25519-donna-portable.h135
-rw-r--r--lib/Utils.Cryptography/monocypher/vendor/tests/externals/ed25519-donna/ed25519-donna.h117
-rw-r--r--lib/Utils.Cryptography/monocypher/vendor/tests/externals/ed25519-donna/ed25519-hash-custom.h23
-rw-r--r--lib/Utils.Cryptography/monocypher/vendor/tests/externals/ed25519-donna/ed25519-hash.h219
-rw-r--r--lib/Utils.Cryptography/monocypher/vendor/tests/externals/ed25519-donna/ed25519-randombytes.h91
-rw-r--r--lib/Utils.Cryptography/monocypher/vendor/tests/externals/ed25519-donna/ed25519.c150
-rw-r--r--lib/Utils.Cryptography/monocypher/vendor/tests/externals/ed25519-donna/ed25519.h30
-rw-r--r--lib/Utils.Cryptography/monocypher/vendor/tests/externals/ed25519-donna/modm-donna-32bit.h469
-rw-r--r--lib/Utils.Cryptography/monocypher/vendor/tests/externals/tinyssh/LICENCE121
-rw-r--r--lib/Utils.Cryptography/monocypher/vendor/tests/externals/tinyssh/cleanup.c9
-rw-r--r--lib/Utils.Cryptography/monocypher/vendor/tests/externals/tinyssh/cleanup.h7
-rw-r--r--lib/Utils.Cryptography/monocypher/vendor/tests/externals/tinyssh/crypto_hash_sha512.c110
-rw-r--r--lib/Utils.Cryptography/monocypher/vendor/tests/externals/tinyssh/crypto_hash_sha512.h12
-rw-r--r--lib/Utils.Cryptography/monocypher/vendor/tests/externals/tinyssh/crypto_int64.h8
-rw-r--r--lib/Utils.Cryptography/monocypher/vendor/tests/externals/tinyssh/crypto_onetimeauth_poly1305.c154
-rw-r--r--lib/Utils.Cryptography/monocypher/vendor/tests/externals/tinyssh/crypto_onetimeauth_poly1305.h16
-rw-r--r--lib/Utils.Cryptography/monocypher/vendor/tests/externals/tinyssh/crypto_scalarmult_curve25519.c73
-rw-r--r--lib/Utils.Cryptography/monocypher/vendor/tests/externals/tinyssh/crypto_scalarmult_curve25519.h16
-rw-r--r--lib/Utils.Cryptography/monocypher/vendor/tests/externals/tinyssh/crypto_sign_ed25519.c121
-rw-r--r--lib/Utils.Cryptography/monocypher/vendor/tests/externals/tinyssh/crypto_sign_ed25519.h20
-rw-r--r--lib/Utils.Cryptography/monocypher/vendor/tests/externals/tinyssh/crypto_stream_chacha20.c145
-rw-r--r--lib/Utils.Cryptography/monocypher/vendor/tests/externals/tinyssh/crypto_stream_chacha20.h16
-rw-r--r--lib/Utils.Cryptography/monocypher/vendor/tests/externals/tinyssh/crypto_uint32.h8
-rw-r--r--lib/Utils.Cryptography/monocypher/vendor/tests/externals/tinyssh/crypto_uint64.h8
-rw-r--r--lib/Utils.Cryptography/monocypher/vendor/tests/externals/tinyssh/crypto_verify_32.c6
-rw-r--r--lib/Utils.Cryptography/monocypher/vendor/tests/externals/tinyssh/crypto_verify_32.h12
-rw-r--r--lib/Utils.Cryptography/monocypher/vendor/tests/externals/tinyssh/fe.c171
-rw-r--r--lib/Utils.Cryptography/monocypher/vendor/tests/externals/tinyssh/fe.h21
-rw-r--r--lib/Utils.Cryptography/monocypher/vendor/tests/externals/tinyssh/fe25519.c236
-rw-r--r--lib/Utils.Cryptography/monocypher/vendor/tests/externals/tinyssh/fe25519.h22
-rw-r--r--lib/Utils.Cryptography/monocypher/vendor/tests/externals/tinyssh/ge25519.c226
-rw-r--r--lib/Utils.Cryptography/monocypher/vendor/tests/externals/tinyssh/ge25519.h14
-rw-r--r--lib/Utils.Cryptography/monocypher/vendor/tests/externals/tinyssh/randombytes.c41
-rw-r--r--lib/Utils.Cryptography/monocypher/vendor/tests/externals/tinyssh/randombytes.h10
-rw-r--r--lib/Utils.Cryptography/monocypher/vendor/tests/externals/tinyssh/sc25519.c67
-rw-r--r--lib/Utils.Cryptography/monocypher/vendor/tests/externals/tinyssh/sc25519.h7
-rw-r--r--lib/Utils.Cryptography/monocypher/vendor/tests/externals/tinyssh/uint32_pack.c11
-rw-r--r--lib/Utils.Cryptography/monocypher/vendor/tests/externals/tinyssh/uint32_pack.h8
-rw-r--r--lib/Utils.Cryptography/monocypher/vendor/tests/externals/tinyssh/uint32_unpack.c13
-rw-r--r--lib/Utils.Cryptography/monocypher/vendor/tests/externals/tinyssh/uint32_unpack.h8
-rw-r--r--lib/Utils.Cryptography/monocypher/vendor/tests/externals/tinyssh/verify.c10
-rw-r--r--lib/Utils.Cryptography/monocypher/vendor/tests/externals/tinyssh/verify.h6
-rw-r--r--lib/Utils.Cryptography/monocypher/vendor/tests/externals/tweetnacl/AUTHORS.md20
-rw-r--r--lib/Utils.Cryptography/monocypher/vendor/tests/externals/tweetnacl/tweetnacl.c809
-rw-r--r--lib/Utils.Cryptography/monocypher/vendor/tests/externals/tweetnacl/tweetnacl.h272
-rw-r--r--lib/Utils.Cryptography/monocypher/vendor/tests/formal-analysis.sh66
-rw-r--r--lib/Utils.Cryptography/monocypher/vendor/tests/frama-c.sh61
-rw-r--r--lib/Utils.Cryptography/monocypher/vendor/tests/gen/aead_8439.c83
-rw-r--r--lib/Utils.Cryptography/monocypher/vendor/tests/gen/aead_ietf.c83
-rw-r--r--lib/Utils.Cryptography/monocypher/vendor/tests/gen/argon2.c99
-rw-r--r--lib/Utils.Cryptography/monocypher/vendor/tests/gen/blake2b.c83
-rw-r--r--lib/Utils.Cryptography/monocypher/vendor/tests/gen/chacha20.c82
-rw-r--r--lib/Utils.Cryptography/monocypher/vendor/tests/gen/edDSA.c74
-rw-r--r--lib/Utils.Cryptography/monocypher/vendor/tests/gen/edDSA_pk.c76
-rw-r--r--lib/Utils.Cryptography/monocypher/vendor/tests/gen/ed_25519.c75
-rw-r--r--lib/Utils.Cryptography/monocypher/vendor/tests/gen/ed_25519_pk.c77
-rw-r--r--lib/Utils.Cryptography/monocypher/vendor/tests/gen/elligator-direct.py84
-rw-r--r--lib/Utils.Cryptography/monocypher/vendor/tests/gen/elligator-inverse.py128
-rw-r--r--lib/Utils.Cryptography/monocypher/vendor/tests/gen/elligator.py370
-rw-r--r--lib/Utils.Cryptography/monocypher/vendor/tests/gen/elligator_scalarmult.py230
-rw-r--r--lib/Utils.Cryptography/monocypher/vendor/tests/gen/hchacha20.c73
-rw-r--r--lib/Utils.Cryptography/monocypher/vendor/tests/gen/ietf_chacha20.c77
-rw-r--r--lib/Utils.Cryptography/monocypher/vendor/tests/gen/makefile150
-rw-r--r--lib/Utils.Cryptography/monocypher/vendor/tests/gen/poly1305.c74
-rw-r--r--lib/Utils.Cryptography/monocypher/vendor/tests/gen/sha512.c74
-rw-r--r--lib/Utils.Cryptography/monocypher/vendor/tests/gen/sha512_hkdf.py109
-rw-r--r--lib/Utils.Cryptography/monocypher/vendor/tests/gen/sha512_hmac.c79
-rw-r--r--lib/Utils.Cryptography/monocypher/vendor/tests/gen/utils.c100
-rw-r--r--lib/Utils.Cryptography/monocypher/vendor/tests/gen/utils.h78
-rw-r--r--lib/Utils.Cryptography/monocypher/vendor/tests/gen/vector_to_header.c122
-rw-r--r--lib/Utils.Cryptography/monocypher/vendor/tests/gen/vectors/argon276
-rw-r--r--lib/Utils.Cryptography/monocypher/vendor/tests/gen/vectors/blake2b1028
-rw-r--r--lib/Utils.Cryptography/monocypher/vendor/tests/gen/vectors/chacha2036
-rw-r--r--lib/Utils.Cryptography/monocypher/vendor/tests/gen/vectors/ed_25519_check1981
-rw-r--r--lib/Utils.Cryptography/monocypher/vendor/tests/gen/vectors/ed_25519ph11
-rw-r--r--lib/Utils.Cryptography/monocypher/vendor/tests/gen/vectors/elligator_dir115
-rw-r--r--lib/Utils.Cryptography/monocypher/vendor/tests/gen/vectors/elligator_inv22
-rw-r--r--lib/Utils.Cryptography/monocypher/vendor/tests/gen/vectors/poly1305105
-rw-r--r--lib/Utils.Cryptography/monocypher/vendor/tests/gen/vectors/sha512_hmac155
-rw-r--r--lib/Utils.Cryptography/monocypher/vendor/tests/gen/vectors/x255193168
-rw-r--r--lib/Utils.Cryptography/monocypher/vendor/tests/gen/x25519.c83
-rw-r--r--lib/Utils.Cryptography/monocypher/vendor/tests/gen/x25519_pk.c79
-rw-r--r--lib/Utils.Cryptography/monocypher/vendor/tests/gen/xchacha20.c82
-rw-r--r--lib/Utils.Cryptography/monocypher/vendor/tests/speed/README.md31
-rw-r--r--lib/Utils.Cryptography/monocypher/vendor/tests/speed/libhydrogen.pc12
-rw-r--r--lib/Utils.Cryptography/monocypher/vendor/tests/speed/makefile208
-rw-r--r--lib/Utils.Cryptography/monocypher/vendor/tests/speed/speed-c25519.c123
-rw-r--r--lib/Utils.Cryptography/monocypher/vendor/tests/speed/speed-donna.c92
-rw-r--r--lib/Utils.Cryptography/monocypher/vendor/tests/speed/speed-hydrogen.c129
-rw-r--r--lib/Utils.Cryptography/monocypher/vendor/tests/speed/speed-sodium.c191
-rw-r--r--lib/Utils.Cryptography/monocypher/vendor/tests/speed/speed-tinyssh.c159
-rw-r--r--lib/Utils.Cryptography/monocypher/vendor/tests/speed/speed-tweetnacl.c169
-rw-r--r--lib/Utils.Cryptography/monocypher/vendor/tests/speed/speed.c270
-rw-r--r--lib/Utils.Cryptography/monocypher/vendor/tests/speed/speed.h105
-rw-r--r--lib/Utils.Cryptography/monocypher/vendor/tests/test.c1252
-rw-r--r--lib/Utils.Cryptography/monocypher/vendor/tests/test.sh69
-rw-r--r--lib/Utils.Cryptography/monocypher/vendor/tests/tis-ci-gen-config.sh114
-rw-r--r--lib/Utils.Cryptography/monocypher/vendor/tests/tis-ci-vectors.h532
-rw-r--r--lib/Utils.Cryptography/monocypher/vendor/tests/tis-ci.c474
-rw-r--r--lib/Utils.Cryptography/monocypher/vendor/tests/utils.c176
-rw-r--r--lib/Utils.Cryptography/monocypher/vendor/tests/utils.h107
-rw-r--r--lib/Utils.Cryptography/monocypher/vnlib_monocypher.c119
-rw-r--r--lib/Utils.Cryptography/monocypher/vnlib_monocypher.h24
-rw-r--r--lib/Utils.Cryptography/monocypher/vnlib_monocypher.vcxitems28
174 files changed, 33529 insertions, 0 deletions
diff --git a/lib/Utils.Cryptography/monocypher/CMakeLists.txt b/lib/Utils.Cryptography/monocypher/CMakeLists.txt
new file mode 100644
index 0000000..9b17ea7
--- /dev/null
+++ b/lib/Utils.Cryptography/monocypher/CMakeLists.txt
@@ -0,0 +1,105 @@
+cmake_minimum_required(VERSION 3.0)
+
+project(vnlib_monocypher C)
+
+#export header files to the main project
+file(GLOB HEADERS *.h)
+list(APPEND HEADERS vendor/src/monocypher.h)
+
+#Add indepednent source files to the project
+set(VNLIB_MONOCYPHER_SOURCES
+ "vnlib_monocypher.c"
+ "argon2.c"
+ "blake2b.c"
+ "vendor/src/monocypher.c"
+)
+
+#add monocypher includes, there will only be one library
+include_directories(vendor/src)
+
+
+#create my shared library
+add_library(${CMAKE_PROJECT_NAME} SHARED ${VNLIB_MONOCYPHER_SOURCES} ${HEADERS})
+#also create static library
+add_library(${CMAKE_PROJECT_NAME}_static STATIC ${VNLIB_MONOCYPHER_SOURCES} ${HEADERS})
+
+#if on unix lib will be appended, so we can adjust
+if(UNIX)
+ set_target_properties(${CMAKE_PROJECT_NAME} ${CMAKE_PROJECT_NAME}_static PROPERTIES OUTPUT_NAME _vnmonocypher)
+endif()
+
+#Setup the compiler options
+set(CMAKE_C_STANDARD 90)
+set(CMAKE_C_STANDARD_REQUIRED ON)
+
+#enable position independent code (for shared libraries with exports)
+set(CMAKE_POSITION_INDEPENDENT_CODE ON)
+
+message(STATUS "Build type is '${CMAKE_BUILD_TYPE}'")
+
+#if debug
+add_compile_definitions($<$<CONFIG:Debug>:DEBUG>)
+
+
+#setup flags for windows compilation
+if(MSVC)
+
+ #global windows cl flags
+ add_compile_options(
+ /Qspectre
+ /sdl
+ /TC
+ /GS
+ /machine:x64
+
+ $<$<CONFIG:Debug>:/FC>
+ $<$<CONFIG:Debug>:/showIncludes>
+ )
+
+ #only target our project
+ target_compile_options(
+ ${CMAKE_PROJECT_NAME}
+ PRIVATE
+
+ #disable warnings for struct padding and spectre mitigation wuen WX is enabled
+ $<$<CONFIG:Debug>:/wd5045>
+ $<$<CONFIG:Debug>:/wd4820>
+ $<$<CONFIG:Debug>:/wd4574>
+
+ #for debug configs
+ $<$<CONFIG:Debug>:/options:strict>
+ #disable warnings for struct padding and spectre mitigation wuen WX is enabled
+ $<$<CONFIG:Debug>:/Wall>
+ $<$<CONFIG:Debug>:/WX> #warnings as errors (only for our project)
+ $<$<CONFIG:Debug>:/Zi>
+ $<$<CONFIG:Debug>:/Zo>
+ )
+
+ #set build macros
+ add_compile_definitions(
+ $<$<CONFIG:DEBUG>:DEBUG>
+ $<$<CONFIG:RELEASE>:RELEASE>
+ )
+
+#configure gcc flags
+elseif(CMAKE_COMPILER_IS_GNUCC)
+
+ add_compile_options(
+ -Wextra
+ -fstack-protector
+
+ $<$<CONFIG:Debug>:-g>
+ $<$<CONFIG:Debug>:-Og>
+ $<$<CONFIG:Debug>:-Wall>
+ $<$<CONFIG:Debug>:-Werror>
+ )
+
+ #only target our project
+ target_compile_options(
+ ${CMAKE_PROJECT_NAME}
+ PRIVATE
+ $<$<CONFIG:Debug>:-Wall>
+ $<$<CONFIG:Debug>:-pedantic>
+ )
+
+endif() \ No newline at end of file
diff --git a/lib/Utils.Cryptography/monocypher/LICENSE b/lib/Utils.Cryptography/monocypher/LICENSE
new file mode 100644
index 0000000..ce09686
--- /dev/null
+++ b/lib/Utils.Cryptography/monocypher/LICENSE
@@ -0,0 +1,293 @@
+Copyright (c) 2023 Vaughn Nugent
+
+Contact information
+ Name: Vaughn Nugent
+ Email: vnpublic[at]proton.me
+ Website: https://www.vaughnnugent.com
+
+The software in this repository is licensed under the GNU GPL version 2.0 (or any later version).
+
+SPDX-License-Identifier: GPL-2.0-or-later
+
+License-Text:
+
+GNU GENERAL PUBLIC LICENSE
+ Version 2, June 1991
+
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+ Preamble
+
+ The licenses for most software are designed to take away your
+freedom to share and change it. By contrast, the GNU General Public
+License is intended to guarantee your freedom to share and change free
+software--to make sure the software is free for all its users. This
+General Public License applies to most of the Free Software
+Foundation's software and to any other program whose authors commit to
+using it. (Some other Free Software Foundation software is covered by
+the GNU Lesser General Public License instead.) You can apply it to
+your programs, too.
+
+ When we speak of free software, we are referring to freedom, not
+price. Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+this service if you wish), that you receive source code or can get it
+if you want it, that you can change the software or use pieces of it
+in new free programs; and that you know you can do these things.
+
+ To protect your rights, we need to make restrictions that forbid
+anyone to deny you these rights or to ask you to surrender the rights.
+These restrictions translate to certain responsibilities for you if you
+distribute copies of the software, or if you modify it.
+
+ For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must give the recipients all the rights that
+you have. You must make sure that they, too, receive or can get the
+source code. And you must show them these terms so they know their
+rights.
+
+ We protect your rights with two steps: (1) copyright the software, and
+(2) offer you this license which gives you legal permission to copy,
+distribute and/or modify the software.
+
+ Also, for each author's protection and ours, we want to make certain
+that everyone understands that there is no warranty for this free
+software. If the software is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original, so
+that any problems introduced by others will not reflect on the original
+authors' reputations.
+
+ Finally, any free program is threatened constantly by software
+patents. We wish to avoid the danger that redistributors of a free
+program will individually obtain patent licenses, in effect making the
+program proprietary. To prevent this, we have made it clear that any
+patent must be licensed for everyone's free use or not licensed at all.
+
+ The precise terms and conditions for copying, distribution and
+modification follow.
+
+ GNU GENERAL PUBLIC LICENSE
+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+ 0. This License applies to any program or other work which contains
+a notice placed by the copyright holder saying it may be distributed
+under the terms of this General Public License. The "Program", below,
+refers to any such program or work, and a "work based on the Program"
+means either the Program or any derivative work under copyright law:
+that is to say, a work containing the Program or a portion of it,
+either verbatim or with modifications and/or translated into another
+language. (Hereinafter, translation is included without limitation in
+the term "modification".) Each licensee is addressed as "you".
+
+Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope. The act of
+running the Program is not restricted, and the output from the Program
+is covered only if its contents constitute a work based on the
+Program (independent of having been made by running the Program).
+Whether that is true depends on what the Program does.
+
+ 1. You may copy and distribute verbatim copies of the Program's
+source code as you receive it, in any medium, provided that you
+conspicuously and appropriately publish on each copy an appropriate
+copyright notice and disclaimer of warranty; keep intact all the
+notices that refer to this License and to the absence of any warranty;
+and give any other recipients of the Program a copy of this License
+along with the Program.
+
+You may charge a fee for the physical act of transferring a copy, and
+you may at your option offer warranty protection in exchange for a fee.
+
+ 2. You may modify your copy or copies of the Program or any portion
+of it, thus forming a work based on the Program, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+ a) You must cause the modified files to carry prominent notices
+ stating that you changed the files and the date of any change.
+
+ b) You must cause any work that you distribute or publish, that in
+ whole or in part contains or is derived from the Program or any
+ part thereof, to be licensed as a whole at no charge to all third
+ parties under the terms of this License.
+
+ c) If the modified program normally reads commands interactively
+ when run, you must cause it, when started running for such
+ interactive use in the most ordinary way, to print or display an
+ announcement including an appropriate copyright notice and a
+ notice that there is no warranty (or else, saying that you provide
+ a warranty) and that users may redistribute the program under
+ these conditions, and telling the user how to view a copy of this
+ License. (Exception: if the Program itself is interactive but
+ does not normally print such an announcement, your work based on
+ the Program is not required to print an announcement.)
+
+These requirements apply to the modified work as a whole. If
+identifiable sections of that work are not derived from the Program,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works. But when you
+distribute the same sections as part of a whole which is a work based
+on the Program, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Program.
+
+In addition, mere aggregation of another work not based on the Program
+with the Program (or with a work based on the Program) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+ 3. You may copy and distribute the Program (or a work based on it,
+under Section 2) in object code or executable form under the terms of
+Sections 1 and 2 above provided that you also do one of the following:
+
+ a) Accompany it with the complete corresponding machine-readable
+ source code, which must be distributed under the terms of Sections
+ 1 and 2 above on a medium customarily used for software interchange; or,
+
+ b) Accompany it with a written offer, valid for at least three
+ years, to give any third party, for a charge no more than your
+ cost of physically performing source distribution, a complete
+ machine-readable copy of the corresponding source code, to be
+ distributed under the terms of Sections 1 and 2 above on a medium
+ customarily used for software interchange; or,
+
+ c) Accompany it with the information you received as to the offer
+ to distribute corresponding source code. (This alternative is
+ allowed only for noncommercial distribution and only if you
+ received the program in object code or executable form with such
+ an offer, in accord with Subsection b above.)
+
+The source code for a work means the preferred form of the work for
+making modifications to it. For an executable work, complete source
+code means all the source code for all modules it contains, plus any
+associated interface definition files, plus the scripts used to
+control compilation and installation of the executable. However, as a
+special exception, the source code distributed need not include
+anything that is normally distributed (in either source or binary
+form) with the major components (compiler, kernel, and so on) of the
+operating system on which the executable runs, unless that component
+itself accompanies the executable.
+
+If distribution of executable or object code is made by offering
+access to copy from a designated place, then offering equivalent
+access to copy the source code from the same place counts as
+distribution of the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+ 4. You may not copy, modify, sublicense, or distribute the Program
+except as expressly provided under this License. Any attempt
+otherwise to copy, modify, sublicense or distribute the Program is
+void, and will automatically terminate your rights under this License.
+However, parties who have received copies, or rights, from you under
+this License will not have their licenses terminated so long as such
+parties remain in full compliance.
+
+ 5. You are not required to accept this License, since you have not
+signed it. However, nothing else grants you permission to modify or
+distribute the Program or its derivative works. These actions are
+prohibited by law if you do not accept this License. Therefore, by
+modifying or distributing the Program (or any work based on the
+Program), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Program or works based on it.
+
+ 6. Each time you redistribute the Program (or any work based on the
+Program), the recipient automatically receives a license from the
+original licensor to copy, distribute or modify the Program subject to
+these terms and conditions. You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties to
+this License.
+
+ 7. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Program at all. For example, if a patent
+license would not permit royalty-free redistribution of the Program by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Program.
+
+If any portion of this section is held invalid or unenforceable under
+any particular circumstance, the balance of the section is intended to
+apply and the section as a whole is intended to apply in other
+circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system, which is
+implemented by public license practices. Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+ 8. If the distribution and/or use of the Program is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Program under this License
+may add an explicit geographical distribution limitation excluding
+those countries, so that distribution is permitted only in or among
+countries not thus excluded. In such case, this License incorporates
+the limitation as if written in the body of this License.
+
+ 9. The Free Software Foundation may publish revised and/or new versions
+of the General Public License from time to time. Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+Each version is given a distinguishing version number. If the Program
+specifies a version number of this License which applies to it and "any
+later version", you have the option of following the terms and conditions
+either of that version or of any later version published by the Free
+Software Foundation. If the Program does not specify a version number of
+this License, you may choose any version ever published by the Free Software
+Foundation.
+
+ 10. If you wish to incorporate parts of the Program into other free
+programs whose distribution conditions are different, write to the author
+to ask for permission. For software which is copyrighted by the Free
+Software Foundation, write to the Free Software Foundation; we sometimes
+make exceptions for this. Our decision will be guided by the two goals
+of preserving the free status of all derivatives of our free software and
+of promoting the sharing and reuse of software generally.
+
+ NO WARRANTY
+
+ 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
+FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
+OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
+PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
+OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
+TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
+PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
+REPAIR OR CORRECTION.
+
+ 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
+REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
+INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
+OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
+TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
+YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
+PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGES.
+
+ END OF TERMS AND CONDITIONS \ No newline at end of file
diff --git a/lib/Utils.Cryptography/monocypher/Taskfile.yaml b/lib/Utils.Cryptography/monocypher/Taskfile.yaml
new file mode 100644
index 0000000..64a4461
--- /dev/null
+++ b/lib/Utils.Cryptography/monocypher/Taskfile.yaml
@@ -0,0 +1,105 @@
+# https://taskfile.dev
+
+#Called by the vnbuild system to produce builds for my website
+#https://www.vaughnnugent.com/resources/software
+
+#This taskfile is called in this directory and is specific to the vnlib_monocypher project
+#that handles the MSBuild outside of the solution file
+
+version: '3'
+
+vars:
+ MS_ARGS: '/p:Platform=x64 /p:RunAnalyzersDuringBuild=false /p:BuildInParallel=true /p:MultiProcessorCompilation=true'
+ PROJECT_NAME: 'vnlib_monocypher'
+ MODULE_NAME: 'vnlib.core'
+
+tasks:
+
+ default:
+ desc: "Builds the entire project from source code without using the VNBuild build system for target machines"
+ cmds:
+ #build with defaults
+ - task: build
+ - cmd: echo "Your vnlib_monocypher dll file can be found in '{{.USER_WORKING_DIR}}/build'"
+ silent: true
+
+ build:
+ cmds:
+ #init cmake build
+ - cmake -B./build
+
+ #build the monocypher library in debug mode first
+ - task: build-monocypher-win
+ - task: build-monocypher-gnumake
+
+ #build using msbuild for monocypher libraries for debug and release modes
+ build-monocypher-win:
+ platforms: ['windows']
+ internal: true
+ cmds:
+ #build solution in debug mode
+ - cd build && msbuild {{.PROJECT_NAME}}.sln /p:Configuration=debug {{.BUILD_FLAGS}} {{.MS_ARGS}}
+ #build in release
+ - cd build && msbuild {{.PROJECT_NAME}}.sln /p:Configuration=release {{.BUILD_FLAGS}} {{.MS_ARGS}}
+
+ #build using gnu make
+ build-monocypher-gnumake:
+ platforms: ['linux']
+ internal: true
+ cmds:
+ #build project with make
+ - cd build && make
+
+ postbuild_success:
+ vars:
+ #required files to include in tar
+ TAR_FILES: "license.txt readme.txt"
+
+ cmds:
+ #make bin dir
+ - cmd: powershell -Command "New-Item -Type Directory -Force -Path './bin'"
+ ignore_error: true
+
+ #get licenses for debug
+ - task: licenses
+ vars:
+ TARGET: './build/Debug'
+
+ - task: licenses
+ vars:
+ TARGET: './build/Release'
+
+
+ #static debug lib
+ - cd build/Debug && tar -czf '../../bin/win-x64-debug-{{.PROJECT_NAME}}-static.tgz' {{.PROJECT_NAME}}_static.lib {{.TAR_FILES}} {{.PROJECT_NAME}}_static.pdb
+ #dynamic debug lib
+ - cd build/Debug && tar -czf '../../bin/win-x64-debug-{{.PROJECT_NAME}}.tgz' {{.PROJECT_NAME}}.dll {{.TAR_FILES}} {{.PROJECT_NAME}}.pdb
+
+ #release static lib
+ - cd build/Release && tar -czf '../../bin/win-x64-release-{{.PROJECT_NAME}}-static.tgz' {{.PROJECT_NAME}}_static.lib {{.TAR_FILES}}
+ #release dll
+ - cd build/Release && tar -czf '../../bin/win-x64-release-{{.PROJECT_NAME}}.tgz' {{.PROJECT_NAME}}.dll {{.TAR_FILES}}
+
+ #source code
+ - task: pack_source
+
+ licenses:
+ cmds:
+ #add monocypher license to binary output (wrong on purpose see source code)
+ - powershell -Command "Copy-Item -Path vendor/LICENCE.md -Destination '{{.TARGET}}/license.md'"
+ #add my license file
+ - powershell -Command "Copy-Item -Path license -Destination '{{.TARGET}}/license.txt'"
+ #add readme file
+ - powershell -Command "Copy-Item -Path build.readme.txt -Destination '{{.TARGET}}/readme.txt'"
+
+ pack_source:
+ dir: '{{.USER_WORKING_DIR}}'
+ cmds:
+ #pack monocypher source code and create the archive
+ - powershell -Command "tar --exclude build/* --exclude bin/* --exclude .git/* -cvf 'bin/src.tar' ."
+
+ clean:
+ ignore_error: true
+ cmds:
+ - cmd: powershell -Command "Remove-Item -Recurse './bin'"
+ - cmd: powershell -Command "Remove-Item -Recurse './build'" \ No newline at end of file
diff --git a/lib/Utils.Cryptography/monocypher/argon2.c b/lib/Utils.Cryptography/monocypher/argon2.c
new file mode 100644
index 0000000..9b13ce0
--- /dev/null
+++ b/lib/Utils.Cryptography/monocypher/argon2.c
@@ -0,0 +1,102 @@
+/*
+* Copyright (c) 2023 Vaughn Nugent
+*
+* vnlib_monocypher is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published
+* by the Free Software Foundation, either version 2 of the License,
+* or (at your option) any later version.
+*
+* vnlib_monocypher is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+* General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with vnlib_monocypher. If not, see http://www.gnu.org/licenses/.
+*/
+
+#include "argon2.h"
+#include <monocypher.h>
+
+VNLIB_EXPORT uint32_t VNLIB_CC Argon2CalcWorkAreaSize(const argon2Ctx* context)
+{
+ return context->m_cost * 1024;
+}
+
+/*
+* The purpose of this function is to remap the Argon2 context/function call
+* interface to the Monocypher library version. Also performing some basic
+* input validation that also matches the Argon2 library.
+*/
+
+VNLIB_EXPORT argon2_error_codes VNLIB_CC Argon2ComputeHash(const argon2Ctx* context, void* workArea)
+{
+ crypto_argon2_config config;
+ crypto_argon2_inputs inputs;
+ crypto_argon2_extras extras;
+
+ if (!context || !workArea)
+ {
+ return ERR_INVALID_PTR;
+ }
+
+ config.algorithm = context->version;
+ config.nb_blocks = context->m_cost;
+ config.nb_passes = context->t_cost;
+ config.nb_lanes = context->threads;
+
+ inputs.pass_size = context->pwdlen;
+ inputs.pass = context->pwd;
+
+ inputs.salt_size = context->saltlen;
+ inputs.salt = context->salt;
+
+ /* must specify a password input */
+ if (inputs.pass_size < 1)
+ {
+ return ARGON2_PWD_TOO_SHORT;
+ }
+
+ if (!inputs.pass)
+ {
+ return ARGON2_PWD_PTR_MISMATCH;
+ }
+
+ if (inputs.salt_size < 1)
+ {
+ return ARGON2_SALT_TOO_SHORT;
+ }
+
+ /* Verify salt pointer 1is not invalid */
+ if (!inputs.salt)
+ {
+ return ARGON2_SALT_PTR_MISMATCH;
+ }
+
+ extras.ad = context->ad;
+ extras.ad_size = context->adlen;
+
+ extras.key = context->secret;
+ extras.key_size = context->secretlen;
+
+ //If key is set, verify a valid pointer
+ if (extras.key_size > 0 && !extras.key)
+ {
+ return ARGON2_SECRET_PTR_MISMATCH;
+ }
+
+ if (context->outlen < 1)
+ {
+ return ARGON2_OUTPUT_TOO_SHORT;
+ }
+
+ if (!context->out)
+ {
+ return ARGON2_OUTPUT_PTR_NULL;
+ }
+
+ /* invoke lib function */
+ crypto_argon2(context->out, context->outlen, workArea, config, inputs, extras);
+
+ return ARGON2_OK;
+} \ No newline at end of file
diff --git a/lib/Utils.Cryptography/monocypher/argon2.h b/lib/Utils.Cryptography/monocypher/argon2.h
new file mode 100644
index 0000000..700e582
--- /dev/null
+++ b/lib/Utils.Cryptography/monocypher/argon2.h
@@ -0,0 +1,135 @@
+/*
+* Copyright (c) 2023 Vaughn Nugent
+*
+* vnlib_monocypher is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published
+* by the Free Software Foundation, either version 2 of the License,
+* or (at your option) any later version.
+*
+* vnlib_monocypher is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+* General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with vnlib_monocypher. If not, see http://www.gnu.org/licenses/.
+*/
+
+
+#ifndef VN_MONOCYPHER_ARGON2_H
+#define VN_MONOCYPHER_ARGON2_H
+
+#include <stdint.h>
+#include "util.h"
+
+/*
+ The following types are 1:1 with the Argon2 reference library,
+ this allows for a common api interface between the two libraries for
+ dynamic linking
+*/
+
+typedef enum Argon2Type
+{
+ Argon2_d = 0,
+ Argon2_i = 1,
+ Argon2_id = 2
+
+} Argon2Type;
+
+/* 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;
+
+typedef struct Argon2_Context {
+
+ uint8_t* out; /* output array */
+ const uint32_t outlen; /* digest length */
+
+ const uint8_t* pwd; /* password array */
+ const uint32_t pwdlen; /* password length */
+
+ const uint8_t* salt; /* salt array */
+ const uint32_t saltlen; /* salt length */
+
+ const uint8_t* secret; /* key array */
+ const uint32_t secretlen; /* key length */
+
+ const uint8_t* ad; /* associated data array */
+ const uint32_t adlen; /* associated data length */
+
+ const uint32_t t_cost; /* number of passes */
+ const uint32_t m_cost; /* amount of memory requested (KB) */
+ const uint32_t lanes; /* number of lanes */
+ const uint32_t threads; /* maximum number of threads */
+
+ const Argon2Type version; /* version number */
+
+ const void* allocate_cbk; /* pointer to memory allocator */
+ const void* free_cbk; /* pointer to memory deallocator */
+
+ const uint32_t flags; /* array of bool options */
+} argon2Ctx;
+
+
+VNLIB_EXPORT uint32_t VNLIB_CC Argon2CalcWorkAreaSize(const argon2Ctx* context);
+
+VNLIB_EXPORT argon2_error_codes VNLIB_CC Argon2ComputeHash(const argon2Ctx* context, void* workArea);
+
+#endif /* VN_MONOCYPHER_ARGON2_H */ \ No newline at end of file
diff --git a/lib/Utils.Cryptography/monocypher/blake2b.c b/lib/Utils.Cryptography/monocypher/blake2b.c
new file mode 100644
index 0000000..3d9a1d1
--- /dev/null
+++ b/lib/Utils.Cryptography/monocypher/blake2b.c
@@ -0,0 +1,90 @@
+/*
+* Copyright (c) 2023 Vaughn Nugent
+*
+* vnlib_monocypher is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published
+* by the Free Software Foundation, either version 2 of the License,
+* or (at your option) any later version.
+*
+* vnlib_monocypher is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+* General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with vnlib_monocypher. If not, see http://www.gnu.org/licenses/.
+*/
+
+#include <stdlib.h>
+#include <monocypher.h>
+#include "blake2b.h"
+
+VNLIB_EXPORT uint32_t VNLIB_CC Blake2GetContextSize(void)
+{
+ return sizeof(crypto_blake2b_ctx);
+}
+
+VNLIB_EXPORT int32_t VNLIB_CC Blake2Init(void* context, uint32_t hashlen, const void* key, uint32_t keylen)
+{
+ crypto_blake2b_ctx* ctx;
+ ctx = (crypto_blake2b_ctx*)context;
+
+ VALIDATE_PTR(ctx);
+
+ /* validate key pointer if set */
+ if (keylen > 0 && !key)
+ {
+ return ERR_KEY_PTR_INVALID;
+ }
+
+ if (keylen > MC_MAX_KEY_SIZE)
+ {
+ return ERR_KEY_LEN_INVALID;
+ }
+
+ /* validate hash length */
+ if (hashlen > MC_MAX_HASH_SIZE)
+ {
+ return ERR_HASH_LEN_INVALID;
+ }
+
+ /* initialize context, non-keyed just calls the keyed funciton */
+ crypto_blake2b_keyed_init(ctx, hashlen, key, keylen);
+
+ return BLAKE2B_RESULT_SUCCESS;
+}
+
+VNLIB_EXPORT int32_t VNLIB_CC Blake2Update(void* context, const void* data, uint32_t datalen)
+{
+ crypto_blake2b_ctx* ctx;
+ ctx = (crypto_blake2b_ctx*)context;
+ VALIDATE_PTR(ctx);
+ VALIDATE_PTR(data);
+
+ crypto_blake2b_update(ctx, data, datalen);
+ return BLAKE2B_RESULT_SUCCESS;
+}
+
+VNLIB_EXPORT int32_t VNLIB_CC Blake2Final(void* context, void* hash, uint32_t hashlen)
+{
+ crypto_blake2b_ctx* ctx;
+ ctx = (crypto_blake2b_ctx*)context;
+ VALIDATE_PTR(ctx);
+ VALIDATE_PTR(hash);
+
+ /* validate hash length */
+ if (hashlen != ctx->hash_size)
+ {
+ return ERR_HASH_LEN_INVALID;
+ }
+ crypto_blake2b_final(ctx, hash);
+ return BLAKE2B_RESULT_SUCCESS;
+}
+
+VNLIB_EXPORT int32_t VNLIB_CC Blake2GetHashSize(void* context)
+{
+ crypto_blake2b_ctx* ctx;
+ ctx = (crypto_blake2b_ctx*)context;
+ VALIDATE_PTR(ctx);
+ return (int32_t)ctx->hash_size;
+}
diff --git a/lib/Utils.Cryptography/monocypher/blake2b.h b/lib/Utils.Cryptography/monocypher/blake2b.h
new file mode 100644
index 0000000..4167aca
--- /dev/null
+++ b/lib/Utils.Cryptography/monocypher/blake2b.h
@@ -0,0 +1,43 @@
+/*
+* Copyright (c) 2023 Vaughn Nugent
+*
+* vnlib_monocypher is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published
+* by the Free Software Foundation, either version 2 of the License,
+* or (at your option) any later version.
+*
+* vnlib_monocypher is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+* General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with vnlib_monocypher. If not, see http://www.gnu.org/licenses/.
+*/
+
+#pragma once
+#ifndef VN_MONOCYPHER_BLAKE2_H
+
+#include <stdint.h>
+#include "util.h"
+
+#define ERR_HASH_LEN_INVALID -16
+#define ERR_KEY_LEN_INVALID -17
+#define ERR_KEY_PTR_INVALID -18
+
+#define MC_MAX_HASH_SIZE 64
+#define MC_MAX_KEY_SIZE 64
+
+#define BLAKE2B_RESULT_SUCCESS 0
+
+VNLIB_EXPORT uint32_t VNLIB_CC Blake2GetContextSize(void);
+
+VNLIB_EXPORT int32_t VNLIB_CC Blake2Init(void* context, uint32_t hashlen, const void* key, uint32_t keylen);
+
+VNLIB_EXPORT int32_t VNLIB_CC Blake2Update(void* context, const void* data, uint32_t datalen);
+
+VNLIB_EXPORT int32_t VNLIB_CC Blake2Final(void* context, void* hash, uint32_t hashlen);
+
+VNLIB_EXPORT int32_t VNLIB_CC Blake2GetHashSize(void* context);
+
+#endif
diff --git a/lib/Utils.Cryptography/monocypher/build.readme.txt b/lib/Utils.Cryptography/monocypher/build.readme.txt
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/lib/Utils.Cryptography/monocypher/build.readme.txt
diff --git a/lib/Utils.Cryptography/monocypher/package.json b/lib/Utils.Cryptography/monocypher/package.json
new file mode 100644
index 0000000..2ce626d
--- /dev/null
+++ b/lib/Utils.Cryptography/monocypher/package.json
@@ -0,0 +1,10 @@
+{
+ "name": "vnlib_monocypher",
+ "version": "0.1.0",
+ "output_dir": "bin",
+ "author": "Vaughn Nugent",
+ "description": "Integrates the MonoCypher native library into a wrapper utility library for usage in VNLib.Hashing.Portable for Blake2, Argon2 and more coming",
+ "copyright": "Copyright \u00A9 2023 Vaughn Nugent",
+ "company": "Vaughn Nugent",
+ "repository": "https://github.com/VnUgE/VNLib.Core/tree/main/lib/Utils.Cryptography/monocypher"
+} \ No newline at end of file
diff --git a/lib/Utils.Cryptography/monocypher/readme.md b/lib/Utils.Cryptography/monocypher/readme.md
new file mode 100644
index 0000000..940c95f
--- /dev/null
+++ b/lib/Utils.Cryptography/monocypher/readme.md
@@ -0,0 +1,17 @@
+# VNLib.Utils.Cryptography
+Contains vendored packages that are (optionally)used with VNLib applications such as Argon2 and MonoCypher, as well as build files for compiling the projects cross-platform using CMake and Taskfile.dev.
+
+Pre-build Windows binaries are available on my website (link below).
+Source code blobs are also packaged and ready for building. See the docs link below for building instructions.
+
+## Builds
+Debug build w/ symbols & xml docs, release builds, NuGet packages, and individually packaged source code are available on my website (link below). All tar-gzip (.tgz) files will have an associated checksum and PGP signature of the desired download file.
+
+## Docs and Guides
+Documentation, specifications, and setup guides are available on my website.
+
+[Docs and Articles](https://www.vaughnnugent.com/resources/software/articles?tags=docs,_vnlib.utils.cryptography)
+[Builds and Source](https://www.vaughnnugent.com/resources/software/modules/VNLib.Core)
+
+## License
+Code is individually licensed. See the `LICENSE` file in each subdirectory for more information. \ No newline at end of file
diff --git a/lib/Utils.Cryptography/monocypher/util.h b/lib/Utils.Cryptography/monocypher/util.h
new file mode 100644
index 0000000..68b3e51
--- /dev/null
+++ b/lib/Utils.Cryptography/monocypher/util.h
@@ -0,0 +1,77 @@
+/*
+* Copyright (c) 2023 Vaughn Nugent
+*
+* vnlib_monocypher is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published
+* by the Free Software Foundation, either version 2 of the License,
+* or (at your option) any later version.
+*
+* vnlib_monocypher is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+* General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with vnlib_monocypher. If not, see http://www.gnu.org/licenses/.
+*/
+
+#pragma once
+#ifndef VN_MONOCYPHER_UTIL_H
+
+#if defined(__GNUC__)
+ #define inline __inline__
+ #define VNLIB_EXPORT __attribute__((visibility("default")))
+ #define VNLIB_CC
+#elif defined(_MSC_VER)
+ #define VNLIB_EXPORT __declspec(dllexport)
+ #define VNLIB_CC __cdecl
+#endif /* WIN32 */
+
+#ifdef USE_MEM_UTIL
+
+ /* Include stdlib for malloc */
+ #include <stdlib.h>
+
+ /* If a custom allocator is not defined, set macros for built-in function */
+ #ifndef CUSTOM_ALLOCATOR
+
+ /* malloc and friends fallback if not defined */
+ #define vnmalloc(size) malloc(size)
+ #define vncalloc(count, size) calloc(count, size)
+ #define vnrealloc(ptr, size) realloc(ptr, size)
+ #define vnfree(ptr) free(ptr)
+
+ #endif /* !CUSTOM_ALLOCATOR */
+
+ #ifdef WIN32
+
+ /* required for memove on windows */
+ #include <memory.h>
+
+ #define _memmove(dst, src, size) memmove_s(dst, size, src, size)
+ #else
+ /* use string.h posix on non-win platforms */
+ #include <string.h>
+
+ #define _memmove memmove
+ #endif /* WIN32 */
+
+#endif // USE_MEM_UTIL
+
+#ifndef _In_
+#define _In_
+#endif
+
+#define ERR_INVALID_PTR -1
+#define ERR_OUT_OF_MEMORY -2
+
+#define TRUE 1
+#define FALSE 0
+
+#ifndef NULL
+#define NULL 0
+#endif /* !NULL */
+
+#define VALIDATE_PTR(ptr) if (!ptr) return ERR_INVALID_PTR
+
+#endif /* !VN_MONOCYPHER_UTIL_H */ \ No newline at end of file
diff --git a/lib/Utils.Cryptography/monocypher/vendor/.editorconfig b/lib/Utils.Cryptography/monocypher/vendor/.editorconfig
new file mode 100644
index 0000000..b791d00
--- /dev/null
+++ b/lib/Utils.Cryptography/monocypher/vendor/.editorconfig
@@ -0,0 +1,16 @@
+# https://EditorConfig.org
+
+root = true
+
+# UNIX style line ending rulez
+# End all files with a single line ending OCD
+[*]
+end_of_line = lf
+insert_final_newline = true
+
+# Tabs for indentation for accessibility reasons.
+# Indent size of 4 because that's my preference.
+# Note: line lengths limits (80 columns) assume tabs are 4 columns wide.
+[*.{c,h}]
+indent_style = tab
+indent_size = 4
diff --git a/lib/Utils.Cryptography/monocypher/vendor/.gitignore b/lib/Utils.Cryptography/monocypher/vendor/.gitignore
new file mode 100644
index 0000000..2a1e6fe
--- /dev/null
+++ b/lib/Utils.Cryptography/monocypher/vendor/.gitignore
@@ -0,0 +1,29 @@
+*~
+*.o
+*.a
+*.so
+*.so.*
+*.out
+*.vec
+*.gch
+*.sav
+*.profraw
+*.profdata
+*.creator
+*.creator.*
+*.config
+*.cflags
+*.cxxflags
+*.files
+*.includes
+*.su
+*.su.*
+*.gen.*
+tests/formal-analysis/*
+tests/formal-analysis
+*.tar.gz
+monocypher-*/
+**/__pycache__/**
+doc/html/
+doc/man3/
+tests/vectors.h
diff --git a/lib/Utils.Cryptography/monocypher/vendor/AUTHORS.md b/lib/Utils.Cryptography/monocypher/vendor/AUTHORS.md
new file mode 100644
index 0000000..65e2c01
--- /dev/null
+++ b/lib/Utils.Cryptography/monocypher/vendor/AUTHORS.md
@@ -0,0 +1,63 @@
+Designers
+---------
+
+- **ChaCha20:** Daniel J. Bernstein.
+- **Poly1305:** Daniel J. Bernstein.
+- **BLAKE2:** Jean-Philippe Aumasson, Christian Winnerlein, Samuel Neves,
+ and Zooko Wilcox-O'Hearn.
+- **Argon2:** Alex Biryukov, Daniel Dinu, and Dmitry Khovratovich.
+- **X25519:** Daniel J. Bernstein.
+- **EdDSA:** Daniel J. Bernstein, Bo-Yin Yang, Niels Duif, Peter
+ Schwabe, and Tanja Lange.
+
+Implementors
+------------
+
+- **ChaCha20:** Loup Vaillant, implemented from spec.
+- **Poly1305:** Loup Vaillant, implemented from spec.
+- **BLAKE2b:** Loup Vaillant, implemented from spec.
+- **Argon2i:** Loup Vaillant, implemented from spec.
+- **X25519:** Daniel J. Bernstein, taken and packaged from SUPERCOP
+ ref10.
+- **EdDSA:** Loup Vaillant, with bits and pieces from SUPERCOP ref10.
+
+Test suite
+----------
+
+Designed and implemented by Loup Vaillant, using _libsodium_ (by many
+authors), and _ed25519-donna_ (by Andrew Moon —floodyberry).
+
+Manual
+------
+
+Loup Vaillant, Fabio Scotoni, and Michael Savage.
+
+- Loup Vaillant did a first draft.
+- Fabio Scotoni rewrote the manual into proper man pages (and
+ substantially changed it in the process).
+- Michael Savage did extensive editing and proofreading.
+
+Thanks
+------
+
+Fabio Scotoni provided much needed advice about testing, interface,
+packaging, and the general direction of the whole project. He also
+redesigned the monocypher.org style sheets.
+
+Mike Pechkin and André Maroneze found bugs in earlier versions of
+Monocypher.
+
+Andrew Moon clarified carry propagation in modular arithmetic, and
+provided advice and code that significantly simplified and improved
+Elligator2 mappings.
+
+Mike Hamburg explained comb algorithms, including the signed
+all-bits-set comb described in his 2012 paper, Fast and compact
+elliptic-curve cryptography. This made EdDSA signatures over twice as
+fast.
+
+Samuel Lucas found many typos in both the manual and the website.
+
+Jens Alfke added some #ifdefs that enabled Monocypher to compile into
+a C++ namespace, preventing symbol collisions with similarly-named
+functions in other crypto libraries.
diff --git a/lib/Utils.Cryptography/monocypher/vendor/CHANGELOG.md b/lib/Utils.Cryptography/monocypher/vendor/CHANGELOG.md
new file mode 100644
index 0000000..b109b2d
--- /dev/null
+++ b/lib/Utils.Cryptography/monocypher/vendor/CHANGELOG.md
@@ -0,0 +1,295 @@
+4.0.2
+-----
+2023/08/24
+
+- Fixed multiple-lanes Argon2.
+- Improved Poly1305 performance.
+- Improved Argon2 performance.
+- Makefiles no longer override standard environment variables.
+
+
+4.0.1
+-----
+2023/03/06
+
+- Fixed Ed25519 secret key size in function prototype.
+- Fixed soname (should have been changed in 4.0.0)
+- Added convenience sub-targets to makefile.
+- Briefly specified wire format of Elligator and incremental AEAD.
+
+
+4.0.0
+-----
+2023/02/20
+
+- Fixed unsafe signature API.
+- Simpler, more flexible low-level signature API.
+- Fully specified, consensus-friendly signatures.
+- Added Argon2d and Argon2id, support multiple lanes.
+- Added safe and fast streaming AEAD.
+- Added HKDF-SHA-512 and documented BLAKE2b KDF.
+- More consistent and memorable function names.
+- POSIX makefile.
+
+
+3.1.3
+-----
+2022/04/25
+
+- Fixed many typos in the documentation.
+- Fixed buffer overflow in speed benchmarks.
+- Fixed some MSVC warnings.
+- Fixed a minor violation of the Elligator2 reverse map specs.
+- Added `change-prefix.sh` to help changing the `crypto_` prefix.
+- Added the `MONOCYPHER_CPP_NAMESPACE` preprocessor definition to
+ support namespaces for C++.
+- Deprecated `crypto_key_exchange()`
+- Use GitHub actions to automate the regular test suite.
+
+
+3.1.2
+-----
+2020/12/27
+
+- Addressed issues from Cure53's audit:
+ - MON-01-001: Clarified which CSPRNG to use on Darwin.
+ - MON-01-002: Won't fix (nonce handling is a core design decision).
+ - MON-01-004: Compared with Kleshni's implementation.
+ - MON-01-005: Split a dedicated "advanced" folder in the manual.
+- Quality assurance for 2^255-19 arithmetic (elliptic curves):
+ - Documented carry propagation.
+ - Enforced slightly safer invariants.
+- Improved the speed of EdDSA signature generation.
+- Made the vectors.h header more compact and easier to modify.
+- TIS-CI integration.
+- Added speed benchmark for ed25519-donna.
+- Documented lengths limits of `crypto_ietf_chacha20()`
+
+
+3.1.1
+-----
+2020/06/15
+
+- Various documentation fixes.
+- Fixed various compiler warnings.
+- Fixed some integer overflows (16-bit platforms only).
+
+
+3.1.0
+-----
+2020/04/03
+
+- Added Elligator 2 mappings (hash to curve, curve to hash).
+- Added OPRF support (with scalar inversion).
+- Added Edwards25519 -> Curve25519 conversions.
+
+
+3.0.0
+-----
+2020/01/19
+
+- Deprecated the incremental AEAD interface.
+- Deprecated the incremental Chacha20, added a direct interface.
+- Added IETF Chacha20 (96-bit nonce), as described in RFC 8439.
+- Moved deprecated interfaces to a separate `src/deprecated` folder.
+- Removed the `ED25519_SHA512` preprocessor flag.
+- `crypto_x25519()` and `crypto_key_exchange()` now return `void`.
+- Added a custom hash interface to EdDSA. Several instances of EdDSA
+ can share the same binary.
+- Added optional support for HMAC SHA-512.
+- Moved SHA-512 operations to `src/optional/monocypher-ed25519.(h|c)`.
+- Optional support for Ed25519 no longer requires a preprocessor flag.
+ Add `src/optional/monocypher-ed25519.(h|c)` to your project instead.
+
+
+2.0.6
+-----
+2019/10/21
+
+- Added the `BLAKE2_NO_UNROLLING` preprocessor definition. Activating
+ it makes the binary about 5KB smaller and speeds up processing times
+ on many embedded processors.
+- Reduced the stack usage of signature verification by about
+ 40%. Signature verification now fits in smaller machines.
+- Fixed many implicit casts warnings.
+- Fixed the manual here and there.
+- Lots of small nitpicks.
+
+
+2.0.5
+-----
+2018/08/23
+
+- Faster EdDSA signatures and verification. Like, 4 times as fast.
+
+
+2.0.4
+-----
+2018/06/24
+
+- Corrected a critical vulnerability found by Mike Pechkin in EdDSA,
+ where crypto_check() was accepting invalid signatures. The current
+ fix removes a buggy optimisation, effectively halving the performance
+ of EdDSA.
+- The test suite no longer tries to allocate zero bytes (some platforms
+ fail such an allocation).
+
+2.0.3
+-----
+2018/06/16
+
+- Corrected undefined behaviour in BLAKE2b.
+- Improved the test suite (faster, better coverage).
+
+2.0.2
+-----
+2018/04/23
+
+- Corrected a couple failures to wipe secret buffers.
+- Corrected a bug that prevented compilation in Ed25519 mode.
+- Adjusted the number of test vectors in the test suite.
+- Improved tests for incremental interfaces.
+- Replaced the GNU all permissive licence by a public domain dedication
+ (Creative Commons CC-0). The BSD licence remains as a fallback.
+
+2.0.1
+-----
+2018/03/07
+
+- Followed a systematic pattern for the loading code of symmetric
+ crypto. It is now easier to review.
+- Tweaked Poly1305 code to make it easier to prove correct.
+
+2.0.0
+-----
+2018/02/14
+
+- Changed the authenticated encryption format. It now conforms to
+ RFC 7539, with one exception: it uses XChacha20 initialisation instead
+ of the IETF version of Chacha20. This new format conforms to
+ libsodium's `crypto_aead_xchacha20poly1305_ietf_encrypt`.
+- Removed `crypto_lock_encrypt()` and `crypto_lock_auth()`.
+- Renamed `crypto_lock_aead_auth()` to `crypto_lock_auth_ad()`.
+- Renamed `crypto_unlock_aead_auth()` to `crypto_unlock_auth_ad()`.
+- Added `crypto_lock_auth_message()` and `crypto_unlock_auth_message()`.
+- Renamed `crypto_aead_lock` to `crypto_lock_aead`.
+- Renamed `crypto_aead_unlock` to `crypto_unlock_aead`.
+
+The format change facilitates optimisation by aligning data to block
+boundaries. The API changes increase consistency.
+
+1.1.0
+-----
+2018/02/06
+
+- Rewrote the manual into proper man pages.
+- Added incremental interfaces for authenticated encryption and
+ signatures.
+- Replaced `crypto_memcmp()` by 3 fixed size buffer comparisons (16, 32,
+ and 64 bytes), to make sure the generated code remains constant time.
+- A couple breaking API changes, easily fixed by renaming the affected
+ functions.
+
+1.0.1
+-----
+2017/07/23
+
+- Optimised the loading and unloading code of the symmetric crypto
+ (BLAKE2b, SHA-512, Chacha20, and Poly1305).
+- Fused self-contained tests together for easier analysis with Frama-C
+ and the TIS interpreter.
+
+1.0
+---
+2017/07/18
+
+- Renamed `crypto_chacha20_Xinit` to `crypto_chacha20_x_init`, for
+ consistency reasons (snake case everywhere).
+- Fixed signed integer overflow detected by UBSan.
+- Doubled the speed of EdDSA by performing the scalar product in
+ Montgomery space.
+
+0.8
+---
+2017/07/06
+
+- Added about a hundred lines of code to improve performance of public
+ key cryptography. Diffie-Hellman is now 20% faster than before.
+ The effects are less pronounced for EdDSA.
+- Added random self-consistency tests.
+- Added a speed benchmark against libsodium.
+
+0.7
+---
+2017/06/07
+
+- Slightly changed the authenticated encryption API. Functions are
+ now all in "detached" mode. The reason is better support for
+ authenticated encryption _without_ additional data.
+- Rewrote BLAKE2b from spec so it can use the same licence as
+ everything else.
+- Added random tests that compare Monocypher with libsodium and
+ ed25519-donna.
+- Added explicit support for Frama-C analysis (this doesn't affect the
+ source code).
+
+0.6
+---
+2017/03/17
+
+- Fixed incorrect Poly1305 output on empty messages. (Found by Mike
+ Pechkin.)
+
+0.5
+---
+2017/03/10
+
+- Fixed many undefined behaviours in Curve25519 that occur whenever
+ we perform a left shift on a signed negative integer. It doesn't
+ affect the generated code, but you never know. (Found with Frama-C
+ by André Maroneze.)
+
+Fun fact: TweetNaCl and ref10 have the same bug. Libsodium has
+corrected the issue, though.
+
+For those who don't comprehend the magnitude of this madness, the
+expression `-1 << 3` is undefined in C. This is explained in
+section 6.5.7(§4) of the C11 standard.
+
+0.4
+---
+2017/03/09
+
+- Fixed critical bug causing Argon2i to fail whenever it uses more
+ than 512 blocks. It was reading uninitialised memory and the
+ results were incorrect. (Found by Mike Pechkin.)
+- Fixed an undefined behaviour in Curve25519 (`fe_tobytes()`). It was
+ accessing uninitialised memory before throwing it away. It didn't
+ affect the compiled code nor the results, but you never know.
+ (Found with [Frama-C](http://frama-c.com) by André Maroneze.)
+
+0.3
+---
+2017/02/27
+
+- Got the invariants of Poly1305 right and put them in the comments.
+ There was no bug, but that was lucky (turned out the IETF test
+ vectors were designed to trigger the bugs I was afraid of).
+- Simplified Poly1305 finalisation (replaced conditional subtraction
+ by a carry propagation).
+- Made a few cosmetic changes here and there.
+
+0.2
+---
+????/??/??
+
+- Public interface significantly reworked. Removed redundant, hard to
+ mess up constructions.
+- Added AEAD.
+- Sped up Curve25519 by a factor of more than 6 (switched to ref10
+ arithmetic).
+- Added various test vectors and completed the consistency tests.
+
+0.1
+---
+2016/??/??
diff --git a/lib/Utils.Cryptography/monocypher/vendor/CMakeLists.txt b/lib/Utils.Cryptography/monocypher/vendor/CMakeLists.txt
new file mode 100644
index 0000000..31a1428
--- /dev/null
+++ b/lib/Utils.Cryptography/monocypher/vendor/CMakeLists.txt
@@ -0,0 +1,82 @@
+cmake_minimum_required(VERSION 3.0)
+
+project(Monocypher C)
+
+#export header files to the main project
+file(GLOB HEADERS src/*.h)
+
+#Add indepednent source files to the project
+set(MONOCYPHER_SRCS
+ src/monocypher.c
+)
+
+#create shared library
+add_library(${CMAKE_PROJECT_NAME} SHARED ${MONOCYPHER_SRCS} ${HEADERS})
+#also create static library
+add_library(${CMAKE_PROJECT_NAME}_static STATIC ${MONOCYPHER_SRCS} ${HEADERS})
+
+#if on unix lib will be appended, so we can adjust
+if(UNIX)
+ set_target_properties(${CMAKE_PROJECT_NAME} ${CMAKE_PROJECT_NAME}_static PROPERTIES OUTPUT_NAME _monocypher)
+endif()
+
+#Setup the compiler options
+set(CMAKE_C_STANDARD 99)
+set(CMAKE_C_STANDARD_REQUIRED ON)
+
+#enable position independent code (for shared libraries with exports)
+set(CMAKE_POSITION_INDEPENDENT_CODE ON)
+
+message(STATUS "Build type is '${CMAKE_BUILD_TYPE}'")
+
+#if debug
+add_compile_definitions($<$<CONFIG:Debug>:DEBUG>)
+
+#setup flags for windows compilation
+if(MSVC)
+
+ #global windows cl flags
+ add_compile_options(
+ /sdl
+ /TC
+ /GS
+ /machine:x64
+
+ $<$<CONFIG:Debug>:/FC>
+ $<$<CONFIG:Debug>:/showIncludes>
+
+ #disable warnings for struct padding and spectre mitigation wuen WX is enabled
+ $<$<CONFIG:Debug>:/wd5045>
+ $<$<CONFIG:Debug>:/wd4820>
+ $<$<CONFIG:Debug>:/wd4574>
+
+ #for debug configs
+ $<$<CONFIG:Debug>:/options:strict>
+ #disable warnings for struct padding and spectre mitigation wuen WX is enabled
+ $<$<CONFIG:Debug>:/Wall>
+ $<$<CONFIG:Debug>:/Zi>
+ $<$<CONFIG:Debug>:/Zo>
+ )
+
+ #set build macros
+ add_compile_definitions(
+ $<$<CONFIG:DEBUG>:DEBUG>
+ $<$<CONFIG:RELEASE>:RELEASE>
+ )
+
+#configure gcc flags
+elseif(CMAKE_COMPILER_IS_GNUCC)
+
+ #global gcc cl flags
+ add_compile_options(
+ -Wextra
+ -fstack-protector
+ -march=native
+
+ $<$<CONFIG:Debug>:-g>
+ $<$<CONFIG:Debug>:-Og>
+ $<$<CONFIG:Debug>:-Wall>
+ $<$<CONFIG:Debug>:-pedantic>
+ )
+
+endif()
diff --git a/lib/Utils.Cryptography/monocypher/vendor/LICENCE.md b/lib/Utils.Cryptography/monocypher/vendor/LICENCE.md
new file mode 100644
index 0000000..9d69ad7
--- /dev/null
+++ b/lib/Utils.Cryptography/monocypher/vendor/LICENCE.md
@@ -0,0 +1,173 @@
+Monocypher as a whole is dual-licensed. Choose whichever licence you
+want from the two licences listed below.
+
+The first licence is a regular 2-clause BSD licence. The second licence
+is the CC-0 from Creative Commons. It is intended to release Monocypher
+to the public domain. The BSD licence serves as a fallback option.
+
+See the individual files for specific information about who contributed
+to what file during which years. See below for special notes.
+
+Licence 1 (2-clause BSD)
+------------------------
+
+Copyright (c) 2017-2023, Loup Vaillant
+Copyright (c) 2017-2019, Michael Savage
+Copyright (c) 2017-2023, Fabio Scotoni
+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 COPYRIGHT HOLDERS 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 COPYRIGHT
+HOLDER 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.
+
+
+Licence 2 (CC-0)
+----------------
+
+> CREATIVE COMMONS CORPORATION IS NOT A LAW FIRM AND DOES NOT PROVIDE
+> LEGAL SERVICES. DISTRIBUTION OF THIS DOCUMENT DOES NOT CREATE AN
+> ATTORNEY-CLIENT RELATIONSHIP. CREATIVE COMMONS PROVIDES THIS
+> INFORMATION ON AN "AS-IS" BASIS. CREATIVE COMMONS MAKES NO WARRANTIES
+> REGARDING THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS
+> PROVIDED HEREUNDER, AND DISCLAIMS LIABILITY FOR DAMAGES RESULTING FROM
+> THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS PROVIDED
+> HEREUNDER.
+
+### Statement of Purpose
+
+The laws of most jurisdictions throughout the world automatically confer
+exclusive Copyright and Related Rights (defined below) upon the creator
+and subsequent owner(s) (each and all, an "owner") of an original work
+of authorship and/or a database (each, a "Work").
+
+Certain owners wish to permanently relinquish those rights to a Work for
+the purpose of contributing to a commons of creative, cultural and
+scientific works ("Commons") that the public can reliably and without
+fear of later claims of infringement build upon, modify, incorporate in
+other works, reuse and redistribute as freely as possible in any form
+whatsoever and for any purposes, including without limitation commercial
+purposes. These owners may contribute to the Commons to promote the
+ideal of a free culture and the further production of creative, cultural
+and scientific works, or to gain reputation or greater distribution for
+their Work in part through the use and efforts of others.
+
+For these and/or other purposes and motivations, and without any
+expectation of additional consideration or compensation, the person
+associating CC0 with a Work (the "Affirmer"), to the extent that he or
+she is an owner of Copyright and Related Rights in the Work, voluntarily
+elects to apply CC0 to the Work and publicly distribute the Work under
+its terms, with knowledge of his or her Copyright and Related Rights in
+the Work and the meaning and intended legal effect of CC0 on those
+rights.
+
+1. **Copyright and Related Rights.** A Work made available under CC0 may
+ be protected by copyright and related or neighboring rights
+ ("Copyright and Related Rights"). Copyright and Related Rights
+ include, but are not limited to, the following:
+
+ - the right to reproduce, adapt, distribute, perform, display,
+ communicate, and translate a Work;
+ - moral rights retained by the original author(s) and/or
+ performer(s); publicity and privacy rights pertaining to a person's
+ image or likeness depicted in a Work;
+ - rights protecting against unfair competition in regards to a Work,
+ subject to the limitations in paragraph 4(a), below;
+ - rights protecting the extraction, dissemination, use and reuse of
+ data in a Work;
+ - database rights (such as those arising under Directive 96/9/EC of
+ the European Parliament and of the Council of 11 March 1996 on the
+ legal protection of databases, and under any national
+ implementation thereof, including any amended or successor version
+ of such directive); and
+ - other similar, equivalent or corresponding rights throughout the
+ world based on applicable law or treaty, and any national
+ implementations thereof.
+
+2. **Waiver.** To the greatest extent permitted by, but not in
+ contravention of, applicable law, Affirmer hereby overtly, fully,
+ permanently, irrevocably and unconditionally waives, abandons, and
+ surrenders all of Affirmer's Copyright and Related Rights and
+ associated claims and causes of action, whether now known or unknown
+ (including existing as well as future claims and causes of action),
+ in the Work (i) in all territories worldwide, (ii) for the maximum
+ duration provided by applicable law or treaty (including future time
+ extensions), (iii) in any current or future medium and for any number
+ of copies, and (iv) for any purpose whatsoever, including without
+ limitation commercial, advertising or promotional purposes (the
+ "Waiver"). Affirmer makes the Waiver for the benefit of each member
+ of the public at large and to the detriment of Affirmer's heirs and
+ successors, fully intending that such Waiver shall not be subject to
+ revocation, rescission, cancellation, termination, or any other legal
+ or equitable action to disrupt the quiet enjoyment of the Work by the
+ public as contemplated by Affirmer's express Statement of Purpose.
+
+3. **Public License Fallback.** Should any part of the Waiver for any
+ reason be judged legally invalid or ineffective under applicable law,
+ then the Waiver shall be preserved to the maximum extent permitted
+ taking into account Affirmer's express Statement of Purpose. In
+ addition, to the extent the Waiver is so judged Affirmer hereby
+ grants to each affected person a royalty-free, non transferable, non
+ sublicensable, non exclusive, irrevocable and unconditional license
+ to exercise Affirmer's Copyright and Related Rights in the Work (i)
+ in all territories worldwide, (ii) for the maximum duration provided
+ by applicable law or treaty (including future time extensions), (iii)
+ in any current or future medium and for any number of copies, and
+ (iv) for any purpose whatsoever, including without limitation
+ commercial, advertising or promotional purposes (the "License"). The
+ License shall be deemed effective as of the date CC0 was applied by
+ Affirmer to the Work. Should any part of the License for any reason
+ be judged legally invalid or ineffective under applicable law, such
+ partial invalidity or ineffectiveness shall not invalidate the
+ remainder of the License, and in such case Affirmer hereby affirms
+ that he or she will not (i) exercise any of his or her remaining
+ Copyright and Related Rights in the Work or (ii) assert any
+ associated claims and causes of action with respect to the Work, in
+ either case contrary to Affirmer's express Statement of Purpose.
+
+4. **Limitations and Disclaimers.**
+
+ - No trademark or patent rights held by Affirmer are waived,
+ abandoned, surrendered, licensed or otherwise affected by this
+ document.
+ - Affirmer offers the Work as-is and makes no representations or
+ warranties of any kind concerning the Work, express, implied,
+ statutory or otherwise, including without limitation warranties of
+ title, merchantability, fitness for a particular purpose, non
+ infringement, or the absence of latent or other defects, accuracy,
+ or the present or absence of errors, whether or not discoverable,
+ all to the greatest extent permissible under applicable law.
+ - Affirmer disclaims responsibility for clearing rights of other
+ persons that may apply to the Work or any use thereof, including
+ without limitation any person's Copyright and Related Rights in the
+ Work. Further, Affirmer disclaims responsibility for obtaining any
+ necessary consents, permissions or other rights required for any
+ use of the Work.
+ - Affirmer understands and acknowledges that Creative Commons is not
+ a party to this document and has no duty or obligation with respect
+ to this CC0 or use of the Work.
+
+Special notes
+-------------
+
+The files in `tests/externals/` were placed in the public domain by
+their respective authors. See the `AUTHORS.md` files in each directory.
diff --git a/lib/Utils.Cryptography/monocypher/vendor/README.md b/lib/Utils.Cryptography/monocypher/vendor/README.md
new file mode 100644
index 0000000..f0c28df
--- /dev/null
+++ b/lib/Utils.Cryptography/monocypher/vendor/README.md
@@ -0,0 +1,196 @@
+[![TrustInSoft CI](https://ci.trust-in-soft.com/projects/LoupVaillant/Monocypher.svg?branch=master)](https://ci.trust-in-soft.com/projects/LoupVaillant/Monocypher)
+
+[![Github Actions CI](https://github.com/LoupVaillant/Monocypher/actions/workflows/ci.yml/badge.svg)](https://github.com/LoupVaillant/Monocypher/actions/workflows/ci.yml)
+
+
+Monocypher (Developer Edition)
+------------------------------
+
+_(This is the bleeding edge, not yet released version. If you just want
+to use Monocypher, grab the [latest version][latest], or download the
+[source][] and [header][] files directly. If you want to contribute, see
+the notes at the end.)_
+
+[source]: https://monocypher.org/download/monocypher.c
+[header]: https://monocypher.org/download/monocypher.h
+[latest]: https://monocypher.org/download/monocypher-latest.tar.gz
+
+---
+
+Monocypher is an easy to use, easy to deploy, auditable crypto library
+written in portable C. It approaches the size of [TweetNaCl][] and the
+speed of [libsodium][].
+
+[Official site.](https://monocypher.org/)
+[Official releases.](https://monocypher.org/download/)
+
+[libsodium]: https://libsodium.org
+[TweetNaCl]: https://tweetnacl.cr.yp.to/
+
+
+Features
+--------
+
+- [Authenticated Encryption][AEAD] with XChaCha20 and Poly1305
+ (RFC 8439).
+- [Hashing and key derivation][HASH] with BLAKE2b (and [SHA-512][]).
+- [Password Hashing][PWH] with Argon2.
+- [Public Key Cryptography][PKC] with X25519 key exchanges.
+- [Public Key Signatures][EDDSA] with EdDSA and [Ed25519][].
+- [Steganography and PAKE][STEG] with [Elligator 2][ELLI].
+
+[AEAD]: https://monocypher.org/manual/aead
+[HASH]: https://monocypher.org/manual/blake2
+[SHA-512]: https://monocypher.org/manual/sha-512
+[PWH]: https://monocypher.org/manual/argon2
+[PKC]: https://monocypher.org/manual/x25519
+[EDDSA]: https://monocypher.org/manual/eddsa
+[Ed25519]: https://monocypher.org/manual/ed25519
+[STEG]: https://monocypher.org/manual/elligator
+[ELLI]: https://elligator.org
+
+
+Manual
+------
+
+The manual can be found at https://monocypher.org/manual/, and in the
+`doc/` folder.
+
+
+Installation
+------------
+
+### Option 1: grab the sources
+
+The easiest way to use Monocypher is to include `src/monocypher.h` and
+`src/monocypher.c` directly into your project. They compile as C (since
+C99) and C++ (since C++98).
+
+If you need the optional SHA-512 or Ed25519, grab
+`src/optional/monocypher-ed25519.h` and
+`src/optional/monocypher-ed25519.c` as well.
+
+### Option 2: grab the library
+
+Run `make`, then grab the `src/monocypher.h` header and either the
+`lib/libmonocypher.a` or `lib/libmonocypher.so` library. The default
+compiler is `gcc -std=c99`, and the default flags are `-pedantic -Wall
+-Wextra -O3 -march=native`. If they don't work on your platform, you
+can change them like this:
+
+ $ make CC="clang -std=c11" CFLAGS="-O2"
+
+### Option 3: install it on your system
+
+Run `make`, then `make install` as root. This will install Monocypher in
+`/usr/local` by default. This can be changed with `PREFIX` and
+`DESTDIR`:
+
+ $ make install PREFIX="/opt"
+
+Once installed, you may use `pkg-config` to compile and link your
+program. For instance:
+
+ $ gcc program.c $(pkg-config monocypher --cflags) -c
+ $ gcc program.o $(pkg-config monocypher --libs) -o program
+
+If for any reason you wish to avoid installing the man pages or the
+`pkg-config` file, you can use the following installation sub targets
+instead: `install-lib`, `install-doc`, and `install-pc`.
+
+
+Test suite
+----------
+
+ $ make test
+
+It should display a nice printout of all the tests, ending with "All
+tests OK!". If you see "failure" or "Error" anywhere, something has gone
+wrong.
+
+*Do not* use Monocypher without running those tests at least once.
+
+The same test suite can be run under Clang sanitisers and Valgrind, and
+be checked for code coverage:
+
+ $ tests/test.sh
+ $ tests/coverage.sh
+
+
+### Serious auditing
+
+The code may be analysed more formally with [Frama-c][] and the
+[TIS interpreter][TIS]. To analyse the code with Frama-c, run:
+
+ $ tests/formal-analysis.sh
+ $ tests/frama-c.sh
+
+This will have Frama-c parse, and analyse the code, then launch a GUI.
+You must have Frama-c installed. See `frama-c.sh` for the recommended
+settings. To run the code under the TIS interpreter, run
+
+ $ tests/formal-analysis.sh
+ $ tis-interpreter.sh --cc -Dvolatile= tests/formal-analysis/*.c
+
+Notes:
+
+- `tis-interpreter.sh` is part of TIS. If it is not in your path,
+ adjust the command accordingly.
+
+- The TIS interpreter sometimes fails to evaluate correct programs when
+ they use the `volatile` keyword (which is only used as an attempt to
+ prevent dead store elimination for memory wipes). The `-cc
+ -Dvolatile=` option works around that bug by ignoring `volatile`
+ altogether.
+
+[Frama-c]:https://frama-c.com/
+[TIS]: https://trust-in-soft.com/tis-interpreter/
+
+
+Customisation
+-------------
+
+Monocypher has optional compatibility with Ed25519. To have that, add
+`monocypher-ed25519.h` and `monocypher-ed25519.c` provided in
+`src/optional` to your project. If you compile or install Monocypher
+with the makefile, they will be automatically included.
+
+Monocypher also has the `BLAKE2_NO_UNROLLING` preprocessor flag, which
+is activated by compiling monocypher.c with the `-DBLAKE2_NO_UNROLLING`
+option.
+
+The `-DBLAKE2_NO_UNROLLING` option is a performance tweak. By default,
+Monocypher unrolls the BLAKE2b inner loop, because doing so is over 25%
+faster on modern processors. Some embedded processors however, run the
+unrolled loop _slower_ (possibly because of the cost of fetching 5KB of
+additional code). If you're using an embedded platform, try this
+option. The binary will be about 5KB smaller, and in some cases faster.
+
+The `MONOCYPHER_CPP_NAMESPACE` preprocessor definition allows C++ users
+who compile Monocypher as C++ to wrap it in a namespace. When it is not
+defined (the default), we assume Monocypher is compiled as C, and an
+`extern "C"` declaration is added when we detect that the header is
+included in C++ code.
+
+The `change-prefix.sh` script can rename all functions by replacing
+`crypto_` by a chosen prefix, so you can avoid name clashes. For
+instance, the following command changes all instances of `crypto_` by
+`foobar_` (note the absence of the underscore):
+
+ ./change-prefix.sh foobar
+
+
+Contributor notes
+-----------------
+
+If you are reading this, you cloned the GitHub repository. You miss a
+couple files that ship with the tarball releases:
+
+- The `tests/vectors.h` header. Generating it requires libsodium. Go
+ to `tests/gen/`, then run `make`.
+- The html version of the manual, generated by the `doc/doc_gen.sh`
+ script. You will need mandoc and Python 3.
+
+To generate a tarball, simply type `make dist`. It will make a tarball
+with a name that matches the current version (using `git describe`), in
+the current directory.
diff --git a/lib/Utils.Cryptography/monocypher/vendor/change-prefix.sh b/lib/Utils.Cryptography/monocypher/vendor/change-prefix.sh
new file mode 100644
index 0000000..63ef535
--- /dev/null
+++ b/lib/Utils.Cryptography/monocypher/vendor/change-prefix.sh
@@ -0,0 +1,70 @@
+#! /bin/sh
+
+# This file is dual-licensed. Choose whichever licence you want from
+# the two licences listed below.
+#
+# The first licence is a regular 2-clause BSD licence. The second licence
+# is the CC-0 from Creative Commons. It is intended to release Monocypher
+# to the public domain. The BSD licence serves as a fallback option.
+#
+# SPDX-License-Identifier: BSD-2-Clause OR CC0-1.0
+#
+# ------------------------------------------------------------------------
+#
+# Copyright (c) 2022, Loup Vaillant
+# 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 COPYRIGHT HOLDERS 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 COPYRIGHT
+# HOLDER 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.
+#
+# ------------------------------------------------------------------------
+#
+# Written in 2022 by Loup Vaillant
+#
+# To the extent possible under law, the author(s) have dedicated all copyright
+# and related 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
+# <https://creativecommons.org/publicdomain/zero/1.0/>
+
+
+# Usage:
+# ./change-prefix.sh foobar
+#
+# The above changes the default "crypto_" prefix of all Monocypher
+# functions by the "foobar_" prefix instead.
+#
+# This can be used to avoid name clashes with other libraries.
+# This also renames the test code, so the tests should still pass.
+
+set -e
+
+find . -name "*.*" \
+ | egrep "\.(c|h)$" \
+ | egrep -v "^\./tests/(gen|externals|speed/speed-)" \
+ | xargs sed -i "s/crypto_/$1_/g" \
+ tests/externals/ed25519-donna/ed25519-hash-custom.h
diff --git a/lib/Utils.Cryptography/monocypher/vendor/dist.sh b/lib/Utils.Cryptography/monocypher/vendor/dist.sh
new file mode 100644
index 0000000..d0db2ff
--- /dev/null
+++ b/lib/Utils.Cryptography/monocypher/vendor/dist.sh
@@ -0,0 +1,119 @@
+#! /bin/sh
+
+# This file is dual-licensed. Choose whichever licence you want from
+# the two licences listed below.
+#
+# The first licence is a regular 2-clause BSD licence. The second licence
+# is the CC-0 from Creative Commons. It is intended to release Monocypher
+# to the public domain. The BSD licence serves as a fallback option.
+#
+# SPDX-License-Identifier: BSD-2-Clause OR CC0-1.0
+#
+# ------------------------------------------------------------------------
+#
+# Copyright (c) 2019, Loup Vaillant
+# Copyright (c) 2019-2020, Fabio Scotoni
+# 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 COPYRIGHT HOLDERS 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 COPYRIGHT
+# HOLDER 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.
+#
+# ------------------------------------------------------------------------
+#
+# Written in 2019-2020 by Loup Vaillant and Fabio Scotoni
+#
+# To the extent possible under law, the author(s) have dedicated all copyright
+# and related 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
+# <https://creativecommons.org/publicdomain/zero/1.0/>
+
+set -e
+
+VERSION=`git describe --tags`
+FOLDER=monocypher-$VERSION
+TARBALL=$FOLDER.tar
+
+# Generate documentation
+doc/doc_gen.sh
+
+# Delete the destination folder just to make sure everything is clean.
+# May be needed if we unpack the tarball in place for testing purposes,
+# then run the release script again.
+rm -rf $FOLDER
+
+# copy everything except ignored files to the
+rsync -ad --exclude-from=dist_ignore ./ $FOLDER
+
+# Replace version markers by the actual version number (from tags)
+find $FOLDER -type f -exec sed -i "s/__git__/$VERSION/g" \{\} \;
+
+# Remove the dist target from the makefile (no recursive releases!),
+# and the tests/vector.h target, which ships with the tarball.
+sed -i '/# Remove lines below for the tarball/,$d' $FOLDER/makefile
+sed -i 's/clean uninstall dist/clean uninstall/' $FOLDER/makefile
+sed -i 's| doc/man3/intro.3monocypher||' $FOLDER/makefile
+sed -i 's|rm -rf lib/ doc/html/ doc/man3/|rm -rf lib/|' $FOLDER/makefile
+
+# Remove contributor notes from the README
+sed -e '/Contributor notes/,$d' -e '1,/^---$/d' -i $FOLDER/README.md
+sed -e '$d' -i $FOLDER/README.md
+sed -e '$d' -i $FOLDER/README.md
+sed -e '1i\
+Monocypher\
+----------' -i $FOLDER/README.md
+
+# Remove special notes from the LICENCE
+sed -e '/Special notes/,$d' -i $FOLDER/LICENCE.md
+sed -e '$d' -i $FOLDER/LICENCE.md
+
+# Make the actual tarball. The options here were taken from:
+# https://reproducible-builds.org/docs/archives/#full-example
+# This requires GNU tar.
+# The --mtime value was chosen arbitrarily, but the date is chosen such
+# that it is after the release 3.1.0, the last one without reproducible
+# tarballs.
+tar --sort=name \
+ --mtime=@1587513600 \
+ --owner=0 --group=0 --numeric-owner \
+ --pax-option=exthdr.name=%d/PaxHeaders/%f,delete=atime,delete=ctime \
+ -cvf $TARBALL $FOLDER
+# Compress separately so that we can set the -n option to avoid any kind
+# of timestamp metadata
+gzip -n $TARBALL
+
+# Remove the temporary folder
+rm -rf $FOLDER
+
+# Run tests in the tarball, to make sure we didn't screw up anything
+# important. We're missing the TIS interpreter run, but that's a good
+# quick check.
+tar -xzf $TARBALL.gz
+cd $FOLDER # Extracting from the tarball, just to make sure
+tests/test.sh
+make clean
+make
diff --git a/lib/Utils.Cryptography/monocypher/vendor/dist_ignore b/lib/Utils.Cryptography/monocypher/vendor/dist_ignore
new file mode 100644
index 0000000..9aa4940
--- /dev/null
+++ b/lib/Utils.Cryptography/monocypher/vendor/dist_ignore
@@ -0,0 +1,36 @@
+*~
+*.o
+*.a
+*.so
+*.so.*
+*.out
+*.vec
+*.gch
+*.sav
+*.profraw
+*.profdata
+*.creator
+*.creator.*
+*.config
+*.cflags
+*.cxxflags
+*.files
+*.includes
+*.su
+*.su.*
+*.gen.*
+tests/formal-analysis/*
+tests/formal-analysis
+*.tar.gz
+monocypher-*/
+**/__pycache__/**
+doc/*.*
+tests/speed*
+tests/externals*
+lib*
+.git*
+dist.sh
+dist_ignore
+tests/gen*
+tis.config
+tests/tis-ci-gen-config.sh
diff --git a/lib/Utils.Cryptography/monocypher/vendor/doc/crypto_aead_lock.3monocypher b/lib/Utils.Cryptography/monocypher/vendor/doc/crypto_aead_lock.3monocypher
new file mode 100644
index 0000000..348c3bf
--- /dev/null
+++ b/lib/Utils.Cryptography/monocypher/vendor/doc/crypto_aead_lock.3monocypher
@@ -0,0 +1,507 @@
+.\" This file is dual-licensed. Choose whichever you want.
+.\"
+.\" The first licence is a regular 2-clause BSD licence. The second licence
+.\" is the CC-0 from Creative Commons. It is intended to release Monocypher
+.\" to the public domain. The BSD licence serves as a fallback option.
+.\"
+.\" SPDX-License-Identifier: BSD-2-Clause OR CC0-1.0
+.\"
+.\" ----------------------------------------------------------------------------
+.\"
+.\" Copyright (c) 2017-2019, 2023 Loup Vaillant
+.\" Copyright (c) 2017-2018 Michael Savage
+.\" Copyright (c) 2017, 2019-2022 Fabio Scotoni
+.\" 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 COPYRIGHT HOLDERS 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 COPYRIGHT
+.\" HOLDER 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.
+.\"
+.\" ----------------------------------------------------------------------------
+.\"
+.\" Written in 2017-2023 by Loup Vaillant, Michael Savage and Fabio Scotoni
+.\"
+.\" To the extent possible under law, the author(s) have dedicated all copyright
+.\" and related 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
+.\" <https://creativecommons.org/publicdomain/zero/1.0/>
+.\"
+.Dd March 6, 2023
+.Dt CRYPTO_LOCK 3MONOCYPHER
+.Os
+.Sh NAME
+.Nm crypto_aead_lock ,
+.Nm crypto_aead_unlock ,
+.Nm crypto_aead_init_x ,
+.Nm crypto_aead_init_djb ,
+.Nm crypto_aead_init_ietf ,
+.Nm crypto_aead_write ,
+.Nm crypto_aead_read
+.Nd authenticated encryption with additional data
+.Sh SYNOPSIS
+.In monocypher.h
+.Ft void
+.Fo crypto_aead_lock
+.Fa "uint8_t *cipher_text"
+.Fa "uint8_t mac[16]"
+.Fa "const uint8_t key[32]"
+.Fa "const uint8_t nonce[24]"
+.Fa "const uint8_t *ad"
+.Fa "size_t ad_size"
+.Fa "const uint8_t *plain_text"
+.Fa "size_t text_size"
+.Fc
+.Ft int
+.Fo crypto_aead_unlock
+.Fa "uint8_t *plain_text"
+.Fa "const uint8_t mac[16]"
+.Fa "const uint8_t key[32]"
+.Fa "const uint8_t nonce[24]"
+.Fa "const uint8_t *ad"
+.Fa "size_t ad_size"
+.Fa "const uint8_t *cipher_text"
+.Fa "size_t text_size"
+.Fc
+.Ft void
+.Fo crypto_aead_init_x
+.Fa "crypto_aead_ctx *ctx"
+.Fa "const uint8_t key[32]"
+.Fa "const uint8_t nonce[24]"
+.Fc
+.Ft void
+.Fo crypto_aead_init_djb
+.Fa "crypto_aead_ctx *ctx"
+.Fa "const uint8_t key[32]"
+.Fa "const uint8_t nonce[8]"
+.Fc
+.Ft void
+.Fo crypto_aead_init_ietf
+.Fa "crypto_aead_ctx *ctx"
+.Fa "const uint8_t key[32]"
+.Fa "const uint8_t nonce[12]"
+.Fc
+.Ft void
+.Fo crypto_aead_write
+.Fa "crypto_aead_ctx *ctx"
+.Fa "uint8_t *cipher_text"
+.Fa "uint8_t mac[16]"
+.Fa "const uint8_t *ad"
+.Fa "size_t ad_size"
+.Fa "const uint8_t *plain_text"
+.Fa "size_t text_size"
+.Fc
+.Ft int
+.Fo crypto_aead_read
+.Fa "crypto_aead_ctx *ctx"
+.Fa "uint8_t *plain_text"
+.Fa "const uint8_t mac[16]"
+.Fa "const uint8_t *ad"
+.Fa "size_t ad_size"
+.Fa "const uint8_t *cipher_text"
+.Fa "size_t text_size"
+.Fc
+.Sh DESCRIPTION
+.Fn crypto_aead_lock
+encrypts and authenticates a plaintext.
+It can be decrypted by
+.Fn crypto_aead_unlock .
+The arguments are:
+.Bl -tag -width Ds
+.It Fa key
+A 32-byte session key shared between the sender and the recipient.
+It must be secret and random.
+Different methods can be used to produce and exchange this key,
+such as Diffie-Hellman key exchange,
+password-based key derivation
+(the password must be communicated on a secure channel),
+or even meeting physically.
+See
+.Xr crypto_x25519 3monocypher
+for a building block for a key exchange protocol and
+.Xr crypto_argon2 3monocypher
+for password-based key derivation.
+.It Fa nonce
+A 24-byte number, used only once with any given session key.
+It does not need to be secret or random, but it does have to be
+unique.
+.Em Never
+use the same nonce twice with the same key.
+This would basically reveal the affected messages
+and leave you vulnerable to forgeries.
+The easiest (and recommended) way to generate this nonce is to
+select it at random.
+See
+.Xr intro 3monocypher
+about random number generation (use your operating system's random
+number generator).
+.Pp
+Note:
+.Fn crypto_aead_init_djb
+and
+.Fn crypto_aead_init_ietf
+use shorter nonces
+(8 and 12 bytes respectively),
+which
+.Em cannot
+be selected at random without risking a catastrophic reuse.
+For those shorter nonces, use a counter instead.
+.It Fa mac
+A 16-byte
+.Em message authentication code
+(MAC) that can only be produced by someone who knows the session key.
+This guarantee cannot be upheld if a nonce has been reused with the
+session key because doing so allows the attacker to learn the
+authentication key associated with that nonce.
+The MAC is intended to be sent along with the ciphertext.
+.It Fa ad
+Additional data to authenticate.
+It will
+.Em not
+be encrypted.
+This is used to authenticate relevant data that cannot be encrypted.
+May be
+.Dv NULL
+if
+.Fa ad_size
+is zero.
+.It Fa ad_size
+Length of the additional data, in bytes.
+.It Fa plain_text
+The secret message.
+Its contents will be kept hidden from attackers.
+Its length, however, will
+.Em not .
+Be careful when combining encryption with compression.
+See
+.Xr intro 3monocypher
+for details.
+.It Fa cipher_text
+The encrypted message.
+.It Fa text_size
+Length of both
+.Fa plain_text and
+.Fa cipher_text ,
+in bytes.
+.El
+.Pp
+The
+.Fa cipher_text
+and
+.Fa plain_text
+arguments may point to the same buffer for in-place encryption.
+Otherwise, the buffers they point to must not overlap.
+.Pp
+.Fn crypto_aead_unlock
+first checks the integrity of an encrypted message.
+If it has been corrupted,
+.Fn crypto_aead_unlock
+does nothing and returns -1 immediately.
+Otherwise it decrypts the message then returns zero.
+.Em Always check the return value .
+.Ss Incremental interface
+For long messages that may not fit in memory,
+first initialise a context with
+.Fn crypto_aead_init_x ,
+then encrypt each chunk with
+.Fn crypto_aead_write .
+The receiving end will initialise its own context with
+.Fn crypto_aead_init_x ,
+then decrypt each chunk with
+.Fn crypto_aead_read .
+.Pp
+Just like
+.Fn crypto_aead_unlock ,
+.Fn crypto_aead_read
+first checks the integrity of the encrypted chunk,
+then returns -1 immediately if it has been corrupted.
+Otherwise it decrypts the chunk then returns zero.
+.Em Always check the return value .
+.Pp
+The encryption key is changed between each chunk,
+providing a symmetric ratchet that enforces the order of the messages.
+Attackers cannot reorder chunks without
+.Fn crypto_aead_read
+noticing.
+.Sy Truncation however is not detected .
+You must detect the last chunk manually.
+Possible methods include using
+.Fa ad
+to mark the last chunk differently,
+prefixing all plaintext messages with a marking byte
+(and use a different marking byte for the last chunk),
+or sending the total message size up front and encode the remaining size
+in
+.Fa ad .
+Once the last chunk is sent or received, wipe the context with
+.Xr crypto_wipe 3monocypher .
+.Pp
+.Fn crypto_aead_init_djb
+and
+.Fn crypto_aead_init_ietf
+are variants of
+.Fn crypto_aead_init_x
+with a shorter nonce.
+.Em Those nonces are too short to be selected at random .
+Use a counter instead.
+.Pp
+In addition to its short nonce,
+.Fn crypto_aead_init_ietf
+has a smaller internal counter that limits the size of chunks to
+256GiB.
+Exceeding this size leaks the contents of the chunk.
+It is provided strictly for compatibility with RFC 8439.
+.Sh RETURN VALUES
+.Fn crypto_aead_lock ,
+.Fn crypto_aead_init_x ,
+.Fn crypto_aead_init_djb ,
+.Fn crypto_aead_init_ietf ,
+and
+.Fn crypto_aead_write
+return nothing.
+.Fn crypto_aead_unlock
+and
+.Fn crypto_aead_read
+return 0 on success or -1 if the message was corrupted (i.e.
+.Fa mac
+mismatched the combination of
+.Fa key ,
+.Fa nonce ,
+.Fa ad ,
+and
+.Fa cipher_text ) .
+Corruption can be caused by transmission errors, programmer error, or an
+attacker's interference.
+.Fa plain_text
+does not need to be wiped if the decryption fails.
+.Sh EXAMPLES
+The following examples assume the existence of
+.Fn arc4random_buf ,
+which fills the given buffer with cryptographically secure random bytes.
+If
+.Fn arc4random_buf
+does not exist on your system, see
+.Xr intro 3monocypher
+for advice about how to generate cryptographically secure random bytes.
+.Pp
+Encryption:
+.Bd -literal -offset indent
+uint8_t key [32]; /* Random, secret session key */
+uint8_t nonce [24]; /* Use only once per key */
+uint8_t plain_text [12] = "Lorem ipsum"; /* Secret message */
+uint8_t mac [16]; /* Message authentication code */
+uint8_t cipher_text[12]; /* Encrypted message */
+arc4random_buf(key, 32);
+arc4random_buf(nonce, 24);
+crypto_aead_lock(cipher_text, mac,
+ key, nonce,
+ NULL, 0,
+ plain_text, sizeof(plain_text));
+/* Wipe secrets if they are no longer needed */
+crypto_wipe(plain_text, 12);
+crypto_wipe(key, 32);
+/* Transmit cipher_text, nonce, and mac over the network,
+ * store them in a file, etc.
+ */
+.Ed
+.Pp
+To decrypt the above:
+.Bd -literal -offset indent
+uint8_t key [32]; /* Same as the above */
+uint8_t nonce [24]; /* Same as the above */
+const uint8_t cipher_text[12]; /* Encrypted message */
+const uint8_t mac [16]; /* Received along with text */
+uint8_t plain_text [12]; /* Secret message */
+if (crypto_aead_unlock(plain_text, mac,
+ key, nonce,
+ NULL, 0,
+ cipher_text, sizeof(plain_text))) {
+ /* The message is corrupted.
+ * Wipe key if it is no longer needed,
+ * and abort the decryption.
+ */
+ crypto_wipe(key, 32);
+} else {
+ /* ...do something with the decrypted text here... */
+ /* Finally, wipe secrets if they are no longer needed */
+ crypto_wipe(plain_text, 12);
+ crypto_wipe(key, 32);
+}
+.Ed
+.Pp
+In-place encryption:
+.Bd -literal -offset indent
+uint8_t key [32]; /* Random, secret session key */
+uint8_t nonce[24]; /* Use only once per key */
+uint8_t text [12] = "Lorem ipsum"; /* Secret message */
+uint8_t mac [16]; /* Message authentication code */
+arc4random_buf(key, 32);
+arc4random_buf(nonce, 24);
+crypto_aead_lock(text, mac,
+ key, nonce,
+ NULL, 0,
+ text, sizeof(text));
+/* Wipe secrets if they are no longer needed */
+crypto_wipe(key, 32);
+/* Transmit cipher_text, nonce, and mac over the network,
+ * store them in a file, etc.
+ */
+.Ed
+.Pp
+In-place decryption:
+.Bd -literal -offset indent
+uint8_t key [32]; /* Same as the above */
+const uint8_t nonce[24]; /* Same as the above */
+const uint8_t mac [16]; /* Received from along with text */
+uint8_t text [12]; /* Message to decrypt */
+if (crypto_aead_unlock(text, mac, key, nonce,
+ NULL, 0,
+ text, sizeof(text))) {
+ /* The message is corrupted.
+ * Wipe key if it is no longer needed,
+ * and abort the decryption.
+ */
+ crypto_wipe(key, 32);
+} else {
+ /* ...do something with the decrypted text here... */
+ /* Finally, wipe secrets if they are no longer needed */
+ crypto_wipe(text, 12);
+ crypto_wipe(key, 32);
+}
+.Ed
+.Pp
+Encrypt one message with the incremental interface:
+.Bd -literal -offset indent
+uint8_t key [32]; /* Random, secret session key */
+uint8_t nonce [24]; /* Use only once per key */
+uint8_t plain_text [12] = "Lorem ipsum"; /* Secret message */
+uint8_t mac [16]; /* Message authentication code */
+uint8_t cipher_text[12]; /* Encrypted message */
+arc4random_buf(key, 32);
+arc4random_buf(nonce, 24);
+crypto_aead_ctx ctx;
+crypto_aead_init_x(&ctx, key, nonce);
+crypto_aead_write(&ctx, cipher_text, mac,
+ NULL, 0,
+ plain_text, sizeof(plain_text));
+/* Wipe secrets if they are no longer needed */
+crypto_wipe(plain_text, 12);
+crypto_wipe(key, 32);
+crypto_wipe(&ctx, sizeof(ctx));
+/* Transmit cipher_text, nonce, and mac over the network,
+ * store them in a file, etc.
+ */
+.Ed
+.Pp
+To decrypt the above:
+.Bd -literal -offset indent
+uint8_t key [32]; /* Same as the above */
+uint8_t nonce [24]; /* Same as the above */
+const uint8_t cipher_text[12]; /* Encrypted message */
+const uint8_t mac [16]; /* Received along with text */
+uint8_t plain_text [12]; /* Secret message */
+crypto_aead_ctx ctx;
+crypto_aead_init_x(&ctx, key, nonce);
+if (crypto_aead_read(&ctx, plain_text, mac,
+ NULL, 0,
+ cipher_text, sizeof(plain_text))) {
+ /* The message is corrupted.
+ * Wipe key if it is no longer needed,
+ * and abort the decryption.
+ */
+ crypto_wipe(key, 32);
+ crypto_wipe(&ctx, sizeof(ctx));
+} else {
+ /* ...do something with the decrypted text here... */
+ /* Finally, wipe secrets if they are no longer needed */
+ crypto_wipe(plain_text, 12);
+ crypto_wipe(key, 32);
+ crypto_wipe(&ctx, sizeof(ctx));
+}
+.Ed
+.Sh SEE ALSO
+.Xr crypto_x25519 3monocypher ,
+.Xr crypto_wipe 3monocypher ,
+.Xr intro 3monocypher
+.Sh STANDARDS
+These functions implement RFC 8439.
+.Fn crypto_aead_lock
+and
+.Fn crypto_aead_init_x ,
+use XChaCha20 instead of ChaCha20.
+.Fn crypto_aead_init_djb
+uses a 64-bit nonce and a 64-bit counter.
+.Fn crypto_aead_init_ietf
+is fully compatible with the RFC.
+Note that XChaCha20 derives from ChaCha20 the same way XSalsa20 derives
+from Salsa20 and benefits from the same security reduction
+(proven secure as long as ChaCha20 itself is secure).
+.Pp
+.Fn crypto_aead_read
+and
+.Fn crypto_aead_write
+preserve the nonce and counter defined in
+.Fn crypto_aead_init_x ,
+.Fn crypto_aead_init_djb ,
+or
+.Fn crypto_aead_init_ietf ,
+and instead change the session key.
+The new session key is made from bytes [32..63] of the ChaCha20 stream
+used to generate the authentication key and encrypt the message.
+(Recall that bytes [0..31] are the authentication key, and bytes [64..]
+are used to encrypt the message.)
+.Sh HISTORY
+The
+.Fn crypto_lock
+and
+.Fn crypto_unlock
+functions first appeared in Monocypher 0.1.
+.Fn crypto_lock_aead
+and
+.Fn crypto_unlock_aead
+were introduced in Monocypher 1.1.0.
+In Monocypher 2.0.0, the underlying algorithms for these functions were
+changed from a custom XChaCha20/Poly1305 construction to an
+implementation of RFC 7539 (now RFC 8439) with XChaCha20 instead of
+ChaCha20.
+The
+.Fn crypto_lock_encrypt
+and
+.Fn crypto_lock_auth
+functions were removed in Monocypher 2.0.0.
+In Monocypher 4.0.0, the
+.Fn crypto_lock
+and
+.Fn crypto_unlock
+were removed,
+Functions were renamed and arguments reordered for consistency,
+and the incremental interface was added.
+.Sh CAVEATS
+Monocypher does not perform any input validation.
+Any deviation from the specified input and output length ranges results
+in
+.Sy undefined behaviour .
+Make sure your inputs are correct.
diff --git a/lib/Utils.Cryptography/monocypher/vendor/doc/crypto_argon2.3monocypher b/lib/Utils.Cryptography/monocypher/vendor/doc/crypto_argon2.3monocypher
new file mode 100644
index 0000000..a84f3d9
--- /dev/null
+++ b/lib/Utils.Cryptography/monocypher/vendor/doc/crypto_argon2.3monocypher
@@ -0,0 +1,400 @@
+.\" This file is dual-licensed. Choose whichever you want.
+.\"
+.\" The first licence is a regular 2-clause BSD licence. The second licence
+.\" is the CC-0 from Creative Commons. It is intended to release Monocypher
+.\" to the public domain. The BSD licence serves as a fallback option.
+.\"
+.\" SPDX-License-Identifier: BSD-2-Clause OR CC0-1.0
+.\"
+.\" ----------------------------------------------------------------------------
+.\"
+.\" Copyright (c) 2017-2019, 2023 Loup Vaillant
+.\" Copyright (c) 2018 Michael Savage
+.\" Copyright (c) 2017, 2019-2021, 2023 Fabio Scotoni
+.\" 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 COPYRIGHT HOLDERS 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 COPYRIGHT
+.\" HOLDER 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.
+.\"
+.\" ----------------------------------------------------------------------------
+.\"
+.\" Written in 2017-2021, 2023 by Loup Vaillant, Michael Savage and Fabio Scotoni
+.\"
+.\" To the extent possible under law, the author(s) have dedicated all copyright
+.\" and related 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
+.\" <https://creativecommons.org/publicdomain/zero/1.0/>
+.\"
+.Dd February 25, 2023
+.Dt CRYPTO_ARGON2 3MONOCYPHER
+.Os
+.Sh NAME
+.Nm crypto_argon2
+.Nd password-based key derivation
+.Sh SYNOPSIS
+.In monocypher.h
+.Ft void
+.Fo crypto_argon2
+.Fa "uint8_t *hash"
+.Fa "uint32_t hash_size"
+.Fa "void *work_area"
+.Fa "crypto_argon2_config config"
+.Fa "crypto_argon2_inputs inputs"
+.Fa "crypto_argon2_extras extras"
+.Fc
+.Pp
+.Fa "extern const crypto_argon2_extras crypto_argon2_no_extras;"
+.Sh DESCRIPTION
+Argon2 is a resource intensive password-based key derivation scheme
+optimised for the typical x86-like processor.
+It runs in constant time with respect to the contents of the password.
+.Pp
+Typical applications are password checking (for online services) and
+key derivation (for encryption).
+Derived keys can be used to encrypt, for example, private keys or
+password databases.
+.Pp
+The version provided by Monocypher has no threading support, so the
+degree of parallelism is limited to 1.
+This is considered good enough for most purposes.
+.Pp
+The arguments to
+.Fn crypto_argon2
+are:
+.Bl -tag -width Ds
+.It Fa hash
+The output hash.
+If all parameters to
+.Fn crypto_argon2
+are identical between two calls,
+then the output
+.Fa hash
+is also identical.
+In other words, all input parameters passed to the function influence
+the output value.
+.It Fa hash_size
+Length of
+.Fa hash ,
+in bytes.
+This argument should be set to 32 or 64 for compatibility with the
+.Xr crypto_verify32 3monocypher
+or
+.Xr crypto_verify64 3monocypher
+constant time comparison functions.
+.It Fa work_area
+Temporary buffer for the algorithm, allocated by the caller.
+It must be
+.Fa config.nb_blocks
+× 1024 bytes big and suitably aligned for 64-bit integers.
+If you are not sure how to allocate that buffer, just use
+.Xr malloc 3 .
+.Pp
+The work area is automatically wiped by
+.Fn crypto_argon2 .
+.It Fa config
+A struct of type
+.Vt crypto_argon2_config
+that determines the base parameters of this particular
+instance of Argon2.
+These are domain parameters and remain constant between
+multiple invocations of
+.Fn crypto_argon2 .
+.It Fa inputs
+A struct of type
+.Vt crypto_argon2_inputs
+that contains the actual input parameters.
+.It Fa extras
+A struct of type
+.Vt crypto_argon2_extras
+that contains optional extra input parameters,
+which are not commonly used.
+.El
+.Pp
+The
+.Vt crypto_argon2_config
+struct is defined as follows:
+.Bd -literal -offset indent
+typedef struct {
+ uint32_t algorithm;
+ uint32_t nb_blocks;
+ uint32_t nb_passes;
+ uint32_t nb_lanes;
+} crypto_argon2_config;
+.Ed
+.Pp
+Its members are:
+.Bl -tag -width Ds
+.It Fa algorithm
+This value determines which variant of Argon2 should be used.
+.Dv CRYPTO_ARGON2_D
+indicates Argon2d,
+.Dv CRYPTO_ARGON2_I
+indicates Argon2i,
+.Dv CRYPTO_ARGON2_ID
+indicates Argon2id.
+.It Fa nb_blocks
+The number of blocks for the work area.
+Must be at least 8 ×
+.Fa nb_lanes .
+A value of 100000 (one hundred megabytes) is a good starting point.
+If the computation takes too long, reduce this number.
+If it is too fast, increase it.
+If it is still too fast with all available memory, increase
+.Fa nb_passes .
+.It Fa nb_passes
+The number of passes.
+Must be at least 1.
+A value of 3 is
+.Em strongly
+recommended when using Argon2i;
+any value lower than 3 enables significantly more efficient attacks.
+.It Fa nb_lanes
+The level of parallelism.
+Must be at least 1.
+Since Monocypher does not support threads,
+this does not actually increase the number of threads.
+It is only provided for completeness to match the Argon2 specification.
+Otherwise, leaving it to 1 is strongly recommended.
+.Pp
+Users who want to take actual advantage of parallelism should instead
+call several instances of Argon2 in parallel.
+The
+.Fa extras
+parameter may be used to differentiate the inputs and produce
+independent digests that can be hashed together.
+.El
+.Pp
+The
+.Vt crypto_argon2_inputs
+struct is defined as follows:
+.Bd -literal -offset indent
+typedef struct {
+ const uint8_t *pass;
+ const uint8_t *salt;
+ uint32_t pass_size;
+ uint32_t salt_size;
+} crypto_argon2_inputs;
+.Ed
+.Pp
+Its members are:
+.Bl -tag -width Ds
+.It Fa pass
+The password to hash.
+It should be wiped with
+.Xr crypto_wipe 3monocypher
+after being hashed.
+.It Fa pass_size
+Length of
+.Fa pass ,
+in bytes.
+.It Fa salt
+A password salt.
+This should be filled with random bytes, generated separately for each
+password to be hashed.
+See
+.Xr intro 3monocypher
+for advice about generating random bytes (use the operating system's
+random number generator).
+.It Fa salt_size
+Length of
+.Fa salt ,
+in bytes.
+Must be at least 8.
+16 is recommended.
+.El
+.Pp
+The
+.Vt crypto_argon2_extras
+struct is defined as follows:
+.Bd -literal -offset indent
+typedef struct {
+ const uint8_t *key;
+ const uint8_t *ad;
+ uint32_t key_size;
+ uint32_t ad_size;
+} crypto_argon2_extras;
+.Ed
+.Pp
+Its members are:
+.Bl -tag -width Ds
+.It Fa key
+A key to use in the hash.
+May be
+.Dv NULL
+if
+.Fa key_size
+is zero.
+The key is generally not needed, but it does have some uses.
+In the context of password derivation, it would be stored separately
+from the password database and would remain secret even if an
+attacker were to steal the database.
+Note that changing the key requires rehashing the user's password,
+which can only be done when the user logs in.
+.It Fa key_size
+Length of
+.Fa key ,
+in bytes.
+Must be zero if there is no key.
+.It Fa ad
+Additional data.
+May be
+.Dv NULL
+if
+.Fa ad_size
+is zero.
+This is additional data that goes into the hash, similar to the
+authenticated encryption construction in
+.Xr crypto_aead_lock 3monocypher .
+Can be used to differentiate inputs when invoking several Argon2
+instances in parallel:
+each instance gets a different thread number as additional data,
+generating as many independent digests as we need.
+We can then hash those digests with
+.Xr crypto_blake2b 3monocypher .
+.It Fa ad_size
+Length of
+.Fa ad ,
+in bytes.
+Must be zero if there is no additional data.
+.El
+.Pp
+The arguments in the
+.Fa config
+and
+.Fa extras
+structs may overlap or point at the same buffer.
+.Pp
+Use
+.Xr crypto_verify16 3monocypher ,
+.Xr crypto_verify32 3monocypher ,
+or
+.Xr crypto_verify64 3monocypher
+to compare password hashes to prevent timing attacks.
+.Pp
+To select the
+.Fa nb_blocks
+and
+.Fa nb_passes
+parameters, it should first be decided how long the computation should
+take.
+For user authentication, values somewhere between half a second
+(convenient) and several seconds (paranoid) are recommended.
+The computation should use as much memory as can be spared.
+.Pp
+Since parameter selection depends on your hardware, some trial and error
+will be required in order to determine the ideal settings.
+Argon2i with three iterations and 100000 blocks
+(one hundred megabytes of memory)
+is a good starting point.
+So is Argon2id with one iteration and 300000 blocks.
+Adjust
+.Fa nb_blocks
+first.
+If using all available memory is not slow enough, increase
+.Fa nb_passes .
+.Sh RETURN VALUES
+.Fn crypto_argon2
+returns nothing.
+.Sh EXAMPLES
+The following example assumes the existence of
+.Fn arc4random_buf ,
+which fills the given buffer with cryptographically secure random bytes.
+If
+.Fn arc4random_buf
+does not exist on your system, see
+.Xr intro 3monocypher
+for advice about how to generate cryptographically secure random bytes.
+.Pp
+This example shows how to hash a password with the recommended baseline
+parameters:
+.Bd -literal -offset indent
+uint8_t hash[32]; /* Output hash */
+uint8_t salt[16]; /* Random salt */
+crypto_argon2_config config = {
+ .algorithm = CRYPTO_ARGON2_I, /* Argon2i */
+ .nb_blocks = 100000, /* 100 megabytes */
+ .nb_passes = 3, /* 3 iterations */
+ .nb_lanes = 1 /* Single-threaded */
+};
+uint8_t password[] = "Okay Password!";
+crypto_argon2_inputs inputs = {
+ .pass = password, /* User password */
+ .salt = salt, /* Salt for the password */
+ .pass_size = sizeof(password) - 1, /* Password length */
+ .salt_size = 16
+};
+crypto_argon2_extras extras = {0}; /* Extra parameters unused */
+
+/* Allocate work area.
+ * Note the conversion to size_t.
+ * Without it we cannot allocate more than 4GiB.
+ */
+void *work_area = malloc((size_t)config.nb_blocks * 1024);
+if (work_area == NULL) {
+ /* Handle malloc() failure */
+ /* Wipe secrets if they are no longer needed */
+ crypto_wipe(password, sizeof(password));
+} else {
+ arc4random_buf(salt, 16);
+ crypto_argon2(hash, 32, work_area,
+ config, inputs, extras);
+ /* Wipe secrets if they are no longer needed */
+ crypto_wipe(password, sizeof(password));
+ free(work_area);
+}
+
+
+.Ed
+.Sh SEE ALSO
+.Xr crypto_aead_lock 3monocypher ,
+.Xr crypto_verify16 3monocypher ,
+.Xr crypto_wipe 3monocypher ,
+.Xr intro 3monocypher
+.Sh STANDARDS
+.Fn crypto_argon2
+implements Argon2 as described in RFC 9106,
+but does not support actual parallelism.
+.Sh HISTORY
+In Monocypher 0.1,
+.Fn crypto_argon2i
+implemented Argon2i and had all extra parameters as input.
+It was then split into a
+.Fn crypto_argon2i_general
+and a simplified
+.Fn crypto_argon2i
+function in Monocypher 1.1.0.
+Both were replaced by
+.Fn crypto_argon2
+in Monocypher 4.0.0.
+.Sh CAVEATS
+Monocypher does not perform any input validation.
+Any deviation from the algorithm constants,
+specified input and output length ranges results
+in
+.Sy undefined behaviour .
+Make sure your inputs are correct.
diff --git a/lib/Utils.Cryptography/monocypher/vendor/doc/crypto_blake2b.3monocypher b/lib/Utils.Cryptography/monocypher/vendor/doc/crypto_blake2b.3monocypher
new file mode 100644
index 0000000..86ff25b
--- /dev/null
+++ b/lib/Utils.Cryptography/monocypher/vendor/doc/crypto_blake2b.3monocypher
@@ -0,0 +1,544 @@
+.\" This file is dual-licensed. Choose whichever you want.
+.\"
+.\" The first licence is a regular 2-clause BSD licence. The second licence
+.\" is the CC-0 from Creative Commons. It is intended to release Monocypher
+.\" to the public domain. The BSD licence serves as a fallback option.
+.\"
+.\" SPDX-License-Identifier: BSD-2-Clause OR CC0-1.0
+.\"
+.\" ----------------------------------------------------------------------------
+.\"
+.\" Copyright (c) 2017-2023 Loup Vaillant
+.\" Copyright (c) 2018 Michael Savage
+.\" Copyright (c) 2017, 2020-2023 Fabio Scotoni
+.\" 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 COPYRIGHT HOLDERS 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 COPYRIGHT
+.\" HOLDER 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.
+.\"
+.\" ----------------------------------------------------------------------------
+.\"
+.\" Written in 2017-2023 by Loup Vaillant, Michael Savage and Fabio Scotoni
+.\"
+.\" To the extent possible under law, the author(s) have dedicated all copyright
+.\" and related 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
+.\" <https://creativecommons.org/publicdomain/zero/1.0/>
+.\"
+.Dd February 2, 2023
+.Dt CRYPTO_BLAKE2B 3MONOCYPHER
+.Os
+.Sh NAME
+.Nm crypto_blake2b ,
+.Nm crypto_blake2b_keyed ,
+.Nm crypto_blake2b_init ,
+.Nm crypto_blake2b_keyed_init ,
+.Nm crypto_blake2b_update ,
+.Nm crypto_blake2b_final
+.Nd hashing, message authentication, and key derivation with BLAKE2b
+.Sh SYNOPSIS
+.In monocypher.h
+.Ft void
+.Fo crypto_blake2b
+.Fa "uint8_t hash[64]"
+.Fa "size_t hash_size"
+.Fa "const uint8_t *message"
+.Fa "size_t message_size"
+.Fc
+.Fo crypto_blake2b_keyed
+.Fa "uint8_t hash[64]"
+.Fa "size_t hash_size"
+.Fa "uint8_t key[64]"
+.Fa "size_t key_size"
+.Fa "const uint8_t *message"
+.Fa "size_t message_size"
+.Fc
+.Ft void
+.Fo crypto_blake2b_init
+.Fa "crypto_blake2b_ctx *ctx"
+.Fa "size_t hash_size"
+.Fc
+.Ft void
+.Fo crypto_blake2b_keyed_init
+.Fa "crypto_blake2b_ctx *ctx"
+.Fa "size_t hash_size"
+.Fa "uint8_t key[64]"
+.Fa "size_t key_size"
+.Fc
+.Ft void
+.Fo crypto_blake2b_update
+.Fa "crypto_blake2b_ctx *ctx"
+.Fa "const uint8_t *message"
+.Fa "size_t message_size"
+.Fc
+.Ft void
+.Fo crypto_blake2b_final
+.Fa "crypto_blake2b_ctx *ctx"
+.Fa "uint8_t *hash"
+.Fc
+.Sh DESCRIPTION
+.Ss Hashing
+.Fn crypto_blake2b ,
+.Fn crypto_blake2b_init ,
+.Fn crypto_blake2b_update ,
+and
+.Fn crypto_blake2b_final
+implement BLAKE2b,
+a cryptographically secure hash based on the ideas of ChaCha20.
+It is faster than MD5, yet just as secure as SHA-3.
+.Pp
+Note that BLAKE2b itself is not suitable for hashing passwords and
+deriving keys from them;
+use the
+.Xr crypto_argon2 3monocypher
+family of functions for that purpose instead.
+.Pp
+While BLAKE2b is immune to length extension attacks,
+and as such requires fewer precautions than older hashes,
+we do recommend avoiding prefix-MAC and using keyed mode with
+.Fn crypto_blake2b_keyed
+instead.
+Doing so enables better security arguments when using BLAKE2b as a
+random oracle.
+.Pp
+The arguments are:
+.Bl -tag -width Ds
+.It Fa config
+The configuration parameter structure, see below.
+.It Fa hash
+The output hash.
+.It Fa hash_size
+Length of
+.Fa hash ,
+in bytes.
+Must be between 1 and 64.
+Anything below 32 is discouraged when using BLAKE2b as a general-purpose
+hash function.
+.It Fa message
+The message to hash.
+May overlap with
+.Fa hash .
+May be
+.Dv NULL
+if
+.Fa message_size
+is 0.
+.It Fa message_size
+Length of
+.Fa message ,
+in bytes.
+.El
+.Ss Message authentication codes
+.Fn crypto_blake2b_keyed ,
+.Fn crypto_blake2b_keyed_init ,
+.Fn crypto_blake2b_update ,
+and
+.Fn crypto_blake2b_final
+implement keyed BLAKE2b,
+and can be used for message authentication codes or as a random oracle,
+just like HMAC.
+The arguments are:
+.Bl -tag -width Ds
+.It Fa hash
+The output message authentication code (MAC).
+To avoid timing attacks,
+use
+.Xr crypto_verify16 3monocypher ,
+.Xr crypto_verify32 3monocypher ,
+or
+.Xr crypto_verify64 3monocypher
+to compare (possibly truncated) MACs.
+.It Fa hash_size
+Length of
+.Fa hash ,
+in bytes.
+Must be between 1 and 64.
+Anything below 16 is discouraged when using BLAKE2b as a message
+authentication code.
+Anything below 32 is discouraged when using BLAKE2b as a key derivation
+function (KDF).
+.It Fa key
+Some secret key.
+When uniformly random,
+one cannot predict the final hash without it.
+Users may want to wipe the key with
+.Xr crypto_wipe 3monocypher
+once they are done with it.
+May overlap with
+.Fa hash or
+.Fa message .
+May be
+.Dv NULL
+if
+.Fa key_size
+is 0, in which case no key is used.
+Can also be used as a random salt in the context of KDF extraction,
+or as pre-shared-key in the context of KDF expansion.
+.It Fa key_size
+Length of
+.Fa key ,
+in bytes.
+Must be between 0 and 64.
+32 is a good default.
+.It Fa message
+The message to compute the MAC for.
+May overlap with
+.Fa hash or
+.Fa key .
+May be
+.Dv NULL
+if
+.Fa message_size
+is 0.
+Can also be used as input key material in the context of KDF extraction,
+or to host a counter and domain separation string in the context of KDF
+expansion.
+.It Fa message_size
+Length of
+.Fa message ,
+in bytes.
+.El
+.Ss Key derivation
+BLAKE2b can be used to implement
+.Dq key derivation functions
+(KDF) very similar to HKDF.
+The typical parameters of a KDF are:
+.Bl -tag -width Ds
+.It Em IKM
+Input key material containing enough secret entropy to derive uniformly
+random keys from,
+such as the shared secret of a key exchange performed with
+.Xr crypto_x25519 3monocypher .
+Passwords do
+.Sy not
+contain enough entropy to be used as input key material.
+Hash them with
+.Xr crypto_argon2 3monocypher
+instead.
+.It Em salt
+An optional random salt,
+used to increase the security of the output key material (OKM) in some
+settings.
+It should be either absent,
+constant,
+or contain at least 16 random bytes.
+.It Em info
+Optional domain separation string for key derivation.
+.El
+.Pp
+From these parameters,
+the KDF derives an arbitrary amount of independent random bytes,
+also called
+.Dq output key material
+(OKM),
+that can be used as regular encryption or secret keys.
+.Pp
+In practice, KDFs are often separated in two steps:
+.Dq extraction
+and
+.Dq expansion .
+The extraction step reads the IKM (and optional salt) to derive a
+.Dq pseudo-random key
+(PRK),
+which can be used either directly as a regular key,
+.Em or
+as an input for the extraction step.
+The expansion step then reads the PRK (and optional info) to make the
+OKM.
+.Pp
+To implement KDF extraction,
+just call
+.Fn crypto_blake2b_keyed
+with the
+.Fa message
+as the IKM and
+.Fa key
+as the salt,
+or
+.Fn crypto_blake2b
+if there is no salt.
+This is unintuitive,
+but having the IKM in the
+.Fa message
+argument lets us input arbitrary amounts of data.
+It is also the HMAC and HKDF way.
+.Pp
+For KDF expansion any pseudo-random-function (PRF) can be used.
+You can call
+.Fn crypto_blake2b_keyed
+in counter mode with
+.Fa key
+as the PRK
+(though doing it manually is a bit tedious),
+or
+.Xr crypto_chacha20_djb 3monocypher
+with its
+.Fa key
+as the PRK and its
+.Fa nonce
+for domain separation.
+.Ss Incremental interface
+An incremental interface is provided.
+It is useful for handling streams of data or
+large files without using too much memory.
+This interface uses three steps:
+.Bl -bullet
+.It
+Initialisation with
+.Fn crypto_blake2b_init
+or
+.Fn crypto_blake2b_keyed_init ,
+which set up a context with the hashing parameters;
+.It
+Update with
+.Fn crypto_blake2b_update ,
+which hashes the message chunk by chunk and keeps the intermediary
+result in the context;
+.It
+and Finalisation with
+.Fn crypto_blake2b_final ,
+which produces the final hash.
+The
+.Ft crypto_blake2b_ctx
+is automatically wiped upon finalisation.
+.El
+.Pp
+Calling
+.Fn crypto_blake2b
+is the same as calling
+.Fn crypto_blake2b_init ,
+.Fn crypto_blake2b_update ,
+and
+.Fn crypto_blake2b_final .
+Calling
+.Fn crypto_blake2b_keyed
+is the same as calling
+.Fn crypto_blake2b_keyed_init ,
+.Fn crypto_blake2b_update ,
+and
+.Fn crypto_blake2b_final .
+.Pp
+Calling
+.Fn crypto_blake2b
+is the same as calling
+.Fn crypto_blake2b_keyed
+with an empty key.
+.Sh RETURN VALUES
+These functions return nothing.
+.Sh EXAMPLES
+The following examples assume the existence of
+.Fn arc4random_buf ,
+which fills the given buffer with cryptographically secure random bytes.
+If
+.Fn arc4random_buf
+does not exist on your system, see
+.Xr intro 3monocypher
+for advice about how to generate cryptographically secure random bytes.
+.Pp
+Hashing a message all at once:
+.Bd -literal -offset indent
+uint8_t hash [64]; /* Output hash (64 bytes) */
+uint8_t message[12] = "Lorem ipsum"; /* Message to hash */
+crypto_blake2b(hash, sizeof(hash), message, sizeof(message));
+.Ed
+.Pp
+Computing a message authentication code all at once:
+.Bd -literal -offset indent
+uint8_t hash [16];
+uint8_t key [32];
+uint8_t message[11] = "Lorem ipsu"; /* Message to authenticate */
+arc4random_buf(key, sizeof(key));
+crypto_blake2b_keyed(hash , sizeof(hash),
+ key , sizeof(key),
+ message, sizeof(message));
+/* Wipe secrets if they are no longer needed */
+crypto_wipe(message, sizeof(message));
+crypto_wipe(key, sizeof(key));
+.Ed
+.Pp
+Hashing a message incrementally (without a key):
+.Bd -literal -offset indent
+uint8_t hash [ 64]; /* Output hash (64 bytes) */
+uint8_t message[500] = {1}; /* Message to hash */
+crypto_blake2b_ctx ctx;
+crypto_blake2b_init(&ctx, sizeof(hash));
+for (size_t i = 0; i < 500; i += 100) {
+ crypto_blake2b_update(&ctx, message + i, 100);
+}
+crypto_blake2b_final(&ctx, hash);
+.Ed
+.Pp
+Computing a message authentication code incrementally:
+.Bd -literal -offset indent
+uint8_t hash [ 16];
+uint8_t key [ 32];
+uint8_t message[500] = {1}; /* Message to authenticate */
+arc4random_buf(key, sizeof(key));
+crypto_blake2b_ctx ctx;
+crypto_blake2b_keyed_init(&ctx, sizeof(hash), key,
+ sizeof(key));
+/* Wipe the key */
+crypto_wipe(key, sizeof(key));
+for (size_t i = 0; i < 500; i += 100) {
+ crypto_blake2b_update(&ctx, message + i, 100);
+ /* Wipe secrets if they are no longer needed */
+ crypto_wipe(message + i, 100);
+}
+crypto_blake2b_final(&ctx, hash);
+.Ed
+.Pp
+Computing key derivation with BLAKE2b and ChaCha20:
+.Bd -literal -offset indent
+void kdf(uint8_t *okm, size_t okm_size, /* unlimited */
+ uint8_t *ikm, size_t ikm_size, /* unlimited */
+ uint8_t *salt, size_t salt_size, /* <= 64 bytes */
+ uint8_t info[8]) /* == 8 bytes */
+{
+ /* Extract */
+ uint8_t prk[32];
+ crypto_blake2b_keyed(prk , sizeof(prk),
+ salt, salt_size,
+ ikm , ikm_size);
+ /* Expand */
+ crypto_chacha20_djb(okm, NULL, okm_size, prk, info, 0);
+}
+.Ed
+.Pp
+Computing key derivation with BLAKE2b and XChaCha20:
+.Bd -literal -offset indent
+void xkdf(uint8_t *okm, size_t okm_size, /* unlimited */
+ uint8_t *ikm, size_t ikm_size, /* unlimited */
+ uint8_t *salt, size_t salt_size, /* <= 64 bytes */
+ uint8_t *info, size_t info_size) /* unlimited */
+{
+ /* Extract */
+ uint8_t prk[32];
+ crypto_blake2b_keyed(prk , sizeof(prk),
+ salt, salt_size,
+ ikm , ikm_size);
+ /* Expand */
+ uint8_t nonce[24];
+ crypto_blake2b(nonce, sizeof(nonce), info, info_size);
+ crypto_chacha20_x(okm, NULL, okm_size, prk, nonce, 0);
+}
+.Ed
+.Pp
+Computing key derivation with BLAKE2b alone
+(a little tedious indeed):
+.Bd -literal -offset indent
+#define MIN(a, b) ((a) < (b) ? (a) : (b))
+
+void b2kdf(uint8_t *okm, size_t okm_size, /* unlimited */
+ uint8_t *ikm, size_t ikm_size, /* unlimited */
+ uint8_t *salt, size_t salt_size, /* <= 64 bytes */
+ uint8_t *info, size_t info_size) /* unlimited */
+{
+ /* Extract */
+ uint8_t prk[64];
+ crypto_blake2b_keyed(prk , sizeof(prk),
+ salt, salt_size,
+ ikm , ikm_size);
+ /* Expand */
+ uint8_t ctr[8] = {0};
+ while(okm_size > 0) {
+ size_t size = MIN(okm_size, 64);
+ crypto_blake2b_ctx ctx;
+ crypto_blake2b_keyed_init(&ctx, size, prk, 64);
+ crypto_blake2b_update(&ctx, ctr, sizeof(ctr));
+ crypto_blake2b_update(&ctx, info, info_size);
+ crypto_blake2b_final(&ctx, okm);
+ okm += size;
+ okm_size -= size;
+ /* increment ctr */
+ unsigned acc = 1;
+ for (size_t i = 0; i < sizeof(ctr); i++) {
+ acc = ctr[i] + acc;
+ ctr[i] = acc & 0xff;
+ acc >>= 8;
+ }
+ }
+}
+.Ed
+.Sh SEE ALSO
+.Xr crypto_x25519 3monocypher ,
+.Xr crypto_aead_lock 3monocypher ,
+.Xr intro 3monocypher
+.Sh STANDARDS
+These functions implement BLAKE2b, described in RFC 7693.
+.Sh HISTORY
+The
+.Fn crypto_blake2b ,
+.Fn crypto_blake2b_init ,
+.Fn crypto_blake2b_update ,
+and
+.Fn crypto_blake2b_final
+functions first appeared in Monocypher 0.1.
+In Monocypher 4.0.0,
+.Fn crypto_blake2b_general
+and
+.Fn crypto_blake2b_general_init
+were removed,
+.Fn crypto_blake2b_keyed
+and
+.Fn crypto_blake2b_keyed_init
+were added,
+and the
+.Fa hash_size
+argument were added to
+.Fn crypto_blake2b
+and
+.Fn crypto_blake2b_init .
+.Sh CAVEATS
+Monocypher does not perform any input validation.
+Any deviation from the specified input and output length ranges results
+in
+.Sy undefined behaviour .
+Make sure your inputs are correct.
+.Sh SECURITY CONSIDERATIONS
+BLAKE2b is a general-purpose cryptographic hash function;
+this means that it is not suited for hashing passwords and deriving
+cryptographic keys from passwords.
+While cryptographic keys usually have hundreds of bits of entropy,
+passwords are often much less complex.
+When storing passwords as hashes or when deriving keys from them,
+the goal is normally to prevent attackers from quickly iterating all
+possible passwords.
+Because passwords tend to be simple,
+it is important to artificially slow down attackers by using
+computationally difficult hashing algorithms.
+Monocypher therefore provides
+.Xr crypto_argon2 3monocypher
+for password hashing and deriving keys from passwords.
+.Sh IMPLEMENTATION DETAILS
+The core loop is unrolled by default.
+This speeds up BLAKE2b by about 20% on modern processors.
+On the other hand,
+this inflates the binary size by several kilobytes,
+and is slower on some embedded platforms.
+To roll the loop and generate a smaller binary,
+compile Monocypher with the -DBLAKE2_NO_UNROLLING option.
diff --git a/lib/Utils.Cryptography/monocypher/vendor/doc/crypto_chacha20_djb.3monocypher b/lib/Utils.Cryptography/monocypher/vendor/doc/crypto_chacha20_djb.3monocypher
new file mode 100644
index 0000000..84bcff2
--- /dev/null
+++ b/lib/Utils.Cryptography/monocypher/vendor/doc/crypto_chacha20_djb.3monocypher
@@ -0,0 +1,447 @@
+.\" This file is dual-licensed. Choose whichever you want.
+.\"
+.\" The first licence is a regular 2-clause BSD licence. The second licence
+.\" is the CC-0 from Creative Commons. It is intended to release Monocypher
+.\" to the public domain. The BSD licence serves as a fallback option.
+.\"
+.\" SPDX-License-Identifier: BSD-2-Clause OR CC0-1.0
+.\"
+.\" ----------------------------------------------------------------------------
+.\"
+.\" Copyright (c) 2017-2019, 2023 Loup Vaillant
+.\" Copyright (c) 2017-2018 Michael Savage
+.\" Copyright (c) 2017, 2019-2021, 2023 Fabio Scotoni
+.\" 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 COPYRIGHT HOLDERS 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 COPYRIGHT
+.\" HOLDER 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.
+.\"
+.\" ----------------------------------------------------------------------------
+.\"
+.\" Written in 2017-2023 by Loup Vaillant, Michael Savage and Fabio Scotoni
+.\"
+.\" To the extent possible under law, the author(s) have dedicated all copyright
+.\" and related 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
+.\" <https://creativecommons.org/publicdomain/zero/1.0/>
+.\"
+.Dd February 25, 2023
+.Dt CRYPTO_CHACHA20 3MONOCYPHER
+.Os
+.Sh NAME
+.Nm crypto_chacha20_djb ,
+.Nm crypto_chacha20_ietf ,
+.Nm crypto_chacha20_x ,
+.Nm crypto_chacha20_h
+.Nd ChaCha20 and XChaCha20 encryption functions
+.Sh SYNOPSIS
+.In monocypher.h
+.Ft uint64_t
+.Fo crypto_chacha20_djb
+.Fa "uint8_t *cipher_text"
+.Fa "const uint8_t *plain_text"
+.Fa "size_t text_size"
+.Fa "const uint8_t key[32]"
+.Fa "const uint8_t nonce[8]"
+.Fa "uint64_t ctr"
+.Fc
+.Ft uint32_t
+.Fo crypto_chacha20_ietf
+.Fa "uint8_t *cipher_text"
+.Fa "const uint8_t *plain_text"
+.Fa "size_t text_size"
+.Fa "const uint8_t key[32]"
+.Fa "const uint8_t nonce[12]"
+.Fa "uint32_t ctr"
+.Fc
+.Ft uint64_t
+.Fo crypto_chacha20_x
+.Fa "uint8_t *cipher_text"
+.Fa "const uint8_t *plain_text"
+.Fa "size_t text_size"
+.Fa "const uint8_t key[32]"
+.Fa "const uint8_t nonce[24]"
+.Fa "uint64_t ctr"
+.Fc
+.Ft void
+.Fo crypto_chacha20_h
+.Fa "uint8_t out[32]"
+.Fa "const uint8_t key[32]"
+.Fa "const uint8_t in[16]"
+.Fc
+.Sh DESCRIPTION
+These functions provide an interface for the ChaCha20 encryption
+primitive.
+.Pp
+ChaCha20 is a low-level primitive.
+Consider using authenticated encryption, implemented by
+.Xr crypto_aead_lock 3monocypher .
+.Pp
+The arguments are:
+.Bl -tag -width Ds
+.It Fa key
+A 32-byte secret key.
+.It Fa nonce
+An 8-byte, 12-byte, or 24-byte number used only once with any given key.
+It does not need to be secret or random, but it does have to be unique.
+Repeating a nonce with the same key reveals the XOR of two different
+messages, which allows decryption.
+24-byte nonces can be selected at random.
+8-byte and 12-byte nonces
+.Em cannot
+because they are too small and the same nonce may be selected twice by
+accident.
+See
+.Xr intro 3monocypher
+for advice about generating random numbers (use the operating system's
+random number generator).
+.It Fa plain_text
+The message to encrypt.
+It is allowed to be
+.Dv NULL ,
+in which case it will be interpreted as an all-zero input.
+.Fa cipher_text
+will then contain the raw ChaCha20 stream.
+.It Fa cipher_text
+The encrypted message.
+.It Fa text_size
+Length of both
+.Fa plain_text
+and
+.Fa cipher_text ,
+in bytes.
+.It Fa ctr
+The number of 64-byte blocks we skip from the beginning of the stream.
+This can be used to encrypt (or decrypt) part of a long message or to
+implement some AEAD constructions such as the one described in RFC
+8439.
+Should be zero by default.
+When using this, be careful not to accidentally reuse parts of the
+random stream as that would destroy confidentiality.
+The return value can help here.
+.El
+.Pp
+The
+.Fa key
+and
+.Fa nonce
+buffers may overlap.
+.Fa plain_text
+and
+.Fa cipher_text
+must either be the same buffer (for in-place encryption) or
+non-overlapping.
+.Pp
+.Fn crypto_chacha20_djb ,
+.Fn crypto_chacha20_ietf ,
+and
+.Fn crypto_chacha20_x
+perform a ChaCha20 operation.
+Their main difference is the size of their nonce and counter.
+.Fn crypto_chacha20_ietf
+in particular implements RFC 8439,
+and is provided strictly for compatibility with existing systems or
+standards compliance.
+.Pp
+.Fn crypto_chacha20_x
+Is the only function that uses a nonce long enough to be random.
+This makes it easier to use securely,
+and the performance hit of the extended nonce is often negligible in
+practice.
+Use it instead of
+.Fn crypto_chacha20_djb
+and
+.Fn crypto_chacha20_ietf
+if possible.
+.Pp
+The
+.Fn crypto_chacha20_djb ,
+.Fn crypto_chacha20_ietf ,
+and
+.Fn crypto_chacha20_x
+encrypt
+.Fa plain_text
+by XORing it with a pseudo-random stream of
+numbers, seeded by the provided
+.Fa key
+and
+.Fa nonce .
+.Pp
+Since XOR is its own inverse, decryption is the same operation as
+encryption.
+To decrypt the cipher text,
+.Dq encrypt
+it again with the same key and nonce.
+You will likely want to wipe the key when you are done with
+encryption or decryption.
+Use
+.Xr crypto_wipe 3monocypher
+to wipe them.
+.Pp
+The
+.Fa plain_text
+pointer is allowed to be
+.Dv NULL ,
+in which case it will be interpreted as an all-zero input.
+This is useful as a user space random number generator.
+While
+.Sy this should not be used as a random number generator for secrets ,
+for which the operating system random number generator should be
+preferred,
+it can be handy outside of a security context.
+Deterministic procedural generation and reproducible property-based
+tests come to mind.
+Additionally, it
+.Em can
+be used to generate large amounts of random-looking data quickly
+\(en for example to generate padding.
+.Sh RETURN VALUES
+.Fn crypto_chacha20_djb ,
+.Fn crypto_chacha20_ietf ,
+and
+.Fn crypto_chacha20_x
+return the next
+.Fa ctr
+to use with the same key and nonce values;
+this is the previous
+.Fa ctr ,
+plus
+.Fa text_size
+divided by 64 (rounded up).
+.Sh EXAMPLES
+The following examples assume the existence of
+.Fn arc4random_buf ,
+which fills the given buffer with cryptographically secure random bytes.
+If
+.Fn arc4random_buf
+does not exist on your system, see
+.Xr intro 3monocypher
+for advice about how to generate cryptographically secure random bytes.
+.Pp
+Simple encryption:
+.Bd -literal -offset indent
+uint8_t key [ 32]; /* Secret random key */
+uint8_t nonce [ 24]; /* Unique nonce (possibly random) */
+uint8_t plain_text [500] = {1}; /* Secret message */
+uint8_t cipher_text[500]; /* Encrypted message */
+arc4random_buf(key, 32);
+arc4random_buf(nonce, 24);
+crypto_chacha20_x(cipher_text, plain_text, 500, key, nonce, 0);
+/* Wipe secrets if they are no longer needed */
+crypto_wipe(key, 32);
+crypto_wipe(plain_text, 500);
+.Ed
+.Pp
+To decrypt the above:
+.Bd -literal -offset indent
+uint8_t key [ 32]; /* Same key as above */
+const uint8_t nonce [ 24]; /* Same nonce as above */
+uint8_t plain_text [500]; /* Message to decrypt */
+uint8_t cipher_text[500]; /* Secret message */
+crypto_chacha20_x(cipher_text, plain_text, 500, key, nonce, 0);
+/* Wipe secrets if they are no longer needed */
+crypto_wipe(key, 32);
+/* The plaintext likely needs to be processed before you wipe it */
+crypto_wipe(plain_text, 12);
+.Ed
+.Pp
+Incremental encryption (in blocks of 64 bytes):
+.Bd -literal -offset indent
+uint8_t key [ 32]; /* Secret random key */
+uint8_t nonce [ 24]; /* Unique nonce (possibly random) */
+uint8_t plain_text [500]; /* Secret message */
+uint8_t cipher_text[500]; /* Encrypted message */
+uint64_t ctr = 0; /* Block counter */
+unsigned int i;
+arc4random_buf(key, 32);
+arc4random_buf(nonce, 24);
+for(i = 0; i < 500; i += 64) {
+ ctr = crypto_chacha20_x(cipher_text+i, plain_text+i, 64,
+ key, nonce, ctr);
+}
+/* Process data that didn't fit into 64-byte pieces */
+crypto_chacha20_x(cipher_text+500-(i-64),
+ plain_text+500-(i-64),
+ 500-(i-64),
+ key, nonce, ctr);
+/* Wipe secrets if they are no longer needed */
+crypto_wipe(key, 32);
+crypto_wipe(plain_text, 500);
+.Ed
+.Pp
+Encryption by jumping around (do not do this, this is only meant to show
+how the counter works):
+.Bd -literal -offset indent
+uint8_t key [ 32]; /* Secret random key */
+uint8_t nonce [ 24]; /* Unique nonce (possibly random) */
+uint8_t plain_text [500] = {1}; /* Message to be encrypted */
+uint8_t cipher_text[500]; /* Will be the encrypted message */
+arc4random_buf(key, 32);
+arc4random_buf(nonce, 24);
+/* Encrypt the second part of the message first... */
+crypto_chacha20_x(cipher_text + (3 * 64),
+ plain_text + (3 * 64),
+ 500 - (3 * 64),
+ key, nonce, 3);
+/* ...then encrypt the first part */
+crypto_chacha20_x(cipher_text, plain_text, 3 * 64, key, nonce, 0);
+/* Wipe secrets if they are no longer needed */
+crypto_wipe(key, 32);
+crypto_wipe(plain_text, 500);
+.Ed
+.Sh HCHACHA20
+.Fn crypto_chacha20_h
+provides a not-so-cryptographic hash.
+.Sy This is not a general-purpose cryptographic hash function .
+It may be used for some specific purposes such as X25519 key
+derivation or XChaCha20 initialisation.
+If in doubt, do not use directly.
+Use
+.Xr crypto_blake2b 3monocypher
+instead.
+.Pp
+The arguments are:
+.Bl -tag -width Ds
+.It Fa key
+A sufficiently random key, such as the output of
+.Xr crypto_x25519 3monocypher .
+.It Fa in
+The space reserved for the ChaCha20 nonce and counter.
+It does not have to be random.
+.It Fa out
+A cryptographically secure random number
+.Em if
+there is enough entropy in
+.Fa key .
+X25519 shared secrets have enough entropy.
+.El
+.Pp
+For instance:
+.Bd -literal -offset indent
+uint8_t key[32]; /* Must have enough entropy */
+uint8_t in [16]; /* Does not have to be random */
+uint8_t out[32]; /* Will be random iff the above holds */
+arc4random_buf(key, 32);
+crypto_chacha20_h(out, key, in);
+/* Wipe secrets if they are no longer needed */
+crypto_wipe(key, 32);
+crypto_wipe(in , 16);
+.Ed
+.Sh SEE ALSO
+.Xr crypto_aead_lock 3monocypher ,
+.Xr crypto_wipe 3monocypher ,
+.Xr intro 3monocypher
+.Sh STANDARDS
+These functions implement ChaCha20, XChaCha20, and HChaCha20.
+ChaCha20 is described in:
+.Rs
+.%A Daniel J. Bernstein
+.%J SASC 2008 \(en The State of the Art of Stream Ciphers
+.%P pp. 273\(en278
+.%T ChaCha, a variant of Salsa20
+.Re
+The nonce and counter sizes were modified in RFC 8439.
+XChaCha20 derives from ChaCha20 the same way XSalsa20 derives from
+Salsa20 and benefits from the same security reduction (proven secure
+as long as ChaCha20 itself is secure).
+.Sh HISTORY
+.Fn crypto_chacha20 ,
+.Fn crypto_chacha20_ctr ,
+.Fn crypto_ietf_chacha20 ,
+.Fn crypto_ietf_chacha20_ctr ,
+.Fn crypto_xchacha20 ,
+and
+.Fn crypto_xchacha20_ctr
+were added in Monocypher 3.0.0.
+They replace
+.Fn crypto_chacha20_encrypt ,
+.Fn crypto_chacha20_init ,
+.Fn crypto_chacha20_stream ,
+.Fn crypto_chacha20_x_init ,
+and
+.Fn crypto_chacha20_set_ctr
+that were deprecated in Monocypher 3.0.0.
+In Monocypher 4.0.0, only the ctr variants have been kept,
+and were renamed
+.Fn crypto_chacha20_djb ,
+.Fn crypto_chacha20_ietf ,
+and
+.Fn crypto_chacha20_x
+respectively.
+.Pp
+.Fn crypto_chacha20_h
+function first appeared in Monocypher 0.1 as
+.Fn crypto_chacha20_H .
+It was renamed to
+.Fn crypto_hchacha20
+in Monocypher 3.0.0, then
+.Fn crypto_chacha20_h
+in Monocypher 4.0.0.
+.Sh CAVEATS
+Monocypher does not perform any input validation.
+Any deviation from the specified input and output length ranges results
+in
+.Sy undefined behaviour .
+Make sure your inputs are correct.
+.Sh SECURITY CONSIDERATIONS
+.Ss Encrypted does not mean secure
+ChaCha20 only protects against eavesdropping, not forgeries.
+Most applications need protection against forgeries to be properly
+secure.
+To ensure the integrity of a message, use BLAKE2b in keyed mode or
+authenticated encryption; see
+.Xr crypto_blake2b 3monocypher
+and
+.Xr crypto_aead_lock 3monocypher .
+.Ss Nonce reuse
+Repeating a nonce with the same key exposes the XOR of two or more
+plaintext messages, effectively destroying confidentiality.
+.Pp
+For the same reason,
+.Sy do not select small nonces at random .
+The
+.Fn crypto_chacha20_djb
+nonce spans only 64 bits, which is small enough to trigger accidental
+reuses.
+A message counter should be used instead.
+If multiple parties send out messages,
+each can start with an initial nonce of 0, 1, 2 (...) n-1 respectively,
+and increment them by n for each new message.
+Make sure the counters never wrap around.
+.Ss Secure random number generation
+Do not use these functions as a cryptographic random number generator.
+Always use the operating system's random number generator for
+cryptographic purposes; see
+.Xr intro 3monocypher .
+.Ss Protection against side channels
+Secrets should not dwell in memory longer than needed.
+Use
+.Xr crypto_wipe 3monocypher
+to erase secrets you no longer need.
+For ChaCha20, this means the key and in some cases the
+plaintext itself.
diff --git a/lib/Utils.Cryptography/monocypher/vendor/doc/crypto_ed25519_sign.3monocypher b/lib/Utils.Cryptography/monocypher/vendor/doc/crypto_ed25519_sign.3monocypher
new file mode 100644
index 0000000..6418c94
--- /dev/null
+++ b/lib/Utils.Cryptography/monocypher/vendor/doc/crypto_ed25519_sign.3monocypher
@@ -0,0 +1,189 @@
+.\" This file is dual-licensed. Choose whichever you want.
+.\"
+.\" The first licence is a regular 2-clause BSD licence. The second licence
+.\" is the CC-0 from Creative Commons. It is intended to release Monocypher
+.\" to the public domain. The BSD licence serves as a fallback option.
+.\"
+.\" SPDX-License-Identifier: BSD-2-Clause OR CC0-1.0
+.\"
+.\" ----------------------------------------------------------------------------
+.\"
+.\" Copyright (c) 2019-2020, 2022-2023 Fabio Scotoni
+.\" Copyright (c) 2023 Loup Vaillant
+.\" 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 COPYRIGHT HOLDERS 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 COPYRIGHT
+.\" HOLDER 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.
+.\"
+.\" ----------------------------------------------------------------------------
+.\"
+.\" Written in 2019-2020 and 2022-2023 by Fabio Scotoni and Loup Vaillant
+.\"
+.\" To the extent possible under law, the author(s) have dedicated all copyright
+.\" and related 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
+.\" <https://creativecommons.org/publicdomain/zero/1.0/>
+.\"
+.Dd March 01, 2022
+.Dt CRYPTO_ED25519_SIGN 3MONOCYPHER
+.Os
+.Sh NAME
+.Nm crypto_ed25519_sign ,
+.Nm crypto_ed25519_check ,
+.Nm crypto_ed25519_key_pair ,
+.Nm crypto_ed25519_ph_sign ,
+.Nm crypto_ed25519_ph_check
+.Nd public key signatures
+.Sh SYNOPSIS
+.In monocypher-ed25519.h
+.Ft void
+.Fo crypto_ed25519_sign
+.Fa "uint8_t signature[64]"
+.Fa "const uint8_t secret_key[64]"
+.Fa "const uint8_t *message"
+.Fa "size_t message_size"
+.Fc
+.Ft int
+.Fo crypto_ed25519_check
+.Fa "const uint8_t signature[64]"
+.Fa "const uint8_t public_key[32]"
+.Fa "const uint8_t *message"
+.Fa "size_t message_size"
+.Fc
+.Ft void
+.Fo crypto_ed25519_key_pair
+.Fa "uint8_t secret_key[64]"
+.Fa "uint8_t public_key[32]"
+.Fa "uint8_t seed[32]"
+.Fc
+.Ft void
+.Fo crypto_ed25519_ph_sign
+.Fa "uint8_t signature[64]"
+.Fa "const uint8_t secret_key[64]"
+.Fa "const uint8_t message_hash[64]"
+.Fc
+.Ft int
+.Fo crypto_ed25519_ph_check
+.Fa "const uint8_t signature[64]"
+.Fa "const uint8_t public_key[32]"
+.Fa "const uint8_t message_hash[64]"
+.Fc
+.Sh DESCRIPTION
+The
+.Fn crypto_ed25519_sign
+and
+.Fn crypto_ed25519_check
+functions provide Ed25519 public key signatures and verification
+with SHA-512 as the underlying hash function.
+They are interoperable with other Ed25519 implementations.
+If you have no interoperability requirements, prefer
+.Xr crypto_eddsa_sign 3monocypher .
+.Pp
+The arguments and security considerations are the same as those
+described in
+.Xr crypto_eddsa_sign 3monocypher .
+.Pp
+.Fn crypto_ed25519_ph_sign
+and
+.Fn crypto_ed25519_ph_check
+implement Ed25519ph.
+To sign or check a message,
+first hash the message with
+.Xr crypto_sha512 3monocypher ,
+then process the resulting
+.Fa message_hash .
+.Sh RETURN VALUES
+.Fn crypto_ed25519_key_pair ,
+.Fn crypto_ed25519_sign ,
+and
+.Fn crypto_ed25519_ph_sign
+return nothing.
+.Pp
+.Fn crypto_ed25519_check
+and
+.Fn crypto_ed25519_ph_check
+returns 0 for legitimate messages and -1 for forgeries.
+.Sh SEE ALSO
+.Xr crypto_eddsa_sign 3monocypher ,
+.Xr crypto_x25519 3monocypher ,
+.Xr crypto_aead_lock 3monocypher ,
+.Xr crypto_sha512 3monocypher ,
+.Xr intro 3monocypher
+.Sh STANDARDS
+These functions implement Ed25519 as described in RFC 8032.
+.Sh HISTORY
+The
+.Fn crypto_ed25519_sign ,
+.Fn crypto_ed25519_check ,
+and
+.Fn crypto_ed25519_public_key
+functions appeared in Monocypher 3.0.0.
+They replace recompilation of Monocypher with the
+.Dv ED25519_SHA512
+preprocessor definition.
+.Pp
+In Monocypher 4.0.0,
+the incremental and custom hash API removed.
+The main interface was also reworked to avoid misuse,
+and
+.Fn crypto_ed25519_key_pair
+replaced
+.Fn crypto_ed25519_public_key .
+.Sh CAVEATS
+Monocypher does not perform any input validation.
+Any deviation from the specified input and output length ranges results
+in
+.Sy undefined behaviour .
+Make sure your inputs are correct.
+.Sh SECURITY CONSIDERATIONS
+.Ss Signature malleability
+Signature malleability is the ability of an attacker to produce a valid
+signature with knowledge of only an existing signature and the public
+key.
+Monocypher prevents that by checking the encoding of the signature,
+and guarantees that generating new signatures requires the private key.
+.Pp
+On the other hand, EdDSA signatures are not unique like cryptographic
+hashes.
+The signing procedure is deterministic by specification and
+.Fn crypto_ed25519_sign
+follows this specification.
+However, someone with the private key can generate arbitrarily many
+valid, canonical, and different signatures of the same message.
+Because of this, never assume that signatures are unique.
+.Ss Fault injection and power analysis
+Fault injection (also known as glitching) and power analysis may be used
+to manipulate the resulting signature and recover the secret key in
+some cases.
+This requires hardware access.
+We can try to mitigate this attack by prefixing all hashes a random data
+block,
+in a construction similar to Ed25519ctx.
+Note that there may still be other power-related side channels (such as
+if the CPU leaks information when an operation overflows a register)
+that must be considered.
diff --git a/lib/Utils.Cryptography/monocypher/vendor/doc/crypto_eddsa_sign.3monocypher b/lib/Utils.Cryptography/monocypher/vendor/doc/crypto_eddsa_sign.3monocypher
new file mode 100644
index 0000000..e3b2179
--- /dev/null
+++ b/lib/Utils.Cryptography/monocypher/vendor/doc/crypto_eddsa_sign.3monocypher
@@ -0,0 +1,522 @@
+.\" This file is dual-licensed. Choose whichever you want.
+.\"
+.\" The first licence is a regular 2-clause BSD licence. The second licence
+.\" is the CC-0 from Creative Commons. It is intended to release Monocypher
+.\" to the public domain. The BSD licence serves as a fallback option.
+.\"
+.\" SPDX-License-Identifier: BSD-2-Clause OR CC0-1.0
+.\"
+.\" ----------------------------------------------------------------------------
+.\"
+.\" Copyright (c) 2017-2019, 2022-2023 Loup Vaillant
+.\" Copyright (c) 2017-2018 Michael Savage
+.\" Copyright (c) 2017, 2019-2023 Fabio Scotoni
+.\" 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 COPYRIGHT HOLDERS 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 COPYRIGHT
+.\" HOLDER 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.
+.\"
+.\" ----------------------------------------------------------------------------
+.\"
+.\" Written in 2017-2023 by Loup Vaillant, Michael Savage and Fabio Scotoni
+.\"
+.\" To the extent possible under law, the author(s) have dedicated all copyright
+.\" and related 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
+.\" <https://creativecommons.org/publicdomain/zero/1.0/>
+.\"
+.Dd February 25, 2023
+.Dt CRYPTO_SIGN 3MONOCYPHER
+.Os
+.Sh NAME
+.Nm crypto_eddsa_sign ,
+.Nm crypto_eddsa_check ,
+.Nm crypto_eddsa_key_pair ,
+.Nm crypto_eddsa_to_x25519 ,
+.Nm crypto_eddsa_trim_scalar ,
+.Nm crypto_eddsa_reduce ,
+.Nm crypto_eddsa_mul_add ,
+.Nm crypto_eddsa_scalarbase ,
+.Nm crypto_eddsa_check_equation
+.Nd public key signatures
+.Sh SYNOPSIS
+.In monocypher.h
+.Ft void
+.Fo crypto_eddsa_sign
+.Fa "uint8_t signature[64]"
+.Fa "const uint8_t secret_key[64]"
+.Fa "const uint8_t *message"
+.Fa "size_t message_size"
+.Fc
+.Ft int
+.Fo crypto_eddsa_check
+.Fa "const uint8_t signature[64]"
+.Fa "const uint8_t public_key[32]"
+.Fa "const uint8_t *message"
+.Fa "size_t message_size"
+.Fc
+.Ft void
+.Fo crypto_eddsa_key_pair
+.Fa "uint8_t secret_key[64]"
+.Fa "uint8_t public_key[32]"
+.Fa "uint8_t seed[32]"
+.Fc
+.Ft void
+.Fo crypto_eddsa_to_x25519
+.Fa "uint8_t x25519[32]"
+.Fa "const uint8_t eddsa[32]"
+.Fc
+.Ft void
+.Fo crypto_eddsa_trim_scalar
+.Fa "uint8_t out[32]"
+.Fa "const uint8_t in[32]"
+.Fc
+.Ft void
+.Fo crypto_eddsa_reduce
+.Fa "uint8_t reduced[32]"
+.Fa "const uint8_t expanded[64]"
+.Fc
+.Ft void
+.Fo crypto_eddsa_mul_add
+.Fa "uint8_t r[32]"
+.Fa "const uint8_t a[32]"
+.Fa "const uint8_t b[32]"
+.Fa "const uint8_t c[32]"
+.Fc
+.Ft void
+.Fo crypto_eddsa_scalarbase
+.Fa "uint8_t point[32]"
+.Fa "const uint8_t scalar[32]"
+.Fc
+.Ft int
+.Fo crypto_eddsa_check_equation
+.Fa "const uint8_t Rs[64]"
+.Fa "const uint8_t A[32]"
+.Fa "const uint8_t h[32]"
+.Fc
+.Sh DESCRIPTION
+.Ss High level API
+.Fn crypto_eddsa_sign
+and
+.Fn crypto_eddsa_check
+provide EdDSA public key signatures and verification.
+.Fn crypto_eddsa_key_pair
+computes the private and public keys from a random seed.
+The arguments are:
+.Bl -tag -width Ds
+.It Fa seed
+Random seed, freshly generated and used only once.
+It is automatically wiped by
+.Fn crypto_eddsa_key_pair .
+See
+.Xr intro 3monocypher
+about random number generation (use your operating system's random
+number generator).
+.It Fa signature
+The signature.
+.It Fa secret_key
+A secret key generated by
+.Fn crypto_eddsa_key_pair ,
+known only to you.
+Internally the secret key is made up of the seed and the public key.
+They are bundled together to avoid misuse,
+and should be treated as a unit.
+.It Fa public_key
+The associated public key,
+known to everyone.
+.It Fa message
+The message to sign.
+.It Fa message_size
+Length of
+.Fa message ,
+in bytes.
+.El
+.Pp
+.Fa signature
+and
+.Fa message
+may overlap.
+.Pp
+.Fn crypto_eddsa_sign
+signs a message with
+.Fa secret_key .
+.Pp
+.Fn crypto_eddsa_check
+checks that a given signature is genuine.
+Meaning, only someone who had the private key could have signed the
+message.
+.Sy \&It does not run in constant time .
+It does not have to in most threat models because nothing is secret:
+everyone knows the public key, and the signature and message are
+rarely secret.
+If the message needs to be secret, use
+a key exchange protocol involving
+.Xr crypto_x25519 3monocypher
+and then
+.Xr crypto_aead_lock 3monocypher
+instead.
+.Ss Conversion to X25519
+.Fn crypto_eddsa_to_x25519
+Converts and EdDSA public key to an X25519 public key.
+Note that it ignores the sign of the
+.Em x
+coordinate of the EdDSA input.
+The inverse operation is provided by
+.Xr crypto_x25519_to_eddsa 3monocypher .
+.Ss Low-level building blocks
+.Fn crypto_eddsa_trim_scalar ,
+.Fn crypto_eddsa_reduce ,
+.Fn crypto_eddsa_mul_add ,
+.Fn crypto_eddsa_scalarbase ,
+and
+.Fn crypto_eddsa_check_equation
+provide low-level functionality to implement specialised APIs and
+variants of EdDSA.
+Monocypher uses them to implement all high-level EdDSA and Ed25519
+functions.
+.Pp
+These functions are
+.Sy dangerous ,
+using them directly allows many kinds of catastrophic misuse.
+The following descriptions are kept concise and technical on purpose.
+If you do not understand them, do not not use those functions.
+.Pp
+.Fn crypto_eddsa_trim_scalar
+reads a 256-bit number represented in little-endian,
+and outputs the same number modified as follows:
+the 3 least significant bits are cleared;
+the most significant bit is cleared;
+and the second most significant bit is set.
+.Pp
+.Fn crypto_eddsa_reduce
+reads a 512-bit number represented in little-endian,
+and outputs the same number reduced modulo the prime order of
+Curve25519.
+.Pp
+.Fn crypto_eddsa_mul_add
+reads three 256-bit numbers represented in little-endian,
+and outputs
+.Fa a
+.Fa b
++
+.Fa c ,
+reduced modulo the prime order of Curve25519.
+.Pp
+.Fn crypto_eddsa_scalarbase
+reads a 256-bit number represented in little-endian,
+and outputs the result of the scalar multiplication between that number
+and the twisted Edwards base point of Curve25519.
+The output uses the same compressed representation as regular EdDSA
+public keys:
+the most significant bit represents the sign of the
+.Em x
+coordinate (1 if it is odd, 0 if it is even),
+and the 255 other bits represent the
+.Em y
+coordinate in little-endian.
+.Pp
+.Fn crypto_eddsa_check_equation
+reads a signature
+.Fa \&Rs ,
+a public_key
+.Fa A ,
+and hash
+.Fa h ,
+then checks the following:
+.Bl -dash
+.It
+.Fa A
+and
+.Fa R
+are both on the curve.
+.It
+.Fa s
+is below the prime order of Curve25519.
+.It
+[8×s]B = [8]R + [8×h]A
+.El
+.Pp
+It then returns 0 if all checks hold,
+-1 otherwise.
+Note that
+.Fa A
+and
+.Fa R
+are allowed to have low order,
+and their encoding is allowed to be non-canonical.
+.Sy This function does not run in constant time ,
+do not use it with secret inputs.
+.Sh RETURN VALUES
+.Ss High level API
+.Fn crypto_eddsa_key_pair
+and
+.Fn crypto_eddsa_sign
+return nothing.
+.Pp
+.Fn crypto_eddsa_check
+returns 0 for legitimate signatures and -1 for forgeries.
+.Ss Conversion to X25519
+.Fn crypto_eddsa_to_x25519
+returns nothing.
+.Ss Low-level building blocks
+.Fn crypto_eddsa_trim_scalar ,
+.Fn crypto_eddsa_reduce ,
+.Fn crypto_eddsa_mul_add ,
+and
+.Fn crypto_eddsa_scalarbase
+return nothing.
+.Pp
+.Fn crypto_eddsa_check_equation
+returns 0 for legitimate signatures and -1 for forgeries.
+.Sh EXAMPLES
+The following examples assume the existence of
+.Fn arc4random_buf ,
+which fills the given buffer with cryptographically secure random bytes.
+If
+.Fn arc4random_buf
+does not exist on your system, see
+.Xr intro 3monocypher
+for advice about how to generate cryptographically secure random bytes.
+.Pp
+Generate a key pair:
+.Bd -literal -offset indent
+uint8_t seed[32]; /* Random seed */
+uint8_t sk [64]; /* secret key */
+uint8_t pk [32]; /* Matching public key */
+arc4random_buf(seed, 32);
+crypto_eddsa_key_pair(sk, pk, seed);
+/* Wipe the secret key if it is no longer needed */
+/* The seed is wiped automatically */
+crypto_wipe(sk, 32);
+.Ed
+.Pp
+Sign a message:
+.Bd -literal -offset indent
+uint8_t sk [64]; /* Secret key from above */
+const uint8_t message [11] = "Lorem ipsu"; /* Message to sign */
+uint8_t signature[64];
+crypto_eddsa_sign(signature, sk, message, 10);
+/* Wipe the secret key if it is no longer needed */
+crypto_wipe(sk, 32);
+.Ed
+.Pp
+Check the above:
+.Bd -literal -offset indent
+const uint8_t pk [32]; /* Their public key */
+const uint8_t message [11] = "Lorem ipsu"; /* Signed message */
+const uint8_t signature[64]; /* Signature to check */
+if (crypto_eddsa_check(signature, pk, message, 10)) {
+ /* Message is corrupted, do not trust it */
+} else {
+ /* Message is genuine */
+}
+.Ed
+.Pp
+Implement XEdDSA
+(signatures with X25519 keys normally used for key exchange)
+with the low-level building blocks
+.Bd -literal -offset indent
+#include <monocypher.h>
+#include <monocypher-ed25519.h>
+#include <string.h>
+
+void xed25519_sign(uint8_t signature[64],
+ const uint8_t secret_key[32],
+ const uint8_t random[64],
+ const uint8_t *message, size_t message_size)
+{
+ static const uint8_t zero [32] = {0};
+ static const uint8_t minus_1[32] = {
+ 0xec, 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,
+ };
+ static const uint8_t prefix[32] = {
+ 0xfe, 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,
+ };
+
+ /* Key pair (a, A) */
+ uint8_t A[32]; /* XEdDSA public key */
+ uint8_t a[32]; /* XEdDSA private key */
+ crypto_eddsa_trim_scalar(a, secret_key);
+ crypto_eddsa_scalarbase(A, a);
+ int is_negative = A[31] & 0x80; /* Retrieve sign bit */
+ A[31] &= 0x7f; /* Clear sign bit */
+ if (is_negative) {
+ /* a = -a */
+ crypto_eddsa_mul_add(a, a, minus_1, zero);
+ }
+
+ /* Secret nonce r */
+ uint8_t r[64];
+ crypto_sha512_ctx ctx;
+ crypto_sha512_init (&ctx);
+ crypto_sha512_update(&ctx, prefix , 32);
+ crypto_sha512_update(&ctx, a , 32);
+ crypto_sha512_update(&ctx, message, message_size);
+ crypto_sha512_update(&ctx, random , 64);
+ crypto_sha512_final (&ctx, r);
+ crypto_eddsa_reduce(r, r);
+
+ /* First half of the signature R */
+ uint8_t R[32];
+ crypto_eddsa_scalarbase(R, r);
+
+ /* hash(R || A || M) */
+ uint8_t H[64];
+ crypto_sha512_init (&ctx);
+ crypto_sha512_update(&ctx, R , 32);
+ crypto_sha512_update(&ctx, A , 32);
+ crypto_sha512_update(&ctx, message, message_size);
+ crypto_sha512_final (&ctx, H);
+ crypto_eddsa_reduce(H, H);
+
+ /* Signature */
+ memcpy(signature, R, 32);
+ crypto_eddsa_mul_add(signature + 32, a, H, r);
+
+ /* Wipe secrets (A, R, and H are not secret) */
+ crypto_wipe(a, 32);
+ crypto_wipe(r, 32);
+}
+
+int xed25519_verify(const uint8_t signature[64],
+ const uint8_t public_key[32],
+ const uint8_t *message, size_t message_size)
+{
+ /* Convert X25519 key to EdDSA */
+ uint8_t A[32];
+ crypto_x25519_to_eddsa(A, public_key);
+
+ /* hash(R || A || M) */
+ uint8_t H[64];
+ crypto_sha512_ctx ctx;
+ crypto_sha512_init (&ctx);
+ crypto_sha512_update(&ctx, signature, 32);
+ crypto_sha512_update(&ctx, A , 32);
+ crypto_sha512_update(&ctx, message , message_size);
+ crypto_sha512_final (&ctx, H);
+ crypto_eddsa_reduce(H, H);
+
+ /* Check signature */
+ return crypto_eddsa_check_equation(signature, A, H);
+}
+.Ed
+.Sh SEE ALSO
+.Xr crypto_blake2b 3monocypher ,
+.Xr crypto_x25519 3monocypher ,
+.Xr crypto_aead_lock 3monocypher ,
+.Xr intro 3monocypher
+.Sh STANDARDS
+.Fn crypto_eddsa_sign ,
+.Fn crypto_eddsa_check ,
+and
+.Fn crypto_eddsa_key_pair
+implement PureEdDSA with Curve25519 and BLAKE2b,
+as described in RFC 8032.
+This is the same as Ed25519, with BLAKE2b instead of SHA-512.
+.Pp
+.Fn crypto_eddsa_trim_scalar ,
+.Fn crypto_eddsa_reduce ,
+.Fn crypto_eddsa_mul_add ,
+.Fn crypto_eddsa_scalarbase ,
+and
+.Fn crypto_eddsa_check_equation
+can be used to implement any Curve25519 based EdDSA variant,
+including Ed25519 and Ed25519ph.
+.Sh HISTORY
+The
+.Fn crypto_sign ,
+.Fn crypto_check ,
+and
+.Fn crypto_sign_public_key
+functions appeared in Monocypher 0.2.
+.Pp
+Starting with Monocypher 2.0.5, modified signatures abusing the inherent
+signature malleability property of EdDSA now cause a non-zero return
+value of
+.Fn crypto_check ;
+in prior versions, such signatures would be accepted.
+.Pp
+.Sy A critical security vulnerability
+that caused all-zero signatures to be accepted was introduced in
+Monocypher 0.3;
+it was fixed in Monocypher 1.1.1 and 2.0.4.
+.Pp
+In Monocypher 4.0.0
+.Fn crypto_eddsa_trim_scalar ,
+.Fn crypto_eddsa_reduce ,
+.Fn crypto_eddsa_mul_add ,
+.Fn crypto_eddsa_scalarbase ,
+and
+.Fn crypto_eddsa_check_equation
+were added,
+and the incremental and custom hash API removed.
+The main interface was also reworked to avoid misuse,
+and
+.Fn crypto_eddsa_key_pair
+replaced
+.Fn crypto_sign_public_key .
+.Sh CAVEATS
+Monocypher does not perform any input validation.
+Any deviation from the specified input and output length ranges results
+in
+.Sy undefined behaviour .
+Make sure your inputs are correct.
+.Sh SECURITY CONSIDERATIONS
+.Ss Signature malleability
+Signature malleability is the ability of an attacker to produce a valid
+signature with knowledge of only an existing signature and the public
+key.
+Monocypher prevents that by checking the encoding of the signature,
+and guarantees that generating new signatures requires the private key.
+.Pp
+On the other hand, EdDSA signatures are not unique like cryptographic
+hashes.
+The signing procedure is deterministic by specification and
+.Fn crypto_eddsa_sign
+follows this specification.
+However, someone with the private key can generate arbitrarily many
+valid, canonical, and different signatures of the same message.
+Because of this, never assume that signatures are unique.
+.Ss Fault injection and power analysis
+Fault injection (also known as glitching) and power analysis may be used
+to manipulate the resulting signature and recover the secret key in
+some cases.
+This requires hardware access.
+We can try to mitigate this attack by prefixing all hashes a random data
+block,
+in a construction similar to Ed25519ctx.
+Note that there may still be other power-related side channels (such as
+if the CPU leaks information when an operation overflows a register)
+that must be considered.
diff --git a/lib/Utils.Cryptography/monocypher/vendor/doc/crypto_elligator_map.3monocypher b/lib/Utils.Cryptography/monocypher/vendor/doc/crypto_elligator_map.3monocypher
new file mode 100644
index 0000000..5c0f943
--- /dev/null
+++ b/lib/Utils.Cryptography/monocypher/vendor/doc/crypto_elligator_map.3monocypher
@@ -0,0 +1,316 @@
+.\" This file is dual-licensed. Choose whichever you want.
+.\"
+.\" The first licence is a regular 2-clause BSD licence. The second licence
+.\" is the CC-0 from Creative Commons. It is intended to release Monocypher
+.\" to the public domain. The BSD licence serves as a fallback option.
+.\"
+.\" SPDX-License-Identifier: BSD-2-Clause OR CC0-1.0
+.\"
+.\" ----------------------------------------------------------------------------
+.\"
+.\" Copyright (c) 2020, 2022 Fabio Scotoni
+.\" Copyright (c) 2023 Loup Vaillant
+.\" 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 COPYRIGHT HOLDERS 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 COPYRIGHT
+.\" HOLDER 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.
+.\"
+.\" ----------------------------------------------------------------------------
+.\"
+.\" Written in 2020, 2022, and 2023 by Fabio Scotoni and Loup Vaillant
+.\"
+.\" To the extent possible under law, the author(s) have dedicated all copyright
+.\" and related 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
+.\" <https://creativecommons.org/publicdomain/zero/1.0/>
+.\"
+.Dd March 6, 2023
+.Dt CRYPTO_ELLIGATOR_MAP 3MONOCYPHER
+.Os
+.Sh NAME
+.Nm crypto_elligator_map ,
+.Nm crypto_elligator_rev ,
+.Nm crypto_elligator_key_pair
+.Nd hiding of X25519 public keys
+.Sh SYNOPSIS
+.In monocypher.h
+.Ft void
+.Fo crypto_elligator_map
+.Fa "uint8_t curve[32]"
+.Fa "const uint8_t hidden[32]"
+.Fc
+.Ft int
+.Fo crypto_elligator_rev
+.Fa "uint8_t hidden[32]"
+.Fa "const uint8_t curve[32]"
+.Fa "uint8_t tweak"
+.Fc
+.Ft void
+.Fo crypto_elligator_key_pair
+.Fa "uint8_t hidden[32]"
+.Fa "uint8_t secret_key[32]"
+.Fa "uint8_t seed[32]"
+.Fc
+.Sh DESCRIPTION
+These functions allow obfuscating X25519 public keys by making
+them appear effectively indistinguishable from random noise.
+This is of interest for key exchange protocols that require
+indistinguishability from randomness, such as padded uniform random
+blobs (PURBs).
+They are intended for ephemeral (short-lived, possibly just one-time)
+X25519 keys, not for long-term public keys.
+After an initial key exchange involving hidden keys,
+subsequent key exchange messages should be encrypted instead;
+see, for example, the Noise Protocol Framework.
+This is an
+.Em advanced feature .
+Unless you are implementing an protocol that requires
+indistinguishability of all communications from random noise,
+consider
+.Xr crypto_x25519 3monocypher
+instead.
+Both this family of functions and
+.Xr crypto_x25519 3monocypher
+should be used as a building block to implement a key exchange protocol.
+.Pp
+For understanding what these functions do, it is important to note that
+a
+.Dq public key
+in this context refers to a
+.Em point on Curve25519 .
+This also means that these functions are not compatible with
+.Xr crypto_eddsa_sign 3monocypher
+and related functions.
+.Pp
+.Fn crypto_elligator_rev
+takes a public key
+.Fa curve
+and a
+.Fa tweak ,
+hiding the public key so that it is effectively indistinguishable
+from random noise.
+Note that only
+.Xr crypto_x25519_dirty_fast 3monocypher
+or
+.Xr crypto_x25519_dirty_small 3monocypher
+can generate a suitable public key;
+the
+.Xr crypto_x25519 3monocypher
+function is insufficient.
+The
+.Fa tweak
+must be chosen at random.
+Even then, this operation
+.Em may
+fail because
+not all curve points are capable of being hidden.
+In this case,
+.Fn crypto_elligator_rev
+must be tried again with a new key pair,
+though
+.Fa tweak
+does not need to be changed.
+On average, two attempts are needed.
+Once a suitable public key has been found,
+.Fn crypto_elligator_rev
+always succeeds for it.
+Given the same values for
+.Fa tweak
+and
+.Fa curve ,
+.Fn crypto_elligator_rev
+yields the same output value
+.Fa hidden .
+.Pp
+.Fn crypto_elligator_map
+performs the inverse operation:
+It decodes a hidden point to a curve point on Curve25519.
+.Pp
+.Fn crypto_elligator_key_pair
+is a convenience function that generates a secret key and its
+corresponding public key, which is effectively indistinguishable from
+random noise, from a random seed.
+.Em The execution time of this function is unpredictable
+because it may take many failures until a key pair could be generated
+successfully.
+.Fn crypto_elligator_key_pair
+uses
+.Xr crypto_x25519_dirty_fast 3monocypher
+internally;
+if code size is an important concern,
+its functionality can be replicated with
+.Xr crypto_x25519_dirty_small 3monocypher
+instead.
+.Pp
+The arguments are:
+.Bl -tag -width Ds
+.It Fa curve
+A point on the curve which is a Curve25519 public key generated with
+either
+.Xr crypto_x25519_dirty_fast 3monocypher
+or
+.Xr crypto_x25519_dirty_small 3monocypher .
+.It Fa hidden
+The hidden encoding of a point on the curve which is effectively
+indistinguishable from random.
+.It Fa secret_key
+The secret key that was generated from the given
+.Fa seed .
+.It Fa seed
+A 32-byte random number from which to derive a key pair.
+See
+.Xr intro 3monocypher
+for advice about generating random bytes (use the operating system's
+random number generator).
+The
+.Fa seed
+is wiped automatically.
+.It Fa tweak
+A 1-byte random number,
+which influences the final output of
+.Fn crypto_elligator_rev .
+.El
+.Pp
+The
+.Fa hidden
+and
+.Fa curve
+arguments may overlap or point at the same buffer.
+.Sh RETURN VALUES
+.Fn crypto_elligator_rev
+returns 0 on success and -1 if the given
+.Fa curve
+argument is unsuitable for hiding.
+.Pp
+.Fn crypto_elligator_map
+and
+.Fn crypto_elligator_key_pair
+return nothing.
+They cannot fail.
+.Sh EXAMPLES
+Generate a key pair manually using
+.Xr crypto_x25519_dirty_small 3monocypher
+instead of its fast variant:
+.Bd -literal -offset indent
+uint8_t sk [32]; /* Secret key output */
+uint8_t pk [32]; /* Hidden public key output */
+uint8_t tweak; /* Random tweak input */
+arc4random_buf(&tweak, 1);
+for (;;) {
+ arc4random_buf(sk, 32);
+ crypto_x25519_dirty_small(pk, sk);
+ if (crypto_elligator_rev(pk, pk, tweak) == 0)
+ break;
+}
+/* Now save the secret key and send the hidden public key. */
+.Ed
+.Pp
+Performing a key exchange with the other party's public key having been
+hidden:
+.Bd -literal -offset indent
+uint8_t hidden_pk [32]; /* Their hidden public key */
+uint8_t their_pk [32]; /* Their unhidden public key */
+uint8_t your_sk [32]; /* Your secret key */
+uint8_t shared_key[32]; /* Shared session key */
+crypto_elligator_map(their_pk, hidden_pk);
+crypto_x25519(shared_key, your_sk, their_pk);
+/* Wipe secrets if they are no longer needed */
+crypto_wipe(your_sk, 32);
+.Ed
+.Sh SEE ALSO
+.Xr crypto_x25519 3monocypher ,
+.Xr crypto_x25519_dirty_small 3monocypher ,
+.Xr intro 3monocypher
+.Sh STANDARDS
+These functions implement the Elligator 2 mapping for Curve25519.
+This mapping is incompatible with both the hash-to-curve Internet draft
+and the implementation of Elligator 2 in libsodium.
+Elligator 2 was described in:
+.Rs
+.%A Daniel J. Bernstein
+.%A Mike Hamburg
+.%A Anna Krasnova
+.%A Tanja Lange
+.%T Elligator: Elliptic-curve points indistinguishable from uniform random strings
+.%J CCS '13: Proceedings of the 2013 ACM SIGSAC conference on Computer & communications security
+.%I Association for Computing Machinery
+.%D 2013
+.%P pp. 967\(en980
+.Re
+.Pp
+Monocypher's Elligator 2 representatives are encoded as little-endian
+254-bit numbers.
+The two most significant bits (254 and 255) are not used.
+.Fn crypto_elligator_map
+ignores them,
+and
+.Fn crypto_elligator_rev
+sets them at random.
+The mapping uses 2 as the non-square
+.Va Z ,
+and [0..2^254-10] as the set of non-negative field elements.
+See
+.Lk https://elligator.org/map
+for more details.
+.Sh HISTORY
+The
+.Fn crypto_curve_to_hidden ,
+.Fn crypto_hidden_to_curve ,
+and
+.Fn crypto_hidden_key_pair
+functions first appeared in Monocypher 3.1.0.
+In Monocypher 4.1.0,
+they were renamed
+.Fn crypto_elligator_rev ,
+.Fn crypto_elligator_map ,
+and
+.Fn crypto_elligator_key_pair
+respectively.
+.Sh CAVEATS
+Monocypher does not perform any input validation.
+Any deviation from the specified input and output length ranges results
+in
+.Sy undefined behaviour .
+Make sure your inputs are correct.
+.Sh SECURITY CONSIDERATIONS
+The secret keys for the public keys fed into
+.Fn crypto_elligator_rev
+.Sy must be chosen randomly
+rather than deterministically.
+Otherwise, the timing information given by the required number of
+retries also leaks information on the secret keys.
+.Pp
+These functions
+.Em help
+build highly difficult-to-analyse protocols
+but are insufficient by themselves:
+Other metadata, such as the number of bytes sent in a packet or the size
+of the 32-byte random looking string that represents the curve point
+itself, can be very strong indicators of the use of cryptography.
+Consider using appropriate padding algorithms, such as PADME,
+and obscure other metadata as much as possible.
diff --git a/lib/Utils.Cryptography/monocypher/vendor/doc/crypto_poly1305.3monocypher b/lib/Utils.Cryptography/monocypher/vendor/doc/crypto_poly1305.3monocypher
new file mode 100644
index 0000000..5fb3e25
--- /dev/null
+++ b/lib/Utils.Cryptography/monocypher/vendor/doc/crypto_poly1305.3monocypher
@@ -0,0 +1,279 @@
+.\" This file is dual-licensed. Choose whichever you want.
+.\"
+.\" The first licence is a regular 2-clause BSD licence. The second licence
+.\" is the CC-0 from Creative Commons. It is intended to release Monocypher
+.\" to the public domain. The BSD licence serves as a fallback option.
+.\"
+.\" SPDX-License-Identifier: BSD-2-Clause OR CC0-1.0
+.\"
+.\" ----------------------------------------------------------------------------
+.\"
+.\" Copyright (c) 2017-2019 Loup Vaillant
+.\" Copyright (c) 2017-2018 Michael Savage
+.\" Copyright (c) 2017-2021 Fabio Scotoni
+.\" 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 COPYRIGHT HOLDERS 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 COPYRIGHT
+.\" HOLDER 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.
+.\"
+.\" ----------------------------------------------------------------------------
+.\"
+.\" Written in 2017-2021 by Loup Vaillant, Michael Savage and Fabio Scotoni
+.\"
+.\" To the extent possible under law, the author(s) have dedicated all copyright
+.\" and related 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
+.\" <https://creativecommons.org/publicdomain/zero/1.0/>
+.\"
+.Dd June 11, 2021
+.Dt CRYPTO_POLY1305 3MONOCYPHER
+.Os
+.Sh NAME
+.Nm crypto_poly1305 ,
+.Nm crypto_poly1305_init ,
+.Nm crypto_poly1305_update ,
+.Nm crypto_poly1305_final
+.Nd Poly1305 one-time message authentication codes
+.Sh SYNOPSIS
+.In monocypher.h
+.Ft void
+.Fo crypto_poly1305
+.Fa "uint8_t mac[16]"
+.Fa "const uint8_t *message"
+.Fa "size_t message_size"
+.Fa "const uint8_t key[32]"
+.Fc
+.Ft void
+.Fo crypto_poly1305_init
+.Fa "crypto_poly1305_ctx *ctx"
+.Fa "const uint8_t key[32]"
+.Fc
+.Ft void
+.Fo crypto_poly1305_update
+.Fa "crypto_poly1305_ctx *ctx"
+.Fa "const uint8_t *message"
+.Fa "size_t message_size"
+.Fc
+.Ft void
+.Fo crypto_poly1305_final
+.Fa "crypto_poly1305_ctx *ctx"
+.Fa "uint8_t mac[16]"
+.Fc
+.Sh DESCRIPTION
+Poly1305 is a one-time message authentication code.
+.Dq One-time
+means the authentication key can be used only once.
+.Sy This makes Poly1305 easy to misuse .
+On the other hand, Poly1305 is fast and provably secure if used
+correctly.
+.Pp
+Poly1305 is a low-level primitive.
+Consider using authenticated encryption, implemented by
+.Xr crypto_aead_lock 3monocypher .
+.Pp
+The arguments are:
+.Bl -tag -width Ds
+.It Fa mac
+The message authentication code.
+.It Fa key
+The secret authentication key.
+Use only once per message.
+Do not use the session key to authenticate messages.
+It should be wiped with
+.Xr crypto_wipe 3monocypher
+after use.
+.It Fa message
+The message to authenticate.
+May overlap with the
+.Fa mac
+argument.
+.It Fa message_size
+Length of
+.Fa message ,
+in bytes.
+.El
+.Ss Direct interface
+.Fn crypto_poly1305
+produces a message authentication code for the given message and
+authentication key.
+To verify the integrity of a message, use
+.Xr crypto_verify16 3monocypher
+to compare the received MAC to the output
+.Fa mac .
+.Ss Incremental interface
+.Fn crypto_poly1305_init
+initialises a context.
+.Fa key
+should be wiped once the context is initialised.
+Then
+.Fn crypto_poly1305_update
+authenticates the message chunk by chunk.
+Once the message is entirely processed,
+.Fn crypto_poly1305_final
+yields the message authentication code.
+.Sh RETURN VALUES
+These functions return nothing.
+.Sh EXAMPLES
+The following examples assume the existence of
+.Fn arc4random_buf ,
+which fills the given buffer with cryptographically secure random bytes.
+If
+.Fn arc4random_buf
+does not exist on your system, see
+.Xr intro 3monocypher
+for advice about how to generate cryptographically secure random bytes.
+.Pp
+To authenticate a message:
+.Bd -literal -offset indent
+const uint8_t msg[ 5] = "Lorem"; /* Message to authenticate */
+uint8_t key[32]; /* Random secret key (use only once) */
+uint8_t mac[16]; /* Message authentication code (MAC) */
+arc4random_buf(key, 32);
+crypto_poly1305(mac, msg, 5, key);
+/* Wipe the key */
+crypto_wipe(key, 32);
+.Ed
+.Pp
+To verify the above message:
+.Bd -literal -offset indent
+const uint8_t msg [ 5] = "Lorem"; /* Message to verify */
+uint8_t key [32]; /* The above key */
+const uint8_t mac [16]; /* The above MAC */
+uint8_t real_mac[16]; /* The actual MAC */
+crypto_poly1305(real_mac, msg, 5, key);
+/* Wipe the key */
+crypto_wipe(key, 32);
+if (crypto_verify16(mac, real_mac)) {
+ /* Corrupted message, abort processing */
+} else {
+ /* Genuine message */
+}
+/* The real mac is secret. Wipe it */
+crypto_wipe(real_mac, 16);
+.Ed
+.Pp
+Incremental authentication:
+.Bd -literal -offset indent
+const uint8_t msg[500]= {1}; /* Message to authenticate */
+uint8_t key[ 32]; /* Random secret key (use only once) */
+uint8_t mac[ 16]; /* Message authentication code (MAC) */
+crypto_poly1305_ctx ctx;
+arc4random_buf(key, 32);
+crypto_poly1305_init(&ctx, key);
+/* Wipe the key */
+crypto_wipe(key, 32);
+for (int i = 0; i < 500; i += 100) {
+ crypto_poly1305_update(&ctx, msg, 100);
+}
+crypto_poly1305_final(&ctx, mac);
+.Ed
+.Sh SEE ALSO
+.Xr crypto_blake2b 3monocypher ,
+.Xr crypto_aead_lock 3monocypher ,
+.Xr crypto_verify16 3monocypher ,
+.Xr intro 3monocypher
+.Sh STANDARDS
+These functions implement Poly1305, described in RFC 8439.
+.Sh HISTORY
+The
+.Fn crypto_poly1305_init ,
+.Fn crypto_poly1305_update ,
+and
+.Fn crypto_poly1305_final
+functions first appeared in Monocypher 0.1.
+.Fn crypto_poly1305
+first appeared in Monocypher 1.1.0.
+.Sh CAVEATS
+Monocypher does not perform any input validation.
+Any deviation from the specified input and output length ranges results
+in
+.Sy undefined behaviour .
+Make sure your inputs are correct.
+.Sh SECURITY CONSIDERATIONS
+Poly1305 is difficult to use correctly.
+Do not use it unless you are absolutely sure what you are doing.
+Use authenticated encryption instead; see
+.Xr crypto_aead_lock 3monocypher .
+If you are certain you do not want encryption, refer to
+.Xr crypto_blake2b 3monocypher
+on how to use BLAKE2b to generate message authentication codes.
+.Ss Authentication key requirements
+Poly1305 is a
+.Em one-time
+authenticator.
+This puts rather stringent constraints on the authentication key:
+.Bl -bullet
+.It
+Any given key must be used only once.
+Using the same key for two different messages reveals it to the
+attacker.
+Do not use the session key, or it will void all security.
+.It
+Authentication keys must be random, and independent from each other.
+Do not use non-random nonces.
+Do not use related keys.
+Use fresh, unpredictable, uniformly distributed random numbers.
+.It
+The key must be transmitted to the recipient without revealing it to the
+attacker.
+Somehow.
+.El
+.Pp
+The only practical source for the authentication key is a chunk of the
+encryption stream used to encrypt the message.
+That chunk must be
+.Em dedicated
+to the authentication key:
+if it is reused to encrypt the message itself, the attacker may recover
+that chunk by guessing the message then forge arbitrary messages.
+.Pp
+To get this right, you need a session key, a
+.Em unique
+nonce, and a
+stream cipher.
+Generate a stream with the session key and nonce.
+Take the first 32 bytes of that stream as your authentication key, then
+use the
+.Em rest
+of the stream to encrypt your message.
+This is the approach used by
+.Xr crypto_aead_lock 3monocypher .
+.Ss Protection against side channels
+Use
+.Xr crypto_verify16 3monocypher
+to compare message authentication codes.
+Avoid standard buffer comparison functions:
+they may not run in constant time, enabling an attacker to exploit timing
+attacks to recover the MAC.
+.Pp
+The authentication key should be wiped with
+.Xr crypto_wipe 3monocypher
+after use.
+.Pp
+The incremental interface automatically wipes its context when finished,
+so users do not need to do it themselves.
diff --git a/lib/Utils.Cryptography/monocypher/vendor/doc/crypto_sha512.3monocypher b/lib/Utils.Cryptography/monocypher/vendor/doc/crypto_sha512.3monocypher
new file mode 100644
index 0000000..d03578e
--- /dev/null
+++ b/lib/Utils.Cryptography/monocypher/vendor/doc/crypto_sha512.3monocypher
@@ -0,0 +1,578 @@
+.\" This file is dual-licensed. Choose whichever you want.
+.\"
+.\" The first licence is a regular 2-clause BSD licence. The second licence
+.\" is the CC-0 from Creative Commons. It is intended to release Monocypher
+.\" to the public domain. The BSD licence serves as a fallback option.
+.\"
+.\" SPDX-License-Identifier: BSD-2-Clause OR CC0-1.0
+.\"
+.\" ----------------------------------------------------------------------------
+.\"
+.\" Copyright (c) 2019-2020, 2023 Fabio Scotoni
+.\" Copyright (c) 2023 Loup Vaillant
+.\" 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 COPYRIGHT HOLDERS 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 COPYRIGHT
+.\" HOLDER 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.
+.\"
+.\" ----------------------------------------------------------------------------
+.\"
+.\" Written in 2019-2020, 2023 by Fabio Scotoni and Loup Vaillant
+.\"
+.\" To the extent possible under law, the author(s) have dedicated all copyright
+.\" and related 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
+.\" <https://creativecommons.org/publicdomain/zero/1.0/>
+.\"
+.Dd February 25, 2023
+.Dt CRYPTO_SHA512 3MONOCYPHER
+.Os
+.Sh NAME
+.Nm crypto_sha512 ,
+.Nm crypto_sha512_init ,
+.Nm crypto_sha512_update ,
+.Nm crypto_sha512_final
+.Nm crypto_sha512_hmac ,
+.Nm crypto_sha512_hmac_init ,
+.Nm crypto_sha512_hmac_update ,
+.Nm crypto_sha512_hmac_final ,
+.Nm crypto_sha512_hkdf ,
+.Nm crypto_sha512_hkdf_expand
+.Nd hashing, message authentication, and key derivation with SHA-512
+.Sh SYNOPSIS
+.In monocypher-ed25519.h
+.Ft void
+.Fo crypto_sha512
+.Fa "uint8_t hash[64]"
+.Fa "const uint8_t *message"
+.Fa "size_t message_size"
+.Fc
+.Ft void
+.Fo crypto_sha512_init
+.Fa "crypto_sha512_ctx *ctx"
+.Fc
+.Ft void
+.Fo crypto_sha512_update
+.Fa "crypto_sha512_ctx *ctx"
+.Fa "const uint8_t *message"
+.Fa "size_t message_size"
+.Fc
+.Ft void
+.Fo crypto_sha512_final
+.Fa "crypto_sha512_ctx *ctx"
+.Fa "uint8_t hash[64]"
+.Fc
+.Ft void
+.Fo crypto_sha512_hmac
+.Fa "uint8_t hmac[64]"
+.Fa "const uint8_t *key"
+.Fa "size_t key_size"
+.Fa "const uint8_t *message"
+.Fa "size_t message_size"
+.Fc
+.Ft void
+.Fo crypto_sha512_hmac_init
+.Fa "crypto_sha512_hmac_ctx *ctx"
+.Fa "const uint8_t *key"
+.Fa "size_t key_size"
+.Fc
+.Ft void
+.Fo crypto_sha512_hmac_update
+.Fa "crypto_sha512_hmac_ctx *ctx"
+.Fa "const uint8_t *message"
+.Fa "size_t message_size"
+.Fc
+.Ft void
+.Fo crypto_sha512_hmac_final
+.Fa "crypto_sha512_hmac_ctx *ctx"
+.Fa "uint8_t hmac[64]"
+.Fc
+.Fo crypto_sha512_hkdf
+.Fa "uint8_t *okm"
+.Fa "size_t okm_size"
+.Fa "const uint8_t *ikm"
+.Fa "size_t ikm_size"
+.Fa "const uint8_t *salt"
+.Fa "size_t salt_size"
+.Fa "const uint8_t *info"
+.Fa "size_t info_size"
+.Fc
+.Ft void
+.Fo crypto_sha512_hkdf_expand
+.Fa "uint8_t *okm"
+.Fa "size_t okm_size"
+.Fa "const uint8_t *prk"
+.Fa "size_t prk_size"
+.Fa "const uint8_t *info"
+.Fa "size_t info_size"
+.Fc
+.Ft void
+.Sh DESCRIPTION
+.Ss Hashing
+.Fn crypto_sha512 ,
+.Fn crypto_sha512_init ,
+.Fn crypto_sha512_update ,
+and
+.Fn crypto_sha512_final
+implement SHA-512,
+a cryptographically secure hash.
+They are provided to enable compatibility with other cryptographic
+systems.
+It is generally recommended to use
+.Xr crypto_blake2b 3monocypher
+instead,
+as it both performs faster on x86_64 CPUs and
+lacks many of the pitfalls of SHA-512.
+.Pp
+Note that SHA-512 itself is not suitable for hashing passwords and
+deriving keys from them;
+use the
+.Xr crypto_argon2 3monocypher
+family of functions for that purpose instead.
+.Pp
+SHA-512 is
+.Em vulnerable to length extension attacks ,
+and thus cannot directly be used for message authentication codes (MAC),
+nor as a random oracle.
+For those, use the
+.Fn crypto_sha512_hmac
+family of functions instead.
+.Pp
+The arguments are:
+.Bl -tag -width Ds
+.It Fa hash
+The output SHA-512 hash,
+which is always 64-bytes long.
+.It Fa message
+The message to hash.
+May be
+.Dv NULL
+if
+.Fa message_size
+is 0.
+.It Fa message_size
+Length of
+.Fa message ,
+in bytes.
+.El
+.Ss Message authentication codes
+.Fn crypto_sha512_hmac ,
+.Fn crypto_sha512_hmac_init ,
+.Fn crypto_sha512_hmac_update ,
+and
+.Fn crypto_sha512_hmac_final
+implement HMAC with SHA-512,
+and can be used for message authentication codes or as a random oracle.
+They are provided to enable compatibility with other cryptographic
+systems.
+It is generally recommended to use keyed
+.Xr crypto_blake2b 3monocypher
+instead,
+as it performs faster on x86_64 CPUs.
+.Pp
+The arguments are:
+.Bl -tag -width Ds
+.It Fa hmac
+The output MAC,
+which is always 64-bytes long.
+When used as a message authentication code,
+it can safely be truncated down to 16 bytes.
+To avoid timing attacks,
+use
+.Xr crypto_verify16 3monocypher ,
+.Xr crypto_verify32 3monocypher ,
+or
+.Xr crypto_verify64 3monocypher
+to compare (possibly truncated) MACs.
+.It Fa key
+Some secret key.
+When uniformly random,
+one cannot predict the final HMAC without it.
+Users may want to wipe the key with
+.Xr crypto_wipe 3monocypher
+once they are done with it.
+Also stands for the
+.Fa salt
+argument when using
+.Fn crypto_sha512_hmac
+for HKDF extraction.
+.It Fa key_size
+Length of
+.Fa key ,
+in bytes.
+32 is a good default.
+Keys longer than 128 bytes will be reduced to 64 bytes by hashing
+the key with SHA-512.
+.It Fa message
+The message to compute the HMAC for.
+May be
+.Dv NULL
+if
+.Fa message_size
+is 0.
+Also stands for the
+.Fa ikm
+argument when using
+.Fn crypto_sha512_hmac
+for HKDF extraction.
+.It Fa message_size
+Length of
+.Fa message ,
+in bytes.
+.El
+.Ss Key derivation
+.Fn crypto_sha512_hkdf
+and
+.Fn crypto_sha512_hkdf_expand
+implement HKDF key derivation on top of SHA-512.
+HKDF is divided in two phases:
+first we
+.Em extract
+entropy from some input key material to produce a
+.Em pseudo-random key
+(PRK) which is indistinguishable from uniform random bytes.
+Then we
+.Em expand
+that pseudo-random key into a longer stream of independent random bytes
+called
+.Em output key material
+(OKM).
+.Pp
+HKDF extraction is already implemented in
+.Fn crypto_sha512_hmac ,
+so there is no dedicated function.
+HKDF expansion is implemented by
+.Fn crypto_sha512_hkdf_expand .
+Note that expansion works with any uniformly random key,
+the PRK does not have to come from
+.Fn crypto_sha512_hmac
+specifically.
+Likewise,
+if compatibility or standard compliance is not an issue,
+expansion could in principle use any pseudo-random function,
+such as
+.Xr crypto_chacha20_djb 3monocypher .
+.Pp
+.Fn crypto_sha512_hkdf
+is a convenience function that performs
+.Fn crypto_sha512_hmac
+and
+.Fn crypto_sha512_hkdf_expand .
+.Pp
+Contrary to most functions in Monocypher,
+the inputs of
+.Fn crypto_sha512_hkdf
+and
+.Fn crypto_sha512_hkdf_expand
+.Em cannot overlap
+with their output.
+The unlimited size of both inputs and output prevents us from from
+caching one of them in a local variable.
+.Pp
+The arguments are:
+.Bl -tag -width Ds
+.It Fa okm
+The output key material of HKDF or HKDF expansion,
+usable as a symmetric encryption key,
+or set thereof.
+.It Fa okm_size
+Length of
+.Fa okm ,
+in bytes.
+.It Fa ikm
+Input key material containing enough secret entropy to derive uniformly
+random keys from,
+such as the shared secret of a key exchange performed with
+.Xr crypto_x25519 3monocypher .
+Passwords do
+.Sy not
+contain enough entropy to be used as input key material.
+Hash them with
+.Xr crypto_argon2 3monocypher
+instead.
+.It Fa ikm_size
+Length of
+.Fa ikm ,
+in bytes.
+.It Fa prk
+Pseudo-random key.
+Typically comes from an HKDF extraction with
+.Fn crypto_sha512_hmac ,
+but can come from any source as long as it is uniformly random.
+Should be at least 32 bytes long.
+.It Fa prk_size
+Length of
+.Fa prk ,
+in bytes.
+.It Fa salt
+An optional random salt,
+used to increase the security of the output key material
+.Fa okm
+in some settings.
+Can be NULL if
+.Fa salt_size
+is zero.
+Otherwise it should contain at least 16 bytes.
+.It Fa salt_size
+Length of
+.Fa salt ,
+in bytes.
+.It Fa info
+Optional domain separation string for key derivation.
+Can be NULL if
+.Fa info_size
+is zero.
+.It Fa info_size
+Length of
+.Fa info ,
+in bytes.
+.El
+.Ss Incremental interface
+An incremental interface is provided.
+It is useful for handling streams of data or
+large files without using too much memory.
+This interface uses three steps:
+.Bl -bullet
+.It
+initialisation with
+.Fn crypto_sha512_init
+or
+.Fn crypto_sha512_hmac_init ,
+which sets up a context with the hashing parameters;
+.It
+update with
+.Fn crypto_sha512_update
+or
+.Fn crypto_sha512_hmac_update ,
+which hashes the message chunk by chunk and keeps the intermediary
+result in the context;
+.It
+and finalisation with
+.Fn crypto_sha512_final
+or
+.Fn crypto_sha512_hmac_final ,
+which produces the final hash.
+The
+.Ft crypto_sha512_ctx
+or
+.Ft crypto_sha512_hmac_ctx
+is automatically wiped upon finalisation.
+.El
+.Pp
+.Fn crypto_sha512
+is a convenience function that
+performs
+.Fn crypto_sha512_init ,
+.Fn crypto_sha512_update ,
+and
+.Fn crypto_sha512_final .
+.Pp
+.Fn crypto_sha512_hmac
+is a convenience function that
+performs
+.Fn crypto_sha512_hmac_init ,
+.Fn crypto_sha512_hmac_update ,
+and
+.Fn crypto_sha512_hmac_final .
+.Sh RETURN VALUES
+These functions return nothing.
+.Sh EXAMPLES
+Hashing a message all at once:
+.Bd -literal -offset indent
+uint8_t hash [64]; /* Output hash (64 bytes) */
+uint8_t message[12] = "Lorem ipsum"; /* Message to hash */
+crypto_sha512(hash, message, 12);
+.Ed
+.Pp
+Hashing a message incrementally:
+.Bd -literal -offset indent
+uint8_t hash [ 64]; /* Output hash (64 bytes) */
+uint8_t message[500] = {1}; /* Message to hash */
+crypto_sha512_ctx ctx;
+crypto_sha512_init(&ctx);
+for (size_t i = 0; i < 500; i += 100) {
+ crypto_sha512_update(&ctx, message + i, 100);
+}
+crypto_sha512_final(&ctx, hash);
+.Ed
+.Pp
+Computing a message authentication code all at once:
+.Bd -literal -offset indent
+uint8_t hash [64]; /* Output hash */
+uint8_t key [32]; /* Key */
+uint8_t message[10] = "Lorem ipsu"; /* Message to authenticate */
+arc4random_buf(key, 32);
+crypto_sha512_hmac(hash, key, 32, message, 10);
+/* Wipe secrets if they are no longer needed */
+crypto_wipe(message, 10);
+crypto_wipe(key, 32);
+.Ed
+.Pp
+Computing a message authentication code incrementally:
+.Bd -literal -offset indent
+uint8_t hash [64]; /* Output hash */
+uint8_t key [32]; /* Key */
+uint8_t message[500] = {1}; /* Message to authenticate */
+crypto_sha512_hmac_ctx ctx;
+arc4random_buf(key, 32);
+crypto_sha512_hmac_init(&ctx, key, 32);
+/* Wipe the key */
+crypto_wipe(key, 32);
+for (size_t i = 0; i < 500; i += 100) {
+ crypto_sha512_hmac_update(&ctx, message + i, 100);
+ /* Wipe secrets if they are no longer needed */
+ crypto_wipe(message + i, 100);
+}
+crypto_sha512_hmac_final(&ctx, hash);
+.Ed
+.Pp
+Deriving keys from input key material:
+.Bd -literal -offset indent
+uint8_t okm[128]; /* Output random keys */
+uint8_t ikm [96]; /* Input key material */
+uint8_t salt[16]; /* Random salt */
+uint8_t info[11] = "Lorem ipsum"; /* Domain separation */
+arc4random_buf(salt, sizeof(salt));
+crypto_sha512_hkdf(okm, sizeof(okm),
+ ikm, sizeof(ikm),
+ salt, sizeof(salt),
+ info, sizeof(info));
+uint8_t *key1 = okm + 0;
+uint8_t *key2 = okm + 32;
+uint8_t *key3 = okm + 64;
+uint8_t *key4 = okm + 96;
+/* Wipe okm when it is no longer needed */
+.Ed
+.Pp
+Deriving keys from several bits of input key material:
+.Bd -literal -offset indent
+uint8_t okm [96]; /* Output secret keys */
+uint8_t pk_a[32]; /* Alice public X25519 key */
+uint8_t pk_b[32]; /* Bob public X25519 key */
+uint8_t skab[32]; /* Alice & bob shared secret */
+uint8_t ikm [96]; /* Input key material */
+uint8_t salt[16]; /* Random salt */
+uint8_t info[ 6] = "X25519"; /* Domain separation */
+arc4random_buf(salt, sizeof(salt));
+
+/* Extract */
+uint8_t prk[64]; /* pseudo-random key */
+crypto_sha512_hmac_ctx ctx;
+crypto_sha512_hmac_init (&ctx, salt, sizeof(salt));
+crypto_sha512_hmac_update(&ctx, pk_a, sizeof(pk_a));
+crypto_sha512_hmac_update(&ctx, pk_b, sizeof(pk_b));
+crypto_sha512_hmac_update(&ctx, skab, sizeof(skab));
+crypto_sha512_hmac_final (&ctx, prk);
+
+/* Expand */
+crypto_sha512_hkdf_expand(okm, sizeof(okm),
+ prk, sizeof(prk),
+ info, sizeof(info));
+uint8_t *key1 = okm + 0;
+uint8_t *key2 = okm + 32;
+uint8_t *key3 = okm + 64;
+/* Wipe okm when it is no longer needed */
+.Ed
+.Sh SEE ALSO
+.Xr crypto_blake2b 3monocypher ,
+.Xr crypto_aead_lock 3monocypher ,
+.Xr crypto_poly1305 3monocypher ,
+.Xr intro 3monocypher
+.Sh STANDARDS
+These functions implement SHA-512,
+HMAC with SHA-512,
+and HKDF with SHA-512.
+HMAC and SHA-512 are described in RFC 6234;
+SHA-512 is also described in the Federal Information Processing Standard
+(FIPS) 180-4;
+HMAC is also described in FIPS 198-1.
+HKDF is described in RFC 5869.
+.Sh HISTORY
+The
+.Fn crypto_sha512 ,
+.Fn crypto_sha512_init ,
+.Fn crypto_sha512_update ,
+and
+.Fn crypto_sha512_final
+functions first appeared in Monocypher 0.3,
+but were not intended for use outside Monocypher itself and thus
+undocumented.
+They became part of the official API in Monocypher 3.0.0.
+.Pp
+The
+.Fn crypto_hmac_sha512 ,
+.Fn crypto_hmac_sha512_init ,
+.Fn crypto_hmac_sha512_update ,
+and
+.Fn crypto_hmac_sha512_final
+functions first appeared in Monocypher 3.0.0,
+then renamed
+.Fn crypto_sha512_hmac ,
+.Fn crypto_sha512_hmac_init ,
+.Fn crypto_sha512_hmac_update ,
+and
+.Fn crypto_sha512_hmac_final
+in Monocypher 4.0.0.
+.Pp
+.Fn crypto_sha512_hkdf
+and
+.Fn crypto_sha512_hkdf_expand
+were added in Monocypher 4.0.0.
+.Sh CAVEATS
+Monocypher does not perform any input validation.
+Any deviation from the specified input and output length ranges results
+in
+.Sy undefined behaviour .
+Make sure your inputs are correct.
+.Sh SECURITY CONSIDERATIONS
+SHA-512 is a general-purpose cryptographic hash function;
+this means that it is not suited for hashing passwords and deriving
+cryptographic keys from passwords.
+While cryptographic keys usually have hundreds of bits of entropy,
+passwords are often much less complex.
+When storing passwords as hashes or when deriving keys from them,
+the goal is normally to prevent attackers from quickly iterating all
+possible passwords.
+Because passwords tend to be simple,
+it is important to artificially slow down attackers by using especially
+computationally difficult hashing algorithms.
+Monocypher therefore provides
+.Xr crypto_argon2 3monocypher
+for password hashing and deriving keys from passwords.
+.Pp
+While HKDF and HMAC are proper key derivation functions (KDF),
+the HKDF expand step alone is
+.Em not .
+It is a
+.Em pseudo-random function
+(PRF),
+that only works with a
+.Em uniformly
+random key.
+We cannot simply input regular (non uniform) input key material
+without making unusually strong assumptions about the security of HMAC.
diff --git a/lib/Utils.Cryptography/monocypher/vendor/doc/crypto_verify16.3monocypher b/lib/Utils.Cryptography/monocypher/vendor/doc/crypto_verify16.3monocypher
new file mode 100644
index 0000000..09a7dcd
--- /dev/null
+++ b/lib/Utils.Cryptography/monocypher/vendor/doc/crypto_verify16.3monocypher
@@ -0,0 +1,132 @@
+.\" This file is dual-licensed. Choose whichever you want.
+.\"
+.\" The first licence is a regular 2-clause BSD licence. The second licence
+.\" is the CC-0 from Creative Commons. It is intended to release Monocypher
+.\" to the public domain. The BSD licence serves as a fallback option.
+.\"
+.\" SPDX-License-Identifier: BSD-2-Clause OR CC0-1.0
+.\"
+.\" ----------------------------------------------------------------------------
+.\"
+.\" Copyright (c) 2017-2019 Loup Vaillant
+.\" Copyright (c) 2017-2018 Michael Savage
+.\" Copyright (c) 2017, 2019-2020 Fabio Scotoni
+.\" 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 COPYRIGHT HOLDERS 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 COPYRIGHT
+.\" HOLDER 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.
+.\"
+.\" ----------------------------------------------------------------------------
+.\"
+.\" Written in 2017-2020 by Loup Vaillant, Michael Savage and Fabio Scotoni
+.\"
+.\" To the extent possible under law, the author(s) have dedicated all copyright
+.\" and related 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
+.\" <https://creativecommons.org/publicdomain/zero/1.0/>
+.\"
+.Dd March 31, 2020
+.Dt CRYPTO_VERIFY16 3MONOCYPHER
+.Os
+.Sh NAME
+.Nm crypto_verify16 ,
+.Nm crypto_verify32 ,
+.Nm crypto_verify64
+.Nd timing-safe data comparison
+.Sh SYNOPSIS
+.In monocypher.h
+.Ft int
+.Fo crypto_verify16
+.Fa "const uint8_t a[16]"
+.Fa "const uint8_t b[16]"
+.Fc
+.Ft int
+.Fo crypto_verify32
+.Fa "const uint8_t a[32]"
+.Fa "const uint8_t b[32]"
+.Fc
+.Ft int
+.Fo crypto_verify64
+.Fa "const uint8_t a[64]"
+.Fa "const uint8_t b[64]"
+.Fc
+.Sh DESCRIPTION
+Cryptographic operations often require comparison of secrets or values
+derived from secrets.
+Standard comparison functions like
+.Xr memcmp 3
+tend to exit when they find the first difference, leaking information
+through timing differences.
+.Pp
+As an example, say a message authentication code (MAC) is sent over the
+network along with a message, but the correct MAC is secret.
+If the attacker attempts a forgery, one does not want to reveal
+.Dq your MAC is wrong, Em and it took 384 microseconds to tell .
+If the next attempt takes 462 microseconds instead, it tells the
+attacker that they just guessed a byte correctly.
+That way, an attacker can derive the correct MAC byte by byte
+and successfully forge a message.
+This has led to practical attacks in the past.
+.Pp
+To avoid such catastrophic failure,
+.Fn crypto_verify16 ,
+.Fn crypto_verify32 ,
+and
+.Fn crypto_verify64
+provide comparison functions whose timing is independent from
+the content of their input.
+They compare the first
+16, 32, or 64 bytes of the two byte arrays
+.Fa a
+and
+.Fa b .
+.Pp
+When in doubt, prefer these functions over
+.Xr memcmp 3 .
+.Sh RETURN VALUES
+These functions return 0 if the two memory chunks are the same and -1
+otherwise.
+.Sh SEE ALSO
+.Xr intro 3monocypher
+.Sh HISTORY
+The
+.Fn crypto_verify16 ,
+.Fn crypto_verify32 ,
+.Fn crypto_verify64 ,
+functions first appeared in Monocypher 1.1.0.
+They replaced the
+.Fn crypto_memcmp
+and
+.Fn crypto_zerocmp
+functions that were present until Monocypher 1.0.1.
+.Sh CAVEATS
+Monocypher does not perform any input validation.
+Any deviation from the specified input and output length ranges results
+in
+.Sy undefined behaviour .
+Make sure your inputs are correct.
diff --git a/lib/Utils.Cryptography/monocypher/vendor/doc/crypto_wipe.3monocypher b/lib/Utils.Cryptography/monocypher/vendor/doc/crypto_wipe.3monocypher
new file mode 100644
index 0000000..4f299fb
--- /dev/null
+++ b/lib/Utils.Cryptography/monocypher/vendor/doc/crypto_wipe.3monocypher
@@ -0,0 +1,116 @@
+.\" This file is dual-licensed. Choose whichever you want.
+.\"
+.\" The first licence is a regular 2-clause BSD licence. The second licence
+.\" is the CC-0 from Creative Commons. It is intended to release Monocypher
+.\" to the public domain. The BSD licence serves as a fallback option.
+.\"
+.\" SPDX-License-Identifier: BSD-2-Clause OR CC0-1.0
+.\"
+.\" ----------------------------------------------------------------------------
+.\"
+.\" Copyright (c) 2017-2019 Loup Vaillant
+.\" Copyright (c) 2017-2018 Michael Savage
+.\" Copyright (c) 2017, 2019 Fabio Scotoni
+.\" 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 COPYRIGHT HOLDERS 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 COPYRIGHT
+.\" HOLDER 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.
+.\"
+.\" ----------------------------------------------------------------------------
+.\"
+.\" Written in 2017-2019 by Loup Vaillant, Michael Savage and Fabio Scotoni
+.\"
+.\" To the extent possible under law, the author(s) have dedicated all copyright
+.\" and related 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
+.\" <https://creativecommons.org/publicdomain/zero/1.0/>
+.\"
+.Dd December 12, 2019
+.Dt CRYPTO_WIPE 3MONOCYPHER
+.Os
+.Sh NAME
+.Nm crypto_wipe
+.Nd wipe data from memory
+.Sh SYNOPSIS
+.In monocypher.h
+.Ft void
+.Fo crypto_wipe
+.Fa "void *secret"
+.Fa "size_t secret_size"
+.Fc
+.Sh DESCRIPTION
+.Fn crypto_wipe
+securely erases sensitive data in memory.
+.Pp
+Sensitive data (such as cryptographic keys or secret plaintexts) should
+be erased from memory as early as possible to minimise the window in
+which it can be leaked.
+Standard functions like memset and bzero are not safe to use as the
+compiler may decide they have no effect and optimise them out.
+.Pp
+The arguments are:
+.Bl -tag -width Ds
+.It Fa secret
+The buffer to erase.
+.It Fa secret_size
+The number of bytes to erase from the buffer.
+This is normally the size of the entire buffer.
+.El
+.Pp
+Monocypher will wipe its context structs when finalizing an operation
+such as signing or decrypting.
+When using direct interfaces like
+.Xr crypto_aead_lock 3monocypher ,
+these context structs are invisible to you.
+However, they are exposed in incremental interfaces like
+.Xr crypto_blake2b_init 3monocypher .
+The original key buffer does not get automatically wiped.
+When using incremental interfaces, you may want to wipe the original key
+buffers immediately after calling the respective init function.
+.Pp
+Using
+.Fn crypto_wipe
+alone may not be enough for security.
+It is recommended to lock down relevant memory regions as well.
+Refer to
+.Xr intro 3monocypher
+for instructions on how to lock down memory on common operating systems.
+.Sh RETURN VALUES
+This function returns nothing.
+.Sh SEE ALSO
+.Xr intro 3monocypher
+.Sh HISTORY
+The
+.Fn crypto_wipe
+function first appeared in Monocypher 1.1.0.
+.Sh CAVEATS
+Monocypher does not perform any input validation.
+Any deviation from the specified input and output length ranges results
+in
+.Sy undefined behaviour .
+Make sure your inputs are correct.
diff --git a/lib/Utils.Cryptography/monocypher/vendor/doc/crypto_x25519.3monocypher b/lib/Utils.Cryptography/monocypher/vendor/doc/crypto_x25519.3monocypher
new file mode 100644
index 0000000..d9abbe3
--- /dev/null
+++ b/lib/Utils.Cryptography/monocypher/vendor/doc/crypto_x25519.3monocypher
@@ -0,0 +1,329 @@
+.\" This file is dual-licensed. Choose whichever you want.
+.\"
+.\" The first licence is a regular 2-clause BSD licence. The second licence
+.\" is the CC-0 from Creative Commons. It is intended to release Monocypher
+.\" to the public domain. The BSD licence serves as a fallback option.
+.\"
+.\" SPDX-License-Identifier: BSD-2-Clause OR CC0-1.0
+.\"
+.\" ----------------------------------------------------------------------------
+.\"
+.\" Copyright (c) 2017-2021, 2022-2023 Loup Vaillant
+.\" Copyright (c) 2017-2018 Michael Savage
+.\" Copyright (c) 2017, 2019-2020, 2022 Fabio Scotoni
+.\" Copyright (c) 2020 Richard Walmsley
+.\" Copyright (c) 2022 Samuel Lucas
+.\" 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 COPYRIGHT HOLDERS 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 COPYRIGHT
+.\" HOLDER 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.
+.\"
+.\" ----------------------------------------------------------------------------
+.\"
+.\" Written in 2017-2023 by Loup Vaillant, Michael Savage, Fabio Scotoni,
+.\" Richard Walmsley and Samuel Lucas
+.\"
+.\" To the extent possible under law, the author(s) have dedicated all copyright
+.\" and related 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
+.\" <https://creativecommons.org/publicdomain/zero/1.0/>
+.\"
+.Dd January 26, 2023
+.Dt CRYPTO_X25519 3MONOCYPHER
+.Os
+.Sh NAME
+.Nm crypto_x25519 ,
+.Nm crypto_x25519_public_key ,
+.Nm crypto_x25519_dirty_fast ,
+.Nm crypto_x25519_dirty_small ,
+.Nm crypto_x25519_inverse ,
+.Nm crypto_x25519_to_eddsa
+.Nd X25519 key exchange (Public Key Cryptography)
+.Sh SYNOPSIS
+.In monocypher.h
+.Ft void
+.Fo crypto_x25519
+.Fa "uint8_t raw_shared_secret[32]"
+.Fa "const uint8_t your_secret_key[32]"
+.Fa "const uint8_t their_public_key[32]"
+.Fc
+.Ft void
+.Fo crypto_x25519_public_key
+.Fa "uint8_t your_public_key[32]"
+.Fa "const uint8_t your_secret_key[32]"
+.Fc
+.Ft void
+.Fo crypto_x25519_dirty_fast
+.Fa "uint8_t your_public_key[32]"
+.Fa "const uint8_t your_secret_key[32]"
+.Fc
+.Ft void
+.Fo crypto_x25519_dirty_small
+.Fa "uint8_t your_public_key[32]"
+.Fa "const uint8_t your_secret_key[32]"
+.Fc
+.Ft void
+.Fo crypto_x25519_inverse
+.Fa "uint8_t blind_salt[32]"
+.Fa "const uint8_t private_key[32]"
+.Fa "const uint8_t curve_point[32]"
+.Fc
+.Ft void
+.Fo crypto_x25519_to_eddsa
+.Fa "uint8_t eddsa[32]"
+.Fa "const uint8_t x25519[32]"
+.Fc
+.Sh DESCRIPTION
+.Fn crypto_x25519
+performs an X25519 key exchange between
+.Fa your_secret_key
+and
+.Fa their_public_key .
+It is a low-level building block for protocols such as X3DH.
+.Fn crypto_x25519_public_key
+Generates a public key from a secret key.
+The arguments are:
+.Bl -tag -width Ds
+.It Fa raw_shared_secret
+The shared secret, known only to those who know a relevant secret key
+(yours or theirs).
+It is not cryptographically random.
+Do not use it directly as a key.
+Hash it concatenated with
+.Fa your_public_key
+and
+.Fa their_public_key
+using
+.Xr crypto_blake2b 3monocypher
+for key derivation.
+.It Fa your_secret_key
+A 32-byte secret random number.
+See
+.Xr intro 3monocypher
+for advice about generating random bytes (use the operating system's
+random number generator).
+.It Fa your_public_key
+Your public key, generated by
+.Fn crypto_x25519_public_key .
+.It Fa their_public_key
+The public key of the other party.
+.El
+.Pp
+.Fa raw_shared_secret
+and
+.Fa your_secret_key
+may overlap if your secret is no longer required.
+.Pp
+Some protocols,
+such as some password-authenticated key exchange (PAKE) protocols
+and oblivious pseudo-random functions (OPRF),
+may require
+.Dq contributory
+behaviour, which ensures that no untrusted party forces the shared
+secret to a known constant.
+If a protocol requires contributory behaviour,
+compare the output of
+.Fn crypto_x25519
+to an all-zero buffer using
+.Xr crypto_verify32 3monocypher ,
+then abort the protocol if the output and the all-zero buffer are equal.
+.Pp
+Do not use the same secret key for both key exchanges and signatures.
+The public keys are different and revealing both may leak information.
+If there really is no room to store or derive two different secret keys,
+consider generating a key pair for signatures and then converting the
+private half with
+.Xr crypto_blake2b 3monocypher
+or
+.Xr crypto_sha512 3monocypher ,
+and the public half with
+.Xr crypto_eddsa_to_x25519 3monocypher .
+Or go the other way and implement XEdDSA with the help of
+.Fn crypto_x25519_to_eddsa .
+.Sh RETURN VALUES
+.Fn crypto_x25519
+and
+.Fn crypto_x25519_public_key
+return nothing.
+.Sh EXAMPLES
+The following example assumes the existence of
+.Fn arc4random_buf ,
+which fills the given buffer with cryptographically secure random bytes.
+If
+.Fn arc4random_buf
+does not exist on your system, see
+.Xr intro 3monocypher
+for advice about how to generate cryptographically secure random bytes.
+.Pp
+Generate a pair of shared keys with your secret key and their public
+key
+(this can help nonce management for full duplex communications).
+.Bd -literal -offset indent
+const uint8_t their_pk [32]; /* Their public key */
+uint8_t your_sk [32]; /* Your secret key */
+uint8_t your_pk [32]; /* Your public key */
+uint8_t shared_secret[32]; /* Shared secret (NOT a key) */
+arc4random_buf(your_sk, 32);
+crypto_x25519_public_key(your_pk, your_sk);
+crypto_x25519(shared_secret, your_sk, their_pk);
+/* Wipe secrets if they are no longer needed */
+crypto_wipe(your_sk, 32);
+
+uint8_t shared_keys[64]; /* Two shared session keys */
+crypto_blake2b_ctx ctx;
+crypto_blake2b_init (&ctx, 64);
+crypto_blake2b_update(&ctx, shared_secret, 32);
+crypto_blake2b_update(&ctx, your_pk , 32);
+crypto_blake2b_update(&ctx, their_pk , 32);
+crypto_blake2b_final (&ctx, shared_keys);
+const uint8_t *key_1 = shared_keys; /* Shared key 1 */
+const uint8_t *key_2 = shared_keys + 32; /* Shared key 2 */
+/* Wipe secrets if they are no longer needed */
+crypto_wipe(shared_secret, 32);
+.Ed
+.Sh INVERSE SCALAR MULTIPLICATION
+The
+.Fn crypto_x25519_inverse
+function performs the scalar multiplication of the multiplicative
+inverse of a scalar for X25519.
+It is basically the reverse of
+.Fn crypto_x25519 :
+.Bd -literal -offset indent
+uint8_t b [32]; /* Random scalar */
+uint8_t base [32]; /* Point on the prime order subgroup */
+crypto_x25519_public_key(base, b);
+
+uint8_t private_key[32]; /* Random secret key */
+uint8_t curve_point[32]; /* Point on the prime order subgroup */
+uint8_t blind_salt [32];
+crypto_x25519(curve_point, private_key, base);
+crypto_x25519_inverse(blind_salt, private_key, curve_point);
+assert(memcmp(blind_salt, base, 32) == 0); /* blind_salt == base */
+.Ed
+.Pp
+We can think of it as a scalar division that also clears the cofactor.
+The arguments are:
+.Bl -tag -width Ds
+.It Fa blind_salt
+The output point.
+Guaranteed to be on the prime order subgroup.
+The only possible low order result is a buffer full of zeroes.
+.It Fa private_key
+The private key (scalar) to use.
+It is clamped,
+inverted modulo the prime order of Curve25519,
+cleared of its cofactor,
+and finally used to multiply
+.Fa curve_point .
+.It Fa curve_point
+The curve point to divide by
+.Fa private_key .
+.El
+.Sh DIRTY PUBLIC KEY GENERATION
+.Fn crypto_x25519_dirty_fast
+and
+.Fn crypto_x25519_dirty_small
+do the same as
+.Fn crypto_x25519_public_key ,
+with one key difference:
+they also add a low order point to the public key.
+Such public keys can be on the
+.Em whole
+curve, rather than just the main prime-order subgroup.
+Yet they are fully compatible with
+.Fn crypto_x25519 ,
+and will generate the same shared secrets as regular public keys.
+.Em They do however leak information about the private key .
+Only use them for ephemeral keys that need to be hidden as random noise,
+in conjunction with
+.Xr crypto_elligator_rev 3monocypher .
+.Pp
+Both functions do the same with different code size and memory
+characteristics:
+.Fn crypto_x25519_dirty_fast
+uses multiple large temporary variables and functions that are
+normally used internally for
+.Xr crypto_eddsa_sign 3monocypher .
+Accordingly, it uses both more stack memory and more code
+(unless the signing code is already compiled in elsewhere).
+.Fn crypto_x25519_dirty_small
+yields the same result with less code, less memory,
+and about twice as much time as
+.Fn crypto_x25519_dirty_fast .
+.Sh CONVERSION TO EDDSA
+The
+.Fn crypto_x25519_to_eddsa
+converts an X25519 public key to the corresponding EdDSA public key.
+The sign bit of the resulting EdDSa key is set to zero (positive).
+This can be used to implement the XEdDSA protocol from Signal.
+.Sh SEE ALSO
+.Xr intro 3monocypher
+.Sh STANDARDS
+This function implements X25519, described in RFC 7748.
+.Sh HISTORY
+The
+.Fn crypto_x25519
+and
+.Fn crypto_x25519_public_key
+functions first appeared in Monocypher 0.1.
+The
+.Fn crypto_x25519_inverse ,
+.Fn crypto_x25519_dirty_fast ,
+.Fn crypto_x25519_dirty_small ,
+and
+.Fn crypto_x25519_to_eddsa
+functions first appeared in Monocypher 3.1.0.
+.Sh CAVEATS
+Monocypher does not perform any input validation.
+Any deviation from the specified input and output length ranges results
+in
+.Sy undefined behaviour .
+Make sure your inputs are correct.
+.Sh SECURITY CONSIDERATIONS
+If either of the long-term secret keys leaks, it may compromise
+.Em all past messages .
+This can be avoided by using protocols that provide forward secrecy,
+such as the X3DH key agreement protocol.
+.Pp
+Many (private, public) key pairs produce the same shared secret.
+Therefore, not including the public keys in the key derivation can
+lead to subtle vulnerabilities.
+This can be avoided by hashing the shared secret concatenated with
+both public keys.
+For example,
+.D1 BLAKE2b(shared_secret || your_pk || their_pk)
+using
+.Xr crypto_blake2b 3monocypher .
+.Sh IMPLEMENTATION DETAILS
+The most significant bit of the public key is systematically ignored.
+It is not needed because every public key should be smaller than
+2^255-19, which fits in 255 bits.
+If another implementation of X25519 gives you a key that is not fully
+reduced and has its high bit set, the computation will fail.
+On the other hand, it also means you may use this bit for other purposes
+(such as parity flipping for Ed25519 compatibility).
diff --git a/lib/Utils.Cryptography/monocypher/vendor/doc/doc_check.py b/lib/Utils.Cryptography/monocypher/vendor/doc/doc_check.py
new file mode 100644
index 0000000..3e9d1a8
--- /dev/null
+++ b/lib/Utils.Cryptography/monocypher/vendor/doc/doc_check.py
@@ -0,0 +1,138 @@
+#! /usr/bin/env python3
+
+# This file is dual-licensed. Choose whichever licence you want from
+# the two licences listed below.
+#
+# The first licence is a regular 2-clause BSD licence. The second licence
+# is the CC-0 from Creative Commons. It is intended to release Monocypher
+# to the public domain. The BSD licence serves as a fallback option.
+#
+# SPDX-License-Identifier: BSD-2-Clause OR CC0-1.0
+#
+# ------------------------------------------------------------------------
+#
+# Copyright (c) 2023, Loup Vaillant
+# 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 COPYRIGHT HOLDERS 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 COPYRIGHT
+# HOLDER 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.
+#
+# ------------------------------------------------------------------------
+#
+# Written in 2023 by Loup Vaillant
+#
+# To the extent possible under law, the author(s) have dedicated all copyright
+# and related 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
+# <https://creativecommons.org/publicdomain/zero/1.0/>
+
+import sys
+
+def map_prepend(s, l):
+ return [s + ": " + x for x in l]
+
+def extract(lines, start='', sub=''):
+ return [line.split(' ')[1].strip()
+ for line in lines
+ if (line.startswith(start) and line.__contains__(sub))]
+
+def without(item, list):
+ return [x for x in list if x != item]
+
+def check_inside(lines, all_functions):
+ errors = []
+
+ no_history = []
+ in_history = False
+ for line in lines:
+ if line.startswith('.Sh HISTORY'): in_history = True
+ elif line.startswith('.Sh') : in_history = False
+ if not in_history : no_history.append(line)
+
+ nm = extract(no_history, '.Nm')
+ fo = extract(no_history, '.Fo')
+ fn = extract(no_history, '.Fn')
+ fn = without('arc4random_buf', sorted(set(fn)))
+
+ dupes_nm = sorted(set([x for x in nm if nm.count(x) > 1]))
+ dupes_fo = sorted(set([x for x in fo if fo.count(x) > 1]))
+
+ only_fo = [x for x in fo if nm .count(x) == 0]
+ only_nm = [x for x in nm if fo .count(x) == 0]
+ only_fn = [x for x in fn if fo .count(x) == 0]
+ no_src = [x for x in fn if all_functions.count(x) == 0]
+
+ if len(dupes_nm) > 0: errors.append('Duplicates in .Nm: ' + str(dupes_nm))
+ if len(dupes_fo) > 0: errors.append('Duplicates in .Fo: ' + str(dupes_fo))
+ if len(only_fo) > 0: errors.append('Missing in .Nm: ' + str(only_fo))
+ if len(only_nm) > 0: errors.append('Only in .Nm: ' + str(only_nm))
+ if len(only_fn) > 0: errors.append('Only in .Fn: ' + str(only_fn))
+ if len(no_src) > 0: errors.append('Not in sources: ' + str(no_src))
+
+ return errors
+
+def check_xr(lines, all_nm):
+ errors = []
+ xr = sorted(set(extract(lines, '.Xr', '3monocypher')))
+ dead_xr = [x for x in xr if all_nm.count(x) == 0]
+ if len(dead_xr) > 0:
+ errors.append('Dead .Xr: ' + str(dead_xr))
+ return errors
+
+# Every line from every doc file
+all_lines = {}
+for file_name in sys.argv[1:]:
+ name = file_name.split('.')[0]
+ with open(file_name) as file:
+ all_lines[name] = file.readlines()
+
+# All .Nm (to spot .Xr dead references)
+all_nm = []
+for lines in all_lines.values():
+ all_nm += extract(lines, '.Nm')
+
+# All functions from source files
+all_functions = [x.strip()for x in sys.stdin.readlines()]
+
+# Errors
+errors = []
+for name, lines in all_lines.items():
+ if name != "intro": # skip internal checks for the intro page
+ errors += map_prepend(name, check_inside(lines, all_functions))
+ errors += map_prepend(name, check_xr(lines, all_nm))
+
+# Undocumented functions
+undocumented = [x for x in all_functions if all_nm.count(x) == 0]
+if len(undocumented) > 0:
+ errors.append('Undocumented functions: ' + str(undocumented))
+
+# Print any error, then exit accordingly
+if len(errors) != 0:
+ for e in errors:
+ print(e)
+ exit(1)
diff --git a/lib/Utils.Cryptography/monocypher/vendor/doc/doc_extract_examples.sh b/lib/Utils.Cryptography/monocypher/vendor/doc/doc_extract_examples.sh
new file mode 100644
index 0000000..8fd0736
--- /dev/null
+++ b/lib/Utils.Cryptography/monocypher/vendor/doc/doc_extract_examples.sh
@@ -0,0 +1,78 @@
+#! /bin/sh
+
+# This file is dual-licensed. Choose whichever licence you want from
+# the two licences listed below.
+#
+# The first licence is a regular 2-clause BSD licence. The second licence
+# is the CC-0 from Creative Commons. It is intended to release Monocypher
+# to the public domain. The BSD licence serves as a fallback option.
+#
+# SPDX-License-Identifier: BSD-2-Clause OR CC0-1.0
+#
+# ------------------------------------------------------------------------
+#
+# Copyright (c) 2019 Michael Savage
+# Copyright (c) 2020 Fabio Scotoni
+# 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 COPYRIGHT HOLDERS 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 COPYRIGHT
+# HOLDER 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.
+#
+# ------------------------------------------------------------------------
+#
+# Written in 2019-2020 by Michael Savage and Fabio Scotoni
+#
+# To the extent possible under law, the author(s) have dedicated all copyright
+# and related 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
+# <https://creativecommons.org/publicdomain/zero/1.0/>
+
+cat << END
+#include <assert.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include "../src/monocypher.h"
+#include "../src/optional/monocypher-ed25519.h"
+
+void arc4random_buf(void*, size_t);
+
+int main() {
+END
+
+for f in *.3monocypher
+do
+ if [ ! -h "$f" ]
+ then
+ echo "// $f"
+ cat "$f" | sed -n "/^\.Bd/,/^\.Ed/p" | sed "s/\.Bd.*/{/" | sed "s/\.Ed/}/"
+ fi
+done
+
+echo "return 0;"
+echo "}"
diff --git a/lib/Utils.Cryptography/monocypher/vendor/doc/doc_gen.sh b/lib/Utils.Cryptography/monocypher/vendor/doc/doc_gen.sh
new file mode 100644
index 0000000..804f602
--- /dev/null
+++ b/lib/Utils.Cryptography/monocypher/vendor/doc/doc_gen.sh
@@ -0,0 +1,93 @@
+#! /bin/sh
+
+# This file is dual-licensed. Choose whichever licence you want from
+# the two licences listed below.
+#
+# The first licence is a regular 2-clause BSD licence. The second licence
+# is the CC-0 from Creative Commons. It is intended to release Monocypher
+# to the public domain. The BSD licence serves as a fallback option.
+#
+# SPDX-License-Identifier: BSD-2-Clause OR CC0-1.0
+#
+# ------------------------------------------------------------------------
+#
+# Copyright (c) 2017, 2023, Loup Vaillant
+# Copyright (c) 2017, 2019, Fabio Scotoni
+# 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 COPYRIGHT HOLDERS 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 COPYRIGHT
+# HOLDER 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.
+#
+# ------------------------------------------------------------------------
+#
+# Written in 2017, 2019 and 2023 by Loup Vaillant and Fabio Scotoni
+#
+# To the extent possible under law, the author(s) have dedicated all copyright
+# and related 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
+# <https://creativecommons.org/publicdomain/zero/1.0/>
+
+set -e
+
+cd $(dirname "$0")
+
+# clean before
+rm -rf "html"
+rm -rf "man3"
+find . -type l | xargs rm -f
+
+mkdir -p man3
+mkdir -p html
+cp style.css html/
+
+cat ../src/monocypher.h ../src/optional/monocypher-ed25519.h |\
+ egrep -v "^(//|\}| | |extern)" |\
+ grep crypto_ |\
+ sed 's|[a-z0-9_]* *\([a-z0-9_]*\).*|\1|' |\
+ ./doc_check.py *.3monocypher
+
+for source in $(find . -name "*.3monocypher" | sed 's|^\./||' | sort)
+do
+ name=$(echo "$source" | sed 's/.3monocypher//')
+
+ # Copy source file to the final man page directory
+ cp "$source" "man3/$source"
+
+ # Generate HTML version,
+ mandoc \
+ -Oman=%N.html,style=style.css \
+ -Thtml "$source" \
+ > "./html/$name.html"
+
+ # Add all symbolic links
+ for link in $(grep "^\.Fo " "$source" | tail -n+2 | sed 's/^\.Fo //')
+ do
+ ln -s "$source" "man3/$link.3monocypher"
+ ln -s "$name.html" "html/$link.html"
+ done
+done
diff --git a/lib/Utils.Cryptography/monocypher/vendor/doc/intro.3monocypher b/lib/Utils.Cryptography/monocypher/vendor/doc/intro.3monocypher
new file mode 100644
index 0000000..a02863e
--- /dev/null
+++ b/lib/Utils.Cryptography/monocypher/vendor/doc/intro.3monocypher
@@ -0,0 +1,335 @@
+.\" This file is dual-licensed. Choose whichever you want.
+.\"
+.\" The first licence is a regular 2-clause BSD licence. The second licence
+.\" is the CC-0 from Creative Commons. It is intended to release Monocypher
+.\" to the public domain. The BSD licence serves as a fallback option.
+.\"
+.\" SPDX-License-Identifier: BSD-2-Clause OR CC0-1.0
+.\"
+.\" ----------------------------------------------------------------------------
+.\"
+.\" Copyright (c) 2017-2021 Loup Vaillant
+.\" Copyright (c) 2018 Michael Savage
+.\" Copyright (c) 2017, 2019-2022 Fabio Scotoni
+.\" 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 COPYRIGHT HOLDERS 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 COPYRIGHT
+.\" HOLDER 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.
+.\"
+.\" ----------------------------------------------------------------------------
+.\"
+.\" Written in 2017-2022 by Loup Vaillant, Michael Savage and Fabio Scotoni
+.\"
+.\" To the extent possible under law, the author(s) have dedicated all copyright
+.\" and related 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
+.\" <https://creativecommons.org/publicdomain/zero/1.0/>
+.\"
+.Dd February 20, 2022
+.Dt INTRO 3MONOCYPHER
+.Os
+.Sh NAME
+.Nm intro
+.Nd introduction to Monocypher
+.Sh DESCRIPTION
+Monocypher is a cryptographic library.
+It provides functions for authenticated encryption, hashing, password
+hashing and key derivation, key exchange, and public key signatures.
+.Ss Authenticated encryption
+.Xr crypto_aead_lock 3monocypher
+and
+.Xr crypto_aead_unlock 3monocypher
+use the ChaCha20 cipher and the Poly1305 one-time authenticator.
+There is also an incremental interface to facilitate
+file encryption and encrypted streams.
+.Pp
+ChaCha20 is a stream cipher based on a cryptographic hash function.
+It runs efficiently on a wide variety of hardware, and unlike AES
+naturally runs in constant time on all hardware.
+.Pp
+Poly1305 is a one-time authenticator, derived from Carter & Wegman
+universal hashing.
+It is very fast and very simple.
+.Ss Hashing
+.Xr crypto_blake2b 3monocypher
+implements the BLAKE2b hash.
+BLAKE2b combines the security of SHA-3 and the speed of MD5.
+It is immune to length extension attacks and provides a keyed mode
+that makes it a safe, easy to use authenticator.
+.Ss Password hashing and key derivation
+.Xr crypto_argon2 3monocypher
+implements the Argon2 resource intensive hash algorithm,
+which can be used to hash passwords for storage and to derive keys
+from passwords.
+Argon2 won the password hashing competition in 2015.
+Unlike scrypt, the Argon2i variant is immune to timing attacks.
+.Ss Key exchange (Public Key Cryptography)
+.Xr crypto_x25519 3monocypher
+implements X25519, an elliptic curve Diffie Hellman key exchange
+algorithm based on Curve25519.
+X25519 derives a shared secret from two private/public key pairs.
+It is fast, simple, and relatively easy to implement securely.
+.Pp
+For specialised protocols that require indistinguishability from random
+noise,
+.Xr crypto_elligator_rev 3monocypher
+gives the option to disguise ephemeral (one-time use) X25519 public keys
+as random noise.
+.Ss Public key signatures
+.Xr crypto_eddsa_sign 3monocypher
+and
+.Xr crypto_eddsa_check 3monocypher
+implement EdDSA, with Curve25519 and BLAKE2b.
+This is the same as the more famous Ed25519, with SHA-512 replaced by
+the faster BLAKE2b.
+.Ss Constant time comparison
+.Xr crypto_verify16 3monocypher ,
+.Xr crypto_verify32 3monocypher ,
+and
+.Xr crypto_verify64 3monocypher
+compare buffers in constant time.
+They should be used to compare secrets to prevent timing attacks.
+.Ss Memory wipe
+.Xr crypto_wipe 3monocypher
+wipes a buffer.
+It is meant to erase secrets when they are no longer needed, to reduce
+the chances of leaks.
+.Ss Optional code
+If Monocypher was compiled and installed with the provided makefile,
+SHA-512 functions become available as well.
+See
+.Xr crypto_ed25519_sign 3monocypher ,
+and
+.Xr crypto_sha512 3monocypher .
+.Sh SEE ALSO
+.Xr crypto_aead_init_djb 3monocypher ,
+.Xr crypto_aead_init_ietf 3monocypher ,
+.Xr crypto_aead_init_x 3monocypher ,
+.Xr crypto_aead_lock 3monocypher ,
+.Xr crypto_aead_read 3monocypher ,
+.Xr crypto_aead_unlock 3monocypher ,
+.Xr crypto_aead_write 3monocypher ,
+.Xr crypto_argon2 3monocypher ,
+.Xr crypto_blake2b 3monocypher ,
+.Xr crypto_blake2b_final 3monocypher ,
+.Xr crypto_blake2b_init 3monocypher ,
+.Xr crypto_blake2b_keyed 3monocypher ,
+.Xr crypto_blake2b_keyed_init 3monocypher ,
+.Xr crypto_blake2b_update 3monocypher ,
+.Xr crypto_chacha20_djb 3monocypher ,
+.Xr crypto_chacha20_h 3monocypher ,
+.Xr crypto_chacha20_ietf 3monocypher ,
+.Xr crypto_chacha20_x 3monocypher ,
+.Xr crypto_eddsa_check 3monocypher ,
+.Xr crypto_eddsa_check_equation 3monocypher ,
+.Xr crypto_eddsa_key_pair 3monocypher ,
+.Xr crypto_eddsa_mul_add 3monocypher ,
+.Xr crypto_eddsa_reduce 3monocypher ,
+.Xr crypto_eddsa_scalarbase 3monocypher ,
+.Xr crypto_eddsa_sign 3monocypher ,
+.Xr crypto_eddsa_to_x25519 3monocypher ,
+.Xr crypto_eddsa_trim_scalar 3monocypher ,
+.Xr crypto_elligator_key_pair 3monocypher ,
+.Xr crypto_elligator_map 3monocypher ,
+.Xr crypto_elligator_rev 3monocypher ,
+.Xr crypto_poly1305 3monocypher ,
+.Xr crypto_poly1305_final 3monocypher ,
+.Xr crypto_poly1305_init 3monocypher ,
+.Xr crypto_poly1305_update 3monocypher ,
+.Xr crypto_verify16 3monocypher ,
+.Xr crypto_verify32 3monocypher ,
+.Xr crypto_verify64 3monocypher ,
+.Xr crypto_wipe 3monocypher ,
+.Xr crypto_x25519 3monocypher ,
+.Xr crypto_x25519_dirty_fast 3monocypher ,
+.Xr crypto_x25519_dirty_small 3monocypher ,
+.Xr crypto_x25519_inverse 3monocypher ,
+.Xr crypto_x25519_public_key 3monocypher ,
+.Xr crypto_x25519_to_eddsa 3monocypher
+.Ss Optional code
+.Xr crypto_ed25519_check 3monocypher ,
+.Xr crypto_ed25519_key_pair 3monocypher ,
+.Xr crypto_ed25519_ph_check 3monocypher ,
+.Xr crypto_ed25519_ph_sign 3monocypher ,
+.Xr crypto_ed25519_sign 3monocypher ,
+.Xr crypto_sha512 3monocypher ,
+.Xr crypto_sha512_final 3monocypher ,
+.Xr crypto_sha512_hkdf 3monocypher ,
+.Xr crypto_sha512_hkdf_expand 3monocypher ,
+.Xr crypto_sha512_hmac 3monocypher ,
+.Xr crypto_sha512_hmac_final 3monocypher ,
+.Xr crypto_sha512_hmac_init 3monocypher ,
+.Xr crypto_sha512_hmac_update 3monocypher ,
+.Xr crypto_sha512_init 3monocypher ,
+.Xr crypto_sha512_update 3monocypher
+.Sh CAVEATS
+Monocypher does not perform any input validation.
+Any deviation from the specified input and output length ranges results
+in
+.Sy undefined behaviour .
+Make sure your inputs are correct.
+.Sh SECURITY CONSIDERATIONS
+Using cryptography securely is difficult.
+Flaws that never manifest under normal use might be exploited by a
+clever adversary.
+Cryptographic libraries are easy to catastrophically misuse,
+and Monocypher is no exception.
+.Pp
+Users should follow a formal introduction to cryptography.
+We currently recommend the
+.Lk https://www.crypto101.io/ "Crypto 101 online course" .
+.Ss Random number generation
+Use the facilities of your operating system.
+Avoid user space random number generators,
+whose misuse has led to countless vulnerabilities in the past.
+For instance, the random stream may be repeated if one is not careful
+with multi-threading, and forward secrecy is lost without proper key
+erasure.
+.Pp
+Different system calls are available on different systems:
+.Bl -bullet
+.It
+Recent versions of Linux (glibc >= 2.25, Linux >= 3.17), provide
+.Fn getrandom
+in
+.In sys/random.h .
+Do not set any flag.
+.It
+BSD, Darwin/macOS, illumos, and Solaris provide
+.Fn arc4random_buf
+in
+.In stdlib.h
+or
+.In bsd/stdlib.h .
+This is easier to use than
+.Fn getrandom .
+.It
+Windows provides
+.Fn BCryptGenRandom .
+.El
+.Pp
+The
+.Pa /dev/urandom
+special file may be used on systems that do not provide an easy-to-use
+system call.
+Be careful though, being a file makes
+.Pa /dev/urandom
+hard to use correctly and securely.
+Reads may be interrupted, and more attacks are possible on a file than
+on a system call.
+.Ss Timing attacks
+Monocypher runs in
+.Dq constant time .
+There is no flow from secrets to timings.
+No secret dependent indices, no secret dependent branches.
+Nevertheless, there are a couple important caveats.
+.Pp
+Comparing secrets should be done with constant-time comparison
+functions, such as
+.Xr crypto_verify16 3monocypher ,
+.Xr crypto_verify32 3monocypher ,
+or
+.Xr crypto_verify64 3monocypher .
+Do not use standard comparison functions.
+They tend to stop as soon as a difference is spotted.
+In many cases this enables attackers to recover the secrets and
+destroy all security.
+.Pp
+The Poly1305 authenticator, X25519, and EdDSA use multiplication.
+Some older processors do not multiply in constant time.
+If the target platform is something other than Intel or AMD x86_64,
+double check how it handles multiplication.
+In particular,
+.Em ARM Cortex-M CPUs may lack constant-time multiplication .
+Some VIA Nano x86 and x86_64 CPUs may lack constant-time multiplication
+as well.
+.Ss Data compression
+Encryption does not hide the length of the input plaintext.
+Most compression algorithms work by using fewer bytes to encode
+previously seen data or common characters.
+If an attacker can add data to the input before it is compressed and
+encrypted, they can observe changes to the ciphertext length to recover
+secrets from the input.
+Researchers have demonstrated an attack on HTTPS to steal session
+cookies when compression is enabled, dubbed
+.Dq CRIME .
+.Ss Forward secrecy
+Long-term secrets cannot be expected to stay safe indefinitely.
+Users may reveal them by mistake, or the host computer might have a
+vulnerability and be compromised.
+To mitigate this problem, some protocols guarantee that past messages
+are not compromised even if the long-term keys are.
+This is done by generating temporary keys, then encrypting messages
+using them.
+.Pp
+In general, secrets that went through a computer should not be
+compromised when this computer is stolen or infected at a later point.
+.Pp
+A first layer of defence is to explicitly wipe secrets as soon as
+they are no longer used.
+Monocypher already wipes its own temporary buffers, and contexts are
+erased with the
+.Fn crypto_*_final
+functions.
+The secret keys and messages however are the responsibility of the
+user.
+Use
+.Xr crypto_wipe 3monocypher
+to erase them.
+.Pp
+A second layer of defence is to ensure those secrets are not swapped
+to disk while they are used.
+There are several ways to do this.
+The most secure is to disable swapping entirely.
+Doing so is recommended on sensitive machines.
+Another way is to encrypt the swap partition (this is less safe).
+Finally, swap can be disabled locally \(en this is often the only
+way.
+.Pp
+UNIX systems can disable swap for specific buffers with
+.Fn mlock
+and disable swap for the whole process with
+.Fn mlockall .
+Windows can disable swap for specific buffers with
+.Fn VirtualLock .
+.Pp
+Core dumps cause similar problems.
+Disable them.
+Also beware of suspend to disk (deep sleep mode), which writes all RAM
+to disk regardless of swap policy, as well as virtual machine snapshots.
+Erasing secrets with
+.Xr crypto_wipe 3monocypher
+is often the only way to mitigate these dangers.
+.Ss Undefined behaviour
+Monocypher is a C library.
+C is notoriously unsafe.
+Using Monocypher incorrectly can trigger undefined behaviour.
+This can lead to data corruption, data theft, or even arbitrary code
+execution.
+.Pp
+Consider binding to a safe language if possible.
diff --git a/lib/Utils.Cryptography/monocypher/vendor/doc/style.css b/lib/Utils.Cryptography/monocypher/vendor/doc/style.css
new file mode 100644
index 0000000..0c930dd
--- /dev/null
+++ b/lib/Utils.Cryptography/monocypher/vendor/doc/style.css
@@ -0,0 +1,292 @@
+/*
+ * This file is dual-licensed. Choose whichever licence you want from
+ * the two licences listed below.
+ *
+ * The first licence is a regular 2-clause BSD licence. The second licence
+ * is the CC-0 from Creative Commons. It is intended to release Monocypher
+ * to the public domain. The BSD licence serves as a fallback option.
+ *
+ * SPDX-License-Identifier: BSD-2-Clause OR CC0-1.0
+ *
+ * ------------------------------------------------------------------------
+ *
+ * Copyright (c) 2017-2019, Loup Vaillant
+ * 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 COPYRIGHT HOLDERS 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 COPYRIGHT
+ * HOLDER 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.
+ *
+ * ------------------------------------------------------------------------
+ *
+ * Written in 2017-2019 by Loup Vaillant
+ *
+ * To the extent possible under law, the author(s) have dedicated all copyright
+ * and related 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
+ * <https://creativecommons.org/publicdomain/zero/1.0/>
+ */
+
+/*
+ * This file has been engineered to be compatible with both older mandoc and
+ * newer mandoc.
+ *
+ * mandoc 1.14.1 changed the class named for emph/symb/lit/spacer to
+ * Em/Sy/Li/Pp.
+ * The classes here account for that and are duplicated as necessary.
+ *
+ * The formatting was taken from mandoc.css (mandoc 1.14.5). Assorted changes:
+ * - Liberation Sans was added to the font-family in body.
+ * - added to body:
+ * margin: 1em auto; max-width: 40em; padding: 0 .62em; font-size: 1.1em;
+ * line-height: 1.62;
+ * - Removed .Sh and .Ss from h1 (not present in older mandoc)
+ * - Removed html styling breaking centering in body. It was:
+ * html { max-width: 100ex; }
+ *
+ * Much of the markup that got moved to CSS (e.g. .Ft) was pure HTML in older
+ * versions (<i class="ftype">) so that few adjustments are necessary.
+ *
+ * Upstream mandoc.css was placed in the public domain in CVS revision 1.39:
+ * ----------------------------------------------------------------------------
+ * Written by Ingo Schwarze <schwarze@openbsd.org>.
+ * I place this file into the public domain.
+ * Permission to use, copy, modify, and distribute it for any purpose
+ * with or without fee is hereby granted, without any conditions.
+ * ----------------------------------------------------------------------------
+ */
+body { margin: 1em auto;
+ max-width: 40em;
+ padding: 0 .62em;
+ font-size: 1.1em;
+ line-height: 1.62;
+ font-size: 125%;
+ font-family: "Liberation Sans", Arial, sans-serif; }
+table { margin-top: 0em;
+ margin-bottom: 0em; }
+td { vertical-align: top; }
+ul, ol, dl { margin-top: 0em;
+ margin-bottom: 0em; }
+li, dt { margin-top: 1em; }
+
+a.selflink { border-bottom: thin dotted;
+ color: inherit;
+ font: inherit;
+ text-decoration: inherit; }
+* { clear: both }
+
+/* Search form and search results. */
+
+fieldset { border: thin solid silver;
+ border-radius: 1em;
+ text-align: center; }
+input[name=expr] {
+ width: 25%; }
+
+table.results { margin-top: 1em;
+ margin-left: 2em;
+ font-size: smaller; }
+
+/* Header and footer lines. */
+
+table.head { width: 100%;
+ border-bottom: 1px dotted #808080;
+ margin-bottom: 1em;
+ font-size: smaller; }
+td.head-vol { text-align: center; }
+td.head-rtitle {
+ text-align: right; }
+span.Nd { }
+
+table.foot { width: 100%;
+ border-top: 1px dotted #808080;
+ margin-top: 1em;
+ font-size: smaller; }
+td.foot-os { text-align: right; }
+
+/* Sections and paragraphs. */
+
+div.manual-text {
+ margin-left: 5ex; }
+h1 { margin-top: 2ex;
+ margin-bottom: 1ex;
+ margin-left: -4ex;
+ font-size: 110%; }
+h2 { margin-top: 2ex;
+ margin-bottom: 1ex;
+ margin-left: -2ex;
+ font-size: 105%; }
+div.Pp { margin: 1ex 0ex; }
+div.spacer { margin: 1ex 0ex; }
+a.Sx { }
+a.Xr { }
+
+/* Displays and lists. */
+
+div.Bd { }
+div.D1 { margin-left: 5ex; }
+
+ul.Bl-bullet { list-style-type: disc;
+ padding-left: 1em; }
+li.It-bullet { }
+ul.Bl-dash { list-style-type: none;
+ padding-left: 0em; }
+li.It-dash:before {
+ content: "\2014 "; }
+ul.Bl-item { list-style-type: none;
+ padding-left: 0em; }
+li.It-item { }
+ul.Bl-compact > li {
+ margin-top: 0ex; }
+
+ol.Bl-enum { padding-left: 2em; }
+li.It-enum { }
+ol.Bl-compact > li {
+ margin-top: 0ex; }
+
+dl.Bl-diag { }
+dt.It-diag { }
+dd.It-diag { margin-left: 0ex; }
+b.It-diag { font-style: normal; }
+dl.Bl-hang { }
+dt.It-hang { }
+dd.It-hang { margin-left: 10.2ex; }
+dl.Bl-inset { }
+dt.It-inset { }
+dd.It-inset { margin-left: 0ex; }
+dl.Bl-ohang { }
+dt.It-ohang { }
+dd.It-ohang { margin-left: 0ex; }
+dl.Bl-tag { margin-left: 10.2ex; }
+dt.It-tag { float: left;
+ margin-top: 0ex;
+ margin-left: -10.2ex;
+ padding-right: 2ex;
+ vertical-align: top; }
+dd.It-tag { clear: right;
+ width: 100%;
+ margin-top: 0ex;
+ margin-left: 0ex;
+ vertical-align: top;
+ overflow: auto; }
+dl.Bl-compact > dt {
+ margin-top: 0ex; }
+
+table.Bl-column { }
+tr.It-column { }
+td.It-column { margin-top: 1em; }
+table.Bl-compact > tbody > tr > td {
+ margin-top: 0ex; }
+
+cite.Rs { font-style: normal;
+ font-weight: normal; }
+span.RsA { }
+i.RsB { font-weight: normal; }
+span.RsC { }
+span.RsD { }
+i.RsI { font-weight: normal; }
+i.RsJ { font-weight: normal; }
+span.RsN { }
+span.RsO { }
+span.RsP { }
+span.RsQ { }
+span.RsR { }
+span.RsT { text-decoration: underline; }
+a.RsU { }
+span.RsV { }
+
+span.eqn { }
+table.tbl { }
+
+/* Semantic markup for command line utilities. */
+
+table.Nm { }
+b.Nm { font-style: normal; }
+b.Fl { font-style: normal; }
+b.Cm { font-style: normal; }
+var.Ar { font-style: italic;
+ font-weight: normal; }
+span.Op { }
+b.Ic { font-style: normal; }
+code.Ev { font-style: normal;
+ font-weight: normal;
+ font-family: monospace; }
+i.Pa { font-weight: normal; }
+
+/* Semantic markup for function libraries. */
+
+span.Lb { }
+b.In { font-style: normal; }
+a.In { }
+b.Fd { font-style: normal; }
+var.Ft { font-style: italic;
+ font-weight: normal; }
+b.Fn { font-style: normal; }
+var.Fa { font-style: italic;
+ font-weight: normal; }
+var.Vt { font-style: italic;
+ font-weight: normal; }
+var.Va { font-style: italic;
+ font-weight: normal; }
+code.Dv { font-style: normal;
+ font-weight: normal;
+ font-family: monospace; }
+code.Er { font-style: normal;
+ font-weight: normal;
+ font-family: monospace; }
+
+/* Various semantic markup. */
+
+span.An { }
+a.Lk { }
+a.Mt { }
+b.Cd { font-style: normal; }
+i.Ad { font-weight: normal; }
+b.Ms { font-style: normal; }
+span.St { }
+a.Ux { }
+
+/* Physical markup. */
+
+.No { font-style: normal;
+ font-weight: normal; }
+.none { font-style: normal;
+ font-weight: normal; }
+.Em { font-style: italic;
+ font-weight: normal; }
+.emph { font-style: italic;
+ font-weight: normal; }
+.Sy { font-style: normal;
+ font-weight: bold; }
+.symb { font-style: normal;
+ font-weight: bold; }
+.Li { font-style: normal;
+ font-weight: normal;
+ font-family: monospace; }
+.lit { font-style: normal;
+ font-weight: normal;
+ font-family: monospace; }
diff --git a/lib/Utils.Cryptography/monocypher/vendor/makefile b/lib/Utils.Cryptography/monocypher/vendor/makefile
new file mode 100644
index 0000000..d747ff2
--- /dev/null
+++ b/lib/Utils.Cryptography/monocypher/vendor/makefile
@@ -0,0 +1,211 @@
+# This file is dual-licensed. Choose whichever licence you want from
+# the two licences listed below.
+#
+# The first licence is a regular 2-clause BSD licence. The second licence
+# is the CC-0 from Creative Commons. It is intended to release Monocypher
+# to the public domain. The BSD licence serves as a fallback option.
+#
+# SPDX-License-Identifier: BSD-2-Clause OR CC0-1.0
+#
+# ------------------------------------------------------------------------
+#
+# Copyright (c) 2017-2019, Loup Vaillant
+# Copyright (c) 2017, 2019, Fabio Scotoni
+# 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 COPYRIGHT HOLDERS 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 COPYRIGHT
+# HOLDER 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.
+#
+# ------------------------------------------------------------------------
+#
+# Written in 2017-2019 by Loup Vaillant and Fabio Scotoni
+#
+# To the extent possible under law, the author(s) have dedicated all copyright
+# and related 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
+# <https://creativecommons.org/publicdomain/zero/1.0/>
+.POSIX:
+.SUFFIXES:
+
+CC ?= gcc -std=c99
+CFLAGS ?= -pedantic -Wall -Wextra -O3 -march=native
+DESTDIR ?=
+PREFIX ?= /usr/local
+LIBDIR ?= $(PREFIX)/lib
+INCLUDEDIR ?= $(PREFIX)/include
+PKGCONFIGDIR ?= $(LIBDIR)/pkgconfig
+MANDIR ?= $(PREFIX)/share/man/man3
+SONAME = libmonocypher.so.4
+
+.PHONY: all library static-library dynamic-library \
+ install install-lib install-pc install-doc \
+ check test tis-ci ctgrind \
+ clean uninstall dist
+
+##################
+## Main targets ##
+##################
+all : library doc/man3/intro.3monocypher
+check: test
+
+test: test.out
+ ./test.out
+
+tis-ci: tis-ci.out
+ ./tis-ci.out
+
+ctgrind: ctgrind.out
+ valgrind ./ctgrind.out
+
+clean:
+ rm -rf lib/ doc/html/ doc/man3/
+ rm -f *.out
+
+#############
+## Install ##
+#############
+install: install-lib install-pc install-doc
+
+install-lib: library
+ mkdir -p $(DESTDIR)$(INCLUDEDIR)
+ mkdir -p $(DESTDIR)$(LIBDIR)
+ cp -P lib/libmonocypher.a lib/libmonocypher.so* $(DESTDIR)$(LIBDIR)
+ cp -P src/monocypher.h $(DESTDIR)$(INCLUDEDIR)
+ cp -P src/optional/monocypher-ed25519.h $(DESTDIR)$(INCLUDEDIR)
+
+install-pc: monocypher.pc
+ mkdir -p $(DESTDIR)$(PKGCONFIGDIR)
+ sed "s|PREFIX|$(PREFIX)|" monocypher.pc \
+ > $(DESTDIR)$(PKGCONFIGDIR)/monocypher.pc
+
+install-doc: doc/man3/intro.3monocypher
+ mkdir -p $(DESTDIR)$(MANDIR)
+ cp -PR doc/man3/*.3monocypher $(DESTDIR)$(MANDIR)
+
+uninstall:
+ rm -f $(DESTDIR)$(LIBDIR)/libmonocypher.a
+ rm -f $(DESTDIR)$(LIBDIR)/libmonocypher.so*
+ rm -f $(DESTDIR)$(INCLUDEDIR)/monocypher.h
+ rm -f $(DESTDIR)$(INCLUDEDIR)/monocypher-ed25519.h
+ rm -f $(DESTDIR)$(PKGCONFIGDIR)/monocypher.pc
+ rm -f $(DESTDIR)$(MANDIR)/*.3monocypher
+
+##################
+## Main library ##
+##################
+library: static-library dynamic-library
+static-library : lib/libmonocypher.a
+dynamic-library: lib/libmonocypher.so lib/$(SONAME)
+
+MAIN_O=lib/monocypher.o lib/monocypher-ed25519.o
+MAIN_I=-I src -I src/optional
+
+lib/libmonocypher.a: $(MAIN_O)
+ $(AR) cr $@ $(MAIN_O)
+
+lib/libmonocypher.so: lib/$(SONAME)
+ ln -sf `basename lib/$(SONAME)` $@
+
+lib/$(SONAME): $(MAIN_O)
+ $(CC) $(CFLAGS) $(LDFLAGS) -shared -Wl,-soname,$(SONAME) -o $@ $(MAIN_O)
+
+lib/monocypher.o: src/monocypher.c src/monocypher.h
+ @mkdir -p $(@D)
+ $(CC) $(CFLAGS) $(MAIN_I) -fPIC -c -o $@ src/monocypher.c
+
+lib/monocypher-ed25519.o: src/optional/monocypher-ed25519.c \
+ src/optional/monocypher-ed25519.h
+ @mkdir -p $(@D)
+ $(CC) $(CFLAGS) $(MAIN_I) -fPIC -c -o $@ src/optional/monocypher-ed25519.c
+
+####################
+## Test libraries ##
+####################
+TEST_COMMON=tests/utils.h src/monocypher.h src/optional/monocypher-ed25519.h
+TEST_I=$(MAIN_I) -I tests
+
+lib/utils.o: tests/utils.c
+ @mkdir -p $(@D)
+ $(CC) $(CFLAGS) $(TEST_I) -fPIC -c -o $@ tests/utils.c
+
+lib/test.o: tests/test.c $(TEST_COMMON) tests/vectors.h
+ @mkdir -p $(@D)
+ $(CC) $(CFLAGS) $(TEST_I) -fPIC -c -o $@ tests/test.c
+
+lib/tis-ci.o: tests/tis-ci.c $(TEST_COMMON) tests/tis-ci-vectors.h
+ @mkdir -p $(@D)
+ $(CC) $(CFLAGS) $(TEST_I) -fPIC -c -o $@ tests/tis-ci.c
+
+lib/ctgrind.o: tests/ctgrind.c $(TEST_COMMON)
+ @mkdir -p $(@D)
+ $(CC) $(CFLAGS) $(TEST_I) -fPIC -c -o $@ tests/ctgrind.c
+
+######################
+## Test executables ##
+######################
+TEST_OBJ = lib/utils.o lib/monocypher.o lib/monocypher-ed25519.o
+
+test.out: lib/test.o $(TEST_OBJ)
+ $(CC) $(CFLAGS) -o $@ lib/test.o $(TEST_OBJ)
+
+tis-ci.out: lib/tis-ci.o $(TEST_OBJ)
+ $(CC) $(CFLAGS) -o $@ lib/tis-ci.o $(TEST_OBJ)
+
+ctgrind.out: lib/ctgrind.o $(TEST_OBJ)
+ $(CC) $(CFLAGS) -o $@ lib/ctgrind.o $(TEST_OBJ)
+# Remove lines below for the tarball
+
+tests/vectors.h:
+ @echo ""
+ @echo "======================================================"
+ @echo " I cannot perform the tests without the test vectors."
+ @echo " You must generate them. This requires Libsodium."
+ @echo " The following will generate the test vectors:"
+ @echo ""
+ @echo " $ cd tests/gen"
+ @echo " $ make"
+ @echo ""
+ @echo " Alternatively, you can grab an official release."
+ @echo " It will include the test vectors, so you won't"
+ @echo " need libsodium."
+ @echo "======================================================"
+ @echo ""
+ exit 1
+
+doc/man3/intro.3monocypher: \
+ doc/crypto_aead_lock.3monocypher doc/crypto_argon2.3monocypher \
+ doc/crypto_blake2b.3monocypher doc/crypto_chacha20_djb.3monocypher \
+ doc/crypto_ed25519_sign.3monocypher doc/crypto_eddsa_sign.3monocypher \
+ doc/crypto_elligator_map.3monocypher doc/crypto_poly1305.3monocypher \
+ doc/crypto_sha512.3monocypher doc/crypto_verify16.3monocypher \
+ doc/crypto_wipe.3monocypher doc/crypto_x25519.3monocypher \
+ doc/intro.3monocypher
+ doc/doc_gen.sh
+
+dist: tests/vectors.h
+ ./dist.sh
diff --git a/lib/Utils.Cryptography/monocypher/vendor/monocypher.pc b/lib/Utils.Cryptography/monocypher/vendor/monocypher.pc
new file mode 100644
index 0000000..0945104
--- /dev/null
+++ b/lib/Utils.Cryptography/monocypher/vendor/monocypher.pc
@@ -0,0 +1,11 @@
+prefix=PREFIX
+exec_prefix=${prefix}
+libdir=${exec_prefix}/lib
+includedir=${prefix}/include
+
+Name: monocypher
+Version: __git__
+Description: Easy to use, easy to deploy crypto library
+
+Libs: -L${libdir} -lmonocypher
+Cflags: -I${includedir}
diff --git a/lib/Utils.Cryptography/monocypher/vendor/src/monocypher.c b/lib/Utils.Cryptography/monocypher/vendor/src/monocypher.c
new file mode 100644
index 0000000..0accae7
--- /dev/null
+++ b/lib/Utils.Cryptography/monocypher/vendor/src/monocypher.c
@@ -0,0 +1,2956 @@
+// Monocypher version __git__
+//
+// This file is dual-licensed. Choose whichever licence you want from
+// the two licences listed below.
+//
+// The first licence is a regular 2-clause BSD licence. The second licence
+// is the CC-0 from Creative Commons. It is intended to release Monocypher
+// to the public domain. The BSD licence serves as a fallback option.
+//
+// SPDX-License-Identifier: BSD-2-Clause OR CC0-1.0
+//
+// ------------------------------------------------------------------------
+//
+// Copyright (c) 2017-2020, Loup Vaillant
+// 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 COPYRIGHT HOLDERS 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 COPYRIGHT
+// HOLDER 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.
+//
+// ------------------------------------------------------------------------
+//
+// Written in 2017-2020 by Loup Vaillant
+//
+// To the extent possible under law, the author(s) have dedicated all copyright
+// and related 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
+// <https://creativecommons.org/publicdomain/zero/1.0/>
+
+#include "monocypher.h"
+
+#ifdef MONOCYPHER_CPP_NAMESPACE
+namespace MONOCYPHER_CPP_NAMESPACE {
+#endif
+
+/////////////////
+/// Utilities ///
+/////////////////
+#define FOR_T(type, i, start, end) for (type i = (start); i < (end); i++)
+#define FOR(i, start, end) FOR_T(size_t, i, start, end)
+#define COPY(dst, src, size) FOR(_i_, 0, size) (dst)[_i_] = (src)[_i_]
+#define ZERO(buf, size) FOR(_i_, 0, size) (buf)[_i_] = 0
+#define WIPE_CTX(ctx) crypto_wipe(ctx , sizeof(*(ctx)))
+#define WIPE_BUFFER(buffer) crypto_wipe(buffer, sizeof(buffer))
+#define MIN(a, b) ((a) <= (b) ? (a) : (b))
+#define MAX(a, b) ((a) >= (b) ? (a) : (b))
+
+typedef int8_t i8;
+typedef uint8_t u8;
+typedef int16_t i16;
+typedef uint32_t u32;
+typedef int32_t i32;
+typedef int64_t i64;
+typedef uint64_t u64;
+
+static const u8 zero[128] = {0};
+
+// returns the smallest positive integer y such that
+// (x + y) % pow_2 == 0
+// Basically, y is the "gap" missing to align x.
+// Only works when pow_2 is a power of 2.
+// Note: we use ~x+1 instead of -x to avoid compiler warnings
+static size_t gap(size_t x, size_t pow_2)
+{
+ return (~x + 1) & (pow_2 - 1);
+}
+
+static u32 load24_le(const u8 s[3])
+{
+ return
+ ((u32)s[0] << 0) |
+ ((u32)s[1] << 8) |
+ ((u32)s[2] << 16);
+}
+
+static u32 load32_le(const u8 s[4])
+{
+ return
+ ((u32)s[0] << 0) |
+ ((u32)s[1] << 8) |
+ ((u32)s[2] << 16) |
+ ((u32)s[3] << 24);
+}
+
+static u64 load64_le(const u8 s[8])
+{
+ return load32_le(s) | ((u64)load32_le(s+4) << 32);
+}
+
+static void store32_le(u8 out[4], u32 in)
+{
+ out[0] = in & 0xff;
+ out[1] = (in >> 8) & 0xff;
+ out[2] = (in >> 16) & 0xff;
+ out[3] = (in >> 24) & 0xff;
+}
+
+static void store64_le(u8 out[8], u64 in)
+{
+ store32_le(out , (u32)in );
+ store32_le(out + 4, in >> 32);
+}
+
+static void load32_le_buf (u32 *dst, const u8 *src, size_t size) {
+ FOR(i, 0, size) { dst[i] = load32_le(src + i*4); }
+}
+static void load64_le_buf (u64 *dst, const u8 *src, size_t size) {
+ FOR(i, 0, size) { dst[i] = load64_le(src + i*8); }
+}
+static void store32_le_buf(u8 *dst, const u32 *src, size_t size) {
+ FOR(i, 0, size) { store32_le(dst + i*4, src[i]); }
+}
+static void store64_le_buf(u8 *dst, const u64 *src, size_t size) {
+ FOR(i, 0, size) { store64_le(dst + i*8, src[i]); }
+}
+
+static u64 rotr64(u64 x, u64 n) { return (x >> n) ^ (x << (64 - n)); }
+static u32 rotl32(u32 x, u32 n) { return (x << n) ^ (x >> (32 - n)); }
+
+static int neq0(u64 diff)
+{
+ // constant time comparison to zero
+ // return diff != 0 ? -1 : 0
+ u64 half = (diff >> 32) | ((u32)diff);
+ return (1 & ((half - 1) >> 32)) - 1;
+}
+
+static u64 x16(const u8 a[16], const u8 b[16])
+{
+ return (load64_le(a + 0) ^ load64_le(b + 0))
+ | (load64_le(a + 8) ^ load64_le(b + 8));
+}
+static u64 x32(const u8 a[32],const u8 b[32]){return x16(a,b)| x16(a+16, b+16);}
+static u64 x64(const u8 a[64],const u8 b[64]){return x32(a,b)| x32(a+32, b+32);}
+int crypto_verify16(const u8 a[16], const u8 b[16]){ return neq0(x16(a, b)); }
+int crypto_verify32(const u8 a[32], const u8 b[32]){ return neq0(x32(a, b)); }
+int crypto_verify64(const u8 a[64], const u8 b[64]){ return neq0(x64(a, b)); }
+
+void crypto_wipe(void *secret, size_t size)
+{
+ volatile u8 *v_secret = (u8*)secret;
+ ZERO(v_secret, size);
+}
+
+/////////////////
+/// Chacha 20 ///
+/////////////////
+#define QUARTERROUND(a, b, c, d) \
+ 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)
+
+static void chacha20_rounds(u32 out[16], const u32 in[16])
+{
+ // The temporary variables make Chacha20 10% faster.
+ u32 t0 = in[ 0]; u32 t1 = in[ 1]; u32 t2 = in[ 2]; u32 t3 = in[ 3];
+ u32 t4 = in[ 4]; u32 t5 = in[ 5]; u32 t6 = in[ 6]; u32 t7 = in[ 7];
+ u32 t8 = in[ 8]; u32 t9 = in[ 9]; u32 t10 = in[10]; u32 t11 = in[11];
+ u32 t12 = in[12]; u32 t13 = in[13]; u32 t14 = in[14]; u32 t15 = in[15];
+
+ FOR (i, 0, 10) { // 20 rounds, 2 rounds per loop.
+ QUARTERROUND(t0, t4, t8 , t12); // column 0
+ QUARTERROUND(t1, t5, t9 , t13); // column 1
+ QUARTERROUND(t2, t6, t10, t14); // column 2
+ QUARTERROUND(t3, t7, t11, t15); // column 3
+ QUARTERROUND(t0, t5, t10, t15); // diagonal 0
+ QUARTERROUND(t1, t6, t11, t12); // diagonal 1
+ QUARTERROUND(t2, t7, t8 , t13); // diagonal 2
+ QUARTERROUND(t3, t4, t9 , t14); // diagonal 3
+ }
+ out[ 0] = t0; out[ 1] = t1; out[ 2] = t2; out[ 3] = t3;
+ out[ 4] = t4; out[ 5] = t5; out[ 6] = t6; out[ 7] = t7;
+ out[ 8] = t8; out[ 9] = t9; out[10] = t10; out[11] = t11;
+ out[12] = t12; out[13] = t13; out[14] = t14; out[15] = t15;
+}
+
+static const u8 *chacha20_constant = (const u8*)"expand 32-byte k"; // 16 bytes
+
+void crypto_chacha20_h(u8 out[32], const u8 key[32], const u8 in [16])
+{
+ u32 block[16];
+ load32_le_buf(block , chacha20_constant, 4);
+ load32_le_buf(block + 4, key , 8);
+ load32_le_buf(block + 12, in , 4);
+
+ chacha20_rounds(block, block);
+
+ // prevent reversal of the rounds by revealing only half of the buffer.
+ store32_le_buf(out , block , 4); // constant
+ store32_le_buf(out+16, block+12, 4); // counter and nonce
+ WIPE_BUFFER(block);
+}
+
+u64 crypto_chacha20_djb(u8 *cipher_text, const u8 *plain_text,
+ size_t text_size, const u8 key[32], const u8 nonce[8],
+ u64 ctr)
+{
+ u32 input[16];
+ load32_le_buf(input , chacha20_constant, 4);
+ load32_le_buf(input + 4, key , 8);
+ load32_le_buf(input + 14, nonce , 2);
+ input[12] = (u32) ctr;
+ input[13] = (u32)(ctr >> 32);
+
+ // Whole blocks
+ u32 pool[16];
+ size_t nb_blocks = text_size >> 6;
+ FOR (i, 0, nb_blocks) {
+ chacha20_rounds(pool, input);
+ if (plain_text != NULL) {
+ FOR (j, 0, 16) {
+ u32 p = pool[j] + input[j];
+ store32_le(cipher_text, p ^ load32_le(plain_text));
+ cipher_text += 4;
+ plain_text += 4;
+ }
+ } else {
+ FOR (j, 0, 16) {
+ u32 p = pool[j] + input[j];
+ store32_le(cipher_text, p);
+ cipher_text += 4;
+ }
+ }
+ input[12]++;
+ if (input[12] == 0) {
+ input[13]++;
+ }
+ }
+ text_size &= 63;
+
+ // Last (incomplete) block
+ if (text_size > 0) {
+ if (plain_text == NULL) {
+ plain_text = zero;
+ }
+ chacha20_rounds(pool, input);
+ u8 tmp[64];
+ FOR (i, 0, 16) {
+ store32_le(tmp + i*4, pool[i] + input[i]);
+ }
+ FOR (i, 0, text_size) {
+ cipher_text[i] = tmp[i] ^ plain_text[i];
+ }
+ WIPE_BUFFER(tmp);
+ }
+ ctr = input[12] + ((u64)input[13] << 32) + (text_size > 0);
+
+ WIPE_BUFFER(pool);
+ WIPE_BUFFER(input);
+ return ctr;
+}
+
+u32 crypto_chacha20_ietf(u8 *cipher_text, const u8 *plain_text,
+ size_t text_size,
+ const u8 key[32], const u8 nonce[12], u32 ctr)
+{
+ u64 big_ctr = ctr + ((u64)load32_le(nonce) << 32);
+ return (u32)crypto_chacha20_djb(cipher_text, plain_text, text_size,
+ key, nonce + 4, big_ctr);
+}
+
+u64 crypto_chacha20_x(u8 *cipher_text, const u8 *plain_text,
+ size_t text_size,
+ const u8 key[32], const u8 nonce[24], u64 ctr)
+{
+ u8 sub_key[32];
+ crypto_chacha20_h(sub_key, key, nonce);
+ ctr = crypto_chacha20_djb(cipher_text, plain_text, text_size,
+ sub_key, nonce + 16, ctr);
+ WIPE_BUFFER(sub_key);
+ return ctr;
+}
+
+/////////////////
+/// Poly 1305 ///
+/////////////////
+
+// h = (h + c) * r
+// preconditions:
+// ctx->h <= 4_ffffffff_ffffffff_ffffffff_ffffffff
+// ctx->r <= 0ffffffc_0ffffffc_0ffffffc_0fffffff
+// end <= 1
+// Postcondition:
+// ctx->h <= 4_ffffffff_ffffffff_ffffffff_ffffffff
+static void poly_blocks(crypto_poly1305_ctx *ctx, const u8 *in,
+ size_t nb_blocks, unsigned end)
+{
+ // Local all the things!
+ const u32 r0 = ctx->r[0];
+ const u32 r1 = ctx->r[1];
+ const u32 r2 = ctx->r[2];
+ const u32 r3 = ctx->r[3];
+ const u32 rr0 = (r0 >> 2) * 5; // lose 2 bits...
+ const u32 rr1 = (r1 >> 2) + r1; // rr1 == (r1 >> 2) * 5
+ const u32 rr2 = (r2 >> 2) + r2; // rr1 == (r2 >> 2) * 5
+ const u32 rr3 = (r3 >> 2) + r3; // rr1 == (r3 >> 2) * 5
+ const u32 rr4 = r0 & 3; // ...recover 2 bits
+ u32 h0 = ctx->h[0];
+ u32 h1 = ctx->h[1];
+ u32 h2 = ctx->h[2];
+ u32 h3 = ctx->h[3];
+ u32 h4 = ctx->h[4];
+
+ FOR (i, 0, nb_blocks) {
+ // h + c, without carry propagation
+ const u64 s0 = (u64)h0 + load32_le(in); in += 4;
+ const u64 s1 = (u64)h1 + load32_le(in); in += 4;
+ const u64 s2 = (u64)h2 + load32_le(in); in += 4;
+ const u64 s3 = (u64)h3 + load32_le(in); in += 4;
+ const u32 s4 = h4 + end;
+
+ // (h + c) * r, without carry propagation
+ const u64 x0 = s0*r0+ s1*rr3+ s2*rr2+ s3*rr1+ s4*rr0;
+ const u64 x1 = s0*r1+ s1*r0 + s2*rr3+ s3*rr2+ s4*rr1;
+ const u64 x2 = s0*r2+ s1*r1 + s2*r0 + s3*rr3+ s4*rr2;
+ const u64 x3 = s0*r3+ s1*r2 + s2*r1 + s3*r0 + s4*rr3;
+ const u32 x4 = s4*rr4;
+
+ // partial reduction modulo 2^130 - 5
+ const u32 u5 = x4 + (x3 >> 32); // u5 <= 7ffffff5
+ const u64 u0 = (u5 >> 2) * 5 + (x0 & 0xffffffff);
+ const u64 u1 = (u0 >> 32) + (x1 & 0xffffffff) + (x0 >> 32);
+ const u64 u2 = (u1 >> 32) + (x2 & 0xffffffff) + (x1 >> 32);
+ const u64 u3 = (u2 >> 32) + (x3 & 0xffffffff) + (x2 >> 32);
+ const u32 u4 = (u3 >> 32) + (u5 & 3); // u4 <= 4
+
+ // Update the hash
+ h0 = u0 & 0xffffffff;
+ h1 = u1 & 0xffffffff;
+ h2 = u2 & 0xffffffff;
+ h3 = u3 & 0xffffffff;
+ h4 = u4;
+ }
+ ctx->h[0] = h0;
+ ctx->h[1] = h1;
+ ctx->h[2] = h2;
+ ctx->h[3] = h3;
+ ctx->h[4] = h4;
+}
+
+void crypto_poly1305_init(crypto_poly1305_ctx *ctx, const u8 key[32])
+{
+ ZERO(ctx->h, 5); // Initial hash is zero
+ ctx->c_idx = 0;
+ // load r and pad (r has some of its bits cleared)
+ load32_le_buf(ctx->r , key , 4);
+ load32_le_buf(ctx->pad, key+16, 4);
+ FOR (i, 0, 1) { ctx->r[i] &= 0x0fffffff; }
+ FOR (i, 1, 4) { ctx->r[i] &= 0x0ffffffc; }
+}
+
+void crypto_poly1305_update(crypto_poly1305_ctx *ctx,
+ const u8 *message, size_t message_size)
+{
+ // Avoid undefined NULL pointer increments with empty messages
+ if (message_size == 0) {
+ return;
+ }
+
+ // Align ourselves with block boundaries
+ size_t aligned = MIN(gap(ctx->c_idx, 16), message_size);
+ FOR (i, 0, aligned) {
+ ctx->c[ctx->c_idx] = *message;
+ ctx->c_idx++;
+ message++;
+ message_size--;
+ }
+
+ // If block is complete, process it
+ if (ctx->c_idx == 16) {
+ poly_blocks(ctx, ctx->c, 1, 1);
+ ctx->c_idx = 0;
+ }
+
+ // Process the message block by block
+ size_t nb_blocks = message_size >> 4;
+ poly_blocks(ctx, message, nb_blocks, 1);
+ message += nb_blocks << 4;
+ message_size &= 15;
+
+ // remaining bytes (we never complete a block here)
+ FOR (i, 0, message_size) {
+ ctx->c[ctx->c_idx] = message[i];
+ ctx->c_idx++;
+ }
+}
+
+void crypto_poly1305_final(crypto_poly1305_ctx *ctx, u8 mac[16])
+{
+ // Process the last block (if any)
+ // We move the final 1 according to remaining input length
+ // (this will add less than 2^130 to the last input block)
+ if (ctx->c_idx != 0) {
+ ZERO(ctx->c + ctx->c_idx, 16 - ctx->c_idx);
+ ctx->c[ctx->c_idx] = 1;
+ poly_blocks(ctx, ctx->c, 1, 0);
+ }
+
+ // check if we should subtract 2^130-5 by performing the
+ // corresponding carry propagation.
+ u64 c = 5;
+ FOR (i, 0, 4) {
+ c += ctx->h[i];
+ c >>= 32;
+ }
+ c += ctx->h[4];
+ c = (c >> 2) * 5; // shift the carry back to the beginning
+ // c now indicates how many times we should subtract 2^130-5 (0 or 1)
+ FOR (i, 0, 4) {
+ c += (u64)ctx->h[i] + ctx->pad[i];
+ store32_le(mac + i*4, (u32)c);
+ c = c >> 32;
+ }
+ WIPE_CTX(ctx);
+}
+
+void crypto_poly1305(u8 mac[16], const u8 *message,
+ size_t message_size, const u8 key[32])
+{
+ crypto_poly1305_ctx ctx;
+ crypto_poly1305_init (&ctx, key);
+ crypto_poly1305_update(&ctx, message, message_size);
+ crypto_poly1305_final (&ctx, mac);
+}
+
+////////////////
+/// BLAKE2 b ///
+////////////////
+static const u64 iv[8] = {
+ 0x6a09e667f3bcc908, 0xbb67ae8584caa73b,
+ 0x3c6ef372fe94f82b, 0xa54ff53a5f1d36f1,
+ 0x510e527fade682d1, 0x9b05688c2b3e6c1f,
+ 0x1f83d9abfb41bd6b, 0x5be0cd19137e2179,
+};
+
+static void blake2b_compress(crypto_blake2b_ctx *ctx, int is_last_block)
+{
+ static const u8 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 },
+ };
+
+ // increment input offset
+ u64 *x = ctx->input_offset;
+ size_t y = ctx->input_idx;
+ x[0] += y;
+ if (x[0] < y) {
+ x[1]++;
+ }
+
+ // init work vector
+ u64 v0 = ctx->hash[0]; u64 v8 = iv[0];
+ u64 v1 = ctx->hash[1]; u64 v9 = iv[1];
+ u64 v2 = ctx->hash[2]; u64 v10 = iv[2];
+ u64 v3 = ctx->hash[3]; u64 v11 = iv[3];
+ u64 v4 = ctx->hash[4]; u64 v12 = iv[4] ^ ctx->input_offset[0];
+ u64 v5 = ctx->hash[5]; u64 v13 = iv[5] ^ ctx->input_offset[1];
+ u64 v6 = ctx->hash[6]; u64 v14 = iv[6] ^ (u64)~(is_last_block - 1);
+ u64 v7 = ctx->hash[7]; u64 v15 = iv[7];
+
+ // mangle work vector
+ u64 *input = ctx->input;
+#define BLAKE2_G(a, b, c, d, x, y) \
+ a += b + x; d = rotr64(d ^ a, 32); \
+ c += d; b = rotr64(b ^ c, 24); \
+ a += b + y; d = rotr64(d ^ a, 16); \
+ c += d; b = rotr64(b ^ c, 63)
+#define BLAKE2_ROUND(i) \
+ BLAKE2_G(v0, v4, v8 , v12, input[sigma[i][ 0]], input[sigma[i][ 1]]); \
+ BLAKE2_G(v1, v5, v9 , v13, input[sigma[i][ 2]], input[sigma[i][ 3]]); \
+ BLAKE2_G(v2, v6, v10, v14, input[sigma[i][ 4]], input[sigma[i][ 5]]); \
+ BLAKE2_G(v3, v7, v11, v15, input[sigma[i][ 6]], input[sigma[i][ 7]]); \
+ BLAKE2_G(v0, v5, v10, v15, input[sigma[i][ 8]], input[sigma[i][ 9]]); \
+ BLAKE2_G(v1, v6, v11, v12, input[sigma[i][10]], input[sigma[i][11]]); \
+ BLAKE2_G(v2, v7, v8 , v13, input[sigma[i][12]], input[sigma[i][13]]); \
+ BLAKE2_G(v3, v4, v9 , v14, input[sigma[i][14]], input[sigma[i][15]])
+
+#ifdef BLAKE2_NO_UNROLLING
+ FOR (i, 0, 12) {
+ BLAKE2_ROUND(i);
+ }
+#else
+ BLAKE2_ROUND(0); BLAKE2_ROUND(1); BLAKE2_ROUND(2); BLAKE2_ROUND(3);
+ BLAKE2_ROUND(4); BLAKE2_ROUND(5); BLAKE2_ROUND(6); BLAKE2_ROUND(7);
+ BLAKE2_ROUND(8); BLAKE2_ROUND(9); BLAKE2_ROUND(10); BLAKE2_ROUND(11);
+#endif
+
+ // update hash
+ ctx->hash[0] ^= v0 ^ v8; ctx->hash[1] ^= v1 ^ v9;
+ ctx->hash[2] ^= v2 ^ v10; ctx->hash[3] ^= v3 ^ v11;
+ ctx->hash[4] ^= v4 ^ v12; ctx->hash[5] ^= v5 ^ v13;
+ ctx->hash[6] ^= v6 ^ v14; ctx->hash[7] ^= v7 ^ v15;
+}
+
+void crypto_blake2b_keyed_init(crypto_blake2b_ctx *ctx, size_t hash_size,
+ const u8 *key, size_t key_size)
+{
+ // initial hash
+ COPY(ctx->hash, iv, 8);
+ ctx->hash[0] ^= 0x01010000 ^ (key_size << 8) ^ hash_size;
+
+ ctx->input_offset[0] = 0; // beginning of the input, no offset
+ ctx->input_offset[1] = 0; // beginning of the input, no offset
+ ctx->hash_size = hash_size;
+ ctx->input_idx = 0;
+ ZERO(ctx->input, 16);
+
+ // if there is a key, the first block is that key (padded with zeroes)
+ if (key_size > 0) {
+ u8 key_block[128] = {0};
+ COPY(key_block, key, key_size);
+ // same as calling crypto_blake2b_update(ctx, key_block , 128)
+ load64_le_buf(ctx->input, key_block, 16);
+ ctx->input_idx = 128;
+ }
+}
+
+void crypto_blake2b_init(crypto_blake2b_ctx *ctx, size_t hash_size)
+{
+ crypto_blake2b_keyed_init(ctx, hash_size, 0, 0);
+}
+
+void crypto_blake2b_update(crypto_blake2b_ctx *ctx,
+ const u8 *message, size_t message_size)
+{
+ // Avoid undefined NULL pointer increments with empty messages
+ if (message_size == 0) {
+ return;
+ }
+
+ // Align with word boundaries
+ if ((ctx->input_idx & 7) != 0) {
+ size_t nb_bytes = MIN(gap(ctx->input_idx, 8), message_size);
+ size_t word = ctx->input_idx >> 3;
+ size_t byte = ctx->input_idx & 7;
+ FOR (i, 0, nb_bytes) {
+ ctx->input[word] |= (u64)message[i] << ((byte + i) << 3);
+ }
+ ctx->input_idx += nb_bytes;
+ message += nb_bytes;
+ message_size -= nb_bytes;
+ }
+
+ // Align with block boundaries (faster than byte by byte)
+ if ((ctx->input_idx & 127) != 0) {
+ size_t nb_words = MIN(gap(ctx->input_idx, 128), message_size) >> 3;
+ load64_le_buf(ctx->input + (ctx->input_idx >> 3), message, nb_words);
+ ctx->input_idx += nb_words << 3;
+ message += nb_words << 3;
+ message_size -= nb_words << 3;
+ }
+
+ // Process block by block
+ size_t nb_blocks = message_size >> 7;
+ FOR (i, 0, nb_blocks) {
+ if (ctx->input_idx == 128) {
+ blake2b_compress(ctx, 0);
+ }
+ load64_le_buf(ctx->input, message, 16);
+ message += 128;
+ ctx->input_idx = 128;
+ }
+ message_size &= 127;
+
+ if (message_size != 0) {
+ // Compress block & flush input buffer as needed
+ if (ctx->input_idx == 128) {
+ blake2b_compress(ctx, 0);
+ ctx->input_idx = 0;
+ }
+ if (ctx->input_idx == 0) {
+ ZERO(ctx->input, 16);
+ }
+ // Fill remaining words (faster than byte by byte)
+ size_t nb_words = message_size >> 3;
+ load64_le_buf(ctx->input, message, nb_words);
+ ctx->input_idx += nb_words << 3;
+ message += nb_words << 3;
+ message_size -= nb_words << 3;
+
+ // Fill remaining bytes
+ FOR (i, 0, message_size) {
+ size_t word = ctx->input_idx >> 3;
+ size_t byte = ctx->input_idx & 7;
+ ctx->input[word] |= (u64)message[i] << (byte << 3);
+ ctx->input_idx++;
+ }
+ }
+}
+
+void crypto_blake2b_final(crypto_blake2b_ctx *ctx, u8 *hash)
+{
+ blake2b_compress(ctx, 1); // compress the last block
+ size_t hash_size = MIN(ctx->hash_size, 64);
+ size_t nb_words = hash_size >> 3;
+ store64_le_buf(hash, ctx->hash, nb_words);
+ FOR (i, nb_words << 3, hash_size) {
+ hash[i] = (ctx->hash[i >> 3] >> (8 * (i & 7))) & 0xff;
+ }
+ WIPE_CTX(ctx);
+}
+
+void crypto_blake2b_keyed(u8 *hash, size_t hash_size,
+ const u8 *key, size_t key_size,
+ const u8 *message, size_t message_size)
+{
+ crypto_blake2b_ctx ctx;
+ crypto_blake2b_keyed_init(&ctx, hash_size, key, key_size);
+ crypto_blake2b_update (&ctx, message, message_size);
+ crypto_blake2b_final (&ctx, hash);
+}
+
+void crypto_blake2b(u8 *hash, size_t hash_size, const u8 *msg, size_t msg_size)
+{
+ crypto_blake2b_keyed(hash, hash_size, 0, 0, msg, msg_size);
+}
+
+//////////////
+/// Argon2 ///
+//////////////
+// references to R, Z, Q etc. come from the spec
+
+// Argon2 operates on 1024 byte blocks.
+typedef struct { u64 a[128]; } blk;
+
+// updates a BLAKE2 hash with a 32 bit word, little endian.
+static void blake_update_32(crypto_blake2b_ctx *ctx, u32 input)
+{
+ u8 buf[4];
+ store32_le(buf, input);
+ crypto_blake2b_update(ctx, buf, 4);
+ WIPE_BUFFER(buf);
+}
+
+static void blake_update_32_buf(crypto_blake2b_ctx *ctx,
+ const u8 *buf, u32 size)
+{
+ blake_update_32(ctx, size);
+ crypto_blake2b_update(ctx, buf, size);
+}
+
+
+static void copy_block(blk *o,const blk*in){FOR(i, 0, 128) o->a[i] = in->a[i];}
+static void xor_block(blk *o,const blk*in){FOR(i, 0, 128) o->a[i] ^= in->a[i];}
+
+// Hash with a virtually unlimited digest size.
+// Doesn't extract more entropy than the base hash function.
+// Mainly used for filling a whole kilobyte block with pseudo-random bytes.
+// (One could use a stream cipher with a seed hash as the key, but
+// this would introduce another dependency —and point of failure.)
+static void extended_hash(u8 *digest, u32 digest_size,
+ const u8 *input , u32 input_size)
+{
+ crypto_blake2b_ctx ctx;
+ crypto_blake2b_init (&ctx, MIN(digest_size, 64));
+ blake_update_32 (&ctx, digest_size);
+ crypto_blake2b_update(&ctx, input, input_size);
+ crypto_blake2b_final (&ctx, digest);
+
+ if (digest_size > 64) {
+ // the conversion to u64 avoids integer overflow on
+ // ludicrously big hash sizes.
+ u32 r = (u32)(((u64)digest_size + 31) >> 5) - 2;
+ u32 i = 1;
+ u32 in = 0;
+ u32 out = 32;
+ while (i < r) {
+ // Input and output overlap. This is intentional
+ crypto_blake2b(digest + out, 64, digest + in, 64);
+ i += 1;
+ in += 32;
+ out += 32;
+ }
+ crypto_blake2b(digest + out, digest_size - (32 * r), digest + in , 64);
+ }
+}
+
+#define LSB(x) ((u64)(u32)x)
+#define G(a, b, c, d) \
+ a += b + ((LSB(a) * LSB(b)) << 1); d ^= a; d = rotr64(d, 32); \
+ c += d + ((LSB(c) * LSB(d)) << 1); b ^= c; b = rotr64(b, 24); \
+ a += b + ((LSB(a) * LSB(b)) << 1); d ^= a; d = rotr64(d, 16); \
+ c += d + ((LSB(c) * LSB(d)) << 1); b ^= c; b = rotr64(b, 63)
+#define ROUND(v0, v1, v2, v3, v4, v5, v6, v7, \
+ v8, v9, v10, v11, v12, v13, v14, v15) \
+ 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)
+
+// Core of the compression function G. Computes Z from R in place.
+static void g_rounds(blk *b)
+{
+ // column rounds (work_block = Q)
+ for (int i = 0; i < 128; i += 16) {
+ ROUND(b->a[i ], b->a[i+ 1], b->a[i+ 2], b->a[i+ 3],
+ b->a[i+ 4], b->a[i+ 5], b->a[i+ 6], b->a[i+ 7],
+ b->a[i+ 8], b->a[i+ 9], b->a[i+10], b->a[i+11],
+ b->a[i+12], b->a[i+13], b->a[i+14], b->a[i+15]);
+ }
+ // row rounds (b = Z)
+ for (int i = 0; i < 16; i += 2) {
+ ROUND(b->a[i ], b->a[i+ 1], b->a[i+ 16], b->a[i+ 17],
+ b->a[i+32], b->a[i+33], b->a[i+ 48], b->a[i+ 49],
+ b->a[i+64], b->a[i+65], b->a[i+ 80], b->a[i+ 81],
+ b->a[i+96], b->a[i+97], b->a[i+112], b->a[i+113]);
+ }
+}
+
+const crypto_argon2_extras crypto_argon2_no_extras = { 0, 0, 0, 0 };
+
+void crypto_argon2(u8 *hash, u32 hash_size, void *work_area,
+ crypto_argon2_config config,
+ crypto_argon2_inputs inputs,
+ crypto_argon2_extras extras)
+{
+ const u32 segment_size = config.nb_blocks / config.nb_lanes / 4;
+ const u32 lane_size = segment_size * 4;
+ const u32 nb_blocks = lane_size * config.nb_lanes; // rounding down
+
+ // work area seen as blocks (must be suitably aligned)
+ blk *blocks = (blk*)work_area;
+ {
+ u8 initial_hash[72]; // 64 bytes plus 2 words for future hashes
+ crypto_blake2b_ctx ctx;
+ crypto_blake2b_init (&ctx, 64);
+ blake_update_32 (&ctx, config.nb_lanes ); // p: number of "threads"
+ blake_update_32 (&ctx, hash_size);
+ blake_update_32 (&ctx, config.nb_blocks);
+ blake_update_32 (&ctx, config.nb_passes);
+ blake_update_32 (&ctx, 0x13); // v: version number
+ blake_update_32 (&ctx, config.algorithm); // y: Argon2i, Argon2d...
+ blake_update_32_buf (&ctx, inputs.pass, inputs.pass_size);
+ blake_update_32_buf (&ctx, inputs.salt, inputs.salt_size);
+ blake_update_32_buf (&ctx, extras.key, extras.key_size);
+ blake_update_32_buf (&ctx, extras.ad, extras.ad_size);
+ crypto_blake2b_final(&ctx, initial_hash); // fill 64 first bytes only
+
+ // fill first 2 blocks of each lane
+ u8 hash_area[1024];
+ FOR_T(u32, l, 0, config.nb_lanes) {
+ FOR_T(u32, i, 0, 2) {
+ store32_le(initial_hash + 64, i); // first additional word
+ store32_le(initial_hash + 68, l); // second additional word
+ extended_hash(hash_area, 1024, initial_hash, 72);
+ load64_le_buf(blocks[l * lane_size + i].a, hash_area, 128);
+ }
+ }
+
+ WIPE_BUFFER(initial_hash);
+ WIPE_BUFFER(hash_area);
+ }
+
+ // Argon2i and Argon2id start with constant time indexing
+ int constant_time = config.algorithm != CRYPTO_ARGON2_D;
+
+ // Fill (and re-fill) the rest of the blocks
+ //
+ // Note: even though each segment within the same slice can be
+ // computed in parallel, (one thread per lane), we are computing
+ // them sequentially, because Monocypher doesn't support threads.
+ //
+ // Yet optimal performance (and therefore security) requires one
+ // thread per lane. The only reason Monocypher supports multiple
+ // lanes is compatibility.
+ blk tmp;
+ FOR_T(u32, pass, 0, config.nb_passes) {
+ FOR_T(u32, slice, 0, 4) {
+ // On the first slice of the first pass,
+ // blocks 0 and 1 are already filled, hence pass_offset.
+ u32 pass_offset = pass == 0 && slice == 0 ? 2 : 0;
+ u32 slice_offset = slice * segment_size;
+
+ // Argon2id switches back to non-constant time indexing
+ // after the first two slices of the first pass
+ if (slice == 2 && config.algorithm == CRYPTO_ARGON2_ID) {
+ constant_time = 0;
+ }
+
+ // Each iteration of the following loop may be performed in
+ // a separate thread. All segments must be fully completed
+ // before we start filling the next slice.
+ FOR_T(u32, segment, 0, config.nb_lanes) {
+ blk index_block;
+ u32 index_ctr = 1;
+ FOR_T (u32, block, pass_offset, segment_size) {
+ // Current and previous blocks
+ u32 lane_offset = segment * lane_size;
+ blk *segment_start = blocks + lane_offset + slice_offset;
+ blk *current = segment_start + block;
+ blk *previous =
+ block == 0 && slice_offset == 0
+ ? segment_start + lane_size - 1
+ : segment_start + block - 1;
+
+ u64 index_seed;
+ if (constant_time) {
+ if (block == pass_offset || (block % 128) == 0) {
+ // Fill or refresh deterministic indices block
+
+ // seed the beginning of the block...
+ ZERO(index_block.a, 128);
+ index_block.a[0] = pass;
+ index_block.a[1] = segment;
+ index_block.a[2] = slice;
+ index_block.a[3] = nb_blocks;
+ index_block.a[4] = config.nb_passes;
+ index_block.a[5] = config.algorithm;
+ index_block.a[6] = index_ctr;
+ index_ctr++;
+
+ // ... then shuffle it
+ copy_block(&tmp, &index_block);
+ g_rounds (&index_block);
+ xor_block (&index_block, &tmp);
+ copy_block(&tmp, &index_block);
+ g_rounds (&index_block);
+ xor_block (&index_block, &tmp);
+ }
+ index_seed = index_block.a[block % 128];
+ } else {
+ index_seed = previous->a[0];
+ }
+
+ // Establish the reference set. *Approximately* comprises:
+ // - The last 3 slices (if they exist yet)
+ // - The already constructed blocks in the current segment
+ u32 next_slice = ((slice + 1) % 4) * segment_size;
+ u32 window_start = pass == 0 ? 0 : next_slice;
+ u32 nb_segments = pass == 0 ? slice : 3;
+ u32 lane =
+ pass == 0 && slice == 0
+ ? segment
+ : (index_seed >> 32) % config.nb_lanes;
+ u32 window_size =
+ nb_segments * segment_size +
+ (lane == segment ? block-1 :
+ block == 0 ? (u32)-1 : 0);
+
+ // Find reference block
+ u64 j1 = index_seed & 0xffffffff; // block selector
+ u64 x = (j1 * j1) >> 32;
+ u64 y = (window_size * x) >> 32;
+ u64 z = (window_size - 1) - y;
+ u32 ref = (window_start + z) % lane_size;
+ u32 index = lane * lane_size + ref;
+ blk *reference = blocks + index;
+
+ // Shuffle the previous & reference block
+ // into the current block
+ copy_block(&tmp, previous);
+ xor_block (&tmp, reference);
+ if (pass == 0) { copy_block(current, &tmp); }
+ else { xor_block (current, &tmp); }
+ g_rounds (&tmp);
+ xor_block (current, &tmp);
+ }
+ }
+ }
+ }
+
+ // Wipe temporary block
+ volatile u64* p = tmp.a;
+ ZERO(p, 128);
+
+ // XOR last blocks of each lane
+ blk *last_block = blocks + lane_size - 1;
+ FOR_T (u32, lane, 1, config.nb_lanes) {
+ blk *next_block = last_block + lane_size;
+ xor_block(next_block, last_block);
+ last_block = next_block;
+ }
+
+ // Serialize last block
+ u8 final_block[1024];
+ store64_le_buf(final_block, last_block->a, 128);
+
+ // Wipe work area
+ p = (u64*)work_area;
+ ZERO(p, 128 * nb_blocks);
+
+ // Hash the very last block with H' into the output hash
+ extended_hash(hash, hash_size, final_block, 1024);
+ WIPE_BUFFER(final_block);
+}
+
+////////////////////////////////////
+/// Arithmetic modulo 2^255 - 19 ///
+////////////////////////////////////
+// Originally taken from SUPERCOP's ref10 implementation.
+// A bit bigger than TweetNaCl, over 4 times faster.
+
+// field element
+typedef i32 fe[10];
+
+// field constants
+//
+// fe_one : 1
+// sqrtm1 : sqrt(-1)
+// d : -121665 / 121666
+// D2 : 2 * -121665 / 121666
+// lop_x, lop_y: low order point in Edwards coordinates
+// ufactor : -sqrt(-1) * 2
+// A2 : 486662^2 (A squared)
+static const fe fe_one = {1};
+static const fe sqrtm1 = {
+ -32595792, -7943725, 9377950, 3500415, 12389472,
+ -272473, -25146209, -2005654, 326686, 11406482,
+};
+static const fe d = {
+ -10913610, 13857413, -15372611, 6949391, 114729,
+ -8787816, -6275908, -3247719, -18696448, -12055116,
+};
+static const fe D2 = {
+ -21827239, -5839606, -30745221, 13898782, 229458,
+ 15978800, -12551817, -6495438, 29715968, 9444199,
+};
+static const fe lop_x = {
+ 21352778, 5345713, 4660180, -8347857, 24143090,
+ 14568123, 30185756, -12247770, -33528939, 8345319,
+};
+static const fe lop_y = {
+ -6952922, -1265500, 6862341, -7057498, -4037696,
+ -5447722, 31680899, -15325402, -19365852, 1569102,
+};
+static const fe ufactor = {
+ -1917299, 15887451, -18755900, -7000830, -24778944,
+ 544946, -16816446, 4011309, -653372, 10741468,
+};
+static const fe A2 = {
+ 12721188, 3529, 0, 0, 0, 0, 0, 0, 0, 0,
+};
+
+static void fe_0(fe h) { ZERO(h , 10); }
+static void fe_1(fe h) { h[0] = 1; ZERO(h+1, 9); }
+
+static void fe_copy(fe h,const fe f ){FOR(i,0,10) h[i] = f[i]; }
+static void fe_neg (fe h,const fe f ){FOR(i,0,10) h[i] = -f[i]; }
+static void fe_add (fe h,const fe f,const fe g){FOR(i,0,10) h[i] = f[i] + g[i];}
+static void fe_sub (fe h,const fe f,const fe g){FOR(i,0,10) h[i] = f[i] - g[i];}
+
+static void fe_cswap(fe f, fe g, int b)
+{
+ i32 mask = -b; // -1 = 0xffffffff
+ FOR (i, 0, 10) {
+ i32 x = (f[i] ^ g[i]) & mask;
+ f[i] = f[i] ^ x;
+ g[i] = g[i] ^ x;
+ }
+}
+
+static void fe_ccopy(fe f, const fe g, int b)
+{
+ i32 mask = -b; // -1 = 0xffffffff
+ FOR (i, 0, 10) {
+ i32 x = (f[i] ^ g[i]) & mask;
+ f[i] = f[i] ^ x;
+ }
+}
+
+
+// Signed carry propagation
+// ------------------------
+//
+// Let t be a number. It can be uniquely decomposed thus:
+//
+// t = h*2^26 + l
+// such that -2^25 <= l < 2^25
+//
+// Let c = (t + 2^25) / 2^26 (rounded down)
+// c = (h*2^26 + l + 2^25) / 2^26 (rounded down)
+// c = h + (l + 2^25) / 2^26 (rounded down)
+// c = h (exactly)
+// Because 0 <= l + 2^25 < 2^26
+//
+// Let u = t - c*2^26
+// u = h*2^26 + l - h*2^26
+// u = l
+// Therefore, -2^25 <= u < 2^25
+//
+// Additionally, if |t| < x, then |h| < x/2^26 (rounded down)
+//
+// Notations:
+// - In C, 1<<25 means 2^25.
+// - In C, x>>25 means floor(x / (2^25)).
+// - All of the above applies with 25 & 24 as well as 26 & 25.
+//
+//
+// Note on negative right shifts
+// -----------------------------
+//
+// In C, x >> n, where x is a negative integer, is implementation
+// defined. In practice, all platforms do arithmetic shift, which is
+// equivalent to division by 2^26, rounded down. Some compilers, like
+// GCC, even guarantee it.
+//
+// If we ever stumble upon a platform that does not propagate the sign
+// bit (we won't), visible failures will show at the slightest test, and
+// the signed shifts can be replaced by the following:
+//
+// typedef struct { i64 x:39; } s25;
+// typedef struct { i64 x:38; } s26;
+// i64 shift25(i64 x) { s25 s; s.x = ((u64)x)>>25; return s.x; }
+// i64 shift26(i64 x) { s26 s; s.x = ((u64)x)>>26; return s.x; }
+//
+// Current compilers cannot optimise this, causing a 30% drop in
+// performance. Fairly expensive for something that never happens.
+//
+//
+// Precondition
+// ------------
+//
+// |t0| < 2^63
+// |t1|..|t9| < 2^62
+//
+// Algorithm
+// ---------
+// c = t0 + 2^25 / 2^26 -- |c| <= 2^36
+// t0 -= c * 2^26 -- |t0| <= 2^25
+// t1 += c -- |t1| <= 2^63
+//
+// c = t4 + 2^25 / 2^26 -- |c| <= 2^36
+// t4 -= c * 2^26 -- |t4| <= 2^25
+// t5 += c -- |t5| <= 2^63
+//
+// c = t1 + 2^24 / 2^25 -- |c| <= 2^38
+// t1 -= c * 2^25 -- |t1| <= 2^24
+// t2 += c -- |t2| <= 2^63
+//
+// c = t5 + 2^24 / 2^25 -- |c| <= 2^38
+// t5 -= c * 2^25 -- |t5| <= 2^24
+// t6 += c -- |t6| <= 2^63
+//
+// c = t2 + 2^25 / 2^26 -- |c| <= 2^37
+// t2 -= c * 2^26 -- |t2| <= 2^25 < 1.1 * 2^25 (final t2)
+// t3 += c -- |t3| <= 2^63
+//
+// c = t6 + 2^25 / 2^26 -- |c| <= 2^37
+// t6 -= c * 2^26 -- |t6| <= 2^25 < 1.1 * 2^25 (final t6)
+// t7 += c -- |t7| <= 2^63
+//
+// c = t3 + 2^24 / 2^25 -- |c| <= 2^38
+// t3 -= c * 2^25 -- |t3| <= 2^24 < 1.1 * 2^24 (final t3)
+// t4 += c -- |t4| <= 2^25 + 2^38 < 2^39
+//
+// c = t7 + 2^24 / 2^25 -- |c| <= 2^38
+// t7 -= c * 2^25 -- |t7| <= 2^24 < 1.1 * 2^24 (final t7)
+// t8 += c -- |t8| <= 2^63
+//
+// c = t4 + 2^25 / 2^26 -- |c| <= 2^13
+// t4 -= c * 2^26 -- |t4| <= 2^25 < 1.1 * 2^25 (final t4)
+// t5 += c -- |t5| <= 2^24 + 2^13 < 1.1 * 2^24 (final t5)
+//
+// c = t8 + 2^25 / 2^26 -- |c| <= 2^37
+// t8 -= c * 2^26 -- |t8| <= 2^25 < 1.1 * 2^25 (final t8)
+// t9 += c -- |t9| <= 2^63
+//
+// c = t9 + 2^24 / 2^25 -- |c| <= 2^38
+// t9 -= c * 2^25 -- |t9| <= 2^24 < 1.1 * 2^24 (final t9)
+// t0 += c * 19 -- |t0| <= 2^25 + 2^38*19 < 2^44
+//
+// c = t0 + 2^25 / 2^26 -- |c| <= 2^18
+// t0 -= c * 2^26 -- |t0| <= 2^25 < 1.1 * 2^25 (final t0)
+// t1 += c -- |t1| <= 2^24 + 2^18 < 1.1 * 2^24 (final t1)
+//
+// Postcondition
+// -------------
+// |t0|, |t2|, |t4|, |t6|, |t8| < 1.1 * 2^25
+// |t1|, |t3|, |t5|, |t7|, |t9| < 1.1 * 2^24
+#define FE_CARRY \
+ i64 c; \
+ c = (t0 + ((i64)1<<25)) >> 26; t0 -= c * ((i64)1 << 26); t1 += c; \
+ c = (t4 + ((i64)1<<25)) >> 26; t4 -= c * ((i64)1 << 26); t5 += c; \
+ c = (t1 + ((i64)1<<24)) >> 25; t1 -= c * ((i64)1 << 25); t2 += c; \
+ c = (t5 + ((i64)1<<24)) >> 25; t5 -= c * ((i64)1 << 25); t6 += c; \
+ c = (t2 + ((i64)1<<25)) >> 26; t2 -= c * ((i64)1 << 26); t3 += c; \
+ c = (t6 + ((i64)1<<25)) >> 26; t6 -= c * ((i64)1 << 26); t7 += c; \
+ c = (t3 + ((i64)1<<24)) >> 25; t3 -= c * ((i64)1 << 25); t4 += c; \
+ c = (t7 + ((i64)1<<24)) >> 25; t7 -= c * ((i64)1 << 25); t8 += c; \
+ c = (t4 + ((i64)1<<25)) >> 26; t4 -= c * ((i64)1 << 26); t5 += c; \
+ c = (t8 + ((i64)1<<25)) >> 26; t8 -= c * ((i64)1 << 26); t9 += c; \
+ c = (t9 + ((i64)1<<24)) >> 25; t9 -= c * ((i64)1 << 25); t0 += c * 19; \
+ c = (t0 + ((i64)1<<25)) >> 26; t0 -= c * ((i64)1 << 26); t1 += c; \
+ h[0]=(i32)t0; h[1]=(i32)t1; h[2]=(i32)t2; h[3]=(i32)t3; h[4]=(i32)t4; \
+ h[5]=(i32)t5; h[6]=(i32)t6; h[7]=(i32)t7; h[8]=(i32)t8; h[9]=(i32)t9
+
+// Decodes a field element from a byte buffer.
+// mask specifies how many bits we ignore.
+// Traditionally we ignore 1. It's useful for EdDSA,
+// which uses that bit to denote the sign of x.
+// Elligator however uses positive representatives,
+// which means ignoring 2 bits instead.
+static void fe_frombytes_mask(fe h, const u8 s[32], unsigned nb_mask)
+{
+ u32 mask = 0xffffff >> nb_mask;
+ i64 t0 = load32_le(s); // t0 < 2^32
+ i64 t1 = load24_le(s + 4) << 6; // t1 < 2^30
+ i64 t2 = load24_le(s + 7) << 5; // t2 < 2^29
+ i64 t3 = load24_le(s + 10) << 3; // t3 < 2^27
+ i64 t4 = load24_le(s + 13) << 2; // t4 < 2^26
+ i64 t5 = load32_le(s + 16); // t5 < 2^32
+ i64 t6 = load24_le(s + 20) << 7; // t6 < 2^31
+ i64 t7 = load24_le(s + 23) << 5; // t7 < 2^29
+ i64 t8 = load24_le(s + 26) << 4; // t8 < 2^28
+ i64 t9 = (load24_le(s + 29) & mask) << 2; // t9 < 2^25
+ FE_CARRY; // Carry precondition OK
+}
+
+static void fe_frombytes(fe h, const u8 s[32])
+{
+ fe_frombytes_mask(h, s, 1);
+}
+
+
+// Precondition
+// |h[0]|, |h[2]|, |h[4]|, |h[6]|, |h[8]| < 1.1 * 2^25
+// |h[1]|, |h[3]|, |h[5]|, |h[7]|, |h[9]| < 1.1 * 2^24
+//
+// Therefore, |h| < 2^255-19
+// There are two possibilities:
+//
+// - If h is positive, all we need to do is reduce its individual
+// limbs down to their tight positive range.
+// - If h is negative, we also need to add 2^255-19 to it.
+// Or just remove 19 and chop off any excess bit.
+static void fe_tobytes(u8 s[32], const fe h)
+{
+ i32 t[10];
+ COPY(t, h, 10);
+ i32 q = (19 * t[9] + (((i32) 1) << 24)) >> 25;
+ // |t9| < 1.1 * 2^24
+ // -1.1 * 2^24 < t9 < 1.1 * 2^24
+ // -21 * 2^24 < 19 * t9 < 21 * 2^24
+ // -2^29 < 19 * t9 + 2^24 < 2^29
+ // -2^29 / 2^25 < (19 * t9 + 2^24) / 2^25 < 2^29 / 2^25
+ // -16 < (19 * t9 + 2^24) / 2^25 < 16
+ FOR (i, 0, 5) {
+ q += t[2*i ]; q >>= 26; // q = 0 or -1
+ q += t[2*i+1]; q >>= 25; // q = 0 or -1
+ }
+ // q = 0 iff h >= 0
+ // q = -1 iff h < 0
+ // Adding q * 19 to h reduces h to its proper range.
+ q *= 19; // Shift carry back to the beginning
+ FOR (i, 0, 5) {
+ t[i*2 ] += q; q = t[i*2 ] >> 26; t[i*2 ] -= q * ((i32)1 << 26);
+ t[i*2+1] += q; q = t[i*2+1] >> 25; t[i*2+1] -= q * ((i32)1 << 25);
+ }
+ // h is now fully reduced, and q represents the excess bit.
+
+ store32_le(s + 0, ((u32)t[0] >> 0) | ((u32)t[1] << 26));
+ store32_le(s + 4, ((u32)t[1] >> 6) | ((u32)t[2] << 19));
+ store32_le(s + 8, ((u32)t[2] >> 13) | ((u32)t[3] << 13));
+ store32_le(s + 12, ((u32)t[3] >> 19) | ((u32)t[4] << 6));
+ store32_le(s + 16, ((u32)t[5] >> 0) | ((u32)t[6] << 25));
+ store32_le(s + 20, ((u32)t[6] >> 7) | ((u32)t[7] << 19));
+ store32_le(s + 24, ((u32)t[7] >> 13) | ((u32)t[8] << 12));
+ store32_le(s + 28, ((u32)t[8] >> 20) | ((u32)t[9] << 6));
+
+ WIPE_BUFFER(t);
+}
+
+// Precondition
+// -------------
+// |f0|, |f2|, |f4|, |f6|, |f8| < 1.65 * 2^26
+// |f1|, |f3|, |f5|, |f7|, |f9| < 1.65 * 2^25
+//
+// |g0|, |g2|, |g4|, |g6|, |g8| < 1.65 * 2^26
+// |g1|, |g3|, |g5|, |g7|, |g9| < 1.65 * 2^25
+static void fe_mul_small(fe h, const fe f, i32 g)
+{
+ i64 t0 = f[0] * (i64) g; i64 t1 = f[1] * (i64) g;
+ i64 t2 = f[2] * (i64) g; i64 t3 = f[3] * (i64) g;
+ i64 t4 = f[4] * (i64) g; i64 t5 = f[5] * (i64) g;
+ i64 t6 = f[6] * (i64) g; i64 t7 = f[7] * (i64) g;
+ i64 t8 = f[8] * (i64) g; i64 t9 = f[9] * (i64) g;
+ // |t0|, |t2|, |t4|, |t6|, |t8| < 1.65 * 2^26 * 2^31 < 2^58
+ // |t1|, |t3|, |t5|, |t7|, |t9| < 1.65 * 2^25 * 2^31 < 2^57
+
+ FE_CARRY; // Carry precondition OK
+}
+
+// Precondition
+// -------------
+// |f0|, |f2|, |f4|, |f6|, |f8| < 1.65 * 2^26
+// |f1|, |f3|, |f5|, |f7|, |f9| < 1.65 * 2^25
+//
+// |g0|, |g2|, |g4|, |g6|, |g8| < 1.65 * 2^26
+// |g1|, |g3|, |g5|, |g7|, |g9| < 1.65 * 2^25
+static void fe_mul(fe h, const fe f, const fe g)
+{
+ // Everything is unrolled and put in temporary variables.
+ // We could roll the loop, but that would make curve25519 twice as slow.
+ i32 f0 = f[0]; i32 f1 = f[1]; i32 f2 = f[2]; i32 f3 = f[3]; i32 f4 = f[4];
+ i32 f5 = f[5]; i32 f6 = f[6]; i32 f7 = f[7]; i32 f8 = f[8]; i32 f9 = f[9];
+ i32 g0 = g[0]; i32 g1 = g[1]; i32 g2 = g[2]; i32 g3 = g[3]; i32 g4 = g[4];
+ i32 g5 = g[5]; i32 g6 = g[6]; i32 g7 = g[7]; i32 g8 = g[8]; i32 g9 = g[9];
+ i32 F1 = f1*2; i32 F3 = f3*2; i32 F5 = f5*2; i32 F7 = f7*2; i32 F9 = f9*2;
+ i32 G1 = g1*19; i32 G2 = g2*19; i32 G3 = g3*19;
+ i32 G4 = g4*19; i32 G5 = g5*19; i32 G6 = g6*19;
+ i32 G7 = g7*19; i32 G8 = g8*19; i32 G9 = g9*19;
+ // |F1|, |F3|, |F5|, |F7|, |F9| < 1.65 * 2^26
+ // |G0|, |G2|, |G4|, |G6|, |G8| < 2^31
+ // |G1|, |G3|, |G5|, |G7|, |G9| < 2^30
+
+ i64 t0 = f0*(i64)g0 + F1*(i64)G9 + f2*(i64)G8 + F3*(i64)G7 + f4*(i64)G6
+ + F5*(i64)G5 + f6*(i64)G4 + F7*(i64)G3 + f8*(i64)G2 + F9*(i64)G1;
+ i64 t1 = f0*(i64)g1 + f1*(i64)g0 + f2*(i64)G9 + f3*(i64)G8 + f4*(i64)G7
+ + f5*(i64)G6 + f6*(i64)G5 + f7*(i64)G4 + f8*(i64)G3 + f9*(i64)G2;
+ i64 t2 = f0*(i64)g2 + F1*(i64)g1 + f2*(i64)g0 + F3*(i64)G9 + f4*(i64)G8
+ + F5*(i64)G7 + f6*(i64)G6 + F7*(i64)G5 + f8*(i64)G4 + F9*(i64)G3;
+ i64 t3 = f0*(i64)g3 + f1*(i64)g2 + f2*(i64)g1 + f3*(i64)g0 + f4*(i64)G9
+ + f5*(i64)G8 + f6*(i64)G7 + f7*(i64)G6 + f8*(i64)G5 + f9*(i64)G4;
+ i64 t4 = f0*(i64)g4 + F1*(i64)g3 + f2*(i64)g2 + F3*(i64)g1 + f4*(i64)g0
+ + F5*(i64)G9 + f6*(i64)G8 + F7*(i64)G7 + f8*(i64)G6 + F9*(i64)G5;
+ i64 t5 = f0*(i64)g5 + f1*(i64)g4 + f2*(i64)g3 + f3*(i64)g2 + f4*(i64)g1
+ + f5*(i64)g0 + f6*(i64)G9 + f7*(i64)G8 + f8*(i64)G7 + f9*(i64)G6;
+ i64 t6 = f0*(i64)g6 + F1*(i64)g5 + f2*(i64)g4 + F3*(i64)g3 + f4*(i64)g2
+ + F5*(i64)g1 + f6*(i64)g0 + F7*(i64)G9 + f8*(i64)G8 + F9*(i64)G7;
+ i64 t7 = f0*(i64)g7 + f1*(i64)g6 + f2*(i64)g5 + f3*(i64)g4 + f4*(i64)g3
+ + f5*(i64)g2 + f6*(i64)g1 + f7*(i64)g0 + f8*(i64)G9 + f9*(i64)G8;
+ i64 t8 = f0*(i64)g8 + F1*(i64)g7 + f2*(i64)g6 + F3*(i64)g5 + f4*(i64)g4
+ + F5*(i64)g3 + f6*(i64)g2 + F7*(i64)g1 + f8*(i64)g0 + F9*(i64)G9;
+ i64 t9 = f0*(i64)g9 + f1*(i64)g8 + f2*(i64)g7 + f3*(i64)g6 + f4*(i64)g5
+ + f5*(i64)g4 + f6*(i64)g3 + f7*(i64)g2 + f8*(i64)g1 + f9*(i64)g0;
+ // t0 < 0.67 * 2^61
+ // t1 < 0.41 * 2^61
+ // t2 < 0.52 * 2^61
+ // t3 < 0.32 * 2^61
+ // t4 < 0.38 * 2^61
+ // t5 < 0.22 * 2^61
+ // t6 < 0.23 * 2^61
+ // t7 < 0.13 * 2^61
+ // t8 < 0.09 * 2^61
+ // t9 < 0.03 * 2^61
+
+ FE_CARRY; // Everything below 2^62, Carry precondition OK
+}
+
+// Precondition
+// -------------
+// |f0|, |f2|, |f4|, |f6|, |f8| < 1.65 * 2^26
+// |f1|, |f3|, |f5|, |f7|, |f9| < 1.65 * 2^25
+//
+// Note: we could use fe_mul() for this, but this is significantly faster
+static void fe_sq(fe h, const fe f)
+{
+ i32 f0 = f[0]; i32 f1 = f[1]; i32 f2 = f[2]; i32 f3 = f[3]; i32 f4 = f[4];
+ i32 f5 = f[5]; i32 f6 = f[6]; i32 f7 = f[7]; i32 f8 = f[8]; i32 f9 = f[9];
+ i32 f0_2 = f0*2; i32 f1_2 = f1*2; i32 f2_2 = f2*2; i32 f3_2 = f3*2;
+ i32 f4_2 = f4*2; i32 f5_2 = f5*2; i32 f6_2 = f6*2; i32 f7_2 = f7*2;
+ i32 f5_38 = f5*38; i32 f6_19 = f6*19; i32 f7_38 = f7*38;
+ i32 f8_19 = f8*19; i32 f9_38 = f9*38;
+ // |f0_2| , |f2_2| , |f4_2| , |f6_2| , |f8_2| < 1.65 * 2^27
+ // |f1_2| , |f3_2| , |f5_2| , |f7_2| , |f9_2| < 1.65 * 2^26
+ // |f5_38|, |f6_19|, |f7_38|, |f8_19|, |f9_38| < 2^31
+
+ i64 t0 = f0 *(i64)f0 + f1_2*(i64)f9_38 + f2_2*(i64)f8_19
+ + f3_2*(i64)f7_38 + f4_2*(i64)f6_19 + f5 *(i64)f5_38;
+ i64 t1 = f0_2*(i64)f1 + f2 *(i64)f9_38 + f3_2*(i64)f8_19
+ + f4 *(i64)f7_38 + f5_2*(i64)f6_19;
+ i64 t2 = f0_2*(i64)f2 + f1_2*(i64)f1 + f3_2*(i64)f9_38
+ + f4_2*(i64)f8_19 + f5_2*(i64)f7_38 + f6 *(i64)f6_19;
+ i64 t3 = f0_2*(i64)f3 + f1_2*(i64)f2 + f4 *(i64)f9_38
+ + f5_2*(i64)f8_19 + f6 *(i64)f7_38;
+ i64 t4 = f0_2*(i64)f4 + f1_2*(i64)f3_2 + f2 *(i64)f2
+ + f5_2*(i64)f9_38 + f6_2*(i64)f8_19 + f7 *(i64)f7_38;
+ i64 t5 = f0_2*(i64)f5 + f1_2*(i64)f4 + f2_2*(i64)f3
+ + f6 *(i64)f9_38 + f7_2*(i64)f8_19;
+ i64 t6 = f0_2*(i64)f6 + f1_2*(i64)f5_2 + f2_2*(i64)f4
+ + f3_2*(i64)f3 + f7_2*(i64)f9_38 + f8 *(i64)f8_19;
+ i64 t7 = f0_2*(i64)f7 + f1_2*(i64)f6 + f2_2*(i64)f5
+ + f3_2*(i64)f4 + f8 *(i64)f9_38;
+ i64 t8 = f0_2*(i64)f8 + f1_2*(i64)f7_2 + f2_2*(i64)f6
+ + f3_2*(i64)f5_2 + f4 *(i64)f4 + f9 *(i64)f9_38;
+ i64 t9 = f0_2*(i64)f9 + f1_2*(i64)f8 + f2_2*(i64)f7
+ + f3_2*(i64)f6 + f4 *(i64)f5_2;
+ // t0 < 0.67 * 2^61
+ // t1 < 0.41 * 2^61
+ // t2 < 0.52 * 2^61
+ // t3 < 0.32 * 2^61
+ // t4 < 0.38 * 2^61
+ // t5 < 0.22 * 2^61
+ // t6 < 0.23 * 2^61
+ // t7 < 0.13 * 2^61
+ // t8 < 0.09 * 2^61
+ // t9 < 0.03 * 2^61
+
+ FE_CARRY;
+}
+
+// Parity check. Returns 0 if even, 1 if odd
+static int fe_isodd(const fe f)
+{
+ u8 s[32];
+ fe_tobytes(s, f);
+ u8 isodd = s[0] & 1;
+ WIPE_BUFFER(s);
+ return isodd;
+}
+
+// Returns 1 if equal, 0 if not equal
+static int fe_isequal(const fe f, const fe g)
+{
+ u8 fs[32];
+ u8 gs[32];
+ fe_tobytes(fs, f);
+ fe_tobytes(gs, g);
+ int isdifferent = crypto_verify32(fs, gs);
+ WIPE_BUFFER(fs);
+ WIPE_BUFFER(gs);
+ return 1 + isdifferent;
+}
+
+// Inverse square root.
+// Returns true if x is a square, false otherwise.
+// After the call:
+// isr = sqrt(1/x) if x is a non-zero square.
+// isr = sqrt(sqrt(-1)/x) if x is not a square.
+// isr = 0 if x is zero.
+// We do not guarantee the sign of the square root.
+//
+// Notes:
+// Let quartic = x^((p-1)/4)
+//
+// x^((p-1)/2) = chi(x)
+// quartic^2 = chi(x)
+// quartic = sqrt(chi(x))
+// quartic = 1 or -1 or sqrt(-1) or -sqrt(-1)
+//
+// Note that x is a square if quartic is 1 or -1
+// There are 4 cases to consider:
+//
+// if quartic = 1 (x is a square)
+// then x^((p-1)/4) = 1
+// x^((p-5)/4) * x = 1
+// x^((p-5)/4) = 1/x
+// x^((p-5)/8) = sqrt(1/x) or -sqrt(1/x)
+//
+// if quartic = -1 (x is a square)
+// then x^((p-1)/4) = -1
+// x^((p-5)/4) * x = -1
+// x^((p-5)/4) = -1/x
+// x^((p-5)/8) = sqrt(-1) / sqrt(x)
+// x^((p-5)/8) * sqrt(-1) = sqrt(-1)^2 / sqrt(x)
+// x^((p-5)/8) * sqrt(-1) = -1/sqrt(x)
+// x^((p-5)/8) * sqrt(-1) = -sqrt(1/x) or sqrt(1/x)
+//
+// if quartic = sqrt(-1) (x is not a square)
+// then x^((p-1)/4) = sqrt(-1)
+// x^((p-5)/4) * x = sqrt(-1)
+// x^((p-5)/4) = sqrt(-1)/x
+// x^((p-5)/8) = sqrt(sqrt(-1)/x) or -sqrt(sqrt(-1)/x)
+//
+// Note that the product of two non-squares is always a square:
+// For any non-squares a and b, chi(a) = -1 and chi(b) = -1.
+// Since chi(x) = x^((p-1)/2), chi(a)*chi(b) = chi(a*b) = 1.
+// Therefore a*b is a square.
+//
+// Since sqrt(-1) and x are both non-squares, their product is a
+// square, and we can compute their square root.
+//
+// if quartic = -sqrt(-1) (x is not a square)
+// then x^((p-1)/4) = -sqrt(-1)
+// x^((p-5)/4) * x = -sqrt(-1)
+// x^((p-5)/4) = -sqrt(-1)/x
+// x^((p-5)/8) = sqrt(-sqrt(-1)/x)
+// x^((p-5)/8) = sqrt( sqrt(-1)/x) * sqrt(-1)
+// x^((p-5)/8) * sqrt(-1) = sqrt( sqrt(-1)/x) * sqrt(-1)^2
+// x^((p-5)/8) * sqrt(-1) = sqrt( sqrt(-1)/x) * -1
+// x^((p-5)/8) * sqrt(-1) = -sqrt(sqrt(-1)/x) or sqrt(sqrt(-1)/x)
+static int invsqrt(fe isr, const fe x)
+{
+ fe t0, t1, t2;
+
+ // t0 = x^((p-5)/8)
+ // Can be achieved with a simple double & add ladder,
+ // but it would be slower.
+ fe_sq(t0, x);
+ fe_sq(t1,t0); fe_sq(t1, t1); fe_mul(t1, x, t1);
+ fe_mul(t0, t0, t1);
+ fe_sq(t0, t0); fe_mul(t0, t1, t0);
+ fe_sq(t1, t0); FOR (i, 1, 5) { fe_sq(t1, t1); } fe_mul(t0, t1, t0);
+ fe_sq(t1, t0); FOR (i, 1, 10) { fe_sq(t1, t1); } fe_mul(t1, t1, t0);
+ fe_sq(t2, t1); FOR (i, 1, 20) { fe_sq(t2, t2); } fe_mul(t1, t2, t1);
+ fe_sq(t1, t1); FOR (i, 1, 10) { fe_sq(t1, t1); } fe_mul(t0, t1, t0);
+ fe_sq(t1, t0); FOR (i, 1, 50) { fe_sq(t1, t1); } fe_mul(t1, t1, t0);
+ fe_sq(t2, t1); FOR (i, 1, 100) { fe_sq(t2, t2); } fe_mul(t1, t2, t1);
+ fe_sq(t1, t1); FOR (i, 1, 50) { fe_sq(t1, t1); } fe_mul(t0, t1, t0);
+ fe_sq(t0, t0); FOR (i, 1, 2) { fe_sq(t0, t0); } fe_mul(t0, t0, x);
+
+ // quartic = x^((p-1)/4)
+ i32 *quartic = t1;
+ fe_sq (quartic, t0);
+ fe_mul(quartic, quartic, x);
+
+ i32 *check = t2;
+ fe_0 (check); int z0 = fe_isequal(x , check);
+ fe_1 (check); int p1 = fe_isequal(quartic, check);
+ fe_neg(check, check ); int m1 = fe_isequal(quartic, check);
+ fe_neg(check, sqrtm1); int ms = fe_isequal(quartic, check);
+
+ // if quartic == -1 or sqrt(-1)
+ // then isr = x^((p-1)/4) * sqrt(-1)
+ // else isr = x^((p-1)/4)
+ fe_mul(isr, t0, sqrtm1);
+ fe_ccopy(isr, t0, 1 - (m1 | ms));
+
+ WIPE_BUFFER(t0);
+ WIPE_BUFFER(t1);
+ WIPE_BUFFER(t2);
+ return p1 | m1 | z0;
+}
+
+// Inverse in terms of inverse square root.
+// Requires two additional squarings to get rid of the sign.
+//
+// 1/x = x * (+invsqrt(x^2))^2
+// = x * (-invsqrt(x^2))^2
+//
+// A fully optimised exponentiation by p-1 would save 6 field
+// multiplications, but it would require more code.
+static void fe_invert(fe out, const fe x)
+{
+ fe tmp;
+ fe_sq(tmp, x);
+ invsqrt(tmp, tmp);
+ fe_sq(tmp, tmp);
+ fe_mul(out, tmp, x);
+ WIPE_BUFFER(tmp);
+}
+
+// trim a scalar for scalar multiplication
+void crypto_eddsa_trim_scalar(u8 out[32], const u8 in[32])
+{
+ COPY(out, in, 32);
+ out[ 0] &= 248;
+ out[31] &= 127;
+ out[31] |= 64;
+}
+
+// get bit from scalar at position i
+static int scalar_bit(const u8 s[32], int i)
+{
+ if (i < 0) { return 0; } // handle -1 for sliding windows
+ return (s[i>>3] >> (i&7)) & 1;
+}
+
+///////////////
+/// X-25519 /// Taken from SUPERCOP's ref10 implementation.
+///////////////
+static void scalarmult(u8 q[32], const u8 scalar[32], const u8 p[32],
+ int nb_bits)
+{
+ // computes the scalar product
+ fe x1;
+ fe_frombytes(x1, p);
+
+ // computes the actual scalar product (the result is in x2 and z2)
+ fe x2, z2, x3, z3, t0, t1;
+ // Montgomery ladder
+ // In projective coordinates, to avoid divisions: x = X / Z
+ // We don't care about the y coordinate, it's only 1 bit of information
+ fe_1(x2); fe_0(z2); // "zero" point
+ fe_copy(x3, x1); fe_1(z3); // "one" point
+ int swap = 0;
+ for (int pos = nb_bits-1; pos >= 0; --pos) {
+ // constant time conditional swap before ladder step
+ int b = scalar_bit(scalar, pos);
+ swap ^= b; // xor trick avoids swapping at the end of the loop
+ fe_cswap(x2, x3, swap);
+ fe_cswap(z2, z3, swap);
+ swap = b; // anticipates one last swap after the loop
+
+ // Montgomery ladder step: replaces (P2, P3) by (P2*2, P2+P3)
+ // with differential addition
+ fe_sub(t0, x3, z3);
+ fe_sub(t1, x2, z2);
+ fe_add(x2, x2, z2);
+ fe_add(z2, x3, z3);
+ fe_mul(z3, t0, x2);
+ fe_mul(z2, z2, t1);
+ fe_sq (t0, t1 );
+ fe_sq (t1, x2 );
+ fe_add(x3, z3, z2);
+ fe_sub(z2, z3, z2);
+ fe_mul(x2, t1, t0);
+ fe_sub(t1, t1, t0);
+ fe_sq (z2, z2 );
+ fe_mul_small(z3, t1, 121666);
+ fe_sq (x3, x3 );
+ fe_add(t0, t0, z3);
+ fe_mul(z3, x1, z2);
+ fe_mul(z2, t1, t0);
+ }
+ // last swap is necessary to compensate for the xor trick
+ // Note: after this swap, P3 == P2 + P1.
+ fe_cswap(x2, x3, swap);
+ fe_cswap(z2, z3, swap);
+
+ // normalises the coordinates: x == X / Z
+ fe_invert(z2, z2);
+ fe_mul(x2, x2, z2);
+ fe_tobytes(q, x2);
+
+ WIPE_BUFFER(x1);
+ WIPE_BUFFER(x2); WIPE_BUFFER(z2); WIPE_BUFFER(t0);
+ WIPE_BUFFER(x3); WIPE_BUFFER(z3); WIPE_BUFFER(t1);
+}
+
+void crypto_x25519(u8 raw_shared_secret[32],
+ const u8 your_secret_key [32],
+ const u8 their_public_key [32])
+{
+ // restrict the possible scalar values
+ u8 e[32];
+ crypto_eddsa_trim_scalar(e, your_secret_key);
+ scalarmult(raw_shared_secret, e, their_public_key, 255);
+ WIPE_BUFFER(e);
+}
+
+void crypto_x25519_public_key(u8 public_key[32],
+ const u8 secret_key[32])
+{
+ static const u8 base_point[32] = {9};
+ crypto_x25519(public_key, secret_key, base_point);
+}
+
+///////////////////////////
+/// Arithmetic modulo L ///
+///////////////////////////
+static const u32 L[8] = {
+ 0x5cf5d3ed, 0x5812631a, 0xa2f79cd6, 0x14def9de,
+ 0x00000000, 0x00000000, 0x00000000, 0x10000000,
+};
+
+// p = a*b + p
+static void multiply(u32 p[16], const u32 a[8], const u32 b[8])
+{
+ FOR (i, 0, 8) {
+ u64 carry = 0;
+ FOR (j, 0, 8) {
+ carry += p[i+j] + (u64)a[i] * b[j];
+ p[i+j] = (u32)carry;
+ carry >>= 32;
+ }
+ p[i+8] = (u32)carry;
+ }
+}
+
+static int is_above_l(const u32 x[8])
+{
+ // We work with L directly, in a 2's complement encoding
+ // (-L == ~L + 1)
+ u64 carry = 1;
+ FOR (i, 0, 8) {
+ carry += (u64)x[i] + (~L[i] & 0xffffffff);
+ carry >>= 32;
+ }
+ return (int)carry; // carry is either 0 or 1
+}
+
+// Final reduction modulo L, by conditionally removing L.
+// if x < l , then r = x
+// if l <= x 2*l, then r = x-l
+// otherwise the result will be wrong
+static void remove_l(u32 r[8], const u32 x[8])
+{
+ u64 carry = (u64)is_above_l(x);
+ u32 mask = ~(u32)carry + 1; // carry == 0 or 1
+ FOR (i, 0, 8) {
+ carry += (u64)x[i] + (~L[i] & mask);
+ r[i] = (u32)carry;
+ carry >>= 32;
+ }
+}
+
+// Full reduction modulo L (Barrett reduction)
+static void mod_l(u8 reduced[32], const u32 x[16])
+{
+ static const u32 r[9] = {
+ 0x0a2c131b,0xed9ce5a3,0x086329a7,0x2106215d,
+ 0xffffffeb,0xffffffff,0xffffffff,0xffffffff,0xf,
+ };
+ // xr = x * r
+ u32 xr[25] = {0};
+ FOR (i, 0, 9) {
+ u64 carry = 0;
+ FOR (j, 0, 16) {
+ carry += xr[i+j] + (u64)r[i] * x[j];
+ xr[i+j] = (u32)carry;
+ carry >>= 32;
+ }
+ xr[i+16] = (u32)carry;
+ }
+ // xr = floor(xr / 2^512) * L
+ // Since the result is guaranteed to be below 2*L,
+ // it is enough to only compute the first 256 bits.
+ // The division is performed by saying xr[i+16]. (16 * 32 = 512)
+ ZERO(xr, 8);
+ FOR (i, 0, 8) {
+ u64 carry = 0;
+ FOR (j, 0, 8-i) {
+ carry += xr[i+j] + (u64)xr[i+16] * L[j];
+ xr[i+j] = (u32)carry;
+ carry >>= 32;
+ }
+ }
+ // xr = x - xr
+ u64 carry = 1;
+ FOR (i, 0, 8) {
+ carry += (u64)x[i] + (~xr[i] & 0xffffffff);
+ xr[i] = (u32)carry;
+ carry >>= 32;
+ }
+ // Final reduction modulo L (conditional subtraction)
+ remove_l(xr, xr);
+ store32_le_buf(reduced, xr, 8);
+
+ WIPE_BUFFER(xr);
+}
+
+void crypto_eddsa_reduce(u8 reduced[32], const u8 expanded[64])
+{
+ u32 x[16];
+ load32_le_buf(x, expanded, 16);
+ mod_l(reduced, x);
+ WIPE_BUFFER(x);
+}
+
+// r = (a * b) + c
+void crypto_eddsa_mul_add(u8 r[32],
+ const u8 a[32], const u8 b[32], const u8 c[32])
+{
+ u32 A[8]; load32_le_buf(A, a, 8);
+ u32 B[8]; load32_le_buf(B, b, 8);
+ u32 p[16]; load32_le_buf(p, c, 8); ZERO(p + 8, 8);
+ multiply(p, A, B);
+ mod_l(r, p);
+ WIPE_BUFFER(p);
+ WIPE_BUFFER(A);
+ WIPE_BUFFER(B);
+}
+
+///////////////
+/// Ed25519 ///
+///////////////
+
+// Point (group element, ge) in a twisted Edwards curve,
+// in extended projective coordinates.
+// ge : x = X/Z, y = Y/Z, T = XY/Z
+// ge_cached : Yp = X+Y, Ym = X-Y, T2 = T*D2
+// ge_precomp: Z = 1
+typedef struct { fe X; fe Y; fe Z; fe T; } ge;
+typedef struct { fe Yp; fe Ym; fe Z; fe T2; } ge_cached;
+typedef struct { fe Yp; fe Ym; fe T2; } ge_precomp;
+
+static void ge_zero(ge *p)
+{
+ fe_0(p->X);
+ fe_1(p->Y);
+ fe_1(p->Z);
+ fe_0(p->T);
+}
+
+static void ge_tobytes(u8 s[32], const ge *h)
+{
+ fe recip, x, y;
+ fe_invert(recip, h->Z);
+ fe_mul(x, h->X, recip);
+ fe_mul(y, h->Y, recip);
+ fe_tobytes(s, y);
+ s[31] ^= fe_isodd(x) << 7;
+
+ WIPE_BUFFER(recip);
+ WIPE_BUFFER(x);
+ WIPE_BUFFER(y);
+}
+
+// h = -s, where s is a point encoded in 32 bytes
+//
+// Variable time! Inputs must not be secret!
+// => Use only to *check* signatures.
+//
+// From the specifications:
+// The encoding of s contains y and the sign of x
+// x = sqrt((y^2 - 1) / (d*y^2 + 1))
+// In extended coordinates:
+// X = x, Y = y, Z = 1, T = x*y
+//
+// Note that num * den is a square iff num / den is a square
+// If num * den is not a square, the point was not on the curve.
+// From the above:
+// Let num = y^2 - 1
+// Let den = d*y^2 + 1
+// x = sqrt((y^2 - 1) / (d*y^2 + 1))
+// x = sqrt(num / den)
+// x = sqrt(num^2 / (num * den))
+// x = num * sqrt(1 / (num * den))
+//
+// Therefore, we can just compute:
+// num = y^2 - 1
+// den = d*y^2 + 1
+// isr = invsqrt(num * den) // abort if not square
+// x = num * isr
+// Finally, negate x if its sign is not as specified.
+static int ge_frombytes_neg_vartime(ge *h, const u8 s[32])
+{
+ fe_frombytes(h->Y, s);
+ fe_1(h->Z);
+ fe_sq (h->T, h->Y); // t = y^2
+ fe_mul(h->X, h->T, d ); // x = d*y^2
+ fe_sub(h->T, h->T, h->Z); // t = y^2 - 1
+ fe_add(h->X, h->X, h->Z); // x = d*y^2 + 1
+ fe_mul(h->X, h->T, h->X); // x = (y^2 - 1) * (d*y^2 + 1)
+ int is_square = invsqrt(h->X, h->X);
+ if (!is_square) {
+ return -1; // Not on the curve, abort
+ }
+ fe_mul(h->X, h->T, h->X); // x = sqrt((y^2 - 1) / (d*y^2 + 1))
+ if (fe_isodd(h->X) == (s[31] >> 7)) {
+ fe_neg(h->X, h->X);
+ }
+ fe_mul(h->T, h->X, h->Y);
+ return 0;
+}
+
+static void ge_cache(ge_cached *c, const ge *p)
+{
+ fe_add (c->Yp, p->Y, p->X);
+ fe_sub (c->Ym, p->Y, p->X);
+ fe_copy(c->Z , p->Z );
+ fe_mul (c->T2, p->T, D2 );
+}
+
+// Internal buffers are not wiped! Inputs must not be secret!
+// => Use only to *check* signatures.
+static void ge_add(ge *s, const ge *p, const ge_cached *q)
+{
+ fe a, b;
+ fe_add(a , p->Y, p->X );
+ fe_sub(b , p->Y, p->X );
+ fe_mul(a , a , q->Yp);
+ fe_mul(b , b , q->Ym);
+ fe_add(s->Y, a , b );
+ fe_sub(s->X, a , b );
+
+ fe_add(s->Z, p->Z, p->Z );
+ fe_mul(s->Z, s->Z, q->Z );
+ fe_mul(s->T, p->T, q->T2);
+ fe_add(a , s->Z, s->T );
+ fe_sub(b , s->Z, s->T );
+
+ fe_mul(s->T, s->X, s->Y);
+ fe_mul(s->X, s->X, b );
+ fe_mul(s->Y, s->Y, a );
+ fe_mul(s->Z, a , b );
+}
+
+// Internal buffers are not wiped! Inputs must not be secret!
+// => Use only to *check* signatures.
+static void ge_sub(ge *s, const ge *p, const ge_cached *q)
+{
+ ge_cached neg;
+ fe_copy(neg.Ym, q->Yp);
+ fe_copy(neg.Yp, q->Ym);
+ fe_copy(neg.Z , q->Z );
+ fe_neg (neg.T2, q->T2);
+ ge_add(s, p, &neg);
+}
+
+static void ge_madd(ge *s, const ge *p, const ge_precomp *q, fe a, fe b)
+{
+ fe_add(a , p->Y, p->X );
+ fe_sub(b , p->Y, p->X );
+ fe_mul(a , a , q->Yp);
+ fe_mul(b , b , q->Ym);
+ fe_add(s->Y, a , b );
+ fe_sub(s->X, a , b );
+
+ fe_add(s->Z, p->Z, p->Z );
+ fe_mul(s->T, p->T, q->T2);
+ fe_add(a , s->Z, s->T );
+ fe_sub(b , s->Z, s->T );
+
+ fe_mul(s->T, s->X, s->Y);
+ fe_mul(s->X, s->X, b );
+ fe_mul(s->Y, s->Y, a );
+ fe_mul(s->Z, a , b );
+}
+
+// Internal buffers are not wiped! Inputs must not be secret!
+// => Use only to *check* signatures.
+static void ge_msub(ge *s, const ge *p, const ge_precomp *q, fe a, fe b)
+{
+ ge_precomp neg;
+ fe_copy(neg.Ym, q->Yp);
+ fe_copy(neg.Yp, q->Ym);
+ fe_neg (neg.T2, q->T2);
+ ge_madd(s, p, &neg, a, b);
+}
+
+static void ge_double(ge *s, const ge *p, ge *q)
+{
+ fe_sq (q->X, p->X);
+ fe_sq (q->Y, p->Y);
+ fe_sq (q->Z, p->Z); // qZ = pZ^2
+ fe_mul_small(q->Z, q->Z, 2); // qZ = pZ^2 * 2
+ fe_add(q->T, p->X, p->Y);
+ fe_sq (s->T, q->T);
+ fe_add(q->T, q->Y, q->X);
+ fe_sub(q->Y, q->Y, q->X);
+ fe_sub(q->X, s->T, q->T);
+ fe_sub(q->Z, q->Z, q->Y);
+
+ fe_mul(s->X, q->X , q->Z);
+ fe_mul(s->Y, q->T , q->Y);
+ fe_mul(s->Z, q->Y , q->Z);
+ fe_mul(s->T, q->X , q->T);
+}
+
+// 5-bit signed window in cached format (Niels coordinates, Z=1)
+static const ge_precomp b_window[8] = {
+ {{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,},},
+};
+
+// Incremental sliding windows (left to right)
+// Based on Roberto Maria Avanzi[2005]
+typedef struct {
+ i16 next_index; // position of the next signed digit
+ i8 next_digit; // next signed digit (odd number below 2^window_width)
+ u8 next_check; // point at which we must check for a new window
+} slide_ctx;
+
+static void slide_init(slide_ctx *ctx, const u8 scalar[32])
+{
+ // scalar is guaranteed to be below L, either because we checked (s),
+ // or because we reduced it modulo L (h_ram). L is under 2^253, so
+ // so bits 253 to 255 are guaranteed to be zero. No need to test them.
+ //
+ // Note however that L is very close to 2^252, so bit 252 is almost
+ // always zero. If we were to start at bit 251, the tests wouldn't
+ // catch the off-by-one error (constructing one that does would be
+ // prohibitively expensive).
+ //
+ // We should still check bit 252, though.
+ int i = 252;
+ while (i > 0 && scalar_bit(scalar, i) == 0) {
+ i--;
+ }
+ ctx->next_check = (u8)(i + 1);
+ ctx->next_index = -1;
+ ctx->next_digit = -1;
+}
+
+static int slide_step(slide_ctx *ctx, int width, int i, const u8 scalar[32])
+{
+ if (i == ctx->next_check) {
+ if (scalar_bit(scalar, i) == scalar_bit(scalar, i - 1)) {
+ ctx->next_check--;
+ } else {
+ // compute digit of next window
+ int w = MIN(width, i + 1);
+ int v = -(scalar_bit(scalar, i) << (w-1));
+ FOR_T (int, j, 0, w-1) {
+ v += scalar_bit(scalar, i-(w-1)+j) << j;
+ }
+ v += scalar_bit(scalar, i-w);
+ int lsb = v & (~v + 1); // smallest bit of v
+ int s = // log2(lsb)
+ (((lsb & 0xAA) != 0) << 0) |
+ (((lsb & 0xCC) != 0) << 1) |
+ (((lsb & 0xF0) != 0) << 2);
+ ctx->next_index = (i16)(i-(w-1)+s);
+ ctx->next_digit = (i8) (v >> s );
+ ctx->next_check -= (u8) w;
+ }
+ }
+ return i == ctx->next_index ? ctx->next_digit: 0;
+}
+
+#define P_W_WIDTH 3 // Affects the size of the stack
+#define B_W_WIDTH 5 // Affects the size of the binary
+#define P_W_SIZE (1<<(P_W_WIDTH-2))
+
+int crypto_eddsa_check_equation(const u8 signature[64], const u8 public_key[32],
+ const u8 h[32])
+{
+ ge minus_A; // -public_key
+ ge minus_R; // -first_half_of_signature
+ const u8 *s = signature + 32;
+
+ // Check that A and R are on the curve
+ // Check that 0 <= S < L (prevents malleability)
+ // *Allow* non-cannonical encoding for A and R
+ {
+ u32 s32[8];
+ load32_le_buf(s32, s, 8);
+ if (ge_frombytes_neg_vartime(&minus_A, public_key) ||
+ ge_frombytes_neg_vartime(&minus_R, signature) ||
+ is_above_l(s32)) {
+ return -1;
+ }
+ }
+
+ // look-up table for minus_A
+ ge_cached lutA[P_W_SIZE];
+ {
+ ge minus_A2, tmp;
+ ge_double(&minus_A2, &minus_A, &tmp);
+ ge_cache(&lutA[0], &minus_A);
+ FOR (i, 1, P_W_SIZE) {
+ ge_add(&tmp, &minus_A2, &lutA[i-1]);
+ ge_cache(&lutA[i], &tmp);
+ }
+ }
+
+ // sum = [s]B - [h]A
+ // Merged double and add ladder, fused with sliding
+ slide_ctx h_slide; slide_init(&h_slide, h);
+ slide_ctx s_slide; slide_init(&s_slide, s);
+ int i = MAX(h_slide.next_check, s_slide.next_check);
+ ge *sum = &minus_A; // reuse minus_A for the sum
+ ge_zero(sum);
+ while (i >= 0) {
+ ge tmp;
+ ge_double(sum, sum, &tmp);
+ int h_digit = slide_step(&h_slide, P_W_WIDTH, i, h);
+ int s_digit = slide_step(&s_slide, B_W_WIDTH, i, s);
+ if (h_digit > 0) { ge_add(sum, sum, &lutA[ h_digit / 2]); }
+ if (h_digit < 0) { ge_sub(sum, sum, &lutA[-h_digit / 2]); }
+ fe t1, t2;
+ if (s_digit > 0) { ge_madd(sum, sum, b_window + s_digit/2, t1, t2); }
+ if (s_digit < 0) { ge_msub(sum, sum, b_window + -s_digit/2, t1, t2); }
+ i--;
+ }
+
+ // Compare [8](sum-R) and the zero point
+ // The multiplication by 8 eliminates any low-order component
+ // and ensures consistency with batched verification.
+ ge_cached cached;
+ u8 check[32];
+ static const u8 zero_point[32] = {1}; // Point of order 1
+ ge_cache(&cached, &minus_R);
+ ge_add(sum, sum, &cached);
+ ge_double(sum, sum, &minus_R); // reuse minus_R as temporary
+ ge_double(sum, sum, &minus_R); // reuse minus_R as temporary
+ ge_double(sum, sum, &minus_R); // reuse minus_R as temporary
+ ge_tobytes(check, sum);
+ return crypto_verify32(check, zero_point);
+}
+
+// 5-bit signed comb in cached format (Niels coordinates, Z=1)
+static const ge_precomp b_comb_low[8] = {
+ {{-6816601,-2324159,-22559413,124364,18015490,
+ 8373481,19993724,1979872,-18549925,9085059,},
+ {10306321,403248,14839893,9633706,8463310,
+ -8354981,-14305673,14668847,26301366,2818560,},
+ {-22701500,-3210264,-13831292,-2927732,-16326337,
+ -14016360,12940910,177905,12165515,-2397893,},},
+ {{-12282262,-7022066,9920413,-3064358,-32147467,
+ 2927790,22392436,-14852487,2719975,16402117,},
+ {-7236961,-4729776,2685954,-6525055,-24242706,
+ -15940211,-6238521,14082855,10047669,12228189,},
+ {-30495588,-12893761,-11161261,3539405,-11502464,
+ 16491580,-27286798,-15030530,-7272871,-15934455,},},
+ {{17650926,582297,-860412,-187745,-12072900,
+ -10683391,-20352381,15557840,-31072141,-5019061,},
+ {-6283632,-2259834,-4674247,-4598977,-4089240,
+ 12435688,-31278303,1060251,6256175,10480726,},
+ {-13871026,2026300,-21928428,-2741605,-2406664,
+ -8034988,7355518,15733500,-23379862,7489131,},},
+ {{6883359,695140,23196907,9644202,-33430614,
+ 11354760,-20134606,6388313,-8263585,-8491918,},
+ {-7716174,-13605463,-13646110,14757414,-19430591,
+ -14967316,10359532,-11059670,-21935259,12082603,},
+ {-11253345,-15943946,10046784,5414629,24840771,
+ 8086951,-6694742,9868723,15842692,-16224787,},},
+ {{9639399,11810955,-24007778,-9320054,3912937,
+ -9856959,996125,-8727907,-8919186,-14097242,},
+ {7248867,14468564,25228636,-8795035,14346339,
+ 8224790,6388427,-7181107,6468218,-8720783,},
+ {15513115,15439095,7342322,-10157390,18005294,
+ -7265713,2186239,4884640,10826567,7135781,},},
+ {{-14204238,5297536,-5862318,-6004934,28095835,
+ 4236101,-14203318,1958636,-16816875,3837147,},
+ {-5511166,-13176782,-29588215,12339465,15325758,
+ -15945770,-8813185,11075932,-19608050,-3776283,},
+ {11728032,9603156,-4637821,-5304487,-7827751,
+ 2724948,31236191,-16760175,-7268616,14799772,},},
+ {{-28842672,4840636,-12047946,-9101456,-1445464,
+ 381905,-30977094,-16523389,1290540,12798615,},
+ {27246947,-10320914,14792098,-14518944,5302070,
+ -8746152,-3403974,-4149637,-27061213,10749585,},
+ {25572375,-6270368,-15353037,16037944,1146292,
+ 32198,23487090,9585613,24714571,-1418265,},},
+ {{19844825,282124,-17583147,11004019,-32004269,
+ -2716035,6105106,-1711007,-21010044,14338445,},
+ {8027505,8191102,-18504907,-12335737,25173494,
+ -5923905,15446145,7483684,-30440441,10009108,},
+ {-14134701,-4174411,10246585,-14677495,33553567,
+ -14012935,23366126,15080531,-7969992,7663473,},},
+};
+
+static const ge_precomp b_comb_high[8] = {
+ {{33055887,-4431773,-521787,6654165,951411,
+ -6266464,-5158124,6995613,-5397442,-6985227,},
+ {4014062,6967095,-11977872,3960002,8001989,
+ 5130302,-2154812,-1899602,-31954493,-16173976,},
+ {16271757,-9212948,23792794,731486,-25808309,
+ -3546396,6964344,-4767590,10976593,10050757,},},
+ {{2533007,-4288439,-24467768,-12387405,-13450051,
+ 14542280,12876301,13893535,15067764,8594792,},
+ {20073501,-11623621,3165391,-13119866,13188608,
+ -11540496,-10751437,-13482671,29588810,2197295,},
+ {-1084082,11831693,6031797,14062724,14748428,
+ -8159962,-20721760,11742548,31368706,13161200,},},
+ {{2050412,-6457589,15321215,5273360,25484180,
+ 124590,-18187548,-7097255,-6691621,-14604792,},
+ {9938196,2162889,-6158074,-1711248,4278932,
+ -2598531,-22865792,-7168500,-24323168,11746309,},
+ {-22691768,-14268164,5965485,9383325,20443693,
+ 5854192,28250679,-1381811,-10837134,13717818,},},
+ {{-8495530,16382250,9548884,-4971523,-4491811,
+ -3902147,6182256,-12832479,26628081,10395408,},
+ {27329048,-15853735,7715764,8717446,-9215518,
+ -14633480,28982250,-5668414,4227628,242148,},
+ {-13279943,-7986904,-7100016,8764468,-27276630,
+ 3096719,29678419,-9141299,3906709,11265498,},},
+ {{11918285,15686328,-17757323,-11217300,-27548967,
+ 4853165,-27168827,6807359,6871949,-1075745,},
+ {-29002610,13984323,-27111812,-2713442,28107359,
+ -13266203,6155126,15104658,3538727,-7513788,},
+ {14103158,11233913,-33165269,9279850,31014152,
+ 4335090,-1827936,4590951,13960841,12787712,},},
+ {{1469134,-16738009,33411928,13942824,8092558,
+ -8778224,-11165065,1437842,22521552,-2792954,},
+ {31352705,-4807352,-25327300,3962447,12541566,
+ -9399651,-27425693,7964818,-23829869,5541287,},
+ {-25732021,-6864887,23848984,3039395,-9147354,
+ 6022816,-27421653,10590137,25309915,-1584678,},},
+ {{-22951376,5048948,31139401,-190316,-19542447,
+ -626310,-17486305,-16511925,-18851313,-12985140,},
+ {-9684890,14681754,30487568,7717771,-10829709,
+ 9630497,30290549,-10531496,-27798994,-13812825,},
+ {5827835,16097107,-24501327,12094619,7413972,
+ 11447087,28057551,-1793987,-14056981,4359312,},},
+ {{26323183,2342588,-21887793,-1623758,-6062284,
+ 2107090,-28724907,9036464,-19618351,-13055189,},
+ {-29697200,14829398,-4596333,14220089,-30022969,
+ 2955645,12094100,-13693652,-5941445,7047569,},
+ {-3201977,14413268,-12058324,-16417589,-9035655,
+ -7224648,9258160,1399236,30397584,-5684634,},},
+};
+
+static void lookup_add(ge *p, ge_precomp *tmp_c, fe tmp_a, fe tmp_b,
+ const ge_precomp comb[8], const u8 scalar[32], int i)
+{
+ u8 teeth = (u8)((scalar_bit(scalar, i) ) +
+ (scalar_bit(scalar, i + 32) << 1) +
+ (scalar_bit(scalar, i + 64) << 2) +
+ (scalar_bit(scalar, i + 96) << 3));
+ u8 high = teeth >> 3;
+ u8 index = (teeth ^ (high - 1)) & 7;
+ FOR (j, 0, 8) {
+ i32 select = 1 & (((j ^ index) - 1) >> 8);
+ fe_ccopy(tmp_c->Yp, comb[j].Yp, select);
+ fe_ccopy(tmp_c->Ym, comb[j].Ym, select);
+ fe_ccopy(tmp_c->T2, comb[j].T2, select);
+ }
+ fe_neg(tmp_a, tmp_c->T2);
+ fe_cswap(tmp_c->T2, tmp_a , high ^ 1);
+ fe_cswap(tmp_c->Yp, tmp_c->Ym, high ^ 1);
+ ge_madd(p, p, tmp_c, tmp_a, tmp_b);
+}
+
+// p = [scalar]B, where B is the base point
+static void ge_scalarmult_base(ge *p, const u8 scalar[32])
+{
+ // twin 4-bits signed combs, from Mike Hamburg's
+ // Fast and compact elliptic-curve cryptography (2012)
+ // 1 / 2 modulo L
+ static const u8 half_mod_L[32] = {
+ 247,233,122,46,141,49,9,44,107,206,123,81,239,124,111,10,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,8,
+ };
+ // (2^256 - 1) / 2 modulo L
+ static const u8 half_ones[32] = {
+ 142,74,204,70,186,24,118,107,184,231,190,57,250,173,119,99,
+ 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,7,
+ };
+
+ // All bits set form: 1 means 1, 0 means -1
+ u8 s_scalar[32];
+ crypto_eddsa_mul_add(s_scalar, scalar, half_mod_L, half_ones);
+
+ // Double and add ladder
+ fe tmp_a, tmp_b; // temporaries for addition
+ ge_precomp tmp_c; // temporary for comb lookup
+ ge tmp_d; // temporary for doubling
+ fe_1(tmp_c.Yp);
+ fe_1(tmp_c.Ym);
+ fe_0(tmp_c.T2);
+
+ // Save a double on the first iteration
+ ge_zero(p);
+ lookup_add(p, &tmp_c, tmp_a, tmp_b, b_comb_low , s_scalar, 31);
+ lookup_add(p, &tmp_c, tmp_a, tmp_b, b_comb_high, s_scalar, 31+128);
+ // Regular double & add for the rest
+ for (int i = 30; i >= 0; i--) {
+ ge_double(p, p, &tmp_d);
+ lookup_add(p, &tmp_c, tmp_a, tmp_b, b_comb_low , s_scalar, i);
+ lookup_add(p, &tmp_c, tmp_a, tmp_b, b_comb_high, s_scalar, i+128);
+ }
+ // Note: we could save one addition at the end if we assumed the
+ // scalar fit in 252 bits. Which it does in practice if it is
+ // selected at random. However, non-random, non-hashed scalars
+ // *can* overflow 252 bits in practice. Better account for that
+ // than leaving that kind of subtle corner case.
+
+ WIPE_BUFFER(tmp_a); WIPE_CTX(&tmp_d);
+ WIPE_BUFFER(tmp_b); WIPE_CTX(&tmp_c);
+ WIPE_BUFFER(s_scalar);
+}
+
+void crypto_eddsa_scalarbase(u8 point[32], const u8 scalar[32])
+{
+ ge P;
+ ge_scalarmult_base(&P, scalar);
+ ge_tobytes(point, &P);
+ WIPE_CTX(&P);
+}
+
+void crypto_eddsa_key_pair(u8 secret_key[64], u8 public_key[32], u8 seed[32])
+{
+ // To allow overlaps, observable writes happen in this order:
+ // 1. seed
+ // 2. secret_key
+ // 3. public_key
+ u8 a[64];
+ COPY(a, seed, 32);
+ crypto_wipe(seed, 32);
+ COPY(secret_key, a, 32);
+ crypto_blake2b(a, 64, a, 32);
+ crypto_eddsa_trim_scalar(a, a);
+ crypto_eddsa_scalarbase(secret_key + 32, a);
+ COPY(public_key, secret_key + 32, 32);
+ WIPE_BUFFER(a);
+}
+
+static void hash_reduce(u8 h[32],
+ const u8 *a, size_t a_size,
+ const u8 *b, size_t b_size,
+ const u8 *c, size_t c_size)
+{
+ u8 hash[64];
+ crypto_blake2b_ctx ctx;
+ crypto_blake2b_init (&ctx, 64);
+ crypto_blake2b_update(&ctx, a, a_size);
+ crypto_blake2b_update(&ctx, b, b_size);
+ crypto_blake2b_update(&ctx, c, c_size);
+ crypto_blake2b_final (&ctx, hash);
+ crypto_eddsa_reduce(h, hash);
+}
+
+// Digital signature of a message with from a secret key.
+//
+// The secret key comprises two parts:
+// - The seed that generates the key (secret_key[ 0..31])
+// - The public key (secret_key[32..63])
+//
+// The seed and the public key are bundled together to make sure users
+// don't use mismatched seeds and public keys, which would instantly
+// leak the secret scalar and allow forgeries (allowing this to happen
+// has resulted in critical vulnerabilities in the wild).
+//
+// The seed is hashed to derive the secret scalar and a secret prefix.
+// The sole purpose of the prefix is to generate a secret random nonce.
+// The properties of that nonce must be as follows:
+// - Unique: we need a different one for each message.
+// - Secret: third parties must not be able to predict it.
+// - Random: any detectable bias would break all security.
+//
+// There are two ways to achieve these properties. The obvious one is
+// to simply generate a random number. Here that would be a parameter
+// (Monocypher doesn't have an RNG). It works, but then users may reuse
+// the nonce by accident, which _also_ leaks the secret scalar and
+// allows forgeries. This has happened in the wild too.
+//
+// This is no good, so instead we generate that nonce deterministically
+// by reducing modulo L a hash of the secret prefix and the message.
+// The secret prefix makes the nonce unpredictable, the message makes it
+// unique, and the hash/reduce removes all bias.
+//
+// The cost of that safety is hashing the message twice. If that cost
+// is unacceptable, there are two alternatives:
+//
+// - Signing a hash of the message instead of the message itself. This
+// is fine as long as the hash is collision resistant. It is not
+// compatible with existing "pure" signatures, but at least it's safe.
+//
+// - Using a random nonce. Please exercise **EXTREME CAUTION** if you
+// ever do that. It is absolutely **critical** that the nonce is
+// really an unbiased random number between 0 and L-1, never reused,
+// and wiped immediately.
+//
+// To lower the likelihood of complete catastrophe if the RNG is
+// either flawed or misused, you can hash the RNG output together with
+// the secret prefix and the beginning of the message, and use the
+// reduction of that hash instead of the RNG output itself. It's not
+// foolproof (you'd need to hash the whole message) but it helps.
+//
+// Signing a message involves the following operations:
+//
+// scalar, prefix = HASH(secret_key)
+// r = HASH(prefix || message) % L
+// R = [r]B
+// h = HASH(R || public_key || message) % L
+// S = ((h * a) + r) % L
+// signature = R || S
+void crypto_eddsa_sign(u8 signature [64], const u8 secret_key[64],
+ const u8 *message, size_t message_size)
+{
+ u8 a[64]; // secret scalar and prefix
+ u8 r[32]; // secret deterministic "random" nonce
+ u8 h[32]; // publically verifiable hash of the message (not wiped)
+ u8 R[32]; // first half of the signature (allows overlapping inputs)
+
+ crypto_blake2b(a, 64, secret_key, 32);
+ crypto_eddsa_trim_scalar(a, a);
+ hash_reduce(r, a + 32, 32, message, message_size, 0, 0);
+ crypto_eddsa_scalarbase(R, r);
+ hash_reduce(h, R, 32, secret_key + 32, 32, message, message_size);
+ COPY(signature, R, 32);
+ crypto_eddsa_mul_add(signature + 32, h, a, r);
+
+ WIPE_BUFFER(a);
+ WIPE_BUFFER(r);
+}
+
+// To check the signature R, S of the message M with the public key A,
+// there are 3 steps:
+//
+// compute h = HASH(R || A || message) % L
+// check that A is on the curve.
+// check that R == [s]B - [h]A
+//
+// The last two steps are done in crypto_eddsa_check_equation()
+int crypto_eddsa_check(const u8 signature[64], const u8 public_key[32],
+ const u8 *message, size_t message_size)
+{
+ u8 h[32];
+ hash_reduce(h, signature, 32, public_key, 32, message, message_size);
+ return crypto_eddsa_check_equation(signature, public_key, h);
+}
+
+/////////////////////////
+/// EdDSA <--> X25519 ///
+/////////////////////////
+void crypto_eddsa_to_x25519(u8 x25519[32], const u8 eddsa[32])
+{
+ // (u, v) = ((1+y)/(1-y), sqrt(-486664)*u/x)
+ // Only converting y to u, the sign of x is ignored.
+ fe t1, t2;
+ fe_frombytes(t2, eddsa);
+ fe_add(t1, fe_one, t2);
+ fe_sub(t2, fe_one, t2);
+ fe_invert(t2, t2);
+ fe_mul(t1, t1, t2);
+ fe_tobytes(x25519, t1);
+ WIPE_BUFFER(t1);
+ WIPE_BUFFER(t2);
+}
+
+void crypto_x25519_to_eddsa(u8 eddsa[32], const u8 x25519[32])
+{
+ // (x, y) = (sqrt(-486664)*u/v, (u-1)/(u+1))
+ // Only converting u to y, x is assumed positive.
+ fe t1, t2;
+ fe_frombytes(t2, x25519);
+ fe_sub(t1, t2, fe_one);
+ fe_add(t2, t2, fe_one);
+ fe_invert(t2, t2);
+ fe_mul(t1, t1, t2);
+ fe_tobytes(eddsa, t1);
+ WIPE_BUFFER(t1);
+ WIPE_BUFFER(t2);
+}
+
+/////////////////////////////////////////////
+/// Dirty ephemeral public key generation ///
+/////////////////////////////////////////////
+
+// Those functions generates a public key, *without* clearing the
+// cofactor. Sending that key over the network leaks 3 bits of the
+// private key. Use only to generate ephemeral keys that will be hidden
+// with crypto_curve_to_hidden().
+//
+// The public key is otherwise compatible with crypto_x25519(), which
+// properly clears the cofactor.
+//
+// Note that the distribution of the resulting public keys is almost
+// uniform. Flipping the sign of the v coordinate (not provided by this
+// function), covers the entire key space almost perfectly, where
+// "almost" means a 2^-128 bias (undetectable). This uniformity is
+// needed to ensure the proper randomness of the resulting
+// representatives (once we apply crypto_curve_to_hidden()).
+//
+// Recall that Curve25519 has order C = 2^255 + e, with e < 2^128 (not
+// to be confused with the prime order of the main subgroup, L, which is
+// 8 times less than that).
+//
+// Generating all points would require us to multiply a point of order C
+// (the base point plus any point of order 8) by all scalars from 0 to
+// C-1. Clamping limits us to scalars between 2^254 and 2^255 - 1. But
+// by negating the resulting point at random, we also cover scalars from
+// -2^255 + 1 to -2^254 (which modulo C is congruent to e+1 to 2^254 + e).
+//
+// In practice:
+// - Scalars from 0 to e + 1 are never generated
+// - Scalars from 2^255 to 2^255 + e are never generated
+// - Scalars from 2^254 + 1 to 2^254 + e are generated twice
+//
+// Since e < 2^128, detecting this bias requires observing over 2^100
+// representatives from a given source (this will never happen), *and*
+// recovering enough of the private key to determine that they do, or do
+// not, belong to the biased set (this practically requires solving
+// discrete logarithm, which is conjecturally intractable).
+//
+// In practice, this means the bias is impossible to detect.
+
+// s + (x*L) % 8*L
+// Guaranteed to fit in 256 bits iff s fits in 255 bits.
+// L < 2^253
+// x%8 < 2^3
+// L * (x%8) < 2^255
+// s < 2^255
+// s + L * (x%8) < 2^256
+static void add_xl(u8 s[32], u8 x)
+{
+ u64 mod8 = x & 7;
+ u64 carry = 0;
+ FOR (i , 0, 8) {
+ carry = carry + load32_le(s + 4*i) + L[i] * mod8;
+ store32_le(s + 4*i, (u32)carry);
+ carry >>= 32;
+ }
+}
+
+// "Small" dirty ephemeral key.
+// Use if you need to shrink the size of the binary, and can afford to
+// slow down by a factor of two (compared to the fast version)
+//
+// This version works by decoupling the cofactor from the main factor.
+//
+// - The trimmed scalar determines the main factor
+// - The clamped bits of the scalar determine the cofactor.
+//
+// Cofactor and main factor are combined into a single scalar, which is
+// then multiplied by a point of order 8*L (unlike the base point, which
+// has prime order). That "dirty" base point is the addition of the
+// regular base point (9), and a point of order 8.
+void crypto_x25519_dirty_small(u8 public_key[32], const u8 secret_key[32])
+{
+ // Base point of order 8*L
+ // Raw scalar multiplication with it does not clear the cofactor,
+ // and the resulting public key will reveal 3 bits of the scalar.
+ //
+ // The low order component of this base point has been chosen
+ // to yield the same results as crypto_x25519_dirty_fast().
+ static const u8 dirty_base_point[32] = {
+ 0xd8, 0x86, 0x1a, 0xa2, 0x78, 0x7a, 0xd9, 0x26,
+ 0x8b, 0x74, 0x74, 0xb6, 0x82, 0xe3, 0xbe, 0xc3,
+ 0xce, 0x36, 0x9a, 0x1e, 0x5e, 0x31, 0x47, 0xa2,
+ 0x6d, 0x37, 0x7c, 0xfd, 0x20, 0xb5, 0xdf, 0x75,
+ };
+ // separate the main factor & the cofactor of the scalar
+ u8 scalar[32];
+ crypto_eddsa_trim_scalar(scalar, secret_key);
+
+ // Separate the main factor and the cofactor
+ //
+ // The scalar is trimmed, so its cofactor is cleared. The three
+ // least significant bits however still have a main factor. We must
+ // remove it for X25519 compatibility.
+ //
+ // cofactor = lsb * L (modulo 8*L)
+ // combined = scalar + cofactor (modulo 8*L)
+ add_xl(scalar, secret_key[0]);
+ scalarmult(public_key, scalar, dirty_base_point, 256);
+ WIPE_BUFFER(scalar);
+}
+
+// Select low order point
+// We're computing the [cofactor]lop scalar multiplication, where:
+//
+// cofactor = tweak & 7.
+// lop = (lop_x, lop_y)
+// lop_x = sqrt((sqrt(d + 1) + 1) / d)
+// lop_y = -lop_x * sqrtm1
+//
+// The low order point has order 8. There are 4 such points. We've
+// chosen the one whose both coordinates are positive (below p/2).
+// The 8 low order points are as follows:
+//
+// [0]lop = ( 0 , 1 )
+// [1]lop = ( lop_x , lop_y)
+// [2]lop = ( sqrt(-1), -0 )
+// [3]lop = ( lop_x , -lop_y)
+// [4]lop = (-0 , -1 )
+// [5]lop = (-lop_x , -lop_y)
+// [6]lop = (-sqrt(-1), 0 )
+// [7]lop = (-lop_x , lop_y)
+//
+// The x coordinate is either 0, sqrt(-1), lop_x, or their opposite.
+// The y coordinate is either 0, -1 , lop_y, or their opposite.
+// The pattern for both is the same, except for a rotation of 2 (modulo 8)
+//
+// This helper function captures the pattern, and we can use it thus:
+//
+// select_lop(x, lop_x, sqrtm1, cofactor);
+// select_lop(y, lop_y, fe_one, cofactor + 2);
+//
+// This is faster than an actual scalar multiplication,
+// and requires less code than naive constant time look up.
+static void select_lop(fe out, const fe x, const fe k, u8 cofactor)
+{
+ fe tmp;
+ fe_0(out);
+ fe_ccopy(out, k , (cofactor >> 1) & 1); // bit 1
+ fe_ccopy(out, x , (cofactor >> 0) & 1); // bit 0
+ fe_neg (tmp, out);
+ fe_ccopy(out, tmp, (cofactor >> 2) & 1); // bit 2
+ WIPE_BUFFER(tmp);
+}
+
+// "Fast" dirty ephemeral key
+// We use this one by default.
+//
+// This version works by performing a regular scalar multiplication,
+// then add a low order point. The scalar multiplication is done in
+// Edwards space for more speed (*2 compared to the "small" version).
+// The cost is a bigger binary for programs that don't also sign messages.
+void crypto_x25519_dirty_fast(u8 public_key[32], const u8 secret_key[32])
+{
+ // Compute clean scalar multiplication
+ u8 scalar[32];
+ ge pk;
+ crypto_eddsa_trim_scalar(scalar, secret_key);
+ ge_scalarmult_base(&pk, scalar);
+
+ // Compute low order point
+ fe t1, t2;
+ select_lop(t1, lop_x, sqrtm1, secret_key[0]);
+ select_lop(t2, lop_y, fe_one, secret_key[0] + 2);
+ ge_precomp low_order_point;
+ fe_add(low_order_point.Yp, t2, t1);
+ fe_sub(low_order_point.Ym, t2, t1);
+ fe_mul(low_order_point.T2, t2, t1);
+ fe_mul(low_order_point.T2, low_order_point.T2, D2);
+
+ // Add low order point to the public key
+ ge_madd(&pk, &pk, &low_order_point, t1, t2);
+
+ // Convert to Montgomery u coordinate (we ignore the sign)
+ fe_add(t1, pk.Z, pk.Y);
+ fe_sub(t2, pk.Z, pk.Y);
+ fe_invert(t2, t2);
+ fe_mul(t1, t1, t2);
+
+ fe_tobytes(public_key, t1);
+
+ WIPE_BUFFER(t1); WIPE_CTX(&pk);
+ WIPE_BUFFER(t2); WIPE_CTX(&low_order_point);
+ WIPE_BUFFER(scalar);
+}
+
+///////////////////
+/// Elligator 2 ///
+///////////////////
+static const fe A = {486662};
+
+// Elligator direct map
+//
+// Computes the point corresponding to a representative, encoded in 32
+// bytes (little Endian). Since positive representatives fits in 254
+// bits, The two most significant bits are ignored.
+//
+// From the paper:
+// w = -A / (fe(1) + non_square * r^2)
+// e = chi(w^3 + A*w^2 + w)
+// u = e*w - (fe(1)-e)*(A//2)
+// v = -e * sqrt(u^3 + A*u^2 + u)
+//
+// We ignore v because we don't need it for X25519 (the Montgomery
+// ladder only uses u).
+//
+// Note that e is either 0, 1 or -1
+// if e = 0 u = 0 and v = 0
+// if e = 1 u = w
+// if e = -1 u = -w - A = w * non_square * r^2
+//
+// Let r1 = non_square * r^2
+// Let r2 = 1 + r1
+// Note that r2 cannot be zero, -1/non_square is not a square.
+// We can (tediously) verify that:
+// w^3 + A*w^2 + w = (A^2*r1 - r2^2) * A / r2^3
+// Therefore:
+// chi(w^3 + A*w^2 + w) = chi((A^2*r1 - r2^2) * (A / r2^3))
+// chi(w^3 + A*w^2 + w) = chi((A^2*r1 - r2^2) * (A / r2^3)) * 1
+// chi(w^3 + A*w^2 + w) = chi((A^2*r1 - r2^2) * (A / r2^3)) * chi(r2^6)
+// chi(w^3 + A*w^2 + w) = chi((A^2*r1 - r2^2) * (A / r2^3) * r2^6)
+// chi(w^3 + A*w^2 + w) = chi((A^2*r1 - r2^2) * A * r2^3)
+// Corollary:
+// e = 1 if (A^2*r1 - r2^2) * A * r2^3) is a non-zero square
+// e = -1 if (A^2*r1 - r2^2) * A * r2^3) is not a square
+// Note that w^3 + A*w^2 + w (and therefore e) can never be zero:
+// w^3 + A*w^2 + w = w * (w^2 + A*w + 1)
+// w^3 + A*w^2 + w = w * (w^2 + A*w + A^2/4 - A^2/4 + 1)
+// w^3 + A*w^2 + w = w * (w + A/2)^2 - A^2/4 + 1)
+// which is zero only if:
+// w = 0 (impossible)
+// (w + A/2)^2 = A^2/4 - 1 (impossible, because A^2/4-1 is not a square)
+//
+// Let isr = invsqrt((A^2*r1 - r2^2) * A * r2^3)
+// isr = sqrt(1 / ((A^2*r1 - r2^2) * A * r2^3)) if e = 1
+// isr = sqrt(sqrt(-1) / ((A^2*r1 - r2^2) * A * r2^3)) if e = -1
+//
+// if e = 1
+// let u1 = -A * (A^2*r1 - r2^2) * A * r2^2 * isr^2
+// u1 = w
+// u1 = u
+//
+// if e = -1
+// let ufactor = -non_square * sqrt(-1) * r^2
+// let vfactor = sqrt(ufactor)
+// let u2 = -A * (A^2*r1 - r2^2) * A * r2^2 * isr^2 * ufactor
+// u2 = w * -1 * -non_square * r^2
+// u2 = w * non_square * r^2
+// u2 = u
+void crypto_elligator_map(u8 curve[32], const u8 hidden[32])
+{
+ fe r, u, t1, t2, t3;
+ fe_frombytes_mask(r, hidden, 2); // r is encoded in 254 bits.
+ fe_sq(r, r);
+ fe_add(t1, r, r);
+ fe_add(u, t1, fe_one);
+ fe_sq (t2, u);
+ fe_mul(t3, A2, t1);
+ fe_sub(t3, t3, t2);
+ fe_mul(t3, t3, A);
+ fe_mul(t1, t2, u);
+ fe_mul(t1, t3, t1);
+ int is_square = invsqrt(t1, t1);
+ fe_mul(u, r, ufactor);
+ fe_ccopy(u, fe_one, is_square);
+ fe_sq (t1, t1);
+ fe_mul(u, u, A);
+ fe_mul(u, u, t3);
+ fe_mul(u, u, t2);
+ fe_mul(u, u, t1);
+ fe_neg(u, u);
+ fe_tobytes(curve, u);
+
+ WIPE_BUFFER(t1); WIPE_BUFFER(r);
+ WIPE_BUFFER(t2); WIPE_BUFFER(u);
+ WIPE_BUFFER(t3);
+}
+
+// Elligator inverse map
+//
+// Computes the representative of a point, if possible. If not, it does
+// nothing and returns -1. Note that the success of the operation
+// depends only on the point (more precisely its u coordinate). The
+// tweak parameter is used only upon success
+//
+// The tweak should be a random byte. Beyond that, its contents are an
+// implementation detail. Currently, the tweak comprises:
+// - Bit 1 : sign of the v coordinate (0 if positive, 1 if negative)
+// - Bit 2-5: not used
+// - Bits 6-7: random padding
+//
+// From the paper:
+// Let sq = -non_square * u * (u+A)
+// if sq is not a square, or u = -A, there is no mapping
+// Assuming there is a mapping:
+// if v is positive: r = sqrt(-u / (non_square * (u+A)))
+// if v is negative: r = sqrt(-(u+A) / (non_square * u ))
+//
+// We compute isr = invsqrt(-non_square * u * (u+A))
+// if it wasn't a square, abort.
+// else, isr = sqrt(-1 / (non_square * u * (u+A))
+//
+// If v is positive, we return isr * u:
+// isr * u = sqrt(-1 / (non_square * u * (u+A)) * u
+// isr * u = sqrt(-u / (non_square * (u+A))
+//
+// If v is negative, we return isr * (u+A):
+// isr * (u+A) = sqrt(-1 / (non_square * u * (u+A)) * (u+A)
+// isr * (u+A) = sqrt(-(u+A) / (non_square * u)
+int crypto_elligator_rev(u8 hidden[32], const u8 public_key[32], u8 tweak)
+{
+ fe t1, t2, t3;
+ fe_frombytes(t1, public_key); // t1 = u
+
+ fe_add(t2, t1, A); // t2 = u + A
+ fe_mul(t3, t1, t2);
+ fe_mul_small(t3, t3, -2);
+ int is_square = invsqrt(t3, t3); // t3 = sqrt(-1 / non_square * u * (u+A))
+ if (is_square) {
+ // The only variable time bit. This ultimately reveals how many
+ // tries it took us to find a representable key.
+ // This does not affect security as long as we try keys at random.
+
+ fe_ccopy (t1, t2, tweak & 1); // multiply by u if v is positive,
+ fe_mul (t3, t1, t3); // multiply by u+A otherwise
+ fe_mul_small(t1, t3, 2);
+ fe_neg (t2, t3);
+ fe_ccopy (t3, t2, fe_isodd(t1));
+ fe_tobytes(hidden, t3);
+
+ // Pad with two random bits
+ hidden[31] |= tweak & 0xc0;
+ }
+
+ WIPE_BUFFER(t1);
+ WIPE_BUFFER(t2);
+ WIPE_BUFFER(t3);
+ return is_square - 1;
+}
+
+void crypto_elligator_key_pair(u8 hidden[32], u8 secret_key[32], u8 seed[32])
+{
+ u8 pk [32]; // public key
+ u8 buf[64]; // seed + representative
+ COPY(buf + 32, seed, 32);
+ do {
+ crypto_chacha20_djb(buf, 0, 64, buf+32, zero, 0);
+ crypto_x25519_dirty_fast(pk, buf); // or the "small" version
+ } while(crypto_elligator_rev(buf+32, pk, buf[32]));
+ // Note that the return value of crypto_elligator_rev() is
+ // independent from its tweak parameter.
+ // Therefore, buf[32] is not actually reused. Either we loop one
+ // more time and buf[32] is used for the new seed, or we succeeded,
+ // and buf[32] becomes the tweak parameter.
+
+ crypto_wipe(seed, 32);
+ COPY(hidden , buf + 32, 32);
+ COPY(secret_key, buf , 32);
+ WIPE_BUFFER(buf);
+ WIPE_BUFFER(pk);
+}
+
+///////////////////////
+/// Scalar division ///
+///////////////////////
+
+// Montgomery reduction.
+// Divides x by (2^256), and reduces the result modulo L
+//
+// Precondition:
+// x < L * 2^256
+// Constants:
+// r = 2^256 (makes division by r trivial)
+// k = (r * (1/r) - 1) // L (1/r is computed modulo L )
+// Algorithm:
+// s = (x * k) % r
+// t = x + s*L (t is always a multiple of r)
+// u = (t/r) % L (u is always below 2*L, conditional subtraction is enough)
+static void redc(u32 u[8], u32 x[16])
+{
+ static const u32 k[8] = {
+ 0x12547e1b, 0xd2b51da3, 0xfdba84ff, 0xb1a206f2,
+ 0xffa36bea, 0x14e75438, 0x6fe91836, 0x9db6c6f2,
+ };
+
+ // s = x * k (modulo 2^256)
+ // This is cheaper than the full multiplication.
+ u32 s[8] = {0};
+ FOR (i, 0, 8) {
+ u64 carry = 0;
+ FOR (j, 0, 8-i) {
+ carry += s[i+j] + (u64)x[i] * k[j];
+ s[i+j] = (u32)carry;
+ carry >>= 32;
+ }
+ }
+ u32 t[16] = {0};
+ multiply(t, s, L);
+
+ // t = t + x
+ u64 carry = 0;
+ FOR (i, 0, 16) {
+ carry += (u64)t[i] + x[i];
+ t[i] = (u32)carry;
+ carry >>= 32;
+ }
+
+ // u = (t / 2^256) % L
+ // Note that t / 2^256 is always below 2*L,
+ // So a constant time conditional subtraction is enough
+ remove_l(u, t+8);
+
+ WIPE_BUFFER(s);
+ WIPE_BUFFER(t);
+}
+
+void crypto_x25519_inverse(u8 blind_salt [32], const u8 private_key[32],
+ const u8 curve_point[32])
+{
+ static const u8 Lm2[32] = { // L - 2
+ 0xeb, 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,
+ };
+ // 1 in Montgomery form
+ u32 m_inv [8] = {
+ 0x8d98951d, 0xd6ec3174, 0x737dcf70, 0xc6ef5bf4,
+ 0xfffffffe, 0xffffffff, 0xffffffff, 0x0fffffff,
+ };
+
+ u8 scalar[32];
+ crypto_eddsa_trim_scalar(scalar, private_key);
+
+ // Convert the scalar in Montgomery form
+ // m_scl = scalar * 2^256 (modulo L)
+ u32 m_scl[8];
+ {
+ u32 tmp[16];
+ ZERO(tmp, 8);
+ load32_le_buf(tmp+8, scalar, 8);
+ mod_l(scalar, tmp);
+ load32_le_buf(m_scl, scalar, 8);
+ WIPE_BUFFER(tmp); // Wipe ASAP to save stack space
+ }
+
+ // Compute the inverse
+ u32 product[16];
+ for (int i = 252; i >= 0; i--) {
+ ZERO(product, 16);
+ multiply(product, m_inv, m_inv);
+ redc(m_inv, product);
+ if (scalar_bit(Lm2, i)) {
+ ZERO(product, 16);
+ multiply(product, m_inv, m_scl);
+ redc(m_inv, product);
+ }
+ }
+ // Convert the inverse *out* of Montgomery form
+ // scalar = m_inv / 2^256 (modulo L)
+ COPY(product, m_inv, 8);
+ ZERO(product + 8, 8);
+ redc(m_inv, product);
+ store32_le_buf(scalar, m_inv, 8); // the *inverse* of the scalar
+
+ // Clear the cofactor of scalar:
+ // cleared = scalar * (3*L + 1) (modulo 8*L)
+ // cleared = scalar + scalar * 3 * L (modulo 8*L)
+ // Note that (scalar * 3) is reduced modulo 8, so we only need the
+ // first byte.
+ add_xl(scalar, scalar[0] * 3);
+
+ // Recall that 8*L < 2^256. However it is also very close to
+ // 2^255. If we spanned the ladder over 255 bits, random tests
+ // wouldn't catch the off-by-one error.
+ scalarmult(blind_salt, scalar, curve_point, 256);
+
+ WIPE_BUFFER(scalar); WIPE_BUFFER(m_scl);
+ WIPE_BUFFER(product); WIPE_BUFFER(m_inv);
+}
+
+////////////////////////////////
+/// Authenticated encryption ///
+////////////////////////////////
+static void lock_auth(u8 mac[16], const u8 auth_key[32],
+ const u8 *ad , size_t ad_size,
+ const u8 *cipher_text, size_t text_size)
+{
+ u8 sizes[16]; // Not secret, not wiped
+ store64_le(sizes + 0, ad_size);
+ store64_le(sizes + 8, text_size);
+ crypto_poly1305_ctx poly_ctx; // auto wiped...
+ crypto_poly1305_init (&poly_ctx, auth_key);
+ crypto_poly1305_update(&poly_ctx, ad , ad_size);
+ crypto_poly1305_update(&poly_ctx, zero , gap(ad_size, 16));
+ crypto_poly1305_update(&poly_ctx, cipher_text, text_size);
+ crypto_poly1305_update(&poly_ctx, zero , gap(text_size, 16));
+ crypto_poly1305_update(&poly_ctx, sizes , 16);
+ crypto_poly1305_final (&poly_ctx, mac); // ...here
+}
+
+void crypto_aead_init_x(crypto_aead_ctx *ctx,
+ u8 const key[32], const u8 nonce[24])
+{
+ crypto_chacha20_h(ctx->key, key, nonce);
+ COPY(ctx->nonce, nonce + 16, 8);
+ ctx->counter = 0;
+}
+
+void crypto_aead_init_djb(crypto_aead_ctx *ctx,
+ const u8 key[32], const u8 nonce[8])
+{
+ COPY(ctx->key , key , 32);
+ COPY(ctx->nonce, nonce, 8);
+ ctx->counter = 0;
+}
+
+void crypto_aead_init_ietf(crypto_aead_ctx *ctx,
+ const u8 key[32], const u8 nonce[12])
+{
+ COPY(ctx->key , key , 32);
+ COPY(ctx->nonce, nonce + 4, 8);
+ ctx->counter = (u64)load32_le(nonce) << 32;
+}
+
+void crypto_aead_write(crypto_aead_ctx *ctx, u8 *cipher_text, u8 mac[16],
+ const u8 *ad, size_t ad_size,
+ const u8 *plain_text, size_t text_size)
+{
+ u8 auth_key[64]; // the last 32 bytes are used for rekeying.
+ crypto_chacha20_djb(auth_key, 0, 64, ctx->key, ctx->nonce, ctx->counter);
+ crypto_chacha20_djb(cipher_text, plain_text, text_size,
+ ctx->key, ctx->nonce, ctx->counter + 1);
+ lock_auth(mac, auth_key, ad, ad_size, cipher_text, text_size);
+ COPY(ctx->key, auth_key + 32, 32);
+ WIPE_BUFFER(auth_key);
+}
+
+int crypto_aead_read(crypto_aead_ctx *ctx, u8 *plain_text, const u8 mac[16],
+ const u8 *ad, size_t ad_size,
+ const u8 *cipher_text, size_t text_size)
+{
+ u8 auth_key[64]; // the last 32 bytes are used for rekeying.
+ u8 real_mac[16];
+ crypto_chacha20_djb(auth_key, 0, 64, ctx->key, ctx->nonce, ctx->counter);
+ lock_auth(real_mac, auth_key, ad, ad_size, cipher_text, text_size);
+ int mismatch = crypto_verify16(mac, real_mac);
+ if (!mismatch) {
+ crypto_chacha20_djb(plain_text, cipher_text, text_size,
+ ctx->key, ctx->nonce, ctx->counter + 1);
+ COPY(ctx->key, auth_key + 32, 32);
+ }
+ WIPE_BUFFER(auth_key);
+ WIPE_BUFFER(real_mac);
+ return mismatch;
+}
+
+void crypto_aead_lock(u8 *cipher_text, u8 mac[16], const u8 key[32],
+ const u8 nonce[24], const u8 *ad, size_t ad_size,
+ const u8 *plain_text, size_t text_size)
+{
+ crypto_aead_ctx ctx;
+ crypto_aead_init_x(&ctx, key, nonce);
+ crypto_aead_write(&ctx, cipher_text, mac, ad, ad_size,
+ plain_text, text_size);
+ crypto_wipe(&ctx, sizeof(ctx));
+}
+
+int crypto_aead_unlock(u8 *plain_text, const u8 mac[16], const u8 key[32],
+ const u8 nonce[24], const u8 *ad, size_t ad_size,
+ const u8 *cipher_text, size_t text_size)
+{
+ crypto_aead_ctx ctx;
+ crypto_aead_init_x(&ctx, key, nonce);
+ int mismatch = crypto_aead_read(&ctx, plain_text, mac, ad, ad_size,
+ cipher_text, text_size);
+ crypto_wipe(&ctx, sizeof(ctx));
+ return mismatch;
+}
+
+#ifdef MONOCYPHER_CPP_NAMESPACE
+}
+#endif
diff --git a/lib/Utils.Cryptography/monocypher/vendor/src/monocypher.h b/lib/Utils.Cryptography/monocypher/vendor/src/monocypher.h
new file mode 100644
index 0000000..cf635e8
--- /dev/null
+++ b/lib/Utils.Cryptography/monocypher/vendor/src/monocypher.h
@@ -0,0 +1,321 @@
+// Monocypher version __git__
+//
+// This file is dual-licensed. Choose whichever licence you want from
+// the two licences listed below.
+//
+// The first licence is a regular 2-clause BSD licence. The second licence
+// is the CC-0 from Creative Commons. It is intended to release Monocypher
+// to the public domain. The BSD licence serves as a fallback option.
+//
+// SPDX-License-Identifier: BSD-2-Clause OR CC0-1.0
+//
+// ------------------------------------------------------------------------
+//
+// Copyright (c) 2017-2019, Loup Vaillant
+// 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 COPYRIGHT HOLDERS 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 COPYRIGHT
+// HOLDER 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.
+//
+// ------------------------------------------------------------------------
+//
+// Written in 2017-2019 by Loup Vaillant
+//
+// To the extent possible under law, the author(s) have dedicated all copyright
+// and related 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
+// <https://creativecommons.org/publicdomain/zero/1.0/>
+
+#ifndef MONOCYPHER_H
+#define MONOCYPHER_H
+
+#include <stddef.h>
+#include <stdint.h>
+
+#ifdef MONOCYPHER_CPP_NAMESPACE
+namespace MONOCYPHER_CPP_NAMESPACE {
+#elif defined(__cplusplus)
+extern "C" {
+#endif
+
+// Constant time comparisons
+// -------------------------
+
+// Return 0 if a and b are equal, -1 otherwise
+int crypto_verify16(const uint8_t a[16], const uint8_t b[16]);
+int crypto_verify32(const uint8_t a[32], const uint8_t b[32]);
+int crypto_verify64(const uint8_t a[64], const uint8_t b[64]);
+
+
+// Erase sensitive data
+// --------------------
+void crypto_wipe(void *secret, size_t size);
+
+
+// Authenticated encryption
+// ------------------------
+void crypto_aead_lock(uint8_t *cipher_text,
+ uint8_t mac [16],
+ const uint8_t key [32],
+ const uint8_t nonce[24],
+ const uint8_t *ad, size_t ad_size,
+ const uint8_t *plain_text, size_t text_size);
+int crypto_aead_unlock(uint8_t *plain_text,
+ const uint8_t mac [16],
+ const uint8_t key [32],
+ const uint8_t nonce[24],
+ const uint8_t *ad, size_t ad_size,
+ const uint8_t *cipher_text, size_t text_size);
+
+// Authenticated stream
+// --------------------
+typedef struct {
+ uint64_t counter;
+ uint8_t key[32];
+ uint8_t nonce[8];
+} crypto_aead_ctx;
+
+void crypto_aead_init_x(crypto_aead_ctx *ctx,
+ const uint8_t key[32], const uint8_t nonce[24]);
+void crypto_aead_init_djb(crypto_aead_ctx *ctx,
+ const uint8_t key[32], const uint8_t nonce[8]);
+void crypto_aead_init_ietf(crypto_aead_ctx *ctx,
+ const uint8_t key[32], const uint8_t nonce[12]);
+
+void crypto_aead_write(crypto_aead_ctx *ctx,
+ uint8_t *cipher_text,
+ uint8_t mac[16],
+ const uint8_t *ad , size_t ad_size,
+ const uint8_t *plain_text, size_t text_size);
+int crypto_aead_read(crypto_aead_ctx *ctx,
+ uint8_t *plain_text,
+ const uint8_t mac[16],
+ const uint8_t *ad , size_t ad_size,
+ const uint8_t *cipher_text, size_t text_size);
+
+
+// General purpose hash (BLAKE2b)
+// ------------------------------
+
+// Direct interface
+void crypto_blake2b(uint8_t *hash, size_t hash_size,
+ const uint8_t *message, size_t message_size);
+
+void crypto_blake2b_keyed(uint8_t *hash, size_t hash_size,
+ const uint8_t *key, size_t key_size,
+ const uint8_t *message, size_t message_size);
+
+// Incremental interface
+typedef struct {
+ // Do not rely on the size or contents of this type,
+ // for they may change without notice.
+ uint64_t hash[8];
+ uint64_t input_offset[2];
+ uint64_t input[16];
+ size_t input_idx;
+ size_t hash_size;
+} crypto_blake2b_ctx;
+
+void crypto_blake2b_init(crypto_blake2b_ctx *ctx, size_t hash_size);
+void crypto_blake2b_keyed_init(crypto_blake2b_ctx *ctx, size_t hash_size,
+ const uint8_t *key, size_t key_size);
+void crypto_blake2b_update(crypto_blake2b_ctx *ctx,
+ const uint8_t *message, size_t message_size);
+void crypto_blake2b_final(crypto_blake2b_ctx *ctx, uint8_t *hash);
+
+
+// Password key derivation (Argon2)
+// --------------------------------
+#define CRYPTO_ARGON2_D 0
+#define CRYPTO_ARGON2_I 1
+#define CRYPTO_ARGON2_ID 2
+
+typedef struct {
+ uint32_t algorithm; // Argon2d, Argon2i, Argon2id
+ uint32_t nb_blocks; // memory hardness, >= 8 * nb_lanes
+ uint32_t nb_passes; // CPU hardness, >= 1 (>= 3 recommended for Argon2i)
+ uint32_t nb_lanes; // parallelism level (single threaded anyway)
+} crypto_argon2_config;
+
+typedef struct {
+ const uint8_t *pass;
+ const uint8_t *salt;
+ uint32_t pass_size;
+ uint32_t salt_size; // 16 bytes recommended
+} crypto_argon2_inputs;
+
+typedef struct {
+ const uint8_t *key; // may be NULL if no key
+ const uint8_t *ad; // may be NULL if no additional data
+ uint32_t key_size; // 0 if no key (32 bytes recommended otherwise)
+ uint32_t ad_size; // 0 if no additional data
+} crypto_argon2_extras;
+
+extern const crypto_argon2_extras crypto_argon2_no_extras;
+
+void crypto_argon2(uint8_t *hash, uint32_t hash_size, void *work_area,
+ crypto_argon2_config config,
+ crypto_argon2_inputs inputs,
+ crypto_argon2_extras extras);
+
+
+// Key exchange (X-25519)
+// ----------------------
+
+// Shared secrets are not quite random.
+// Hash them to derive an actual shared key.
+void crypto_x25519_public_key(uint8_t public_key[32],
+ const uint8_t secret_key[32]);
+void crypto_x25519(uint8_t raw_shared_secret[32],
+ const uint8_t your_secret_key [32],
+ const uint8_t their_public_key [32]);
+
+// Conversion to EdDSA
+void crypto_x25519_to_eddsa(uint8_t eddsa[32], const uint8_t x25519[32]);
+
+// scalar "division"
+// Used for OPRF. Be aware that exponential blinding is less secure
+// than Diffie-Hellman key exchange.
+void crypto_x25519_inverse(uint8_t blind_salt [32],
+ const uint8_t private_key[32],
+ const uint8_t curve_point[32]);
+
+// "Dirty" versions of x25519_public_key().
+// Use with crypto_elligator_rev().
+// Leaks 3 bits of the private key.
+void crypto_x25519_dirty_small(uint8_t pk[32], const uint8_t sk[32]);
+void crypto_x25519_dirty_fast (uint8_t pk[32], const uint8_t sk[32]);
+
+
+// Signatures
+// ----------
+
+// EdDSA with curve25519 + BLAKE2b
+void crypto_eddsa_key_pair(uint8_t secret_key[64],
+ uint8_t public_key[32],
+ uint8_t seed[32]);
+void crypto_eddsa_sign(uint8_t signature [64],
+ const uint8_t secret_key[64],
+ const uint8_t *message, size_t message_size);
+int crypto_eddsa_check(const uint8_t signature [64],
+ const uint8_t public_key[32],
+ const uint8_t *message, size_t message_size);
+
+// Conversion to X25519
+void crypto_eddsa_to_x25519(uint8_t x25519[32], const uint8_t eddsa[32]);
+
+// EdDSA building blocks
+void crypto_eddsa_trim_scalar(uint8_t out[32], const uint8_t in[32]);
+void crypto_eddsa_reduce(uint8_t reduced[32], const uint8_t expanded[64]);
+void crypto_eddsa_mul_add(uint8_t r[32],
+ const uint8_t a[32],
+ const uint8_t b[32],
+ const uint8_t c[32]);
+void crypto_eddsa_scalarbase(uint8_t point[32], const uint8_t scalar[32]);
+int crypto_eddsa_check_equation(const uint8_t signature[64],
+ const uint8_t public_key[32],
+ const uint8_t h_ram[32]);
+
+
+// Chacha20
+// --------
+
+// Specialised hash.
+// Used to hash X25519 shared secrets.
+void crypto_chacha20_h(uint8_t out[32],
+ const uint8_t key[32],
+ const uint8_t in [16]);
+
+// Unauthenticated stream cipher.
+// Don't forget to add authentication.
+uint64_t crypto_chacha20_djb(uint8_t *cipher_text,
+ const uint8_t *plain_text,
+ size_t text_size,
+ const uint8_t key[32],
+ const uint8_t nonce[8],
+ uint64_t ctr);
+uint32_t crypto_chacha20_ietf(uint8_t *cipher_text,
+ const uint8_t *plain_text,
+ size_t text_size,
+ const uint8_t key[32],
+ const uint8_t nonce[12],
+ uint32_t ctr);
+uint64_t crypto_chacha20_x(uint8_t *cipher_text,
+ const uint8_t *plain_text,
+ size_t text_size,
+ const uint8_t key[32],
+ const uint8_t nonce[24],
+ uint64_t ctr);
+
+
+// Poly 1305
+// ---------
+
+// This is a *one time* authenticator.
+// Disclosing the mac reveals the key.
+// See crypto_lock() on how to use it properly.
+
+// Direct interface
+void crypto_poly1305(uint8_t mac[16],
+ const uint8_t *message, size_t message_size,
+ const uint8_t key[32]);
+
+// Incremental interface
+typedef struct {
+ // Do not rely on the size or contents of this type,
+ // for they may change without notice.
+ uint8_t c[16]; // chunk of the message
+ size_t c_idx; // How many bytes are there in the chunk.
+ uint32_t r [4]; // constant multiplier (from the secret key)
+ uint32_t pad[4]; // random number added at the end (from the secret key)
+ uint32_t h [5]; // accumulated hash
+} crypto_poly1305_ctx;
+
+void crypto_poly1305_init (crypto_poly1305_ctx *ctx, const uint8_t key[32]);
+void crypto_poly1305_update(crypto_poly1305_ctx *ctx,
+ const uint8_t *message, size_t message_size);
+void crypto_poly1305_final (crypto_poly1305_ctx *ctx, uint8_t mac[16]);
+
+
+// Elligator 2
+// -----------
+
+// Elligator mappings proper
+void crypto_elligator_map(uint8_t curve [32], const uint8_t hidden[32]);
+int crypto_elligator_rev(uint8_t hidden[32], const uint8_t curve [32],
+ uint8_t tweak);
+
+// Easy to use key pair generation
+void crypto_elligator_key_pair(uint8_t hidden[32], uint8_t secret_key[32],
+ uint8_t seed[32]);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // MONOCYPHER_H
diff --git a/lib/Utils.Cryptography/monocypher/vendor/src/optional/monocypher-ed25519.c b/lib/Utils.Cryptography/monocypher/vendor/src/optional/monocypher-ed25519.c
new file mode 100644
index 0000000..5e4dcdf
--- /dev/null
+++ b/lib/Utils.Cryptography/monocypher/vendor/src/optional/monocypher-ed25519.c
@@ -0,0 +1,500 @@
+// Monocypher version __git__
+//
+// This file is dual-licensed. Choose whichever licence you want from
+// the two licences listed below.
+//
+// The first licence is a regular 2-clause BSD licence. The second licence
+// is the CC-0 from Creative Commons. It is intended to release Monocypher
+// to the public domain. The BSD licence serves as a fallback option.
+//
+// SPDX-License-Identifier: BSD-2-Clause OR CC0-1.0
+//
+// ------------------------------------------------------------------------
+//
+// Copyright (c) 2017-2019, Loup Vaillant
+// 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 COPYRIGHT HOLDERS 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 COPYRIGHT
+// HOLDER 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.
+//
+// ------------------------------------------------------------------------
+//
+// Written in 2017-2019 by Loup Vaillant
+//
+// To the extent possible under law, the author(s) have dedicated all copyright
+// and related 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
+// <https://creativecommons.org/publicdomain/zero/1.0/>
+
+#include "monocypher-ed25519.h"
+
+#ifdef MONOCYPHER_CPP_NAMESPACE
+namespace MONOCYPHER_CPP_NAMESPACE {
+#endif
+
+/////////////////
+/// Utilities ///
+/////////////////
+#define FOR(i, min, max) for (size_t i = min; i < max; i++)
+#define COPY(dst, src, size) FOR(_i_, 0, size) (dst)[_i_] = (src)[_i_]
+#define ZERO(buf, size) FOR(_i_, 0, size) (buf)[_i_] = 0
+#define WIPE_CTX(ctx) crypto_wipe(ctx , sizeof(*(ctx)))
+#define WIPE_BUFFER(buffer) crypto_wipe(buffer, sizeof(buffer))
+#define MIN(a, b) ((a) <= (b) ? (a) : (b))
+typedef uint8_t u8;
+typedef uint64_t u64;
+
+// Returns the smallest positive integer y such that
+// (x + y) % pow_2 == 0
+// Basically, it's how many bytes we need to add to "align" x.
+// Only works when pow_2 is a power of 2.
+// Note: we use ~x+1 instead of -x to avoid compiler warnings
+static size_t align(size_t x, size_t pow_2)
+{
+ return (~x + 1) & (pow_2 - 1);
+}
+
+static u64 load64_be(const u8 s[8])
+{
+ return((u64)s[0] << 56)
+ | ((u64)s[1] << 48)
+ | ((u64)s[2] << 40)
+ | ((u64)s[3] << 32)
+ | ((u64)s[4] << 24)
+ | ((u64)s[5] << 16)
+ | ((u64)s[6] << 8)
+ | (u64)s[7];
+}
+
+static void store64_be(u8 out[8], u64 in)
+{
+ out[0] = (in >> 56) & 0xff;
+ out[1] = (in >> 48) & 0xff;
+ out[2] = (in >> 40) & 0xff;
+ out[3] = (in >> 32) & 0xff;
+ out[4] = (in >> 24) & 0xff;
+ out[5] = (in >> 16) & 0xff;
+ out[6] = (in >> 8) & 0xff;
+ out[7] = in & 0xff;
+}
+
+static void load64_be_buf (u64 *dst, const u8 *src, size_t size) {
+ FOR(i, 0, size) { dst[i] = load64_be(src + i*8); }
+}
+
+///////////////
+/// SHA 512 ///
+///////////////
+static u64 rot(u64 x, int c ) { return (x >> c) | (x << (64 - c)); }
+static u64 ch (u64 x, u64 y, u64 z) { return (x & y) ^ (~x & z); }
+static u64 maj(u64 x, u64 y, u64 z) { return (x & y) ^ ( x & z) ^ (y & z); }
+static u64 big_sigma0(u64 x) { return rot(x, 28) ^ rot(x, 34) ^ rot(x, 39); }
+static u64 big_sigma1(u64 x) { return rot(x, 14) ^ rot(x, 18) ^ rot(x, 41); }
+static u64 lit_sigma0(u64 x) { return rot(x, 1) ^ rot(x, 8) ^ (x >> 7); }
+static u64 lit_sigma1(u64 x) { return rot(x, 19) ^ rot(x, 61) ^ (x >> 6); }
+
+static const u64 K[80] = {
+ 0x428a2f98d728ae22,0x7137449123ef65cd,0xb5c0fbcfec4d3b2f,0xe9b5dba58189dbbc,
+ 0x3956c25bf348b538,0x59f111f1b605d019,0x923f82a4af194f9b,0xab1c5ed5da6d8118,
+ 0xd807aa98a3030242,0x12835b0145706fbe,0x243185be4ee4b28c,0x550c7dc3d5ffb4e2,
+ 0x72be5d74f27b896f,0x80deb1fe3b1696b1,0x9bdc06a725c71235,0xc19bf174cf692694,
+ 0xe49b69c19ef14ad2,0xefbe4786384f25e3,0x0fc19dc68b8cd5b5,0x240ca1cc77ac9c65,
+ 0x2de92c6f592b0275,0x4a7484aa6ea6e483,0x5cb0a9dcbd41fbd4,0x76f988da831153b5,
+ 0x983e5152ee66dfab,0xa831c66d2db43210,0xb00327c898fb213f,0xbf597fc7beef0ee4,
+ 0xc6e00bf33da88fc2,0xd5a79147930aa725,0x06ca6351e003826f,0x142929670a0e6e70,
+ 0x27b70a8546d22ffc,0x2e1b21385c26c926,0x4d2c6dfc5ac42aed,0x53380d139d95b3df,
+ 0x650a73548baf63de,0x766a0abb3c77b2a8,0x81c2c92e47edaee6,0x92722c851482353b,
+ 0xa2bfe8a14cf10364,0xa81a664bbc423001,0xc24b8b70d0f89791,0xc76c51a30654be30,
+ 0xd192e819d6ef5218,0xd69906245565a910,0xf40e35855771202a,0x106aa07032bbd1b8,
+ 0x19a4c116b8d2d0c8,0x1e376c085141ab53,0x2748774cdf8eeb99,0x34b0bcb5e19b48a8,
+ 0x391c0cb3c5c95a63,0x4ed8aa4ae3418acb,0x5b9cca4f7763e373,0x682e6ff3d6b2b8a3,
+ 0x748f82ee5defb2fc,0x78a5636f43172f60,0x84c87814a1f0ab72,0x8cc702081a6439ec,
+ 0x90befffa23631e28,0xa4506cebde82bde9,0xbef9a3f7b2c67915,0xc67178f2e372532b,
+ 0xca273eceea26619c,0xd186b8c721c0c207,0xeada7dd6cde0eb1e,0xf57d4f7fee6ed178,
+ 0x06f067aa72176fba,0x0a637dc5a2c898a6,0x113f9804bef90dae,0x1b710b35131c471b,
+ 0x28db77f523047d84,0x32caab7b40c72493,0x3c9ebe0a15c9bebc,0x431d67c49c100d4c,
+ 0x4cc5d4becb3e42b6,0x597f299cfc657e2a,0x5fcb6fab3ad6faec,0x6c44198c4a475817
+};
+
+static void sha512_compress(crypto_sha512_ctx *ctx)
+{
+ u64 a = ctx->hash[0]; u64 b = ctx->hash[1];
+ u64 c = ctx->hash[2]; u64 d = ctx->hash[3];
+ u64 e = ctx->hash[4]; u64 f = ctx->hash[5];
+ u64 g = ctx->hash[6]; u64 h = ctx->hash[7];
+
+ FOR (j, 0, 16) {
+ u64 in = K[j] + ctx->input[j];
+ u64 t1 = big_sigma1(e) + ch (e, f, g) + h + in;
+ u64 t2 = big_sigma0(a) + maj(a, b, c);
+ h = g; g = f; f = e; e = d + t1;
+ d = c; c = b; b = a; a = t1 + t2;
+ }
+ size_t i16 = 0;
+ FOR(i, 1, 5) {
+ i16 += 16;
+ FOR (j, 0, 16) {
+ ctx->input[j] += lit_sigma1(ctx->input[(j- 2) & 15]);
+ ctx->input[j] += lit_sigma0(ctx->input[(j-15) & 15]);
+ ctx->input[j] += ctx->input[(j- 7) & 15];
+ u64 in = K[i16 + j] + ctx->input[j];
+ u64 t1 = big_sigma1(e) + ch (e, f, g) + h + in;
+ u64 t2 = big_sigma0(a) + maj(a, b, c);
+ h = g; g = f; f = e; e = d + t1;
+ d = c; c = b; b = a; a = t1 + t2;
+ }
+ }
+
+ ctx->hash[0] += a; ctx->hash[1] += b;
+ ctx->hash[2] += c; ctx->hash[3] += d;
+ ctx->hash[4] += e; ctx->hash[5] += f;
+ ctx->hash[6] += g; ctx->hash[7] += h;
+}
+
+// Write 1 input byte
+static void sha512_set_input(crypto_sha512_ctx *ctx, u8 input)
+{
+ size_t word = ctx->input_idx >> 3;
+ size_t byte = ctx->input_idx & 7;
+ ctx->input[word] |= (u64)input << (8 * (7 - byte));
+}
+
+// Increment a 128-bit "word".
+static void sha512_incr(u64 x[2], u64 y)
+{
+ x[1] += y;
+ if (x[1] < y) {
+ x[0]++;
+ }
+}
+
+void crypto_sha512_init(crypto_sha512_ctx *ctx)
+{
+ ctx->hash[0] = 0x6a09e667f3bcc908;
+ ctx->hash[1] = 0xbb67ae8584caa73b;
+ ctx->hash[2] = 0x3c6ef372fe94f82b;
+ ctx->hash[3] = 0xa54ff53a5f1d36f1;
+ ctx->hash[4] = 0x510e527fade682d1;
+ ctx->hash[5] = 0x9b05688c2b3e6c1f;
+ ctx->hash[6] = 0x1f83d9abfb41bd6b;
+ ctx->hash[7] = 0x5be0cd19137e2179;
+ ctx->input_size[0] = 0;
+ ctx->input_size[1] = 0;
+ ctx->input_idx = 0;
+ ZERO(ctx->input, 16);
+}
+
+void crypto_sha512_update(crypto_sha512_ctx *ctx,
+ const u8 *message, size_t message_size)
+{
+ // Avoid undefined NULL pointer increments with empty messages
+ if (message_size == 0) {
+ return;
+ }
+
+ // Align ourselves with word boundaries
+ if ((ctx->input_idx & 7) != 0) {
+ size_t nb_bytes = MIN(align(ctx->input_idx, 8), message_size);
+ FOR (i, 0, nb_bytes) {
+ sha512_set_input(ctx, message[i]);
+ ctx->input_idx++;
+ }
+ message += nb_bytes;
+ message_size -= nb_bytes;
+ }
+
+ // Align ourselves with block boundaries
+ if ((ctx->input_idx & 127) != 0) {
+ size_t nb_words = MIN(align(ctx->input_idx, 128), message_size) >> 3;
+ load64_be_buf(ctx->input + (ctx->input_idx >> 3), message, nb_words);
+ ctx->input_idx += nb_words << 3;
+ message += nb_words << 3;
+ message_size -= nb_words << 3;
+ }
+
+ // Compress block if needed
+ if (ctx->input_idx == 128) {
+ sha512_incr(ctx->input_size, 1024); // size is in bits
+ sha512_compress(ctx);
+ ctx->input_idx = 0;
+ ZERO(ctx->input, 16);
+ }
+
+ // Process the message block by block
+ FOR (i, 0, message_size >> 7) { // number of blocks
+ load64_be_buf(ctx->input, message, 16);
+ sha512_incr(ctx->input_size, 1024); // size is in bits
+ sha512_compress(ctx);
+ ctx->input_idx = 0;
+ ZERO(ctx->input, 16);
+ message += 128;
+ }
+ message_size &= 127;
+
+ if (message_size != 0) {
+ // Remaining words
+ size_t nb_words = message_size >> 3;
+ load64_be_buf(ctx->input, message, nb_words);
+ ctx->input_idx += nb_words << 3;
+ message += nb_words << 3;
+ message_size -= nb_words << 3;
+
+ // Remaining bytes
+ FOR (i, 0, message_size) {
+ sha512_set_input(ctx, message[i]);
+ ctx->input_idx++;
+ }
+ }
+}
+
+void crypto_sha512_final(crypto_sha512_ctx *ctx, u8 hash[64])
+{
+ // Add padding bit
+ if (ctx->input_idx == 0) {
+ ZERO(ctx->input, 16);
+ }
+ sha512_set_input(ctx, 128);
+
+ // Update size
+ sha512_incr(ctx->input_size, ctx->input_idx * 8);
+
+ // Compress penultimate block (if any)
+ if (ctx->input_idx > 111) {
+ sha512_compress(ctx);
+ ZERO(ctx->input, 14);
+ }
+ // Compress last block
+ ctx->input[14] = ctx->input_size[0];
+ ctx->input[15] = ctx->input_size[1];
+ sha512_compress(ctx);
+
+ // Copy hash to output (big endian)
+ FOR (i, 0, 8) {
+ store64_be(hash + i*8, ctx->hash[i]);
+ }
+
+ WIPE_CTX(ctx);
+}
+
+void crypto_sha512(u8 hash[64], const u8 *message, size_t message_size)
+{
+ crypto_sha512_ctx ctx;
+ crypto_sha512_init (&ctx);
+ crypto_sha512_update(&ctx, message, message_size);
+ crypto_sha512_final (&ctx, hash);
+}
+
+////////////////////
+/// HMAC SHA 512 ///
+////////////////////
+void crypto_sha512_hmac_init(crypto_sha512_hmac_ctx *ctx,
+ const u8 *key, size_t key_size)
+{
+ // hash key if it is too long
+ if (key_size > 128) {
+ crypto_sha512(ctx->key, key, key_size);
+ key = ctx->key;
+ key_size = 64;
+ }
+ // Compute inner key: padded key XOR 0x36
+ FOR (i, 0, key_size) { ctx->key[i] = key[i] ^ 0x36; }
+ FOR (i, key_size, 128) { ctx->key[i] = 0x36; }
+ // Start computing inner hash
+ crypto_sha512_init (&ctx->ctx);
+ crypto_sha512_update(&ctx->ctx, ctx->key, 128);
+}
+
+void crypto_sha512_hmac_update(crypto_sha512_hmac_ctx *ctx,
+ const u8 *message, size_t message_size)
+{
+ crypto_sha512_update(&ctx->ctx, message, message_size);
+}
+
+void crypto_sha512_hmac_final(crypto_sha512_hmac_ctx *ctx, u8 hmac[64])
+{
+ // Finish computing inner hash
+ crypto_sha512_final(&ctx->ctx, hmac);
+ // Compute outer key: padded key XOR 0x5c
+ FOR (i, 0, 128) {
+ ctx->key[i] ^= 0x36 ^ 0x5c;
+ }
+ // Compute outer hash
+ crypto_sha512_init (&ctx->ctx);
+ crypto_sha512_update(&ctx->ctx, ctx->key , 128);
+ crypto_sha512_update(&ctx->ctx, hmac, 64);
+ crypto_sha512_final (&ctx->ctx, hmac); // outer hash
+ WIPE_CTX(ctx);
+}
+
+void crypto_sha512_hmac(u8 hmac[64], const u8 *key, size_t key_size,
+ const u8 *message, size_t message_size)
+{
+ crypto_sha512_hmac_ctx ctx;
+ crypto_sha512_hmac_init (&ctx, key, key_size);
+ crypto_sha512_hmac_update(&ctx, message, message_size);
+ crypto_sha512_hmac_final (&ctx, hmac);
+}
+
+////////////////////
+/// HKDF SHA 512 ///
+////////////////////
+void crypto_sha512_hkdf_expand(u8 *okm, size_t okm_size,
+ const u8 *prk, size_t prk_size,
+ const u8 *info, size_t info_size)
+{
+ int not_first = 0;
+ u8 ctr = 1;
+ u8 blk[64];
+
+ while (okm_size > 0) {
+ size_t out_size = MIN(okm_size, sizeof(blk));
+
+ crypto_sha512_hmac_ctx ctx;
+ crypto_sha512_hmac_init(&ctx, prk , prk_size);
+ if (not_first) {
+ // For some reason HKDF uses some kind of CBC mode.
+ // For some reason CTR mode alone wasn't enough.
+ // Like what, they didn't trust HMAC in 2010? Really??
+ crypto_sha512_hmac_update(&ctx, blk , sizeof(blk));
+ }
+ crypto_sha512_hmac_update(&ctx, info, info_size);
+ crypto_sha512_hmac_update(&ctx, &ctr, 1);
+ crypto_sha512_hmac_final(&ctx, blk);
+
+ COPY(okm, blk, out_size);
+
+ not_first = 1;
+ okm += out_size;
+ okm_size -= out_size;
+ ctr++;
+ }
+}
+
+void crypto_sha512_hkdf(u8 *okm , size_t okm_size,
+ const u8 *ikm , size_t ikm_size,
+ const u8 *salt, size_t salt_size,
+ const u8 *info, size_t info_size)
+{
+ // Extract
+ u8 prk[64];
+ crypto_sha512_hmac(prk, salt, salt_size, ikm, ikm_size);
+
+ // Expand
+ crypto_sha512_hkdf_expand(okm, okm_size, prk, sizeof(prk), info, info_size);
+}
+
+///////////////
+/// Ed25519 ///
+///////////////
+void crypto_ed25519_key_pair(u8 secret_key[64], u8 public_key[32], u8 seed[32])
+{
+ u8 a[64];
+ COPY(a, seed, 32); // a[ 0..31] = seed
+ crypto_wipe(seed, 32);
+ COPY(secret_key, a, 32); // secret key = seed
+ crypto_sha512(a, a, 32); // a[ 0..31] = scalar
+ crypto_eddsa_trim_scalar(a, a); // a[ 0..31] = trimmed scalar
+ crypto_eddsa_scalarbase(public_key, a); // public key = [trimmed scalar]B
+ COPY(secret_key + 32, public_key, 32); // secret key includes public half
+ WIPE_BUFFER(a);
+}
+
+static void hash_reduce(u8 h[32],
+ const u8 *a, size_t a_size,
+ const u8 *b, size_t b_size,
+ const u8 *c, size_t c_size,
+ const u8 *d, size_t d_size)
+{
+ u8 hash[64];
+ crypto_sha512_ctx ctx;
+ crypto_sha512_init (&ctx);
+ crypto_sha512_update(&ctx, a, a_size);
+ crypto_sha512_update(&ctx, b, b_size);
+ crypto_sha512_update(&ctx, c, c_size);
+ crypto_sha512_update(&ctx, d, d_size);
+ crypto_sha512_final (&ctx, hash);
+ crypto_eddsa_reduce(h, hash);
+}
+
+static void ed25519_dom_sign(u8 signature [64], const u8 secret_key[32],
+ const u8 *dom, size_t dom_size,
+ const u8 *message, size_t message_size)
+{
+ u8 a[64]; // secret scalar and prefix
+ u8 r[32]; // secret deterministic "random" nonce
+ u8 h[32]; // publically verifiable hash of the message (not wiped)
+ u8 R[32]; // first half of the signature (allows overlapping inputs)
+ const u8 *pk = secret_key + 32;
+
+ crypto_sha512(a, secret_key, 32);
+ crypto_eddsa_trim_scalar(a, a);
+ hash_reduce(r, dom, dom_size, a + 32, 32, message, message_size, 0, 0);
+ crypto_eddsa_scalarbase(R, r);
+ hash_reduce(h, dom, dom_size, R, 32, pk, 32, message, message_size);
+ COPY(signature, R, 32);
+ crypto_eddsa_mul_add(signature + 32, h, a, r);
+
+ WIPE_BUFFER(a);
+ WIPE_BUFFER(r);
+}
+
+void crypto_ed25519_sign(u8 signature [64], const u8 secret_key[64],
+ const u8 *message, size_t message_size)
+{
+ ed25519_dom_sign(signature, secret_key, 0, 0, message, message_size);
+}
+
+int crypto_ed25519_check(const u8 signature[64], const u8 public_key[32],
+ const u8 *msg, size_t msg_size)
+{
+ u8 h_ram[32];
+ hash_reduce(h_ram, signature, 32, public_key, 32, msg, msg_size, 0, 0);
+ return crypto_eddsa_check_equation(signature, public_key, h_ram);
+}
+
+static const u8 domain[34] = "SigEd25519 no Ed25519 collisions\1";
+
+void crypto_ed25519_ph_sign(uint8_t signature[64], const uint8_t secret_key[64],
+ const uint8_t message_hash[64])
+{
+ ed25519_dom_sign(signature, secret_key, domain, sizeof(domain),
+ message_hash, 64);
+}
+
+int crypto_ed25519_ph_check(const uint8_t sig[64], const uint8_t pk[32],
+ const uint8_t msg_hash[64])
+{
+ u8 h_ram[32];
+ hash_reduce(h_ram, domain, sizeof(domain), sig, 32, pk, 32, msg_hash, 64);
+ return crypto_eddsa_check_equation(sig, pk, h_ram);
+}
+
+
+#ifdef MONOCYPHER_CPP_NAMESPACE
+}
+#endif
diff --git a/lib/Utils.Cryptography/monocypher/vendor/src/optional/monocypher-ed25519.h b/lib/Utils.Cryptography/monocypher/vendor/src/optional/monocypher-ed25519.h
new file mode 100644
index 0000000..d7aa004
--- /dev/null
+++ b/lib/Utils.Cryptography/monocypher/vendor/src/optional/monocypher-ed25519.h
@@ -0,0 +1,140 @@
+// Monocypher version __git__
+//
+// This file is dual-licensed. Choose whichever licence you want from
+// the two licences listed below.
+//
+// The first licence is a regular 2-clause BSD licence. The second licence
+// is the CC-0 from Creative Commons. It is intended to release Monocypher
+// to the public domain. The BSD licence serves as a fallback option.
+//
+// SPDX-License-Identifier: BSD-2-Clause OR CC0-1.0
+//
+// ------------------------------------------------------------------------
+//
+// Copyright (c) 2017-2019, Loup Vaillant
+// 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 COPYRIGHT HOLDERS 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 COPYRIGHT
+// HOLDER 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.
+//
+// ------------------------------------------------------------------------
+//
+// Written in 2017-2019 by Loup Vaillant
+//
+// To the extent possible under law, the author(s) have dedicated all copyright
+// and related 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
+// <https://creativecommons.org/publicdomain/zero/1.0/>
+
+#ifndef ED25519_H
+#define ED25519_H
+
+#include "monocypher.h"
+
+#ifdef MONOCYPHER_CPP_NAMESPACE
+namespace MONOCYPHER_CPP_NAMESPACE {
+#elif defined(__cplusplus)
+extern "C" {
+#endif
+
+////////////////////////
+/// Type definitions ///
+////////////////////////
+
+// Do not rely on the size or content on any of those types,
+// they may change without notice.
+typedef struct {
+ uint64_t hash[8];
+ uint64_t input[16];
+ uint64_t input_size[2];
+ size_t input_idx;
+} crypto_sha512_ctx;
+
+typedef struct {
+ uint8_t key[128];
+ crypto_sha512_ctx ctx;
+} crypto_sha512_hmac_ctx;
+
+
+// SHA 512
+// -------
+void crypto_sha512_init (crypto_sha512_ctx *ctx);
+void crypto_sha512_update(crypto_sha512_ctx *ctx,
+ const uint8_t *message, size_t message_size);
+void crypto_sha512_final (crypto_sha512_ctx *ctx, uint8_t hash[64]);
+void crypto_sha512(uint8_t hash[64],
+ const uint8_t *message, size_t message_size);
+
+// SHA 512 HMAC
+// ------------
+void crypto_sha512_hmac_init(crypto_sha512_hmac_ctx *ctx,
+ const uint8_t *key, size_t key_size);
+void crypto_sha512_hmac_update(crypto_sha512_hmac_ctx *ctx,
+ const uint8_t *message, size_t message_size);
+void crypto_sha512_hmac_final(crypto_sha512_hmac_ctx *ctx, uint8_t hmac[64]);
+void crypto_sha512_hmac(uint8_t hmac[64],
+ const uint8_t *key , size_t key_size,
+ const uint8_t *message, size_t message_size);
+
+// SHA 512 HKDF
+// ------------
+void crypto_sha512_hkdf_expand(uint8_t *okm, size_t okm_size,
+ const uint8_t *prk, size_t prk_size,
+ const uint8_t *info, size_t info_size);
+void crypto_sha512_hkdf(uint8_t *okm , size_t okm_size,
+ const uint8_t *ikm , size_t ikm_size,
+ const uint8_t *salt, size_t salt_size,
+ const uint8_t *info, size_t info_size);
+
+// Ed25519
+// -------
+// Signatures (EdDSA with curve25519 + SHA-512)
+// --------------------------------------------
+void crypto_ed25519_key_pair(uint8_t secret_key[64],
+ uint8_t public_key[32],
+ uint8_t seed[32]);
+void crypto_ed25519_sign(uint8_t signature [64],
+ const uint8_t secret_key[64],
+ const uint8_t *message, size_t message_size);
+int crypto_ed25519_check(const uint8_t signature [64],
+ const uint8_t public_key[32],
+ const uint8_t *message, size_t message_size);
+
+// Pre-hash variants
+void crypto_ed25519_ph_sign(uint8_t signature [64],
+ const uint8_t secret_key [64],
+ const uint8_t message_hash[64]);
+int crypto_ed25519_ph_check(const uint8_t signature [64],
+ const uint8_t public_key [32],
+ const uint8_t message_hash[64]);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // ED25519_H
diff --git a/lib/Utils.Cryptography/monocypher/vendor/tests/coverage.sh b/lib/Utils.Cryptography/monocypher/vendor/tests/coverage.sh
new file mode 100644
index 0000000..dd872a9
--- /dev/null
+++ b/lib/Utils.Cryptography/monocypher/vendor/tests/coverage.sh
@@ -0,0 +1,59 @@
+#! /bin/sh
+
+# This file is dual-licensed. Choose whichever licence you want from
+# the two licences listed below.
+#
+# The first licence is a regular 2-clause BSD licence. The second licence
+# is the CC-0 from Creative Commons. It is intended to release Monocypher
+# to the public domain. The BSD licence serves as a fallback option.
+#
+# SPDX-License-Identifier: BSD-2-Clause OR CC0-1.0
+#
+# ------------------------------------------------------------------------
+#
+# Copyright (c) 2017-2019, Loup Vaillant
+# 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 COPYRIGHT HOLDERS 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 COPYRIGHT
+# HOLDER 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.
+#
+# ------------------------------------------------------------------------
+#
+# Written in 2017-2019 by Loup Vaillant
+#
+# To the extent possible under law, the author(s) have dedicated all copyright
+# and related 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
+# <https://creativecommons.org/publicdomain/zero/1.0/>
+
+set -e
+
+make clean
+make test CC="clang -std=c99" CFLAGS="-fprofile-instr-generate -fcoverage-mapping"
+llvm-profdata merge default.profraw -o all.profdata
+llvm-cov show -instr-profile=all.profdata "./test.out"
diff --git a/lib/Utils.Cryptography/monocypher/vendor/tests/ctgrind.c b/lib/Utils.Cryptography/monocypher/vendor/tests/ctgrind.c
new file mode 100644
index 0000000..b928683
--- /dev/null
+++ b/lib/Utils.Cryptography/monocypher/vendor/tests/ctgrind.c
@@ -0,0 +1,330 @@
+// This file is dual-licensed. Choose whichever licence you want from
+// the two licences listed below.
+//
+// The first licence is a regular 2-clause BSD licence. The second licence
+// is the CC-0 from Creative Commons. It is intended to release Monocypher
+// to the public domain. The BSD licence serves as a fallback option.
+//
+// SPDX-License-Identifier: BSD-2-Clause OR CC0-1.0
+//
+// ------------------------------------------------------------------------
+//
+// Copyright (c) 2020, 2023 Loup Vaillant
+// 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 COPYRIGHT HOLDERS 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 COPYRIGHT
+// HOLDER 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.
+//
+// ------------------------------------------------------------------------
+//
+// Written in 2020 and 2023 by Loup Vaillant
+//
+// To the extent possible under law, the author(s) have dedicated all copyright
+// and related 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
+// <https://creativecommons.org/publicdomain/zero/1.0/>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include "monocypher.h"
+#include "monocypher-ed25519.h"
+#include "utils.h"
+
+static void verify16()
+{
+ u8 a[16];
+ u8 b[16];
+ crypto_verify16(a, b);
+}
+
+static void verify32()
+{
+ u8 a[32];
+ u8 b[32];
+ crypto_verify32(a, b);
+}
+
+static void verify64()
+{
+ u8 a[64];
+ u8 b[64];
+ crypto_verify64(a, b);
+}
+
+static void wipe()
+{
+ FOR (i, 0, 128) {
+ u8 secret[128];
+ crypto_wipe(secret, i);
+ }
+}
+
+static void lock_aead()
+{
+ FOR(i, 0, 128) {
+ u8 mac [ 16];
+ u8 cipher_text[128];
+ u8 key [ 32];
+ u8 nonce [ 24];
+ u8 ad [128];
+ u8 plain_text [128];
+ crypto_aead_lock(cipher_text, mac, key, nonce, ad, i, plain_text, i);
+ }
+}
+
+static void unlock_aead()
+{
+ FOR(i, 0, 128) {
+ u8 plain_text [128];
+ u8 key [ 32];
+ u8 nonce [ 24];
+ u8 mac [ 16];
+ u8 ad [128];
+ u8 cipher_text[128];
+ crypto_aead_unlock(plain_text, mac, key, nonce, ad, i, cipher_text, i);
+ }
+}
+
+static void blake2b()
+{
+ FOR (i, 0, 256) {
+ u8 hash [ 64];
+ u8 key [ 64];
+ u8 message[256];
+ crypto_blake2b_keyed(hash, 64, key, 0, message, i);
+ }
+ FOR (i, 0, 64) {
+ u8 hash [ 64];
+ u8 key [ 64];
+ u8 message[256];
+ crypto_blake2b_keyed(hash, 64, key, i, message, 128);
+ }
+ FOR (i, 0, 64) {
+ u8 hash [ 64];
+ u8 key [ 64];
+ u8 message[256];
+ crypto_blake2b_keyed(hash, i, key, 0, message, 0);
+ }
+}
+
+static void argon2()
+{
+ void *work_area = alloc(1024 * 600 * 4);
+ u8 hash[ 32];
+ u8 pass[ 16];
+ u8 salt[ 16];
+ u8 key [ 32];
+ u8 ad [128];
+
+ crypto_argon2_config config;
+ config.algorithm = CRYPTO_ARGON2_ID;
+ config.nb_blocks = 600 * 4;
+ config.nb_passes = 3;
+ config.nb_lanes = 4;
+
+ crypto_argon2_inputs inputs;
+ inputs.pass = pass;
+ inputs.salt = salt;
+ inputs.pass_size = sizeof(pass);
+ inputs.salt_size = sizeof(salt);
+
+ crypto_argon2_extras extras;
+ extras.key = key;
+ extras.ad = ad;
+ extras.key_size = sizeof(key);
+ extras.ad_size = sizeof(ad);
+
+ crypto_argon2(hash, 32, work_area, config, inputs, extras);
+ free(work_area);
+}
+
+static void x25519()
+{
+ u8 shared_key [32];
+ u8 your_secret_key [32];
+ u8 their_public_key[32];
+ crypto_x25519(shared_key, your_secret_key, their_public_key);
+}
+
+static void x25519_to_eddsa()
+{
+ u8 x25519[32];
+ u8 eddsa[32];
+ crypto_x25519_to_eddsa(eddsa, x25519);
+}
+
+static void eddsa_key_pair()
+{
+ u8 seed[32];
+ u8 secret_key[64];
+ u8 public_key[32];
+ crypto_eddsa_key_pair(secret_key, public_key, seed);
+}
+
+static void eddsa_sign()
+{
+ u8 signature [64];
+ u8 secret_key[64];
+ u8 message [64];
+ crypto_eddsa_sign(signature, secret_key, message, 64);
+}
+
+static void eddsa_to_x25519()
+{
+ u8 x25519[32];
+ u8 eddsa [32];
+ crypto_eddsa_to_x25519(x25519, eddsa);
+}
+
+static void elligator_map()
+{
+ u8 curve [32];
+ u8 hidden[32];
+ crypto_elligator_map(curve, hidden);
+}
+
+static void elligator_rev()
+{
+ u8 hidden[32];
+ u8 curve [32];
+ u8 tweak; // The compiler notices this one is used uninitialised
+ crypto_elligator_rev(hidden, curve, tweak);
+}
+
+static void elligator_key_pair()
+{
+ u8 hidden [32];
+ u8 secret_key[32];
+ u8 seed [32];
+ crypto_elligator_key_pair(hidden, secret_key,seed);
+}
+
+static void chacha20_h()
+{
+ u8 out[32], key[32], in[16];
+ crypto_chacha20_h(out, key, in);
+}
+
+static void chacha20_x()
+{
+ FOR (i, 0, 128) {
+ u8 cipher_text[128];
+ u8 plain_text [128];
+ u8 key [ 32];
+ u8 nonce [ 24];
+ crypto_chacha20_x(cipher_text, plain_text, i, key, nonce, 0);
+ }
+}
+
+static void chacha20_djb()
+{
+ FOR (i, 0, 128) {
+ u8 cipher_text[128];
+ u8 plain_text [128];
+ u8 key [ 32];
+ u8 nonce [ 8];
+ crypto_chacha20_djb(cipher_text, plain_text, i, key, nonce, 0);
+ }
+}
+
+static void chacha20_ietf()
+{
+ FOR (i, 0, 128) {
+ u8 cipher_text[128];
+ u8 plain_text [128];
+ u8 key [ 32];
+ u8 nonce [ 12];
+ crypto_chacha20_ietf(cipher_text, plain_text, i, key, nonce, 0);
+ }
+}
+
+static void poly1305()
+{
+ FOR (i, 0, 32) {
+ u8 mac [16];
+ u8 message [32];
+ u8 key [32];
+ crypto_poly1305(mac, message, i, key);
+ }
+}
+
+static void x25519_dirty_small()
+{
+ u8 pk[32];
+ u8 sk[32];
+ crypto_x25519_dirty_small(pk, sk);
+}
+static void x25519_dirty_fast()
+{
+ u8 pk[32];
+ u8 sk[32];
+ crypto_x25519_dirty_fast(pk, sk);
+}
+
+static void x25519_inverse()
+{
+ u8 blind_salt [32];
+ u8 private_key[32];
+ u8 curve_point[32];
+ crypto_x25519_inverse(blind_salt, private_key, curve_point);
+}
+
+
+#define RUN(f, s) printf("%s: crypto_"#f"\n", s); f()
+
+int main()
+{
+ RUN(verify16 , "constant time");
+ RUN(verify32 , "constant time");
+ RUN(verify64 , "constant time");
+ RUN(wipe , "constant time");
+ RUN(lock_aead , "constant time");
+ RUN(unlock_aead , "1 conditional");
+ RUN(blake2b , "constant time");
+ RUN(argon2 , "constant time"); // "use" of uninitialised value
+ RUN(x25519 , "constant time");
+ RUN(x25519_to_eddsa , "constant time");
+ RUN(eddsa_key_pair , "constant time");
+ RUN(eddsa_sign , "constant time");
+ printf( "skipped : crypto_check.\n");
+ RUN(eddsa_to_x25519 , "constant time");
+ RUN(elligator_map , "constant time");
+ RUN(elligator_rev , "1 conditional");
+ RUN(elligator_key_pair, "2 conditionals");
+ RUN(chacha20_h , "constant time");
+ RUN(chacha20_x , "constant time");
+ RUN(chacha20_djb , "constant time");
+ RUN(chacha20_ietf , "constant time");
+ RUN(poly1305 , "constant time");
+ RUN(x25519_dirty_small, "constant time");
+ RUN(x25519_dirty_fast , "constant time");
+ RUN(x25519_inverse , "constant time");
+
+ return 0;
+}
diff --git a/lib/Utils.Cryptography/monocypher/vendor/tests/externals/c25519/.gitignore b/lib/Utils.Cryptography/monocypher/vendor/tests/externals/c25519/.gitignore
new file mode 100644
index 0000000..d74e014
--- /dev/null
+++ b/lib/Utils.Cryptography/monocypher/vendor/tests/externals/c25519/.gitignore
@@ -0,0 +1,5 @@
+.*.swp
+*~
+*.o
+*.su
+*.test
diff --git a/lib/Utils.Cryptography/monocypher/vendor/tests/externals/c25519/AUTHORS.md b/lib/Utils.Cryptography/monocypher/vendor/tests/externals/c25519/AUTHORS.md
new file mode 100644
index 0000000..d7c7bfb
--- /dev/null
+++ b/lib/Utils.Cryptography/monocypher/vendor/tests/externals/c25519/AUTHORS.md
@@ -0,0 +1,5 @@
+The code of C25519 has been written by Daniel Beers <dlbeer@gmail.com>
+and dedicated to the public domain; refer to the file headers.
+
+C25519 has been obtained via <https://www.dlbeer.co.nz/oss/c25519.html>.
+
diff --git a/lib/Utils.Cryptography/monocypher/vendor/tests/externals/c25519/c25519.c b/lib/Utils.Cryptography/monocypher/vendor/tests/externals/c25519/c25519.c
new file mode 100644
index 0000000..a9c9f08
--- /dev/null
+++ b/lib/Utils.Cryptography/monocypher/vendor/tests/externals/c25519/c25519.c
@@ -0,0 +1,124 @@
+/* Curve25519 (Montgomery form)
+ * Daniel Beer <dlbeer@gmail.com>, 18 Apr 2014
+ *
+ * This file is in the public domain.
+ */
+
+#include "c25519.h"
+
+const uint8_t c25519_base_x[F25519_SIZE] = {9};
+
+/* Double an X-coordinate */
+static void xc_double(uint8_t *x3, uint8_t *z3,
+ const uint8_t *x1, const uint8_t *z1)
+{
+ /* Explicit formulas database: dbl-1987-m
+ *
+ * source 1987 Montgomery "Speeding the Pollard and elliptic
+ * curve methods of factorization", page 261, fourth display
+ * compute X3 = (X1^2-Z1^2)^2
+ * compute Z3 = 4 X1 Z1 (X1^2 + a X1 Z1 + Z1^2)
+ */
+ uint8_t x1sq[F25519_SIZE];
+ uint8_t z1sq[F25519_SIZE];
+ uint8_t x1z1[F25519_SIZE];
+ uint8_t a[F25519_SIZE];
+
+ f25519_mul__distinct(x1sq, x1, x1);
+ f25519_mul__distinct(z1sq, z1, z1);
+ f25519_mul__distinct(x1z1, x1, z1);
+
+ f25519_sub(a, x1sq, z1sq);
+ f25519_mul__distinct(x3, a, a);
+
+ f25519_mul_c(a, x1z1, 486662);
+ f25519_add(a, x1sq, a);
+ f25519_add(a, z1sq, a);
+ f25519_mul__distinct(x1sq, x1z1, a);
+ f25519_mul_c(z3, x1sq, 4);
+}
+
+/* Differential addition */
+static void xc_diffadd(uint8_t *x5, uint8_t *z5,
+ const uint8_t *x1, const uint8_t *z1,
+ const uint8_t *x2, const uint8_t *z2,
+ const uint8_t *x3, const uint8_t *z3)
+{
+ /* Explicit formulas database: dbl-1987-m3
+ *
+ * source 1987 Montgomery "Speeding the Pollard and elliptic curve
+ * methods of factorization", page 261, fifth display, plus
+ * common-subexpression elimination
+ * compute A = X2+Z2
+ * compute B = X2-Z2
+ * compute C = X3+Z3
+ * compute D = X3-Z3
+ * compute DA = D A
+ * compute CB = C B
+ * compute X5 = Z1(DA+CB)^2
+ * compute Z5 = X1(DA-CB)^2
+ */
+ uint8_t da[F25519_SIZE];
+ uint8_t cb[F25519_SIZE];
+ uint8_t a[F25519_SIZE];
+ uint8_t b[F25519_SIZE];
+
+ f25519_add(a, x2, z2);
+ f25519_sub(b, x3, z3); /* D */
+ f25519_mul__distinct(da, a, b);
+
+ f25519_sub(b, x2, z2);
+ f25519_add(a, x3, z3); /* C */
+ f25519_mul__distinct(cb, a, b);
+
+ f25519_add(a, da, cb);
+ f25519_mul__distinct(b, a, a);
+ f25519_mul__distinct(x5, z1, b);
+
+ f25519_sub(a, da, cb);
+ f25519_mul__distinct(b, a, a);
+ f25519_mul__distinct(z5, x1, b);
+}
+
+void c25519_smult(uint8_t *result, const uint8_t *q, const uint8_t *e)
+{
+ /* Current point: P_m */
+ uint8_t xm[F25519_SIZE];
+ uint8_t zm[F25519_SIZE] = {1};
+
+ /* Predecessor: P_(m-1) */
+ uint8_t xm1[F25519_SIZE] = {1};
+ uint8_t zm1[F25519_SIZE] = {0};
+
+ int i;
+
+ /* Note: bit 254 is assumed to be 1 */
+ f25519_copy(xm, q);
+
+ for (i = 253; i >= 0; i--) {
+ const int bit = (e[i >> 3] >> (i & 7)) & 1;
+ uint8_t xms[F25519_SIZE];
+ uint8_t zms[F25519_SIZE];
+
+ /* From P_m and P_(m-1), compute P_(2m) and P_(2m-1) */
+ xc_diffadd(xm1, zm1, q, f25519_one, xm, zm, xm1, zm1);
+ xc_double(xm, zm, xm, zm);
+
+ /* Compute P_(2m+1) */
+ xc_diffadd(xms, zms, xm1, zm1, xm, zm, q, f25519_one);
+
+ /* Select:
+ * bit = 1 --> (P_(2m+1), P_(2m))
+ * bit = 0 --> (P_(2m), P_(2m-1))
+ */
+ f25519_select(xm1, xm1, xm, bit);
+ f25519_select(zm1, zm1, zm, bit);
+ f25519_select(xm, xm, xms, bit);
+ f25519_select(zm, zm, zms, bit);
+ }
+
+ /* Freeze out of projective coordinates */
+ f25519_inv__distinct(zm1, zm);
+ f25519_mul__distinct(result, zm1, xm);
+ f25519_normalize(result);
+}
diff --git a/lib/Utils.Cryptography/monocypher/vendor/tests/externals/c25519/c25519.h b/lib/Utils.Cryptography/monocypher/vendor/tests/externals/c25519/c25519.h
new file mode 100644
index 0000000..4596438
--- /dev/null
+++ b/lib/Utils.Cryptography/monocypher/vendor/tests/externals/c25519/c25519.h
@@ -0,0 +1,48 @@
+/* Curve25519 (Montgomery form)
+ * Daniel Beer <dlbeer@gmail.com>, 18 Apr 2014
+ *
+ * This file is in the public domain.
+ */
+
+#ifndef C25519_H_
+#define C25519_H_
+
+#include <stdint.h>
+#include "f25519.h"
+
+/* Curve25519 has the equation over F(p = 2^255-19):
+ *
+ * y^2 = x^3 + 486662x^2 + x
+ *
+ * 486662 = 4A+2, where A = 121665. This is a Montgomery curve.
+ *
+ * For more information, see:
+ *
+ * Bernstein, D.J. (2006) "Curve25519: New Diffie-Hellman speed
+ * records". Document ID: 4230efdfa673480fc079449d90f322c0.
+ */
+
+/* This is the site of a Curve25519 exponent (private key) */
+#define C25519_EXPONENT_SIZE 32
+
+/* Having generated 32 random bytes, you should call this function to
+ * finalize the generated key.
+ */
+static inline void c25519_prepare(uint8_t *key)
+{
+ key[0] &= 0xf8;
+ key[31] &= 0x7f;
+ key[31] |= 0x40;
+}
+
+/* X-coordinate of the base point */
+extern const uint8_t c25519_base_x[F25519_SIZE];
+
+/* X-coordinate scalar multiply: given the X-coordinate of q, return the
+ * X-coordinate of e*q.
+ *
+ * result and q are field elements. e is an exponent.
+ */
+void c25519_smult(uint8_t *result, const uint8_t *q, const uint8_t *e);
+
+#endif
diff --git a/lib/Utils.Cryptography/monocypher/vendor/tests/externals/c25519/ed25519.c b/lib/Utils.Cryptography/monocypher/vendor/tests/externals/c25519/ed25519.c
new file mode 100644
index 0000000..51ac462
--- /dev/null
+++ b/lib/Utils.Cryptography/monocypher/vendor/tests/externals/c25519/ed25519.c
@@ -0,0 +1,320 @@
+/* Edwards curve operations
+ * Daniel Beer <dlbeer@gmail.com>, 9 Jan 2014
+ *
+ * This file is in the public domain.
+ */
+
+#include "ed25519.h"
+
+/* Base point is (numbers wrapped):
+ *
+ * x = 151122213495354007725011514095885315114
+ * 54012693041857206046113283949847762202
+ * y = 463168356949264781694283940034751631413
+ * 07993866256225615783033603165251855960
+ *
+ * y is derived by transforming the original Montgomery base (u=9). x
+ * is the corresponding positive coordinate for the new curve equation.
+ * t is x*y.
+ */
+const struct ed25519_pt ed25519_base = {
+ .x = {
+ 0x1a, 0xd5, 0x25, 0x8f, 0x60, 0x2d, 0x56, 0xc9,
+ 0xb2, 0xa7, 0x25, 0x95, 0x60, 0xc7, 0x2c, 0x69,
+ 0x5c, 0xdc, 0xd6, 0xfd, 0x31, 0xe2, 0xa4, 0xc0,
+ 0xfe, 0x53, 0x6e, 0xcd, 0xd3, 0x36, 0x69, 0x21
+ },
+ .y = {
+ 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
+ },
+ .t = {
+ 0xa3, 0xdd, 0xb7, 0xa5, 0xb3, 0x8a, 0xde, 0x6d,
+ 0xf5, 0x52, 0x51, 0x77, 0x80, 0x9f, 0xf0, 0x20,
+ 0x7d, 0xe3, 0xab, 0x64, 0x8e, 0x4e, 0xea, 0x66,
+ 0x65, 0x76, 0x8b, 0xd7, 0x0f, 0x5f, 0x87, 0x67
+ },
+ .z = {1, 0}
+};
+
+const struct ed25519_pt ed25519_neutral = {
+ .x = {0},
+ .y = {1, 0},
+ .t = {0},
+ .z = {1, 0}
+};
+
+/* Conversion to and from projective coordinates */
+void ed25519_project(struct ed25519_pt *p,
+ const uint8_t *x, const uint8_t *y)
+{
+ f25519_copy(p->x, x);
+ f25519_copy(p->y, y);
+ f25519_load(p->z, 1);
+ f25519_mul__distinct(p->t, x, y);
+}
+
+void ed25519_unproject(uint8_t *x, uint8_t *y,
+ const struct ed25519_pt *p)
+{
+ uint8_t z1[F25519_SIZE];
+
+ f25519_inv__distinct(z1, p->z);
+ f25519_mul__distinct(x, p->x, z1);
+ f25519_mul__distinct(y, p->y, z1);
+
+ f25519_normalize(x);
+ f25519_normalize(y);
+}
+
+/* Compress/uncompress points. We compress points by storing the x
+ * coordinate and the parity of the y coordinate.
+ *
+ * Rearranging the curve equation, we obtain explicit formulae for the
+ * coordinates:
+ *
+ * x = sqrt((y^2-1) / (1+dy^2))
+ * y = sqrt((x^2+1) / (1-dx^2))
+ *
+ * Where d = (-121665/121666), or:
+ *
+ * d = 370957059346694393431380835087545651895
+ * 42113879843219016388785533085940283555
+ */
+
+static const uint8_t ed25519_d[F25519_SIZE] = {
+ 0xa3, 0x78, 0x59, 0x13, 0xca, 0x4d, 0xeb, 0x75,
+ 0xab, 0xd8, 0x41, 0x41, 0x4d, 0x0a, 0x70, 0x00,
+ 0x98, 0xe8, 0x79, 0x77, 0x79, 0x40, 0xc7, 0x8c,
+ 0x73, 0xfe, 0x6f, 0x2b, 0xee, 0x6c, 0x03, 0x52
+};
+
+void ed25519_pack(uint8_t *c, const uint8_t *x, const uint8_t *y)
+{
+ uint8_t tmp[F25519_SIZE];
+ uint8_t parity;
+
+ f25519_copy(tmp, x);
+ f25519_normalize(tmp);
+ parity = (tmp[0] & 1) << 7;
+
+ f25519_copy(c, y);
+ f25519_normalize(c);
+ c[31] |= parity;
+}
+
+uint8_t ed25519_try_unpack(uint8_t *x, uint8_t *y, const uint8_t *comp)
+{
+ const int parity = comp[31] >> 7;
+ uint8_t a[F25519_SIZE];
+ uint8_t b[F25519_SIZE];
+ uint8_t c[F25519_SIZE];
+
+ /* Unpack y */
+ f25519_copy(y, comp);
+ y[31] &= 127;
+
+ /* Compute c = y^2 */
+ f25519_mul__distinct(c, y, y);
+
+ /* Compute b = (1+dy^2)^-1 */
+ f25519_mul__distinct(b, c, ed25519_d);
+ f25519_add(a, b, f25519_one);
+ f25519_inv__distinct(b, a);
+
+ /* Compute a = y^2-1 */
+ f25519_sub(a, c, f25519_one);
+
+ /* Compute c = a*b = (y^2-1)/(1-dy^2) */
+ f25519_mul__distinct(c, a, b);
+
+ /* Compute a, b = +/-sqrt(c), if c is square */
+ f25519_sqrt(a, c);
+ f25519_neg(b, a);
+
+ /* Select one of them, based on the compressed parity bit */
+ f25519_select(x, a, b, (a[0] ^ parity) & 1);
+
+ /* Verify that x^2 = c */
+ f25519_mul__distinct(a, x, x);
+ f25519_normalize(a);
+ f25519_normalize(c);
+
+ return f25519_eq(a, c);
+}
+
+/* k = 2d */
+static const uint8_t ed25519_k[F25519_SIZE] = {
+ 0x59, 0xf1, 0xb2, 0x26, 0x94, 0x9b, 0xd6, 0xeb,
+ 0x56, 0xb1, 0x83, 0x82, 0x9a, 0x14, 0xe0, 0x00,
+ 0x30, 0xd1, 0xf3, 0xee, 0xf2, 0x80, 0x8e, 0x19,
+ 0xe7, 0xfc, 0xdf, 0x56, 0xdc, 0xd9, 0x06, 0x24
+};
+
+void ed25519_add(struct ed25519_pt *r,
+ const struct ed25519_pt *p1, const struct ed25519_pt *p2)
+{
+ /* Explicit formulas database: add-2008-hwcd-3
+ *
+ * source 2008 Hisil--Wong--Carter--Dawson,
+ * http://eprint.iacr.org/2008/522, Section 3.1
+ * appliesto extended-1
+ * parameter k
+ * assume k = 2 d
+ * compute A = (Y1-X1)(Y2-X2)
+ * compute B = (Y1+X1)(Y2+X2)
+ * compute C = T1 k T2
+ * compute D = Z1 2 Z2
+ * compute E = B - A
+ * compute F = D - C
+ * compute G = D + C
+ * compute H = B + A
+ * compute X3 = E F
+ * compute Y3 = G H
+ * compute T3 = E H
+ * compute Z3 = F G
+ */
+ uint8_t a[F25519_SIZE];
+ uint8_t b[F25519_SIZE];
+ uint8_t c[F25519_SIZE];
+ uint8_t d[F25519_SIZE];
+ uint8_t e[F25519_SIZE];
+ uint8_t f[F25519_SIZE];
+ uint8_t g[F25519_SIZE];
+ uint8_t h[F25519_SIZE];
+
+ /* A = (Y1-X1)(Y2-X2) */
+ f25519_sub(c, p1->y, p1->x);
+ f25519_sub(d, p2->y, p2->x);
+ f25519_mul__distinct(a, c, d);
+
+ /* B = (Y1+X1)(Y2+X2) */
+ f25519_add(c, p1->y, p1->x);
+ f25519_add(d, p2->y, p2->x);
+ f25519_mul__distinct(b, c, d);
+
+ /* C = T1 k T2 */
+ f25519_mul__distinct(d, p1->t, p2->t);
+ f25519_mul__distinct(c, d, ed25519_k);
+
+ /* D = Z1 2 Z2 */
+ f25519_mul__distinct(d, p1->z, p2->z);
+ f25519_add(d, d, d);
+
+ /* E = B - A */
+ f25519_sub(e, b, a);
+
+ /* F = D - C */
+ f25519_sub(f, d, c);
+
+ /* G = D + C */
+ f25519_add(g, d, c);
+
+ /* H = B + A */
+ f25519_add(h, b, a);
+
+ /* X3 = E F */
+ f25519_mul__distinct(r->x, e, f);
+
+ /* Y3 = G H */
+ f25519_mul__distinct(r->y, g, h);
+
+ /* T3 = E H */
+ f25519_mul__distinct(r->t, e, h);
+
+ /* Z3 = F G */
+ f25519_mul__distinct(r->z, f, g);
+}
+
+void ed25519_double(struct ed25519_pt *r, const struct ed25519_pt *p)
+{
+ /* Explicit formulas database: dbl-2008-hwcd
+ *
+ * source 2008 Hisil--Wong--Carter--Dawson,
+ * http://eprint.iacr.org/2008/522, Section 3.3
+ * compute A = X1^2
+ * compute B = Y1^2
+ * compute C = 2 Z1^2
+ * compute D = a A
+ * compute E = (X1+Y1)^2-A-B
+ * compute G = D + B
+ * compute F = G - C
+ * compute H = D - B
+ * compute X3 = E F
+ * compute Y3 = G H
+ * compute T3 = E H
+ * compute Z3 = F G
+ */
+ uint8_t a[F25519_SIZE];
+ uint8_t b[F25519_SIZE];
+ uint8_t c[F25519_SIZE];
+ uint8_t e[F25519_SIZE];
+ uint8_t f[F25519_SIZE];
+ uint8_t g[F25519_SIZE];
+ uint8_t h[F25519_SIZE];
+
+ /* A = X1^2 */
+ f25519_mul__distinct(a, p->x, p->x);
+
+ /* B = Y1^2 */
+ f25519_mul__distinct(b, p->y, p->y);
+
+ /* C = 2 Z1^2 */
+ f25519_mul__distinct(c, p->z, p->z);
+ f25519_add(c, c, c);
+
+ /* D = a A (alter sign) */
+ /* E = (X1+Y1)^2-A-B */
+ f25519_add(f, p->x, p->y);
+ f25519_mul__distinct(e, f, f);
+ f25519_sub(e, e, a);
+ f25519_sub(e, e, b);
+
+ /* G = D + B */
+ f25519_sub(g, b, a);
+
+ /* F = G - C */
+ f25519_sub(f, g, c);
+
+ /* H = D - B */
+ f25519_neg(h, b);
+ f25519_sub(h, h, a);
+
+ /* X3 = E F */
+ f25519_mul__distinct(r->x, e, f);
+
+ /* Y3 = G H */
+ f25519_mul__distinct(r->y, g, h);
+
+ /* T3 = E H */
+ f25519_mul__distinct(r->t, e, h);
+
+ /* Z3 = F G */
+ f25519_mul__distinct(r->z, f, g);
+}
+
+void ed25519_smult(struct ed25519_pt *r_out, const struct ed25519_pt *p,
+ const uint8_t *e)
+{
+ struct ed25519_pt r;
+ int i;
+
+ ed25519_copy(&r, &ed25519_neutral);
+
+ for (i = 255; i >= 0; i--) {
+ const uint8_t bit = (e[i >> 3] >> (i & 7)) & 1;
+ struct ed25519_pt s;
+
+ ed25519_double(&r, &r);
+ ed25519_add(&s, &r, p);
+
+ f25519_select(r.x, r.x, s.x, bit);
+ f25519_select(r.y, r.y, s.y, bit);
+ f25519_select(r.z, r.z, s.z, bit);
+ f25519_select(r.t, r.t, s.t, bit);
+ }
+
+ ed25519_copy(r_out, &r);
+}
diff --git a/lib/Utils.Cryptography/monocypher/vendor/tests/externals/c25519/ed25519.h b/lib/Utils.Cryptography/monocypher/vendor/tests/externals/c25519/ed25519.h
new file mode 100644
index 0000000..62f0120
--- /dev/null
+++ b/lib/Utils.Cryptography/monocypher/vendor/tests/externals/c25519/ed25519.h
@@ -0,0 +1,82 @@
+/* Edwards curve operations
+ * Daniel Beer <dlbeer@gmail.com>, 9 Jan 2014
+ *
+ * This file is in the public domain.
+ */
+
+#ifndef ED25519_H_
+#define ED25519_H_
+
+#include "f25519.h"
+
+/* This is not the Ed25519 signature system. Rather, we're implementing
+ * basic operations on the twisted Edwards curve over (Z mod 2^255-19):
+ *
+ * -x^2 + y^2 = 1 - (121665/121666)x^2y^2
+ *
+ * With the positive-x base point y = 4/5.
+ *
+ * These functions will not leak secret data through timing.
+ *
+ * For more information, see:
+ *
+ * Bernstein, D.J. & Lange, T. (2007) "Faster addition and doubling on
+ * elliptic curves". Document ID: 95616567a6ba20f575c5f25e7cebaf83.
+ *
+ * Hisil, H. & Wong, K K. & Carter, G. & Dawson, E. (2008) "Twisted
+ * Edwards curves revisited". Advances in Cryptology, ASIACRYPT 2008,
+ * Vol. 5350, pp. 326-343.
+ */
+
+/* Projective coordinates */
+struct ed25519_pt {
+ uint8_t x[F25519_SIZE];
+ uint8_t y[F25519_SIZE];
+ uint8_t t[F25519_SIZE];
+ uint8_t z[F25519_SIZE];
+};
+
+extern const struct ed25519_pt ed25519_base;
+extern const struct ed25519_pt ed25519_neutral;
+
+/* Convert between projective and affine coordinates (x/y in F25519) */
+void ed25519_project(struct ed25519_pt *p,
+ const uint8_t *x, const uint8_t *y);
+
+void ed25519_unproject(uint8_t *x, uint8_t *y,
+ const struct ed25519_pt *p);
+
+/* Compress/uncompress points. try_unpack() will check that the
+ * compressed point is on the curve, returning 1 if the unpacked point
+ * is valid, and 0 otherwise.
+ */
+#define ED25519_PACK_SIZE F25519_SIZE
+
+void ed25519_pack(uint8_t *c, const uint8_t *x, const uint8_t *y);
+uint8_t ed25519_try_unpack(uint8_t *x, uint8_t *y, const uint8_t *c);
+
+/* Add, double and scalar multiply */
+#define ED25519_EXPONENT_SIZE 32
+
+/* Prepare an exponent by clamping appropriate bits */
+static inline void ed25519_prepare(uint8_t *e)
+{
+ e[0] &= 0xf8;
+ e[31] &= 0x7f;
+ e[31] |= 0x40;
+}
+
+/* Order of the group generated by the base point */
+static inline void ed25519_copy(struct ed25519_pt *dst,
+ const struct ed25519_pt *src)
+{
+ memcpy(dst, src, sizeof(*dst));
+}
+
+void ed25519_add(struct ed25519_pt *r,
+ const struct ed25519_pt *a, const struct ed25519_pt *b);
+void ed25519_double(struct ed25519_pt *r, const struct ed25519_pt *a);
+void ed25519_smult(struct ed25519_pt *r, const struct ed25519_pt *a,
+ const uint8_t *e);
+
+#endif
diff --git a/lib/Utils.Cryptography/monocypher/vendor/tests/externals/c25519/edsign.c b/lib/Utils.Cryptography/monocypher/vendor/tests/externals/c25519/edsign.c
new file mode 100644
index 0000000..bf131a5
--- /dev/null
+++ b/lib/Utils.Cryptography/monocypher/vendor/tests/externals/c25519/edsign.c
@@ -0,0 +1,168 @@
+/* Edwards curve signature system
+ * Daniel Beer <dlbeer@gmail.com>, 22 Apr 2014
+ *
+ * This file is in the public domain.
+ */
+
+#include "ed25519.h"
+#include "sha512.h"
+#include "fprime.h"
+#include "edsign.h"
+
+#define EXPANDED_SIZE 64
+
+static const uint8_t ed25519_order[FPRIME_SIZE] = {
+ 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
+};
+
+static void expand_key(uint8_t *expanded, const uint8_t *secret)
+{
+ struct sha512_state s;
+
+ sha512_init(&s);
+ sha512_final(&s, secret, EDSIGN_SECRET_KEY_SIZE);
+ sha512_get(&s, expanded, 0, EXPANDED_SIZE);
+ ed25519_prepare(expanded);
+}
+
+static uint8_t upp(struct ed25519_pt *p, const uint8_t *packed)
+{
+ uint8_t x[F25519_SIZE];
+ uint8_t y[F25519_SIZE];
+ uint8_t ok = ed25519_try_unpack(x, y, packed);
+
+ ed25519_project(p, x, y);
+ return ok;
+}
+
+static void pp(uint8_t *packed, const struct ed25519_pt *p)
+{
+ uint8_t x[F25519_SIZE];
+ uint8_t y[F25519_SIZE];
+
+ ed25519_unproject(x, y, p);
+ ed25519_pack(packed, x, y);
+}
+
+static void sm_pack(uint8_t *r, const uint8_t *k)
+{
+ struct ed25519_pt p;
+
+ ed25519_smult(&p, &ed25519_base, k);
+ pp(r, &p);
+}
+
+void edsign_sec_to_pub(uint8_t *pub, const uint8_t *secret)
+{
+ uint8_t expanded[EXPANDED_SIZE];
+
+ expand_key(expanded, secret);
+ sm_pack(pub, expanded);
+}
+
+static void hash_with_prefix(uint8_t *out_fp,
+ uint8_t *init_block, unsigned int prefix_size,
+ const uint8_t *message, size_t len)
+{
+ struct sha512_state s;
+
+ sha512_init(&s);
+
+ if (len < SHA512_BLOCK_SIZE && len + prefix_size < SHA512_BLOCK_SIZE) {
+ memcpy(init_block + prefix_size, message, len);
+ sha512_final(&s, init_block, len + prefix_size);
+ } else {
+ size_t i;
+
+ memcpy(init_block + prefix_size, message,
+ SHA512_BLOCK_SIZE - prefix_size);
+ sha512_block(&s, init_block);
+
+ for (i = SHA512_BLOCK_SIZE - prefix_size;
+ i + SHA512_BLOCK_SIZE <= len;
+ i += SHA512_BLOCK_SIZE)
+ sha512_block(&s, message + i);
+
+ sha512_final(&s, message + i, len + prefix_size);
+ }
+
+ sha512_get(&s, init_block, 0, SHA512_HASH_SIZE);
+ fprime_from_bytes(out_fp, init_block, SHA512_HASH_SIZE, ed25519_order);
+}
+
+static void generate_k(uint8_t *k, const uint8_t *kgen_key,
+ const uint8_t *message, size_t len)
+{
+ uint8_t block[SHA512_BLOCK_SIZE];
+
+ memcpy(block, kgen_key, 32);
+ hash_with_prefix(k, block, 32, message, len);
+}
+
+static void hash_message(uint8_t *z, const uint8_t *r, const uint8_t *a,
+ const uint8_t *m, size_t len)
+{
+ uint8_t block[SHA512_BLOCK_SIZE];
+
+ memcpy(block, r, 32);
+ memcpy(block + 32, a, 32);
+ hash_with_prefix(z, block, 64, m, len);
+}
+
+void edsign_sign(uint8_t *signature, const uint8_t *pub,
+ const uint8_t *secret,
+ const uint8_t *message, size_t len)
+{
+ uint8_t expanded[EXPANDED_SIZE];
+ uint8_t e[FPRIME_SIZE];
+ uint8_t s[FPRIME_SIZE];
+ uint8_t k[FPRIME_SIZE];
+ uint8_t z[FPRIME_SIZE];
+
+ expand_key(expanded, secret);
+
+ /* Generate k and R = kB */
+ generate_k(k, expanded + 32, message, len);
+ sm_pack(signature, k);
+
+ /* Compute z = H(R, A, M) */
+ hash_message(z, signature, pub, message, len);
+
+ /* Obtain e */
+ fprime_from_bytes(e, expanded, 32, ed25519_order);
+
+ /* Compute s = ze + k */
+ fprime_mul(s, z, e, ed25519_order);
+ fprime_add(s, k, ed25519_order);
+ memcpy(signature + 32, s, 32);
+}
+
+uint8_t edsign_verify(const uint8_t *signature, const uint8_t *pub,
+ const uint8_t *message, size_t len)
+{
+ struct ed25519_pt p;
+ struct ed25519_pt q;
+ uint8_t lhs[F25519_SIZE];
+ uint8_t rhs[F25519_SIZE];
+ uint8_t z[FPRIME_SIZE];
+ uint8_t ok = 1;
+
+ /* Compute z = H(R, A, M) */
+ hash_message(z, signature, pub, message, len);
+
+ /* sB = (ze + k)B = ... */
+ sm_pack(lhs, signature + 32);
+
+ /* ... = zA + R */
+ ok &= upp(&p, pub);
+ ed25519_smult(&p, &p, z);
+ ok &= upp(&q, signature);
+ ed25519_add(&p, &p, &q);
+ pp(rhs, &p);
+
+ /* Equal? */
+ return ok & f25519_eq(lhs, rhs);
+}
diff --git a/lib/Utils.Cryptography/monocypher/vendor/tests/externals/c25519/edsign.h b/lib/Utils.Cryptography/monocypher/vendor/tests/externals/c25519/edsign.h
new file mode 100644
index 0000000..85e2208
--- /dev/null
+++ b/lib/Utils.Cryptography/monocypher/vendor/tests/externals/c25519/edsign.h
@@ -0,0 +1,51 @@
+/* Edwards curve signature system
+ * Daniel Beer <dlbeer@gmail.com>, 22 Apr 2014
+ *
+ * This file is in the public domain.
+ */
+
+#ifndef EDSIGN_H_
+#define EDSIGN_H_
+
+#include <stdint.h>
+#include <stddef.h>
+
+/* This is the Ed25519 signature system, as described in:
+ *
+ * Daniel J. Bernstein, Niels Duif, Tanja Lange, Peter Schwabe, Bo-Yin
+ * Yang. High-speed high-security signatures. Journal of Cryptographic
+ * Engineering 2 (2012), 77-89. Document ID:
+ * a1a62a2f76d23f65d622484ddd09caf8. URL:
+ * http://cr.yp.to/papers.html#ed25519. Date: 2011.09.26.
+ *
+ * The format and calculation of signatures is compatible with the
+ * Ed25519 implementation in SUPERCOP. Note, however, that our secret
+ * keys are half the size: we don't store a copy of the public key in
+ * the secret key (we generate it on demand).
+ */
+
+/* Any string of 32 random bytes is a valid secret key. There is no
+ * clamping of bits, because we don't use the key directly as an
+ * exponent (the exponent is derived from part of a key expansion).
+ */
+#define EDSIGN_SECRET_KEY_SIZE 32
+
+/* Given a secret key, produce the public key (a packed Edwards-curve
+ * point).
+ */
+#define EDSIGN_PUBLIC_KEY_SIZE 32
+
+void edsign_sec_to_pub(uint8_t *pub, const uint8_t *secret);
+
+/* Produce a signature for a message. */
+#define EDSIGN_SIGNATURE_SIZE 64
+
+void edsign_sign(uint8_t *signature, const uint8_t *pub,
+ const uint8_t *secret,
+ const uint8_t *message, size_t len);
+
+/* Verify a message signature. Returns non-zero if ok. */
+uint8_t edsign_verify(const uint8_t *signature, const uint8_t *pub,
+ const uint8_t *message, size_t len);
+
+#endif
diff --git a/lib/Utils.Cryptography/monocypher/vendor/tests/externals/c25519/f25519.c b/lib/Utils.Cryptography/monocypher/vendor/tests/externals/c25519/f25519.c
new file mode 100644
index 0000000..3b06fa6
--- /dev/null
+++ b/lib/Utils.Cryptography/monocypher/vendor/tests/externals/c25519/f25519.c
@@ -0,0 +1,324 @@
+/* Arithmetic mod p = 2^255-19
+ * Daniel Beer <dlbeer@gmail.com>, 5 Jan 2014
+ *
+ * This file is in the public domain.
+ */
+
+#include "f25519.h"
+
+const uint8_t f25519_zero[F25519_SIZE] = {0};
+const uint8_t f25519_one[F25519_SIZE] = {1};
+
+void f25519_load(uint8_t *x, uint32_t c)
+{
+ unsigned int i;
+
+ for (i = 0; i < sizeof(c); i++) {
+ x[i] = c;
+ c >>= 8;
+ }
+
+ for (; i < F25519_SIZE; i++)
+ x[i] = 0;
+}
+
+void f25519_normalize(uint8_t *x)
+{
+ uint8_t minusp[F25519_SIZE];
+ uint16_t c;
+ int i;
+
+ /* Reduce using 2^255 = 19 mod p */
+ c = (x[31] >> 7) * 19;
+ x[31] &= 127;
+
+ for (i = 0; i < F25519_SIZE; i++) {
+ c += x[i];
+ x[i] = c;
+ c >>= 8;
+ }
+
+ /* The number is now less than 2^255 + 18, and therefore less than
+ * 2p. Try subtracting p, and conditionally load the subtracted
+ * value if underflow did not occur.
+ */
+ c = 19;
+
+ for (i = 0; i + 1 < F25519_SIZE; i++) {
+ c += x[i];
+ minusp[i] = c;
+ c >>= 8;
+ }
+
+ c += ((uint16_t)x[i]) - 128;
+ minusp[31] = c;
+
+ /* Load x-p if no underflow */
+ f25519_select(x, minusp, x, (c >> 15) & 1);
+}
+
+uint8_t f25519_eq(const uint8_t *x, const uint8_t *y)
+{
+ uint8_t sum = 0;
+ int i;
+
+ for (i = 0; i < F25519_SIZE; i++)
+ sum |= x[i] ^ y[i];
+
+ sum |= (sum >> 4);
+ sum |= (sum >> 2);
+ sum |= (sum >> 1);
+
+ return (sum ^ 1) & 1;
+}
+
+void f25519_select(uint8_t *dst,
+ const uint8_t *zero, const uint8_t *one,
+ uint8_t condition)
+{
+ const uint8_t mask = -condition;
+ int i;
+
+ for (i = 0; i < F25519_SIZE; i++)
+ dst[i] = zero[i] ^ (mask & (one[i] ^ zero[i]));
+}
+
+void f25519_add(uint8_t *r, const uint8_t *a, const uint8_t *b)
+{
+ uint16_t c = 0;
+ int i;
+
+ /* Add */
+ for (i = 0; i < F25519_SIZE; i++) {
+ c >>= 8;
+ c += ((uint16_t)a[i]) + ((uint16_t)b[i]);
+ r[i] = c;
+ }
+
+ /* Reduce with 2^255 = 19 mod p */
+ r[31] &= 127;
+ c = (c >> 7) * 19;
+
+ for (i = 0; i < F25519_SIZE; i++) {
+ c += r[i];
+ r[i] = c;
+ c >>= 8;
+ }
+}
+
+void f25519_sub(uint8_t *r, const uint8_t *a, const uint8_t *b)
+{
+ uint32_t c = 0;
+ int i;
+
+ /* Calculate a + 2p - b, to avoid underflow */
+ c = 218;
+ for (i = 0; i + 1 < F25519_SIZE; i++) {
+ c += 65280 + ((uint32_t)a[i]) - ((uint32_t)b[i]);
+ r[i] = c;
+ c >>= 8;
+ }
+
+ c += ((uint32_t)a[31]) - ((uint32_t)b[31]);
+ r[31] = c & 127;
+ c = (c >> 7) * 19;
+
+ for (i = 0; i < F25519_SIZE; i++) {
+ c += r[i];
+ r[i] = c;
+ c >>= 8;
+ }
+}
+
+void f25519_neg(uint8_t *r, const uint8_t *a)
+{
+ uint32_t c = 0;
+ int i;
+
+ /* Calculate 2p - a, to avoid underflow */
+ c = 218;
+ for (i = 0; i + 1 < F25519_SIZE; i++) {
+ c += 65280 - ((uint32_t)a[i]);
+ r[i] = c;
+ c >>= 8;
+ }
+
+ c -= ((uint32_t)a[31]);
+ r[31] = c & 127;
+ c = (c >> 7) * 19;
+
+ for (i = 0; i < F25519_SIZE; i++) {
+ c += r[i];
+ r[i] = c;
+ c >>= 8;
+ }
+}
+
+void f25519_mul__distinct(uint8_t *r, const uint8_t *a, const uint8_t *b)
+{
+ uint32_t c = 0;
+ int i;
+
+ for (i = 0; i < F25519_SIZE; i++) {
+ int j;
+
+ c >>= 8;
+ for (j = 0; j <= i; j++)
+ c += ((uint32_t)a[j]) * ((uint32_t)b[i - j]);
+
+ for (; j < F25519_SIZE; j++)
+ c += ((uint32_t)a[j]) *
+ ((uint32_t)b[i + F25519_SIZE - j]) * 38;
+
+ r[i] = c;
+ }
+
+ r[31] &= 127;
+ c = (c >> 7) * 19;
+
+ for (i = 0; i < F25519_SIZE; i++) {
+ c += r[i];
+ r[i] = c;
+ c >>= 8;
+ }
+}
+
+void f25519_mul(uint8_t *r, const uint8_t *a, const uint8_t *b)
+{
+ uint8_t tmp[F25519_SIZE];
+
+ f25519_mul__distinct(tmp, a, b);
+ f25519_copy(r, tmp);
+}
+
+void f25519_mul_c(uint8_t *r, const uint8_t *a, uint32_t b)
+{
+ uint32_t c = 0;
+ int i;
+
+ for (i = 0; i < F25519_SIZE; i++) {
+ c >>= 8;
+ c += b * ((uint32_t)a[i]);
+ r[i] = c;
+ }
+
+ r[31] &= 127;
+ c >>= 7;
+ c *= 19;
+
+ for (i = 0; i < F25519_SIZE; i++) {
+ c += r[i];
+ r[i] = c;
+ c >>= 8;
+ }
+}
+
+void f25519_inv__distinct(uint8_t *r, const uint8_t *x)
+{
+ uint8_t s[F25519_SIZE];
+ int i;
+
+ /* This is a prime field, so by Fermat's little theorem:
+ *
+ * x^(p-1) = 1 mod p
+ *
+ * Therefore, raise to (p-2) = 2^255-21 to get a multiplicative
+ * inverse.
+ *
+ * This is a 255-bit binary number with the digits:
+ *
+ * 11111111... 01011
+ *
+ * We compute the result by the usual binary chain, but
+ * alternate between keeping the accumulator in r and s, so as
+ * to avoid copying temporaries.
+ */
+
+ /* 1 1 */
+ f25519_mul__distinct(s, x, x);
+ f25519_mul__distinct(r, s, x);
+
+ /* 1 x 248 */
+ for (i = 0; i < 248; i++) {
+ f25519_mul__distinct(s, r, r);
+ f25519_mul__distinct(r, s, x);
+ }
+
+ /* 0 */
+ f25519_mul__distinct(s, r, r);
+
+ /* 1 */
+ f25519_mul__distinct(r, s, s);
+ f25519_mul__distinct(s, r, x);
+
+ /* 0 */
+ f25519_mul__distinct(r, s, s);
+
+ /* 1 */
+ f25519_mul__distinct(s, r, r);
+ f25519_mul__distinct(r, s, x);
+
+ /* 1 */
+ f25519_mul__distinct(s, r, r);
+ f25519_mul__distinct(r, s, x);
+}
+
+void f25519_inv(uint8_t *r, const uint8_t *x)
+{
+ uint8_t tmp[F25519_SIZE];
+
+ f25519_inv__distinct(tmp, x);
+ f25519_copy(r, tmp);
+}
+
+/* Raise x to the power of (p-5)/8 = 2^252-3, using s for temporary
+ * storage.
+ */
+static void exp2523(uint8_t *r, const uint8_t *x, uint8_t *s)
+{
+ int i;
+
+ /* This number is a 252-bit number with the binary expansion:
+ *
+ * 111111... 01
+ */
+
+ /* 1 1 */
+ f25519_mul__distinct(r, x, x);
+ f25519_mul__distinct(s, r, x);
+
+ /* 1 x 248 */
+ for (i = 0; i < 248; i++) {
+ f25519_mul__distinct(r, s, s);
+ f25519_mul__distinct(s, r, x);
+ }
+
+ /* 0 */
+ f25519_mul__distinct(r, s, s);
+
+ /* 1 */
+ f25519_mul__distinct(s, r, r);
+ f25519_mul__distinct(r, s, x);
+}
+
+void f25519_sqrt(uint8_t *r, const uint8_t *a)
+{
+ uint8_t v[F25519_SIZE];
+ uint8_t i[F25519_SIZE];
+ uint8_t x[F25519_SIZE];
+ uint8_t y[F25519_SIZE];
+
+ /* v = (2a)^((p-5)/8) [x = 2a] */
+ f25519_mul_c(x, a, 2);
+ exp2523(v, x, y);
+
+ /* i = 2av^2 - 1 */
+ f25519_mul__distinct(y, v, v);
+ f25519_mul__distinct(i, x, y);
+ f25519_load(y, 1);
+ f25519_sub(i, i, y);
+
+ /* r = avi */
+ f25519_mul__distinct(x, v, a);
+ f25519_mul__distinct(r, x, i);
+}
diff --git a/lib/Utils.Cryptography/monocypher/vendor/tests/externals/c25519/f25519.h b/lib/Utils.Cryptography/monocypher/vendor/tests/externals/c25519/f25519.h
new file mode 100644
index 0000000..4cfa5ec
--- /dev/null
+++ b/lib/Utils.Cryptography/monocypher/vendor/tests/externals/c25519/f25519.h
@@ -0,0 +1,92 @@
+/* Arithmetic mod p = 2^255-19
+ * Daniel Beer <dlbeer@gmail.com>, 8 Jan 2014
+ *
+ * This file is in the public domain.
+ */
+
+#ifndef F25519_H_
+#define F25519_H_
+
+#include <stdint.h>
+#include <string.h>
+
+/* Field elements are represented as little-endian byte strings. All
+ * operations have timings which are independent of input data, so they
+ * can be safely used for cryptography.
+ *
+ * Computation is performed on un-normalized elements. These are byte
+ * strings which fall into the range 0 <= x < 2p. Use f25519_normalize()
+ * to convert to a value 0 <= x < p.
+ *
+ * Elements received from the outside may greater even than 2p.
+ * f25519_normalize() will correctly deal with these numbers too.
+ */
+#define F25519_SIZE 32
+
+/* Identity constants */
+extern const uint8_t f25519_zero[F25519_SIZE];
+extern const uint8_t f25519_one[F25519_SIZE];
+
+/* Load a small constant */
+void f25519_load(uint8_t *x, uint32_t c);
+
+/* Copy two points */
+static inline void f25519_copy(uint8_t *x, const uint8_t *a)
+{
+ memcpy(x, a, F25519_SIZE);
+}
+
+/* Normalize a field point x < 2*p by subtracting p if necessary */
+void f25519_normalize(uint8_t *x);
+
+/* Compare two field points in constant time. Return one if equal, zero
+ * otherwise. This should be performed only on normalized values.
+ */
+uint8_t f25519_eq(const uint8_t *x, const uint8_t *y);
+
+/* Conditional copy. If condition == 0, then zero is copied to dst. If
+ * condition == 1, then one is copied to dst. Any other value results in
+ * undefined behaviour.
+ */
+void f25519_select(uint8_t *dst,
+ const uint8_t *zero, const uint8_t *one,
+ uint8_t condition);
+
+/* Add/subtract two field points. The three pointers are not required to
+ * be distinct.
+ */
+void f25519_add(uint8_t *r, const uint8_t *a, const uint8_t *b);
+void f25519_sub(uint8_t *r, const uint8_t *a, const uint8_t *b);
+
+/* Unary negation */
+void f25519_neg(uint8_t *r, const uint8_t *a);
+
+/* Multiply two field points. The __distinct variant is used when r is
+ * known to be in a different location to a and b.
+ */
+void f25519_mul(uint8_t *r, const uint8_t *a, const uint8_t *b);
+void f25519_mul__distinct(uint8_t *r, const uint8_t *a, const uint8_t *b);
+
+/* Multiply a point by a small constant. The two pointers are not
+ * required to be distinct.
+ *
+ * The constant must be less than 2^24.
+ */
+void f25519_mul_c(uint8_t *r, const uint8_t *a, uint32_t b);
+
+/* Take the reciprocal of a field point. The __distinct variant is used
+ * when r is known to be in a different location to x.
+ */
+void f25519_inv(uint8_t *r, const uint8_t *x);
+void f25519_inv__distinct(uint8_t *r, const uint8_t *x);
+
+/* Compute one of the square roots of the field element, if the element
+ * is square. The other square is -r.
+ *
+ * If the input is not square, the returned value is a valid field
+ * element, but not the correct answer. If you don't already know that
+ * your element is square, you should square the return value and test.
+ */
+void f25519_sqrt(uint8_t *r, const uint8_t *x);
+
+#endif
diff --git a/lib/Utils.Cryptography/monocypher/vendor/tests/externals/c25519/fprime.c b/lib/Utils.Cryptography/monocypher/vendor/tests/externals/c25519/fprime.c
new file mode 100644
index 0000000..25f2197
--- /dev/null
+++ b/lib/Utils.Cryptography/monocypher/vendor/tests/externals/c25519/fprime.c
@@ -0,0 +1,215 @@
+/* Arithmetic in prime fields
+ * Daniel Beer <dlbeer@gmail.com>, 10 Jan 2014
+ *
+ * This file is in the public domain.
+ */
+
+#include "fprime.h"
+
+const uint8_t fprime_zero[FPRIME_SIZE] = {0};
+const uint8_t fprime_one[FPRIME_SIZE] = {1};
+
+static void raw_add(uint8_t *x, const uint8_t *p)
+{
+ uint16_t c = 0;
+ int i;
+
+ for (i = 0; i < FPRIME_SIZE; i++) {
+ c += ((uint16_t)x[i]) + ((uint16_t)p[i]);
+ x[i] = c;
+ c >>= 8;
+ }
+}
+
+static void raw_try_sub(uint8_t *x, const uint8_t *p)
+{
+ uint8_t minusp[FPRIME_SIZE];
+ uint16_t c = 0;
+ int i;
+
+ for (i = 0; i < FPRIME_SIZE; i++) {
+ c = ((uint16_t)x[i]) - ((uint16_t)p[i]) - c;
+ minusp[i] = c;
+ c = (c >> 8) & 1;
+ }
+
+ fprime_select(x, minusp, x, c);
+}
+
+/* Warning: this function is variable-time */
+static int prime_msb(const uint8_t *p)
+{
+ int i;
+ uint8_t x;
+
+ for (i = FPRIME_SIZE - 1; i >= 0; i--)
+ if (p[i])
+ break;
+
+ x = p[i];
+ i <<= 3;
+
+ while (x) {
+ x >>= 1;
+ i++;
+ }
+
+ return i - 1;
+}
+
+/* Warning: this function may be variable-time in the argument n */
+static void shift_n_bits(uint8_t *x, int n)
+{
+ uint16_t c = 0;
+ int i;
+
+ for (i = 0; i < FPRIME_SIZE; i++) {
+ c |= ((uint16_t)x[i]) << n;
+ x[i] = c;
+ c >>= 8;
+ }
+}
+
+void fprime_load(uint8_t *x, uint32_t c)
+{
+ unsigned int i;
+
+ for (i = 0; i < sizeof(c); i++) {
+ x[i] = c;
+ c >>= 8;
+ }
+
+ for (; i < FPRIME_SIZE; i++)
+ x[i] = 0;
+}
+
+static inline int min_int(int a, int b)
+{
+ return a < b ? a : b;
+}
+
+void fprime_from_bytes(uint8_t *n,
+ const uint8_t *x, size_t len,
+ const uint8_t *modulus)
+{
+ const int preload_total = min_int(prime_msb(modulus) - 1, len << 3);
+ const int preload_bytes = preload_total >> 3;
+ const int preload_bits = preload_total & 7;
+ const int rbits = (len << 3) - preload_total;
+ int i;
+
+ memset(n, 0, FPRIME_SIZE);
+
+ for (i = 0; i < preload_bytes; i++)
+ n[i] = x[len - preload_bytes + i];
+
+ if (preload_bits) {
+ shift_n_bits(n, preload_bits);
+ n[0] |= x[len - preload_bytes - 1] >> (8 - preload_bits);
+ }
+
+ for (i = rbits - 1; i >= 0; i--) {
+ const uint8_t bit = (x[i >> 3] >> (i & 7)) & 1;
+
+ shift_n_bits(n, 1);
+ n[0] |= bit;
+ raw_try_sub(n, modulus);
+ }
+}
+
+void fprime_normalize(uint8_t *x, const uint8_t *modulus)
+{
+ uint8_t n[FPRIME_SIZE];
+
+ fprime_from_bytes(n, x, FPRIME_SIZE, modulus);
+ fprime_copy(x, n);
+}
+
+uint8_t fprime_eq(const uint8_t *x, const uint8_t *y)
+{
+ uint8_t sum = 0;
+ int i;
+
+ for (i = 0; i < FPRIME_SIZE; i++)
+ sum |= x[i] ^ y[i];
+
+ sum |= (sum >> 4);
+ sum |= (sum >> 2);
+ sum |= (sum >> 1);
+
+ return (sum ^ 1) & 1;
+}
+
+void fprime_select(uint8_t *dst,
+ const uint8_t *zero, const uint8_t *one,
+ uint8_t condition)
+{
+ const uint8_t mask = -condition;
+ int i;
+
+ for (i = 0; i < FPRIME_SIZE; i++)
+ dst[i] = zero[i] ^ (mask & (one[i] ^ zero[i]));
+}
+
+void fprime_add(uint8_t *r, const uint8_t *a, const uint8_t *modulus)
+{
+ raw_add(r, a);
+ raw_try_sub(r, modulus);
+}
+
+void fprime_sub(uint8_t *r, const uint8_t *a, const uint8_t *modulus)
+{
+ raw_add(r, modulus);
+ raw_try_sub(r, a);
+ raw_try_sub(r, modulus);
+}
+
+void fprime_mul(uint8_t *r, const uint8_t *a, const uint8_t *b,
+ const uint8_t *modulus)
+{
+ int i;
+
+ memset(r, 0, FPRIME_SIZE);
+
+ for (i = prime_msb(modulus); i >= 0; i--) {
+ const uint8_t bit = (b[i >> 3] >> (i & 7)) & 1;
+ uint8_t plusa[FPRIME_SIZE];
+
+ shift_n_bits(r, 1);
+ raw_try_sub(r, modulus);
+
+ fprime_copy(plusa, r);
+ fprime_add(plusa, a, modulus);
+
+ fprime_select(r, r, plusa, bit);
+ }
+}
+
+void fprime_inv(uint8_t *r, const uint8_t *a, const uint8_t *modulus)
+{
+ uint8_t pm2[FPRIME_SIZE];
+ uint16_t c = 2;
+ int i;
+
+ /* Compute (p-2) */
+ fprime_copy(pm2, modulus);
+ for (i = 0; i < FPRIME_SIZE; i++) {
+ c = modulus[i] - c;
+ pm2[i] = c;
+ c >>= 8;
+ }
+
+ /* Binary exponentiation */
+ fprime_load(r, 1);
+
+ for (i = prime_msb(modulus); i >= 0; i--) {
+ uint8_t r2[FPRIME_SIZE];
+
+ fprime_mul(r2, r, r, modulus);
+
+ if ((pm2[i >> 3] >> (i & 7)) & 1)
+ fprime_mul(r, r2, a, modulus);
+ else
+ fprime_copy(r, r2);
+ }
+}
diff --git a/lib/Utils.Cryptography/monocypher/vendor/tests/externals/c25519/fprime.h b/lib/Utils.Cryptography/monocypher/vendor/tests/externals/c25519/fprime.h
new file mode 100644
index 0000000..4a5486c
--- /dev/null
+++ b/lib/Utils.Cryptography/monocypher/vendor/tests/externals/c25519/fprime.h
@@ -0,0 +1,70 @@
+/* Arithmetic in prime fields
+ * Daniel Beer <dlbeer@gmail.com>, 10 Jan 2014
+ *
+ * This file is in the public domain.
+ */
+
+#ifndef FPRIME_H_
+#define FPRIME_H_
+
+#include <stdint.h>
+#include <string.h>
+
+/* Maximum size of a field element (or a prime). Field elements are
+ * always manipulated and stored in normalized form, with 0 <= x < p.
+ * You can use normalize() to convert a denormalized bitstring to normal
+ * form.
+ *
+ * Operations are constant with respect to the value of field elements,
+ * but not with respect to the modulus.
+ *
+ * The modulus is a number p, such that 2p-1 fits in FPRIME_SIZE bytes.
+ */
+#define FPRIME_SIZE 32
+
+/* Useful constants */
+extern const uint8_t fprime_zero[FPRIME_SIZE];
+extern const uint8_t fprime_one[FPRIME_SIZE];
+
+/* Load a small constant */
+void fprime_load(uint8_t *x, uint32_t c);
+
+/* Load a large constant */
+void fprime_from_bytes(uint8_t *x,
+ const uint8_t *in, size_t len,
+ const uint8_t *modulus);
+
+/* Copy an element */
+static inline void fprime_copy(uint8_t *x, const uint8_t *a)
+{
+ memcpy(x, a, FPRIME_SIZE);
+}
+
+/* Normalize a field element */
+void fprime_normalize(uint8_t *x, const uint8_t *modulus);
+
+/* Compare two field points in constant time. Return one if equal, zero
+ * otherwise. This should be performed only on normalized values.
+ */
+uint8_t fprime_eq(const uint8_t *x, const uint8_t *y);
+
+/* Conditional copy. If condition == 0, then zero is copied to dst. If
+ * condition == 1, then one is copied to dst. Any other value results in
+ * undefined behaviour.
+ */
+void fprime_select(uint8_t *dst,
+ const uint8_t *zero, const uint8_t *one,
+ uint8_t condition);
+
+/* Add one value to another. The two pointers must be distinct. */
+void fprime_add(uint8_t *r, const uint8_t *a, const uint8_t *modulus);
+void fprime_sub(uint8_t *r, const uint8_t *a, const uint8_t *modulus);
+
+/* Multiply two values to get a third. r must be distinct from a and b */
+void fprime_mul(uint8_t *r, const uint8_t *a, const uint8_t *b,
+ const uint8_t *modulus);
+
+/* Compute multiplicative inverse. r must be distinct from a */
+void fprime_inv(uint8_t *r, const uint8_t *a, const uint8_t *modulus);
+
+#endif
diff --git a/lib/Utils.Cryptography/monocypher/vendor/tests/externals/c25519/morph25519.c b/lib/Utils.Cryptography/monocypher/vendor/tests/externals/c25519/morph25519.c
new file mode 100644
index 0000000..3d64022
--- /dev/null
+++ b/lib/Utils.Cryptography/monocypher/vendor/tests/externals/c25519/morph25519.c
@@ -0,0 +1,87 @@
+/* Montgomery <-> Edwards isomorphism
+ * Daniel Beer <dlbeer@gmail.com>, 18 Jan 2014
+ *
+ * This file is in the public domain.
+ */
+
+#include "morph25519.h"
+#include "f25519.h"
+
+void morph25519_e2m(uint8_t *montgomery, const uint8_t *y)
+{
+ uint8_t yplus[F25519_SIZE];
+ uint8_t yminus[F25519_SIZE];
+
+ f25519_sub(yplus, f25519_one, y);
+ f25519_inv__distinct(yminus, yplus);
+ f25519_add(yplus, f25519_one, y);
+ f25519_mul__distinct(montgomery, yplus, yminus);
+ f25519_normalize(montgomery);
+}
+
+static void mx2ey(uint8_t *ey, const uint8_t *mx)
+{
+ uint8_t n[F25519_SIZE];
+ uint8_t d[F25519_SIZE];
+
+ f25519_add(n, mx, f25519_one);
+ f25519_inv__distinct(d, n);
+ f25519_sub(n, mx, f25519_one);
+ f25519_mul__distinct(ey, n, d);
+}
+
+static uint8_t ey2ex(uint8_t *x, const uint8_t *y, int parity)
+{
+ static const uint8_t d[F25519_SIZE] = {
+ 0xa3, 0x78, 0x59, 0x13, 0xca, 0x4d, 0xeb, 0x75,
+ 0xab, 0xd8, 0x41, 0x41, 0x4d, 0x0a, 0x70, 0x00,
+ 0x98, 0xe8, 0x79, 0x77, 0x79, 0x40, 0xc7, 0x8c,
+ 0x73, 0xfe, 0x6f, 0x2b, 0xee, 0x6c, 0x03, 0x52
+ };
+
+ uint8_t a[F25519_SIZE];
+ uint8_t b[F25519_SIZE];
+ uint8_t c[F25519_SIZE];
+
+ /* Compute c = y^2 */
+ f25519_mul__distinct(c, y, y);
+
+ /* Compute b = (1+dy^2)^-1 */
+ f25519_mul__distinct(b, c, d);
+ f25519_add(a, b, f25519_one);
+ f25519_inv__distinct(b, a);
+
+ /* Compute a = y^2-1 */
+ f25519_sub(a, c, f25519_one);
+
+ /* Compute c = a*b = (y^2+1)/(1-dy^2) */
+ f25519_mul__distinct(c, a, b);
+
+ /* Compute a, b = +/-sqrt(c), if c is square */
+ f25519_sqrt(a, c);
+ f25519_neg(b, a);
+
+ /* Select one of them, based on the parity bit */
+ f25519_select(x, a, b, (a[0] ^ parity) & 1);
+
+ /* Verify that x^2 = c */
+ f25519_mul__distinct(a, x, x);
+ f25519_normalize(a);
+ f25519_normalize(c);
+
+ return f25519_eq(a, c);
+}
+
+uint8_t morph25519_m2e(uint8_t *ex, uint8_t *ey,
+ const uint8_t *mx, int parity)
+{
+ uint8_t ok;
+
+ mx2ey(ey, mx);
+ ok = ey2ex(ex, ey, parity);
+
+ f25519_normalize(ex);
+ f25519_normalize(ey);
+
+ return ok;
+}
diff --git a/lib/Utils.Cryptography/monocypher/vendor/tests/externals/c25519/morph25519.h b/lib/Utils.Cryptography/monocypher/vendor/tests/externals/c25519/morph25519.h
new file mode 100644
index 0000000..ead91f4
--- /dev/null
+++ b/lib/Utils.Cryptography/monocypher/vendor/tests/externals/c25519/morph25519.h
@@ -0,0 +1,29 @@
+/* Montgomery <-> Edwards isomorphism
+ * Daniel Beer <dlbeer@gmail.com>, 18 Jan 2014
+ *
+ * This file is in the public domain.
+ */
+
+#ifndef MORPH25519_H_
+#define MORPH25519_H_
+
+#include <stdint.h>
+
+/* Convert an Edwards Y to a Montgomery X (Edwards X is not used).
+ * Resulting coordinate is normalized.
+ */
+void morph25519_e2m(uint8_t *montgomery_x, const uint8_t *edwards_y);
+
+/* Return a parity bit for the Edwards X coordinate */
+static inline int morph25519_eparity(const uint8_t *edwards_x)
+{
+ return edwards_x[0] & 1;
+}
+
+/* Convert a Montgomery X and a parity bit to an Edwards X/Y. Returns
+ * non-zero if successful.
+ */
+uint8_t morph25519_m2e(uint8_t *ex, uint8_t *ey,
+ const uint8_t *mx, int parity);
+
+#endif
diff --git a/lib/Utils.Cryptography/monocypher/vendor/tests/externals/c25519/sha512.c b/lib/Utils.Cryptography/monocypher/vendor/tests/externals/c25519/sha512.c
new file mode 100644
index 0000000..d90d22d
--- /dev/null
+++ b/lib/Utils.Cryptography/monocypher/vendor/tests/externals/c25519/sha512.c
@@ -0,0 +1,228 @@
+/* SHA512
+ * Daniel Beer <dlbeer@gmail.com>, 22 Apr 2014
+ *
+ * This file is in the public domain.
+ */
+
+#include "sha512.h"
+
+const struct sha512_state sha512_initial_state = { {
+ 0x6a09e667f3bcc908LL, 0xbb67ae8584caa73bLL,
+ 0x3c6ef372fe94f82bLL, 0xa54ff53a5f1d36f1LL,
+ 0x510e527fade682d1LL, 0x9b05688c2b3e6c1fLL,
+ 0x1f83d9abfb41bd6bLL, 0x5be0cd19137e2179LL,
+} };
+
+static const uint64_t round_k[80] = {
+ 0x428a2f98d728ae22LL, 0x7137449123ef65cdLL,
+ 0xb5c0fbcfec4d3b2fLL, 0xe9b5dba58189dbbcLL,
+ 0x3956c25bf348b538LL, 0x59f111f1b605d019LL,
+ 0x923f82a4af194f9bLL, 0xab1c5ed5da6d8118LL,
+ 0xd807aa98a3030242LL, 0x12835b0145706fbeLL,
+ 0x243185be4ee4b28cLL, 0x550c7dc3d5ffb4e2LL,
+ 0x72be5d74f27b896fLL, 0x80deb1fe3b1696b1LL,
+ 0x9bdc06a725c71235LL, 0xc19bf174cf692694LL,
+ 0xe49b69c19ef14ad2LL, 0xefbe4786384f25e3LL,
+ 0x0fc19dc68b8cd5b5LL, 0x240ca1cc77ac9c65LL,
+ 0x2de92c6f592b0275LL, 0x4a7484aa6ea6e483LL,
+ 0x5cb0a9dcbd41fbd4LL, 0x76f988da831153b5LL,
+ 0x983e5152ee66dfabLL, 0xa831c66d2db43210LL,
+ 0xb00327c898fb213fLL, 0xbf597fc7beef0ee4LL,
+ 0xc6e00bf33da88fc2LL, 0xd5a79147930aa725LL,
+ 0x06ca6351e003826fLL, 0x142929670a0e6e70LL,
+ 0x27b70a8546d22ffcLL, 0x2e1b21385c26c926LL,
+ 0x4d2c6dfc5ac42aedLL, 0x53380d139d95b3dfLL,
+ 0x650a73548baf63deLL, 0x766a0abb3c77b2a8LL,
+ 0x81c2c92e47edaee6LL, 0x92722c851482353bLL,
+ 0xa2bfe8a14cf10364LL, 0xa81a664bbc423001LL,
+ 0xc24b8b70d0f89791LL, 0xc76c51a30654be30LL,
+ 0xd192e819d6ef5218LL, 0xd69906245565a910LL,
+ 0xf40e35855771202aLL, 0x106aa07032bbd1b8LL,
+ 0x19a4c116b8d2d0c8LL, 0x1e376c085141ab53LL,
+ 0x2748774cdf8eeb99LL, 0x34b0bcb5e19b48a8LL,
+ 0x391c0cb3c5c95a63LL, 0x4ed8aa4ae3418acbLL,
+ 0x5b9cca4f7763e373LL, 0x682e6ff3d6b2b8a3LL,
+ 0x748f82ee5defb2fcLL, 0x78a5636f43172f60LL,
+ 0x84c87814a1f0ab72LL, 0x8cc702081a6439ecLL,
+ 0x90befffa23631e28LL, 0xa4506cebde82bde9LL,
+ 0xbef9a3f7b2c67915LL, 0xc67178f2e372532bLL,
+ 0xca273eceea26619cLL, 0xd186b8c721c0c207LL,
+ 0xeada7dd6cde0eb1eLL, 0xf57d4f7fee6ed178LL,
+ 0x06f067aa72176fbaLL, 0x0a637dc5a2c898a6LL,
+ 0x113f9804bef90daeLL, 0x1b710b35131c471bLL,
+ 0x28db77f523047d84LL, 0x32caab7b40c72493LL,
+ 0x3c9ebe0a15c9bebcLL, 0x431d67c49c100d4cLL,
+ 0x4cc5d4becb3e42b6LL, 0x597f299cfc657e2aLL,
+ 0x5fcb6fab3ad6faecLL, 0x6c44198c4a475817LL,
+};
+
+static inline uint64_t load64(const uint8_t *x)
+{
+ uint64_t r;
+
+ r = *(x++);
+ r = (r << 8) | *(x++);
+ r = (r << 8) | *(x++);
+ r = (r << 8) | *(x++);
+ r = (r << 8) | *(x++);
+ r = (r << 8) | *(x++);
+ r = (r << 8) | *(x++);
+ r = (r << 8) | *(x++);
+
+ return r;
+}
+
+static inline void store64(uint8_t *x, uint64_t v)
+{
+ x += 7;
+ *(x--) = v;
+ v >>= 8;
+ *(x--) = v;
+ v >>= 8;
+ *(x--) = v;
+ v >>= 8;
+ *(x--) = v;
+ v >>= 8;
+ *(x--) = v;
+ v >>= 8;
+ *(x--) = v;
+ v >>= 8;
+ *(x--) = v;
+ v >>= 8;
+ *(x--) = v;
+}
+
+static inline uint64_t rot64(uint64_t x, int bits)
+{
+ return (x >> bits) | (x << (64 - bits));
+}
+
+void sha512_block(struct sha512_state *s, const uint8_t *blk)
+{
+ uint64_t w[16];
+ uint64_t a, b, c, d, e, f, g, h;
+ int i;
+
+ for (i = 0; i < 16; i++) {
+ w[i] = load64(blk);
+ blk += 8;
+ }
+
+ /* Load state */
+ a = s->h[0];
+ b = s->h[1];
+ c = s->h[2];
+ d = s->h[3];
+ e = s->h[4];
+ f = s->h[5];
+ g = s->h[6];
+ h = s->h[7];
+
+ for (i = 0; i < 80; i++) {
+ /* Compute value of w[i + 16]. w[wrap(i)] is currently w[i] */
+ const uint64_t wi = w[i & 15];
+ const uint64_t wi15 = w[(i + 1) & 15];
+ const uint64_t wi2 = w[(i + 14) & 15];
+ const uint64_t wi7 = w[(i + 9) & 15];
+ const uint64_t s0 =
+ rot64(wi15, 1) ^ rot64(wi15, 8) ^ (wi15 >> 7);
+ const uint64_t s1 =
+ rot64(wi2, 19) ^ rot64(wi2, 61) ^ (wi2 >> 6);
+
+ /* Round calculations */
+ const uint64_t S0 = rot64(a, 28) ^ rot64(a, 34) ^ rot64(a, 39);
+ const uint64_t S1 = rot64(e, 14) ^ rot64(e, 18) ^ rot64(e, 41);
+ const uint64_t ch = (e & f) ^ ((~e) & g);
+ const uint64_t temp1 = h + S1 + ch + round_k[i] + wi;
+ const uint64_t maj = (a & b) ^ (a & c) ^ (b & c);
+ const uint64_t temp2 = S0 + maj;
+
+ /* Update round state */
+ h = g;
+ g = f;
+ f = e;
+ e = d + temp1;
+ d = c;
+ c = b;
+ b = a;
+ a = temp1 + temp2;
+
+ /* w[wrap(i)] becomes w[i + 16] */
+ w[i & 15] = wi + s0 + wi7 + s1;
+ }
+
+ /* Store state */
+ s->h[0] += a;
+ s->h[1] += b;
+ s->h[2] += c;
+ s->h[3] += d;
+ s->h[4] += e;
+ s->h[5] += f;
+ s->h[6] += g;
+ s->h[7] += h;
+}
+
+void sha512_final(struct sha512_state *s, const uint8_t *blk,
+ size_t total_size)
+{
+ uint8_t temp[SHA512_BLOCK_SIZE] = {0};
+ const size_t last_size = total_size & (SHA512_BLOCK_SIZE - 1);
+
+ if (last_size)
+ memcpy(temp, blk, last_size);
+ temp[last_size] = 0x80;
+
+ if (last_size > 111) {
+ sha512_block(s, temp);
+ memset(temp, 0, sizeof(temp));
+ }
+
+ /* Note: we assume total_size fits in 61 bits */
+ store64(temp + SHA512_BLOCK_SIZE - 8, total_size << 3);
+ sha512_block(s, temp);
+}
+
+void sha512_get(const struct sha512_state *s, uint8_t *hash,
+ unsigned int offset, unsigned int len)
+{
+ int i;
+
+ if (offset > SHA512_BLOCK_SIZE)
+ return;
+
+ if (len > SHA512_BLOCK_SIZE - offset)
+ len = SHA512_BLOCK_SIZE - offset;
+
+ /* Skip whole words */
+ i = offset >> 3;
+ offset &= 7;
+
+ /* Skip/read out bytes */
+ if (offset) {
+ uint8_t tmp[8];
+ unsigned int c = 8 - offset;
+
+ if (c > len)
+ c = len;
+
+ store64(tmp, s->h[i++]);
+ memcpy(hash, tmp + offset, c);
+ len -= c;
+ hash += c;
+ }
+
+ /* Read out whole words */
+ while (len >= 8) {
+ store64(hash, s->h[i++]);
+ hash += 8;
+ len -= 8;
+ }
+
+ /* Read out bytes */
+ if (len) {
+ uint8_t tmp[8];
+
+ store64(tmp, s->h[i]);
+ memcpy(hash, tmp, len);
+ }
+}
diff --git a/lib/Utils.Cryptography/monocypher/vendor/tests/externals/c25519/sha512.h b/lib/Utils.Cryptography/monocypher/vendor/tests/externals/c25519/sha512.h
new file mode 100644
index 0000000..1391745
--- /dev/null
+++ b/lib/Utils.Cryptography/monocypher/vendor/tests/externals/c25519/sha512.h
@@ -0,0 +1,52 @@
+/* SHA512
+ * Daniel Beer <dlbeer@gmail.com>, 22 Apr 2014
+ *
+ * This file is in the public domain.
+ */
+
+#ifndef SHA512_H_
+#define SHA512_H_
+
+#include <stdint.h>
+#include <stddef.h>
+#include <string.h>
+
+/* SHA512 state. State is updated as data is fed in, and then the final
+ * hash can be read out in slices.
+ *
+ * Data is fed in as a sequence of full blocks terminated by a single
+ * partial block.
+ */
+struct sha512_state {
+ uint64_t h[8];
+};
+
+/* Initial state */
+extern const struct sha512_state sha512_initial_state;
+
+/* Set up a new context */
+static inline void sha512_init(struct sha512_state *s)
+{
+ memcpy(s, &sha512_initial_state, sizeof(*s));
+}
+
+/* Feed a full block in */
+#define SHA512_BLOCK_SIZE 128
+
+void sha512_block(struct sha512_state *s, const uint8_t *blk);
+
+/* Feed the last partial block in. The total stream size must be
+ * specified. The size of the block given is assumed to be (total_size %
+ * SHA512_BLOCK_SIZE). This might be zero, but you still need to call
+ * this function to terminate the stream.
+ */
+void sha512_final(struct sha512_state *s, const uint8_t *blk,
+ size_t total_size);
+
+/* Fetch a slice of the hash result. */
+#define SHA512_HASH_SIZE 64
+
+void sha512_get(const struct sha512_state *s, uint8_t *hash,
+ unsigned int offset, unsigned int len);
+
+#endif
diff --git a/lib/Utils.Cryptography/monocypher/vendor/tests/externals/ed25519-donna/AUTHORS.md b/lib/Utils.Cryptography/monocypher/vendor/tests/externals/ed25519-donna/AUTHORS.md
new file mode 100644
index 0000000..79cf545
--- /dev/null
+++ b/lib/Utils.Cryptography/monocypher/vendor/tests/externals/ed25519-donna/AUTHORS.md
@@ -0,0 +1,42 @@
+The following files have been written by Andrew Moon and have been
+dedicated to the public domain:
+
+* curve25519-donna-32bit.h
+* curve25519-donna-helpers.h
+* ed25519.c
+* modm-donna-32bit.h
+
+The following files carry no copyright information:
+
+* ed25519-donna-32bit-tables.h
+* ed25519-donna-basepoint-table.h
+* ed25519-donna-batchverify.h
+* ed25519-donna-impl-base.h
+* ed25519-donna-portable-identify.h
+* ed25519-donna-portable.h
+* ed25519-hash-custom.h
+* ed25519-hash.h
+* ed25519-randombytes.h
+* ed25519.h
+
+However, their git history shows that they were written by Andrew Moon
+as well; the initial check-in has public domain headers for all files
+(git commit a98e950f). Newer files lack a similar header, but it seems
+the author didn't realise that that adding them would be required
+(see https://github.com/floodyberry/ed25519-donna/issues/24);
+issue comment 24#issuecomment-82552250 in particular seems to suggest as
+much. It is therefore assumed that they are intended to be placed in
+the public domain as well.
+
+curve25519-donna.h has been modified by Andrew Moon, based on the
+amd64-51-30k implementation by Daniel J. Bernstein, Niels Duif,
+Tanja Lange, Peter Schwabe, and Bo-Yin Yang. The amd64-51-30k
+implementation is contained in SUPERCOP
+(<https://bench.cr.yp.to/supercop.html>);
+the amd64-51-30k is part of the Ed25519 software, which has been
+dedicated to the public domain by its authors
+(<https://ed25519.cr.yp.to/software.html>).
+
+The code in this directory has been obtained via
+<https://www.github.com/floodyberry/ed25519-donna>.
+
diff --git a/lib/Utils.Cryptography/monocypher/vendor/tests/externals/ed25519-donna/curve25519-donna-32bit.h b/lib/Utils.Cryptography/monocypher/vendor/tests/externals/ed25519-donna/curve25519-donna-32bit.h
new file mode 100644
index 0000000..b0861ac
--- /dev/null
+++ b/lib/Utils.Cryptography/monocypher/vendor/tests/externals/ed25519-donna/curve25519-donna-32bit.h
@@ -0,0 +1,579 @@
+/*
+ Public domain by Andrew M. <liquidsun@gmail.com>
+ See: https://github.com/floodyberry/curve25519-donna
+
+ 32 bit integer curve25519 implementation
+*/
+
+typedef uint32_t bignum25519[10];
+typedef uint32_t bignum25519align16[12];
+
+static const uint32_t reduce_mask_25 = (1 << 25) - 1;
+static const uint32_t reduce_mask_26 = (1 << 26) - 1;
+
+
+/* out = in */
+DONNA_INLINE static void
+curve25519_copy(bignum25519 out, const bignum25519 in) {
+ out[0] = in[0];
+ out[1] = in[1];
+ out[2] = in[2];
+ out[3] = in[3];
+ out[4] = in[4];
+ out[5] = in[5];
+ out[6] = in[6];
+ out[7] = in[7];
+ out[8] = in[8];
+ out[9] = in[9];
+}
+
+/* out = a + b */
+DONNA_INLINE static void
+curve25519_add(bignum25519 out, const bignum25519 a, const bignum25519 b) {
+ out[0] = a[0] + b[0];
+ out[1] = a[1] + b[1];
+ out[2] = a[2] + b[2];
+ out[3] = a[3] + b[3];
+ out[4] = a[4] + b[4];
+ out[5] = a[5] + b[5];
+ out[6] = a[6] + b[6];
+ out[7] = a[7] + b[7];
+ out[8] = a[8] + b[8];
+ out[9] = a[9] + b[9];
+}
+
+DONNA_INLINE static void
+curve25519_add_after_basic(bignum25519 out, const bignum25519 a, const bignum25519 b) {
+ uint32_t c;
+ out[0] = a[0] + b[0] ; c = (out[0] >> 26); out[0] &= reduce_mask_26;
+ out[1] = a[1] + b[1] + c; c = (out[1] >> 25); out[1] &= reduce_mask_25;
+ out[2] = a[2] + b[2] + c; c = (out[2] >> 26); out[2] &= reduce_mask_26;
+ out[3] = a[3] + b[3] + c; c = (out[3] >> 25); out[3] &= reduce_mask_25;
+ out[4] = a[4] + b[4] + c; c = (out[4] >> 26); out[4] &= reduce_mask_26;
+ out[5] = a[5] + b[5] + c; c = (out[5] >> 25); out[5] &= reduce_mask_25;
+ out[6] = a[6] + b[6] + c; c = (out[6] >> 26); out[6] &= reduce_mask_26;
+ out[7] = a[7] + b[7] + c; c = (out[7] >> 25); out[7] &= reduce_mask_25;
+ out[8] = a[8] + b[8] + c; c = (out[8] >> 26); out[8] &= reduce_mask_26;
+ out[9] = a[9] + b[9] + c; c = (out[9] >> 25); out[9] &= reduce_mask_25;
+ out[0] += 19 * c;
+}
+
+DONNA_INLINE static void
+curve25519_add_reduce(bignum25519 out, const bignum25519 a, const bignum25519 b) {
+ uint32_t c;
+ out[0] = a[0] + b[0] ; c = (out[0] >> 26); out[0] &= reduce_mask_26;
+ out[1] = a[1] + b[1] + c; c = (out[1] >> 25); out[1] &= reduce_mask_25;
+ out[2] = a[2] + b[2] + c; c = (out[2] >> 26); out[2] &= reduce_mask_26;
+ out[3] = a[3] + b[3] + c; c = (out[3] >> 25); out[3] &= reduce_mask_25;
+ out[4] = a[4] + b[4] + c; c = (out[4] >> 26); out[4] &= reduce_mask_26;
+ out[5] = a[5] + b[5] + c; c = (out[5] >> 25); out[5] &= reduce_mask_25;
+ out[6] = a[6] + b[6] + c; c = (out[6] >> 26); out[6] &= reduce_mask_26;
+ out[7] = a[7] + b[7] + c; c = (out[7] >> 25); out[7] &= reduce_mask_25;
+ out[8] = a[8] + b[8] + c; c = (out[8] >> 26); out[8] &= reduce_mask_26;
+ out[9] = a[9] + b[9] + c; c = (out[9] >> 25); out[9] &= reduce_mask_25;
+ out[0] += 19 * c;
+}
+
+/* multiples of p */
+static const uint32_t twoP0 = 0x07ffffda;
+static const uint32_t twoP13579 = 0x03fffffe;
+static const uint32_t twoP2468 = 0x07fffffe;
+static const uint32_t fourP0 = 0x0fffffb4;
+static const uint32_t fourP13579 = 0x07fffffc;
+static const uint32_t fourP2468 = 0x0ffffffc;
+
+/* out = a - b */
+DONNA_INLINE static void
+curve25519_sub(bignum25519 out, const bignum25519 a, const bignum25519 b) {
+ uint32_t c;
+ out[0] = twoP0 + a[0] - b[0] ; c = (out[0] >> 26); out[0] &= reduce_mask_26;
+ out[1] = twoP13579 + a[1] - b[1] + c; c = (out[1] >> 25); out[1] &= reduce_mask_25;
+ out[2] = twoP2468 + a[2] - b[2] + c; c = (out[2] >> 26); out[2] &= reduce_mask_26;
+ out[3] = twoP13579 + a[3] - b[3] + c; c = (out[3] >> 25); out[3] &= reduce_mask_25;
+ out[4] = twoP2468 + a[4] - b[4] + c;
+ out[5] = twoP13579 + a[5] - b[5] ;
+ out[6] = twoP2468 + a[6] - b[6] ;
+ out[7] = twoP13579 + a[7] - b[7] ;
+ out[8] = twoP2468 + a[8] - b[8] ;
+ out[9] = twoP13579 + a[9] - b[9] ;
+}
+
+/* out = a - b, where a is the result of a basic op (add,sub) */
+DONNA_INLINE static void
+curve25519_sub_after_basic(bignum25519 out, const bignum25519 a, const bignum25519 b) {
+ uint32_t c;
+ out[0] = fourP0 + a[0] - b[0] ; c = (out[0] >> 26); out[0] &= reduce_mask_26;
+ out[1] = fourP13579 + a[1] - b[1] + c; c = (out[1] >> 25); out[1] &= reduce_mask_25;
+ out[2] = fourP2468 + a[2] - b[2] + c; c = (out[2] >> 26); out[2] &= reduce_mask_26;
+ out[3] = fourP13579 + a[3] - b[3] + c; c = (out[3] >> 25); out[3] &= reduce_mask_25;
+ out[4] = fourP2468 + a[4] - b[4] + c; c = (out[4] >> 26); out[4] &= reduce_mask_26;
+ out[5] = fourP13579 + a[5] - b[5] + c; c = (out[5] >> 25); out[5] &= reduce_mask_25;
+ out[6] = fourP2468 + a[6] - b[6] + c; c = (out[6] >> 26); out[6] &= reduce_mask_26;
+ out[7] = fourP13579 + a[7] - b[7] + c; c = (out[7] >> 25); out[7] &= reduce_mask_25;
+ out[8] = fourP2468 + a[8] - b[8] + c; c = (out[8] >> 26); out[8] &= reduce_mask_26;
+ out[9] = fourP13579 + a[9] - b[9] + c; c = (out[9] >> 25); out[9] &= reduce_mask_25;
+ out[0] += 19 * c;
+}
+
+DONNA_INLINE static void
+curve25519_sub_reduce(bignum25519 out, const bignum25519 a, const bignum25519 b) {
+ uint32_t c;
+ out[0] = fourP0 + a[0] - b[0] ; c = (out[0] >> 26); out[0] &= reduce_mask_26;
+ out[1] = fourP13579 + a[1] - b[1] + c; c = (out[1] >> 25); out[1] &= reduce_mask_25;
+ out[2] = fourP2468 + a[2] - b[2] + c; c = (out[2] >> 26); out[2] &= reduce_mask_26;
+ out[3] = fourP13579 + a[3] - b[3] + c; c = (out[3] >> 25); out[3] &= reduce_mask_25;
+ out[4] = fourP2468 + a[4] - b[4] + c; c = (out[4] >> 26); out[4] &= reduce_mask_26;
+ out[5] = fourP13579 + a[5] - b[5] + c; c = (out[5] >> 25); out[5] &= reduce_mask_25;
+ out[6] = fourP2468 + a[6] - b[6] + c; c = (out[6] >> 26); out[6] &= reduce_mask_26;
+ out[7] = fourP13579 + a[7] - b[7] + c; c = (out[7] >> 25); out[7] &= reduce_mask_25;
+ out[8] = fourP2468 + a[8] - b[8] + c; c = (out[8] >> 26); out[8] &= reduce_mask_26;
+ out[9] = fourP13579 + a[9] - b[9] + c; c = (out[9] >> 25); out[9] &= reduce_mask_25;
+ out[0] += 19 * c;
+}
+
+/* out = -a */
+DONNA_INLINE static void
+curve25519_neg(bignum25519 out, const bignum25519 a) {
+ uint32_t c;
+ out[0] = twoP0 - a[0] ; c = (out[0] >> 26); out[0] &= reduce_mask_26;
+ out[1] = twoP13579 - a[1] + c; c = (out[1] >> 25); out[1] &= reduce_mask_25;
+ out[2] = twoP2468 - a[2] + c; c = (out[2] >> 26); out[2] &= reduce_mask_26;
+ out[3] = twoP13579 - a[3] + c; c = (out[3] >> 25); out[3] &= reduce_mask_25;
+ out[4] = twoP2468 - a[4] + c; c = (out[4] >> 26); out[4] &= reduce_mask_26;
+ out[5] = twoP13579 - a[5] + c; c = (out[5] >> 25); out[5] &= reduce_mask_25;
+ out[6] = twoP2468 - a[6] + c; c = (out[6] >> 26); out[6] &= reduce_mask_26;
+ out[7] = twoP13579 - a[7] + c; c = (out[7] >> 25); out[7] &= reduce_mask_25;
+ out[8] = twoP2468 - a[8] + c; c = (out[8] >> 26); out[8] &= reduce_mask_26;
+ out[9] = twoP13579 - a[9] + c; c = (out[9] >> 25); out[9] &= reduce_mask_25;
+ out[0] += 19 * c;
+}
+
+/* out = a * b */
+#define curve25519_mul_noinline curve25519_mul
+static void
+curve25519_mul(bignum25519 out, const bignum25519 a, const bignum25519 b) {
+ uint32_t r0,r1,r2,r3,r4,r5,r6,r7,r8,r9;
+ uint32_t s0,s1,s2,s3,s4,s5,s6,s7,s8,s9;
+ uint64_t m0,m1,m2,m3,m4,m5,m6,m7,m8,m9,c;
+ uint32_t p;
+
+ r0 = b[0];
+ r1 = b[1];
+ r2 = b[2];
+ r3 = b[3];
+ r4 = b[4];
+ r5 = b[5];
+ r6 = b[6];
+ r7 = b[7];
+ r8 = b[8];
+ r9 = b[9];
+
+ s0 = a[0];
+ s1 = a[1];
+ s2 = a[2];
+ s3 = a[3];
+ s4 = a[4];
+ s5 = a[5];
+ s6 = a[6];
+ s7 = a[7];
+ s8 = a[8];
+ s9 = a[9];
+
+ m1 = mul32x32_64(r0, s1) + mul32x32_64(r1, s0);
+ m3 = mul32x32_64(r0, s3) + mul32x32_64(r1, s2) + mul32x32_64(r2, s1) + mul32x32_64(r3, s0);
+ m5 = mul32x32_64(r0, s5) + mul32x32_64(r1, s4) + mul32x32_64(r2, s3) + mul32x32_64(r3, s2) + mul32x32_64(r4, s1) + mul32x32_64(r5, s0);
+ m7 = mul32x32_64(r0, s7) + mul32x32_64(r1, s6) + mul32x32_64(r2, s5) + mul32x32_64(r3, s4) + mul32x32_64(r4, s3) + mul32x32_64(r5, s2) + mul32x32_64(r6, s1) + mul32x32_64(r7, s0);
+ m9 = mul32x32_64(r0, s9) + mul32x32_64(r1, s8) + mul32x32_64(r2, s7) + mul32x32_64(r3, s6) + mul32x32_64(r4, s5) + mul32x32_64(r5, s4) + mul32x32_64(r6, s3) + mul32x32_64(r7, s2) + mul32x32_64(r8, s1) + mul32x32_64(r9, s0);
+
+ r1 *= 2;
+ r3 *= 2;
+ r5 *= 2;
+ r7 *= 2;
+
+ m0 = mul32x32_64(r0, s0);
+ m2 = mul32x32_64(r0, s2) + mul32x32_64(r1, s1) + mul32x32_64(r2, s0);
+ m4 = mul32x32_64(r0, s4) + mul32x32_64(r1, s3) + mul32x32_64(r2, s2) + mul32x32_64(r3, s1) + mul32x32_64(r4, s0);
+ m6 = mul32x32_64(r0, s6) + mul32x32_64(r1, s5) + mul32x32_64(r2, s4) + mul32x32_64(r3, s3) + mul32x32_64(r4, s2) + mul32x32_64(r5, s1) + mul32x32_64(r6, s0);
+ m8 = mul32x32_64(r0, s8) + mul32x32_64(r1, s7) + mul32x32_64(r2, s6) + mul32x32_64(r3, s5) + mul32x32_64(r4, s4) + mul32x32_64(r5, s3) + mul32x32_64(r6, s2) + mul32x32_64(r7, s1) + mul32x32_64(r8, s0);
+
+ r1 *= 19;
+ r2 *= 19;
+ r3 = (r3 / 2) * 19;
+ r4 *= 19;
+ r5 = (r5 / 2) * 19;
+ r6 *= 19;
+ r7 = (r7 / 2) * 19;
+ r8 *= 19;
+ r9 *= 19;
+
+ m1 += (mul32x32_64(r9, s2) + mul32x32_64(r8, s3) + mul32x32_64(r7, s4) + mul32x32_64(r6, s5) + mul32x32_64(r5, s6) + mul32x32_64(r4, s7) + mul32x32_64(r3, s8) + mul32x32_64(r2, s9));
+ m3 += (mul32x32_64(r9, s4) + mul32x32_64(r8, s5) + mul32x32_64(r7, s6) + mul32x32_64(r6, s7) + mul32x32_64(r5, s8) + mul32x32_64(r4, s9));
+ m5 += (mul32x32_64(r9, s6) + mul32x32_64(r8, s7) + mul32x32_64(r7, s8) + mul32x32_64(r6, s9));
+ m7 += (mul32x32_64(r9, s8) + mul32x32_64(r8, s9));
+
+ r3 *= 2;
+ r5 *= 2;
+ r7 *= 2;
+ r9 *= 2;
+
+ m0 += (mul32x32_64(r9, s1) + mul32x32_64(r8, s2) + mul32x32_64(r7, s3) + mul32x32_64(r6, s4) + mul32x32_64(r5, s5) + mul32x32_64(r4, s6) + mul32x32_64(r3, s7) + mul32x32_64(r2, s8) + mul32x32_64(r1, s9));
+ m2 += (mul32x32_64(r9, s3) + mul32x32_64(r8, s4) + mul32x32_64(r7, s5) + mul32x32_64(r6, s6) + mul32x32_64(r5, s7) + mul32x32_64(r4, s8) + mul32x32_64(r3, s9));
+ m4 += (mul32x32_64(r9, s5) + mul32x32_64(r8, s6) + mul32x32_64(r7, s7) + mul32x32_64(r6, s8) + mul32x32_64(r5, s9));
+ m6 += (mul32x32_64(r9, s7) + mul32x32_64(r8, s8) + mul32x32_64(r7, s9));
+ m8 += (mul32x32_64(r9, s9));
+
+ r0 = (uint32_t)m0 & reduce_mask_26; c = (m0 >> 26);
+ m1 += c; r1 = (uint32_t)m1 & reduce_mask_25; c = (m1 >> 25);
+ m2 += c; r2 = (uint32_t)m2 & reduce_mask_26; c = (m2 >> 26);
+ m3 += c; r3 = (uint32_t)m3 & reduce_mask_25; c = (m3 >> 25);
+ m4 += c; r4 = (uint32_t)m4 & reduce_mask_26; c = (m4 >> 26);
+ m5 += c; r5 = (uint32_t)m5 & reduce_mask_25; c = (m5 >> 25);
+ m6 += c; r6 = (uint32_t)m6 & reduce_mask_26; c = (m6 >> 26);
+ m7 += c; r7 = (uint32_t)m7 & reduce_mask_25; c = (m7 >> 25);
+ m8 += c; r8 = (uint32_t)m8 & reduce_mask_26; c = (m8 >> 26);
+ m9 += c; r9 = (uint32_t)m9 & reduce_mask_25; p = (uint32_t)(m9 >> 25);
+ m0 = r0 + mul32x32_64(p,19); r0 = (uint32_t)m0 & reduce_mask_26; p = (uint32_t)(m0 >> 26);
+ r1 += p;
+
+ out[0] = r0;
+ out[1] = r1;
+ out[2] = r2;
+ out[3] = r3;
+ out[4] = r4;
+ out[5] = r5;
+ out[6] = r6;
+ out[7] = r7;
+ out[8] = r8;
+ out[9] = r9;
+}
+
+/* out = in*in */
+static void
+curve25519_square(bignum25519 out, const bignum25519 in) {
+ uint32_t r0,r1,r2,r3,r4,r5,r6,r7,r8,r9;
+ uint32_t d6,d7,d8,d9;
+ uint64_t m0,m1,m2,m3,m4,m5,m6,m7,m8,m9,c;
+ uint32_t p;
+
+ r0 = in[0];
+ r1 = in[1];
+ r2 = in[2];
+ r3 = in[3];
+ r4 = in[4];
+ r5 = in[5];
+ r6 = in[6];
+ r7 = in[7];
+ r8 = in[8];
+ r9 = in[9];
+
+ m0 = mul32x32_64(r0, r0);
+ r0 *= 2;
+ m1 = mul32x32_64(r0, r1);
+ m2 = mul32x32_64(r0, r2) + mul32x32_64(r1, r1 * 2);
+ r1 *= 2;
+ m3 = mul32x32_64(r0, r3) + mul32x32_64(r1, r2 );
+ m4 = mul32x32_64(r0, r4) + mul32x32_64(r1, r3 * 2) + mul32x32_64(r2, r2);
+ r2 *= 2;
+ m5 = mul32x32_64(r0, r5) + mul32x32_64(r1, r4 ) + mul32x32_64(r2, r3);
+ m6 = mul32x32_64(r0, r6) + mul32x32_64(r1, r5 * 2) + mul32x32_64(r2, r4) + mul32x32_64(r3, r3 * 2);
+ r3 *= 2;
+ m7 = mul32x32_64(r0, r7) + mul32x32_64(r1, r6 ) + mul32x32_64(r2, r5) + mul32x32_64(r3, r4 );
+ m8 = mul32x32_64(r0, r8) + mul32x32_64(r1, r7 * 2) + mul32x32_64(r2, r6) + mul32x32_64(r3, r5 * 2) + mul32x32_64(r4, r4 );
+ m9 = mul32x32_64(r0, r9) + mul32x32_64(r1, r8 ) + mul32x32_64(r2, r7) + mul32x32_64(r3, r6 ) + mul32x32_64(r4, r5 * 2);
+
+ d6 = r6 * 19;
+ d7 = r7 * 2 * 19;
+ d8 = r8 * 19;
+ d9 = r9 * 2 * 19;
+
+ m0 += (mul32x32_64(d9, r1 ) + mul32x32_64(d8, r2 ) + mul32x32_64(d7, r3 ) + mul32x32_64(d6, r4 * 2) + mul32x32_64(r5, r5 * 2 * 19));
+ m1 += (mul32x32_64(d9, r2 / 2) + mul32x32_64(d8, r3 ) + mul32x32_64(d7, r4 ) + mul32x32_64(d6, r5 * 2));
+ m2 += (mul32x32_64(d9, r3 ) + mul32x32_64(d8, r4 * 2) + mul32x32_64(d7, r5 * 2) + mul32x32_64(d6, r6 ));
+ m3 += (mul32x32_64(d9, r4 ) + mul32x32_64(d8, r5 * 2) + mul32x32_64(d7, r6 ));
+ m4 += (mul32x32_64(d9, r5 * 2) + mul32x32_64(d8, r6 * 2) + mul32x32_64(d7, r7 ));
+ m5 += (mul32x32_64(d9, r6 ) + mul32x32_64(d8, r7 * 2));
+ m6 += (mul32x32_64(d9, r7 * 2) + mul32x32_64(d8, r8 ));
+ m7 += (mul32x32_64(d9, r8 ));
+ m8 += (mul32x32_64(d9, r9 ));
+
+ r0 = (uint32_t)m0 & reduce_mask_26; c = (m0 >> 26);
+ m1 += c; r1 = (uint32_t)m1 & reduce_mask_25; c = (m1 >> 25);
+ m2 += c; r2 = (uint32_t)m2 & reduce_mask_26; c = (m2 >> 26);
+ m3 += c; r3 = (uint32_t)m3 & reduce_mask_25; c = (m3 >> 25);
+ m4 += c; r4 = (uint32_t)m4 & reduce_mask_26; c = (m4 >> 26);
+ m5 += c; r5 = (uint32_t)m5 & reduce_mask_25; c = (m5 >> 25);
+ m6 += c; r6 = (uint32_t)m6 & reduce_mask_26; c = (m6 >> 26);
+ m7 += c; r7 = (uint32_t)m7 & reduce_mask_25; c = (m7 >> 25);
+ m8 += c; r8 = (uint32_t)m8 & reduce_mask_26; c = (m8 >> 26);
+ m9 += c; r9 = (uint32_t)m9 & reduce_mask_25; p = (uint32_t)(m9 >> 25);
+ m0 = r0 + mul32x32_64(p,19); r0 = (uint32_t)m0 & reduce_mask_26; p = (uint32_t)(m0 >> 26);
+ r1 += p;
+
+ out[0] = r0;
+ out[1] = r1;
+ out[2] = r2;
+ out[3] = r3;
+ out[4] = r4;
+ out[5] = r5;
+ out[6] = r6;
+ out[7] = r7;
+ out[8] = r8;
+ out[9] = r9;
+}
+
+
+/* out = in ^ (2 * count) */
+static void
+curve25519_square_times(bignum25519 out, const bignum25519 in, int count) {
+ uint32_t r0,r1,r2,r3,r4,r5,r6,r7,r8,r9;
+ uint32_t d6,d7,d8,d9;
+ uint64_t m0,m1,m2,m3,m4,m5,m6,m7,m8,m9,c;
+ uint32_t p;
+
+ r0 = in[0];
+ r1 = in[1];
+ r2 = in[2];
+ r3 = in[3];
+ r4 = in[4];
+ r5 = in[5];
+ r6 = in[6];
+ r7 = in[7];
+ r8 = in[8];
+ r9 = in[9];
+
+ do {
+ m0 = mul32x32_64(r0, r0);
+ r0 *= 2;
+ m1 = mul32x32_64(r0, r1);
+ m2 = mul32x32_64(r0, r2) + mul32x32_64(r1, r1 * 2);
+ r1 *= 2;
+ m3 = mul32x32_64(r0, r3) + mul32x32_64(r1, r2 );
+ m4 = mul32x32_64(r0, r4) + mul32x32_64(r1, r3 * 2) + mul32x32_64(r2, r2);
+ r2 *= 2;
+ m5 = mul32x32_64(r0, r5) + mul32x32_64(r1, r4 ) + mul32x32_64(r2, r3);
+ m6 = mul32x32_64(r0, r6) + mul32x32_64(r1, r5 * 2) + mul32x32_64(r2, r4) + mul32x32_64(r3, r3 * 2);
+ r3 *= 2;
+ m7 = mul32x32_64(r0, r7) + mul32x32_64(r1, r6 ) + mul32x32_64(r2, r5) + mul32x32_64(r3, r4 );
+ m8 = mul32x32_64(r0, r8) + mul32x32_64(r1, r7 * 2) + mul32x32_64(r2, r6) + mul32x32_64(r3, r5 * 2) + mul32x32_64(r4, r4 );
+ m9 = mul32x32_64(r0, r9) + mul32x32_64(r1, r8 ) + mul32x32_64(r2, r7) + mul32x32_64(r3, r6 ) + mul32x32_64(r4, r5 * 2);
+
+ d6 = r6 * 19;
+ d7 = r7 * 2 * 19;
+ d8 = r8 * 19;
+ d9 = r9 * 2 * 19;
+
+ m0 += (mul32x32_64(d9, r1 ) + mul32x32_64(d8, r2 ) + mul32x32_64(d7, r3 ) + mul32x32_64(d6, r4 * 2) + mul32x32_64(r5, r5 * 2 * 19));
+ m1 += (mul32x32_64(d9, r2 / 2) + mul32x32_64(d8, r3 ) + mul32x32_64(d7, r4 ) + mul32x32_64(d6, r5 * 2));
+ m2 += (mul32x32_64(d9, r3 ) + mul32x32_64(d8, r4 * 2) + mul32x32_64(d7, r5 * 2) + mul32x32_64(d6, r6 ));
+ m3 += (mul32x32_64(d9, r4 ) + mul32x32_64(d8, r5 * 2) + mul32x32_64(d7, r6 ));
+ m4 += (mul32x32_64(d9, r5 * 2) + mul32x32_64(d8, r6 * 2) + mul32x32_64(d7, r7 ));
+ m5 += (mul32x32_64(d9, r6 ) + mul32x32_64(d8, r7 * 2));
+ m6 += (mul32x32_64(d9, r7 * 2) + mul32x32_64(d8, r8 ));
+ m7 += (mul32x32_64(d9, r8 ));
+ m8 += (mul32x32_64(d9, r9 ));
+
+ r0 = (uint32_t)m0 & reduce_mask_26; c = (m0 >> 26);
+ m1 += c; r1 = (uint32_t)m1 & reduce_mask_25; c = (m1 >> 25);
+ m2 += c; r2 = (uint32_t)m2 & reduce_mask_26; c = (m2 >> 26);
+ m3 += c; r3 = (uint32_t)m3 & reduce_mask_25; c = (m3 >> 25);
+ m4 += c; r4 = (uint32_t)m4 & reduce_mask_26; c = (m4 >> 26);
+ m5 += c; r5 = (uint32_t)m5 & reduce_mask_25; c = (m5 >> 25);
+ m6 += c; r6 = (uint32_t)m6 & reduce_mask_26; c = (m6 >> 26);
+ m7 += c; r7 = (uint32_t)m7 & reduce_mask_25; c = (m7 >> 25);
+ m8 += c; r8 = (uint32_t)m8 & reduce_mask_26; c = (m8 >> 26);
+ m9 += c; r9 = (uint32_t)m9 & reduce_mask_25; p = (uint32_t)(m9 >> 25);
+ m0 = r0 + mul32x32_64(p,19); r0 = (uint32_t)m0 & reduce_mask_26; p = (uint32_t)(m0 >> 26);
+ r1 += p;
+ } while (--count);
+
+ out[0] = r0;
+ out[1] = r1;
+ out[2] = r2;
+ out[3] = r3;
+ out[4] = r4;
+ out[5] = r5;
+ out[6] = r6;
+ out[7] = r7;
+ out[8] = r8;
+ out[9] = r9;
+}
+
+/* Take a little-endian, 32-byte number and expand it into polynomial form */
+static void
+curve25519_expand(bignum25519 out, const unsigned char in[32]) {
+ static const union { uint8_t b[2]; uint16_t s; } endian_check = {{1,0}};
+ uint32_t x0,x1,x2,x3,x4,x5,x6,x7;
+
+ if (endian_check.s == 1) {
+ x0 = *(uint32_t *)(in + 0);
+ x1 = *(uint32_t *)(in + 4);
+ x2 = *(uint32_t *)(in + 8);
+ x3 = *(uint32_t *)(in + 12);
+ x4 = *(uint32_t *)(in + 16);
+ x5 = *(uint32_t *)(in + 20);
+ x6 = *(uint32_t *)(in + 24);
+ x7 = *(uint32_t *)(in + 28);
+ } else {
+ #define F(s) \
+ ((((uint32_t)in[s + 0]) ) | \
+ (((uint32_t)in[s + 1]) << 8) | \
+ (((uint32_t)in[s + 2]) << 16) | \
+ (((uint32_t)in[s + 3]) << 24))
+ x0 = F(0);
+ x1 = F(4);
+ x2 = F(8);
+ x3 = F(12);
+ x4 = F(16);
+ x5 = F(20);
+ x6 = F(24);
+ x7 = F(28);
+ #undef F
+ }
+
+ out[0] = ( x0 ) & 0x3ffffff;
+ out[1] = ((((uint64_t)x1 << 32) | x0) >> 26) & 0x1ffffff;
+ out[2] = ((((uint64_t)x2 << 32) | x1) >> 19) & 0x3ffffff;
+ out[3] = ((((uint64_t)x3 << 32) | x2) >> 13) & 0x1ffffff;
+ out[4] = (( x3) >> 6) & 0x3ffffff;
+ out[5] = ( x4 ) & 0x1ffffff;
+ out[6] = ((((uint64_t)x5 << 32) | x4) >> 25) & 0x3ffffff;
+ out[7] = ((((uint64_t)x6 << 32) | x5) >> 19) & 0x1ffffff;
+ out[8] = ((((uint64_t)x7 << 32) | x6) >> 12) & 0x3ffffff;
+ out[9] = (( x7) >> 6) & 0x1ffffff;
+}
+
+/* Take a fully reduced polynomial form number and contract it into a
+ * little-endian, 32-byte array
+ */
+static void
+curve25519_contract(unsigned char out[32], const bignum25519 in) {
+ bignum25519 f;
+ curve25519_copy(f, in);
+
+ #define carry_pass() \
+ f[1] += f[0] >> 26; f[0] &= reduce_mask_26; \
+ f[2] += f[1] >> 25; f[1] &= reduce_mask_25; \
+ f[3] += f[2] >> 26; f[2] &= reduce_mask_26; \
+ f[4] += f[3] >> 25; f[3] &= reduce_mask_25; \
+ f[5] += f[4] >> 26; f[4] &= reduce_mask_26; \
+ f[6] += f[5] >> 25; f[5] &= reduce_mask_25; \
+ f[7] += f[6] >> 26; f[6] &= reduce_mask_26; \
+ f[8] += f[7] >> 25; f[7] &= reduce_mask_25; \
+ f[9] += f[8] >> 26; f[8] &= reduce_mask_26;
+
+ #define carry_pass_full() \
+ carry_pass() \
+ f[0] += 19 * (f[9] >> 25); f[9] &= reduce_mask_25;
+
+ #define carry_pass_final() \
+ carry_pass() \
+ f[9] &= reduce_mask_25;
+
+ carry_pass_full()
+ carry_pass_full()
+
+ /* 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. */
+ f[0] += 19;
+ carry_pass_full()
+
+ /* now between 19 and 2^255-1 in both cases, and offset by 19. */
+ f[0] += (reduce_mask_26 + 1) - 19;
+ f[1] += (reduce_mask_25 + 1) - 1;
+ f[2] += (reduce_mask_26 + 1) - 1;
+ f[3] += (reduce_mask_25 + 1) - 1;
+ f[4] += (reduce_mask_26 + 1) - 1;
+ f[5] += (reduce_mask_25 + 1) - 1;
+ f[6] += (reduce_mask_26 + 1) - 1;
+ f[7] += (reduce_mask_25 + 1) - 1;
+ f[8] += (reduce_mask_26 + 1) - 1;
+ f[9] += (reduce_mask_25 + 1) - 1;
+
+ /* now between 2^255 and 2^256-20, and offset by 2^255. */
+ carry_pass_final()
+
+ #undef carry_pass
+ #undef carry_full
+ #undef carry_final
+
+ f[1] <<= 2;
+ f[2] <<= 3;
+ f[3] <<= 5;
+ f[4] <<= 6;
+ f[6] <<= 1;
+ f[7] <<= 3;
+ f[8] <<= 4;
+ f[9] <<= 6;
+
+ #define F(i, s) \
+ out[s+0] |= (unsigned char )(f[i] & 0xff); \
+ out[s+1] = (unsigned char )((f[i] >> 8) & 0xff); \
+ out[s+2] = (unsigned char )((f[i] >> 16) & 0xff); \
+ out[s+3] = (unsigned char )((f[i] >> 24) & 0xff);
+
+ out[0] = 0;
+ out[16] = 0;
+ F(0,0);
+ F(1,3);
+ F(2,6);
+ F(3,9);
+ F(4,12);
+ F(5,16);
+ F(6,19);
+ F(7,22);
+ F(8,25);
+ F(9,28);
+ #undef F
+}
+
+
+/* out = (flag) ? in : out */
+DONNA_INLINE static void
+curve25519_move_conditional_bytes(uint8_t out[96], const uint8_t in[96], uint32_t flag) {
+ const uint32_t nb = flag - 1, b = ~nb;
+ const uint32_t *inl = (const uint32_t *)in;
+ uint32_t *outl = (uint32_t *)out;
+ outl[0] = (outl[0] & nb) | (inl[0] & b);
+ outl[1] = (outl[1] & nb) | (inl[1] & b);
+ outl[2] = (outl[2] & nb) | (inl[2] & b);
+ outl[3] = (outl[3] & nb) | (inl[3] & b);
+ outl[4] = (outl[4] & nb) | (inl[4] & b);
+ outl[5] = (outl[5] & nb) | (inl[5] & b);
+ outl[6] = (outl[6] & nb) | (inl[6] & b);
+ outl[7] = (outl[7] & nb) | (inl[7] & b);
+ outl[8] = (outl[8] & nb) | (inl[8] & b);
+ outl[9] = (outl[9] & nb) | (inl[9] & b);
+ outl[10] = (outl[10] & nb) | (inl[10] & b);
+ outl[11] = (outl[11] & nb) | (inl[11] & b);
+ outl[12] = (outl[12] & nb) | (inl[12] & b);
+ outl[13] = (outl[13] & nb) | (inl[13] & b);
+ outl[14] = (outl[14] & nb) | (inl[14] & b);
+ outl[15] = (outl[15] & nb) | (inl[15] & b);
+ outl[16] = (outl[16] & nb) | (inl[16] & b);
+ outl[17] = (outl[17] & nb) | (inl[17] & b);
+ outl[18] = (outl[18] & nb) | (inl[18] & b);
+ outl[19] = (outl[19] & nb) | (inl[19] & b);
+ outl[20] = (outl[20] & nb) | (inl[20] & b);
+ outl[21] = (outl[21] & nb) | (inl[21] & b);
+ outl[22] = (outl[22] & nb) | (inl[22] & b);
+ outl[23] = (outl[23] & nb) | (inl[23] & b);
+
+}
+
+/* if (iswap) swap(a, b) */
+DONNA_INLINE static void
+curve25519_swap_conditional(bignum25519 a, bignum25519 b, uint32_t iswap) {
+ const uint32_t swap = (uint32_t)(-(int32_t)iswap);
+ uint32_t x0,x1,x2,x3,x4,x5,x6,x7,x8,x9;
+
+ x0 = swap & (a[0] ^ b[0]); a[0] ^= x0; b[0] ^= x0;
+ x1 = swap & (a[1] ^ b[1]); a[1] ^= x1; b[1] ^= x1;
+ x2 = swap & (a[2] ^ b[2]); a[2] ^= x2; b[2] ^= x2;
+ x3 = swap & (a[3] ^ b[3]); a[3] ^= x3; b[3] ^= x3;
+ x4 = swap & (a[4] ^ b[4]); a[4] ^= x4; b[4] ^= x4;
+ x5 = swap & (a[5] ^ b[5]); a[5] ^= x5; b[5] ^= x5;
+ x6 = swap & (a[6] ^ b[6]); a[6] ^= x6; b[6] ^= x6;
+ x7 = swap & (a[7] ^ b[7]); a[7] ^= x7; b[7] ^= x7;
+ x8 = swap & (a[8] ^ b[8]); a[8] ^= x8; b[8] ^= x8;
+ x9 = swap & (a[9] ^ b[9]); a[9] ^= x9; b[9] ^= x9;
+}
diff --git a/lib/Utils.Cryptography/monocypher/vendor/tests/externals/ed25519-donna/curve25519-donna-helpers.h b/lib/Utils.Cryptography/monocypher/vendor/tests/externals/ed25519-donna/curve25519-donna-helpers.h
new file mode 100644
index 0000000..e4058ff
--- /dev/null
+++ b/lib/Utils.Cryptography/monocypher/vendor/tests/externals/ed25519-donna/curve25519-donna-helpers.h
@@ -0,0 +1,67 @@
+/*
+ Public domain by Andrew M. <liquidsun@gmail.com>
+ See: https://github.com/floodyberry/curve25519-donna
+
+ Curve25519 implementation agnostic helpers
+*/
+
+/*
+ * In: b = 2^5 - 2^0
+ * Out: b = 2^250 - 2^0
+ */
+static void
+curve25519_pow_two5mtwo0_two250mtwo0(bignum25519 b) {
+ bignum25519 ALIGN(16) t0,c;
+
+ /* 2^5 - 2^0 */ /* b */
+ /* 2^10 - 2^5 */ curve25519_square_times(t0, b, 5);
+ /* 2^10 - 2^0 */ curve25519_mul_noinline(b, t0, b);
+ /* 2^20 - 2^10 */ curve25519_square_times(t0, b, 10);
+ /* 2^20 - 2^0 */ curve25519_mul_noinline(c, t0, b);
+ /* 2^40 - 2^20 */ curve25519_square_times(t0, c, 20);
+ /* 2^40 - 2^0 */ curve25519_mul_noinline(t0, t0, c);
+ /* 2^50 - 2^10 */ curve25519_square_times(t0, t0, 10);
+ /* 2^50 - 2^0 */ curve25519_mul_noinline(b, t0, b);
+ /* 2^100 - 2^50 */ curve25519_square_times(t0, b, 50);
+ /* 2^100 - 2^0 */ curve25519_mul_noinline(c, t0, b);
+ /* 2^200 - 2^100 */ curve25519_square_times(t0, c, 100);
+ /* 2^200 - 2^0 */ curve25519_mul_noinline(t0, t0, c);
+ /* 2^250 - 2^50 */ curve25519_square_times(t0, t0, 50);
+ /* 2^250 - 2^0 */ curve25519_mul_noinline(b, t0, b);
+}
+
+/*
+ * z^(p - 2) = z(2^255 - 21)
+ */
+static void
+curve25519_recip(bignum25519 out, const bignum25519 z) {
+ bignum25519 ALIGN(16) a,t0,b;
+
+ /* 2 */ curve25519_square_times(a, z, 1); /* a = 2 */
+ /* 8 */ curve25519_square_times(t0, a, 2);
+ /* 9 */ curve25519_mul_noinline(b, t0, z); /* b = 9 */
+ /* 11 */ curve25519_mul_noinline(a, b, a); /* a = 11 */
+ /* 22 */ curve25519_square_times(t0, a, 1);
+ /* 2^5 - 2^0 = 31 */ curve25519_mul_noinline(b, t0, b);
+ /* 2^250 - 2^0 */ curve25519_pow_two5mtwo0_two250mtwo0(b);
+ /* 2^255 - 2^5 */ curve25519_square_times(b, b, 5);
+ /* 2^255 - 21 */ curve25519_mul_noinline(out, b, a);
+}
+
+/*
+ * z^((p-5)/8) = z^(2^252 - 3)
+ */
+static void
+curve25519_pow_two252m3(bignum25519 two252m3, const bignum25519 z) {
+ bignum25519 ALIGN(16) b,c,t0;
+
+ /* 2 */ curve25519_square_times(c, z, 1); /* c = 2 */
+ /* 8 */ curve25519_square_times(t0, c, 2); /* t0 = 8 */
+ /* 9 */ curve25519_mul_noinline(b, t0, z); /* b = 9 */
+ /* 11 */ curve25519_mul_noinline(c, b, c); /* c = 11 */
+ /* 22 */ curve25519_square_times(t0, c, 1);
+ /* 2^5 - 2^0 = 31 */ curve25519_mul_noinline(b, t0, b);
+ /* 2^250 - 2^0 */ curve25519_pow_two5mtwo0_two250mtwo0(b);
+ /* 2^252 - 2^2 */ curve25519_square_times(b, b, 2);
+ /* 2^252 - 3 */ curve25519_mul_noinline(two252m3, b, z);
+}
diff --git a/lib/Utils.Cryptography/monocypher/vendor/tests/externals/ed25519-donna/ed25519-donna-32bit-tables.h b/lib/Utils.Cryptography/monocypher/vendor/tests/externals/ed25519-donna/ed25519-donna-32bit-tables.h
new file mode 100644
index 0000000..c977c26
--- /dev/null
+++ b/lib/Utils.Cryptography/monocypher/vendor/tests/externals/ed25519-donna/ed25519-donna-32bit-tables.h
@@ -0,0 +1,61 @@
+static const ge25519 ALIGN(16) ge25519_basepoint = {
+ {0x0325d51a,0x018b5823,0x00f6592a,0x0104a92d,0x01a4b31d,0x01d6dc5c,0x027118fe,0x007fd814,0x013cd6e5,0x0085a4db},
+ {0x02666658,0x01999999,0x00cccccc,0x01333333,0x01999999,0x00666666,0x03333333,0x00cccccc,0x02666666,0x01999999},
+ {0x00000001,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000},
+ {0x01b7dda3,0x01a2ace9,0x025eadbb,0x0003ba8a,0x0083c27e,0x00abe37d,0x01274732,0x00ccacdd,0x00fd78b7,0x019e1d7c}
+};
+
+/*
+ d
+*/
+
+static const bignum25519 ALIGN(16) ge25519_ecd = {
+ 0x035978a3,0x00d37284,0x03156ebd,0x006a0a0e,0x0001c029,0x0179e898,0x03a03cbb,0x01ce7198,0x02e2b6ff,0x01480db3
+};
+
+static const bignum25519 ALIGN(16) ge25519_ec2d = {
+ 0x02b2f159,0x01a6e509,0x022add7a,0x00d4141d,0x00038052,0x00f3d130,0x03407977,0x019ce331,0x01c56dff,0x00901b67
+};
+
+/*
+ sqrt(-1)
+*/
+
+static const bignum25519 ALIGN(16) ge25519_sqrtneg1 = {
+ 0x020ea0b0,0x0186c9d2,0x008f189d,0x0035697f,0x00bd0c60,0x01fbd7a7,0x02804c9e,0x01e16569,0x0004fc1d,0x00ae0c92
+};
+
+static const ge25519_niels ALIGN(16) ge25519_niels_sliding_multiples[32] = {
+ {{0x0340913e,0x000e4175,0x03d673a2,0x002e8a05,0x03f4e67c,0x008f8a09,0x00c21a34,0x004cf4b8,0x01298f81,0x0113f4be},{0x018c3b85,0x0124f1bd,0x01c325f7,0x0037dc60,0x033e4cb7,0x003d42c2,0x01a44c32,0x014ca4e1,0x03a33d4b,0x001f3e74},{0x037aaa68,0x00448161,0x0093d579,0x011e6556,0x009b67a0,0x0143598c,0x01bee5ee,0x00b50b43,0x0289f0c6,0x01bc45ed}},
+ {{0x00fcd265,0x0047fa29,0x034faacc,0x01ef2e0d,0x00ef4d4f,0x014bd6bd,0x00f98d10,0x014c5026,0x007555bd,0x00aae456},{0x00ee9730,0x016c2a13,0x017155e4,0x01874432,0x00096a10,0x01016732,0x01a8014f,0x011e9823,0x01b9a80f,0x01e85938},{0x01d0d889,0x01a4cfc3,0x034c4295,0x0110e1ae,0x0162508c,0x00f2db4c,0x0072a2c6,0x0098da2e,0x02f12b9b,0x0168a09a}},
+ {{0x0047d6ba,0x0060b0e9,0x0136eff2,0x008a5939,0x03540053,0x0064a087,0x02788e5c,0x00be7c67,0x033eb1b5,0x005529f9},{0x00a5bb33,0x00af1102,0x01a05442,0x001e3af7,0x02354123,0x00bfec44,0x01f5862d,0x00dd7ba3,0x03146e20,0x00a51733},{0x012a8285,0x00f6fc60,0x023f9797,0x003e85ee,0x009c3820,0x01bda72d,0x01b3858d,0x00d35683,0x0296b3bb,0x010eaaf9}},
+ {{0x023221b1,0x01cb26aa,0x0074f74d,0x0099ddd1,0x01b28085,0x00192c3a,0x013b27c9,0x00fc13bd,0x01d2e531,0x0075bb75},{0x004ea3bf,0x00973425,0x001a4d63,0x01d59cee,0x01d1c0d4,0x00542e49,0x01294114,0x004fce36,0x029283c9,0x01186fa9},{0x01b8b3a2,0x00db7200,0x00935e30,0x003829f5,0x02cc0d7d,0x0077adf3,0x0220dd2c,0x0014ea53,0x01c6a0f9,0x01ea7eec}},
+ {{0x039d8064,0x01885f80,0x00337e6d,0x01b7a902,0x02628206,0x015eb044,0x01e30473,0x0191f2d9,0x011fadc9,0x01270169},{0x02a8632f,0x0199e2a9,0x00d8b365,0x017a8de2,0x02994279,0x0086f5b5,0x0119e4e3,0x01eb39d6,0x0338add7,0x00d2e7b4},{0x0045af1b,0x013a2fe4,0x0245e0d6,0x014538ce,0x038bfe0f,0x01d4cf16,0x037e14c9,0x0160d55e,0x0021b008,0x01cf05c8}},
+ {{0x01864348,0x01d6c092,0x0070262b,0x014bb844,0x00fb5acd,0x008deb95,0x003aaab5,0x00eff474,0x00029d5c,0x0062ad66},{0x02802ade,0x01c02122,0x01c4e5f7,0x00781181,0x039767fb,0x01703406,0x0342388b,0x01f5e227,0x022546d8,0x0109d6ab},{0x016089e9,0x00cb317f,0x00949b05,0x01099417,0x000c7ad2,0x011a8622,0x0088ccda,0x01290886,0x022b53df,0x00f71954}},
+ {{0x027fbf93,0x01c04ecc,0x01ed6a0d,0x004cdbbb,0x02bbf3af,0x00ad5968,0x01591955,0x0094f3a2,0x02d17602,0x00099e20},{0x02007f6d,0x003088a8,0x03db77ee,0x00d5ade6,0x02fe12ce,0x0107ba07,0x0107097d,0x00482a6f,0x02ec346f,0x008d3f5f},{0x032ea378,0x0028465c,0x028e2a6c,0x018efc6e,0x0090df9a,0x01a7e533,0x039bfc48,0x010c745d,0x03daa097,0x0125ee9b}},
+ {{0x028ccf0b,0x00f36191,0x021ac081,0x012154c8,0x034e0a6e,0x01b25192,0x00180403,0x01d7eea1,0x00218d05,0x010ed735},{0x03cfeaa0,0x01b300c4,0x008da499,0x0068c4e1,0x0219230a,0x01f2d4d0,0x02defd60,0x00e565b7,0x017f12de,0x018788a4},{0x03d0b516,0x009d8be6,0x03ddcbb3,0x0071b9fe,0x03ace2bd,0x01d64270,0x032d3ec9,0x01084065,0x0210ae4d,0x01447584}},
+ {{0x0020de87,0x00e19211,0x01b68102,0x00b5ac97,0x022873c0,0x01942d25,0x01271394,0x0102073f,0x02fe2482,0x01c69ff9},{0x010e9d81,0x019dbbe5,0x0089f258,0x006e06b8,0x02951883,0x018f1248,0x019b3237,0x00bc7553,0x024ddb85,0x01b4c964},{0x01c8c854,0x0060ae29,0x01406d8e,0x01cff2f9,0x00cff451,0x01778d0c,0x03ac8c41,0x01552e59,0x036559ee,0x011d1b12}},
+ {{0x00741147,0x0151b219,0x01092690,0x00e877e6,0x01f4d6bb,0x0072a332,0x01cd3b03,0x00dadff2,0x0097db5e,0x0086598d},{0x01c69a2b,0x01decf1b,0x02c2fa6e,0x013b7c4f,0x037beac8,0x013a16b5,0x028e7bda,0x01f6e8ac,0x01e34fe9,0x01726947},{0x01f10e67,0x003c73de,0x022b7ea2,0x010f32c2,0x03ff776a,0x00142277,0x01d38b88,0x00776138,0x03c60822,0x01201140}},
+ {{0x0236d175,0x0008748e,0x03c6476d,0x013f4cdc,0x02eed02a,0x00838a47,0x032e7210,0x018bcbb3,0x00858de4,0x01dc7826},{0x00a37fc7,0x0127b40b,0x01957884,0x011d30ad,0x02816683,0x016e0e23,0x00b76be4,0x012db115,0x02516506,0x0154ce62},{0x00451edf,0x00bd749e,0x03997342,0x01cc2c4c,0x00eb6975,0x01a59508,0x03a516cf,0x00c228ef,0x0168ff5a,0x01697b47}},
+ {{0x00527359,0x01783156,0x03afd75c,0x00ce56dc,0x00e4b970,0x001cabe9,0x029e0f6d,0x0188850c,0x0135fefd,0x00066d80},{0x02150e83,0x01448abf,0x02bb0232,0x012bf259,0x033c8268,0x00711e20,0x03fc148f,0x005e0e70,0x017d8bf9,0x0112b2e2},{0x02134b83,0x001a0517,0x0182c3cc,0x00792182,0x0313d799,0x001a3ed7,0x0344547e,0x01f24a0d,0x03de6ad2,0x00543127}},
+ {{0x00dca868,0x00618f27,0x015a1709,0x00ddc38a,0x0320fd13,0x0036168d,0x0371ab06,0x01783fc7,0x0391e05f,0x01e29b5d},{0x01471138,0x00fca542,0x00ca31cf,0x01ca7bad,0x0175bfbc,0x01a708ad,0x03bce212,0x01244215,0x0075bb99,0x01acad68},{0x03a0b976,0x01dc12d1,0x011aab17,0x00aba0ba,0x029806cd,0x0142f590,0x018fd8ea,0x01a01545,0x03c4ad55,0x01c971ff}},
+ {{0x00d098c0,0x000afdc7,0x006cd230,0x01276af3,0x03f905b2,0x0102994c,0x002eb8a4,0x015cfbeb,0x025f855f,0x01335518},{0x01cf99b2,0x0099c574,0x01a69c88,0x00881510,0x01cd4b54,0x0112109f,0x008abdc5,0x0074647a,0x0277cb1f,0x01e53324},{0x02ac5053,0x01b109b0,0x024b095e,0x016997b3,0x02f26bb6,0x00311021,0x00197885,0x01d0a55a,0x03b6fcc8,0x01c020d5}},
+ {{0x02584a34,0x00e7eee0,0x03257a03,0x011e95a3,0x011ead91,0x00536202,0x00b1ce24,0x008516c6,0x03669d6d,0x004ea4a8},{0x00773f01,0x0019c9ce,0x019f6171,0x01d4afde,0x02e33323,0x01ad29b6,0x02ead1dc,0x01ed51a5,0x01851ad0,0x001bbdfa},{0x00577de5,0x00ddc730,0x038b9952,0x00f281ae,0x01d50390,0x0002e071,0x000780ec,0x010d448d,0x01f8a2af,0x00f0a5b7}},
+ {{0x031f2541,0x00d34bae,0x0323ff9d,0x003a056d,0x02e25443,0x00a1ad05,0x00d1bee8,0x002f7f8e,0x03007477,0x002a24b1},{0x0114a713,0x01457e76,0x032255d5,0x01cc647f,0x02a4bdef,0x0153d730,0x00118bcf,0x00f755ff,0x013490c7,0x01ea674e},{0x02bda3e8,0x00bb490d,0x00f291ea,0x000abf40,0x01dea321,0x002f9ce0,0x00b2b193,0x00fa54b5,0x0128302f,0x00a19d8b}},
+ {{0x022ef5bd,0x01638af3,0x038c6f8a,0x01a33a3d,0x039261b2,0x01bb89b8,0x010bcf9d,0x00cf42a9,0x023d6f17,0x01da1bca},{0x00e35b25,0x000d824f,0x0152e9cf,0x00ed935d,0x020b8460,0x01c7b83f,0x00c969e5,0x01a74198,0x0046a9d9,0x00cbc768},{0x01597c6a,0x0144a99b,0x00a57551,0x0018269c,0x023c464c,0x0009b022,0x00ee39e1,0x0114c7f2,0x038a9ad2,0x01584c17}},
+ {{0x03b0c0d5,0x00b30a39,0x038a6ce4,0x01ded83a,0x01c277a6,0x01010a61,0x0346d3eb,0x018d995e,0x02f2c57c,0x000c286b},{0x0092aed1,0x0125e37b,0x027ca201,0x001a6b6b,0x03290f55,0x0047ba48,0x018d916c,0x01a59062,0x013e35d4,0x0002abb1},{0x003ad2aa,0x007ddcc0,0x00c10f76,0x0001590b,0x002cfca6,0x000ed23e,0x00ee4329,0x00900f04,0x01c24065,0x0082fa70}},
+ {{0x02025e60,0x003912b8,0x0327041c,0x017e5ee5,0x02c0ecec,0x015a0d1c,0x02b1ce7c,0x0062220b,0x0145067e,0x01a5d931},{0x009673a6,0x00e1f609,0x00927c2a,0x016faa37,0x01650ef0,0x016f63b5,0x03cd40e1,0x003bc38f,0x0361f0ac,0x01d42acc},{0x02f81037,0x008ca0e8,0x017e23d1,0x011debfe,0x01bcbb68,0x002e2563,0x03e8add6,0x000816e5,0x03fb7075,0x0153e5ac}},
+ {{0x02b11ecd,0x016bf185,0x008f22ef,0x00e7d2bb,0x0225d92e,0x00ece785,0x00508873,0x017e16f5,0x01fbe85d,0x01e39a0e},{0x01669279,0x017c810a,0x024941f5,0x0023ebeb,0x00eb7688,0x005760f1,0x02ca4146,0x0073cde7,0x0052bb75,0x00f5ffa7},{0x03b8856b,0x00cb7dcd,0x02f14e06,0x001820d0,0x01d74175,0x00e59e22,0x03fba550,0x00484641,0x03350088,0x01c3c9a3}},
+ {{0x00dcf355,0x0104481c,0x0022e464,0x01f73fe7,0x00e03325,0x0152b698,0x02ef769a,0x00973663,0x00039b8c,0x0101395b},{0x01805f47,0x019160ec,0x03832cd0,0x008b06eb,0x03d4d717,0x004cb006,0x03a75b8f,0x013b3d30,0x01cfad88,0x01f034d1},{0x0078338a,0x01c7d2e3,0x02bc2b23,0x018b3f05,0x0280d9aa,0x005f3d44,0x0220a95a,0x00eeeb97,0x0362aaec,0x00835d51}},
+ {{0x01b9f543,0x013fac4d,0x02ad93ae,0x018ef464,0x0212cdf7,0x01138ba9,0x011583ab,0x019c3d26,0x028790b4,0x00e2e2b6},{0x033bb758,0x01f0dbf1,0x03734bd1,0x0129b1e5,0x02b3950e,0x003bc922,0x01a53ec8,0x018c5532,0x006f3cee,0x00ae3c79},{0x0351f95d,0x0012a737,0x03d596b8,0x017658fe,0x00ace54a,0x008b66da,0x0036c599,0x012a63a2,0x032ceba1,0x00126bac}},
+ {{0x03dcfe7e,0x019f4f18,0x01c81aee,0x0044bc2b,0x00827165,0x014f7c13,0x03b430f0,0x00bf96cc,0x020c8d62,0x01471997},{0x01fc7931,0x001f42dd,0x00ba754a,0x005bd339,0x003fbe49,0x016b3930,0x012a159c,0x009f83b0,0x03530f67,0x01e57b85},{0x02ecbd81,0x0096c294,0x01fce4a9,0x017701a5,0x0175047d,0x00ee4a31,0x012686e5,0x008efcd4,0x0349dc54,0x01b3466f}},
+ {{0x02179ca3,0x01d86414,0x03f0afd0,0x00305964,0x015c7428,0x0099711e,0x015d5442,0x00c71014,0x01b40b2e,0x01d483cf},{0x01afc386,0x01984859,0x036203ff,0x0045c6a8,0x0020a8aa,0x00990baa,0x03313f10,0x007ceede,0x027429e4,0x017806ce},{0x039357a1,0x0142f8f4,0x0294a7b6,0x00eaccf4,0x0259edb3,0x01311e6e,0x004d326f,0x0130c346,0x01ccef3c,0x01c424b2}},
+ {{0x0364918c,0x00148fc0,0x01638a7b,0x01a1fd5b,0x028ad013,0x0081e5a4,0x01a54f33,0x0174e101,0x003d0257,0x003a856c},{0x00051dcf,0x00f62b1d,0x0143d0ad,0x0042adbd,0x000fda90,0x01743ceb,0x0173e5e4,0x017bc749,0x03b7137a,0x0105ce96},{0x00f9218a,0x015b8c7c,0x00e102f8,0x0158d7e2,0x0169a5b8,0x00b2f176,0x018b347a,0x014cfef2,0x0214a4e3,0x017f1595}},
+ {{0x006d7ae5,0x0195c371,0x0391e26d,0x0062a7c6,0x003f42ab,0x010dad86,0x024f8198,0x01542b2a,0x0014c454,0x0189c471},{0x0390988e,0x00b8799d,0x02e44912,0x0078e2e6,0x00075654,0x01923eed,0x0040cd72,0x00a37c76,0x0009d466,0x00c8531d},{0x02651770,0x00609d01,0x0286c265,0x0134513c,0x00ee9281,0x005d223c,0x035c760c,0x00679b36,0x0073ecb8,0x016faa50}},
+ {{0x02c89be4,0x016fc244,0x02f38c83,0x018beb72,0x02b3ce2c,0x0097b065,0x034f017b,0x01dd957f,0x00148f61,0x00eab357},{0x0343d2f8,0x003398fc,0x011e368e,0x00782a1f,0x00019eea,0x00117b6f,0x0128d0d1,0x01a5e6bb,0x01944f1b,0x012b41e1},{0x03318301,0x018ecd30,0x0104d0b1,0x0038398b,0x03726701,0x019da88c,0x002d9769,0x00a7a681,0x031d9028,0x00ebfc32}},
+ {{0x0220405e,0x0171face,0x02d930f8,0x017f6d6a,0x023b8c47,0x0129d5f9,0x02972456,0x00a3a524,0x006f4cd2,0x004439fa},{0x00c53505,0x0190c2fd,0x00507244,0x009930f9,0x01a39270,0x01d327c6,0x0399bc47,0x01cfe13d,0x0332bd99,0x00b33e7d},{0x0203f5e4,0x003627b5,0x00018af8,0x01478581,0x004a2218,0x002e3bb7,0x039384d0,0x0146ea62,0x020b9693,0x0017155f}},
+ {{0x03c97e6f,0x00738c47,0x03b5db1f,0x01808fcf,0x01e8fc98,0x01ed25dd,0x01bf5045,0x00eb5c2b,0x0178fe98,0x01b85530},{0x01c20eb0,0x01aeec22,0x030b9eee,0x01b7d07e,0x0187e16f,0x014421fb,0x009fa731,0x0040b6d7,0x00841861,0x00a27fbc},{0x02d69abf,0x0058cdbf,0x0129f9ec,0x013c19ae,0x026c5b93,0x013a7fe7,0x004bb2ba,0x0063226f,0x002a95ca,0x01abefd9}},
+ {{0x02f5d2c1,0x00378318,0x03734fb5,0x01258073,0x0263f0f6,0x01ad70e0,0x01b56d06,0x01188fbd,0x011b9503,0x0036d2e1},{0x0113a8cc,0x01541c3e,0x02ac2bbc,0x01d95867,0x01f47459,0x00ead489,0x00ab5b48,0x01db3b45,0x00edb801,0x004b024f},{0x00b8190f,0x011fe4c2,0x00621f82,0x010508d7,0x001a5a76,0x00c7d7fd,0x03aab96d,0x019cd9dc,0x019c6635,0x00ceaa1e}},
+ {{0x01085cf2,0x01fd47af,0x03e3f5e1,0x004b3e99,0x01e3d46a,0x0060033c,0x015ff0a8,0x0150cdd8,0x029e8e21,0x008cf1bc},{0x00156cb1,0x003d623f,0x01a4f069,0x00d8d053,0x01b68aea,0x01ca5ab6,0x0316ae43,0x0134dc44,0x001c8d58,0x0084b343},{0x0318c781,0x0135441f,0x03a51a5e,0x019293f4,0x0048bb37,0x013d3341,0x0143151e,0x019c74e1,0x00911914,0x0076ddde}},
+ {{0x006bc26f,0x00d48e5f,0x00227bbe,0x00629ea8,0x01ea5f8b,0x0179a330,0x027a1d5f,0x01bf8f8e,0x02d26e2a,0x00c6b65e},{0x01701ab6,0x0051da77,0x01b4b667,0x00a0ce7c,0x038ae37b,0x012ac852,0x03a0b0fe,0x0097c2bb,0x00a017d2,0x01eb8b2a},{0x0120b962,0x0005fb42,0x0353b6fd,0x0061f8ce,0x007a1463,0x01560a64,0x00e0a792,0x01907c92,0x013a6622,0x007b47f1}}
+};
diff --git a/lib/Utils.Cryptography/monocypher/vendor/tests/externals/ed25519-donna/ed25519-donna-basepoint-table.h b/lib/Utils.Cryptography/monocypher/vendor/tests/externals/ed25519-donna/ed25519-donna-basepoint-table.h
new file mode 100644
index 0000000..41dcd52
--- /dev/null
+++ b/lib/Utils.Cryptography/monocypher/vendor/tests/externals/ed25519-donna/ed25519-donna-basepoint-table.h
@@ -0,0 +1,259 @@
+/* multiples of the base point in packed {ysubx, xaddy, t2d} form */
+static const uint8_t ALIGN(16) ge25519_niels_base_multiples[256][96] = {
+ {0x3e,0x91,0x40,0xd7,0x05,0x39,0x10,0x9d,0xb3,0xbe,0x40,0xd1,0x05,0x9f,0x39,0xfd,0x09,0x8a,0x8f,0x68,0x34,0x84,0xc1,0xa5,0x67,0x12,0xf8,0x98,0x92,0x2f,0xfd,0x44,0x85,0x3b,0x8c,0xf5,0xc6,0x93,0xbc,0x2f,0x19,0x0e,0x8c,0xfb,0xc6,0x2d,0x93,0xcf,0xc2,0x42,0x3d,0x64,0x98,0x48,0x0b,0x27,0x65,0xba,0xd4,0x33,0x3a,0x9d,0xcf,0x07,0x59,0xbb,0x6f,0x4b,0x67,0x15,0xbd,0xdb,0xea,0xa5,0xa2,0xee,0x00,0x3f,0xe1,0x41,0xfa,0xc6,0x57,0xc9,0x1c,0x9d,0xd4,0xcd,0xca,0xec,0x16,0xaf,0x1f,0xbe,0x0e,0x4f},
+ {0xa8,0xd5,0xb4,0x42,0x60,0xa5,0x99,0x8a,0xf6,0xac,0x60,0x4e,0x0c,0x81,0x2b,0x8f,0xaa,0x37,0x6e,0xb1,0x6b,0x23,0x9e,0xe0,0x55,0x25,0xc9,0x69,0xa6,0x95,0xb5,0x6b,0xd7,0x71,0x3c,0x93,0xfc,0xe7,0x24,0x92,0xb5,0xf5,0x0f,0x7a,0x96,0x9d,0x46,0x9f,0x02,0x07,0xd6,0xe1,0x65,0x9a,0xa6,0x5a,0x2e,0x2e,0x7d,0xa8,0x3f,0x06,0x0c,0x59,0x02,0x68,0xd3,0xda,0xaa,0x7e,0x34,0x6e,0x05,0x48,0xee,0x83,0x93,0x59,0xf3,0xba,0x26,0x68,0x07,0xe6,0x10,0xbe,0xca,0x3b,0xb8,0xd1,0x5e,0x16,0x0a,0x4f,0x31,0x49},
+ {0x65,0xd2,0xfc,0xa4,0xe8,0x1f,0x61,0x56,0x7d,0xba,0xc1,0xe5,0xfd,0x53,0xd3,0x3b,0xbd,0xd6,0x4b,0x21,0x1a,0xf3,0x31,0x81,0x62,0xda,0x5b,0x55,0x87,0x15,0xb9,0x2a,0x30,0x97,0xee,0x4c,0xa8,0xb0,0x25,0xaf,0x8a,0x4b,0x86,0xe8,0x30,0x84,0x5a,0x02,0x32,0x67,0x01,0x9f,0x02,0x50,0x1b,0xc1,0xf4,0xf8,0x80,0x9a,0x1b,0x4e,0x16,0x7a,0x34,0x48,0x67,0xf1,0xf4,0x11,0xf2,0x9b,0x95,0xf8,0x2d,0xf6,0x17,0x6b,0x4e,0xb8,0x4e,0x2a,0x72,0x5b,0x07,0x6f,0xde,0xd7,0x21,0x2a,0xbb,0x63,0xb9,0x04,0x9a,0x54},
+ {0xbf,0x18,0x68,0x05,0x0a,0x05,0xfe,0x95,0xa9,0xfa,0x60,0x56,0x71,0x89,0x7e,0x32,0x73,0x50,0xa0,0x06,0xcd,0xe3,0xe8,0xc3,0x9a,0xa4,0x45,0x74,0x4c,0x3f,0x93,0x27,0x9f,0x09,0xfc,0x8e,0xb9,0x51,0x73,0x28,0x38,0x25,0xfd,0x7d,0xf4,0xc6,0x65,0x67,0x65,0x92,0x0a,0xfb,0x3d,0x8d,0x34,0xca,0x27,0x87,0xe5,0x21,0x03,0x91,0x0e,0x68,0xb0,0x26,0x14,0xe5,0xec,0x45,0x1e,0xbf,0x94,0x0f,0xba,0x6d,0x3d,0xc6,0x2b,0xe3,0xc0,0x52,0xf8,0x8c,0xd5,0x74,0x29,0xe4,0x18,0x4c,0xe6,0xb0,0xb1,0x79,0xf0,0x44},
+ {0xba,0xd6,0x47,0xa4,0xc3,0x82,0x91,0x7f,0xb7,0x29,0x27,0x4b,0xd1,0x14,0x00,0xd5,0x87,0xa0,0x64,0xb8,0x1c,0xf1,0x3c,0xe3,0xf3,0x55,0x1b,0xeb,0x73,0x7e,0x4a,0x15,0x33,0xbb,0xa5,0x08,0x44,0xbc,0x12,0xa2,0x02,0xed,0x5e,0xc7,0xc3,0x48,0x50,0x8d,0x44,0xec,0xbf,0x5a,0x0c,0xeb,0x1b,0xdd,0xeb,0x06,0xe2,0x46,0xf1,0xcc,0x45,0x29,0xb3,0x03,0xd0,0xe7,0x79,0xa1,0x32,0xc8,0x7e,0x4d,0x12,0x00,0x0a,0x9d,0x72,0x5f,0xf3,0x8f,0x6d,0x0e,0xa1,0xd4,0xc1,0x62,0x98,0x7a,0xb2,0x38,0x59,0xac,0xb8,0x68},
+ {0xa4,0x8c,0x7d,0x7b,0xb6,0x06,0x98,0x49,0x39,0x27,0xd2,0x27,0x84,0xe2,0x5b,0x57,0xb9,0x53,0x45,0x20,0xe7,0x5c,0x08,0xbb,0x84,0x78,0x41,0xae,0x41,0x4c,0xb6,0x38,0x31,0x71,0x15,0x77,0xeb,0xee,0x0c,0x3a,0x88,0xaf,0xc8,0x00,0x89,0x15,0x27,0x9b,0x36,0xa7,0x59,0xda,0x68,0xb6,0x65,0x80,0xbd,0x38,0xcc,0xa2,0xb6,0x7b,0xe5,0x51,0xa4,0xe3,0x9d,0x68,0x91,0xad,0x9d,0x8f,0x37,0x91,0xfb,0xf8,0x28,0x24,0x5f,0x17,0x88,0xb9,0xcf,0x9f,0x32,0xb5,0x0a,0x05,0x9f,0xc0,0x54,0x13,0xa2,0xdf,0x65,0x78},
+ {0xb1,0x21,0x32,0xaa,0x9a,0x2c,0x6f,0xba,0xa7,0x23,0xba,0x3b,0x53,0x21,0xa0,0x6c,0x3a,0x2c,0x19,0x92,0x4f,0x76,0xea,0x9d,0xe0,0x17,0x53,0x2e,0x5d,0xdd,0x6e,0x1d,0xbf,0xa3,0x4e,0x94,0xd0,0x5c,0x1a,0x6b,0xd2,0xc0,0x9d,0xb3,0x3a,0x35,0x70,0x74,0x49,0x2e,0x54,0x28,0x82,0x52,0xb2,0x71,0x7e,0x92,0x3c,0x28,0x69,0xea,0x1b,0x46,0x36,0xda,0x0f,0xab,0xac,0x8a,0x7a,0x21,0xc8,0x49,0x35,0x3d,0x54,0xc6,0x28,0xa5,0x68,0x75,0xab,0x13,0x8b,0x5b,0xd0,0x37,0x37,0xbc,0x2c,0x3a,0x62,0xef,0x3c,0x23},
+ {0xd9,0x34,0x92,0xf3,0xed,0x5d,0xa7,0xe2,0xf9,0x58,0xb5,0xe1,0x80,0x76,0x3d,0x96,0xfb,0x23,0x3c,0x6e,0xac,0x41,0x27,0x2c,0xc3,0x01,0x0e,0x32,0xa1,0x24,0x90,0x3a,0x8f,0x3e,0xdd,0x04,0x66,0x59,0xb7,0x59,0x2c,0x70,0x88,0xe2,0x77,0x03,0xb3,0x6c,0x23,0xc3,0xd9,0x5e,0x66,0x9c,0x33,0xb1,0x2f,0xe5,0xbc,0x61,0x60,0xe7,0x15,0x09,0x7e,0xa3,0x34,0xa8,0x35,0xe8,0x7d,0xdf,0xea,0x57,0x98,0x68,0xda,0x9c,0xe1,0x8b,0x26,0xb3,0x67,0x71,0x36,0x85,0x11,0x2c,0xc2,0xd5,0xef,0xdb,0xd9,0xb3,0x9e,0x58},
+ {0x5e,0x51,0xaa,0x49,0x54,0x63,0x5b,0xed,0x3a,0x82,0xc6,0x0b,0x9f,0xc4,0x65,0xa8,0xc4,0xd1,0x42,0x5b,0xe9,0x1f,0x0c,0x85,0xb9,0x15,0xd3,0x03,0x6f,0x6d,0xd7,0x30,0x1d,0x9c,0x2f,0x63,0x0e,0xdd,0xcc,0x2e,0x15,0x31,0x89,0x76,0x96,0xb6,0xd0,0x51,0x58,0x7a,0x63,0xa8,0x6b,0xb7,0xdf,0x52,0x39,0xef,0x0e,0xa0,0x49,0x7d,0xd3,0x6d,0xc7,0xe4,0x06,0x21,0x17,0x44,0x44,0x6c,0x69,0x7f,0x8d,0x92,0x80,0xd6,0x53,0xfb,0x26,0x3f,0x4d,0x69,0xa4,0x9e,0x73,0xb4,0xb0,0x4b,0x86,0x2e,0x11,0x97,0xc6,0x10},
+ {0xde,0x5f,0xbe,0x7d,0x27,0xc4,0x93,0x64,0xa2,0x7e,0xad,0x19,0xad,0x4f,0x5d,0x26,0x90,0x45,0x30,0x46,0xc8,0xdf,0x00,0x0e,0x09,0xfe,0x66,0xed,0xab,0x1c,0xe6,0x25,0x05,0xc8,0x58,0x83,0xa0,0x2a,0xa6,0x0c,0x47,0x42,0x20,0x7a,0xe3,0x4a,0x3d,0x6a,0xdc,0xed,0x11,0x3b,0xa6,0xd3,0x64,0x74,0xef,0x06,0x08,0x55,0xaf,0x9b,0xbf,0x03,0x04,0x66,0x58,0xcc,0x28,0xe1,0x13,0x3f,0x7e,0x74,0x59,0xb4,0xec,0x73,0x58,0x6f,0xf5,0x68,0x12,0xcc,0xed,0x3d,0xb6,0xa0,0x2c,0xe2,0x86,0x45,0x63,0x78,0x6d,0x56},
+ {0x34,0x08,0xc1,0x9c,0x9f,0xa4,0x37,0x16,0x51,0xc4,0x9b,0xa8,0xd5,0x56,0x8e,0xbc,0xdb,0xd2,0x7f,0x7f,0x0f,0xec,0xb5,0x1c,0xd9,0x35,0xcc,0x5e,0xca,0x5b,0x97,0x33,0xd0,0x2f,0x5a,0xc6,0x85,0x42,0x05,0xa1,0xc3,0x67,0x16,0xf3,0x2a,0x11,0x64,0x6c,0x58,0xee,0x1a,0x73,0x40,0xe2,0x0a,0x68,0x2a,0xb2,0x93,0x47,0xf3,0xa5,0xfb,0x14,0xd4,0xf7,0x85,0x69,0x16,0x46,0xd7,0x3c,0x57,0x00,0xc8,0xc9,0x84,0x5e,0x3e,0x59,0x1e,0x13,0x61,0x7b,0xb6,0xf2,0xc3,0x2f,0x6c,0x52,0xfc,0x83,0xea,0x9c,0x82,0x14},
+ {0xc2,0x95,0xdd,0x97,0x84,0x7b,0x43,0xff,0xa7,0xb5,0x4e,0xaa,0x30,0x4e,0x74,0x6c,0x8b,0xe8,0x85,0x3c,0x61,0x5d,0x0c,0x9e,0x73,0x81,0x75,0x5f,0x1e,0xc7,0xd9,0x2f,0xb8,0xec,0x71,0x4e,0x2f,0x0b,0xe7,0x21,0xe3,0x77,0xa4,0x40,0xb9,0xdd,0x56,0xe6,0x80,0x4f,0x1d,0xce,0xce,0x56,0x65,0xbf,0x7e,0x7b,0x5d,0x53,0xc4,0x3b,0xfc,0x05,0xdd,0xde,0xaf,0x52,0xae,0xb3,0xb8,0x24,0xcf,0x30,0x3b,0xed,0x8c,0x63,0x95,0x34,0x95,0x81,0xbe,0xa9,0x83,0xbc,0xa4,0x33,0x04,0x1f,0x65,0x5c,0x47,0x67,0x37,0x37},
+ {0xd9,0xad,0xd1,0x40,0xfd,0x99,0xba,0x2f,0x27,0xd0,0xf4,0x96,0x6f,0x16,0x07,0xb3,0xae,0x3b,0xf0,0x15,0x52,0xf0,0x63,0x43,0x99,0xf9,0x18,0x3b,0x6c,0xa5,0xbe,0x1f,0x90,0x65,0x24,0x14,0xcb,0x95,0x40,0x63,0x35,0x55,0xc1,0x16,0x40,0x14,0x12,0xef,0x60,0xbc,0x10,0x89,0x0c,0x14,0x38,0x9e,0x8c,0x7c,0x90,0x30,0x57,0x90,0xf5,0x6b,0x8a,0x5b,0x41,0xe1,0xf1,0x78,0xa7,0x0f,0x7e,0xa7,0xc3,0xba,0xf7,0x9f,0x40,0x06,0x50,0x9a,0xa2,0x9a,0xb8,0xd7,0x52,0x6f,0x56,0x5a,0x63,0x7a,0xf6,0x1c,0x52,0x02},
+ {0x94,0x52,0x9d,0x0a,0x0b,0xee,0x3f,0x51,0x66,0x5a,0xdf,0x0f,0x5c,0xe7,0x98,0x8f,0xce,0x07,0xe1,0xbf,0x88,0x86,0x61,0xd4,0xed,0x2c,0x38,0x71,0x7e,0x0a,0xa0,0x3f,0xe4,0x5e,0x2f,0x77,0x20,0x67,0x14,0xb1,0xce,0x9a,0x07,0x96,0xb1,0x94,0xf8,0xe8,0x4a,0x82,0xac,0x00,0x4d,0x22,0xf8,0x4a,0xc4,0x6c,0xcd,0xf7,0xd9,0x53,0x17,0x00,0x34,0xdb,0x3d,0x96,0x2d,0x23,0x69,0x3c,0x58,0x38,0x97,0xb4,0xda,0x87,0xde,0x1d,0x85,0xf2,0x91,0xa0,0xf9,0xd1,0xd7,0xaa,0xb6,0xed,0x48,0xa0,0x2f,0xfe,0xb5,0x12},
+ {0x4d,0xe3,0xfc,0x96,0xc4,0xfb,0xf0,0x71,0xed,0x5b,0xf3,0xad,0x6b,0x82,0xb9,0x73,0x61,0xc5,0x28,0xff,0x61,0x72,0x04,0xd2,0x6f,0x20,0xb1,0x6f,0xf9,0x76,0x9b,0x74,0x92,0x1e,0x6f,0xad,0x26,0x7c,0x2b,0xdf,0x13,0x89,0x4b,0x50,0x23,0xd3,0x66,0x4b,0xc3,0x8b,0x1c,0x75,0xc0,0x9d,0x40,0x8c,0xb8,0xc7,0x96,0x07,0xc2,0x93,0x7e,0x6f,0x05,0xae,0xa6,0xae,0x04,0xf6,0x5a,0x1f,0x99,0x9c,0xe4,0xbe,0xf1,0x51,0x23,0xc1,0x66,0x6b,0xff,0xee,0xb5,0x08,0xa8,0x61,0x51,0x21,0xe0,0x01,0x0f,0xc1,0xce,0x0f},
+ {0x44,0x1e,0xfe,0x49,0xa6,0x58,0x4d,0x64,0x7e,0x77,0xad,0x31,0xa2,0xae,0xfc,0x21,0xd2,0xd0,0x7f,0x88,0x5a,0x1c,0x44,0x02,0xf3,0x11,0xc5,0x83,0x71,0xaa,0x01,0x49,0x45,0x4e,0x24,0xc4,0x9d,0xd2,0xf2,0x3d,0x0a,0xde,0xd8,0x93,0x74,0x0e,0x02,0x2b,0x4d,0x21,0x0c,0x82,0x7e,0x06,0xc8,0x6c,0x0a,0xb9,0xea,0x6f,0x16,0x79,0x37,0x41,0xf0,0xf8,0x1a,0x8c,0x54,0xb7,0xb1,0x08,0xb4,0x99,0x62,0x24,0x7c,0x7a,0x0f,0xce,0x39,0xd9,0x06,0x1e,0xf9,0xb0,0x60,0xf7,0x13,0x12,0x6d,0x72,0x7b,0x88,0xbb,0x41},
+ {0xbe,0x46,0x43,0x74,0x44,0x7d,0xe8,0x40,0x25,0x2b,0xb5,0x15,0xd4,0xda,0x48,0x1d,0x3e,0x60,0x3b,0xa1,0x18,0x8a,0x3a,0x7c,0xf7,0xbd,0xcd,0x2f,0xc1,0x28,0xb7,0x4e,0xae,0x91,0x66,0x7c,0x59,0x4c,0x23,0x7e,0xc8,0xb4,0x85,0x0a,0x3d,0x9d,0x88,0x64,0xe7,0xfa,0x4a,0x35,0x0c,0xc9,0xe2,0xda,0x1d,0x9e,0x6a,0x0c,0x07,0x1e,0x87,0x0a,0x89,0x89,0xbc,0x4b,0x99,0xb5,0x01,0x33,0x60,0x42,0xdd,0x5b,0x3a,0xae,0x6b,0x73,0x3c,0x9e,0xd5,0x19,0xe2,0xad,0x61,0x0d,0x64,0xd4,0x85,0x26,0x0f,0x30,0xe7,0x3e},
+ {0xb7,0xd6,0x7d,0x9e,0xe4,0x55,0xd2,0xf5,0xac,0x1e,0x0b,0x61,0x5c,0x11,0x16,0x80,0xca,0x87,0xe1,0x92,0x5d,0x97,0x99,0x3c,0xc2,0x25,0x91,0x97,0x62,0x57,0x81,0x13,0x18,0x75,0x1e,0x84,0x47,0x79,0xfa,0x43,0xd7,0x46,0x9c,0x63,0x59,0xfa,0xc6,0xe5,0x74,0x2b,0x05,0xe3,0x1d,0x5e,0x06,0xa1,0x30,0x90,0xb8,0xcf,0xa2,0xc6,0x47,0x7d,0xe0,0xd6,0xf0,0x8e,0x14,0xd0,0xda,0x3f,0x3c,0x6f,0x54,0x91,0x9a,0x74,0x3e,0x9d,0x57,0x81,0xbb,0x26,0x10,0x62,0xec,0x71,0x80,0xec,0xc9,0x34,0x8d,0xf5,0x8c,0x14},
+ {0x27,0xf0,0x34,0x79,0xf6,0x92,0xa4,0x46,0xa9,0x0a,0x84,0xf6,0xbe,0x84,0x99,0x46,0x54,0x18,0x61,0x89,0x2a,0xbc,0xa1,0x5c,0xd4,0xbb,0x5d,0xbd,0x1e,0xfa,0xf2,0x3f,0x6d,0x75,0xe4,0x9a,0x7d,0x2f,0x57,0xe2,0x7f,0x48,0xf3,0x88,0xbb,0x45,0xc3,0x56,0x8d,0xa8,0x60,0x69,0x6d,0x0b,0xd1,0x9f,0xb9,0xa1,0xae,0x4e,0xad,0xeb,0x8f,0x27,0x66,0x39,0x93,0x8c,0x1f,0x68,0xaa,0xb1,0x98,0x0c,0x29,0x20,0x9c,0x94,0x21,0x8c,0x52,0x3c,0x9d,0x21,0x91,0x52,0x11,0x39,0x7b,0x67,0x9c,0xfe,0x02,0xdd,0x04,0x41},
+ {0x2a,0x42,0x24,0x11,0x5e,0xbf,0xb2,0x72,0xb5,0x3a,0xa3,0x98,0x33,0x0c,0xfa,0xa1,0x66,0xb6,0x52,0xfa,0x01,0x61,0xcb,0x94,0xd5,0x53,0xaf,0xaf,0x00,0x3b,0x86,0x2c,0xb8,0x6a,0x09,0xdb,0x06,0x4e,0x21,0x81,0x35,0x4f,0xe4,0x0c,0xc9,0xb6,0xa8,0x21,0xf5,0x2a,0x9e,0x40,0x2a,0xc1,0x24,0x65,0x81,0xa4,0xfc,0x8e,0xa4,0xb5,0x65,0x01,0x76,0x6a,0x84,0xa0,0x74,0xa4,0x90,0xf1,0xc0,0x7c,0x2f,0xcd,0x84,0xf9,0xef,0x12,0x8f,0x2b,0xaa,0x58,0x06,0x29,0x5e,0x69,0xb8,0xc8,0xfe,0xbf,0xd9,0x67,0x1b,0x59},
+ {0xfa,0x9b,0xb4,0x80,0x1c,0x0d,0x2f,0x31,0x8a,0xec,0xf3,0xab,0x5e,0x51,0x79,0x59,0x88,0x1c,0xf0,0x9e,0xc0,0x33,0x70,0x72,0xcb,0x7b,0x8f,0xca,0xc7,0x2e,0xe0,0x3d,0x5d,0xb5,0x18,0x9f,0x71,0xb3,0xb9,0x99,0x1e,0x64,0x8c,0xa1,0xfa,0xe5,0x65,0xe4,0xed,0x05,0x9f,0xc2,0x36,0x11,0x08,0x61,0x8b,0x12,0x30,0x70,0x86,0x4f,0x9b,0x48,0xef,0x92,0xeb,0x3a,0x2d,0x10,0x32,0xd2,0x61,0xa8,0x16,0x61,0xb4,0x53,0x62,0xe1,0x24,0xaa,0x0b,0x19,0xe7,0xab,0x7e,0x3d,0xbf,0xbe,0x6c,0x49,0xba,0xfb,0xf5,0x49},
+ {0xd4,0xcf,0x5b,0x8a,0x10,0x9a,0x94,0x30,0xeb,0x73,0x64,0xbc,0x70,0xdd,0x40,0xdc,0x1c,0x0d,0x7c,0x30,0xc1,0x94,0xc2,0x92,0x74,0x6e,0xfa,0xcb,0x6d,0xa8,0x04,0x56,0x2e,0x57,0x9c,0x1e,0x8c,0x62,0x5d,0x15,0x41,0x47,0x88,0xc5,0xac,0x86,0x4d,0x8a,0xeb,0x63,0x57,0x51,0xf6,0x52,0xa3,0x91,0x5b,0x51,0x67,0x88,0xc2,0xa6,0xa1,0x06,0xb6,0x64,0x17,0x7c,0xd4,0xd1,0x88,0x72,0x51,0x8b,0x41,0xe0,0x40,0x11,0x54,0x72,0xd1,0xf6,0xac,0x18,0x60,0x1a,0x03,0x9f,0xc6,0x42,0x27,0xfe,0x89,0x9e,0x98,0x20},
+ {0x7f,0xcc,0x2d,0x3a,0xfd,0x77,0x97,0x49,0x92,0xd8,0x4f,0xa5,0x2c,0x7c,0x85,0x32,0xa0,0xe3,0x07,0xd2,0x64,0xd8,0x79,0xa2,0x29,0x7e,0xa6,0x0c,0x1d,0xed,0x03,0x04,0x2e,0xec,0xea,0x85,0x8b,0x27,0x74,0x16,0xdf,0x2b,0xcb,0x7a,0x07,0xdc,0x21,0x56,0x5a,0xf4,0xcb,0x61,0x16,0x4c,0x0a,0x64,0xd3,0x95,0x05,0xf7,0x50,0x99,0x0b,0x73,0x52,0xc5,0x4e,0x87,0x35,0x2d,0x4b,0xc9,0x8d,0x6f,0x24,0x98,0xcf,0xc8,0xe6,0xc5,0xce,0x35,0xc0,0x16,0xfa,0x46,0xcb,0xf7,0xcc,0x3d,0x30,0x08,0x43,0x45,0xd7,0x5b},
+ {0xc2,0x4c,0xb2,0x28,0x95,0xd1,0x9a,0x7f,0x81,0xc1,0x35,0x63,0x65,0x54,0x6b,0x7f,0x36,0x72,0xc0,0x4f,0x6e,0xb6,0xb8,0x66,0x83,0xad,0x80,0x73,0x00,0x78,0x3a,0x13,0x2a,0x79,0xe7,0x15,0x21,0x93,0xc4,0x85,0xc9,0xdd,0xcd,0xbd,0xa2,0x89,0x4c,0xc6,0x62,0xd7,0xa3,0xad,0xa8,0x3d,0x1e,0x9d,0x2c,0xf8,0x67,0x30,0x12,0xdb,0xb7,0x5b,0xbe,0x62,0xca,0xc6,0x67,0xf4,0x61,0x09,0xee,0x52,0x19,0x21,0xd6,0x21,0xec,0x04,0x70,0x47,0xd5,0x9b,0x77,0x60,0x23,0x18,0xd2,0xe0,0xf0,0x58,0x6d,0xca,0x0d,0x74},
+ {0x4e,0xce,0xcf,0x52,0x07,0xee,0x48,0xdf,0xb7,0x08,0xec,0x06,0xf3,0xfa,0xff,0xc3,0xc4,0x59,0x54,0xb9,0x2a,0x0b,0x71,0x05,0x8d,0xa3,0x3e,0x96,0xfa,0x25,0x1d,0x16,0x3c,0x43,0x78,0x04,0x57,0x8c,0x1a,0x23,0x9d,0x43,0x81,0xc2,0x0e,0x27,0xb5,0xb7,0x9f,0x07,0xd9,0xe3,0xea,0x99,0xaa,0xdb,0xd9,0x03,0x2b,0x6c,0x25,0xf5,0x03,0x2c,0x7d,0xa4,0x53,0x7b,0x75,0x18,0x0f,0x79,0x79,0x58,0x0c,0xcf,0x30,0x01,0x7b,0x30,0xf9,0xf7,0x7e,0x25,0x77,0x3d,0x90,0x31,0xaf,0xbb,0x96,0xbd,0xbd,0x68,0x94,0x69},
+ {0xcf,0xfe,0xda,0xf4,0x46,0x2f,0x1f,0xbd,0xf7,0xd6,0x7f,0xa4,0x14,0x01,0xef,0x7c,0x7f,0xb3,0x47,0x4a,0xda,0xfd,0x1f,0xd3,0x85,0x57,0x90,0x73,0xa4,0x19,0x52,0x52,0x48,0x19,0xa9,0x6a,0xe6,0x3d,0xdd,0xd8,0xcc,0xd2,0xc0,0x2f,0xc2,0x64,0x50,0x48,0x2f,0xea,0xfd,0x34,0x66,0x24,0x48,0x9b,0x3a,0x2e,0x4a,0x6c,0x4e,0x1c,0x3e,0x29,0xe1,0x12,0x51,0x92,0x4b,0x13,0x6e,0x37,0xa0,0x5d,0xa1,0xdc,0xb5,0x78,0x37,0x70,0x11,0x31,0x1c,0x46,0xaf,0x89,0x45,0xb0,0x23,0x28,0x03,0x7f,0x44,0x5c,0x60,0x5b},
+ {0x89,0x7c,0xc4,0x20,0x59,0x80,0x65,0xb9,0xcc,0x8f,0x3b,0x92,0x0c,0x10,0xf0,0xe7,0x77,0xef,0xe2,0x02,0x65,0x25,0x01,0x00,0xee,0xb3,0xae,0xa8,0xce,0x6d,0xa7,0x24,0x4c,0xf0,0xe7,0xf0,0xc6,0xfe,0xe9,0x3b,0x62,0x49,0xe3,0x75,0x9e,0x57,0x6a,0x86,0x1a,0xe6,0x1d,0x1e,0x16,0xef,0x42,0x55,0xd5,0xbd,0x5a,0xcc,0xf4,0xfe,0x12,0x2f,0x40,0xc7,0xc0,0xdf,0xb2,0x22,0x45,0x0a,0x07,0xa4,0xc9,0x40,0x7f,0x6e,0xd0,0x10,0x68,0xf6,0xcf,0x78,0x41,0x14,0xcf,0xc6,0x90,0x37,0xa4,0x18,0x25,0x7b,0x60,0x5e},
+ {0x18,0x18,0xdf,0x6c,0x8f,0x1d,0xb3,0x58,0xa2,0x58,0x62,0xc3,0x4f,0xa7,0xcf,0x35,0x6e,0x1d,0xe6,0x66,0x4f,0xff,0xb3,0xe1,0xf7,0xd5,0xcd,0x6c,0xab,0xac,0x67,0x50,0x14,0xcf,0x96,0xa5,0x1c,0x43,0x2c,0xa0,0x00,0xe4,0xd3,0xae,0x40,0x2d,0xc4,0xe3,0xdb,0x26,0x0f,0x2e,0x80,0x26,0x45,0xd2,0x68,0x70,0x45,0x9e,0x13,0x33,0x1f,0x20,0x51,0x9d,0x03,0x08,0x6b,0x7f,0x52,0xfd,0x06,0x00,0x7c,0x01,0x64,0x49,0xb1,0x18,0xa8,0xa4,0x25,0x2e,0xb0,0x0e,0x22,0xd5,0x75,0x03,0x46,0x62,0x88,0xba,0x7c,0x39},
+ {0xb2,0x59,0x59,0xf0,0x93,0x30,0xc1,0x30,0x76,0x79,0xa9,0xe9,0x8d,0xa1,0x3a,0xe2,0x26,0x5e,0x1d,0x72,0x91,0xd4,0x2f,0x22,0x3a,0x6c,0x6e,0x76,0x20,0xd3,0x39,0x23,0xe7,0x79,0x13,0xc8,0xfb,0xc3,0x15,0x78,0xf1,0x2a,0xe1,0xdd,0x20,0x94,0x61,0xa6,0xd5,0xfd,0xa8,0x85,0xf8,0xc0,0xa9,0xff,0x52,0xc2,0xe1,0xc1,0x22,0x40,0x1b,0x77,0xa7,0x2f,0x3a,0x51,0x86,0xd9,0x7d,0xd8,0x08,0xcf,0xd4,0xf9,0x71,0x9b,0xac,0xf5,0xb3,0x83,0xa2,0x1e,0x1b,0xc3,0x6b,0xd0,0x76,0x1a,0x97,0x19,0x92,0x18,0x1a,0x33},
+ {0xc6,0x80,0x4f,0xfb,0x45,0x6f,0x16,0xf5,0xcf,0x75,0xc7,0x61,0xde,0xc7,0x36,0x9c,0x1c,0xd9,0x41,0x90,0x1b,0xe8,0xd4,0xe3,0x21,0xfe,0xbd,0x83,0x6b,0x7c,0x16,0x31,0xaf,0x72,0x75,0x9d,0x3a,0x2f,0x51,0x26,0x9e,0x4a,0x07,0x68,0x88,0xe2,0xcb,0x5b,0xc4,0xf7,0x80,0x11,0xc1,0xc1,0xed,0x84,0x7b,0xa6,0x49,0xf6,0x9f,0x61,0xc9,0x1a,0x68,0x10,0x4b,0x52,0x42,0x38,0x2b,0xf2,0x87,0xe9,0x9c,0xee,0x3b,0x34,0x68,0x50,0xc8,0x50,0x62,0x4a,0x84,0x71,0x9d,0xfc,0x11,0xb1,0x08,0x1f,0x34,0x36,0x24,0x61},
+ {0x8d,0x89,0x4e,0x87,0xdb,0x41,0x9d,0xd9,0x20,0xdc,0x07,0x6c,0xf1,0xa5,0xfe,0x09,0xbc,0x9b,0x0f,0xd0,0x67,0x2c,0x3d,0x79,0x40,0xff,0x5e,0x9e,0x30,0xe2,0xeb,0x46,0x38,0x26,0x2d,0x1a,0xe3,0x49,0x63,0x8b,0x35,0xfd,0xd3,0x9b,0x00,0xb7,0xdf,0x9d,0xa4,0x6b,0xa0,0xa3,0xb8,0xf1,0x8b,0x7f,0x45,0x04,0xd9,0x78,0x31,0xaa,0x22,0x15,0x38,0x49,0x61,0x69,0x53,0x2f,0x38,0x2c,0x10,0x6d,0x2d,0xb7,0x9a,0x40,0xfe,0xda,0x27,0xf2,0x46,0xb6,0x91,0x33,0xc8,0xe8,0x6c,0x30,0x24,0x05,0xf5,0x70,0xfe,0x45},
+ {0x8c,0x0b,0x0c,0x96,0xa6,0x75,0x48,0xda,0x20,0x2f,0x0e,0xef,0x76,0xd0,0x68,0x5b,0xd4,0x8f,0x0b,0x3d,0xcf,0x51,0xfb,0x07,0xd4,0x92,0xe3,0xa0,0x23,0x16,0x8d,0x42,0x91,0x14,0x95,0xc8,0x20,0x49,0xf2,0x62,0xa2,0x0c,0x63,0x3f,0xc8,0x07,0xf0,0x05,0xb8,0xd4,0xc9,0xf5,0xd2,0x45,0xbb,0x6f,0x45,0x22,0x7a,0xb5,0x6d,0x9f,0x61,0x16,0xfd,0x08,0xa3,0x01,0x44,0x4a,0x4f,0x08,0xac,0xca,0xa5,0x76,0xc3,0x19,0x22,0xa8,0x7d,0xbc,0xd1,0x43,0x46,0xde,0xb8,0xde,0xc6,0x38,0xbd,0x60,0x2d,0x59,0x81,0x1d},
+ {0x5f,0xac,0x0d,0xa6,0x56,0x87,0x36,0x61,0x57,0xdc,0xab,0xeb,0x6a,0x2f,0xe0,0x17,0x7d,0x0f,0xce,0x4c,0x2d,0x3f,0x19,0x7f,0xf0,0xdc,0xec,0x89,0x77,0x4a,0x23,0x20,0xe8,0xc5,0x85,0x7b,0x9f,0xb6,0x65,0x87,0xb2,0xba,0x68,0xd1,0x8b,0x67,0xf0,0x6f,0x9b,0x0f,0x33,0x1d,0x7c,0xe7,0x70,0x3a,0x7c,0x8e,0xaf,0xb0,0x51,0x6d,0x5f,0x3a,0x52,0xb2,0x78,0x71,0xb6,0x0d,0xd2,0x76,0x60,0xd1,0x1e,0xd5,0xf9,0x34,0x1c,0x07,0x70,0x11,0xe4,0xb3,0x20,0x4a,0x2a,0xf6,0x66,0xe3,0xff,0x3c,0x35,0x82,0xd6,0x7c},
+ {0xb6,0xfa,0x87,0xd8,0x5b,0xa4,0xe1,0x0b,0x6e,0x3b,0x40,0xba,0x32,0x6a,0x84,0x2a,0x00,0x60,0x6e,0xe9,0x12,0x10,0x92,0xd9,0x43,0x09,0xdc,0x3b,0x86,0xc8,0x38,0x28,0xf3,0xf4,0xac,0x68,0x60,0xcd,0x65,0xa6,0xd3,0xe3,0xd7,0x3c,0x18,0x2d,0xd9,0x42,0xd9,0x25,0x60,0x33,0x9d,0x38,0x59,0x57,0xff,0xd8,0x2c,0x2b,0x3b,0x25,0xf0,0x3e,0x30,0x50,0x46,0x4a,0xcf,0xb0,0x6b,0xd1,0xab,0x77,0xc5,0x15,0x41,0x6b,0x49,0xfa,0x9d,0x41,0xab,0xf4,0x8a,0xae,0xcf,0x82,0x12,0x28,0xa8,0x06,0xa6,0xb8,0xdc,0x21},
+ {0xc8,0x9f,0x9d,0x8c,0x46,0x04,0x60,0x5c,0xcb,0xa3,0x2a,0xd4,0x6e,0x09,0x40,0x25,0x9c,0x2f,0xee,0x12,0x4c,0x4d,0x5b,0x12,0xab,0x1d,0xa3,0x94,0x81,0xd0,0xc3,0x0b,0xba,0x31,0x77,0xbe,0xfa,0x00,0x8d,0x9a,0x89,0x18,0x9e,0x62,0x7e,0x60,0x03,0x82,0x7f,0xd9,0xf3,0x43,0x37,0x02,0xcc,0xb2,0x8b,0x67,0x6f,0x6c,0xbf,0x0d,0x84,0x5d,0x8b,0xe1,0x9f,0x30,0x0d,0x38,0x6e,0x70,0xc7,0x65,0xe1,0xb9,0xa6,0x2d,0xb0,0x6e,0xab,0x20,0xae,0x7d,0x99,0xba,0xbb,0x57,0xdd,0x96,0xc1,0x2a,0x23,0x76,0x42,0x3a},
+ {0xfa,0x84,0x70,0x8a,0x2c,0x43,0x42,0x4b,0x45,0xe5,0xb9,0xdf,0xe3,0x19,0x8a,0x89,0x5d,0xe4,0x58,0x9c,0x21,0x00,0x9f,0xbe,0xd1,0xeb,0x6d,0xa1,0xce,0x77,0xf1,0x1f,0xcb,0x7e,0x44,0xdb,0x72,0xc1,0xf8,0x3b,0xbd,0x2d,0x28,0xc6,0x1f,0xc4,0xcf,0x5f,0xfe,0x15,0xaa,0x75,0xc0,0xff,0xac,0x80,0xf9,0xa9,0xe1,0x24,0xe8,0xc9,0x70,0x07,0xfd,0xb5,0xb5,0x45,0x9a,0xd9,0x61,0xcf,0x24,0x79,0x3a,0x1b,0xe9,0x84,0x09,0x86,0x89,0x3e,0x3e,0x30,0x19,0x09,0x30,0xe7,0x1e,0x0b,0x50,0x41,0xfd,0x64,0xf2,0x39},
+ {0x9c,0xe2,0xe7,0xdb,0x17,0x34,0xad,0xa7,0x9c,0x13,0x9c,0x2b,0x6a,0x37,0x94,0xbd,0xa9,0x7b,0x59,0x93,0x8e,0x1b,0xe9,0xa0,0x40,0x98,0x88,0x68,0x34,0xd7,0x12,0x17,0xe1,0x7b,0x09,0xfe,0xab,0x4a,0x9b,0xd1,0x29,0x19,0xe0,0xdf,0xe1,0xfc,0x6d,0xa4,0xff,0xf1,0xa6,0x2c,0x94,0x08,0xc9,0xc3,0x4e,0xf1,0x35,0x2c,0x27,0x21,0xc6,0x65,0xdd,0x93,0x31,0xce,0xf8,0x89,0x2b,0xe7,0xbb,0xc0,0x25,0xa1,0x56,0x33,0x10,0x4d,0x83,0xfe,0x1c,0x2e,0x3d,0xa9,0x19,0x04,0x72,0xe2,0x9c,0xb1,0x0a,0x80,0xf9,0x22},
+ {0xcb,0xf8,0x9e,0x3e,0x8a,0x36,0x5a,0x60,0x15,0x47,0x50,0xa5,0x22,0xc0,0xe9,0xe3,0x8f,0x24,0x24,0x5f,0xb0,0x48,0x3d,0x55,0xe5,0x26,0x76,0x64,0xcd,0x16,0xf4,0x13,0xac,0xfd,0x6e,0x9a,0xdd,0x9f,0x02,0x42,0x41,0x49,0xa5,0x34,0xbe,0xce,0x12,0xb9,0x7b,0xf3,0xbd,0x87,0xb9,0x64,0x0f,0x64,0xb4,0xca,0x98,0x85,0xd3,0xa4,0x71,0x41,0x8c,0x4c,0xc9,0x99,0xaa,0x58,0x27,0xfa,0x07,0xb8,0x00,0xb0,0x6f,0x6f,0x00,0x23,0x92,0x53,0xda,0xad,0xdd,0x91,0xd2,0xfb,0xab,0xd1,0x4b,0x57,0xfa,0x14,0x82,0x50},
+ {0x4b,0xfe,0xd6,0x3e,0x15,0x69,0x02,0xc2,0xc4,0x77,0x1d,0x51,0x39,0x67,0x5a,0xa6,0x94,0xaf,0x14,0x2c,0x46,0x26,0xde,0xcb,0x4b,0xa7,0xab,0x6f,0xec,0x60,0xf9,0x22,0xd6,0x03,0xd0,0x53,0xbb,0x15,0x1a,0x46,0x65,0xc9,0xf3,0xbc,0x88,0x28,0x10,0xb2,0x5a,0x3a,0x68,0x6c,0x75,0x76,0xc5,0x27,0x47,0xb4,0x6c,0xc8,0xa4,0x58,0x77,0x3a,0x76,0x50,0xae,0x93,0xf6,0x11,0x81,0x54,0xa6,0x54,0xfd,0x1d,0xdf,0x21,0xae,0x1d,0x65,0x5e,0x11,0xf3,0x90,0x8c,0x24,0x12,0x94,0xf4,0xe7,0x8d,0x5f,0xd1,0x9f,0x5d},
+ {0x7f,0x72,0x63,0x6d,0xd3,0x08,0x14,0x03,0x33,0xb5,0xc7,0xd7,0xef,0x9a,0x37,0x6a,0x4b,0xe2,0xae,0xcc,0xc5,0x8f,0xe1,0xa9,0xd3,0xbe,0x8f,0x4f,0x91,0x35,0x2f,0x33,0x1e,0x52,0xd7,0xee,0x2a,0x4d,0x24,0x3f,0x15,0x96,0x2e,0x43,0x28,0x90,0x3a,0x8e,0xd4,0x16,0x9c,0x2e,0x77,0xba,0x64,0xe1,0xd8,0x98,0xeb,0x47,0xfa,0x87,0xc1,0x3b,0x0c,0xc2,0x86,0xea,0x15,0x01,0x47,0x6d,0x25,0xd1,0x46,0x6c,0xcb,0xb7,0x8a,0x99,0x88,0x01,0x66,0x3a,0xb5,0x32,0x78,0xd7,0x03,0xba,0x6f,0x90,0xce,0x81,0x0d,0x45},
+ {0x75,0x52,0x20,0xa6,0xa1,0xb6,0x7b,0x6e,0x83,0x8e,0x3c,0x41,0xd7,0x21,0x4f,0xaa,0xb2,0x5c,0x8f,0xe8,0x55,0xd1,0x56,0x6f,0xe1,0x5b,0x34,0xa6,0x4b,0x5d,0xe2,0x2d,0x3f,0x74,0xae,0x1c,0x96,0xd8,0x74,0xd0,0xed,0x63,0x1c,0xee,0xf5,0x18,0x6d,0xf8,0x29,0xed,0xf4,0xe7,0x5b,0xc5,0xbd,0x97,0x08,0xb1,0x3a,0x66,0x79,0xd2,0xba,0x4c,0xcd,0x1f,0xd7,0xa0,0x24,0x90,0xd1,0x80,0xf8,0x8a,0x28,0xfb,0x0a,0xc2,0x25,0xc5,0x19,0x64,0x3a,0x5f,0x4b,0x97,0xa3,0xb1,0x33,0x72,0x00,0xe2,0xef,0xbc,0x7f,0x7d},
+ {0x01,0x28,0x6b,0x26,0x6a,0x1e,0xef,0xfa,0x16,0x9f,0x73,0xd5,0xc4,0x68,0x6c,0x86,0x2c,0x76,0x03,0x1b,0xbc,0x2f,0x8a,0xf6,0x8d,0x5a,0xb7,0x87,0x5e,0x43,0x75,0x59,0x94,0x90,0xc2,0xf3,0xc5,0x5d,0x7c,0xcd,0xab,0x05,0x91,0x2a,0x9a,0xa2,0x81,0xc7,0x58,0x30,0x1c,0x42,0x36,0x1d,0xc6,0x80,0xd7,0xd4,0xd8,0xdc,0x96,0xd1,0x9c,0x4f,0x68,0x37,0x7b,0x6a,0xd8,0x97,0x92,0x19,0x63,0x7a,0xd1,0x1a,0x24,0x58,0xd0,0xd0,0x17,0x0c,0x1c,0x5c,0xad,0x9c,0x02,0xba,0x07,0x03,0x7a,0x38,0x84,0xd0,0xcd,0x7c},
+ {0x17,0x04,0x26,0x6d,0x2c,0x42,0xa6,0xdc,0xbd,0x40,0x82,0x94,0x50,0x3d,0x15,0xae,0x77,0xc6,0x68,0xfb,0xb4,0xc1,0xc0,0xa9,0x53,0xcf,0xd0,0x61,0xed,0xd0,0x8b,0x42,0x93,0xcc,0x60,0x67,0x18,0x84,0x0c,0x9b,0x99,0x2a,0xb3,0x1a,0x7a,0x00,0xae,0xcd,0x18,0xda,0x0b,0x62,0x86,0xec,0x8d,0xa8,0x44,0xca,0x90,0x81,0x84,0xca,0x93,0x35,0xa7,0x9a,0x84,0x5e,0x9a,0x18,0x13,0x92,0xcd,0xfa,0xd8,0x65,0x35,0xc3,0xd8,0xd4,0xd1,0xbb,0xfd,0x53,0x5b,0x54,0x52,0x8c,0xe6,0x63,0x2d,0xda,0x08,0x83,0x39,0x27},
+ {0x13,0xd4,0x5e,0x43,0x28,0x8d,0xc3,0x42,0xc9,0xcc,0x78,0x32,0x60,0xf3,0x50,0xbd,0xef,0x03,0xda,0x79,0x1a,0xab,0x07,0xbb,0x55,0x33,0x8c,0xbe,0xae,0x97,0x95,0x26,0x53,0x24,0x70,0x0a,0x4c,0x0e,0xa1,0xb9,0xde,0x1b,0x7d,0xd5,0x66,0x58,0xa2,0x0f,0xf7,0xda,0x27,0xcd,0xb5,0xd9,0xb9,0xff,0xfd,0x33,0x2c,0x49,0x45,0x29,0x2c,0x57,0xbe,0x30,0xcd,0xd6,0x45,0xc7,0x7f,0xc7,0xfb,0xae,0xba,0xe3,0xd3,0xe8,0xdf,0xe4,0x0c,0xda,0x5d,0xaa,0x30,0x88,0x2c,0xa2,0x80,0xca,0x5b,0xc0,0x98,0x54,0x98,0x7f},
+ {0x17,0xe1,0x0b,0x9f,0x88,0xce,0x49,0x38,0x88,0xa2,0x54,0x7b,0x1b,0xad,0x05,0x80,0x1c,0x92,0xfc,0x23,0x9f,0xc3,0xa3,0x3d,0x04,0xf3,0x31,0x0a,0x47,0xec,0xc2,0x76,0x63,0x63,0xbf,0x0f,0x52,0x15,0x56,0xd3,0xa6,0xfb,0x4d,0xcf,0x45,0x5a,0x04,0x08,0xc2,0xa0,0x3f,0x87,0xbc,0x4f,0xc2,0xee,0xe7,0x12,0x9b,0xd6,0x3c,0x65,0xf2,0x30,0x85,0x0c,0xc1,0xaa,0x38,0xc9,0x08,0x8a,0xcb,0x6b,0x27,0xdb,0x60,0x9b,0x17,0x46,0x70,0xac,0x6f,0x0e,0x1e,0xc0,0x20,0xa9,0xda,0x73,0x64,0x59,0xf1,0x73,0x12,0x2f},
+ {0x11,0x1e,0xe0,0x8a,0x7c,0xfc,0x39,0x47,0x9f,0xab,0x6a,0x4a,0x90,0x74,0x52,0xfd,0x2e,0x8f,0x72,0x87,0x82,0x8a,0xd9,0x41,0xf2,0x69,0x5b,0xd8,0x2a,0x57,0x9e,0x5d,0xc0,0x0b,0xa7,0x55,0xd7,0x8b,0x48,0x30,0xe7,0x42,0xd4,0xf1,0xa4,0xb5,0xd6,0x06,0x62,0x61,0x59,0xbc,0x9e,0xa6,0xd1,0xea,0x84,0xf7,0xc5,0xed,0x97,0x19,0xac,0x38,0x3b,0xb1,0x51,0xa7,0x17,0xb5,0x66,0x06,0x8c,0x85,0x9b,0x7e,0x86,0x06,0x7d,0x74,0x49,0xde,0x4d,0x45,0x11,0xc0,0xac,0xac,0x9c,0xe6,0xe9,0xbf,0x9c,0xcd,0xdf,0x22},
+ {0xd9,0x0c,0x0d,0xc3,0xe0,0xd2,0xdb,0x8d,0x33,0x43,0xbb,0xac,0x5f,0x66,0x8e,0xad,0x1f,0x96,0x2a,0x32,0x8c,0x25,0x6b,0x8f,0xc7,0xc1,0x48,0x54,0xc0,0x16,0x29,0x6b,0xa1,0xe0,0x3b,0x10,0xb4,0x59,0xec,0x56,0x69,0xf9,0x59,0xd2,0xec,0xba,0xe3,0x2e,0x32,0xcd,0xf5,0x13,0x94,0xb2,0x7c,0x79,0x72,0xe4,0xcd,0x24,0x78,0x87,0xe9,0x0f,0x3b,0x91,0xba,0x0a,0xd1,0x34,0xdb,0x7e,0x0e,0xac,0x6d,0x2e,0x82,0xcd,0xa3,0x4e,0x15,0xf8,0x78,0x65,0xff,0x3d,0x08,0x66,0x17,0x0a,0xf0,0x7f,0x30,0x3f,0x30,0x4c},
+ {0x85,0x8c,0xb2,0x17,0xd6,0x3b,0x0a,0xd3,0xea,0x3b,0x77,0x39,0xb7,0x77,0xd3,0xc5,0xbf,0x5c,0x6a,0x1e,0x8c,0xe7,0xc6,0xc6,0xc4,0xb7,0x2a,0x8b,0xf7,0xb8,0x61,0x0d,0x00,0x45,0xd9,0x0d,0x58,0x03,0xfc,0x29,0x93,0xec,0xbb,0x6f,0xa4,0x7a,0xd2,0xec,0xf8,0xa7,0xe2,0xc2,0x5f,0x15,0x0a,0x13,0xd5,0xa1,0x06,0xb7,0x1a,0x15,0x6b,0x41,0xb0,0x36,0xc1,0xe9,0xef,0xd7,0xa8,0x56,0x20,0x4b,0xe4,0x58,0xcd,0xe5,0x07,0xbd,0xab,0xe0,0x57,0x1b,0xda,0x2f,0xe6,0xaf,0xd2,0xe8,0x77,0x42,0xf7,0x2a,0x1a,0x19},
+ {0x31,0x14,0x3c,0xc5,0x4b,0xf7,0x16,0xce,0xde,0xed,0x72,0x20,0xce,0x25,0x97,0x2b,0xe7,0x3e,0xb2,0xb5,0x6f,0xc3,0xb9,0xb8,0x08,0xc9,0x5c,0x0b,0x45,0x0e,0x2e,0x7e,0xfb,0x0e,0x46,0x4f,0x43,0x2b,0xe6,0x9f,0xd6,0x07,0x36,0xa6,0xd4,0x03,0xd3,0xde,0x24,0xda,0xa0,0xb7,0x0e,0x21,0x52,0xf0,0x93,0x5b,0x54,0x00,0xbe,0x7d,0x7e,0x23,0x30,0xb4,0x01,0x67,0xed,0x75,0x35,0x01,0x10,0xfd,0x0b,0x9f,0xe6,0x94,0x10,0x23,0x22,0x7f,0xe4,0x83,0x15,0x0f,0x32,0x75,0xe3,0x55,0x11,0xb1,0x99,0xa6,0xaf,0x71},
+ {0x1d,0xb6,0x53,0x39,0x9b,0x6f,0xce,0x65,0xe6,0x41,0xa1,0xaf,0xea,0x39,0x58,0xc6,0xfe,0x59,0xf7,0xa9,0xfd,0x5f,0x43,0x0f,0x8e,0xc2,0xb1,0xc2,0xe9,0x42,0x11,0x02,0xd6,0x50,0x3b,0x47,0x1c,0x3c,0x42,0xea,0x10,0xef,0x38,0x3b,0x1f,0x7a,0xe8,0x51,0x95,0xbe,0xc9,0xb2,0x5f,0xbf,0x84,0x9b,0x1c,0x9a,0xf8,0x78,0xbc,0x1f,0x73,0x00,0x80,0x18,0xf8,0x48,0x18,0xc7,0x30,0xe4,0x19,0xc1,0xce,0x5e,0x22,0x0c,0x96,0xbf,0xe3,0x15,0xba,0x6b,0x83,0xe0,0xda,0xb6,0x08,0x58,0xe1,0x47,0x33,0x6f,0x4d,0x4c},
+ {0xc9,0x1f,0x7d,0xc1,0xcf,0xec,0xf7,0x18,0x14,0x3c,0x40,0x51,0xa6,0xf5,0x75,0x6c,0xdf,0x0c,0xee,0xf7,0x2b,0x71,0xde,0xdb,0x22,0x7a,0xe4,0xa7,0xaa,0xdd,0x3f,0x19,0x70,0x19,0x8f,0x98,0xfc,0xdd,0x0c,0x2f,0x1b,0xf5,0xb9,0xb0,0x27,0x62,0x91,0x6b,0xbe,0x76,0x91,0x77,0xc4,0xb6,0xc7,0x6e,0xa8,0x9f,0x8f,0xa8,0x00,0x95,0xbf,0x38,0x6f,0x87,0xe8,0x37,0x3c,0xc9,0xd2,0x1f,0x2c,0x46,0xd1,0x18,0x5a,0x1e,0xf6,0xa2,0x76,0x12,0x24,0x39,0x82,0xf5,0x80,0x50,0x69,0x49,0x0d,0xbf,0x9e,0xb9,0x6f,0x6a},
+ {0xeb,0x55,0x08,0x56,0xbb,0xc1,0x46,0x6a,0x9d,0xf0,0x93,0xf8,0x38,0xbb,0x16,0x24,0xc1,0xac,0x71,0x8f,0x37,0x11,0x1d,0xd7,0xea,0x96,0x18,0xa3,0x14,0x69,0xf7,0x75,0xc6,0x23,0xe4,0xb6,0xb5,0x22,0xb1,0xee,0x8e,0xff,0x86,0xf2,0x10,0x70,0x9d,0x93,0x8c,0x5d,0xcf,0x1d,0x83,0x2a,0xa9,0x90,0x10,0xeb,0xc5,0x42,0x9f,0xda,0x6f,0x13,0xd1,0xbd,0x05,0xa3,0xb1,0xdf,0x4c,0xf9,0x08,0x2c,0xf8,0x9f,0x9d,0x4b,0x36,0x0f,0x8a,0x58,0xbb,0xc3,0xa5,0xd8,0x87,0x2a,0xba,0xdc,0xe8,0x0b,0x51,0x83,0x21,0x02},
+ {0x14,0x2d,0xad,0x5e,0x38,0x66,0xf7,0x4a,0x30,0x58,0x7c,0xca,0x80,0xd8,0x8e,0xa0,0x3d,0x1e,0x21,0x10,0xe6,0xa6,0x13,0x0d,0x03,0x6c,0x80,0x7b,0xe1,0x1c,0x07,0x6a,0x7f,0x7a,0x30,0x43,0x01,0x71,0x5a,0x9d,0x5f,0xa4,0x7d,0xc4,0x9e,0xde,0x63,0xb0,0xd3,0x7a,0x92,0xbe,0x52,0xfe,0xbb,0x22,0x6c,0x42,0x40,0xfd,0x41,0xc4,0x87,0x13,0xf8,0x8a,0x97,0x87,0xd1,0xc3,0xd3,0xb5,0x13,0x44,0x0e,0x7f,0x3d,0x5a,0x2b,0x72,0xa0,0x7c,0x47,0xbb,0x48,0x48,0x7b,0x0d,0x92,0xdc,0x1e,0xaf,0x6a,0xb2,0x71,0x31},
+ {0xa8,0x4c,0x56,0x97,0x90,0x31,0x2f,0xa9,0x19,0xe1,0x75,0x22,0x4c,0xb8,0x7b,0xff,0x50,0x51,0x87,0xa4,0x37,0xfe,0x55,0x4f,0x5a,0x83,0xf0,0x3c,0x87,0xd4,0x1f,0x22,0xd1,0x47,0x8a,0xb2,0xd8,0xb7,0x0d,0xa6,0xf1,0xa4,0x70,0x17,0xd6,0x14,0xbf,0xa6,0x58,0xbd,0xdd,0x53,0x93,0xf8,0xa1,0xd4,0xe9,0x43,0x42,0x34,0x63,0x4a,0x51,0x6c,0x41,0x63,0x15,0x3a,0x4f,0x20,0x22,0x23,0x2d,0x03,0x0a,0xba,0xe9,0xe0,0x73,0xfb,0x0e,0x03,0x0f,0x41,0x4c,0xdd,0xe0,0xfc,0xaa,0x4a,0x92,0xfb,0x96,0xa5,0xda,0x48},
+ {0xc7,0x9c,0xa5,0x5c,0x66,0x8e,0xca,0x6e,0xa0,0xac,0x38,0x2e,0x4b,0x25,0x47,0xa8,0xce,0x17,0x1e,0xd2,0x08,0xc7,0xaf,0x31,0xf7,0x4a,0xd8,0xca,0xfc,0xd6,0x6d,0x67,0x93,0x97,0x4c,0xc8,0x5d,0x1d,0xf6,0x14,0x06,0x82,0x41,0xef,0xe3,0xf9,0x41,0x99,0xac,0x77,0x62,0x34,0x8f,0xb8,0xf5,0xcd,0xa9,0x79,0x8a,0x0e,0xfa,0x37,0xc8,0x58,0x58,0x90,0xfc,0x96,0x85,0x68,0xf9,0x0c,0x1b,0xa0,0x56,0x7b,0xf3,0xbb,0xdc,0x1d,0x6a,0xd6,0x35,0x49,0x7d,0xe7,0xc2,0xdc,0x0a,0x7f,0xa5,0xc6,0xf2,0x73,0x4f,0x1c},
+ {0xbb,0xa0,0x5f,0x30,0xbd,0x4f,0x7a,0x0e,0xad,0x63,0xc6,0x54,0xe0,0x4c,0x9d,0x82,0x48,0x38,0xe3,0x2f,0x83,0xc3,0x21,0xf4,0x42,0x4c,0xf6,0x1b,0x0d,0xc8,0x5a,0x79,0x84,0x34,0x7c,0xfc,0x6e,0x70,0x6e,0xb3,0x61,0xcf,0xc1,0xc3,0xb4,0xc9,0xdf,0x73,0xe5,0xc7,0x1c,0x78,0xc9,0x79,0x1d,0xeb,0x5c,0x67,0xaf,0x7d,0xdb,0x9a,0x45,0x70,0xb3,0x2b,0xb4,0x91,0x49,0xdb,0x91,0x1b,0xca,0xdc,0x02,0x4b,0x23,0x96,0x26,0x57,0xdc,0x78,0x8c,0x1f,0xe5,0x9e,0xdf,0x9f,0xd3,0x1f,0xe2,0x8c,0x84,0x62,0xe1,0x5f},
+ {0x1a,0x96,0x94,0xe1,0x4f,0x21,0x59,0x4e,0x4f,0xcd,0x71,0x0d,0xc7,0x7d,0xbe,0x49,0x2d,0xf2,0x50,0x3b,0xd2,0xcf,0x00,0x93,0x32,0x72,0x91,0xfc,0x46,0xd4,0x89,0x47,0x08,0xb2,0x7c,0x5d,0x2d,0x85,0x79,0x28,0xe7,0xf2,0x7d,0x68,0x70,0xdd,0xde,0xb8,0x91,0x78,0x68,0x21,0xab,0xff,0x0b,0xdc,0x35,0xaa,0x7d,0x67,0x43,0xc0,0x44,0x2b,0x8e,0xb7,0x4e,0x07,0xab,0x87,0x1c,0x1a,0x67,0xf4,0xda,0x99,0x8e,0xd1,0xc6,0xfa,0x67,0x90,0x4f,0x48,0xcd,0xbb,0xac,0x3e,0xe4,0xa4,0xb9,0x2b,0xef,0x2e,0xc5,0x60},
+ {0xf1,0x8b,0xfd,0x3b,0xbc,0x89,0x5d,0x0b,0x1a,0x55,0xf3,0xc9,0x37,0x92,0x6b,0xb0,0xf5,0x28,0x30,0xd5,0xb0,0x16,0x4c,0x0e,0xab,0xca,0xcf,0x2c,0x31,0x9c,0xbc,0x10,0x11,0x6d,0xae,0x7c,0xc2,0xc5,0x2b,0x70,0xab,0x8c,0xa4,0x54,0x9b,0x69,0xc7,0x44,0xb2,0x2e,0x49,0xba,0x56,0x40,0xbc,0xef,0x6d,0x67,0xb6,0xd9,0x48,0x72,0xd7,0x70,0x5b,0xa0,0xc2,0x3e,0x4b,0xe8,0x8a,0xaa,0xe0,0x81,0x17,0xed,0xf4,0x9e,0x69,0x98,0xd1,0x85,0x8e,0x70,0xe4,0x13,0x45,0x79,0x13,0xf4,0x76,0xa9,0xd3,0x5b,0x75,0x63},
+ {0x53,0x08,0xd1,0x2a,0x3e,0xa0,0x5f,0xb5,0x69,0x35,0xe6,0x9e,0x90,0x75,0x6f,0x35,0x90,0xb8,0x69,0xbe,0xfd,0xf1,0xf9,0x9f,0x84,0x6f,0xc1,0x8b,0xc4,0xc1,0x8c,0x0d,0xb7,0xac,0xf1,0x97,0x18,0x10,0xc7,0x3d,0xd8,0xbb,0x65,0xc1,0x5e,0x7d,0xda,0x5d,0x0f,0x02,0xa1,0x0f,0x9c,0x5b,0x8e,0x50,0x56,0x2a,0xc5,0x37,0x17,0x75,0x63,0x27,0xa9,0x19,0xb4,0x6e,0xd3,0x02,0x94,0x02,0xa5,0x60,0xb4,0x77,0x7e,0x4e,0xb4,0xf0,0x56,0x49,0x3c,0xd4,0x30,0x62,0xa8,0xcf,0xe7,0x66,0xd1,0x7a,0x8a,0xdd,0xc2,0x70},
+ {0x0e,0xec,0x6f,0x9f,0x50,0x94,0x61,0x65,0x8d,0x51,0xc6,0x46,0xa9,0x7e,0x2e,0xee,0x5c,0x9b,0xe0,0x67,0xf3,0xc1,0x33,0x97,0x95,0x84,0x94,0x63,0x63,0xac,0x0f,0x2e,0x13,0x7e,0xed,0xb8,0x7d,0x96,0xd4,0x91,0x7a,0x81,0x76,0xd7,0x0a,0x2f,0x25,0x74,0x64,0x25,0x85,0x0d,0xe0,0x82,0x09,0xe4,0xe5,0x3c,0xa5,0x16,0x38,0x61,0xb8,0x32,0x64,0xcd,0x48,0xe4,0xbe,0xf7,0xe7,0x79,0xd0,0x86,0x78,0x08,0x67,0x3a,0xc8,0x6a,0x2e,0xdb,0xe4,0xa0,0xd9,0xd4,0x9f,0xf8,0x41,0x4f,0x5a,0x73,0x5c,0x21,0x79,0x41},
+ {0x2a,0xed,0xdc,0xd7,0xe7,0x94,0x70,0x8c,0x70,0x9c,0xd3,0x47,0xc3,0x8a,0xfb,0x97,0x02,0xd9,0x06,0xa9,0x33,0xe0,0x3b,0xe1,0x76,0x9d,0xd9,0x0c,0xa3,0x44,0x03,0x70,0x34,0xcd,0x6b,0x28,0xb9,0x33,0xae,0xe4,0xdc,0xd6,0x9d,0x55,0xb6,0x7e,0xef,0xb7,0x1f,0x8e,0xd3,0xb3,0x1f,0x14,0x8b,0x27,0x86,0xc2,0x41,0x22,0x66,0x85,0xfa,0x31,0xf4,0x22,0x36,0x2e,0x42,0x6c,0x82,0xaf,0x2d,0x50,0x33,0x98,0x87,0x29,0x20,0xc1,0x23,0x91,0x38,0x2b,0xe1,0xb7,0xc1,0x9b,0x89,0x24,0x95,0xa9,0x12,0x23,0xbb,0x24},
+ {0xc3,0x67,0xde,0x32,0x17,0xed,0xa8,0xb1,0x48,0x49,0x1b,0x46,0x18,0x94,0xb4,0x3c,0xd2,0xbc,0xcf,0x76,0x43,0x43,0xbd,0x8e,0x08,0x80,0x18,0x1e,0x87,0x3e,0xee,0x0f,0x6b,0x5c,0xf8,0xf5,0x2a,0x0c,0xf8,0x41,0x94,0x67,0xfa,0x04,0xc3,0x84,0x72,0x68,0xad,0x1b,0xba,0xa3,0x99,0xdf,0x45,0x89,0x16,0x5d,0xeb,0xff,0xf9,0x2a,0x1d,0x0d,0xdf,0x1e,0x62,0x32,0xa1,0x8a,0xda,0xa9,0x79,0x65,0x22,0x59,0xa1,0x22,0xb8,0x30,0x93,0xc1,0x9a,0xa7,0x7b,0x19,0x04,0x40,0x76,0x1d,0x53,0x18,0x97,0xd7,0xac,0x16},
+ {0x3d,0x1d,0x9b,0x2d,0xaf,0x72,0xdf,0x72,0x5a,0x24,0x32,0xa4,0x36,0x2a,0x46,0x63,0x37,0x96,0xb3,0x16,0x79,0xa0,0xce,0x3e,0x09,0x23,0x30,0xb9,0xf6,0x0e,0x3e,0x12,0xad,0xb6,0x87,0x78,0xc5,0xc6,0x59,0xc9,0xba,0xfe,0x90,0x5f,0xad,0x9e,0xe1,0x94,0x04,0xf5,0x42,0xa3,0x62,0x4e,0xe2,0x16,0x00,0x17,0x16,0x18,0x4b,0xd3,0x4e,0x16,0x9a,0xe6,0x2f,0x19,0x4c,0xd9,0x7e,0x48,0x13,0x15,0x91,0x3a,0xea,0x2c,0xae,0x61,0x27,0xde,0xa4,0xb9,0xd3,0xf6,0x7b,0x87,0xeb,0xf3,0x73,0x10,0xc6,0x0f,0xda,0x78},
+ {0x6a,0xc6,0x2b,0xe5,0x28,0x5d,0xf1,0x5b,0x8e,0x1a,0xf0,0x70,0x18,0xe3,0x47,0x2c,0xdd,0x8b,0xc2,0x06,0xbc,0xaf,0x19,0x24,0x3a,0x17,0x6b,0x25,0xeb,0xde,0x25,0x2d,0x94,0x3a,0x0c,0x68,0xf1,0x80,0x9f,0xa2,0xe6,0xe7,0xe9,0x1a,0x15,0x7e,0xf7,0x71,0x73,0x79,0x01,0x48,0x58,0xf1,0x00,0x11,0xdd,0x8d,0xb3,0x16,0xb3,0xa4,0x4a,0x05,0xb8,0x7c,0x26,0x19,0x8d,0x46,0xc8,0xdf,0xaf,0x4d,0xe5,0x66,0x9c,0x78,0x28,0x0b,0x17,0xec,0x6e,0x66,0x2a,0x1d,0xeb,0x2a,0x60,0xa7,0x7d,0xab,0xa6,0x10,0x46,0x13},
+ {0xfe,0xb0,0xf6,0x8d,0xc7,0x8e,0x13,0x51,0x1b,0xf5,0x75,0xe5,0x89,0xda,0x97,0x53,0xb9,0xf1,0x7a,0x71,0x1d,0x7a,0x20,0x09,0x50,0xd6,0x20,0x2b,0xba,0xfd,0x02,0x21,0x15,0xf5,0xd1,0x77,0xe7,0x65,0x2a,0xcd,0xf1,0x60,0xaa,0x8f,0x87,0x91,0x89,0x54,0xe5,0x06,0xbc,0xda,0xbc,0x3b,0xb7,0xb1,0xfb,0xc9,0x7c,0xa9,0xcb,0x78,0x48,0x65,0xa1,0xe6,0x5c,0x05,0x05,0xe4,0x9e,0x96,0x29,0xad,0x51,0x12,0x68,0xa7,0xbc,0x36,0x15,0xa4,0x7d,0xaa,0x17,0xf5,0x1a,0x3a,0xba,0xb2,0xec,0x29,0xdb,0x25,0xd7,0x0a},
+ {0x57,0x24,0x4e,0x83,0xb1,0x67,0x42,0xdc,0xc5,0x1b,0xce,0x70,0xb5,0x44,0x75,0xb6,0xd7,0x5e,0xd1,0xf7,0x0b,0x7a,0xf0,0x1a,0x50,0x36,0xa0,0x71,0xfb,0xcf,0xef,0x4a,0x85,0x6f,0x05,0x9b,0x0c,0xbc,0xc7,0xfe,0xd7,0xff,0xf5,0xe7,0x68,0x52,0x7d,0x53,0xfa,0xae,0x12,0x43,0x62,0xc6,0xaf,0x77,0xd9,0x9f,0x39,0x02,0x53,0x5f,0x67,0x4f,0x1e,0x17,0x15,0x04,0x36,0x36,0x2d,0xc3,0x3b,0x48,0x98,0x89,0x11,0xef,0x2b,0xcd,0x10,0x51,0x94,0xd0,0xad,0x6e,0x0a,0x87,0x61,0x65,0xa8,0xa2,0x72,0xbb,0xcc,0x0b},
+ {0xc8,0xa9,0xb1,0xea,0x2f,0x96,0x5e,0x18,0xcd,0x7d,0x14,0x65,0x35,0xe6,0xe7,0x86,0xf2,0x6d,0x5b,0xbb,0x31,0xe0,0x92,0xb0,0x3e,0xb7,0xd6,0x59,0xab,0xf0,0x24,0x40,0x96,0x12,0xfe,0x50,0x4c,0x5e,0x6d,0x18,0x7e,0x9f,0xe8,0xfe,0x82,0x7b,0x39,0xe0,0xb0,0x31,0x70,0x50,0xc5,0xf6,0xc7,0x3b,0xc2,0x37,0x8f,0x10,0x69,0xfd,0x78,0x66,0xc2,0x63,0x68,0x63,0x31,0xfa,0x86,0x15,0xf2,0x33,0x2d,0x57,0x48,0x8c,0xf6,0x07,0xfc,0xae,0x9e,0x78,0x9f,0xcc,0x73,0x4f,0x01,0x47,0xad,0x8e,0x10,0xe2,0x42,0x2d},
+ {0x9b,0xd2,0xdf,0x94,0x15,0x13,0xf5,0x97,0x6a,0x4c,0x3f,0x31,0x5d,0x98,0x55,0x61,0x10,0x50,0x45,0x08,0x07,0x3f,0xa1,0xeb,0x22,0xd3,0xd2,0xb8,0x08,0x26,0x6b,0x67,0x93,0x75,0x53,0x0f,0x0d,0x7b,0x71,0x21,0x4c,0x06,0x1e,0x13,0x0b,0x69,0x4e,0x91,0x9f,0xe0,0x2a,0x75,0xae,0x87,0xb6,0x1b,0x6e,0x3c,0x42,0x9b,0xa7,0xf3,0x0b,0x42,0x47,0x2b,0x5b,0x1c,0x65,0xba,0x38,0x81,0x80,0x1b,0x1b,0x31,0xec,0xb6,0x71,0x86,0xb0,0x35,0x31,0xbc,0xb1,0x0c,0xff,0x7b,0xe0,0xf1,0x0c,0x9c,0xfa,0x2f,0x5d,0x74},
+ {0xbd,0xc8,0xc9,0x2b,0x1e,0x5a,0x52,0xbf,0x81,0x9d,0x47,0x26,0x08,0x26,0x5b,0xea,0xdb,0x55,0x01,0xdf,0x0e,0xc7,0x11,0xd5,0xd0,0xf5,0x0c,0x96,0xeb,0x3c,0xe2,0x1a,0x6a,0x4e,0xd3,0x21,0x57,0xdf,0x36,0x60,0xd0,0xb3,0x7b,0x99,0x27,0x88,0xdb,0xb1,0xfa,0x6a,0x75,0xc8,0xc3,0x09,0xc2,0xd3,0x39,0xc8,0x1d,0x4c,0xe5,0x5b,0xe1,0x06,0x4a,0x99,0x32,0x19,0x87,0x5d,0x72,0x5b,0xb0,0xda,0xb1,0xce,0xb5,0x1c,0x35,0x32,0x05,0xca,0xb7,0xda,0x49,0x15,0xc4,0x7d,0xf7,0xc1,0x8e,0x27,0x61,0xd8,0xde,0x58},
+ {0x5c,0xc5,0x66,0xf2,0x93,0x37,0x17,0xd8,0x49,0x4e,0x45,0xcc,0xc5,0x76,0xc9,0xc8,0xa8,0xc3,0x26,0xbc,0xf8,0x82,0xe3,0x5c,0xf9,0xf6,0x85,0x54,0xe8,0x9d,0xf3,0x2f,0xa8,0xc9,0xc2,0xb6,0xa8,0x5b,0xfb,0x2d,0x8c,0x59,0x2c,0xf5,0x8e,0xef,0xee,0x48,0x73,0x15,0x2d,0xf1,0x07,0x91,0x80,0x33,0xd8,0x5b,0x1d,0x53,0x6b,0x69,0xba,0x08,0x7a,0xc5,0xef,0xc3,0xee,0x3e,0xed,0x77,0x11,0x48,0xff,0xd4,0x17,0x55,0xe0,0x04,0xcb,0x71,0xa6,0xf1,0x3f,0x7a,0x3d,0xea,0x54,0xfe,0x7c,0x94,0xb4,0x33,0x06,0x12},
+ {0x42,0x00,0x61,0x91,0x78,0x98,0x94,0x0b,0xe8,0xfa,0xeb,0xec,0x3c,0xb1,0xe7,0x4e,0xc0,0xa4,0xf0,0x94,0x95,0x73,0xbe,0x70,0x85,0x91,0xd5,0xb4,0x99,0x0a,0xd3,0x35,0x0a,0x10,0x12,0x49,0x47,0x31,0xbd,0x82,0x06,0xbe,0x6f,0x7e,0x6d,0x7b,0x23,0xde,0xc6,0x79,0xea,0x11,0x19,0x76,0x1e,0xe1,0xde,0x3b,0x39,0xcb,0xe3,0x3b,0x43,0x07,0xf4,0x97,0xe9,0x5c,0xc0,0x44,0x79,0xff,0xa3,0x51,0x5c,0xb0,0xe4,0x3d,0x5d,0x57,0x7c,0x84,0x76,0x5a,0xfd,0x81,0x33,0x58,0x9f,0xda,0xf6,0x7a,0xde,0x3e,0x87,0x2d},
+ {0x09,0x34,0x37,0x43,0x64,0x31,0x7a,0x15,0xd9,0x81,0xaa,0xf4,0xee,0xb7,0xb8,0xfa,0x06,0x48,0xa6,0xf5,0xe6,0xfe,0x93,0xb0,0xb6,0xa7,0x7f,0x70,0x54,0x36,0x77,0x2e,0x81,0xf9,0x5d,0x4e,0xe1,0x02,0x62,0xaa,0xf5,0xe1,0x15,0x50,0x17,0x59,0x0d,0xa2,0x6c,0x1d,0xe2,0xba,0xd3,0x75,0xa2,0x18,0x53,0x02,0x60,0x01,0x8a,0x61,0x43,0x05,0xc1,0x23,0x4c,0x97,0xf4,0xbd,0xea,0x0d,0x93,0x46,0xce,0x9d,0x25,0x0a,0x6f,0xaa,0x2c,0xba,0x9a,0xa2,0xb8,0x2c,0x20,0x04,0x0d,0x96,0x07,0x2d,0x36,0x43,0x14,0x4b},
+ {0x7a,0x1f,0x6e,0xb6,0xc7,0xb7,0xc4,0xcc,0x7e,0x2f,0x0c,0xf5,0x25,0x7e,0x15,0x44,0x1c,0xaf,0x3e,0x71,0xfc,0x6d,0xf0,0x3e,0xf7,0x63,0xda,0x52,0x67,0x44,0x2f,0x58,0xcb,0x9c,0x52,0x1c,0xe9,0x54,0x7c,0x96,0xfb,0x35,0xc6,0x64,0x92,0x26,0xf6,0x30,0x65,0x19,0x12,0x78,0xf4,0xaf,0x47,0x27,0x5c,0x6f,0xf6,0xea,0x18,0x84,0x03,0x17,0xe4,0x4c,0x32,0x20,0xd3,0x7b,0x31,0xc6,0xc4,0x8b,0x48,0xa4,0xe8,0x42,0x10,0xa8,0x64,0x13,0x5a,0x4e,0x8b,0xf1,0x1e,0xb2,0xc9,0x8d,0xa2,0xcd,0x4b,0x1c,0x2a,0x0c},
+ {0x47,0x04,0x1f,0x6f,0xd0,0xc7,0x4d,0xd2,0x59,0xc0,0x87,0xdb,0x3e,0x9e,0x26,0xb2,0x8f,0xd2,0xb2,0xfb,0x72,0x02,0x5b,0xd1,0x77,0x48,0xf6,0xc6,0xd1,0x8b,0x55,0x7c,0x45,0x69,0xbd,0x69,0x48,0x81,0xc4,0xed,0x22,0x8d,0x1c,0xbe,0x7d,0x90,0x6d,0x0d,0xab,0xc5,0x5c,0xd5,0x12,0xd2,0x3b,0xc6,0x83,0xdc,0x14,0xa3,0x30,0x9b,0x6a,0x5a,0x3d,0x46,0x96,0xd3,0x24,0x15,0xec,0xd0,0xf0,0x24,0x5a,0xc3,0x8a,0x62,0xbb,0x12,0xa4,0x5f,0xbc,0x1c,0x79,0x3a,0x0c,0xa5,0xc3,0xaf,0xfb,0x0a,0xca,0xa5,0x04,0x04},
+ {0xd6,0x43,0xa7,0x0a,0x07,0x40,0x1f,0x8c,0xe8,0x5e,0x26,0x5b,0xcb,0xd0,0xba,0xcc,0xde,0xd2,0x8f,0x66,0x6b,0x04,0x4b,0x57,0x33,0x96,0xdd,0xca,0xfd,0x5b,0x39,0x46,0xd1,0x6f,0x41,0x2a,0x1b,0x9e,0xbc,0x62,0x8b,0x59,0x50,0xe3,0x28,0xf7,0xc6,0xb5,0x67,0x69,0x5d,0x3d,0xd8,0x3f,0x34,0x04,0x98,0xee,0xf8,0xe7,0x16,0x75,0x52,0x39,0x9c,0x9a,0x5d,0x1a,0x2d,0xdb,0x7f,0x11,0x2a,0x5c,0x00,0xd1,0xbc,0x45,0x77,0x9c,0xea,0x6f,0xd5,0x54,0xf1,0xbe,0xd4,0xef,0x16,0xd0,0x22,0xe8,0x29,0x9a,0x57,0x76},
+ {0x17,0x2a,0xc0,0x49,0x7e,0x8e,0xb6,0x45,0x7f,0xa3,0xa9,0xbc,0xa2,0x51,0xcd,0x23,0x1b,0x4c,0x22,0xec,0x11,0x5f,0xd6,0x3e,0xb1,0xbd,0x05,0x9e,0xdc,0x84,0xa3,0x43,0xf2,0x34,0xb4,0x52,0x13,0xb5,0x3c,0x33,0xe1,0x80,0xde,0x93,0x49,0x28,0x32,0xd8,0xce,0x35,0x0d,0x75,0x87,0x28,0x51,0xb5,0xc1,0x77,0x27,0x2a,0xbb,0x14,0xc5,0x02,0x45,0xb6,0xf1,0x8b,0xda,0xd5,0x4b,0x68,0x53,0x4b,0xb5,0xf6,0x7e,0xd3,0x8b,0xfb,0x53,0xd2,0xb0,0xa9,0xd7,0x16,0x39,0x31,0x59,0x80,0x54,0x61,0x09,0x92,0x60,0x11},
+ {0xaa,0xcf,0xda,0x29,0x69,0x16,0x4d,0xb4,0x8f,0x59,0x13,0x84,0x4c,0x9f,0x52,0xda,0x59,0x55,0x3d,0x45,0xca,0x63,0xef,0xe9,0x0b,0x8e,0x69,0xc5,0x5b,0x12,0x1e,0x35,0xcd,0x4d,0x9b,0x36,0x16,0x56,0x38,0x7a,0x63,0x35,0x5c,0x65,0xa7,0x2c,0xc0,0x75,0x21,0x80,0xf1,0xd4,0xf9,0x1b,0xc2,0x7d,0x42,0xe0,0xe6,0x91,0x74,0x7d,0x63,0x2f,0xbe,0x7b,0xf6,0x1a,0x46,0x9b,0xb4,0xd4,0x61,0x89,0xab,0xc8,0x7a,0x03,0x03,0xd6,0xfb,0x99,0xa6,0xf9,0x9f,0xe1,0xde,0x71,0x9a,0x2a,0xce,0xe7,0x06,0x2d,0x18,0x7f},
+ {0xec,0x68,0x01,0xab,0x64,0x8e,0x7c,0x7a,0x43,0xc5,0xed,0x15,0x55,0x4a,0x5a,0xcb,0xda,0x0e,0xcd,0x47,0xd3,0x19,0x55,0x09,0xb0,0x93,0x3e,0x34,0x8c,0xac,0xd4,0x67,0x22,0x75,0x21,0x8e,0x72,0x4b,0x45,0x09,0xd8,0xb8,0x84,0xd4,0xf4,0xe8,0x58,0xaa,0x3c,0x90,0x46,0x7f,0x4d,0x25,0x58,0xd3,0x17,0x52,0x1c,0x24,0x43,0xc0,0xac,0x44,0x77,0x57,0x7a,0x4f,0xbb,0x6b,0x7d,0x1c,0xe1,0x13,0x83,0x91,0xd4,0xfe,0x35,0x8b,0x84,0x46,0x6b,0xc9,0xc6,0xa1,0xdc,0x4a,0xbd,0x71,0xad,0x12,0x83,0x1c,0x6d,0x55},
+ {0x82,0x39,0x8d,0x0c,0xe3,0x40,0xef,0x17,0x34,0xfa,0xa3,0x15,0x3e,0x07,0xf7,0x31,0x6e,0x64,0x73,0x07,0xcb,0xf3,0x21,0x4f,0xff,0x4e,0x82,0x1d,0x6d,0x6c,0x6c,0x74,0x21,0xe8,0x1b,0xb1,0x56,0x67,0xf0,0x81,0xdd,0xf3,0xa3,0x10,0x23,0xf8,0xaf,0x0f,0x5d,0x46,0x99,0x6a,0x55,0xd0,0xb2,0xf8,0x05,0x7f,0x8c,0xcc,0x38,0xbe,0x7a,0x09,0xa4,0x2d,0xa5,0x7e,0x87,0xc9,0x49,0x0c,0x43,0x1d,0xdc,0x9b,0x55,0x69,0x43,0x4c,0xd2,0xeb,0xcc,0xf7,0x09,0x38,0x2c,0x02,0xbd,0x84,0xee,0x4b,0xa3,0x14,0x7e,0x57},
+ {0x0a,0x3b,0xa7,0x61,0xac,0x68,0xe2,0xf0,0xf5,0xa5,0x91,0x37,0x10,0xfa,0xfa,0xf2,0xe9,0x00,0x6d,0x6b,0x82,0x3e,0xe1,0xc1,0x42,0x8f,0xd7,0x6f,0xe9,0x7e,0xfa,0x60,0x2b,0xd7,0x4d,0xbd,0xbe,0xce,0xfe,0x94,0x11,0x22,0x0f,0x06,0xda,0x4f,0x6a,0xf4,0xff,0xd1,0xc8,0xc0,0x77,0x59,0x4a,0x12,0x95,0x92,0x00,0xfb,0xb8,0x04,0x53,0x70,0xc6,0x6e,0x29,0x4d,0x35,0x1d,0x3d,0xb6,0xd8,0x31,0xad,0x5f,0x3e,0x05,0xc3,0xf3,0xec,0x42,0xbd,0xb4,0x8c,0x95,0x0b,0x67,0xfd,0x53,0x63,0xa1,0x0c,0x8e,0x39,0x21},
+ {0xf3,0x33,0x2b,0x38,0x8a,0x05,0xf5,0x89,0xb4,0xc0,0x48,0xad,0x0b,0xba,0xe2,0x5a,0x6e,0xb3,0x3d,0xa5,0x03,0xb5,0x93,0x8f,0xe6,0x32,0xa2,0x95,0x9d,0xed,0xa3,0x5a,0x01,0x56,0xb7,0xb4,0xf9,0xaa,0x98,0x27,0x72,0xad,0x8d,0x5c,0x13,0x72,0xac,0x5e,0x23,0xa0,0xb7,0x61,0x61,0xaa,0xce,0xd2,0x4e,0x7d,0x8f,0xe9,0x84,0xb2,0xbf,0x1b,0x61,0x65,0xd9,0xc7,0xe9,0x77,0x67,0x65,0x36,0x80,0xc7,0x72,0x54,0x12,0x2b,0xcb,0xee,0x6e,0x50,0xd9,0x99,0x32,0x05,0x65,0xcc,0x57,0x89,0x5e,0x4e,0xe1,0x07,0x4a},
+ {0x99,0xf9,0x0d,0x98,0xcb,0x12,0xe4,0x4e,0x71,0xc7,0x6e,0x3c,0x6f,0xd7,0x15,0xa3,0xfd,0x77,0x5c,0x92,0xde,0xed,0xa5,0xbb,0x02,0x34,0x31,0x1d,0x39,0xac,0x0b,0x3f,0x9b,0xa4,0x77,0xc4,0xcd,0x58,0x0b,0x24,0x17,0xf0,0x47,0x64,0xde,0xda,0x38,0xfd,0xad,0x6a,0xc8,0xa7,0x32,0x8d,0x92,0x19,0x81,0xa0,0xaf,0x84,0xed,0x7a,0xaf,0x50,0xe5,0x5b,0xf6,0x15,0x01,0xde,0x4f,0x6e,0xb2,0x09,0x61,0x21,0x21,0x26,0x98,0x29,0xd9,0xd6,0xad,0x0b,0x81,0x05,0x02,0x78,0x06,0xd0,0xeb,0xba,0x16,0xa3,0x21,0x19},
+ {0xfc,0x70,0xb8,0xdf,0x7e,0x2f,0x42,0x89,0xbd,0xb3,0x76,0x4f,0xeb,0x6b,0x29,0x2c,0xf7,0x4d,0xc2,0x36,0xd4,0xf1,0x38,0x07,0xb0,0xae,0x73,0xe2,0x41,0xdf,0x58,0x64,0x8b,0xc1,0xf3,0xd9,0x9a,0xad,0x5a,0xd7,0x9c,0xc1,0xb1,0x60,0xef,0x0e,0x6a,0x56,0xd9,0x0e,0x5c,0x25,0xac,0x0b,0x9a,0x3e,0xf5,0xc7,0x62,0xa0,0xec,0x9d,0x04,0x7b,0x83,0x44,0x44,0x35,0x7a,0xe3,0xcb,0xdc,0x93,0xbe,0xed,0x0f,0x33,0x79,0x88,0x75,0x87,0xdd,0xc5,0x12,0xc3,0x04,0x60,0x78,0x64,0x0e,0x95,0xc2,0xcb,0xdc,0x93,0x60},
+ {0x6d,0x70,0xe0,0x85,0x85,0x9a,0xf3,0x1f,0x33,0x39,0xe7,0xb3,0xd8,0xa5,0xd0,0x36,0x3b,0x45,0x8f,0x71,0xe1,0xf2,0xb9,0x43,0x7c,0xa9,0x27,0x48,0x08,0xea,0xd1,0x57,0x4b,0x03,0x84,0x60,0xbe,0xee,0xde,0x6b,0x54,0xb8,0x0f,0x78,0xb6,0xc2,0x99,0x31,0x95,0x06,0x2d,0xb6,0xab,0x76,0x33,0x97,0x90,0x7d,0x64,0x8b,0xc9,0x80,0x31,0x6e,0x71,0xb0,0x28,0xa1,0xe7,0xb6,0x7a,0xee,0xaa,0x8b,0xa8,0x93,0x6d,0x59,0xc1,0xa4,0x30,0x61,0x21,0xb2,0x82,0xde,0xb4,0xf7,0x18,0xbd,0x97,0xdd,0x9d,0x99,0x3e,0x36},
+ {0xc4,0x1f,0xee,0x35,0xc1,0x43,0xa8,0x96,0xcf,0xc8,0xe4,0x08,0x55,0xb3,0x6e,0x97,0x30,0xd3,0x8c,0xb5,0x01,0x68,0x2f,0xb4,0x2b,0x05,0x3a,0x69,0x78,0x9b,0xee,0x48,0xc6,0xae,0x4b,0xe2,0xdc,0x48,0x18,0x2f,0x60,0xaf,0xbc,0xba,0x55,0x72,0x9b,0x76,0x31,0xe9,0xef,0x3c,0x6e,0x3c,0xcb,0x90,0x55,0xb3,0xf9,0xc6,0x9b,0x97,0x1f,0x23,0xc6,0xf3,0x2a,0xcc,0x4b,0xde,0x31,0x5c,0x1f,0x8d,0x20,0xfe,0x30,0xb0,0x4b,0xb0,0x66,0xb4,0x4f,0xc1,0x09,0x70,0x8d,0xb7,0x13,0x24,0x79,0x08,0x9b,0xfa,0x9b,0x07},
+ {0xf4,0x0d,0x30,0xda,0x51,0x3a,0x90,0xe3,0xb0,0x5a,0xa9,0x3d,0x23,0x64,0x39,0x84,0x80,0x64,0x35,0x0b,0x2d,0xf1,0x3c,0xed,0x94,0x71,0x81,0x84,0xf6,0x77,0x8c,0x03,0x45,0x42,0xd5,0xa2,0x80,0xed,0xc9,0xf3,0x52,0x39,0xf6,0x77,0x78,0x8b,0xa0,0x0a,0x75,0x54,0x08,0xd1,0x63,0xac,0x6d,0xd7,0x6b,0x63,0x70,0x94,0x15,0xfb,0xf4,0x1e,0xec,0x7b,0x16,0x5b,0xe6,0x5e,0x4e,0x85,0xc2,0xcd,0xd0,0x96,0x42,0x0a,0x59,0x59,0x99,0x21,0x10,0x98,0x34,0xdf,0xb2,0x72,0x56,0xff,0x0b,0x4a,0x2a,0xe9,0x5e,0x57},
+ {0xcf,0x2f,0x18,0x8a,0x90,0x80,0xc0,0xd4,0xbd,0x9d,0x48,0x99,0xc2,0x70,0xe1,0x30,0xde,0x33,0xf7,0x52,0x57,0xbd,0xba,0x05,0x00,0xfd,0xd3,0x2c,0x11,0xe7,0xd4,0x43,0x01,0xd8,0xa4,0x0a,0x45,0xbc,0x46,0x5d,0xd8,0xb9,0x33,0xa5,0x27,0x12,0xaf,0xc3,0xc2,0x06,0x89,0x2b,0x26,0x3b,0x9e,0x38,0x1b,0x58,0x2f,0x38,0x7e,0x1e,0x0a,0x20,0xc5,0x3a,0xf9,0xea,0x67,0xb9,0x8d,0x51,0xc0,0x52,0x66,0x05,0x9b,0x98,0xbc,0x71,0xf5,0x97,0x71,0x56,0xd9,0x85,0x2b,0xfe,0x38,0x4e,0x1e,0x65,0x52,0xca,0x0e,0x05},
+ {0x9c,0x0c,0x3f,0x45,0xde,0x1a,0x43,0xc3,0x9b,0x3b,0x70,0xff,0x5e,0x04,0xf5,0xe9,0x3d,0x7b,0x84,0xed,0xc9,0x7a,0xd9,0xfc,0xc6,0xf4,0x58,0x1c,0xc2,0xe6,0x0e,0x4b,0xea,0x68,0xe6,0x60,0x76,0x39,0xac,0x97,0x97,0xb4,0x3a,0x15,0xfe,0xbb,0x19,0x9b,0x9f,0xa7,0xec,0x34,0xb5,0x79,0xb1,0x4c,0x57,0xae,0x31,0xa1,0x9f,0xc0,0x51,0x61,0x96,0x5d,0xf0,0xfd,0x0d,0x5c,0xf5,0x3a,0x7a,0xee,0xb4,0x2a,0xe0,0x2e,0x26,0xdd,0x09,0x17,0x17,0x12,0x87,0xbb,0xb2,0x11,0x0b,0x03,0x0f,0x80,0xfa,0x24,0xef,0x1f},
+ {0x96,0x31,0xa7,0x1a,0xfb,0x53,0xd6,0x37,0x18,0x64,0xd7,0x3f,0x30,0x95,0x94,0x0f,0xb2,0x17,0x3a,0xfb,0x09,0x0b,0x20,0xad,0x3e,0x61,0xc8,0x2f,0x29,0x49,0x4d,0x54,0x86,0x6b,0x97,0x30,0xf5,0xaf,0xd2,0x22,0x04,0x46,0xd2,0xc2,0x06,0xb8,0x90,0x8d,0xe5,0xba,0xe5,0x4d,0x6c,0x89,0xa1,0xdc,0x17,0x0c,0x34,0xc8,0xe6,0x5f,0x00,0x28,0x88,0x86,0x52,0x34,0x9f,0xba,0xef,0x6a,0xa1,0x7d,0x10,0x25,0x94,0xff,0x1b,0x5c,0x36,0x4b,0xd9,0x66,0xcd,0xbb,0x5b,0xf7,0xfa,0x6d,0x31,0x0f,0x93,0x72,0xe4,0x72},
+ {0x4f,0x08,0x81,0x97,0x8c,0x20,0x95,0x26,0xe1,0x0e,0x45,0x23,0x0b,0x2a,0x50,0xb1,0x02,0xde,0xef,0x03,0xa6,0xae,0x9d,0xfd,0x4c,0xa3,0x33,0x27,0x8c,0x2e,0x9d,0x5a,0x27,0x76,0x2a,0xd3,0x35,0xf6,0xf3,0x07,0xf0,0x66,0x65,0x5f,0x86,0x4d,0xaa,0x7a,0x50,0x44,0xd0,0x28,0x97,0xe7,0x85,0x3c,0x38,0x64,0xe0,0x0f,0x00,0x7f,0xee,0x1f,0xe5,0xf7,0xdb,0x03,0xda,0x05,0x53,0x76,0xbd,0xcd,0x34,0x14,0x49,0xf2,0xda,0xa4,0xec,0x88,0x4a,0xd2,0xcd,0xd5,0x4a,0x7b,0x43,0x05,0x04,0xee,0x51,0x40,0xf9,0x00},
+ {0xb2,0x30,0xd3,0xc3,0x23,0x6b,0x35,0x8d,0x06,0x1b,0x47,0xb0,0x9b,0x8b,0x1c,0xf2,0x3c,0xb8,0x42,0x6e,0x6c,0x31,0x6c,0xb3,0x0d,0xb1,0xea,0x8b,0x7e,0x9c,0xd7,0x07,0x53,0x97,0xaf,0x07,0xbb,0x93,0xef,0xd7,0xa7,0x66,0xb7,0x3d,0xcf,0xd0,0x3e,0x58,0xc5,0x1e,0x0b,0x6e,0xbf,0x98,0x69,0xce,0x52,0x04,0xd4,0x5d,0xd2,0xff,0xb7,0x47,0x12,0xdd,0x08,0xbc,0x9c,0xfb,0xfb,0x87,0x9b,0xc2,0xee,0xe1,0x3a,0x6b,0x06,0x8a,0xbf,0xc1,0x1f,0xdb,0x2b,0x24,0x57,0x0d,0xb6,0x4b,0xa6,0x5e,0xa3,0x20,0x35,0x1c},
+ {0x4a,0xa3,0xcb,0xbc,0xa6,0x53,0xd2,0x80,0x9b,0x21,0x38,0x38,0xa1,0xc3,0x61,0x3e,0x96,0xe3,0x82,0x98,0x01,0xb6,0xc3,0x90,0x6f,0xe6,0x0e,0x5d,0x77,0x05,0x3d,0x1c,0x59,0xc0,0x6b,0x21,0x40,0x6f,0xa8,0xcd,0x7e,0xd8,0xbc,0x12,0x1d,0x23,0xbb,0x1f,0x90,0x09,0xc7,0x17,0x9e,0x6a,0x95,0xb4,0x55,0x2e,0xd1,0x66,0x3b,0x0c,0x75,0x38,0x1a,0xe5,0x22,0x94,0x40,0xf1,0x2e,0x69,0x71,0xf6,0x5d,0x2b,0x3c,0xc7,0xc0,0xcb,0x29,0xe0,0x4c,0x74,0xe7,0x4f,0x01,0x21,0x7c,0x48,0x30,0xd3,0xc7,0xe2,0x21,0x06},
+ {0x8d,0x83,0x59,0x82,0xcc,0x60,0x98,0xaf,0xdc,0x9a,0x9f,0xc6,0xc1,0x48,0xea,0x90,0x30,0x1e,0x58,0x65,0x37,0x48,0x26,0x65,0xbc,0xa5,0xd3,0x7b,0x09,0xd6,0x07,0x00,0xf3,0xf0,0xdb,0xb0,0x96,0x17,0xae,0xb7,0x96,0xe1,0x7c,0xe1,0xb9,0xaf,0xdf,0x54,0xb4,0xa3,0xaa,0xe9,0x71,0x30,0x92,0x25,0x9d,0x2e,0x00,0xa1,0x9c,0x58,0x8e,0x5d,0x4b,0xa9,0x42,0x08,0x95,0x1d,0xbf,0xc0,0x3e,0x2e,0x8f,0x58,0x63,0xc3,0xd3,0xb2,0xef,0xe2,0x51,0xbb,0x38,0x14,0x96,0x0a,0x86,0xbf,0x1c,0x3c,0x78,0xd7,0x83,0x15},
+ {0xe1,0x7a,0xa2,0x5d,0xef,0xa2,0xee,0xec,0x74,0x01,0x67,0x55,0x14,0x3a,0x7c,0x59,0x7a,0x16,0x09,0x66,0x12,0x2a,0xa6,0xc9,0x70,0x8f,0xed,0x81,0x2e,0x5f,0x2a,0x25,0xc7,0x28,0x9d,0xcc,0x04,0x47,0x03,0x90,0x8f,0xc5,0x2c,0xf7,0x9e,0x67,0x1b,0x1d,0x26,0x87,0x5b,0xbe,0x5f,0x2b,0xe1,0x16,0x0a,0x58,0xc5,0x83,0x4e,0x06,0x58,0x49,0x0d,0xe8,0x66,0x50,0x26,0x94,0x28,0x0d,0x6b,0x8c,0x7c,0x30,0x85,0xf7,0xc3,0xfc,0xfd,0x12,0x11,0x0c,0x78,0xda,0x53,0x1b,0x88,0xb3,0x43,0xd8,0x0b,0x17,0x9c,0x07},
+ {0xff,0x6f,0xfa,0x64,0xe4,0xec,0x06,0x05,0x23,0xe5,0x05,0x62,0x1e,0x43,0xe3,0xbe,0x42,0xea,0xb8,0x51,0x24,0x42,0x79,0x35,0x00,0xfb,0xc9,0x4a,0xe3,0x05,0xec,0x6d,0x56,0xd0,0xd5,0xc0,0x50,0xcd,0xd6,0xcd,0x3b,0x57,0x03,0xbb,0x6d,0x68,0xf7,0x9a,0x48,0xef,0xc3,0xf3,0x3f,0x72,0xa6,0x3c,0xcc,0x8a,0x7b,0x31,0xd7,0xc0,0x68,0x67,0xb3,0xc1,0x55,0xf1,0xe5,0x25,0xb6,0x94,0x91,0x7b,0x7b,0x99,0xa7,0xf3,0x7b,0x41,0x00,0x26,0x6b,0x6d,0xdc,0xbd,0x2c,0xc2,0xf4,0x52,0xcd,0xdd,0x14,0x5e,0x44,0x51},
+ {0x51,0x49,0x14,0x3b,0x4b,0x2b,0x50,0x57,0xb3,0xbc,0x4b,0x44,0x6b,0xff,0x67,0x8e,0xdb,0x85,0x63,0x16,0x27,0x69,0xbd,0xb8,0xc8,0x95,0x92,0xe3,0x31,0x6f,0x18,0x13,0x55,0xa4,0xbe,0x2b,0xab,0x47,0x31,0x89,0x29,0x91,0x07,0x92,0x4f,0xa2,0x53,0x8c,0xa7,0xf7,0x30,0xbe,0x48,0xf9,0x49,0x4b,0x3d,0xd4,0x4f,0x6e,0x08,0x90,0xe9,0x12,0x2e,0xbb,0xdf,0x7f,0xb3,0x96,0x0c,0xf1,0xf9,0xea,0x1c,0x12,0x5e,0x93,0x9a,0x9f,0x3f,0x98,0x5b,0x3a,0xc4,0x36,0x11,0xdf,0xaf,0x99,0x3e,0x5d,0xf0,0xe3,0xb2,0x77},
+ {0xde,0xc4,0x2e,0x9c,0xc5,0xa9,0x6f,0x29,0xcb,0xf3,0x84,0x4f,0xbf,0x61,0x8b,0xbc,0x08,0xf9,0xa8,0x17,0xd9,0x06,0x77,0x1c,0x5d,0x25,0xd3,0x7a,0xfc,0x95,0xb7,0x63,0xa4,0xb0,0xdd,0x12,0x9c,0x63,0x98,0xd5,0x6b,0x86,0x24,0xc0,0x30,0x9f,0xd1,0xa5,0x60,0xe4,0xfc,0x58,0x03,0x2f,0x7c,0xd1,0x8a,0x5e,0x09,0x2e,0x15,0x95,0xa1,0x07,0xc8,0x5f,0x9e,0x38,0x02,0x8f,0x36,0xa8,0x3b,0xe4,0x8d,0xcf,0x02,0x3b,0x43,0x90,0x43,0x26,0x41,0xc5,0x5d,0xfd,0xa1,0xaf,0x37,0x01,0x2f,0x03,0x3d,0xe8,0x8f,0x3e},
+ {0x94,0xa2,0x70,0x05,0xb9,0x15,0x8b,0x2f,0x49,0x45,0x08,0x67,0x70,0x42,0xf2,0x94,0x84,0xfd,0xbb,0x61,0xe1,0x5a,0x1c,0xde,0x07,0x40,0xac,0x7f,0x79,0x3b,0xba,0x75,0x3c,0xd1,0xef,0xe8,0x8d,0x4c,0x70,0x08,0x31,0x37,0xe0,0x33,0x8e,0x1a,0xc5,0xdf,0xe3,0xcd,0x60,0x12,0xa5,0x5d,0x9d,0xa5,0x86,0x8c,0x25,0xa6,0x99,0x08,0xd6,0x22,0x96,0xd1,0xcd,0x70,0xc0,0xdb,0x39,0x62,0x9a,0x8a,0x7d,0x6c,0x8b,0x8a,0xfe,0x60,0x60,0x12,0x40,0xeb,0xbc,0x47,0x88,0xb3,0x5e,0x9e,0x77,0x87,0x7b,0xd0,0x04,0x09},
+ {0x9c,0x91,0xba,0xdd,0xd4,0x1f,0xce,0xb4,0xaa,0x8d,0x4c,0xc7,0x3e,0xdb,0x31,0xcf,0x51,0xcc,0x86,0xad,0x63,0xcc,0x63,0x2c,0x07,0xde,0x1d,0xbc,0x3f,0x14,0xe2,0x43,0xb9,0x40,0xf9,0x48,0x66,0x2d,0x32,0xf4,0x39,0x0c,0x2d,0xbd,0x0c,0x2f,0x95,0x06,0x31,0xf9,0x81,0xa0,0xad,0x97,0x76,0x16,0x6c,0x2a,0xf7,0xba,0xce,0xaa,0x40,0x62,0xa0,0x95,0xa2,0x5b,0x9c,0x74,0x34,0xf8,0x5a,0xd2,0x37,0xca,0x5b,0x7c,0x94,0xd6,0x6a,0x31,0xc9,0xe7,0xa7,0x3b,0xf1,0x66,0xac,0x0c,0xb4,0x8d,0x23,0xaf,0xbd,0x56},
+ {0xeb,0x33,0x35,0xf5,0xe3,0xb9,0x2a,0x36,0x40,0x3d,0xb9,0x6e,0xd5,0x68,0x85,0x33,0x72,0x55,0x5a,0x1d,0x52,0x14,0x0e,0x9e,0x18,0x13,0x74,0x83,0x6d,0xa8,0x24,0x1d,0xb2,0x3b,0x9d,0xc1,0x6c,0xd3,0x10,0x13,0xb9,0x86,0x23,0x62,0xb7,0x6b,0x2a,0x06,0x5c,0x4f,0xa1,0xd7,0x91,0x85,0x9b,0x7c,0x54,0x57,0x1e,0x7e,0x50,0x31,0xaa,0x03,0x1f,0xce,0xd4,0xff,0x48,0x76,0xec,0xf4,0x1c,0x8c,0xac,0x54,0xf0,0xea,0x45,0xe0,0x7c,0x35,0x09,0x1d,0x82,0x25,0xd2,0x88,0x59,0x48,0xeb,0x9a,0xdc,0x61,0xb2,0x43},
+ {0xbb,0x79,0xbb,0x88,0x19,0x1e,0x5b,0xe5,0x9d,0x35,0x7a,0xc1,0x7d,0xd0,0x9e,0xa0,0x33,0xea,0x3d,0x60,0xe2,0x2e,0x2c,0xb0,0xc2,0x6b,0x27,0x5b,0xcf,0x55,0x60,0x32,0x64,0x13,0x95,0x6c,0x8b,0x3d,0x51,0x19,0x7b,0xf4,0x0b,0x00,0x26,0x71,0xfe,0x94,0x67,0x95,0x4f,0xd5,0xdd,0x10,0x8d,0x02,0x64,0x09,0x94,0x42,0xe2,0xd5,0xb4,0x02,0xf2,0x8d,0xd1,0x28,0xcb,0x55,0xa1,0xb4,0x08,0xe5,0x6c,0x18,0x46,0x46,0xcc,0xea,0x89,0x43,0x82,0x6c,0x93,0xf4,0x9c,0xc4,0x10,0x34,0x5d,0xae,0x09,0xc8,0xa6,0x27},
+ {0x88,0xb1,0x0d,0x1f,0xcd,0xeb,0xa6,0x8b,0xe8,0x5b,0x5a,0x67,0x3a,0xd7,0xd3,0x37,0x5a,0x58,0xf5,0x15,0xa3,0xdf,0x2e,0xf2,0x7e,0xa1,0x60,0xff,0x74,0x71,0xb6,0x2c,0x54,0x69,0x3d,0xc4,0x0a,0x27,0x2c,0xcd,0xb2,0xca,0x66,0x6a,0x57,0x3e,0x4a,0xdd,0x6c,0x03,0xd7,0x69,0x24,0x59,0xfa,0x79,0x99,0x25,0x8c,0x3d,0x60,0x03,0x15,0x22,0xd0,0xe1,0x0b,0x39,0xf9,0xcd,0xee,0x59,0xf1,0xe3,0x8c,0x72,0x44,0x20,0x42,0xa9,0xf4,0xf0,0x94,0x7a,0x66,0x1c,0x89,0x82,0x36,0xf4,0x90,0x38,0xb7,0xf4,0x1d,0x7b},
+ {0x24,0xa2,0xb2,0xb3,0xe0,0xf2,0x92,0xe4,0x60,0x11,0x55,0x2b,0x06,0x9e,0x6c,0x7c,0x0e,0x7b,0x7f,0x0d,0xe2,0x8f,0xeb,0x15,0x92,0x59,0xfc,0x58,0x26,0xef,0xfc,0x61,0x8c,0xf5,0xf8,0x07,0x18,0x22,0x2e,0x5f,0xd4,0x09,0x94,0xd4,0x9f,0x5c,0x55,0xe3,0x30,0xa6,0xb6,0x1f,0x8d,0xa8,0xaa,0xb2,0x3d,0xe0,0x52,0xd3,0x45,0x82,0x69,0x68,0x7a,0x18,0x18,0x2a,0x85,0x5d,0xb1,0xdb,0xd7,0xac,0xdd,0x86,0xd3,0xaa,0xe4,0xf3,0x82,0xc4,0xf6,0x0f,0x81,0xe2,0xba,0x44,0xcf,0x01,0xaf,0x3d,0x47,0x4c,0xcf,0x46},
+ {0xf9,0xe5,0xc4,0x9e,0xed,0x25,0x65,0x42,0x03,0x33,0x90,0x16,0x01,0xda,0x5e,0x0e,0xdc,0xca,0xe5,0xcb,0xf2,0xa7,0xb1,0x72,0x40,0x5f,0xeb,0x14,0xcd,0x7b,0x38,0x29,0x40,0x81,0x49,0xf1,0xa7,0x6e,0x3c,0x21,0x54,0x48,0x2b,0x39,0xf8,0x7e,0x1e,0x7c,0xba,0xce,0x29,0x56,0x8c,0xc3,0x88,0x24,0xbb,0xc5,0x8c,0x0d,0xe5,0xaa,0x65,0x10,0x57,0x0d,0x20,0xdf,0x25,0x45,0x2c,0x1c,0x4a,0x67,0xca,0xbf,0xd6,0x2d,0x3b,0x5c,0x30,0x40,0x83,0xe1,0xb1,0xe7,0x07,0x0a,0x16,0xe7,0x1c,0x4f,0xe6,0x98,0xa1,0x69},
+ {0xbc,0x78,0x1a,0xd9,0xe0,0xb2,0x62,0x90,0x67,0x96,0x50,0xc8,0x9c,0x88,0xc9,0x47,0xb8,0x70,0x50,0x40,0x66,0x4a,0xf5,0x9d,0xbf,0xa1,0x93,0x24,0xa9,0xe6,0x69,0x73,0xed,0xca,0xc5,0xdc,0x34,0x44,0x01,0xe1,0x33,0xfb,0x84,0x3c,0x96,0x5d,0xed,0x47,0xe7,0xa0,0x86,0xed,0x76,0x95,0x01,0x70,0xe4,0xf9,0x67,0xd2,0x7b,0x69,0xb2,0x25,0x64,0x68,0x98,0x13,0xfb,0x3f,0x67,0x9d,0xb8,0xc7,0x5d,0x41,0xd9,0xfb,0xa5,0x3c,0x5e,0x3b,0x27,0xdf,0x3b,0xcc,0x4e,0xe0,0xd2,0x4c,0x4e,0xb5,0x3d,0x68,0x20,0x14},
+ {0x97,0xd1,0x9d,0x24,0x1e,0xbd,0x78,0xb4,0x02,0xc1,0x58,0x5e,0x00,0x35,0x0c,0x62,0x5c,0xac,0xba,0xcc,0x2f,0xd3,0x02,0xfb,0x2d,0xa7,0x08,0xf5,0xeb,0x3b,0xb6,0x60,0xd0,0x5a,0xcc,0xc1,0x6f,0xbb,0xee,0x34,0x8b,0xac,0x46,0x96,0xe9,0x0c,0x1b,0x6a,0x53,0xde,0x6b,0xa6,0x49,0xda,0xb0,0xd3,0xc1,0x81,0xd0,0x61,0x41,0x3b,0xe8,0x31,0x4f,0x2b,0x06,0x9e,0x12,0xc7,0xe8,0x97,0xd8,0x0a,0x32,0x29,0x4f,0x8f,0xe4,0x49,0x3f,0x68,0x18,0x6f,0x4b,0xe1,0xec,0x5b,0x17,0x03,0x55,0x2d,0xb6,0x1e,0xcf,0x55},
+ {0x58,0x3d,0xc2,0x65,0x10,0x10,0x79,0x58,0x9c,0x81,0x94,0x50,0x6d,0x08,0x9d,0x8b,0xa7,0x5f,0xc5,0x12,0xa9,0x2f,0x40,0xe2,0xd4,0x91,0x08,0x57,0x64,0x65,0x9a,0x66,0x52,0x8c,0xf5,0x7d,0xe3,0xb5,0x76,0x30,0x36,0xcc,0x99,0xe7,0xdd,0xb9,0x3a,0xd7,0x20,0xee,0x13,0x49,0xe3,0x1c,0x83,0xbd,0x33,0x01,0xba,0x62,0xaa,0xfb,0x56,0x1a,0xec,0xc9,0x9d,0x5c,0x50,0x6b,0x3e,0x94,0x1a,0x37,0x7c,0xa7,0xbb,0x57,0x25,0x30,0x51,0x76,0x34,0x41,0x56,0xae,0x73,0x98,0x5c,0x8a,0xc5,0x99,0x67,0x83,0xc4,0x13},
+ {0xb9,0xe1,0xb3,0x5a,0x46,0x5d,0x3a,0x42,0x61,0x3f,0xf1,0xc7,0x87,0xc1,0x13,0xfc,0xb6,0xb9,0xb5,0xec,0x64,0x36,0xf8,0x19,0x07,0xb6,0x37,0xa6,0x93,0x0c,0xf8,0x66,0x80,0xd0,0x8b,0x5d,0x6a,0xfb,0xdc,0xc4,0x42,0x48,0x1a,0x57,0xec,0xc4,0xeb,0xde,0x65,0x53,0xe5,0xb8,0x83,0xe8,0xb2,0xd4,0x27,0xb8,0xe5,0xc8,0x7d,0xc8,0xbd,0x50,0x11,0xe1,0xdf,0x6e,0x83,0x37,0x6d,0x60,0xd9,0xab,0x11,0xf0,0x15,0x3e,0x35,0x32,0x96,0x3b,0xb7,0x25,0xc3,0x3a,0xb0,0x64,0xae,0xd5,0x5f,0x72,0x44,0x64,0xd5,0x1d},
+ {0x7d,0x12,0x62,0x33,0xf8,0x7f,0xa4,0x8f,0x15,0x7c,0xcd,0x71,0xc4,0x6a,0x9f,0xbc,0x8b,0x0c,0x22,0x49,0x43,0x45,0x71,0x6e,0x2e,0x73,0x9f,0x21,0x12,0x59,0x64,0x0e,0x9a,0xc8,0xba,0x08,0x00,0xe6,0x97,0xc2,0xe0,0xc3,0xe1,0xea,0x11,0xea,0x4c,0x7d,0x7c,0x97,0xe7,0x9f,0xe1,0x8b,0xe3,0xf3,0xcd,0x05,0xa3,0x63,0x0f,0x45,0x3a,0x3a,0x27,0x46,0x39,0xd8,0x31,0x2f,0x8f,0x07,0x10,0xa5,0x94,0xde,0x83,0x31,0x9d,0x38,0x80,0x6f,0x99,0x17,0x6d,0x6c,0xe3,0xd1,0x7b,0xa8,0xa9,0x93,0x93,0x8d,0x8c,0x31},
+ {0x19,0xfe,0xff,0x2a,0x03,0x5d,0x74,0xf2,0x66,0xdb,0x24,0x7f,0x49,0x3c,0x9f,0x0c,0xef,0x98,0x85,0xba,0xe3,0xd3,0x98,0xbc,0x14,0x53,0x1d,0x9a,0x67,0x7c,0x4c,0x22,0x98,0xd3,0x1d,0xab,0x29,0x9e,0x66,0x5d,0x3b,0x9e,0x2d,0x34,0x58,0x16,0x92,0xfc,0xcd,0x73,0x59,0xf3,0xfd,0x1d,0x85,0x55,0xf6,0x0a,0x95,0x25,0xc3,0x41,0x9a,0x50,0xe9,0x25,0xf9,0xa6,0xdc,0x6e,0xc0,0xbd,0x33,0x1f,0x1b,0x64,0xf4,0xf3,0x3e,0x79,0x89,0x3e,0x83,0x9d,0x80,0x12,0xec,0x82,0x89,0x13,0xa1,0x28,0x23,0xf0,0xbf,0x05},
+ {0x0b,0xe0,0xca,0x23,0x70,0x13,0x32,0x36,0x59,0xcf,0xac,0xd1,0x0a,0xcf,0x4a,0x54,0x88,0x1c,0x1a,0xd2,0x49,0x10,0x74,0x96,0xa7,0x44,0x2a,0xfa,0xc3,0x8c,0x0b,0x78,0xe4,0x12,0xc5,0x0d,0xdd,0xa0,0x81,0x68,0xfe,0xfa,0xa5,0x44,0xc8,0x0d,0xe7,0x4f,0x40,0x52,0x4a,0x8f,0x6b,0x8e,0x74,0x1f,0xea,0xa3,0x01,0xee,0xcd,0x77,0x62,0x57,0x5f,0x30,0x4f,0x23,0xbc,0x8a,0xf3,0x1e,0x08,0xde,0x05,0x14,0xbd,0x7f,0x57,0x9a,0x0d,0x2a,0xe6,0x34,0x14,0xa5,0x82,0x5e,0xa1,0xb7,0x71,0x62,0x72,0x18,0xf4,0x5f},
+ {0x9d,0xdb,0x89,0x17,0x0c,0x08,0x8e,0x39,0xf5,0x78,0xe7,0xf3,0x25,0x20,0x60,0xa7,0x5d,0x03,0xbd,0x06,0x4c,0x89,0x98,0xfa,0xbe,0x66,0xa9,0x25,0xdc,0x03,0x6a,0x10,0x40,0x95,0xb6,0x13,0xe8,0x47,0xdb,0xe5,0xe1,0x10,0x26,0x43,0x3b,0x2a,0x5d,0xf3,0x76,0x12,0x78,0x38,0xe9,0x26,0x1f,0xac,0x69,0xcb,0xa0,0xa0,0x8c,0xdb,0xd4,0x29,0xd0,0x53,0x33,0x33,0xaf,0x0a,0xad,0xd9,0xe5,0x09,0xd3,0xac,0xa5,0x9d,0x66,0x38,0xf0,0xf7,0x88,0xc8,0x8a,0x65,0x57,0x3c,0xfa,0xbe,0x2c,0x05,0x51,0x8a,0xb3,0x4a},
+ {0x93,0xd5,0x68,0x67,0x25,0x2b,0x7c,0xda,0x13,0xca,0x22,0x44,0x57,0xc0,0xc1,0x98,0x1d,0xce,0x0a,0xca,0xd5,0x0b,0xa8,0xf1,0x90,0xa6,0x88,0xc0,0xad,0xd1,0xcd,0x29,0x9c,0xc0,0xdd,0x5f,0xef,0xd1,0xcf,0xd6,0xce,0x5d,0x57,0xf7,0xfd,0x3e,0x2b,0xe8,0xc2,0x34,0x16,0x20,0x5d,0x6b,0xd5,0x25,0x9b,0x2b,0xed,0x04,0xbb,0xc6,0x41,0x30,0x48,0xe1,0x56,0xd9,0xf9,0xf2,0xf2,0x0f,0x2e,0x6b,0x35,0x9f,0x75,0x97,0xe7,0xad,0x5c,0x02,0x6c,0x5f,0xbb,0x98,0x46,0x1a,0x7b,0x9a,0x04,0x14,0x68,0xbd,0x4b,0x10},
+ {0x67,0xed,0xf1,0x68,0x31,0xfd,0xf0,0x51,0xc2,0x3b,0x6f,0xd8,0xcd,0x1d,0x81,0x2c,0xde,0xf2,0xd2,0x04,0x43,0x5c,0xdc,0x44,0x49,0x71,0x2a,0x09,0x57,0xcc,0xe8,0x5b,0x63,0xf1,0x7f,0xd6,0x5f,0x9a,0x5d,0xa9,0x81,0x56,0xc7,0x4c,0x9d,0xe6,0x2b,0xe9,0x57,0xf2,0x20,0xde,0x4c,0x02,0xf8,0xb7,0xf5,0x2d,0x07,0xfb,0x20,0x2a,0x4f,0x20,0x79,0xb0,0xeb,0x30,0x3d,0x3b,0x14,0xc8,0x30,0x2e,0x65,0xbd,0x5a,0x15,0x89,0x75,0x31,0x5c,0x6d,0x8f,0x31,0x3c,0x3c,0x65,0x1f,0x16,0x79,0xc2,0x17,0xfb,0x70,0x25},
+ {0x75,0x15,0xb6,0x2c,0x7f,0x36,0xfa,0x3e,0x6c,0x02,0xd6,0x1c,0x76,0x6f,0xf9,0xf5,0x62,0x25,0xb5,0x65,0x2a,0x14,0xc7,0xe8,0xcd,0x0a,0x03,0x53,0xea,0x65,0xcb,0x3d,0x5a,0x24,0xb8,0x0b,0x55,0xa9,0x2e,0x19,0xd1,0x50,0x90,0x8f,0xa8,0xfb,0xe6,0xc8,0x35,0xc9,0xa4,0x88,0x2d,0xea,0x86,0x79,0x68,0x86,0x01,0xde,0x91,0x5f,0x1c,0x24,0xaa,0x6c,0xde,0x40,0x29,0x17,0xd8,0x28,0x3a,0x73,0xd9,0x22,0xf0,0x2c,0xbf,0x8f,0xd1,0x01,0x5b,0x23,0xdd,0xfc,0xd7,0x16,0xe5,0xf0,0xcd,0x5f,0xdd,0x0e,0x42,0x08},
+ {0x4a,0xfa,0x62,0x83,0xab,0x20,0xff,0xcd,0x6e,0x3e,0x1a,0xe2,0xd4,0x18,0xe1,0x57,0x2b,0xe6,0x39,0xfc,0x17,0x96,0x17,0xe3,0xfd,0x69,0x17,0xbc,0xef,0x53,0x9a,0x0d,0xce,0x10,0xf4,0x04,0x4e,0xc3,0x58,0x03,0x85,0x06,0x6e,0x27,0x5a,0x5b,0x13,0xb6,0x21,0x15,0xb9,0xeb,0xc7,0x70,0x96,0x5d,0x9c,0x88,0xdb,0x21,0xf3,0x54,0xd6,0x04,0xd5,0xb5,0xbd,0xdd,0x16,0xc1,0x7d,0x5e,0x2d,0xdd,0xa5,0x8d,0xb6,0xde,0x54,0x29,0x92,0xa2,0x34,0x33,0x17,0x08,0xb6,0x1c,0xd7,0x1a,0x99,0x18,0x26,0x4f,0x7a,0x4a},
+ {0x95,0x5f,0xb1,0x5f,0x02,0x18,0xa7,0xf4,0x8f,0x1b,0x5c,0x6b,0x34,0x5f,0xf6,0x3d,0x12,0x11,0xe0,0x00,0x85,0xf0,0xfc,0xcd,0x48,0x18,0xd3,0xdd,0x4c,0x0c,0xb5,0x11,0x4b,0x2a,0x37,0xaf,0x91,0xb2,0xc3,0x24,0xf2,0x47,0x81,0x71,0x70,0x82,0xda,0x93,0xf2,0x9e,0x89,0x86,0x64,0x85,0x84,0xdd,0x33,0xee,0xe0,0x23,0x42,0x31,0x96,0x4a,0xd6,0xff,0xa4,0x08,0x44,0x27,0xe8,0xa6,0xd9,0x76,0x15,0x9c,0x7e,0x17,0x8e,0x73,0xf2,0xb3,0x02,0x3d,0xb6,0x48,0x33,0x77,0x51,0xcc,0x6b,0xce,0x4d,0xce,0x4b,0x4f},
+ {0x84,0x25,0x24,0xe2,0x5a,0xce,0x1f,0xa7,0x9e,0x8a,0xf5,0x92,0x56,0x72,0xea,0x26,0xf4,0x3c,0xea,0x1c,0xd7,0x09,0x1a,0xd2,0xe6,0x01,0x1c,0xb7,0x14,0xdd,0xfc,0x73,0x6f,0x0b,0x9d,0xc4,0x6e,0x61,0xe2,0x30,0x17,0x23,0xec,0xca,0x8f,0x71,0x56,0xe4,0xa6,0x4f,0x6b,0xf2,0x9b,0x40,0xeb,0x48,0x37,0x5f,0x59,0x61,0xe5,0xce,0x42,0x30,0x41,0xac,0x9b,0x44,0x79,0x70,0x7e,0x42,0x0a,0x31,0xe2,0xbc,0x6d,0xe3,0x5a,0x85,0x7c,0x1a,0x84,0x5f,0x21,0x76,0xae,0x4c,0xd6,0xe1,0x9c,0x9a,0x0c,0x74,0x9e,0x38},
+ {0xce,0xb9,0xdc,0x34,0xae,0xb3,0xfc,0x64,0xad,0xd0,0x48,0xe3,0x23,0x03,0x50,0x97,0x1b,0x38,0xc6,0x62,0x7d,0xf0,0xb3,0x45,0x88,0x67,0x5a,0x46,0x79,0x53,0x54,0x61,0x28,0xac,0x0e,0x57,0xf6,0x78,0xbd,0xc9,0xe1,0x9c,0x91,0x27,0x32,0x0b,0x5b,0xe5,0xed,0x91,0x9b,0xa1,0xab,0x3e,0xfc,0x65,0x90,0x36,0x26,0xd6,0xe5,0x25,0xc4,0x25,0x6e,0xde,0xd7,0xf1,0xa6,0x06,0x3e,0x3f,0x08,0x23,0x06,0x8e,0x27,0x76,0xf9,0x3e,0x77,0x6c,0x8a,0x4e,0x26,0xf6,0x14,0x8c,0x59,0x47,0x48,0x15,0x89,0xa0,0x39,0x65},
+ {0x73,0xf7,0xd2,0xc3,0x74,0x1f,0xd2,0xe9,0x45,0x68,0xc4,0x25,0x41,0x54,0x50,0xc1,0x33,0x9e,0xb9,0xf9,0xe8,0x5c,0x4e,0x62,0x6c,0x18,0xcd,0xc5,0xaa,0xe4,0xc5,0x11,0x19,0x4a,0xbb,0x14,0xd4,0xdb,0xc4,0xdd,0x8e,0x4f,0x42,0x98,0x3c,0xbc,0xb2,0x19,0x69,0x71,0xca,0x36,0xd7,0x9f,0xa8,0x48,0x90,0xbd,0x19,0xf0,0x0e,0x32,0x65,0x0f,0xc6,0xe0,0xfd,0xca,0xb1,0xd1,0x86,0xd4,0x81,0x51,0x3b,0x16,0xe3,0xe6,0x3f,0x4f,0x9a,0x93,0xf2,0xfa,0x0d,0xaf,0xa8,0x59,0x2a,0x07,0x33,0xec,0xbd,0xc7,0xab,0x4c},
+ {0x2e,0x0a,0x9c,0x08,0x24,0x96,0x9e,0x23,0x38,0x47,0xfe,0x3a,0xc0,0xc4,0x48,0xc7,0x2a,0xa1,0x4f,0x76,0x2a,0xed,0xdb,0x17,0x82,0x85,0x1c,0x32,0xf0,0x93,0x9b,0x63,0x89,0xd2,0x78,0x3f,0x8f,0x78,0x8f,0xc0,0x9f,0x4d,0x40,0xa1,0x2c,0xa7,0x30,0xfe,0x9d,0xcc,0x65,0xcf,0xfc,0x8b,0x77,0xf2,0x21,0x20,0xcb,0x5a,0x16,0x98,0xe4,0x7e,0xc3,0xa1,0x11,0x91,0xe3,0x08,0xd5,0x7b,0x89,0x74,0x90,0x80,0xd4,0x90,0x2b,0x2b,0x19,0xfd,0x72,0xae,0xc2,0xae,0xd2,0xe7,0xa6,0x02,0xb6,0x85,0x3c,0x49,0xdf,0x0e},
+ {0x68,0x5a,0x9b,0x59,0x58,0x81,0xcc,0xae,0x0e,0xe2,0xad,0xeb,0x0f,0x4f,0x57,0xea,0x07,0x7f,0xb6,0x22,0x74,0x1d,0xe4,0x4f,0xb4,0x4f,0x9d,0x01,0xe3,0x92,0x3b,0x40,0x13,0x41,0x76,0x84,0xd2,0xc4,0x67,0x67,0x35,0xf8,0xf5,0xf7,0x3f,0x40,0x90,0xa0,0xde,0xbe,0xe6,0xca,0xfa,0xcf,0x8f,0x1c,0x69,0xa3,0xdf,0xd1,0x54,0x0c,0xc0,0x04,0xf8,0x5c,0x46,0x8b,0x81,0x2f,0xc2,0x4d,0xf8,0xef,0x80,0x14,0x5a,0xf3,0xa0,0x71,0x57,0xd6,0xc7,0x04,0xad,0xbf,0xe8,0xae,0xf4,0x76,0x61,0xb2,0x2a,0xb1,0x5b,0x35},
+ {0xf4,0xbb,0x93,0x74,0xcc,0x64,0x1e,0xa7,0xc3,0xb0,0xa3,0xec,0xd9,0x84,0xbd,0xe5,0x85,0xe7,0x05,0xfa,0x0c,0xc5,0x6b,0x0a,0x12,0xc3,0x2e,0x18,0x32,0x81,0x9b,0x0f,0x18,0x73,0x8c,0x5a,0xc7,0xda,0x01,0xa3,0x11,0xaa,0xce,0xb3,0x9d,0x03,0x90,0xed,0x2d,0x3f,0xae,0x3b,0xbf,0x7c,0x07,0x6f,0x8e,0xad,0x52,0xe0,0xf8,0xea,0x18,0x75,0x32,0x6c,0x7f,0x1b,0xc4,0x59,0x88,0xa4,0x98,0x32,0x38,0xf4,0xbc,0x60,0x2d,0x0f,0xd9,0xd1,0xb1,0xc9,0x29,0xa9,0x15,0x18,0xc4,0x55,0x17,0xbb,0x1b,0x87,0xc3,0x47},
+ {0x48,0x4f,0xec,0x71,0x97,0x53,0x44,0x51,0x6e,0x5d,0x8c,0xc9,0x7d,0xb1,0x05,0xf8,0x6b,0xc6,0xc3,0x47,0x1a,0xc1,0x62,0xf7,0xdc,0x99,0x46,0x76,0x85,0x9b,0xb8,0x00,0xb0,0x66,0x50,0xc8,0x50,0x5d,0xe6,0xfb,0xb0,0x99,0xa2,0xb3,0xb0,0xc4,0xec,0x62,0xe0,0xe8,0x1a,0x44,0xea,0x54,0x37,0xe5,0x5f,0x8d,0xd4,0xe8,0x2c,0xa0,0xfe,0x08,0xd0,0xea,0xde,0x68,0x76,0xdd,0x4d,0x82,0x23,0x5d,0x68,0x4b,0x20,0x45,0x64,0xc8,0x65,0xd6,0x89,0x5d,0xcd,0xcf,0x14,0xb5,0x37,0xd5,0x75,0x4f,0xa7,0x29,0x38,0x47},
+ {0x18,0xc4,0x79,0x46,0x75,0xda,0xd2,0x82,0xf0,0x8d,0x61,0xb2,0xd8,0xd7,0x3b,0xe6,0x0a,0xeb,0x47,0xac,0x24,0xef,0x5e,0x35,0xb4,0xc6,0x33,0x48,0x4c,0x68,0x78,0x20,0xc9,0x02,0x39,0xad,0x3a,0x53,0xd9,0x23,0x8f,0x58,0x03,0xef,0xce,0xdd,0xc2,0x64,0xb4,0x2f,0xe1,0xcf,0x90,0x73,0x25,0x15,0x90,0xd3,0xe4,0x44,0x4d,0x8b,0x66,0x6c,0x0c,0x82,0x78,0x7a,0x21,0xcf,0x48,0x3b,0x97,0x3e,0x27,0x81,0xb2,0x0a,0x6a,0xf7,0x7b,0xed,0x8e,0x8c,0xa7,0x65,0x6c,0xa9,0x3f,0x43,0x8a,0x4f,0x05,0xa6,0x11,0x74},
+ {0x6d,0xc8,0x9d,0xb9,0x32,0x9d,0x65,0x4d,0x15,0xf1,0x3a,0x60,0x75,0xdc,0x4c,0x04,0x88,0xe4,0xc2,0xdc,0x2c,0x71,0x4c,0xb3,0xff,0x34,0x81,0xfb,0x74,0x65,0x13,0x7c,0xb4,0x75,0xb1,0x18,0x3d,0xe5,0x9a,0x57,0x02,0xa1,0x92,0xf3,0x59,0x31,0x71,0x68,0xf5,0x35,0xef,0x1e,0xba,0xec,0x55,0x84,0x8f,0x39,0x8c,0x45,0x72,0xa8,0xc9,0x1e,0x9b,0x50,0xa2,0x00,0xd4,0xa4,0xe6,0xb8,0xb4,0x82,0xc8,0x0b,0x02,0xd7,0x81,0x9b,0x61,0x75,0x95,0xf1,0x9b,0xcc,0xe7,0x57,0x60,0x64,0xcd,0xc7,0xa5,0x88,0xdd,0x3a},
+ {0xf2,0xdc,0x35,0xb6,0x70,0x57,0x89,0xab,0xbc,0x1f,0x6c,0xf6,0x6c,0xef,0xdf,0x02,0x87,0xd1,0xb6,0xbe,0x68,0x02,0x53,0x85,0x74,0x9e,0x87,0xcc,0xfc,0x29,0x99,0x24,0x46,0x30,0x39,0x59,0xd4,0x98,0xc2,0x85,0xec,0x59,0xf6,0x5f,0x98,0x35,0x7e,0x8f,0x3a,0x6e,0xf6,0xf2,0x2a,0xa2,0x2c,0x1d,0x20,0xa7,0x06,0xa4,0x31,0x11,0xba,0x61,0x29,0x90,0x95,0x16,0xf1,0xa0,0xd0,0xa3,0x89,0xbd,0x7e,0xba,0x6c,0x6b,0x3b,0x02,0x07,0x33,0x78,0x26,0x3e,0x5a,0xf1,0x7b,0xe7,0xec,0xd8,0xbb,0x0c,0x31,0x20,0x56},
+ {0x43,0xd6,0x34,0x49,0x43,0x93,0x89,0x52,0xf5,0x22,0x12,0xa5,0x06,0xf8,0xdb,0xb9,0x22,0x1c,0xf4,0xc3,0x8f,0x87,0x6d,0x8f,0x30,0x97,0x9d,0x4d,0x2a,0x6a,0x67,0x37,0xd6,0x85,0xe2,0x77,0xf4,0xb5,0x46,0x66,0x93,0x61,0x8f,0x6c,0x67,0xff,0xe8,0x40,0xdd,0x94,0xb5,0xab,0x11,0x73,0xec,0xa6,0x4d,0xec,0x8c,0x65,0xf3,0x46,0xc8,0x7e,0xc7,0x2e,0xa2,0x1d,0x3f,0x8f,0x5e,0x9b,0x13,0xcd,0x01,0x6c,0x77,0x1d,0x0f,0x13,0xb8,0x9f,0x98,0xa2,0xcf,0x8f,0x4c,0x21,0xd5,0x9d,0x9b,0x39,0x23,0xf7,0xaa,0x6d},
+ {0x47,0xbe,0x3d,0xeb,0x62,0x75,0x3a,0x5f,0xb8,0xa0,0xbd,0x8e,0x54,0x38,0xea,0xf7,0x99,0x72,0x74,0x45,0x31,0xe5,0xc3,0x00,0x51,0xd5,0x27,0x16,0xe7,0xe9,0x04,0x13,0xa2,0x8e,0xad,0xac,0xbf,0x04,0x3b,0x58,0x84,0xe8,0x8b,0x14,0xe8,0x43,0xb7,0x29,0xdb,0xc5,0x10,0x08,0x3b,0x58,0x1e,0x2b,0xaa,0xbb,0xb3,0x8e,0xe5,0x49,0x54,0x2b,0xfe,0x9c,0xdc,0x6a,0xd2,0x14,0x98,0x78,0x0b,0xdd,0x48,0x8b,0x3f,0xab,0x1b,0x3c,0x0a,0xc6,0x79,0xf9,0xff,0xe1,0x0f,0xda,0x93,0xd6,0x2d,0x7c,0x2d,0xde,0x68,0x44},
+ {0x9e,0x46,0x19,0x94,0x5e,0x35,0xbb,0x51,0x54,0xc7,0xdd,0x23,0x4c,0xdc,0xe6,0x33,0x62,0x99,0x7f,0x44,0xd6,0xb6,0xa5,0x93,0x63,0xbd,0x44,0xfb,0x6f,0x7c,0xce,0x6c,0xce,0x07,0x63,0xf8,0xc6,0xd8,0x9a,0x4b,0x28,0x0c,0x5d,0x43,0x31,0x35,0x11,0x21,0x2c,0x77,0x7a,0x65,0xc5,0x66,0xa8,0xd4,0x52,0x73,0x24,0x63,0x7e,0x42,0xa6,0x5d,0xca,0x22,0xac,0xde,0x88,0xc6,0x94,0x1a,0xf8,0x1f,0xae,0xbb,0xf7,0x6e,0x06,0xb9,0x0f,0x58,0x59,0x8d,0x38,0x8c,0xad,0x88,0xa8,0x2c,0x9f,0xe7,0xbf,0x9a,0xf2,0x58},
+ {0x68,0x3e,0xe7,0x8d,0xab,0xcf,0x0e,0xe9,0xa5,0x76,0x7e,0x37,0x9f,0x6f,0x03,0x54,0x82,0x59,0x01,0xbe,0x0b,0x5b,0x49,0xf0,0x36,0x1e,0xf4,0xa7,0xc4,0x29,0x76,0x57,0xf6,0xcd,0x0e,0x71,0xbf,0x64,0x5a,0x4b,0x3c,0x29,0x2c,0x46,0x38,0xe5,0x4c,0xb1,0xb9,0x3a,0x0b,0xd5,0x56,0xd0,0x43,0x36,0x70,0x48,0x5b,0x18,0x24,0x37,0xf9,0x6a,0x88,0xa8,0xc6,0x09,0x45,0x02,0x20,0x32,0x73,0x89,0x55,0x4b,0x13,0x36,0xe0,0xd2,0x9f,0x28,0x33,0x3c,0x23,0x36,0xe2,0x83,0x8f,0xc1,0xae,0x0c,0xbb,0x25,0x1f,0x70},
+ {0xed,0x6c,0x61,0xe4,0xf8,0xb0,0xa8,0xc3,0x7d,0xa8,0x25,0x9e,0x0e,0x66,0x00,0xf7,0x9c,0xa5,0xbc,0xf4,0x1f,0x06,0xe3,0x61,0xe9,0x0b,0xc4,0xbd,0xbf,0x92,0x0c,0x2e,0x13,0xc1,0xbe,0x7c,0xd9,0xf6,0x18,0x9d,0xe4,0xdb,0xbf,0x74,0xe6,0x06,0x4a,0x84,0xd6,0x60,0x4e,0xac,0x22,0xb5,0xf5,0x20,0x51,0x5e,0x95,0x50,0xc0,0x5b,0x0a,0x72,0x35,0x5a,0x80,0x9b,0x43,0x09,0x3f,0x0c,0xfc,0xab,0x42,0x62,0x37,0x8b,0x4e,0xe8,0x46,0x93,0x22,0x5c,0xf3,0x17,0x14,0x69,0xec,0xf0,0x4e,0x14,0xbb,0x9c,0x9b,0x0e},
+ {0xad,0x20,0x57,0xfb,0x8f,0xd4,0xba,0xfb,0x0e,0x0d,0xf9,0xdb,0x6b,0x91,0x81,0xee,0xbf,0x43,0x55,0x63,0x52,0x31,0x81,0xd4,0xd8,0x7b,0x33,0x3f,0xeb,0x04,0x11,0x22,0xee,0xbe,0xb1,0x5d,0xd5,0x9b,0xee,0x8d,0xb9,0x3f,0x72,0x0a,0x37,0xab,0xc3,0xc9,0x91,0xd7,0x68,0x1c,0xbf,0xf1,0xa8,0x44,0xde,0x3c,0xfd,0x1c,0x19,0x44,0x6d,0x36,0x14,0x8c,0xbc,0xf2,0x43,0x17,0x3c,0x9e,0x3b,0x6c,0x85,0xb5,0xfc,0x26,0xda,0x2e,0x97,0xfb,0xa7,0x68,0x0e,0x2f,0xb8,0xcc,0x44,0x32,0x59,0xbc,0xe6,0xa4,0x67,0x41},
+ {0x00,0x27,0xf6,0x76,0x28,0x9d,0x3b,0x64,0xeb,0x68,0x76,0x0e,0x40,0x9d,0x1d,0x5d,0x84,0x06,0xfc,0x21,0x03,0x43,0x4b,0x1b,0x6a,0x24,0x55,0x22,0x7e,0xbb,0x38,0x79,0xee,0x8f,0xce,0xf8,0x65,0x26,0xbe,0xc2,0x2c,0xd6,0x80,0xe8,0x14,0xff,0x67,0xe9,0xee,0x4e,0x36,0x2f,0x7e,0x6e,0x2e,0xf1,0xf6,0xd2,0x7e,0xcb,0x70,0x33,0xb3,0x34,0xcc,0xd6,0x81,0x86,0xee,0x91,0xc5,0xcd,0x53,0xa7,0x85,0xed,0x9c,0x10,0x02,0xce,0x83,0x88,0x80,0x58,0xc1,0x85,0x74,0xed,0xe4,0x65,0xfe,0x2d,0x6e,0xfc,0x76,0x11},
+ {0x9b,0x61,0x9c,0x5b,0xd0,0x6c,0xaf,0xb4,0x80,0x84,0xa5,0xb2,0xf4,0xc9,0xdf,0x2d,0xc4,0x4d,0xe9,0xeb,0x02,0xa5,0x4f,0x3d,0x34,0x5f,0x7d,0x67,0x4c,0x3a,0xfc,0x08,0xb8,0x0e,0x77,0x49,0x89,0xe2,0x90,0xdb,0xa3,0x40,0xf4,0xac,0x2a,0xcc,0xfb,0x98,0x9b,0x87,0xd7,0xde,0xfe,0x4f,0x35,0x21,0xb6,0x06,0x69,0xf2,0x54,0x3e,0x6a,0x1f,0xea,0x34,0x07,0xd3,0x99,0xc1,0xa4,0x60,0xd6,0x5c,0x16,0x31,0xb6,0x85,0xc0,0x40,0x95,0x82,0x59,0xf7,0x23,0x3e,0x33,0xe2,0xd1,0x00,0xb9,0x16,0x01,0xad,0x2f,0x4f},
+ {0x54,0x4e,0xae,0x94,0x41,0xb2,0xbe,0x44,0x6c,0xef,0x57,0x18,0x51,0x1c,0x54,0x5f,0x98,0x04,0x8d,0x36,0x2d,0x6b,0x1e,0xa6,0xab,0xf7,0x2e,0x97,0xa4,0x84,0x54,0x44,0x38,0xb6,0x3b,0xb7,0x1d,0xd9,0x2c,0x96,0x08,0x9c,0x12,0xfc,0xaa,0x77,0x05,0xe6,0x89,0x16,0xb6,0xf3,0x39,0x9b,0x61,0x6f,0x81,0xee,0x44,0x29,0x5f,0x99,0x51,0x34,0x7c,0x7d,0xea,0x9f,0xd0,0xfc,0x52,0x91,0xf6,0x5c,0x93,0xb0,0x94,0x6c,0x81,0x4a,0x40,0x5c,0x28,0x47,0xaa,0x9a,0x8e,0x25,0xb7,0x93,0x28,0x04,0xa6,0x9c,0xb8,0x10},
+ {0x9c,0x28,0x18,0x97,0x49,0x47,0x59,0x3d,0x26,0x3f,0x53,0x24,0xc5,0xf8,0xeb,0x12,0x15,0xef,0xc3,0x14,0xcb,0xbf,0x62,0x02,0x8e,0x51,0xb7,0x77,0xd5,0x78,0xb8,0x20,0x6e,0xf0,0x45,0x5a,0xbe,0x41,0x39,0x75,0x65,0x5f,0x9c,0x6d,0xed,0xae,0x7c,0xd0,0xb6,0x51,0xff,0x72,0x9c,0x6b,0x77,0x11,0xa9,0x4d,0x0d,0xef,0xd9,0xd1,0xd2,0x17,0x6a,0x3e,0x3f,0x07,0x18,0xaf,0xf2,0x27,0x69,0x10,0x52,0xd7,0x19,0xe5,0x3f,0xfd,0x22,0x00,0xa6,0x3c,0x2c,0xb7,0xe3,0x22,0xa7,0xc6,0x65,0xcc,0x63,0x4f,0x21,0x72},
+ {0x93,0xa6,0x07,0x53,0x40,0x7f,0xe3,0xb4,0x95,0x67,0x33,0x2f,0xd7,0x14,0xa7,0xab,0x99,0x10,0x76,0x73,0xa7,0xd0,0xfb,0xd6,0xc9,0xcb,0x71,0x81,0xc5,0x48,0xdf,0x5f,0xc9,0x29,0x3b,0xf4,0xb9,0xb7,0x9d,0x1d,0x75,0x8f,0x51,0x4f,0x4a,0x82,0x05,0xd6,0xc4,0x9d,0x2f,0x31,0xbd,0x72,0xc0,0xf2,0xb0,0x45,0x15,0x5a,0x85,0xac,0x24,0x1f,0xaa,0x05,0x95,0x8e,0x32,0x08,0xd6,0x24,0xee,0x20,0x14,0x0c,0xd1,0xc1,0x48,0x47,0xa2,0x25,0xfb,0x06,0x5c,0xe4,0xff,0xc7,0xe6,0x95,0xe3,0x2a,0x9e,0x73,0xba,0x00},
+ {0xd6,0x90,0x87,0x5c,0xde,0x98,0x2e,0x59,0xdf,0xa2,0xc2,0x45,0xd3,0xb7,0xbf,0xe5,0x22,0x99,0xb4,0xf9,0x60,0x3b,0x5a,0x11,0xf3,0x78,0xad,0x67,0x3e,0x3a,0x28,0x03,0x26,0xbb,0x88,0xea,0xf5,0x26,0x44,0xae,0xfb,0x3b,0x97,0x84,0xd9,0x79,0x06,0x36,0x50,0x4e,0x69,0x26,0x0c,0x03,0x9f,0x5c,0x26,0xd2,0x18,0xd5,0xe7,0x7d,0x29,0x72,0x39,0xb9,0x0c,0xbe,0xc7,0x1d,0x24,0x48,0x80,0x30,0x63,0x8b,0x4d,0x9b,0xf1,0x32,0x08,0x93,0x28,0x02,0x0d,0xc9,0xdf,0xd3,0x45,0x19,0x27,0x46,0x68,0x29,0xe1,0x05},
+ {0x5a,0x49,0x9c,0x2d,0xb3,0xee,0x82,0xba,0x7c,0xb9,0x2b,0xf1,0xfc,0xc8,0xef,0xce,0xe0,0xd1,0xb5,0x93,0xae,0xab,0x2d,0xb0,0x9b,0x8d,0x69,0x13,0x9c,0x0c,0xc0,0x39,0x50,0x45,0x2c,0x24,0xc8,0xbb,0xbf,0xad,0xd9,0x81,0x30,0xd0,0xec,0x0c,0xc8,0xbc,0x92,0xdf,0xc8,0xf5,0xa6,0x66,0x35,0x84,0x4c,0xce,0x58,0x82,0xd3,0x25,0xcf,0x78,0x68,0x9d,0x48,0x31,0x8e,0x6b,0xae,0x15,0x87,0xf0,0x2b,0x9c,0xab,0x1c,0x85,0xaa,0x05,0xfa,0x4e,0xf0,0x97,0x5a,0xa7,0xc9,0x32,0xf8,0x3f,0x6b,0x07,0x52,0x6b,0x00},
+ {0x1c,0x78,0x95,0x9d,0xe1,0xcf,0xe0,0x29,0xe2,0x10,0x63,0x96,0x18,0xdf,0x81,0xb6,0x39,0x6b,0x51,0x70,0xd3,0x39,0xdf,0x57,0x22,0x61,0xc7,0x3b,0x44,0xe3,0x57,0x4d,0x2d,0x08,0xce,0xb9,0x16,0x7e,0xcb,0xf5,0x29,0xbc,0x7a,0x41,0x4c,0xf1,0x07,0x34,0xab,0xa7,0xf4,0x2b,0xce,0x6b,0xb3,0xd4,0xce,0x75,0x9f,0x1a,0x56,0xe9,0xe2,0x7d,0xcb,0x5e,0xa5,0xb6,0xf4,0xd4,0x70,0xde,0x99,0xdb,0x85,0x5d,0x7f,0x52,0x01,0x48,0x81,0x9a,0xee,0xd3,0x40,0xc4,0xc9,0xdb,0xed,0x29,0x60,0x1a,0xaf,0x90,0x2a,0x6b},
+ {0x97,0x1e,0xe6,0x9a,0xfc,0xf4,0x23,0x69,0xd1,0x5f,0x3f,0xe0,0x1d,0x28,0x35,0x57,0x2d,0xd1,0xed,0xe6,0x43,0xae,0x64,0xa7,0x4a,0x3e,0x2d,0xd1,0xe9,0xf4,0xd8,0x5f,0x0a,0xd8,0xb2,0x5b,0x24,0xf3,0xeb,0x77,0x9b,0x07,0xb9,0x2f,0x47,0x1b,0x30,0xd8,0x33,0x73,0xee,0x4c,0xf2,0xe6,0x47,0xc6,0x09,0x21,0x6c,0x27,0xc8,0x12,0x58,0x46,0xd9,0x62,0x10,0x2a,0xb2,0xbe,0x43,0x4d,0x16,0xdc,0x31,0x38,0x75,0xfb,0x65,0x70,0xd7,0x68,0x29,0xde,0x7b,0x4a,0x0d,0x18,0x90,0x67,0xb1,0x1c,0x2b,0x2c,0xb3,0x05},
+ {0xfd,0xa8,0x4d,0xd2,0xcc,0x5e,0xc0,0xc8,0x83,0xef,0xdf,0x05,0xac,0x1a,0xcf,0xa1,0x61,0xcd,0xf9,0x7d,0xf2,0xef,0xbe,0xdb,0x99,0x1e,0x47,0x7b,0xa3,0x56,0x55,0x3b,0x95,0x81,0xd5,0x7a,0x2c,0xa4,0xfc,0xf7,0xcc,0xf3,0x33,0x43,0x6e,0x28,0x14,0x32,0x9d,0x97,0x0b,0x34,0x0d,0x9d,0xc2,0xb6,0xe1,0x07,0x73,0x56,0x48,0x1a,0x77,0x31,0x82,0xd4,0x4d,0xe1,0x24,0xc5,0xb0,0x32,0xb6,0xa4,0x2b,0x1a,0x54,0x51,0xb3,0xed,0xf3,0x5a,0x2b,0x28,0x48,0x60,0xd1,0xa3,0xeb,0x36,0x73,0x7a,0xd2,0x79,0xc0,0x4f},
+ {0x7f,0x2f,0xbf,0x89,0xb0,0x38,0xc9,0x51,0xa7,0xe9,0xdf,0x02,0x65,0xbd,0x97,0x24,0x53,0xe4,0x80,0x78,0x9c,0xc0,0xff,0xff,0x92,0x8e,0xf9,0xca,0xce,0x67,0x45,0x12,0x0d,0xc5,0x86,0x0c,0x44,0x8b,0x34,0xdc,0x51,0xe6,0x94,0xcc,0xc9,0xcb,0x37,0x13,0xb9,0x3c,0x3e,0x64,0x4d,0xf7,0x22,0x64,0x08,0xcd,0xe3,0xba,0xc2,0x70,0x11,0x24,0xb4,0x73,0xc4,0x0a,0x86,0xab,0xf9,0x3f,0x35,0xe4,0x13,0x01,0xee,0x1d,0x91,0xf0,0xaf,0xc4,0xc6,0xeb,0x60,0x50,0xe7,0x4a,0x0d,0x00,0x87,0x6c,0x96,0x12,0x86,0x3f},
+ {0xde,0x0d,0x2a,0x78,0xc9,0x0c,0x9a,0x55,0x85,0x83,0x71,0xea,0xb2,0xcd,0x1d,0x55,0x8c,0x23,0xef,0x31,0x5b,0x86,0x62,0x7f,0x3d,0x61,0x73,0x79,0x76,0xa7,0x4a,0x50,0x13,0x8d,0x04,0x36,0xfa,0xfc,0x18,0x9c,0xdd,0x9d,0x89,0x73,0xb3,0x9d,0x15,0x29,0xaa,0xd0,0x92,0x9f,0x0b,0x35,0x9f,0xdc,0xd4,0x19,0x8a,0x87,0xee,0x7e,0xf5,0x26,0xb1,0xef,0x87,0x56,0xd5,0x2c,0xab,0x0c,0x7b,0xf1,0x7a,0x24,0x62,0xd1,0x80,0x51,0x67,0x24,0x5a,0x4f,0x34,0x5a,0xc1,0x85,0x69,0x30,0xba,0x9d,0x3d,0x94,0x41,0x40},
+ {0x96,0xcc,0xeb,0x43,0xba,0xee,0xc0,0xc3,0xaf,0x9c,0xea,0x26,0x9c,0x9c,0x74,0x8d,0xc6,0xcc,0x77,0x1c,0xee,0x95,0xfa,0xd9,0x0f,0x34,0x84,0x76,0xd9,0xa1,0x20,0x14,0xdd,0xaa,0x6c,0xa2,0x43,0x77,0x21,0x4b,0xce,0xb7,0x8a,0x64,0x24,0xb4,0xa6,0x47,0xe3,0xc9,0xfb,0x03,0x7a,0x4f,0x1d,0xcb,0x19,0xd0,0x00,0x98,0x42,0x31,0xd9,0x12,0x4f,0x59,0x37,0xd3,0x99,0x77,0xc6,0x00,0x7b,0xa4,0x3a,0xb2,0x40,0x51,0x3c,0x5e,0x95,0xf3,0x5f,0xe3,0x54,0x28,0x18,0x44,0x12,0xa0,0x59,0x43,0x31,0x92,0x4f,0x1b},
+ {0x51,0x09,0x15,0x89,0x9d,0x10,0x5c,0x3e,0x6a,0x69,0xe9,0x2d,0x91,0xfa,0xce,0x39,0x20,0x30,0x5f,0x97,0x3f,0xe4,0xea,0x20,0xae,0x2d,0x13,0x7f,0x2a,0x57,0x9b,0x23,0xb1,0x66,0x98,0xa4,0x30,0x30,0xcf,0x33,0x59,0x48,0x5f,0x21,0xd2,0x73,0x1f,0x25,0xf6,0xf4,0xde,0x51,0x40,0xaa,0x82,0xab,0xf6,0x23,0x9a,0x6f,0xd5,0x91,0xf1,0x5f,0x68,0x90,0x2d,0xac,0x33,0xd4,0x9e,0x81,0x23,0x85,0xc9,0x5f,0x79,0xab,0x83,0x28,0x3d,0xeb,0x93,0x55,0x80,0x72,0x45,0xef,0xcb,0x36,0x8f,0x75,0x6a,0x52,0x0c,0x02},
+ {0xbc,0xdb,0xd8,0x9e,0xf8,0x34,0x98,0x77,0x6c,0xa4,0x7c,0xdc,0xf9,0xaa,0xf2,0xc8,0x74,0xb0,0xe1,0xa3,0xdc,0x4c,0x52,0xa9,0x77,0x38,0x31,0x15,0x46,0xcc,0xaa,0x02,0x89,0xcc,0x42,0xf0,0x59,0xef,0x31,0xe9,0xb6,0x4b,0x12,0x8e,0x9d,0x9c,0x58,0x2c,0x97,0x59,0xc7,0xae,0x8a,0xe1,0xc8,0xad,0x0c,0xc5,0x02,0x56,0x0a,0xfe,0x2c,0x45,0xdf,0x77,0x78,0x64,0xa0,0xf7,0xa0,0x86,0x9f,0x7c,0x60,0x0e,0x27,0x64,0xc4,0xbb,0xc9,0x11,0xfb,0xf1,0x25,0xea,0x17,0xab,0x7b,0x87,0x4b,0x30,0x7b,0x7d,0xfb,0x4c},
+ {0xfe,0x75,0x9b,0xb8,0x6c,0x3d,0xb4,0x72,0x80,0xdc,0x6a,0x9c,0xd9,0x94,0xc6,0x54,0x9f,0x4c,0xe3,0x3e,0x37,0xaa,0xc3,0xb8,0x64,0x53,0x07,0x39,0x2b,0x62,0xb4,0x14,0x12,0xef,0x89,0x97,0xc2,0x99,0x86,0xe2,0x0d,0x19,0x57,0xdf,0x71,0xcd,0x6e,0x2b,0xd0,0x70,0xc9,0xec,0x57,0xc8,0x43,0xc3,0xc5,0x3a,0x4d,0x43,0xbc,0x4c,0x1d,0x5b,0x26,0x9f,0x0a,0xcc,0x15,0x26,0xfb,0xb6,0xe5,0xcc,0x8d,0xb8,0x2b,0x0e,0x4f,0x3a,0x05,0xa7,0x69,0x33,0x8b,0x49,0x01,0x13,0xd1,0x2d,0x59,0x58,0x12,0xf7,0x98,0x2f},
+ {0x56,0x9e,0x0f,0xb5,0x4c,0xa7,0x94,0x0c,0x20,0x13,0x8e,0x8e,0xa9,0xf4,0x1f,0x5b,0x67,0x0f,0x30,0x82,0x21,0xcc,0x2a,0x9a,0xf9,0xaa,0x06,0xd8,0x49,0xe2,0x6a,0x3a,0x01,0xa7,0x54,0x4f,0x44,0xae,0x12,0x2e,0xde,0xd7,0xcb,0xa9,0xf0,0x3e,0xfe,0xfc,0xe0,0x5d,0x83,0x75,0x0d,0x89,0xbf,0xce,0x54,0x45,0x61,0xe7,0xe9,0x62,0x80,0x1d,0x5a,0x7c,0x90,0xa9,0x85,0xda,0x7a,0x65,0x62,0x0f,0xb9,0x91,0xb5,0xa8,0x0e,0x1a,0xe9,0xb4,0x34,0xdf,0xfb,0x1d,0x0e,0x8d,0xf3,0x5f,0xf2,0xae,0xe8,0x8c,0x8b,0x29},
+ {0xb2,0x0c,0xf7,0xef,0x53,0x79,0x92,0x2a,0x76,0x70,0x15,0x79,0x2a,0xc9,0x89,0x4b,0x6a,0xcf,0xa7,0x30,0x7a,0x45,0x18,0x94,0x85,0xe4,0x5c,0x4d,0x40,0xa8,0xb8,0x34,0xde,0x65,0x21,0x0a,0xea,0x72,0x7a,0x83,0xf6,0x79,0xcf,0x0b,0xb4,0x07,0xab,0x3f,0x70,0xae,0x38,0x77,0xc7,0x36,0x16,0x52,0xdc,0xd7,0xa7,0x03,0x18,0x27,0xa6,0x6b,0x35,0x33,0x69,0x83,0xb5,0xec,0x6e,0xc2,0xfd,0xfe,0xb5,0x63,0xdf,0x13,0xa8,0xd5,0x73,0x25,0xb2,0xa4,0x9a,0xaa,0x93,0xa2,0x6a,0x1c,0x5e,0x46,0xdd,0x2b,0xd6,0x71},
+ {0x80,0xdf,0x78,0xd3,0x28,0xcc,0x33,0x65,0xb4,0xa4,0x0f,0x0a,0x79,0x43,0xdb,0xf6,0x5a,0xda,0x01,0xf7,0xf9,0x5f,0x64,0xe3,0xa4,0x2b,0x17,0xf3,0x17,0xf3,0xd5,0x74,0xf5,0x5e,0xf7,0xb1,0xda,0xb5,0x2d,0xcd,0xf5,0x65,0xb0,0x16,0xcf,0x95,0x7f,0xd7,0x85,0xf0,0x49,0x3f,0xea,0x1f,0x57,0x14,0x3d,0x2b,0x2b,0x26,0x21,0x36,0x33,0x1c,0x81,0xca,0xd9,0x67,0x54,0xe5,0x6f,0xa8,0x37,0x8c,0x29,0x2b,0x75,0x7c,0x8b,0x39,0x3b,0x62,0xac,0xe3,0x92,0x08,0x6d,0xda,0x8c,0xd9,0xe9,0x47,0x45,0xcc,0xeb,0x4a},
+ {0xc9,0x01,0x6d,0x27,0x1b,0x07,0xf0,0x12,0x70,0x8c,0xc4,0x86,0xc5,0xba,0xb8,0xe7,0xa9,0xfb,0xd6,0x71,0x9b,0x12,0x08,0x53,0x92,0xb7,0x3d,0x5a,0xf9,0xfb,0x88,0x5d,0x10,0xb6,0x54,0x73,0x9e,0x8d,0x40,0x0b,0x6e,0x5b,0xa8,0x5b,0x53,0x32,0x6b,0x80,0x07,0xa2,0x58,0x4a,0x03,0x3a,0xe6,0xdb,0x2c,0xdf,0xa1,0xc9,0xdd,0xd9,0x3b,0x17,0xdf,0x72,0x58,0xfe,0x1e,0x0f,0x50,0x2b,0xc1,0x18,0x39,0xd4,0x2e,0x58,0xd6,0x58,0xe0,0x3a,0x67,0xc9,0x8e,0x27,0xed,0xe6,0x19,0xa3,0x9e,0xb1,0x13,0xcd,0xe1,0x06},
+ {0x23,0x6f,0x16,0x6f,0x51,0xad,0xd0,0x40,0xbe,0x6a,0xab,0x1f,0x93,0x32,0x8e,0x11,0x8e,0x08,0x4d,0xa0,0x14,0x5e,0xe3,0x3f,0x66,0x62,0xe1,0x26,0x35,0x60,0x80,0x30,0x53,0x03,0x5b,0x9e,0x62,0xaf,0x2b,0x47,0x47,0x04,0x8d,0x27,0x90,0x0b,0xaa,0x3b,0x27,0xbf,0x43,0x96,0x46,0x5f,0x78,0x0c,0x13,0x7b,0x83,0x8d,0x1a,0x6a,0x3a,0x7f,0x0b,0x80,0x3d,0x5d,0x39,0x44,0xe6,0xf7,0xf6,0xed,0x01,0xc9,0x55,0xd5,0xa8,0x95,0x39,0x63,0x2c,0x59,0x30,0x78,0xcd,0x68,0x7e,0x30,0x51,0x2e,0xed,0xfd,0xd0,0x30},
+ {0xb3,0x33,0x12,0xf2,0x1a,0x4d,0x59,0xe0,0x9c,0x4d,0xcc,0xf0,0x8e,0xe7,0xdb,0x1b,0x77,0x9a,0x49,0x8f,0x7f,0x18,0x65,0x69,0x68,0x98,0x09,0x2c,0x20,0x14,0x92,0x0a,0x50,0x47,0xb8,0x68,0x1e,0x97,0xb4,0x9c,0xcf,0xbb,0x64,0x66,0x29,0x72,0x95,0xa0,0x2b,0x41,0xfa,0x72,0x26,0xe7,0x8d,0x5c,0xd9,0x89,0xc5,0x51,0x43,0x08,0x15,0x46,0x2e,0xa0,0xb9,0xae,0xc0,0x19,0x90,0xbc,0xae,0x4c,0x03,0x16,0x0d,0x11,0xc7,0x55,0xec,0x32,0x99,0x65,0x01,0xf5,0x6d,0x0e,0xfe,0x5d,0xca,0x95,0x28,0x0d,0xca,0x3b},
+ {0xa4,0x62,0x5d,0x3c,0xbc,0x31,0xf0,0x40,0x60,0x7a,0xf0,0xcf,0x3e,0x8b,0xfc,0x19,0x45,0xb5,0x0f,0x13,0xa2,0x3d,0x18,0x98,0xcd,0x13,0x8f,0xae,0xdd,0xde,0x31,0x56,0xbf,0x01,0xcc,0x9e,0xb6,0x8e,0x68,0x9c,0x6f,0x89,0x44,0xa6,0xad,0x83,0xbc,0xf0,0xe2,0x9f,0x7a,0x5f,0x5f,0x95,0x2d,0xca,0x41,0x82,0xf2,0x8d,0x03,0xb4,0xa8,0x4e,0x02,0xd2,0xca,0xf1,0x0a,0x46,0xed,0x2a,0x83,0xee,0x8c,0xa4,0x05,0x53,0x30,0x46,0x5f,0x1a,0xf1,0x49,0x45,0x77,0x21,0x91,0x63,0xa4,0x2c,0x54,0x30,0x09,0xce,0x24},
+ {0x06,0xc1,0x06,0xfd,0xf5,0x90,0xe8,0x1f,0xf2,0x10,0x88,0x5d,0x35,0x68,0xc4,0xb5,0x3e,0xaf,0x8c,0x6e,0xfe,0x08,0x78,0x82,0x4b,0xd7,0x06,0x8a,0xc2,0xe3,0xd4,0x41,0x85,0x0b,0xf3,0xfd,0x55,0xa1,0xcf,0x3f,0xa4,0x2e,0x37,0x36,0x8e,0x16,0xf7,0xd2,0x44,0xf8,0x92,0x64,0xde,0x64,0xe0,0xb2,0x80,0x42,0x4f,0x32,0xa7,0x28,0x99,0x54,0x2e,0x1a,0xee,0x63,0xa7,0x32,0x6e,0xf2,0xea,0xfd,0x5f,0xd2,0xb7,0xe4,0x91,0xae,0x69,0x4d,0x7f,0xd1,0x3b,0xd3,0x3b,0xbc,0x6a,0xff,0xdc,0xc0,0xde,0x66,0x1b,0x49},
+ {0xa7,0x32,0xea,0xc7,0x3d,0xb1,0xf5,0x98,0x98,0xdb,0x16,0x7e,0xcc,0xf8,0xd5,0xe3,0x47,0xd9,0xf8,0xcb,0x52,0xbf,0x0a,0xac,0xac,0xe4,0x5e,0xc8,0xd0,0x38,0xf3,0x08,0xa1,0x64,0xda,0xd0,0x8e,0x4a,0xf0,0x75,0x4b,0x28,0xe2,0x67,0xaf,0x2c,0x22,0xed,0xa4,0x7b,0x7b,0x1f,0x79,0xa3,0x34,0x82,0x67,0x8b,0x01,0xb7,0xb0,0xb8,0xf6,0x4c,0xbd,0x73,0x1a,0x99,0x21,0xa8,0x83,0xc3,0x7a,0x0c,0x32,0xdf,0x01,0xbc,0x27,0xab,0x63,0x70,0x77,0x84,0x1b,0x33,0x3d,0xc1,0x99,0x8a,0x07,0xeb,0x82,0x4a,0x0d,0x53},
+ {0x25,0x48,0xf9,0xe1,0x30,0x36,0x4c,0x00,0x5a,0x53,0xab,0x8c,0x26,0x78,0x2d,0x7e,0x8b,0xff,0x84,0xcc,0x23,0x23,0x48,0xc7,0xb9,0x70,0x17,0x10,0x3f,0x75,0xea,0x65,0x9e,0xbf,0x9a,0x6c,0x45,0x73,0x69,0x6d,0x80,0xa8,0x00,0x49,0xfc,0xb2,0x7f,0x25,0x50,0xb8,0xcf,0xc8,0x12,0xf4,0xac,0x2b,0x5b,0xbd,0xbf,0x0c,0xe0,0xe7,0xb3,0x0d,0x63,0x63,0x09,0xe2,0x3e,0xfc,0x66,0x3d,0x6b,0xcb,0xb5,0x61,0x7f,0x2c,0xd6,0x81,0x1a,0x3b,0x44,0x13,0x42,0x04,0xbe,0x0f,0xdb,0xa1,0xe1,0x21,0x19,0xec,0xa4,0x02},
+ {0xa2,0xb8,0x24,0x3b,0x9a,0x25,0xe6,0x5c,0xb8,0xa0,0xaf,0x45,0xcc,0x7a,0x57,0xb8,0x37,0x70,0xa0,0x8b,0xe8,0xe6,0xcb,0xcc,0xbf,0x09,0x78,0x12,0x51,0x3c,0x14,0x3d,0x5f,0x79,0xcf,0xf1,0x62,0x61,0xc8,0xf5,0xf2,0x57,0xee,0x26,0x19,0x86,0x8c,0x11,0x78,0x35,0x06,0x1c,0x85,0x24,0x21,0x17,0xcf,0x7f,0x06,0xec,0x5d,0x2b,0xd1,0x36,0x57,0x45,0x15,0x79,0x91,0x27,0x6d,0x12,0x0a,0x3a,0x78,0xfc,0x5c,0x8f,0xe4,0xd5,0xac,0x9b,0x17,0xdf,0xe8,0xb6,0xbd,0x36,0x59,0x28,0xa8,0x5b,0x88,0x17,0xf5,0x2e},
+ {0xdc,0xae,0x58,0x8c,0x4e,0x97,0x37,0x46,0xa4,0x41,0xf0,0xab,0xfb,0x22,0xef,0xb9,0x8a,0x71,0x80,0xe9,0x56,0xd9,0x85,0xe1,0xa6,0xa8,0x43,0xb1,0xfa,0x78,0x1b,0x2f,0x51,0x2f,0x5b,0x30,0xfb,0xbf,0xee,0x96,0xb8,0x96,0x95,0x88,0xad,0x38,0xf9,0xd3,0x25,0xdd,0xd5,0x46,0xc7,0x2d,0xf5,0xf0,0x95,0x00,0x3a,0xbb,0x90,0x82,0x96,0x57,0x01,0xe1,0x20,0x0a,0x43,0xb8,0x1a,0xf7,0x47,0xec,0xf0,0x24,0x8d,0x65,0x93,0xf3,0xd1,0xee,0xe2,0x6e,0xa8,0x09,0x75,0xcf,0xe1,0xa3,0x2a,0xdc,0x35,0x3e,0xc4,0x7d},
+ {0xc3,0xd9,0x7d,0x88,0x65,0x66,0x96,0x85,0x55,0x53,0xb0,0x4b,0x31,0x9b,0x0f,0xc9,0xb1,0x79,0x20,0xef,0xf8,0x8d,0xe0,0xc6,0x2f,0xc1,0x8c,0x75,0x16,0x20,0xf7,0x7e,0x18,0x97,0x3e,0x27,0x5c,0x2a,0x78,0x5a,0x94,0xfd,0x4e,0x5e,0x99,0xc6,0x76,0x35,0x3e,0x7d,0x23,0x1f,0x05,0xd8,0x2e,0x0f,0x99,0x0a,0xd5,0x82,0x1d,0xb8,0x4f,0x04,0xd9,0xe3,0x07,0xa9,0xc5,0x18,0xdf,0xc1,0x59,0x63,0x4c,0xce,0x1d,0x37,0xb3,0x57,0x49,0xbb,0x01,0xb2,0x34,0x45,0x70,0xca,0x2e,0xdd,0x30,0x9c,0x3f,0x82,0x79,0x7f},
+ {0xe8,0x13,0xb5,0xa3,0x39,0xd2,0x34,0x83,0xd8,0xa8,0x1f,0xb9,0xd4,0x70,0x36,0xc1,0x33,0xbd,0x90,0xf5,0x36,0x41,0xb5,0x12,0xb4,0xd9,0x84,0xd7,0x73,0x03,0x4e,0x0a,0xba,0x87,0xf5,0x68,0xf0,0x1f,0x9c,0x6a,0xde,0xc8,0x50,0x00,0x4e,0x89,0x27,0x08,0xe7,0x5b,0xed,0x7d,0x55,0x99,0xbf,0x3c,0xf0,0xd6,0x06,0x1c,0x43,0xb0,0xa9,0x64,0x19,0x29,0x7d,0x5b,0xa1,0xd6,0xb3,0x2e,0x35,0x82,0x3a,0xd5,0xa0,0xf6,0xb4,0xb0,0x47,0x5d,0xa4,0x89,0x43,0xce,0x56,0x71,0x6c,0x34,0x18,0xce,0x0a,0x7d,0x1a,0x07},
+ {0x0b,0xba,0x87,0xc8,0xaa,0x2d,0x07,0xd3,0xee,0x62,0xa5,0xbf,0x05,0x29,0x26,0x01,0x8b,0x76,0xef,0xc0,0x02,0x30,0x54,0xcf,0x9c,0x7e,0xea,0x46,0x71,0xcc,0x3b,0x2c,0x31,0x44,0xe1,0x20,0x52,0x35,0x0c,0xcc,0x41,0x51,0xb1,0x09,0x07,0x95,0x65,0x0d,0x36,0x5f,0x9d,0x20,0x1b,0x62,0xf5,0x9a,0xd3,0x55,0x77,0x61,0xf7,0xbc,0x69,0x7c,0x5f,0x29,0xe8,0x04,0xeb,0xd7,0xf0,0x07,0x7d,0xf3,0x50,0x2f,0x25,0x18,0xdb,0x10,0xd7,0x98,0x17,0x17,0xa3,0xa9,0x51,0xe9,0x1d,0xa5,0xac,0x22,0x73,0x9a,0x5a,0x6f},
+ {0xc5,0xc6,0x41,0x2f,0x0c,0x00,0xa1,0x8b,0x9b,0xfb,0xfe,0x0c,0xc1,0x79,0x9f,0xc4,0x9f,0x1c,0xc5,0x3c,0x70,0x47,0xfa,0x4e,0xca,0xaf,0x47,0xe1,0xa2,0x21,0x4e,0x49,0xbe,0x44,0xd9,0xa3,0xeb,0xd4,0x29,0xe7,0x9e,0xaf,0x78,0x80,0x40,0x09,0x9e,0x8d,0x03,0x9c,0x86,0x47,0x7a,0x56,0x25,0x45,0x24,0x3b,0x8d,0xee,0x80,0x96,0xab,0x02,0x9a,0x0d,0xe5,0xdd,0x85,0x8a,0xa4,0xef,0x49,0xa2,0xb9,0x0f,0x4e,0x22,0x9a,0x21,0xd9,0xf6,0x1e,0xd9,0x1d,0x1f,0x09,0xfa,0x34,0xbb,0x46,0xea,0xcb,0x76,0x5d,0x6b},
+ {0x94,0xd9,0x0c,0xec,0x6c,0x55,0x57,0x88,0xba,0x1d,0xd0,0x5c,0x6f,0xdc,0x72,0x64,0x77,0xb4,0x42,0x8f,0x14,0x69,0x01,0xaf,0x54,0x73,0x27,0x85,0xf6,0x33,0xe3,0x0a,0x22,0x25,0x78,0x1e,0x17,0x41,0xf9,0xe0,0xd3,0x36,0x69,0x03,0x74,0xae,0xe6,0xf1,0x46,0xc7,0xfc,0xd0,0xa2,0x3e,0x8b,0x40,0x3e,0x31,0xdd,0x03,0x9c,0x86,0xfb,0x16,0x62,0x09,0xb6,0x33,0x97,0x19,0x8e,0x28,0x33,0xe1,0xab,0xd8,0xb4,0x72,0xfc,0x24,0x3e,0xd0,0x91,0x09,0xed,0xf7,0x11,0x48,0x75,0xd0,0x70,0x8f,0x8b,0xe3,0x81,0x3f},
+ {0xfe,0xaf,0xd9,0x7e,0xcc,0x0f,0x91,0x7f,0x4b,0x87,0x65,0x24,0xa1,0xb8,0x5c,0x54,0x04,0x47,0x0c,0x4b,0xd2,0x7e,0x39,0xa8,0x93,0x09,0xf5,0x04,0xc1,0x0f,0x51,0x50,0x24,0xc8,0x17,0x5f,0x35,0x7f,0xdb,0x0a,0xa4,0x99,0x42,0xd7,0xc3,0x23,0xb9,0x74,0xf7,0xea,0xf8,0xcb,0x8b,0x3e,0x7c,0xd5,0x3d,0xdc,0xde,0x4c,0xd3,0xe2,0xd3,0x0a,0x9d,0x24,0x6e,0x33,0xc5,0x0f,0x0c,0x6f,0xd9,0xcf,0x31,0xc3,0x19,0xde,0x5e,0x74,0x1c,0xfe,0xee,0x09,0x00,0xfd,0xd6,0xf2,0xbe,0x1e,0xfa,0xf0,0x8b,0x15,0x7c,0x12},
+ {0xa2,0x79,0x98,0x2e,0x42,0x7c,0x19,0xf6,0x47,0x36,0xca,0x52,0xd4,0xdd,0x4a,0xa4,0xcb,0xac,0x4e,0x4b,0xc1,0x3f,0x41,0x9b,0x68,0x4f,0xef,0x07,0x7d,0xf8,0x4e,0x35,0x74,0xb9,0x51,0xae,0xc4,0x8f,0xa2,0xde,0x96,0xfe,0x4d,0x74,0xd3,0x73,0x99,0x1d,0xa8,0x48,0x38,0x87,0x0b,0x68,0x40,0x62,0x95,0xdf,0x67,0xd1,0x79,0x24,0xd8,0x4e,0x75,0xd9,0xc5,0x60,0x22,0xb5,0xe3,0xfe,0xb8,0xb0,0x41,0xeb,0xfc,0x2e,0x35,0x50,0x3c,0x65,0xf6,0xa9,0x30,0xac,0x08,0x88,0x6d,0x23,0x39,0x05,0xd2,0x92,0x2d,0x30},
+ {0x3d,0x28,0xa4,0xbc,0xa2,0xc1,0x13,0x78,0xd9,0x3d,0x86,0xa1,0x91,0xf0,0x62,0xed,0x86,0xfa,0x68,0xc2,0xb8,0xbc,0xc7,0xae,0x4c,0xae,0x1c,0x6f,0xb7,0xd3,0xe5,0x10,0x77,0xf1,0xe0,0xe4,0xb6,0x6f,0xbc,0x2d,0x93,0x6a,0xbd,0xa4,0x29,0xbf,0xe1,0x04,0xe8,0xf6,0x7a,0x78,0xd4,0x66,0x19,0x5e,0x60,0xd0,0x26,0xb4,0x5e,0x5f,0xdc,0x0e,0x67,0x8e,0xda,0x53,0xd6,0xbf,0x53,0x54,0x41,0xf6,0xa9,0x24,0xec,0x1e,0xdc,0xe9,0x23,0x8a,0x57,0x03,0x3b,0x26,0x87,0xbf,0x72,0xba,0x1c,0x36,0x51,0x6c,0xb4,0x45},
+ {0xa1,0x7f,0x4f,0x31,0xbf,0x2a,0x40,0xa9,0x50,0xf4,0x8c,0x8e,0xdc,0xf1,0x57,0xe2,0x84,0xbe,0xa8,0x23,0x4b,0xd5,0xbb,0x1d,0x3b,0x71,0xcb,0x6d,0xa3,0xbf,0x77,0x21,0xe4,0xe3,0x7f,0x8a,0xdd,0x4d,0x9d,0xce,0x30,0x0e,0x62,0x76,0x56,0x64,0x13,0xab,0x58,0x99,0x0e,0xb3,0x7b,0x4f,0x59,0x4b,0xdf,0x29,0x12,0x32,0xef,0x0a,0x1c,0x5c,0x8f,0xdb,0x79,0xfa,0xbc,0x1b,0x08,0x37,0xb3,0x59,0x5f,0xc2,0x1e,0x81,0x48,0x60,0x87,0x24,0x83,0x9c,0x65,0x76,0x7a,0x08,0xbb,0xb5,0x8a,0x7d,0x38,0x19,0xe6,0x4a},
+ {0x2e,0xa3,0x44,0x53,0xaa,0xf6,0xdb,0x8d,0x78,0x40,0x1b,0xb4,0xb4,0xea,0x88,0x7d,0x60,0x0d,0x13,0x4a,0x97,0xeb,0xb0,0x5e,0x03,0x3e,0xbf,0x17,0x1b,0xd9,0x00,0x1a,0x83,0xfb,0x5b,0x98,0x44,0x7e,0x11,0x61,0x36,0x31,0x96,0x71,0x2a,0x46,0xe0,0xfc,0x4b,0x90,0x25,0xd4,0x48,0x34,0xac,0x83,0x64,0x3d,0xa4,0x5b,0xbe,0x5a,0x68,0x75,0xb2,0xf2,0x61,0xeb,0x33,0x09,0x96,0x6e,0x52,0x49,0xff,0xc9,0xa8,0x0f,0x3d,0x54,0x69,0x65,0xf6,0x7a,0x10,0x75,0x72,0xdf,0xaa,0xe6,0xb0,0x23,0xb6,0x29,0x55,0x13},
+ {0x18,0xd5,0xd1,0xad,0xd7,0xdb,0xf0,0x18,0x11,0x1f,0xc1,0xcf,0x88,0x78,0x9f,0x97,0x9b,0x75,0x14,0x71,0xf0,0xe1,0x32,0x87,0x01,0x3a,0xca,0x65,0x1a,0xb8,0xb5,0x79,0xfe,0x83,0x2e,0xe2,0xbc,0x16,0xc7,0xf5,0xc1,0x85,0x09,0xe8,0x19,0xeb,0x2b,0xb4,0xae,0x4a,0x25,0x14,0x37,0xa6,0x9d,0xec,0x13,0xa6,0x90,0x15,0x05,0xea,0x72,0x59,0x11,0x78,0x8f,0xdc,0x20,0xac,0xd4,0x0f,0xa8,0x4f,0x4d,0xac,0x94,0xd2,0x9a,0x9a,0x34,0x04,0x36,0xb3,0x64,0x2d,0x1b,0xc0,0xdb,0x3b,0x5f,0x90,0x95,0x9c,0x7e,0x4f},
+ {0x2e,0x30,0x81,0x57,0xbc,0x4b,0x67,0x62,0x0f,0xdc,0xad,0x89,0x39,0x0f,0x52,0xd8,0xc6,0xd9,0xfb,0x53,0xae,0x99,0x29,0x8c,0x4c,0x8e,0x63,0x2e,0xd9,0x3a,0x99,0x31,0xfe,0x99,0x52,0x35,0x3d,0x44,0xc8,0x71,0xd7,0xea,0xeb,0xdb,0x1c,0x3b,0xcd,0x8b,0x66,0x94,0xa4,0xf1,0x9e,0x49,0x92,0x80,0xc8,0xad,0x44,0xa1,0xc4,0xee,0x42,0x19,0x92,0x49,0x23,0xae,0x19,0x53,0xac,0x7d,0x92,0x3e,0xea,0x0c,0x91,0x3d,0x1b,0x2c,0x22,0x11,0x3c,0x25,0x94,0xe4,0x3c,0x55,0x75,0xca,0xf9,0x4e,0x31,0x65,0x0a,0x2a},
+ {0xc2,0x27,0xf9,0xf7,0x7f,0x93,0xb7,0x2d,0x35,0xa6,0xd0,0x17,0x06,0x1f,0x74,0xdb,0x76,0xaf,0x55,0x11,0xa2,0xf3,0x82,0x59,0xed,0x2d,0x7c,0x64,0x18,0xe2,0xf6,0x4c,0x3a,0x79,0x1c,0x3c,0xcd,0x1a,0x36,0xcf,0x3b,0xbc,0x35,0x5a,0xac,0xbc,0x9e,0x2f,0xab,0xa6,0xcd,0xa8,0xe9,0x60,0xe8,0x60,0x13,0x1a,0xea,0x6d,0x9b,0xc3,0x5d,0x05,0xb6,0x5b,0x8d,0xc2,0x7c,0x22,0x19,0xb1,0xab,0xff,0x4d,0x77,0xbc,0x4e,0xe2,0x07,0x89,0x2c,0xa3,0xe4,0xce,0x78,0x3c,0xa8,0xb6,0x24,0xaa,0x10,0x77,0x30,0x1a,0x12},
+ {0x97,0x4a,0x03,0x9f,0x5e,0x5d,0xdb,0xe4,0x2d,0xbc,0x34,0x30,0x09,0xfc,0x53,0xe1,0xb1,0xd3,0x51,0x95,0x91,0x46,0x05,0x46,0x2d,0xe5,0x40,0x7a,0x6c,0xc7,0x3f,0x33,0xc9,0x83,0x74,0xc7,0x3e,0x71,0x59,0xd6,0xaf,0x96,0x2b,0xb8,0x77,0xe0,0xbf,0x88,0xd3,0xbc,0x97,0x10,0x23,0x28,0x9e,0x28,0x9b,0x3a,0xed,0x6c,0x4a,0xb9,0x7b,0x52,0x2e,0x48,0x5b,0x99,0x2a,0x99,0x3d,0x56,0x01,0x38,0x38,0x6e,0x7c,0xd0,0x05,0x34,0xe5,0xd8,0x64,0x2f,0xde,0x35,0x50,0x48,0xf7,0xa9,0xa7,0x20,0x9b,0x06,0x89,0x6b},
+ {0x0d,0x22,0x70,0x62,0x41,0xa0,0x2a,0x81,0x4e,0x5b,0x24,0xf9,0xfa,0x89,0x5a,0x99,0x05,0xef,0x72,0x50,0xce,0xc4,0xad,0xff,0x73,0xeb,0x73,0xaa,0x03,0x21,0xbc,0x23,0x77,0xdb,0xc7,0xb5,0x8c,0xfa,0x82,0x40,0x55,0xc1,0x34,0xc7,0xf8,0x86,0x86,0x06,0x7e,0xa5,0xe7,0xf6,0xd9,0xc8,0xe6,0x29,0xcf,0x9b,0x63,0xa7,0x08,0xd3,0x73,0x04,0x05,0x9e,0x58,0x03,0x26,0x79,0xee,0xca,0x92,0xc4,0xdc,0x46,0x12,0x42,0x4b,0x2b,0x4f,0xa9,0x01,0xe6,0x74,0xef,0xa1,0x02,0x1a,0x34,0x04,0xde,0xbf,0x73,0x2f,0x10},
+ {0xc6,0x45,0x57,0x7f,0xab,0xb9,0x18,0xeb,0x90,0xc6,0x87,0x57,0xee,0x8a,0x3a,0x02,0xa9,0xaf,0xf7,0x2d,0xda,0x12,0x27,0xb7,0x3d,0x01,0x5c,0xea,0x25,0x7d,0x59,0x36,0x9a,0x1c,0x51,0xb5,0xe0,0xda,0xb4,0xa2,0x06,0xff,0xff,0x2b,0x29,0x60,0xc8,0x7a,0x34,0x42,0x50,0xf5,0x5d,0x37,0x1f,0x98,0x2d,0xa1,0x4e,0xda,0x25,0xd7,0x6b,0x3f,0xac,0x58,0x60,0x10,0x7b,0x8d,0x4d,0x73,0x5f,0x90,0xc6,0x6f,0x9e,0x57,0x40,0xd9,0x2d,0x93,0x02,0x92,0xf9,0xf8,0x66,0x64,0xd0,0xd6,0x60,0xda,0x19,0xcc,0x7e,0x7b},
+ {0x0d,0x69,0x5c,0x69,0x3c,0x37,0xc2,0x78,0x6e,0x90,0x42,0x06,0x66,0x2e,0x25,0xdd,0xd2,0x2b,0xe1,0x4a,0x44,0x44,0x1d,0x95,0x56,0x39,0x74,0x01,0x76,0xad,0x35,0x42,0x9b,0xfa,0x7c,0xa7,0x51,0x4a,0xae,0x6d,0x50,0x86,0xa3,0xe7,0x54,0x36,0x26,0x82,0xdb,0x82,0x2d,0x8f,0xcd,0xff,0xbb,0x09,0xba,0xca,0xf5,0x1b,0x66,0xdc,0xbe,0x03,0xf5,0x75,0x89,0x07,0x0d,0xcb,0x58,0x62,0x98,0xf2,0x89,0x91,0x54,0x42,0x29,0x49,0xe4,0x6e,0xe3,0xe2,0x23,0xb4,0xca,0xa0,0xa1,0x66,0xf0,0xcd,0xb0,0xe2,0x7c,0x0e},
+ {0xa3,0x85,0x8c,0xc4,0x3a,0x64,0x94,0xc4,0xad,0x39,0x61,0x3c,0xf4,0x1d,0x36,0xfd,0x48,0x4d,0xe9,0x3a,0xdd,0x17,0xdb,0x09,0x4a,0x67,0xb4,0x8f,0x5d,0x0a,0x6e,0x66,0xf9,0x70,0x4b,0xd9,0xdf,0xfe,0xa6,0xfe,0x2d,0xba,0xfc,0xc1,0x51,0xc0,0x30,0xf1,0x89,0xab,0x2f,0x7f,0x7e,0xd4,0x82,0x48,0xb5,0xee,0xec,0x8a,0x13,0x56,0x52,0x61,0x0d,0xcb,0x70,0x48,0x4e,0xf6,0xbb,0x2a,0x6b,0x8b,0x45,0xaa,0xf0,0xbc,0x65,0xcd,0x5d,0x98,0xe8,0x75,0xba,0x4e,0xbe,0x9a,0xe4,0xde,0x14,0xd5,0x10,0xc8,0x0b,0x7f},
+ {0x6f,0x13,0xf4,0x26,0xa4,0x6b,0x00,0xb9,0x35,0x30,0xe0,0x57,0x9e,0x36,0x67,0x8d,0x28,0x3c,0x46,0x4f,0xd9,0xdf,0xc8,0xcb,0xf5,0xdb,0xee,0xf8,0xbc,0x8d,0x1f,0x0d,0xa0,0x13,0x72,0x73,0xad,0x9d,0xac,0x83,0x98,0x2e,0xf7,0x2e,0xba,0xf8,0xf6,0x9f,0x57,0x69,0xec,0x43,0xdd,0x2e,0x1e,0x31,0x75,0xab,0xc5,0xde,0x7d,0x90,0x3a,0x1d,0xdc,0x81,0xd0,0x3e,0x31,0x93,0x16,0xba,0x80,0x34,0x1b,0x85,0xad,0x9f,0x32,0x29,0xcb,0x21,0x03,0x03,0x3c,0x01,0x28,0x01,0xe3,0xfd,0x1b,0xa3,0x44,0x1b,0x01,0x00},
+ {0x0c,0x6c,0xc6,0x3f,0x6c,0xa0,0xdf,0x3f,0xd2,0x0d,0xd6,0x4d,0x8e,0xe3,0x40,0x5d,0x71,0x4d,0x8e,0x26,0x38,0x8b,0xe3,0x7a,0xe1,0x57,0x83,0x6e,0x91,0x8d,0xc4,0x3a,0x5c,0xa7,0x0a,0x6a,0x69,0x1f,0x56,0x16,0x6a,0xbd,0x52,0x58,0x5c,0x72,0xbf,0xc1,0xad,0x66,0x79,0x9a,0x7f,0xdd,0xa8,0x11,0x26,0x10,0x85,0xd2,0xa2,0x88,0xd9,0x63,0x2e,0x23,0xbd,0xaf,0x53,0x07,0x12,0x00,0x83,0xf6,0xd8,0xfd,0xb8,0xce,0x2b,0xe9,0x91,0x2b,0xe7,0x84,0xb3,0x69,0x16,0xf8,0x66,0xa0,0x68,0x23,0x2b,0xd5,0xfa,0x33},
+ {0x16,0x1e,0xe4,0xc5,0xc6,0x49,0x06,0x54,0x35,0x77,0x3f,0x33,0x30,0x64,0xf8,0x0a,0x46,0xe7,0x05,0xf3,0xd2,0xfc,0xac,0xb2,0xa7,0xdc,0x56,0xa2,0x29,0xf4,0xc0,0x16,0xe8,0xcf,0x22,0xc4,0xd0,0xc8,0x2c,0x8d,0xcb,0x3a,0xa1,0x05,0x7b,0x4f,0x2b,0x07,0x6f,0xa5,0xf6,0xec,0xe6,0xb6,0xfe,0xa3,0xe2,0x71,0x0a,0xb9,0xcc,0x55,0xc3,0x3c,0x31,0x91,0x3e,0x90,0x43,0x94,0xb6,0xe9,0xce,0x37,0x56,0x7a,0xcb,0x94,0xa4,0xb8,0x44,0x92,0xba,0xba,0xa4,0xd1,0x7c,0xc8,0x68,0x75,0xae,0x6b,0x42,0xaf,0x1e,0x63},
+ {0x9f,0xfe,0x66,0xda,0x10,0x04,0xe9,0xb3,0xa6,0xe5,0x16,0x6c,0x52,0x4b,0xdd,0x85,0x83,0xbf,0xf9,0x1e,0x61,0x97,0x3d,0xbc,0xb5,0x19,0xa9,0x1e,0x8b,0x64,0x99,0x55,0xe8,0x0d,0x70,0xa3,0xb9,0x75,0xd9,0x47,0x52,0x05,0xf8,0xe2,0xfb,0xc5,0x80,0x72,0xe1,0x5d,0xe4,0x32,0x27,0x8f,0x65,0x53,0xb5,0x80,0x5f,0x66,0x7f,0x2c,0x1f,0x43,0x19,0x7b,0x8f,0x85,0x44,0x63,0x02,0xd6,0x4a,0x51,0xea,0xa1,0x2f,0x35,0xab,0x14,0xd7,0xa9,0x90,0x20,0x1a,0x44,0x00,0x89,0x26,0x3b,0x25,0x91,0x5f,0x71,0x04,0x7b},
+ {0x43,0xae,0xf6,0xac,0x28,0xbd,0xed,0x83,0xb4,0x7a,0x5c,0x7d,0x8b,0x7c,0x35,0x86,0x44,0x2c,0xeb,0xb7,0x69,0x47,0x40,0xc0,0x3f,0x58,0xf6,0xc2,0xf5,0x7b,0xb3,0x59,0xc6,0xba,0xe6,0xc4,0x80,0xc2,0x76,0xb3,0x0b,0x9b,0x1d,0x6d,0xdd,0xd3,0x0e,0x97,0x44,0xf9,0x0b,0x45,0x58,0x95,0x9a,0xb0,0x23,0xe2,0xcd,0x57,0xfa,0xac,0xd0,0x48,0x71,0xe6,0xab,0x7d,0xe4,0x26,0x0f,0xb6,0x37,0x3a,0x2f,0x62,0x97,0xa1,0xd1,0xf1,0x94,0x03,0x96,0xe9,0x7e,0xce,0x08,0x42,0xdb,0x3b,0x6d,0x33,0x91,0x41,0x23,0x16},
+ {0xf6,0x7f,0x26,0xf6,0xde,0x99,0xe4,0xb9,0x43,0x08,0x2c,0x74,0x7b,0xca,0x72,0x77,0xb1,0xf2,0xa4,0xe9,0x3f,0x15,0xa0,0x23,0x06,0x50,0xd0,0xd5,0xec,0xdf,0xdf,0x2c,0x40,0x86,0xf3,0x1f,0xd6,0x9c,0x49,0xdd,0xa0,0x25,0x36,0x06,0xc3,0x9b,0xcd,0x29,0xc3,0x3d,0xd7,0x3d,0x02,0xd8,0xe2,0x51,0x31,0x92,0x3b,0x20,0x7a,0x70,0x25,0x4a,0x6a,0xed,0xf6,0x53,0x8a,0x66,0xb7,0x2a,0xa1,0x70,0xd1,0x1d,0x58,0x42,0x42,0x30,0x61,0x01,0xe2,0x3a,0x4c,0x14,0x00,0x40,0xfc,0x49,0x8e,0x24,0x6d,0x89,0x21,0x57},
+ {0xae,0x1b,0x18,0xfd,0x17,0x55,0x6e,0x0b,0xb4,0x63,0xb9,0x2b,0x9f,0x62,0x22,0x90,0x25,0x46,0x06,0x32,0xe9,0xbc,0x09,0x55,0xda,0x13,0x3c,0xf6,0x74,0xdd,0x8e,0x57,0x4e,0xda,0xd0,0xa1,0x91,0x50,0x5d,0x28,0x08,0x3e,0xfe,0xb5,0xa7,0x6f,0xaa,0x4b,0xb3,0x93,0x93,0xe1,0x7c,0x17,0xe5,0x63,0xfd,0x30,0xb0,0xc4,0xaf,0x35,0xc9,0x03,0x3d,0x0c,0x2b,0x49,0xc6,0x76,0x72,0x99,0xfc,0x05,0xe2,0xdf,0xc4,0xc2,0xcc,0x47,0x3c,0x3a,0x62,0xdd,0x84,0x9b,0xd2,0xdc,0xa2,0xc7,0x88,0x02,0x59,0xab,0xc2,0x3e},
+ {0xb9,0x7b,0xd8,0xe4,0x7b,0xd2,0xa0,0xa1,0xed,0x1a,0x39,0x61,0xeb,0x4d,0x8b,0xa9,0x83,0x9b,0xcb,0x73,0xd0,0xdd,0xa0,0x99,0xce,0xca,0x0f,0x20,0x5a,0xc2,0xd5,0x2d,0xcb,0xd1,0x32,0xae,0x09,0x3a,0x21,0xa7,0xd5,0xc2,0xf5,0x40,0xdf,0x87,0x2b,0x0f,0x29,0xab,0x1e,0xe8,0xc6,0xa4,0xae,0x0b,0x5e,0xac,0xdb,0x6a,0x6c,0xf6,0x1b,0x0e,0x7e,0x88,0x2c,0x79,0xe9,0xd5,0xab,0xe2,0x5d,0x6d,0x92,0xcb,0x18,0x00,0x02,0x1a,0x1e,0x5f,0xae,0xba,0xcd,0x69,0xba,0xbf,0x5f,0x8f,0xe8,0x5a,0xb3,0x48,0x05,0x73},
+ {0xee,0xb8,0xa8,0xcb,0xa3,0x51,0x35,0xc4,0x16,0x5f,0x11,0xb2,0x1d,0x6f,0xa2,0x65,0x50,0x38,0x8c,0xab,0x52,0x4f,0x0f,0x76,0xca,0xb8,0x1d,0x41,0x3b,0x44,0x43,0x30,0x34,0xe3,0xd6,0xa1,0x4b,0x09,0x5b,0x80,0x19,0x3f,0x35,0x09,0x77,0xf1,0x3e,0xbf,0x2b,0x70,0x22,0x06,0xcb,0x06,0x3f,0x42,0xdd,0x45,0x78,0xd8,0x77,0x22,0x5a,0x58,0x62,0x89,0xd4,0x33,0x82,0x5f,0x8a,0xa1,0x7f,0x25,0x78,0xec,0xb5,0xc4,0x98,0x66,0xff,0x41,0x3e,0x37,0xa5,0x6f,0x8e,0xa7,0x1f,0x98,0xef,0x50,0x89,0x27,0x56,0x76},
+ {0xc0,0xc8,0x1f,0xd5,0x59,0xcf,0xc3,0x38,0xf2,0xb6,0x06,0x05,0xfd,0xd2,0xed,0x9b,0x8f,0x0e,0x57,0xab,0x9f,0x10,0xbf,0x26,0xa6,0x46,0xb8,0xc1,0xa8,0x60,0x41,0x3f,0x9d,0xcf,0x86,0xea,0xa3,0x73,0x70,0xe1,0xdc,0x5f,0x15,0x07,0xb7,0xfb,0x8c,0x3a,0x8e,0x8a,0x83,0x31,0xfc,0xe7,0x53,0x48,0x16,0xf6,0x13,0xb6,0x84,0xf4,0xbb,0x28,0x7c,0x6c,0x13,0x6f,0x5c,0x2f,0x61,0xf2,0xbe,0x11,0xdd,0xf6,0x07,0xd1,0xea,0xaf,0x33,0x6f,0xde,0x13,0xd2,0x9a,0x7e,0x52,0x5d,0xf7,0x88,0x81,0x35,0xcb,0x79,0x1e},
+ {0xf1,0xe3,0xf7,0xee,0xc3,0x36,0x34,0x01,0xf8,0x10,0x9e,0xfe,0x7f,0x6a,0x8b,0x82,0xfc,0xde,0xf9,0xbc,0xe5,0x08,0xf9,0x7f,0x31,0x38,0x3b,0x3a,0x1b,0x95,0xd7,0x65,0x81,0x81,0xe0,0xf5,0xd8,0x53,0xe9,0x77,0xd9,0xde,0x9d,0x29,0x44,0x0c,0xa5,0x84,0xe5,0x25,0x45,0x86,0x0c,0x2d,0x6c,0xdc,0xf4,0xf2,0xd1,0x39,0x2d,0xb5,0x8a,0x47,0x59,0xd1,0x52,0x92,0xd3,0xa4,0xa6,0x66,0x07,0xc8,0x1a,0x87,0xbc,0xe1,0xdd,0xe5,0x6f,0xc9,0xc1,0xa6,0x40,0x6b,0x2c,0xb8,0x14,0x22,0x21,0x1a,0x41,0x7a,0xd8,0x16},
+ {0x15,0x62,0x06,0x42,0x5a,0x7e,0xbd,0xb3,0xc1,0x24,0x5a,0x0c,0xcd,0xe3,0x9b,0x87,0xb7,0x94,0xf9,0xd6,0xb1,0x5d,0xc0,0x57,0xa6,0x8c,0xf3,0x65,0x81,0x7c,0xf8,0x28,0x83,0x05,0x4e,0xd5,0xe2,0xd5,0xa4,0xfb,0xfa,0x99,0xbd,0x2e,0xd7,0xaf,0x1f,0xe2,0x8f,0x77,0xe9,0x6e,0x73,0xc2,0x7a,0x49,0xde,0x6d,0x5a,0x7a,0x57,0x0b,0x99,0x1f,0xd6,0xf7,0xe8,0x1b,0xad,0x4e,0x34,0xa3,0x8f,0x79,0xea,0xac,0xeb,0x50,0x1e,0x7d,0x52,0xe0,0x0d,0x52,0x9e,0x56,0xc6,0x77,0x3e,0x6d,0x4d,0x53,0xe1,0x2f,0x88,0x45},
+ {0xd6,0x83,0x79,0x75,0x5d,0x34,0x69,0x66,0xa6,0x11,0xaa,0x17,0x11,0xed,0xb6,0x62,0x8f,0x12,0x5e,0x98,0x57,0x18,0xdd,0x7d,0xdd,0xf6,0x26,0xf6,0xb8,0xe5,0x8f,0x68,0xe4,0x6f,0x3c,0x94,0x29,0x99,0xac,0xd8,0xa2,0x92,0x83,0xa3,0x61,0xf1,0xf9,0xb5,0xf3,0x9a,0xc8,0xbe,0x13,0xdb,0x99,0x26,0x74,0xf0,0x05,0xe4,0x3c,0x84,0xcf,0x7d,0xc0,0x32,0x47,0x4a,0x48,0xd6,0x90,0x6c,0x99,0x32,0x56,0xca,0xfd,0x43,0x21,0xd5,0xe1,0xc6,0x5d,0x91,0xc3,0x28,0xbe,0xb3,0x1b,0x19,0x27,0x73,0x7e,0x68,0x39,0x67},
+ {0xa6,0x75,0x56,0x38,0x14,0x20,0x78,0xef,0xe8,0xa9,0xfd,0xaa,0x30,0x9f,0x64,0xa2,0xcb,0xa8,0xdf,0x5c,0x50,0xeb,0xd1,0x4c,0xb3,0xc0,0x4d,0x1d,0xba,0x5a,0x11,0x46,0xc0,0x1a,0x0c,0xc8,0x9d,0xcc,0x6d,0xa6,0x36,0xa4,0x38,0x1b,0xf4,0x5c,0xa0,0x97,0xc6,0xd7,0xdb,0x95,0xbe,0xf3,0xeb,0xa7,0xab,0x7d,0x7e,0x8d,0xf6,0xb8,0xa0,0x7d,0x76,0xda,0xb5,0xc3,0x53,0x19,0x0f,0xd4,0x9b,0x9e,0x11,0x21,0x73,0x6f,0xac,0x1d,0x60,0x59,0xb2,0xfe,0x21,0x60,0xcc,0x03,0x4b,0x4b,0x67,0x83,0x7e,0x88,0x5f,0x5a},
+ {0x11,0x3d,0xa1,0x70,0xcf,0x01,0x63,0x8f,0xc4,0xd0,0x0d,0x35,0x15,0xb8,0xce,0xcf,0x7e,0xa4,0xbc,0xa4,0xd4,0x97,0x02,0xf7,0x34,0x14,0x4d,0xe4,0x56,0xb6,0x69,0x36,0xb9,0x43,0xa6,0xa0,0xd3,0x28,0x96,0x9e,0x64,0x20,0xc3,0xe6,0x00,0xcb,0xc3,0xb5,0x32,0xec,0x2d,0x7c,0x89,0x02,0x53,0x9b,0x0c,0xc7,0xd1,0xd5,0xe2,0x7a,0xe3,0x43,0x33,0xe1,0xa6,0xed,0x06,0x3f,0x7e,0x38,0xc0,0x3a,0xa1,0x99,0x51,0x1d,0x30,0x67,0x11,0x38,0x26,0x36,0xf8,0xd8,0x5a,0xbd,0xbe,0xe9,0xd5,0x4f,0xcd,0xe6,0x21,0x6a},
+ {0x5f,0xe6,0x46,0x30,0x0a,0x17,0xc6,0xf1,0x24,0x35,0xd2,0x00,0x2a,0x2a,0x71,0x58,0x55,0xb7,0x82,0x8c,0x3c,0xbd,0xdb,0x69,0x57,0xff,0x95,0xa1,0xf1,0xf9,0x6b,0x58,0xe3,0xb2,0x99,0x66,0x12,0x29,0x41,0xef,0x01,0x13,0x8d,0x70,0x47,0x08,0xd3,0x71,0xbd,0xb0,0x82,0x11,0xd0,0x32,0x54,0x32,0x36,0x8b,0x1e,0x00,0x07,0x1b,0x37,0x45,0x0b,0x79,0xf8,0x5e,0x8d,0x08,0xdb,0xa6,0xe5,0x37,0x09,0x61,0xdc,0xf0,0x78,0x52,0xb8,0x6e,0xa1,0x61,0xd2,0x49,0x03,0xac,0x79,0x21,0xe5,0x90,0x37,0xb0,0xaf,0x0e},
+ {0x2f,0x04,0x48,0x37,0xc1,0x55,0x05,0x96,0x11,0xaa,0x0b,0x82,0xe6,0x41,0x9a,0x21,0x0c,0x6d,0x48,0x73,0x38,0xf7,0x81,0x1c,0x61,0xc6,0x02,0x5a,0x67,0xcc,0x9a,0x30,0x1d,0xae,0x75,0x0f,0x5e,0x80,0x40,0x51,0x30,0xcc,0x62,0x26,0xe3,0xfb,0x02,0xec,0x6d,0x39,0x92,0xea,0x1e,0xdf,0xeb,0x2c,0xb3,0x5b,0x43,0xc5,0x44,0x33,0xae,0x44,0xee,0x43,0xa5,0xbb,0xb9,0x89,0xf2,0x9c,0x42,0x71,0xc9,0x5a,0x9d,0x0e,0x76,0xf3,0xaa,0x60,0x93,0x4f,0xc6,0xe5,0x82,0x1d,0x8f,0x67,0x94,0x7f,0x1b,0x22,0xd5,0x62},
+ {0x6d,0x93,0xd0,0x18,0x9c,0x29,0x4c,0x52,0x0c,0x1a,0x0c,0x8a,0x6c,0xb5,0x6b,0xc8,0x31,0x86,0x4a,0xdb,0x2e,0x05,0x75,0xa3,0x62,0x45,0x75,0xbc,0xe4,0xfd,0x0e,0x5c,0x3c,0x7a,0xf7,0x3a,0x26,0xd4,0x85,0x75,0x4d,0x14,0xe9,0xfe,0x11,0x7b,0xae,0xdf,0x3d,0x19,0xf7,0x59,0x80,0x70,0x06,0xa5,0x37,0x20,0x92,0x83,0x53,0x9a,0xf2,0x14,0xf5,0xd7,0xb2,0x25,0xdc,0x7e,0x71,0xdf,0x40,0x30,0xb5,0x99,0xdb,0x70,0xf9,0x21,0x62,0x4c,0xed,0xc3,0xb7,0x34,0x92,0xda,0x3e,0x09,0xee,0x7b,0x5c,0x36,0x72,0x5e},
+ {0x7f,0x21,0x71,0x45,0x07,0xfc,0x5b,0x57,0x5b,0xd9,0x94,0x06,0x5d,0x67,0x79,0x37,0x33,0x1e,0x19,0xf4,0xbb,0x37,0x0a,0x9a,0xbc,0xea,0xb4,0x47,0x4c,0x10,0xf1,0x77,0x3e,0xb3,0x08,0x2f,0x06,0x39,0x93,0x7d,0xbe,0x32,0x9f,0xdf,0xe5,0x59,0x96,0x5b,0xfd,0xbd,0x9e,0x1f,0xad,0x3d,0xff,0xac,0xb7,0x49,0x73,0xcb,0x55,0x05,0xb2,0x70,0x4c,0x2c,0x11,0x55,0xc5,0x13,0x51,0xbe,0xcd,0x1f,0x88,0x9a,0x3a,0x42,0x88,0x66,0x47,0x3b,0x50,0x5e,0x85,0x77,0x66,0x44,0x4a,0x40,0x06,0x4a,0x8f,0x39,0x34,0x0e},
+ {0xe8,0xbd,0xce,0x3e,0xd9,0x22,0x7d,0xb6,0x07,0x2f,0x82,0x27,0x41,0xe8,0xb3,0x09,0x8d,0x6d,0x5b,0xb0,0x1f,0xa6,0x3f,0x74,0x72,0x23,0x36,0x8a,0x36,0x05,0x54,0x5e,0x28,0x19,0x4b,0x3e,0x09,0x0b,0x93,0x18,0x40,0xf6,0xf3,0x73,0x0e,0xe1,0xe3,0x7d,0x6f,0x5d,0x39,0x73,0xda,0x17,0x32,0xf4,0x3e,0x9c,0x37,0xca,0xd6,0xde,0x8a,0x6f,0x9a,0xb2,0xb7,0xfd,0x3d,0x12,0x40,0xe3,0x91,0xb2,0x1a,0xa2,0xe1,0x97,0x7b,0x48,0x9e,0x94,0xe6,0xfd,0x02,0x7d,0x96,0xf9,0x97,0xde,0xd3,0xc8,0x2e,0xe7,0x0d,0x78},
+ {0xbc,0xe7,0x9a,0x08,0x45,0x85,0xe2,0x0a,0x06,0x4d,0x7f,0x1c,0xcf,0xde,0x8d,0x38,0xb8,0x11,0x48,0x0a,0x51,0x15,0xac,0x38,0xe4,0x8c,0x92,0x71,0xf6,0x8b,0xb2,0x0e,0x72,0x27,0xf4,0x00,0xf3,0xea,0x1f,0x67,0xaa,0x41,0x8c,0x2a,0x2a,0xeb,0x72,0x8f,0x92,0x32,0x37,0x97,0xd7,0x7f,0xa1,0x29,0xa6,0x87,0xb5,0x32,0xad,0xc6,0xef,0x1d,0xa7,0x95,0x51,0xef,0x1a,0xbe,0x5b,0xaf,0xed,0x15,0x7b,0x91,0x77,0x12,0x8c,0x14,0x2e,0xda,0xe5,0x7a,0xfb,0xf7,0x91,0x29,0x67,0x28,0xdd,0xf8,0x1b,0x20,0x7d,0x46},
+ {0xad,0x4f,0xef,0x74,0x9a,0x91,0xfe,0x95,0xa2,0x08,0xa3,0xf6,0xec,0x7b,0x82,0x3a,0x01,0x7b,0xa4,0x09,0xd3,0x01,0x4e,0x96,0x97,0xc7,0xa3,0x5b,0x4f,0x3c,0xc4,0x71,0xa9,0xe7,0x7a,0x56,0xbd,0xf4,0x1e,0xbc,0xbd,0x98,0x44,0xd6,0xb2,0x4c,0x62,0x3f,0xc8,0x4e,0x1f,0x2c,0xd2,0x64,0x10,0xe4,0x01,0x40,0x38,0xba,0xa5,0xc5,0xf9,0x2e,0xcd,0x74,0x9e,0xfa,0xf6,0x6d,0xfd,0xb6,0x7a,0x26,0xaf,0xe4,0xbc,0x78,0x82,0xf1,0x0e,0x99,0xef,0xf1,0xd0,0xb3,0x55,0x82,0x93,0xf2,0xc5,0x90,0xa3,0x8c,0x75,0x5a},
+ {0x95,0x24,0x46,0xd9,0x10,0x27,0xb7,0xa2,0x03,0x50,0x7d,0xd5,0xd2,0xc6,0xa8,0x3a,0xca,0x87,0xb4,0xa0,0xbf,0x00,0xd4,0xe3,0xec,0x72,0xeb,0xb3,0x44,0xe2,0xba,0x2d,0x94,0xdc,0x61,0x1d,0x8b,0x91,0xe0,0x8c,0x66,0x30,0x81,0x9a,0x46,0x36,0xed,0x8d,0xd3,0xaa,0xe8,0xaf,0x29,0xa8,0xe6,0xd4,0x3f,0xd4,0x39,0xf6,0x27,0x80,0x73,0x0a,0xcc,0xe1,0xff,0x57,0x2f,0x4a,0x0f,0x98,0x43,0x98,0x83,0xe1,0x0d,0x0d,0x67,0x00,0xfd,0x15,0xfb,0x49,0x4a,0x3f,0x5c,0x10,0x9c,0xa6,0x26,0x51,0x63,0xca,0x98,0x26},
+ {0x78,0xba,0xb0,0x32,0x88,0x31,0x65,0xe7,0x8b,0xff,0x5c,0x92,0xf7,0x31,0x18,0x38,0xcc,0x1f,0x29,0xa0,0x91,0x1b,0xa8,0x08,0x07,0xeb,0xca,0x49,0xcc,0x3d,0xb4,0x1f,0x0e,0xd9,0x3d,0x5e,0x2f,0x70,0x3d,0x2e,0x86,0x53,0xd2,0xe4,0x18,0x09,0x3f,0x9e,0x6a,0xa9,0x4d,0x02,0xf6,0x3e,0x77,0x5e,0x32,0x33,0xfa,0x4a,0x0c,0x4b,0x00,0x3c,0x2b,0xb8,0xf4,0x06,0xac,0x46,0xa9,0x9a,0xf3,0xc4,0x06,0xa8,0xa5,0x84,0xa2,0x1c,0x87,0x47,0xcd,0xc6,0x5f,0x26,0xd3,0x3e,0x17,0xd2,0x1f,0xcd,0x01,0xfd,0x43,0x6b},
+ {0x44,0xc5,0x97,0x46,0x4b,0x5d,0xa7,0xc7,0xbf,0xff,0x0f,0xdf,0x48,0xf8,0xfd,0x15,0x5a,0x78,0x46,0xaa,0xeb,0xb9,0x68,0x28,0x14,0xf7,0x52,0x5b,0x10,0xd7,0x68,0x5a,0xf3,0x0e,0x76,0x3e,0x58,0x42,0xc7,0xb5,0x90,0xb9,0x0a,0xee,0xb9,0x52,0xdc,0x75,0x3f,0x92,0x2b,0x07,0xc2,0x27,0x14,0xbf,0xf0,0xd9,0xf0,0x6f,0x2d,0x0b,0x42,0x73,0x06,0x1e,0x85,0x9e,0xcb,0xf6,0x2c,0xaf,0xc4,0x38,0x22,0xc6,0x13,0x39,0x59,0x8f,0x73,0xf3,0xfb,0x99,0x96,0xb8,0x8a,0xda,0x9e,0xbc,0x34,0xea,0x2f,0x63,0xb5,0x3d},
+ {0xd8,0xd9,0x5d,0xf7,0x2b,0xee,0x6e,0xf4,0xa5,0x59,0x67,0x39,0xf6,0xb1,0x17,0x0d,0x73,0x72,0x9e,0x49,0x31,0xd1,0xf2,0x1b,0x13,0x5f,0xd7,0x49,0xdf,0x1a,0x32,0x04,0xd5,0x25,0x98,0x82,0xb1,0x90,0x49,0x2e,0x91,0x89,0x9a,0x3e,0x87,0xeb,0xea,0xed,0xf8,0x4a,0x70,0x4c,0x39,0x3d,0xf0,0xee,0x0e,0x2b,0xdf,0x95,0xa4,0x7e,0x19,0x59,0xae,0x5a,0xe5,0xe4,0x19,0x60,0xe1,0x04,0xe9,0x92,0x2f,0x7e,0x7a,0x43,0x7b,0xe7,0xa4,0x9a,0x15,0x6f,0xc1,0x2d,0xce,0xc7,0xc0,0x0c,0xd7,0xf4,0xc1,0xfd,0xea,0x45},
+ {0x2b,0xd7,0x45,0x80,0x85,0x01,0x84,0x69,0x51,0x06,0x2f,0xcf,0xa2,0xfa,0x22,0x4c,0xc6,0x2d,0x22,0x6b,0x65,0x36,0x1a,0x94,0xde,0xda,0x62,0x03,0xc8,0xeb,0x5e,0x5a,0xed,0xb1,0xcc,0xcf,0x24,0x46,0x0e,0xb6,0x95,0x03,0x5c,0xbd,0x92,0xc2,0xdb,0x59,0xc9,0x81,0x04,0xdc,0x1d,0x9d,0xa0,0x31,0x40,0xd9,0x56,0x5d,0xea,0xce,0x73,0x3f,0xc6,0x8d,0x4e,0x0a,0xd1,0xbf,0xa7,0xb7,0x39,0xb3,0xc9,0x44,0x7e,0x00,0x57,0xbe,0xfa,0xae,0x57,0x15,0x7f,0x20,0xc1,0x60,0xdb,0x18,0x62,0x26,0x91,0x88,0x05,0x26},
+ {0x04,0xff,0x60,0x83,0xa6,0x04,0xf7,0x59,0xf4,0xe6,0x61,0x76,0xde,0x3f,0xd9,0xc3,0x51,0x35,0x87,0x12,0x73,0x2a,0x1b,0x83,0x57,0x5d,0x61,0x4e,0x2e,0x0c,0xad,0x54,0x42,0xe5,0x76,0xc6,0x3c,0x8e,0x81,0x4c,0xad,0xcc,0xce,0x03,0x93,0x2c,0x42,0x5e,0x08,0x9f,0x12,0xb4,0xca,0xcc,0x07,0xec,0xb8,0x43,0x44,0xb2,0x10,0xfa,0xed,0x0d,0x2a,0x52,0x2b,0xb8,0xd5,0x67,0x3b,0xee,0xeb,0xc1,0xa5,0x9f,0x46,0x63,0xf1,0x36,0xd3,0x9f,0xc1,0x6e,0xf2,0xd2,0xb4,0xa5,0x08,0x94,0x7a,0xa7,0xba,0xb2,0xec,0x62},
+ {0x3d,0x2b,0x15,0x61,0x52,0x79,0xed,0xe5,0xd1,0xd7,0xdd,0x0e,0x7d,0x35,0x62,0x49,0x71,0x4c,0x6b,0xb9,0xd0,0xc8,0x82,0x74,0xbe,0xd8,0x66,0xa9,0x19,0xf9,0x59,0x2e,0x74,0x28,0xb6,0xaf,0x36,0x28,0x07,0x92,0xa5,0x04,0xe1,0x79,0x85,0x5e,0xcd,0x5f,0x4a,0xa1,0x30,0xc6,0xad,0x01,0xad,0x5a,0x98,0x3f,0x66,0x75,0x50,0x3d,0x91,0x61,0xda,0x31,0x32,0x1a,0x36,0x2d,0xc6,0x0d,0x70,0x02,0x20,0x94,0x32,0x58,0x47,0xfa,0xce,0x94,0x95,0x3f,0x51,0x01,0xd8,0x02,0x5c,0x5d,0xc0,0x31,0xa1,0xc2,0xdb,0x3d},
+ {0x4b,0xc5,0x5e,0xce,0xf9,0x0f,0xdc,0x9a,0x0d,0x13,0x2f,0x8c,0x6b,0x2a,0x9c,0x03,0x15,0x95,0xf8,0xf0,0xc7,0x07,0x80,0x02,0x6b,0xb3,0x04,0xac,0x14,0x83,0x96,0x78,0x14,0xbb,0x96,0x27,0xa2,0x57,0xaa,0xf3,0x21,0xda,0x07,0x9b,0xb7,0xba,0x3a,0x88,0x1c,0x39,0xa0,0x31,0x18,0xe2,0x4b,0xe5,0xf9,0x05,0x32,0xd8,0x38,0xfb,0xe7,0x5e,0x8e,0x6a,0x44,0x41,0xcb,0xfd,0x8d,0x53,0xf9,0x37,0x49,0x43,0xa9,0xfd,0xac,0xa5,0x78,0x8c,0x3c,0x26,0x8d,0x90,0xaf,0x46,0x09,0x0d,0xca,0x9b,0x3c,0x63,0xd0,0x61},
+ {0x66,0x25,0xdb,0xff,0x35,0x49,0x74,0x63,0xbb,0x68,0x0b,0x78,0x89,0x6b,0xbd,0xc5,0x03,0xec,0x3e,0x55,0x80,0x32,0x1b,0x6f,0xf5,0xd7,0xae,0x47,0xd8,0x5f,0x96,0x6e,0xdf,0x73,0xfc,0xf8,0xbc,0x28,0xa3,0xad,0xfc,0x37,0xf0,0xa6,0x5d,0x69,0x84,0xee,0x09,0xa9,0xc2,0x38,0xdb,0xb4,0x7f,0x63,0xdc,0x7b,0x06,0xf8,0x2d,0xac,0x23,0x5b,0x7b,0x52,0x80,0xee,0x53,0xb9,0xd2,0x9a,0x8d,0x6d,0xde,0xfa,0xaa,0x19,0x8f,0xe8,0xcf,0x82,0x0e,0x15,0x04,0x17,0x71,0x0e,0xdc,0xde,0x95,0xdd,0xb9,0xbb,0xb9,0x79},
+ {0xc2,0x26,0x31,0x6a,0x40,0x55,0xb3,0xeb,0x93,0xc3,0xc8,0x68,0xa8,0x83,0x63,0xd2,0x82,0x7a,0xb9,0xe5,0x29,0x64,0x0c,0x6c,0x47,0x21,0xfd,0xc9,0x58,0xf1,0x65,0x50,0x74,0x73,0x9f,0x8e,0xae,0x7d,0x99,0xd1,0x16,0x08,0xbb,0xcf,0xf8,0xa2,0x32,0xa0,0x0a,0x5f,0x44,0x6d,0x12,0xba,0x6c,0xcd,0x34,0xb8,0xcc,0x0a,0x46,0x11,0xa8,0x1b,0x54,0x99,0x42,0x0c,0xfb,0x69,0x81,0x70,0x67,0xcf,0x6e,0xd7,0xac,0x00,0x46,0xe1,0xba,0x45,0xe6,0x70,0x8a,0xb9,0xaa,0x2e,0xf2,0xfa,0xa4,0x58,0x9e,0xf3,0x81,0x39},
+ {0x93,0x0a,0x23,0x59,0x75,0x8a,0xfb,0x18,0x5d,0xf4,0xe6,0x60,0x69,0x8f,0x16,0x1d,0xb5,0x3c,0xa9,0x14,0x45,0xa9,0x85,0x3a,0xfd,0xd0,0xac,0x05,0x37,0x08,0xdc,0x38,0xde,0x6f,0xe6,0x6d,0xa5,0xdf,0x45,0xc8,0x3a,0x48,0x40,0x2c,0x00,0xa5,0x52,0xe1,0x32,0xf6,0xb4,0xc7,0x63,0xe1,0xd2,0xe9,0x65,0x1b,0xbc,0xdc,0x2e,0x45,0xf4,0x30,0x40,0x97,0x75,0xc5,0x82,0x27,0x6d,0x85,0xcc,0xbe,0x9c,0xf9,0x69,0x45,0x13,0xfa,0x71,0x4e,0xea,0xc0,0x73,0xfc,0x44,0x88,0x69,0x24,0x3f,0x59,0x1a,0x9a,0x2d,0x63},
+ {0xa6,0xcb,0x07,0xb8,0x15,0x6b,0xbb,0xf6,0xd7,0xf0,0x54,0xbc,0xdf,0xc7,0x23,0x18,0x0b,0x67,0x29,0x6e,0x03,0x97,0x1d,0xbb,0x57,0x4a,0xed,0x47,0x88,0xf4,0x24,0x0b,0xa7,0x84,0x0c,0xed,0x11,0xfd,0x09,0xbf,0x3a,0x69,0x9f,0x0d,0x81,0x71,0xf0,0x63,0x79,0x87,0xcf,0x57,0x2d,0x8c,0x90,0x21,0xa2,0x4b,0xf6,0x8a,0xf2,0x7d,0x5a,0x3a,0xc7,0xea,0x1b,0x51,0xbe,0xd4,0xda,0xdc,0xf2,0xcc,0x26,0xed,0x75,0x80,0x53,0xa4,0x65,0x9a,0x5f,0x00,0x9f,0xff,0x9c,0xe1,0x63,0x1f,0x48,0x75,0x44,0xf7,0xfc,0x34},
+ {0xca,0x67,0x97,0x78,0x4c,0xe0,0x97,0xc1,0x7d,0x46,0xd9,0x38,0xcb,0x4d,0x71,0xb8,0xa8,0x5f,0xf9,0x83,0x82,0x88,0xde,0x55,0xf7,0x63,0xfa,0x4d,0x16,0xdc,0x3b,0x3d,0x98,0xaa,0xcf,0x78,0xab,0x1d,0xbb,0xa5,0xf2,0x72,0x0b,0x19,0x67,0xa2,0xed,0x5c,0x8e,0x60,0x92,0x0a,0x11,0xc9,0x09,0x93,0xb0,0x74,0xb3,0x2f,0x04,0xa3,0x19,0x01,0x7d,0x17,0xc2,0xe8,0x9c,0xd8,0xa2,0x67,0xc1,0xd0,0x95,0x68,0xf6,0xa5,0x9d,0x66,0xb0,0xa2,0x82,0xb2,0xe5,0x98,0x65,0xf5,0x73,0x0a,0xe2,0xed,0xf1,0x88,0xc0,0x56},
+ {0x17,0x6e,0xa8,0x10,0x11,0x3d,0x6d,0x33,0xfa,0xb2,0x75,0x0b,0x32,0x88,0xf3,0xd7,0x88,0x29,0x07,0x25,0x76,0x33,0x15,0xf9,0x87,0x8b,0x10,0x99,0x6b,0x4c,0x67,0x09,0x02,0x8f,0xf3,0x24,0xac,0x5f,0x1b,0x58,0xbd,0x0c,0xe3,0xba,0xfe,0xe9,0x0b,0xa9,0xf0,0x92,0xcf,0x8a,0x02,0x69,0x21,0x9a,0x8f,0x03,0x59,0x83,0xa4,0x7e,0x8b,0x03,0xf8,0x6f,0x31,0x99,0x21,0xf8,0x4e,0x9f,0x4f,0x8d,0xa7,0xea,0x82,0xd2,0x49,0x2f,0x74,0x31,0xef,0x5a,0xab,0xa5,0x71,0x09,0x65,0xeb,0x69,0x59,0x02,0x31,0x5e,0x6e},
+ {0xfb,0x93,0xe5,0x87,0xf5,0x62,0x6c,0xb1,0x71,0x3e,0x5d,0xca,0xde,0xed,0x99,0x49,0x6d,0x3e,0xcc,0x14,0xe0,0xc1,0x91,0xb4,0xa8,0xdb,0xa8,0x89,0x47,0x11,0xf5,0x08,0x22,0x62,0x06,0x63,0x0e,0xfb,0x04,0x33,0x3f,0xba,0xac,0x87,0x89,0x06,0x35,0xfb,0xa3,0x61,0x10,0x8c,0x77,0x24,0x19,0xbd,0x20,0x86,0x83,0xd1,0x43,0xad,0x58,0x30,0xd0,0x63,0x76,0xe5,0xfd,0x0f,0x3c,0x32,0x10,0xa6,0x2e,0xa2,0x38,0xdf,0xc3,0x05,0x9a,0x4f,0x99,0xac,0xbd,0x8a,0xc7,0xbd,0x99,0xdc,0xe3,0xef,0xa4,0x9f,0x54,0x26},
+ {0xd6,0xf9,0x6b,0x1e,0x46,0x5a,0x1d,0x74,0x81,0xa5,0x77,0x77,0xfc,0xb3,0x05,0x23,0xd9,0xd3,0x74,0x64,0xa2,0x74,0x55,0xd4,0xff,0xe0,0x01,0x64,0xdc,0xe1,0x26,0x19,0x6e,0x66,0x3f,0xaf,0x49,0x85,0x46,0xdb,0xa5,0x0e,0x4a,0xf1,0x04,0xcf,0x7f,0xd7,0x47,0x0c,0xba,0xa4,0xf7,0x3f,0xf2,0x3d,0x85,0x3c,0xce,0x32,0xe1,0xdf,0x10,0x3a,0xa0,0xce,0x17,0xea,0x8a,0x4e,0x7f,0xe0,0xfd,0xc1,0x1f,0x3a,0x46,0x15,0xd5,0x2f,0xf1,0xc0,0xf2,0x31,0xfd,0x22,0x53,0x17,0x15,0x5d,0x1e,0x86,0x1d,0xd0,0xa1,0x1f},
+ {0x32,0x98,0x59,0x7d,0x94,0x55,0x80,0xcc,0x20,0x55,0xf1,0x37,0xda,0x56,0x46,0x1e,0x20,0x93,0x05,0x4e,0x74,0xf7,0xf6,0x99,0x33,0xcf,0x75,0x6a,0xbc,0x63,0x35,0x77,0xab,0x94,0xdf,0xd1,0x00,0xac,0xdc,0x38,0xe9,0x0d,0x08,0xd1,0xdd,0x2b,0x71,0x2e,0x62,0xe2,0xd5,0xfd,0x3e,0xe9,0x13,0x7f,0xe5,0x01,0x9a,0xee,0x18,0xed,0xfc,0x73,0xb3,0x9c,0x13,0x63,0x08,0xe9,0xb1,0x06,0xcd,0x3e,0xa0,0xc5,0x67,0xda,0x93,0xa4,0x32,0x89,0x63,0xad,0xc8,0xce,0x77,0x8d,0x44,0x4f,0x86,0x1b,0x70,0x6b,0x42,0x1f},
+ {0x01,0x1c,0x91,0x41,0x4c,0x26,0xc9,0xef,0x25,0x2c,0xa2,0x17,0xb8,0xb7,0xa3,0xf1,0x47,0x14,0x0f,0xf3,0x6b,0xda,0x75,0x58,0x90,0xb0,0x31,0x1d,0x27,0xf5,0x1a,0x4e,0x52,0x25,0xa1,0x91,0xc8,0x35,0x7e,0xf1,0x76,0x9c,0x5e,0x57,0x53,0x81,0x6b,0xb7,0x3e,0x72,0x9b,0x0d,0x6f,0x40,0x83,0xfa,0x38,0xe4,0xa7,0x3f,0x1b,0xbb,0x76,0x0b,0x9b,0x93,0x92,0x7f,0xf9,0xc1,0xb8,0x08,0x6e,0xab,0x44,0xd4,0xcb,0x71,0x67,0xbe,0x17,0x80,0xbb,0x99,0x63,0x64,0xe5,0x22,0x55,0xa9,0x72,0xb7,0x1e,0xd6,0x6d,0x7b},
+ {0x92,0x3d,0xf3,0x50,0xe8,0xc1,0xad,0xb7,0xcf,0xd5,0x8c,0x60,0x4f,0xfa,0x98,0x79,0xdb,0x5b,0xfc,0x8d,0xbd,0x2d,0x96,0xad,0x4f,0x2f,0x1d,0xaf,0xce,0x9b,0x3e,0x70,0xc7,0xd2,0x01,0xab,0xf9,0xab,0x30,0x57,0x18,0x3b,0x14,0x40,0xdc,0x76,0xfb,0x16,0x81,0xb2,0xcb,0xa0,0x65,0xbe,0x6c,0x86,0xfe,0x6a,0xff,0x9b,0x65,0x9b,0xfa,0x53,0x55,0x54,0x88,0x94,0xe9,0xc8,0x14,0x6c,0xe5,0xd4,0xae,0x65,0x66,0x5d,0x3a,0x84,0xf1,0x5a,0xd6,0xbc,0x3e,0xb7,0x1b,0x18,0x50,0x1f,0xc6,0xc4,0xe5,0x93,0x8d,0x39},
+ {0xf3,0x48,0xe2,0x33,0x67,0xd1,0x4b,0x1c,0x5f,0x0a,0xbf,0x15,0x87,0x12,0x9e,0xbd,0x76,0x03,0x0b,0xa1,0xf0,0x8c,0x3f,0xd4,0x13,0x1b,0x19,0xdf,0x5d,0x9b,0xb0,0x53,0xf2,0xe3,0xe7,0xd2,0x60,0x7c,0x87,0xc3,0xb1,0x8b,0x82,0x30,0xa0,0xaa,0x34,0x3b,0x38,0xf1,0x9e,0x73,0xe7,0x26,0x3e,0x28,0x77,0x05,0xc3,0x02,0x90,0x9c,0x9c,0x69,0xcc,0xf1,0x46,0x59,0x23,0xa7,0x06,0xf3,0x7d,0xd9,0xe5,0xcc,0xb5,0x18,0x17,0x92,0x75,0xe9,0xb4,0x81,0x47,0xd2,0xcd,0x28,0x07,0xd9,0xcd,0x6f,0x0c,0xf3,0xca,0x51},
+ {0x0a,0xe0,0x74,0x76,0x42,0xa7,0x0b,0xa6,0xf3,0x7b,0x7a,0xa1,0x70,0x85,0x0e,0x63,0xcc,0x24,0x33,0xcf,0x3d,0x56,0x58,0x37,0xaa,0xfd,0x83,0x23,0x29,0xaa,0x04,0x55,0xc7,0x54,0xac,0x18,0x9a,0xf9,0x7a,0x73,0x0f,0xb3,0x1c,0xc5,0xdc,0x78,0x33,0x90,0xc7,0x0c,0xe1,0x4c,0x33,0xbc,0x89,0x2b,0x9a,0xe9,0xf8,0x89,0xc1,0x29,0xae,0x12,0xcf,0x01,0x0d,0x1f,0xcb,0xc0,0x9e,0xa9,0xae,0xf7,0x34,0x3a,0xcc,0xef,0xd1,0x0d,0x22,0x4e,0x9c,0xd0,0x21,0x75,0xca,0x55,0xea,0xa5,0xeb,0x58,0xe9,0x4f,0xd1,0x5f},
+ {0x2c,0xab,0x45,0x28,0xdf,0x2d,0xdc,0xb5,0x93,0xe9,0x7f,0x0a,0xb1,0x91,0x94,0x06,0x46,0xe3,0x02,0x40,0xd6,0xf3,0xaa,0x4d,0xd1,0x74,0x64,0x58,0x6e,0xf2,0x3f,0x09,0x8e,0xcb,0x93,0xbf,0x5e,0xfe,0x42,0x3c,0x5f,0x56,0xd4,0x36,0x51,0xa8,0xdf,0xbe,0xe8,0x20,0x42,0x88,0x9e,0x85,0xf0,0xe0,0x28,0xd1,0x25,0x07,0x96,0x3f,0xd7,0x7d,0x29,0x98,0x05,0x68,0xfe,0x24,0x0d,0xb1,0xe5,0x23,0xaf,0xdb,0x72,0x06,0x73,0x75,0x29,0xac,0x57,0xb4,0x3a,0x25,0x67,0x13,0xa4,0x70,0xb4,0x86,0xbc,0xbc,0x59,0x2f},
+ {0x5f,0x13,0x17,0x99,0x42,0x7d,0x84,0x83,0xd7,0x03,0x7d,0x56,0x1f,0x91,0x1b,0xad,0xd1,0xaa,0x77,0xbe,0xd9,0x48,0x77,0x7e,0x4a,0xaf,0x51,0x2e,0x2e,0xb4,0x58,0x54,0x01,0xc3,0x91,0xb6,0x60,0xd5,0x41,0x70,0x1e,0xe7,0xd7,0xad,0x3f,0x1b,0x20,0x85,0x85,0x55,0x33,0x11,0x63,0xe1,0xc2,0x16,0xb1,0x28,0x08,0x01,0x3d,0x5e,0xa5,0x2a,0x4f,0x44,0x07,0x0c,0xe6,0x92,0x51,0xed,0x10,0x1d,0x42,0x74,0x2d,0x4e,0xc5,0x42,0x64,0xc8,0xb5,0xfd,0x82,0x4c,0x2b,0x35,0x64,0x86,0x76,0x8a,0x4a,0x00,0xe9,0x13},
+ {0xdb,0xce,0x2f,0x83,0x45,0x88,0x9d,0x73,0x63,0xf8,0x6b,0xae,0xc9,0xd6,0x38,0xfa,0xf7,0xfe,0x4f,0xb7,0xca,0x0d,0xbc,0x32,0x5e,0xe4,0xbc,0x14,0x88,0x7e,0x93,0x73,0x7f,0x87,0x3b,0x19,0xc9,0x00,0x2e,0xbb,0x6b,0x50,0xdc,0xe0,0x90,0xa8,0xe3,0xec,0x9f,0x64,0xde,0x36,0xc0,0xb7,0xf3,0xec,0x1a,0x9e,0xde,0x98,0x08,0x04,0x46,0x5f,0x8d,0xf4,0x7b,0x29,0x16,0x71,0x03,0xb9,0x34,0x68,0xf0,0xd4,0x22,0x3b,0xd1,0xa9,0xc6,0xbd,0x96,0x46,0x57,0x15,0x97,0xe1,0x35,0xe8,0xd5,0x91,0xe8,0xa4,0xf8,0x2c},
+ {0x67,0x0f,0x11,0x07,0x87,0xfd,0x93,0x6d,0x49,0xb5,0x38,0x7c,0xd3,0x09,0x4c,0xdd,0x86,0x6a,0x73,0xc2,0x4c,0x6a,0xb1,0x7c,0x09,0x2a,0x25,0x58,0x6e,0xbd,0x49,0x20,0xa2,0x6b,0xd0,0x17,0x7e,0x48,0xb5,0x2c,0x6b,0x19,0x50,0x39,0x1c,0x38,0xd2,0x24,0x30,0x8a,0x97,0x85,0x81,0x9c,0x65,0xd7,0xf6,0xa4,0xd6,0x91,0x28,0x7f,0x6f,0x7a,0x49,0xef,0x9a,0x6a,0x8d,0xfd,0x09,0x7d,0x0b,0xb9,0x3d,0x5b,0xbe,0x60,0xee,0xf0,0xd4,0xbf,0x9e,0x51,0x2c,0xb5,0x21,0x4c,0x1d,0x94,0x45,0xc5,0xdf,0xaa,0x11,0x60},
+ {0x3c,0xf8,0x95,0xcf,0x6d,0x92,0x67,0x5f,0x71,0x90,0x28,0x71,0x61,0x85,0x7e,0x7c,0x5b,0x7a,0x8f,0x99,0xf3,0xe7,0xa1,0xd6,0xe0,0xf9,0x62,0x0b,0x1b,0xcc,0xc5,0x6f,0x90,0xf8,0xcb,0x02,0xc8,0xd0,0xde,0x63,0xaa,0x6a,0xff,0x0d,0xca,0x98,0xd0,0xfb,0x99,0xed,0xb6,0xb9,0xfd,0x0a,0x4d,0x62,0x1e,0x0b,0x34,0x79,0xb7,0x18,0xce,0x69,0xcb,0x79,0x98,0xb2,0x28,0x55,0xef,0xd1,0x92,0x90,0x7e,0xd4,0x3c,0xae,0x1a,0xdd,0x52,0x23,0x9f,0x18,0x42,0x04,0x7e,0x12,0xf1,0x01,0x71,0xe5,0x3a,0x6b,0x59,0x15},
+ {0xa2,0x79,0x91,0x3f,0xd2,0x39,0x27,0x46,0xcf,0xdd,0xd6,0x97,0x31,0x12,0x83,0xff,0x8a,0x14,0xf2,0x53,0xb5,0xde,0x07,0x13,0xda,0x4d,0x5f,0x7b,0x68,0x37,0x22,0x0d,0xca,0x24,0x51,0x7e,0x16,0x31,0xff,0x09,0xdf,0x45,0xc7,0xd9,0x8b,0x15,0xe4,0x0b,0xe5,0x56,0xf5,0x7e,0x22,0x7d,0x2b,0x29,0x38,0xd1,0xb6,0xaf,0x41,0xe2,0xa4,0x3a,0xf5,0x05,0x33,0x2a,0xbf,0x38,0xc1,0x2c,0xc3,0x26,0xe9,0xa2,0x8f,0x3f,0x58,0x48,0xeb,0xd2,0x49,0x55,0xa2,0xb1,0x3a,0x08,0x6c,0xa3,0x87,0x46,0x6e,0xaa,0xfc,0x32},
+ {0xf5,0x9a,0x7d,0xc5,0x8d,0x6e,0xc5,0x7b,0xf2,0xbd,0xf0,0x9d,0xed,0xd2,0x0b,0x3e,0xa3,0xe4,0xef,0x22,0xde,0x14,0xc0,0xaa,0x5c,0x6a,0xbd,0xfe,0xce,0xe9,0x27,0x46,0xdf,0xcc,0x87,0x27,0x73,0xa4,0x07,0x32,0xf8,0xe3,0x13,0xf2,0x08,0x19,0xe3,0x17,0x4e,0x96,0x0d,0xf6,0xd7,0xec,0xb2,0xd5,0xe9,0x0b,0x60,0xc2,0x36,0x63,0x6f,0x74,0x1c,0x97,0x6c,0xab,0x45,0xf3,0x4a,0x3f,0x1f,0x73,0x43,0x99,0x72,0xeb,0x88,0xe2,0x6d,0x18,0x44,0x03,0x8a,0x6a,0x59,0x33,0x93,0x62,0xd6,0x7e,0x00,0x17,0x49,0x7b},
+ {0x64,0xb0,0x84,0xab,0x5c,0xfb,0x85,0x2d,0x14,0xbc,0xf3,0x89,0xd2,0x10,0x78,0x49,0x0c,0xce,0x15,0x7b,0x44,0xdc,0x6a,0x47,0x7b,0xfd,0x44,0xf8,0x76,0xa3,0x2b,0x12,0xdd,0xa2,0x53,0xdd,0x28,0x1b,0x34,0x54,0x3f,0xfc,0x42,0xdf,0x5b,0x90,0x17,0xaa,0xf4,0xf8,0xd2,0x4d,0xd9,0x92,0xf5,0x0f,0x7d,0xd3,0x8c,0xe0,0x0f,0x62,0x03,0x1d,0x54,0xe5,0xb4,0xa2,0xcd,0x32,0x02,0xc2,0x7f,0x18,0x5d,0x11,0x42,0xfd,0xd0,0x9e,0xd9,0x79,0xd4,0x7d,0xbe,0xb4,0xab,0x2e,0x4c,0xec,0x68,0x2b,0xf5,0x0b,0xc7,0x02},
+ {0xbb,0x2f,0x0b,0x5d,0x4b,0xec,0x87,0xa2,0xca,0x82,0x48,0x07,0x90,0x57,0x5c,0x41,0x5c,0x81,0xd0,0xc1,0x1e,0xa6,0x44,0xe0,0xe0,0xf5,0x9e,0x40,0x0a,0x4f,0x33,0x26,0xe1,0x72,0x8d,0x45,0xbf,0x32,0xe5,0xac,0xb5,0x3c,0xb7,0x7c,0xe0,0x68,0xe7,0x5b,0xe7,0xbd,0x8b,0xee,0x94,0x7d,0xcf,0x56,0x03,0x3a,0xb4,0xfe,0xe3,0x97,0x06,0x6b,0xc0,0xa3,0x62,0xdf,0x4a,0xf0,0xc8,0xb6,0x5d,0xa4,0x6d,0x07,0xef,0x00,0xf0,0x3e,0xa9,0xd2,0xf0,0x49,0x58,0xb9,0x9c,0x9c,0xae,0x2f,0x1b,0x44,0x43,0x7f,0xc3,0x1c},
+ {0x4f,0x32,0xc7,0x5c,0x5a,0x56,0x8f,0x50,0x22,0xa9,0x06,0xe5,0xc0,0xc4,0x61,0xd0,0x19,0xac,0x45,0x5c,0xdb,0xab,0x18,0xfb,0x4a,0x31,0x80,0x03,0xc1,0x09,0x68,0x6c,0xb9,0xae,0xce,0xc9,0xf1,0x56,0x66,0xd7,0x6a,0x65,0xe5,0x18,0xf8,0x15,0x5b,0x1c,0x34,0x23,0x4c,0x84,0x32,0x28,0xe7,0x26,0x38,0x68,0x19,0x2f,0x77,0x6f,0x34,0x3a,0xc8,0x6a,0xda,0xe2,0x12,0x51,0xd5,0xd2,0xed,0x51,0xe8,0xb1,0x31,0x03,0xbd,0xe9,0x62,0x72,0xc6,0x8e,0xdd,0x46,0x07,0x96,0xd0,0xc5,0xf7,0x6e,0x9f,0x1b,0x91,0x05},
+ {0xbb,0x0e,0xdf,0xf5,0x83,0x99,0x33,0xc1,0xac,0x4c,0x2c,0x51,0x8f,0x75,0xf3,0xc0,0xe1,0x98,0xb3,0x0b,0x0a,0x13,0xf1,0x2c,0x62,0x0c,0x27,0xaa,0xf9,0xec,0x3c,0x6b,0xef,0xea,0x2e,0x51,0xf3,0xac,0x49,0x53,0x49,0xcb,0xc1,0x1c,0xd3,0x41,0xc1,0x20,0x8d,0x68,0x9a,0xa9,0x07,0x0c,0x18,0x24,0x17,0x2d,0x4b,0xc6,0xd1,0xf9,0x5e,0x55,0x08,0xbd,0x73,0x3b,0xba,0x70,0xa7,0x36,0x0c,0xbf,0xaf,0xa3,0x08,0xef,0x4a,0x62,0xf2,0x46,0x09,0xb4,0x98,0xff,0x37,0x57,0x9d,0x74,0x81,0x33,0xe1,0x4d,0x5f,0x67},
+ {0xfc,0x82,0x17,0x6b,0x03,0x52,0x2c,0x0e,0xb4,0x83,0xad,0x6c,0x81,0x6c,0x81,0x64,0x3e,0x07,0x64,0x69,0xd9,0xbd,0xdc,0xd0,0x20,0xc5,0x64,0x01,0xf7,0x9d,0xd9,0x13,0x1d,0xb3,0xda,0x3b,0xd9,0xf6,0x2f,0xa1,0xfe,0x2d,0x65,0x9d,0x0f,0xd8,0x25,0x07,0x87,0x94,0xbe,0x9a,0xf3,0x4f,0x9c,0x01,0x43,0x3c,0xcd,0x82,0xb8,0x50,0xf4,0x60,0xca,0xc0,0xe5,0x21,0xc3,0x5e,0x4b,0x01,0xa2,0xbf,0x19,0xd7,0xc9,0x69,0xcb,0x4f,0xa0,0x23,0x00,0x75,0x18,0x1c,0x5f,0x4e,0x80,0xac,0xed,0x55,0x9e,0xde,0x06,0x1c},
+ {0xe2,0xc4,0x3e,0xa3,0xd6,0x7a,0x0f,0x99,0x8e,0xe0,0x2e,0xbe,0x38,0xf9,0x08,0x66,0x15,0x45,0x28,0x63,0xc5,0x43,0xa1,0x9c,0x0d,0xb6,0x2d,0xec,0x1f,0x8a,0xf3,0x4c,0xaa,0x69,0x6d,0xff,0x40,0x2b,0xd5,0xff,0xbb,0x49,0x40,0xdc,0x18,0x0b,0x53,0x34,0x97,0x98,0x4d,0xa3,0x2f,0x5c,0x4a,0x5e,0x2d,0xba,0x32,0x7d,0x8e,0x6f,0x09,0x78,0xe7,0x5c,0xfa,0x0d,0x65,0xaa,0xaa,0xa0,0x8c,0x47,0xb5,0x48,0x2a,0x9e,0xc4,0xf9,0x5b,0x72,0x03,0x70,0x7d,0xcc,0x09,0x4f,0xbe,0x1a,0x09,0x26,0x3a,0xad,0x3c,0x37},
+ {0x7c,0xf5,0xc9,0x82,0x4d,0x63,0x94,0xb2,0x36,0x45,0x93,0x24,0xe1,0xfd,0xcb,0x1f,0x5a,0xdb,0x8c,0x41,0xb3,0x4d,0x9c,0x9e,0xfc,0x19,0x44,0x45,0xd9,0xf3,0x40,0x00,0xad,0xbb,0xdd,0x89,0xfb,0xa8,0xbe,0xf1,0xcb,0xae,0xae,0x61,0xbc,0x2c,0xcb,0x3b,0x9d,0x8d,0x9b,0x1f,0xbb,0xa7,0x58,0x8f,0x86,0xa6,0x12,0x51,0xda,0x7e,0x54,0x21,0xd3,0x86,0x59,0xfd,0x39,0xe9,0xfd,0xde,0x0c,0x38,0x0a,0x51,0x89,0x2c,0x27,0xf4,0xb9,0x19,0x31,0xbb,0x07,0xa4,0x2b,0xb7,0xf4,0x4d,0x25,0x4a,0x33,0x0a,0x55,0x63},
+ {0x37,0xcf,0x69,0xb5,0xed,0xd6,0x07,0x65,0xe1,0x2e,0xa5,0x0c,0xb0,0x29,0x84,0x17,0x5d,0xd6,0x6b,0xeb,0x90,0x00,0x7c,0xea,0x51,0x8f,0xf7,0xda,0xc7,0x62,0xea,0x3e,0x49,0x7b,0x54,0x72,0x45,0x58,0xba,0x9b,0xe0,0x08,0xc4,0xe2,0xfa,0xc6,0x05,0xf3,0x8d,0xf1,0x34,0xc7,0x69,0xfa,0xe8,0x60,0x7a,0x76,0x7d,0xaa,0xaf,0x2b,0xa9,0x39,0x4e,0x27,0x93,0xe6,0x13,0xc7,0x24,0x9d,0x75,0xd3,0xdb,0x68,0x77,0x85,0x63,0x5f,0x9a,0xb3,0x8a,0xeb,0x60,0x55,0x52,0x70,0xcd,0xc4,0xc9,0x65,0x06,0x6a,0x43,0x68},
+ {0x27,0x3f,0x2f,0x20,0xe8,0x35,0x02,0xbc,0xb0,0x75,0xf9,0x64,0xe2,0x00,0x5c,0xc7,0x16,0x24,0x8c,0xa3,0xd5,0xe9,0xa4,0x91,0xf9,0x89,0xb7,0x8a,0xf6,0xe7,0xb6,0x17,0x7c,0x10,0x20,0xe8,0x17,0xd3,0x56,0x1e,0x65,0xe9,0x0a,0x84,0x44,0x68,0x26,0xc5,0x7a,0xfc,0x0f,0x32,0xc6,0xa1,0xe0,0xc1,0x72,0x14,0x61,0x91,0x9c,0x66,0x73,0x53,0x57,0x52,0x0e,0x9a,0xab,0x14,0x28,0x5d,0xfc,0xb3,0xca,0xc9,0x84,0x20,0x8f,0x90,0xca,0x1e,0x2d,0x5b,0x88,0xf5,0xca,0xaf,0x11,0x7d,0xf8,0x78,0xa6,0xb5,0xb4,0x1c},
+ {0x6c,0xfc,0x4a,0x39,0x6b,0xc0,0x64,0xb6,0xb1,0x5f,0xda,0x98,0x24,0xde,0x88,0x0c,0x34,0xd8,0xca,0x4b,0x16,0x03,0x8d,0x4f,0xa2,0x34,0x74,0xde,0x78,0xca,0x0b,0x33,0xe7,0x07,0xa0,0xa2,0x62,0xaa,0x74,0x6b,0xb1,0xc7,0x71,0xf0,0xb0,0xe0,0x11,0xf3,0x23,0xe2,0x0b,0x00,0x38,0xe4,0x07,0x57,0xac,0x6e,0xef,0x82,0x2d,0xfd,0xc0,0x2d,0x4e,0x74,0x19,0x11,0x84,0xff,0x2e,0x98,0x24,0x47,0x07,0x2b,0x96,0x5e,0x69,0xf9,0xfb,0x53,0xc9,0xbf,0x4f,0xc1,0x8a,0xc5,0xf5,0x1c,0x9f,0x36,0x1b,0xbe,0x31,0x3c},
+ {0xee,0x8a,0x94,0x08,0x4d,0x86,0xf4,0xb0,0x6f,0x1c,0xba,0x91,0xee,0x19,0xdc,0x07,0x58,0xa1,0xac,0xa6,0xae,0xcd,0x75,0x79,0xbb,0xd4,0x62,0x42,0x13,0x61,0x0b,0x33,0x72,0x42,0xcb,0xf9,0x93,0xbc,0x68,0xc1,0x98,0xdb,0xce,0xc7,0x1f,0x71,0xb8,0xae,0x7a,0x8d,0xac,0x34,0xaa,0x52,0x0e,0x7f,0xbb,0x55,0x7d,0x7e,0x09,0xc1,0xce,0x41,0x8a,0x80,0x6d,0xa2,0xd7,0x19,0x96,0xf7,0x6d,0x15,0x9e,0x1d,0x9e,0xd4,0x1f,0xbb,0x27,0xdf,0xa1,0xdb,0x6c,0xc3,0xd7,0x73,0x7d,0x77,0x28,0x1f,0xd9,0x4c,0xb4,0x26},
+ {0x75,0x74,0x38,0x8f,0x47,0x48,0xf0,0x51,0x3c,0xcb,0xbe,0x9c,0xf4,0xbc,0x5d,0xb2,0x55,0x20,0x9f,0xd9,0x44,0x12,0xab,0x9a,0xd6,0xa5,0x10,0x1c,0x6c,0x9e,0x70,0x2c,0x83,0x03,0x73,0x62,0x93,0xf2,0xb7,0xe1,0x2c,0x8a,0xca,0xeb,0xff,0x79,0x52,0x4b,0x14,0x13,0xd4,0xbf,0x8a,0x77,0xfc,0xda,0x0f,0x61,0x72,0x9c,0x14,0x10,0xeb,0x7d,0x7a,0xee,0x66,0x87,0x6a,0xaf,0x62,0xcb,0x0e,0xcd,0x53,0x55,0x04,0xec,0xcb,0x66,0xb5,0xe4,0x0b,0x0f,0x38,0x01,0x80,0x58,0xea,0xe2,0x2c,0xf6,0x9f,0x8e,0xe6,0x08},
+ {0xad,0x30,0xc1,0x4b,0x0a,0x50,0xad,0x34,0x9c,0xd4,0x0b,0x3d,0x49,0xdb,0x38,0x8d,0xbe,0x89,0x0a,0x50,0x98,0x3d,0x5c,0xa2,0x09,0x3b,0xba,0xee,0x87,0x3f,0x1f,0x2f,0xf9,0xf2,0xb8,0x0a,0xd5,0x09,0x2d,0x2f,0xdf,0x23,0x59,0xc5,0x8d,0x21,0xb9,0xac,0xb9,0x6c,0x76,0x73,0x26,0x34,0x8f,0x4a,0xf5,0x19,0xf7,0x38,0xd7,0x3b,0xb1,0x4c,0x4a,0xb6,0x15,0xe5,0x75,0x8c,0x84,0xf7,0x38,0x90,0x4a,0xdb,0xba,0x01,0x95,0xa5,0x50,0x1b,0x75,0x3f,0x3f,0x31,0x0d,0xc2,0xe8,0x2e,0xae,0xc0,0x53,0xe3,0xa1,0x19},
+ {0xc3,0x05,0xfa,0xba,0x60,0x75,0x1c,0x7d,0x61,0x5e,0xe5,0xc6,0xa0,0xa0,0xe1,0xb3,0x73,0x64,0xd6,0xc0,0x18,0x97,0x52,0xe3,0x86,0x34,0x0c,0xc2,0x11,0x6b,0x54,0x41,0xbd,0xbd,0x96,0xd5,0xcd,0x72,0x21,0xb4,0x40,0xfc,0xee,0x98,0x43,0x45,0xe0,0x93,0xb5,0x09,0x41,0xb4,0x47,0x53,0xb1,0x9f,0x34,0xae,0x66,0x02,0x99,0xd3,0x6b,0x73,0xb4,0xb3,0x34,0x93,0x50,0x2d,0x53,0x85,0x73,0x65,0x81,0x60,0x4b,0x11,0xfd,0x46,0x75,0x83,0x5c,0x42,0x30,0x5f,0x5f,0xcc,0x5c,0xab,0x7f,0xb8,0xa2,0x95,0x22,0x41},
+ {0xe9,0xd6,0x7e,0xf5,0x88,0x9b,0xc9,0x19,0x25,0xc8,0xf8,0x6d,0x26,0xcb,0x93,0x53,0x73,0xd2,0x0a,0xb3,0x13,0x32,0xee,0x5c,0x34,0x2e,0x2d,0xb5,0xeb,0x53,0xe1,0x14,0xc6,0xea,0x93,0xe2,0x61,0x52,0x65,0x2e,0xdb,0xac,0x33,0x21,0x03,0x92,0x5a,0x84,0x6b,0x99,0x00,0x79,0xcb,0x75,0x09,0x46,0x80,0xdd,0x5a,0x19,0x8d,0xbb,0x60,0x07,0x8a,0x81,0xe6,0xcd,0x17,0x1a,0x3e,0x41,0x84,0xa0,0x69,0xed,0xa9,0x6d,0x15,0x57,0xb1,0xcc,0xca,0x46,0x8f,0x26,0xbf,0x2c,0xf2,0xc5,0x3a,0xc3,0x9b,0xbe,0x34,0x6b},
+ {0xb2,0xc0,0x78,0x3a,0x64,0x2f,0xdf,0xf3,0x7c,0x02,0x2e,0xf2,0x1e,0x97,0x3e,0x4c,0xa3,0xb5,0xc1,0x49,0x5e,0x1c,0x7d,0xec,0x2d,0xdd,0x22,0x09,0x8f,0xc1,0x12,0x20,0xd3,0xf2,0x71,0x65,0x65,0x69,0xfc,0x11,0x7a,0x73,0x0e,0x53,0x45,0xe8,0xc9,0xc6,0x35,0x50,0xfe,0xd4,0xa2,0xe7,0x3a,0xe3,0x0b,0xd3,0x6d,0x2e,0xb6,0xc7,0xb9,0x01,0x29,0x9d,0xc8,0x5a,0xe5,0x55,0x0b,0x88,0x63,0xa7,0xa0,0x45,0x1f,0x24,0x83,0x14,0x1f,0x6c,0xe7,0xc2,0xdf,0xef,0x36,0x3d,0xe8,0xad,0x4b,0x4e,0x78,0x5b,0xaf,0x08},
+ {0x33,0x25,0x1f,0x88,0xdc,0x99,0x34,0x28,0xb6,0x23,0x93,0x77,0xda,0x25,0x05,0x9d,0xf4,0x41,0x34,0x67,0xfb,0xdd,0x7a,0x89,0x8d,0x16,0x3a,0x16,0x71,0x9d,0xb7,0x32,0x4b,0x2c,0xcc,0x89,0xd2,0x14,0x73,0xe2,0x8d,0x17,0x87,0xa2,0x11,0xbd,0xe4,0x4b,0xce,0x64,0x33,0xfa,0xd6,0x28,0xd5,0x18,0x6e,0x82,0xd9,0xaf,0xd5,0xc1,0x23,0x64,0x6a,0xb3,0xfc,0xed,0xd9,0xf8,0x85,0xcc,0xf9,0xe5,0x46,0x37,0x8f,0xc2,0xbc,0x22,0xcd,0xd3,0xe5,0xf9,0x38,0xe3,0x9d,0xe4,0xcc,0x2d,0x3e,0xc1,0xfb,0x5e,0x0a,0x48},
+ {0x71,0x20,0x62,0x01,0x0b,0xe7,0x51,0x0b,0xc5,0xaf,0x1d,0x8b,0xcf,0x05,0xb5,0x06,0xcd,0xab,0x5a,0xef,0x61,0xb0,0x6b,0x2c,0x31,0xbf,0xb7,0x0c,0x60,0x27,0xaa,0x47,0x1f,0x22,0xce,0x42,0xe4,0x4c,0x61,0xb6,0x28,0x39,0x05,0x4c,0xcc,0x9d,0x19,0x6e,0x03,0xbe,0x1c,0xdc,0xa4,0xb4,0x3f,0x66,0x06,0x8e,0x1c,0x69,0x47,0x1d,0xb3,0x24,0xc3,0xf8,0x15,0xc0,0xed,0x1e,0x54,0x2a,0x7c,0x3f,0x69,0x7c,0x7e,0xfe,0xa4,0x11,0xd6,0x78,0xa2,0x4e,0x13,0x66,0xaf,0xf0,0x94,0xa0,0xdd,0x14,0x5d,0x58,0x5b,0x54},
+ {0x0f,0x3a,0xd4,0xa0,0x5e,0x27,0xbf,0x67,0xbe,0xee,0x9b,0x08,0x34,0x8e,0xe6,0xad,0x2e,0xe7,0x79,0xd4,0x4c,0x13,0x89,0x42,0x54,0x54,0xba,0x32,0xc3,0xf9,0x62,0x0f,0xe1,0x21,0xb3,0xe3,0xd0,0xe4,0x04,0x62,0x95,0x1e,0xff,0x28,0x7a,0x63,0xaa,0x3b,0x9e,0xbd,0x99,0x5b,0xfd,0xcf,0x0c,0x0b,0x71,0xd0,0xc8,0x64,0x3e,0xdc,0x22,0x4d,0x39,0x5f,0x3b,0xd6,0x89,0x65,0xb4,0xfc,0x61,0xcf,0xcb,0x57,0x3f,0x6a,0xae,0x5c,0x05,0xfa,0x3a,0x95,0xd2,0xc2,0xba,0xfe,0x36,0x14,0x37,0x36,0x1a,0xa0,0x0f,0x1c},
+ {0xff,0x3d,0x94,0x22,0xb6,0x04,0xc6,0xd2,0xa0,0xb3,0xcf,0x44,0xce,0xbe,0x8c,0xbc,0x78,0x86,0x80,0x97,0xf3,0x4f,0x25,0x5d,0xbf,0xa6,0x1c,0x3b,0x4f,0x61,0xa3,0x0f,0x50,0x6a,0x93,0x8c,0x0e,0x2b,0x08,0x69,0xb6,0xc5,0xda,0xc1,0x35,0xa0,0xc9,0xf9,0x34,0xb6,0xdf,0xc4,0x54,0x3e,0xb7,0x6f,0x40,0xc1,0x2b,0x1d,0x9b,0x41,0x05,0x40,0xf0,0x82,0xbe,0xb9,0xbd,0xfe,0x03,0xa0,0x90,0xac,0x44,0x3a,0xaf,0xc1,0x89,0x20,0x8e,0xfa,0x54,0x19,0x91,0x9f,0x49,0xf8,0x42,0xab,0x40,0xef,0x8a,0x21,0xba,0x1f},
+ {0x3e,0xf5,0xc8,0xfa,0x48,0x94,0x54,0xab,0x41,0x37,0xa6,0x7b,0x9a,0xe8,0xf6,0x81,0x01,0x5e,0x2b,0x6c,0x7d,0x6c,0xfd,0x74,0x42,0x6e,0xc8,0xa8,0xca,0x3a,0x2e,0x39,0x94,0x01,0x7b,0x3e,0x04,0x57,0x3e,0x4f,0x7f,0xaf,0xda,0x08,0xee,0x3e,0x1d,0xa8,0xf1,0xde,0xdc,0x99,0xab,0xc6,0x39,0xc8,0xd5,0x61,0x77,0xff,0x13,0x5d,0x53,0x6c,0xaf,0x35,0x8a,0x3e,0xe9,0x34,0xbd,0x4c,0x16,0xe8,0x87,0x58,0x44,0x81,0x07,0x2e,0xab,0xb0,0x9a,0xf2,0x76,0x9c,0x31,0x19,0x3b,0xc1,0x0a,0xd5,0xe4,0x7f,0xe1,0x25},
+ {0x76,0xf6,0x04,0x1e,0xd7,0x9b,0x28,0x0a,0x95,0x0f,0x42,0xd6,0x52,0x1c,0x8e,0x20,0xab,0x1f,0x69,0x34,0xb0,0xd8,0x86,0x51,0x51,0xb3,0x9f,0x2a,0x44,0x51,0x57,0x25,0xa7,0x21,0xf1,0x76,0xf5,0x7f,0x5f,0x91,0xe3,0x87,0xcd,0x2f,0x27,0x32,0x4a,0xc3,0x26,0xe5,0x1b,0x4d,0xde,0x2f,0xba,0xcc,0x9b,0x89,0x69,0x89,0x8f,0x82,0xba,0x6b,0x01,0x39,0xfe,0x90,0x66,0xbc,0xd1,0xe2,0xd5,0x7a,0x99,0xa0,0x18,0x4a,0xb5,0x4c,0xd4,0x60,0x84,0xaf,0x14,0x69,0x1d,0x97,0xe4,0x7b,0x6b,0x7f,0x4f,0x50,0x9d,0x55},
+ {0xd5,0x54,0xeb,0xb3,0x78,0x83,0x73,0xa7,0x7c,0x3c,0x55,0xa5,0x66,0xd3,0x69,0x1d,0xba,0x00,0x28,0xf9,0x62,0xcf,0x26,0x0a,0x17,0x32,0x7e,0x80,0xd5,0x12,0xab,0x01,0xfd,0x66,0xd2,0xf6,0xe7,0x91,0x48,0x9c,0x1b,0x78,0x07,0x03,0x9b,0xa1,0x44,0x07,0x3b,0xe2,0x61,0x60,0x1d,0x8f,0x38,0x88,0x0e,0xd5,0x4b,0x35,0xa3,0xa6,0x3e,0x12,0x96,0x2d,0xe3,0x41,0x90,0x18,0x8d,0x11,0x48,0x58,0x31,0xd8,0xc2,0xe3,0xed,0xb9,0xd9,0x45,0x32,0xd8,0x71,0x42,0xab,0x1e,0x54,0xa1,0x18,0xc9,0xe2,0x61,0x39,0x4a},
+ {0xa0,0xbb,0xe6,0xf8,0xe0,0x3b,0xdc,0x71,0x0a,0xe3,0xff,0x7e,0x34,0xf8,0xce,0xd6,0x6a,0x47,0x3a,0xe1,0x5f,0x42,0x92,0xa9,0x63,0xb7,0x1d,0xfb,0xe3,0xbc,0xd6,0x2c,0x1e,0x3f,0x23,0xf3,0x44,0xd6,0x27,0x03,0x16,0xf0,0xfc,0x34,0x0e,0x26,0x9a,0x49,0x79,0xb9,0xda,0xf2,0x16,0xa7,0xb5,0x83,0x1f,0x11,0xd4,0x9b,0xad,0xee,0xac,0x68,0x10,0xc2,0xd7,0xf3,0x0e,0xc9,0xb4,0x38,0x0c,0x04,0xad,0xb7,0x24,0x6e,0x8e,0x30,0x23,0x3e,0xe7,0xb7,0xf1,0xd9,0x60,0x38,0x97,0xf5,0x08,0xb5,0xd5,0x60,0x57,0x59},
+ {0x97,0x63,0xaa,0x04,0xe1,0xbf,0x29,0x61,0xcb,0xfc,0xa7,0xa4,0x08,0x00,0x96,0x8f,0x58,0x94,0x90,0x7d,0x89,0xc0,0x8b,0x3f,0xa9,0x91,0xb2,0xdc,0x3e,0xa4,0x9f,0x70,0x90,0x27,0x02,0xfd,0xeb,0xcb,0x2a,0x88,0x60,0x57,0x11,0xc4,0x05,0x33,0xaf,0x89,0xf4,0x73,0x34,0x7d,0xe3,0x92,0xf4,0x65,0x2b,0x5a,0x51,0x54,0xdf,0xc5,0xb2,0x2c,0xca,0x2a,0xfd,0x63,0x8c,0x5d,0x0a,0xeb,0xff,0x4e,0x69,0x2e,0x66,0xc1,0x2b,0xd2,0x3a,0xb0,0xcb,0xf8,0x6e,0xf3,0x23,0x27,0x1f,0x13,0xc8,0xf0,0xec,0x29,0xf0,0x70},
+ {0x33,0x3e,0xed,0x2e,0xb3,0x07,0x13,0x46,0xe7,0x81,0x55,0xa4,0x33,0x2f,0x04,0xae,0x66,0x03,0x5f,0x19,0xd3,0x49,0x44,0xc9,0x58,0x48,0x31,0x6c,0x8a,0x5d,0x7d,0x0b,0xb9,0xb0,0x10,0x5e,0xaa,0xaf,0x6a,0x2a,0xa9,0x1a,0x04,0xef,0x70,0xa3,0xf0,0x78,0x1f,0xd6,0x3a,0xaa,0x77,0xfb,0x3e,0x77,0xe1,0xd9,0x4b,0xa7,0xa2,0xa5,0xec,0x44,0x43,0xd5,0x95,0x7b,0x32,0x48,0xd4,0x25,0x1d,0x0f,0x34,0xa3,0x00,0x83,0xd3,0x70,0x2b,0xc5,0xe1,0x60,0x1c,0x53,0x1c,0xde,0xe4,0xe9,0x7d,0x2c,0x51,0x24,0x22,0x27},
+ {0x2e,0x34,0xc5,0x49,0xaf,0x92,0xbc,0x1a,0xd0,0xfa,0xe6,0xb2,0x11,0xd8,0xee,0xff,0x29,0x4e,0xc8,0xfc,0x8d,0x8c,0xa2,0xef,0x43,0xc5,0x4c,0xa4,0x18,0xdf,0xb5,0x11,0xfc,0x75,0xa9,0x42,0x8a,0xbb,0x7b,0xbf,0x58,0xa3,0xad,0x96,0x77,0x39,0x5c,0x8c,0x48,0xaa,0xed,0xcd,0x6f,0xc7,0x7f,0xe2,0xa6,0x20,0xbc,0xf6,0xd7,0x5f,0x73,0x19,0x66,0x42,0xc8,0x42,0xd0,0x90,0xab,0xe3,0x7e,0x54,0x19,0x7f,0x0f,0x8e,0x84,0xeb,0xb9,0x97,0xa4,0x65,0xd0,0xa1,0x03,0x25,0x5f,0x89,0xdf,0x91,0x11,0x91,0xef,0x0f}
+};
diff --git a/lib/Utils.Cryptography/monocypher/vendor/tests/externals/ed25519-donna/ed25519-donna-batchverify.h b/lib/Utils.Cryptography/monocypher/vendor/tests/externals/ed25519-donna/ed25519-donna-batchverify.h
new file mode 100644
index 0000000..43c4923
--- /dev/null
+++ b/lib/Utils.Cryptography/monocypher/vendor/tests/externals/ed25519-donna/ed25519-donna-batchverify.h
@@ -0,0 +1,275 @@
+/*
+ Ed25519 batch verification
+*/
+
+#define max_batch_size 64
+#define heap_batch_size ((max_batch_size * 2) + 1)
+
+/* which limb is the 128th bit in? */
+static const size_t limb128bits = (128 + bignum256modm_bits_per_limb - 1) / bignum256modm_bits_per_limb;
+
+typedef size_t heap_index_t;
+
+typedef struct batch_heap_t {
+ unsigned char r[heap_batch_size][16]; /* 128 bit random values */
+ ge25519 points[heap_batch_size];
+ bignum256modm scalars[heap_batch_size];
+ heap_index_t heap[heap_batch_size];
+ size_t size;
+} batch_heap;
+
+/* swap two values in the heap */
+static void
+heap_swap(heap_index_t *heap, size_t a, size_t b) {
+ heap_index_t temp;
+ temp = heap[a];
+ heap[a] = heap[b];
+ heap[b] = temp;
+}
+
+/* add the scalar at the end of the list to the heap */
+static void
+heap_insert_next(batch_heap *heap) {
+ size_t node = heap->size, parent;
+ heap_index_t *pheap = heap->heap;
+ bignum256modm *scalars = heap->scalars;
+
+ /* insert at the bottom */
+ pheap[node] = (heap_index_t)node;
+
+ /* sift node up to its sorted spot */
+ parent = (node - 1) / 2;
+ while (node && lt256_modm_batch(scalars[pheap[parent]], scalars[pheap[node]], bignum256modm_limb_size - 1)) {
+ heap_swap(pheap, parent, node);
+ node = parent;
+ parent = (node - 1) / 2;
+ }
+ heap->size++;
+}
+
+/* update the heap when the root element is updated */
+static void
+heap_updated_root(batch_heap *heap, size_t limbsize) {
+ size_t node, parent, childr, childl;
+ heap_index_t *pheap = heap->heap;
+ bignum256modm *scalars = heap->scalars;
+
+ /* sift root to the bottom */
+ parent = 0;
+ node = 1;
+ childl = 1;
+ childr = 2;
+ while ((childr < heap->size)) {
+ node = lt256_modm_batch(scalars[pheap[childl]], scalars[pheap[childr]], limbsize) ? childr : childl;
+ heap_swap(pheap, parent, node);
+ parent = node;
+ childl = (parent * 2) + 1;
+ childr = childl + 1;
+ }
+
+ /* sift root back up to its sorted spot */
+ parent = (node - 1) / 2;
+ while (node && lte256_modm_batch(scalars[pheap[parent]], scalars[pheap[node]], limbsize)) {
+ heap_swap(pheap, parent, node);
+ node = parent;
+ parent = (node - 1) / 2;
+ }
+}
+
+/* build the heap with count elements, count must be >= 3 */
+static void
+heap_build(batch_heap *heap, size_t count) {
+ heap->heap[0] = 0;
+ heap->size = 0;
+ while (heap->size < count)
+ heap_insert_next(heap);
+}
+
+/* extend the heap to contain new_count elements */
+static void
+heap_extend(batch_heap *heap, size_t new_count) {
+ while (heap->size < new_count)
+ heap_insert_next(heap);
+}
+
+/* get the top 2 elements of the heap */
+static void
+heap_get_top2(batch_heap *heap, heap_index_t *max1, heap_index_t *max2, size_t limbsize) {
+ heap_index_t h0 = heap->heap[0], h1 = heap->heap[1], h2 = heap->heap[2];
+ if (lt256_modm_batch(heap->scalars[h1], heap->scalars[h2], limbsize))
+ h1 = h2;
+ *max1 = h0;
+ *max2 = h1;
+}
+
+/* */
+static void
+ge25519_multi_scalarmult_vartime_final(ge25519 *r, ge25519 *point, bignum256modm scalar) {
+ const bignum256modm_element_t topbit = ((bignum256modm_element_t)1 << (bignum256modm_bits_per_limb - 1));
+ size_t limb = limb128bits;
+ bignum256modm_element_t flag;
+
+ if (isone256_modm_batch(scalar)) {
+ /* this will happen most of the time after bos-carter */
+ *r = *point;
+ return;
+ } else if (iszero256_modm_batch(scalar)) {
+ /* this will only happen if all scalars == 0 */
+ memset(r, 0, sizeof(*r));
+ r->y[0] = 1;
+ r->z[0] = 1;
+ return;
+ }
+
+ *r = *point;
+
+ /* find the limb where first bit is set */
+ while (!scalar[limb])
+ limb--;
+
+ /* find the first bit */
+ flag = topbit;
+ while ((scalar[limb] & flag) == 0)
+ flag >>= 1;
+
+ /* exponentiate */
+ for (;;) {
+ ge25519_double(r, r);
+ if (scalar[limb] & flag)
+ ge25519_add(r, r, point);
+
+ flag >>= 1;
+ if (!flag) {
+ if (!limb--)
+ break;
+ flag = topbit;
+ }
+ }
+}
+
+/* count must be >= 5 */
+static void
+ge25519_multi_scalarmult_vartime(ge25519 *r, batch_heap *heap, size_t count) {
+ heap_index_t max1, max2;
+
+ /* start with the full limb size */
+ size_t limbsize = bignum256modm_limb_size - 1;
+
+ /* whether the heap has been extended to include the 128 bit scalars */
+ int extended = 0;
+
+ /* grab an odd number of scalars to build the heap, unknown limb sizes */
+ heap_build(heap, ((count + 1) / 2) | 1);
+
+ for (;;) {
+ heap_get_top2(heap, &max1, &max2, limbsize);
+
+ /* only one scalar remaining, we're done */
+ if (iszero256_modm_batch(heap->scalars[max2]))
+ break;
+
+ /* exhausted another limb? */
+ if (!heap->scalars[max1][limbsize])
+ limbsize -= 1;
+
+ /* can we extend to the 128 bit scalars? */
+ if (!extended && isatmost128bits256_modm_batch(heap->scalars[max1])) {
+ heap_extend(heap, count);
+ heap_get_top2(heap, &max1, &max2, limbsize);
+ extended = 1;
+ }
+
+ sub256_modm_batch(heap->scalars[max1], heap->scalars[max1], heap->scalars[max2], limbsize);
+ ge25519_add(&heap->points[max2], &heap->points[max2], &heap->points[max1]);
+ heap_updated_root(heap, limbsize);
+ }
+
+ ge25519_multi_scalarmult_vartime_final(r, &heap->points[max1], heap->scalars[max1]);
+}
+
+/* not actually used for anything other than testing */
+unsigned char batch_point_buffer[3][32];
+
+static int
+ge25519_is_neutral_vartime(const ge25519 *p) {
+ static const unsigned char zero[32] = {0};
+ unsigned char point_buffer[3][32];
+ curve25519_contract(point_buffer[0], p->x);
+ curve25519_contract(point_buffer[1], p->y);
+ curve25519_contract(point_buffer[2], p->z);
+ memcpy(batch_point_buffer[1], point_buffer[1], 32);
+ return (memcmp(point_buffer[0], zero, 32) == 0) && (memcmp(point_buffer[1], point_buffer[2], 32) == 0);
+}
+
+int
+ED25519_FN(ed25519_sign_open_batch) (const unsigned char **m, size_t *mlen, const unsigned char **pk, const unsigned char **RS, size_t num, int *valid) {
+ batch_heap ALIGN(16) batch;
+ ge25519 ALIGN(16) p;
+ bignum256modm *r_scalars;
+ size_t i, batchsize;
+ unsigned char hram[64];
+ int ret = 0;
+
+ for (i = 0; i < num; i++)
+ valid[i] = 1;
+
+ while (num > 3) {
+ batchsize = (num > max_batch_size) ? max_batch_size : num;
+
+ /* generate r (scalars[batchsize+1]..scalars[2*batchsize] */
+ ED25519_FN(ed25519_randombytes_unsafe) (batch.r, batchsize * 16);
+ r_scalars = &batch.scalars[batchsize + 1];
+ for (i = 0; i < batchsize; i++)
+ expand256_modm(r_scalars[i], batch.r[i], 16);
+
+ /* compute scalars[0] = ((r1s1 + r2s2 + ...)) */
+ for (i = 0; i < batchsize; i++) {
+ expand256_modm(batch.scalars[i], RS[i] + 32, 32);
+ mul256_modm(batch.scalars[i], batch.scalars[i], r_scalars[i]);
+ }
+ for (i = 1; i < batchsize; i++)
+ add256_modm(batch.scalars[0], batch.scalars[0], batch.scalars[i]);
+
+ /* compute scalars[1]..scalars[batchsize] as r[i]*H(R[i],A[i],m[i]) */
+ for (i = 0; i < batchsize; i++) {
+ ed25519_hram(hram, RS[i], pk[i], m[i], mlen[i]);
+ expand256_modm(batch.scalars[i+1], hram, 64);
+ mul256_modm(batch.scalars[i+1], batch.scalars[i+1], r_scalars[i]);
+ }
+
+ /* compute points */
+ batch.points[0] = ge25519_basepoint;
+ for (i = 0; i < batchsize; i++)
+ if (!ge25519_unpack_negative_vartime(&batch.points[i+1], pk[i]))
+ goto fallback;
+ for (i = 0; i < batchsize; i++)
+ if (!ge25519_unpack_negative_vartime(&batch.points[batchsize+i+1], RS[i]))
+ goto fallback;
+
+ ge25519_multi_scalarmult_vartime(&p, &batch, (batchsize * 2) + 1);
+ if (!ge25519_is_neutral_vartime(&p)) {
+ ret |= 2;
+
+ fallback:
+ for (i = 0; i < batchsize; i++) {
+ valid[i] = ED25519_FN(ed25519_sign_open) (m[i], mlen[i], pk[i], RS[i]) ? 0 : 1;
+ ret |= (valid[i] ^ 1);
+ }
+ }
+
+ m += batchsize;
+ mlen += batchsize;
+ pk += batchsize;
+ RS += batchsize;
+ num -= batchsize;
+ valid += batchsize;
+ }
+
+ for (i = 0; i < num; i++) {
+ valid[i] = ED25519_FN(ed25519_sign_open) (m[i], mlen[i], pk[i], RS[i]) ? 0 : 1;
+ ret |= (valid[i] ^ 1);
+ }
+
+ return ret;
+}
+
diff --git a/lib/Utils.Cryptography/monocypher/vendor/tests/externals/ed25519-donna/ed25519-donna-impl-base.h b/lib/Utils.Cryptography/monocypher/vendor/tests/externals/ed25519-donna/ed25519-donna-impl-base.h
new file mode 100644
index 0000000..48913ed
--- /dev/null
+++ b/lib/Utils.Cryptography/monocypher/vendor/tests/externals/ed25519-donna/ed25519-donna-impl-base.h
@@ -0,0 +1,364 @@
+/*
+ conversions
+*/
+
+DONNA_INLINE static void
+ge25519_p1p1_to_partial(ge25519 *r, const ge25519_p1p1 *p) {
+ curve25519_mul(r->x, p->x, p->t);
+ curve25519_mul(r->y, p->y, p->z);
+ curve25519_mul(r->z, p->z, p->t);
+}
+
+DONNA_INLINE static void
+ge25519_p1p1_to_full(ge25519 *r, const ge25519_p1p1 *p) {
+ curve25519_mul(r->x, p->x, p->t);
+ curve25519_mul(r->y, p->y, p->z);
+ curve25519_mul(r->z, p->z, p->t);
+ curve25519_mul(r->t, p->x, p->y);
+}
+
+static void
+ge25519_full_to_pniels(ge25519_pniels *p, const ge25519 *r) {
+ curve25519_sub(p->ysubx, r->y, r->x);
+ curve25519_add(p->xaddy, r->y, r->x);
+ curve25519_copy(p->z, r->z);
+ curve25519_mul(p->t2d, r->t, ge25519_ec2d);
+}
+
+/*
+ adding & doubling
+*/
+
+static void
+ge25519_add_p1p1(ge25519_p1p1 *r, const ge25519 *p, const ge25519 *q) {
+ bignum25519 a,b,c,d,t,u;
+
+ curve25519_sub(a, p->y, p->x);
+ curve25519_add(b, p->y, p->x);
+ curve25519_sub(t, q->y, q->x);
+ curve25519_add(u, q->y, q->x);
+ curve25519_mul(a, a, t);
+ curve25519_mul(b, b, u);
+ curve25519_mul(c, p->t, q->t);
+ curve25519_mul(c, c, ge25519_ec2d);
+ curve25519_mul(d, p->z, q->z);
+ curve25519_add(d, d, d);
+ curve25519_sub(r->x, b, a);
+ curve25519_add(r->y, b, a);
+ curve25519_add_after_basic(r->z, d, c);
+ curve25519_sub_after_basic(r->t, d, c);
+}
+
+
+static void
+ge25519_double_p1p1(ge25519_p1p1 *r, const ge25519 *p) {
+ bignum25519 a,b,c;
+
+ curve25519_square(a, p->x);
+ curve25519_square(b, p->y);
+ curve25519_square(c, p->z);
+ curve25519_add_reduce(c, c, c);
+ curve25519_add(r->x, p->x, p->y);
+ curve25519_square(r->x, r->x);
+ curve25519_add(r->y, b, a);
+ curve25519_sub(r->z, b, a);
+ curve25519_sub_after_basic(r->x, r->x, r->y);
+ curve25519_sub_after_basic(r->t, c, r->z);
+}
+
+static void
+ge25519_nielsadd2_p1p1(ge25519_p1p1 *r, const ge25519 *p, const ge25519_niels *q, unsigned char signbit) {
+ const bignum25519 *qb = (const bignum25519 *)q;
+ bignum25519 *rb = (bignum25519 *)r;
+ bignum25519 a,b,c;
+
+ curve25519_sub(a, p->y, p->x);
+ curve25519_add(b, p->y, p->x);
+ curve25519_mul(a, a, qb[signbit]); /* x for +, y for - */
+ curve25519_mul(r->x, b, qb[signbit^1]); /* y for +, x for - */
+ curve25519_add(r->y, r->x, a);
+ curve25519_sub(r->x, r->x, a);
+ curve25519_mul(c, p->t, q->t2d);
+ curve25519_add_reduce(r->t, p->z, p->z);
+ curve25519_copy(r->z, r->t);
+ curve25519_add(rb[2+signbit], rb[2+signbit], c); /* z for +, t for - */
+ curve25519_sub(rb[2+(signbit^1)], rb[2+(signbit^1)], c); /* t for +, z for - */
+}
+
+static void
+ge25519_pnielsadd_p1p1(ge25519_p1p1 *r, const ge25519 *p, const ge25519_pniels *q, unsigned char signbit) {
+ const bignum25519 *qb = (const bignum25519 *)q;
+ bignum25519 *rb = (bignum25519 *)r;
+ bignum25519 a,b,c;
+
+ curve25519_sub(a, p->y, p->x);
+ curve25519_add(b, p->y, p->x);
+ curve25519_mul(a, a, qb[signbit]); /* ysubx for +, xaddy for - */
+ curve25519_mul(r->x, b, qb[signbit^1]); /* xaddy for +, ysubx for - */
+ curve25519_add(r->y, r->x, a);
+ curve25519_sub(r->x, r->x, a);
+ curve25519_mul(c, p->t, q->t2d);
+ curve25519_mul(r->t, p->z, q->z);
+ curve25519_add_reduce(r->t, r->t, r->t);
+ curve25519_copy(r->z, r->t);
+ curve25519_add(rb[2+signbit], rb[2+signbit], c); /* z for +, t for - */
+ curve25519_sub(rb[2+(signbit^1)], rb[2+(signbit^1)], c); /* t for +, z for - */
+}
+
+static void
+ge25519_double_partial(ge25519 *r, const ge25519 *p) {
+ ge25519_p1p1 t;
+ ge25519_double_p1p1(&t, p);
+ ge25519_p1p1_to_partial(r, &t);
+}
+
+static void
+ge25519_double(ge25519 *r, const ge25519 *p) {
+ ge25519_p1p1 t;
+ ge25519_double_p1p1(&t, p);
+ ge25519_p1p1_to_full(r, &t);
+}
+
+static void
+ge25519_add(ge25519 *r, const ge25519 *p, const ge25519 *q) {
+ ge25519_p1p1 t;
+ ge25519_add_p1p1(&t, p, q);
+ ge25519_p1p1_to_full(r, &t);
+}
+
+static void
+ge25519_nielsadd2(ge25519 *r, const ge25519_niels *q) {
+ bignum25519 a,b,c,e,f,g,h;
+
+ curve25519_sub(a, r->y, r->x);
+ curve25519_add(b, r->y, r->x);
+ curve25519_mul(a, a, q->ysubx);
+ curve25519_mul(e, b, q->xaddy);
+ curve25519_add(h, e, a);
+ curve25519_sub(e, e, a);
+ curve25519_mul(c, r->t, q->t2d);
+ curve25519_add(f, r->z, r->z);
+ curve25519_add_after_basic(g, f, c);
+ curve25519_sub_after_basic(f, f, c);
+ curve25519_mul(r->x, e, f);
+ curve25519_mul(r->y, h, g);
+ curve25519_mul(r->z, g, f);
+ curve25519_mul(r->t, e, h);
+}
+
+static void
+ge25519_pnielsadd(ge25519_pniels *r, const ge25519 *p, const ge25519_pniels *q) {
+ bignum25519 a,b,c,x,y,z,t;
+
+ curve25519_sub(a, p->y, p->x);
+ curve25519_add(b, p->y, p->x);
+ curve25519_mul(a, a, q->ysubx);
+ curve25519_mul(x, b, q->xaddy);
+ curve25519_add(y, x, a);
+ curve25519_sub(x, x, a);
+ curve25519_mul(c, p->t, q->t2d);
+ curve25519_mul(t, p->z, q->z);
+ curve25519_add(t, t, t);
+ curve25519_add_after_basic(z, t, c);
+ curve25519_sub_after_basic(t, t, c);
+ curve25519_mul(r->xaddy, x, t);
+ curve25519_mul(r->ysubx, y, z);
+ curve25519_mul(r->z, z, t);
+ curve25519_mul(r->t2d, x, y);
+ curve25519_copy(y, r->ysubx);
+ curve25519_sub(r->ysubx, r->ysubx, r->xaddy);
+ curve25519_add(r->xaddy, r->xaddy, y);
+ curve25519_mul(r->t2d, r->t2d, ge25519_ec2d);
+}
+
+
+/*
+ pack & unpack
+*/
+
+static void
+ge25519_pack(unsigned char r[32], const ge25519 *p) {
+ bignum25519 tx, ty, zi;
+ unsigned char parity[32];
+ curve25519_recip(zi, p->z);
+ curve25519_mul(tx, p->x, zi);
+ curve25519_mul(ty, p->y, zi);
+ curve25519_contract(r, ty);
+ curve25519_contract(parity, tx);
+ r[31] ^= ((parity[0] & 1) << 7);
+}
+
+static int
+ge25519_unpack_negative_vartime(ge25519 *r, const unsigned char p[32]) {
+ static const unsigned char zero[32] = {0};
+ static const bignum25519 one = {1};
+ unsigned char parity = p[31] >> 7;
+ unsigned char check[32];
+ bignum25519 t, root, num, den, d3;
+
+ curve25519_expand(r->y, p);
+ curve25519_copy(r->z, one);
+ curve25519_square(num, r->y); /* x = y^2 */
+ curve25519_mul(den, num, ge25519_ecd); /* den = dy^2 */
+ curve25519_sub_reduce(num, num, r->z); /* x = y^1 - 1 */
+ curve25519_add(den, den, r->z); /* den = dy^2 + 1 */
+
+ /* Computation of sqrt(num/den) */
+ /* 1.: computation of num^((p-5)/8)*den^((7p-35)/8) = (num*den^7)^((p-5)/8) */
+ curve25519_square(t, den);
+ curve25519_mul(d3, t, den);
+ curve25519_square(r->x, d3);
+ curve25519_mul(r->x, r->x, den);
+ curve25519_mul(r->x, r->x, num);
+ curve25519_pow_two252m3(r->x, r->x);
+
+ /* 2. computation of r->x = num * den^3 * (num*den^7)^((p-5)/8) */
+ curve25519_mul(r->x, r->x, d3);
+ curve25519_mul(r->x, r->x, num);
+
+ /* 3. Check if either of the roots works: */
+ curve25519_square(t, r->x);
+ curve25519_mul(t, t, den);
+ curve25519_sub_reduce(root, t, num);
+ curve25519_contract(check, root);
+ if (!ed25519_verify(check, zero, 32)) {
+ curve25519_add_reduce(t, t, num);
+ curve25519_contract(check, t);
+ if (!ed25519_verify(check, zero, 32))
+ return 0;
+ curve25519_mul(r->x, r->x, ge25519_sqrtneg1);
+ }
+
+ curve25519_contract(check, r->x);
+ if ((check[0] & 1) == parity) {
+ curve25519_copy(t, r->x);
+ curve25519_neg(r->x, t);
+ }
+ curve25519_mul(r->t, r->x, r->y);
+ return 1;
+}
+
+
+/*
+ scalarmults
+*/
+
+#define S1_SWINDOWSIZE 5
+#define S1_TABLE_SIZE (1<<(S1_SWINDOWSIZE-2))
+#define S2_SWINDOWSIZE 7
+#define S2_TABLE_SIZE (1<<(S2_SWINDOWSIZE-2))
+
+/* computes [s1]p1 + [s2]basepoint */
+static void
+ge25519_double_scalarmult_vartime(ge25519 *r, const ge25519 *p1, const bignum256modm s1, const bignum256modm s2) {
+ signed char slide1[256], slide2[256];
+ ge25519_pniels pre1[S1_TABLE_SIZE];
+ ge25519 d1;
+ ge25519_p1p1 t;
+ int32_t i;
+
+ contract256_slidingwindow_modm(slide1, s1, S1_SWINDOWSIZE);
+ contract256_slidingwindow_modm(slide2, s2, S2_SWINDOWSIZE);
+
+ ge25519_double(&d1, p1);
+ ge25519_full_to_pniels(pre1, p1);
+ for (i = 0; i < S1_TABLE_SIZE - 1; i++)
+ ge25519_pnielsadd(&pre1[i+1], &d1, &pre1[i]);
+
+ /* set neutral */
+ memset(r, 0, sizeof(ge25519));
+ r->y[0] = 1;
+ r->z[0] = 1;
+
+ i = 255;
+ while ((i >= 0) && !(slide1[i] | slide2[i]))
+ i--;
+
+ for (; i >= 0; i--) {
+ ge25519_double_p1p1(&t, r);
+
+ if (slide1[i]) {
+ ge25519_p1p1_to_full(r, &t);
+ ge25519_pnielsadd_p1p1(&t, r, &pre1[abs(slide1[i]) / 2], (unsigned char)slide1[i] >> 7);
+ }
+
+ if (slide2[i]) {
+ ge25519_p1p1_to_full(r, &t);
+ ge25519_nielsadd2_p1p1(&t, r, &ge25519_niels_sliding_multiples[abs(slide2[i]) / 2], (unsigned char)slide2[i] >> 7);
+ }
+
+ ge25519_p1p1_to_partial(r, &t);
+ }
+}
+
+
+
+#if !defined(HAVE_GE25519_SCALARMULT_BASE_CHOOSE_NIELS)
+
+static uint32_t
+ge25519_windowb_equal(uint32_t b, uint32_t c) {
+ return ((b ^ c) - 1) >> 31;
+}
+
+static void
+ge25519_scalarmult_base_choose_niels(ge25519_niels *t, const uint8_t table[256][96], uint32_t pos, signed char b) {
+ bignum25519 neg;
+ uint32_t sign = (uint32_t)((unsigned char)b >> 7);
+ uint32_t mask = ~(sign - 1);
+ uint32_t u = (b + mask) ^ mask;
+ uint32_t i;
+
+ /* ysubx, xaddy, t2d in packed form. initialize to ysubx = 1, xaddy = 1, t2d = 0 */
+ uint8_t packed[96] = {0};
+ packed[0] = 1;
+ packed[32] = 1;
+
+ for (i = 0; i < 8; i++)
+ curve25519_move_conditional_bytes(packed, table[(pos * 8) + i], ge25519_windowb_equal(u, i + 1));
+
+ /* expand in to t */
+ curve25519_expand(t->ysubx, packed + 0);
+ curve25519_expand(t->xaddy, packed + 32);
+ curve25519_expand(t->t2d , packed + 64);
+
+ /* adjust for sign */
+ curve25519_swap_conditional(t->ysubx, t->xaddy, sign);
+ curve25519_neg(neg, t->t2d);
+ curve25519_swap_conditional(t->t2d, neg, sign);
+}
+
+#endif /* HAVE_GE25519_SCALARMULT_BASE_CHOOSE_NIELS */
+
+
+/* computes [s]basepoint */
+static void
+ge25519_scalarmult_base_niels(ge25519 *r, const uint8_t basepoint_table[256][96], const bignum256modm s) {
+ signed char b[64];
+ uint32_t i;
+ ge25519_niels t;
+
+ contract256_window4_modm(b, s);
+
+ ge25519_scalarmult_base_choose_niels(&t, basepoint_table, 0, b[1]);
+ curve25519_sub_reduce(r->x, t.xaddy, t.ysubx);
+ curve25519_add_reduce(r->y, t.xaddy, t.ysubx);
+ memset(r->z, 0, sizeof(bignum25519));
+ curve25519_copy(r->t, t.t2d);
+ r->z[0] = 2;
+ for (i = 3; i < 64; i += 2) {
+ ge25519_scalarmult_base_choose_niels(&t, basepoint_table, i / 2, b[i]);
+ ge25519_nielsadd2(r, &t);
+ }
+ ge25519_double_partial(r, r);
+ ge25519_double_partial(r, r);
+ ge25519_double_partial(r, r);
+ ge25519_double(r, r);
+ ge25519_scalarmult_base_choose_niels(&t, basepoint_table, 0, b[0]);
+ curve25519_mul(t.t2d, t.t2d, ge25519_ecd);
+ ge25519_nielsadd2(r, &t);
+ for(i = 2; i < 64; i += 2) {
+ ge25519_scalarmult_base_choose_niels(&t, basepoint_table, i / 2, b[i]);
+ ge25519_nielsadd2(r, &t);
+ }
+}
+
diff --git a/lib/Utils.Cryptography/monocypher/vendor/tests/externals/ed25519-donna/ed25519-donna-portable-identify.h b/lib/Utils.Cryptography/monocypher/vendor/tests/externals/ed25519-donna/ed25519-donna-portable-identify.h
new file mode 100644
index 0000000..26a264c
--- /dev/null
+++ b/lib/Utils.Cryptography/monocypher/vendor/tests/externals/ed25519-donna/ed25519-donna-portable-identify.h
@@ -0,0 +1,103 @@
+/* os */
+#if defined(_WIN32) || defined(_WIN64) || defined(__TOS_WIN__) || defined(__WINDOWS__)
+ #define OS_WINDOWS
+#elif defined(sun) || defined(__sun) || defined(__SVR4) || defined(__svr4__)
+ #define OS_SOLARIS
+#else
+ #include <sys/param.h> /* need this to define BSD */
+ #define OS_NIX
+ #if defined(__linux__)
+ #define OS_LINUX
+ #elif defined(BSD)
+ #define OS_BSD
+ #if defined(MACOS_X) || (defined(__APPLE__) & defined(__MACH__))
+ #define OS_OSX
+ #elif defined(macintosh) || defined(Macintosh)
+ #define OS_MAC
+ #elif defined(__OpenBSD__)
+ #define OS_OPENBSD
+ #endif
+ #endif
+#endif
+
+
+/* compiler */
+#if defined(_MSC_VER)
+ #define COMPILER_MSVC
+#endif
+#if defined(__ICC)
+ #define COMPILER_INTEL
+#endif
+#if defined(__GNUC__)
+ #if (__GNUC__ >= 3)
+ #define COMPILER_GCC ((__GNUC__ * 10000) + (__GNUC_MINOR__ * 100) + (__GNUC_PATCHLEVEL__))
+ #else
+ #define COMPILER_GCC ((__GNUC__ * 10000) + (__GNUC_MINOR__ * 100) )
+ #endif
+#endif
+#if defined(__PATHCC__)
+ #define COMPILER_PATHCC
+#endif
+#if defined(__clang__)
+ #define COMPILER_CLANG ((__clang_major__ * 10000) + (__clang_minor__ * 100) + (__clang_patchlevel__))
+#endif
+
+
+
+/* cpu */
+#if defined(__amd64__) || defined(__amd64) || defined(__x86_64__ ) || defined(_M_X64)
+ #define CPU_X86_64
+#elif defined(__i586__) || defined(__i686__) || (defined(_M_IX86) && (_M_IX86 >= 500))
+ #define CPU_X86 500
+#elif defined(__i486__) || (defined(_M_IX86) && (_M_IX86 >= 400))
+ #define CPU_X86 400
+#elif defined(__i386__) || (defined(_M_IX86) && (_M_IX86 >= 300)) || defined(__X86__) || defined(_X86_) || defined(__I86__)
+ #define CPU_X86 300
+#elif defined(__ia64__) || defined(_IA64) || defined(__IA64__) || defined(_M_IA64) || defined(__ia64)
+ #define CPU_IA64
+#endif
+
+#if defined(__sparc__) || defined(__sparc) || defined(__sparcv9)
+ #define CPU_SPARC
+ #if defined(__sparcv9)
+ #define CPU_SPARC64
+ #endif
+#endif
+
+#if defined(powerpc) || defined(__PPC__) || defined(__ppc__) || defined(_ARCH_PPC) || defined(__powerpc__) || defined(__powerpc) || defined(POWERPC) || defined(_M_PPC)
+ #define CPU_PPC
+ #if defined(_ARCH_PWR7)
+ #define CPU_POWER7
+ #elif defined(__64BIT__)
+ #define CPU_PPC64
+ #else
+ #define CPU_PPC32
+ #endif
+#endif
+
+#if defined(__hppa__) || defined(__hppa)
+ #define CPU_HPPA
+#endif
+
+#if defined(__alpha__) || defined(__alpha) || defined(_M_ALPHA)
+ #define CPU_ALPHA
+#endif
+
+/* 64 bit cpu */
+#if defined(CPU_X86_64) || defined(CPU_IA64) || defined(CPU_SPARC64) || defined(__64BIT__) || defined(__LP64__) || defined(_LP64) || (defined(_MIPS_SZLONG) && (_MIPS_SZLONG == 64))
+ #define CPU_64BITS
+#endif
+
+#if defined(COMPILER_MSVC)
+ typedef signed char int8_t;
+ typedef unsigned char uint8_t;
+ typedef signed short int16_t;
+ typedef unsigned short uint16_t;
+ typedef signed int int32_t;
+ typedef unsigned int uint32_t;
+ typedef signed __int64 int64_t;
+ typedef unsigned __int64 uint64_t;
+#else
+ #include <stdint.h>
+#endif
+
diff --git a/lib/Utils.Cryptography/monocypher/vendor/tests/externals/ed25519-donna/ed25519-donna-portable.h b/lib/Utils.Cryptography/monocypher/vendor/tests/externals/ed25519-donna/ed25519-donna-portable.h
new file mode 100644
index 0000000..0a0f7fc
--- /dev/null
+++ b/lib/Utils.Cryptography/monocypher/vendor/tests/externals/ed25519-donna/ed25519-donna-portable.h
@@ -0,0 +1,135 @@
+#include "ed25519-donna-portable-identify.h"
+
+#define mul32x32_64(a,b) (((uint64_t)(a))*(b))
+
+/* platform */
+#if defined(COMPILER_MSVC)
+ #include <intrin.h>
+ #if !defined(_DEBUG)
+ #undef mul32x32_64
+ #define mul32x32_64(a,b) __emulu(a,b)
+ #endif
+ #undef inline
+ #define inline __forceinline
+ #define DONNA_INLINE __forceinline
+ #define DONNA_NOINLINE __declspec(noinline)
+ #define ALIGN(x) __declspec(align(x))
+ #define ROTL32(a,b) _rotl(a,b)
+ #define ROTR32(a,b) _rotr(a,b)
+#else
+ #include <sys/param.h>
+ #define DONNA_INLINE inline __attribute__((always_inline))
+ #define DONNA_NOINLINE __attribute__((noinline))
+ #define ALIGN(x) __attribute__((aligned(x)))
+ #define ROTL32(a,b) (((a) << (b)) | ((a) >> (32 - b)))
+ #define ROTR32(a,b) (((a) >> (b)) | ((a) << (32 - b)))
+#endif
+
+/* uint128_t */
+#if defined(CPU_64BITS) && !defined(ED25519_FORCE_32BIT)
+ #if defined(COMPILER_CLANG) && (COMPILER_CLANG >= 30100)
+ #define HAVE_NATIVE_UINT128
+ typedef unsigned __int128 uint128_t;
+ #elif defined(COMPILER_MSVC)
+ #define HAVE_UINT128
+ typedef struct uint128_t {
+ uint64_t lo, hi;
+ } uint128_t;
+ #define mul64x64_128(out,a,b) out.lo = _umul128(a,b,&out.hi);
+ #define shr128_pair(out,hi,lo,shift) out = __shiftright128(lo, hi, shift);
+ #define shl128_pair(out,hi,lo,shift) out = __shiftleft128(lo, hi, shift);
+ #define shr128(out,in,shift) shr128_pair(out, in.hi, in.lo, shift)
+ #define shl128(out,in,shift) shl128_pair(out, in.hi, in.lo, shift)
+ #define add128(a,b) { uint64_t p = a.lo; a.lo += b.lo; a.hi += b.hi + (a.lo < p); }
+ #define add128_64(a,b) { uint64_t p = a.lo; a.lo += b; a.hi += (a.lo < p); }
+ #define lo128(a) (a.lo)
+ #define hi128(a) (a.hi)
+ #elif defined(COMPILER_GCC) && !defined(HAVE_NATIVE_UINT128)
+ #if defined(__SIZEOF_INT128__)
+ #define HAVE_NATIVE_UINT128
+ typedef unsigned __int128 uint128_t;
+ #elif (COMPILER_GCC >= 40400)
+ #define HAVE_NATIVE_UINT128
+ typedef unsigned uint128_t __attribute__((mode(TI)));
+ #elif defined(CPU_X86_64)
+ #define HAVE_UINT128
+ typedef struct uint128_t {
+ uint64_t lo, hi;
+ } uint128_t;
+ #define mul64x64_128(out,a,b) __asm__ ("mulq %3" : "=a" (out.lo), "=d" (out.hi) : "a" (a), "rm" (b));
+ #define shr128_pair(out,hi,lo,shift) __asm__ ("shrdq %2,%1,%0" : "+r" (lo) : "r" (hi), "J" (shift)); out = lo;
+ #define shl128_pair(out,hi,lo,shift) __asm__ ("shldq %2,%1,%0" : "+r" (hi) : "r" (lo), "J" (shift)); out = hi;
+ #define shr128(out,in,shift) shr128_pair(out,in.hi, in.lo, shift)
+ #define shl128(out,in,shift) shl128_pair(out,in.hi, in.lo, shift)
+ #define add128(a,b) __asm__ ("addq %4,%2; adcq %5,%3" : "=r" (a.hi), "=r" (a.lo) : "1" (a.lo), "0" (a.hi), "rm" (b.lo), "rm" (b.hi) : "cc");
+ #define add128_64(a,b) __asm__ ("addq %4,%2; adcq $0,%3" : "=r" (a.hi), "=r" (a.lo) : "1" (a.lo), "0" (a.hi), "rm" (b) : "cc");
+ #define lo128(a) (a.lo)
+ #define hi128(a) (a.hi)
+ #endif
+ #endif
+
+ #if defined(HAVE_NATIVE_UINT128)
+ #define HAVE_UINT128
+ #define mul64x64_128(out,a,b) out = (uint128_t)a * b;
+ #define shr128_pair(out,hi,lo,shift) out = (uint64_t)((((uint128_t)hi << 64) | lo) >> (shift));
+ #define shl128_pair(out,hi,lo,shift) out = (uint64_t)(((((uint128_t)hi << 64) | lo) << (shift)) >> 64);
+ #define shr128(out,in,shift) out = (uint64_t)(in >> (shift));
+ #define shl128(out,in,shift) out = (uint64_t)((in << shift) >> 64);
+ #define add128(a,b) a += b;
+ #define add128_64(a,b) a += (uint64_t)b;
+ #define lo128(a) ((uint64_t)a)
+ #define hi128(a) ((uint64_t)(a >> 64))
+ #endif
+
+ #if !defined(HAVE_UINT128)
+ #error Need a uint128_t implementation!
+ #endif
+#endif
+
+/* endian */
+#if !defined(ED25519_OPENSSLRNG)
+static inline void U32TO8_LE(unsigned char *p, const uint32_t v) {
+ p[0] = (unsigned char)(v );
+ p[1] = (unsigned char)(v >> 8);
+ p[2] = (unsigned char)(v >> 16);
+ p[3] = (unsigned char)(v >> 24);
+}
+#endif
+
+#if !defined(HAVE_UINT128)
+static inline uint32_t U8TO32_LE(const unsigned char *p) {
+ return
+ (((uint32_t)(p[0]) ) |
+ ((uint32_t)(p[1]) << 8) |
+ ((uint32_t)(p[2]) << 16) |
+ ((uint32_t)(p[3]) << 24));
+}
+#else
+static inline uint64_t U8TO64_LE(const unsigned char *p) {
+ return
+ (((uint64_t)(p[0]) ) |
+ ((uint64_t)(p[1]) << 8) |
+ ((uint64_t)(p[2]) << 16) |
+ ((uint64_t)(p[3]) << 24) |
+ ((uint64_t)(p[4]) << 32) |
+ ((uint64_t)(p[5]) << 40) |
+ ((uint64_t)(p[6]) << 48) |
+ ((uint64_t)(p[7]) << 56));
+}
+
+static inline void U64TO8_LE(unsigned char *p, const uint64_t v) {
+ p[0] = (unsigned char)(v );
+ p[1] = (unsigned char)(v >> 8);
+ p[2] = (unsigned char)(v >> 16);
+ p[3] = (unsigned char)(v >> 24);
+ p[4] = (unsigned char)(v >> 32);
+ p[5] = (unsigned char)(v >> 40);
+ p[6] = (unsigned char)(v >> 48);
+ p[7] = (unsigned char)(v >> 56);
+}
+#endif
+
+#include <stdlib.h>
+#include <string.h>
+
+
diff --git a/lib/Utils.Cryptography/monocypher/vendor/tests/externals/ed25519-donna/ed25519-donna.h b/lib/Utils.Cryptography/monocypher/vendor/tests/externals/ed25519-donna/ed25519-donna.h
new file mode 100644
index 0000000..fa95a09
--- /dev/null
+++ b/lib/Utils.Cryptography/monocypher/vendor/tests/externals/ed25519-donna/ed25519-donna.h
@@ -0,0 +1,117 @@
+/*
+ Public domain by Andrew M. <liquidsun@gmail.com>
+ Modified from the amd64-51-30k implementation by
+ Daniel J. Bernstein
+ Niels Duif
+ Tanja Lange
+ Peter Schwabe
+ Bo-Yin Yang
+*/
+
+
+#include "ed25519-donna-portable.h"
+
+#if defined(ED25519_SSE2)
+#else
+ #if defined(HAVE_UINT128) && !defined(ED25519_FORCE_32BIT)
+ #define ED25519_64BIT
+ #else
+ #define ED25519_32BIT
+ #endif
+#endif
+
+#if !defined(ED25519_NO_INLINE_ASM)
+ /* detect extra features first so un-needed functions can be disabled throughout */
+ #if defined(ED25519_SSE2)
+ #if defined(COMPILER_GCC) && defined(CPU_X86)
+ #define ED25519_GCC_32BIT_SSE_CHOOSE
+ #elif defined(COMPILER_GCC) && defined(CPU_X86_64)
+ #define ED25519_GCC_64BIT_SSE_CHOOSE
+ #endif
+ #else
+ #if defined(CPU_X86_64)
+ #if defined(COMPILER_GCC)
+ #if defined(ED25519_64BIT)
+ #define ED25519_GCC_64BIT_X86_CHOOSE
+ #else
+ #define ED25519_GCC_64BIT_32BIT_CHOOSE
+ #endif
+ #endif
+ #endif
+ #endif
+#endif
+
+#if defined(ED25519_SSE2)
+ #include "curve25519-donna-sse2.h"
+#elif defined(ED25519_64BIT)
+ #include "curve25519-donna-64bit.h"
+#else
+ #include "curve25519-donna-32bit.h"
+#endif
+
+#include "curve25519-donna-helpers.h"
+
+/* separate uint128 check for 64 bit sse2 */
+#if defined(HAVE_UINT128) && !defined(ED25519_FORCE_32BIT)
+ #include "modm-donna-64bit.h"
+#else
+ #include "modm-donna-32bit.h"
+#endif
+
+typedef unsigned char hash_512bits[64];
+
+/*
+ Timing safe memory compare
+*/
+static int
+ed25519_verify(const unsigned char *x, const unsigned char *y, size_t len) {
+ size_t differentbits = 0;
+ while (len--)
+ differentbits |= (*x++ ^ *y++);
+ return (int) (1 & ((differentbits - 1) >> 8));
+}
+
+
+/*
+ * Arithmetic on the twisted Edwards curve -x^2 + y^2 = 1 + dx^2y^2
+ * with d = -(121665/121666) = 37095705934669439343138083508754565189542113879843219016388785533085940283555
+ * Base point: (15112221349535400772501151409588531511454012693041857206046113283949847762202,46316835694926478169428394003475163141307993866256225615783033603165251855960);
+ */
+
+typedef struct ge25519_t {
+ bignum25519 x, y, z, t;
+} ge25519;
+
+typedef struct ge25519_p1p1_t {
+ bignum25519 x, y, z, t;
+} ge25519_p1p1;
+
+typedef struct ge25519_niels_t {
+ bignum25519 ysubx, xaddy, t2d;
+} ge25519_niels;
+
+typedef struct ge25519_pniels_t {
+ bignum25519 ysubx, xaddy, z, t2d;
+} ge25519_pniels;
+
+#include "ed25519-donna-basepoint-table.h"
+
+#if defined(ED25519_64BIT)
+ #include "ed25519-donna-64bit-tables.h"
+ #include "ed25519-donna-64bit-x86.h"
+#else
+ #include "ed25519-donna-32bit-tables.h"
+ #if defined(ED25519_GCC_64BIT_32BIT_CHOOSE)
+ #include "ed25519-donna-64bit-x86-32bit.h"
+ #endif
+#endif
+
+
+#if defined(ED25519_SSE2)
+ #include "ed25519-donna-32bit-sse2.h"
+ #include "ed25519-donna-64bit-sse2.h"
+ #include "ed25519-donna-impl-sse2.h"
+#else
+ #include "ed25519-donna-impl-base.h"
+#endif
+
diff --git a/lib/Utils.Cryptography/monocypher/vendor/tests/externals/ed25519-donna/ed25519-hash-custom.h b/lib/Utils.Cryptography/monocypher/vendor/tests/externals/ed25519-donna/ed25519-hash-custom.h
new file mode 100644
index 0000000..94a0076
--- /dev/null
+++ b/lib/Utils.Cryptography/monocypher/vendor/tests/externals/ed25519-donna/ed25519-hash-custom.h
@@ -0,0 +1,23 @@
+#include <sodium.h>
+
+typedef crypto_generichash_state ed25519_hash_context;
+
+void ed25519_hash_init(ed25519_hash_context *ctx)
+{
+ crypto_generichash_init(ctx, 0, 0, 64);
+}
+
+void ed25519_hash_update(ed25519_hash_context *ctx, const uint8_t *in, size_t inlen)
+{
+ crypto_generichash_update(ctx, in, inlen);
+}
+
+void ed25519_hash_final(ed25519_hash_context *ctx, uint8_t *hash)
+{
+ crypto_generichash_final(ctx, hash, 64);
+}
+
+void ed25519_hash(uint8_t *hash, const uint8_t *in, size_t inlen)
+{
+ crypto_generichash(hash, 64, in, inlen, 0, 0);
+}
diff --git a/lib/Utils.Cryptography/monocypher/vendor/tests/externals/ed25519-donna/ed25519-hash.h b/lib/Utils.Cryptography/monocypher/vendor/tests/externals/ed25519-donna/ed25519-hash.h
new file mode 100644
index 0000000..6ba8f52
--- /dev/null
+++ b/lib/Utils.Cryptography/monocypher/vendor/tests/externals/ed25519-donna/ed25519-hash.h
@@ -0,0 +1,219 @@
+#if defined(ED25519_REFHASH)
+
+/* reference/slow SHA-512. really, do not use this */
+
+#define HASH_BLOCK_SIZE 128
+#define HASH_DIGEST_SIZE 64
+
+typedef struct sha512_state_t {
+ uint64_t H[8];
+ uint64_t T[2];
+ uint32_t leftover;
+ uint8_t buffer[HASH_BLOCK_SIZE];
+} sha512_state;
+
+typedef sha512_state ed25519_hash_context;
+
+static const uint64_t sha512_constants[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
+};
+
+static uint64_t
+sha512_ROTR64(uint64_t x, int k) {
+ return (x >> k) | (x << (64 - k));
+}
+
+static uint64_t
+sha512_LOAD64_BE(const uint8_t *p) {
+ return
+ ((uint64_t)p[0] << 56) |
+ ((uint64_t)p[1] << 48) |
+ ((uint64_t)p[2] << 40) |
+ ((uint64_t)p[3] << 32) |
+ ((uint64_t)p[4] << 24) |
+ ((uint64_t)p[5] << 16) |
+ ((uint64_t)p[6] << 8) |
+ ((uint64_t)p[7] );
+}
+
+static void
+sha512_STORE64_BE(uint8_t *p, uint64_t v) {
+ p[0] = (uint8_t)(v >> 56);
+ p[1] = (uint8_t)(v >> 48);
+ p[2] = (uint8_t)(v >> 40);
+ p[3] = (uint8_t)(v >> 32);
+ p[4] = (uint8_t)(v >> 24);
+ p[5] = (uint8_t)(v >> 16);
+ p[6] = (uint8_t)(v >> 8);
+ p[7] = (uint8_t)(v );
+}
+
+#define Ch(x,y,z) (z ^ (x & (y ^ z)))
+#define Maj(x,y,z) (((x | y) & z) | (x & y))
+#define S0(x) (sha512_ROTR64(x, 28) ^ sha512_ROTR64(x, 34) ^ sha512_ROTR64(x, 39))
+#define S1(x) (sha512_ROTR64(x, 14) ^ sha512_ROTR64(x, 18) ^ sha512_ROTR64(x, 41))
+#define G0(x) (sha512_ROTR64(x, 1) ^ sha512_ROTR64(x, 8) ^ (x >> 7))
+#define G1(x) (sha512_ROTR64(x, 19) ^ sha512_ROTR64(x, 61) ^ (x >> 6))
+#define W0(in,i) (sha512_LOAD64_BE(&in[i * 8]))
+#define W1(i) (G1(w[i - 2]) + w[i - 7] + G0(w[i - 15]) + w[i - 16])
+#define STEP(i) \
+ t1 = S0(r[0]) + Maj(r[0], r[1], r[2]); \
+ t0 = r[7] + S1(r[4]) + Ch(r[4], r[5], r[6]) + sha512_constants[i] + w[i]; \
+ r[7] = r[6]; \
+ r[6] = r[5]; \
+ r[5] = r[4]; \
+ r[4] = r[3] + t0; \
+ r[3] = r[2]; \
+ r[2] = r[1]; \
+ r[1] = r[0]; \
+ r[0] = t0 + t1;
+
+static void
+sha512_blocks(sha512_state *S, const uint8_t *in, size_t blocks) {
+ uint64_t r[8], w[80], t0, t1;
+ size_t i;
+
+ for (i = 0; i < 8; i++) r[i] = S->H[i];
+
+ while (blocks--) {
+ for (i = 0; i < 16; i++) { w[i] = W0(in, i); }
+ for (i = 16; i < 80; i++) { w[i] = W1(i); }
+ for (i = 0; i < 80; i++) { STEP(i); }
+ for (i = 0; i < 8; i++) { r[i] += S->H[i]; S->H[i] = r[i]; }
+ S->T[0] += HASH_BLOCK_SIZE * 8;
+ S->T[1] += (!S->T[0]) ? 1 : 0;
+ in += HASH_BLOCK_SIZE;
+ }
+}
+
+static void
+ed25519_hash_init(sha512_state *S) {
+ S->H[0] = 0x6a09e667f3bcc908ull;
+ S->H[1] = 0xbb67ae8584caa73bull;
+ S->H[2] = 0x3c6ef372fe94f82bull;
+ S->H[3] = 0xa54ff53a5f1d36f1ull;
+ S->H[4] = 0x510e527fade682d1ull;
+ S->H[5] = 0x9b05688c2b3e6c1full;
+ S->H[6] = 0x1f83d9abfb41bd6bull;
+ S->H[7] = 0x5be0cd19137e2179ull;
+ S->T[0] = 0;
+ S->T[1] = 0;
+ S->leftover = 0;
+}
+
+static void
+ed25519_hash_update(sha512_state *S, const uint8_t *in, size_t inlen) {
+ size_t blocks, want;
+
+ /* handle the previous data */
+ if (S->leftover) {
+ want = (HASH_BLOCK_SIZE - S->leftover);
+ want = (want < inlen) ? want : inlen;
+ memcpy(S->buffer + S->leftover, in, want);
+ S->leftover += (uint32_t)want;
+ if (S->leftover < HASH_BLOCK_SIZE)
+ return;
+ in += want;
+ inlen -= want;
+ sha512_blocks(S, S->buffer, 1);
+ }
+
+ /* handle the current data */
+ blocks = (inlen & ~(HASH_BLOCK_SIZE - 1));
+ S->leftover = (uint32_t)(inlen - blocks);
+ if (blocks) {
+ sha512_blocks(S, in, blocks / HASH_BLOCK_SIZE);
+ in += blocks;
+ }
+
+ /* handle leftover data */
+ if (S->leftover)
+ memcpy(S->buffer, in, S->leftover);
+}
+
+static void
+ed25519_hash_final(sha512_state *S, uint8_t *hash) {
+ uint64_t t0 = S->T[0] + (S->leftover * 8), t1 = S->T[1];
+
+ S->buffer[S->leftover] = 0x80;
+ if (S->leftover <= 111) {
+ memset(S->buffer + S->leftover + 1, 0, 111 - S->leftover);
+ } else {
+ memset(S->buffer + S->leftover + 1, 0, 127 - S->leftover);
+ sha512_blocks(S, S->buffer, 1);
+ memset(S->buffer, 0, 112);
+ }
+
+ sha512_STORE64_BE(S->buffer + 112, t1);
+ sha512_STORE64_BE(S->buffer + 120, t0);
+ sha512_blocks(S, S->buffer, 1);
+
+ sha512_STORE64_BE(&hash[ 0], S->H[0]);
+ sha512_STORE64_BE(&hash[ 8], S->H[1]);
+ sha512_STORE64_BE(&hash[16], S->H[2]);
+ sha512_STORE64_BE(&hash[24], S->H[3]);
+ sha512_STORE64_BE(&hash[32], S->H[4]);
+ sha512_STORE64_BE(&hash[40], S->H[5]);
+ sha512_STORE64_BE(&hash[48], S->H[6]);
+ sha512_STORE64_BE(&hash[56], S->H[7]);
+}
+
+static void
+ed25519_hash(uint8_t *hash, const uint8_t *in, size_t inlen) {
+ ed25519_hash_context ctx;
+ ed25519_hash_init(&ctx);
+ ed25519_hash_update(&ctx, in, inlen);
+ ed25519_hash_final(&ctx, hash);
+}
+
+#elif defined(ED25519_CUSTOMHASH)
+
+#include "ed25519-hash-custom.h"
+
+#else
+
+#include <openssl/sha.h>
+
+typedef SHA512_CTX ed25519_hash_context;
+
+static void
+ed25519_hash_init(ed25519_hash_context *ctx) {
+ SHA512_Init(ctx);
+}
+
+static void
+ed25519_hash_update(ed25519_hash_context *ctx, const uint8_t *in, size_t inlen) {
+ SHA512_Update(ctx, in, inlen);
+}
+
+static void
+ed25519_hash_final(ed25519_hash_context *ctx, uint8_t *hash) {
+ SHA512_Final(hash, ctx);
+}
+
+static void
+ed25519_hash(uint8_t *hash, const uint8_t *in, size_t inlen) {
+ SHA512(in, inlen, hash);
+}
+
+#endif
+
diff --git a/lib/Utils.Cryptography/monocypher/vendor/tests/externals/ed25519-donna/ed25519-randombytes.h b/lib/Utils.Cryptography/monocypher/vendor/tests/externals/ed25519-donna/ed25519-randombytes.h
new file mode 100644
index 0000000..1dc6290
--- /dev/null
+++ b/lib/Utils.Cryptography/monocypher/vendor/tests/externals/ed25519-donna/ed25519-randombytes.h
@@ -0,0 +1,91 @@
+#if defined(ED25519_TEST)
+/*
+ ISAAC+ "variant", the paper is not clear on operator precedence and other
+ things. This is the "first in, first out" option!
+
+ Not threadsafe or securely initialized, only for deterministic testing
+*/
+typedef struct isaacp_state_t {
+ uint32_t state[256];
+ unsigned char buffer[1024];
+ uint32_t a, b, c;
+ size_t left;
+} isaacp_state;
+
+#define isaacp_step(offset, mix) \
+ x = mm[i + offset]; \
+ a = (a ^ (mix)) + (mm[(i + offset + 128) & 0xff]); \
+ y = (a ^ b) + mm[(x >> 2) & 0xff]; \
+ mm[i + offset] = y; \
+ b = (x + a) ^ mm[(y >> 10) & 0xff]; \
+ U32TO8_LE(out + (i + offset) * 4, b);
+
+static void
+isaacp_mix(isaacp_state *st) {
+ uint32_t i, x, y;
+ uint32_t a = st->a, b = st->b, c = st->c;
+ uint32_t *mm = st->state;
+ unsigned char *out = st->buffer;
+
+ c = c + 1;
+ b = b + c;
+
+ for (i = 0; i < 256; i += 4) {
+ isaacp_step(0, ROTL32(a,13))
+ isaacp_step(1, ROTR32(a, 6))
+ isaacp_step(2, ROTL32(a, 2))
+ isaacp_step(3, ROTR32(a,16))
+ }
+
+ st->a = a;
+ st->b = b;
+ st->c = c;
+ st->left = 1024;
+}
+
+static void
+isaacp_random(isaacp_state *st, void *p, size_t len) {
+ size_t use;
+ unsigned char *c = (unsigned char *)p;
+ while (len) {
+ use = (len > st->left) ? st->left : len;
+ memcpy(c, st->buffer + (sizeof(st->buffer) - st->left), use);
+
+ st->left -= use;
+ c += use;
+ len -= use;
+
+ if (!st->left)
+ isaacp_mix(st);
+ }
+}
+
+void
+ED25519_FN(ed25519_randombytes_unsafe) (void *p, size_t len) {
+ static int initialized = 0;
+ static isaacp_state rng;
+
+ if (!initialized) {
+ memset(&rng, 0, sizeof(rng));
+ isaacp_mix(&rng);
+ isaacp_mix(&rng);
+ initialized = 1;
+ }
+
+ isaacp_random(&rng, p, len);
+}
+#elif defined(ED25519_CUSTOMRANDOM)
+
+#include "ed25519-randombytes-custom.h"
+
+#else
+
+#include <openssl/rand.h>
+
+void
+ED25519_FN(ed25519_randombytes_unsafe) (void *p, size_t len) {
+
+ RAND_bytes(p, (int) len);
+
+}
+#endif
diff --git a/lib/Utils.Cryptography/monocypher/vendor/tests/externals/ed25519-donna/ed25519.c b/lib/Utils.Cryptography/monocypher/vendor/tests/externals/ed25519-donna/ed25519.c
new file mode 100644
index 0000000..58a755b
--- /dev/null
+++ b/lib/Utils.Cryptography/monocypher/vendor/tests/externals/ed25519-donna/ed25519.c
@@ -0,0 +1,150 @@
+/*
+ Public domain by Andrew M. <liquidsun@gmail.com>
+
+ Ed25519 reference implementation using Ed25519-donna
+*/
+
+
+/* define ED25519_SUFFIX to have it appended to the end of each public function */
+#if !defined(ED25519_SUFFIX)
+#define ED25519_SUFFIX
+#endif
+
+#define ED25519_FN3(fn,suffix) fn##suffix
+#define ED25519_FN2(fn,suffix) ED25519_FN3(fn,suffix)
+#define ED25519_FN(fn) ED25519_FN2(fn,ED25519_SUFFIX)
+
+#include "ed25519-donna.h"
+#include "ed25519.h"
+#include "ed25519-randombytes.h"
+#include "ed25519-hash.h"
+
+/*
+ Generates a (extsk[0..31]) and aExt (extsk[32..63])
+*/
+
+DONNA_INLINE static void
+ed25519_extsk(hash_512bits extsk, const ed25519_secret_key sk) {
+ ed25519_hash(extsk, sk, 32);
+ extsk[0] &= 248;
+ extsk[31] &= 127;
+ extsk[31] |= 64;
+}
+
+static void
+ed25519_hram(hash_512bits hram, const ed25519_signature RS, const ed25519_public_key pk, const unsigned char *m, size_t mlen) {
+ ed25519_hash_context ctx;
+ ed25519_hash_init(&ctx);
+ ed25519_hash_update(&ctx, RS, 32);
+ ed25519_hash_update(&ctx, pk, 32);
+ ed25519_hash_update(&ctx, m, mlen);
+ ed25519_hash_final(&ctx, hram);
+}
+
+void
+ED25519_FN(ed25519_publickey) (const ed25519_secret_key sk, ed25519_public_key pk) {
+ bignum256modm a;
+ ge25519 ALIGN(16) A;
+ hash_512bits extsk;
+
+ /* A = aB */
+ ed25519_extsk(extsk, sk);
+ expand256_modm(a, extsk, 32);
+ ge25519_scalarmult_base_niels(&A, ge25519_niels_base_multiples, a);
+ ge25519_pack(pk, &A);
+}
+
+
+void
+ED25519_FN(ed25519_sign) (const unsigned char *m, size_t mlen, const ed25519_secret_key sk, const ed25519_public_key pk, ed25519_signature RS) {
+ ed25519_hash_context ctx;
+ bignum256modm r, S, a;
+ ge25519 ALIGN(16) R;
+ hash_512bits extsk, hashr, hram;
+
+ ed25519_extsk(extsk, sk);
+
+ /* r = H(aExt[32..64], m) */
+ ed25519_hash_init(&ctx);
+ ed25519_hash_update(&ctx, extsk + 32, 32);
+ ed25519_hash_update(&ctx, m, mlen);
+ ed25519_hash_final(&ctx, hashr);
+ expand256_modm(r, hashr, 64);
+
+ /* R = rB */
+ ge25519_scalarmult_base_niels(&R, ge25519_niels_base_multiples, r);
+ ge25519_pack(RS, &R);
+
+ /* S = H(R,A,m).. */
+ ed25519_hram(hram, RS, pk, m, mlen);
+ expand256_modm(S, hram, 64);
+
+ /* S = H(R,A,m)a */
+ expand256_modm(a, extsk, 32);
+ mul256_modm(S, S, a);
+
+ /* S = (r + H(R,A,m)a) */
+ add256_modm(S, S, r);
+
+ /* S = (r + H(R,A,m)a) mod L */
+ contract256_modm(RS + 32, S);
+}
+
+int
+ED25519_FN(ed25519_sign_open) (const unsigned char *m, size_t mlen, const ed25519_public_key pk, const ed25519_signature RS) {
+ ge25519 ALIGN(16) R, A;
+ hash_512bits hash;
+ bignum256modm hram, S;
+ unsigned char checkR[32];
+
+ if ((RS[63] & 224) || !ge25519_unpack_negative_vartime(&A, pk))
+ return -1;
+
+ /* hram = H(R,A,m) */
+ ed25519_hram(hash, RS, pk, m, mlen);
+ expand256_modm(hram, hash, 64);
+
+ /* S */
+ expand256_modm(S, RS + 32, 32);
+
+ /* SB - H(R,A,m)A */
+ ge25519_double_scalarmult_vartime(&R, &A, hram, S);
+ ge25519_pack(checkR, &R);
+
+ /* check that R = SB - H(R,A,m)A */
+ return ed25519_verify(RS, checkR, 32) ? 0 : -1;
+}
+
+#include "ed25519-donna-batchverify.h"
+
+/*
+ Fast Curve25519 basepoint scalar multiplication
+*/
+
+void
+ED25519_FN(curved25519_scalarmult_basepoint) (curved25519_key pk, const curved25519_key e) {
+ curved25519_key ec;
+ bignum256modm s;
+ bignum25519 ALIGN(16) yplusz, zminusy;
+ ge25519 ALIGN(16) p;
+ size_t i;
+
+ /* clamp */
+ for (i = 0; i < 32; i++) ec[i] = e[i];
+ ec[0] &= 248;
+ ec[31] &= 127;
+ ec[31] |= 64;
+
+ expand_raw256_modm(s, ec);
+
+ /* scalar * basepoint */
+ ge25519_scalarmult_base_niels(&p, ge25519_niels_base_multiples, s);
+
+ /* u = (y + z) / (z - y) */
+ curve25519_add(yplusz, p.y, p.z);
+ curve25519_sub(zminusy, p.z, p.y);
+ curve25519_recip(zminusy, zminusy);
+ curve25519_mul(yplusz, yplusz, zminusy);
+ curve25519_contract(pk, yplusz);
+}
+
diff --git a/lib/Utils.Cryptography/monocypher/vendor/tests/externals/ed25519-donna/ed25519.h b/lib/Utils.Cryptography/monocypher/vendor/tests/externals/ed25519-donna/ed25519.h
new file mode 100644
index 0000000..dc86675
--- /dev/null
+++ b/lib/Utils.Cryptography/monocypher/vendor/tests/externals/ed25519-donna/ed25519.h
@@ -0,0 +1,30 @@
+#ifndef ED25519_H
+#define ED25519_H
+
+#include <stdlib.h>
+
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+typedef unsigned char ed25519_signature[64];
+typedef unsigned char ed25519_public_key[32];
+typedef unsigned char ed25519_secret_key[32];
+
+typedef unsigned char curved25519_key[32];
+
+void ed25519_publickey(const ed25519_secret_key sk, ed25519_public_key pk);
+int ed25519_sign_open(const unsigned char *m, size_t mlen, const ed25519_public_key pk, const ed25519_signature RS);
+void ed25519_sign(const unsigned char *m, size_t mlen, const ed25519_secret_key sk, const ed25519_public_key pk, ed25519_signature RS);
+
+int ed25519_sign_open_batch(const unsigned char **m, size_t *mlen, const unsigned char **pk, const unsigned char **RS, size_t num, int *valid);
+
+void ed25519_randombytes_unsafe(void *out, size_t count);
+
+void curved25519_scalarmult_basepoint(curved25519_key pk, const curved25519_key e);
+
+#if defined(__cplusplus)
+}
+#endif
+
+#endif // ED25519_H
diff --git a/lib/Utils.Cryptography/monocypher/vendor/tests/externals/ed25519-donna/modm-donna-32bit.h b/lib/Utils.Cryptography/monocypher/vendor/tests/externals/ed25519-donna/modm-donna-32bit.h
new file mode 100644
index 0000000..62a5d3b
--- /dev/null
+++ b/lib/Utils.Cryptography/monocypher/vendor/tests/externals/ed25519-donna/modm-donna-32bit.h
@@ -0,0 +1,469 @@
+ /*
+ Public domain by Andrew M. <liquidsun@gmail.com>
+*/
+
+
+/*
+ Arithmetic modulo the group order n = 2^252 + 27742317777372353535851937790883648493 = 7237005577332262213973186563042994240857116359379907606001950938285454250989
+
+ k = 32
+ b = 1 << 8 = 256
+ m = 2^252 + 27742317777372353535851937790883648493 = 0x1000000000000000000000000000000014def9dea2f79cd65812631a5cf5d3ed
+ mu = floor( b^(k*2) / m ) = 0xfffffffffffffffffffffffffffffffeb2106215d086329a7ed9ce5a30a2c131b
+*/
+
+#define bignum256modm_bits_per_limb 30
+#define bignum256modm_limb_size 9
+
+typedef uint32_t bignum256modm_element_t;
+typedef bignum256modm_element_t bignum256modm[9];
+
+static const bignum256modm modm_m = {
+ 0x1cf5d3ed, 0x20498c69, 0x2f79cd65, 0x37be77a8,
+ 0x00000014, 0x00000000, 0x00000000, 0x00000000,
+ 0x00001000
+};
+
+static const bignum256modm modm_mu = {
+ 0x0a2c131b, 0x3673968c, 0x06329a7e, 0x01885742,
+ 0x3fffeb21, 0x3fffffff, 0x3fffffff, 0x3fffffff,
+ 0x000fffff
+};
+
+static bignum256modm_element_t
+lt_modm(bignum256modm_element_t a, bignum256modm_element_t b) {
+ return (a - b) >> 31;
+}
+
+/* see HAC, Alg. 14.42 Step 4 */
+static void
+reduce256_modm(bignum256modm r) {
+ bignum256modm t;
+ bignum256modm_element_t b = 0, pb, mask;
+
+ /* t = r - m */
+ pb = 0;
+ pb += modm_m[0]; b = lt_modm(r[0], pb); t[0] = (r[0] - pb + (b << 30)); pb = b;
+ pb += modm_m[1]; b = lt_modm(r[1], pb); t[1] = (r[1] - pb + (b << 30)); pb = b;
+ pb += modm_m[2]; b = lt_modm(r[2], pb); t[2] = (r[2] - pb + (b << 30)); pb = b;
+ pb += modm_m[3]; b = lt_modm(r[3], pb); t[3] = (r[3] - pb + (b << 30)); pb = b;
+ pb += modm_m[4]; b = lt_modm(r[4], pb); t[4] = (r[4] - pb + (b << 30)); pb = b;
+ pb += modm_m[5]; b = lt_modm(r[5], pb); t[5] = (r[5] - pb + (b << 30)); pb = b;
+ pb += modm_m[6]; b = lt_modm(r[6], pb); t[6] = (r[6] - pb + (b << 30)); pb = b;
+ pb += modm_m[7]; b = lt_modm(r[7], pb); t[7] = (r[7] - pb + (b << 30)); pb = b;
+ pb += modm_m[8]; b = lt_modm(r[8], pb); t[8] = (r[8] - pb + (b << 16));
+
+ /* keep r if r was smaller than m */
+ mask = b - 1;
+ r[0] ^= mask & (r[0] ^ t[0]);
+ r[1] ^= mask & (r[1] ^ t[1]);
+ r[2] ^= mask & (r[2] ^ t[2]);
+ r[3] ^= mask & (r[3] ^ t[3]);
+ r[4] ^= mask & (r[4] ^ t[4]);
+ r[5] ^= mask & (r[5] ^ t[5]);
+ r[6] ^= mask & (r[6] ^ t[6]);
+ r[7] ^= mask & (r[7] ^ t[7]);
+ r[8] ^= mask & (r[8] ^ t[8]);
+}
+
+/*
+ Barrett reduction, see HAC, Alg. 14.42
+
+ Instead of passing in x, pre-process in to q1 and r1 for efficiency
+*/
+static void
+barrett_reduce256_modm(bignum256modm r, const bignum256modm q1, const bignum256modm r1) {
+ bignum256modm q3, r2;
+ uint64_t c;
+ bignum256modm_element_t f, b, pb;
+
+ /* q1 = x >> 248 = 264 bits = 9 30 bit elements
+ q2 = mu * q1
+ q3 = (q2 / 256(32+1)) = q2 / (2^8)^(32+1) = q2 >> 264 */
+ c = mul32x32_64(modm_mu[0], q1[7]) + mul32x32_64(modm_mu[1], q1[6]) + mul32x32_64(modm_mu[2], q1[5]) + mul32x32_64(modm_mu[3], q1[4]) + mul32x32_64(modm_mu[4], q1[3]) + mul32x32_64(modm_mu[5], q1[2]) + mul32x32_64(modm_mu[6], q1[1]) + mul32x32_64(modm_mu[7], q1[0]);
+ c >>= 30;
+ c += mul32x32_64(modm_mu[0], q1[8]) + mul32x32_64(modm_mu[1], q1[7]) + mul32x32_64(modm_mu[2], q1[6]) + mul32x32_64(modm_mu[3], q1[5]) + mul32x32_64(modm_mu[4], q1[4]) + mul32x32_64(modm_mu[5], q1[3]) + mul32x32_64(modm_mu[6], q1[2]) + mul32x32_64(modm_mu[7], q1[1]) + mul32x32_64(modm_mu[8], q1[0]);
+ f = (bignum256modm_element_t)c; q3[0] = (f >> 24) & 0x3f; c >>= 30;
+ c += mul32x32_64(modm_mu[1], q1[8]) + mul32x32_64(modm_mu[2], q1[7]) + mul32x32_64(modm_mu[3], q1[6]) + mul32x32_64(modm_mu[4], q1[5]) + mul32x32_64(modm_mu[5], q1[4]) + mul32x32_64(modm_mu[6], q1[3]) + mul32x32_64(modm_mu[7], q1[2]) + mul32x32_64(modm_mu[8], q1[1]);
+ f = (bignum256modm_element_t)c; q3[0] |= (f << 6) & 0x3fffffff; q3[1] = (f >> 24) & 0x3f; c >>= 30;
+ c += mul32x32_64(modm_mu[2], q1[8]) + mul32x32_64(modm_mu[3], q1[7]) + mul32x32_64(modm_mu[4], q1[6]) + mul32x32_64(modm_mu[5], q1[5]) + mul32x32_64(modm_mu[6], q1[4]) + mul32x32_64(modm_mu[7], q1[3]) + mul32x32_64(modm_mu[8], q1[2]);
+ f = (bignum256modm_element_t)c; q3[1] |= (f << 6) & 0x3fffffff; q3[2] = (f >> 24) & 0x3f; c >>= 30;
+ c += mul32x32_64(modm_mu[3], q1[8]) + mul32x32_64(modm_mu[4], q1[7]) + mul32x32_64(modm_mu[5], q1[6]) + mul32x32_64(modm_mu[6], q1[5]) + mul32x32_64(modm_mu[7], q1[4]) + mul32x32_64(modm_mu[8], q1[3]);
+ f = (bignum256modm_element_t)c; q3[2] |= (f << 6) & 0x3fffffff; q3[3] = (f >> 24) & 0x3f; c >>= 30;
+ c += mul32x32_64(modm_mu[4], q1[8]) + mul32x32_64(modm_mu[5], q1[7]) + mul32x32_64(modm_mu[6], q1[6]) + mul32x32_64(modm_mu[7], q1[5]) + mul32x32_64(modm_mu[8], q1[4]);
+ f = (bignum256modm_element_t)c; q3[3] |= (f << 6) & 0x3fffffff; q3[4] = (f >> 24) & 0x3f; c >>= 30;
+ c += mul32x32_64(modm_mu[5], q1[8]) + mul32x32_64(modm_mu[6], q1[7]) + mul32x32_64(modm_mu[7], q1[6]) + mul32x32_64(modm_mu[8], q1[5]);
+ f = (bignum256modm_element_t)c; q3[4] |= (f << 6) & 0x3fffffff; q3[5] = (f >> 24) & 0x3f; c >>= 30;
+ c += mul32x32_64(modm_mu[6], q1[8]) + mul32x32_64(modm_mu[7], q1[7]) + mul32x32_64(modm_mu[8], q1[6]);
+ f = (bignum256modm_element_t)c; q3[5] |= (f << 6) & 0x3fffffff; q3[6] = (f >> 24) & 0x3f; c >>= 30;
+ c += mul32x32_64(modm_mu[7], q1[8]) + mul32x32_64(modm_mu[8], q1[7]);
+ f = (bignum256modm_element_t)c; q3[6] |= (f << 6) & 0x3fffffff; q3[7] = (f >> 24) & 0x3f; c >>= 30;
+ c += mul32x32_64(modm_mu[8], q1[8]);
+ f = (bignum256modm_element_t)c; q3[7] |= (f << 6) & 0x3fffffff; q3[8] = (bignum256modm_element_t)(c >> 24);
+
+ /* r1 = (x mod 256^(32+1)) = x mod (2^8)(31+1) = x & ((1 << 264) - 1)
+ r2 = (q3 * m) mod (256^(32+1)) = (q3 * m) & ((1 << 264) - 1) */
+ c = mul32x32_64(modm_m[0], q3[0]);
+ r2[0] = (bignum256modm_element_t)(c & 0x3fffffff); c >>= 30;
+ c += mul32x32_64(modm_m[0], q3[1]) + mul32x32_64(modm_m[1], q3[0]);
+ r2[1] = (bignum256modm_element_t)(c & 0x3fffffff); c >>= 30;
+ c += mul32x32_64(modm_m[0], q3[2]) + mul32x32_64(modm_m[1], q3[1]) + mul32x32_64(modm_m[2], q3[0]);
+ r2[2] = (bignum256modm_element_t)(c & 0x3fffffff); c >>= 30;
+ c += mul32x32_64(modm_m[0], q3[3]) + mul32x32_64(modm_m[1], q3[2]) + mul32x32_64(modm_m[2], q3[1]) + mul32x32_64(modm_m[3], q3[0]);
+ r2[3] = (bignum256modm_element_t)(c & 0x3fffffff); c >>= 30;
+ c += mul32x32_64(modm_m[0], q3[4]) + mul32x32_64(modm_m[1], q3[3]) + mul32x32_64(modm_m[2], q3[2]) + mul32x32_64(modm_m[3], q3[1]) + mul32x32_64(modm_m[4], q3[0]);
+ r2[4] = (bignum256modm_element_t)(c & 0x3fffffff); c >>= 30;
+ c += mul32x32_64(modm_m[0], q3[5]) + mul32x32_64(modm_m[1], q3[4]) + mul32x32_64(modm_m[2], q3[3]) + mul32x32_64(modm_m[3], q3[2]) + mul32x32_64(modm_m[4], q3[1]) + mul32x32_64(modm_m[5], q3[0]);
+ r2[5] = (bignum256modm_element_t)(c & 0x3fffffff); c >>= 30;
+ c += mul32x32_64(modm_m[0], q3[6]) + mul32x32_64(modm_m[1], q3[5]) + mul32x32_64(modm_m[2], q3[4]) + mul32x32_64(modm_m[3], q3[3]) + mul32x32_64(modm_m[4], q3[2]) + mul32x32_64(modm_m[5], q3[1]) + mul32x32_64(modm_m[6], q3[0]);
+ r2[6] = (bignum256modm_element_t)(c & 0x3fffffff); c >>= 30;
+ c += mul32x32_64(modm_m[0], q3[7]) + mul32x32_64(modm_m[1], q3[6]) + mul32x32_64(modm_m[2], q3[5]) + mul32x32_64(modm_m[3], q3[4]) + mul32x32_64(modm_m[4], q3[3]) + mul32x32_64(modm_m[5], q3[2]) + mul32x32_64(modm_m[6], q3[1]) + mul32x32_64(modm_m[7], q3[0]);
+ r2[7] = (bignum256modm_element_t)(c & 0x3fffffff); c >>= 30;
+ c += mul32x32_64(modm_m[0], q3[8]) + mul32x32_64(modm_m[1], q3[7]) + mul32x32_64(modm_m[2], q3[6]) + mul32x32_64(modm_m[3], q3[5]) + mul32x32_64(modm_m[4], q3[4]) + mul32x32_64(modm_m[5], q3[3]) + mul32x32_64(modm_m[6], q3[2]) + mul32x32_64(modm_m[7], q3[1]) + mul32x32_64(modm_m[8], q3[0]);
+ r2[8] = (bignum256modm_element_t)(c & 0xffffff);
+
+ /* r = r1 - r2
+ if (r < 0) r += (1 << 264) */
+ pb = 0;
+ pb += r2[0]; b = lt_modm(r1[0], pb); r[0] = (r1[0] - pb + (b << 30)); pb = b;
+ pb += r2[1]; b = lt_modm(r1[1], pb); r[1] = (r1[1] - pb + (b << 30)); pb = b;
+ pb += r2[2]; b = lt_modm(r1[2], pb); r[2] = (r1[2] - pb + (b << 30)); pb = b;
+ pb += r2[3]; b = lt_modm(r1[3], pb); r[3] = (r1[3] - pb + (b << 30)); pb = b;
+ pb += r2[4]; b = lt_modm(r1[4], pb); r[4] = (r1[4] - pb + (b << 30)); pb = b;
+ pb += r2[5]; b = lt_modm(r1[5], pb); r[5] = (r1[5] - pb + (b << 30)); pb = b;
+ pb += r2[6]; b = lt_modm(r1[6], pb); r[6] = (r1[6] - pb + (b << 30)); pb = b;
+ pb += r2[7]; b = lt_modm(r1[7], pb); r[7] = (r1[7] - pb + (b << 30)); pb = b;
+ pb += r2[8]; b = lt_modm(r1[8], pb); r[8] = (r1[8] - pb + (b << 24));
+
+ reduce256_modm(r);
+ reduce256_modm(r);
+}
+
+/* addition modulo m */
+static void
+add256_modm(bignum256modm r, const bignum256modm x, const bignum256modm y) {
+ bignum256modm_element_t c;
+
+ c = x[0] + y[0]; r[0] = c & 0x3fffffff; c >>= 30;
+ c += x[1] + y[1]; r[1] = c & 0x3fffffff; c >>= 30;
+ c += x[2] + y[2]; r[2] = c & 0x3fffffff; c >>= 30;
+ c += x[3] + y[3]; r[3] = c & 0x3fffffff; c >>= 30;
+ c += x[4] + y[4]; r[4] = c & 0x3fffffff; c >>= 30;
+ c += x[5] + y[5]; r[5] = c & 0x3fffffff; c >>= 30;
+ c += x[6] + y[6]; r[6] = c & 0x3fffffff; c >>= 30;
+ c += x[7] + y[7]; r[7] = c & 0x3fffffff; c >>= 30;
+ c += x[8] + y[8]; r[8] = c;
+
+ reduce256_modm(r);
+}
+
+/* multiplication modulo m */
+static void
+mul256_modm(bignum256modm r, const bignum256modm x, const bignum256modm y) {
+ bignum256modm r1, q1;
+ uint64_t c;
+ bignum256modm_element_t f;
+
+ /* r1 = (x mod 256^(32+1)) = x mod (2^8)(31+1) = x & ((1 << 264) - 1)
+ q1 = x >> 248 = 264 bits = 9 30 bit elements */
+ c = mul32x32_64(x[0], y[0]);
+ f = (bignum256modm_element_t)c; r1[0] = (f & 0x3fffffff); c >>= 30;
+ c += mul32x32_64(x[0], y[1]) + mul32x32_64(x[1], y[0]);
+ f = (bignum256modm_element_t)c; r1[1] = (f & 0x3fffffff); c >>= 30;
+ c += mul32x32_64(x[0], y[2]) + mul32x32_64(x[1], y[1]) + mul32x32_64(x[2], y[0]);
+ f = (bignum256modm_element_t)c; r1[2] = (f & 0x3fffffff); c >>= 30;
+ c += mul32x32_64(x[0], y[3]) + mul32x32_64(x[1], y[2]) + mul32x32_64(x[2], y[1]) + mul32x32_64(x[3], y[0]);
+ f = (bignum256modm_element_t)c; r1[3] = (f & 0x3fffffff); c >>= 30;
+ c += mul32x32_64(x[0], y[4]) + mul32x32_64(x[1], y[3]) + mul32x32_64(x[2], y[2]) + mul32x32_64(x[3], y[1]) + mul32x32_64(x[4], y[0]);
+ f = (bignum256modm_element_t)c; r1[4] = (f & 0x3fffffff); c >>= 30;
+ c += mul32x32_64(x[0], y[5]) + mul32x32_64(x[1], y[4]) + mul32x32_64(x[2], y[3]) + mul32x32_64(x[3], y[2]) + mul32x32_64(x[4], y[1]) + mul32x32_64(x[5], y[0]);
+ f = (bignum256modm_element_t)c; r1[5] = (f & 0x3fffffff); c >>= 30;
+ c += mul32x32_64(x[0], y[6]) + mul32x32_64(x[1], y[5]) + mul32x32_64(x[2], y[4]) + mul32x32_64(x[3], y[3]) + mul32x32_64(x[4], y[2]) + mul32x32_64(x[5], y[1]) + mul32x32_64(x[6], y[0]);
+ f = (bignum256modm_element_t)c; r1[6] = (f & 0x3fffffff); c >>= 30;
+ c += mul32x32_64(x[0], y[7]) + mul32x32_64(x[1], y[6]) + mul32x32_64(x[2], y[5]) + mul32x32_64(x[3], y[4]) + mul32x32_64(x[4], y[3]) + mul32x32_64(x[5], y[2]) + mul32x32_64(x[6], y[1]) + mul32x32_64(x[7], y[0]);
+ f = (bignum256modm_element_t)c; r1[7] = (f & 0x3fffffff); c >>= 30;
+ c += mul32x32_64(x[0], y[8]) + mul32x32_64(x[1], y[7]) + mul32x32_64(x[2], y[6]) + mul32x32_64(x[3], y[5]) + mul32x32_64(x[4], y[4]) + mul32x32_64(x[5], y[3]) + mul32x32_64(x[6], y[2]) + mul32x32_64(x[7], y[1]) + mul32x32_64(x[8], y[0]);
+ f = (bignum256modm_element_t)c; r1[8] = (f & 0x00ffffff); q1[0] = (f >> 8) & 0x3fffff; c >>= 30;
+ c += mul32x32_64(x[1], y[8]) + mul32x32_64(x[2], y[7]) + mul32x32_64(x[3], y[6]) + mul32x32_64(x[4], y[5]) + mul32x32_64(x[5], y[4]) + mul32x32_64(x[6], y[3]) + mul32x32_64(x[7], y[2]) + mul32x32_64(x[8], y[1]);
+ f = (bignum256modm_element_t)c; q1[0] = (q1[0] | (f << 22)) & 0x3fffffff; q1[1] = (f >> 8) & 0x3fffff; c >>= 30;
+ c += mul32x32_64(x[2], y[8]) + mul32x32_64(x[3], y[7]) + mul32x32_64(x[4], y[6]) + mul32x32_64(x[5], y[5]) + mul32x32_64(x[6], y[4]) + mul32x32_64(x[7], y[3]) + mul32x32_64(x[8], y[2]);
+ f = (bignum256modm_element_t)c; q1[1] = (q1[1] | (f << 22)) & 0x3fffffff; q1[2] = (f >> 8) & 0x3fffff; c >>= 30;
+ c += mul32x32_64(x[3], y[8]) + mul32x32_64(x[4], y[7]) + mul32x32_64(x[5], y[6]) + mul32x32_64(x[6], y[5]) + mul32x32_64(x[7], y[4]) + mul32x32_64(x[8], y[3]);
+ f = (bignum256modm_element_t)c; q1[2] = (q1[2] | (f << 22)) & 0x3fffffff; q1[3] = (f >> 8) & 0x3fffff; c >>= 30;
+ c += mul32x32_64(x[4], y[8]) + mul32x32_64(x[5], y[7]) + mul32x32_64(x[6], y[6]) + mul32x32_64(x[7], y[5]) + mul32x32_64(x[8], y[4]);
+ f = (bignum256modm_element_t)c; q1[3] = (q1[3] | (f << 22)) & 0x3fffffff; q1[4] = (f >> 8) & 0x3fffff; c >>= 30;
+ c += mul32x32_64(x[5], y[8]) + mul32x32_64(x[6], y[7]) + mul32x32_64(x[7], y[6]) + mul32x32_64(x[8], y[5]);
+ f = (bignum256modm_element_t)c; q1[4] = (q1[4] | (f << 22)) & 0x3fffffff; q1[5] = (f >> 8) & 0x3fffff; c >>= 30;
+ c += mul32x32_64(x[6], y[8]) + mul32x32_64(x[7], y[7]) + mul32x32_64(x[8], y[6]);
+ f = (bignum256modm_element_t)c; q1[5] = (q1[5] | (f << 22)) & 0x3fffffff; q1[6] = (f >> 8) & 0x3fffff; c >>= 30;
+ c += mul32x32_64(x[7], y[8]) + mul32x32_64(x[8], y[7]);
+ f = (bignum256modm_element_t)c; q1[6] = (q1[6] | (f << 22)) & 0x3fffffff; q1[7] = (f >> 8) & 0x3fffff; c >>= 30;
+ c += mul32x32_64(x[8], y[8]);
+ f = (bignum256modm_element_t)c; q1[7] = (q1[7] | (f << 22)) & 0x3fffffff; q1[8] = (f >> 8) & 0x3fffff;
+
+ barrett_reduce256_modm(r, q1, r1);
+}
+
+static void
+expand256_modm(bignum256modm out, const unsigned char *in, size_t len) {
+ unsigned char work[64] = {0};
+ bignum256modm_element_t x[16];
+ bignum256modm q1;
+
+ memcpy(work, in, len);
+ x[0] = U8TO32_LE(work + 0);
+ x[1] = U8TO32_LE(work + 4);
+ x[2] = U8TO32_LE(work + 8);
+ x[3] = U8TO32_LE(work + 12);
+ x[4] = U8TO32_LE(work + 16);
+ x[5] = U8TO32_LE(work + 20);
+ x[6] = U8TO32_LE(work + 24);
+ x[7] = U8TO32_LE(work + 28);
+ x[8] = U8TO32_LE(work + 32);
+ x[9] = U8TO32_LE(work + 36);
+ x[10] = U8TO32_LE(work + 40);
+ x[11] = U8TO32_LE(work + 44);
+ x[12] = U8TO32_LE(work + 48);
+ x[13] = U8TO32_LE(work + 52);
+ x[14] = U8TO32_LE(work + 56);
+ x[15] = U8TO32_LE(work + 60);
+
+ /* r1 = (x mod 256^(32+1)) = x mod (2^8)(31+1) = x & ((1 << 264) - 1) */
+ out[0] = ( x[0]) & 0x3fffffff;
+ out[1] = ((x[ 0] >> 30) | (x[ 1] << 2)) & 0x3fffffff;
+ out[2] = ((x[ 1] >> 28) | (x[ 2] << 4)) & 0x3fffffff;
+ out[3] = ((x[ 2] >> 26) | (x[ 3] << 6)) & 0x3fffffff;
+ out[4] = ((x[ 3] >> 24) | (x[ 4] << 8)) & 0x3fffffff;
+ out[5] = ((x[ 4] >> 22) | (x[ 5] << 10)) & 0x3fffffff;
+ out[6] = ((x[ 5] >> 20) | (x[ 6] << 12)) & 0x3fffffff;
+ out[7] = ((x[ 6] >> 18) | (x[ 7] << 14)) & 0x3fffffff;
+ out[8] = ((x[ 7] >> 16) | (x[ 8] << 16)) & 0x00ffffff;
+
+ /* 8*31 = 248 bits, no need to reduce */
+ if (len < 32)
+ return;
+
+ /* q1 = x >> 248 = 264 bits = 9 30 bit elements */
+ q1[0] = ((x[ 7] >> 24) | (x[ 8] << 8)) & 0x3fffffff;
+ q1[1] = ((x[ 8] >> 22) | (x[ 9] << 10)) & 0x3fffffff;
+ q1[2] = ((x[ 9] >> 20) | (x[10] << 12)) & 0x3fffffff;
+ q1[3] = ((x[10] >> 18) | (x[11] << 14)) & 0x3fffffff;
+ q1[4] = ((x[11] >> 16) | (x[12] << 16)) & 0x3fffffff;
+ q1[5] = ((x[12] >> 14) | (x[13] << 18)) & 0x3fffffff;
+ q1[6] = ((x[13] >> 12) | (x[14] << 20)) & 0x3fffffff;
+ q1[7] = ((x[14] >> 10) | (x[15] << 22)) & 0x3fffffff;
+ q1[8] = ((x[15] >> 8) );
+
+ barrett_reduce256_modm(out, q1, out);
+}
+
+static void
+expand_raw256_modm(bignum256modm out, const unsigned char in[32]) {
+ bignum256modm_element_t x[8];
+
+ x[0] = U8TO32_LE(in + 0);
+ x[1] = U8TO32_LE(in + 4);
+ x[2] = U8TO32_LE(in + 8);
+ x[3] = U8TO32_LE(in + 12);
+ x[4] = U8TO32_LE(in + 16);
+ x[5] = U8TO32_LE(in + 20);
+ x[6] = U8TO32_LE(in + 24);
+ x[7] = U8TO32_LE(in + 28);
+
+ out[0] = ( x[0]) & 0x3fffffff;
+ out[1] = ((x[ 0] >> 30) | (x[ 1] << 2)) & 0x3fffffff;
+ out[2] = ((x[ 1] >> 28) | (x[ 2] << 4)) & 0x3fffffff;
+ out[3] = ((x[ 2] >> 26) | (x[ 3] << 6)) & 0x3fffffff;
+ out[4] = ((x[ 3] >> 24) | (x[ 4] << 8)) & 0x3fffffff;
+ out[5] = ((x[ 4] >> 22) | (x[ 5] << 10)) & 0x3fffffff;
+ out[6] = ((x[ 5] >> 20) | (x[ 6] << 12)) & 0x3fffffff;
+ out[7] = ((x[ 6] >> 18) | (x[ 7] << 14)) & 0x3fffffff;
+ out[8] = ((x[ 7] >> 16) ) & 0x0000ffff;
+}
+
+static void
+contract256_modm(unsigned char out[32], const bignum256modm in) {
+ U32TO8_LE(out + 0, (in[0] ) | (in[1] << 30));
+ U32TO8_LE(out + 4, (in[1] >> 2) | (in[2] << 28));
+ U32TO8_LE(out + 8, (in[2] >> 4) | (in[3] << 26));
+ U32TO8_LE(out + 12, (in[3] >> 6) | (in[4] << 24));
+ U32TO8_LE(out + 16, (in[4] >> 8) | (in[5] << 22));
+ U32TO8_LE(out + 20, (in[5] >> 10) | (in[6] << 20));
+ U32TO8_LE(out + 24, (in[6] >> 12) | (in[7] << 18));
+ U32TO8_LE(out + 28, (in[7] >> 14) | (in[8] << 16));
+}
+
+
+
+static void
+contract256_window4_modm(signed char r[64], const bignum256modm in) {
+ char carry;
+ signed char *quads = r;
+ bignum256modm_element_t i, j, v;
+
+ for (i = 0; i < 8; i += 2) {
+ v = in[i];
+ for (j = 0; j < 7; j++) {
+ *quads++ = (v & 15);
+ v >>= 4;
+ }
+ v |= (in[i+1] << 2);
+ for (j = 0; j < 8; j++) {
+ *quads++ = (v & 15);
+ v >>= 4;
+ }
+ }
+ v = in[8];
+ *quads++ = (v & 15); v >>= 4;
+ *quads++ = (v & 15); v >>= 4;
+ *quads++ = (v & 15); v >>= 4;
+ *quads++ = (v & 15); v >>= 4;
+
+ /* making it signed */
+ carry = 0;
+ for(i = 0; i < 63; i++) {
+ r[i] += carry;
+ r[i+1] += (r[i] >> 4);
+ r[i] &= 15;
+ carry = (r[i] >> 3);
+ r[i] -= (carry << 4);
+ }
+ r[63] += carry;
+}
+
+static void
+contract256_slidingwindow_modm(signed char r[256], const bignum256modm s, int windowsize) {
+ int i,j,k,b;
+ int m = (1 << (windowsize - 1)) - 1, soplen = 256;
+ signed char *bits = r;
+ bignum256modm_element_t v;
+
+ /* first put the binary expansion into r */
+ for (i = 0; i < 8; i++) {
+ v = s[i];
+ for (j = 0; j < 30; j++, v >>= 1)
+ *bits++ = (v & 1);
+ }
+ v = s[8];
+ for (j = 0; j < 16; j++, v >>= 1)
+ *bits++ = (v & 1);
+
+ /* Making it sliding window */
+ for (j = 0; j < soplen; j++) {
+ if (!r[j])
+ continue;
+
+ for (b = 1; (b < (soplen - j)) && (b <= 6); b++) {
+ if ((r[j] + (r[j + b] << b)) <= m) {
+ r[j] += r[j + b] << b;
+ r[j + b] = 0;
+ } else if ((r[j] - (r[j + b] << b)) >= -m) {
+ r[j] -= r[j + b] << b;
+ for (k = j + b; k < soplen; k++) {
+ if (!r[k]) {
+ r[k] = 1;
+ break;
+ }
+ r[k] = 0;
+ }
+ } else if (r[j + b]) {
+ break;
+ }
+ }
+ }
+}
+
+
+/*
+ helpers for batch verifcation, are allowed to be vartime
+*/
+
+/* out = a - b, a must be larger than b */
+static void
+sub256_modm_batch(bignum256modm out, const bignum256modm a, const bignum256modm b, size_t limbsize) {
+ size_t i = 0;
+ bignum256modm_element_t carry = 0;
+ switch (limbsize) {
+ case 8: out[i] = (a[i] - b[i]) - carry; carry = (out[i] >> 31); out[i] &= 0x3fffffff; i++; /* FALLTHRU */
+ case 7: out[i] = (a[i] - b[i]) - carry; carry = (out[i] >> 31); out[i] &= 0x3fffffff; i++; /* FALLTHRU */
+ case 6: out[i] = (a[i] - b[i]) - carry; carry = (out[i] >> 31); out[i] &= 0x3fffffff; i++; /* FALLTHRU */
+ case 5: out[i] = (a[i] - b[i]) - carry; carry = (out[i] >> 31); out[i] &= 0x3fffffff; i++; /* FALLTHRU */
+ case 4: out[i] = (a[i] - b[i]) - carry; carry = (out[i] >> 31); out[i] &= 0x3fffffff; i++; /* FALLTHRU */
+ case 3: out[i] = (a[i] - b[i]) - carry; carry = (out[i] >> 31); out[i] &= 0x3fffffff; i++; /* FALLTHRU */
+ case 2: out[i] = (a[i] - b[i]) - carry; carry = (out[i] >> 31); out[i] &= 0x3fffffff; i++; /* FALLTHRU */
+ case 1: out[i] = (a[i] - b[i]) - carry; carry = (out[i] >> 31); out[i] &= 0x3fffffff; i++; /* FALLTHRU */
+ case 0:
+ default: out[i] = (a[i] - b[i]) - carry;
+ }
+}
+
+
+/* is a < b */
+static int
+lt256_modm_batch(const bignum256modm a, const bignum256modm b, size_t limbsize) {
+ switch (limbsize) {
+ case 8: if (a[8] > b[8]) return 0; if (a[8] < b[8]) return 1; /* FALLTHRU */
+ case 7: if (a[7] > b[7]) return 0; if (a[7] < b[7]) return 1; /* FALLTHRU */
+ case 6: if (a[6] > b[6]) return 0; if (a[6] < b[6]) return 1; /* FALLTHRU */
+ case 5: if (a[5] > b[5]) return 0; if (a[5] < b[5]) return 1; /* FALLTHRU */
+ case 4: if (a[4] > b[4]) return 0; if (a[4] < b[4]) return 1; /* FALLTHRU */
+ case 3: if (a[3] > b[3]) return 0; if (a[3] < b[3]) return 1; /* FALLTHRU */
+ case 2: if (a[2] > b[2]) return 0; if (a[2] < b[2]) return 1; /* FALLTHRU */
+ case 1: if (a[1] > b[1]) return 0; if (a[1] < b[1]) return 1; /* FALLTHRU */
+ case 0: if (a[0] > b[0]) return 0; if (a[0] < b[0]) return 1; /* FALLTHRU */
+ }
+ return 0;
+}
+
+/* is a <= b */
+static int
+lte256_modm_batch(const bignum256modm a, const bignum256modm b, size_t limbsize) {
+ switch (limbsize) {
+ case 8: if (a[8] > b[8]) return 0; if (a[8] < b[8]) return 1; /* FALLTHRU */
+ case 7: if (a[7] > b[7]) return 0; if (a[7] < b[7]) return 1; /* FALLTHRU */
+ case 6: if (a[6] > b[6]) return 0; if (a[6] < b[6]) return 1; /* FALLTHRU */
+ case 5: if (a[5] > b[5]) return 0; if (a[5] < b[5]) return 1; /* FALLTHRU */
+ case 4: if (a[4] > b[4]) return 0; if (a[4] < b[4]) return 1; /* FALLTHRU */
+ case 3: if (a[3] > b[3]) return 0; if (a[3] < b[3]) return 1; /* FALLTHRU */
+ case 2: if (a[2] > b[2]) return 0; if (a[2] < b[2]) return 1; /* FALLTHRU */
+ case 1: if (a[1] > b[1]) return 0; if (a[1] < b[1]) return 1; /* FALLTHRU */
+ case 0: if (a[0] > b[0]) return 0; if (a[0] < b[0]) return 1; /* FALLTHRU */
+ }
+ return 1;
+}
+
+
+/* is a == 0 */
+static int
+iszero256_modm_batch(const bignum256modm a) {
+ size_t i;
+ for (i = 0; i < 9; i++)
+ if (a[i])
+ return 0;
+ return 1;
+}
+
+/* is a == 1 */
+static int
+isone256_modm_batch(const bignum256modm a) {
+ size_t i;
+ if (a[0] != 1)
+ return 0;
+ for (i = 1; i < 9; i++)
+ if (a[i])
+ return 0;
+ return 1;
+}
+
+/* can a fit in to (at most) 128 bits */
+static int
+isatmost128bits256_modm_batch(const bignum256modm a) {
+ uint32_t mask =
+ ((a[8] ) | /* 16 */
+ (a[7] ) | /* 46 */
+ (a[6] ) | /* 76 */
+ (a[5] ) | /* 106 */
+ (a[4] & 0x3fffff00)); /* 128 */
+
+ return (mask == 0);
+}
diff --git a/lib/Utils.Cryptography/monocypher/vendor/tests/externals/tinyssh/LICENCE b/lib/Utils.Cryptography/monocypher/vendor/tests/externals/tinyssh/LICENCE
new file mode 100644
index 0000000..0e259d4
--- /dev/null
+++ b/lib/Utils.Cryptography/monocypher/vendor/tests/externals/tinyssh/LICENCE
@@ -0,0 +1,121 @@
+Creative Commons Legal Code
+
+CC0 1.0 Universal
+
+ CREATIVE COMMONS CORPORATION IS NOT A LAW FIRM AND DOES NOT PROVIDE
+ LEGAL SERVICES. DISTRIBUTION OF THIS DOCUMENT DOES NOT CREATE AN
+ ATTORNEY-CLIENT RELATIONSHIP. CREATIVE COMMONS PROVIDES THIS
+ INFORMATION ON AN "AS-IS" BASIS. CREATIVE COMMONS MAKES NO WARRANTIES
+ REGARDING THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS
+ PROVIDED HEREUNDER, AND DISCLAIMS LIABILITY FOR DAMAGES RESULTING FROM
+ THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS PROVIDED
+ HEREUNDER.
+
+Statement of Purpose
+
+The laws of most jurisdictions throughout the world automatically confer
+exclusive Copyright and Related Rights (defined below) upon the creator
+and subsequent owner(s) (each and all, an "owner") of an original work of
+authorship and/or a database (each, a "Work").
+
+Certain owners wish to permanently relinquish those rights to a Work for
+the purpose of contributing to a commons of creative, cultural and
+scientific works ("Commons") that the public can reliably and without fear
+of later claims of infringement build upon, modify, incorporate in other
+works, reuse and redistribute as freely as possible in any form whatsoever
+and for any purposes, including without limitation commercial purposes.
+These owners may contribute to the Commons to promote the ideal of a free
+culture and the further production of creative, cultural and scientific
+works, or to gain reputation or greater distribution for their Work in
+part through the use and efforts of others.
+
+For these and/or other purposes and motivations, and without any
+expectation of additional consideration or compensation, the person
+associating CC0 with a Work (the "Affirmer"), to the extent that he or she
+is an owner of Copyright and Related Rights in the Work, voluntarily
+elects to apply CC0 to the Work and publicly distribute the Work under its
+terms, with knowledge of his or her Copyright and Related Rights in the
+Work and the meaning and intended legal effect of CC0 on those rights.
+
+1. Copyright and Related Rights. A Work made available under CC0 may be
+protected by copyright and related or neighboring rights ("Copyright and
+Related Rights"). Copyright and Related Rights include, but are not
+limited to, the following:
+
+ i. the right to reproduce, adapt, distribute, perform, display,
+ communicate, and translate a Work;
+ ii. moral rights retained by the original author(s) and/or performer(s);
+iii. publicity and privacy rights pertaining to a person's image or
+ likeness depicted in a Work;
+ iv. rights protecting against unfair competition in regards to a Work,
+ subject to the limitations in paragraph 4(a), below;
+ v. rights protecting the extraction, dissemination, use and reuse of data
+ in a Work;
+ vi. database rights (such as those arising under Directive 96/9/EC of the
+ European Parliament and of the Council of 11 March 1996 on the legal
+ protection of databases, and under any national implementation
+ thereof, including any amended or successor version of such
+ directive); and
+vii. other similar, equivalent or corresponding rights throughout the
+ world based on applicable law or treaty, and any national
+ implementations thereof.
+
+2. Waiver. To the greatest extent permitted by, but not in contravention
+of, applicable law, Affirmer hereby overtly, fully, permanently,
+irrevocably and unconditionally waives, abandons, and surrenders all of
+Affirmer's Copyright and Related Rights and associated claims and causes
+of action, whether now known or unknown (including existing as well as
+future claims and causes of action), in the Work (i) in all territories
+worldwide, (ii) for the maximum duration provided by applicable law or
+treaty (including future time extensions), (iii) in any current or future
+medium and for any number of copies, and (iv) for any purpose whatsoever,
+including without limitation commercial, advertising or promotional
+purposes (the "Waiver"). Affirmer makes the Waiver for the benefit of each
+member of the public at large and to the detriment of Affirmer's heirs and
+successors, fully intending that such Waiver shall not be subject to
+revocation, rescission, cancellation, termination, or any other legal or
+equitable action to disrupt the quiet enjoyment of the Work by the public
+as contemplated by Affirmer's express Statement of Purpose.
+
+3. Public License Fallback. Should any part of the Waiver for any reason
+be judged legally invalid or ineffective under applicable law, then the
+Waiver shall be preserved to the maximum extent permitted taking into
+account Affirmer's express Statement of Purpose. In addition, to the
+extent the Waiver is so judged Affirmer hereby grants to each affected
+person a royalty-free, non transferable, non sublicensable, non exclusive,
+irrevocable and unconditional license to exercise Affirmer's Copyright and
+Related Rights in the Work (i) in all territories worldwide, (ii) for the
+maximum duration provided by applicable law or treaty (including future
+time extensions), (iii) in any current or future medium and for any number
+of copies, and (iv) for any purpose whatsoever, including without
+limitation commercial, advertising or promotional purposes (the
+"License"). The License shall be deemed effective as of the date CC0 was
+applied by Affirmer to the Work. Should any part of the License for any
+reason be judged legally invalid or ineffective under applicable law, such
+partial invalidity or ineffectiveness shall not invalidate the remainder
+of the License, and in such case Affirmer hereby affirms that he or she
+will not (i) exercise any of his or her remaining Copyright and Related
+Rights in the Work or (ii) assert any associated claims and causes of
+action with respect to the Work, in either case contrary to Affirmer's
+express Statement of Purpose.
+
+4. Limitations and Disclaimers.
+
+ a. No trademark or patent rights held by Affirmer are waived, abandoned,
+ surrendered, licensed or otherwise affected by this document.
+ b. Affirmer offers the Work as-is and makes no representations or
+ warranties of any kind concerning the Work, express, implied,
+ statutory or otherwise, including without limitation warranties of
+ title, merchantability, fitness for a particular purpose, non
+ infringement, or the absence of latent or other defects, accuracy, or
+ the present or absence of errors, whether or not discoverable, all to
+ the greatest extent permissible under applicable law.
+ c. Affirmer disclaims responsibility for clearing rights of other persons
+ that may apply to the Work or any use thereof, including without
+ limitation any person's Copyright and Related Rights in the Work.
+ Further, Affirmer disclaims responsibility for obtaining any necessary
+ consents, permissions or other rights required for any use of the
+ Work.
+ d. Affirmer understands and acknowledges that Creative Commons is not a
+ party to this document and has no duty or obligation with respect to
+ this CC0 or use of the Work.
diff --git a/lib/Utils.Cryptography/monocypher/vendor/tests/externals/tinyssh/cleanup.c b/lib/Utils.Cryptography/monocypher/vendor/tests/externals/tinyssh/cleanup.c
new file mode 100644
index 0000000..e126d36
--- /dev/null
+++ b/lib/Utils.Cryptography/monocypher/vendor/tests/externals/tinyssh/cleanup.c
@@ -0,0 +1,9 @@
+#include "cleanup.h"
+
+void cleanup_(void *yv, long long ylen) {
+ volatile char *y = (volatile char *)yv;
+ while (ylen > 0) { *y++ = 0; --ylen; }
+#ifdef HASASMVOLATILEMEMORY
+ __asm__ __volatile__("" : : "r"(yv) : "memory");
+#endif
+}
diff --git a/lib/Utils.Cryptography/monocypher/vendor/tests/externals/tinyssh/cleanup.h b/lib/Utils.Cryptography/monocypher/vendor/tests/externals/tinyssh/cleanup.h
new file mode 100644
index 0000000..a42fcb3
--- /dev/null
+++ b/lib/Utils.Cryptography/monocypher/vendor/tests/externals/tinyssh/cleanup.h
@@ -0,0 +1,7 @@
+#ifndef _CLEANUP_H____
+#define _CLEANUP_H____
+
+extern void cleanup_(void *, long long);
+#define cleanup(x) cleanup_((x), sizeof(x))
+
+#endif
diff --git a/lib/Utils.Cryptography/monocypher/vendor/tests/externals/tinyssh/crypto_hash_sha512.c b/lib/Utils.Cryptography/monocypher/vendor/tests/externals/tinyssh/crypto_hash_sha512.c
new file mode 100644
index 0000000..06a2d9e
--- /dev/null
+++ b/lib/Utils.Cryptography/monocypher/vendor/tests/externals/tinyssh/crypto_hash_sha512.c
@@ -0,0 +1,110 @@
+/*
+20180104
+*/
+/*
+- based on tweetnacl 20140427 (http://tweetnacl.cr.yp.to/software.html)
+- slightly modified
+*/
+
+#include "crypto_hash_sha512.h"
+
+static void store64_bigendian(unsigned char *y, unsigned long long x) {
+
+ long long i;
+
+ for (i = 7; i >= 0; --i) { y[i] = x; x >>= 8; }
+}
+
+static unsigned long long load64_bigendian(const unsigned char *x) {
+
+ unsigned long long y = 0;
+ long long i;
+
+ for (i = 0; i < 8; ++i) y = (y << 8) | x[i];
+ return y;
+}
+
+static unsigned long long R(unsigned long long x,int c) { return (x >> c) | ((x & 0xffffffffffffffffULL) << (64 - c)); }
+static unsigned long long Ch(unsigned long long x, unsigned long long y, unsigned long long z) { return (x & y) ^ (~x & z); }
+static unsigned long long Maj(unsigned long long x, unsigned long long y, unsigned long long z) { return (x & y) ^ (x & z) ^ (y & z); }
+static unsigned long long Sigma0(unsigned long long x) { return R(x, 28) ^ R(x, 34) ^ R(x, 39); }
+static unsigned long long Sigma1(unsigned long long x) { return R(x, 14) ^ R(x, 18) ^ R(x, 41); }
+static unsigned long long sigma0(unsigned long long x) { return R(x, 1) ^ R(x, 8) ^ (x >> 7); }
+static unsigned long long sigma1(unsigned long long x) { return R(x, 19) ^ R(x, 61) ^ (x >> 6); }
+
+static const unsigned long long K[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
+};
+
+static void blocks(unsigned long long *z, const unsigned char *m, unsigned long long n) {
+
+ unsigned long long b[8], a[8], w[80], t;
+ long long i, j;
+
+ for (i = 0; i < 8; ++i) a[i] = z[i];
+
+ while (n >= 128) {
+ for (i = 0; i < 16; ++i) w[i] = load64_bigendian(m + 8 * i);
+ for (i = 16; i < 80; ++i) w[i] = (sigma1(w[i - 2]) + w[i - 7] + sigma0(w[i - 15]) + w[i - 16]) & 0xffffffffffffffffULL;
+
+ for (i = 0; i < 80; ++i) {
+ for (j = 0; j < 8; ++j) b[j] = a[j];
+ t = a[7] + Sigma1(a[4]) + Ch(a[4], a[5], a[6]) + K[i] + w[i];
+ b[7] = t + Sigma0(a[0]) + Maj(a[0], a[1], a[2]);
+ b[3] += t;
+ for (j = 0; j < 8; ++j) a[(j + 1) % 8] = b[j] & 0xffffffffffffffffULL;
+ }
+
+ for (i = 0; i < 8; ++i) { a[i] += z[i]; a[i] &= 0xffffffffffffffffULL; z[i] = a[i]; }
+
+ m += 128;
+ n -= 128;
+ }
+}
+
+int crypto_hash_sha512_tinyssh(unsigned char *o,const unsigned char *m, unsigned long long n) {
+
+ long long i;
+ unsigned char x[256];
+ unsigned long long b = n;
+ unsigned long long h[8] = {
+ 0x6a09e667f3bcc908ULL, 0xbb67ae8584caa73bULL, 0x3c6ef372fe94f82bULL, 0xa54ff53a5f1d36f1ULL,
+ 0x510e527fade682d1ULL, 0x9b05688c2b3e6c1fULL, 0x1f83d9abfb41bd6bULL, 0x5be0cd19137e2179ULL
+ };
+
+ blocks(h, m, n);
+ m += n;
+ n &= 127;
+ m -= n;
+
+ for (i = 0; i < sizeof x; ++i) x[i] = 0;
+ for (i = 0; i < n; ++i) x[i] = m[i];
+ x[n] = 128;
+
+ n = 256 - 128 * (n < 112);
+ x[n - 9] = b >> 61;
+ store64_bigendian(x + n - 8, b << 3);
+ blocks(h, x, n);
+
+ for (i = 0; i < 8; ++i) store64_bigendian(o + 8 * i, h[i]);
+ return 0;
+}
diff --git a/lib/Utils.Cryptography/monocypher/vendor/tests/externals/tinyssh/crypto_hash_sha512.h b/lib/Utils.Cryptography/monocypher/vendor/tests/externals/tinyssh/crypto_hash_sha512.h
new file mode 100644
index 0000000..7b1d1ac
--- /dev/null
+++ b/lib/Utils.Cryptography/monocypher/vendor/tests/externals/tinyssh/crypto_hash_sha512.h
@@ -0,0 +1,12 @@
+#ifndef crypto_hash_sha512_H
+#define crypto_hash_sha512_H
+
+#define crypto_hash_sha512_tinyssh_BYTES 64
+extern int crypto_hash_sha512_tinyssh(unsigned char *, const unsigned char *, unsigned long long);
+
+#define crypto_hash_sha512 crypto_hash_sha512_tinyssh
+#define crypto_hash_sha512_BYTES crypto_hash_sha512_tinyssh_BYTES
+#define crypto_hash_sha512_IMPLEMENTATION "tinyssh"
+#define crypto_hash_sha512_VERSION "-"
+
+#endif
diff --git a/lib/Utils.Cryptography/monocypher/vendor/tests/externals/tinyssh/crypto_int64.h b/lib/Utils.Cryptography/monocypher/vendor/tests/externals/tinyssh/crypto_int64.h
new file mode 100644
index 0000000..acfd192
--- /dev/null
+++ b/lib/Utils.Cryptography/monocypher/vendor/tests/externals/tinyssh/crypto_int64.h
@@ -0,0 +1,8 @@
+#ifndef crypto_int64_h
+#define crypto_int64_h
+
+#include <stdint.h>
+
+typedef int64_t crypto_int64;
+
+#endif
diff --git a/lib/Utils.Cryptography/monocypher/vendor/tests/externals/tinyssh/crypto_onetimeauth_poly1305.c b/lib/Utils.Cryptography/monocypher/vendor/tests/externals/tinyssh/crypto_onetimeauth_poly1305.c
new file mode 100644
index 0000000..631e733
--- /dev/null
+++ b/lib/Utils.Cryptography/monocypher/vendor/tests/externals/tinyssh/crypto_onetimeauth_poly1305.c
@@ -0,0 +1,154 @@
+/*
+20200202
+*/
+/*
+Based on poly1305-donna (https://github.com/floodyberry/poly1305-opt/blob/master/extensions/poly1305_ref-32.c)
+- modified for NaCl API
+*/
+
+#include "crypto_onetimeauth_poly1305.h"
+
+/* clang-format off */
+static inline unsigned long unpack32(const unsigned char *x) {
+ return
+ (unsigned long) (x[0]) \
+ | (((unsigned long) (x[1])) << 8) \
+ | (((unsigned long) (x[2])) << 16) \
+ | (((unsigned long) (x[3])) << 24);
+}
+static inline void pack32(unsigned char *x, unsigned long u) {
+ x[0] = u; u >>= 8;
+ x[1] = u; u >>= 8;
+ x[2] = u; u >>= 8;
+ x[3] = u;
+}
+
+int crypto_onetimeauth_poly1305_tinyssh(unsigned char *o, const unsigned char *m, unsigned long long n, const unsigned char *k) {
+
+ unsigned long h0, h1, h2, h3, h4;
+ unsigned long r0, r1, r2, r3, r4;
+ unsigned long s1, s2, s3, s4;
+ unsigned long long d0, d1, d2, d3, d4;
+ unsigned long c, mask;
+ unsigned long long f;
+ long long i;
+
+
+ /* r &= 0xffffffc0ffffffc0ffffffc0fffffff */
+ r0 = (unpack32(k + 0) ) & 0x3ffffff;
+ r1 = (unpack32(k + 3) >> 2) & 0x3ffff03;
+ r2 = (unpack32(k + 6) >> 4) & 0x3ffc0ff;
+ r3 = (unpack32(k + 9) >> 6) & 0x3f03fff;
+ r4 = (unpack32(k + 12) >> 8) & 0x00fffff;
+
+ s1 = r1 * 5;
+ s2 = r2 * 5;
+ s3 = r3 * 5;
+ s4 = r4 * 5;
+
+ /* h = 0 */
+ h0 = h1 = h2 = h3 = h4 = 0;
+
+ while (n > 0) {
+ /* h += m[i] */
+ if (n >= 16) {
+ h0 += (unpack32(m ) ) & 0x3ffffff;
+ h1 += (unpack32(m + 3) >> 2) & 0x3ffffff;
+ h2 += (unpack32(m + 6) >> 4) & 0x3ffffff;
+ h3 += (unpack32(m + 9) >> 6) & 0x3ffffff;
+ h4 += (unpack32(m + 12) >> 8) | 16777216;
+ m += 16;
+ n -= 16;
+ }
+ else {
+ unsigned char mm[16];
+ for (i = 0; i < 16; ++i) mm[i] = 0;
+ for (i = 0; i < n; ++i) mm[i] = m[i];
+ mm[i] = 1;
+ h0 += (unpack32(mm ) ) & 0x3ffffff;
+ h1 += (unpack32(mm + 3) >> 2) & 0x3ffffff;
+ h2 += (unpack32(mm + 6) >> 4) & 0x3ffffff;
+ h3 += (unpack32(mm + 9) >> 6) & 0x3ffffff;
+ h4 += (unpack32(mm + 12) >> 8);
+ n = 0;
+ }
+
+ /* 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;
+ }
+
+
+ /* fully carry h */
+ 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 */
+ r0 = h0 + 5; c = r0 >> 26; r0 &= 0x3ffffff;
+ r1 = h1 + c; c = r1 >> 26; r1 &= 0x3ffffff;
+ r2 = h2 + c; c = r2 >> 26; r2 &= 0x3ffffff;
+ r3 = h3 + c; c = r3 >> 26; r3 &= 0x3ffffff;
+ r4 = h4 + c - (1 << 26);
+
+ /* select h if h < p, or h + -p if h >= p */
+ mask = (r4 >> ((sizeof(unsigned long) * 8) - 1)) - 1;
+ r0 &= mask;
+ r1 &= mask;
+ r2 &= mask;
+ r3 &= mask;
+ r4 &= mask;
+ mask = ~mask;
+ h0 = (h0 & mask) | r0;
+ h1 = (h1 & mask) | r1;
+ h2 = (h2 & mask) | r2;
+ h3 = (h3 & mask) | r3;
+ h4 = (h4 & mask) | r4;
+
+ /* 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 + unpack32(k + 16) ; h0 = (unsigned long)f;
+ f = (unsigned long long)h1 + unpack32(k + 20) + (f >> 32); h1 = (unsigned long)f;
+ f = (unsigned long long)h2 + unpack32(k + 24) + (f >> 32); h2 = (unsigned long)f;
+ f = (unsigned long long)h3 + unpack32(k + 28) + (f >> 32); h3 = (unsigned long)f;
+
+ pack32(o + 0, h0);
+ pack32(o + 4, h1);
+ pack32(o + 8, h2);
+ pack32(o + 12, h3);
+
+ return 0;
+}
+
+int crypto_onetimeauth_poly1305_tinyssh_verify(const unsigned char *h, const unsigned char *in, unsigned long long l, const unsigned char *k) {
+
+ unsigned char correct[16];
+ unsigned int d = 0;
+ long long i;
+
+ crypto_onetimeauth_poly1305(correct, in, l, k);
+
+ for (i = 0; i < 16; ++i) d |= correct[i] ^ h[i];
+ return (1 & ((d - 1) >> 8)) - 1;
+}
+/* clang-format on */
diff --git a/lib/Utils.Cryptography/monocypher/vendor/tests/externals/tinyssh/crypto_onetimeauth_poly1305.h b/lib/Utils.Cryptography/monocypher/vendor/tests/externals/tinyssh/crypto_onetimeauth_poly1305.h
new file mode 100644
index 0000000..3d9f9ea
--- /dev/null
+++ b/lib/Utils.Cryptography/monocypher/vendor/tests/externals/tinyssh/crypto_onetimeauth_poly1305.h
@@ -0,0 +1,16 @@
+#ifndef crypto_onetimeauth_poly1305_H
+#define crypto_onetimeauth_poly1305_H
+
+#define crypto_onetimeauth_poly1305_tinyssh_BYTES 16
+#define crypto_onetimeauth_poly1305_tinyssh_KEYBYTES 32
+extern int crypto_onetimeauth_poly1305_tinyssh(unsigned char *,const unsigned char *,unsigned long long,const unsigned char *);
+extern int crypto_onetimeauth_poly1305_tinyssh_verify(const unsigned char *,const unsigned char *,unsigned long long,const unsigned char *);
+
+#define crypto_onetimeauth_poly1305 crypto_onetimeauth_poly1305_tinyssh
+#define crypto_onetimeauth_poly1305_verify crypto_onetimeauth_poly1305_tinyssh_verify
+#define crypto_onetimeauth_poly1305_BYTES crypto_onetimeauth_poly1305_tinyssh_BYTES
+#define crypto_onetimeauth_poly1305_KEYBYTES crypto_onetimeauth_poly1305_tinyssh_KEYBYTES
+#define crypto_onetimeauth_poly1305_IMPLEMENTATION "tinyssh"
+#define crypto_onetimeauth_poly1305_VERSION "-"
+
+#endif
diff --git a/lib/Utils.Cryptography/monocypher/vendor/tests/externals/tinyssh/crypto_scalarmult_curve25519.c b/lib/Utils.Cryptography/monocypher/vendor/tests/externals/tinyssh/crypto_scalarmult_curve25519.c
new file mode 100644
index 0000000..6681128
--- /dev/null
+++ b/lib/Utils.Cryptography/monocypher/vendor/tests/externals/tinyssh/crypto_scalarmult_curve25519.c
@@ -0,0 +1,73 @@
+#include "cleanup.h"
+#include "fe25519.h"
+#include "crypto_scalarmult_curve25519.h"
+
+int crypto_scalarmult_curve25519_tinyssh(unsigned char *q, const unsigned char *n, const unsigned char *p) {
+
+ unsigned char e[32];
+ fe x1, x2, z2, x3, z3, tmp0, tmp1;
+ long long i;
+ unsigned int d = 0;
+ int pos;
+ crypto_uint32 swap, b;
+
+ for (i = 0; i < 32; ++i) e[i] = n[i];
+ e[0] &= 248;
+ e[31] &= 127;
+ e[31] |= 64;
+ fe25519_frombytes(x1, p);
+ fe_1(x2);
+ fe_0(z2);
+ fe_copy(x3, x1);
+ fe_1(z3);
+
+ swap = 0;
+ for (pos = 254; pos >= 0; --pos) {
+ b = e[pos / 8] >> (pos & 7);
+ b &= 1;
+ swap ^= b;
+ fe_cswap(x2, x3, swap);
+ fe_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_mul121666(z3, tmp1);
+ fe25519_sq(x3, x3);
+ fe25519_add(tmp0, tmp0, z3);
+ fe25519_mul(z3, x1, z2);
+ fe25519_mul(z2, tmp1, tmp0);
+ }
+
+ fe_cswap(x2, x3, swap);
+ fe_cswap(z2, z3, swap);
+
+ fe25519_inv(z2, z2);
+ fe25519_mul(x2, x2, z2);
+ fe25519_tobytes(q, x2);
+
+ cleanup(e);
+ cleanup(tmp0); cleanup(tmp1);
+ cleanup(x1); cleanup(x2); cleanup(x3);
+ cleanup(z2); cleanup(z3);
+
+ for (i = 0; i < 32; ++i) d |= q[i];
+ return -(1 & ((d - 1) >> 8));
+}
+
+static const unsigned char basepoint[32] = {9};
+
+int crypto_scalarmult_curve25519_tinyssh_base(unsigned char *q, const unsigned char *n) {
+ return crypto_scalarmult_curve25519_tinyssh(q, n, basepoint);
+}
diff --git a/lib/Utils.Cryptography/monocypher/vendor/tests/externals/tinyssh/crypto_scalarmult_curve25519.h b/lib/Utils.Cryptography/monocypher/vendor/tests/externals/tinyssh/crypto_scalarmult_curve25519.h
new file mode 100644
index 0000000..98a3ccf
--- /dev/null
+++ b/lib/Utils.Cryptography/monocypher/vendor/tests/externals/tinyssh/crypto_scalarmult_curve25519.h
@@ -0,0 +1,16 @@
+#ifndef crypto_scalarmult_curve25519_H
+#define crypto_scalarmult_curve25519_H
+
+#define crypto_scalarmult_curve25519_tinyssh_BYTES 32
+#define crypto_scalarmult_curve25519_tinyssh_SCALARBYTES 32
+extern int crypto_scalarmult_curve25519_tinyssh(unsigned char *,const unsigned char *,const unsigned char *);
+extern int crypto_scalarmult_curve25519_tinyssh_base(unsigned char *,const unsigned char *);
+
+#define crypto_scalarmult_curve25519 crypto_scalarmult_curve25519_tinyssh
+#define crypto_scalarmult_curve25519_base crypto_scalarmult_curve25519_tinyssh_base
+#define crypto_scalarmult_curve25519_BYTES crypto_scalarmult_curve25519_tinyssh_BYTES
+#define crypto_scalarmult_curve25519_SCALARBYTES crypto_scalarmult_curve25519_tinyssh_SCALARBYTES
+#define crypto_scalarmult_curve25519_IMPLEMENTATION "tinyssh"
+#define crypto_scalarmult_curve25519_VERSION "-"
+
+#endif
diff --git a/lib/Utils.Cryptography/monocypher/vendor/tests/externals/tinyssh/crypto_sign_ed25519.c b/lib/Utils.Cryptography/monocypher/vendor/tests/externals/tinyssh/crypto_sign_ed25519.c
new file mode 100644
index 0000000..d16164c
--- /dev/null
+++ b/lib/Utils.Cryptography/monocypher/vendor/tests/externals/tinyssh/crypto_sign_ed25519.c
@@ -0,0 +1,121 @@
+#include "randombytes.h"
+#include "cleanup.h"
+#include "crypto_hash_sha512.h"
+#include "crypto_verify_32.h"
+#include "ge25519.h"
+#include "sc25519.h"
+#include "crypto_sign_ed25519.h"
+
+int crypto_sign_ed25519_tinyssh(unsigned char *sm, unsigned long long *smlen, const unsigned char *m, unsigned long long n, const unsigned char *skorig) {
+
+ long long i;
+ unsigned char nonce[64], hram[64], sk[64], pk[32];
+ ge25519 R;
+
+ /* compute secret key from seed sk = H(skorig), H = sha512 */
+ crypto_hash_sha512(sk, skorig, 32);
+ sk[0] &= 248;
+ sk[31] &= 63;
+ sk[31] |= 64;
+
+ /* copy m to sm, copy secret key and public key */
+ *smlen = n + 64;
+ for (i = 31; i >= 0; --i) pk[i ] = skorig[i + 32];
+ for (i = n - 1; i >= 0; --i) sm[i + 64] = m[i];
+ for (i = 31; i >= 0; --i) sm[i + 32] = sk[i + 32];
+
+ /* get pseudorandom nonce = H(sk2, m) */
+ crypto_hash_sha512(nonce, sm + 32, n + 32);
+ sc25519_reduce(nonce);
+
+ /* copy pk to sm */
+ for (i = 31; i >= 0; --i) sm[i + 32] = pk[i];
+
+ /* compute R */
+ ge25519_scalarmult_base(R, nonce);
+ ge25519_tobytes(sm, R);
+
+ /* calculate hram = H(r, a, m) */
+ crypto_hash_sha512(hram, sm, n + 64);
+ sc25519_reduce(hram);
+
+ /* compute S */
+ sc25519_muladd(sm + 32, hram, sk, nonce);
+
+ /* cleanup */
+ cleanup(nonce); cleanup(hram); cleanup(sk); cleanup(pk); cleanup(R);
+ return 0;
+}
+
+int crypto_sign_ed25519_tinyssh_open(unsigned char *m, unsigned long long *mlen, const unsigned char *sm, unsigned long long n, const unsigned char *pk) {
+
+ long long i;
+ unsigned char pkcopy[32], rcopy[32], scopy[32], hram[64], rcheck[32];
+ ge25519 R, S, A;
+ int ret = -1;
+
+ /* check input */
+ if (n < 64) goto fail;
+ if (sm[63] & 224) goto fail;
+
+ /* unpack pk */
+ if (ge25519_frombytes_negate_vartime(A, pk) != 0) goto fail;
+
+ /* copy pk, r, s */
+ for (i = 0; i < 32; ++i) pkcopy[i] = pk[i];
+ for (i = 0; i < 32; ++i) rcopy[i] = sm[i];
+ for (i = 0; i < 32; ++i) scopy[i] = sm[i + 32];
+
+ /* copy sm to m and copy pk to m */
+ for (i = n - 1; i >= 0; --i) m[i] = sm[i];
+ for (i = 0; i < 32; ++i) m[i + 32] = pkcopy[i];
+
+ /* calculate hram = H(r, a, m) */
+ crypto_hash_sha512(hram, m, n);
+ sc25519_reduce(hram);
+
+ /* compute R */
+ ge25519_scalarmult(A, A, hram);
+ ge25519_scalarmult_base(S, scopy);
+ ge25519_add(R, S, A);
+
+ /* check R */
+ ge25519_tobytes(rcheck, R);
+ if (crypto_verify_32(rcheck, rcopy) != 0) goto fail;
+
+ /* copy message */
+ n -= 64; *mlen = n;
+ for (i = 0; i < n; ++i) m[i] = m[i + 64];
+ for (i = 0; i < 64; ++i) m[i + n] = 0;
+ ret = 0;
+ goto cleanup;
+
+fail:
+ for (i = 0; i < n; ++i) m[i] = 0;
+
+cleanup:
+ cleanup(pkcopy); cleanup(rcopy); cleanup(scopy);
+ cleanup(hram); cleanup(rcheck);
+ cleanup(R); cleanup(S); cleanup(A);
+ return ret;
+}
+
+int crypto_sign_ed25519_tinyssh_keypair(unsigned char *pk, unsigned char *sk) {
+
+ unsigned char h[64];
+ ge25519 A;
+ long long i;
+
+ randombytes(sk, 32);
+ crypto_hash_sha512(h, sk, 32);
+ h[0] &= 248;
+ h[31] &= 63;
+ h[31] |= 64;
+
+ ge25519_scalarmult_base(A, h);
+ ge25519_tobytes(pk, A);
+
+ for (i = 31; i >= 0; --i) sk[i + 32] = pk[i];
+ cleanup(h); cleanup(A);
+ return 0;
+}
diff --git a/lib/Utils.Cryptography/monocypher/vendor/tests/externals/tinyssh/crypto_sign_ed25519.h b/lib/Utils.Cryptography/monocypher/vendor/tests/externals/tinyssh/crypto_sign_ed25519.h
new file mode 100644
index 0000000..e777efa
--- /dev/null
+++ b/lib/Utils.Cryptography/monocypher/vendor/tests/externals/tinyssh/crypto_sign_ed25519.h
@@ -0,0 +1,20 @@
+#ifndef crypto_sign_ed25519_H
+#define crypto_sign_ed25519_H
+
+#define crypto_sign_ed25519_tinyssh_SECRETKEYBYTES 64
+#define crypto_sign_ed25519_tinyssh_PUBLICKEYBYTES 32
+#define crypto_sign_ed25519_tinyssh_BYTES 64
+extern int crypto_sign_ed25519_tinyssh(unsigned char *,unsigned long long *,const unsigned char *,unsigned long long,const unsigned char *);
+extern int crypto_sign_ed25519_tinyssh_open(unsigned char *,unsigned long long *,const unsigned char *,unsigned long long,const unsigned char *);
+extern int crypto_sign_ed25519_tinyssh_keypair(unsigned char *,unsigned char *);
+
+#define crypto_sign_ed25519 crypto_sign_ed25519_tinyssh
+#define crypto_sign_ed25519_open crypto_sign_ed25519_tinyssh_open
+#define crypto_sign_ed25519_keypair crypto_sign_ed25519_tinyssh_keypair
+#define crypto_sign_ed25519_BYTES crypto_sign_ed25519_tinyssh_BYTES
+#define crypto_sign_ed25519_PUBLICKEYBYTES crypto_sign_ed25519_tinyssh_PUBLICKEYBYTES
+#define crypto_sign_ed25519_SECRETKEYBYTES crypto_sign_ed25519_tinyssh_SECRETKEYBYTES
+#define crypto_sign_ed25519_IMPLEMENTATION "tinyssh"
+#define crypto_sign_ed25519_VERSION "-"
+
+#endif
diff --git a/lib/Utils.Cryptography/monocypher/vendor/tests/externals/tinyssh/crypto_stream_chacha20.c b/lib/Utils.Cryptography/monocypher/vendor/tests/externals/tinyssh/crypto_stream_chacha20.c
new file mode 100644
index 0000000..6104a4c
--- /dev/null
+++ b/lib/Utils.Cryptography/monocypher/vendor/tests/externals/tinyssh/crypto_stream_chacha20.c
@@ -0,0 +1,145 @@
+/*
+20210508
+Jan Mojzis
+Public domain.
+*/
+
+#include <stdint.h>
+#include "crypto_stream_chacha20.h"
+
+/* clang-format off */
+static inline uint32_t unpack32(const unsigned char *x) {
+ return
+ (uint32_t) (x[0]) \
+ | (((uint32_t) (x[1])) << 8) \
+ | (((uint32_t) (x[2])) << 16) \
+ | (((uint32_t) (x[3])) << 24);
+}
+static inline void pack32(unsigned char *x, uint32_t u) {
+ x[0] = u; u >>= 8;
+ x[1] = u; u >>= 8;
+ x[2] = u; u >>= 8;
+ x[3] = u;
+}
+
+#define ROTATE(x, c) ((x) << (c)) ^ ((x) >> (32 - (c)))
+
+#define QUARTERROUND(a, b, c, d) \
+ a += b; d = ROTATE(d ^ a, 16); \
+ c += d; b = ROTATE(b ^ c, 12); \
+ a += b; d = ROTATE(d ^ a, 8); \
+ c += d; b = ROTATE(b ^ c, 7);
+
+#define TWOROUNDS \
+ 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)
+
+#define XORBLOCK(o, i) \
+ x0 = s0; \
+ x1 = s1; \
+ x2 = s2; \
+ x3 = s3; \
+ x4 = k0; \
+ x5 = k1; \
+ x6 = k2; \
+ x7 = k3; \
+ x8 = k4; \
+ x9 = k5; \
+ x10 = k6; \
+ x11 = k7; \
+ x12 = n0; \
+ x13 = n1; \
+ x14 = n2; \
+ x15 = n3; \
+ \
+ TWOROUNDS /* round 1, 2 */ \
+ TWOROUNDS /* round 3, 4 */ \
+ TWOROUNDS /* round 5, 6 */ \
+ TWOROUNDS /* round 7, 8 */ \
+ TWOROUNDS /* round 9, 10 */ \
+ TWOROUNDS /* round 11, 12 */ \
+ TWOROUNDS /* round 13, 14 */ \
+ TWOROUNDS /* round 15, 16 */ \
+ TWOROUNDS /* round 17, 18 */ \
+ TWOROUNDS /* round 19, 20 */ \
+ \
+ pack32(o , (x0 + s0) ^ unpack32(i )); \
+ pack32(o + 4, (x1 + s1) ^ unpack32(i + 4)); \
+ pack32(o + 8, (x2 + s2) ^ unpack32(i + 8)); \
+ pack32(o + 12, (x3 + s3) ^ unpack32(i + 12)); \
+ pack32(o + 16, (x4 + k0) ^ unpack32(i + 16)); \
+ pack32(o + 20, (x5 + k1) ^ unpack32(i + 20)); \
+ pack32(o + 24, (x6 + k2) ^ unpack32(i + 24)); \
+ pack32(o + 28, (x7 + k3) ^ unpack32(i + 28)); \
+ pack32(o + 32, (x8 + k4) ^ unpack32(i + 32)); \
+ pack32(o + 36, (x9 + k5) ^ unpack32(i + 36)); \
+ pack32(o + 40, (x10 + k6) ^ unpack32(i + 40)); \
+ pack32(o + 44, (x11 + k7) ^ unpack32(i + 44)); \
+ pack32(o + 48, (x12 + n0) ^ unpack32(i + 48)); \
+ pack32(o + 52, (x13 + n1) ^ unpack32(i + 52)); \
+ pack32(o + 56, (x14 + n2) ^ unpack32(i + 56)); \
+ pack32(o + 60, (x15 + n3) ^ unpack32(i + 60));
+
+int crypto_stream_chacha20_tinyssh_xor(unsigned char *c, const unsigned char *m, unsigned long long l, const unsigned char *n, const unsigned char *k) {
+
+ register uint32_t x0, x1, x2, x3, x4, x5, x6, x7;
+ register uint32_t x8, x9, x10, x11, x12, x13, x14, x15;
+ uint32_t k0 = unpack32(k );
+ uint32_t k1 = unpack32(k + 4);
+ uint32_t k2 = unpack32(k + 8);
+ uint32_t k3 = unpack32(k + 12);
+ uint32_t k4 = unpack32(k + 16);
+ uint32_t k5 = unpack32(k + 20);
+ uint32_t k6 = unpack32(k + 24);
+ uint32_t k7 = unpack32(k + 28);
+ uint32_t n0 = 0;
+ uint32_t n1 = 0;
+ uint32_t n2 = unpack32(n );
+ uint32_t n3 = unpack32(n + 4);
+ uint32_t s0 = 0x61707865;
+ uint32_t s1 = 0x3320646E;
+ uint32_t s2 = 0x79622D32;
+ uint32_t s3 = 0x6B206574;
+ uint64_t u = 0;
+
+ if (!l) return 0;
+
+ while (l >= 64) {
+ XORBLOCK(c, m);
+
+ if (!++u) return -1;
+ n0 = u;
+ n1 = u >> 32;
+
+ l -= 64;
+ c += 64;
+ m += 64;
+ }
+ if (l) {
+ unsigned char b[64] = {0};
+ unsigned long long j;
+
+ for (j = 0; j < l; ++j) b[j] = m[j];
+ XORBLOCK(b, b);
+ for (j = 0; j < l; ++j) c[j] = b[j];
+ }
+ return 0;
+}
+
+int crypto_stream_chacha20_tinyssh(unsigned char *c, unsigned long long l, const unsigned char *n, const unsigned char *k) {
+
+ unsigned long long j;
+ unsigned char ncopy[8], kcopy[32];
+
+ for (j = 0; j < 32; ++j) kcopy[j] = k[j];
+ for (j = 0; j < 8; ++j) ncopy[j] = n[j];
+ for (j = 0; j < l; ++j) c[j] = 0;
+ return crypto_stream_chacha20_tinyssh_xor(c, c, l, ncopy, kcopy);
+}
+/* clang-format on */
diff --git a/lib/Utils.Cryptography/monocypher/vendor/tests/externals/tinyssh/crypto_stream_chacha20.h b/lib/Utils.Cryptography/monocypher/vendor/tests/externals/tinyssh/crypto_stream_chacha20.h
new file mode 100644
index 0000000..1451757
--- /dev/null
+++ b/lib/Utils.Cryptography/monocypher/vendor/tests/externals/tinyssh/crypto_stream_chacha20.h
@@ -0,0 +1,16 @@
+#ifndef crypto_stream_chacha20_H
+#define crypto_stream_chacha20_H
+
+#define crypto_stream_chacha20_tinyssh_KEYBYTES 32
+#define crypto_stream_chacha20_tinyssh_NONCEBYTES 8
+extern int crypto_stream_chacha20_tinyssh(unsigned char *, unsigned long long, const unsigned char *, const unsigned char *);
+extern int crypto_stream_chacha20_tinyssh_xor(unsigned char *, const unsigned char *, unsigned long long, const unsigned char *, const unsigned char *);
+
+#define crypto_stream_chacha20 crypto_stream_chacha20_tinyssh
+#define crypto_stream_chacha20_xor crypto_stream_chacha20_tinyssh_xor
+#define crypto_stream_chacha20_KEYBYTES crypto_stream_chacha20_tinyssh_KEYBYTES
+#define crypto_stream_chacha20_NONCEBYTES crypto_stream_chacha20_tinyssh_NONCEBYTES
+#define crypto_stream_chacha20_IMPLEMENTATION "tinyssh"
+#define crypto_stream_chacha20_VERSION "-"
+
+#endif
diff --git a/lib/Utils.Cryptography/monocypher/vendor/tests/externals/tinyssh/crypto_uint32.h b/lib/Utils.Cryptography/monocypher/vendor/tests/externals/tinyssh/crypto_uint32.h
new file mode 100644
index 0000000..73f22b1
--- /dev/null
+++ b/lib/Utils.Cryptography/monocypher/vendor/tests/externals/tinyssh/crypto_uint32.h
@@ -0,0 +1,8 @@
+#ifndef crypto_uint32_h
+#define crypto_uint32_h
+
+#include <stdint.h>
+
+typedef uint32_t crypto_uint32;
+
+#endif
diff --git a/lib/Utils.Cryptography/monocypher/vendor/tests/externals/tinyssh/crypto_uint64.h b/lib/Utils.Cryptography/monocypher/vendor/tests/externals/tinyssh/crypto_uint64.h
new file mode 100644
index 0000000..b1b47a9
--- /dev/null
+++ b/lib/Utils.Cryptography/monocypher/vendor/tests/externals/tinyssh/crypto_uint64.h
@@ -0,0 +1,8 @@
+#ifndef crypto_uint64_h
+#define crypto_uint64_h
+
+#include <stdint.h>
+
+typedef uint64_t crypto_uint64;
+
+#endif
diff --git a/lib/Utils.Cryptography/monocypher/vendor/tests/externals/tinyssh/crypto_verify_32.c b/lib/Utils.Cryptography/monocypher/vendor/tests/externals/tinyssh/crypto_verify_32.c
new file mode 100644
index 0000000..a7b5bec
--- /dev/null
+++ b/lib/Utils.Cryptography/monocypher/vendor/tests/externals/tinyssh/crypto_verify_32.c
@@ -0,0 +1,6 @@
+#include "verify.h"
+#include "crypto_verify_32.h"
+
+int crypto_verify_32_tinyssh(const unsigned char *x, const unsigned char *y) {
+ return verify(x, y, 32);
+}
diff --git a/lib/Utils.Cryptography/monocypher/vendor/tests/externals/tinyssh/crypto_verify_32.h b/lib/Utils.Cryptography/monocypher/vendor/tests/externals/tinyssh/crypto_verify_32.h
new file mode 100644
index 0000000..87767b9
--- /dev/null
+++ b/lib/Utils.Cryptography/monocypher/vendor/tests/externals/tinyssh/crypto_verify_32.h
@@ -0,0 +1,12 @@
+#ifndef crypto_verify_32_H
+#define crypto_verify_32_H
+
+#define crypto_verify_32_tinyssh_BYTES 32
+extern int crypto_verify_32_tinyssh(const unsigned char *, const unsigned char *);
+
+#define crypto_verify_32 crypto_verify_32_tinyssh
+#define crypto_verify_32_BYTES crypto_verify_32_tinyssh_BYTES
+#define crypto_verify_32_IMPLEMENTATION "tinyssh"
+#define crypto_verify_32_VERSION "-"
+
+#endif
diff --git a/lib/Utils.Cryptography/monocypher/vendor/tests/externals/tinyssh/fe.c b/lib/Utils.Cryptography/monocypher/vendor/tests/externals/tinyssh/fe.c
new file mode 100644
index 0000000..cf66d8d
--- /dev/null
+++ b/lib/Utils.Cryptography/monocypher/vendor/tests/externals/tinyssh/fe.c
@@ -0,0 +1,171 @@
+/*
+20140918
+Jan Mojzis
+Public domain.
+*/
+
+#include "fe.h"
+
+/*
+o = 0
+*/
+void fe_0(fe o) {
+
+ long long i;
+ for (i = 0; i < 8; ++i) o[i] = 0;
+}
+
+/*
+o = 1
+*/
+void fe_1(fe o) {
+
+ fe_0(o);
+ o[0] = 1;
+}
+
+/*
+o = x
+*/
+void fe_copy(fe o, const fe x) {
+
+ long long i;
+ for (i = 0; i < 8; ++i) o[i] = x[i];
+}
+
+/*
+if (b) swap(f, g)
+*/
+void fe_cswap(fe f, fe g, crypto_uint32 b) {
+
+ long long i;
+ fe t;
+
+ b = -b;
+
+ for (i = 0; i < 8; ++i) t[i] = b & (f[i] ^ g[i]);
+ for (i = 0; i < 8; ++i) f[i] ^= t[i];
+ for (i = 0; i < 8; ++i) g[i] ^= t[i];
+ fe_0(t);
+}
+
+/*
+if (b) f = g
+*/
+void fe_cmov(fe f, const fe g, crypto_uint32 b) {
+
+ long long i;
+ fe t;
+
+ b = -b;
+
+ for (i = 0; i < 8; ++i) t[i] = b & (f[i] ^ g[i]);
+ for (i = 0; i < 8; ++i) f[i] ^= t[i];
+ fe_0(t);
+}
+
+
+/*
+o = a * b
+*/
+/*
+Implementation note: fe_mul_() is unrolled version of:
+void fe_mul_(fel o, const fe a, const fe b) {
+
+ crypto_uint64 u;
+ long long i, j;
+
+ for (i = 0; i < 16; ++i) o[i] = 0;
+ for (i = 0; i < 8; ++i) for (j = 0; j < 8; ++j) {
+ u = (crypto_uint64)a[i] * (crypto_uint64)b[j];
+ o[i + j ] += u & 0xffffffff;
+ o[i + j + 1] += u >> 32;
+ }
+}
+*/
+#define M(i, j) u = (crypto_uint64)a[i] * (crypto_uint64)b[j]; \
+ o[i + j ] += u & 0xffffffff; \
+ o[i + j + 1] += u >> 32;
+void fe_mul_(fel o, const fe a, const fe b) {
+
+ crypto_uint64 u;
+ long long i;
+
+ for (i = 0; i < 16; ++i) o[i] = 0;
+
+ M(0, 0); M(0, 1); M(0, 2); M(0, 3); M(0, 4); M(0, 5); M(0, 6); M(0, 7);
+ M(1, 0); M(1, 1); M(1, 2); M(1, 3); M(1, 4); M(1, 5); M(1, 6); M(1, 7);
+ M(2, 0); M(2, 1); M(2, 2); M(2, 3); M(2, 4); M(2, 5); M(2, 6); M(2, 7);
+ M(3, 0); M(3, 1); M(3, 2); M(3, 3); M(3, 4); M(3, 5); M(3, 6); M(3, 7);
+ M(4, 0); M(4, 1); M(4, 2); M(4, 3); M(4, 4); M(4, 5); M(4, 6); M(4, 7);
+ M(5, 0); M(5, 1); M(5, 2); M(5, 3); M(5, 4); M(5, 5); M(5, 6); M(5, 7);
+ M(6, 0); M(6, 1); M(6, 2); M(6, 3); M(6, 4); M(6, 5); M(6, 6); M(6, 7);
+ M(7, 0); M(7, 1); M(7, 2); M(7, 3); M(7, 4); M(7, 5); M(7, 6); M(7, 7);
+}
+
+/*
+o = x ^ 2
+*/
+/*
+Implementation note: fe_sq_() is unrolled version of:
+void fe_sq_(fel o, const fe a) {
+
+ crypto_uint64 u;
+ long long i, j;
+
+ for (i = 0; i < 16; ++i) o[i] = 0;
+ for (i = 0; i < 8; ++i) for (j = i + 1; j < 8; ++j) {
+ u = (crypto_uint64)a[i] * (crypto_uint64)a[j];
+ o[i + j ] += 2 * (u & 0xffffffff);
+ o[i + j + 1] += 2 * (u >> 32);
+ }
+ for (i = 0; i < 8; ++i) {
+ u = (crypto_uint64)a[i] * (crypto_uint64)a[i];
+ o[2 * i ] += (u & 0xffffffff);
+ o[2 * i + 1] += (u >> 32);
+ }
+}
+*/
+#define M2(i, j) u = (crypto_uint64)a[i] * (crypto_uint64)a[j]; \
+ o[i + j ] += 2 * (u & 0xffffffff); \
+ o[i + j + 1] += 2 * (u >> 32);
+#define SQ(i) u = (crypto_uint64)a[i] * (crypto_uint64)a[i]; \
+ o[2 * i ] += (u & 0xffffffff); \
+ o[2 * i + 1] += (u >> 32)
+void fe_sq_(fel o, const fe a) {
+
+ crypto_uint64 u;
+ long long i;
+
+ for (i = 0; i < 16; ++i) o[i] = 0;
+
+ M2(0, 1); M2(0, 2); M2(0, 3); M2(0, 4); M2(0, 5); M2(0, 6); M2(0, 7);
+ M2(1, 2); M2(1, 3); M2(1, 4); M2(1, 5); M2(1, 6); M2(1, 7);
+ M2(2, 3); M2(2, 4); M2(2, 5); M2(2, 6); M2(2, 7);
+ M2(3, 4); M2(3, 5); M2(3, 6); M2(3, 7);
+ M2(4, 5); M2(4, 6); M2(4, 7);
+ M2(5, 6); M2(5, 7);
+ M2(6, 7);
+ SQ(0); SQ(1); SQ(2); SQ(3); SQ(4); SQ(5); SQ(6); SQ(7);
+}
+
+/*
+if (p < r) r -= p
+*/
+void fe_reducesmall(fe r, const fe p, const crypto_uint64 carry) {
+
+ crypto_uint64 pb = 0, b;
+ long long i;
+ fe t;
+
+ for (i = 0; i < 8; ++i) {
+ pb += (crypto_uint64)p[i];
+ b = (crypto_uint64)r[i] - pb; b >>= 63;
+ t[i] = (crypto_uint64)r[i] - pb + (b << 32);
+ pb = b;
+ }
+ b = carry - pb; b >>= 63;
+ b -= 1;
+ for (i = 0; i < 8; ++i) r[i] ^= b & (r[i] ^ t[i]);
+ fe_0(t);
+}
diff --git a/lib/Utils.Cryptography/monocypher/vendor/tests/externals/tinyssh/fe.h b/lib/Utils.Cryptography/monocypher/vendor/tests/externals/tinyssh/fe.h
new file mode 100644
index 0000000..5eeb93d
--- /dev/null
+++ b/lib/Utils.Cryptography/monocypher/vendor/tests/externals/tinyssh/fe.h
@@ -0,0 +1,21 @@
+#ifndef _FE_H____
+#define _FE_H____
+
+#include "crypto_uint32.h"
+#include "crypto_uint64.h"
+
+typedef crypto_uint32 fe[8];
+typedef crypto_uint64 fel[16];
+
+extern void fe_0(fe);
+extern void fe_1(fe);
+extern void fe_copy(fe, const fe);
+extern void fe_cswap(fe, fe, crypto_uint32);
+extern void fe_cmov(fe, const fe, crypto_uint32);
+
+extern void fe_mul_(fel, const fe, const fe);
+extern void fe_sq_(fel, const fe);
+
+extern void fe_reducesmall(fe, const fe, const crypto_uint64);
+
+#endif
diff --git a/lib/Utils.Cryptography/monocypher/vendor/tests/externals/tinyssh/fe25519.c b/lib/Utils.Cryptography/monocypher/vendor/tests/externals/tinyssh/fe25519.c
new file mode 100644
index 0000000..fb6e08e
--- /dev/null
+++ b/lib/Utils.Cryptography/monocypher/vendor/tests/externals/tinyssh/fe25519.c
@@ -0,0 +1,236 @@
+#include "uint32_pack.h"
+#include "uint32_unpack.h"
+#include "crypto_verify_32.h"
+#include "cleanup.h"
+#include "fe.h"
+#include "fe25519.h"
+
+/*
+p = 2^255 - 19
+*/
+static const fe p = {
+ 0xffffffed, 0xffffffff, 0xffffffff, 0xffffffff,
+ 0xffffffff, 0xffffffff, 0xffffffff, 0x7fffffff
+};
+
+/*
+p3 = 3 * p
+*/
+static const crypto_uint64 p3[8] = {
+ 0x2ffffffc7ULL, 0x2fffffffdULL, 0x2fffffffdULL, 0x2fffffffdULL,
+ 0x2fffffffdULL, 0x2fffffffdULL, 0x2fffffffdULL, 0x17ffffffdULL
+};
+
+/*
+reduction modulo p: 16 limbs -> 8 limbs
+*/
+static void fe25519_reducebig(fe o, fel t) {
+
+ crypto_uint64 u = 0;
+ long long i;
+
+ for (i = 0; i < 7; ++i) { u += t[i] + 38ULL * t[i + 8]; t[i] = u & 0xffffffff; u >>= 32; }
+ u += t[i] + 38ULL * t[i + 8]; t[i] = u & 0x7fffffff; u >>= 31;
+ u *= 19ULL;
+ for (i = 0; i < 8; ++i) { u += t[i]; o[i] = u & 0xffffffff; u >>= 32; }
+}
+
+/*
+o = (a * b) % p
+*/
+void fe25519_mul(fe o, const fe a, const fe b) {
+
+ fel t;
+
+ fe_mul_(t, a, b);
+ fe25519_reducebig(o, t);
+
+ cleanup(t);
+}
+
+/*
+o = (a ^ 2) % p
+*/
+void fe25519_sq(fe o, const fe a) {
+
+ fel t;
+
+ fe_sq_(t, a);
+ fe25519_reducebig(o, t);
+
+ cleanup(t);
+}
+
+/*
+o = (121666 * f) % p;
+*/
+void fe25519_mul121666(fe o, const fe f) {
+
+ crypto_uint64 u = 0;
+ long long i;
+
+ for (i = 0; i < 7; ++i) { u += (crypto_uint64)121666 * (crypto_uint64)f[i]; o[i] = u & 0xffffffff; u >>= 32; }
+ u += (crypto_uint64)121666 * (crypto_uint64)f[i]; o[i] = u & 0x7fffffff; u >>= 31;
+ u *= 19ULL;
+ for (i = 0; i < 8; ++i) { u += o[i]; o[i] = u & 0xffffffff; u >>= 32; }
+}
+
+/*
+o = (x + y) % p
+*/
+void fe25519_add(fe o, const fe x, const fe y) {
+
+ crypto_uint64 u = 0;
+ long long i;
+
+ for (i = 0; i < 7; ++i) { u += (crypto_uint64)x[i] + (crypto_uint64)y[i]; o[i] = u & 0xffffffff; u >>= 32; }
+ u += (crypto_uint64)x[i] + (crypto_uint64)y[i]; o[i] = u & 0x7fffffff; u >>= 31;
+ u *= 19ULL;
+ for (i = 0; i < 8; ++i) { u += o[i]; o[i] = u & 0xffffffff; u >>= 32; }
+}
+
+/*
+o = (x - y) % p
+*/
+void fe25519_sub(fe o, const fe x, const fe y) {
+
+ crypto_uint64 u = 0;
+ long long i;
+
+ for (i = 0; i < 7; ++i) { u += p3[i] - (crypto_uint64)y[i] + (crypto_uint64)x[i]; o[i] = u & 0xffffffff; u >>= 32; }
+ u += p3[i] - (crypto_uint64)y[i] + (crypto_uint64)x[i]; o[i] = u & 0x7fffffff; u >>= 31;
+ u *= 19ULL;
+ for (i = 0; i < 8; ++i) { u += o[i]; o[i] = u & 0xffffffff; u >>= 32; }
+}
+
+/*
+o = -x % p
+*/
+void fe25519_neg(fe o, const fe x) {
+
+ fe t;
+
+ fe_0(t);
+ fe25519_sub(o, t, x);
+}
+
+
+/*
+o = (1 / z) % p
+... using Fermat's Little Theorem
+*/
+void fe25519_inv(fe o, const fe z) {
+
+ fe t0, t1, t2, t3;
+ long long i;
+
+ fe25519_sq(t0, z); for (i = 1; i < 1; ++i) fe25519_sq(t0, t0);
+ fe25519_sq(t1,t0); for (i = 1; i < 2; ++i) fe25519_sq(t1, t1);
+ fe25519_mul(t1, z, t1);
+ fe25519_mul(t0, t0, t1);
+ fe25519_sq(t2, t0); for (i = 1; i < 1; ++i) fe25519_sq(t2, t2);
+ 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(o, t1, t0);
+
+ cleanup(t0); cleanup(t1); cleanup(t2); cleanup(t3);
+}
+
+void fe25519_pow22523(fe out, const fe z) {
+
+ fe t0, t1, t2;
+ long long i;
+
+ fe25519_sq(t0, z); for (i = 1; i < 1; ++i) fe25519_sq(t0, t0);
+ fe25519_sq(t1, t0); for (i = 1; i < 2; ++i) fe25519_sq(t1, t1);
+ fe25519_mul(t1, z, t1);
+ fe25519_mul(t0, t0, t1);
+ fe25519_sq(t0, t0); for (i = 1; i < 1; ++i) 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); for (i = 1; i < 2; ++i) fe25519_sq(t0, t0);
+ fe25519_mul(out, t0, z);
+
+ cleanup(t0); cleanup(t1); cleanup(t2);
+}
+
+/*
+converts field-element into byte-array
+*/
+void fe25519_tobytes(unsigned char *out, const fe in) {
+
+ long long i;
+ fe x;
+
+ fe_copy(x, in);
+ fe_reducesmall(x, p, 0);
+ for (i = 0; i < 8; ++i) uint32_pack(out + 4 * i, x[i]);
+ cleanup(x);
+}
+
+/*
+converts byte-array into field-element
+*/
+void fe25519_frombytes(fe out, const unsigned char *in) {
+
+ long long i;
+
+ for (i = 0; i < 8; ++i) out[i] = uint32_unpack(in + 4 * i);
+ out[7] &= 0x7fffffff;
+}
+
+
+/*
+if (f == 0) return 0;
+else return -1;
+*/
+static const unsigned char zero[32] = {0};
+int fe25519_isnonzero(const fe f) {
+ unsigned char s[32];
+ int r;
+ fe25519_tobytes(s, f);
+ r = crypto_verify_32(s, zero);
+ cleanup(s);
+ return r;
+}
+
+
+/*
+if (f >= 0) return 0;
+else return -1;
+*/
+int fe25519_isnegative(const fe f) {
+ unsigned char s[32];
+ int r;
+ fe25519_tobytes(s,f);
+ r = s[0] & 1;
+ cleanup(s);
+ return r;
+}
diff --git a/lib/Utils.Cryptography/monocypher/vendor/tests/externals/tinyssh/fe25519.h b/lib/Utils.Cryptography/monocypher/vendor/tests/externals/tinyssh/fe25519.h
new file mode 100644
index 0000000..2722d26
--- /dev/null
+++ b/lib/Utils.Cryptography/monocypher/vendor/tests/externals/tinyssh/fe25519.h
@@ -0,0 +1,22 @@
+#ifndef _FE25519_H____
+#define _FE25519_H____
+
+#include "fe.h"
+
+extern void fe25519_mul(fe, const fe, const fe);
+extern void fe25519_sq(fe, const fe);
+extern void fe25519_add(fe, const fe, const fe);
+extern void fe25519_mul121666(fe, const fe);
+extern void fe25519_sub(fe, const fe, const fe);
+extern void fe25519_neg(fe, const fe);
+extern void fe25519_inv(fe, const fe);
+extern void fe25519_pow22523(fe, const fe);
+
+extern void fe25519_tobytes(unsigned char *, const fe);
+extern void fe25519_frombytes(fe, const unsigned char *);
+
+extern int fe25519_isnonzero(const fe);
+extern int fe25519_isnegative(const fe);
+
+#endif
+
diff --git a/lib/Utils.Cryptography/monocypher/vendor/tests/externals/tinyssh/ge25519.c b/lib/Utils.Cryptography/monocypher/vendor/tests/externals/tinyssh/ge25519.c
new file mode 100644
index 0000000..31af206
--- /dev/null
+++ b/lib/Utils.Cryptography/monocypher/vendor/tests/externals/tinyssh/ge25519.c
@@ -0,0 +1,226 @@
+#include "fe25519.h"
+#include "cleanup.h"
+#include "ge25519.h"
+
+/* D = -121665/121666 */
+static fe D = {
+ 0x135978a3, 0x75eb4dca, 0x4141d8ab, 0x00700a4d,
+ 0x7779e898, 0x8cc74079, 0x2b6ffe73, 0x52036cee
+};
+/* D2 = 2 * -121665/121666 */
+static fe D2 = {
+ 0x26b2f159, 0xebd69b94, 0x8283b156, 0x00e0149a,
+ 0xeef3d130, 0x198e80f2, 0x56dffce7, 0x2406d9dc
+};
+
+static fe sqrtm1 = {
+ 0x4a0ea0b0, 0xc4ee1b27, 0xad2fe478, 0x2f431806,
+ 0x3dfbd7a7, 0x2b4d0099, 0x4fc1df0b, 0x2b832480,
+};
+
+static void neutral(ge25519 p) {
+ fe_0(p[0]);
+ fe_1(p[1]);
+ fe_1(p[2]);
+ fe_0(p[3]);
+}
+
+
+/*
+p = q
+*/
+static void copy(ge25519 p, ge25519 q) {
+
+ fe_copy(p[0], q[0]);
+ fe_copy(p[1], q[1]);
+ fe_copy(p[2], q[2]);
+ fe_copy(p[3], q[3]);
+}
+
+
+/*
+if (b) p = q;
+*/
+static void cmov(ge25519 p, ge25519 q, crypto_uint32 b) {
+
+ fe_cmov(p[0], q[0], b);
+ fe_cmov(p[1], q[1], b);
+ fe_cmov(p[2], q[2], b);
+ fe_cmov(p[3], q[3], b);
+}
+
+void ge25519_add(ge25519 o, ge25519 p, ge25519 q) {
+
+ fe a, b, c, d, t, e, f, g, h;
+
+ fe25519_sub(a, p[1], p[0]);
+ fe25519_sub(t, q[1], q[0]);
+ fe25519_mul(a, a, t);
+ fe25519_add(b, p[0], p[1]);
+ fe25519_add(t, q[0], q[1]);
+ fe25519_mul(b, b, t);
+ fe25519_mul(c, p[3], q[3]);
+ fe25519_mul(c, c, D2);
+ fe25519_mul(d, p[2], q[2]);
+ fe25519_add(d, d, d);
+ fe25519_sub(e, b, a);
+ fe25519_sub(f, d, c);
+ fe25519_add(g, d, c);
+ fe25519_add(h, b, a);
+
+ fe25519_mul(o[0], e, f);
+ fe25519_mul(o[1], h, g);
+ fe25519_mul(o[2], g, f);
+ fe25519_mul(o[3], e, h);
+
+ cleanup(a); cleanup(b); cleanup(c); cleanup(d); cleanup(t);
+ cleanup(e); cleanup(f); cleanup(g); cleanup(h);
+}
+
+
+/* https://hyperelliptic.org/EFD/g1p/auto-code/twisted/extended/doubling/dbl-2008-hwcd.op3 */
+static void dbl(ge25519 o, ge25519 p) {
+
+ fe a, b, c, d, e, f, g, h;
+
+ fe25519_sq(a, p[0]); /* A = X1^2 */
+ fe25519_sq(b, p[1]); /* B = Y1^2 */
+ fe25519_sq(c, p[2]); /* t0 = Z1^2 */
+ fe25519_add(c, c, c); /* C = 2*t0 */
+ fe25519_neg(d, a); /* D = a*A */
+ fe25519_add(e, p[0], p[1]); /* t1 = X1+Y1 */
+ fe25519_sq(e, e); /* t2 = t1^2 */
+ fe25519_sub(e, e, a); /* t3 = t2-A */
+ fe25519_sub(e, e, b); /* E = t3-B */
+ fe25519_add(g, d, b); /* G = D+B */
+ fe25519_sub(f, g, c); /* F = G-C */
+ fe25519_sub(h, d, b); /* H = D-B */
+
+ fe25519_mul(o[0], e, f); /* X3 = E*F */
+ fe25519_mul(o[1], g, h); /* Y3 = G*H */
+ fe25519_mul(o[2], f, g); /* Z3 = F*G */
+ fe25519_mul(o[3], e, h); /* T3 = E*H */
+
+ cleanup(a); cleanup(b); cleanup(c); cleanup(d);
+ cleanup(e); cleanup(f); cleanup(g); cleanup(h);
+}
+
+
+void ge25519_tobytes(unsigned char *s, ge25519 h) {
+
+ fe x, y, z;
+
+ fe25519_inv(z, h[2]);
+ fe25519_mul(x, h[0], z);
+ fe25519_mul(y, h[1], z);
+ fe25519_tobytes(s, y);
+ s[31] ^= fe25519_isnegative(x) << 7;
+
+ cleanup(x); cleanup(y); cleanup(z);
+}
+
+int ge25519_frombytes_negate_vartime(ge25519 h, const unsigned char *s) {
+
+ fe u, v, v3, vxx, check;
+ int ret = -1;
+
+ fe25519_frombytes(h[1], s);
+ fe_1(h[2]);
+ fe25519_sq(u,h[1]);
+ fe25519_mul(v,u,D);
+ fe25519_sub(u,u,h[2]); /* u = y^2-1 */
+ fe25519_add(v,v,h[2]); /* v = dy^2+1 */
+
+ fe25519_sq(v3,v);
+ fe25519_mul(v3,v3,v); /* v3 = v^3 */
+ fe25519_sq(h[0],v3);
+ fe25519_mul(h[0],h[0],v);
+ fe25519_mul(h[0],h[0],u); /* x = uv^7 */
+
+ fe25519_pow22523(h[0],h[0]); /* x = (uv^7)^((q-5)/8) */
+ fe25519_mul(h[0],h[0],v3);
+ fe25519_mul(h[0],h[0],u); /* x = uv^3(uv^7)^((q-5)/8) */
+
+ fe25519_sq(vxx,h[0]);
+ fe25519_mul(vxx,vxx,v);
+ fe25519_sub(check,vxx,u); /* vx^2-u */
+ if (fe25519_isnonzero(check)) {
+ fe25519_add(check,vxx,u); /* vx^2+u */
+ if (fe25519_isnonzero(check)) {
+ goto cleanup;
+ }
+ fe25519_mul(h[0],h[0],sqrtm1);
+ }
+
+ if (fe25519_isnegative(h[0]) == (s[31] >> 7))
+ fe25519_neg(h[0], h[0]);
+
+ fe25519_mul(h[3],h[0],h[1]);
+ ret = 0;
+
+cleanup:
+ cleanup(u); cleanup(v); cleanup(v3);
+ cleanup(vxx); cleanup(check);
+ return ret;
+}
+
+
+/*
+if (a == b) return 1;
+else return 0;
+*/
+static unsigned char equal(unsigned char a, unsigned char b) {
+
+ unsigned char x = a ^ b;
+ crypto_uint32 y = x;
+ y -= 1;
+ y >>= 31;
+ return y;
+}
+
+/*
+point multiplication using windowed method
+*/
+void ge25519_scalarmult(ge25519 o, ge25519 q, const unsigned char *a) {
+
+ long long i, j;
+ ge25519 t[16], sp, p;
+ unsigned char e[64];
+
+ for (i = 0; i < 32; ++i) {
+ e[2 * i + 0] = (a[i] >> 0) & 0x0f;
+ e[2 * i + 1] = (a[i] >> 4) & 0x0f;
+ }
+
+ neutral(p);
+
+ /* precompute points */
+ copy(t[0], p);
+ copy(t[1], q);
+ for (i = 2; i < 16; ++i) {
+ if ((i & 1) == 0) dbl(t[i], t[i / 2]);
+ else ge25519_add(t[i], t[i - 1], q);
+ }
+
+ for (i = 63; i >= 0; --i) {
+ for (j = 0; j < 4; ++j) dbl(p, p);
+ for (j = 0; j < 16; ++j) cmov(sp, t[j], equal(e[i], j));
+ ge25519_add(p, p, sp);
+ }
+
+ copy(o, p);
+
+ cleanup(p); cleanup(t); cleanup(sp); cleanup(e);
+}
+
+static ge25519 baseq = {
+ { 0x8f25d51a,0xc9562d60,0x9525a7b2,0x692cc760,0xfdd6dc5c,0xc0a4e231,0xcd6e53fe,0x216936d3 },
+ { 0x66666658,0x66666666,0x66666666,0x66666666,0x66666666,0x66666666,0x66666666,0x66666666 },
+ { 0x00000001,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000 },
+ { 0xa5b7dda3,0x6dde8ab3,0x775152f5,0x20f09f80,0x64abe37d,0x66ea4e8e,0xd78b7665,0x67875f0f },
+ };
+
+void ge25519_scalarmult_base(ge25519 p, const unsigned char *a) {
+
+ ge25519_scalarmult(p, baseq, a);
+}
diff --git a/lib/Utils.Cryptography/monocypher/vendor/tests/externals/tinyssh/ge25519.h b/lib/Utils.Cryptography/monocypher/vendor/tests/externals/tinyssh/ge25519.h
new file mode 100644
index 0000000..0428b73
--- /dev/null
+++ b/lib/Utils.Cryptography/monocypher/vendor/tests/externals/tinyssh/ge25519.h
@@ -0,0 +1,14 @@
+#ifndef _GE25519_H____
+#define _GE25519_H____
+
+#include "fe.h"
+
+typedef fe ge25519[4]; /* X, Y, Z, T */
+
+extern void ge25519_tobytes(unsigned char *, ge25519);
+extern int ge25519_frombytes_negate_vartime(ge25519, const unsigned char *);
+extern void ge25519_add(ge25519, ge25519, ge25519);
+extern void ge25519_scalarmult(ge25519, ge25519, const unsigned char *);
+extern void ge25519_scalarmult_base(ge25519, const unsigned char *);
+
+#endif
diff --git a/lib/Utils.Cryptography/monocypher/vendor/tests/externals/tinyssh/randombytes.c b/lib/Utils.Cryptography/monocypher/vendor/tests/externals/tinyssh/randombytes.c
new file mode 100644
index 0000000..95645a9
--- /dev/null
+++ b/lib/Utils.Cryptography/monocypher/vendor/tests/externals/tinyssh/randombytes.c
@@ -0,0 +1,41 @@
+/* taken from nacl-20110221, from randombytes/devurandom.c, added close-on-exec */
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include "randombytes.h"
+
+/* it's really stupid that there isn't a syscall for this */
+
+static int fd = -1;
+
+void randombytes(unsigned char *x,unsigned long long xlen)
+{
+ int i;
+
+ if (fd == -1) {
+ for (;;) {
+#ifdef O_CLOEXEC
+ fd = open("/dev/urandom",O_RDONLY | O_CLOEXEC);
+#else
+ fd = open("/dev/urandom",O_RDONLY);
+ fcntl(fd,F_SETFD,1);
+#endif
+ if (fd != -1) break;
+ sleep(1);
+ }
+ }
+
+ while (xlen > 0) {
+ if (xlen < 1048576) i = xlen; else i = 1048576;
+
+ i = read(fd,x,i);
+ if (i < 1) {
+ sleep(1);
+ continue;
+ }
+
+ x += i;
+ xlen -= i;
+ }
+}
diff --git a/lib/Utils.Cryptography/monocypher/vendor/tests/externals/tinyssh/randombytes.h b/lib/Utils.Cryptography/monocypher/vendor/tests/externals/tinyssh/randombytes.h
new file mode 100644
index 0000000..724104f
--- /dev/null
+++ b/lib/Utils.Cryptography/monocypher/vendor/tests/externals/tinyssh/randombytes.h
@@ -0,0 +1,10 @@
+#ifndef _RANDOMBYTES_H____
+#define _RANDOMBYTES_H____
+
+extern void randombytes(unsigned char *, unsigned long long);
+
+#ifndef randombytes_implementation
+#define randombytes_implementation "tinyssh"
+#endif
+
+#endif
diff --git a/lib/Utils.Cryptography/monocypher/vendor/tests/externals/tinyssh/sc25519.c b/lib/Utils.Cryptography/monocypher/vendor/tests/externals/tinyssh/sc25519.c
new file mode 100644
index 0000000..12610c3
--- /dev/null
+++ b/lib/Utils.Cryptography/monocypher/vendor/tests/externals/tinyssh/sc25519.c
@@ -0,0 +1,67 @@
+/*
+- based on tweetnacl 20140427 (http://tweetnacl.cr.yp.to/software.html)
+*/
+
+#include "crypto_int64.h"
+#include "crypto_uint32.h"
+#include "crypto_uint64.h"
+#include "cleanup.h"
+#include "sc25519.h"
+
+#define FOR(i,n) for (i = 0;i < n;++i)
+
+static const crypto_uint64 L[32] = {0xed, 0xd3, 0xf5, 0x5c, 0x1a, 0x63, 0x12, 0x58, 0xd6, 0x9c, 0xf7, 0xa2, 0xde, 0xf9, 0xde, 0x14, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x10};
+
+static void modL(unsigned char *r,crypto_int64 x[64])
+{
+ crypto_int64 carry,i,j;
+ for (i = 63;i >= 32;--i) {
+ carry = 0;
+ for (j = i - 32;j < i - 12;++j) {
+ x[j] += carry - 16 * x[i] * L[j - (i - 32)];
+ carry = (x[j] + 128) >> 8;
+ x[j] -= carry << 8;
+ }
+ x[j] += carry;
+ x[i] = 0;
+ }
+ carry = 0;
+ FOR(j,32) {
+ x[j] += carry - (x[31] >> 4) * L[j];
+ carry = x[j] >> 8;
+ x[j] &= 255;
+ }
+ FOR(j,32) x[j] -= carry * L[j];
+ FOR(i,32) {
+ x[i+1] += x[i] >> 8;
+ r[i] = x[i] & 255;
+ }
+}
+
+void sc25519_reduce(unsigned char *s) {
+
+ crypto_int64 t[64], i;
+
+ for (i = 0; i < 64; ++i) t[i] = s[i];
+ for (i = 0; i < 64; ++i) s[i] = 0;
+ modL(s, t);
+
+ cleanup(t);
+}
+
+void sc25519_muladd(unsigned char *s, const unsigned char *a, const unsigned char *b, const unsigned char *c) {
+
+ crypto_int64 t[64], i, j;
+
+
+ for (i = 0; i < 64; ++i) t[i] = 0;
+
+ for (i = 0; i < 32; ++i) for (j = 0; j < 32; ++j) {
+ t[i + j] += (crypto_int64)a[i] * (crypto_int64)b[j];
+ }
+
+ for (i = 0; i < 32; ++i) t[i] += c[i];
+ modL(s, t);
+
+ cleanup(t);
+}
diff --git a/lib/Utils.Cryptography/monocypher/vendor/tests/externals/tinyssh/sc25519.h b/lib/Utils.Cryptography/monocypher/vendor/tests/externals/tinyssh/sc25519.h
new file mode 100644
index 0000000..c08df70
--- /dev/null
+++ b/lib/Utils.Cryptography/monocypher/vendor/tests/externals/tinyssh/sc25519.h
@@ -0,0 +1,7 @@
+#ifndef _SC25519_H____
+#define _SC25519_H____
+
+extern void sc25519_reduce(unsigned char *);
+extern void sc25519_muladd(unsigned char *, const unsigned char *, const unsigned char *, const unsigned char *);
+
+#endif
diff --git a/lib/Utils.Cryptography/monocypher/vendor/tests/externals/tinyssh/uint32_pack.c b/lib/Utils.Cryptography/monocypher/vendor/tests/externals/tinyssh/uint32_pack.c
new file mode 100644
index 0000000..8bf87fb
--- /dev/null
+++ b/lib/Utils.Cryptography/monocypher/vendor/tests/externals/tinyssh/uint32_pack.c
@@ -0,0 +1,11 @@
+#include "uint32_pack.h"
+
+/*
+The 'uint32_pack' function converts 32-bit unsigned
+integer into 4 bytes stored in little-endian format
+*/
+void uint32_pack(unsigned char *y, crypto_uint32 x) {
+
+ long long i;
+ for (i = 0; i < 4; ++i) { y[i] = x; x >>= 8; }
+}
diff --git a/lib/Utils.Cryptography/monocypher/vendor/tests/externals/tinyssh/uint32_pack.h b/lib/Utils.Cryptography/monocypher/vendor/tests/externals/tinyssh/uint32_pack.h
new file mode 100644
index 0000000..6f4f053
--- /dev/null
+++ b/lib/Utils.Cryptography/monocypher/vendor/tests/externals/tinyssh/uint32_pack.h
@@ -0,0 +1,8 @@
+#ifndef _UINT32_PACK_H____
+#define _UINT32_PACK_H____
+
+#include "crypto_uint32.h"
+
+extern void uint32_pack(unsigned char *, crypto_uint32);
+
+#endif
diff --git a/lib/Utils.Cryptography/monocypher/vendor/tests/externals/tinyssh/uint32_unpack.c b/lib/Utils.Cryptography/monocypher/vendor/tests/externals/tinyssh/uint32_unpack.c
new file mode 100644
index 0000000..172c65d
--- /dev/null
+++ b/lib/Utils.Cryptography/monocypher/vendor/tests/externals/tinyssh/uint32_unpack.c
@@ -0,0 +1,13 @@
+#include "uint32_unpack.h"
+
+/*
+The 'uint32_unpack' function converts 4 bytes
+in little-endian format into 32-bit unsigned integer.
+*/
+crypto_uint32 uint32_unpack(const unsigned char *x) {
+
+ crypto_uint32 y = 0;
+ long long i;
+ for (i = 3; i >= 0; --i) y = (y << 8) | x[i];
+ return y;
+}
diff --git a/lib/Utils.Cryptography/monocypher/vendor/tests/externals/tinyssh/uint32_unpack.h b/lib/Utils.Cryptography/monocypher/vendor/tests/externals/tinyssh/uint32_unpack.h
new file mode 100644
index 0000000..fb0588a
--- /dev/null
+++ b/lib/Utils.Cryptography/monocypher/vendor/tests/externals/tinyssh/uint32_unpack.h
@@ -0,0 +1,8 @@
+#ifndef _UINT32_UNPACK_H____
+#define _UINT32_UNPACK_H____
+
+#include "crypto_uint32.h"
+
+extern crypto_uint32 uint32_unpack(const unsigned char *);
+
+#endif
diff --git a/lib/Utils.Cryptography/monocypher/vendor/tests/externals/tinyssh/verify.c b/lib/Utils.Cryptography/monocypher/vendor/tests/externals/tinyssh/verify.c
new file mode 100644
index 0000000..9dcf121
--- /dev/null
+++ b/lib/Utils.Cryptography/monocypher/vendor/tests/externals/tinyssh/verify.c
@@ -0,0 +1,10 @@
+#include "verify.h"
+
+int verify(const unsigned char *x, const unsigned char *y, long long n) {
+
+ unsigned int d = 0;
+ long long i;
+
+ for (i = 0; i < n; ++i) d |= x[i] ^ y[i];
+ return (1 & ((d - 1) >> 8)) - 1;
+}
diff --git a/lib/Utils.Cryptography/monocypher/vendor/tests/externals/tinyssh/verify.h b/lib/Utils.Cryptography/monocypher/vendor/tests/externals/tinyssh/verify.h
new file mode 100644
index 0000000..718b831
--- /dev/null
+++ b/lib/Utils.Cryptography/monocypher/vendor/tests/externals/tinyssh/verify.h
@@ -0,0 +1,6 @@
+#ifndef _VERIFY_H____
+#define _VERIFY_H____
+
+extern int verify(const unsigned char *, const unsigned char *, long long);
+
+#endif
diff --git a/lib/Utils.Cryptography/monocypher/vendor/tests/externals/tweetnacl/AUTHORS.md b/lib/Utils.Cryptography/monocypher/vendor/tests/externals/tweetnacl/AUTHORS.md
new file mode 100644
index 0000000..e3300f3
--- /dev/null
+++ b/lib/Utils.Cryptography/monocypher/vendor/tests/externals/tweetnacl/AUTHORS.md
@@ -0,0 +1,20 @@
+The code of TweetNaCl has been written by:
+
+* Daniel J. Bernstein
+* Bernard von Gastel
+* Wesley Janssen
+* Tanja Lange
+* Peter Schwabe
+* Sjaak Smetsers
+
+TweetNaCl has been dedicated to the public domain;
+refer to <https://tweetnacl.cr.yp.to/>
+("TweetNaCl is a self-contained public-domain C library, [...]")
+and Daniel J. Bernstein et al., TweetNaCl: a crypto library in
+100 tweets, LATINCRYPT 2014, pp. 64-83, (also available from
+<https://tweetnacl.cr.yp.to/tweetnacl-20140917.pdf>), p. 3:
+"We have placed TweetNaCl into the public domain, and we encourage
+applications to make use of it".
+
+TweetNaCl has been obtained via <https://tweetnacl.cr.yp.to/>.
+
diff --git a/lib/Utils.Cryptography/monocypher/vendor/tests/externals/tweetnacl/tweetnacl.c b/lib/Utils.Cryptography/monocypher/vendor/tests/externals/tweetnacl/tweetnacl.c
new file mode 100644
index 0000000..8ac0a18
--- /dev/null
+++ b/lib/Utils.Cryptography/monocypher/vendor/tests/externals/tweetnacl/tweetnacl.c
@@ -0,0 +1,809 @@
+#include "tweetnacl.h"
+#define FOR(i,n) for (i = 0;i < n;++i)
+#define sv static void
+
+typedef unsigned char u8;
+typedef unsigned long u32;
+typedef unsigned long long u64;
+typedef long long i64;
+typedef i64 gf[16];
+extern void randombytes(u8 *,u64);
+
+static const u8
+ _0[16],
+ _9[32] = {9};
+static const gf
+ gf0,
+ gf1 = {1},
+ _121665 = {0xDB41,1},
+ D = {0x78a3, 0x1359, 0x4dca, 0x75eb, 0xd8ab, 0x4141, 0x0a4d, 0x0070, 0xe898, 0x7779, 0x4079, 0x8cc7, 0xfe73, 0x2b6f, 0x6cee, 0x5203},
+ D2 = {0xf159, 0x26b2, 0x9b94, 0xebd6, 0xb156, 0x8283, 0x149a, 0x00e0, 0xd130, 0xeef3, 0x80f2, 0x198e, 0xfce7, 0x56df, 0xd9dc, 0x2406},
+ X = {0xd51a, 0x8f25, 0x2d60, 0xc956, 0xa7b2, 0x9525, 0xc760, 0x692c, 0xdc5c, 0xfdd6, 0xe231, 0xc0a4, 0x53fe, 0xcd6e, 0x36d3, 0x2169},
+ Y = {0x6658, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666},
+ I = {0xa0b0, 0x4a0e, 0x1b27, 0xc4ee, 0xe478, 0xad2f, 0x1806, 0x2f43, 0xd7a7, 0x3dfb, 0x0099, 0x2b4d, 0xdf0b, 0x4fc1, 0x2480, 0x2b83};
+
+static u32 L32(u32 x,int c) { return (x << c) | ((x&0xffffffff) >> (32 - c)); }
+
+static u32 ld32(const u8 *x)
+{
+ u32 u = x[3];
+ u = (u<<8)|x[2];
+ u = (u<<8)|x[1];
+ return (u<<8)|x[0];
+}
+
+static u64 dl64(const u8 *x)
+{
+ u64 i,u=0;
+ FOR(i,8) u=(u<<8)|x[i];
+ return u;
+}
+
+sv st32(u8 *x,u32 u)
+{
+ int i;
+ FOR(i,4) { x[i] = u; u >>= 8; }
+}
+
+sv ts64(u8 *x,u64 u)
+{
+ int i;
+ for (i = 7;i >= 0;--i) { x[i] = u; u >>= 8; }
+}
+
+static int vn(const u8 *x,const u8 *y,int n)
+{
+ u32 i,d = 0;
+ FOR(i,n) d |= x[i]^y[i];
+ return (1 & ((d - 1) >> 8)) - 1;
+}
+
+int crypto_verify_16(const u8 *x,const u8 *y)
+{
+ return vn(x,y,16);
+}
+
+int crypto_verify_32(const u8 *x,const u8 *y)
+{
+ return vn(x,y,32);
+}
+
+sv core(u8 *out,const u8 *in,const u8 *k,const u8 *c,int h)
+{
+ u32 w[16],x[16],y[16],t[4];
+ int i,j,m;
+
+ FOR(i,4) {
+ x[5*i] = ld32(c+4*i);
+ x[1+i] = ld32(k+4*i);
+ x[6+i] = ld32(in+4*i);
+ x[11+i] = ld32(k+16+4*i);
+ }
+
+ FOR(i,16) y[i] = x[i];
+
+ FOR(i,20) {
+ FOR(j,4) {
+ FOR(m,4) t[m] = x[(5*j+4*m)%16];
+ t[1] ^= L32(t[0]+t[3], 7);
+ t[2] ^= L32(t[1]+t[0], 9);
+ t[3] ^= L32(t[2]+t[1],13);
+ t[0] ^= L32(t[3]+t[2],18);
+ FOR(m,4) w[4*j+(j+m)%4] = t[m];
+ }
+ FOR(m,16) x[m] = w[m];
+ }
+
+ if (h) {
+ FOR(i,16) x[i] += y[i];
+ FOR(i,4) {
+ x[5*i] -= ld32(c+4*i);
+ x[6+i] -= ld32(in+4*i);
+ }
+ FOR(i,4) {
+ st32(out+4*i,x[5*i]);
+ st32(out+16+4*i,x[6+i]);
+ }
+ } else
+ FOR(i,16) st32(out + 4 * i,x[i] + y[i]);
+}
+
+int crypto_core_salsa20(u8 *out,const u8 *in,const u8 *k,const u8 *c)
+{
+ core(out,in,k,c,0);
+ return 0;
+}
+
+int crypto_core_hsalsa20(u8 *out,const u8 *in,const u8 *k,const u8 *c)
+{
+ core(out,in,k,c,1);
+ return 0;
+}
+
+static const u8 sigma[16] = "expand 32-byte k";
+
+int crypto_stream_salsa20_xor(u8 *c,const u8 *m,u64 b,const u8 *n,const u8 *k)
+{
+ u8 z[16],x[64];
+ u32 u,i;
+ if (!b) return 0;
+ FOR(i,16) z[i] = 0;
+ FOR(i,8) z[i] = n[i];
+ while (b >= 64) {
+ crypto_core_salsa20(x,z,k,sigma);
+ FOR(i,64) c[i] = (m?m[i]:0) ^ x[i];
+ u = 1;
+ for (i = 8;i < 16;++i) {
+ u += (u32) z[i];
+ z[i] = u;
+ u >>= 8;
+ }
+ b -= 64;
+ c += 64;
+ if (m) m += 64;
+ }
+ if (b) {
+ crypto_core_salsa20(x,z,k,sigma);
+ FOR(i,b) c[i] = (m?m[i]:0) ^ x[i];
+ }
+ return 0;
+}
+
+int crypto_stream_salsa20(u8 *c,u64 d,const u8 *n,const u8 *k)
+{
+ return crypto_stream_salsa20_xor(c,0,d,n,k);
+}
+
+int crypto_stream(u8 *c,u64 d,const u8 *n,const u8 *k)
+{
+ u8 s[32];
+ crypto_core_hsalsa20(s,n,k,sigma);
+ return crypto_stream_salsa20(c,d,n+16,s);
+}
+
+int crypto_stream_xor(u8 *c,const u8 *m,u64 d,const u8 *n,const u8 *k)
+{
+ u8 s[32];
+ crypto_core_hsalsa20(s,n,k,sigma);
+ return crypto_stream_salsa20_xor(c,m,d,n+16,s);
+}
+
+sv add1305(u32 *h,const u32 *c)
+{
+ u32 j,u = 0;
+ FOR(j,17) {
+ u += h[j] + c[j];
+ h[j] = u & 255;
+ u >>= 8;
+ }
+}
+
+static const u32 minusp[17] = {
+ 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 252
+} ;
+
+int crypto_onetimeauth(u8 *out,const u8 *m,u64 n,const u8 *k)
+{
+ u32 s,i,j,u,x[17],r[17],h[17],c[17],g[17];
+
+ FOR(j,17) r[j]=h[j]=0;
+ FOR(j,16) r[j]=k[j];
+ r[3]&=15;
+ r[4]&=252;
+ r[7]&=15;
+ r[8]&=252;
+ r[11]&=15;
+ r[12]&=252;
+ r[15]&=15;
+
+ while (n > 0) {
+ FOR(j,17) c[j] = 0;
+ for (j = 0;(j < 16) && (j < n);++j) c[j] = m[j];
+ c[j] = 1;
+ m += j; n -= j;
+ add1305(h,c);
+ FOR(i,17) {
+ x[i] = 0;
+ FOR(j,17) x[i] += h[j] * ((j <= i) ? r[i - j] : 320 * r[i + 17 - j]);
+ }
+ FOR(i,17) h[i] = x[i];
+ u = 0;
+ FOR(j,16) {
+ u += h[j];
+ h[j] = u & 255;
+ u >>= 8;
+ }
+ u += h[16]; h[16] = u & 3;
+ u = 5 * (u >> 2);
+ FOR(j,16) {
+ u += h[j];
+ h[j] = u & 255;
+ u >>= 8;
+ }
+ u += h[16]; h[16] = u;
+ }
+
+ FOR(j,17) g[j] = h[j];
+ add1305(h,minusp);
+ s = -(h[16] >> 7);
+ FOR(j,17) h[j] ^= s & (g[j] ^ h[j]);
+
+ FOR(j,16) c[j] = k[j + 16];
+ c[16] = 0;
+ add1305(h,c);
+ FOR(j,16) out[j] = h[j];
+ return 0;
+}
+
+int crypto_onetimeauth_verify(const u8 *h,const u8 *m,u64 n,const u8 *k)
+{
+ u8 x[16];
+ crypto_onetimeauth(x,m,n,k);
+ return crypto_verify_16(h,x);
+}
+
+int crypto_secretbox(u8 *c,const u8 *m,u64 d,const u8 *n,const u8 *k)
+{
+ int i;
+ if (d < 32) return -1;
+ crypto_stream_xor(c,m,d,n,k);
+ crypto_onetimeauth(c + 16,c + 32,d - 32,c);
+ FOR(i,16) c[i] = 0;
+ return 0;
+}
+
+int crypto_secretbox_open(u8 *m,const u8 *c,u64 d,const u8 *n,const u8 *k)
+{
+ int i;
+ u8 x[32];
+ if (d < 32) return -1;
+ crypto_stream(x,32,n,k);
+ if (crypto_onetimeauth_verify(c + 16,c + 32,d - 32,x) != 0) return -1;
+ crypto_stream_xor(m,c,d,n,k);
+ FOR(i,32) m[i] = 0;
+ return 0;
+}
+
+sv set25519(gf r, const gf a)
+{
+ int i;
+ FOR(i,16) r[i]=a[i];
+}
+
+sv car25519(gf o)
+{
+ int i;
+ i64 c;
+ FOR(i,16) {
+ o[i]+=(1LL<<16);
+ c=o[i]>>16;
+ o[(i+1)*(i<15)]+=c-1+37*(c-1)*(i==15);
+ o[i]-=c<<16;
+ }
+}
+
+sv sel25519(gf p,gf q,int b)
+{
+ i64 t,i,c=~(b-1);
+ FOR(i,16) {
+ t= c&(p[i]^q[i]);
+ p[i]^=t;
+ q[i]^=t;
+ }
+}
+
+sv pack25519(u8 *o,const gf n)
+{
+ int i,j,b;
+ gf m,t;
+ FOR(i,16) t[i]=n[i];
+ car25519(t);
+ car25519(t);
+ car25519(t);
+ FOR(j,2) {
+ m[0]=t[0]-0xffed;
+ for(i=1;i<15;i++) {
+ m[i]=t[i]-0xffff-((m[i-1]>>16)&1);
+ m[i-1]&=0xffff;
+ }
+ m[15]=t[15]-0x7fff-((m[14]>>16)&1);
+ b=(m[15]>>16)&1;
+ m[14]&=0xffff;
+ sel25519(t,m,1-b);
+ }
+ FOR(i,16) {
+ o[2*i]=t[i]&0xff;
+ o[2*i+1]=t[i]>>8;
+ }
+}
+
+static int neq25519(const gf a, const gf b)
+{
+ u8 c[32],d[32];
+ pack25519(c,a);
+ pack25519(d,b);
+ return crypto_verify_32(c,d);
+}
+
+static u8 par25519(const gf a)
+{
+ u8 d[32];
+ pack25519(d,a);
+ return d[0]&1;
+}
+
+sv unpack25519(gf o, const u8 *n)
+{
+ int i;
+ FOR(i,16) o[i]=n[2*i]+((i64)n[2*i+1]<<8);
+ o[15]&=0x7fff;
+}
+
+sv A(gf o,const gf a,const gf b)
+{
+ int i;
+ FOR(i,16) o[i]=a[i]+b[i];
+}
+
+sv Z(gf o,const gf a,const gf b)
+{
+ int i;
+ FOR(i,16) o[i]=a[i]-b[i];
+}
+
+sv M(gf o,const gf a,const gf b)
+{
+ i64 i,j,t[31];
+ FOR(i,31) t[i]=0;
+ FOR(i,16) FOR(j,16) t[i+j]+=a[i]*b[j];
+ FOR(i,15) t[i]+=38*t[i+16];
+ FOR(i,16) o[i]=t[i];
+ car25519(o);
+ car25519(o);
+}
+
+sv S(gf o,const gf a)
+{
+ M(o,a,a);
+}
+
+sv inv25519(gf o,const gf i)
+{
+ gf c;
+ int a;
+ FOR(a,16) c[a]=i[a];
+ for(a=253;a>=0;a--) {
+ S(c,c);
+ if(a!=2&&a!=4) M(c,c,i);
+ }
+ FOR(a,16) o[a]=c[a];
+}
+
+sv pow2523(gf o,const gf i)
+{
+ gf c;
+ int a;
+ FOR(a,16) c[a]=i[a];
+ for(a=250;a>=0;a--) {
+ S(c,c);
+ if(a!=1) M(c,c,i);
+ }
+ FOR(a,16) o[a]=c[a];
+}
+
+int crypto_scalarmult(u8 *q,const u8 *n,const u8 *p)
+{
+ u8 z[32];
+ i64 x[80],r,i;
+ gf a,b,c,d,e,f;
+ FOR(i,31) z[i]=n[i];
+ z[31]=(n[31]&127)|64;
+ z[0]&=248;
+ unpack25519(x,p);
+ FOR(i,16) {
+ b[i]=x[i];
+ d[i]=a[i]=c[i]=0;
+ }
+ a[0]=d[0]=1;
+ for(i=254;i>=0;--i) {
+ r=(z[i>>3]>>(i&7))&1;
+ sel25519(a,b,r);
+ sel25519(c,d,r);
+ A(e,a,c);
+ Z(a,a,c);
+ A(c,b,d);
+ Z(b,b,d);
+ S(d,e);
+ S(f,a);
+ M(a,c,a);
+ M(c,b,e);
+ A(e,a,c);
+ Z(a,a,c);
+ S(b,a);
+ Z(c,d,f);
+ M(a,c,_121665);
+ A(a,a,d);
+ M(c,c,a);
+ M(a,d,f);
+ M(d,b,x);
+ S(b,e);
+ sel25519(a,b,r);
+ sel25519(c,d,r);
+ }
+ FOR(i,16) {
+ x[i+16]=a[i];
+ x[i+32]=c[i];
+ x[i+48]=b[i];
+ x[i+64]=d[i];
+ }
+ inv25519(x+32,x+32);
+ M(x+16,x+16,x+32);
+ pack25519(q,x+16);
+ return 0;
+}
+
+int crypto_scalarmult_base(u8 *q,const u8 *n)
+{
+ return crypto_scalarmult(q,n,_9);
+}
+
+int crypto_box_keypair(u8 *y,u8 *x)
+{
+ randombytes(x,32);
+ return crypto_scalarmult_base(y,x);
+}
+
+int crypto_box_beforenm(u8 *k,const u8 *y,const u8 *x)
+{
+ u8 s[32];
+ crypto_scalarmult(s,x,y);
+ return crypto_core_hsalsa20(k,_0,s,sigma);
+}
+
+int crypto_box_afternm(u8 *c,const u8 *m,u64 d,const u8 *n,const u8 *k)
+{
+ return crypto_secretbox(c,m,d,n,k);
+}
+
+int crypto_box_open_afternm(u8 *m,const u8 *c,u64 d,const u8 *n,const u8 *k)
+{
+ return crypto_secretbox_open(m,c,d,n,k);
+}
+
+int crypto_box(u8 *c,const u8 *m,u64 d,const u8 *n,const u8 *y,const u8 *x)
+{
+ u8 k[32];
+ crypto_box_beforenm(k,y,x);
+ return crypto_box_afternm(c,m,d,n,k);
+}
+
+int crypto_box_open(u8 *m,const u8 *c,u64 d,const u8 *n,const u8 *y,const u8 *x)
+{
+ u8 k[32];
+ crypto_box_beforenm(k,y,x);
+ return crypto_box_open_afternm(m,c,d,n,k);
+}
+
+static u64 R(u64 x,int c) { return (x >> c) | (x << (64 - c)); }
+static u64 Ch(u64 x,u64 y,u64 z) { return (x & y) ^ (~x & z); }
+static u64 Maj(u64 x,u64 y,u64 z) { return (x & y) ^ (x & z) ^ (y & z); }
+static u64 Sigma0(u64 x) { return R(x,28) ^ R(x,34) ^ R(x,39); }
+static u64 Sigma1(u64 x) { return R(x,14) ^ R(x,18) ^ R(x,41); }
+static u64 sigma0(u64 x) { return R(x, 1) ^ R(x, 8) ^ (x >> 7); }
+static u64 sigma1(u64 x) { return R(x,19) ^ R(x,61) ^ (x >> 6); }
+
+static const u64 K[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
+};
+
+int crypto_hashblocks(u8 *x,const u8 *m,u64 n)
+{
+ u64 z[8],b[8],a[8],w[16],t;
+ int i,j;
+
+ FOR(i,8) z[i] = a[i] = dl64(x + 8 * i);
+
+ while (n >= 128) {
+ FOR(i,16) w[i] = dl64(m + 8 * i);
+
+ FOR(i,80) {
+ FOR(j,8) b[j] = a[j];
+ t = a[7] + Sigma1(a[4]) + Ch(a[4],a[5],a[6]) + K[i] + w[i%16];
+ b[7] = t + Sigma0(a[0]) + Maj(a[0],a[1],a[2]);
+ b[3] += t;
+ FOR(j,8) a[(j+1)%8] = b[j];
+ if (i%16 == 15)
+ FOR(j,16)
+ w[j] += w[(j+9)%16] + sigma0(w[(j+1)%16]) + sigma1(w[(j+14)%16]);
+ }
+
+ FOR(i,8) { a[i] += z[i]; z[i] = a[i]; }
+
+ m += 128;
+ n -= 128;
+ }
+
+ FOR(i,8) ts64(x+8*i,z[i]);
+
+ return n;
+}
+
+static const u8 iv[64] = {
+ 0x6a,0x09,0xe6,0x67,0xf3,0xbc,0xc9,0x08,
+ 0xbb,0x67,0xae,0x85,0x84,0xca,0xa7,0x3b,
+ 0x3c,0x6e,0xf3,0x72,0xfe,0x94,0xf8,0x2b,
+ 0xa5,0x4f,0xf5,0x3a,0x5f,0x1d,0x36,0xf1,
+ 0x51,0x0e,0x52,0x7f,0xad,0xe6,0x82,0xd1,
+ 0x9b,0x05,0x68,0x8c,0x2b,0x3e,0x6c,0x1f,
+ 0x1f,0x83,0xd9,0xab,0xfb,0x41,0xbd,0x6b,
+ 0x5b,0xe0,0xcd,0x19,0x13,0x7e,0x21,0x79
+} ;
+
+int crypto_hash(u8 *out,const u8 *m,u64 n)
+{
+ u8 h[64],x[256];
+ u64 i,b = n;
+
+ FOR(i,64) h[i] = iv[i];
+
+ crypto_hashblocks(h,m,n);
+ m += n;
+ n &= 127;
+ m -= n;
+
+ FOR(i,256) x[i] = 0;
+ FOR(i,n) x[i] = m[i];
+ x[n] = 128;
+
+ n = 256-128*(n<112);
+ x[n-9] = b >> 61;
+ ts64(x+n-8,b<<3);
+ crypto_hashblocks(h,x,n);
+
+ FOR(i,64) out[i] = h[i];
+
+ return 0;
+}
+
+sv add(gf p[4],gf q[4])
+{
+ gf a,b,c,d,t,e,f,g,h;
+
+ Z(a, p[1], p[0]);
+ Z(t, q[1], q[0]);
+ M(a, a, t);
+ A(b, p[0], p[1]);
+ A(t, q[0], q[1]);
+ M(b, b, t);
+ M(c, p[3], q[3]);
+ M(c, c, D2);
+ M(d, p[2], q[2]);
+ A(d, d, d);
+ Z(e, b, a);
+ Z(f, d, c);
+ A(g, d, c);
+ A(h, b, a);
+
+ M(p[0], e, f);
+ M(p[1], h, g);
+ M(p[2], g, f);
+ M(p[3], e, h);
+}
+
+sv cswap(gf p[4],gf q[4],u8 b)
+{
+ int i;
+ FOR(i,4)
+ sel25519(p[i],q[i],b);
+}
+
+sv pack(u8 *r,gf p[4])
+{
+ gf tx, ty, zi;
+ inv25519(zi, p[2]);
+ M(tx, p[0], zi);
+ M(ty, p[1], zi);
+ pack25519(r, ty);
+ r[31] ^= par25519(tx) << 7;
+}
+
+sv scalarmult(gf p[4],gf q[4],const u8 *s)
+{
+ int i;
+ set25519(p[0],gf0);
+ set25519(p[1],gf1);
+ set25519(p[2],gf1);
+ set25519(p[3],gf0);
+ for (i = 255;i >= 0;--i) {
+ u8 b = (s[i/8]>>(i&7))&1;
+ cswap(p,q,b);
+ add(q,p);
+ add(p,p);
+ cswap(p,q,b);
+ }
+}
+
+sv scalarbase(gf p[4],const u8 *s)
+{
+ gf q[4];
+ set25519(q[0],X);
+ set25519(q[1],Y);
+ set25519(q[2],gf1);
+ M(q[3],X,Y);
+ scalarmult(p,q,s);
+}
+
+int crypto_sign_keypair(u8 *pk, u8 *sk)
+{
+ u8 d[64];
+ gf p[4];
+ int i;
+
+ randombytes(sk, 32);
+ crypto_hash(d, sk, 32);
+ d[0] &= 248;
+ d[31] &= 127;
+ d[31] |= 64;
+
+ scalarbase(p,d);
+ pack(pk,p);
+
+ FOR(i,32) sk[32 + i] = pk[i];
+ return 0;
+}
+
+static const u64 L[32] = {0xed, 0xd3, 0xf5, 0x5c, 0x1a, 0x63, 0x12, 0x58, 0xd6, 0x9c, 0xf7, 0xa2, 0xde, 0xf9, 0xde, 0x14, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x10};
+
+sv modL(u8 *r,i64 x[64])
+{
+ i64 carry,i,j;
+ for (i = 63;i >= 32;--i) {
+ carry = 0;
+ for (j = i - 32;j < i - 12;++j) {
+ x[j] += carry - 16 * x[i] * L[j - (i - 32)];
+ carry = (x[j] + 128) >> 8;
+ x[j] -= carry << 8;
+ }
+ x[j] += carry;
+ x[i] = 0;
+ }
+ carry = 0;
+ FOR(j,32) {
+ x[j] += carry - (x[31] >> 4) * L[j];
+ carry = x[j] >> 8;
+ x[j] &= 255;
+ }
+ FOR(j,32) x[j] -= carry * L[j];
+ FOR(i,32) {
+ x[i+1] += x[i] >> 8;
+ r[i] = x[i] & 255;
+ }
+}
+
+sv reduce(u8 *r)
+{
+ i64 x[64],i;
+ FOR(i,64) x[i] = (u64) r[i];
+ FOR(i,64) r[i] = 0;
+ modL(r,x);
+}
+
+int crypto_sign(u8 *sm,u64 *smlen,const u8 *m,u64 n,const u8 *sk)
+{
+ u8 d[64],h[64],r[64];
+ i64 i,j,x[64];
+ gf p[4];
+
+ crypto_hash(d, sk, 32);
+ d[0] &= 248;
+ d[31] &= 127;
+ d[31] |= 64;
+
+ *smlen = n+64;
+ FOR(i,n) sm[64 + i] = m[i];
+ FOR(i,32) sm[32 + i] = d[32 + i];
+
+ crypto_hash(r, sm+32, n+32);
+ reduce(r);
+ scalarbase(p,r);
+ pack(sm,p);
+
+ FOR(i,32) sm[i+32] = sk[i+32];
+ crypto_hash(h,sm,n + 64);
+ reduce(h);
+
+ FOR(i,64) x[i] = 0;
+ FOR(i,32) x[i] = (u64) r[i];
+ FOR(i,32) FOR(j,32) x[i+j] += h[i] * (u64) d[j];
+ modL(sm + 32,x);
+
+ return 0;
+}
+
+static int unpackneg(gf r[4],const u8 p[32])
+{
+ gf t, chk, num, den, den2, den4, den6;
+ set25519(r[2],gf1);
+ unpack25519(r[1],p);
+ S(num,r[1]);
+ M(den,num,D);
+ Z(num,num,r[2]);
+ A(den,r[2],den);
+
+ S(den2,den);
+ S(den4,den2);
+ M(den6,den4,den2);
+ M(t,den6,num);
+ M(t,t,den);
+
+ pow2523(t,t);
+ M(t,t,num);
+ M(t,t,den);
+ M(t,t,den);
+ M(r[0],t,den);
+
+ S(chk,r[0]);
+ M(chk,chk,den);
+ if (neq25519(chk, num)) M(r[0],r[0],I);
+
+ S(chk,r[0]);
+ M(chk,chk,den);
+ if (neq25519(chk, num)) return -1;
+
+ if (par25519(r[0]) == (p[31]>>7)) Z(r[0],gf0,r[0]);
+
+ M(r[3],r[0],r[1]);
+ return 0;
+}
+
+int crypto_sign_open(u8 *m,u64 *mlen,const u8 *sm,u64 n,const u8 *pk)
+{
+ int i;
+ u8 t[32],h[64];
+ gf p[4],q[4];
+
+ *mlen = -1;
+ if (n < 64) return -1;
+
+ if (unpackneg(q,pk)) return -1;
+
+ FOR(i,n) m[i] = sm[i];
+ FOR(i,32) m[i+32] = pk[i];
+ crypto_hash(h,m,n);
+ reduce(h);
+ scalarmult(p,q,h);
+
+ scalarbase(q,sm + 32);
+ add(p,q);
+ pack(t,p);
+
+ n -= 64;
+ if (crypto_verify_32(sm, t)) {
+ FOR(i,n) m[i] = 0;
+ return -1;
+ }
+
+ FOR(i,n) m[i] = sm[i + 64];
+ *mlen = n;
+ return 0;
+}
diff --git a/lib/Utils.Cryptography/monocypher/vendor/tests/externals/tweetnacl/tweetnacl.h b/lib/Utils.Cryptography/monocypher/vendor/tests/externals/tweetnacl/tweetnacl.h
new file mode 100644
index 0000000..9277fbf
--- /dev/null
+++ b/lib/Utils.Cryptography/monocypher/vendor/tests/externals/tweetnacl/tweetnacl.h
@@ -0,0 +1,272 @@
+#ifndef TWEETNACL_H
+#define TWEETNACL_H
+#define crypto_auth_PRIMITIVE "hmacsha512256"
+#define crypto_auth crypto_auth_hmacsha512256
+#define crypto_auth_verify crypto_auth_hmacsha512256_verify
+#define crypto_auth_BYTES crypto_auth_hmacsha512256_BYTES
+#define crypto_auth_KEYBYTES crypto_auth_hmacsha512256_KEYBYTES
+#define crypto_auth_IMPLEMENTATION crypto_auth_hmacsha512256_IMPLEMENTATION
+#define crypto_auth_VERSION crypto_auth_hmacsha512256_VERSION
+#define crypto_auth_hmacsha512256_tweet_BYTES 32
+#define crypto_auth_hmacsha512256_tweet_KEYBYTES 32
+extern int crypto_auth_hmacsha512256_tweet(unsigned char *,const unsigned char *,unsigned long long,const unsigned char *);
+extern int crypto_auth_hmacsha512256_tweet_verify(const unsigned char *,const unsigned char *,unsigned long long,const unsigned char *);
+#define crypto_auth_hmacsha512256_tweet_VERSION "-"
+#define crypto_auth_hmacsha512256 crypto_auth_hmacsha512256_tweet
+#define crypto_auth_hmacsha512256_verify crypto_auth_hmacsha512256_tweet_verify
+#define crypto_auth_hmacsha512256_BYTES crypto_auth_hmacsha512256_tweet_BYTES
+#define crypto_auth_hmacsha512256_KEYBYTES crypto_auth_hmacsha512256_tweet_KEYBYTES
+#define crypto_auth_hmacsha512256_VERSION crypto_auth_hmacsha512256_tweet_VERSION
+#define crypto_auth_hmacsha512256_IMPLEMENTATION "crypto_auth/hmacsha512256/tweet"
+#define crypto_box_PRIMITIVE "curve25519xsalsa20poly1305"
+#define crypto_box crypto_box_curve25519xsalsa20poly1305
+#define crypto_box_open crypto_box_curve25519xsalsa20poly1305_open
+#define crypto_box_keypair crypto_box_curve25519xsalsa20poly1305_keypair
+#define crypto_box_beforenm crypto_box_curve25519xsalsa20poly1305_beforenm
+#define crypto_box_afternm crypto_box_curve25519xsalsa20poly1305_afternm
+#define crypto_box_open_afternm crypto_box_curve25519xsalsa20poly1305_open_afternm
+#define crypto_box_PUBLICKEYBYTES crypto_box_curve25519xsalsa20poly1305_PUBLICKEYBYTES
+#define crypto_box_SECRETKEYBYTES crypto_box_curve25519xsalsa20poly1305_SECRETKEYBYTES
+#define crypto_box_BEFORENMBYTES crypto_box_curve25519xsalsa20poly1305_BEFORENMBYTES
+#define crypto_box_NONCEBYTES crypto_box_curve25519xsalsa20poly1305_NONCEBYTES
+#define crypto_box_ZEROBYTES crypto_box_curve25519xsalsa20poly1305_ZEROBYTES
+#define crypto_box_BOXZEROBYTES crypto_box_curve25519xsalsa20poly1305_BOXZEROBYTES
+#define crypto_box_IMPLEMENTATION crypto_box_curve25519xsalsa20poly1305_IMPLEMENTATION
+#define crypto_box_VERSION crypto_box_curve25519xsalsa20poly1305_VERSION
+#define crypto_box_curve25519xsalsa20poly1305_tweet_PUBLICKEYBYTES 32
+#define crypto_box_curve25519xsalsa20poly1305_tweet_SECRETKEYBYTES 32
+#define crypto_box_curve25519xsalsa20poly1305_tweet_BEFORENMBYTES 32
+#define crypto_box_curve25519xsalsa20poly1305_tweet_NONCEBYTES 24
+#define crypto_box_curve25519xsalsa20poly1305_tweet_ZEROBYTES 32
+#define crypto_box_curve25519xsalsa20poly1305_tweet_BOXZEROBYTES 16
+extern int crypto_box_curve25519xsalsa20poly1305_tweet(unsigned char *,const unsigned char *,unsigned long long,const unsigned char *,const unsigned char *,const unsigned char *);
+extern int crypto_box_curve25519xsalsa20poly1305_tweet_open(unsigned char *,const unsigned char *,unsigned long long,const unsigned char *,const unsigned char *,const unsigned char *);
+extern int crypto_box_curve25519xsalsa20poly1305_tweet_keypair(unsigned char *,unsigned char *);
+extern int crypto_box_curve25519xsalsa20poly1305_tweet_beforenm(unsigned char *,const unsigned char *,const unsigned char *);
+extern int crypto_box_curve25519xsalsa20poly1305_tweet_afternm(unsigned char *,const unsigned char *,unsigned long long,const unsigned char *,const unsigned char *);
+extern int crypto_box_curve25519xsalsa20poly1305_tweet_open_afternm(unsigned char *,const unsigned char *,unsigned long long,const unsigned char *,const unsigned char *);
+#define crypto_box_curve25519xsalsa20poly1305_tweet_VERSION "-"
+#define crypto_box_curve25519xsalsa20poly1305 crypto_box_curve25519xsalsa20poly1305_tweet
+#define crypto_box_curve25519xsalsa20poly1305_open crypto_box_curve25519xsalsa20poly1305_tweet_open
+#define crypto_box_curve25519xsalsa20poly1305_keypair crypto_box_curve25519xsalsa20poly1305_tweet_keypair
+#define crypto_box_curve25519xsalsa20poly1305_beforenm crypto_box_curve25519xsalsa20poly1305_tweet_beforenm
+#define crypto_box_curve25519xsalsa20poly1305_afternm crypto_box_curve25519xsalsa20poly1305_tweet_afternm
+#define crypto_box_curve25519xsalsa20poly1305_open_afternm crypto_box_curve25519xsalsa20poly1305_tweet_open_afternm
+#define crypto_box_curve25519xsalsa20poly1305_PUBLICKEYBYTES crypto_box_curve25519xsalsa20poly1305_tweet_PUBLICKEYBYTES
+#define crypto_box_curve25519xsalsa20poly1305_SECRETKEYBYTES crypto_box_curve25519xsalsa20poly1305_tweet_SECRETKEYBYTES
+#define crypto_box_curve25519xsalsa20poly1305_BEFORENMBYTES crypto_box_curve25519xsalsa20poly1305_tweet_BEFORENMBYTES
+#define crypto_box_curve25519xsalsa20poly1305_NONCEBYTES crypto_box_curve25519xsalsa20poly1305_tweet_NONCEBYTES
+#define crypto_box_curve25519xsalsa20poly1305_ZEROBYTES crypto_box_curve25519xsalsa20poly1305_tweet_ZEROBYTES
+#define crypto_box_curve25519xsalsa20poly1305_BOXZEROBYTES crypto_box_curve25519xsalsa20poly1305_tweet_BOXZEROBYTES
+#define crypto_box_curve25519xsalsa20poly1305_VERSION crypto_box_curve25519xsalsa20poly1305_tweet_VERSION
+#define crypto_box_curve25519xsalsa20poly1305_IMPLEMENTATION "crypto_box/curve25519xsalsa20poly1305/tweet"
+#define crypto_core_PRIMITIVE "salsa20"
+#define crypto_core crypto_core_salsa20
+#define crypto_core_OUTPUTBYTES crypto_core_salsa20_OUTPUTBYTES
+#define crypto_core_INPUTBYTES crypto_core_salsa20_INPUTBYTES
+#define crypto_core_KEYBYTES crypto_core_salsa20_KEYBYTES
+#define crypto_core_CONSTBYTES crypto_core_salsa20_CONSTBYTES
+#define crypto_core_IMPLEMENTATION crypto_core_salsa20_IMPLEMENTATION
+#define crypto_core_VERSION crypto_core_salsa20_VERSION
+#define crypto_core_salsa20_tweet_OUTPUTBYTES 64
+#define crypto_core_salsa20_tweet_INPUTBYTES 16
+#define crypto_core_salsa20_tweet_KEYBYTES 32
+#define crypto_core_salsa20_tweet_CONSTBYTES 16
+extern int crypto_core_salsa20_tweet(unsigned char *,const unsigned char *,const unsigned char *,const unsigned char *);
+#define crypto_core_salsa20_tweet_VERSION "-"
+#define crypto_core_salsa20 crypto_core_salsa20_tweet
+#define crypto_core_salsa20_OUTPUTBYTES crypto_core_salsa20_tweet_OUTPUTBYTES
+#define crypto_core_salsa20_INPUTBYTES crypto_core_salsa20_tweet_INPUTBYTES
+#define crypto_core_salsa20_KEYBYTES crypto_core_salsa20_tweet_KEYBYTES
+#define crypto_core_salsa20_CONSTBYTES crypto_core_salsa20_tweet_CONSTBYTES
+#define crypto_core_salsa20_VERSION crypto_core_salsa20_tweet_VERSION
+#define crypto_core_salsa20_IMPLEMENTATION "crypto_core/salsa20/tweet"
+#define crypto_core_hsalsa20_tweet_OUTPUTBYTES 32
+#define crypto_core_hsalsa20_tweet_INPUTBYTES 16
+#define crypto_core_hsalsa20_tweet_KEYBYTES 32
+#define crypto_core_hsalsa20_tweet_CONSTBYTES 16
+extern int crypto_core_hsalsa20_tweet(unsigned char *,const unsigned char *,const unsigned char *,const unsigned char *);
+#define crypto_core_hsalsa20_tweet_VERSION "-"
+#define crypto_core_hsalsa20 crypto_core_hsalsa20_tweet
+#define crypto_core_hsalsa20_OUTPUTBYTES crypto_core_hsalsa20_tweet_OUTPUTBYTES
+#define crypto_core_hsalsa20_INPUTBYTES crypto_core_hsalsa20_tweet_INPUTBYTES
+#define crypto_core_hsalsa20_KEYBYTES crypto_core_hsalsa20_tweet_KEYBYTES
+#define crypto_core_hsalsa20_CONSTBYTES crypto_core_hsalsa20_tweet_CONSTBYTES
+#define crypto_core_hsalsa20_VERSION crypto_core_hsalsa20_tweet_VERSION
+#define crypto_core_hsalsa20_IMPLEMENTATION "crypto_core/hsalsa20/tweet"
+#define crypto_hashblocks_PRIMITIVE "sha512"
+#define crypto_hashblocks crypto_hashblocks_sha512
+#define crypto_hashblocks_STATEBYTES crypto_hashblocks_sha512_STATEBYTES
+#define crypto_hashblocks_BLOCKBYTES crypto_hashblocks_sha512_BLOCKBYTES
+#define crypto_hashblocks_IMPLEMENTATION crypto_hashblocks_sha512_IMPLEMENTATION
+#define crypto_hashblocks_VERSION crypto_hashblocks_sha512_VERSION
+#define crypto_hashblocks_sha512_tweet_STATEBYTES 64
+#define crypto_hashblocks_sha512_tweet_BLOCKBYTES 128
+extern int crypto_hashblocks_sha512_tweet(unsigned char *,const unsigned char *,unsigned long long);
+#define crypto_hashblocks_sha512_tweet_VERSION "-"
+#define crypto_hashblocks_sha512 crypto_hashblocks_sha512_tweet
+#define crypto_hashblocks_sha512_STATEBYTES crypto_hashblocks_sha512_tweet_STATEBYTES
+#define crypto_hashblocks_sha512_BLOCKBYTES crypto_hashblocks_sha512_tweet_BLOCKBYTES
+#define crypto_hashblocks_sha512_VERSION crypto_hashblocks_sha512_tweet_VERSION
+#define crypto_hashblocks_sha512_IMPLEMENTATION "crypto_hashblocks/sha512/tweet"
+#define crypto_hashblocks_sha256_tweet_STATEBYTES 32
+#define crypto_hashblocks_sha256_tweet_BLOCKBYTES 64
+extern int crypto_hashblocks_sha256_tweet(unsigned char *,const unsigned char *,unsigned long long);
+#define crypto_hashblocks_sha256_tweet_VERSION "-"
+#define crypto_hashblocks_sha256 crypto_hashblocks_sha256_tweet
+#define crypto_hashblocks_sha256_STATEBYTES crypto_hashblocks_sha256_tweet_STATEBYTES
+#define crypto_hashblocks_sha256_BLOCKBYTES crypto_hashblocks_sha256_tweet_BLOCKBYTES
+#define crypto_hashblocks_sha256_VERSION crypto_hashblocks_sha256_tweet_VERSION
+#define crypto_hashblocks_sha256_IMPLEMENTATION "crypto_hashblocks/sha256/tweet"
+#define crypto_hash_PRIMITIVE "sha512"
+#define crypto_hash crypto_hash_sha512
+#define crypto_hash_BYTES crypto_hash_sha512_BYTES
+#define crypto_hash_IMPLEMENTATION crypto_hash_sha512_IMPLEMENTATION
+#define crypto_hash_VERSION crypto_hash_sha512_VERSION
+#define crypto_hash_sha512_tweet_BYTES 64
+extern int crypto_hash_sha512_tweet(unsigned char *,const unsigned char *,unsigned long long);
+#define crypto_hash_sha512_tweet_VERSION "-"
+#define crypto_hash_sha512 crypto_hash_sha512_tweet
+#define crypto_hash_sha512_BYTES crypto_hash_sha512_tweet_BYTES
+#define crypto_hash_sha512_VERSION crypto_hash_sha512_tweet_VERSION
+#define crypto_hash_sha512_IMPLEMENTATION "crypto_hash/sha512/tweet"
+#define crypto_hash_sha256_tweet_BYTES 32
+extern int crypto_hash_sha256_tweet(unsigned char *,const unsigned char *,unsigned long long);
+#define crypto_hash_sha256_tweet_VERSION "-"
+#define crypto_hash_sha256 crypto_hash_sha256_tweet
+#define crypto_hash_sha256_BYTES crypto_hash_sha256_tweet_BYTES
+#define crypto_hash_sha256_VERSION crypto_hash_sha256_tweet_VERSION
+#define crypto_hash_sha256_IMPLEMENTATION "crypto_hash/sha256/tweet"
+#define crypto_onetimeauth_PRIMITIVE "poly1305"
+#define crypto_onetimeauth crypto_onetimeauth_poly1305
+#define crypto_onetimeauth_verify crypto_onetimeauth_poly1305_verify
+#define crypto_onetimeauth_BYTES crypto_onetimeauth_poly1305_BYTES
+#define crypto_onetimeauth_KEYBYTES crypto_onetimeauth_poly1305_KEYBYTES
+#define crypto_onetimeauth_IMPLEMENTATION crypto_onetimeauth_poly1305_IMPLEMENTATION
+#define crypto_onetimeauth_VERSION crypto_onetimeauth_poly1305_VERSION
+#define crypto_onetimeauth_poly1305_tweet_BYTES 16
+#define crypto_onetimeauth_poly1305_tweet_KEYBYTES 32
+extern int crypto_onetimeauth_poly1305_tweet(unsigned char *,const unsigned char *,unsigned long long,const unsigned char *);
+extern int crypto_onetimeauth_poly1305_tweet_verify(const unsigned char *,const unsigned char *,unsigned long long,const unsigned char *);
+#define crypto_onetimeauth_poly1305_tweet_VERSION "-"
+#define crypto_onetimeauth_poly1305 crypto_onetimeauth_poly1305_tweet
+#define crypto_onetimeauth_poly1305_verify crypto_onetimeauth_poly1305_tweet_verify
+#define crypto_onetimeauth_poly1305_BYTES crypto_onetimeauth_poly1305_tweet_BYTES
+#define crypto_onetimeauth_poly1305_KEYBYTES crypto_onetimeauth_poly1305_tweet_KEYBYTES
+#define crypto_onetimeauth_poly1305_VERSION crypto_onetimeauth_poly1305_tweet_VERSION
+#define crypto_onetimeauth_poly1305_IMPLEMENTATION "crypto_onetimeauth/poly1305/tweet"
+#define crypto_scalarmult_PRIMITIVE "curve25519"
+#define crypto_scalarmult crypto_scalarmult_curve25519
+#define crypto_scalarmult_base crypto_scalarmult_curve25519_base
+#define crypto_scalarmult_BYTES crypto_scalarmult_curve25519_BYTES
+#define crypto_scalarmult_SCALARBYTES crypto_scalarmult_curve25519_SCALARBYTES
+#define crypto_scalarmult_IMPLEMENTATION crypto_scalarmult_curve25519_IMPLEMENTATION
+#define crypto_scalarmult_VERSION crypto_scalarmult_curve25519_VERSION
+#define crypto_scalarmult_curve25519_tweet_BYTES 32
+#define crypto_scalarmult_curve25519_tweet_SCALARBYTES 32
+extern int crypto_scalarmult_curve25519_tweet(unsigned char *,const unsigned char *,const unsigned char *);
+extern int crypto_scalarmult_curve25519_tweet_base(unsigned char *,const unsigned char *);
+#define crypto_scalarmult_curve25519_tweet_VERSION "-"
+#define crypto_scalarmult_curve25519 crypto_scalarmult_curve25519_tweet
+#define crypto_scalarmult_curve25519_base crypto_scalarmult_curve25519_tweet_base
+#define crypto_scalarmult_curve25519_BYTES crypto_scalarmult_curve25519_tweet_BYTES
+#define crypto_scalarmult_curve25519_SCALARBYTES crypto_scalarmult_curve25519_tweet_SCALARBYTES
+#define crypto_scalarmult_curve25519_VERSION crypto_scalarmult_curve25519_tweet_VERSION
+#define crypto_scalarmult_curve25519_IMPLEMENTATION "crypto_scalarmult/curve25519/tweet"
+#define crypto_secretbox_PRIMITIVE "xsalsa20poly1305"
+#define crypto_secretbox crypto_secretbox_xsalsa20poly1305
+#define crypto_secretbox_open crypto_secretbox_xsalsa20poly1305_open
+#define crypto_secretbox_KEYBYTES crypto_secretbox_xsalsa20poly1305_KEYBYTES
+#define crypto_secretbox_NONCEBYTES crypto_secretbox_xsalsa20poly1305_NONCEBYTES
+#define crypto_secretbox_ZEROBYTES crypto_secretbox_xsalsa20poly1305_ZEROBYTES
+#define crypto_secretbox_BOXZEROBYTES crypto_secretbox_xsalsa20poly1305_BOXZEROBYTES
+#define crypto_secretbox_IMPLEMENTATION crypto_secretbox_xsalsa20poly1305_IMPLEMENTATION
+#define crypto_secretbox_VERSION crypto_secretbox_xsalsa20poly1305_VERSION
+#define crypto_secretbox_xsalsa20poly1305_tweet_KEYBYTES 32
+#define crypto_secretbox_xsalsa20poly1305_tweet_NONCEBYTES 24
+#define crypto_secretbox_xsalsa20poly1305_tweet_ZEROBYTES 32
+#define crypto_secretbox_xsalsa20poly1305_tweet_BOXZEROBYTES 16
+extern int crypto_secretbox_xsalsa20poly1305_tweet(unsigned char *,const unsigned char *,unsigned long long,const unsigned char *,const unsigned char *);
+extern int crypto_secretbox_xsalsa20poly1305_tweet_open(unsigned char *,const unsigned char *,unsigned long long,const unsigned char *,const unsigned char *);
+#define crypto_secretbox_xsalsa20poly1305_tweet_VERSION "-"
+#define crypto_secretbox_xsalsa20poly1305 crypto_secretbox_xsalsa20poly1305_tweet
+#define crypto_secretbox_xsalsa20poly1305_open crypto_secretbox_xsalsa20poly1305_tweet_open
+#define crypto_secretbox_xsalsa20poly1305_KEYBYTES crypto_secretbox_xsalsa20poly1305_tweet_KEYBYTES
+#define crypto_secretbox_xsalsa20poly1305_NONCEBYTES crypto_secretbox_xsalsa20poly1305_tweet_NONCEBYTES
+#define crypto_secretbox_xsalsa20poly1305_ZEROBYTES crypto_secretbox_xsalsa20poly1305_tweet_ZEROBYTES
+#define crypto_secretbox_xsalsa20poly1305_BOXZEROBYTES crypto_secretbox_xsalsa20poly1305_tweet_BOXZEROBYTES
+#define crypto_secretbox_xsalsa20poly1305_VERSION crypto_secretbox_xsalsa20poly1305_tweet_VERSION
+#define crypto_secretbox_xsalsa20poly1305_IMPLEMENTATION "crypto_secretbox/xsalsa20poly1305/tweet"
+#define crypto_sign_PRIMITIVE "ed25519"
+#define crypto_sign crypto_sign_ed25519
+#define crypto_sign_open crypto_sign_ed25519_open
+#define crypto_sign_keypair crypto_sign_ed25519_keypair
+#define crypto_sign_BYTES crypto_sign_ed25519_BYTES
+#define crypto_sign_PUBLICKEYBYTES crypto_sign_ed25519_PUBLICKEYBYTES
+#define crypto_sign_SECRETKEYBYTES crypto_sign_ed25519_SECRETKEYBYTES
+#define crypto_sign_IMPLEMENTATION crypto_sign_ed25519_IMPLEMENTATION
+#define crypto_sign_VERSION crypto_sign_ed25519_VERSION
+#define crypto_sign_ed25519_tweet_BYTES 64
+#define crypto_sign_ed25519_tweet_PUBLICKEYBYTES 32
+#define crypto_sign_ed25519_tweet_SECRETKEYBYTES 64
+extern int crypto_sign_ed25519_tweet(unsigned char *,unsigned long long *,const unsigned char *,unsigned long long,const unsigned char *);
+extern int crypto_sign_ed25519_tweet_open(unsigned char *,unsigned long long *,const unsigned char *,unsigned long long,const unsigned char *);
+extern int crypto_sign_ed25519_tweet_keypair(unsigned char *,unsigned char *);
+#define crypto_sign_ed25519_tweet_VERSION "-"
+#define crypto_sign_ed25519 crypto_sign_ed25519_tweet
+#define crypto_sign_ed25519_open crypto_sign_ed25519_tweet_open
+#define crypto_sign_ed25519_keypair crypto_sign_ed25519_tweet_keypair
+#define crypto_sign_ed25519_BYTES crypto_sign_ed25519_tweet_BYTES
+#define crypto_sign_ed25519_PUBLICKEYBYTES crypto_sign_ed25519_tweet_PUBLICKEYBYTES
+#define crypto_sign_ed25519_SECRETKEYBYTES crypto_sign_ed25519_tweet_SECRETKEYBYTES
+#define crypto_sign_ed25519_VERSION crypto_sign_ed25519_tweet_VERSION
+#define crypto_sign_ed25519_IMPLEMENTATION "crypto_sign/ed25519/tweet"
+#define crypto_stream_PRIMITIVE "xsalsa20"
+#define crypto_stream crypto_stream_xsalsa20
+#define crypto_stream_xor crypto_stream_xsalsa20_xor
+#define crypto_stream_KEYBYTES crypto_stream_xsalsa20_KEYBYTES
+#define crypto_stream_NONCEBYTES crypto_stream_xsalsa20_NONCEBYTES
+#define crypto_stream_IMPLEMENTATION crypto_stream_xsalsa20_IMPLEMENTATION
+#define crypto_stream_VERSION crypto_stream_xsalsa20_VERSION
+#define crypto_stream_xsalsa20_tweet_KEYBYTES 32
+#define crypto_stream_xsalsa20_tweet_NONCEBYTES 24
+extern int crypto_stream_xsalsa20_tweet(unsigned char *,unsigned long long,const unsigned char *,const unsigned char *);
+extern int crypto_stream_xsalsa20_tweet_xor(unsigned char *,const unsigned char *,unsigned long long,const unsigned char *,const unsigned char *);
+#define crypto_stream_xsalsa20_tweet_VERSION "-"
+#define crypto_stream_xsalsa20 crypto_stream_xsalsa20_tweet
+#define crypto_stream_xsalsa20_xor crypto_stream_xsalsa20_tweet_xor
+#define crypto_stream_xsalsa20_KEYBYTES crypto_stream_xsalsa20_tweet_KEYBYTES
+#define crypto_stream_xsalsa20_NONCEBYTES crypto_stream_xsalsa20_tweet_NONCEBYTES
+#define crypto_stream_xsalsa20_VERSION crypto_stream_xsalsa20_tweet_VERSION
+#define crypto_stream_xsalsa20_IMPLEMENTATION "crypto_stream/xsalsa20/tweet"
+#define crypto_stream_salsa20_tweet_KEYBYTES 32
+#define crypto_stream_salsa20_tweet_NONCEBYTES 8
+extern int crypto_stream_salsa20_tweet(unsigned char *,unsigned long long,const unsigned char *,const unsigned char *);
+extern int crypto_stream_salsa20_tweet_xor(unsigned char *,const unsigned char *,unsigned long long,const unsigned char *,const unsigned char *);
+#define crypto_stream_salsa20_tweet_VERSION "-"
+#define crypto_stream_salsa20 crypto_stream_salsa20_tweet
+#define crypto_stream_salsa20_xor crypto_stream_salsa20_tweet_xor
+#define crypto_stream_salsa20_KEYBYTES crypto_stream_salsa20_tweet_KEYBYTES
+#define crypto_stream_salsa20_NONCEBYTES crypto_stream_salsa20_tweet_NONCEBYTES
+#define crypto_stream_salsa20_VERSION crypto_stream_salsa20_tweet_VERSION
+#define crypto_stream_salsa20_IMPLEMENTATION "crypto_stream/salsa20/tweet"
+#define crypto_verify_PRIMITIVE "16"
+#define crypto_verify crypto_verify_16
+#define crypto_verify_BYTES crypto_verify_16_BYTES
+#define crypto_verify_IMPLEMENTATION crypto_verify_16_IMPLEMENTATION
+#define crypto_verify_VERSION crypto_verify_16_VERSION
+#define crypto_verify_16_tweet_BYTES 16
+extern int crypto_verify_16_tweet(const unsigned char *,const unsigned char *);
+#define crypto_verify_16_tweet_VERSION "-"
+#define crypto_verify_16 crypto_verify_16_tweet
+#define crypto_verify_16_BYTES crypto_verify_16_tweet_BYTES
+#define crypto_verify_16_VERSION crypto_verify_16_tweet_VERSION
+#define crypto_verify_16_IMPLEMENTATION "crypto_verify/16/tweet"
+#define crypto_verify_32_tweet_BYTES 32
+extern int crypto_verify_32_tweet(const unsigned char *,const unsigned char *);
+#define crypto_verify_32_tweet_VERSION "-"
+#define crypto_verify_32 crypto_verify_32_tweet
+#define crypto_verify_32_BYTES crypto_verify_32_tweet_BYTES
+#define crypto_verify_32_VERSION crypto_verify_32_tweet_VERSION
+#define crypto_verify_32_IMPLEMENTATION "crypto_verify/32/tweet"
+#endif
diff --git a/lib/Utils.Cryptography/monocypher/vendor/tests/formal-analysis.sh b/lib/Utils.Cryptography/monocypher/vendor/tests/formal-analysis.sh
new file mode 100644
index 0000000..741a13e
--- /dev/null
+++ b/lib/Utils.Cryptography/monocypher/vendor/tests/formal-analysis.sh
@@ -0,0 +1,66 @@
+#! /bin/sh
+
+# This file is dual-licensed. Choose whichever licence you want from
+# the two licences listed below.
+#
+# The first licence is a regular 2-clause BSD licence. The second licence
+# is the CC-0 from Creative Commons. It is intended to release Monocypher
+# to the public domain. The BSD licence serves as a fallback option.
+#
+# SPDX-License-Identifier: BSD-2-Clause OR CC0-1.0
+#
+# ------------------------------------------------------------------------
+#
+# Copyright (c) 2017-2019, Loup Vaillant
+# 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 COPYRIGHT HOLDERS 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 COPYRIGHT
+# HOLDER 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.
+#
+# ------------------------------------------------------------------------
+#
+# Written in 2017-2019 by Loup Vaillant
+#
+# To the extent possible under law, the author(s) have dedicated all copyright
+# and related 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
+# <https://creativecommons.org/publicdomain/zero/1.0/>
+
+mkdir -p tests/formal-analysis
+cp src/monocypher.c \
+ src/monocypher.h \
+ src/optional/monocypher-ed25519.h \
+ src/optional/monocypher-ed25519.c \
+ tests/utils.h \
+ tests/utils.c \
+ tests/test.c \
+ tests/vectors.h \
+ tests/formal-analysis
+
+# Get rid of the `volatile` keyword that confuses the TIS interpreter
+sed -i 's/volatile //g' tests/formal-analysis/monocypher.c
diff --git a/lib/Utils.Cryptography/monocypher/vendor/tests/frama-c.sh b/lib/Utils.Cryptography/monocypher/vendor/tests/frama-c.sh
new file mode 100644
index 0000000..dc23c6b
--- /dev/null
+++ b/lib/Utils.Cryptography/monocypher/vendor/tests/frama-c.sh
@@ -0,0 +1,61 @@
+#! /bin/sh
+
+# This file is dual-licensed. Choose whichever licence you want from
+# the two licences listed below.
+#
+# The first licence is a regular 2-clause BSD licence. The second licence
+# is the CC-0 from Creative Commons. It is intended to release Monocypher
+# to the public domain. The BSD licence serves as a fallback option.
+#
+# SPDX-License-Identifier: BSD-2-Clause OR CC0-1.0
+#
+# ------------------------------------------------------------------------
+#
+# Copyright (c) 2017-2019, Loup Vaillant
+# 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 COPYRIGHT HOLDERS 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 COPYRIGHT
+# HOLDER 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.
+#
+# ------------------------------------------------------------------------
+#
+# Written in 2017-2019 by Loup Vaillant
+#
+# To the extent possible under law, the author(s) have dedicated all copyright
+# and related 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
+# <https://creativecommons.org/publicdomain/zero/1.0/>
+
+# Parses the source code
+frama-c tests/formal-analysis/*.c -save parsed.sav
+
+# Analyses the source code
+frama-c -load parsed.sav -val-builtins-auto -val -save value.sav -no-val-show-progress -memexec-all
+
+# Launches the Gui
+frama-c-gui -load value.sav
diff --git a/lib/Utils.Cryptography/monocypher/vendor/tests/gen/aead_8439.c b/lib/Utils.Cryptography/monocypher/vendor/tests/gen/aead_8439.c
new file mode 100644
index 0000000..57edf03
--- /dev/null
+++ b/lib/Utils.Cryptography/monocypher/vendor/tests/gen/aead_8439.c
@@ -0,0 +1,83 @@
+// This file is dual-licensed. Choose whichever licence you want from
+// the two licences listed below.
+//
+// The first licence is a regular 2-clause BSD licence. The second licence
+// is the CC-0 from Creative Commons. It is intended to release Monocypher
+// to the public domain. The BSD licence serves as a fallback option.
+//
+// SPDX-License-Identifier: BSD-2-Clause OR CC0-1.0
+//
+// ------------------------------------------------------------------------
+//
+// Copyright (c) 2022, Loup Vaillant
+// 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 COPYRIGHT HOLDERS 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 COPYRIGHT
+// HOLDER 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.
+//
+// ------------------------------------------------------------------------
+//
+// Written in 2022 by Loup Vaillant
+//
+// To the extent possible under law, the author(s) have dedicated all copyright
+// and related 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
+// <https://creativecommons.org/publicdomain/zero/1.0/>
+
+#include <sodium.h>
+#include "utils.h"
+
+static void test(size_t text_size, size_t ad_size)
+{
+ RANDOM_INPUT(key , 32);
+ RANDOM_INPUT(nonce, 12);
+ RANDOM_INPUT(ad , 32); // ad size <= 32
+ RANDOM_INPUT(text , 128); // text_size <= 128
+ u8 out[16 + 128]; // text_size <= 128
+
+ crypto_aead_chacha20poly1305_ietf_encrypt_detached(
+ out + 16, out, 0, text, text_size, ad, ad_size, 0, nonce, key);
+
+ print_vector(key , 32);
+ print_vector(nonce , 12);
+ print_vector(ad , ad_size);
+ print_vector(text , text_size);
+ print_vector(out , text_size + 16);
+ printf("\n");
+}
+
+int main(void)
+{
+ SODIUM_INIT;
+ // regular tests
+ FOR (text_size, 0, 128) { test(text_size, 0); }
+ FOR (text_size, 0, 128) { test(text_size, 4); }
+ FOR ( ad_size, 0, 32) { test(0, ad_size); }
+ FOR ( ad_size, 0, 32) { test(16, ad_size); }
+ return 0;
+}
diff --git a/lib/Utils.Cryptography/monocypher/vendor/tests/gen/aead_ietf.c b/lib/Utils.Cryptography/monocypher/vendor/tests/gen/aead_ietf.c
new file mode 100644
index 0000000..a45547e
--- /dev/null
+++ b/lib/Utils.Cryptography/monocypher/vendor/tests/gen/aead_ietf.c
@@ -0,0 +1,83 @@
+// This file is dual-licensed. Choose whichever licence you want from
+// the two licences listed below.
+//
+// The first licence is a regular 2-clause BSD licence. The second licence
+// is the CC-0 from Creative Commons. It is intended to release Monocypher
+// to the public domain. The BSD licence serves as a fallback option.
+//
+// SPDX-License-Identifier: BSD-2-Clause OR CC0-1.0
+//
+// ------------------------------------------------------------------------
+//
+// Copyright (c) 2017-2019, Loup Vaillant
+// 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 COPYRIGHT HOLDERS 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 COPYRIGHT
+// HOLDER 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.
+//
+// ------------------------------------------------------------------------
+//
+// Written in 2017-2019 by Loup Vaillant
+//
+// To the extent possible under law, the author(s) have dedicated all copyright
+// and related 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
+// <https://creativecommons.org/publicdomain/zero/1.0/>
+
+#include <sodium.h>
+#include "utils.h"
+
+static void test(size_t text_size, size_t ad_size)
+{
+ RANDOM_INPUT(key , 32);
+ RANDOM_INPUT(nonce, 24);
+ RANDOM_INPUT(ad , 32); // ad size <= 32
+ RANDOM_INPUT(text , 128); // text_size <= 128
+ u8 out[16 + 128]; // text_size <= 128
+
+ crypto_aead_xchacha20poly1305_ietf_encrypt_detached(
+ out + 16, out, 0, text, text_size, ad, ad_size, 0, nonce, key);
+
+ print_vector(key , 32);
+ print_vector(nonce , 24);
+ print_vector(ad , ad_size);
+ print_vector(text , text_size);
+ print_vector(out , text_size + 16);
+ printf("\n");
+}
+
+int main(void)
+{
+ SODIUM_INIT;
+ // regular tests
+ FOR (text_size, 0, 128) { test(text_size, 0); }
+ FOR (text_size, 0, 128) { test(text_size, 4); }
+ FOR ( ad_size, 0, 32) { test(0, ad_size); }
+ FOR ( ad_size, 0, 32) { test(16, ad_size); }
+ return 0;
+}
diff --git a/lib/Utils.Cryptography/monocypher/vendor/tests/gen/argon2.c b/lib/Utils.Cryptography/monocypher/vendor/tests/gen/argon2.c
new file mode 100644
index 0000000..75dd4ca
--- /dev/null
+++ b/lib/Utils.Cryptography/monocypher/vendor/tests/gen/argon2.c
@@ -0,0 +1,99 @@
+// This file is dual-licensed. Choose whichever licence you want from
+// the two licences listed below.
+//
+// The first licence is a regular 2-clause BSD licence. The second licence
+// is the CC-0 from Creative Commons. It is intended to release Monocypher
+// to the public domain. The BSD licence serves as a fallback option.
+//
+// SPDX-License-Identifier: BSD-2-Clause OR CC0-1.0
+//
+// ------------------------------------------------------------------------
+//
+// Copyright (c) 2017-2019, Loup Vaillant
+// 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 COPYRIGHT HOLDERS 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 COPYRIGHT
+// HOLDER 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.
+//
+// ------------------------------------------------------------------------
+//
+// Written in 2017-2019 by Loup Vaillant
+//
+// To the extent possible under law, the author(s) have dedicated all copyright
+// and related 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
+// <https://creativecommons.org/publicdomain/zero/1.0/>
+
+#include <sodium.h>
+#include "utils.h"
+
+static void test(u32 alg, size_t nb_blocks, size_t hash_size, size_t nb_passes)
+{
+ RANDOM_INPUT(password, 16 );
+ RANDOM_INPUT(salt , crypto_pwhash_SALTBYTES);
+ u8 hash[256];
+
+ int algorithm = -1;
+ switch (alg) {
+ case 0: fprintf(stderr, "Libsodium does not support Argon2d"); break;
+ case 1: algorithm = crypto_pwhash_ALG_ARGON2I13; break;
+ case 2: algorithm = crypto_pwhash_ALG_ARGON2ID13; break;
+ default: fprintf(stderr, "Unknown algorithm");
+ }
+
+ if (crypto_pwhash(hash, hash_size, (char*)password, 16, salt,
+ nb_passes, nb_blocks * 1024, algorithm)) {
+ fprintf(stderr, "Argon2i failed. "
+ "nb_blocks = %lu, "
+ "hash_size = %lu "
+ "nb_passes = %lu\n",
+ nb_blocks, hash_size, nb_passes);
+ printf(":deadbeef:\n"); // prints a canary to fail subsequent tests
+ }
+
+ print_number(alg);
+ print_number(nb_blocks);
+ print_number(nb_passes);
+ print_number(1); // one lane (no parallelism)
+ print_vector(password, 16);
+ print_vector(salt , crypto_pwhash_SALTBYTES);
+ printf(":\n"); // no key
+ printf(":\n"); // no additionnal data
+ print_vector(hash, hash_size);
+ printf("\n");
+}
+
+int main(void)
+{
+ SODIUM_INIT;
+ FOR (nb_blocks, 508, 517) { test(1, nb_blocks, 32 , 3 ); }
+ FOR (nb_blocks, 508, 517) { test(2, nb_blocks, 32 , 3 ); }
+ FOR (hash_size, 63, 65) { test(1, 8 , hash_size, 3 ); }
+ FOR (nb_passes, 3, 6) { test(1, 8 , 32 , nb_passes); }
+ return 0;
+}
diff --git a/lib/Utils.Cryptography/monocypher/vendor/tests/gen/blake2b.c b/lib/Utils.Cryptography/monocypher/vendor/tests/gen/blake2b.c
new file mode 100644
index 0000000..97b629b
--- /dev/null
+++ b/lib/Utils.Cryptography/monocypher/vendor/tests/gen/blake2b.c
@@ -0,0 +1,83 @@
+// This file is dual-licensed. Choose whichever licence you want from
+// the two licences listed below.
+//
+// The first licence is a regular 2-clause BSD licence. The second licence
+// is the CC-0 from Creative Commons. It is intended to release Monocypher
+// to the public domain. The BSD licence serves as a fallback option.
+//
+// SPDX-License-Identifier: BSD-2-Clause OR CC0-1.0
+//
+// ------------------------------------------------------------------------
+//
+// Copyright (c) 2017-2019, Loup Vaillant
+// 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 COPYRIGHT HOLDERS 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 COPYRIGHT
+// HOLDER 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.
+//
+// ------------------------------------------------------------------------
+//
+// Written in 2017-2019 by Loup Vaillant
+//
+// To the extent possible under law, the author(s) have dedicated all copyright
+// and related 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
+// <https://creativecommons.org/publicdomain/zero/1.0/>
+
+#include <sodium.h>
+#include "utils.h"
+
+static void test(size_t size, size_t key_size, size_t hash_size)
+{
+ RANDOM_INPUT(in , 256);
+ RANDOM_INPUT(key , 64);
+ u8 hash[64];
+
+ crypto_generichash(hash, hash_size, in, size, key, key_size);
+
+ print_vector(in , size);
+ print_vector(key , key_size);
+ print_vector(hash, hash_size);
+ printf("\n");
+}
+
+int main(void)
+{
+ SODIUM_INIT;
+ // Official test vectors test for all message sizes, so no need to
+ // repeat ourselves here. However they only test keys and hashes of size 64.
+ // Here we're testing many possible key and hash sizes.
+ for (size_t key_size = 0; key_size <= 64; key_size += 16) {
+ for (size_t hash_size = 0; hash_size <= 64; hash_size += 16) {
+ for (size_t input_size = 0; input_size <= 256; input_size += 16) {
+ test(input_size, key_size, hash_size);
+ }
+ }
+ }
+ return 0;
+}
diff --git a/lib/Utils.Cryptography/monocypher/vendor/tests/gen/chacha20.c b/lib/Utils.Cryptography/monocypher/vendor/tests/gen/chacha20.c
new file mode 100644
index 0000000..1ebdc6d
--- /dev/null
+++ b/lib/Utils.Cryptography/monocypher/vendor/tests/gen/chacha20.c
@@ -0,0 +1,82 @@
+// This file is dual-licensed. Choose whichever licence you want from
+// the two licences listed below.
+//
+// The first licence is a regular 2-clause BSD licence. The second licence
+// is the CC-0 from Creative Commons. It is intended to release Monocypher
+// to the public domain. The BSD licence serves as a fallback option.
+//
+// SPDX-License-Identifier: BSD-2-Clause OR CC0-1.0
+//
+// ------------------------------------------------------------------------
+//
+// Copyright (c) 2017-2019, Loup Vaillant
+// 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 COPYRIGHT HOLDERS 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 COPYRIGHT
+// HOLDER 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.
+//
+// ------------------------------------------------------------------------
+//
+// Written in 2017-2019 by Loup Vaillant
+//
+// To the extent possible under law, the author(s) have dedicated all copyright
+// and related 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
+// <https://creativecommons.org/publicdomain/zero/1.0/>
+
+#include <sodium.h>
+#include "utils.h"
+
+static void test(size_t size, u64 ctr)
+{
+ RANDOM_INPUT(key , 32);
+ RANDOM_INPUT(nonce, 8);
+ RANDOM_INPUT(in , 128); // size <= 128
+ u8 out [128]; // size <= 128
+
+ crypto_stream_chacha20_xor_ic(out, in, size, nonce, ctr, key);
+
+ print_vector(key , 32);
+ print_vector(nonce , 8);
+ print_vector(in , size);
+ print_number(ctr );
+ print_vector(out, size);
+ printf("\n");
+}
+
+int main(void)
+{
+ SODIUM_INIT;
+ // regular tests
+ FOR (size, 0, 128) { test(size, rand64()); }
+ // counter overflow (should wrap around)
+ test(128, -1);
+ test(128, -2);
+ test(128, -3);
+ return 0;
+}
diff --git a/lib/Utils.Cryptography/monocypher/vendor/tests/gen/edDSA.c b/lib/Utils.Cryptography/monocypher/vendor/tests/gen/edDSA.c
new file mode 100644
index 0000000..835344d
--- /dev/null
+++ b/lib/Utils.Cryptography/monocypher/vendor/tests/gen/edDSA.c
@@ -0,0 +1,74 @@
+// This file is dual-licensed. Choose whichever licence you want from
+// the two licences listed below.
+//
+// The first licence is a regular 2-clause BSD licence. The second licence
+// is the CC-0 from Creative Commons. It is intended to release Monocypher
+// to the public domain. The BSD licence serves as a fallback option.
+//
+// SPDX-License-Identifier: BSD-2-Clause OR CC0-1.0
+//
+// ------------------------------------------------------------------------
+//
+// Copyright (c) 2017-2019, Loup Vaillant
+// 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 COPYRIGHT HOLDERS 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 COPYRIGHT
+// HOLDER 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.
+//
+// ------------------------------------------------------------------------
+//
+// Written in 2017-2019 by Loup Vaillant
+//
+// To the extent possible under law, the author(s) have dedicated all copyright
+// and related 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
+// <https://creativecommons.org/publicdomain/zero/1.0/>
+
+#include "utils.h"
+#include "ed25519.h"
+
+static void test(size_t msg_size)
+{
+ RANDOM_INPUT(sk , 32);
+ RANDOM_INPUT(msg, 256);
+ u8 pk[32], sig[64];
+
+ ed25519_publickey(sk, pk);
+ ed25519_sign(msg, msg_size, sk, pk, sig);
+
+ print_vector(sk , 32 );
+ print_vector(pk , 32 );
+ print_vector(msg, msg_size);
+ print_vector(sig, 64 );
+}
+
+int main(void)
+{
+ FOR (msg_size, 0, 256) { test(msg_size); }
+ return 0;
+}
diff --git a/lib/Utils.Cryptography/monocypher/vendor/tests/gen/edDSA_pk.c b/lib/Utils.Cryptography/monocypher/vendor/tests/gen/edDSA_pk.c
new file mode 100644
index 0000000..420bb2e
--- /dev/null
+++ b/lib/Utils.Cryptography/monocypher/vendor/tests/gen/edDSA_pk.c
@@ -0,0 +1,76 @@
+// This file is dual-licensed. Choose whichever licence you want from
+// the two licences listed below.
+//
+// The first licence is a regular 2-clause BSD licence. The second licence
+// is the CC-0 from Creative Commons. It is intended to release Monocypher
+// to the public domain. The BSD licence serves as a fallback option.
+//
+// SPDX-License-Identifier: BSD-2-Clause OR CC0-1.0
+//
+// ------------------------------------------------------------------------
+//
+// Copyright (c) 2017-2019, Loup Vaillant
+// 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 COPYRIGHT HOLDERS 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 COPYRIGHT
+// HOLDER 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.
+//
+// ------------------------------------------------------------------------
+//
+// Written in 2017-2019 by Loup Vaillant
+//
+// To the extent possible under law, the author(s) have dedicated all copyright
+// and related 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
+// <https://creativecommons.org/publicdomain/zero/1.0/>
+
+#include "utils.h"
+#include "ed25519.h"
+
+static void test(u8 sk[32])
+{
+ u8 pk[32];
+ ed25519_publickey(sk, pk);
+
+ print_vector(sk, 32);
+ print_vector(pk, 32);
+}
+
+int main(void)
+{
+ // random secret keys
+ FOR (msg_size, 0, 256) {
+ RANDOM_INPUT(sk, 32);
+ test(sk);
+ }
+ // zero secret key
+ u8 sk[32] = {0};
+ test(sk);
+
+ return 0;
+}
diff --git a/lib/Utils.Cryptography/monocypher/vendor/tests/gen/ed_25519.c b/lib/Utils.Cryptography/monocypher/vendor/tests/gen/ed_25519.c
new file mode 100644
index 0000000..47a1c5a
--- /dev/null
+++ b/lib/Utils.Cryptography/monocypher/vendor/tests/gen/ed_25519.c
@@ -0,0 +1,75 @@
+// This file is dual-licensed. Choose whichever licence you want from
+// the two licences listed below.
+//
+// The first licence is a regular 2-clause BSD licence. The second licence
+// is the CC-0 from Creative Commons. It is intended to release Monocypher
+// to the public domain. The BSD licence serves as a fallback option.
+//
+// SPDX-License-Identifier: BSD-2-Clause OR CC0-1.0
+//
+// ------------------------------------------------------------------------
+//
+// Copyright (c) 2017-2019, Loup Vaillant
+// 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 COPYRIGHT HOLDERS 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 COPYRIGHT
+// HOLDER 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.
+//
+// ------------------------------------------------------------------------
+//
+// Written in 2017-2019 by Loup Vaillant
+//
+// To the extent possible under law, the author(s) have dedicated all copyright
+// and related 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
+// <https://creativecommons.org/publicdomain/zero/1.0/>
+
+#include <sodium.h>
+#include "utils.h"
+
+static void test(size_t msg_size)
+{
+ RANDOM_INPUT(seed, 32);
+ RANDOM_INPUT(msg , 256);
+ u8 pk[32], sk[64], sig[64];
+
+ crypto_sign_seed_keypair(pk, sk, seed);
+ crypto_sign_detached(sig, 0, msg, msg_size, sk);
+
+ print_vector(sk , 32 );
+ print_vector(pk , 32 );
+ print_vector(msg, msg_size);
+ print_vector(sig, 64 );
+}
+
+int main(void)
+{
+ SODIUM_INIT;
+ FOR (msg_size, 0, 256) { test(msg_size); }
+ return 0;
+}
diff --git a/lib/Utils.Cryptography/monocypher/vendor/tests/gen/ed_25519_pk.c b/lib/Utils.Cryptography/monocypher/vendor/tests/gen/ed_25519_pk.c
new file mode 100644
index 0000000..dc5db7e
--- /dev/null
+++ b/lib/Utils.Cryptography/monocypher/vendor/tests/gen/ed_25519_pk.c
@@ -0,0 +1,77 @@
+// This file is dual-licensed. Choose whichever licence you want from
+// the two licences listed below.
+//
+// The first licence is a regular 2-clause BSD licence. The second licence
+// is the CC-0 from Creative Commons. It is intended to release Monocypher
+// to the public domain. The BSD licence serves as a fallback option.
+//
+// SPDX-License-Identifier: BSD-2-Clause OR CC0-1.0
+//
+// ------------------------------------------------------------------------
+//
+// Copyright (c) 2017-2019, Loup Vaillant
+// 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 COPYRIGHT HOLDERS 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 COPYRIGHT
+// HOLDER 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.
+//
+// ------------------------------------------------------------------------
+//
+// Written in 2017-2019 by Loup Vaillant
+//
+// To the extent possible under law, the author(s) have dedicated all copyright
+// and related 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
+// <https://creativecommons.org/publicdomain/zero/1.0/>
+
+#include <sodium.h>
+#include "utils.h"
+
+static void test(u8 seed[32])
+{
+ u8 pk[32];
+ u8 sk[64];
+ crypto_sign_seed_keypair(pk, sk, seed);
+ print_vector(sk, 32);
+ print_vector(pk, 32);
+}
+
+int main(void)
+{
+ SODIUM_INIT;
+ // random secret keys
+ FOR (msg_size, 0, 256) {
+ RANDOM_INPUT(sk, 32);
+ test(sk);
+ }
+ // zero secret key
+ u8 sk[32] = {0};
+ test(sk);
+
+ return 0;
+}
diff --git a/lib/Utils.Cryptography/monocypher/vendor/tests/gen/elligator-direct.py b/lib/Utils.Cryptography/monocypher/vendor/tests/gen/elligator-direct.py
new file mode 100644
index 0000000..a0d38e2
--- /dev/null
+++ b/lib/Utils.Cryptography/monocypher/vendor/tests/gen/elligator-direct.py
@@ -0,0 +1,84 @@
+#! /usr/bin/env python3
+
+# This file is dual-licensed. Choose whichever licence you want from
+# the two licences listed below.
+#
+# The first licence is a regular 2-clause BSD licence. The second licence
+# is the CC-0 from Creative Commons. It is intended to release Monocypher
+# to the public domain. The BSD licence serves as a fallback option.
+#
+# SPDX-License-Identifier: BSD-2-Clause OR CC0-1.0
+#
+# ------------------------------------------------------------------------
+#
+# Copyright (c) 2020, Loup Vaillant
+# Copyright (c) 2020, Fabio Scotoni
+# 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 COPYRIGHT HOLDERS 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 COPYRIGHT
+# HOLDER 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.
+#
+# ------------------------------------------------------------------------
+#
+# Written in 2020 by Loup Vaillant and Fabio Scotoni
+#
+# To the extent possible under law, the author(s) have dedicated all copyright
+# and related 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
+# <https://creativecommons.org/publicdomain/zero/1.0/>
+
+from elligator import fe
+from elligator import curve_to_hash
+from elligator import hash_to_curve
+from elligator import fast_hash_to_curve
+from elligator import p
+from elligator import print_raw
+from random import randrange
+from random import seed
+
+def direct(r1, padding):
+ q1 = hash_to_curve(r1)
+ q2 = fast_hash_to_curve(r1)
+ r2 = curve_to_hash(q1[0], q1[1].is_negative())
+ if q1 != q2: raise ValueError('Incorrect fast_hash_to_curve')
+ if r1 != r2: raise ValueError('Round trip failure')
+ print_raw(r1.val + padding * 2**254)
+ q1[0].print() # u coordinate only
+ print()
+
+direct(fe(0), 0) # representative 0 maps to point (0, 0)
+direct(fe(0), 1) # representative 0 maps to point (0, 0)
+direct(fe(0), 2) # representative 0 maps to point (0, 0)
+direct(fe(0), 3) # representative 0 maps to point (0, 0)
+
+# Make test vector generation deterministic, the actual randomness does
+# not matter here since these are just tests.
+seed(12345)
+
+for i in range(50):
+ direct(fe(randrange(0, (p-1)//2)), i % 4)
diff --git a/lib/Utils.Cryptography/monocypher/vendor/tests/gen/elligator-inverse.py b/lib/Utils.Cryptography/monocypher/vendor/tests/gen/elligator-inverse.py
new file mode 100644
index 0000000..f607ee4
--- /dev/null
+++ b/lib/Utils.Cryptography/monocypher/vendor/tests/gen/elligator-inverse.py
@@ -0,0 +1,128 @@
+#! /usr/bin/env python3
+
+# This file is dual-licensed. Choose whichever licence you want from
+# the two licences listed below.
+#
+# The first licence is a regular 2-clause BSD licence. The second licence
+# is the CC-0 from Creative Commons. It is intended to release Monocypher
+# to the public domain. The BSD licence serves as a fallback option.
+#
+# SPDX-License-Identifier: BSD-2-Clause OR CC0-1.0
+#
+# ------------------------------------------------------------------------
+#
+# Copyright (c) 2020, Loup Vaillant
+# Copyright (c) 2020, Fabio Scotoni
+# 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 COPYRIGHT HOLDERS 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 COPYRIGHT
+# HOLDER 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.
+#
+# ------------------------------------------------------------------------
+#
+# Written in 2020 by Loup Vaillant and Fabio Scotoni
+#
+# To the extent possible under law, the author(s) have dedicated all copyright
+# and related 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
+# <https://creativecommons.org/publicdomain/zero/1.0/>
+
+from elligator import can_curve_to_hash
+from elligator import curve_to_hash
+from elligator import fast_curve_to_hash
+from elligator import fe
+from elligator import hash_to_curve
+from elligator import print_raw
+
+from elligator_scalarmult import scalarmult
+
+from random import randrange
+from random import seed
+
+def redundant_curve_to_hash(u, tweak):
+ v_is_negative = tweak % 2 == 1;
+ r1 = None
+ if can_curve_to_hash(u):
+ r1 = curve_to_hash(u, v_is_negative)
+ r2 = fast_curve_to_hash(u, v_is_negative)
+ if r1 != r2: raise ValueError('Incoherent hash_to_curve')
+ return r1
+
+def private_to_curve_and_hash(scalar, tweak):
+ cofactor = scalar % 8
+ msb = (tweak // 2**6) * 2**254
+ u = scalarmult(scalar, cofactor)
+ r1 = redundant_curve_to_hash(u, tweak)
+ if r1 is None:
+ return u, None
+ if r1.val > 2**254: raise ValueError('Representative too big')
+ u2, v2 = hash_to_curve(r1)
+ if u2 != u: raise ValueError('Round trip failure')
+ return (u, r1.val + msb)
+
+# Make test vector generation deterministic, the actual randomness does
+# not matter here since these are just tests.
+seed(12345)
+
+# Zero
+for tweak in range(2):
+ print_raw(0)
+ print(format(tweak, '02x') + ":")
+ print('00:') # Success
+ redundant_curve_to_hash(fe(0), tweak).print()
+ print()
+
+# All possible failures
+for cofactor in range(8):
+ tweak = randrange(0, 256)
+ while True:
+ scalar = randrange(0, 2**253) * 8 + cofactor
+ u, r = private_to_curve_and_hash(scalar, tweak)
+ if r is None:
+ u.print()
+ print(format(tweak, '02x') + ":")
+ print('ff:') # Failure
+ print(':') # dummy value for the hash
+ print()
+ break
+
+# All possible successes
+for cofactor in range(8):
+ for sign in range(2):
+ for msb in range(4):
+ tweak = sign + randrange(0, 32) * 2 + msb * 64
+ while True:
+ scalar = randrange(0, 2**253) * 8 + cofactor
+ u, r = private_to_curve_and_hash(scalar, tweak)
+ if r is not None:
+ u.print()
+ print(format(tweak, '02x') + ":")
+ print('00:') # Success
+ print_raw(r)
+ print()
+ break
diff --git a/lib/Utils.Cryptography/monocypher/vendor/tests/gen/elligator.py b/lib/Utils.Cryptography/monocypher/vendor/tests/gen/elligator.py
new file mode 100644
index 0000000..b1362bd
--- /dev/null
+++ b/lib/Utils.Cryptography/monocypher/vendor/tests/gen/elligator.py
@@ -0,0 +1,370 @@
+#! /usr/bin/env python3
+
+# This file is dual-licensed. Choose whichever licence you want from
+# the two licences listed below.
+#
+# The first licence is a regular 2-clause BSD licence. The second licence
+# is the CC-0 from Creative Commons. It is intended to release Monocypher
+# to the public domain. The BSD licence serves as a fallback option.
+#
+# SPDX-License-Identifier: BSD-2-Clause OR CC0-1.0
+#
+# ------------------------------------------------------------------------
+#
+# Copyright (c) 2020, Loup Vaillant and Andrew Moon
+# 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 COPYRIGHT HOLDERS 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 COPYRIGHT
+# HOLDER 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.
+#
+# ------------------------------------------------------------------------
+#
+# Written in 2020 by Loup Vaillant and Andrew Moon
+#
+# To the extent possible under law, the author(s) have dedicated all copyright
+# and related 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
+# <https://creativecommons.org/publicdomain/zero/1.0/>
+
+####################
+# Field arithmetic #
+####################
+class fe:
+ """Prime field over 2^255 - 19"""
+ p = 2**255 - 19
+ def __init__(self, x):
+ self.val = x % self.p
+
+ # Basic arithmetic operations
+ def __neg__ (self ): return fe(-self.val )
+ def __add__ (self, o): return fe( self.val + o.val )
+ def __sub__ (self, o): return fe( self.val - o.val )
+ def __mul__ (self, o): return fe((self.val * o.val ) % self.p)
+ def __truediv__ (self, o): return fe((self.val * o.invert().val) % self.p)
+ def __floordiv__(self, o): return fe( self.val // o )
+ def __pow__ (self, s): return fe(pow(self.val, s , self.p))
+ def invert (self ): return fe(pow(self.val, self.p-2, self.p))
+
+ def __eq__(self, other): return self.val % self.p == other.val % self.p
+ def __ne__(self, other): return self.val % self.p != other.val % self.p
+ def is_positive(self) : return self.val % self.p <= (p-1) // 2
+ def is_negative(self) : return self.val % self.p > (p-1) // 2
+
+ def abs(self):
+ if self.is_positive(): return self
+ else : return -self
+
+ def print(self):
+ """prints a field element in little endian"""
+ m = self.val % self.p
+ for _ in range(32):
+ print(format(m % 256, '02x'), end='')
+ m //= 256
+ if m != 0: raise ValueError('number is too big!!')
+ print(':')
+
+def print_raw(raw):
+ """prints a raw element in little endian"""
+ for _ in range(32):
+ print(format(raw % 256, '02x'), end='')
+ raw //= 256
+ if raw != 0: raise ValueError('number is too big!!')
+ print(':')
+
+########################
+# Curve25519 constants #
+########################
+p = fe.p
+A = fe(486662)
+# B = 1
+
+###############
+# Square root #
+###############
+
+# Legendre symbol:
+# - 0 if n is zero
+# - 1 if n is a non-zero square
+# - -1 if n is not a square
+# We take for granted that n^((p-1)/2) does what we want
+def chi (n): return n**((p-1)//2)
+def is_square(n): return n == fe(0) or chi(n) == fe(1)
+
+# square root of -1
+sqrtm1 = (fe(2)**((p-1) // 4)).abs()
+if sqrtm1 * sqrtm1 != fe(-1): raise ValueError('Wrong sqrtm1')
+
+# The square root of n, if n is a square.
+#
+# Note that p is congruent to 5 modulo 8, so (p+3)/8 is an integer.
+# If n is zero, then n^((p+3)/8) is zero (zero is its own square root).
+# Otherwise:
+# (n^((p+3)/8))^4 = n^((p+3)/2)
+# (n^((p+3)/8))^4 = n^((p-1)/2) * n^2
+# (n^((p+3)/8))^4 = chi(n) * n^2 -- chi(n) == 1
+# (n^((p+3)/8))^4 = n^2 -- because n is a non-zero square
+# (n^((p+3)/8))^2 = n or -n
+# case n:
+# (n^((p+3)/8))^2 = n
+# n^((p+3)/8) = sqrt(n) or -sqrt(n)
+# case -n:
+# (n^((p+3)/8))^2 = -n
+# -1 * (n^((p+3)/8))^2 = n
+# sqrt(-1) * n^((p+3)/8) = sqrt(n) or -sqrt(n)
+#
+# We then choose the positive square root, between 0 and (p-1)/2
+def sqrt(n):
+ if not is_square(n) : raise ValueError('Not a square!')
+ root = n**((p+3) // 8)
+ if root * root != n: root = (root * sqrtm1)
+ if root * root != n: raise ValueError('Should be a square!!')
+ return root.abs()
+
+###########################
+# Elligator 2 (reference) #
+###########################
+
+# Elligator: Elliptic-curve points indistinguishable from uniform random strings
+# by Daniel J. Bernstein, Mike Hamburg, Anna Krasnova, and Tanja Lange
+# 2013
+# https://elligator.cr.yp.to/
+
+# Arbitrary non square, typically chosen to minimise computation.
+# 2 and sqrt(-1) both work fairly well, but 2 seems to be more popular.
+# We stick to 2 for compatibility.
+non_square = fe(2)
+
+# Representative to curve point, straight from the paper.
+
+# Unlike the paper, curve coordinates are called (u, v) to follow
+# established conventions. Thus, "v" in the paper is called "w" here.
+def hash_to_curve(r):
+ w = -A / (fe(1) + non_square * r**2)
+ e = chi(w**3 + A*w**2 + w)
+ u = e*w - (fe(1)-e)*(A//2)
+ v = -e * sqrt(u**3 + A*u**2 + u)
+ return (u, v)
+
+# Test whether a point has a representative, straight from the paper.
+def can_curve_to_hash(u):
+ return u != -A and is_square(-non_square * u * (u+A))
+
+# Computes the representative of a point, straight from the paper.
+def curve_to_hash(u, v_is_negative):
+ if not can_curve_to_hash(u):
+ raise ValueError('cannot curve to hash')
+ sq1 = sqrt(-u / (non_square * (u+A)))
+ sq2 = sqrt(-(u+A) / (non_square * u ))
+ if v_is_negative: return sq2
+ else : return sq1
+
+#####################
+# Elligator2 (fast) #
+#####################
+
+# Inverse square root.
+# Returns (0 , True ) if x is zero.
+# Returns (sqrt(1/x) , True ) if x is non-zero square.
+# Returns (sqrt(sqrt(-1)/x), False) if x is not a square.
+# We do not guarantee the sign of the square root.
+#
+# Notes:
+# Let quartic = x^((p-1)/4)
+#
+# x^((p-1)/2) = chi(x)
+# quartic^2 = chi(x)
+# quartic = sqrt(chi(x))
+# quartic = 1 or -1 or sqrt(-1) or -sqrt(-1)
+#
+# Note that x is a square if quartic is 1 or -1
+# There are 4 cases to consider:
+#
+# if quartic = 1 (x is a square)
+# then x^((p-1)/4) = 1
+# x^((p-5)/4) * x = 1
+# x^((p-5)/4) = 1/x
+# x^((p-5)/8) = sqrt(1/x) or -sqrt(1/x)
+#
+# if quartic = -1 (x is a square)
+# then x^((p-1)/4) = -1
+# x^((p-5)/4) * x = -1
+# x^((p-5)/4) = -1/x
+# x^((p-5)/8) = sqrt(-1) / sqrt(x)
+# x^((p-5)/8) * sqrt(-1) = sqrt(-1)^2 / sqrt(x)
+# x^((p-5)/8) * sqrt(-1) = -1/sqrt(x)
+# x^((p-5)/8) * sqrt(-1) = -sqrt(1/x) or sqrt(1/x)
+#
+# if quartic = sqrt(-1) (x is not a square)
+# then x^((p-1)/4) = sqrt(-1)
+# x^((p-5)/4) * x = sqrt(-1)
+# x^((p-5)/4) = sqrt(-1)/x
+# x^((p-5)/8) = sqrt(sqrt(-1)/x) or -sqrt(sqrt(-1)/x)
+#
+# Note that the product of two non-squares is always a square:
+# For any non-squares a and b, chi(a) = -1 and chi(b) = -1.
+# Since chi(x) = x^((p-1)/2), chi(a)*chi(b) = chi(a*b) = 1.
+# Therefore a*b is a square.
+#
+# Since sqrt(-1) and x are both non-squares, their product is a
+# square, and we can compute their square root.
+#
+# if quartic = -sqrt(-1) (x is not a square)
+# then x^((p-1)/4) = -sqrt(-1)
+# x^((p-5)/4) * x = -sqrt(-1)
+# x^((p-5)/4) = -sqrt(-1)/x
+# x^((p-5)/8) = sqrt(-sqrt(-1)/x)
+# x^((p-5)/8) = sqrt( sqrt(-1)/x) * sqrt(-1)
+# x^((p-5)/8) * sqrt(-1) = sqrt( sqrt(-1)/x) * sqrt(-1)^2
+# x^((p-5)/8) * sqrt(-1) = sqrt( sqrt(-1)/x) * -1
+# x^((p-5)/8) * sqrt(-1) = -sqrt(sqrt(-1)/x) or sqrt(sqrt(-1)/x)
+def invsqrt(x):
+ isr = x**((p - 5) // 8)
+ quartic = x * isr**2
+ if quartic == fe(-1) or quartic == -sqrtm1:
+ isr = isr * sqrtm1
+ is_square = quartic == fe(1) or quartic == fe(-1) or x == fe(0)
+ return isr, is_square
+
+# From the paper:
+# w = -A / (fe(1) + non_square * r^2)
+# e = chi(w^3 + A*w^2 + w)
+# u = e*w - (fe(1)-e)*(A//2)
+# v = -e * sqrt(u^3 + A*u^2 + u)
+#
+# Note that e is either 0, 1 or -1
+# if e = 0
+# (u, v) = (0, 0)
+# if e = 1
+# u = w
+# v = -sqrt(u^3 + A*u^2 + u)
+# if e = -1
+# u = -w - A = w * non_square * r^2
+# v = sqrt(u^3 + A*u^2 + u)
+#
+# Let r1 = non_square * r^2
+# Let r2 = 1 + r1
+# Note that r2 cannot be zero, -1/non_square is not a square.
+# We can (tediously) verify that:
+# w^3 + A*w^2 + w = (A^2*r1 - r2^2) * A / r2^3
+# Therefore:
+# chi(w^3 + A*w^2 + w) = chi((A^2*r1 - r2^2) * (A / r2^3))
+# chi(w^3 + A*w^2 + w) = chi((A^2*r1 - r2^2) * (A / r2^3)) * 1
+# chi(w^3 + A*w^2 + w) = chi((A^2*r1 - r2^2) * (A / r2^3)) * chi(r2^6)
+# chi(w^3 + A*w^2 + w) = chi((A^2*r1 - r2^2) * (A / r2^3) * r2^6)
+# chi(w^3 + A*w^2 + w) = chi((A^2*r1 - r2^2) * A * r2^3)
+# Corollary:
+# e = 1 if (A^2*r1 - r2^2) * A * r2^3) is a non-zero square
+# e = -1 if (A^2*r1 - r2^2) * A * r2^3) is not a square
+# Note that w^3 + A*w^2 + w (and therefore e) can never be zero:
+# w^3 + A*w^2 + w = w * (w^2 + A*w + 1)
+# w^3 + A*w^2 + w = w * (w^2 + A*w + A^2/4 - A^2/4 + 1)
+# w^3 + A*w^2 + w = w * (w + A/2)^2 - A^2/4 + 1)
+# which is zero only if:
+# w = 0 (impossible)
+# (w + A/2)^2 = A^2/4 - 1 (impossible, because A^2/4-1 is not a square)
+#
+# Let isr = invsqrt((A^2*r1 - r2^2) * A * r2^3)
+# isr = sqrt(1 / ((A^2*r1 - r2^2) * A * r2^3)) if e = 1
+# isr = strt(sqrt(-1) / ((A^2*r1 - r2^2) * A * r2^3)) if e = -1
+#
+# if e = 1
+# let u1 = -A * (A^2*r1 - r2^2) * A * r2^2 * isr^2
+# u1 = w
+# u1 = u
+# let v1 = -(A^2*r1 - r2^2) * A * isr
+# v1 = -sqrt((A^2*r1 - r2^2) * A / r2^3)
+# v1 = -sqrt(w^3 + A*w^2 + w)
+# v1 = -sqrt(u^3 + A*u^2 + u) (because u = w)
+# v1 = v
+#
+# if e = -1
+# let ufactor = -non_square * sqrt(-1) * r^2
+# let vfactor = sqrt(ufactor)
+# let u2 = -A * (A^2*r1 - r2^2) * A * r2^2 * isr^2 * ufactor
+# u2 = w * -1 * -non_square * r^2
+# u2 = w * non_square * r^2
+# u2 = u
+# let v2 = (A^2*r1 - r2^2) * A * isr * vfactor
+# v2 = sqrt(non_square * r^2 * (A^2*r1 - r2^2) * A / r2^3)
+# v2 = sqrt(non_square * r^2 * (w^3 + A*w^2 + w))
+# v2 = sqrt(non_square * r^2 * w * (w^2 + A*w + 1))
+# v2 = sqrt(u (w^2 + A*w + 1))
+# v2 = sqrt(u ((-u-A)^2 + A*(-u-A) + 1))
+# v2 = sqrt(u (u^2 + A^2 + 2*A*u - A*u -A^2) + 1))
+# v2 = sqrt(u (u^2 + A*u + 1))
+# v2 = sqrt(u^3 + A*u^2 + u)
+# v2 = v
+ufactor = -non_square * sqrtm1
+vfactor = sqrt(ufactor)
+
+def fast_hash_to_curve(r):
+ t1 = r**2 * non_square # r1
+ u = t1 + fe(1) # r2
+ t2 = u**2
+ t3 = (A**2 * t1 - t2) * A # numerator
+ t1 = t2 * u # denominator
+ t1, is_square = invsqrt(t3 * t1)
+ u = r**2 * ufactor
+ v = r * vfactor
+ if is_square: u = fe(1)
+ if is_square: v = fe(1)
+ v = v * t3 * t1
+ t1 = t1**2
+ u = u * -A * t3 * t2 * t1
+ if is_square != v.is_negative(): # XOR
+ v = -v
+ return (u, v)
+
+# From the paper:
+# Let sq = -non_square * u * (u+A)
+# if sq is not a square, or u = -A, there is no mapping
+# Assuming there is a mapping:
+# if v is positive: r = sqrt(-u / (non_square * (u+A)))
+# if v is negative: r = sqrt(-(u+A) / (non_square * u ))
+#
+# We compute isr = invsqrt(-non_square * u * (u+A))
+# if it wasn't a square, abort.
+# else, isr = sqrt(-1 / (non_square * u * (u+A))
+#
+# If v is positive, we return isr * u:
+# isr * u = sqrt(-1 / (non_square * u * (u+A)) * u
+# isr * u = sqrt(-u / (non_square * (u+A))
+#
+# If v is negative, we return isr * (u+A):
+# isr * (u+A) = sqrt(-1 / (non_square * u * (u+A)) * (u+A)
+# isr * (u+A) = sqrt(-(u+A) / (non_square * u)
+def fast_curve_to_hash(u, v_is_negative):
+ t = u + A
+ r = -non_square * u * t
+ isr, is_square = invsqrt(r)
+ if not is_square:
+ return None
+ if v_is_negative: u = t
+ r = u * isr
+ r = r.abs()
+ return r
diff --git a/lib/Utils.Cryptography/monocypher/vendor/tests/gen/elligator_scalarmult.py b/lib/Utils.Cryptography/monocypher/vendor/tests/gen/elligator_scalarmult.py
new file mode 100644
index 0000000..a0d84e0
--- /dev/null
+++ b/lib/Utils.Cryptography/monocypher/vendor/tests/gen/elligator_scalarmult.py
@@ -0,0 +1,230 @@
+#! /usr/bin/env python3
+
+# This file is dual-licensed. Choose whichever licence you want from
+# the two licences listed below.
+#
+# The first licence is a regular 2-clause BSD licence. The second licence
+# is the CC-0 from Creative Commons. It is intended to release Monocypher
+# to the public domain. The BSD licence serves as a fallback option.
+#
+# SPDX-License-Identifier: BSD-2-Clause OR CC0-1.0
+#
+# ------------------------------------------------------------------------
+#
+# Copyright (c) 2020, Loup Vaillant
+# 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 COPYRIGHT HOLDERS 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 COPYRIGHT
+# HOLDER 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.
+#
+# ------------------------------------------------------------------------
+#
+# Written in 2020 by Loup Vaillant
+#
+# To the extent possible under law, the author(s) have dedicated all copyright
+# and related 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
+# <https://creativecommons.org/publicdomain/zero/1.0/>
+
+from elligator import fe
+from elligator import sqrt
+from elligator import sqrtm1
+from elligator import A
+
+#########################################
+# scalar multiplication (Edwards space) #
+#########################################
+
+# Edwards25519 equation (d defined below):
+# -x^2 + y^2 = 1 + d*x^2*y^2
+d = fe(-121665) / fe(121666)
+
+# Point addition:
+# denum = d*x1*x2*y1*y2
+# x = (x1*y2 + x2*y1) / (1 + denum)
+# y = (y1*y2 + x1*x2) / (1 - denum)
+# To avoid divisions, we use affine coordinates: x = X/Z, y = Y/Z.
+# We can multiply Z instead of dividing X and Y.
+def point_add(a, b):
+ x1, y1, z1 = a
+ x2, y2, z2 = b
+ denum = d*x1*x2*y1*y2
+ z1z2 = z1 * z2
+ z1z22 = z1z2**2
+ xt = z1z2 * (x1*y2 + x2*y1)
+ yt = z1z2 * (y1*y2 + x1*x2)
+ zx = z1z22 + denum
+ zy = z1z22 - denum
+ return (xt*zy, yt*zx, zx*zy)
+
+# Point addition, with the final division
+def point_add2(p1, p2):
+ x1, y1 = p1
+ x2, y2 = p2
+ z1, z2 = (fe(1), fe(1))
+ x, y, z = point_add((x1, y1, z1), (x2, y2, z2))
+ div = z.invert()
+ return (x*div, y*div)
+
+# scalar multiplication in edwards space:
+# point + point + ... + point, scalar times
+# (using a double and add ladder for speed)
+def ed_scalarmult(point, scalar):
+ affine = (point[0], point[1], fe(1))
+ acc = (fe(0), fe(1), fe(1))
+ binary = [int(c) for c in list(format(scalar, 'b'))]
+ for i in binary:
+ acc = point_add(acc, acc)
+ if i == 1:
+ acc = point_add(acc, affine)
+ return acc
+
+# convert the point to Montgomery (u coordinate only)
+# (u, v) = ((1+y)/(1-y), sqrt(-486664)*u/x)
+# (x, y) = (sqrt(-486664)*u/v, (u-1)/(u+1))
+def from_edwards(point):
+ x, y, z = point
+ return (z + y) / (z - y)
+
+# edwards base point
+eby = fe(4) / fe(5)
+ebx = sqrt((eby**2 - fe(1)) / (fe(1) + d * eby**2))
+edwards_base = (ebx, eby)
+
+############################################
+# scalar multiplication (Montgomery space) #
+############################################
+def mt_scalarmult(u, scalar):
+ x1 = u
+ x2, z2 = fe(1), fe(0) # "zero" point
+ x3, z3 = x1 , fe(1) # "one" point
+ binary = [int(c) for c in list(format(scalar, 'b'))]
+ for b in binary:
+ # Montgomery ladder step:
+ # if b == 0, then (P2, P3) == (P2*2 , P2+P3)
+ # if b == 1, then (P2, P3) == (P2+P3, P3*2 )
+ if b == 1:
+ x2, x3 = x3, x2
+ z2, z3 = z3, z2
+ x3, z3 = ((x2*x3 - z2*z3)**2,
+ (x2*z3 - z2*x3)**2 * x1)
+ x2, z2 = ((x2**2 - z2**2)**2,
+ fe(4)*x2*z2*(x2**2 + A*x2*z2 + z2**2))
+ if b == 1:
+ x2, x3 = x3, x2
+ z2, z3 = z3, z2
+ return x2 / z2
+
+montgomery_base = 9
+
+############################
+# Scalarmult with cofactor #
+############################
+
+# Keeping a random cofactor is important to keep points
+# indistinguishable from random. (Else we'd notice all representatives
+# represent points with cleared cofactor. Not exactly random.)
+
+# Point of order 8, used to add the cofactor component
+low_order_point_x = sqrt((sqrt(d + fe(1)) + fe(1)) / d)
+low_order_point_y = -low_order_point_x * sqrtm1
+low_order_point_1 = (low_order_point_x, low_order_point_y)
+low_order_point_2 = point_add2(low_order_point_1, low_order_point_1)
+low_order_point_4 = point_add2(low_order_point_2, low_order_point_2)
+low_order_point_8 = point_add2(low_order_point_4, low_order_point_4)
+low_order_point_5 = point_add2(low_order_point_1, low_order_point_4)
+
+def check_low_order_point():
+ lop2 = low_order_point_2
+ lop4 = low_order_point_4
+ lop8 = low_order_point_8
+ zero = (fe(0), fe(1))
+ if lop8 != zero: raise ValueError('low_order_point does not have low order')
+ if lop2 == zero: raise ValueError('low_order_point only has order 2')
+ if lop4 == zero: raise ValueError('low_order_point only has order 4')
+check_low_order_point()
+
+# base point + low order point
+ed_base_1 = point_add2(low_order_point_1, edwards_base) # in Edwards space
+ed_base_5 = point_add2(low_order_point_5, edwards_base) # in Edwards space
+mt_base_1 = (fe(1)+ed_base_1[1]) / (fe(1)-ed_base_1[1]) # in Montgomery space
+mt_base_5 = (fe(1)+ed_base_5[1]) / (fe(1)-ed_base_5[1]) # in Montgomery space
+
+# Clamp the scalar.
+# % 8 stops subgroup attacks
+# Clearing bit 255 and setting bit 254 facilitates constant time ladders.
+# We're not supposed to clear the cofactor, but scalar multiplication
+# usually does, and we want to reuse existing code as much as possible.
+def trim(scalar):
+ trimmed = scalar - scalar % 8
+ trimmed = trimmed % 2**254
+ trimmed = trimmed + 2**254
+ return trimmed
+
+order = 2**252 + 27742317777372353535851937790883648493
+
+# Single scalar multiplication (in Edwards space)
+def scalarmult1(scalar, cofactor):
+ co_cleared = ((cofactor * 5) % 8) * order # cleared main factor
+ combined = trim(scalar) + co_cleared
+ return from_edwards(ed_scalarmult(ed_base_1, combined))
+
+# Single scalar multiplication (in Edwards space, simplified)
+def scalarmult2(scalar, cofactor):
+ co_cleared = (cofactor % 8) * order # cleared main factor
+ combined = trim(scalar) + co_cleared
+ return from_edwards(ed_scalarmult(ed_base_5, combined))
+
+# Single scalar multiplication (in Montgomery space)
+def scalarmult3(scalar, cofactor):
+ co_cleared = ((cofactor * 5) % 8) * order # cleared main factor
+ combined = trim(scalar) + co_cleared
+ return mt_scalarmult(mt_base_1, combined)
+
+# Single scalar multiplication (in Montgomery space, simplified)
+def scalarmult4(scalar, cofactor):
+ co_cleared = (cofactor % 8) * order # cleared main factor
+ combined = trim(scalar) + co_cleared
+ return mt_scalarmult(mt_base_5, combined)
+
+# Double scalar multiplication (reuses EdDSA code)
+def scalarmult5(scalar, cofactor):
+ main_point = ed_scalarmult(edwards_base , trim(scalar))
+ low_order = ed_scalarmult(low_order_point_1, cofactor )
+ return from_edwards(point_add(main_point, low_order))
+
+# Combine and compare all ways of doing the scalar multiplication
+def scalarmult(scalar, cofactor):
+ p1 = scalarmult1(scalar, cofactor)
+ p2 = scalarmult2(scalar, cofactor)
+ p3 = scalarmult3(scalar, cofactor)
+ p4 = scalarmult4(scalar, cofactor)
+ p5 = scalarmult5(scalar, cofactor)
+ if p1 != p2 or p1 != p3 or p1 != p4 or p1 != p5:
+ raise ValueError('Incoherent scalarmult')
+ return p1
diff --git a/lib/Utils.Cryptography/monocypher/vendor/tests/gen/hchacha20.c b/lib/Utils.Cryptography/monocypher/vendor/tests/gen/hchacha20.c
new file mode 100644
index 0000000..55b5369
--- /dev/null
+++ b/lib/Utils.Cryptography/monocypher/vendor/tests/gen/hchacha20.c
@@ -0,0 +1,73 @@
+// This file is dual-licensed. Choose whichever licence you want from
+// the two licences listed below.
+//
+// The first licence is a regular 2-clause BSD licence. The second licence
+// is the CC-0 from Creative Commons. It is intended to release Monocypher
+// to the public domain. The BSD licence serves as a fallback option.
+//
+// SPDX-License-Identifier: BSD-2-Clause OR CC0-1.0
+//
+// ------------------------------------------------------------------------
+//
+// Copyright (c) 2017-2019, Loup Vaillant
+// 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 COPYRIGHT HOLDERS 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 COPYRIGHT
+// HOLDER 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.
+//
+// ------------------------------------------------------------------------
+//
+// Written in 2017-2019 by Loup Vaillant
+//
+// To the extent possible under law, the author(s) have dedicated all copyright
+// and related 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
+// <https://creativecommons.org/publicdomain/zero/1.0/>
+
+#include <sodium.h>
+#include "utils.h"
+
+int main(void)
+{
+ SODIUM_INIT;
+
+ FOR (size, 0, 50) {
+ RANDOM_INPUT(key , 32);
+ RANDOM_INPUT(in , 16);
+ u8 out[32];
+
+ crypto_core_hchacha20(out, in, key, 0);
+
+ print_vector(key , 32);
+ print_vector(in , 16);
+ print_vector(out , 32);
+ printf("\n");
+ }
+
+ return 0;
+}
diff --git a/lib/Utils.Cryptography/monocypher/vendor/tests/gen/ietf_chacha20.c b/lib/Utils.Cryptography/monocypher/vendor/tests/gen/ietf_chacha20.c
new file mode 100644
index 0000000..21e01e9
--- /dev/null
+++ b/lib/Utils.Cryptography/monocypher/vendor/tests/gen/ietf_chacha20.c
@@ -0,0 +1,77 @@
+// This file is dual-licensed. Choose whichever licence you want from
+// the two licences listed below.
+//
+// The first licence is a regular 2-clause BSD licence. The second licence
+// is the CC-0 from Creative Commons. It is intended to release Monocypher
+// to the public domain. The BSD licence serves as a fallback option.
+//
+// SPDX-License-Identifier: BSD-2-Clause OR CC0-1.0
+//
+// ------------------------------------------------------------------------
+//
+// Copyright (c) 2017-2019, Loup Vaillant
+// 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 COPYRIGHT HOLDERS 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 COPYRIGHT
+// HOLDER 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.
+//
+// ------------------------------------------------------------------------
+//
+// Written in 2017-2019 by Loup Vaillant
+//
+// To the extent possible under law, the author(s) have dedicated all copyright
+// and related 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
+// <https://creativecommons.org/publicdomain/zero/1.0/>
+
+#include <sodium.h>
+#include "utils.h"
+
+static void test(size_t size, u32 ctr)
+{
+ RANDOM_INPUT(key , 32);
+ RANDOM_INPUT(nonce, 12);
+ RANDOM_INPUT(in , 128); // size <= 128
+ u8 out[128]; // size <= 128
+
+ crypto_stream_chacha20_ietf_xor_ic(out, in, size, nonce, ctr, key);
+
+ print_vector(key , 32);
+ print_vector(nonce, 12);
+ print_vector(in , size);
+ print_number(ctr );
+ print_vector(out , size);
+ printf("\n");
+}
+
+int main(void)
+{
+ SODIUM_INIT;
+ FOR (size, 0, 128) { test(size, (u32)rand64()); }
+ return 0;
+}
diff --git a/lib/Utils.Cryptography/monocypher/vendor/tests/gen/makefile b/lib/Utils.Cryptography/monocypher/vendor/tests/gen/makefile
new file mode 100644
index 0000000..0adc512
--- /dev/null
+++ b/lib/Utils.Cryptography/monocypher/vendor/tests/gen/makefile
@@ -0,0 +1,150 @@
+# This file is dual-licensed. Choose whichever licence you want from
+# the two licences listed below.
+#
+# The first licence is a regular 2-clause BSD licence. The second licence
+# is the CC-0 from Creative Commons. It is intended to release Monocypher
+# to the public domain. The BSD licence serves as a fallback option.
+#
+# SPDX-License-Identifier: BSD-2-Clause OR CC0-1.0
+#
+# ------------------------------------------------------------------------
+#
+# Copyright (c) 2017-2019, Loup Vaillant
+# Copyright (c) 2017, 2019, Fabio Scotoni
+# 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 COPYRIGHT HOLDERS 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 COPYRIGHT
+# HOLDER 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.
+#
+# ------------------------------------------------------------------------
+#
+# Written in 2017-2019 by Loup Vaillant and Fabio Scotoni
+#
+# To the extent possible under law, the author(s) have dedicated all copyright
+# and related 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
+# <https://creativecommons.org/publicdomain/zero/1.0/>
+CC ?= gcc -std=c99
+CFLAGS ?= -pedantic -Wall -Wextra
+
+.PHONY: all clean
+
+VEC = chacha20 hchacha20 xchacha20 ietf_chacha20 \
+ aead_ietf aead_8439 \
+ poly1305 blake2b sha512 sha512_hmac sha512_hkdf argon2 \
+ edDSA edDSA_pk ed_25519 ed_25519_pk ed_25519_check \
+ ed_25519ph \
+ x25519 x25519_pk elligator_inv elligator_dir
+VEC2 = $(patsubst %, %.all.vec, $(VEC))
+HEADERS = $(patsubst %, %.h.vec , $(VEC))
+VECTORS = ../vectors.h
+
+all: $(VECTORS)
+
+clean:
+ rm -f *.out *.vec *.o
+ rm -f $(VECTORS)
+
+elligator_inv.vec: elligator-inverse.py elligator.py elligator_scalarmult.py
+ ./$< >$@
+elligator_dir.vec: elligator-direct.py elligator.py
+ ./$< >$@
+sha512_hkdf.vec: sha512_hkdf.py
+ ./$< >$@
+%.vec: %.out
+ ./$< > $@
+
+utils.o: utils.c utils.h
+ $(CC) $(CFLAGS) -c $< -o $@
+
+%.o: %.c ../utils.h ../externals/ed25519-donna/ed25519.h
+ $(CC) $(CFLAGS) -c $< \
+ -I .. \
+ -I ../externals/ed25519-donna \
+ -I ../../src \
+ -I ../../src/optional \
+ $$(pkg-config --cflags libsodium)
+
+%.out: %.o ed25519.o utils.o
+ $(CC) $(CFLAGS) -o $@ $^ \
+ $$(pkg-config --libs libsodium)
+
+ed25519.o: ../externals/ed25519-donna/ed25519.c \
+ $(wildcard ../externals/ed25519-donna/*.h)
+ $(CC) $(CFLAGS) -c $< \
+ -I ../../src \
+ -I ../../src/optional \
+ $$(pkg-config --cflags libsodium) \
+ -DED25519_CUSTOMHASH \
+ -DED25519_TEST \
+ -DED25519_NO_INLINE_ASM \
+ -DED25519_FORCE_32BIT
+
+vector_to_header.out: vector_to_header.c
+ $(CC) $(CFLAGS) $< -o $@
+
+chacha20.all.vec : chacha20.vec vectors/chacha20
+poly1305.all.vec : poly1305.vec vectors/poly1305
+x25519.all.vec : x25519.vec vectors/x25519
+x25519_pk.all.vec : x25519_pk.vec
+hchacha20.all.vec : hchacha20.vec
+xchacha20.all.vec : xchacha20.vec
+ietf_chacha20.all.vec : ietf_chacha20.vec
+aead_ietf.all.vec : aead_ietf.vec
+aead_8439.all.vec : aead_8439.vec
+blake2b.all.vec : blake2b.vec vectors/blake2b
+sha512.all.vec : sha512.vec
+sha512_hmac.all.vec : sha512_hmac.vec vectors/sha512_hmac
+sha512_hkdf.all.vec : sha512_hkdf.vec
+argon2.all.vec : argon2.vec vectors/argon2
+edDSA.all.vec : edDSA.vec
+edDSA_pk.all.vec : edDSA_pk.vec
+ed_25519.all.vec : ed_25519.vec
+ed_25519_pk.all.vec : ed_25519_pk.vec
+ed_25519_check.all.vec: vectors/ed_25519_check
+ed_25519ph.all.vec : vectors/ed_25519ph
+elligator_dir.all.vec : elligator_dir.vec vectors/elligator_dir
+elligator_inv.all.vec : elligator_inv.vec vectors/elligator_inv
+$(VEC2):
+ mkdir -p $(@D)
+ cat $^ > $@
+
+%.h.vec: %.all.vec vector_to_header.out
+ ./vector_to_header.out $(patsubst %.all.vec,%,$<) < $< > $@
+
+prelude.h.vec:
+ @echo "creating prelude.h.vec"
+ @echo "// Generated with hard coded official vectors, and" > $@
+ @echo "// random vectors with libsodium and ed25519-donna." >> $@
+ @echo "// Download Monocypher's git repository to regenerate." >> $@
+ @echo "#include <inttypes.h>" >> $@
+ @echo "#include <stddef.h>" >> $@
+ @echo "" >> $@
+
+$(VECTORS): prelude.h.vec $(HEADERS)
+ cat $^ > $@
diff --git a/lib/Utils.Cryptography/monocypher/vendor/tests/gen/poly1305.c b/lib/Utils.Cryptography/monocypher/vendor/tests/gen/poly1305.c
new file mode 100644
index 0000000..32ca1c3
--- /dev/null
+++ b/lib/Utils.Cryptography/monocypher/vendor/tests/gen/poly1305.c
@@ -0,0 +1,74 @@
+// This file is dual-licensed. Choose whichever licence you want from
+// the two licences listed below.
+//
+// The first licence is a regular 2-clause BSD licence. The second licence
+// is the CC-0 from Creative Commons. It is intended to release Monocypher
+// to the public domain. The BSD licence serves as a fallback option.
+//
+// SPDX-License-Identifier: BSD-2-Clause OR CC0-1.0
+//
+// ------------------------------------------------------------------------
+//
+// Copyright (c) 2017-2019, Loup Vaillant
+// 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 COPYRIGHT HOLDERS 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 COPYRIGHT
+// HOLDER 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.
+//
+// ------------------------------------------------------------------------
+//
+// Written in 2017-2019 by Loup Vaillant
+//
+// To the extent possible under law, the author(s) have dedicated all copyright
+// and related 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
+// <https://creativecommons.org/publicdomain/zero/1.0/>
+
+#include <sodium.h>
+#include "utils.h"
+
+static void test(size_t size)
+{
+ RANDOM_INPUT(key, 32);
+ RANDOM_INPUT(in , 32);
+ u8 tag[ 16];
+
+ crypto_onetimeauth(tag, in, size, key);
+
+ print_vector(key, 32);
+ print_vector(in , size);
+ print_vector(tag, 16);
+ printf("\n");
+}
+
+int main(void)
+{
+ SODIUM_INIT;
+ FOR (size, 0, 32) { test(size); }
+ return 0;
+}
diff --git a/lib/Utils.Cryptography/monocypher/vendor/tests/gen/sha512.c b/lib/Utils.Cryptography/monocypher/vendor/tests/gen/sha512.c
new file mode 100644
index 0000000..a9befea
--- /dev/null
+++ b/lib/Utils.Cryptography/monocypher/vendor/tests/gen/sha512.c
@@ -0,0 +1,74 @@
+// This file is dual-licensed. Choose whichever licence you want from
+// the two licences listed below.
+//
+// The first licence is a regular 2-clause BSD licence. The second licence
+// is the CC-0 from Creative Commons. It is intended to release Monocypher
+// to the public domain. The BSD licence serves as a fallback option.
+//
+// SPDX-License-Identifier: BSD-2-Clause OR CC0-1.0
+//
+// ------------------------------------------------------------------------
+//
+// Copyright (c) 2017-2019, Loup Vaillant
+// 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 COPYRIGHT HOLDERS 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 COPYRIGHT
+// HOLDER 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.
+//
+// ------------------------------------------------------------------------
+//
+// Written in 2017-2019 by Loup Vaillant
+//
+// To the extent possible under law, the author(s) have dedicated all copyright
+// and related 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
+// <https://creativecommons.org/publicdomain/zero/1.0/>
+
+#include <sodium.h>
+#include "utils.h"
+
+static void test(size_t size)
+{
+ RANDOM_INPUT(in , 256);
+ u8 hash[64];
+
+ crypto_hash_sha512(hash, in, size);
+
+ print_vector(in , size);
+ print_vector(hash, 64);
+ printf("\n");
+}
+
+int main(void)
+{
+ SODIUM_INIT;
+ FOR(size, 0, 256) {
+ test(size);
+ }
+ return 0;
+}
diff --git a/lib/Utils.Cryptography/monocypher/vendor/tests/gen/sha512_hkdf.py b/lib/Utils.Cryptography/monocypher/vendor/tests/gen/sha512_hkdf.py
new file mode 100644
index 0000000..1d696c0
--- /dev/null
+++ b/lib/Utils.Cryptography/monocypher/vendor/tests/gen/sha512_hkdf.py
@@ -0,0 +1,109 @@
+#! /usr/bin/env python3
+
+# This file is dual-licensed. Choose whichever licence you want from
+# the two licences listed below.
+#
+# The first licence is a regular 2-clause BSD licence. The second licence
+# is the CC-0 from Creative Commons. It is intended to release Monocypher
+# to the public domain. The BSD licence serves as a fallback option.
+#
+# SPDX-License-Identifier: BSD-2-Clause OR CC0-1.0
+#
+# ------------------------------------------------------------------------
+#
+# Copyright (c) 2023, Loup Vaillant
+# 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 COPYRIGHT HOLDERS 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 COPYRIGHT
+# HOLDER 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.
+#
+# ------------------------------------------------------------------------
+#
+# Written in 2023 by Loup Vaillant
+#
+# To the extent possible under law, the author(s) have dedicated all copyright
+# and related 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
+# <https://creativecommons.org/publicdomain/zero/1.0/>
+
+from binascii import hexlify
+from cryptography.hazmat.primitives.hashes import SHA512
+from cryptography.hazmat.primitives.kdf.hkdf import HKDF
+from random import randrange
+from random import seed
+
+seed(12345) # deterministic test vectors
+
+def rand_buf(size):
+ buf = bytearray(size)
+ for i in range(size):
+ buf[i] = randrange(0, 256)
+ return bytes(buf)
+
+def vectors(ikm_size, salt_size, info_size, okm_size):
+ ikm = rand_buf(ikm_size)
+ salt = rand_buf(salt_size)
+ info = rand_buf(info_size)
+ okm = HKDF(
+ algorithm = SHA512(),
+ length = okm_size,
+ salt = salt,
+ info = info,
+ ).derive(ikm)
+ print(hexlify(ikm ).decode() + ":")
+ print(hexlify(salt).decode() + ":")
+ print(hexlify(info).decode() + ":")
+ print(hexlify(okm ).decode() + ":")
+
+vectors(0, 0, 0, 0)
+vectors(0, 0, 0, 64)
+
+vectors(32, 16, 8, 63)
+vectors(32, 16, 8, 64)
+vectors(32, 16, 8, 65)
+vectors(32, 16, 8, 127)
+vectors(32, 16, 8, 128)
+vectors(32, 16, 8, 129)
+
+vectors(32, 16, 8, 128)
+
+vectors(127, 16, 8, 128)
+vectors(128, 16, 8, 128)
+vectors(129, 16, 8, 128)
+
+vectors(32, 127, 8, 128)
+vectors(32, 128, 8, 128)
+vectors(32, 129, 8, 128)
+
+vectors(32, 16, 127, 128)
+vectors(32, 16, 128, 128)
+vectors(32, 16, 129, 128)
+
+vectors(127, 127, 127, 127)
+vectors(128, 128, 128, 128)
+vectors(129, 129, 129, 129)
diff --git a/lib/Utils.Cryptography/monocypher/vendor/tests/gen/sha512_hmac.c b/lib/Utils.Cryptography/monocypher/vendor/tests/gen/sha512_hmac.c
new file mode 100644
index 0000000..8d53a2f
--- /dev/null
+++ b/lib/Utils.Cryptography/monocypher/vendor/tests/gen/sha512_hmac.c
@@ -0,0 +1,79 @@
+// This file is dual-licensed. Choose whichever licence you want from
+// the two licences listed below.
+//
+// The first licence is a regular 2-clause BSD licence. The second licence
+// is the CC-0 from Creative Commons. It is intended to release Monocypher
+// to the public domain. The BSD licence serves as a fallback option.
+//
+// SPDX-License-Identifier: BSD-2-Clause OR CC0-1.0
+//
+// ------------------------------------------------------------------------
+//
+// Copyright (c) 2017-2019, Loup Vaillant
+// 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 COPYRIGHT HOLDERS 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 COPYRIGHT
+// HOLDER 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.
+//
+// ------------------------------------------------------------------------
+//
+// Written in 2017-2019 by Loup Vaillant
+//
+// To the extent possible under law, the author(s) have dedicated all copyright
+// and related 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
+// <https://creativecommons.org/publicdomain/zero/1.0/>
+
+#include <sodium.h>
+#include "utils.h"
+
+static void test(size_t key_size, size_t msg_size)
+{
+ RANDOM_INPUT(key, 256);
+ RANDOM_INPUT(msg, 256);
+ u8 tag[64];
+
+ crypto_auth_hmacsha512_state ctx;
+ crypto_auth_hmacsha512_init (&ctx, key, key_size);
+ crypto_auth_hmacsha512_update(&ctx, msg, msg_size);
+ crypto_auth_hmacsha512_final (&ctx, tag);
+
+ print_vector(key, key_size);
+ print_vector(msg, msg_size);
+ print_vector(tag, 64);
+ printf("\n");
+}
+
+int main(void)
+{
+ SODIUM_INIT;
+ FOR (key_size, 0, 32) { test(key_size, 32); }
+ FOR (key_size, 120, 136) { test(key_size, 32); }
+ FOR (msg_size, 0, 256) { test(32, msg_size); }
+ return 0;
+}
diff --git a/lib/Utils.Cryptography/monocypher/vendor/tests/gen/utils.c b/lib/Utils.Cryptography/monocypher/vendor/tests/gen/utils.c
new file mode 100644
index 0000000..0ef5482
--- /dev/null
+++ b/lib/Utils.Cryptography/monocypher/vendor/tests/gen/utils.c
@@ -0,0 +1,100 @@
+// This file is dual-licensed. Choose whichever licence you want from
+// the two licences listed below.
+//
+// The first licence is a regular 2-clause BSD licence. The second licence
+// is the CC-0 from Creative Commons. It is intended to release Monocypher
+// to the public domain. The BSD licence serves as a fallback option.
+//
+// SPDX-License-Identifier: BSD-2-Clause OR CC0-1.0
+//
+// ------------------------------------------------------------------------
+//
+// Copyright (c) 2017-2019, 2023 Loup Vaillant
+// 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 COPYRIGHT HOLDERS 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 COPYRIGHT
+// HOLDER 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.
+//
+// ------------------------------------------------------------------------
+//
+// Written in 2017-2019, 2023 by Loup Vaillant
+//
+// To the extent possible under law, the author(s) have dedicated all copyright
+// and related 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
+// <https://creativecommons.org/publicdomain/zero/1.0/>
+
+#include "utils.h"
+#include <stdio.h>
+
+static void store64_le(u8 out[8], u64 in)
+{
+ out[0] = in & 0xff;
+ out[1] = (in >> 8) & 0xff;
+ out[2] = (in >> 16) & 0xff;
+ out[3] = (in >> 24) & 0xff;
+ out[4] = (in >> 32) & 0xff;
+ out[5] = (in >> 40) & 0xff;
+ out[6] = (in >> 48) & 0xff;
+ out[7] = (in >> 56) & 0xff;
+}
+
+// Must be seeded with a nonzero value.
+// Accessible from the outside so we can modify it
+u64 random_state = 12345;
+
+// Pseudo-random 64 bit number, based on xorshift*
+u64 rand64(void)
+{
+ random_state ^= random_state >> 12;
+ random_state ^= random_state << 25;
+ random_state ^= random_state >> 27;
+ return random_state * 0x2545F4914F6CDD1D; // magic constant
+}
+
+void p_random(u8 *stream, size_t size)
+{
+ FOR (i, 0, size) {
+ stream[i] = (u8)rand64();
+ }
+}
+
+void print_vector(const u8 *buf, size_t size)
+{
+ FOR (i, 0, size) {
+ printf("%x%x", buf[i] >> 4, buf[i] & 0x0f);
+ }
+ printf(":\n");
+}
+
+void print_number(u64 n)
+{
+ u8 buf[8];
+ store64_le(buf, n);
+ print_vector(buf, 8);
+}
diff --git a/lib/Utils.Cryptography/monocypher/vendor/tests/gen/utils.h b/lib/Utils.Cryptography/monocypher/vendor/tests/gen/utils.h
new file mode 100644
index 0000000..5704f66
--- /dev/null
+++ b/lib/Utils.Cryptography/monocypher/vendor/tests/gen/utils.h
@@ -0,0 +1,78 @@
+// This file is dual-licensed. Choose whichever licence you want from
+// the two licences listed below.
+//
+// The first licence is a regular 2-clause BSD licence. The second licence
+// is the CC-0 from Creative Commons. It is intended to release Monocypher
+// to the public domain. The BSD licence serves as a fallback option.
+//
+// SPDX-License-Identifier: BSD-2-Clause OR CC0-1.0
+//
+// ------------------------------------------------------------------------
+//
+// Copyright (c) 2017-2019, 2023 Loup Vaillant
+// 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 COPYRIGHT HOLDERS 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 COPYRIGHT
+// HOLDER 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.
+//
+// ------------------------------------------------------------------------
+//
+// Written in 2017-2019, 2023 by Loup Vaillant
+//
+// To the extent possible under law, the author(s) have dedicated all copyright
+// and related 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
+// <https://creativecommons.org/publicdomain/zero/1.0/>
+
+#ifndef UTILS_H
+#define UTILS_H
+
+#include <inttypes.h>
+#include <stddef.h>
+
+typedef uint8_t u8;
+typedef uint32_t u32;
+typedef uint64_t u64;
+
+#define FOR(i, start, end) for (size_t i = (start); i < (end); i++)
+#define SODIUM_INIT ASSERT(sodium_init() != -1)
+#define RANDOM_INPUT(name, size) u8 name[size]; p_random(name, size)
+#define ASSERT(condition) do { \
+ if (!(condition)) { \
+ fprintf(stderr, "Assert failure(%s, %d): %s\n", \
+ __FILE__, __LINE__, #condition); \
+ exit(1); \
+ } \
+ } while (0)
+
+u64 rand64(void); // Pseudo-random 64 bit number, based on xorshift*
+void p_random(u8 *stream, size_t size);
+void print_vector(const u8 *buf, size_t size);
+void print_number(u64 n);
+
+#endif // UTILS_H
diff --git a/lib/Utils.Cryptography/monocypher/vendor/tests/gen/vector_to_header.c b/lib/Utils.Cryptography/monocypher/vendor/tests/gen/vector_to_header.c
new file mode 100644
index 0000000..5d5aa1f
--- /dev/null
+++ b/lib/Utils.Cryptography/monocypher/vendor/tests/gen/vector_to_header.c
@@ -0,0 +1,122 @@
+// This file is dual-licensed. Choose whichever licence you want from
+// the two licences listed below.
+//
+// The first licence is a regular 2-clause BSD licence. The second licence
+// is the CC-0 from Creative Commons. It is intended to release Monocypher
+// to the public domain. The BSD licence serves as a fallback option.
+//
+// SPDX-License-Identifier: BSD-2-Clause OR CC0-1.0
+//
+// ------------------------------------------------------------------------
+//
+// Copyright (c) 2017-2020, 2023 Loup Vaillant
+// 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 COPYRIGHT HOLDERS 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 COPYRIGHT
+// HOLDER 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.
+//
+// ------------------------------------------------------------------------
+//
+// Written in 2017-2020, 2023 by Loup Vaillant
+//
+// To the extent possible under law, the author(s) have dedicated all copyright
+// and related 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
+// <https://creativecommons.org/publicdomain/zero/1.0/>
+
+// Transforms a test vector file (from stdin) into a C header.
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include <stddef.h>
+#include <assert.h>
+
+#define FOR(i, start, end) for (size_t i = (start); i < (end); i++)
+#define CHECK(cond, msg) do { if (!(cond)) { panic(msg); } } while (0)
+
+static void panic(const char *msg)
+{
+ fprintf(stderr, "%s\n", msg);
+ exit(1);
+}
+
+static int is_digit(int c)
+{
+ return
+ (c >= '0' && c <= '9') ||
+ (c >= 'a' && c <= 'f') ||
+ (c >= 'A' && c <= 'F');
+}
+
+static int whitespace(int c)
+{
+ // Skip whitespace
+ while (c == '\n') {
+ c = getchar();
+ }
+ // Skip comment
+ if (c == '#') {
+ while (c != EOF && c != '\n') {
+ c = getchar();
+ }
+ return whitespace(getchar());
+ }
+ CHECK(is_digit(c) || c == ':' || c == EOF, "Illegal character");
+ return c; // first digit
+}
+
+int main(int argc, char** argv)
+{
+ CHECK(argc == 2, "Wrong use of vector transformer. Give one argument");
+
+ char *prefix = argv[1];
+ size_t nb_vec = 0;
+
+ printf("static const char *%s_vectors[]={\n", prefix);
+
+ int c = whitespace(getchar());
+ while (c != EOF) {
+ printf(" \"");
+ unsigned parity = 0;
+ while (c != ':' && c != EOF) {
+ parity = ~parity;
+ CHECK(is_digit(c), "Not a digit");
+ printf("%c", (char)c);
+ c = getchar();
+ }
+ CHECK(parity == 0, "Odd number of digits");
+ printf("\",\n");
+ c = whitespace(getchar());
+ nb_vec++;
+ }
+ printf("};\n");
+ printf("static size_t nb_%s_vectors=%zu;\n", prefix, nb_vec);
+
+ return 0;
+}
diff --git a/lib/Utils.Cryptography/monocypher/vendor/tests/gen/vectors/argon2 b/lib/Utils.Cryptography/monocypher/vendor/tests/gen/vectors/argon2
new file mode 100644
index 0000000..c111670
--- /dev/null
+++ b/lib/Utils.Cryptography/monocypher/vendor/tests/gen/vectors/argon2
@@ -0,0 +1,76 @@
+# Parameters are in the following order:
+#
+# - Algorithm (0 = Argon2d, 1 = Argon2i, 2 -> Argon2id)
+# - Memory (number of KiB)
+# - Time (number of iterations)
+# - Parallelism (number of lanes)
+# - Password
+# - Salt
+# - Key
+# - Additional data
+# - Digest
+
+# This one is modified from the RFC to only take one lane,
+# from back when Monocypher only supported one lane.
+0100000000000000:
+0800000000000000:
+0300000000000000:
+0100000000000000:
+0101010101010101010101010101010101010101010101010101010101010101:
+02020202020202020202020202020202:
+0303030303030303:
+040404040404040404040404:
+afe519be3ab0e92375df221dfb17347080c7000b1be85f9ee39978bf11e7cc3a:
+
+#
+# From RFC 9106 (Argon2d)
+#
+0000000000000000:
+2000000000000000:
+0300000000000000:
+0400000000000000:
+0101010101010101010101010101010101010101010101010101010101010101:
+02020202020202020202020202020202:
+0303030303030303:
+040404040404040404040404:
+512b391b6f1162975371d30919734294f868e3be3984f3c1a13a4db9fabe4acb:
+
+#
+# From RFC 9106 (Argon2i)
+#
+0100000000000000:
+2000000000000000:
+0300000000000000:
+0400000000000000:
+0101010101010101010101010101010101010101010101010101010101010101:
+02020202020202020202020202020202:
+0303030303030303:
+040404040404040404040404:
+c814d9d1dc7f37aa13f0d77f2494bda1c8de6b016dd388d29952a4c4672b6ce8:
+
+#
+# From RFC 9106 (Argon2id)
+#
+0200000000000000:
+2000000000000000:
+0300000000000000:
+0400000000000000:
+0101010101010101010101010101010101010101010101010101010101010101:
+02020202020202020202020202020202:
+0303030303030303:
+040404040404040404040404:
+0d640df58d78766c08c037a34a8b53c9d01ef0452d75b65eb52520e96b01e659:
+
+#
+# This one was modified from the RFC (Argon2d) to 2 lanes,
+# which is enough to trigger the reference set error
+#
+0000000000000000:
+2000000000000000:
+0300000000000000:
+0200000000000000:
+0101010101010101010101010101010101010101010101010101010101010101:
+02020202020202020202020202020202:
+0303030303030303:
+040404040404040404040404:
+c53c3e988d88e8c37b322e3302d273f4847eb058bf06449f647ea6396f14e87c:
diff --git a/lib/Utils.Cryptography/monocypher/vendor/tests/gen/vectors/blake2b b/lib/Utils.Cryptography/monocypher/vendor/tests/gen/vectors/blake2b
new file mode 100644
index 0000000..d57c0d3
--- /dev/null
+++ b/lib/Utils.Cryptography/monocypher/vendor/tests/gen/vectors/blake2b
@@ -0,0 +1,1028 @@
+#
+# Official BLAKE2b test vectors, from
+# https://github.com/BLAKE2/BLAKE2/blob/master/testvectors/blake2b-kat.txt
+#
+
+:
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f:
+10ebb67700b1868efb4417987acf4690ae9d972fb7a590c2f02871799aaa4786b5e996e8f0f4eb981fc214b005f42d2ff4233499391653df7aefcbc13fc51568:
+
+00:
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f:
+961f6dd1e4dd30f63901690c512e78e4b45e4742ed197c3c5e45c549fd25f2e4187b0bc9fe30492b16b0d0bc4ef9b0f34c7003fac09a5ef1532e69430234cebd:
+
+0001:
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f:
+da2cfbe2d8409a0f38026113884f84b50156371ae304c4430173d08a99d9fb1b983164a3770706d537f49e0c916d9f32b95cc37a95b99d857436f0232c88a965:
+
+000102:
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f:
+33d0825dddf7ada99b0e7e307104ad07ca9cfd9692214f1561356315e784f3e5a17e364ae9dbb14cb2036df932b77f4b292761365fb328de7afdc6d8998f5fc1:
+
+00010203:
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f:
+beaa5a3d08f3807143cf621d95cd690514d0b49efff9c91d24b59241ec0eefa5f60196d407048bba8d2146828ebcb0488d8842fd56bb4f6df8e19c4b4daab8ac:
+
+0001020304:
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f:
+098084b51fd13deae5f4320de94a688ee07baea2800486689a8636117b46c1f4c1f6af7f74ae7c857600456a58a3af251dc4723a64cc7c0a5ab6d9cac91c20bb:
+
+000102030405:
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f:
+6044540d560853eb1c57df0077dd381094781cdb9073e5b1b3d3f6c7829e12066bbaca96d989a690de72ca3133a83652ba284a6d62942b271ffa2620c9e75b1f:
+
+00010203040506:
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f:
+7a8cfe9b90f75f7ecb3acc053aaed6193112b6f6a4aeeb3f65d3de541942deb9e2228152a3c4bbbe72fc3b12629528cfbb09fe630f0474339f54abf453e2ed52:
+
+0001020304050607:
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f:
+380beaf6ea7cc9365e270ef0e6f3a64fb902acae51dd5512f84259ad2c91f4bc4108db73192a5bbfb0cbcf71e46c3e21aee1c5e860dc96e8eb0b7b8426e6abe9:
+
+000102030405060708:
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f:
+60fe3c4535e1b59d9a61ea8500bfac41a69dffb1ceadd9aca323e9a625b64da5763bad7226da02b9c8c4f1a5de140ac5a6c1124e4f718ce0b28ea47393aa6637:
+
+00010203040506070809:
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f:
+4fe181f54ad63a2983feaaf77d1e7235c2beb17fa328b6d9505bda327df19fc37f02c4b6f0368ce23147313a8e5738b5fa2a95b29de1c7f8264eb77b69f585cd:
+
+000102030405060708090a:
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f:
+f228773ce3f3a42b5f144d63237a72d99693adb8837d0e112a8a0f8ffff2c362857ac49c11ec740d1500749dac9b1f4548108bf3155794dcc9e4082849e2b85b:
+
+000102030405060708090a0b:
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f:
+962452a8455cc56c8511317e3b1f3b2c37df75f588e94325fdd77070359cf63a9ae6e930936fdf8e1e08ffca440cfb72c28f06d89a2151d1c46cd5b268ef8563:
+
+000102030405060708090a0b0c:
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f:
+43d44bfa18768c59896bf7ed1765cb2d14af8c260266039099b25a603e4ddc5039d6ef3a91847d1088d401c0c7e847781a8a590d33a3c6cb4df0fab1c2f22355:
+
+000102030405060708090a0b0c0d:
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f:
+dcffa9d58c2a4ca2cdbb0c7aa4c4c1d45165190089f4e983bb1c2cab4aaeff1fa2b5ee516fecd780540240bf37e56c8bcca7fab980e1e61c9400d8a9a5b14ac6:
+
+000102030405060708090a0b0c0d0e:
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f:
+6fbf31b45ab0c0b8dad1c0f5f4061379912dde5aa922099a030b725c73346c524291adef89d2f6fd8dfcda6d07dad811a9314536c2915ed45da34947e83de34e:
+
+000102030405060708090a0b0c0d0e0f:
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f:
+a0c65bddde8adef57282b04b11e7bc8aab105b99231b750c021f4a735cb1bcfab87553bba3abb0c3e64a0b6955285185a0bd35fb8cfde557329bebb1f629ee93:
+
+000102030405060708090a0b0c0d0e0f10:
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f:
+f99d815550558e81eca2f96718aed10d86f3f1cfb675cce06b0eff02f617c5a42c5aa760270f2679da2677c5aeb94f1142277f21c7f79f3c4f0cce4ed8ee62b1:
+
+000102030405060708090a0b0c0d0e0f1011:
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f:
+95391da8fc7b917a2044b3d6f5374e1ca072b41454d572c7356c05fd4bc1e0f40b8bb8b4a9f6bce9be2c4623c399b0dca0dab05cb7281b71a21b0ebcd9e55670:
+
+000102030405060708090a0b0c0d0e0f101112:
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f:
+04b9cd3d20d221c09ac86913d3dc63041989a9a1e694f1e639a3ba7e451840f750c2fc191d56ad61f2e7936bc0ac8e094b60caeed878c18799045402d61ceaf9:
+
+000102030405060708090a0b0c0d0e0f10111213:
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f:
+ec0e0ef707e4ed6c0c66f9e089e4954b058030d2dd86398fe84059631f9ee591d9d77375355149178c0cf8f8e7c49ed2a5e4f95488a2247067c208510fadc44c:
+
+000102030405060708090a0b0c0d0e0f1011121314:
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f:
+9a37cce273b79c09913677510eaf7688e89b3314d3532fd2764c39de022a2945b5710d13517af8ddc0316624e73bec1ce67df15228302036f330ab0cb4d218dd:
+
+000102030405060708090a0b0c0d0e0f101112131415:
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f:
+4cf9bb8fb3d4de8b38b2f262d3c40f46dfe747e8fc0a414c193d9fcf753106ce47a18f172f12e8a2f1c26726545358e5ee28c9e2213a8787aafbc516d2343152:
+
+000102030405060708090a0b0c0d0e0f10111213141516:
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f:
+64e0c63af9c808fd893137129867fd91939d53f2af04be4fa268006100069b2d69daa5c5d8ed7fddcb2a70eeecdf2b105dd46a1e3b7311728f639ab489326bc9:
+
+000102030405060708090a0b0c0d0e0f1011121314151617:
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f:
+5e9c93158d659b2def06b0c3c7565045542662d6eee8a96a89b78ade09fe8b3dcc096d4fe48815d88d8f82620156602af541955e1f6ca30dce14e254c326b88f:
+
+000102030405060708090a0b0c0d0e0f101112131415161718:
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f:
+7775dff889458dd11aef417276853e21335eb88e4dec9cfb4e9edb49820088551a2ca60339f12066101169f0dfe84b098fddb148d9da6b3d613df263889ad64b:
+
+000102030405060708090a0b0c0d0e0f10111213141516171819:
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f:
+f0d2805afbb91f743951351a6d024f9353a23c7ce1fc2b051b3a8b968c233f46f50f806ecb1568ffaa0b60661e334b21dde04f8fa155ac740eeb42e20b60d764:
+
+000102030405060708090a0b0c0d0e0f101112131415161718191a:
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f:
+86a2af316e7d7754201b942e275364ac12ea8962ab5bd8d7fb276dc5fbffc8f9a28cae4e4867df6780d9b72524160927c855da5b6078e0b554aa91e31cb9ca1d:
+
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b:
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f:
+10bdf0caa0802705e706369baf8a3f79d72c0a03a80675a7bbb00be3a45e516424d1ee88efb56f6d5777545ae6e27765c3a8f5e493fc308915638933a1dfee55:
+
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c:
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f:
+b01781092b1748459e2e4ec178696627bf4ebafebba774ecf018b79a68aeb84917bf0b84bb79d17b743151144cd66b7b33a4b9e52c76c4e112050ff5385b7f0b:
+
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d:
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f:
+c6dbc61dec6eaeac81e3d5f755203c8e220551534a0b2fd105a91889945a638550204f44093dd998c076205dffad703a0e5cd3c7f438a7e634cd59fededb539e:
+
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e:
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f:
+eba51acffb4cea31db4b8d87e9bf7dd48fe97b0253ae67aa580f9ac4a9d941f2bea518ee286818cc9f633f2a3b9fb68e594b48cdd6d515bf1d52ba6c85a203a7:
+
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f:
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f:
+86221f3ada52037b72224f105d7999231c5e5534d03da9d9c0a12acb68460cd375daf8e24386286f9668f72326dbf99ba094392437d398e95bb8161d717f8991:
+
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20:
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f:
+5595e05c13a7ec4dc8f41fb70cb50a71bce17c024ff6de7af618d0cc4e9c32d9570d6d3ea45b86525491030c0d8f2b1836d5778c1ce735c17707df364d054347:
+
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f2021:
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f:
+ce0f4f6aca89590a37fe034dd74dd5fa65eb1cbd0a41508aaddc09351a3cea6d18cb2189c54b700c009f4cbf0521c7ea01be61c5ae09cb54f27bc1b44d658c82:
+
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122:
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f:
+7ee80b06a215a3bca970c77cda8761822bc103d44fa4b33f4d07dcb997e36d55298bceae12241b3fa07fa63be5576068da387b8d5859aeab701369848b176d42:
+
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20212223:
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f:
+940a84b6a84d109aab208c024c6ce9647676ba0aaa11f86dbb7018f9fd2220a6d901a9027f9abcf935372727cbf09ebd61a2a2eeb87653e8ecad1bab85dc8327:
+
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f2021222324:
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f:
+2020b78264a82d9f4151141adba8d44bf20c5ec062eee9b595a11f9e84901bf148f298e0c9f8777dcdbc7cc4670aac356cc2ad8ccb1629f16f6a76bcefbee760:
+
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425:
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f:
+d1b897b0e075ba68ab572adf9d9c436663e43eb3d8e62d92fc49c9be214e6f27873fe215a65170e6bea902408a25b49506f47babd07cecf7113ec10c5dd31252:
+
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20212223242526:
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f:
+b14d0c62abfa469a357177e594c10c194243ed2025ab8aa5ad2fa41ad318e0ff48cd5e60bec07b13634a711d2326e488a985f31e31153399e73088efc86a5c55:
+
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f2021222324252627:
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f:
+4169c5cc808d2697dc2a82430dc23e3cd356dc70a94566810502b8d655b39abf9e7f902fe717e0389219859e1945df1af6ada42e4ccda55a197b7100a30c30a1:
+
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728:
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f:
+258a4edb113d66c839c8b1c91f15f35ade609f11cd7f8681a4045b9fef7b0b24c82cda06a5f2067b368825e3914e53d6948ede92efd6e8387fa2e537239b5bee:
+
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20212223242526272829:
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f:
+79d2d8696d30f30fb34657761171a11e6c3f1e64cbe7bebee159cb95bfaf812b4f411e2f26d9c421dc2c284a3342d823ec293849e42d1e46b0a4ac1e3c86abaa:
+
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a:
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f:
+8b9436010dc5dee992ae38aea97f2cd63b946d94fedd2ec9671dcde3bd4ce9564d555c66c15bb2b900df72edb6b891ebcadfeff63c9ea4036a998be7973981e7:
+
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b:
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f:
+c8f68e696ed28242bf997f5b3b34959508e42d613810f1e2a435c96ed2ff560c7022f361a9234b9837feee90bf47922ee0fd5f8ddf823718d86d1e16c6090071:
+
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c:
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f:
+b02d3eee4860d5868b2c39ce39bfe81011290564dd678c85e8783f29302dfc1399ba95b6b53cd9ebbf400cca1db0ab67e19a325f2d115812d25d00978ad1bca4:
+
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d:
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f:
+7693ea73af3ac4dad21ca0d8da85b3118a7d1c6024cfaf557699868217bc0c2f44a199bc6c0edd519798ba05bd5b1b4484346a47c2cadf6bf30b785cc88b2baf:
+
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e:
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f:
+a0e5c1c0031c02e48b7f09a5e896ee9aef2f17fc9e18e997d7f6cac7ae316422c2b1e77984e5f3a73cb45deed5d3f84600105e6ee38f2d090c7d0442ea34c46d:
+
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f:
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f:
+41daa6adcfdb69f1440c37b596440165c15ada596813e2e22f060fcd551f24dee8e04ba6890387886ceec4a7a0d7fc6b44506392ec3822c0d8c1acfc7d5aebe8:
+
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f30:
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f:
+14d4d40d5984d84c5cf7523b7798b254e275a3a8cc0a1bd06ebc0bee726856acc3cbf516ff667cda2058ad5c3412254460a82c92187041363cc77a4dc215e487:
+
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f3031:
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f:
+d0e7a1e2b9a447fee83e2277e9ff8010c2f375ae12fa7aaa8ca5a6317868a26a367a0b69fbc1cf32a55d34eb370663016f3d2110230eba754028a56f54acf57c:
+
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132:
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f:
+e771aa8db5a3e043e8178f39a0857ba04a3f18e4aa05743cf8d222b0b095825350ba422f63382a23d92e4149074e816a36c1cd28284d146267940b31f8818ea2:
+
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f30313233:
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f:
+feb4fd6f9e87a56bef398b3284d2bda5b5b0e166583a66b61e538457ff0584872c21a32962b9928ffab58de4af2edd4e15d8b35570523207ff4e2a5aa7754caa:
+
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f3031323334:
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f:
+462f17bf005fb1c1b9e671779f665209ec2873e3e411f98dabf240a1d5ec3f95ce6796b6fc23fe171903b502023467dec7273ff74879b92967a2a43a5a183d33:
+
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435:
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f:
+d3338193b64553dbd38d144bea71c5915bb110e2d88180dbc5db364fd6171df317fc7268831b5aef75e4342b2fad8797ba39eddcef80e6ec08159350b1ad696d:
+
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f30313233343536:
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f:
+e1590d585a3d39f7cb599abd479070966409a6846d4377acf4471d065d5db94129cc9be92573b05ed226be1e9b7cb0cabe87918589f80dadd4ef5ef25a93d28e:
+
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f3031323334353637:
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f:
+f8f3726ac5a26cc80132493a6fedcb0e60760c09cfc84cad178175986819665e76842d7b9fedf76dddebf5d3f56faaad4477587af21606d396ae570d8e719af2:
+
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738:
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f:
+30186055c07949948183c850e9a756cc09937e247d9d928e869e20bafc3cd9721719d34e04a0899b92c736084550186886efba2e790d8be6ebf040b209c439a4:
+
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f30313233343536373839:
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f:
+f3c4276cb863637712c241c444c5cc1e3554e0fddb174d035819dd83eb700b4ce88df3ab3841ba02085e1a99b4e17310c5341075c0458ba376c95a6818fbb3e2:
+
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a:
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f:
+0aa007c4dd9d5832393040a1583c930bca7dc5e77ea53add7e2b3f7c8e231368043520d4a3ef53c969b6bbfd025946f632bd7f765d53c21003b8f983f75e2a6a:
+
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b:
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f:
+08e9464720533b23a04ec24f7ae8c103145f765387d738777d3d343477fd1c58db052142cab754ea674378e18766c53542f71970171cc4f81694246b717d7564:
+
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c:
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f:
+d37ff7ad297993e7ec21e0f1b4b5ae719cdc83c5db687527f27516cbffa822888a6810ee5c1ca7bfe3321119be1ab7bfa0a502671c8329494df7ad6f522d440f:
+
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d:
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f:
+dd9042f6e464dcf86b1262f6accfafbd8cfd902ed3ed89abf78ffa482dbdeeb6969842394c9a1168ae3d481a017842f660002d42447c6b22f7b72f21aae021c9:
+
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e:
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f:
+bd965bf31e87d70327536f2a341cebc4768eca275fa05ef98f7f1b71a0351298de006fba73fe6733ed01d75801b4a928e54231b38e38c562b2e33ea1284992fa:
+
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f:
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f:
+65676d800617972fbd87e4b9514e1c67402b7a331096d3bfac22f1abb95374abc942f16e9ab0ead33b87c91968a6e509e119ff07787b3ef483e1dcdccf6e3022:
+
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f40:
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f:
+939fa189699c5d2c81ddd1ffc1fa207c970b6a3685bb29ce1d3e99d42f2f7442da53e95a72907314f4588399a3ff5b0a92beb3f6be2694f9f86ecf2952d5b41c:
+
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f4041:
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f:
+c516541701863f91005f314108ceece3c643e04fc8c42fd2ff556220e616aaa6a48aeb97a84bad74782e8dff96a1a2fa949339d722edcaa32b57067041df88cc:
+
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142:
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f:
+987fd6e0d6857c553eaebb3d34970a2c2f6e89a3548f492521722b80a1c21a153892346d2cba6444212d56da9a26e324dccbc0dcde85d4d2ee4399eec5a64e8f:
+
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f40414243:
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f:
+ae56deb1c2328d9c4017706bce6e99d41349053ba9d336d677c4c27d9fd50ae6aee17e853154e1f4fe7672346da2eaa31eea53fcf24a22804f11d03da6abfc2b:
+
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f4041424344:
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f:
+49d6a608c9bde4491870498572ac31aac3fa40938b38a7818f72383eb040ad39532bc06571e13d767e6945ab77c0bdc3b0284253343f9f6c1244ebf2ff0df866:
+
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445:
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f:
+da582ad8c5370b4469af862aa6467a2293b2b28bd80ae0e91f425ad3d47249fdf98825cc86f14028c3308c9804c78bfeeeee461444ce243687e1a50522456a1d:
+
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f40414243444546:
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f:
+d5266aa3331194aef852eed86d7b5b2633a0af1c735906f2e13279f14931a9fc3b0eac5ce9245273bd1aa92905abe16278ef7efd47694789a7283b77da3c70f8:
+
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f4041424344454647:
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f:
+2962734c28252186a9a1111c732ad4de4506d4b4480916303eb7991d659ccda07a9911914bc75c418ab7a4541757ad054796e26797feaf36e9f6ad43f14b35a4:
+
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748:
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f:
+e8b79ec5d06e111bdfafd71e9f5760f00ac8ac5d8bf768f9ff6f08b8f026096b1cc3a4c973333019f1e3553e77da3f98cb9f542e0a90e5f8a940cc58e59844b3:
+
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f40414243444546474849:
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f:
+dfb320c44f9d41d1efdcc015f08dd5539e526e39c87d509ae6812a969e5431bf4fa7d91ffd03b981e0d544cf72d7b1c0374f8801482e6dea2ef903877eba675e:
+
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a:
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f:
+d88675118fdb55a5fb365ac2af1d217bf526ce1ee9c94b2f0090b2c58a06ca58187d7fe57c7bed9d26fca067b4110eefcd9a0a345de872abe20de368001b0745:
+
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b:
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f:
+b893f2fc41f7b0dd6e2f6aa2e0370c0cff7df09e3acfcc0e920b6e6fad0ef747c40668417d342b80d2351e8c175f20897a062e9765e6c67b539b6ba8b9170545:
+
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c:
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f:
+6c67ec5697accd235c59b486d7b70baeedcbd4aa64ebd4eef3c7eac189561a726250aec4d48cadcafbbe2ce3c16ce2d691a8cce06e8879556d4483ed7165c063:
+
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d:
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f:
+f1aa2b044f8f0c638a3f362e677b5d891d6fd2ab0765f6ee1e4987de057ead357883d9b405b9d609eea1b869d97fb16d9b51017c553f3b93c0a1e0f1296fedcd:
+
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e:
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f:
+cbaa259572d4aebfc1917acddc582b9f8dfaa928a198ca7acd0f2aa76a134a90252e6298a65b08186a350d5b7626699f8cb721a3ea5921b753ae3a2dce24ba3a:
+
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f:
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f:
+fa1549c9796cd4d303dcf452c1fbd5744fd9b9b47003d920b92de34839d07ef2a29ded68f6fc9e6c45e071a2e48bd50c5084e96b657dd0404045a1ddefe282ed:
+
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f50:
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f:
+5cf2ac897ab444dcb5c8d87c495dbdb34e1838b6b629427caa51702ad0f9688525f13bec503a3c3a2c80a65e0b5715e8afab00ffa56ec455a49a1ad30aa24fcd:
+
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f5051:
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f:
+9aaf80207bace17bb7ab145757d5696bde32406ef22b44292ef65d4519c3bb2ad41a59b62cc3e94b6fa96d32a7faadae28af7d35097219aa3fd8cda31e40c275:
+
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152:
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f:
+af88b163402c86745cb650c2988fb95211b94b03ef290eed9662034241fd51cf398f8073e369354c43eae1052f9b63b08191caa138aa54fea889cc7024236897:
+
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f50515253:
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f:
+48fa7d64e1ceee27b9864db5ada4b53d00c9bc7626555813d3cd6730ab3cc06ff342d727905e33171bde6e8476e77fb1720861e94b73a2c538d254746285f430:
+
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f5051525354:
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f:
+0e6fd97a85e904f87bfe85bbeb34f69e1f18105cf4ed4f87aec36c6e8b5f68bd2a6f3dc8a9ecb2b61db4eedb6b2ea10bf9cb0251fb0f8b344abf7f366b6de5ab:
+
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455:
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f:
+06622da5787176287fdc8fed440bad187d830099c94e6d04c8e9c954cda70c8bb9e1fc4a6d0baa831b9b78ef6648681a4867a11da93ee36e5e6a37d87fc63f6f:
+
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f50515253545556:
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f:
+1da6772b58fabf9c61f68d412c82f182c0236d7d575ef0b58dd22458d643cd1dfc93b03871c316d8430d312995d4197f0874c99172ba004a01ee295abac24e46:
+
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f5051525354555657:
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f:
+3cd2d9320b7b1d5fb9aab951a76023fa667be14a9124e394513918a3f44096ae4904ba0ffc150b63bc7ab1eeb9a6e257e5c8f000a70394a5afd842715de15f29:
+
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758:
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f:
+04cdc14f7434e0b4be70cb41db4c779a88eaef6accebcb41f2d42fffe7f32a8e281b5c103a27021d0d08362250753cdf70292195a53a48728ceb5844c2d98bab:
+
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f50515253545556575859:
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f:
+9071b7a8a075d0095b8fb3ae5113785735ab98e2b52faf91d5b89e44aac5b5d4ebbf91223b0ff4c71905da55342e64655d6ef8c89a4768c3f93a6dc0366b5bc8:
+
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a:
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f:
+ebb30240dd96c7bc8d0abe49aa4edcbb4afdc51ff9aaf720d3f9e7fbb0f9c6d6571350501769fc4ebd0b2141247ff400d4fd4be414edf37757bb90a32ac5c65a:
+
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b:
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f:
+8532c58bf3c8015d9d1cbe00eef1f5082f8f3632fbe9f1ed4f9dfb1fa79e8283066d77c44c4af943d76b300364aecbd0648c8a8939bd204123f4b56260422dec:
+
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c:
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f:
+fe9846d64f7c7708696f840e2d76cb4408b6595c2f81ec6a28a7f2f20cb88cfe6ac0b9e9b8244f08bd7095c350c1d0842f64fb01bb7f532dfcd47371b0aeeb79:
+
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d:
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f:
+28f17ea6fb6c42092dc264257e29746321fb5bdaea9873c2a7fa9d8f53818e899e161bc77dfe8090afd82bf2266c5c1bc930a8d1547624439e662ef695f26f24:
+
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e:
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f:
+ec6b7d7f030d4850acae3cb615c21dd25206d63e84d1db8d957370737ba0e98467ea0ce274c66199901eaec18a08525715f53bfdb0aacb613d342ebdceeddc3b:
+
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f:
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f:
+b403d3691c03b0d3418df327d5860d34bbfcc4519bfbce36bf33b208385fadb9186bc78a76c489d89fd57e7dc75412d23bcd1dae8470ce9274754bb8585b13c5:
+
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60:
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f:
+31fc79738b8772b3f55cd8178813b3b52d0db5a419d30ba9495c4b9da0219fac6df8e7c23a811551a62b827f256ecdb8124ac8a6792ccfecc3b3012722e94463:
+
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f6061:
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f:
+bb2039ec287091bcc9642fc90049e73732e02e577e2862b32216ae9bedcd730c4c284ef3968c368b7d37584f97bd4b4dc6ef6127acfe2e6ae2509124e66c8af4:
+
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162:
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f:
+f53d68d13f45edfcb9bd415e2831e938350d5380d3432278fc1c0c381fcb7c65c82dafe051d8c8b0d44e0974a0e59ec7bf7ed0459f86e96f329fc79752510fd3:
+
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60616263:
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f:
+8d568c7984f0ecdf7640fbc483b5d8c9f86634f6f43291841b309a350ab9c1137d24066b09da9944bac54d5bb6580d836047aac74ab724b887ebf93d4b32eca9:
+
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f6061626364:
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f:
+c0b65ce5a96ff774c456cac3b5f2c4cd359b4ff53ef93a3da0778be4900d1e8da1601e769e8f1b02d2a2f8c5b9fa10b44f1c186985468feeb008730283a6657d:
+
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465:
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f:
+4900bba6f5fb103ece8ec96ada13a5c3c85488e05551da6b6b33d988e611ec0fe2e3c2aa48ea6ae8986a3a231b223c5d27cec2eadde91ce07981ee652862d1e4:
+
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60616263646566:
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f:
+c7f5c37c7285f927f76443414d4357ff789647d7a005a5a787e03c346b57f49f21b64fa9cf4b7e45573e23049017567121a9c3d4b2b73ec5e9413577525db45a:
+
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f6061626364656667:
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f:
+ec7096330736fdb2d64b5653e7475da746c23a4613a82687a28062d3236364284ac01720ffb406cfe265c0df626a188c9e5963ace5d3d5bb363e32c38c2190a6:
+
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768:
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f:
+82e744c75f4649ec52b80771a77d475a3bc091989556960e276a5f9ead92a03f718742cdcfeaee5cb85c44af198adc43a4a428f5f0c2ddb0be36059f06d7df73:
+
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60616263646566676869:
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f:
+2834b7a7170f1f5b68559ab78c1050ec21c919740b784a9072f6e5d69f828d70c919c5039fb148e39e2c8a52118378b064ca8d5001cd10a5478387b966715ed6:
+
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a:
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f:
+16b4ada883f72f853bb7ef253efcab0c3e2161687ad61543a0d2824f91c1f81347d86be709b16996e17f2dd486927b0288ad38d13063c4a9672c39397d3789b6:
+
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b:
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f:
+78d048f3a69d8b54ae0ed63a573ae350d89f7c6cf1f3688930de899afa037697629b314e5cd303aa62feea72a25bf42b304b6c6bcb27fae21c16d925e1fbdac3:
+
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c:
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f:
+0f746a48749287ada77a82961f05a4da4abdb7d77b1220f836d09ec814359c0ec0239b8c7b9ff9e02f569d1b301ef67c4612d1de4f730f81c12c40cc063c5caa:
+
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d:
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f:
+f0fc859d3bd195fbdc2d591e4cdac15179ec0f1dc821c11df1f0c1d26e6260aaa65b79fafacafd7d3ad61e600f250905f5878c87452897647a35b995bcadc3a3:
+
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e:
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f:
+2620f687e8625f6a412460b42e2cef67634208ce10a0cbd4dff7044a41b7880077e9f8dc3b8d1216d3376a21e015b58fb279b521d83f9388c7382c8505590b9b:
+
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f:
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f:
+227e3aed8d2cb10b918fcb04f9de3e6d0a57e08476d93759cd7b2ed54a1cbf0239c528fb04bbf288253e601d3bc38b21794afef90b17094a182cac557745e75f:
+
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f70:
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f:
+1a929901b09c25f27d6b35be7b2f1c4745131fdebca7f3e2451926720434e0db6e74fd693ad29b777dc3355c592a361c4873b01133a57c2e3b7075cbdb86f4fc:
+
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f7071:
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f:
+5fd7968bc2fe34f220b5e3dc5af9571742d73b7d60819f2888b629072b96a9d8ab2d91b82d0a9aaba61bbd39958132fcc4257023d1eca591b3054e2dc81c8200:
+
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172:
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f:
+dfcce8cf32870cc6a503eadafc87fd6f78918b9b4d0737db6810be996b5497e7e5cc80e312f61e71ff3e9624436073156403f735f56b0b01845c18f6caf772e6:
+
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f70717273:
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f:
+02f7ef3a9ce0fff960f67032b296efca3061f4934d690749f2d01c35c81c14f39a67fa350bc8a0359bf1724bffc3bca6d7c7bba4791fd522a3ad353c02ec5aa8:
+
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f7071727374:
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f:
+64be5c6aba65d594844ae78bb022e5bebe127fd6b6ffa5a13703855ab63b624dcd1a363f99203f632ec386f3ea767fc992e8ed9686586aa27555a8599d5b808f:
+
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475:
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f:
+f78585505c4eaa54a8b5be70a61e735e0ff97af944ddb3001e35d86c4e2199d976104b6ae31750a36a726ed285064f5981b503889fef822fcdc2898dddb7889a:
+
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f70717273747576:
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f:
+e4b5566033869572edfd87479a5bb73c80e8759b91232879d96b1dda36c012076ee5a2ed7ae2de63ef8406a06aea82c188031b560beafb583fb3de9e57952a7e:
+
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f7071727374757677:
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f:
+e1b3e7ed867f6c9484a2a97f7715f25e25294e992e41f6a7c161ffc2adc6daaeb7113102d5e6090287fe6ad94ce5d6b739c6ca240b05c76fb73f25dd024bf935:
+
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778:
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f:
+85fd085fdc12a080983df07bd7012b0d402a0f4043fcb2775adf0bad174f9b08d1676e476985785c0a5dcc41dbff6d95ef4d66a3fbdc4a74b82ba52da0512b74:
+
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f70717273747576777879:
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f:
+aed8fa764b0fbff821e05233d2f7b0900ec44d826f95e93c343c1bc3ba5a24374b1d616e7e7aba453a0ada5e4fab5382409e0d42ce9c2bc7fb39a99c340c20f0:
+
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a:
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f:
+7ba3b2e297233522eeb343bd3ebcfd835a04007735e87f0ca300cbee6d416565162171581e4020ff4cf176450f1291ea2285cb9ebffe4c56660627685145051c:
+
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b:
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f:
+de748bcf89ec88084721e16b85f30adb1a6134d664b5843569babc5bbd1a15ca9b61803c901a4fef32965a1749c9f3a4e243e173939dc5a8dc495c671ab52145:
+
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c:
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f:
+aaf4d2bdf200a919706d9842dce16c98140d34bc433df320aba9bd429e549aa7a3397652a4d768277786cf993cde2338673ed2e6b66c961fefb82cd20c93338f:
+
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d:
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f:
+c408218968b788bf864f0997e6bc4c3dba68b276e2125a4843296052ff93bf5767b8cdce7131f0876430c1165fec6c4f47adaa4fd8bcfacef463b5d3d0fa61a0:
+
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e:
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f:
+76d2d819c92bce55fa8e092ab1bf9b9eab237a25267986cacf2b8ee14d214d730dc9a5aa2d7b596e86a1fd8fa0804c77402d2fcd45083688b218b1cdfa0dcbcb:
+
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f:
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f:
+72065ee4dd91c2d8509fa1fc28a37c7fc9fa7d5b3f8ad3d0d7a25626b57b1b44788d4caf806290425f9890a3a2a35a905ab4b37acfd0da6e4517b2525c9651e4:
+
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f80:
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f:
+64475dfe7600d7171bea0b394e27c9b00d8e74dd1e416a79473682ad3dfdbb706631558055cfc8a40e07bd015a4540dcdea15883cbbf31412df1de1cd4152b91:
+
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f8081:
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f:
+12cd1674a4488a5d7c2b3160d2e2c4b58371bedad793418d6f19c6ee385d70b3e06739369d4df910edb0b0a54cbff43d54544cd37ab3a06cfa0a3ddac8b66c89:
+
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182:
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f:
+60756966479dedc6dd4bcff8ea7d1d4ce4d4af2e7b097e32e3763518441147cc12b3c0ee6d2ecabf1198cec92e86a3616fba4f4e872f5825330adbb4c1dee444:
+
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f80818283:
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f:
+a7803bcb71bc1d0f4383dde1e0612e04f872b715ad30815c2249cf34abb8b024915cb2fc9f4e7cc4c8cfd45be2d5a91eab0941c7d270e2da4ca4a9f7ac68663a:
+
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f8081828384:
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f:
+b84ef6a7229a34a750d9a98ee2529871816b87fbe3bc45b45fa5ae82d5141540211165c3c5d7a7476ba5a4aa06d66476f0d9dc49a3f1ee72c3acabd498967414:
+
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485:
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f:
+fae4b6d8efc3f8c8e64d001dabec3a21f544e82714745251b2b4b393f2f43e0da3d403c64db95a2cb6e23ebb7b9e94cdd5ddac54f07c4a61bd3cb10aa6f93b49:
+
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f80818283848586:
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f:
+34f7286605a122369540141ded79b8957255da2d4155abbf5a8dbb89c8eb7ede8eeef1daa46dc29d751d045dc3b1d658bb64b80ff8589eddb3824b13da235a6b:
+
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f8081828384858687:
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f:
+3b3b48434be27b9eababba43bf6b35f14b30f6a88dc2e750c358470d6b3aa3c18e47db4017fa55106d8252f016371a00f5f8b070b74ba5f23cffc5511c9f09f0:
+
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788:
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f:
+ba289ebd6562c48c3e10a8ad6ce02e73433d1e93d7c9279d4d60a7e879ee11f441a000f48ed9f7c4ed87a45136d7dccdca482109c78a51062b3ba4044ada2469:
+
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f80818283848586878889:
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f:
+022939e2386c5a37049856c850a2bb10a13dfea4212b4c732a8840a9ffa5faf54875c5448816b2785a007da8a8d2bc7d71a54e4e6571f10b600cbdb25d13ede3:
+
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a:
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f:
+e6fec19d89ce8717b1a087024670fe026f6c7cbda11caef959bb2d351bf856f8055d1c0ebdaaa9d1b17886fc2c562b5e99642fc064710c0d3488a02b5ed7f6fd:
+
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b:
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f:
+94c96f02a8f576aca32ba61c2b206f907285d9299b83ac175c209a8d43d53bfe683dd1d83e7549cb906c28f59ab7c46f8751366a28c39dd5fe2693c9019666c8:
+
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c:
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f:
+31a0cd215ebd2cb61de5b9edc91e6195e31c59a5648d5c9f737e125b2605708f2e325ab3381c8dce1a3e958886f1ecdc60318f882cfe20a24191352e617b0f21:
+
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d:
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f:
+91ab504a522dce78779f4c6c6ba2e6b6db5565c76d3e7e7c920caf7f757ef9db7c8fcf10e57f03379ea9bf75eb59895d96e149800b6aae01db778bb90afbc989:
+
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e:
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f:
+d85cabc6bd5b1a01a5afd8c6734740da9fd1c1acc6db29bfc8a2e5b668b028b6b3154bfb8703fa3180251d589ad38040ceb707c4bad1b5343cb426b61eaa49c1:
+
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f:
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f:
+d62efbec2ca9c1f8bd66ce8b3f6a898cb3f7566ba6568c618ad1feb2b65b76c3ce1dd20f7395372faf28427f61c9278049cf0140df434f5633048c86b81e0399:
+
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f90:
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f:
+7c8fdc6175439e2c3db15bafa7fb06143a6a23bc90f449e79deef73c3d492a671715c193b6fea9f036050b946069856b897e08c00768f5ee5ddcf70b7cd6d0e0:
+
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f9091:
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f:
+58602ee7468e6bc9df21bd51b23c005f72d6cb013f0a1b48cbec5eca299299f97f09f54a9a01483eaeb315a6478bad37ba47ca1347c7c8fc9e6695592c91d723:
+
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192:
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f:
+27f5b79ed256b050993d793496edf4807c1d85a7b0a67c9c4fa99860750b0ae66989670a8ffd7856d7ce411599e58c4d77b232a62bef64d15275be46a68235ff:
+
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f90919293:
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f:
+3957a976b9f1887bf004a8dca942c92d2b37ea52600f25e0c9bc5707d0279c00c6e85a839b0d2d8eb59c51d94788ebe62474a791cadf52cccf20f5070b6573fc:
+
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f9091929394:
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f:
+eaa2376d55380bf772ecca9cb0aa4668c95c707162fa86d518c8ce0ca9bf7362b9f2a0adc3ff59922df921b94567e81e452f6c1a07fc817cebe99604b3505d38:
+
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495:
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f:
+c1e2c78b6b2734e2480ec550434cb5d613111adcc21d475545c3b1b7e6ff12444476e5c055132e2229dc0f807044bb919b1a5662dd38a9ee65e243a3911aed1a:
+
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f90919293949596:
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f:
+8ab48713389dd0fcf9f965d3ce66b1e559a1f8c58741d67683cd971354f452e62d0207a65e436c5d5d8f8ee71c6abfe50e669004c302b31a7ea8311d4a916051:
+
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f9091929394959697:
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f:
+24ce0addaa4c65038bd1b1c0f1452a0b128777aabc94a29df2fd6c7e2f85f8ab9ac7eff516b0e0a825c84a24cfe492eaad0a6308e46dd42fe8333ab971bb30ca:
+
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798:
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f:
+5154f929ee03045b6b0c0004fa778edee1d139893267cc84825ad7b36c63de32798e4a166d24686561354f63b00709a1364b3c241de3febf0754045897467cd4:
+
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f90919293949596979899:
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f:
+e74e907920fd87bd5ad636dd11085e50ee70459c443e1ce5809af2bc2eba39f9e6d7128e0e3712c316da06f4705d78a4838e28121d4344a2c79c5e0db307a677:
+
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a:
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f:
+bf91a22334bac20f3fd80663b3cd06c4e8802f30e6b59f90d3035cc9798a217ed5a31abbda7fa6842827bdf2a7a1c21f6fcfccbb54c6c52926f32da816269be1:
+
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b:
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f:
+d9d5c74be5121b0bd742f26bffb8c89f89171f3f934913492b0903c271bbe2b3395ef259669bef43b57f7fcc3027db01823f6baee66e4f9fead4d6726c741fce:
+
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c:
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f:
+50c8b8cf34cd879f80e2faab3230b0c0e1cc3e9dcadeb1b9d97ab923415dd9a1fe38addd5c11756c67990b256e95ad6d8f9fedce10bf1c90679cde0ecf1be347:
+
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d:
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f:
+0a386e7cd5dd9b77a035e09fe6fee2c8ce61b5383c87ea43205059c5e4cd4f4408319bb0a82360f6a58e6c9ce3f487c446063bf813bc6ba535e17fc1826cfc91:
+
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e:
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f:
+1f1459cb6b61cbac5f0efe8fc487538f42548987fcd56221cfa7beb22504769e792c45adfb1d6b3d60d7b749c8a75b0bdf14e8ea721b95dca538ca6e25711209:
+
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9f:
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f:
+e58b3836b7d8fedbb50ca5725c6571e74c0785e97821dab8b6298c10e4c079d4a6cdf22f0fedb55032925c16748115f01a105e77e00cee3d07924dc0d8f90659:
+
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0:
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f:
+b929cc6505f020158672deda56d0db081a2ee34c00c1100029bdf8ea98034fa4bf3e8655ec697fe36f40553c5bb46801644a627d3342f4fc92b61f03290fb381:
+
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1:
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f:
+72d353994b49d3e03153929a1e4d4f188ee58ab9e72ee8e512f29bc773913819ce057ddd7002c0433ee0a16114e3d156dd2c4a7e80ee53378b8670f23e33ef56:
+
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2:
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f:
+c70ef9bfd775d408176737a0736d68517ce1aaad7e81a93c8c1ed967ea214f56c8a377b1763e676615b60f3988241eae6eab9685a5124929d28188f29eab06f7:
+
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3:
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f:
+c230f0802679cb33822ef8b3b21bf7a9a28942092901d7dac3760300831026cf354c9232df3e084d9903130c601f63c1f4a4a4b8106e468cd443bbe5a734f45f:
+
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4:
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f:
+6f43094cafb5ebf1f7a4937ec50f56a4c9da303cbb55ac1f27f1f1976cd96beda9464f0e7b9c54620b8a9fba983164b8be3578425a024f5fe199c36356b88972:
+
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5:
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f:
+3745273f4c38225db2337381871a0c6aafd3af9b018c88aa02025850a5dc3a42a1a3e03e56cbf1b0876d63a441f1d2856a39b8801eb5af325201c415d65e97fe:
+
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6:
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f:
+c50c44cca3ec3edaae779a7e179450ebdda2f97067c690aa6c5a4ac7c30139bb27c0df4db3220e63cb110d64f37ffe078db72653e2daacf93ae3f0a2d1a7eb2e:
+
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7:
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f:
+8aef263e385cbc61e19b28914243262af5afe8726af3ce39a79c27028cf3ecd3f8d2dfd9cfc9ad91b58f6f20778fd5f02894a3d91c7d57d1e4b866a7f364b6be:
+
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8:
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f:
+28696141de6e2d9bcb3235578a66166c1448d3e905a1b482d423be4bc5369bc8c74dae0acc9cc123e1d8ddce9f97917e8c019c552da32d39d2219b9abf0fa8c8:
+
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9:
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f:
+2fb9eb2085830181903a9dafe3db428ee15be7662224efd643371fb25646aee716e531eca69b2bdc8233f1a8081fa43da1500302975a77f42fa592136710e9dc:
+
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aa:
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f:
+66f9a7143f7a3314a669bf2e24bbb35014261d639f495b6c9c1f104fe8e320aca60d4550d69d52edbd5a3cdeb4014ae65b1d87aa770b69ae5c15f4330b0b0ad8:
+
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaab:
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f:
+f4c4dd1d594c3565e3e25ca43dad82f62abea4835ed4cd811bcd975e46279828d44d4c62c3679f1b7f7b9dd4571d7b49557347b8c5460cbdc1bef690fb2a08c0:
+
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabac:
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f:
+8f1dc9649c3a84551f8f6e91cac68242a43b1f8f328ee92280257387fa7559aa6db12e4aeadc2d26099178749c6864b357f3f83b2fb3efa8d2a8db056bed6bcc:
+
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacad:
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f:
+3139c1a7f97afd1675d460ebbc07f2728aa150df849624511ee04b743ba0a833092f18c12dc91b4dd243f333402f59fe28abdbbbae301e7b659c7a26d5c0f979:
+
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadae:
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f:
+06f94a2996158a819fe34c40de3cf0379fd9fb85b3e363ba3926a0e7d960e3f4c2e0c70c7ce0ccb2a64fc29869f6e7ab12bd4d3f14fce943279027e785fb5c29:
+
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeaf:
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f:
+c29c399ef3eee8961e87565c1ce263925fc3d0ce267d13e48dd9e732ee67b0f69fad56401b0f10fcaac119201046cca28c5b14abdea3212ae65562f7f138db3d:
+
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0:
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f:
+4cec4c9df52eef05c3f6faaa9791bc7445937183224ecc37a1e58d0132d35617531d7e795f52af7b1eb9d147de1292d345fe341823f8e6bc1e5badca5c656108:
+
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1:
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f:
+898bfbae93b3e18d00697eab7d9704fa36ec339d076131cefdf30edbe8d9cc81c3a80b129659b163a323bab9793d4feed92d54dae966c77529764a09be88db45:
+
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2:
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f:
+ee9bd0469d3aaf4f14035be48a2c3b84d9b4b1fff1d945e1f1c1d38980a951be197b25fe22c731f20aeacc930ba9c4a1f4762227617ad350fdabb4e80273a0f4:
+
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3:
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f:
+3d4d3113300581cd96acbf091c3d0f3c310138cd6979e6026cde623e2dd1b24d4a8638bed1073344783ad0649cc6305ccec04beb49f31c633088a99b65130267:
+
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4:
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f:
+95c0591ad91f921ac7be6d9ce37e0663ed8011c1cfd6d0162a5572e94368bac02024485e6a39854aa46fe38e97d6c6b1947cd272d86b06bb5b2f78b9b68d559d:
+
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5:
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f:
+227b79ded368153bf46c0a3ca978bfdbef31f3024a5665842468490b0ff748ae04e7832ed4c9f49de9b1706709d623e5c8c15e3caecae8d5e433430ff72f20eb:
+
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6:
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f:
+5d34f3952f0105eef88ae8b64c6ce95ebfade0e02c69b08762a8712d2e4911ad3f941fc4034dc9b2e479fdbcd279b902faf5d838bb2e0c6495d372b5b7029813:
+
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7:
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f:
+7f939bf8353abce49e77f14f3750af20b7b03902e1a1e7fb6aaf76d0259cd401a83190f15640e74f3e6c5a90e839c7821f6474757f75c7bf9002084ddc7a62dc:
+
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8:
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f:
+062b61a2f9a33a71d7d0a06119644c70b0716a504de7e5e1be49bd7b86e7ed6817714f9f0fc313d06129597e9a2235ec8521de36f7290a90ccfc1ffa6d0aee29:
+
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9:
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f:
+f29e01eeae64311eb7f1c6422f946bf7bea36379523e7b2bbaba7d1d34a22d5ea5f1c5a09d5ce1fe682cced9a4798d1a05b46cd72dff5c1b355440b2a2d476bc:
+
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9ba:
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f:
+ec38cd3bbab3ef35d7cb6d5c914298351d8a9dc97fcee051a8a02f58e3ed6184d0b7810a5615411ab1b95209c3c810114fdeb22452084e77f3f847c6dbaafe16:
+
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babb:
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f:
+c2aef5e0ca43e82641565b8cb943aa8ba53550caef793b6532fafad94b816082f0113a3ea2f63608ab40437ecc0f0229cb8fa224dcf1c478a67d9b64162b92d1:
+
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbc:
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f:
+15f534efff7105cd1c254d074e27d5898b89313b7d366dc2d7d87113fa7d53aae13f6dba487ad8103d5e854c91fdb6e1e74b2ef6d1431769c30767dde067a35c:
+
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbd:
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f:
+89acbca0b169897a0a2714c2df8c95b5b79cb69390142b7d6018bb3e3076b099b79a964152a9d912b1b86412b7e372e9cecad7f25d4cbab8a317be36492a67d7:
+
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbe:
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f:
+e3c0739190ed849c9c962fd9dbb55e207e624fcac1eb417691515499eea8d8267b7e8f1287a63633af5011fde8c4ddf55bfdf722edf88831414f2cfaed59cb9a:
+
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebf:
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f:
+8d6cf87c08380d2d1506eee46fd4222d21d8c04e585fbfd08269c98f702833a156326a0724656400ee09351d57b440175e2a5de93cc5f80db6daf83576cf75fa:
+
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0:
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f:
+da24bede383666d563eeed37f6319baf20d5c75d1635a6ba5ef4cfa1ac95487e96f8c08af600aab87c986ebad49fc70a58b4890b9c876e091016daf49e1d322e:
+
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1:
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f:
+f9d1d1b1e87ea7ae753a029750cc1cf3d0157d41805e245c5617bb934e732f0ae3180b78e05bfe76c7c3051e3e3ac78b9b50c05142657e1e03215d6ec7bfd0fc:
+
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2:
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f:
+11b7bc1668032048aa43343de476395e814bbbc223678db951a1b03a021efac948cfbe215f97fe9a72a2f6bc039e3956bfa417c1a9f10d6d7ba5d3d32ff323e5:
+
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3:
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f:
+b8d9000e4fc2b066edb91afee8e7eb0f24e3a201db8b6793c0608581e628ed0bcc4e5aa6787992a4bcc44e288093e63ee83abd0bc3ec6d0934a674a4da13838a:
+
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4:
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f:
+ce325e294f9b6719d6b61278276ae06a2564c03bb0b783fafe785bdf89c7d5acd83e78756d301b445699024eaeb77b54d477336ec2a4f332f2b3f88765ddb0c3:
+
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5:
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f:
+29acc30e9603ae2fccf90bf97e6cc463ebe28c1b2f9b4b765e70537c25c702a29dcbfbf14c99c54345ba2b51f17b77b5f15db92bbad8fa95c471f5d070a137cc:
+
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6:
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f:
+3379cbaae562a87b4c0425550ffdd6bfe1203f0d666cc7ea095be407a5dfe61ee91441cd5154b3e53b4f5fb31ad4c7a9ad5c7af4ae679aa51a54003a54ca6b2d:
+
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7:
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f:
+3095a349d245708c7cf550118703d7302c27b60af5d4e67fc978f8a4e60953c7a04f92fcf41aee64321ccb707a895851552b1e37b00bc5e6b72fa5bcef9e3fff:
+
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8:
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f:
+07262d738b09321f4dbccec4bb26f48cb0f0ed246ce0b31b9a6e7bc683049f1f3e5545f28ce932dd985c5ab0f43bd6de0770560af329065ed2e49d34624c2cbb:
+
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9:
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f:
+b6405eca8ee3316c87061cc6ec18dba53e6c250c63ba1f3bae9e55dd3498036af08cd272aa24d713c6020d77ab2f3919af1a32f307420618ab97e73953994fb4:
+
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9ca:
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f:
+7ee682f63148ee45f6e5315da81e5c6e557c2c34641fc509c7a5701088c38a74756168e2cd8d351e88fd1a451f360a01f5b2580f9b5a2e8cfc138f3dd59a3ffc:
+
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacb:
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f:
+1d263c179d6b268f6fa016f3a4f29e943891125ed8593c81256059f5a7b44af2dcb2030d175c00e62ecaf7ee96682aa07ab20a611024a28532b1c25b86657902:
+
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcc:
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f:
+106d132cbdb4cd2597812846e2bc1bf732fec5f0a5f65dbb39ec4e6dc64ab2ce6d24630d0f15a805c3540025d84afa98e36703c3dbee713e72dde8465bc1be7e:
+
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccd:
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f:
+0e79968226650667a8d862ea8da4891af56a4e3a8b6d1750e394f0dea76d640d85077bcec2cc86886e506751b4f6a5838f7f0b5fef765d9dc90dcdcbaf079f08:
+
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdce:
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f:
+521156a82ab0c4e566e5844d5e31ad9aaf144bbd5a464fdca34dbd5717e8ff711d3ffebbfa085d67fe996a34f6d3e4e60b1396bf4b1610c263bdbb834d560816:
+
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecf:
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f:
+1aba88befc55bc25efbce02db8b9933e46f57661baeabeb21cc2574d2a518a3cba5dc5a38e49713440b25f9c744e75f6b85c9d8f4681f676160f6105357b8406:
+
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0:
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f:
+5a9949fcb2c473cda968ac1b5d08566dc2d816d960f57e63b898fa701cf8ebd3f59b124d95bfbbedc5f1cf0e17d5eaed0c02c50b69d8a402cabcca4433b51fd4:
+
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1:
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f:
+b0cead09807c672af2eb2b0f06dde46cf5370e15a4096b1a7d7cbb36ec31c205fbefca00b7a4162fa89fb4fb3eb78d79770c23f44e7206664ce3cd931c291e5d:
+
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2:
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f:
+bb6664931ec97044e45b2ae420ae1c551a8874bc937d08e969399c3964ebdba8346cdd5d09caafe4c28ba7ec788191ceca65ddd6f95f18583e040d0f30d0364d:
+
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3:
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f:
+65bc770a5faa3792369803683e844b0be7ee96f29f6d6a35568006bd5590f9a4ef639b7a8061c7b0424b66b60ac34af3119905f33a9d8c3ae18382ca9b689900:
+
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4:
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f:
+ea9b4dca333336aaf839a45c6eaa48b8cb4c7ddabffea4f643d6357ea6628a480a5b45f2b052c1b07d1fedca918b6f1139d80f74c24510dcbaa4be70eacc1b06:
+
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5:
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f:
+e6342fb4a780ad975d0e24bce149989b91d360557e87994f6b457b895575cc02d0c15bad3ce7577f4c63927ff13f3e381ff7e72bdbe745324844a9d27e3f1c01:
+
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6:
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f:
+3e209c9b33e8e461178ab46b1c64b49a07fb745f1c8bc95fbfb94c6b87c69516651b264ef980937fad41238b91ddc011a5dd777c7efd4494b4b6ecd3a9c22ac0:
+
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7:
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f:
+fd6a3d5b1875d80486d6e69694a56dbb04a99a4d051f15db2689776ba1c4882e6d462a603b7015dc9f4b7450f05394303b8652cfb404a266962c41bae6e18a94:
+
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8:
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f:
+951e27517e6bad9e4195fc8671dee3e7e9be69cee1422cb9fecfce0dba875f7b310b93ee3a3d558f941f635f668ff832d2c1d033c5e2f0997e4c66f147344e02:
+
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9:
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f:
+8eba2f874f1ae84041903c7c4253c82292530fc8509550bfdc34c95c7e2889d5650b0ad8cb988e5c4894cb87fbfbb19612ea93ccc4c5cad17158b9763464b492:
+
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9da:
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f:
+16f712eaa1b7c6354719a8e7dbdfaf55e4063a4d277d947550019b38dfb564830911057d50506136e2394c3b28945cc964967d54e3000c2181626cfb9b73efd2:
+
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadb:
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f:
+c39639e7d5c7fb8cdd0fd3e6a52096039437122f21c78f1679cea9d78a734c56ecbeb28654b4f18e342c331f6f7229ec4b4bc281b2d80a6eb50043f31796c88c:
+
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdc:
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f:
+72d081af99f8a173dcc9a0ac4eb3557405639a29084b54a40172912a2f8a395129d5536f0918e902f9e8fa6000995f4168ddc5f893011be6a0dbc9b8a1a3f5bb:
+
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdd:
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f:
+c11aa81e5efd24d5fc27ee586cfd8847fbb0e27601ccece5ecca0198e3c7765393bb74457c7e7a27eb9170350e1fb53857177506be3e762cc0f14d8c3afe9077:
+
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcddde:
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f:
+c28f2150b452e6c0c424bcde6f8d72007f9310fed7f2f87de0dbb64f4479d6c1441ba66f44b2accee61609177ed340128b407ecec7c64bbe50d63d22d8627727:
+
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedf:
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f:
+f63d88122877ec30b8c8b00d22e89000a966426112bd44166e2f525b769ccbe9b286d437a0129130dde1a86c43e04bedb594e671d98283afe64ce331de9828fd:
+
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0:
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f:
+348b0532880b88a6614a8d7408c3f913357fbb60e995c60205be9139e74998aede7f4581e42f6b52698f7fa1219708c14498067fd1e09502de83a77dd281150c:
+
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1:
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f:
+5133dc8bef725359dff59792d85eaf75b7e1dcd1978b01c35b1b85fcebc63388ad99a17b6346a217dc1a9622ebd122ecf6913c4d31a6b52a695b86af00d741a0:
+
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2:
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f:
+2753c4c0e98ecad806e88780ec27fccd0f5c1ab547f9e4bf1659d192c23aa2cc971b58b6802580baef8adc3b776ef7086b2545c2987f348ee3719cdef258c403:
+
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3:
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f:
+b1663573ce4b9d8caefc865012f3e39714b9898a5da6ce17c25a6a47931a9ddb9bbe98adaa553beed436e89578455416c2a52a525cf2862b8d1d49a2531b7391:
+
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4:
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f:
+64f58bd6bfc856f5e873b2a2956ea0eda0d6db0da39c8c7fc67c9f9feefcff3072cdf9e6ea37f69a44f0c61aa0da3693c2db5b54960c0281a088151db42b11e8:
+
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5:
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f:
+0764c7be28125d9065c4b98a69d60aede703547c66a12e17e1c618994132f5ef82482c1e3fe3146cc65376cc109f0138ed9a80e49f1f3c7d610d2f2432f20605:
+
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6:
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f:
+f748784398a2ff03ebeb07e155e66116a839741a336e32da71ec696001f0ad1b25cd48c69cfca7265eca1dd71904a0ce748ac4124f3571076dfa7116a9cf00e9:
+
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7:
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f:
+3f0dbc0186bceb6b785ba78d2a2a013c910be157bdaffae81bb6663b1a73722f7f1228795f3ecada87cf6ef0078474af73f31eca0cc200ed975b6893f761cb6d:
+
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8:
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f:
+d4762cd4599876ca75b2b8fe249944dbd27ace741fdab93616cbc6e425460feb51d4e7adcc38180e7fc47c89024a7f56191adb878dfde4ead62223f5a2610efe:
+
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9:
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f:
+cd36b3d5b4c91b90fcbba79513cfee1907d8645a162afd0cd4cf4192d4a5f4c892183a8eacdb2b6b6a9d9aa8c11ac1b261b380dbee24ca468f1bfd043c58eefe:
+
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9ea:
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f:
+98593452281661a53c48a9d8cd790826c1a1ce567738053d0bee4a91a3d5bd92eefdbabebe3204f2031ca5f781bda99ef5d8ae56e5b04a9e1ecd21b0eb05d3e1:
+
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaeb:
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f:
+771f57dd2775ccdab55921d3e8e30ccf484d61fe1c1b9c2ae819d0fb2a12fab9be70c4a7a138da84e8280435daade5bbe66af0836a154f817fb17f3397e725a3:
+
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebec:
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f:
+c60897c6f828e21f16fbb5f15b323f87b6c8955eabf1d38061f707f608abdd993fac3070633e286cf8339ce295dd352df4b4b40b2f29da1dd50b3a05d079e6bb:
+
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebeced:
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f:
+8210cd2c2d3b135c2cf07fa0d1433cd771f325d075c6469d9c7f1ba0943cd4ab09808cabf4acb9ce5bb88b498929b4b847f681ad2c490d042db2aec94214b06b:
+
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedee:
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f:
+1d4edfffd8fd80f7e4107840fa3aa31e32598491e4af7013c197a65b7f36dd3ac4b478456111cd4309d9243510782fa31b7c4c95fa951520d020eb7e5c36e4ef:
+
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeef:
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f:
+af8e6e91fab46ce4873e1a50a8ef448cc29121f7f74deef34a71ef89cc00d9274bc6c2454bbb3230d8b2ec94c62b1dec85f3593bfa30ea6f7a44d7c09465a253:
+
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0:
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f:
+29fd384ed4906f2d13aa9fe7af905990938bed807f1832454a372ab412eea1f5625a1fcc9ac8343b7c67c5aba6e0b1cc4644654913692c6b39eb9187ceacd3ec:
+
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1:
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f:
+a268c7885d9874a51c44dffed8ea53e94f78456e0b2ed99ff5a3924760813826d960a15edbedbb5de5226ba4b074e71b05c55b9756bb79e55c02754c2c7b6c8a:
+
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2:
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f:
+0cf8545488d56a86817cd7ecb10f7116b7ea530a45b6ea497b6c72c997e09e3d0da8698f46bb006fc977c2cd3d1177463ac9057fdd1662c85d0c126443c10473:
+
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3:
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f:
+b39614268fdd8781515e2cfebf89b4d5402bab10c226e6344e6b9ae000fb0d6c79cb2f3ec80e80eaeb1980d2f8698916bd2e9f747236655116649cd3ca23a837:
+
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4:
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f:
+74bef092fc6f1e5dba3663a3fb003b2a5ba257496536d99f62b9d73f8f9eb3ce9ff3eec709eb883655ec9eb896b9128f2afc89cf7d1ab58a72f4a3bf034d2b4a:
+
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5:
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f:
+3a988d38d75611f3ef38b8774980b33e573b6c57bee0469ba5eed9b44f29945e7347967fba2c162e1c3be7f310f2f75ee2381e7bfd6b3f0baea8d95dfb1dafb1:
+
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6:
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f:
+58aedfce6f67ddc85a28c992f1c0bd0969f041e66f1ee88020a125cbfcfebcd61709c9c4eba192c15e69f020d462486019fa8dea0cd7a42921a19d2fe546d43d:
+
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7:
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f:
+9347bd291473e6b4e368437b8e561e065f649a6d8ada479ad09b1999a8f26b91cf6120fd3bfe014e83f23acfa4c0ad7b3712b2c3c0733270663112ccd9285cd9:
+
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8:
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f:
+b32163e7c5dbb5f51fdc11d2eac875efbbcb7e7699090a7e7ff8a8d50795af5d74d9ff98543ef8cdf89ac13d0485278756e0ef00c817745661e1d59fe38e7537:
+
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9:
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f:
+1085d78307b1c4b008c57a2e7e5b234658a0a82e4ff1e4aaac72b312fda0fe27d233bc5b10e9cc17fdc7697b540c7d95eb215a19a1a0e20e1abfa126efd568c7:
+
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fa:
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f:
+4e5c734c7dde011d83eac2b7347b373594f92d7091b9ca34cb9c6f39bdf5a8d2f134379e16d822f6522170ccf2ddd55c84b9e6c64fc927ac4cf8dfb2a17701f2:
+
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafb:
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f:
+695d83bd990a1117b3d0ce06cc888027d12a054c2677fd82f0d4fbfc93575523e7991a5e35a3752e9b70ce62992e268a877744cdd435f5f130869c9a2074b338:
+
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfc:
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f:
+a6213743568e3b3158b9184301f3690847554c68457cb40fc9a4b8cfd8d4a118c301a07737aeda0f929c68913c5f51c80394f53bff1c3e83b2e40ca97eba9e15:
+
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfd:
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f:
+d444bfa2362a96df213d070e33fa841f51334e4e76866b8139e8af3bb3398be2dfaddcbc56b9146de9f68118dc5829e74b0c28d7711907b121f9161cb92b69a9:
+
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfe:
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f:
+142709d62e28fcccd0af97fad0f8465b971e82201dc51070faa0372aa43e92484be1c1e73ba10906d5d1853db6a4106e0a7bf9800d373d6dee2d46d62ef2a461:
diff --git a/lib/Utils.Cryptography/monocypher/vendor/tests/gen/vectors/chacha20 b/lib/Utils.Cryptography/monocypher/vendor/tests/gen/vectors/chacha20
new file mode 100644
index 0000000..34b2fb9
--- /dev/null
+++ b/lib/Utils.Cryptography/monocypher/vendor/tests/gen/vectors/chacha20
@@ -0,0 +1,36 @@
+# RFC 8439
+# Test Vector #1:
+# ==============
+0000000000000000000000000000000000000000000000000000000000000000:
+0000000000000000:
+00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000:
+0000000000000000:
+76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7da41597c5157488d7724e03fb8d84a376a43b8f41518a11cc387b669b2ee6586:
+
+# Same, key slightly modified
+0000000000000000000000000000000000000000000000000000000000000001:
+0000000000000000:
+00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000:
+0000000000000000:
+4540f05a9f1fb296d7736e7b208e3c96eb4fe1834688d2604f450952ed432d41bbe2a0b6ea7566d2a5d1e7e20d42af2c53d792b1c43fea817e9ad275ae546963:
+
+# Same, nonce slightly modified
+0000000000000000000000000000000000000000000000000000000000000000:
+0000000000000001:
+000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000:
+0000000000000000:
+de9cba7bf3d69ef5e786dc63973f653a0b49e015adbff7134fcb7df137821031e85a050278a7084527214f73efc7fa5b5277062eb7a0433e445f41e3:
+
+# Same, nonce MSB modified
+0000000000000000000000000000000000000000000000000000000000000000:
+0100000000000000:
+00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000:
+0000000000000000:
+ef3fdfd6c61578fbf5cf35bd3dd33b8009631634d21e42ac33960bd138e50d32111e4caf237ee53ca8ad6426194a88545ddc497a0b466e7d6bbdb0041b2f586b:
+
+# Don't remember where this one comes from
+000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f:
+0001020304050607:
+00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000:
+0000000000000000:
+f798a189f195e66982105ffb640bb7757f579da31602fc93ec01ac56f85ac3c134a4547b733b46413042c9440049176905d3be59ea1c53f15916155c2be8241a38008b9a26bc35941e2444177c8ade6689de95264986d95889fb60e84629c9bd9a5acb1cc118be563eb9b3a4a472f82e09a7e778492b562ef7130e88dfe031c79db9d4f7c7a899151b9a475032b63fc385245fe054e3dd5a97a5f576fe064025d3ce042c566ab2c507b138db853e3d6959660996546cc9c4a6eafdc777c040d70eaf46f76dad3979e5c5360c3317166a1c894c94a371876a94df7628fe4eaaf2ccb27d5aaae0ad7ad0f9d4b6ad3b54098746d4524d38407a6deb3ab78fab78c9:
diff --git a/lib/Utils.Cryptography/monocypher/vendor/tests/gen/vectors/ed_25519_check b/lib/Utils.Cryptography/monocypher/vendor/tests/gen/vectors/ed_25519_check
new file mode 100644
index 0000000..42e4b47
--- /dev/null
+++ b/lib/Utils.Cryptography/monocypher/vendor/tests/gen/vectors/ed_25519_check
@@ -0,0 +1,1981 @@
+# Daniel Bleichenbacher test vectors from Wycheproof:
+# https://github.com/google/wycheproof/blob/master/testvectors/eddsa_test.json
+#
+# Notes:
+#
+# - SignatureMalleability: EdDSA signatures are non-malleable, if
+# implemented accordingly. Failing to check the range of S allows to
+# modify signatures. See RFC 8032, Section 5.2.7 and Section 8.4.
+
+# valid
+7d4d0e7f6153a69b6242b522abbee685fda4420f8834b108c3bdae369ef549fa:
+:
+d4fbdb52bfa726b44d1786a8c0d171c3e62ca83c9e5bbe63de0bb2483f8fd6cc1429ab72cafc41ab56af02ff8fcc43b99bfe4c7ae940f60f38ebaa9d311c4007:
+00:
+
+# valid
+7d4d0e7f6153a69b6242b522abbee685fda4420f8834b108c3bdae369ef549fa:
+78:
+d80737358ede548acb173ef7e0399f83392fe8125b2ce877de7975d8b726ef5b1e76632280ee38afad12125ea44b961bf92f1178c9fa819d020869975bcbe109:
+00:
+
+# valid
+7d4d0e7f6153a69b6242b522abbee685fda4420f8834b108c3bdae369ef549fa:
+54657374:
+7c38e026f29e14aabd059a0f2db8b0cd783040609a8be684db12f82a27774ab07a9155711ecfaf7f99f277bad0c6ae7e39d4eef676573336a5c51eb6f946b30d:
+00:
+
+# valid
+7d4d0e7f6153a69b6242b522abbee685fda4420f8834b108c3bdae369ef549fa:
+48656c6c6f:
+1c1ad976cbaae3b31dee07971cf92c928ce2091a85f5899f5e11ecec90fc9f8e93df18c5037ec9b29c07195ad284e63d548cd0a6fe358cc775bd6c1608d2c905:
+00:
+
+# valid
+7d4d0e7f6153a69b6242b522abbee685fda4420f8834b108c3bdae369ef549fa:
+313233343030:
+657c1492402ab5ce03e2c3a7f0384d051b9cf3570f1207fc78c1bcc98c281c2bf0cf5b3a289976458a1be6277a5055545253b45b07dcc1abd96c8b989c00f301:
+00:
+
+# valid
+7d4d0e7f6153a69b6242b522abbee685fda4420f8834b108c3bdae369ef549fa:
+000000000000000000000000:
+d46543bfb892f84ec124dcdfc847034c19363bf3fc2fa89b1267833a14856e52e60736918783f950b6f1dd8d40dc343247cd43ce054c2d68ef974f7ed0f3c60f:
+00:
+
+# valid
+7d4d0e7f6153a69b6242b522abbee685fda4420f8834b108c3bdae369ef549fa:
+6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161:
+879350045543bc14ed2c08939b68c30d22251d83e018cacbaf0c9d7a48db577e80bdf76ce99e5926762bc13b7b3483260a5ef63d07e34b58eb9c14621ac92f00:
+00:
+
+# valid
+7d4d0e7f6153a69b6242b522abbee685fda4420f8834b108c3bdae369ef549fa:
+202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60:
+7bdc3f9919a05f1d5db4a3ada896094f6871c1f37afc75db82ec3147d84d6f237b7e5ecc26b59cfea0c7eaf1052dc427b0f724615be9c3d3e01356c65b9b5109:
+00:
+
+# valid
+7d4d0e7f6153a69b6242b522abbee685fda4420f8834b108c3bdae369ef549fa:
+ffffffffffffffffffffffffffffffff:
+5dbd7360e55aa38e855d6ad48c34bd35b7871628508906861a7c4776765ed7d1e13d910faabd689ec8618b78295c8ab8f0e19c8b4b43eb8685778499e943ae04:
+00:
+
+# special values for r and s
+# invalid
+7d4d0e7f6153a69b6242b522abbee685fda4420f8834b108c3bdae369ef549fa:
+3f:
+00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000:
+ff:
+
+# special values for r and s
+# invalid
+7d4d0e7f6153a69b6242b522abbee685fda4420f8834b108c3bdae369ef549fa:
+3f:
+00000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000:
+ff:
+
+# special values for r and s
+# invalid
+7d4d0e7f6153a69b6242b522abbee685fda4420f8834b108c3bdae369ef549fa:
+3f:
+0000000000000000000000000000000000000000000000000000000000000000ecd3f55c1a631258d69cf7a2def9de1400000000000000000000000000000010:
+ff:
+
+# special values for r and s
+# invalid
+7d4d0e7f6153a69b6242b522abbee685fda4420f8834b108c3bdae369ef549fa:
+3f:
+0000000000000000000000000000000000000000000000000000000000000000edd3f55c1a631258d69cf7a2def9de1400000000000000000000000000000010:
+ff:
+
+# special values for r and s
+# invalid
+7d4d0e7f6153a69b6242b522abbee685fda4420f8834b108c3bdae369ef549fa:
+3f:
+0000000000000000000000000000000000000000000000000000000000000000edffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f:
+ff:
+
+# special values for r and s
+# invalid
+7d4d0e7f6153a69b6242b522abbee685fda4420f8834b108c3bdae369ef549fa:
+3f:
+01000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000:
+ff:
+
+# special values for r and s
+# invalid
+7d4d0e7f6153a69b6242b522abbee685fda4420f8834b108c3bdae369ef549fa:
+3f:
+01000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000:
+ff:
+
+# special values for r and s
+# invalid
+7d4d0e7f6153a69b6242b522abbee685fda4420f8834b108c3bdae369ef549fa:
+3f:
+0100000000000000000000000000000000000000000000000000000000000000ecd3f55c1a631258d69cf7a2def9de1400000000000000000000000000000010:
+ff:
+
+# special values for r and s
+# invalid
+7d4d0e7f6153a69b6242b522abbee685fda4420f8834b108c3bdae369ef549fa:
+3f:
+0100000000000000000000000000000000000000000000000000000000000000edd3f55c1a631258d69cf7a2def9de1400000000000000000000000000000010:
+ff:
+
+# special values for r and s
+# invalid
+7d4d0e7f6153a69b6242b522abbee685fda4420f8834b108c3bdae369ef549fa:
+3f:
+0100000000000000000000000000000000000000000000000000000000000000edffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f:
+ff:
+
+# special values for r and s
+# invalid
+7d4d0e7f6153a69b6242b522abbee685fda4420f8834b108c3bdae369ef549fa:
+3f:
+edd3f55c1a631258d69cf7a2def9de14000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000:
+ff:
+
+# special values for r and s
+# invalid
+7d4d0e7f6153a69b6242b522abbee685fda4420f8834b108c3bdae369ef549fa:
+3f:
+edd3f55c1a631258d69cf7a2def9de14000000000000000000000000000000100100000000000000000000000000000000000000000000000000000000000000:
+ff:
+
+# special values for r and s
+# invalid
+7d4d0e7f6153a69b6242b522abbee685fda4420f8834b108c3bdae369ef549fa:
+3f:
+edd3f55c1a631258d69cf7a2def9de1400000000000000000000000000000010ecd3f55c1a631258d69cf7a2def9de1400000000000000000000000000000010:
+ff:
+
+# special values for r and s
+# invalid
+7d4d0e7f6153a69b6242b522abbee685fda4420f8834b108c3bdae369ef549fa:
+3f:
+edd3f55c1a631258d69cf7a2def9de1400000000000000000000000000000010edd3f55c1a631258d69cf7a2def9de1400000000000000000000000000000010:
+ff:
+
+# special values for r and s
+# invalid
+7d4d0e7f6153a69b6242b522abbee685fda4420f8834b108c3bdae369ef549fa:
+3f:
+edd3f55c1a631258d69cf7a2def9de1400000000000000000000000000000010edffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f:
+ff:
+
+# special values for r and s
+# invalid
+7d4d0e7f6153a69b6242b522abbee685fda4420f8834b108c3bdae369ef549fa:
+3f:
+edffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000:
+ff:
+
+# special values for r and s
+# invalid
+7d4d0e7f6153a69b6242b522abbee685fda4420f8834b108c3bdae369ef549fa:
+3f:
+edffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f0100000000000000000000000000000000000000000000000000000000000000:
+ff:
+
+# special values for r and s
+# invalid
+7d4d0e7f6153a69b6242b522abbee685fda4420f8834b108c3bdae369ef549fa:
+3f:
+edffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7fecd3f55c1a631258d69cf7a2def9de1400000000000000000000000000000010:
+ff:
+
+# special values for r and s
+# invalid
+7d4d0e7f6153a69b6242b522abbee685fda4420f8834b108c3bdae369ef549fa:
+3f:
+edffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7fedd3f55c1a631258d69cf7a2def9de1400000000000000000000000000000010:
+ff:
+
+# special values for r and s
+# invalid
+7d4d0e7f6153a69b6242b522abbee685fda4420f8834b108c3bdae369ef549fa:
+3f:
+edffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7fedffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f:
+ff:
+
+# modified bit 0 in R
+# invalid
+7d4d0e7f6153a69b6242b522abbee685fda4420f8834b108c3bdae369ef549fa:
+313233343030:
+647c1492402ab5ce03e2c3a7f0384d051b9cf3570f1207fc78c1bcc98c281c2b1d125e5538f38afbcc1c84e489521083041d24bc6240767029da063271a1ff0c:
+ff:
+
+# modified bit 1 in R
+# invalid
+7d4d0e7f6153a69b6242b522abbee685fda4420f8834b108c3bdae369ef549fa:
+313233343030:
+677c1492402ab5ce03e2c3a7f0384d051b9cf3570f1207fc78c1bcc98c281c2bc108ca4b87a49c9ed2cf383aecad8f54a962b2899da891e12004d7993a627e01:
+ff:
+
+# modified bit 2 in R
+# invalid
+7d4d0e7f6153a69b6242b522abbee685fda4420f8834b108c3bdae369ef549fa:
+313233343030:
+617c1492402ab5ce03e2c3a7f0384d051b9cf3570f1207fc78c1bcc98c281c2b9ce23fc6213ed5b87912e9bbf92f5e2c780eae26d15c50a112d1e97d2ea33c06:
+ff:
+
+# modified bit 7 in R
+# invalid
+7d4d0e7f6153a69b6242b522abbee685fda4420f8834b108c3bdae369ef549fa:
+313233343030:
+e57c1492402ab5ce03e2c3a7f0384d051b9cf3570f1207fc78c1bcc98c281c2bbb3eb51cd98dddb235a5f46f2bded6af184a58d09cce928bda43f41d69118a03:
+ff:
+
+# modified bit 8 in R
+# invalid
+7d4d0e7f6153a69b6242b522abbee685fda4420f8834b108c3bdae369ef549fa:
+313233343030:
+657d1492402ab5ce03e2c3a7f0384d051b9cf3570f1207fc78c1bcc98c281c2bcd237dda9a116501f67a5705a854b9adc304f34720803a91b324f2c13e0f5a09:
+ff:
+
+# modified bit 16 in R
+# invalid
+7d4d0e7f6153a69b6242b522abbee685fda4420f8834b108c3bdae369ef549fa:
+313233343030:
+657c1592402ab5ce03e2c3a7f0384d051b9cf3570f1207fc78c1bcc98c281c2b6b167bbdc0d881cc04d28905552c1876f3709851abc5007376940cc8a435c300:
+ff:
+
+# modified bit 31 in R
+# invalid
+7d4d0e7f6153a69b6242b522abbee685fda4420f8834b108c3bdae369ef549fa:
+313233343030:
+657c1412402ab5ce03e2c3a7f0384d051b9cf3570f1207fc78c1bcc98c281c2b7fd2ac7da14afffcceeb13f2a0d6b887941cb1a5eb57a52f3cb131a16cce7b0e:
+ff:
+
+# modified bit 32 in R
+# invalid
+7d4d0e7f6153a69b6242b522abbee685fda4420f8834b108c3bdae369ef549fa:
+313233343030:
+657c1492412ab5ce03e2c3a7f0384d051b9cf3570f1207fc78c1bcc98c281c2b7373ba13ebbef99cd2a8ead55ce735c987d85a35320925a8e871702dc7c5c40d:
+ff:
+
+# modified bit 63 in R
+# invalid
+7d4d0e7f6153a69b6242b522abbee685fda4420f8834b108c3bdae369ef549fa:
+313233343030:
+657c1492402ab54e03e2c3a7f0384d051b9cf3570f1207fc78c1bcc98c281c2bd35bd331c03f0855504ca1cab87b83c36a028425a3cf007ede4f4254c261cb00:
+ff:
+
+# modified bit 64 in R
+# invalid
+7d4d0e7f6153a69b6242b522abbee685fda4420f8834b108c3bdae369ef549fa:
+313233343030:
+657c1492402ab5ce02e2c3a7f0384d051b9cf3570f1207fc78c1bcc98c281c2bcb35101f73cf467deac8c1a03b6c3dc35af544132734b7e57ab20c89b2e4750d:
+ff:
+
+# modified bit 97 in R
+# invalid
+7d4d0e7f6153a69b6242b522abbee685fda4420f8834b108c3bdae369ef549fa:
+313233343030:
+657c1492402ab5ce03e2c3a7f2384d051b9cf3570f1207fc78c1bcc98c281c2bb58d2e8878290bff8d3355fdd4ea381924ee578752354eb6dee678ab4011c301:
+ff:
+
+# modified bit 127 in R
+# invalid
+7d4d0e7f6153a69b6242b522abbee685fda4420f8834b108c3bdae369ef549fa:
+313233343030:
+657c1492402ab5ce03e2c3a7f0384d851b9cf3570f1207fc78c1bcc98c281c2bb978c866187ffb1cc7b29a0b4045aefc08768df65717194ff0c6e63f4dea0d02:
+ff:
+
+# modified bit 240 in R
+# invalid
+7d4d0e7f6153a69b6242b522abbee685fda4420f8834b108c3bdae369ef549fa:
+313233343030:
+657c1492402ab5ce03e2c3a7f0384d051b9cf3570f1207fc78c1bcc98c281d2b0576ecf8eaf675f00f3dfbe19f75b83b7607a6c96414f6821af920a2498d0305:
+ff:
+
+# modified bit 247 in R
+# invalid
+7d4d0e7f6153a69b6242b522abbee685fda4420f8834b108c3bdae369ef549fa:
+313233343030:
+657c1492402ab5ce03e2c3a7f0384d051b9cf3570f1207fc78c1bcc98c289c2be5241a345c7b5428054c74b7c382fa10d4a5f1e8f8b79a71d3fdea2254f1ff0e:
+ff:
+
+# modified bit 248 in R
+# invalid
+7d4d0e7f6153a69b6242b522abbee685fda4420f8834b108c3bdae369ef549fa:
+313233343030:
+657c1492402ab5ce03e2c3a7f0384d051b9cf3570f1207fc78c1bcc98c281c2a63950c85cd6dc96364e768de50ff7732b538f8a0b1615d799190ab600849230e:
+ff:
+
+# modified bit 253 in R
+# invalid
+7d4d0e7f6153a69b6242b522abbee685fda4420f8834b108c3bdae369ef549fa:
+313233343030:
+657c1492402ab5ce03e2c3a7f0384d051b9cf3570f1207fc78c1bcc98c281c0b543bd3da0a56a8c9c152f59c9fec12f31fa66434d48b817b30d90cb4efa8b501:
+ff:
+
+# modified bit 254 in R
+# invalid
+7d4d0e7f6153a69b6242b522abbee685fda4420f8834b108c3bdae369ef549fa:
+313233343030:
+657c1492402ab5ce03e2c3a7f0384d051b9cf3570f1207fc78c1bcc98c281c6b8da07efd07a6dafb015ed6a32fe136319a972ffbc341f3a0beae97ccf8136505:
+ff:
+
+# modified bit 255 in R
+# invalid
+7d4d0e7f6153a69b6242b522abbee685fda4420f8834b108c3bdae369ef549fa:
+313233343030:
+657c1492402ab5ce03e2c3a7f0384d051b9cf3570f1207fc78c1bcc98c281cab227aedf259f910f0f3a759a335062665217925d019173b88917eae294f75d40f:
+ff:
+
+# R==0
+# invalid
+7d4d0e7f6153a69b6242b522abbee685fda4420f8834b108c3bdae369ef549fa:
+313233343030:
+0000000000000000000000000000000000000000000000000000000000000000e0b8e7770d51c7a36375d006c5bffd6af43ff54aaf47e4330dc118c71d61ec02:
+ff:
+
+# invalid R
+# invalid
+7d4d0e7f6153a69b6242b522abbee685fda4420f8834b108c3bdae369ef549fa:
+313233343030:
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff463a1908382e7eb7693acef9884f7cf931a215e0791876be22c631a59881fd0e:
+ff:
+
+# all bits flipped in R
+# invalid
+7d4d0e7f6153a69b6242b522abbee685fda4420f8834b108c3bdae369ef549fa:
+313233343030:
+9a83eb6dbfd54a31fc1d3c580fc7b2fae4630ca8f0edf803873e433673d7e3d40e94254586cb6188c5386c3febed477cb9a6cb29e3979adc4cb27cf5278fb70a:
+ff:
+
+# checking malleability
+# invalid
+# SignatureMalleability
+7d4d0e7f6153a69b6242b522abbee685fda4420f8834b108c3bdae369ef549fa:
+54657374:
+7c38e026f29e14aabd059a0f2db8b0cd783040609a8be684db12f82a27774ab067654bce3832c2d76f8f6f5dafc08d9339d4eef676573336a5c51eb6f946b31d:
+ff:
+
+# checking malleability
+# invalid
+# SignatureMalleability
+7d4d0e7f6153a69b6242b522abbee685fda4420f8834b108c3bdae369ef549fa:
+54657374:
+7c38e026f29e14aabd059a0f2db8b0cd783040609a8be684db12f82a27774ab05439412b5395d42f462c67008eba6ca839d4eef676573336a5c51eb6f946b32d:
+ff:
+
+# checking malleability
+# invalid
+# SignatureMalleability
+7d4d0e7f6153a69b6242b522abbee685fda4420f8834b108c3bdae369ef549fa:
+54657374:
+7c38e026f29e14aabd059a0f2db8b0cd783040609a8be684db12f82a27774ab02ee12ce5875bf9dff26556464bae2ad239d4eef676573336a5c51eb6f946b34d:
+ff:
+
+# checking malleability
+# invalid
+# SignatureMalleability
+7d4d0e7f6153a69b6242b522abbee685fda4420f8834b108c3bdae369ef549fa:
+54657374:
+7c38e026f29e14aabd059a0f2db8b0cd783040609a8be684db12f82a27774ab0e2300459f1e742404cd934d2c595a6253ad4eef676573336a5c51eb6f946b38d:
+ff:
+
+# checking malleability
+# invalid
+# SignatureMalleability
+7d4d0e7f6153a69b6242b522abbee685fda4420f8834b108c3bdae369ef549fa:
+54657374:
+7c38e026f29e14aabd059a0f2db8b0cd783040609a8be684db12f82a27774ab07a9155711ecfaf7f99f277bad0c6ae7e39d4eef676573336a5c51eb6f946b32d:
+ff:
+
+# checking malleability
+# invalid
+# SignatureMalleability
+7d4d0e7f6153a69b6242b522abbee685fda4420f8834b108c3bdae369ef549fa:
+54657374:
+7c38e026f29e14aabd059a0f2db8b0cd783040609a8be684db12f82a27774ab07a9155711ecfaf7f99f277bad0c6ae7e39d4eef676573336a5c51eb6f946b34d:
+ff:
+
+# checking malleability
+# invalid
+# SignatureMalleability
+7d4d0e7f6153a69b6242b522abbee685fda4420f8834b108c3bdae369ef549fa:
+54657374:
+7c38e026f29e14aabd059a0f2db8b0cd783040609a8be684db12f82a27774ab07a9155711ecfaf7f99f277bad0c6ae7e39d4eef676573336a5c51eb6f946b38d:
+ff:
+
+# checking malleability
+# invalid
+# SignatureMalleability
+7d4d0e7f6153a69b6242b522abbee685fda4420f8834b108c3bdae369ef549fa:
+54657374:
+7c38e026f29e14aabd059a0f2db8b0cd783040609a8be684db12f82a27774ab0679155711ecfaf7f99f277bad0c6ae7e39d4eef676573336a5c51eb6f946b38d:
+ff:
+
+# valid
+a12c2beb77265f2aac953b5009349d94155a03ada416aad451319480e983ca4c:
+:
+5056325d2ab440bf30bbf0f7173199aa8b4e6fbc091cf3eb6bc6cf87cd73d992ffc216c85e4ab5b8a0bbc7e9a6e9f8d33b7f6e5ac0ffdc22d9fcaf784af84302:
+00:
+
+# valid
+a12c2beb77265f2aac953b5009349d94155a03ada416aad451319480e983ca4c:
+78:
+481fafbf4364d7b682475282f517a3ac0538c9a6b6a562e99a3d8e5afb4f90a559b056b9f07af023905753b02d95eb329a35c77f154b79abbcd291615ce42f02:
+00:
+
+# valid
+a12c2beb77265f2aac953b5009349d94155a03ada416aad451319480e983ca4c:
+54657374:
+8a9bb4c465a3863abc9fd0dd35d80bb28f7d33d37d74679802d63f82b20da114b8d765a1206b3e9ad7cf2b2d8d778bb8651f1fa992db293c0039eacb6161480f:
+00:
+
+# valid
+a12c2beb77265f2aac953b5009349d94155a03ada416aad451319480e983ca4c:
+48656c6c6f:
+d839c20abfda1fd429531831c64f813f84b913e9928540310cf060b44c3dbf9457d44a7721fdc0d67724ff81cb450dd39b10cfb65db15dda4b8bf09d26bd3801:
+00:
+
+# valid
+a12c2beb77265f2aac953b5009349d94155a03ada416aad451319480e983ca4c:
+313233343030:
+9bbb1052dcfa8ad2715c2eb716ae4f1902dea353d42ee09fd4c0b4fcb8b52b5219e2200016e1199d0061891c263e31b0bc3b55673c19610c4e0fa5408004160b:
+00:
+
+# valid
+a12c2beb77265f2aac953b5009349d94155a03ada416aad451319480e983ca4c:
+000000000000000000000000:
+f63b5c0667c7897fc283296416f7f60e84bbde9cbd832e56be463ed9f568069702b17a2f7c341ebf590706a6388ac76ac613c1675ec0f2c7118f2573422a500b:
+00:
+
+# valid
+a12c2beb77265f2aac953b5009349d94155a03ada416aad451319480e983ca4c:
+6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161:
+1bc44d7001e6b5b9090fef34b2ca480f9786bbefa7d279353e5881e8dfb91b803ccd46500e270ef0109bfd741037558832120bc2a4f20fbe7b5fb3c3aaf23e08:
+00:
+
+# valid
+a12c2beb77265f2aac953b5009349d94155a03ada416aad451319480e983ca4c:
+202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60:
+ea8e22143b02372e76e99aece3ed36aec529768a27e2bb49bdc135d44378061e1f62d1ac518f33ebf37b2ee8cc6dde68a4bd7d4a2f4d6cb77f015f71ca9fc30d:
+00:
+
+# valid
+a12c2beb77265f2aac953b5009349d94155a03ada416aad451319480e983ca4c:
+ffffffffffffffffffffffffffffffff:
+8acd679e1a914fc45d5fa83d3021f0509c805c8d271df54e52f43cfbd00cb6222bf81d58fe1de2de378df67ee9f453786626961fe50a9b05f12b6f0899ebdd0a:
+00:
+
+# draft-josefsson-eddsa-ed25519-02: Test 1
+# valid
+d75a980182b10ab7d54bfed3c964073a0ee172f3daa62325af021a68f707511a:
+:
+e5564300c360ac729086e2cc806e828a84877f1eb8e5d974d873e065224901555fb8821590a33bacc61e39701cf9b46bd25bf5f0595bbe24655141438e7a100b:
+00:
+
+# draft-josefsson-eddsa-ed25519-02: Test 2
+# valid
+3d4017c3e843895a92b70aa74d1b7ebc9c982ccf2ec4968cc0cd55f12af4660c:
+72:
+92a009a9f0d4cab8720e820b5f642540a2b27b5416503f8fb3762223ebdb69da085ac1e43e15996e458f3613d0f11d8c387b2eaeb4302aeeb00d291612bb0c00:
+00:
+
+# draft-josefsson-eddsa-ed25519-02: Test 3
+# valid
+fc51cd8e6218a1a38da47ed00230f0580816ed13ba3303ac5deb911548908025:
+af82:
+6291d657deec24024827e69c3abe01a30ce548a284743a445e3680d7db5ac3ac18ff9b538d16f290ae67f760984dc6594a7c15e9716ed28dc027beceea1ec40a:
+00:
+
+# draft-josefsson-eddsa-ed25519-02: Test 1024
+# valid
+278117fc144c72340f67d0f2316e8386ceffbf2b2428c9c51fef7c597f1d426e:
+08b8b2b733424243760fe426a4b54908632110a66c2f6591eabd3345e3e4eb98fa6e264bf09efe12ee50f8f54e9f77b1e355f6c50544e23fb1433ddf73be84d879de7c0046dc4996d9e773f4bc9efe5738829adb26c81b37c93a1b270b20329d658675fc6ea534e0810a4432826bf58c941efb65d57a338bbd2e26640f89ffbc1a858efcb8550ee3a5e1998bd177e93a7363c344fe6b199ee5d02e82d522c4feba15452f80288a821a579116ec6dad2b3b310da903401aa62100ab5d1a36553e06203b33890cc9b832f79ef80560ccb9a39ce767967ed628c6ad573cb116dbefefd75499da96bd68a8a97b928a8bbc103b6621fcde2beca1231d206be6cd9ec7aff6f6c94fcd7204ed3455c68c83f4a41da4af2b74ef5c53f1d8ac70bdcb7ed185ce81bd84359d44254d95629e9855a94a7c1958d1f8ada5d0532ed8a5aa3fb2d17ba70eb6248e594e1a2297acbbb39d502f1a8c6eb6f1ce22b3de1a1f40cc24554119a831a9aad6079cad88425de6bde1a9187ebb6092cf67bf2b13fd65f27088d78b7e883c8759d2c4f5c65adb7553878ad575f9fad878e80a0c9ba63bcbcc2732e69485bbc9c90bfbd62481d9089beccf80cfe2df16a2cf65bd92dd597b0707e0917af48bbb75fed413d238f5555a7a569d80c3414a8d0859dc65a46128bab27af87a71314f318c782b23ebfe808b82b0ce26401d2e22f04d83d1255dc51addd3b75a2b1ae0784504df543af8969be3ea7082ff7fc9888c144da2af58429ec96031dbcad3dad9af0dcbaaaf268cb8fcffead94f3c7ca495e056a9b47acdb751fb73e666c6c655ade8297297d07ad1ba5e43f1bca32301651339e22904cc8c42f58c30c04aafdb038dda0847dd988dcda6f3bfd15c4b4c4525004aa06eeff8ca61783aacec57fb3d1f92b0fe2fd1a85f6724517b65e614ad6808d6f6ee34dff7310fdc82aebfd904b01e1dc54b2927094b2db68d6f903b68401adebf5a7e08d78ff4ef5d63653a65040cf9bfd4aca7984a74d37145986780fc0b16ac451649de6188a7dbdf191f64b5fc5e2ab47b57f7f7276cd419c17a3ca8e1b939ae49e488acba6b965610b5480109c8b17b80e1b7b750dfc7598d5d5011fd2dcc5600a32ef5b52a1ecc820e308aa342721aac0943bf6686b64b2579376504ccc493d97e6aed3fb0f9cd71a43dd497f01f17c0e2cb3797aa2a2f256656168e6c496afc5fb93246f6b1116398a346f1a641f3b041e989f7914f90cc2c7fff357876e506b50d334ba77c225bc307ba537152f3f1610e4eafe595f6d9d90d11faa933a15ef1369546868a7f3a45a96768d40fd9d03412c091c6315cf4fde7cb68606937380db2eaaa707b4c4185c32eddcdd306705e4dc1ffc872eeee475a64dfac86aba41c0618983f8741c5ef68d3a101e8a3b8cac60c905c15fc910840b94c00a0b9d0:
+0aab4c900501b3e24d7cdf4663326a3a87df5e4843b2cbdb67cbf6e460fec350aa5371b1508f9f4528ecea23c436d94b5e8fcd4f681e30a6ac00a9704a188a03:
+00:
+
+# Random test failure 1
+# valid
+8fd659b77b558ed93882c1157438450ac86ec62d421d568e98ee236f3810295a:
+b0729a713593a92e46b56eaa66b9e435f7a09a8e7de03b078f6f282285276635f301e7aaafe42187c45d6f5b13f9f16b11195cc125c05b90d24dfe4c:
+7db17557ac470c0eda4eedaabce99197ab62565653cf911f632ee8be0e5ffcfc88fb94276b42e0798fd3aa2f0318be7fc6a29fae75f70c3dcdc414a0ad866601:
+00:
+
+# Random test failure 2
+# valid
+2a606bf67ac770c607038b004101b325edb569efd3413d2d1f2c3e6b4e6e3082:
+a8546e50ba31cae3234310d32672447be213fad91a227a19669c53d309b959782b0e6b71f8791fdb470043b58122003157d2d96a43a6cbd7d3a8d86bf4c97391883e268d50af80e1e6e12939c2bd50ca746cdadfad4edf1bda875299740724148efb1ebe73fb60088cda890317658627a5f7ab5a0c075d9d8f3f97b6492b35519e50ff6b38377432a7081f9176bb1c29a862deac1336ca20b097a47829cec10a6a7cec178eda2d12f6dc6c87f910454af0123555ba184e68804d9cced60fd5c8c90943e56599c8f0ba59a38491ba5e5a53460682474c07e40ca142983314fd762856bb1093f359da6eb0a756bd93a3160c10dd8feea6b97e7c6a17cb54bd5d7649c05c66d7bdee056671dfdaf689fa3945bb8e29a429f4bd5d355dce9687b06f01d5e33e3999f0e8:
+67d84d4c3945aaf06e06d524be63acbfb5dbb1988c4aea96a5ee9f7a9b9eecc29df4f66b8aa1d9e8607a58fb1ef0c2ad69aac005b4f58e34103344a9c8871a09:
+00:
+
+# Random test failure 24
+# valid
+2a606bf67ac770c607038b004101b325edb569efd3413d2d1f2c3e6b4e6e3082:
+b477b0480bb84642608b908d29a51cf2fce63f24ee95:
+28fafbb62b4d688fa79e1ac92851f46e319b161f801d4dc09acc21fdd6780a2c4292b8c1003c61c2bcebe7f3f88ccc4bb26d407387c5f27cb8c94cf6ce810405:
+00:
+
+# Random test failure 3
+# valid
+c9c946cbc5544ac74eef491f07c5881c16faf7ec31ce4aa91bb60ae7b4539051:
+cd2212eddb0706f62c995cef958634f0cb7793444cbf4d30e81c27c41ebea6cb02607510131f9c015692dfd521b148841e9a2d3564d20ac401f6cb8e40f520fe0cafbeaa88840b83013369d879f013463fe52a13267aa0c8c59c45cde9399cd1e6be8cc64cf48315ac2eb31a1c567a4fb7d601746d1f63b5ac020712adbbe07519bded6f:
+24087d47f3e20af51b9668ae0a88ce76586802d0ec75d8c0f28fc30962b5e1d1a1d509571a1624ed125a8df92a6e963728d6b5de99200b8e285f70feb6f05207:
+00:
+
+# Random test failure 20
+# valid
+c9c946cbc5544ac74eef491f07c5881c16faf7ec31ce4aa91bb60ae7b4539051:
+27d465bc632743522aefa23c:
+c2656951e2a0285585a51ff0eda7e9a23c2dfd2ffa273aee7808f4604e8f9a8c8ea49e9fce4eb2d8d75d36b7238fe6fc13b6c5d9427dd58f8c6615d033c0bd0f:
+00:
+
+# Random test failure 4
+# valid
+32ad026f693d0d2afe7f4388d91c4c964426fcb9e3665c3ebd8650009b815c8e:
+ec5c7cb078:
+d920d421a5956b69bfe1ba834c025e2babb6c7a6d78c97de1d9bb1116dfdd1185147b2887e34e15578172e150774275ea2aad9e02106f7e8ca1caa669a066f0c:
+00:
+
+# Random test failure 5
+# valid
+32ad026f693d0d2afe7f4388d91c4c964426fcb9e3665c3ebd8650009b815c8e:
+4668c6a76f0e482190a7175b9f3806a5fe4314a004fa69f988373f7a:
+4f62daf7f7c162038552ad7d306e195baa37ecf6ca7604142679d7d1128e1f8af52e4cb3545748c44ef1ff1c64e877e4f4d248259b7f6eb56e3ef72097dc8e0c:
+00:
+
+# Random test failure 8
+# valid
+32ad026f693d0d2afe7f4388d91c4c964426fcb9e3665c3ebd8650009b815c8e:
+5dc9bb87eb11621a93f92abe53515697d2611b2eef73:
+deecafb6f2ede73fec91a6f10e45b9c1c61c4b9bfbe6b6147e2de0b1df6938971f7896c3ab83851fb5d9e537037bff0fca0ccb4a3cc38f056f91f7d7a0557e08:
+00:
+
+# Random test failure 10
+# valid
+32ad026f693d0d2afe7f4388d91c4c964426fcb9e3665c3ebd8650009b815c8e:
+7dcfe60f881e1285676f35b68a1b2dbcdd7be6f719a288ababc28d36e3a42ac3010a1ca54b32760e74:
+7f8663cf98cbd39d5ff553f00bcf3d0d520605794f8866ce75714d77cc51e66c91818b657d7b0dae430a68353506edc4a714c345f5ddb5c8b958ba3d035f7a01:
+00:
+
+# Random test failure 12
+# valid
+32ad026f693d0d2afe7f4388d91c4c964426fcb9e3665c3ebd8650009b815c8e:
+58e456064dff471109def4ca27fa8310a1df32739655b624f27e6418d34b7f007173f3faa5:
+6aab49e5c0bc309b783378ee03ffda282f0185cdf94c847701ff307a6ee8d0865411c44e0a8206f6a5f606107451940c2593af790ce1860f4c14ab25b2deae08:
+00:
+
+# Random test failure 15
+# valid
+32ad026f693d0d2afe7f4388d91c4c964426fcb9e3665c3ebd8650009b815c8e:
+a1:
+1a74ed2cbdc7d8f3827014e8e6ecf8fd2698ac8f86833acccdd400df710fe0d6b0543c9cfa00d52bf024ab7ce0d91981944097233ec134d5c7abbd44bfd32d0d:
+00:
+
+# Random test failure 19
+# valid
+32ad026f693d0d2afe7f4388d91c4c964426fcb9e3665c3ebd8650009b815c8e:
+11cb1eafa4c42a8402c4193c4696f7b2e6d4585e4b42dcf1a8b67a80b2da80bc9d4b649fb2f35eaf1f56c426fd0b:
+14ceb2eaf4688d995d482f44852d71ad878cd7c77b41e60b0065fd01a59b054ee74759224187dbde9e59a763a70277c960892ef89fba997aba2576b2c54ba608:
+00:
+
+# Random test failure 25
+# valid
+32ad026f693d0d2afe7f4388d91c4c964426fcb9e3665c3ebd8650009b815c8e:
+aa365b442d12b7f3c925:
+83c40ce13d483cc58ff65844875862d93df4bd367af77efa469ec06a8ed9e6d7905a04879535708ddf225567a815c9b941d405c98e918fd0c151165cea7fb101:
+00:
+
+# Random test failure 28
+# valid
+32ad026f693d0d2afe7f4388d91c4c964426fcb9e3665c3ebd8650009b815c8e:
+475f:
+71a4a06a34075f2fd47bc3abf4714d46db7e97b08cb6180d3f1539ac50b18ce51f8af8ae95ed21d4fa0daab7235925631ecea1fd9d0d8a2ba7a7583fd04b900c:
+00:
+
+# Random test failure 6
+# valid
+c29ec1894e06d27b4e40486b4fa5063d66a746c7f9c323b12203c03b72b8b78a:
+0f325ffd87e58131ffa23c05ea4579513b287fdba87b44:
+6669acf94667c5b541afe5307bde9476b13ae7e0e6058a772101ac8eb0a94331428eb4db0a2c68a9b6c1763b8624dab259b0876cdcfaeacc17b21a18e3fc010a:
+00:
+
+# Random test failure 21
+# valid
+c29ec1894e06d27b4e40486b4fa5063d66a746c7f9c323b12203c03b72b8b78a:
+5ffa:
+931e5152fcef078c22cc5d6a3a65f06e396289f6f5f2d1efa6340254a53526ef5dc6874eeddf35c3f50991c53cd02bf06313e37d93ee1f7022128ffa3b8f300b:
+00:
+
+# Random test failure 7
+# valid
+cfda5b899e35764c5229e59295fe1222b7ddce176643697c29e46ecbba10cf10:
+ec5c7cb078:
+30490c28f806298225df62103521dcee047153912c33ab8ab8bbdd1ffabd70fd4fdb360f05be535b067d1cf4e78c2cb432206bf280aab3bd21aaa1cb894c5b06:
+00:
+
+# Random test failure 9
+# valid
+cfda5b899e35764c5229e59295fe1222b7ddce176643697c29e46ecbba10cf10:
+67484059b2490b1a0a4f8dee77979e26:
+4cd4f77ed473a6647387f3163541c67a1708a3c3bd1673247cb87f0cb68b3c56f04bfa72970c8a483efe659c87009ab4020b590b6641316b3deddb5450544e02:
+00:
+
+# Random test failure 11
+# valid
+cfda5b899e35764c5229e59295fe1222b7ddce176643697c29e46ecbba10cf10:
+a020a4381dc9141f47ee508871ab7a8b5a3648727c4281ae9932376f23a8e1bcda0626b7129197d864178631ec89c4332dbb18:
+1e41a24fe732bd7cab14c2a2f5134ee8c87fcbd2e987e60957ed9239e5c32404d56977e1b4282871896cb10625a1937468e4dc266e16a9c1b8e9891177eca802:
+00:
+
+# Random test failure 14
+# valid
+cfda5b899e35764c5229e59295fe1222b7ddce176643697c29e46ecbba10cf10:
+a25176b3afea318b2ec11ddacb10caf7179c0b3f8eabbfa2895581138d3c1e0e:
+2a833aadecd9f28235cb5896bf3781521dc71f28af2e91dbe1735a61dce3e31ac15ca24b3fc47817a59d386bbbb2ce60a6adc0a2703bb2bdea8f70f91051f706:
+00:
+
+# Random test failure 18
+# valid
+cfda5b899e35764c5229e59295fe1222b7ddce176643697c29e46ecbba10cf10:
+a9e6d94870a67a9fe1cf13b1e6f9150cdd407bf6480ec841ea586ae3935e9787163cf419c1:
+c97e3190f83bae7729ba473ad46b420b8aad735f0808ea42c0f898ccfe6addd4fd9d9fa3355d5e67ee21ab7e1f805cd07f1fce980e307f4d7ad36cc924eef00c:
+00:
+
+# Random test failure 13
+# valid
+529919c9c780985a841c42ba6c180ff2d67a276ccfbe281080e47ab71a758f56:
+e1cbf2d86827825613fb7a85811d:
+01abfa4d6bbc726b196928ec84fd03f0c953a4fa2b228249562ff1442a4f63a7150b064f3712b51c2af768d2c2711a71aabf8d186833e941a0301b82f0502905:
+00:
+
+# Random test failure 22
+# valid
+529919c9c780985a841c42ba6c180ff2d67a276ccfbe281080e47ab71a758f56:
+25:
+e4ae21f7a8f4b3b325c161a8c6e53e2edd7005b9c2f8a2e3b0ac4ba94aa80be6f2ee22ac8d4a96b9a3eb73a825e7bb5aff4a3393bf5b4a38119e9c9b1b041106:
+00:
+
+# Random test failure 16
+# valid
+2252b3d57c74cbf8bc460dc2e082847926bc022f09ab6ae95756362bfd1167c1:
+975ef941710071a9e1e6325a0c860becd7c695b5117c3107b686e330e5:
+af0fd9dda7e03e12313410d8d8844ebb6fe6b7f65141f22d7bcba5695a25414a9e54326fb44d59fb14707899a8aae70857b23d4080d7ab2c396ef3a36d45ce02:
+00:
+
+# Random test failure 23
+# valid
+2252b3d57c74cbf8bc460dc2e082847926bc022f09ab6ae95756362bfd1167c1:
+80fdd6218f29c8c8f6bd820945f9b0854e3a8824:
+e097e0bd0370bff5bde359175a11b728ee9639095d5df8eda496395565616edfe079977f7d4dc8c75d6113a83d6a55e6e1676408c0967a2906339b43337dcb01:
+00:
+
+# Random test failure 17
+# valid
+c0a773110f975de3732355bb7ec7f0c41c091c0252966070205516693b992a4a:
+:
+0280427e713378f49d478df6373c6cac847b622b567daa2376c839e7ac10e22c380ab0fa8617c9dcfe76c4d9db5459b21dc1413726e46cc8f387d359e344f407:
+00:
+
+# Random test failure 26
+# valid
+54cda623245759ad6d43e620a606908befc633d60792bc7798447a0ef38e7311:
+27e792b28b2f1702:
+14d9b497c19b91d43481c55bb6f5056de252d9ecb637575c807e58e9b4c5eac8b284089d97e2192dc242014363208e2c9a3435edf8928fb1d893553e9be4c703:
+00:
+
+# Random test failure 27
+# valid
+2362bac514d5fad33802642e979a1e82de6eb6f1bcbf6a5b304f2bb02b9e57fe:
+eef3bb0f617c17d0420c115c21c28e3762edc7b7fb048529b84a9c2bc6:
+242ddb3a5d938d07af690b1b0ef0fa75842c5f9549bf39c8750f75614c712e7cbaf2e37cc0799db38b858d41aec5b9dd2fca6a3c8e082c10408e2cf3932b9d08:
+00:
+
+# Test case for overflow in signature generation
+# valid
+037b55b427dc8daa0f80fcebaf0846902309f8a6cf18b465c0ce9b6539629ac8:
+01234567:
+c964e100033ce8888b23466677da4f4aea29923f642ae508f9d0888d788150636ab9b2c3765e91bbb05153801114d9e52dc700df377212222bb766be4b8c020d:
+00:
+
+# Test case for overflow in signature generation
+# valid
+9c0007698f177998a7666c7cf7973e2b88e9c4946e33804a7bbe8968d2394b2e:
+9399a6db9433d2a28d2b0c11c8794ab7d108c95b:
+176065c6d64a136a2227687d77f61f3fca3b16122c966276fd9a8b14a1a2cea4c33b3533d11101717016684e3810efbea63bb23773f7cc480174199abd734f08:
+00:
+
+# Test case for overflow in signature generation
+# valid
+ed3a6f9721dc9729c1f76635bcf080d7036e1c2f0228654ccbbe1e738c17b963:
+7af783afbbd44c1833ab7237ecaf63b94ffdd003:
+7ca69331eec8610d38f00e2cdbd46966cb359dcde98a257ac6f362cc00c8f4fe85c02285fe4d66e31a44cadb2bf474e1a7957609eb4fe95a71473fe6699aa70d:
+00:
+
+# Test case for overflow in signature generation
+# valid
+4abfb535313705a6570018440cdec1a3ae33e51f352112fa6acbd0c6bc3ea859:
+321b5f663c19e30ee7bbb85e48ecf44db9d3f512:
+f296715e855d8aecccba782b670163dedc4458fe4eb509a856bcac450920fd2e95a3a3eb212d2d9ccaf948c39ae46a2548af125f8e2ad9b77bd18f92d59f9200:
+00:
+
+# Test case for overflow in signature generation
+# valid
+4f2162e6bf03a712db0efa418b7e7006e23871d9d7ec555a313885c4afd96385:
+c48890e92aeeb3af04858a8dc1d34f16a4347b91:
+367d07253a9d5a77d054b9c1a82d3c0a448a51905343320b3559325ef41839608aa45564978da1b2968c556cfb23b0c98a9be83e594d5e769d69d1156e1b1506:
+00:
+
+# regression test for arithmetic error
+# valid
+0717d75ce27ea181ed5a30e6456c649b5cf453a6b4c12cd3f9fd16b31e0c25cd:
+26d5f0631f49106db58c4cfc903691134811b33c:
+9588e02bc815649d359ce710cdc69814556dd8c8bab1c468f40a49ebefb7f0de7ed49725edfd1b708fa1bad277c35d6c1b9c5ec25990997645780f9203d7dd08:
+00:
+
+# regression test for arithmetic error
+# valid
+db5b9eab7e84e5a13505865fa711c9c896c898609fc11fc9bc1e55028f9496df:
+2a71f064af982a3a1103a75cef898732d7881981:
+2217a0be57dd0d6c0090641496bcb65e37213f02a0df50aff0368ee2808e1376504f37b37494132dfc4d4887f58b9e86eff924040db3925ee4f8e1428c4c500e:
+00:
+
+# regression test for arithmetic error
+# valid
+7bac18f6d2625d3915f233434cda38a577247a7332a5170b37142a34644145e0:
+bf26796cef4ddafcf5033c8d105057db0210b6ad:
+1fda6dd4519fdbefb515bfa39e8e5911f4a0a8aa65f40ef0c542b8b34b87f9c249dc57f320718ff457ed5915c4d0fc352affc1287724d3f3a9de1ff777a02e01:
+00:
+
+# regression test for arithmetic error
+# valid
+38ead304624abebf3e2b31e20e5629531e3fc659008887c9106f5e55adbbc62a:
+ae03da6997e40cea67935020152d3a9a365cc055:
+068eafdc2f36b97f9bae7fbda88b530d16b0e35054d3a351e3a4c914b22854c711505e49682e1a447e10a69e3b04d0759c859897b64f71137acf355b63faf100:
+00:
+
+# regression test for arithmetic error
+# valid
+e9bc95049af7e4817b17c402269ba5e767b7348757ac8002fec9e08390c0a9cf:
+489d473f7fb83c7f6823baf65482517bccd8f4ea:
+43670abc9f09a8a415e76f4a21c6a46156f066b5a37b3c1e867cf67248c7b927e8d13a763e37abf936f5f27f7a8aa290539d21f740efd26b65fd5ad27085f400:
+00:
+
+# regression test for arithmetic error
+# valid
+ee8155ca4e8fe7bc5bca5992044eab7f8c3c6a13db1176f42f46c29da5b064f4:
+1b704d6692d60a07ad1e1d047b65e105a80d3459:
+56388f2228893b14ce4f2a5e0cc626591061de3a57c50a5ecab7b9d5bb2caeea191560a1cf2344c75fdb4a085444aa68d727b39f498169eaa82cf64a31f59803:
+00:
+
+# regression test for arithmetic error
+# valid
+db507bfcc9576393f7157bb360532b05c5fcf2e764b690cc6698a4a30d349095:
+dc87030862c4c32f56261e93a367caf458c6be27:
+553e5845fc480a577da6544e602caadaa00ae3e5aa3dce9ef332b1541b6d5f21bdf1d01e98baf80b8435f9932f89b3eb70f02da24787aac8e77279e797d0bd0b:
+00:
+
+# regression test for arithmetic error
+# valid
+994eaf03309d6ad9d95a656bc1744e2886f029023a3750b34f35086b3c7227f8:
+7f41ef68508343ef18813cb2fb332445ec6480cd:
+bc10f88081b7be1f2505b6e76c5c82e358cf21ec11b7df1f334fb587bada465b53d9f7b4d4fec964432ee91ead1bc32ed3c82f2167da1c834a37515df7fe130e:
+00:
+
+# regression test for arithmetic error
+# valid
+127d37e406e0d83e4b55a09e21e8f50fb88af47e4a43f018cdebffc1948757f0:
+e1ce107971534bc46a42ac609a1a37b4ca65791d:
+00c11e76b5866b7c37528b0670188c1a0473fb93c33b72ae604a8865a7d6e094ff722e8ede3cb18389685ff3c4086c29006047466f81e71a329711e0b9294709:
+00:
+
+# regression test for arithmetic error
+# valid
+d83ba84edfb4bec49f29be31d80a64b7c0b5a502438cdb1d0dd1e0e3e55786de:
+869a827397c585cf35acf88a8728833ab1c8c81e:
+0a6f0ac47ea136cb3ff00f7a96638e4984048999ee2da0af6e5c86bffb0e70bb97406b6ad5a4b764f7c99ebb6ec0fd434b8efe253b0423ef876c037998e8ab07:
+00:
+
+# regression test for arithmetic error
+# valid
+d3c9aa2f3d6ef217a166e8ae403ed436c37facbbe3beceb78df6eb439f8fa04a:
+619d8c4f2c93104be01cd574a385ceca08c33a9e:
+b7cbb942a6661e2312f79548224f3e44f5841c6e880c68340756a00ce94a914e8404858265985e6bb97ef01d2d7e5e41340309606bfc43c8c6a8f925126b3d09:
+00:
+
+# regression test for arithmetic error
+# valid
+d53280367c1c0b95ac4112218b92c6a71c51fb6312ce668de196c7d52a136155:
+5257a0bae8326d259a6ce97420c65e6c2794afe2:
+27a4f24009e579173ff3064a6eff2a4d20224f8f85fdec982a9cf2e6a3b51537348a1d7851a3a932128a923a393ea84e6b35eb3473c32dceb9d7e9cab03a0f0d:
+00:
+
+# regression test for arithmetic error
+# valid
+94ac2336ba97a476fb4c9f2b5563e4167ca292c6e99e422350a911ae3172c315:
+5acb6afc9b368f7acac0e71f6a4831c72d628405:
+985b605fe3f449f68081197a68c714da0bfbf6ac2ab9abb0508b6384ea4999cb8d79af98e86f589409e8d2609a8f8bd7e80aaa8d92a84e7737fbe8dcef41920a:
+00:
+
+# regression test for arithmetic error
+# valid
+e1e7316d231f7f275bdf403360304da1509fdf1af1fd25ca214eaac0a289398f:
+3c87b3453277b353941591fc7eaa7dd37604b42a:
+1c8fbda3d39e2b441f06da6071c13115cb4115c7c3341704cf6513324d4cf1ef4a1dd7678a048b0dde84e48994d080befcd70854079d44b6a0b0f9fa002d130c:
+00:
+
+# regression test for arithmetic error
+# valid
+fffbeea71215efaf9888fec2cc68edb3703ff11a66fd629b53cbda5eabc18750:
+0a68e27ef6847bfd9e398b328a0ded3679d4649d:
+59097233eb141ed948b4f3c28a9496b9a7eca77454ecfe7e46737d1449a0b76b15aacf77cf48af27a668aa4434cfa26c504d75a2bcc4feac46465446234c0508:
+00:
+
+# regression test for arithmetic error
+# valid
+19ccc0527599cb032e0b4c4d74e60f13901768a99df041c3bc1bf6c0ef271169:
+4e9bef60737c7d4dd10bd52567e1473a36d3573d:
+519105608508fe2f1b6da4cc8b23e39798b1d18d25972beed0404cec722e01ba1b6a0f85e99e092cca8076b101b60d4ac5035684357f4d0daacdc642da742a06:
+00:
+
+# regression test for arithmetic error
+# valid
+0e726e27047563aa0a1a9c2e085d8d26af2acba129d0869c65031e3e6cac329a:
+cc82b3163efda3ba7e9240e765112caa69113694:
+d8b03ee579e73f16477527fc9dc37a72eaac0748a733772c483ba013944f01ef64fb4ec5e3a95021dc22f4ae282baff6e9b9cc8433c6b6710d82e7397d72ef04:
+00:
+
+# regression test for arithmetic error
+# valid
+e77717b54a2b5e5bce5bccb8f0c5fdb5fd7df77ac254020fc9120dc0d4df4178:
+923a5c9e7b5635bb6c32c5a408a4a15b652450eb:
+26da61fdfd38e6d01792813f27840c8b4766b0faaed39d0ee898cb450d94a5d5f57e58b6a003d7f9b56b20561954c6edcf66492d116b8b5e91f205a3a6449d0b:
+00:
+
+# regression test for arithmetic error
+# valid
+6220972d3f7d150b36790d7d522384876d64d640cd9913186815e1629582ed36:
+6f2f0245de4587062979d0422d349f93ccdc3af2:
+4adeaff7a58c5010a5a067feea0ae504d37b0c6a76c6c153e222f13409dff2df0fab69bc5059b97d925dc1b89e9851d7c627cb82d65585f9fd976124553f8902:
+00:
+
+# regression test for arithmetic error
+# valid
+7b64a28c50ec7678a90e3e1a21522e30ac9db7b5215aea2bfb33bea037eab987:
+6e911edb27a170b983d4dee1110554f804330f41:
+4204d620cde0c3008c0b2901f5d6b44f88f0e3cb4f4d62252bf6f3cb37c1fb150a9ccb296afe5e7c75f65b5c8edd13dc4910ffe1e1265b3707c59042cf9a5902:
+00:
+
+# regression test for arithmetic error
+# valid
+724452210a9e4c994819229bf12bf84e95768a3a97c08d8d8f5f939a4cad34c5:
+b8cf807eea809aaf739aa091f3b7a3f2fd39fb51:
+f8a69d3fd8c2ff0a9dec41e4c6b43675ce08366a35e220b1185ffc246c339e22c20ac661e866f52054015efd04f42eca2adcee6834c4df923b4a62576e4dff0e:
+00:
+
+# regression test for arithmetic error
+# valid
+bad265b294ed2f422cb6a141694086238fbfe987571aa765d8b4f3a24105aa01:
+01a2b5f7fee813b4e9bd7fc25137648004795010:
+61792c9442bc6338ac41fd42a40bee9b02ec1836503d60ff725128c63d72808880c36e6190b7da525cbee5d12900aa043547dd14a2709ef9e49d628f37f6b70c:
+00:
+
+# regression test for arithmetic error
+# valid
+0aaee4b723db9b51ba7d22eb23eb8a76a5ac02f4fc9dd06f77bea42e1d37ec5a:
+0fbf5d47cb5d498feace8f98f1896208da38a885:
+fa3cd41e3a8c00b19eecd404a63c3cb787cd30de0dfc936966cff2117f5aff18db6bef80fcfd8856f3fb2e9c3dc47593e9471103032af918feee638a33d40505:
+00:
+
+# regression test for arithmetic error
+# valid
+812344af15a91ba83c2c91e96f1727ac0f3c4c41385b9fa84efa399ada5168be:
+36e67c1939750bffb3e4ba6cb85562612275e862:
+97fbbcd7a1d0eb42d2f8c42448ef35a2c2472740556b645547865330d6c57068af377fced08aaf810c08cd3c43d296f1975710312e9334c98b485f831efa4103:
+00:
+
+# regression test for arithmetic error
+# valid
+0ee5cb5597fbdf8dccc48b01485e39b33aa133b52d30d23740277267cfec3e3e:
+13945c894c1d3fe8562e8b20e5f0efaa26ade8e3:
+d7dbaa337ffd2a5fd8d5fd8ad5aeccc0c0f83795c2c59fe62a40b87903b1ae62ed748a8df5af4d32f9f822a65d0e498b6f40eaf369a9342a1164ee7d08b58103:
+00:
+
+# regression test for arithmetic error
+# valid
+9fba1de92b60b5b4703089763d0d6f9125e4dd7efae41f08a22882aef96892c4:
+4de142af4b8402f80a47fa812df84f42e283cee7:
+09a2ed303a2fa7027a1dd7c3b0d25121eeed2b644a2fbc17aa0c8aea4524071ede7e7dd7a536d5497f8165d29e4e1b63200f74bbae39fbbbccb29889c62c1f09:
+00:
+
+# regression test for arithmetic error
+# valid
+7582ab1b52e1316e5c13671f43b39ca36b28133cd0832831bcddd0b0f23398cb:
+563357f41b8b23b1d83f19f5667177a67da20b18:
+e6884a6e6b2e60a0b5862251c001e7c79d581d777d6fc11d218d0aecd79f26a30e2ca22cc7c4674f8b72655bc4ee5cb5494ca07c05177656142ac55cc9d33e02:
+00:
+
+# regression test for arithmetic error
+# valid
+dd2d678bae222f3fb6e8278f08cc9e1a66339c926c29ac0a16f9717f5ee18cd8:
+931bbf9c877a6571cf7d4609fc3eb867edd43f51:
+6124c206d864507ea5d984b363b4cf583314db6856a45ded5e61eebff4d5e337e0b4c82b445ae2e52d549d2d961eace2ea01f81158e09a9686baa040db65ad08:
+00:
+
+# regression test for arithmetic error
+# valid
+ccbe7cb2e4bc215cee2f885e1d22f7e0d582b2bbbd782c104e548b152d26fc69:
+44530b0b34f598767a7b875b0caee3c7b9c502d1:
+cfbd450a2c83cb8436c348822fe3ee347d4ee937b7f2ea11ed755cc52852407c9eec2c1fa30d2f9aef90e89b2cc3bcef2b1b9ca59f712110d19894a9cf6a2802:
+00:
+
+
+##########################################
+# Zebra low order & non-canonical points #
+##########################################
+
+# Credits to Henry de Valence for the whole idea:
+# https://hdevalence.ca/blog/2020-10-04-its-25519am
+#
+# To facilitate compatibility in consensus algorithms, Monocypher
+# chooses the maximally permissive (yet still secure) option, used in
+# the ed25519-zebra library.
+#
+# - Low order and non-canonical public keys are accepted.
+# - Low order and non-canonical R are accepted.
+# - Low order components are ignored (batch equation).
+# - (Non-canonical S is still rejected, to avoid malleability problems.)
+#
+#
+# To test this, we test that we do accept all signatures where:
+#
+# - A has low order
+# - R has low order
+# - S is zero
+#
+# Such a signature R || S, with public key A, should verify any message.
+# So we just test every possible combination of A and R. S stays null of
+# course, and we arbitrarily use the empty message.
+#
+# Curve25519 has 8 low-order points:
+#
+# - 0100000000000000000000000000000000000000000000000000000000000000
+# - 26e8958fc2b227b045c3f489f2ef98f0d5dfac05d3c63339b13802886d53fc05
+# - 0000000000000000000000000000000000000000000000000000000000000000
+# - c7176a703d4dd84fba3c0b760d10670f2a2053fa2c39ccc64ec7fd7792ac037a
+# - ecffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f
+# - c7176a703d4dd84fba3c0b760d10670f2a2053fa2c39ccc64ec7fd7792ac03fa
+# - 0000000000000000000000000000000000000000000000000000000000000080
+# - 26e8958fc2b227b045c3f489f2ef98f0d5dfac05d3c63339b13802886d53fc85
+#
+# So this should mean 8*8 possibilities for A and R, meaning 64 tests.
+# But that's not enough. We want to make sure that we accept
+# non-canonical representations as well. And those can happen on a point
+# (x, y) whenever at least one of the following holds:
+#
+# - The y coordinate is between 0 and 18.
+# - The x coordinate is 0.
+#
+# Small y coordinates can have an additional representation (modulo p)
+# that still fit in 255 bits. Null x coordinates can be negated by the
+# parity bit without affecting its value (0 = -0). When we do either
+# (or both) of those things, we get a non-canonical representation of
+# the same point. The low-order points of Curve25519 have 6:
+#
+# - 0100000000000000000000000000000000000000000000000000000000000080
+# - eeffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f
+# - eeffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+# - edffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f
+# - ecffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+# - edffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+#
+# This means 8 + 6 = 14 possibilities for A and R, and a total of 196
+# combinations, which should all be accepted.
+
+# First though, let's test that the code that checks for malleability
+# doesn't have an off-by-one error and mistakenly accepts an S that is
+# exactly the order of the curve (instead of being zero).
+0000000000000000000000000000000000000000000000000000000000000000:
+:
+0000000000000000000000000000000000000000000000000000000000000000edd3f55c1a631258d69cf7a2def9de1400000000000000000000000000000010:
+ff:
+
+# And now the long awaited 196 Zebra tests:
+0100000000000000000000000000000000000000000000000000000000000000:
+:
+01000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000:
+00:
+
+0100000000000000000000000000000000000000000000000000000000000000:
+:
+26e8958fc2b227b045c3f489f2ef98f0d5dfac05d3c63339b13802886d53fc050000000000000000000000000000000000000000000000000000000000000000:
+00:
+
+0100000000000000000000000000000000000000000000000000000000000000:
+:
+00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000:
+00:
+
+0100000000000000000000000000000000000000000000000000000000000000:
+:
+c7176a703d4dd84fba3c0b760d10670f2a2053fa2c39ccc64ec7fd7792ac037a0000000000000000000000000000000000000000000000000000000000000000:
+00:
+
+0100000000000000000000000000000000000000000000000000000000000000:
+:
+ecffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000:
+00:
+
+0100000000000000000000000000000000000000000000000000000000000000:
+:
+c7176a703d4dd84fba3c0b760d10670f2a2053fa2c39ccc64ec7fd7792ac03fa0000000000000000000000000000000000000000000000000000000000000000:
+00:
+
+0100000000000000000000000000000000000000000000000000000000000000:
+:
+00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000:
+00:
+
+0100000000000000000000000000000000000000000000000000000000000000:
+:
+26e8958fc2b227b045c3f489f2ef98f0d5dfac05d3c63339b13802886d53fc850000000000000000000000000000000000000000000000000000000000000000:
+00:
+
+0100000000000000000000000000000000000000000000000000000000000000:
+:
+01000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000:
+00:
+
+0100000000000000000000000000000000000000000000000000000000000000:
+:
+eeffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000:
+00:
+
+0100000000000000000000000000000000000000000000000000000000000000:
+:
+eeffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000000000000000000000000000000000000000000000000000:
+00:
+
+0100000000000000000000000000000000000000000000000000000000000000:
+:
+edffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000:
+00:
+
+0100000000000000000000000000000000000000000000000000000000000000:
+:
+ecffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000000000000000000000000000000000000000000000000000:
+00:
+
+0100000000000000000000000000000000000000000000000000000000000000:
+:
+edffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000000000000000000000000000000000000000000000000000:
+00:
+
+26e8958fc2b227b045c3f489f2ef98f0d5dfac05d3c63339b13802886d53fc05:
+:
+01000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000:
+00:
+
+26e8958fc2b227b045c3f489f2ef98f0d5dfac05d3c63339b13802886d53fc05:
+:
+26e8958fc2b227b045c3f489f2ef98f0d5dfac05d3c63339b13802886d53fc050000000000000000000000000000000000000000000000000000000000000000:
+00:
+
+26e8958fc2b227b045c3f489f2ef98f0d5dfac05d3c63339b13802886d53fc05:
+:
+00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000:
+00:
+
+26e8958fc2b227b045c3f489f2ef98f0d5dfac05d3c63339b13802886d53fc05:
+:
+c7176a703d4dd84fba3c0b760d10670f2a2053fa2c39ccc64ec7fd7792ac037a0000000000000000000000000000000000000000000000000000000000000000:
+00:
+
+26e8958fc2b227b045c3f489f2ef98f0d5dfac05d3c63339b13802886d53fc05:
+:
+ecffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000:
+00:
+
+26e8958fc2b227b045c3f489f2ef98f0d5dfac05d3c63339b13802886d53fc05:
+:
+c7176a703d4dd84fba3c0b760d10670f2a2053fa2c39ccc64ec7fd7792ac03fa0000000000000000000000000000000000000000000000000000000000000000:
+00:
+
+26e8958fc2b227b045c3f489f2ef98f0d5dfac05d3c63339b13802886d53fc05:
+:
+00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000:
+00:
+
+26e8958fc2b227b045c3f489f2ef98f0d5dfac05d3c63339b13802886d53fc05:
+:
+26e8958fc2b227b045c3f489f2ef98f0d5dfac05d3c63339b13802886d53fc850000000000000000000000000000000000000000000000000000000000000000:
+00:
+
+26e8958fc2b227b045c3f489f2ef98f0d5dfac05d3c63339b13802886d53fc05:
+:
+01000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000:
+00:
+
+26e8958fc2b227b045c3f489f2ef98f0d5dfac05d3c63339b13802886d53fc05:
+:
+eeffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000:
+00:
+
+26e8958fc2b227b045c3f489f2ef98f0d5dfac05d3c63339b13802886d53fc05:
+:
+eeffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000000000000000000000000000000000000000000000000000:
+00:
+
+26e8958fc2b227b045c3f489f2ef98f0d5dfac05d3c63339b13802886d53fc05:
+:
+edffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000:
+00:
+
+26e8958fc2b227b045c3f489f2ef98f0d5dfac05d3c63339b13802886d53fc05:
+:
+ecffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000000000000000000000000000000000000000000000000000:
+00:
+
+26e8958fc2b227b045c3f489f2ef98f0d5dfac05d3c63339b13802886d53fc05:
+:
+edffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000000000000000000000000000000000000000000000000000:
+00:
+
+0000000000000000000000000000000000000000000000000000000000000000:
+:
+01000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000:
+00:
+
+0000000000000000000000000000000000000000000000000000000000000000:
+:
+26e8958fc2b227b045c3f489f2ef98f0d5dfac05d3c63339b13802886d53fc050000000000000000000000000000000000000000000000000000000000000000:
+00:
+
+0000000000000000000000000000000000000000000000000000000000000000:
+:
+00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000:
+00:
+
+0000000000000000000000000000000000000000000000000000000000000000:
+:
+c7176a703d4dd84fba3c0b760d10670f2a2053fa2c39ccc64ec7fd7792ac037a0000000000000000000000000000000000000000000000000000000000000000:
+00:
+
+0000000000000000000000000000000000000000000000000000000000000000:
+:
+ecffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000:
+00:
+
+0000000000000000000000000000000000000000000000000000000000000000:
+:
+c7176a703d4dd84fba3c0b760d10670f2a2053fa2c39ccc64ec7fd7792ac03fa0000000000000000000000000000000000000000000000000000000000000000:
+00:
+
+0000000000000000000000000000000000000000000000000000000000000000:
+:
+00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000:
+00:
+
+0000000000000000000000000000000000000000000000000000000000000000:
+:
+26e8958fc2b227b045c3f489f2ef98f0d5dfac05d3c63339b13802886d53fc850000000000000000000000000000000000000000000000000000000000000000:
+00:
+
+0000000000000000000000000000000000000000000000000000000000000000:
+:
+01000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000:
+00:
+
+0000000000000000000000000000000000000000000000000000000000000000:
+:
+eeffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000:
+00:
+
+0000000000000000000000000000000000000000000000000000000000000000:
+:
+eeffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000000000000000000000000000000000000000000000000000:
+00:
+
+0000000000000000000000000000000000000000000000000000000000000000:
+:
+edffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000:
+00:
+
+0000000000000000000000000000000000000000000000000000000000000000:
+:
+ecffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000000000000000000000000000000000000000000000000000:
+00:
+
+0000000000000000000000000000000000000000000000000000000000000000:
+:
+edffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000000000000000000000000000000000000000000000000000:
+00:
+
+c7176a703d4dd84fba3c0b760d10670f2a2053fa2c39ccc64ec7fd7792ac037a:
+:
+01000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000:
+00:
+
+c7176a703d4dd84fba3c0b760d10670f2a2053fa2c39ccc64ec7fd7792ac037a:
+:
+26e8958fc2b227b045c3f489f2ef98f0d5dfac05d3c63339b13802886d53fc050000000000000000000000000000000000000000000000000000000000000000:
+00:
+
+c7176a703d4dd84fba3c0b760d10670f2a2053fa2c39ccc64ec7fd7792ac037a:
+:
+00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000:
+00:
+
+c7176a703d4dd84fba3c0b760d10670f2a2053fa2c39ccc64ec7fd7792ac037a:
+:
+c7176a703d4dd84fba3c0b760d10670f2a2053fa2c39ccc64ec7fd7792ac037a0000000000000000000000000000000000000000000000000000000000000000:
+00:
+
+c7176a703d4dd84fba3c0b760d10670f2a2053fa2c39ccc64ec7fd7792ac037a:
+:
+ecffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000:
+00:
+
+c7176a703d4dd84fba3c0b760d10670f2a2053fa2c39ccc64ec7fd7792ac037a:
+:
+c7176a703d4dd84fba3c0b760d10670f2a2053fa2c39ccc64ec7fd7792ac03fa0000000000000000000000000000000000000000000000000000000000000000:
+00:
+
+c7176a703d4dd84fba3c0b760d10670f2a2053fa2c39ccc64ec7fd7792ac037a:
+:
+00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000:
+00:
+
+c7176a703d4dd84fba3c0b760d10670f2a2053fa2c39ccc64ec7fd7792ac037a:
+:
+26e8958fc2b227b045c3f489f2ef98f0d5dfac05d3c63339b13802886d53fc850000000000000000000000000000000000000000000000000000000000000000:
+00:
+
+c7176a703d4dd84fba3c0b760d10670f2a2053fa2c39ccc64ec7fd7792ac037a:
+:
+01000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000:
+00:
+
+c7176a703d4dd84fba3c0b760d10670f2a2053fa2c39ccc64ec7fd7792ac037a:
+:
+eeffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000:
+00:
+
+c7176a703d4dd84fba3c0b760d10670f2a2053fa2c39ccc64ec7fd7792ac037a:
+:
+eeffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000000000000000000000000000000000000000000000000000:
+00:
+
+c7176a703d4dd84fba3c0b760d10670f2a2053fa2c39ccc64ec7fd7792ac037a:
+:
+edffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000:
+00:
+
+c7176a703d4dd84fba3c0b760d10670f2a2053fa2c39ccc64ec7fd7792ac037a:
+:
+ecffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000000000000000000000000000000000000000000000000000:
+00:
+
+c7176a703d4dd84fba3c0b760d10670f2a2053fa2c39ccc64ec7fd7792ac037a:
+:
+edffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000000000000000000000000000000000000000000000000000:
+00:
+
+ecffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f:
+:
+01000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000:
+00:
+
+ecffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f:
+:
+26e8958fc2b227b045c3f489f2ef98f0d5dfac05d3c63339b13802886d53fc050000000000000000000000000000000000000000000000000000000000000000:
+00:
+
+ecffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f:
+:
+00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000:
+00:
+
+ecffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f:
+:
+c7176a703d4dd84fba3c0b760d10670f2a2053fa2c39ccc64ec7fd7792ac037a0000000000000000000000000000000000000000000000000000000000000000:
+00:
+
+ecffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f:
+:
+ecffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000:
+00:
+
+ecffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f:
+:
+c7176a703d4dd84fba3c0b760d10670f2a2053fa2c39ccc64ec7fd7792ac03fa0000000000000000000000000000000000000000000000000000000000000000:
+00:
+
+ecffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f:
+:
+00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000:
+00:
+
+ecffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f:
+:
+26e8958fc2b227b045c3f489f2ef98f0d5dfac05d3c63339b13802886d53fc850000000000000000000000000000000000000000000000000000000000000000:
+00:
+
+ecffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f:
+:
+01000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000:
+00:
+
+ecffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f:
+:
+eeffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000:
+00:
+
+ecffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f:
+:
+eeffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000000000000000000000000000000000000000000000000000:
+00:
+
+ecffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f:
+:
+edffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000:
+00:
+
+ecffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f:
+:
+ecffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000000000000000000000000000000000000000000000000000:
+00:
+
+ecffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f:
+:
+edffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000000000000000000000000000000000000000000000000000:
+00:
+
+c7176a703d4dd84fba3c0b760d10670f2a2053fa2c39ccc64ec7fd7792ac03fa:
+:
+01000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000:
+00:
+
+c7176a703d4dd84fba3c0b760d10670f2a2053fa2c39ccc64ec7fd7792ac03fa:
+:
+26e8958fc2b227b045c3f489f2ef98f0d5dfac05d3c63339b13802886d53fc050000000000000000000000000000000000000000000000000000000000000000:
+00:
+
+c7176a703d4dd84fba3c0b760d10670f2a2053fa2c39ccc64ec7fd7792ac03fa:
+:
+00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000:
+00:
+
+c7176a703d4dd84fba3c0b760d10670f2a2053fa2c39ccc64ec7fd7792ac03fa:
+:
+c7176a703d4dd84fba3c0b760d10670f2a2053fa2c39ccc64ec7fd7792ac037a0000000000000000000000000000000000000000000000000000000000000000:
+00:
+
+c7176a703d4dd84fba3c0b760d10670f2a2053fa2c39ccc64ec7fd7792ac03fa:
+:
+ecffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000:
+00:
+
+c7176a703d4dd84fba3c0b760d10670f2a2053fa2c39ccc64ec7fd7792ac03fa:
+:
+c7176a703d4dd84fba3c0b760d10670f2a2053fa2c39ccc64ec7fd7792ac03fa0000000000000000000000000000000000000000000000000000000000000000:
+00:
+
+c7176a703d4dd84fba3c0b760d10670f2a2053fa2c39ccc64ec7fd7792ac03fa:
+:
+00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000:
+00:
+
+c7176a703d4dd84fba3c0b760d10670f2a2053fa2c39ccc64ec7fd7792ac03fa:
+:
+26e8958fc2b227b045c3f489f2ef98f0d5dfac05d3c63339b13802886d53fc850000000000000000000000000000000000000000000000000000000000000000:
+00:
+
+c7176a703d4dd84fba3c0b760d10670f2a2053fa2c39ccc64ec7fd7792ac03fa:
+:
+01000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000:
+00:
+
+c7176a703d4dd84fba3c0b760d10670f2a2053fa2c39ccc64ec7fd7792ac03fa:
+:
+eeffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000:
+00:
+
+c7176a703d4dd84fba3c0b760d10670f2a2053fa2c39ccc64ec7fd7792ac03fa:
+:
+eeffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000000000000000000000000000000000000000000000000000:
+00:
+
+c7176a703d4dd84fba3c0b760d10670f2a2053fa2c39ccc64ec7fd7792ac03fa:
+:
+edffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000:
+00:
+
+c7176a703d4dd84fba3c0b760d10670f2a2053fa2c39ccc64ec7fd7792ac03fa:
+:
+ecffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000000000000000000000000000000000000000000000000000:
+00:
+
+c7176a703d4dd84fba3c0b760d10670f2a2053fa2c39ccc64ec7fd7792ac03fa:
+:
+edffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000000000000000000000000000000000000000000000000000:
+00:
+
+0000000000000000000000000000000000000000000000000000000000000080:
+:
+01000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000:
+00:
+
+0000000000000000000000000000000000000000000000000000000000000080:
+:
+26e8958fc2b227b045c3f489f2ef98f0d5dfac05d3c63339b13802886d53fc050000000000000000000000000000000000000000000000000000000000000000:
+00:
+
+0000000000000000000000000000000000000000000000000000000000000080:
+:
+00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000:
+00:
+
+0000000000000000000000000000000000000000000000000000000000000080:
+:
+c7176a703d4dd84fba3c0b760d10670f2a2053fa2c39ccc64ec7fd7792ac037a0000000000000000000000000000000000000000000000000000000000000000:
+00:
+
+0000000000000000000000000000000000000000000000000000000000000080:
+:
+ecffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000:
+00:
+
+0000000000000000000000000000000000000000000000000000000000000080:
+:
+c7176a703d4dd84fba3c0b760d10670f2a2053fa2c39ccc64ec7fd7792ac03fa0000000000000000000000000000000000000000000000000000000000000000:
+00:
+
+0000000000000000000000000000000000000000000000000000000000000080:
+:
+00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000:
+00:
+
+0000000000000000000000000000000000000000000000000000000000000080:
+:
+26e8958fc2b227b045c3f489f2ef98f0d5dfac05d3c63339b13802886d53fc850000000000000000000000000000000000000000000000000000000000000000:
+00:
+
+0000000000000000000000000000000000000000000000000000000000000080:
+:
+01000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000:
+00:
+
+0000000000000000000000000000000000000000000000000000000000000080:
+:
+eeffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000:
+00:
+
+0000000000000000000000000000000000000000000000000000000000000080:
+:
+eeffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000000000000000000000000000000000000000000000000000:
+00:
+
+0000000000000000000000000000000000000000000000000000000000000080:
+:
+edffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000:
+00:
+
+0000000000000000000000000000000000000000000000000000000000000080:
+:
+ecffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000000000000000000000000000000000000000000000000000:
+00:
+
+0000000000000000000000000000000000000000000000000000000000000080:
+:
+edffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000000000000000000000000000000000000000000000000000:
+00:
+
+26e8958fc2b227b045c3f489f2ef98f0d5dfac05d3c63339b13802886d53fc85:
+:
+01000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000:
+00:
+
+26e8958fc2b227b045c3f489f2ef98f0d5dfac05d3c63339b13802886d53fc85:
+:
+26e8958fc2b227b045c3f489f2ef98f0d5dfac05d3c63339b13802886d53fc050000000000000000000000000000000000000000000000000000000000000000:
+00:
+
+26e8958fc2b227b045c3f489f2ef98f0d5dfac05d3c63339b13802886d53fc85:
+:
+00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000:
+00:
+
+26e8958fc2b227b045c3f489f2ef98f0d5dfac05d3c63339b13802886d53fc85:
+:
+c7176a703d4dd84fba3c0b760d10670f2a2053fa2c39ccc64ec7fd7792ac037a0000000000000000000000000000000000000000000000000000000000000000:
+00:
+
+26e8958fc2b227b045c3f489f2ef98f0d5dfac05d3c63339b13802886d53fc85:
+:
+ecffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000:
+00:
+
+26e8958fc2b227b045c3f489f2ef98f0d5dfac05d3c63339b13802886d53fc85:
+:
+c7176a703d4dd84fba3c0b760d10670f2a2053fa2c39ccc64ec7fd7792ac03fa0000000000000000000000000000000000000000000000000000000000000000:
+00:
+
+26e8958fc2b227b045c3f489f2ef98f0d5dfac05d3c63339b13802886d53fc85:
+:
+00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000:
+00:
+
+26e8958fc2b227b045c3f489f2ef98f0d5dfac05d3c63339b13802886d53fc85:
+:
+26e8958fc2b227b045c3f489f2ef98f0d5dfac05d3c63339b13802886d53fc850000000000000000000000000000000000000000000000000000000000000000:
+00:
+
+26e8958fc2b227b045c3f489f2ef98f0d5dfac05d3c63339b13802886d53fc85:
+:
+01000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000:
+00:
+
+26e8958fc2b227b045c3f489f2ef98f0d5dfac05d3c63339b13802886d53fc85:
+:
+eeffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000:
+00:
+
+26e8958fc2b227b045c3f489f2ef98f0d5dfac05d3c63339b13802886d53fc85:
+:
+eeffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000000000000000000000000000000000000000000000000000:
+00:
+
+26e8958fc2b227b045c3f489f2ef98f0d5dfac05d3c63339b13802886d53fc85:
+:
+edffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000:
+00:
+
+26e8958fc2b227b045c3f489f2ef98f0d5dfac05d3c63339b13802886d53fc85:
+:
+ecffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000000000000000000000000000000000000000000000000000:
+00:
+
+26e8958fc2b227b045c3f489f2ef98f0d5dfac05d3c63339b13802886d53fc85:
+:
+edffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000000000000000000000000000000000000000000000000000:
+00:
+
+0100000000000000000000000000000000000000000000000000000000000080:
+:
+01000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000:
+00:
+
+0100000000000000000000000000000000000000000000000000000000000080:
+:
+26e8958fc2b227b045c3f489f2ef98f0d5dfac05d3c63339b13802886d53fc050000000000000000000000000000000000000000000000000000000000000000:
+00:
+
+0100000000000000000000000000000000000000000000000000000000000080:
+:
+00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000:
+00:
+
+0100000000000000000000000000000000000000000000000000000000000080:
+:
+c7176a703d4dd84fba3c0b760d10670f2a2053fa2c39ccc64ec7fd7792ac037a0000000000000000000000000000000000000000000000000000000000000000:
+00:
+
+0100000000000000000000000000000000000000000000000000000000000080:
+:
+ecffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000:
+00:
+
+0100000000000000000000000000000000000000000000000000000000000080:
+:
+c7176a703d4dd84fba3c0b760d10670f2a2053fa2c39ccc64ec7fd7792ac03fa0000000000000000000000000000000000000000000000000000000000000000:
+00:
+
+0100000000000000000000000000000000000000000000000000000000000080:
+:
+00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000:
+00:
+
+0100000000000000000000000000000000000000000000000000000000000080:
+:
+26e8958fc2b227b045c3f489f2ef98f0d5dfac05d3c63339b13802886d53fc850000000000000000000000000000000000000000000000000000000000000000:
+00:
+
+0100000000000000000000000000000000000000000000000000000000000080:
+:
+01000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000:
+00:
+
+0100000000000000000000000000000000000000000000000000000000000080:
+:
+eeffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000:
+00:
+
+0100000000000000000000000000000000000000000000000000000000000080:
+:
+eeffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000000000000000000000000000000000000000000000000000:
+00:
+
+0100000000000000000000000000000000000000000000000000000000000080:
+:
+edffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000:
+00:
+
+0100000000000000000000000000000000000000000000000000000000000080:
+:
+ecffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000000000000000000000000000000000000000000000000000:
+00:
+
+0100000000000000000000000000000000000000000000000000000000000080:
+:
+edffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000000000000000000000000000000000000000000000000000:
+00:
+
+eeffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f:
+:
+01000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000:
+00:
+
+eeffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f:
+:
+26e8958fc2b227b045c3f489f2ef98f0d5dfac05d3c63339b13802886d53fc050000000000000000000000000000000000000000000000000000000000000000:
+00:
+
+eeffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f:
+:
+00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000:
+00:
+
+eeffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f:
+:
+c7176a703d4dd84fba3c0b760d10670f2a2053fa2c39ccc64ec7fd7792ac037a0000000000000000000000000000000000000000000000000000000000000000:
+00:
+
+eeffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f:
+:
+ecffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000:
+00:
+
+eeffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f:
+:
+c7176a703d4dd84fba3c0b760d10670f2a2053fa2c39ccc64ec7fd7792ac03fa0000000000000000000000000000000000000000000000000000000000000000:
+00:
+
+eeffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f:
+:
+00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000:
+00:
+
+eeffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f:
+:
+26e8958fc2b227b045c3f489f2ef98f0d5dfac05d3c63339b13802886d53fc850000000000000000000000000000000000000000000000000000000000000000:
+00:
+
+eeffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f:
+:
+01000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000:
+00:
+
+eeffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f:
+:
+eeffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000:
+00:
+
+eeffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f:
+:
+eeffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000000000000000000000000000000000000000000000000000:
+00:
+
+eeffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f:
+:
+edffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000:
+00:
+
+eeffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f:
+:
+ecffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000000000000000000000000000000000000000000000000000:
+00:
+
+eeffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f:
+:
+edffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000000000000000000000000000000000000000000000000000:
+00:
+
+eeffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff:
+:
+01000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000:
+00:
+
+eeffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff:
+:
+26e8958fc2b227b045c3f489f2ef98f0d5dfac05d3c63339b13802886d53fc050000000000000000000000000000000000000000000000000000000000000000:
+00:
+
+eeffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff:
+:
+00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000:
+00:
+
+eeffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff:
+:
+c7176a703d4dd84fba3c0b760d10670f2a2053fa2c39ccc64ec7fd7792ac037a0000000000000000000000000000000000000000000000000000000000000000:
+00:
+
+eeffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff:
+:
+ecffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000:
+00:
+
+eeffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff:
+:
+c7176a703d4dd84fba3c0b760d10670f2a2053fa2c39ccc64ec7fd7792ac03fa0000000000000000000000000000000000000000000000000000000000000000:
+00:
+
+eeffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff:
+:
+00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000:
+00:
+
+eeffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff:
+:
+26e8958fc2b227b045c3f489f2ef98f0d5dfac05d3c63339b13802886d53fc850000000000000000000000000000000000000000000000000000000000000000:
+00:
+
+eeffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff:
+:
+01000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000:
+00:
+
+eeffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff:
+:
+eeffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000:
+00:
+
+eeffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff:
+:
+eeffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000000000000000000000000000000000000000000000000000:
+00:
+
+eeffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff:
+:
+edffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000:
+00:
+
+eeffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff:
+:
+ecffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000000000000000000000000000000000000000000000000000:
+00:
+
+eeffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff:
+:
+edffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000000000000000000000000000000000000000000000000000:
+00:
+
+edffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f:
+:
+01000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000:
+00:
+
+edffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f:
+:
+26e8958fc2b227b045c3f489f2ef98f0d5dfac05d3c63339b13802886d53fc050000000000000000000000000000000000000000000000000000000000000000:
+00:
+
+edffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f:
+:
+00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000:
+00:
+
+edffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f:
+:
+c7176a703d4dd84fba3c0b760d10670f2a2053fa2c39ccc64ec7fd7792ac037a0000000000000000000000000000000000000000000000000000000000000000:
+00:
+
+edffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f:
+:
+ecffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000:
+00:
+
+edffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f:
+:
+c7176a703d4dd84fba3c0b760d10670f2a2053fa2c39ccc64ec7fd7792ac03fa0000000000000000000000000000000000000000000000000000000000000000:
+00:
+
+edffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f:
+:
+00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000:
+00:
+
+edffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f:
+:
+26e8958fc2b227b045c3f489f2ef98f0d5dfac05d3c63339b13802886d53fc850000000000000000000000000000000000000000000000000000000000000000:
+00:
+
+edffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f:
+:
+01000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000:
+00:
+
+edffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f:
+:
+eeffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000:
+00:
+
+edffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f:
+:
+eeffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000000000000000000000000000000000000000000000000000:
+00:
+
+edffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f:
+:
+edffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000:
+00:
+
+edffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f:
+:
+ecffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000000000000000000000000000000000000000000000000000:
+00:
+
+edffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f:
+:
+edffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000000000000000000000000000000000000000000000000000:
+00:
+
+ecffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff:
+:
+01000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000:
+00:
+
+ecffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff:
+:
+26e8958fc2b227b045c3f489f2ef98f0d5dfac05d3c63339b13802886d53fc050000000000000000000000000000000000000000000000000000000000000000:
+00:
+
+ecffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff:
+:
+00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000:
+00:
+
+ecffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff:
+:
+c7176a703d4dd84fba3c0b760d10670f2a2053fa2c39ccc64ec7fd7792ac037a0000000000000000000000000000000000000000000000000000000000000000:
+00:
+
+ecffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff:
+:
+ecffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000:
+00:
+
+ecffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff:
+:
+c7176a703d4dd84fba3c0b760d10670f2a2053fa2c39ccc64ec7fd7792ac03fa0000000000000000000000000000000000000000000000000000000000000000:
+00:
+
+ecffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff:
+:
+00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000:
+00:
+
+ecffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff:
+:
+26e8958fc2b227b045c3f489f2ef98f0d5dfac05d3c63339b13802886d53fc850000000000000000000000000000000000000000000000000000000000000000:
+00:
+
+ecffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff:
+:
+01000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000:
+00:
+
+ecffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff:
+:
+eeffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000:
+00:
+
+ecffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff:
+:
+eeffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000000000000000000000000000000000000000000000000000:
+00:
+
+ecffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff:
+:
+edffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000:
+00:
+
+ecffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff:
+:
+ecffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000000000000000000000000000000000000000000000000000:
+00:
+
+ecffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff:
+:
+edffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000000000000000000000000000000000000000000000000000:
+00:
+
+edffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff:
+:
+01000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000:
+00:
+
+edffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff:
+:
+26e8958fc2b227b045c3f489f2ef98f0d5dfac05d3c63339b13802886d53fc050000000000000000000000000000000000000000000000000000000000000000:
+00:
+
+edffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff:
+:
+00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000:
+00:
+
+edffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff:
+:
+c7176a703d4dd84fba3c0b760d10670f2a2053fa2c39ccc64ec7fd7792ac037a0000000000000000000000000000000000000000000000000000000000000000:
+00:
+
+edffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff:
+:
+ecffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000:
+00:
+
+edffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff:
+:
+c7176a703d4dd84fba3c0b760d10670f2a2053fa2c39ccc64ec7fd7792ac03fa0000000000000000000000000000000000000000000000000000000000000000:
+00:
+
+edffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff:
+:
+00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000:
+00:
+
+edffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff:
+:
+26e8958fc2b227b045c3f489f2ef98f0d5dfac05d3c63339b13802886d53fc850000000000000000000000000000000000000000000000000000000000000000:
+00:
+
+edffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff:
+:
+01000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000:
+00:
+
+edffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff:
+:
+eeffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000:
+00:
+
+edffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff:
+:
+eeffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000000000000000000000000000000000000000000000000000:
+00:
+
+edffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff:
+:
+edffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000:
+00:
+
+edffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff:
+:
+ecffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000000000000000000000000000000000000000000000000000:
+00:
+
+edffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff:
+:
+edffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000000000000000000000000000000000000000000000000000:
+00:
diff --git a/lib/Utils.Cryptography/monocypher/vendor/tests/gen/vectors/ed_25519ph b/lib/Utils.Cryptography/monocypher/vendor/tests/gen/vectors/ed_25519ph
new file mode 100644
index 0000000..da317a5
--- /dev/null
+++ b/lib/Utils.Cryptography/monocypher/vendor/tests/gen/vectors/ed_25519ph
@@ -0,0 +1,11 @@
+# From RFC 8032
+833fe62409237b9d62ec77587520911e9a759cec1d19755b7da901b96dca3d42:
+ec172b93ad5e563bf4932c70e1245034c35467ef2efd4d64ebf819683467e2bf:
+616263:
+98a70222f0b8121aa9d30f813d683f809e462b469c7ff87639499bb94e6dae4131f85042463c2a355a2003d062adf5aaa10b8c61e636062aaad11c2a26083406:
+
+# Test vector of unknown origin, generated with Bouncy Castle
+17A4AB24CACC54F1ED6AADBDBE0B22328C4F4F9747F75DCEC653796963367476:
+b73f21f54921d332fcb8a32292c65bdafc91358d5383a3145e9aea57c9381440:
+0000000000000000000000000000000000000000000000000000000000000000:
+a8dd09bd36d6588a4535a3e258cd5bb75cef484f8f66bd7631b45bee89fddf03933ea8ea1c2b5636d133b7c5bb63f1ca55251b963cf3c9c13fe43bd773cc8600:
diff --git a/lib/Utils.Cryptography/monocypher/vendor/tests/gen/vectors/elligator_dir b/lib/Utils.Cryptography/monocypher/vendor/tests/gen/vectors/elligator_dir
new file mode 100644
index 0000000..5080532
--- /dev/null
+++ b/lib/Utils.Cryptography/monocypher/vendor/tests/gen/vectors/elligator_dir
@@ -0,0 +1,115 @@
+d3c41ec20dbe9fc33ccc14823d898066f433a892994ffbcc921e9f5ace519d02:
+170a436471aaa00d817436197fde47fa3320aa040b48d1d2a9f155e15ce3975e:
+
+e03a05ebde6ca000cdc5c539bf48a1d08222483b87693046e00a411a8d93dd34:
+b8e22e654ae391c44be4760a30d13950651d454c7ec71f0bdf7c5669bb22b564:
+
+ec3afb86e23aff9a05c54b4274abb5daf77ad956b5a4a38caf7529866e5f5a3e:
+c1f0588b07c7624ff31b1465354d7a55eee0ce4302f4d91fa88236cfd808501f:
+
+4bdb87edb62cc3b3bf55ff767ac7e3c801c7954d2b5c03d3a26811dd6a8ad929:
+9208e81f3ae66b2cae22b4e0f25ca380ad211a5d44284dc1b741401f0decf964:
+
+b41d9ff0d16193a77fb6d68f5fe9d2dc3f8c722a4511ec3e95a184db3aebe617:
+e5bd8597bf26ef88a9e759495fa74288822ffc2ab77dc344d7641b8fb543fc56:
+
+9a8871e5d563da6919f1f24a91c2cad92ed02412ab1aa8b321d1a84459bb8e2a:
+68df2c7c319d39ea9c0fa1e53da178cb5668989f2657f6d25bdda489da83ea16:
+
+82a4c02a4d8041d5f8899c126bd3889fcff3d5cd63ee8e70bbd64b585fade926:
+bb963159d8ecc37772b0cf00d9ca0ed37a76d9b306a6f8f64ebefc8f861d5f5b:
+
+02712da5a7ed5c4ad4117eff95b84cad5b76e67f7dfbcab69215295a7aac4228:
+d7c1d9ee82b24eac542594a44c6f6653c9a8e19918d612f27f99351b30b8d864:
+
+140b05608cf89a4c4cb822f59ba8b25b300e9a36108d21e5c26a03240b5b2a31:
+058070e8efd599be224ba79dc4ee86823c41c14d89e651a7cd968293753f151a:
+
+ab98be98602474dedc91d15346bcb65bb833dd75518871f70bd26e5bfe712931:
+215524de571c221e08edb912dbe9d9c386d971e4239835ad155de6fa1ff82f28:
+
+538155639021f156812c473ed3abff75063fc4bc5e1e78ecf7f1f7fed8594a33:
+d47e10faef70170b6a3ba0ae4727ba6cb86f16f29a7e7747084310a0f466933f:
+
+d261f7d0d6ce68b6d698c4c61d54ec301dfc94e99b5f47df34a3def8e6568233:
+ce674898f882e57c6cdb41a58171cd75233a082def385ef326e35e99e1c1102d:
+
+6cbb36ab7acb90459bd526f6177bc20c49cdcecb156a14a1f65924c7c219211f:
+119a846d3fd2387621eb3e22bfa95eb7ee3abfda1cf5466ba9401ba08de0152b:
+
+664498366a736b04bc592cf18b8ac7bf94b7fcb985d4b77252844e2eeeb4811f:
+64a92a41815b38eb01e4f6e9aee7e34fa2f8d221e9da0502af542c3c203d262a:
+
+11bef745f0f627555fa65787043ea5231e057fc3bb2afc1903b13f88b494cb00:
+94ce42fb8d978dae1d353ad166b2b5ed24b6967bc0ea90f792f49b841952b844:
+
+dbe6aa62ba71ccef606f3cea913ee21b1c98f46c1a9b4ee33c843cba7cea4127:
+2a3bf5765ba945c5c7df871cecfc7374e0b655260f5eb0553e5901442cfca879:
+
+a8b34d537d591177ed521aaacb4d0917eb6d49b60353d9044d4c6d5fc09fb20d:
+d9fb40edd0f4532024fbdfd74fefe50739820085d0d9f6d9c5e9e9523a05b37d:
+
+c5cc85bd95d812d739c704e80c03416f75ae5f6ff01c929548feee5e599cd907:
+a9b74c3c12e4efb31a1d26c7677773bf223d8cb120bd552a8b6f92eadd35ed48:
+
+949523d0fa2e180612d9a776c655d08e0b16d37dff8457218e3d31eba4531413:
+1bc05bdc88c88eba38270af970abff204cfa8b07bd7fa78ea4ab5c04d1ab317c:
+
+2430a2b8a95d2f415f2f2a2a9257ff03a305ad9f2ecdd84ba0aa6760e4b1bf1d:
+7e73a15142ab131d176716129e69161b33c34ca2464b79703f47ba4cf0dcf92d:
+
+ec76eba0794f9a6215194d5c1bbd6b17502ec6b80d9af029d36c30a705e2291a:
+5563bf02a1878455a049ea1bc3c608f69f215aaac8a678977626daa451e14112:
+
+f9ce1ac470f31bbf3010c779b0a8419634052b28bd8e9ad1f07547d70f609313:
+bacf5302a799ac7f459139f6379efa3083457679dd3d2de7431aa1c7d958c725:
+
+e87526cc0db1adad5d496e25949461c13bc0573e4cccf2e76c2eb535ce40223e:
+b1acbbf9410113a467ae0d3731894cc67a131208af70e2f16758a4be0bb6706c:
+
+7a48adebb692fdb8e5a2176389f3f0bcbdc1956b0d57acac4a8eda87b577e618:
+22997bed0e3c6023e73fb371e6d3c5c3661a87c6f3f787ba6054e699aef5aa64:
+
+
+
+e73507d38bae63992b3f57aac48c0abc14509589288457995a2b4ca3490aa207:
+1e8afffed6bf53fe271ad572473262ded8faec68e5e67ef45ebb82eeba52604f:
+
+95a16019041dbefed9832048ede11928d90365f24a38aa7aef1b97e23954101b:
+794f05ba3e3a72958022468c88981e0be5782be1e1145ce2c3c6fde16ded5363:
+
+f6ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff3f:
+9cdb525555555555555555555555555555555555555555555555555555555555:
+
+f7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff3f:
+9cdb525555555555555555555555555555555555555555555555555555555555:
+
+e4e4c4054fe35a75d9c0f679ad8770d8227e68e4c1e68ce67ee88e6be251a207:
+2fd05944d079627cac0b3c292f72d41b1902b31c48457f42ab35dd10fc4eb013:
+
+48b3753cff3a6d990163e6b60da1e4e5d6a2df78c16c96a52d4fb01ea4ecf70e:
+803e8e870b922ae41883e7b41b534ea191c1eca3f657336ab652b7c683ac0176:
+
+81ac001b08d6577bd91ce991c4c45c46bc84d5465fc9139bf17042ae7313181f:
+eb0f19204beb1f397a0e8b8aeaf70fba944f4707a86d0edf4bf58cb289d6110e:
+
+7afb217bd1eceeac1e133aaa9edb441fa88ea3ae0eaa06cb9911b6d218570f12:
+5e5e130e90024e8378c8f61c7033462c1f2bead4bbfc05d1bbd592d34c620759:
+
+4a70a7e992b43e0b18578e892e954c40a51abdb5a85d300c32f391c45d6ef41b:
+dbd60ec2c1c945a5c53017a0c74e38625514307da10a65aa2523e8d3eba2cb35:
+
+043ddcf4214f24ea6ef6b181071f299aa254a4606ab6a058e0c6fb5598218d37:
+6a2ec7cf38c7b8c76a3e40e5ec25ea7b0f82215b27b31bf3fa2bebfe585ee44b:
+
+1deb473f7d04c152e7e857736715dc7b788aca39a3c96a878019e8999c815c17:
+94d5d8b30212b061affa45fa95a27dd48ad053c9e80d3a066b821affdcbf6970:
+
+23dbfbde05e6c71f118afc0dedb5b9f8dea398b2d764bca68dfc023a9821931d:
+468c7bdac19ed43aa625677d8416337c2b4f48b950755b2b5e7d664b3b3f4d03:
+
+389e38a072cf1b413bb1517c3fe83abebb1cdf3a218abb1b0c01da64c24f592e:
+6d15f8b3b5acf7be2fe9408fd1930f20c56da37f150485ef0e6243d406eb3f60:
+
+d19cfb8cb3940aba546f0be57895e2cc869fe55aab069c5abcf9e7ba6444a806:
+12524580b61c9f88f4f1cd24042002b0df4bc3feb242555bf276f96453c15826:
diff --git a/lib/Utils.Cryptography/monocypher/vendor/tests/gen/vectors/elligator_inv b/lib/Utils.Cryptography/monocypher/vendor/tests/gen/vectors/elligator_inv
new file mode 100644
index 0000000..efffd5a
--- /dev/null
+++ b/lib/Utils.Cryptography/monocypher/vendor/tests/gen/vectors/elligator_inv
@@ -0,0 +1,22 @@
+#
+# Elligator inverse map
+#
+# - Point
+# - Tweak
+# - status (00 = success, ff = failure)
+#
+
+e6f66fdf6e230c603c5e6e59a254ea1476a13eb9511b9549846781e12e52230a:
+00:
+ff:
+:
+
+46951964003c940878063ccfd0348af42150ca16d2646f2c5856e8338377d800:
+00:
+00:
+2820b6b241e0f68a6c4a7fee3d978228ef3ae45533cd410aa91a415331d8612d:
+
+46951964003c940878063ccfd0348af42150ca16d2646f2c5856e8338377d800:
+01:
+00:
+3cfb87c46c0b4575ca8175e0ed1c0ae9dae79db78df86997c4847b9f20b27718:
diff --git a/lib/Utils.Cryptography/monocypher/vendor/tests/gen/vectors/poly1305 b/lib/Utils.Cryptography/monocypher/vendor/tests/gen/vectors/poly1305
new file mode 100644
index 0000000..345f25a
--- /dev/null
+++ b/lib/Utils.Cryptography/monocypher/vendor/tests/gen/vectors/poly1305
@@ -0,0 +1,105 @@
+#
+# Empty messages (inspired from RFC 8439)
+#
+0000000000000000000000000000000000000000000000000000000000000000:
+:
+00000000000000000000000000000000:
+
+36e5f6b5c5e06070f0efca96227a863e00000000000000000000000000000000:
+:
+00000000000000000000000000000000:
+
+0000000000000000000000000000000036e5f6b5c5e06070f0efca96227a863e:
+:
+36e5f6b5c5e06070f0efca96227a863e:
+
+79207375626d697373696f6e20746f2036e5f6b5c5e06070f0efca96227a863e:
+:
+36e5f6b5c5e06070f0efca96227a863e:
+
+#
+# No idea where I got this one from.
+# The key looks random, and the message reads
+# "Cryptographic Forum Research Group"
+#
+85d6be7857556d337f4452fe42d506a80103808afb0db2fd4abff6af4149f51b:
+43727970746f6772617068696320466f72756d2052657365617263682047726f7570:
+a8061dc1305136c6c22b8baf0c0127a9:
+
+
+##################################
+### Test vectors from RFC 8439 ###
+##################################
+
+# Notice how, in test vector #2, r is equal to zero. The part of the
+# Poly1305 algorithm where the accumulator is multiplied by r means
+# that with r equal zero, the tag will be equal to s regardless of the
+# content of the text. Fortunately, all the proposed methods of
+# generating r are such that getting this particular weak key is very
+# unlikely.
+
+# Test Vector #1:
+# ==============
+0000000000000000000000000000000000000000000000000000000000000000:
+00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000:
+00000000000000000000000000000000:
+
+# Test Vector #2:
+# ==============
+0000000000000000000000000000000036e5f6b5c5e06070f0efca96227a863e:
+416e79207375626d697373696f6e20746f20746865204945544620696e74656e6465642062792074686520436f6e7472696275746f7220666f72207075626c69636174696f6e20617320616c6c206f722070617274206f6620616e204945544620496e7465726e65742d4472616674206f722052464320616e6420616e792073746174656d656e74206d6164652077697468696e2074686520636f6e74657874206f6620616e204945544620616374697669747920697320636f6e7369646572656420616e20224945544620436f6e747269627574696f6e222e20537563682073746174656d656e747320696e636c756465206f72616c2073746174656d656e747320696e20494554462073657373696f6e732c2061732077656c6c206173207772697474656e20616e6420656c656374726f6e696320636f6d6d756e69636174696f6e73206d61646520617420616e792074696d65206f7220706c6163652c207768696368206172652061646472657373656420746f:
+36e5f6b5c5e06070f0efca96227a863e:
+
+# Test Vector #3:
+# ==============
+36e5f6b5c5e06070f0efca96227a863e00000000000000000000000000000000:
+416e79207375626d697373696f6e20746f20746865204945544620696e74656e6465642062792074686520436f6e7472696275746f7220666f72207075626c69636174696f6e20617320616c6c206f722070617274206f6620616e204945544620496e7465726e65742d4472616674206f722052464320616e6420616e792073746174656d656e74206d6164652077697468696e2074686520636f6e74657874206f6620616e204945544620616374697669747920697320636f6e7369646572656420616e20224945544620436f6e747269627574696f6e222e20537563682073746174656d656e747320696e636c756465206f72616c2073746174656d656e747320696e20494554462073657373696f6e732c2061732077656c6c206173207772697474656e20616e6420656c656374726f6e696320636f6d6d756e69636174696f6e73206d61646520617420616e792074696d65206f7220706c6163652c207768696368206172652061646472657373656420746f:
+f3477e7cd95417af89a6b8794c310cf0:
+
+# Test Vector #4:
+# ==============
+1c9240a5eb55d38af333888604f6b5f0473917c1402b80099dca5cbc207075c0:
+2754776173206272696c6c69672c20616e642074686520736c6974687920746f7665730a446964206779726520616e642067696d626c6520696e2074686520776162653a0a416c6c206d696d737920776572652074686520626f726f676f7665732c0a416e6420746865206d6f6d65207261746873206f757467726162652e:
+4541669a7eaaee61e708dc7cbcc5eb62:
+
+# Test Vector #5: If one uses 130-bit partial reduction, does the code
+# handle the case where partially reduced final result is not fully
+# reduced?
+0200000000000000000000000000000000000000000000000000000000000000:
+FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF:
+03000000000000000000000000000000:
+
+# Test Vector #6: What happens if addition of s overflows modulo 2^128?
+02000000000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF:
+02000000000000000000000000000000:
+03000000000000000000000000000000:
+
+# Test Vector #7: What happens if data limb is all ones and there is
+# carry from lower limb?
+0100000000000000000000000000000000000000000000000000000000000000:
+FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF11000000000000000000000000000000:
+05000000000000000000000000000000:
+
+# Test Vector #8: What happens if final result from polynomial part is
+# exactly 2^130-5?
+0100000000000000000000000000000000000000000000000000000000000000:
+FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBFEFEFEFEFEFEFEFEFEFEFEFEFEFEFE01010101010101010101010101010101:
+00000000000000000000000000000000:
+
+# Test Vector #9: What happens if final result from polynomial part is
+# exactly 2^130-6?
+0200000000000000000000000000000000000000000000000000000000000000:
+FDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF:
+FAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF:
+
+# Test Vector #10: What happens if 5*H+L-type reduction produces
+# 131-bit intermediate result?
+0100000000000000040000000000000000000000000000000000000000000000:
+E33594D7505E43B900000000000000003394D7505E4379CD01000000000000000000000000000000000000000000000001000000000000000000000000000000:
+14000000000000005500000000000000:
+
+# Test Vector #11: What happens if 5*H+L-type reduction produces
+# 131-bit final result?
+0100000000000000040000000000000000000000000000000000000000000000:
+E33594D7505E43B900000000000000003394D7505E4379CD010000000000000000000000000000000000000000000000:
+13000000000000000000000000000000:
diff --git a/lib/Utils.Cryptography/monocypher/vendor/tests/gen/vectors/sha512_hmac b/lib/Utils.Cryptography/monocypher/vendor/tests/gen/vectors/sha512_hmac
new file mode 100644
index 0000000..53f742c
--- /dev/null
+++ b/lib/Utils.Cryptography/monocypher/vendor/tests/gen/vectors/sha512_hmac
@@ -0,0 +1,155 @@
+0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b:
+4869205468657265:
+87aa7cdea5ef619d4ff0b4241a1d6cb02379f4e2ce4ec2787ad0b30545e17cdedaa833b7d6b8a702038b274eaea3f4e4be9d914eeb61f1702e696c203a126854:
+
+4a656665:
+7768617420646f2079612077616e7420666f72206e6f7468696e673f:
+164b7a7bfcf819e2e395fbe73b56e0a387bd64222e831fd610270cd7ea2505549758bf75c05a994a6d034f65f8f0e6fdcaeab1a34d4a6b4b636e070a38bce737:
+
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa:
+dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd:
+fa73b0089d56a284efb0f0756c890be9b1b5dbdd8ee81a3655f83e33b2279d39bf3e848279a722c806b485a47e67c807b946a337bee8942674278859e13292fb:
+
+0102030405060708090a0b0c0d0e0f10111213141516171819:
+cdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcd:
+b0ba465637458c6990e5a8c5f61d4af7e576d97ff94b872de76f8050361ee3dba91ca5c11aa25eb4d679275cc5788063a5f19741120c4f2de2adebeb10a298dd:
+
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa:
+54657374205573696e67204c6172676572205468616e20426c6f636b2d53697a65204b6579202d2048617368204b6579204669727374:
+80b24263c7c1a3ebb71493c1dd7be8b49b46d1f41b4aeec1121b013783f8f3526b56d037e05f2598bd0fd2215d6a1e5295e64f73f63f0aec8b915a985d786598:
+
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa:
+5468697320697320612074657374207573696e672061206c6172676572207468616e20626c6f636b2d73697a65206b657920616e642061206c6172676572207468616e20626c6f636b2d73697a6520646174612e20546865206b6579206e6565647320746f20626520686173686564206265666f7265206265696e6720757365642062792074686520484d414320616c676f726974686d2e:
+e37b6a775dc87dbaa4dfa9f96e5e3ffddebd71f8867289865df5a32d20cdc944b6022cac3c4982b10d5eeb55c3e4de15134676fb6de0446065c97440fa8c6a58:
+
+5365244bb43f23f18dfc86c09d62db4741138bec1fbddc282d295e0a098eb5c3e37bd6f4cc16d5ce7d77b1d474a1eb4db313cc0c24e48992ac125196549df9a8:
+:
+d0a556bd1afa8df1ebf9e3ee683a8a2450a7c83eba2daf2e2ff2f953f0cd64da216e67134cf55578b205c8a1e241ba1369516a5ef4298b9c1d31e9d59fc04fe4:
+
+00698977f7102c67b594166919aa99dc3e58c7b6697a6422e238d04d2f57b2c74e4e84f5c4c6b792952df72f1c09244802f0bcf8752efb90e836110703bfa21c:
+01:
+4d1609cc2c2f1ab5ddc35815ae1b5dc046f226bde17ec37a4c89ec46fbd31af2aeb810b196dffdd11924d3772bef26a7a542e0a1673b76b915d41cbd3df0f6a6:
+
+ed6dc65dbeaadbdaab530a0d35f19f78a7bd93e698546c82751bf650c2a44fc8529033d088febeed288fb4c8132a59df0207687640c76dcdb270ac3af5f042f1:
+a78f:
+0757b27e120559d64cd3d6e3cb40d497845375815181bd9b4e74f2189d09d01a1b3ead53701380d988958ed22bc379ace9d47cbcac1d49bfa7e14f1f44804c30:
+
+463c5e696da0ec0d784388be775d1d91d94746aa8d3d2c209f56ac95ea54e7288329f9fb40be4eef35547e64c61dc51a4a1f3380a2b96420f088655ea9d85b97:
+e956c1:
+ac4b1509391814ae5cb5a123e7a060601575c11d81b563bdc52febe6bb2c747b85eeddcb6748c98147a46a1cc9be6776d1a8e82ae4896b9c18da2ff351c56795:
+
+4bc0d32e945cfdafd20d39be3820f9649727cbda5ab5859953a322cbde1ab7a514d7dcd14ba90905e70919bb86b85cfeaa375ee2ce2703711b938c8f4ab5f178:
+b2aa48b3:
+c4ecdbd2efb17640ce6707e2e9d0ee5bfb98b91584bc86ab386437eaa37b0f2eb70500361105416c0dcecff389dc94c723fcff18cb801740962312007a195a23:
+
+aca47f6350941a0efd8c3bac9064a554be337cde7d192f6fbf86d1b4db09b36531165cbae0a634206f71fa400df33352fff60e1fba4009ac6671cd37312bdd98:
+bc993b1db0:
+89af2f5746cab89fda6993e00f1bf0cc70a77188945bb7b5409b536aec5533ad501db6ecfa3e516b580b7df9c8eadb3cf556ccc01668be984335bd5a6255d566:
+
+b3ecae6f25c2f699f158b3ffcd0a7a575583e4c9cb56b5c22ef4273cde6c6734e84d7400749c17e47e8cfccafaf8b50c65eb47dfeb273d5d30a1181e37b27ad0:
+f0361d58291e:
+4037a57aa279b5a07abe9389dcf508be9495a8257dcb3feba3f0801cd57574c30bfddc6df5df6567cd572c4e82735fd4e67b65e85b030f183a7f4457fb7d2c3d:
+
+70ff24a252d65183bdc6b7c88751f850821141a61246727c3240b4f96088ae3278767a822b65735a28ccebe4c874bcb2c942882cb23f9dd87fe08fbaad5ae72f:
+e18da3ebf0ffa4:
+878d488754bc796c70e11d5db77acda2e1796d86146e27d862586740c4d488ed12239e6fb4ab2925afc88168609edc048f8572536fae96e149d73d230b18db66:
+
+dd4e05933d09711ee88cb4c1ceb3600b2b33808bc08d499387b331d9c7af49bc65b55172cf8083385a940e4b864b7b4b73ddf3bd513a6cbcac73878a879b4d06:
+66948029351432c3:
+9968a16eff2b4eeecb2f9d11fcb105e8d8ca59ed4e69131c9de599cd8155fa4f33def1195a6b452263aad9265e16d4951841d7cd33c74c475da04497c02922ea:
+
+fbd32caf8984fc4376d10daa7288db8e6e74464bdd94b448adab4497b319e9a6dcce542f82a7ff2e775d12477c880e460a9eab8efc49fcfc8c5476cb4b08954a:
+38a2586a2883953cc4:
+e0c69bd034cdec5b48150fdf3a4383456a7626d4405df52dc6c2bc8fe93bd87e369e06a781ed80ba8b1fe1146c4df82b6a514412358b31b77b9b79c7a91ec9e4:
+
+fd4c3f6b2137513616c28ed4d8638f867ad0b97188b73fc9b36f3d52b82d72a49b9dc1b8b25397eb448054a8d38d838e7a88b4df9c263aea1b968771d5ac5756:
+86b4e61b3b7d650044ad:
+29345d7da44e2f228e8d502e29fb655da3676a481f9947c8482502ce070b3da5065589d84c02a05cd774b4bd5a15b668c59bafc192695aec43e5df3a82301745:
+
+f95baea535f477d22b405c67d927f59a9e042c46297a1681bcc16fdbe1b2cd59675a221351a78075981e7eb4998066768801cbd7a85231114d7f27f9bdf24899:
+5a34dee4e0982d458efffb:
+63867bb3e82bd4a5f715b3dd67ba3625666e458c5e3d75804709f80b6dde6f774ea223ba9e2536c60ab636dd12d07b217234a490ea9cae4fe673215d33f8c57a:
+
+4d76ae95a123207e01c6d22d8b587e63ba682963e50961afff531160a9b9aac6c772c5e8bf918ddecbeb56455ea64710e51ac21e3bb9af4b24eaa8535b3c2924:
+2c31f2d986f68a6d6a96c4b0:
+9d4f9549ac134a6f60f17fd0fbc80f55426afa73cdaf84a806d98dfffc94263178116f76aadca95a9243a9128f5f66d3e7f33e72603d4b35ab90ab7d1e870ad7:
+
+0da7fa1f5d217951e3e343cda81f232deb71764eb49e8510bc28dba8eb62afa2a98b6f0536adb10250c74878fe649f47bbafdf3f722fa150f66e83f65f606ab0:
+83511de190663c9c4229ace901:
+11bd76ba2fd5684e3faadd44abc05d32661472ae4c75fd69e62e47a2d462e483ab5fd374070e648017250934d486fed55e68f4338547fb5dc54d4bed894c1c2f:
+
+cec9e9f25ed9a017004a7882b1e44e8bd8fa3203c50cb6058455ed4f2a036788d46fcd328327d0d86b1abae69f7bbb96e3d66373ec8bd45075890879a83f4d33:
+80dcd8ba66f98b51094144e9b8bd:
+c69f1787bf7804bfffd9da7e62f58c1c9f599ccae2ed4fc6abda1be48620afc797d59d4adb396e1fa5d18b8c1aa1c7c15218a9f9e3aab226119adad742641089:
+
+bbe25649ecdf54ae0028fb923cc8c28ec00e10e2d44214590781238a143b75d54efb037eb9f53082a8ab3d8876daf4dbdc2483c4ba222797fe20da3b7730368b:
+33f630088c0d24cda98caff1a3afc7:
+c803ca833e851418a3d9ed764f8c83f481060141eb1b2bf64d7ee7991b041c48bfc747bce13d69722f63944085cef8e7a166270530fe31a2a525a99b8a75f1b1:
+
+f5e2b9e2313f4f807cb3a924a7d4943fc3fb475d8f1a1b40ce09a37770f621af8977729cadf986c98c75f08a4fab4280538e09e7e51e87a8d62c03411bdb8d24:
+74ef623c83275ae99745bff7e6142afa:
+471055f7a2d44758e7d7837db85c33626b8306760eb45e18d4ba8dfbcd0d4279fcf8b539ef7b165eeabf5457ee2c41e52d07e9121da02c988f08162f86bdf208:
+
+8e323d5fb4752d92a6d905c512b287d07b21ae50002d026ff0388e1593bde9998dd02321e200d148f5fa2e824b37e9f5a77441794b840bedd552d1051c1ddd8c:
+4daa229b009b8984354c2ec3e7973e0042:
+93a2137cc84e2fa1439d7c239767b3ce653d634c58a4590eb61af9d3ef986445220aff3554de45a1b0933fa06d3d64460418910977d8d9ddb2eb04963c816841:
+
+465bc1ab2125cca29729d01df044e393b0677defdd939280a3aa141224efa06457e623056d02f6c36eca3dfc4a7476dd36b97d0c2d60c7672129189e73b6af8f:
+dd84599b47ba9ae9f2ad0c8eac678485433eb6b1dfb7c998:
+9fff43a83c71833211f9d60eeef4166965c41a37c76634b1bdf9c5291df75dc877668f2287bcf8108ea9e03d061a708db2db08687eda61fa97b1ca92dcf22b92:
+
+b90226798dff2ffb91d1ee4103f26397d0bf84c13c1ec717392c5fe1d4d0f4dc790236d759fa1be852e305da585a3dbde0d3912bea60d6b140c25645eb00943f:
+aa29c372f136993c65ace5e1d62078806eb787913bb35af33371056359d354b2:
+493a727536b07d434a7fc8df6b70989148a8d94cadb9761ad845ac5fde2068f9565e68607b531b0f307d7c17ce0a2ba69fb1ac1b0c716f93904eec75669e70b7:
+
+af1bb91775cb40c73983f119c927a2ce8f7b954a6274ecc1cd96019e5c417af4b094376194eae71c7f68f3345654d5d9f8198a697b41ae251e82308accd935bd:
+75ededdfa7f1df1dc144fb195b27e454640e3f897cb564222f05e8aab0c6024f90472afea6e7254ed25134ea43452a:
+b53d564086a745b10d88a48b50ed8b53f4c83fd12bf56a75108074de9b343cdf0668ce8b6a3d884ba2da5f4c957f1319e26c0813c99a4269c171ad80981013a2:
+
+513e0e7622eabcb6bfc81669dac903df46daea1240f32248bbf4fc61f1f9b13b2c3fe1bcc97540d30065be9eee41e51748bc42c16a8c8269fbe2b6f625c19228:
+81d8650937f50871a66af71605ea4fa9d6c5d7a375774c2280eb34aefcee8c0ef83345bc547e4de7cbea482369b25a93:
+9d942e4585742ba118bda6e132510af3b9297047d364f76b2a0d1fc803849b06ccac0eaa427934055c9d2e5a5da19cf17299ffdab65089580d10ff7207c9ed03:
+
+627c9a72247d07b0cec8346277468311c7401fc4cecaea8e22e13ece4b352c8f7a7eb1ba81ce348a08670438c97b8d9e883614d550f1ff16d636975c59988c2d:
+118e0468cbb52f93a3396ebfaa114881a98a4101f4ff912ced47ecfc73b27f52205b7a5d4f3899506f9e34ebf99460da7a:
+a186e08c7731d4bbb1d5342a105ef48f5353c5c542277de607831fcbbc8d0b9fd509c74bf9e352ee739792ee3cd6382f96e70adb589fdf1fb031d43eef1a595f:
+
+1e981d0cbbad5bea9480d836b4704bf3147663b6ea59e1e0a280fb45d9b85d445dc972159dde301c6f1e66681f95642dbb9a9218c00d0cd724cb02f3bcaea2ea:
+440dff390688c9fde31c17fdb61c1d13899f9544a986324c34d5eb07bef9a4436297f4a7fe16de5dd7b24e0c7c129051efe6f2dd0a21aec05c3e3c8f6fa30d9c0cbd60d840d14f0b2a928bc7189b9de4a6a731151d6b31e6a0ecae75095434737be8c3db11a6a697d0616c78b97041de:
+c52eb5d18e90687248342a84dc0241c680e992b88b1409275df7e347c99169a50cd780eb4726ad759e2a027fb091354e3d7c7aba8a21f8acd1d0e21236af5f98:
+
+ee8aea2a52eb7e0c1120ab736b1a825b12610063de9642c594766c020cb87314d8ac94b13072bfbf3c019b4aacb1d2695cdd7563a26f574e12559906784d853c:
+a3951f1d18135602fdadceeef5741c24ad22756160d0c55e51b788af952adaeb13e18c24c6b09672f405d7ec3d49b0bd86c7f8691b6f69af49175423215cf57d7c08a54ab0b0293e685c9aa250f1599d78193a00af822dec4b56fdb41f0343ab2cf85ea27bb2e650930f5e8ca836833903b053b3e06899b4012a6532978d90:
+d3678ca7c5c1aa21f12eccc21a1add0b3eb12ccd134033570468191e51b058c61f2a7d88f2ca6c652c29c65c491bf1f0252bc157bdd77436ff55204eac6dfb0d:
+
+ecd1861a12eaee48aef1d7ed278223b50d3416dbff81e976c56ecd4b1a1bc8892b584cbcc72370ff5e976a6af1790caa32f9ea912855914c0315979578fbf165:
+5779c56373a8e5db43bd65c0453ce23144230d43666d717a3b59d2e90f0e10732376831d7281cb23dd5566e5f8c627d00d39650139ceb87cd47e921d65d6c1cc7712ac4bd75bda8828e68abc968f4160ed91b28946c9d706b0360bbbdd65f47ef9983c50f2d09d05c3674c0943ea4af54c381089f9b846dd69ce908e0f6eaaaf:
+d377e4efc39f25ca751452e79dcb5661f8adcc06570bd3f710e03854e032286ca477e6a620647958fd31706463b542ddf617757875f349c61109358d04f6dc58:
+
+71aadbf330ea133b46c939d12e603896902e8df638597c98872dfb5aecd5161bc84095221de3222367012f45c6d70701e862ab000e782e91b505b21b4e212c38:
+e6d7b0280d2f7df83fd26562fcdea2597cf687a9c9fa194f655c44d3271b881f28adc436db8e0437ff4dc5d38356271c338829c3e2d9ba4ac1777c94886983d4b72c275bc00e4f7b06c5ce38a2fe549fe53761857f236da705fd03790b41cc6f759f41aa206feca7ba5486f4fc9d09f35c8e0887241291882010414ae41b8b384a715a409be13da17bfd60d3fbd4b8cb3cc7c26043807264a20b9a5c02725e742fff03e1806b38af357ebf8c79fc4c38b007bf0613286cf063e45482375475e6c426d4f70057cd92efcb2dfe86e45bdea399273a5e0f142221fae206800555c01b18533295f577e23a9a7a0aa072823002b9096501174d3bc4aac33e0dc600:
+0c1cbb2f196d3d1af5f982a330bf1d9accaada72cf6c254658cb32bfd8705481abd2e163a73338700f0d961ca02a31b600df04faf311cd06498557831102f80f:
+
+14d93759fc28f3319ab74b8167c974e800f032344dc2747ec0f4945061a47827:
+:
+68934dbe948d9a77a5e0a92ed98254fa3b6c93c8bf5eeaa912b7dfdf762b37192c5d8523bcab9ad71b09bf96d8454188d001c7f2077eb641199f5731b9f94669:
+
+9fa371f36fb273d514fd628cb938067a4bae32a19a1e045a7d6d7f6de3751cbf:
+311bbf722d322cd7a0710f480fc66518:
+16345f6a6ca6e78d4ccac30b48d76691d6442420efa113c15ef127b538b5b024018b7d2db4bc3ed3424251ab6b8b6c3cb108b0beda842dc3e68e63400287e5cd:
+
+6313f1526bc220f20dde1e64ced8597279586d1e15aad05ad591d841b369284f:
+f744fa3933e16d8bf524afaeb34c715653a9cfb01fa45fe1fb68e701fe1487ca:
+b88d1ba03e2799200a447550d18e310697a57974f513df77eb07bbe315ba5fef397eeb81ad9071680bcc6c70f6b252ade35b4a4040279ec01b86e40b98770e39:
+
+dd1e0bdbb6b60862176484f3669da531455f1cd714f999c29f08b851055fee8d72186d376c236f4e16cba7a25cba879fb2753deca4459aaebc6f6de625d99af330:
+:
+7e4f7d844b3ba0e025b66de7cc6227bc50d4e174930251bfff3df36c3900b5b76b00095a896d0f96842e37b6134df40760307699534d6670f138974ee1c58d94:
+
+432b311ebcfd46ecfcd3cc706ebd05c787dfbe1855fdcfce8d50c9a00f72b65a8d42acec335b4e07d544c92fd7b1d38543ac6e0fc04c26d88de8dd974af69e24d7:
+36b1fbe8f1335e7c0399c24730906420:
+2cfb688f30b10534da9377a4b3fbee1dec161cb288ac8b758793838b45ab953979dadf27817f477c9ebf23cfdcbacb60b81038e08bc4fc3180bd2a1ee805976a:
+
+17f720f09df5972af9b9c63e10043284608900d50b7955db3b4e2679cb4120be2c9b9e2aa1a5743eb519792822c326b4d890b5554d1cb0eb71081b7569a2f04df7:
+57167c2524a55289687b83a40d3a69bc90adc53ad247020b88897f9b95d1516d:
+4f70267b98fceb4f662901bd18fb4c81ac164281dd0ece43028a3c2a65ca213aedf1bd207f0939bd879bbe20fd09cdeb20246e6539766add08b3adc5143d2bd9:
diff --git a/lib/Utils.Cryptography/monocypher/vendor/tests/gen/vectors/x25519 b/lib/Utils.Cryptography/monocypher/vendor/tests/gen/vectors/x25519
new file mode 100644
index 0000000..4e2cb17
--- /dev/null
+++ b/lib/Utils.Cryptography/monocypher/vendor/tests/gen/vectors/x25519
@@ -0,0 +1,3168 @@
+# X25519 test vectors
+
+
+# Random tests I don't quite remember come from
+a546e36bf0527c9d3b16154b82465edd62144c0ac1fc5a18506a2244ba449ac4:
+e6db6867583030db3594c1a424b15f7c726624ec26b3353b10a903a6d0ab1c4c:
+c3da55379de9c6908e94ea4df28d084f32eccf03491c71f754b4075577a28552:
+
+4b66e9d4d1b4673c5ad22691957d6af5c11b6421e0ea01d42ca4169e7918ba0d:
+e5210f12786811d3f4b7959d0538ae2c31dbe7106fc03c3efc4cd549c715a493:
+95cbde9476e8907d7aade45cb4b873f88b595a68799fa152e6f8f7647aac7957:
+
+77076d0a7318a57d3c16c17251b26645df4c2f87ebc0992ab177fba51db92c2a:
+de9edb7d7b7dc1b4d35b61c2ece435373f8343c85b78674dadfc7e146f882b4f:
+4a5d9d5ba4ce2de1728e3bf480350f25e07e21c947d19e3376f09b3c1e161742:
+
+5dab087e624a8a4b79e17f8b83800ee66f3bb1292618b6fd1c2f8b27ff88e0eb:
+8520f0098930a754748b7ddcb43ef75a0dbf3a0d26381af4eba4a98eaa9b4e6a:
+4a5d9d5ba4ce2de1728e3bf480350f25e07e21c947d19e3376f09b3c1e161742:
+
+#
+# First iteration of the iterated scalarmult test
+#
+0900000000000000000000000000000000000000000000000000000000000000:
+0900000000000000000000000000000000000000000000000000000000000000:
+422c8e7a6227d7bca1350b3e2bb7279f7897b87bb6854b783c60e80311ae3079:
+
+
+# Daniel Bleichenbacher test vectors from Wycheproof:
+# https://github.com/google/wycheproof/blob/master/testvectors/x25519_test.json
+#
+# Notes:
+#
+# - LowOrderPublic: The curves and its twists contain some points of low
+# order. This test vector contains a public key with such a
+# point. While many libraries reject such public keys, doing so is not
+# a strict requirement according to RFC 7748.
+#
+# - NonCanonicalPublic: The public key is in non-canonical form. RFC
+# 7749, section 5 defines the value that this public key
+# represents. Section 7 of the same RFC recommends accepting such
+# keys. If a non-canonical key is accepted then it must follow the
+# RFC.
+#
+# - SmallPublicKey: The public key is insecure and does not belong to a
+# valid private key. Some libraries reject such keys.
+# (Note from Monocypher: we accept all keys).
+#
+# - Twist: Public keys are either points on a given curve or points on
+# its twist. The functions X25519 and X448 are defined for points on a
+# twist with the goal that the output of computations do not leak
+# private keys. Implementations may accept or reject points on a
+# twist. If a point multiplication is performed then it is important
+# that the result is correct, since otherwise attacks with invalid
+# keys are possible.
+#
+# - ZeroSharedSecret: Some libraries include a check that the shared
+# secret is not all-zero. This check is described in Section 6.1 of
+# RFC 7748.
+# (Note from Monocypher: we do not, user must check manually.)
+
+# normal case
+# valid
+c8a9d5a91091ad851c668b0736c1c9a02936c0d3ad62670858088047ba057475:
+504a36999f489cd2fdbc08baff3d88fa00569ba986cba22548ffde80f9806829:
+436a2c040cf45fea9b29a0cb81b1f41458f863d0d61b453d0a982720d6d61320:
+
+# public key on twist
+# acceptable: Twist
+d85d8c061a50804ac488ad774ac716c3f5ba714b2712e048491379a500211958:
+63aa40c6e38346c5caf23a6df0a5e6c80889a08647e551b3563449befcfc9733:
+279df67a7c4611db4708a0e8282b195e5ac0ed6f4b2f292c6fbd0acac30d1332:
+
+# public key on twist
+# acceptable: Twist
+c8b45bfd32e55325d9fd648cb302848039000b390e44d521e58aab3b29a6964b:
+0f83c36fded9d32fadf4efa3ae93a90bb5cfa66893bc412c43fa7287dbb99779:
+4bc7e01e7d83d6cf67632bf90033487a5fc29eba5328890ea7b1026d23b9a45f:
+
+# public key on twist
+# acceptable: Twist
+f876e34bcbe1f47fbc0fddfd7c1e1aa53d57bfe0f66d243067b424bb6210be51:
+0b8211a2b6049097f6871c6c052d3c5fc1ba17da9e32ae458403b05bb283092a:
+119d37ed4b109cbd6418b1f28dea83c836c844715cdf98a3a8c362191debd514:
+
+# public key on twist
+# acceptable: Twist
+006ac1f3a653a4cdb1d37bba94738f8b957a57beb24d646e994dc29a276aad45:
+343ac20a3b9c6a27b1008176509ad30735856ec1c8d8fcae13912d08d152f46c:
+cc4873aed3fcee4b3aaea7f0d20716b4276359081f634b7bea4b705bfc8a4d3e:
+
+# public key on twist
+# acceptable: Twist
+08da77b26d06dff9d9f7fd4c5b3769f8cdd5b30516a5ab806be324ff3eb69e60:
+fa695fc7be8d1be5bf704898f388c452bafdd3b8eae805f8681a8d15c2d4e142:
+b6f8e2fcb1affc79e2ff798319b2701139b95ad6dd07f05cbac78bd83edfd92e:
+
+# public key on twist
+# acceptable: Twist
+d03edde9f3e7b799045f9ac3793d4a9277dadeadc41bec0290f81f744f73775f:
+0200000000000000000000000000000000000000000000000000000000000000:
+b87a1722cc6c1e2feecb54e97abd5a22acc27616f78f6e315fd2b73d9f221e57:
+
+# public key on twist
+# acceptable: Twist
+e09d57a914e3c29036fd9a442ba526b5cdcdf28216153e636c10677acab6bd6a:
+0300000000000000000000000000000000000000000000000000000000000000:
+a29d8dad28d590cd3017aa97a4761f851bf1d3672b042a4256a45881e2ad9035:
+
+# public key on twist
+# acceptable: Twist
+e0ed78e6ee02f08bec1c15d66fbbe5b83ffc37ea14e1512cc1bd4b2ea6d8066f:
+ff00000000000000000000000000000000000000000000000000000000000000:
+e703bc8aa94b7d87ba34e2678353d12cdaaa1a97b5ca3e1b8c060c4636087f07:
+
+# public key on twist
+# acceptable: Twist
+a8a1a2ec9fa9915ae7aace6a37c68591d39e15995c4ef5ebd3561c02f72dda41:
+ffff000000000000000000000000000000000000000000000000000000000000:
+ff5cf041e924dbe1a64ac9bdba96bdcdfaf7d59d91c7e33e76ed0e4c8c836446:
+
+# public key on twist
+# acceptable: Twist
+a8c9df5820eb399d471dfa3215d96055b3c7d0f4ea49f8ab028d6a6e3194517b:
+0000010000000000000000000000000000000000000000000000000000000000:
+a92a96fa029960f9530e6fe37e2429cd113be4d8f3f4431f8546e6c76351475d:
+
+# public key on twist
+# acceptable: Twist
+d0d31c491cbd39271859b4a63a316826507b1db8c701709fd0ffe3eb21c4467c:
+ffffff0f00000000000000000000000000000000000000000000000000000000:
+9f8954868158ec62b6b586b8cae1d67d1b9f4c03d5b3ca0393cee71accc9ab65:
+
+# public key on twist
+# acceptable: Twist
+d053e7bf1902619cd61c9c739e09d54c4147f46d190720966f7de1d9cffbbd4e:
+ffffffff00000000000000000000000000000000000000000000000000000000:
+6cbf1dc9af97bc148513a18be4a257de1a3b065584df94e8b43c1ab89720b110:
+
+# public key on twist
+# acceptable: Twist
+a021d75009a4596e5a33f12921c10f3670933bc80dde3bba22881b6120582144:
+0000000000001000000000000000000000000000000000000000000000000000:
+38284b7086095a9406028c1f800c071ea106039ad7a1d7f82fe00906fd90594b:
+
+# public key on twist
+# acceptable: Twist
+a89c6687f99bd569a01fd8bd438236160d15ce2c57c1d71ebaa3f2da88233863:
+0000000000000001000000000000000000000000000000000000000000000000:
+c721041df0244071794a8db06b9f7eaeec690c257265343666f4416f4166840f:
+
+# public key on twist
+# acceptable: Twist
+68964bca51465bf0f5ba524b1482ceff0e960a1ed9f48dcc30f1608d0e501a50:
+ffffffffffffffff000000000000000000000000000000000000000000000000:
+25ff9a6631b143dbdbdc207b38e38f832ae079a52a618c534322e77345fd9049:
+
+# public key on twist
+# acceptable: Twist
+a8e56bb13a9f2b33b8e6750b4a6e6621dc26ae8c5c624a0992c8f0d5b910f170:
+0000000000000000000000000000000000000000000000000100000000000000:
+f294e7922c6cea587aefe72911630d50f2456a2ba7f21207d57f1ecce04f6213:
+
+# public key on twist
+# acceptable: Twist
+e045f55c159451e97814d747050fd7769bd478434a01876a56e553f66384a74c:
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffff00000000:
+ff4715bd8cf847b77c244ce2d9b008b19efaa8e845feb85ce4889b5b2c6a4b4d:
+
+# public key on twist
+# acceptable: Twist
+105d621e1ef339c3d99245cfb77cd3a5bd0c4427a0e4d8752c3b51f045889b4f:
+ffffff030000f8ffff1f0000c0ffffff000000feffff070000f0ffff3f000000:
+61eace52da5f5ecefafa4f199b077ff64f2e3d2a6ece6f8ec0497826b212ef5f:
+
+# public key on twist
+# acceptable: Twist
+d88a441e706f606ae7f630f8b21f3c2554739e3e549f804118c03771f608017b:
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f0000:
+ff1b509a0a1a54726086f1e1c0acf040ab463a2a542e5d54e92c6df8126cf636:
+
+# public key on twist
+# acceptable: Twist
+80bbad168222276200aafd36f7f25fdc025632d8bf9f6354bb762e06fb63e250:
+0000000000000000000000000000000000000000000000000000000000800000:
+f134e6267bf93903085117b99932cc0c7ba26f25fca12102a26d7533d9c4272a:
+
+# public key on twist
+# acceptable: Twist
+68e134092e94e622c8a0cd18aff55be23dabd994ebdee982d90601f6f0f4b369:
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1f:
+74bfc15e5597e9f5193f941e10a5c008fc89f051392723886a4a8fe5093a7354:
+
+# public key on twist
+# acceptable: Twist
+e8e43fc1ebac0bbc9b99c8035ee1ac59b90f19a16c42c0b90f96adfcc5fdee78:
+0000000000000000000000000000000000000000000000000000000000000020:
+0d41a5b3af770bf2fcd34ff7972243a0e2cf4d34f2046a144581ae1ec68df03b:
+
+# public key on twist
+# acceptable: Twist
+18bffb16f92680a9e267473e43c464476d5372ddd1f664f3d0678efe7c98bc79:
+000000fcffff070000e0ffff3f000000ffffff010000f8ffff0f0000c0ffff7f:
+5894e0963583ae14a0b80420894167f4b759c8d2eb9b69cb675543f66510f646:
+
+# public key on twist
+# acceptable: Twist
+300305eb002bf86c71fe9c0b311993727b9dc618d0ce7251d0dfd8552d17905d:
+ffffffffffffff00000000000000ffffffffffffff00000000000000ffffff7f:
+f8624d6e35e6c548ac47832f2e5d151a8e53b9290363b28d2ab8d84ab7cb6a72:
+
+# public key on twist
+# acceptable: Twist
+80da9f02842247d4ade5ddbac51dbce55ea7dca2844e7f97ab8987ce7fd8bc71:
+00000000ffffffff00000000ffffffff00000000ffffffff00000000ffffff7f:
+bfe183ba3d4157a7b53ef178613db619e27800f85359c0b39a9fd6e32152c208:
+
+# public key on twist
+# acceptable: Twist
+806e7f26ca3246de8182946cbed09f52b95da626c823c7b50450001a47b7b252:
+edfffffffffffffffffffffffffffeffffffffffffffffffffffffffffffff7f:
+bca4a0724f5c1feb184078448c898c8620e7caf81f64cca746f557dff2498859:
+
+# public key on twist
+# acceptable: Twist
+58354fd64bc022cba3a71b2ae64281e4ea7bf6d65fdbaead1440eeb18604fe62:
+edfffffffffffffeffffffffffffffffffffffffffffffffffffffffffffff7f:
+b3418a52464c15ab0cacbbd43887a1199206d59229ced49202300638d7a40f04:
+
+# public key on twist
+# acceptable: Twist
+f0019cf05159794cc8052b00c2e75b7f46fb6693c4b38c02b12a4fe272e8556a:
+edffffffffffefffffffffffffffffffffffffffffffffffffffffffffffff7f:
+fcde6e0a3d5fd5b63f10c2d3aad4efa05196f26bc0cb26fd6d9d3bd015eaa74f:
+
+# public key on twist
+# acceptable: Twist
+d0fca64cc5f3a0c8e75c824e8b09d1615aa79aeba139bb7302e2bb2fcbe54b40:
+edfeffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f:
+7d62f189444c6231a48afab10a0af2eee4a52e431ea05ff781d616af2114672f:
+
+# public key on twist
+# acceptable: Twist
+d02456e456911d3c6cd054933199807732dfdc958642ad1aebe900c793bef24a:
+eaffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f:
+07ba5fcbda21a9a17845c401492b10e6de0a168d5c94b606694c11bac39bea41:
+
+# public key = 0
+# acceptable: SmallPublicKey, LowOrderPublic, ZeroSharedSecret
+88227494038f2bb811d47805bcdf04a2ac585ada7f2f23389bfd4658f9ddd45e:
+0000000000000000000000000000000000000000000000000000000000000000:
+0000000000000000000000000000000000000000000000000000000000000000:
+
+# public key = 1
+# acceptable: SmallPublicKey, LowOrderPublic, ZeroSharedSecret
+48232e8972b61c7e61930eb9450b5070eae1c670475685541f0476217e48184f:
+0100000000000000000000000000000000000000000000000000000000000000:
+0000000000000000000000000000000000000000000000000000000000000000:
+
+# edge case public key
+# valid
+a8386f7f16c50731d64f82e6a170b142a4e34f31fd7768fcb8902925e7d1e25a:
+0400000000000000000000000000000000000000000000000000000000000000:
+34b7e4fa53264420d9f943d15513902342b386b172a0b0b7c8b8f2dd3d669f59:
+
+# edge case public key
+# valid
+d05abd08bf5e62538cb9a5ed105dbedd6de38d07940085072b4311c2678ed77d:
+0001000000000000000000000000000000000000000000000000000000000000:
+3aa227a30781ed746bd4b3365e5f61461b844d09410c70570abd0d75574dfc77:
+
+# edge case public key
+# valid
+f0b8b0998c8394364d7dcb25a3885e571374f91615275440db0645ee7c0a6f6b:
+0000001000000000000000000000000000000000000000000000000000000000:
+97755e7e775789184e176847ffbc2f8ef98799d46a709c6a1c0ffd29081d7039:
+
+# edge case public key
+# valid
+d00c35dc17460f360bfae7b94647bc4e9a7ad9ce82abeadb50a2f1a0736e2175:
+0000000001000000000000000000000000000000000000000000000000000000:
+c212bfceb91f8588d46cd94684c2c9ee0734087796dc0a9f3404ff534012123d:
+
+# edge case public key
+# valid
+385fc8058900a85021dd92425d2fb39a62d4e23aef1d5104c4c2d88712d39e4d:
+ffffffffffff0f00000000000000000000000000000000000000000000000000:
+388faffb4a85d06702ba3e479c6b216a8f33efce0542979bf129d860f93b9f02:
+
+# edge case public key
+# valid
+e0614b0c408af24d9d24c0a72f9137fbd6b16f02ccc94797ea3971ab16073a7f:
+ffffffffffffff00000000000000000000000000000000000000000000000000:
+877fec0669d8c1a5c866641420eea9f6bd1dfd38d36a5d55a8c0ab2bf3105c68:
+
+# edge case public key
+# valid
+f004b8fd05d9fffd853cdc6d2266389b737e8dfc296ad00b5a69b2a9dcf72956:
+0000000000000000010000000000000000000000000000000000000000000000:
+180373ea0f23ea73447e5a90398a97d490b541c69320719d7dd733fb80d5480f:
+
+# edge case public key
+# valid
+e80bf0e609bf3b035b552f9db7e9ecbc44a04b7910b1493661a524f46c3c2277:
+ffffffffffffffffffffffffffff000000000000000000000000000000000000:
+208142350af938aba52a156dce19d3c27ab1628729683cf4ef2667c3dc60cf38:
+
+# edge case public key
+# valid
+48890e95d1b03e603bcb51fdf6f296f1f1d10f5df10e00b8a25c9809f9aa1a54:
+0000000000000000000000000000010000000000000000000000000000000000:
+1c3263890f7a081cefe50cb92abd496582d90dcc2b9cb858bd286854aa6b0a7e:
+
+# edge case public key
+# valid
+a806f1e39b742615a7dde3b29415ed827c68f07d4a47a4d9595c40c7fccb9263:
+ffffffffffffffffffffffffffffffff00000000000000000000000000000000:
+56128e78d7c66f48e863e7e6f2caa9c0988fd439deac11d4aac9664083087f7a:
+
+# edge case public key
+# valid
+9899d5e265e1fc7c32345227d6699a6d6b5517cf33b43ab156ee20df4878794e:
+0000000000000000000000000000000001000000000000000000000000000000:
+30eca56f1f1c2e8ff780134e0e9382c5927d305d86b53477e9aeca79fc9ced05:
+
+# edge case public key
+# valid
+d842316e5476aeaee838204258a06f15de011ba40b9962705e7f6e889fe71f40:
+ffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000:
+cb21b7aa3f992ecfc92954849154b3af6b96a01f17bf21c612da748db38eb364:
+
+# edge case public key
+# valid
+a0933ee30512b25ee4e900aaa07f73e507a8ec53b53a44626e0f589af4e0356c:
+ffffffff00000000ffffffff00000000ffffffff00000000ffffffff00000000:
+c5caf8cabc36f086deaf1ab226434098c222abdf8acd3ce75c75e9debb271524:
+
+# edge case public key
+# valid
+38d6403e1377734cdce98285e820f256ad6b769d6b5612bcf42cf2b97945c073:
+0000000000000000000000000000000000000000000000000000000001000000:
+4d46052c7eabba215df8d91327e0c4610421d2d9129b1486d914c766cf104c27:
+
+# edge case public key
+# valid
+182191b7052e9cd630ef08007fc6b43bc7652913be6774e2fd271b71b962a641:
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff03:
+a0e0315175788362d4ebe05e6ac76d52d40187bd687492af05abc7ba7c70197d:
+
+# edge case public key
+# valid
+106221fe5694a710d6e147696c5d5b93d6887d584f24f228182ebe1b1d2db85d:
+ffffff0f000000ffffff0f000000ffffff0f000000ffffff0f000000ffffff0f:
+5e64924b91873b499a5402fa64337c65d4b2ed54beeb3fa5d7347809e43aef1c:
+
+# edge case public key
+# valid
+d035de9456080d85a912083b2e3c7ddd7971f786f25a96c5e782cf6f4376e362:
+000000fcffff030000e0ffff1f000000ffffff000000f8ffff070000c0ffff3f:
+c052466f9712d9ec4ef40f276bb7e6441c5434a83efd8e41d20ce83f2dbf5952:
+
+# edge case public key
+# valid
+a8f37318a4c760f3cb2d894822918735683cb1edacf3e666e15694154978fd6d:
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff3f:
+d151b97cba9c25d48e6d576338b97d53dd8b25e84f65f7a2091a17016317c553:
+
+# edge case public key
+# valid
+20d4d624cf732f826f09e8088017742f13f2da98f4dcf4b40519adb790cebf64:
+edffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff5f:
+5716296baf2b1a6b9cd15b23ba86829743d60b0396569be1d5b40014c06b477d:
+
+# edge case public key
+# valid
+d806a735d138efb3b404683c9d84485ab4af540d0af253b574323d8913003c66:
+edffffffffffffffffffffffffffffffffffffffffffffffffffffffff7fff7f:
+ddbd56d0454b794c1d1d4923f023a51f6f34ef3f4868e3d6659307c683c74126:
+
+# edge case public key
+# valid
+184198c6228177f3ef41dc9a341258f8181ae365fe9ec98d93639b0bbee1467d:
+fffffffffeffff7ffffffffffeffff7ffffffffffeffff7ffffffffffeffff7f:
+8039eebed1a4f3b811ea92102a6267d4da412370f3f0d6b70f1faaa2e8d5236d:
+
+# edge case public key
+# valid
+f0a46a7f4b989fe515edc441109346ba746ec1516896ec5b7e4f4d903064b463:
+edfffffffffffffffffffffffffffffffffffffffffffffffffffffffeffff7f:
+b69524e3955da23df6ad1a7cd38540047f50860f1c8fded9b1fdfcc9e812a035:
+
+# edge case public key
+# valid
+881874fda3a99c0f0216e1172fbd07ab1c7df78602cc6b11264e57aab5f23a49:
+edfffffffffffffffffffffffffffffffffffffffffffffffeffffffffffff7f:
+e417bb8854f3b4f70ecea557454c5c4e5f3804ae537960a8097b9f338410d757:
+
+# edge case public key
+# valid
+b8d0f1ae05a5072831443150e202ac6db00322cdf341f467e9f296588b04db72:
+edfffffffffffffffffffffffffffffffeffffffffffffffffffffffffffff7f:
+afca72bb8ef727b60c530c937a2f7d06bb39c39b903a7f4435b3f5d8fc1ca810:
+
+# edge case public key
+# valid
+c8619ba988859db7d6f20fbf3ffb8b113418cc278065b4e8bb6d4e5b3e7cb569:
+edfffffffffffffffeffffffffffffffffffffffffffffffffffffffffffff7f:
+7e41c2886fed4af04c1641a59af93802f25af0f9cba7a29ae72e2a92f35a1e5a:
+
+# edge case public key
+# valid
+f8d4ca1f37a30ec9acd6dbe5a6e150e5bc447d22b355d80ba002c5b05c26935d:
+edfffffffeffffffffffffffffffffffffffffffffffffffffffffffffffff7f:
+dd3abd4746bf4f2a0d93c02a7d19f76d921c090d07e6ea5abae7f28848355947:
+
+# edge case public key
+# valid
+88037ac8e33c72c2c51037c7c8c5288bba9265c82fd8c31796dd7ea5df9aaa4a:
+edffffefffffffffffffffffffffffffffffffffffffffffffffffffffffff7f:
+8c27b3bff8d3c1f6daf2d3b7b3479cf9ad2056e2002be247992a3b29de13a625:
+
+# edge case public key
+# valid
+5034ee7bf83a13d9167df86b0640294f3620f4f4d9030e5e293f9190824ae562:
+edfffeffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f:
+8e1d2207b47432f881677448b9d426a30de1a1f3fd38cad6f4b23dbdfe8a2901:
+
+# edge case public key
+# valid
+40bd4e1caf39d9def7663823502dad3e7d30eb6eb01e9b89516d4f2f45b7cd7f:
+ebffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f:
+2cf6974b0c070e3707bf92e721d3ea9de3db6f61ed810e0a23d72d433365f631:
+
+# public key with low order
+# acceptable: LowOrderPublic, ZeroSharedSecret
+e0f978dfcd3a8f1a5093418de54136a584c20b7b349afdf6c0520886f95b1272:
+e0eb7a7c3b41b8ae1656e3faf19fc46ada098deb9c32b1fd866205165f49b800:
+0000000000000000000000000000000000000000000000000000000000000000:
+
+# public key with low order
+# acceptable: LowOrderPublic, ZeroSharedSecret
+387355d995616090503aafad49da01fb3dc3eda962704eaee6b86f9e20c92579:
+5f9c95bca3508c24b1d0b1559c83ef5b04445cc4581c8e86d8224eddd09f1157:
+0000000000000000000000000000000000000000000000000000000000000000:
+
+# public key with low order
+# acceptable: LowOrderPublic, Twist, ZeroSharedSecret
+c8fe0df92ae68a03023fc0c9adb9557d31be7feed0d3ab36c558143daf4dbb40:
+ecffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f:
+0000000000000000000000000000000000000000000000000000000000000000:
+
+# public key with low order
+# acceptable: LowOrderPublic, NonCanonicalPublic, Twist, ZeroSharedSecret
+c8d74acde5934e64b9895d5ff7afbffd7f704f7dfccff7ac28fa62a1e6410347:
+e0eb7a7c3b41b8ae1656e3faf19fc46ada098deb9c32b1fd866205165f49b880:
+0000000000000000000000000000000000000000000000000000000000000000:
+
+# public key with low order
+# acceptable: LowOrderPublic, NonCanonicalPublic, Twist, ZeroSharedSecret
+b85649d5120e01e8ccaf7b2fb8d81b62e8ad6f3d5c0553fdde1906cb9d79c050:
+5f9c95bca3508c24b1d0b1559c83ef5b04445cc4581c8e86d8224eddd09f11d7:
+0000000000000000000000000000000000000000000000000000000000000000:
+
+# public key with low order
+# acceptable: LowOrderPublic, NonCanonicalPublic, ZeroSharedSecret
+2064b2f4c9dc97ec7cf58932fdfa3265ba6ea4d11f0259b8efc8afb35db88c48:
+ecffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff:
+0000000000000000000000000000000000000000000000000000000000000000:
+
+# public key with low order
+# acceptable: LowOrderPublic, ZeroSharedSecret
+786a33a4f7af297a20e7642925932bf509e7070fa1bc36986af1eb13f4f50b55:
+0000000000000000000000000000000000000000000000000000000000000000:
+0000000000000000000000000000000000000000000000000000000000000000:
+
+# public key with low order
+# acceptable: LowOrderPublic, ZeroSharedSecret
+786a33a4f7af297a20e7642925932bf509e7070fa1bc36986af1eb13f4f50b55:
+0100000000000000000000000000000000000000000000000000000000000000:
+0000000000000000000000000000000000000000000000000000000000000000:
+
+# public key with low order
+# acceptable: LowOrderPublic, ZeroSharedSecret
+786a33a4f7af297a20e7642925932bf509e7070fa1bc36986af1eb13f4f50b55:
+ecffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f:
+0000000000000000000000000000000000000000000000000000000000000000:
+
+# public key with low order
+# acceptable: LowOrderPublic, ZeroSharedSecret
+786a33a4f7af297a20e7642925932bf509e7070fa1bc36986af1eb13f4f50b55:
+5f9c95bca3508c24b1d0b1559c83ef5b04445cc4581c8e86d8224eddd09f1157:
+0000000000000000000000000000000000000000000000000000000000000000:
+
+# public key with low order
+# acceptable: LowOrderPublic, ZeroSharedSecret
+786a33a4f7af297a20e7642925932bf509e7070fa1bc36986af1eb13f4f50b55:
+e0eb7a7c3b41b8ae1656e3faf19fc46ada098deb9c32b1fd866205165f49b800:
+0000000000000000000000000000000000000000000000000000000000000000:
+
+# public key with low order
+# acceptable: LowOrderPublic, ZeroSharedSecret
+786a33a4f7af297a20e7642925932bf509e7070fa1bc36986af1eb13f4f50b55:
+edffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f:
+0000000000000000000000000000000000000000000000000000000000000000:
+
+# public key with low order
+# acceptable: LowOrderPublic, ZeroSharedSecret
+786a33a4f7af297a20e7642925932bf509e7070fa1bc36986af1eb13f4f50b55:
+eeffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f:
+0000000000000000000000000000000000000000000000000000000000000000:
+
+# public key with low order
+# acceptable: LowOrderPublic, ZeroSharedSecret
+786a33a4f7af297a20e7642925932bf509e7070fa1bc36986af1eb13f4f50b55:
+0000000000000000000000000000000000000000000000000000000000000080:
+0000000000000000000000000000000000000000000000000000000000000000:
+
+# public key with low order
+# acceptable: LowOrderPublic, ZeroSharedSecret
+786a33a4f7af297a20e7642925932bf509e7070fa1bc36986af1eb13f4f50b55:
+0100000000000000000000000000000000000000000000000000000000000080:
+0000000000000000000000000000000000000000000000000000000000000000:
+
+# public key with low order
+# acceptable: LowOrderPublic, ZeroSharedSecret
+786a33a4f7af297a20e7642925932bf509e7070fa1bc36986af1eb13f4f50b55:
+ecffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff:
+0000000000000000000000000000000000000000000000000000000000000000:
+
+# public key with low order
+# acceptable: LowOrderPublic, ZeroSharedSecret
+786a33a4f7af297a20e7642925932bf509e7070fa1bc36986af1eb13f4f50b55:
+5f9c95bca3508c24b1d0b1559c83ef5b04445cc4581c8e86d8224eddd09f11d7:
+0000000000000000000000000000000000000000000000000000000000000000:
+
+# public key with low order
+# acceptable: LowOrderPublic, ZeroSharedSecret
+786a33a4f7af297a20e7642925932bf509e7070fa1bc36986af1eb13f4f50b55:
+e0eb7a7c3b41b8ae1656e3faf19fc46ada098deb9c32b1fd866205165f49b880:
+0000000000000000000000000000000000000000000000000000000000000000:
+
+# public key with low order
+# acceptable: LowOrderPublic, ZeroSharedSecret
+786a33a4f7af297a20e7642925932bf509e7070fa1bc36986af1eb13f4f50b55:
+edffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff:
+0000000000000000000000000000000000000000000000000000000000000000:
+
+# public key with low order
+# acceptable: LowOrderPublic, ZeroSharedSecret
+786a33a4f7af297a20e7642925932bf509e7070fa1bc36986af1eb13f4f50b55:
+eeffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff:
+0000000000000000000000000000000000000000000000000000000000000000:
+
+# public key = 57896044618658097711785492504343953926634992332820282019728792003956564819949
+# acceptable: SmallPublicKey, LowOrderPublic, ZeroSharedSecret
+40ff586e73d61f0960dc2d763ac19e98225f1194f6fe43d5dd97ad55b3d35961:
+edffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f:
+0000000000000000000000000000000000000000000000000000000000000000:
+
+# public key = 57896044618658097711785492504343953926634992332820282019728792003956564819950
+# acceptable: SmallPublicKey, LowOrderPublic, NonCanonicalPublic, ZeroSharedSecret
+584fceaebae944bfe93b2e0d0a575f706ce5ada1da2b1311c3b421f9186c7a6f:
+eeffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f:
+0000000000000000000000000000000000000000000000000000000000000000:
+
+# non-canonical public key
+# acceptable: NonCanonicalPublic, Twist
+0016b62af5cabde8c40938ebf2108e05d27fa0533ed85d70015ad4ad39762d54:
+efffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f:
+b4d10e832714972f96bd3382e4d082a21a8333a16315b3ffb536061d2482360d:
+
+# non-canonical public key
+# acceptable: NonCanonicalPublic, Twist
+d83650ba7cec115881916255e3fa5fa0d6b8dcf968731bd2c9d2aec3f561f649:
+f0ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f:
+515eac8f1ed0b00c70762322c3ef86716cd2c51fe77cec3d31b6388bc6eea336:
+
+# non-canonical public key
+# acceptable: NonCanonicalPublic
+88dd14e2711ebd0b0026c651264ca965e7e3da5082789fbab7e24425e7b4377e:
+f1ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f:
+6919992d6a591e77b3f2bacbd74caf3aea4be4802b18b2bc07eb09ade3ad6662:
+
+# non-canonical public key
+# acceptable: NonCanonicalPublic
+98c2b08cbac14e15953154e3b558d42bb1268a365b0ef2f22725129d8ac5cb7f:
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f:
+9c034fcd8d3bf69964958c0105161fcb5d1ea5b8f8abb371491e42a7684c2322:
+
+# non-canonical public key
+# acceptable: NonCanonicalPublic, Twist
+c0697b6f05e0f3433b44ea352f20508eb0623098a7770853af5ca09727340c4e:
+0200000000000000000000000000000000000000000000000000000000000080:
+ed18b06da512cab63f22d2d51d77d99facd3c4502e4abf4e97b094c20a9ddf10:
+
+# non-canonical public key
+# acceptable: NonCanonicalPublic, Twist
+18422b58a18e0f4519b7a887b8cfb649e0bfe4b34d75963350a9944e5b7f5b7e:
+0300000000000000000000000000000000000000000000000000000000000080:
+448ce410fffc7e6149c5abec0ad5f3607dfde8a34e2ac3243c3009176168b432:
+
+# non-canonical public key
+# acceptable: NonCanonicalPublic
+20620d82487707bedf9ee3549e95cb9390d2618f50cf6acba47ffaa103224a6f:
+0400000000000000000000000000000000000000000000000000000000000080:
+03a633df01480d0d5048d92f51b20dc1d11f73e9515c699429b90a4f6903122a:
+
+# non-canonical public key
+# acceptable: NonCanonicalPublic
+285a6a7ceeb7122f2c78d99c53b2a902b490892f7dff326f89d12673c3101b53:
+daffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff:
+9b01287717d72f4cfb583ec85f8f936849b17d978dbae7b837db56a62f100a68:
+
+# non-canonical public key
+# acceptable: NonCanonicalPublic
+c8e0330ae9dceeff887fba761225879a4bd2e0db08799244136e4721b2c88970:
+dbffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff:
+dfe60831c9f4f96c816e51048804dbdc27795d760eced75ef575cbe3b464054b:
+
+# non-canonical public key
+# acceptable: NonCanonicalPublic, Twist
+10db6210fc1fb13382472fa1787b004b5d11868ab3a79510e0cee30f4a6df26b:
+dcffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff:
+50bfa826ca77036dd2bbfd092c3f78e2e4a1f980d7c8e78f2f14dca3cce5cc3c:
+
+# non-canonical public key
+# acceptable: NonCanonicalPublic
+9041c6e044a277df8466275ca8b5ee0da7bc028648054ade5c592add3057474e:
+eaffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff:
+13da5695a4c206115409b5277a934782fe985fa050bc902cba5616f9156fe277:
+
+# non-canonical public key
+# acceptable: NonCanonicalPublic
+b8d499041a6713c0f6f876db7406587fdb44582f9542356ae89cfa958a34d266:
+ebffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff:
+63483b5d69236c63cddbed33d8e22baecc2b0ccf886598e863c844d2bf256704:
+
+# non-canonical public key
+# acceptable: NonCanonicalPublic
+c85f08e60c845f82099141a66dc4583d2b1040462c544d33d0453b20b1a6377e:
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff:
+e9db74bc88d0d9bf046ddd13f943bccbe6dbb47d49323f8dfeedc4a694991a3c:
+
+# public key = 57896044618658097711785492504343953926634992332820282019728792003956564819968
+# acceptable: SmallPublicKey, LowOrderPublic, NonCanonicalPublic, ZeroSharedSecret
+7887889bac4c629a101d3724f2ed8b98d936fde79e1a1f77d86779626bf8f263:
+0000000000000000000000000000000000000000000000000000000000000080:
+0000000000000000000000000000000000000000000000000000000000000000:
+
+# public key = 57896044618658097711785492504343953926634992332820282019728792003956564819969
+# acceptable: SmallPublicKey, LowOrderPublic, NonCanonicalPublic, Twist, ZeroSharedSecret
+e07971ee820e48b0b266d8be3cdbbb5e900a43f59ee8535c6572418615de4962:
+0100000000000000000000000000000000000000000000000000000000000080:
+0000000000000000000000000000000000000000000000000000000000000000:
+
+# RFC 7748
+# valid
+a046e36bf0527c9d3b16154b82465edd62144c0ac1fc5a18506a2244ba449a44:
+e6db6867583030db3594c1a424b15f7c726624ec26b3353b10a903a6d0ab1c4c:
+c3da55379de9c6908e94ea4df28d084f32eccf03491c71f754b4075577a28552:
+
+# RFC 7748
+# valid
+4866e9d4d1b4673c5ad22691957d6af5c11b6421e0ea01d42ca4169e7918ba4d:
+e5210f12786811d3f4b7959d0538ae2c31dbe7106fc03c3efc4cd549c715a413:
+95cbde9476e8907d7aade45cb4b873f88b595a68799fa152e6f8f7647aac7957:
+
+# RFC 8037, Section A.6
+# valid
+77076d0a7318a57d3c16c17251b26645df4c2f87ebc0992ab177fba51db92c2a:
+de9edb7d7b7dc1b4d35b61c2ece435373f8343c85b78674dadfc7e146f882b4f:
+4a5d9d5ba4ce2de1728e3bf480350f25e07e21c947d19e3376f09b3c1e161742:
+
+# edge case for shared secret
+# acceptable: Twist
+60a3a4f130b98a5be4b1cedb7cb85584a3520e142d474dc9ccb909a073a9767f:
+b7b6d39c765cb60c0c8542f4f3952ffb51d3002d4aeb9f8ff988b192043e6d0a:
+0200000000000000000000000000000000000000000000000000000000000000:
+
+# edge case for shared secret
+# valid
+60a3a4f130b98a5be4b1cedb7cb85584a3520e142d474dc9ccb909a073a9767f:
+3b18df1e50b899ebd588c3161cbd3bf98ebcc2c1f7df53b811bd0e91b4d5153d:
+0900000000000000000000000000000000000000000000000000000000000000:
+
+# edge case for shared secret
+# valid
+60a3a4f130b98a5be4b1cedb7cb85584a3520e142d474dc9ccb909a073a9767f:
+cab6f9e7d8ce00dfcea9bbd8f069ef7fb2ac504abf83b87db601b5ae0a7f7615:
+1000000000000000000000000000000000000000000000000000000000000000:
+
+# edge case for shared secret
+# acceptable: Twist
+60a3a4f130b98a5be4b1cedb7cb85584a3520e142d474dc9ccb909a073a9767f:
+4977d0d897e1ba566590f60f2eb0db6f7b24c13d436918ccfd32708dfad7e247:
+feffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff3f:
+
+# edge case for shared secret
+# valid
+60a3a4f130b98a5be4b1cedb7cb85584a3520e142d474dc9ccb909a073a9767f:
+98730bc03e29e8b057fb1d20ef8c0bffc822485d3db7f45f4e3cc2c3c6d1d14c:
+fcffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff3f:
+
+# edge case for shared secret
+# acceptable: Twist
+60a3a4f130b98a5be4b1cedb7cb85584a3520e142d474dc9ccb909a073a9767f:
+97b4fff682df7f096cd1756569e252db482d45406a3198a1aff282a5da474c49:
+f9ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff3f:
+
+# edge case for shared secret
+# valid
+60a3a4f130b98a5be4b1cedb7cb85584a3520e142d474dc9ccb909a073a9767f:
+317781b0163bae74accc06c0d44ef9a911a22b0d37faf7726621591f9343ea2f:
+f3ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff3f:
+
+# edge case for shared secret
+# valid
+60a3a4f130b98a5be4b1cedb7cb85584a3520e142d474dc9ccb909a073a9767f:
+7e26f8f24cb590027f9d1bc49b0e1a242c7d8f43624d3e8fab28ee08e02cb45e:
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff03:
+
+# edge case for shared secret
+# acceptable: Twist
+60a3a4f130b98a5be4b1cedb7cb85584a3520e142d474dc9ccb909a073a9767f:
+e96d2780e5469a74620ab5aa2f62151d140c473320dbe1b028f1a48f8e76f95f:
+e5ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f:
+
+# edge case for shared secret
+# acceptable: Twist
+60a3a4f130b98a5be4b1cedb7cb85584a3520e142d474dc9ccb909a073a9767f:
+8d612c5831aa64b057300e7e310f3aa332af34066fefcab2b089c9592878f832:
+e3ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f:
+
+# edge case for shared secret
+# valid
+60a3a4f130b98a5be4b1cedb7cb85584a3520e142d474dc9ccb909a073a9767f:
+8d44108d05d940d3dfe5647ea7a87be24d0d036c9f0a95a2386b839e7b7bf145:
+ddffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f:
+
+# edge case for shared secret
+# acceptable: Twist
+60a3a4f130b98a5be4b1cedb7cb85584a3520e142d474dc9ccb909a073a9767f:
+21a35d5db1b6237c739b56345a930aeee373cdcfb4701266782a8ac594913b29:
+dbffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f:
+
+# edge case for shared secret
+# acceptable: Twist
+60a3a4f130b98a5be4b1cedb7cb85584a3520e142d474dc9ccb909a073a9767f:
+3e5efb63c352ce942762482bc9337a5d35ba55664743ac5e93d11f957336cb10:
+0000000000000000000000000000000000000000000000000000000000000002:
+
+# edge case for shared secret
+# acceptable: Twist
+60a3a4f130b98a5be4b1cedb7cb85584a3520e142d474dc9ccb909a073a9767f:
+8e41f05ea3c76572be104ad8788e970863c6e2ca3daae64d1c2f46decfffa571:
+0000000000000000000000000000000000000000000000000000000000008000:
+
+# special case public key
+# acceptable: SmallPublicKey, LowOrderPublic, ZeroSharedSecret
+c8d07c46bbfb827753b92c70e49583ce8bfa44641a7382258ea903d6a832c96b:
+0000000000000000000000000000000000000000000000000000000000000000:
+0000000000000000000000000000000000000000000000000000000000000000:
+
+# special case public key
+# acceptable: SmallPublicKey, LowOrderPublic, ZeroSharedSecret
+90b7ef237a055f348dcb4c4364a59d7d31edc7ab78f2ca254e2c810975c3f543:
+0100000000000000000000000000000000000000000000000000000000000000:
+0000000000000000000000000000000000000000000000000000000000000000:
+
+# special case public key
+# acceptable: Twist
+e0a8be63315c4f0f0a3fee607f44d30a55be63f09561d9af93e0a1c9cf0ed751:
+0200000000000000000000000000000000000000000000000000000000000000:
+0c50ac2bfb6815b47d0734c5981379882a24a2de6166853c735329d978baee4d:
+
+# special case public key
+# valid
+0840a8af5bc4c48da8850e973d7e14220f45c192cea4020d377eecd25c7c3643:
+1200000000000000000000000000000000000000000000000000000000000000:
+77557137a2a2a651c49627a9b239ac1f2bf78b8a3e72168ccecc10a51fc5ae66:
+
+# special case public key
+# acceptable: Twist
+0092229c753a71284d0853909470ad847ab62f439ea51482fb41d30cc3b44743:
+1400000000000000000000000000000000000000000000000000000000000000:
+c88e719ae5c2248b5f90da346a92ae214f44a5d129fd4e9c26cf6a0da1efe077:
+
+# special case public key
+# valid
+b8da2bd2d7cf25a3e54e5f87ee15911effb9ff86baec4076d56c8e953670bf5b:
+0000000000000000000000000080000000000000000000000000000000000000:
+4bf6789c7ea036f973cde0af02d6fdb9b64a0b957022111439570fad7d7a453f:
+
+# special case public key
+# valid
+684cd420af41abb3d10c61e773238cf729c2155f941ac27e15f4c37f49b29576:
+ffffffffffffffffffffffffffff000000000000000000000000000000000000:
+bcac235ae15cc7148372e11f9315e3bc76ceb904b3d2a8246bd9d9be2082bb62:
+
+# special case public key
+# acceptable: Twist
+38cfacaa4460796b4de434bdd6739f0d043671f97fa829517511e6b47aa93474:
+0100000000000000000000000000010000000000000000000000000000000000:
+5dd7d16fff25cc5fdf9e03c3157cb0a235cea17d618f36e6f13461567edeb943:
+
+# special case public key
+# valid
+30832e8cb627ac195f77b1105258e4bb18b99a5ed944404bfacb3a039fbdb14b:
+0000000000000000000000000000000000000000000000000000004000000000:
+2816fd031d51d6750f9225ede950625cca47441ca97e43092650396991afcb6d:
+
+# special case public key
+# acceptable: Twist
+d818fd6971e546447f361d33d3dbb3eadcf02fb28f246f1d5107b9073a93cd4f:
+0000000000000000000000000000000000000000000000000000008000000000:
+7ed8f2d5424e7ebb3edbdf4abe455447e5a48b658e64abd06c218f33bd151f64:
+
+# special case public key
+# acceptable: Twist
+1021cd8682bdc3f5da9100adff5b2230b3acd836b3a455db8352a2c27e69d17e:
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffff00000000:
+e8620ed5ca89c72c5ea5503e6dcd01131cd5e875c30e13d5dc619ce28ec7d559:
+
+# special case public key
+# valid
+20e4c9247102292655d6765d7d84c6fce5309b8004045daea6d7d7dcad462871:
+0100000000000000000000000000000000000000000000000000000001000000:
+ceadb264379dcadd6e3bb8ad24dd653d2a609dd703d41da6caf3ad00f001862c:
+
+# special case public key
+# acceptable: Twist
+90b150d462de512056d5bd55173074969b496f262fb6916b733f6263a8078971:
+a8b9c7372118a53a9de9eaf0868e3b1a3d88e81cb2e407ff7125e9f5c5088715:
+f86cc7bf1be49574fc97a074282e9bb5cd238e002bc8e9a7b8552b2d60eccb52:
+
+# special case public key
+# acceptable: Twist
+9887286b3261c8d857a16f6db21277f75d88d4e861b3ebe7596699047e816668:
+aab9c7372118a53a9de9eaf0868e3b1a3d88e81cb2e407ff7125e9f5c5088715:
+ccbb8fd9dee165a398b2dbd7c8396f81736c1b3da36b35fbec8f326f38f92767:
+
+# special case public key
+# valid
+20ca2c85cc8762e96b7047bf15c71c050ffe0ed1616040a953ae32a1297ad871:
+585007a5930d77623cf29756038ca197d3ebfd9e4c80a69585efe0274092c115:
+46add6f48ffff461777d4f89b6fdf1155aa051a96387d45f3e5e371a236b6e52:
+
+# special case public key
+# valid
+d027656605b10bf18dea28bc52546f9f1f08cef06cafd200fc84f87dbb4ebe46:
+fbffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1f:
+1adbe32207e21f71e1af53884d2a2276481e298e557f4dacb3720f2458e3082d:
+
+# special case public key
+# acceptable: Twist
+4867a83ee9d01b7510840867db1af6a6049bdbb056b74443f70c358e162c8867:
+0000000000000000000000000000000000000000000000000000000000000020:
+e12cc58fbeb70a5e35c861c33710be6516a6a92e52376060211b2487db542b4f:
+
+# special case public key
+# valid
+a015970a8add940fca5b1b5d23875397d547d8d494fcb314f2045a67a2d12c4b:
+afa00e4a271beec478e42fad0618432fa7d7fb3d99004d2b0bdfc14f8024832b:
+421bed1b26da1e9adbeada1f32b91a0fb4ced0f1110e0a4a88e735a19ee4571e:
+
+# special case public key
+# valid
+4058cb6b9aaba02a338aaa392dbc10039e26e9e444117e758e24c5d8b232ea5e:
+b1a00e4a271beec478e42fad0618432fa7d7fb3d99004d2b0bdfc14f8024832b:
+d7b47463e2f4ca9a1a7deea098da8e74ac3b4a109083d997259b12992e7e7e06:
+
+# special case public key
+# acceptable: Twist
+b876b05daff0530b139d9e11250563418077178246c5fa7005ba00e9b6647763:
+fbffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff2f:
+686eb910a937211b9147c8a051a1197906818fdc626668eb5f5d394afd86d41b:
+
+# special case public key
+# valid
+d87fd6aa5d8deef6dee9619a56846a0829620590f2da40835d8e251597e39078:
+22231c64ef73ad62318b8a87bc38e272e1bb8bf1a60d7c00476d0b059d7b3c35:
+09559733b35bcc6bb8ac574b5abe3a4d8841deff051c294a07487e3eec3c5558:
+
+# special case public key
+# valid
+90036321b63751f7622aa93da34d85e59ce81009ac5b9a068921d83bc4715b57:
+f6ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff3f:
+f7d5cbcf39eb722b01ed20c85563ebb81d076511aead4ccc429027866b9fd270:
+
+# special case public key
+# acceptable: Twist
+a06781fd4c4a0874e00e72ba131b9dd87a83b2904e294de176e8a9af1f695d67:
+f7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff3f:
+e995ad6a1ec6c5ab32922cff9d204721704673143c4a11deaa203f3c81989b3f:
+
+# special case public key
+# acceptable: Twist
+b822d72d8b68bdb4fbf67e56a61d672b2c7747e94479fe5ae4072d0accdd6571:
+feffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff3f:
+32b6dabe01d13867f3b5b0892fefd80dca666f2edc5afb43cd0baf703c3e6926:
+
+# special case public key
+# valid
+d08ce1237e248d02cdf619d20bea5848ade4f6ffd171b8dee8793fc67c459640:
+0000000000000000000000000000000000000000000000000000000000000040:
+a93d83fc9ea0f6cb0cc8b631da600019b76cbb2ec57222f2e42dd540e3da850b:
+
+# special case public key
+# valid
+180ae3c928514cfb9edd06e7dc1d5d066160e967445a5c58e4463b69ed205e6d:
+cbdce39b108c529dce74757843c71d8d1e44740e59f283ffb892f4fa6284c34a:
+017cbfa2b38e9ef3297a339ecce1a917bdcf7e910036086a41d1e22d04241870:
+
+# special case public key
+# valid
+e881d806a110560cd8fee899d59c0249f1233a4322c41aa369c7a2a99f5b5962:
+3c5ff1b5d8e4113b871bd052f9e7bcd0582804c266ffb2d4f4203eb07fdb7c54:
+71133905b8a57ea8c38de0ecf213699a75b096c2df21f07f7e9eb03e9fa53f5c:
+
+# special case public key
+# valid
+08e410e1d7e8b9411236af4a35d6b62a5d8931478e4c62197cfafb491467b162:
+3e5ff1b5d8e4113b871bd052f9e7bcd0582804c266ffb2d4f4203eb07fdb7c54:
+3dc7b70e110766b2bf525252ebed98a100b2e532dc69544464da1bbab8625f6d:
+
+# special case public key
+# valid
+e02fdf7e0ee3d55b4440f01432dd253c949793bc04da44ddece83e54c8c39b40:
+f2ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff5f:
+e317e5cc438b5f79ead5533ac7c45519a117b31033cc2140b19edf8572011240:
+
+# special case public key
+# valid
+f05d18f68ef7a5865c14db3a9c255fdf2dabea2aa36581e94f68b727b582867b:
+f6ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff5f:
+d86810516aeddc18061036f599a9eb84d1c6146b0f543652dd4526743ba42c04:
+
+# special case public key
+# acceptable: Twist
+00c103578d5c079d7bcc22c1c31e787c1b15c57fcb493fdafefa20371cfc746b:
+95aff85a6cf2889dc30d68a9fc735e682c140261b37f596a7a101fd8bf6d3e6a:
+dfa988a477003be125b95ccbf2223d97729577d25e1d6e89e3da0afabdd0ae71:
+
+# special case public key
+# acceptable: Twist
+7005bb927485c435642b424a3dde014bcf76345e5be64ae6e9b24db39e1cdb51:
+434638c8dee75ac56216150f7971c4e5c27717e34d1bf8008eda160a3af7786a:
+d450af45b8ed5fe140cc5263ffb7b52e66736899a8b872b6e28552129819b25b:
+
+# special case public key
+# valid
+0822039a5dc13c40fcccf346e2a7769b4fd272052d43260ad626468a50d44162:
+454638c8dee75ac56216150f7971c4e5c27717e34d1bf8008eda160a3af7786a:
+58002c89bf8bc32ae6fc205b796acd13ef7f8476f6492ae4b2be47f1095e8a4f:
+
+# special case public key
+# valid
+40a6349c03f0dc0a42358f6353ca67632af687b14c9dff626c54e211e8fc355a:
+ecfffffffffffffffffffffffffffeffffffffffffffffffffffffffffffff7f:
+7773aad6e72eb1735b65ad51f7dad258c11d7bfff53094424cb103cd6bfb4368:
+
+# special case public key
+# valid
+50696d4d05209971d6ba0676ea274262ba639aac74fa75e5df4570768ad8ae74:
+eefffffffffffffffffffffffffffeffffffffffffffffffffffffffffffff7f:
+c118ddf6462fbea80f14ef1f2972a1ab12cafa511d1323d4d22d0d426d651b5b:
+
+# special case public key
+# valid
+68bb680c853f4e4daa47c586dc886cf4568d7b0383770f6df439a53be4a3236d:
+edffffffffffffffffffffffff7fffffffffffffffffffffffffffffffffff7f:
+cc0775bfd970a2706b11c7222a4436a3d17160382c83b76f89b66192c81b4408:
+
+# special case public key
+# valid
+b0f6c28dbdc647068a76d71805ef770f087cf76b82afdc0d26c45b71ace49768:
+ebffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f:
+f0097fa0ba70d019126277ab15c56ecc170ca88180b2bf9d80fcda3d7d74552a:
+
+# special case public key
+# acceptable: LowOrderPublic, Twist, ZeroSharedSecret
+18630f93598637c35da623a74559cf944374a559114c7937811041fc8605564a:
+ecffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f:
+0000000000000000000000000000000000000000000000000000000000000000:
+
+# special case for E in multiplication by 2
+# acceptable: Twist
+581ecbda5a4a228044fefd6e03df234558c3c79152c6e2c5e60b142c4f26a851:
+0000000000000000000008000000000000000000000000000000000000000000:
+59e7b1e6f47065a48bd34913d910176b6792a1372aad22e73cd7df45fcf91a0e:
+
+# special case for E in multiplication by 2
+# valid
+b0561a38000795b7cb537b55e975ea452c2118506295d5eb15fd9c83b67f7a50:
+77af0d3897a715dfe25df5d538cf133bc9ab7ad52df6bd922a2fb75621d59901:
+179f6b020748acba349133eaa4518f1bd8bab7bfc4fb05fd4c24e7553da1e960:
+
+# special case for E in multiplication by 2
+# valid
+b00f7df2d47128441c7270b9a87eee45b6056fc64236a57bdf81dbcccf5f5d42:
+4e39866127b6a12a54914e106aab86464af55631f3cb61766d5999aa8d2e070e:
+43c5ee1451f213ef7624729e595a0fee7c9af7ee5d27eb03278ee9f94c202352:
+
+# special case for E in multiplication by 2
+# valid
+c8f7a0c0bfb1e9c72576c534f86854fbe4af521d4fa807f67e2440e100ec8852:
+adc6799ed8495ed5ab6eb1ef955479b9b50aa9ce0c349e8992a6665572d1f811:
+2f350bcf0b40784d1d756c9ca3e38ec9dd68ba80faf1f9847de50779c0d4902a:
+
+# special case for E in multiplication by 2
+# acceptable: Twist
+58181f581aa37022ff71c56c6e68e6175d967c5c995a249885f66565074ded4d:
+770f4218ef234f5e185466e32442c302bbec21bbb6cd28c979e783fe5013333f:
+d5d650dc621072eca952e4344efc7320b2b1459aba48f5e2480db881c50cc650:
+
+# special case for E in multiplication by 2
+# acceptable: Twist
+301c935cae4357070b0adaf9cd6192830b2c989c153729eed99f589eb45f884b:
+5c6118c4c74cfb842d9a87449f9d8db8b992d46c5a9093ce2fcb7a49b535c451:
+909cc57275d54f20c67b45f9af9484fd67581afb7d887bee1db5461f303ef257:
+
+# special case for E in multiplication by 2
+# valid
+d002292d4359a3d42bc8767f1380009332e7a0df2f3379011ab78f789f6baa54:
+4039866127b6a12a54914e106aab86464af55631f3cb61766d5999aa8d2e076e:
+4a7e2c5caf1d8180eb1c4f22692f29a14b4cdc9b193bd1d16e2f27438eef1448:
+
+# special case for E in multiplication by 2
+# acceptable: Twist
+d0c2c49e644ab738270707ff9917065942687e2f12886d961161db46c05b565f:
+078fa523498fb51cba1112d83b20af448b8009d8eea14368564d01b8f9b6086f:
+c0ee59d3685fc2c3c803608b5ee39a7f8da30b48e4293ae011f0ea1e5aeb7173:
+
+# special case for E in multiplication by 2
+# valid
+f087d38b274c1dad1bce6eaa36b48e2190b90b9bf8ca59669cc5e00464534342:
+9fc6799ed8495ed5ab6eb1ef955479b9b50aa9ce0c349e8992a6665572d1f871:
+b252bc8eabfaa68c56e54d61b99061a35d11e3a7b9bda417d90f69b1119bcf45:
+
+# special case for E in multiplication by 2
+# valid
+48dbcc5a695f1514bbbaa6ad00842b69d9ae5216b1963add07fb2947c97b8447:
+7650f2c76858ea201da2022ac730ecc43654852ad209426dd5d048a9de2a667e:
+fbda33bc930c08df837208e19afdc1cfe3fd0f8f0e3976be34775e58a4a7771f:
+
+# D = 0 in multiplication by 2
+# acceptable: LowOrderPublic, ZeroSharedSecret
+5891c9272cf9a197735b701e5715268d36d7436b7e351a3e997a0862e4807d4d:
+e0eb7a7c3b41b8ae1656e3faf19fc46ada098deb9c32b1fd866205165f49b800:
+0000000000000000000000000000000000000000000000000000000000000000:
+
+# D = 0 in multiplication by 2
+# acceptable: LowOrderPublic, ZeroSharedSecret
+c0f9c60aea73731d92ab5ed9f4cea122f9a6eb2577bda72f94948fea4d4cc65d:
+5f9c95bca3508c24b1d0b1559c83ef5b04445cc4581c8e86d8224eddd09f1157:
+0000000000000000000000000000000000000000000000000000000000000000:
+
+# special case for DA - CB in multiplication by 2
+# acceptable: Twist
+0066dd7674fe51f9326c1e239b875f8ac0701aae69a804c25fe43595e8660b45:
+b0224e7134cf92d40a31515f2f0e89c2a2777e8ac2fe741db0dc39399fdf2702:
+8dacfe7beaaa62b94bf6e50ee5214d99ad7cda5a431ea0c62f2b20a89d73c62e:
+
+# special case for DA - CB in multiplication by 2
+# valid
+80067f30f40d61318b420c859fce128c9017ab81b47b76028a57bc30d5856846:
+601e3febb848ec3e57fce64588aad82afc9c2af99bbcdffcc4cd58d4b3d15c07:
+20f1d3fe90e08bc6f152bf5dacc3ed35899785333f1470e6a62c3b8cbe28d260:
+
+# special case for DA - CB in multiplication by 2
+# acceptable: Twist
+584577669d21ce0ae3e30b02c9783ffe97709cbfe396889aa31e8ee43352dc52:
+82a3807bbdec2fa9938fb4141e27dc57456606301f78ff7133cf24f3d13ee117:
+2b28cc5140b816add5ad3a77a81b1c073d67bf51bf95bda2064a14eb12d5f766:
+
+# special case for DA - CB in multiplication by 2
+# valid
+18e597a4e2ccdb5e8052d57c9009938c2d4c43d6d8c9f93c98727b7311035953:
+f329ab2376462e5f3128a2682086253c19222ac1e2bca45692f0c3b528f4c428:
+8392160083b9af9e0ef44fcfce53ba8ff7282ee7a6c71ab66f8843a55d09cd68:
+
+# special case for DA in multiplication by 2
+# valid
+88281cc51d5512d8814ea5249b879dcbad0323d38512dafbdc7ba85bba8c8d5d:
+4fce3bb6c8aaf022dbd100e3cde3941b37d543f00401dba7da9bc143dfc55709:
+42184e22c535530c457bd3b4f1084cbf5e297f502fe136b8d1daecf5334cc96c:
+
+# special case for DA in multiplication by 2
+# valid
+d0e795450df0a813c6573496ec5793ca02e1bdbad10ed08df83fdaed68b3385f:
+15c68851c1db844b5a1ef3456a659f188854b1a75fbdb2f68f514c9289ce711f:
+f654d78e5945b24bc63e3e6d790e0ae986e53937764068b1bce920e1d79b756f:
+
+# special case for DA in multiplication by 2
+# valid
+30b69a1cc1eb2d0b83ea213846e90a2c922088bdf294a6995bf6e6e77c646c41:
+4200a242434337b8914f49345301ed782b13594f9ede089c41fb1e7ea82c9053:
+cd8a09b04795edcc7061867373981aa748651ebdce5ec218a335b878cefe4872:
+
+# special case for DA in multiplication by 2
+# valid
+78b30bb63cd8ade71b7a77d426f4419d05f199ffef349e89faa9d9a5f21f6654:
+baabf0174aaaea4de48cc83adfb0401461a741903ea6fb130d7d64b7bf03a966:
+c9f8258f237db1c80702c5c4d9048dfba9dfe259da4aeee90dc2945526961275:
+
+# special case for x_2 in multiplication by 2
+# valid
+c0b386f4ef0d4698686404977e7b60cb6c1f8b6012a22e29d6224c5947439041:
+f12f18bd59c126348f6a7a9f4a5fdd9fcaf581345073a851fba098e5d64b4a0c:
+6600cbe900616a770a126b8b19156d5e27e1174bd538d0944eb3c0be4899c758:
+
+# special case for x_2 in multiplication by 2
+# acceptable: Twist
+9886602e719bacafea092bb75b51ae7258abe1a364c176857f3dc188c03e6759:
+bee386527b772490aeb96fc4d23b9304037cb4430f64b228f3d8b3b498319f22:
+3fe710d6344ff0cb342e52349e1c5b57b7a271f2a133bb5249bbe40dc86e1b40:
+
+# special case for x_2 in multiplication by 2
+# valid
+b83960f5d0613cdaac6dda690351666e9f277bba6bd406b0e27a1886bb2d3e46:
+cf911ac91b0d944049cec66ae5ef0c4549d1e612e107c68e87263a2fbcf8323f:
+71373ebe67f39a2c230027c7db4b3b74bab80ed212b232679785ee10f47c304e:
+
+# special case for x_2 in multiplication by 2
+# valid
+d03b75f09ac807dfd2ee352c04a1f25984720f785ffaa0af88bc5db6ff9c3453:
+1e6ee536e4f26bbfb63139951a10f3bab62e19ed1ef8397178d9c5d04307cd40:
+238eef43c589822e1d3de41c1cc46dcfec7a93febf37c8546b6625e1a123815d:
+
+# special case for x_2 in multiplication by 2
+# valid
+d036948c0ec223f0ee577e390dbf87222358ed199f2823345ad154bbc4cbcc47:
+2f1c79ad8488db6f5146903b2dc46cfbfc834bbcf09b4dd70c274c4b67ce605d:
+87a79c9c231d3b9526b49bf3d683bf38c3c319af7c7c5d1456487398da535010:
+
+# special case for x_2 in multiplication by 2
+# valid
+d054ded613febf2950ac5c927fcb120c387de0ba61b331cd33024c8b6e737048:
+fccfe742a63ed9cb70958560b5a02260350a7ecbaf8c57ae045f671a29b4b573:
+d683ca6194452d878c12d7da35f22833f99728bba89931a51274f61210336a5f:
+
+# special case for AA in multiplication by 2
+# acceptable: Twist
+e82c480631fb153ba2211fe603032b3e71b162dbd3c11bec03208ffcd510655f:
+cb3d4a90f86b3011da3369d9988597c7fff1499273b4a04f84d0e26ed1683c0d:
+dbf6203516635840cf69a02db87cf0d95dae315da7fc1ec7ce2b29e1f2db6666:
+
+# special case for AA in multiplication by 2
+# acceptable: Twist
+c0c01d28c1cab01f59700aca5f18d2697658b37fdd54a339ff391c0a1a1b1645:
+101e13f7bc0570fa2638caa20a67c6e0c21dab132f4b456191590264c493d018:
+1fe314744390d525278b1f5fbf108101b8ded587081375ed4ac4ac690d92414f:
+
+# special case for AA in multiplication by 2
+# acceptable: Twist
+c82bde72df36479688c485a8bf442f4a34412e429c02db97704f03daf4dfd542:
+dce1ec0843fa8f05d9c7355df598391f3de254ecd0b4ba9e6ea6fd9b3b6c2f67:
+ad454395ee392be677be7b9cb914038d57d2d87ec56cc98678dd84f19920912b:
+
+# special case for AA in multiplication by 2
+# valid
+503f697617fb02a7b8ef00ba34e7fc8ce93f9ec3e1cbfe4bf2c05bcee0cb9757:
+21c2b56f0794cfee25cc9626677a6838000eb66d8c4b5fb07b2f1d912e97c372:
+c6d6499255133398f9dd7f32525db977a538118800bfaf3aad8bcd26f02c3863:
+
+# special case for BB in multiplication by 2
+# valid
+58cd4ca1e4331188de2b2889419ce20ec5ef88a0e93af092099065551b904e41:
+cc3d4a90f86b3011da3369d9988597c7fff1499273b4a04f84d0e26ed1683c0d:
+0d74214da1344b111d59dfad3713eb56effe7c560c59cbbb99ec313962dbba58:
+
+# special case for BB in multiplication by 2
+# acceptable: Twist
+004ea3448b84ca509efec5fcc24c63ee984def63b29deb9037894709709c0957:
+111e13f7bc0570fa2638caa20a67c6e0c21dab132f4b456191590264c493d018:
+7b9dbf8d6c6d65898b518167bf4011d54ddc265d953c0743d7868e22d9909e67:
+
+# special case for BB in multiplication by 2
+# valid
+c8a6eb00a4d74bbdff239522c3c891ed7ce1904be2a329cd0ae0061a253c9542:
+dde1ec0843fa8f05d9c7355df598391f3de254ecd0b4ba9e6ea6fd9b3b6c2f67:
+fb0e0209c5b9d51b401183d7e56a59081d37a62ab1e05753a0667eebd377fd39:
+
+# special case for BB in multiplication by 2
+# valid
+50322ff0d0dcdd6b14f307c04dfecefe5b7cdeaf92bffb919e9d62ed27079040:
+22c2b56f0794cfee25cc9626677a6838000eb66d8c4b5fb07b2f1d912e97c372:
+dbe7a1fe3b337c9720123e6fcc02cf96953a17dc9b395a2206cb1bf91d41756e:
+
+# special case for D in multiplication by 2
+# valid
+e0328c7d188d98faf2ac72d728b7d14f2bbbd7a94d0fbd8e8f79abe0b1fe1055:
+e58baccede32bcf33b3b6e3d69c02af8284a9631de74b6af3f046a9369df040f:
+97bd42093e0d48f973f059dd7ab9f97d13d5b0d5eedffdf6da3c3c432872c549:
+
+# special case for D in multiplication by 2
+# valid
+5017679a17bd23adf95ad47e310fc6526f4ba9ca3b0839b53bd0d92839eb5b4f:
+c6d5c693fc0a4e2df6b290026860566a166b6d7aebe3c98828d492745c8df936:
+99bcbc7b9aa5e25580f92bf589e95dae874b83e420225d8a93e18e96dac00b63:
+
+# special case for D in multiplication by 2
+# valid
+2864aaf61c146df06cc256b065f66b34985cc015da5b1d647a6ed4e2c76bfc43:
+d15f4bf2ef5c7bda4ee95196f3c0df710df5d3d206360fc3174ea75c3aa3a743:
+afa2adb52a670aa9c3ec3020d5fda285474ede5c4f4c30e9238b884a77969443:
+
+# special case for D in multiplication by 2
+# acceptable: Twist
+184a6cfbabcbd1507a2ea41f52796583dbdb851b88a85781ee8e3c28782c3349:
+6dffb0a25888bf23cf1ac701bfbdede8a18e323b9d4d3d31e516a05fce7ce872:
+e6a2fc8ed93ce3530178fef94bb0056f43118e5be3a6eabee7d2ed384a73800c:
+
+# special case for D in multiplication by 2
+# acceptable: Twist
+c85f954b85bc102aca799671793452176538d077862ee45e0b253619767dff42:
+21f86d123c923a92aaf2563df94b5b5c93874f5b7ab9954aaa53e3d72f0ff67e:
+7fc28781631410c5a6f25c9cfd91ec0a848adb7a9eb40bc5b495d0f4753f2260:
+
+# special case for D in multiplication by 2
+# valid
+50e3e5a9a19be2ee3548b0964672fb5e3134cb0d2f7adf000e4556d0ffa37643:
+587c347c8cb249564ab77383de358cc2a19fe7370a8476d43091123598941c7f:
+314d8a2b5c76cc7ee1217df2283b7e6724436e273aeb80628dce0600ab478a63:
+
+# special case for DA + CB in multiplication by 2
+# valid
+08ece580bb6ddf96559b81d7a97dd4531def6cc78d448a70cebabdd26caab146:
+f5c6311a1dd1b9e0f8cfd034ac6d01bf28d9d0f962a1934ae2cb97cb173dd810:
+2bfd8e5308c34498eb2b4daf9ed51cf623da3beaeb0efd3d687f2b8becbf3101:
+
+# special case for DA + CB in multiplication by 2
+# acceptable: Twist
+a886033e9dc2b6a913fffbc2bd402e8c11ec34d49c0dc0fa1429329b694a285f:
+9316c06d27b24abc673ffb5105c5b9a89bdfaa79e81cdbb89556074377c70320:
+d53c3d6f538c126b9336785d1d4e6935dc8b21f3d7e9c25bc240a03e39023363:
+
+# special case for DA + CB in multiplication by 2
+# acceptable: Twist
+98b1cc2020a8ec575d5c46c76024cf7c7ad7628eb909730bc4f460aaf0e6da4b:
+8a4179807b07649e04f711bf9473a79993f84293e4a8b9afee44a22ef1000b21:
+4531881ad9cf011693ddf02842fbdab86d71e27680e9b4b3f93b4cf15e737e50:
+
+# special case for DA + CB in multiplication by 2
+# acceptable: Twist
+c8e193de162aa349a3432c7a0c0521d92cbc5e3bf82615e42955dd67ec12345f:
+a773277ae1029f854749137b0f3a02b5b3560b9c4ca4dbdeb3125ec896b81841:
+7ba4d3de697aa11addf3911e93c94b7e943beff3e3b1b56b7de4461f9e48be6b:
+
+# special case for DA + CB in multiplication by 2
+# acceptable: Twist
+88e01237b336014075676082afbde51d595d47e1fa5214b51a351abbf6491442:
+1eceb2b3763231bc3c99dc62266a09ab5d3661c756524cddc5aabcedee92da61:
+bcf0884052f912a63bbab8c5c674b91c4989ae051fa07fcf30cb5317fb1f2e72:
+
+# special case for DA + CB in multiplication by 2
+# acceptable: Twist
+e82313e451a198dce4ae95c6832a8281d847fc87b28db00fe43757c16cc49c4a:
+9a2acbb3b5a386a6102e3728be3a97de03981d5c71fd2d954604bee3d3d0ce62:
+e5772a92b103ee696a999705cf07110c460f0545682db3fac5d875d69648bc68:
+
+# special case for DA + CB in multiplication by 2
+# acceptable: Twist
+2828594d16768e586df39601ecc86d3fad6389d872b53fca3edcaf6fb958f653:
+27430e1c2d3089708bca56d7a5ad03792828d47685b6131e023dd0808716b863:
+378c29e3be97a21b9f81afca0d0f5c242fd4f896114f77a77155d06ce5fbfa5e:
+
+# special case for z_2 in multiplication by 2
+# valid
+a84f488e193139f986b0e5b249635b137d385e420342aef1f194fcde1fe5e850:
+4ef367901aac8ba90a50e0cf86ca4e4a3ff164fb121605be346e2e48d04ac912:
+7eb48a60b14fb9ea5728f6410aef627d1522fad481b934af64e2c483b64d585f:
+
+# special case for z_2 in multiplication by 2
+# valid
+30fd2a781e095c34a483907b3dd2d8bd2736e279617bfa6b8b4e0e1cf90fbd46:
+d1de303c4ddd05d57c29df92ad172dd8c8f424e63ec93445beaea44f9d124b17:
+b71bdbed78023a06deed1c182e14c98f7cf46bc627a4a2c102ad23c41cf32454:
+
+# special case for z_2 in multiplication by 2
+# valid
+28312e17b47dd32d90561168245187963c7469a31c881e4a5c94384262b71959:
+5bccd739fd7517d9344bf6b2b0f19a1e0c38d9349a25ad1f94af4a2cdcf5e837:
+5bb56877caf2cdac98611b60367fbb74265984614e5e73996e8ea1bd6f749f1a:
+
+# special case for z_2 in multiplication by 2
+# acceptable: Twist
+a87640cf8237b473c638b3e9df08644e8607e563b5964363ccc42133b2996742:
+8a7a939310df7ea768454df51bcd0dfbd7be4fcbb2ffc98429d913ec6911f337:
+b568ed46d04f6291f8c176dca8aff6d221de4c9cce4b404d5401fbe70a324501:
+
+# special case for z_2 in multiplication by 2
+# acceptable: Twist
+780c5b882720d85e5ddfaf1033e9a1385df9e21689eeda4dcc7444ad28330a50:
+fe3590fc382da7a82e28d07fafe40d4afc91183a4536e3e6b550fee84a4b7b4b:
+11fb44e810bce8536a957eaa56e02d04dd866700298f13b04ebeb48e20d93647:
+
+# special case for z_2 in multiplication by 2
+# acceptable: Twist
+209e5e0ae1994bd859ce8992b62ec3a66df2eb50232bcc3a3d27b6614f6b014d:
+fad9ab3e803b49fc81b27ee69db6fc9fdb82e35453b59ef8fab2a3beb5e1134c:
+85d9db8f182bc68db67de3471f786b45b1619aec0f32b108ace30ee7b2624305:
+
+# special case for z_2 in multiplication by 2
+# valid
+806d1dee5ff6aea84a848916991a89ef3625583e1bd4ae0b3dd25c2524a4ff46:
+98bed955f1516c7a442751ac590046d7d52ca64f76df82be09d32e5d33b49073:
+61d4ef71cbe7be3128be829ab26ed3463eb4ab25937c309788e876b23412aa7c:
+
+# special case for z_2 in multiplication by 2
+# valid
+00f98b02ae0df5274cc899f526eb1b877289e0963440a57dd97e414cdd2f7c51:
+e59be4917b3f05b6fc8748c9b90f1b910273c9c6e17ff96ef415ff3d927d987e:
+5ba4394ed1a664811b01557944becf7585652a8acbdbf806742911207bd79346:
+
+# special case for A in multiplication by 2
+# acceptable: Twist
+d86c18f2be396b3bb72f22e6ece22e273af6e1506a1c09ad4d01bdd2f439f843:
+8c9885a26cb334054700a270f7a5f4aac06bad8263b651ebf0712eca1ebb6416:
+a5952588613eb7a5cd49dd526f1f20a4f0ffe9423e82cea302c2dd90ce559955:
+
+# special case for A in multiplication by 2
+# acceptable: Twist
+f81aadb9053eb698996d0f781d9cda67f82ddefa3987d276ff5a94ffdf5d255f:
+f6135fe9741c2c9de7dcf7627ef08832f351cb325dbb3a26f93a2b48620e1727:
+cb6fb623084b6197443ec9ba1050c0923332e5e829ae0194269cfaf920a43601:
+
+# special case for A in multiplication by 2
+# valid
+305b4db4321b4923fc559bf91df677d0e12c3a31b16ec655cb708b759d7c114d:
+f6ffffffffffffffffffffffffffffbfffffffffffffffffffffffffffffff3f:
+9e526079c2fcf12426ae6c2a54b5ffb70f2ec662e29ea5ce0c8385c3b21cd162:
+
+# special case for A in multiplication by 2
+# valid
+900638d1979802db9b52e4dd84fa19579f61cd7bef3c0b62fcccaeaa15fa484d:
+f6ffffffffffffffffffffffffffff3f00000000000000000000000000000040:
+6329c7dc2318ec36153ef4f6f91bc6e7d1e008f5293065d9586ab88abb58f241:
+
+# special case for A in multiplication by 2
+# valid
+38575cf7c8691ecc79cd5f8d7d4703aa48592ff6e7f64731c2d98a19aeae514f:
+f6eba0168be3d3621823089d810f77cd0cae34cda244c5d906c5d4b79df1e858:
+603f4fc410081f880944e0e13d56fc542a430eec813fad302b7c5ac380576f1c:
+
+# special case for A in multiplication by 2
+# acceptable: Twist
+e88bd02c7016547a24f428bc2a9dcccad6c6f880c17bffcf66fc68459627af4e:
+60677a5d934ccbfab8ff5d8f085a0b553f94527d9c49ae140f8ed135e1449b69:
+834bbad5470e1498c4b0148782dfe630e8bfadff1997de802ac8ce302a1bda28:
+
+# special case for B in multiplication by 2
+# acceptable: Twist
+9036ed7d68f7448ac440dc51216b49840dcabd3d5e32e3b4ffc32a5fe9e96742:
+8d9885a26cb334054700a270f7a5f4aac06bad8263b651ebf0712eca1ebb6416:
+ec9070ad3491a5ff50d7d0db6c9c844783dde1c6fbd4fe163e9ade1ce9cd041d:
+
+# special case for B in multiplication by 2
+# acceptable: Twist
+90c55e77aa0fe4afb1287109fd010f526364dea18d88e2fd870ac01b66e3fa4e:
+f7135fe9741c2c9de7dcf7627ef08832f351cb325dbb3a26f93a2b48620e1727:
+dc6d05b92edcdb5dc334b1fc3dff58fe5b24a5c5f0b2d4311555d0fc945d7759:
+
+# special case for B in multiplication by 2
+# valid
+a021ba2fd4e3ad57bcbf204d6f6c3e8018d8978552633b6dff1b7447bf529459:
+f7ffffffffffffffffffffffffffffbfffffffffffffffffffffffffffffff3f:
+1b174b189981d81bc6887932083e8488df8bbbed57f9214c9cfa59d59b572359:
+
+# special case for B in multiplication by 2
+# valid
+3035083e984837587f6b7346af871bf3fc9581c50eb55c83aefabeed68cee349:
+f7ffffffffffffffffffffffffffff3f00000000000000000000000000000040:
+15a052148abaad1b0f2e7481a34edb61403589439b5bd5e5646cecebe2a1be2b:
+
+# special case for B in multiplication by 2
+# valid
+30435ce187f2723f9a3bdea0eef892207e152e4cee8985fa72d2db4147bd2a53:
+f7eba0168be3d3621823089d810f77cd0cae34cda244c5d906c5d4b79df1e858:
+1d048cbe2f8df07c233a8f93706f307d17130c2497fb752eeaa31fe3edfc725a:
+
+# special case for B in multiplication by 2
+# acceptable: Twist
+580f0a9bba7281a30fb033490e0f429f22e3f267852caeacefa3e5291f0e614e:
+61677a5d934ccbfab8ff5d8f085a0b553f94527d9c49ae140f8ed135e1449b69:
+cb92a98b6aa99ac9e3c5750cea6f0846b0181faa5992845b798923d419e82756:
+
+# special case for C in multiplication by 2
+# acceptable: Twist
+709098feb2e25c67b4bfd3be0a01af409adb6da52b3fbe3d970642dd2c983856:
+c8239b710136fe431fb4d98436157e47c9e78a10f09ff92e98baff159926061c:
+f1bd12d9d32c6f4c5b2dcb3a5c52d9fd454d52ca704c2c137956ec8ad9aef107:
+
+# special case for C in multiplication by 2
+# valid
+185ac62e729f88528950926c0de7c481c924bf9cf26a122f443b861e8b6af640:
+b7a2f79e0de9b58147691b5546d9ec463da8325e1440e58bb20aa129d1b97327:
+e6f1c494c9e4bd2325c17183e82d31ab0bbee6c847d4b0e4a99c7c6891117c3f:
+
+# special case for C in multiplication by 2
+# valid
+f03743eead7c2f7719794324f271072817d1a04cbda42b232f3bee43f397cc40:
+2dc624e1663f42a7b9336350f277541b50b8ddc7ee0d86133ad53273aed4e62e:
+aa2a12edf752d279bdb000fb1405a5df8c5f1d41309b4f2bd41aed7ac1ed0149:
+
+# special case for C in multiplication by 2
+# valid
+a8fbb4f90da45794981405d59ef310621e3c3b6b7760b5e30308c7822c88ae5f:
+0e5eceee9104a64f82c9093b9bf7b4076ee5bc70815af7ee9f942ef015756176:
+74d5606ba0b6ad1d8ba36ae6f264d6315f479b3984de573e9b001e0555247c32:
+
+# special case for CB in multiplication by 2
+# acceptable: Twist
+c887886fd07107c7221f6d9dd36c305ec779ceca132ac933ff77dab2beac6345:
+737d45477e2beb77a6c38b98e2a19b05c395df7da998cb91f6dfab5819614f27:
+8cf4538ae5f445cc6d273df4ad300a45d7bb2f6e373a562440f1b37773904e32:
+
+# special case for CB in multiplication by 2
+# valid
+58096ee29361978f630ad1fb00c1267c5a901f99c502f9569b933ad0dcce0f50:
+873f8b260ea9d9ddac08b7b030727bf0072315ab54075ecc393a37a975882b7e:
+d5766753211d9968de4ac2559998f22ef44e8aa879f3328cbc46aa858dcb433c:
+
+# special case for CB in multiplication by 2
+# valid
+0829a49046dce2c07ab28440dbad146453e128960e85dd2e6a69a1512873dd44:
+75e1587c5eefc83715d71020aa6be5347bb9ec9d91ce5b28a9bbb74c92ef407e:
+761d8cecf13f93b379a772e5fac5b9ffe996cad9af06152580afe87ff9651c71:
+
+# special case for x_2 in multiplication by 3
+# acceptable: Twist
+587ac36b9a23594632679adea1a826f2f62d79738220fb487464039f36ca2372:
+f85a06065ea2527238fc5ec1b75ead9262e6b1aed61feff83b91230aeb4b7d01:
+f12acd36f6299a4d192c03aa4efeea7df51e2d15d763172e68accf7bc6f5c230:
+
+# special case for x_2 in multiplication by 3
+# valid
+a8a442b7c0a99227b4cb5c75fb9e5a72cea25eba8a0bdf07271bb4a93c2b6665:
+6e0f1d00b1099d2a71f7be86655feb8988bba5577b02f964043a49f00c749613:
+b2bbbd173f41d952d329251da973a9500300628177ad0fb79d01e2e263905b38:
+
+# special case for x_2 in multiplication by 3
+# acceptable: Twist
+d8f7233e9612c00c9dca2c751ec1d3f5f67bad77c2e714a20e71eb3f220a6671:
+696757ced3097fa960c8390a09e8bd6d390dbde8d1fa170261f3422edc192929:
+45ecfa275f1daa25d3fadf33cdf89a152afea25eae37e68e00b30c367789887a:
+
+# special case for x_2 in multiplication by 3
+# acceptable: Twist
+d80c7c7557c9907e1b11e844bf1369cba669bc38e9b7b253e51f239bda322374:
+fd84b3f2fbfa16aebf40c27f46e18d77bafa0c7971bedde4909212e771bd3c35:
+595e144e07bbe65b38e0e4163d02ad75a65e422e74067db35c90dfa6e055d456:
+
+# special case for x_2 in multiplication by 3
+# acceptable: Twist
+8002a85115ad7b41c50f84f35fac750ee8e19734807102830ff6a306beed4464:
+805485703ccfc4a221ef281267f52b61cebc879f0f13b1e5f521c17352a0784f:
+226e16a279ac81e268437eb3e09e07406324cb72a9d4ee58e4cf009147497201:
+
+# special case for x_2 in multiplication by 3
+# acceptable: Twist
+782db0c8e3e68f106fe0c56415e0bd13d812dea0e94cbd18bdf6761295613a6d:
+80642a3279da6bf5fc13db14a569c7089db014225cfcae7dff5a0d25ecc9235b:
+790d09b1726d210957ce8f65869ca1ec8fa0b2b06b6bcf9483b3eb55e49e9272:
+
+# special case for z_2 in multiplication by 3
+# valid
+909fb0bdbf53a69a2fe39c8b2497abd4fa57d2d54e046b5f514595e2c0f33d63:
+84e827f78cae0cf063e4340198f788c284e07430b3a94a3873df38b1f872ce02:
+684cc83af806bcd9cd251e1858f3c10f0166e0a0cd2be154339a886b13e7c76f:
+
+# special case for z_2 in multiplication by 3
+# valid
+78a67909757248665f79371eb014825ab6bd4af3571f140389c636e004bcf46b:
+d445e1df0083bb6b8e886e6632251807171d4e88c41816fc684373c09d7e5d6e:
+e426e4a3c54d3e77f4f157301e0ac7d9e12337a2b58df16780041cf6d6198c5a:
+
+# special case for z_2 in multiplication by 3
+# acceptable: Twist
+286a302d5b076d2aba7c2a4daf9e7cc9d8539b7c0391307db65a2f4220d30f70:
+f26aa6151a4b22390176f6233e742f40f2ecd5137166fb2e1ec9b2f2454ac277:
+862df92e25277bd94f9af2e1dda51f905a6e2a3f6068a92fabfc6c53da21ec11:
+
+# special case for DA - CB in multiplication by 3
+# valid
+a838b70d17161cb38222f7bc69a3c8576032d580275b3b7d63fba08908cb4879:
+2b02db3c82477fe21aa7a94d85df379f571c8449b43cbd0605d0acc53c472f05:
+3f438dbf03947995c99fd4cb366ca7e00e8cfbce64c3039c26d9fad00fa49c70:
+
+# special case for DA - CB in multiplication by 3
+# acceptable: Twist
+b0733b4203267ab3c94c506acadb949a76cc600486fcd601478fcdef79c29d6c:
+d71dd7db122330c9bbaab5da6cf1f6e1c25345ee6a66b17512b1804ace287359:
+95f3f1849b0a070184e6077c92ae36ba3324bf1441168b89bb4b9167edd67308:
+
+# special case for BB in multiplication by 3
+# acceptable: Twist
+d844a36b58aefdb08b981796029a2766101884b348f70eed947c2541064caf6a:
+737bc07de0729bbcfbee3a08e696f97f3770577e4b01ec108f59caf46406d205:
+6a969af6d236aba08fa83160f699e9ed76fb6355f0662f03dbc5915a3c23063e:
+
+# special case for BB in multiplication by 3
+# valid
+a0b7d312d9b832e124d1bc8cb21db545440e3cf14e7473ee9ccbe9b682f2156c:
+9758061a7b3e2c02fb5c20875ae6b55b11fb6795990a0f4fdcd1147be5521607:
+ab39db4aa29ac4017c7446f1ad0c7daa9a37f1b6b4f2e9d2902ccefb84839d28:
+
+# special case for BB in multiplication by 3
+# acceptable: Twist
+787f1ddd78cc6473d3e63949409ad3f35bfe0ce0738f255dee682f2bfbc80f7f:
+37cd65d33036205f3449e8655a50d4b0c86fec02100b4f2db7da92dcf5e3aa0a:
+13de41659e3e308d6e26c94282fcc3e0364ddf0809ddee6c8e7abb5091b02b00:
+
+# special case for BB in multiplication by 3
+# acceptable: Twist
+4080ae60a85c1fa95aad9beabd98b405e7f28141bf08f2c9a4fdbde1c5680265:
+a9b6e8081460383adc587c8f91a02c59a7a35576ca62436ccd1b5fef1b92545d:
+69ed8a0a27812ae6741474bd5c6a4e683a126649f7245aa0f91a3a384bcde25a:
+
+# special case for E in multiplication by 3
+# valid
+08f9f4a4fac4db413315f74a59818b2452fc7b7685592e26556775f9b86d907f:
+fd1a2cd17a93f850deb8c45a2d34539232dfd8a558304209781c6cb58229870e:
+010218bd67b1b92fee3e7fa4578c13617d73195de10279747e53ba01a254525a:
+
+# special case for E in multiplication by 3
+# valid
+1888cfae3085867657b09435c42b74cc762457839451a3659db218d4214fdd63:
+b88119e5ae6d9e6b912d52524739e612ef19ab7e5dd3d946cb9bc003c378f81f:
+e6b298de9cb6358fbbb00f11890f5714a3858e8f05a2a8d1cf39fe78cc55dd4e:
+
+# special case for E in multiplication by 3
+# valid
+789ce13ed007818d7a5181e629eed944a20a058cfe39669c9831bfa5215a1269:
+7b70e29dce0479cde4a36c7f9786582f104bc0788f046b48af495e67bdb88f36:
+967bbe298494b4a5f95853cfde9dc85970b2a4b5dd2c92782901e853957f5809:
+
+# special case for E in multiplication by 3
+# acceptable: Twist
+00022b43775ab2f4b91bc1cb54c97f78026289eaaf02abeed04ca84f736c686c:
+2a209e2ace0e3d6973ffbf7403f9857ff97a5fdcd27f2c7098b444fc3c166738:
+9f66848681d534e52b659946ea2c92d2fabed43fe6e69032c11153db43dca75b:
+
+# special case for E in multiplication by 3
+# valid
+8097a52fc562e8a516682f5363cc5e7c88e9c78e308df0deef40497b35cc127d:
+f50709aca7f314e8d05b5ff97a427e427bd5e85c4e86712125076a771be21448:
+ea7572e27a9120de1f13b85710ba69a3471b7b3f5d12bc430c12c4bbf8aa3957:
+
+# special case for E in multiplication by 3
+# valid
+4028802030d8a8221a7160eebbf1846116c1c253abc467d6e43cb850f1459860:
+0f13955978b93d7b9f9a2e70d96df922850a8ffd8412e236fb074aef99d37d54:
+e23d63a46be67c7443c07b9371ff6a06afcd7a5794bf2537926074b88190307a:
+
+# special case for E in multiplication by 3
+# valid
+d8515d45c7ab2b9529816543150068b8e4bb614cf2b68a8a99363975af503d74:
+18ffe992a729ce70c3b7cdc55bab55f2210d279134b3082a9f682d3a0b131273:
+33ccaf24e1e26290ed7e462093e9f77607ef52a0626b2cd2511c41cd24c13849:
+
+# special case for AA in multiplication by 3
+# acceptable: Twist
+d8815bd144518fa526befdd373f5f9cff254d5d3c4660e8a90ef2a22c6876a74:
+c3ba28057728d0533965ec34979fe7bd93cf6cb644e8da038baa87997b8dc20e:
+74f95b4700f0185f33c5b5528ed5012a3363f8bbd6f6a840aa1f0f3bdb7c9650:
+
+# special case for AA in multiplication by 3
+# valid
+a82d996093eefdaf283f4049bba4f5af6ecc2e64894f325ee1f9ca1e156d0567:
+4eb095a86d1e781bb182233075ebf1db109d57135bf91d54fdb18eb371427640:
+e9677b854851c41cc489e03981ae78690be6cbf0054ea9834759de3e27bcf03e:
+
+# special case for AA in multiplication by 3
+# acceptable: Twist
+c02609df3d5436c123dcd7ee11f23f1da321666c09f379d37914203340510861:
+83f67d7c92b11c8fb072484642a01f43deb022b54d94a4015e39849a2e2e9555:
+f148716ebe7269a7076f0cf1f22b6978d3c7e3607b0bcc87a8c7a85b9fd20c2f:
+
+# special case for AA in multiplication by 3
+# valid
+a0e3b78c0f3be2a760b2c916f244df219624fdda2e9e31b15328f4a77690296a:
+20cc75d376d8453b9d049c84f58eafcf61126c08a03661e735f0a8be228fd466:
+1d5c123e88e9dc7a3b16ec90b60578dfca7e11eab9b88c6eca7bc33d91fde83b:
+
+# special case for AA in multiplication by 3
+# valid
+701f130a290584cb28c7d6539506a1a054f926a17ef7c568ae43047c05e10f60:
+ef31b43d19c0a5434deb56129c16298a394a7032a2e52cb997476bdeca325b73:
+2fc065ba8f5040a0a659f6f7330554bd1b9d7c893b91e316e0af90c37af4f135:
+
+# special case for AA in multiplication by 3
+# acceptable: Twist
+d0e67f68183a4c1aed9c56864b36278bb7bb75d57a78321bc7c24ff61636607a:
+d8c8e2c6f33a98525df3767d1d04430dab0bda41f1f904c95bc61cc122caca74:
+ef7612c156078dae3a81e50ef33951cab661fb07731d8f419bc0105c4d6d6050:
+
+# special case for AA in multiplication by 3
+# acceptable: Twist
+88eb7775dacc32b045ceb35f261b3616315efa98b780e08c79d544edadb5467d:
+1833619516b80db0c05b225509e6698df028d83b66ed6bac6f0f6308970d2c7d:
+a3cf3d81ec56896a68fca0da6335171d0c622568738c0db26fe117033726a049:
+
+# special case for AA in multiplication by 3
+# valid
+7055b1c0576e7ab6c89fcc1ce49e79c8c371bf9fc2b22b8f8396a9b64c5ae26d:
+e2e989aad2397fc34b6cbe2db27d5ab69b28048383c91d9e8226d548253fab7e:
+e7f45823a45b6a46192b37d73e8609b5bda68cd7cfbdccaa49082080993e640f:
+
+# special case for D in multiplication by 4
+# acceptable: Twist
+906a9bfcfd71014d18967680d4509eaa41c666424af98bf9ff7ff49eb1baba41:
+b9bd793624d6a7e808486110058853edb25e136bd4d6a795d6d2ef53b25e3804:
+7c6148134c9e8b2ba5daeca41e6a1f3a82d8f75d0b292b23c40fe7f5ce0a2b7a:
+
+# special case for D in multiplication by 4
+# acceptable: Twist
+28392b1b035a8465aa22aabb571061c6effeed40cc2530b628e4fd40395ae04a:
+e3f444e208da9043f3f74c20e28d7f404bb687a346709abcd555156f88607820:
+ea5e772bac4693ce69ea3ac761011fa7674037653a433c7f05456e7291cd3c4e:
+
+# special case for D in multiplication by 4
+# acceptable: Twist
+78cbb35204cc88676c14e0ff18171392e998411b23d905d4c4dceab70511f442:
+87b43f90f76d12fb3a469fa8687c27e369d4a82f95cf95e8dc3970de8f86d92b:
+81c395aed5cc5f5e2a206a8a4cacecd501df5b81e49433835ad8a3779edffb30:
+
+# special case for D in multiplication by 4
+# acceptable: Twist
+a8225b49ef7b7330e3de787cbc40479644db7ab126370295c94189673430d745:
+86441ea06c5cd2a34c6b51261e93a2f30ea7db0f74e14c42f0fc443c6735973c:
+513eba5870dc5187e2552fe3ba8292b516d2af9ecb9a9bdc51eac2ce2de40112:
+
+# special case for D in multiplication by 4
+# acceptable: Twist
+0841e1a5c7420b94b6cc6991316ebdd608626339c09d0f67b24088588b9d0d49:
+4624aa4ae9d12725bf92b85f93e3e8cea16b7bd83fda0eb18fab2dbe0e8bf742:
+983b7e236ffaddb4b759b7353fe87846f59fb6f28a3ed65c256176b6609b7c6e:
+
+# special case for D in multiplication by 4
+# valid
+08ecf76e31a23039ea8a15ee474b6251a9d725bff1a5751eb5ecde9d7d4e2f49:
+a625a5b7a04cea462d123b485c39ea44a8079aa223c59e9ca97abcd30b500e4b:
+c941369b085c7465d50d23ceaf6717ab06e24638f217a7b8055ce8ebd3ca1225:
+
+# special case for D in multiplication by 4
+# acceptable: Twist
+6038fb0a830d1001ca8ea74a613ea98f6ab8512644e55e8d45a29071bd4bef45:
+8a5f2063f259f3317ae3e0b459f82c4677666e49a2eb9bf0369aee663631265b:
+a3f7e169db44d0d179c242e66347364ab92744dc6ad80e4775aef7f4ff9d5f34:
+
+# special case for D in multiplication by 4
+# acceptable: Twist
+c04cf129f0b33332e2654f8e45225c042d7fa6cbc793c88bd4c731985289b045:
+54cfb6ad0d03e3115acafee12606397f2bb46a8c5f326a255c494118aead3b62:
+401aabfbb73fe6694c446ecfffb43006427a9d4756e049a1ffc79578d62f1660:
+
+# special case for E in multiplication by 4
+# valid
+3806b036c92d7bc0771998d24dbda2945b601d42449bd3ec4bbf3757d01b894d:
+0ee3bee8cb3a0afcec22fa2233706e8ec29ccf1af212c0a674745ebba34f9d08:
+20322dd024fb5a40f327cf7c00da203734c2a279b9666a9ff7d8527c927b675e:
+
+# special case for E in multiplication by 4
+# valid
+380d9056b5a2f4b3dffb30e6ceb722ac4684245f1befafb5661bc8c7a9ad4c43:
+797ec7512afbf0ad918d0e4947903be95234f3abf36750a8f854888d117b774e:
+46152d59c2d2f3ecf03ce652d2b6978d401d5ede4570a6c911771bdcfb37cd41:
+
+# special case for E in multiplication by 4
+# valid
+384929a42c8d8df146db9508e2f21a4e8cd4d99c1b1338df17a457e88afb0043:
+d570c7810f69e502b355253afa7c667bfa5060d90dc86e358ab445f6381e415d:
+37567f7ec0449c7b823cf7b0e219e9dd880e56a1464d0417a9e67eff42332866:
+
+# special case for E in multiplication by 4
+# valid
+48a986825b2680e2f2547ba75a9599b04ed57f8ed18d98e7099c544efbdf284b:
+2c611cb94448f1c7822425a4cf5356236b90a555b1ed4747820ba7f739c8f57d:
+fbf6587ec181116cf1ace7dcd548029d69c130e50fcf6ad5dfcd25c23ee9f939:
+
+# special case for B in multiplication by 4
+# acceptable: Twist
+98452ad7df4e26bc4b3d403f9ebf72bb2d7b6b7d5860dbf6fb9a4f78dc02704a:
+e559c417da7fd5851352f508b90031d49b5d2d0aac88a9c8b5fb6e80165ac10b:
+c7c6f6d7ce1e4f54c727e5900686c34e6a6953254bd470bbbf0c7c18bbddad73:
+
+# special case for B in multiplication by 4
+# acceptable: Twist
+a8dbc9be5034ed7fe7f469264f2135e9c67cd30f525570d2d841e4bdeac52349:
+746d97e7774292a3d703f604e79d8764c99a6a2fe280eaa9811115f5e038f21a:
+cf7d2a66ea4dfed94469b2d343533ff302a576f8402ed2187904437038e54665:
+
+# special case for B in multiplication by 4
+# valid
+f8d26878dff25ced02d3b27ce74002695bb879b3c4328930934315ecae842b47:
+1f354aa8ffc4eae2b40dad2ebf830db3feb07e2a1a2da39e55df87c8c613de1d:
+b204d3bbcbdc624f9f1a743fa3daa8f4c8785ed088d37d08cd13c601170a461b:
+
+# special case for B in multiplication by 4
+# acceptable: Twist
+d0f5e9c43c95b1ffc36f832b943601d5e17647f7d78e2e7710ace63ff274d447:
+9c3f0023e1a4832586af2483bbec64ce9f06f3ea806d4019a5e4abb1b5627029:
+b9f21465615f39dddcc37520ce9b956f7de9883ac93a870d74e388b8e1775463:
+
+# special case for B in multiplication by 4
+# valid
+700679e8c24df828f2e5212a3263d5e93ea61679988298bab3b480f46f961a48:
+d05656aa014d476022dfc55e8d3b4884ed0bdf85209be8b55351394d52be684b:
+20f1fc613874495f20562c10b7a8be47bfc12c168d829d6321aa2de17060e40d:
+
+# special case for B in multiplication by 4
+# acceptable: Twist
+d0d077c9461f747e5660be85cc620428b4cefe805de0fd254adaa465ea5e784f:
+c4a19b8686e18c29359aa548427f06a368d55a8737483d4893523adac6795a4c:
+652b18ffd41cfb7d1f0b6dc79baa3b2a392ef1617f5cf6259b5b4ff065916a16:
+
+# special case for B in multiplication by 4
+# valid
+00711ac08ef88c3d43a3cbda67b6fe5f34f54723dbe6d725c8a3569070ab9a4e:
+4989de79853ff35be8c9f92fc94674feef38a0e65788471c521f8e259adf015d:
+679825c259392d86f8edb15328d4faf52300779d979a503a76e27be3d7a85e03:
+
+# special case for B in multiplication by 4
+# valid
+989a75b40451139ec36ca6aa043765c61a18be323a5987fcb025c2dad8d4bd40:
+a981483cb0ea4385ffbb552826c3dd110d4ae89ff52ed0cd6018f99d3387987b:
+9cadc14ac153fa383ef66d1833f589100dff90523272e32b06e2c6f1f4424040:
+
+# special case for BB in multiplication by 4
+# acceptable: Twist
+90c3cfedd919a2ccd51fb455649e3ad2da1ef0ff619b59a7f9c55a68a8219645:
+1df3dfdab74ff38177dac294b2da2f49a348bc3b3bc6ce9312bea5ef3ecdd30b:
+bcc95fb4890ed311f3fb4f44c2b60866cdddec97db820a7f79f475337e16284a:
+
+# special case for BB in multiplication by 4
+# valid
+e8fef5c9b60f84984e8836d535acb372096ba8159824a0b49a17eccda843bd41:
+fc6b718ba8b47d24b1cfd6b5d0dd8b20fd920960fabc302dbe4f93bd2a06e933:
+06f1b495b04a0010845c9d39b13bf2784ade860d9632c8847618c0b34297c249:
+
+# special case for BB in multiplication by 4
+# acceptable: Twist
+c0e05bde7727db4e352b5e7f035327b4d86a42d513ca116e22d64a4ede56434a:
+b279b6c065f95c7040f148bcb4a3d310e34bdb005931a879be469573deedd041:
+cce7bb644df94501421db49d15e821c7b0aaabecdf8837ab989b1f23bac08f35:
+
+# special case for BB in multiplication by 4
+# valid
+d87308bf753573f596ac8330b204014b2152dbdfc9881a0d9975058582bdf646:
+98e2cd4c10554e41b0a3e41082c8b6b61b55447d26c0aa97f9a06baeeb54b55b:
+71fdd3405c30805701ae4dfad98c493aecfcf2e3b563e7068373c1b19137c268:
+
+# special case for BB in multiplication by 4
+# acceptable: Twist
+d80059a8a387e16f6ded6e7e980e806d1f78b470bb61103d0ca70623ccee8b4f:
+872897f1bd1885da08b9d03e46811044fbb04186ba30c806f38b94ebdc27186a:
+bf280aeecb74ab34e1310aa6fe8dc972f94dc40c7f88b72137ccfe34ed343c13:
+
+# special case for x_2 in multiplication by 4
+# acceptable: Twist
+b0a4fe63515169bd82639b515ff7e5c4ac85bba0a53bbaca80477eb3b4250d44:
+c08f72760d9cb4a542aad6e2af777920c44563bd90356168c3608c6b9af2ef0f:
+72566a91ccd2bcf38cf639e4a5fcb296f0b67de192c6091242a62fae467fb635:
+
+# special case for x_2 in multiplication by 4
+# valid
+984256b12ef154ff6c2e1d030826164cba3614e3df7688d82b59e16201c9114d:
+4f03849c24d584534d74302220cfdc90e1bc360bb5e297c0fd0fd5f8d799e416:
+24acb4afa63919621df795206c3929b599ec9d253693895d51a0555072e89a34:
+
+# special case for x_2 in multiplication by 4
+# acceptable: Twist
+6847141d5d4377af96a2a647c642ee81600fe48d3467e3a70f3ee312bb621742:
+4959771a931e242d5713d5cb76f33310c6a283df16645604289553809cda6518:
+5ba2112a41b5bb381f202446fa9f23c54d2de149f9ad233753417263840ea432:
+
+# special case for x_2 in multiplication by 4
+# acceptable: Twist
+e85f1164e2ab6faf62667c74b03ce529b49a0e2041b1ac0fa242e522d2b7694c:
+f6fe690cf547049635bb3a7785537b4379c9ee06b46120493b8bdb152e09c81d:
+a87c9fdf40c409b9edab481b2cc69687ee1ab92e340c3db0107d40b5de6e7a20:
+
+# special case for x_2 in multiplication by 4
+# acceptable: Twist
+281e1bbfa711de69921a64c5d2183c338db5504606ce2b6b4ce1cdd54b41e14a:
+b468681a1275850c11d37ec736af939a75a7098514e04cfc1c6ca78239a88426:
+3be98798f01e71639f3cb8fd4a17bf273e10c67f8974dd9802eed59d847d4020:
+
+# special case for x_2 in multiplication by 4
+# valid
+20aacf1902b3cd609d7ee15cc96453cc22e2899d7d17852680f2a728bac6dc4a:
+2d71e8457099e3f445f9e2a14f18b0f5914bb35f482f9c069b64bf63710d4228:
+338c9917dbf11a0cabe8ad4a65959229bc00f99c211e752b20b8b49b87756d0b:
+
+# special case for x_2 in multiplication by 4
+# acceptable: Twist
+009e8e9fa993804dce94cecb96b1de2568245a97059e4d7ae116ecdb1badd141:
+fa8f24e944de5d003746d4630350c0f4f6175a3269c19184824105398fbdd329:
+56e2bfc7f6ab7da8fc734afc515e57d0794d002434f9bc8e18bd0b72c0df3c4a:
+
+# special case for x_2 in multiplication by 4
+# acceptable: Twist
+f01574643f231ffac055bd235ee74dd416b94c8e55a2ab2b4d13a8b788d90148:
+ae4e37ef53c79e25e8275a60f2fc1dfc277ebc5d3b88428c6432c3f98494212c:
+17fa1276d9fd5025172736449a1c0ae33512e5037014a18db5903e47bb3bc950:
+
+# special case for x_2 in multiplication by 4
+# valid
+3800a42659954281ca266d7cf1ea9db6d79891a406a70f9e84c3570a6a12d24e:
+95e56a830792478f7c42504043a9cab8e2eebff5fd90983709e29e03c0a41b64:
+167a3b2fdce9413c89ee892daf9f839a2eea80ea8044924035db1724a5b0217c:
+
+# special case for x_2 in multiplication by 4
+# acceptable: Twist
+70a826b186962218dbafca113319daefb5ddf3cf14e15fe3faadc4c0a2e46648:
+5f16aa7ccabf4da6b686bd28c7460e106bb1b97a823792527765c29a9ad8fc71:
+30a4ba793f2dffe1700c61428b4d84b5fcd0aa99a23b903f84a48eca5cc9fb0a:
+
+# special case for DA + CB in multiplication by 4
+# valid
+a85a5eda0a269500b3ab0b58495fc254c2691028ac533494b5f86d44e9dc654c:
+47fb78111805a11982a3d6c5d83e8e189e7fcc462c9abf805d3625be7a6eac11:
+2bf9ab750bd58ff6f877b783eda45a71a65cc9b7c037fcfef4cb5f4c8842f529:
+
+# special case for DA + CB in multiplication by 4
+# valid
+183f28ec867624ef5eca4827ed0714a5525ef21d5e35038b24d307a3391a2846:
+03b8ca5efd1777d6d625a945db52b81f11214daf015d09fdc9df7d47b9850e31:
+35e9289234bd5e531da65d161a065a14f785076088d741c9a2d886efd7d17921:
+
+# special case for DA + CB in multiplication by 4
+# acceptable: Twist
+888c6444ff5eb482b2b10bd4e8a01bdccb65f32934d8026106f16a91349f484c:
+4eca5f8731b0fa0c106acf578b83a350fa8173a290f1eba803956de34eeb7671:
+833afb867054b8b9ac70d6013c163e8b7676fd45ae49a1325f3acb75975d8c13:
+
+# special case for A in multiplication by 4
+# valid
+c8a85d140ba150f5c6a8d3cb363bcbcb75365e51c61640e974a0725b5e9d5940:
+a5562b4ba86b464dff4c2cfae85b384be211771efe8a9697e51d84de47f1eb14:
+8a914760129575c8ab3270d04b0465fc2f327acaf1676463113803bbb2ec8021:
+
+# special case for A in multiplication by 4
+# acceptable: Twist
+90a3aeb1417c3d61c1efef1ac052218fb55d3a59c4fe930b5a33cc5183b48547:
+88ae1631cd08ab54c24a31e1fec860391fe29bc50db23eb66709362ec4264929:
+c1988b6e1f020151ec913b4fb2695bae2c21cc553d0f91cf0c668623a3e5a43d:
+
+# special case for A in multiplication by 4
+# valid
+b858d7414bd9ab9a3ebea79064ab87bc050e74407f4d4748f62fa4d9d203b640:
+cbc4d55d5bfddd0bc5c5edbe3a04836b2c701d25195b26221cbea19311e55a3d:
+bb24817bd9fff423dc0972908e2c03fddf4dbe100016b459f28fe9594adb3714:
+
+# special case for A in multiplication by 4
+# acceptable: Twist
+f825edf1f79eddd715a72b3ac267d6b2e97e18bb13bcafdac5940370b85ba64b:
+d66a2f9f7577e2df4a56cb51962b3056ff5cc0494c60f39511782e79923edd41:
+b3b4513f8a3102e1ae782fbc69888177f2c24c569303a5d01ab1c3c5e285524a:
+
+# special case for DA - CB in multiplication by 4
+# valid
+b0a710b470e324bb56a7d8ff8788d05eb327616129b84972482425ea4ad4f34b:
+de0fed2fab6e01492675bc75cbe45d7b45b0306cec8dc67611699811c9aaef16:
+471ba91a99634f9acf34fd7fd58f72682be97ee1c821486d62ba4e448cbc0417:
+
+# special case for DA - CB in multiplication by 4
+# acceptable: Twist
+b898f0329794747d33269a3989b67e43a7ab5a55fa1210b0e5dba193f4fa094e:
+6418d49fe440a755c9ff1a3582d35dc9b44c818498f15782c95284fe868a914c:
+cdb3ca02d5fdb536dbc7395bab12bdcfd55b1ae771a4176dedb55eb4d755c752:
+
+# special case for DA - CB in multiplication by 4
+# valid
+a0528ed9a8ec22ebe9cc2e32fafc3f467500a9a22f5377382df6604edcdf4f44:
+a89bcfa236bbccf07c434b59f8655fb085b6cbe5ed6376281df813afba22b752:
+cd3245403fd9edfcf91c9581ebb2eb7c77ad6837fca372479e78de9faf60a34a:
+
+# special case for DA - CB in multiplication by 4
+# valid
+f06888bde75d689d056874f6436000497d22d8ad9b95a1c67de1dda4ada3164d:
+cdb1f95f6eacc24b6d029c6ed976666dc51794db8e4aa966ba850fd7f5048965:
+ab7c47ecb0c0167156f44f66a527264b958fc992c21ce98cef3ae214d66bd82d:
+
+# special case for DA - CB in multiplication by 4
+# valid
+e034fcaa3ae40603f9b22af159fd67ef009380946de92cb1d83cc489e8b35041:
+9491a82744f1cb6105b76b0442e54e605ac67f47a1b2b3b552d486f75bd98e6a:
+1bfa264a7c7229147a20dd021211891e61f5d8c76cd83f0be24bc70e466a815b:
+
+# special case for C in multiplication by 4
+# acceptable: Twist
+702a7448c0ed58e1f4e0e332d096a36360beca2f6955c815bc120b3a691d7742:
+4d19e156e084fe582a0eb79b2f12b61d0b03f3f229227e798a933eea5a1b6129:
+c46057fcf63088b3a80e0be5ce24c8026dfadd341b5d8215b8afcb2a5a02bb2b:
+
+# special case for C in multiplication by 4
+# acceptable: Twist
+50025cb508ad4faa06fafd0f4a33b747ccf1b3573885d3426500d51b56300144:
+cc4729c4eae292e431ec3a5cf5020e19f9bea50ef3218d9a790034526c3ee14a:
+d4361e26127adfbe37c2ed8f42cce4ebab8ab74ed9e74f14c3435d612c1a992a:
+
+# special case for C in multiplication by 4
+# valid
+7082fc53299a4d30e5d0c383c035935b1eeebd9408fe4d04b93eec24be52eb47:
+4a474249af8f771f0cfb1116f24fda4c42f4136d2afb766d1b291c73c6668d5a:
+80dfae7a28bb13d9e51ff199267cec2a19dfc8b6f4974e3446b2f62fe9b62470:
+
+# special case for C in multiplication by 4
+# valid
+98ff7e711d65cc7fd9d0ac12dfe8b894e0a93602ca9e75bf0eabbf0bfe670148:
+0f2a5cbbe503139531ac0529183da8e624d25286f6e35d1407ab1f4d76ebc260:
+7a5c373065e339b26ee537cff1cf4597cfcb4bf2dc7c4bcfec9884443281c273:
+
+# special case for z_2 in multiplication by 4
+# valid
+b080f4ac1e758bbfbfa888a78cb8d624d97b8688002b2017e35f52f3d7c79649:
+2fe11d723dba63559e1b96147893cb7ec862711806316daa86cd4da769d4b22d:
+c5edcc5d447071c08dfa8281414ae6a02de753e2f7bb80af5f6253e56db43422:
+
+# special case for z_2 in multiplication by 4
+# valid
+e815bf9a967e1208af8e74ce9af6d113dab17c01c90f1ae2bc25e3e2f9e3a44a:
+98e1211dcf6651fa9f2d00eb083ae5855869a2a53e835f2e03b30c0a19ba8051:
+263a38fe538b50e8e988bf07ae86f33d49886b14c7143efd1d2025c840e36a25:
+
+# special case for z_2 in multiplication by 4
+# valid
+4051b01cdf90af38f0a96ffb83f8d4133abe4fb035b6fe6f65276447caa7314f:
+2f1b938b81a4c90e1251135ad7fabe835f6a8bc5e22d4b2ab119f6f677877677:
+340acf2801de71c18f4c79cfea372bc354e4c8a5eb5c2cce8b45d885df162f45:
+
+# special case for CB in multiplication by 4
+# acceptable: Twist
+98c092363184e58ad6ce510bd32b309c9d5a46f8d9ee6f64a69d8180bbc6cb45:
+340b9f613550d14e3c6256caf029b31cad3fe6db588294e2d3af37605a68d837:
+9efe5cd71102d899a333a45ea6d2c089604b926db8c2645ce5ff21492f27a314:
+
+# special case for CB in multiplication by 4
+# acceptable: Twist
+686e51c00116d1c191aa9d5823b96e5956102e8fe75f5cf2376d99989f6f4342:
+edfbd6f09aa32435440b0ca8ba436308319613f8f2d501133c526c3ff55c7b3d:
+196182095bcd2ef46b18f64c63607e0ab162a0869e6265ac8ae35e358c3d8a63:
+
+# special case for CB in multiplication by 4
+# acceptable: Twist
+208af2c9442b36b521fc3a1ecefe342aac308bd6e6296ee091c196dc02e7ae40:
+9b0538cd618b0a4de09e45420f84d54d74514fbb1a31c1a4aa1e93306f20723f:
+a3c6b75168211e8e0a49ca815bfe3f469f29864dc8166152b456e7074afa9b5b:
+
+# special case for CB in multiplication by 4
+# valid
+c0d861a6d5ff91f91e3bd05934161ff0ab0f3ce7e4a2b5b4fcb31ae34b46664f:
+ae8cf2fcdde710c2c1184524bc32430874dfa08c125f61d6919daf8e66db415a:
+deaae6c9952844a3a1d01688e7105b0bbeadc160763c2002b6d0bcf35c22d123:
+
+# special case for AA in multiplication by 4
+# valid
+70785cad160972b711318659b47b574f6941ef6da1ea06508b2650f57ec9e54a:
+2a59f478402d2829cd3b62e9f7cc01445e8e73a42cb11af00b6b9a9f0e44cb3b:
+c204bd15f01a11a2efdabe2e902b7cd0aa079316f60e911b3ee5d46262e98631:
+
+# special case for AA in multiplication by 4
+# acceptable: Twist
+60afc8eb1f87df4b55287f3c4698c5f8b997b28a73c573fc273e9c467fb7e44c:
+836c8e45dd890e658c33e69b6f578a5a774c48b435bc3b91ac693df94a055857:
+c5457487e90932f57b94af2e8750403e09c9ac727e2bd213590462b6937b0753:
+
+# special case for AA in multiplication by 4
+# valid
+a83c11b2834136b9aaf0152d90e76e3c27177693a2834e8beda0a3571bce6947:
+59519ead7995a6df89bb54c840d61a8481881098b8a4f83c6a2f6ba800338257:
+4ed6f8d62932541c6bea16e03835f1f758a5c41722b5c9989c9c7cc08e34e37b:
+
+# special case for AA in multiplication by 4
+# acceptable: Twist
+b80d8795735806579e71759894939d758853592127efe84fc82eb7cdee45014f:
+32f34da84ab4bfca369c4b884691becf54be7fbed16449dc86969da7ea9abf62:
+521a5b8149a132d155e6b4ed113900506cfc2f76d2a3e14196d69eb85db3c952:
+
+# special case for AA in multiplication by 4
+# valid
+e08ffa45efbe1f96584c76254554adb9177b58ed09609a6ce499e5bd22d35c45:
+82ae48dcf59bc5e469f9a11b18a32d4753ac818692dfae27d675411a2272b363:
+e831d6cee95ca1b4c96bb89457562fff36cb4d08b81da89b810b425ecdbafd78:
+
+# special case for AA in multiplication by 4
+# valid
+688e1bbb5114f34e8531c278b2d9714ba07c32a7aea6e627135bd1fc65238045:
+b33bd3ad14b66896f971cbdf27785fc3aa3cfb39adc6c29257d22ea4df8cbf63:
+350e3ab9d0dbff78f3f2157428beba189333be274827c10d59673f21c0c48a24:
+
+# special case for AA in multiplication by 4
+# acceptable: Twist
+8036a4e2e93e9ed82d99d71a522aac9289bd9905fe41d01d08a499376a258442:
+18e58df6bfbe184b0e3c7c4bf2a051ed055b793501c0d4fc47bc8a95c4deec7c:
+ade71d6460287fe808e947560e67a9d6ff2f96eaa1355d2e9fbbe549e883381b:
+
+# special case for DA in multiplication by 4
+# valid
+901b20f0cda74076c3d4bf4e02653cd406ed480c355159e22ca44b984f10764f:
+772e31e776e8d4f23b7af2037af28a37e68f61e740b3904f4ec4c90157be1478:
+91a9bec28cf18c7094e2d80d2764df59ada0cb1946be422864bd7ad0e533b663:
+
+# special case for z_2 in multiplication by 5
+# valid
+d83eb7affd1bcc1ec0b4823cee5cf0b15b5f57085aa2708ed437a2925329b550:
+a8d55d5c1137e9bb626557f9d6eea8d3120e9364f8bcd9b67934260b1a091801:
+6c1b8e240edfa5db2abb3dc12bcf9e8ac9ca10dd3507083746f6f36dc035d755:
+
+# special case for z_2 in multiplication by 5
+# acceptable: Twist
+989eee317b9c254dc023f9e35eff0224bc2e0bc871996b946a96970e7506a85e:
+33c94be58b0f0e6cf363e1b12a2ebfb93040715be91518f21df2953eeab5fb01:
+d4c3b3467714f2d105904a84cc7e81d7f291304e908041682d8906a683c12125:
+
+# special case for z_2 in multiplication by 5
+# acceptable: Twist
+b8355455d358f2dd7c5707b2c6973c9c27b99e7d8ac1650c791e5fdbcbea4957:
+a218ae9624b07ce05178b9d0cc1b71dee21f27852a2ceb18610b4052b244f00f:
+1ebe6ca711a649ae487b332747e3dc0306340560cab6bc6029e44f6a7e0ee41c:
+
+# special case for z_2 in multiplication by 5
+# acceptable: Twist
+8065567ef082b16c20853487f54893012ba4762224e5c59f250dfbf82581e85a:
+d7067faeafd3e966e57525f930b3317c9e8b9c9a9ae946e76c1e4602a59a7e33:
+03e7a777e648bdc612189f3cd42d34e35736d3e52e6edc8ac873a58e244a6073:
+
+# special case for z_2 in multiplication by 5
+# acceptable: Twist
+00b51448139a61fe6c5fbf9395877d53d820ef59da3be856458b5eb90985ba53:
+8df9682cbe8802478a8531377e752cdde54738d528d639bea9eaf47702f8bf3b:
+308ef99dae1064a444fa90775b5dd5b1952d7224a0e5ae031df432640f416208:
+
+# special case for z_2 in multiplication by 5
+# valid
+e8eb9f6f62f93dbc325b833aa763a90f13f0acb2c2c4b8b33decd471ce70c45f:
+7d92706868aa09538638d633c255f333b9da03bc74b49b35941c57820cd3fd47:
+f33e2e86443a2c68823b72a2b59d6a028e0a8e283cfe29fea4f7aa22bd1afe72:
+
+# special case for E in multiplication by 5
+# valid
+68a1a7ccc50bab4b01e55e18cbd464aff43131fb0741e68d53cdebfc54f33051:
+dfb1ffc176aff84db30182d2378f83728f83dd1b33d79856f3da5459cf9df907:
+7b535fc31c6c2a3803d8bd45410a1781bd90a09205da28c9df120df23a9fa32d:
+
+# special case for E in multiplication by 5
+# valid
+e075bcfc165a471b2f76c3003fb0172c82f707137de2fa7082e43a87a255935c:
+12e81e838b21eac96dc130432571216d7a9b4a817f1938721d2267dd150ebf20:
+ca23a781da0911e4115a29a9f56447157c23bee187b0c17369c4f7730d781718:
+
+# special case for E in multiplication by 5
+# acceptable: Twist
+c0e19634dbf6460e1486930c46e8556b3c16d6de959904600549bb3e08603455:
+832a46aec02240d716fe22dea94ad566a3fafbeedcce35c83e41e58076c99749:
+cd0686b32ea4cddb8e13ff20a78d380749a5d4f6a3dc55d72f4813d949a0ea57:
+
+# special case for E in multiplication by 5
+# valid
+b84caa18acc3db37225d32cab4f60e6fba4acab1277e20425d30f94cab2e2c55:
+8c8033432bcc12d479f67d6d876b1c8e89f16a234b9b093322effa9dee94554d:
+a950aa57bb2beb9ed5d3228c7ef448dab69552f3d3b1e466accf41bfb6d5b874:
+
+# special case for E in multiplication by 5
+# acceptable: Twist
+2896818cddf572521943e9f0c5e845f530b740427588a0f6de2504bd5bf40c53:
+6df799bba6cdf5f46a57ab227f93fba491dad296a2fdb7e491921d610cce8f5e:
+54f5ae57e676d08c8f8a3cf891e36ddaab751093f92f409060c57e745941700e:
+
+# special case for AA in multiplication by 5
+# valid
+a01f0cad98cf2905b812d3530531bb3ac899391abd1eaf4a3ebed96ac6126f58:
+0c8090e1cfe7f761cfdf08d944d4aeb7a509a07a6101645b9a4c7c9e9c3d4609:
+2d49b09f81f3f6fab2c67e32f1bcead2ad09ac9e0d642b0873becfb64de2ab23:
+
+# special case for AA in multiplication by 5
+# valid
+106b36344cc4a5a389d8168137786806ff03cd4a00f8636bb7e758d456151d59:
+08352936c8afd8543ac95f24bce9a07e3e3235763ea512a584298967b83c070a:
+a199368e683c3036a48f4c5f32b32a547dd39f3d1007ca0a0bebcad0a8ac6f5c:
+
+# special case for AA in multiplication by 5
+# acceptable: Twist
+88f9a0d2354adfcbab2d12a0e09b3c7719c944384edfbaa27fe0731cb9c6fc5a:
+73bdeef8cc044f5ad8d6a241273e1995e0007dc9e6579046df86aa6cd97f5d2a:
+5aa750de4207869ec7fddab34c639559b1eb27ef244aaf2a702c84963b6d6e7c:
+
+# special case for AA in multiplication by 5
+# valid
+0811f2e560a205e96e28bc312bcad45fe8befefb7f6da5faa035311eed80b251:
+7fdd399b6ef4a3f5cade62e74113b29c27db15203f9b8e398d2c6f230051cd2b:
+a6947ee089ff28ce3644ea4c6eb33dbb20c7974fb8d853f4e146e2466177502d:
+
+# special case for DA - CB in multiplication by 5
+# valid
+40ad984066a69080fb4a315878e736096cc577dae4c42c40d893d8c2173b785a:
+f0173a96273c646fb63d13b0c686b89e37676fcc7178faf4a6f4601f3068150d:
+230b6aa1f24df90a60839179ba5e9de673cff11cab59e8020b20626c22090b0a:
+
+# special case for DA - CB in multiplication by 5
+# valid
+48b10cd45639bbbf83a0b28f0dd3ad0b7b00caf48d05534480556a8278116d59:
+255bbe7230cd2bee90d283f418a474ab30146ce5e801a0f5ed60ee8def3e6558:
+2299e384958bedd2c3d367759155136d1ff76e4434dc1d9e8212cdca52ea8421:
+
+# special case for DA - CB in multiplication by 5
+# valid
+e8fad77946e0de4cf4236798490b838948b82cfb29f8e7686001b11e8d961657:
+21accf97b7fee173001ccfcab21637c175ef5186ff0002502b3d52fa8c51e766:
+97fca065acd3b943c654997c0f125767f9abc4b7c9d8b7246942f12be65d9231:
+
+# special case for BB in multiplication by 5
+# valid
+d07babed90b27c4eacafdc871703bd036b720a82b5c094dceb4749eeaeb81052:
+5b40777e80ff6efe378b5e81959ccdcbb4ca04b9d77edc6b3006deb99926fa22:
+f482531e523d058d6e3fe3a427fc40dbce6dd6f18defbc097bfd7d0cdd2f710d:
+
+# special case for BB in multiplication by 5
+# acceptable: Twist
+68a3049aef8c069b906cf743286d3952a888bf2b9b93bc8775fb5adde06e9f53:
+48d952a2924ff167f037707469ec715da72bb65f49aaf4dce7ec5a17039ddb42:
+de88af905d37417d8331105345dabaab9fd2d3cb1ee902911c1c8eae2991d911:
+
+# special case for BB in multiplication by 5
+# valid
+18d8c3d2a4e366185a85c38698d937e13bbbafdbdab1a0a83dbbe89badf70756:
+a5ef265ccbc5c54021d34f82364a4624030f5b9d5ff7e63d7a379e533de5e742:
+075d18ccc984761b70752279e7f6a757208f6c11e29480c32b40aba128a4d52b:
+
+# special case for x_2 in multiplication by 5
+# acceptable: Twist
+18efcd5fe345be4985316695391d2c952eee13b0e1ee7584721fbe8b19d4fc5f:
+9051e55a4050ef4dce0b0c40811f16371e8b16932541da37f069406d848ea424:
+212dbf9bc89b6873a60dfc8731a10be11ab2dca4b172142e6c9f06614cd72852:
+
+# special case for x_2 in multiplication by 5
+# valid
+28ec7c693e222c72ac0815f1fd36661357e0a8da7bc996daeeeafcd21c013451:
+419adb8b1f2f87de016b0c78d1029a210492eb8cadd164b12cd65b1d57bf3634:
+379f9221abebf3582681a0e857f3da578a1b0121982b96f14b94de5dc8b24528:
+
+# special case for x_2 in multiplication by 5
+# valid
+78b35e7ae549308b6414bb610196c04f2af79d4266c86e8a9ce0c02bbdb88d59:
+13e00dae3b1ccc97ccd649088c4a7f32ca9976214d645667bd082039bbd9ab7a:
+cff2596b7afe36f4cab9c70133d7aa0f9914f9abc6c3b9895472e2a5894a8037:
+
+# special case for C in multiplication by 6
+# valid
+f0de9c5f8a9372f30c41ca47a55743ce697d46e32e7a9ae26d32503fd5222767:
+441c487a48f0a4989d931cd77a6142a0a13d1aabad82623ba8d94b5c374f4f08:
+d47c46b4329bedcbc1986b3c6d2aa9bcd027d6b68925175d35bbb536b3440801:
+
+# special case for C in multiplication by 6
+# acceptable: Twist
+686be5a12b310420f9bfb209381fd459a5ccd55c752b88337ebe89e1921ae765:
+0e67ee5c6b65aa802259810b2605f8d7accf9b49bf14cb4a536928e883172915:
+1d730158da880533dbf1e6c64a8e99f9169611660969b0a84fb42dd8dc2efa3d:
+
+# special case for C in multiplication by 6
+# valid
+a0c0337c5bec5ca24dea2f1d701498ae2bad87b8269ac23be113929fe4eb1963:
+dc9d7ef1cb49c191e258663a94e731b9c066c11a17d8b5fdea1987f5d9a00568:
+07732529a628badeb8d74946775ba457c700bf8390f46bc523fb64e471c86a7e:
+
+# special case for C in multiplication by 6
+# valid
+b8824cfce5550b5e17b12f74e28459cab34eb49895cc36bf645a0cf00e3d2d67:
+556b3ee7cd0d37979056ecc1f56a5677a4935be6e49ce28e394f8bfb73d13b6a:
+9e3aae35fa1cc80a359878e212180294ff6608dcb4929e91901abbf976f39c16:
+
+# special case for C in multiplication by 6
+# valid
+e02dba7335af8fb9168de2fcd310c2e2df4a3e25263e0ab9ada87bfb8258a66b:
+1211be5809605b54f5727d233c783a2a199a3db24ed4499d7b48c7603e4ad371:
+880f6dc73220307a597670f3282fc366aa66f04a0a9ca30d895fdde337afe825:
+
+# special case for CB in multiplication by 6
+# valid
+30ce71f856ceb874fe580039ca67e896e6d08207a73cd55db7059127c1342b67:
+505e7851e2352e311ca9536a1fe6c0d95d648197374ce08e4b8a0fbddf62910b:
+ea62b0eda2d7b249a42417675a2b82b1e6c0d69a4e7cef336448844d2f432251:
+
+# special case for CB in multiplication by 6
+# valid
+e881f46d4141ea69a671649b93b63e97dc67c12521d445862f087b2626fa2b6f:
+ddf4e90503dd82610c3a034b925a880b72dbde30c626009202b358c6eb00f418:
+302c4f83b5c5bf30c1e3afd9f643f65bfe56ca1628ee042b1ab7393bafe36c06:
+
+# special case for CB in multiplication by 6
+# acceptable: Twist
+e879752683cd73a834251c65749135e06eb9064d3ae35095d88cde14a02ba366:
+0e9c4431999ef1ce177e900d37ec6ae665e387e2d4fa27cba8e7baebc65c6520:
+8ff2ac65c85ee2fe9452fce460f8c87f9570d769cadddc87fe93ef8b7657c726:
+
+# special case for CB in multiplication by 6
+# acceptable: Twist
+20576ab456da26c18da5fbf06ec4d16564e111bfae2a92b9f6e1927c15770a62:
+5761d6c08624104d4117ff17c75e9211a591c9ca9aecca3a665a7ed844195225:
+97c91a23c3e4f3ff727d188a352b67ad490b62381566fb3e111cb67aa9e3435c:
+
+# special case for CB in multiplication by 6
+# valid
+a8467418b924c2c003c56e1610a35469356360c29d52aa557a2bb30fb8a9a464:
+e92d45b3ec56531266303c5113c46310c41650001065b4d87b02b382fc82662e:
+24346bb133dd9ae3ff02d2f50510b3a92d9030834d60e5af08b0eebbf1d4dd6f:
+
+# special case for CB in multiplication by 6
+# valid
+f0f5e162923d7c299388bed781199417ade097475515162d9590976a196fb16f:
+f38b63459d05e422ad024c2dcea5029a0a7a6b6c4c1d2093ce556aab331e2540:
+b3453c9c82a2d1d956156de2399cb70dd4e1ec53aea967e035753c1cdae13c39:
+
+# special case for CB in multiplication by 6
+# valid
+608fcf787fe789644a09bcab958f0737aa81a9e29d505f51035c78e374b9e46b:
+a7ded0eea45a400b8f5637154d42974aa98c92962314d822ef88b01383a9da4d:
+ebeb0c7b7a4165cd02a278f3a222c236eed83266b806d13494c1c3f98a2f3425:
+
+# special case for CB in multiplication by 6
+# valid
+58a3396d291eb23571b52d98a31549e514e501e8d0958ad9f25fe5a76c503e69:
+7b0ecb4c72ee147789d74813ced3ebe40f45c3da526ed1272952e453e43b796d:
+9213a53f22ff0cb5eca87b27b193c773bfdf4c01a193a11f37c157474e15cb07:
+
+# special case for x_2 in multiplication by 6
+# acceptable: Twist
+d805a7014755dd656f98d2b331f2d2d4912725ef3d03752f26f74dc1ad61666a:
+a244413ddc3a205d038d64266833eea1efba51ba62c9c6cdcdbe943be52bb00c:
+66484a4120e0eb0c7e0505e1d2c5d15de9b52b72e094c9bac88634200c557267:
+
+# special case for x_2 in multiplication by 6
+# valid
+40cb1fe06b08f068f7080ba07c695eda91a2bebeadd4db95c97dd7c91af2566d:
+ec3c8b0c10b1fa65dbbd17cf1ba5f86381284765709b07c5f0428e3d5bcd3920:
+384f2221618e71d456b1551651efdb708a161d7f89f5604b27eb872d4aa93276:
+
+# special case for x_2 in multiplication by 6
+# acceptable: Twist
+8021464c64c9d6d3c0c852f6972d11969b04c9e066562fa7f0d5fa0d98ebad62:
+6330d3e28a8b6126ace165a9dfccc6e4bd40dbc9768cfb16330cb7f27f906230:
+8daf5f4b84730144ea8a53ce39cc907e39a89ed09f0202e7be0d3bda38da663b:
+
+# special case for x_2 in multiplication by 6
+# acceptable: Twist
+707a2d710b32f55c6eba34898020a2fb981d61b1e822fca84c47d9321e279268:
+8678aa29cbc06e78b218d22a3e66c38ec0da8fdb0f2570c585c62517c9704f37:
+da8b7eba6f72c3f3ef33d8982093492e06be39bb0db29c465d95a8e52ef64341:
+
+# special case for x_2 in multiplication by 6
+# acceptable: Twist
+204a43dea79d779577581b8c2a51be66e1effce96425b7422b9ca65bdf1a4867:
+303289c2b1079ea59412faccfeba8c113d2299b9dcfedeabc42697b0829c4658:
+0419a71a08d3fdd574cbc932e8f1605933ddcdd9774f5614269b7ed850c8650e:
+
+# special case for x_2 in multiplication by 6
+# valid
+58e4741735d2589322151947a1ce2f5829908626886941cb1631d25a8a684169:
+3e6e16e02d44ebd94680832e065aeddcbb74af64fbb7c6d8367e7605be13ff5b:
+9f2fcd0c756288c1716ecd1f2a74864b93a7717bfaf5248858dcb6fdbea12864:
+
+# special case for x_2 in multiplication by 6
+# valid
+d0af3428ea5205f6bf8d4f1b4e4903cd76f04236a1c0b3ecfdcaf28b21348e63:
+a7c1716a41ed23a8870438714ff9745fb0e46f7a5baeb37c9a2d83fe477d146c:
+261ab6267c35a9755359e957473870522b7f923fe839f2b155408649cc5e8004:
+
+# special case for DA - CB in multiplication by 6
+# valid
+c0ea97e442e5dc1c8142bfab7089ecb9bb9c5ae372f9907c2825e678defae567:
+dad981552c57541c57ef395ed770ce5edc48f8015461b2ba7aa831ec593ceb15:
+9093bfa3ed3491d0891f02ae466e5e13c980df229db7404c5b9d34e4ed21c653:
+
+# special case for DA - CB in multiplication by 6
+# acceptable: Twist
+b0333f09ac1eaacd3cd617eb8832e9de488b458b735cb4b5345f517130c25d6b:
+c588dfe6e733d90581cbe112079749d8eb30ab8631134ec29abfb98b32e76522:
+6e88bb6bf75596bbe5f1fbe91e365a527a156f4f1b57c13ac1e3e6db93191239:
+
+# special case for DA - CB in multiplication by 6
+# valid
+10719099dc63bcc282ef525845c108897ac9fae9590b593e0d505d1cf167c061:
+0670116a435e8d9b7a12ffc4322fd6b149d0b1dc799b5c0957d9d6e42546e824:
+e6de74d2c5cea54094d7a70af03c768afe05d52a038bb72d56dcacf0ba502d74:
+
+# special case for DA - CB in multiplication by 6
+# valid
+10e20e4fda57084ca90f7ad572a78aa8e6575c659cd01f30c43c58040c20e860:
+8b200dd226c5c0f7e116e5388ba162438caf1dddf4edc3b6ba838c21b5929737:
+78c9c3aff9416a538ce3ea8fa553244528d1fbecbcf91695a33ca464ef76b85a:
+
+# special case for DA - CB in multiplication by 6
+# acceptable: Twist
+a8312df473adfec7171e1635f5bad44f0753a88a6b3174ec5ae762703ae25e60:
+419a076b179f79720096eaabaf03477e8f89d61f885c8d7f58f6eaa4fa77df5f:
+c1a96ccba08bdd82d0fc12e8cde4cc1f25cfd5276dce7f18e407ed0e4a898466:
+
+# special case for DA + CB in multiplication by 6
+# valid
+109697f400210f9a92de80a8bed264097199bc240e22767b54d8bb22050b7a61:
+aa34d772e9ace43c4d92f4f85596ab9ccd8c36c4f4cbddc819afe2a33cb8b216:
+2533b845bb83e3d48cffa8dbd1edd5d601778662d5da03759152a5e0a84b357d:
+
+# special case for DA + CB in multiplication by 6
+# acceptable: Twist
+d036308a53c11bebcb02e83688ad74fec43f8462ef4d806272676637d99b3765:
+1f06cfe464ccc0e27a5ec5f9edd9bc7bc822ad2ff5068ca5c963d20edd1a2d22:
+eb40a3974b1b0310b1597d1f1f4101c08dca727455a9d8224cd061a7aa3cb628:
+
+# special case for DA + CB in multiplication by 6
+# valid
+786e5a5ff37405c769d0d3788c3c1b05a62a8442c385570e4438bc5f2eaacd67:
+9d4b2ed7817132af5830e899627ea97dc39bd3772e82f2d05769a918273dc02e:
+9509757e289553cfa2cc71313473c3ff1eebce484ee237eae554fda3d3d22f0e:
+
+# special case for DA + CB in multiplication by 6
+# valid
+c01f66cb094289d728421dd46c6f9718412e1c546dad70e586851be4da58bf67:
+4e056b317a31dd96f8ec14b48474af587d195efcc2a70f01f052ef882d7b3a45:
+bad9f7b27dac64b0fc980a41f1cefa50c5ca40c714296c0c4042095c2db60e11:
+
+# special case for DA + CB in multiplication by 6
+# valid
+3877d9ce25cededeb572604f2d123df685690c26e181f777ed33302b82082966:
+72c60535e9c423f302d6a10796d954d778032cd4dbd40ca0f359e204d67b6f4c:
+51c359768ab0219003af193e2bdb8e5cc9f8e176b8db49e597afca3e7125e370:
+
+# special case for DA + CB in multiplication by 6
+# valid
+50b84618d073c4618f9aa69a3b8518da76dbb2127286214fb43a2b44503b9969:
+5856358ed420047cd084f17ae696bad79a4d26c6d5bb79bfb82bbc6332442d51:
+fa9fb0df4cfbacd0fbf3262d3a1bf8d7aacb45f73bf94671775e509c8043df7d:
+
+# special case for DA + CB in multiplication by 6
+# acceptable: Twist
+109acfa638e112f6bbec21e352a74e8fc9b7ffe5d9dc28634eeb516e59830a63:
+c31e37b04332abca8315f317171566aef38111f622d8bffa29c23c0151cdad6e:
+91ac72b0ed8d7fc4c8846b8a2530d9fb8f0532064880c00dab100c977697db28:
+
+# special case for z_2 in multiplication by 6
+# acceptable: Twist
+685c0784aa6d194c1b859bda44c4e27cd1dfdf34776e498dd03d09f87ae68a65:
+b775e016b32a97f49971121906763f3a0b41689092b9583b6710cf7dee03a61c:
+11393bb548813e04fb54133edbe0626458e80981885e1fe5f3377e8ebe9afa52:
+
+# special case for z_2 in multiplication by 6
+# acceptable: Twist
+18e9a05a20436cf0dbc3d5b92dac8d996e62ea11fbb3445f29195fc75a8beb69:
+f8bd0e7cf6ec6186f205ab03ab72c8f6b3cde8f6ad9b166916a04d43d1d6d546:
+0a83a224fbfcbc5d0f07f6dd8ebb2e9bbee8134f0fab268002ce837f5495d833:
+
+# special case for z_2 in multiplication by 6
+# valid
+00e099eb23125dab5ec35a419d455d0ba8c01da160f9354e9fb21e6a55d55c64:
+8dfee48ad8b367488ea4dafcf7086e305356a80901f87c720149a5f522337453:
+45dc39831f3471d7466bbe29c8142b1a6d6b00c47fea021be2ffc452d9046806:
+
+# special case for z_2 in multiplication by 6
+# valid
+b0ca251e0dbae7324a6ca0c2c8d6a888edd12d1447d400a47bcba004b648716e:
+8f68bfc57d792c322ebb27f44a37c1c93e7eb15c5d5fcedffc1de850487b3372:
+a29005c6b9dbf1707dc2adce4506b55831e8675b7d2d54b0c1037741e3bc611b:
+
+# special case for D in multiplication by 6
+# valid
+a8b64b8ed397773b8290425ca5c2f7c3e50fac7a4781bd4a54c133781c9a1360:
+ff0f15adeab334afeda3916785ddd38d252dce9876c2357b643b5dc2c06a3b1d:
+9f04e42c1b2f311d87e1470a4708bba25ac6ffd3f7b486f9b6b502ecbb2c004e:
+
+# special case for D in multiplication by 6
+# valid
+d0cd0db51ff232afa0919d3106fcb3a8ae581ef12d09c877aa6f31ef74eed068:
+1076fdc827f2550ee95ff9a15d044aedfac65b5e9ba809f62438ccea54637a29:
+688000bd60af375b4eeac4a7d0e0782c0e6188eabdc608b732f49b4d6ccab44f:
+
+# special case for D in multiplication by 6
+# acceptable: Twist
+204a3b5652854ff48e25cd385cabe6360f64ce44fea5621db1fa2f6e219f3063:
+ed1c82082b74cc2aaebf3dc772ba09557c0fc14139a8814fc5f9370bb8e98858:
+e0a82f313046024b3cea93b98e2f8ecf228cbfab8ae10b10292c32feccff1603:
+
+# special case for D in multiplication by 6
+# acceptable: Twist
+88109b1d0e7bace44d41a15d5bcbcd36968c5b8b47c0a2c606b57c4a68cc5f66:
+12e1589a34094af5f121c9bd3c1119f2b1f05264c573f667a748683c5633a47e:
+1fcc50333eb90706935f25b02f437bfd22b6b16cc375afff8a1aa7432fb86251:
+
+# special case for DA in multiplication by 6
+# valid
+5082e497c42979cdbfdd1b3b0653cfea6f2ceb7d07639ebf3541866bb60edb62:
+151f54a8a899711757b3b118fc5501779d621d25227af53d0af00b7583ba8824:
+fac30a74f4ca99f6cf233065e9acd826690cab364bf69320b58095783ed76e11:
+
+# special case for DA in multiplication by 6
+# acceptable: Twist
+f85a8db44f9e56b11729f51682a9769fc504f93597cbe39444616b224532106e:
+a819c667ed466bd9a69ea0b38642ee8e53f40a50377b051eb590142dd27e3431:
+17f6543c4727e7f129ee82477655577635c125a20c3dc8ba206ca3cc4854ca6c:
+
+# special case for DA in multiplication by 6
+# valid
+505a076641fac398fc7d8c629937f42db559db5e12052ad366d46d7b20e95769:
+40b053d056668982a1f550be95e16348e303945f53a3ac64491a9a56d4095b71:
+889a8d611e0a7da71475e7c93a2d7f6f7228c787a00ee5cf55474adc376ff762:
+
+# special case for DA in multiplication by 6
+# acceptable: Twist
+e8db2bf1af5b8907420789c56e71414706aef0d9f6ffaed0c249c3b7ab14bf65:
+e7dd0549a765bbef34be2e8da18a1bc1b989a8b0614d358ebf38c12a9ca64079:
+37232fb397af27f5fb5ca493284ff1c5d25786b0d716c73b33aca8d42265f318:
+
+# special case for z_2 in multiplication by 7
+# valid
+c006ab1762720882017d106b9a4675fdd47005657155c90ca61d4cbf7cc4f973:
+1ee1b9a74604ac31c3db83280170e3811504fcc78c7626b5b2c07a99d80daa0a:
+a1b30418436ba1908804ffcce1be2cdcf50c61a8e3938d95c790abdb786b8022:
+
+# special case for z_2 in multiplication by 7
+# acceptable: Twist
+d071807d607953da432d8574d5f3f420676dafdbc6a285a36e1d737624d77c75:
+f226c2d6bd7831eda1b51ee5aec29443a507ef9f7a04e2340f349dbf14933844:
+a5976fda89954a81e442107f9e416a2b4b481bbd4654ebc0c7b57a78b45b4979:
+
+# special case for z_2 in multiplication by 7
+# acceptable: Twist
+304b526f6fe994731980c0975529bca4d061017fbec56f6070d42678d3e11177:
+c5197312de3a7a3ee11b29873bae3fc8c85109c66784804f89435db210fcc24b:
+55b5b5eb38b127617ffe00056d84d35a5071d18783e3a82b5f4e131b1538b150:
+
+# special case for z_2 in multiplication by 7
+# acceptable: Twist
+982ddf2c035789379b8a58917d5c3c6c061b503b19a0028e01894c2eb371d079:
+590ed0b879319c38a19962a5d216ff2bfaf33555518877969c20c054cbe43e56:
+0080e5b9985a960a832133812a7ab9951c6b2c75894deb3e35509190a6bdf457:
+
+# special case for z_2 in multiplication by 7
+# valid
+78cc3ec0687e3e53d9cec56b79d11bf049d173f127f5b40fae122a6d0016cd76:
+7c5f0143a6682f60ccad16f21150c7bb5bc6f807254d08b353fc96ce07bceb6f:
+5241222226638c4bbbc98792cdbd74882ca2e08aa2edf313070425031009e925:
+
+# special case for BB in multiplication by 7
+# valid
+c86fc76650cf3b58837aa0f0633560415241c6c4f8f293ba0222b7d6a3875773:
+010850a0974d3e89c029d252b46f739548294c0f9a23183863f9455b9559c211:
+63788190b10d7451f5fc2b82c421151db4f3e22782e392da6d8d3aba2c344306:
+
+# special case for BB in multiplication by 7
+# valid
+888d51c0a2230369e5b65a814b3213dde2e62f2eb95d0971486b733e4f90c174:
+ad1dd82c23d6a0d5fe0f2a4561d1c16733a3e1e6afa6d902dd077dc43a961628:
+e4b40974a166ac49ed831715c071c751752744b891465e6c45001855aacdc362:
+
+# special case for BB in multiplication by 7
+# valid
+68bed425d534315584d80f79da6eab9b7e6036b51fe62e1ad933e266640b4673:
+d0c0d6393c41f4d7e0d5e850b7716f401eda1e028a4ed4a05bea8bf81acfd930:
+514a4cd0676f1c3101c8c45c17ad416bd33e20a405544fc1a60449abb22fa104:
+
+# special case for E in multiplication by 7
+# acceptable: Twist
+98ff2856ef44b4fa14d86782ea793828bdf6f1ef9b669cac1aae338a7bb69376:
+0f460100d88a1d316dff02d1b22ffb2e42d99d0b92474fc3ec7d62567d0cf112:
+ed83e810ce5ff0868f8589623bb13478dec1c22326c92765ae5e48c84bbabb24:
+
+# special case for E in multiplication by 7
+# valid
+b0cdbfdd98bd988d7c6a530455c51c57dd33fd2c7aee3961971bd3a31388fc71:
+13756a411ff3ae0c39222dde0810f08c432463162d81ef061071249a48439e15:
+ff94862117d3c6edc9dd5f4852fa8a589452b924ca8a75cb23b3d68dfed88c4b:
+
+# special case for E in multiplication by 7
+# valid
+e0677644ed4935f01e052e9967302d0fb78ff22bb92fbae0605f3ee54e2f6878:
+8fc1fae969a6185404db22749ef6d225de86773a4d1bf3857eb8fbbd829a1b47:
+1c94868bc8acb3137498209b2812feb53501389f5aa37fecbfd5cb54e1358e0e:
+
+# special case for E in multiplication by 7
+# valid
+887b61553843ca99ad1ca92253a6fe082b82494752513fd53ff6530f54c40572:
+7bab0891ecb9e72a15771f0a4fff90547024206339c340b1a2fdb53bcfb86b59:
+adbf3b439b16dbc653578f53374ed3a86f9c0bf1f736573349773bc3b8d60734:
+
+# special case for AA in multiplication by 7
+# acceptable: Twist
+00615e4697014fc12484ef53a1440206410a8df78caa0bfff82161db83fea574:
+102e95eadca7c3c28e5d52336c857bad99ea246f299b06334f401276f49ca814:
+3952efb93573ae9ce2162d10e4b8c46435859f3f2778db89f72bc579e695cb51:
+
+# special case for AA in multiplication by 7
+# acceptable: Twist
+58175113550faad56458fb375a6cb3f05df2f6ff3c4ee09d4a6ba643e022d17a:
+3548c16bf31afdcd445ad9bef0e60d7bd6195aa591ca8c82813cd7d446226720:
+96128f929fc03c1269d429f609a1a8acac7a758e3446a125ecf4a359a0e37b73:
+
+# special case for AA in multiplication by 7
+# valid
+009738e1e6efef9e2cad8b416fe90a098eb5cb0199f2df5218166c7b181ea079:
+ba74e766d44855ec93bd441aa41058a4c4ad2be63c639a3f9a87bde51eeaba20:
+fec3e94cb5f316625b090c2c820828ce0f3ee431e8d6e12abccc7ef2bd0be81a:
+
+# special case for AA in multiplication by 7
+# valid
+c82019159be792747a39f388ea48a8c568594e3383273e51100721b376e8ba73:
+9a5a1d37e5010c356aa80afb347c3d613542ddfa0be7abb8e8cdcd6674411449:
+96903bac9dc60b6178d734890c25db4bed9ea4dbcf6fcbcdc90e6f5694c8b21c:
+
+# special case for AA in multiplication by 7
+# valid
+10ac9f8383262ef280faac1e4da15a7de4f2cb74af33b50e0d82dcb85d8bcb70:
+630847e28274dbae5491210303c85a359074ee742957b0fc3c9ff55d9e019a50:
+50050d0ab1ddd2dd90c460ab8f09e1f80e37cae57d4231adae10c10a4a2b003e:
+
+# special case for AA in multiplication by 7
+# valid
+b84c098382f6e37d510cc33e62ddc664e02c8bb6ed9ed0e5fa78cc099a26fe73:
+11749b00a45067af2c7e7d50f8d178d5a9fedb8f1b69b239763885bc611b136c:
+9170c4c628d5fcfd0ec719cf6e1796dab0a69e46d6379fffa247d444a0056041:
+
+# special case for AA in multiplication by 7
+# valid
+78cde8930a1d81aef6601f71409728854987578b0f8349588c04adbe2c1f6e74:
+df1021d8f95950afde77c86ba5ee2f5876ef778376a7fdc7efb8dff0e4836e7b:
+d7d2a82953f680cee0c81c4d00fe628ac530ce682eb7fb3b0af24f804a58ef5c:
+
+# special case for x_2 in multiplication by 7
+# acceptable: Twist
+b0fe7b06b9950600b3a7ce1d7bb2a1d984194cc9d6c8964504c364dd5c875b74:
+2743ba408d5f68c65324a485086a004b6bbf784cc9e8b1a7dbeb8c4b9414b018:
+a6b97da989dccf730f122d455152328051c8ed9abc1815c19eec6501d6cfc77c:
+
+# special case for x_2 in multiplication by 7
+# valid
+f0c9c3984854d5bd599d3819738a023eb795e93586dc0e5e29b1c870c612d178:
+cc275a2cdd9125e52f20ce2abad41f920afa5a643fb7f276ef416f761d689f1e:
+b210e368729501d9f9b6ebefbebae38f195f91eaf2a5a3a49288bb615ff2216c:
+
+# special case for x_2 in multiplication by 7
+# valid
+906c2f12be89702db26fa7ee905ce36525d2dee4e96a879ca07da097a6aa5075:
+4929543101ee7ae239059cd134c35d400e50d0821441351d0fa6c3d54efb342e:
+b9e3796c58701ded4237c52994501cee14e18f2fb02b781a8400923484bd4a6c:
+
+# special case for x_2 in multiplication by 7
+# acceptable: Twist
+f026031ea373e1d16e6e7e0357bc96bc093f4b6bb76a738cbb54fe6cfd2ea271:
+1324e0368597b3181555bb5b2cc7b7ebba46931aeabb6f05ababd4240f0fb933:
+6dcdf8e86903b0caded124d8a7da18e623430ca869aaf267d31029d93de99e66:
+
+# special case for x_2 in multiplication by 7
+# acceptable: Twist
+703f4ac8667d77f9536045cf748f18d42345e39ccab10c18dde0f5170d307f73:
+c7f3842297d6941cac63d6f1bdaea0709437c82dbc9161fc1bae6c79d668eb44:
+385ddbf2505ebf537bf5e976b61a4b69d190ae965b7e4a81ae4e1c16b7148748:
+
+# special case for x_2 in multiplication by 7
+# valid
+c8a96ae4e77271a0680dd24fcb09f9c5d3ee8316536eec7cc2276597e50fe37f:
+1e4660ba865fb8085afd4692885d74237fa3bca5af4b84ba3de400f16a5ac45c:
+0fbaea73f9518795e026c1fc1079c3738aeb9ee9c8dc9761d65bbf8f94e30154:
+
+# special case for x_2 in multiplication by 7
+# acceptable: Twist
+d0dde8eda38c3783442864c0cb46a0e9832dcf784c21268a21bed2cace87cd70:
+2488bb6fadb79d46585ff01c160c5b4172799d92bd168edceb65cededc492762:
+510c64151e5d0737fc324bd15fb5d3966908751cd1a06954b556196655ee5540:
+
+# special case for x_2 in multiplication by 7
+# acceptable: Twist
+c09cd47e1ce53604f14e4e13426c8f08962f556bcd81f8d75375b1507c6fda78:
+a0c1087811af1491171bc51691b8ca84716af36c4baa764ec536280cc1983d6d:
+23ef825e1c8e6e64428001a7463e32a9701c81cf78203e6ae753740c91570e6b:
+
+# special case for x_2 in multiplication by 7
+# acceptable: Twist
+e09a5f74f318f02303857aa0208d76913d9e240a80549d12013118bad620597f:
+cc5c97934607d8b981bce1d6a232bb3aecc3001f698ae1ae84938fbf2861077b:
+0e55a7ec1a2ddbea1ac5981200812232f7f4c3a60ee3c9ab09f2163bd13da329:
+
+# special case for DA - CB in multiplication by 7
+# acceptable: Twist
+706cee5f9b357c03b2f1913294f6e4f0ca5a190a87d30268327d0cb6bdd5bc79:
+238de7fcc8a3f194c3554c328efb1215d0640ac674b61a98ef934ec004cfd73b:
+0681036a0d27583ba6f2be7630613171a33fb8a6c8991c53b379999f0f15923b:
+
+# special case for DA - CB in multiplication by 7
+# valid
+40e300cb1ff260574f85b3f04aac478464a86e6203b3d4656418f4305157877b:
+ac9fd80a45da109fa2329390e5a951cfc03065d7bb4a7855826ccb22c3bfeb3d:
+67b88774f19bd1081d6f23656a135803e34ae1cdcae10818124a78569c299f42:
+
+# special case for DA - CB in multiplication by 7
+# valid
+882f78b4558b7faa835904c9235e32f300fc8b5ef0a718406a5c8520ca54d071:
+a45ab1dc2fa2c50718fb4985d9791401e8d2d34ffe3cd93cffb4e870cce5e855:
+a512e864bd898a5ba6551adcebd836c6a78e7871728e1b8ee528d483af276104:
+
+# special case for DA - CB in multiplication by 7
+# valid
+d8649b735590a17d0fc4c378fbf4c2f7d6600569b2e84cbe0ff7bcdbac0b5f71:
+1761d3d50ba46b446655aa6a8d9b8b75aa5bb24a7953208d5b69fcc38f18ec7a:
+518b778cf5e976c60235abcf6211a18bad2a8e693ab261074c7fab43dbb5da27:
+
+# special case for D in multiplication by 8
+# acceptable: Twist
+a8edec59ae6ba23813ec54d66df152e0626762b97d4b0c20e0dd8a5695d86e47:
+dc99ad0031463e4537c01e16629966d1b962c0b4e4872f067ca3c26ccc957001:
+6cfa935f24b031ff261a7cd3526660fd6b396c5c30e299575f6a322281191e03:
+
+# special case for D in multiplication by 8
+# valid
+1098723ffe567ea6dcc8d04ecc01efafeea0aee44e1c733be8b1e5d97c8b8041:
+b32750fd80d2d7c62c6b8e39670654baea5719a3e072e99507fd5bcb23898264:
+c623e2d2083f18110a525f2b66d89ed82d313b6a2dd082f6b7a6e733134f5a06:
+
+# special case for D in multiplication by 8
+# acceptable: Twist
+a0f20df98b49218ac832f26fa8c218a0d6872eb7aea07c1d43c9ff699b465b47:
+e7b3205777b375f1b1515a50a16a6067953ff221e12b4f416d74fb28c1c85865:
+388ea421650a8d837bad8904018195e99ef494c2d170b93ee721a67d2c108729:
+
+# special case for DA + CB in multiplication by 8
+# valid
+30473a77a98374f67d5bd43df231ce142916aea0d271e72333fa47dc441a0247:
+21cc338d7869e5863349cc739c8a6946cfc797cb82fbf62dcd2154844b106003:
+b9e5728b37435b1d339988f93267d59f3bd1c517851c5a258e74cb64aea73d2d:
+
+# special case for DA + CB in multiplication by 8
+# valid
+d8657be3a30fc85fb2f3a68e92ace1b31b26e76e6bdb6727aea507cb7c10dc45:
+c34217c02072d7e2bca0454525030780cfb60215d7ca82dbec8f4a59034c5f43:
+20b67b205e22ce87fd44a8e8fd10a6d8890b9270b60e1c6a68b4aa78e6e37961:
+
+# special case for DA + CB in multiplication by 8
+# acceptable: Twist
+882f5578ae4a13d8f5af473bdde1709bf2e059df809ee05b505f34de857c3447:
+8abb8cfd60c6f8a4d84d0750d3b40a4f846b30edf2052fef7df84142cd0d9e47:
+5faba645fc21f9421ebd35c69bdb1d85b46f95e3746ff7f4886bc280a9ab2522:
+
+# special case for DA + CB in multiplication by 8
+# acceptable: Twist
+98294db7cbf4958bfb3ed21d5d5c91e13cc8dc27b3c716c86f7167a4819f8741:
+9fd7b49a08f206688d72db737df8e517aa7b764f5de7c9a2b1c3fcbaa985f64c:
+9cb8a0f4ad86a27b96ca61242eab198db2767d3862dd323e41368fcdcc5fab68:
+
+# special case for DA + CB in multiplication by 8
+# acceptable: Twist
+789bc4047ad81b9b6656eef298b766e8763a2f8ea64e374a603dc1fdf2eee146:
+c4fefac7acd448e8fd4d6ac4f5dd1bc21f2c67d638444060918fb344aa77e757:
+4b42fcf84b51b2b82f1f70b3cf49bd9dc6ab2672920a8de37e81ba7e99acf734:
+
+# special case for DA + CB in multiplication by 8
+# valid
+801ffe4e0f6eeb8a50c8fe79663ff585f9d6aebcfbf4b7edc676c693900cb141:
+a8341deecc0be6db11401ef7f884ac3ade35650cc21f14b5cdb0a5cf0ee6b15a:
+e55fc931669bd02d1c64689eda62648212b1078c43b5caf97cf9763ff87a3455:
+
+# special case for DA + CB in multiplication by 8
+# valid
+e04e412383a63b338b70e1be5fd75995350321dee428aa4f3ba62a50a3b0de44:
+55a0e6631a52f29fb90a1777ccbc69ff94547459d541f72e8316e4d616535a67:
+87f7976a17f3e03a7f1eb74e6db950b8c0994f40b7903495599d227725809e01:
+
+# special case for DA + CB in multiplication by 8
+# acceptable: Twist
+382dbe9f10158bfbb7d1d79a35a7809214899a6b8572b35b55875d79bd2f1640:
+7976d520f1a2512d564af41c68313f5351b0156d5118be4817f192798ae9777d:
+3bb3e30105a71901b115065e39bdb3e053d387b39027b12c92cdf4c638adf00d:
+
+# special case for AA in multiplication by 8
+# valid
+60c9af7f4d03136a6034ae52deadfd9d4f274ad8122812eb92a53169c8354141:
+a26a722f7ba71ccfc96ed8e108d7c9f842d17f92051ee7d429ea7fa7908ab907:
+f5cb3a1b76185a29a6360b2142feebb11f3d08f4fd8d73df3a5228624a521c02:
+
+# special case for AA in multiplication by 8
+# valid
+283fae8bd8b294de2848056449751965abb5c7fa86ba4c2c5cdc3bb524dad140:
+ca3a2d96f5dda482b002324cbbdcf1dacc9815eab797c7151c3a88c75cded621:
+b0b47868e70465ee2dd737f1ba5a6399e09cd813d72da7585ab45c946cc28d4d:
+
+# special case for AA in multiplication by 8
+# acceptable: Twist
+401539703ca4980db4ba42c59fc29e83b4189f2ddea53ba54ca966c06898a640:
+eebd858850b56febb707f27a7aad5ff5ab4b0e0c73b9c86ec4ca0f42e7f38e75:
+581e4b12b0f39a7cc42dee4513ecfdd20b595f905f17ad8c1fbf1b5cb2068b31:
+
+# special case for z_2 in multiplication by 8
+# valid
+c8eb056286e098e6b2c79e42f007ebc6ab3705346cdbdace949b5de1e8c36743:
+c800bf799783275eb93312b43dc032ccdfb00a4b77c8b3772cd2fec8db7e4a09:
+6bf264532fc70a6a7e459f4579eca6b84f8f76ab85c3264b20bca725a6eb6c40:
+
+# special case for z_2 in multiplication by 8
+# valid
+487882956c49c69fd0e2d7277a24fb1dbe4b0365b36a13f63440248bca2fbb42:
+7bbc504e04d134eedc13f06dfdfc69c518257a3f374040a49a8d21dac109110c:
+690305c9e192cd8a513f705b3f101ecdf3db1ea15a09c4a1bce3a8cdc3a1a93f:
+
+# special case for z_2 in multiplication by 8
+# valid
+9876010f4d64c77ffc4d7dccd72b9ac82078deb883609650b8cff8a686719d46:
+132533db62aff4fa06e96314383bf58ebdec5183a19f2e4cb17552ae19a3366e:
+c58591b33e490e4766ff7addff570ce4e89a98338015a55df3d2f232aea3fc4f:
+
+# special case for B in multiplication by 8
+# valid
+a8a5d4f7894a519537babfac736de36054f508dae434b4fe63cd5633846a2647:
+ceb90c56508cf330c7f25bab42b05b5612a8310690107ac63a404c0ade788009:
+3d145851b6ff2b92b5807ed1df21eb50c9f24c4474d4721db3abb7356df7b764:
+
+# special case for B in multiplication by 8
+# acceptable: Twist
+f83e4647e82c560aa082c59641e13bf366be8f24dc01d14801e67841160bed47:
+66a09767a0d83bb18d404e1200375a745d1f1f749d5dc6f84a205efa6a11bc65:
+1401829aac4e64bcfa297a7effc60477090d3627a64a35b872ae055d2091785f:
+
+# special case for B in multiplication by 8
+# valid
+58c6b94bce9b15f64946c2aa6a4e383b0b2d4365b7997eb2310ac4eef1803145:
+39d431316307c85747bd2bcf4f9e0f8892ee45df15f7806ce65147d97f503478:
+a0ebe6908c5472f937769b9aeb313224437fc5d73f4f866fe7ef41f30e359e09:
+
+# special case for C in multiplication by 8
+# acceptable: Twist
+786a97207adbd4b0d6bfc9f49b18660ad3606c12e325044b8690b4fa07874641:
+84c92d8ecf3d0cb22dde7d721f04140c2d9c179cc813ce6cf8db2dce6168880d:
+07538f1b6583041c4949fafae3349d62f9dd302d3d86857af0dedc0d5ad6741f:
+
+# special case for C in multiplication by 8
+# acceptable: Twist
+282310210e575a59393cf19bbe6e24752dc247706f1e0031e5d39b2de4fff745:
+a9cedb9e942a47221e4296953220d10007db327d2acb68da6ef3a4f877b8ef1e:
+1223505fbb534c1bc6108e6b98b4f0af29e11158c02d333d6559beecd6d3e558:
+
+# special case for C in multiplication by 8
+# acceptable: Twist
+c8bf2fd4c40d00f1465aada682b12fa92dec10343484ab62b8871337de1d3345:
+64e1c0c5f59405bbc6c7db41a3485cc9f91c183b0f2b7e1894a7abd8fbbeeb23:
+ee031868165f456f75907bf39742b820e0f8e6df9f9768d757d408e1cc92ff7b:
+
+# special case for C in multiplication by 8
+# acceptable: Twist
+c06a4a4b70f613136f18c0f88e2245086c3d1a52717210a21ac9d63682f2e740:
+a68d2f55e60eac7983926310f4fae13f95b2bbf140be5ea91751884d900ab44d:
+c954fa7b042c32943e03191e367d54be0085fa8950ef2bec99620df79ecbea4b:
+
+# special case for x_2 in multiplication by 8
+# valid
+20596e1dc56596823d37698dfa699c79874aaefde797f863ef92135980fb2043:
+6d3cd623f26a7453fa05a01ae758ba84d3c58d93d60ce32735a15e0d053d5b12:
+7c3219b3c1fae1f95590ac843efd2084a1f4bd3efa2f592f022032db64ebcd77:
+
+# special case for x_2 in multiplication by 8
+# acceptable: Twist
+38141518e8e5efa1d031c6c4d95480239f6c30b8ccd8c751a9e04bd3aec17342:
+8f195547346b3d53b7ea4f742b22f1ef7b3cc01a7d3dcd19aa7c5b03f31bd214:
+a31f6b249d64a87c4aed329c6c05c3f2240b3ca938ccdc920ba8016c1aeaeb45:
+
+# special case for x_2 in multiplication by 8
+# acceptable: Twist
+207147f2b68fef1efc10a04f988f0eb18b273b0b5ed17aa7af32c90480e19b43:
+ffc4fe2c2127a309c739565651e9812f834a86dbadbb78776977f786ecdb0217:
+4cff9f53ce82064882329a18ea4e4d0bc6d80a631c87c9e6fdc918f9c1bda34a:
+
+# special case for x_2 in multiplication by 8
+# acceptable: Twist
+488084537b840f9c93ca57b3ee80491418d44221113e03f56355302604d03547:
+8475babeeab9980d426abd5323dfb335b219e129bddae4d6cebcda50754a6825:
+248d3d1a49b7d173eb080ab716ac8fde6bd1c3ed8e7fd5b448af21bcdc2c1616:
+
+# special case for x_2 in multiplication by 8
+# valid
+28cfc1d03f5c7428ff3e20b137268b33ccc74db03582d2127c566df4ac99f441:
+81f90a2f6633d30c2b72a25795d2a49463a80b6b0edc5aa68bae4bf738185539:
+66c6e70cf630be90a2c88fcde7f58cff3868660fa96406e8df4ac677dbd85f50:
+
+# special case for x_2 in multiplication by 8
+# valid
+c8e37d10f3d03db3f43e467bddf98f595cb529ad253c20d491282d1400b9e740:
+41626e33b3c8f48bd19e49ded307f2b63bde705c4f3cdf9d4f92bf37c48cba42:
+06283fcf69dc83e99d92e5336f499a1d8fa75ed2c819b5ae6ea8094454324b27:
+
+# special case for x_2 in multiplication by 8
+# valid
+00237e91406a7b4db61e780c5976fbb926cdace2fbdfdbcfce65e6dbe7782a42:
+ebb32f781c0e89b252e611f9d8f79f8567874c966598314b2f16aa44cfc07843:
+7d2affb43355f5db1294daff55f59b1f17e7d25bca20746f12484d78e5015517:
+
+# special case for x_2 in multiplication by 8
+# valid
+489c4184a23a8f5eec68a31b41aa2c0392cd6fb123f10acdb4de75292b4b9a43:
+fa75e6f08ca815b4e42af24a8e057c9e00e828e33d12c0e94d1012a758336744:
+ef8e78cab091d667888489fd3a2ec93fb633427d02eb77b328d556f2b2b0e266:
+
+# special case for x_2 in multiplication by 8
+# acceptable: Twist
+c05957fbc3a0e2c22a2aef627651ca1e99307b82a0c6170f7950a334f3004941:
+4d96320cdb0ca52655e91118c33f93afe4ae69e9e513ff4506750b8ea784ce46:
+c8d85bfa74b4b26461297b350c975183fea9d33ba29c3a4934509c2ecda58a79:
+
+# special case for x_2 in multiplication by 8
+# acceptable: Twist
+60111c6629f73635985be964b845f87a88ae5652d45bb1451ce8cfd2ea45fe41:
+c0ef1b7c20237db370501f24274e4eba91998ae4545f937007e1c4a2eab63365:
+22557e0d8741ed2a63afd5e313aa1579fc0c88c7772e23a676c94b60c89df577:
+
+# special case for x_2 in multiplication by 8
+# valid
+58785889a216d15456582d4e1e3de9e9ca4a432954416d81caf52b2b434c1746:
+d534d8ff4d56a73ef7615e94523b17e35edb3d0fb87e98c68536f63f114a8d6c:
+54d7fc17bad00296ba50b0f3d5bf8fb83f82d571952a5fdb5a494120cc61446b:
+
+# special case for x_2 in multiplication by 8
+# valid
+60bef38a3890ec1ed05c299fceb77db5ead4b88d9e931b0f21d664f77df9b544:
+733a711ba01b6e9b64a0be4cdca8c7cf3c66df2435d5248fb4413fec6ee03f70:
+db6851b12585bc11be9362c96a545c6f2ba55f04009792463b96a38cb9b3f07c:
+
+# special case for x_2 in multiplication by 8
+# acceptable: Twist
+5854ee566878ef8b7ebaf5a058306f250edf0c84fd52af2d74b7ce3c1edda746:
+35738dd539d60f69cd1a1cffc8a42b6af68fe7de45392d02831e2a77500ea278:
+f6d1a664257fa5de3d4d57f04eda2976bf1e35cc3ac513e1ee84d57d2135ed13:
+
+# special case for x_2 in multiplication by 8
+# acceptable: Twist
+985b551261fce38ddc8ff3add32f5c26811d271b9a1794e249dd76a38df28446:
+ce932b5af4be4721f96f7b79ba1c43b20687d4af49c37b58dc894279e04bb578:
+f8f7625ac5bde63f753a9bb4aefbfb9c4647207708af9d774ef08ff1b1e5a354:
+
+# special case for E in multiplication by 8
+# acceptable: Twist
+8815052344dcad97efd1341e9072a808cf999e46e52cf04e0cfbcd9901e18d43:
+e3655448339e4850806eb58abba0c89185511ea72c37c49e9583ee6dd235d213:
+5e10dfbff4443efcae2ccc78c289a41460d5a82f79df726b8824ccbef7146d40:
+
+# special case for E in multiplication by 8
+# acceptable: Twist
+b8e032e9e5ffbaa004390f3a0b900bc7cf5d11238b7ec964afc4bda2aa6c3444:
+4d16965b1637e9d7ae8feb499ed0553962a9aa0022d1620c928072f6501bc41b:
+19d7b44c1847c44e8f37a22ab69c180fd9d787f204123013e1b16800b9cd0f57:
+
+# special case for E in multiplication by 8
+# valid
+7012852211f6536fca79937e7e316c9149b0e20ea03f951e1bb072895ca0e044:
+c6b9e6288737ad40452cec1022871d90af1642d10bd0a97792b1a9c8998e2220:
+db990d979f4f22f766e7826d93554e771b361de461274d6c37baadeb8ef7be4e:
+
+# special case for E in multiplication by 8
+# acceptable: Twist
+d039c1b9ec4763e0ad8a0ef2b0870297d0f8b487e660595a484105d180e14a47:
+d566fab505ac4c7a3dc3b9403ef121392cbbe21216e5bcb8eab2dc9408986e34:
+6d7fc5d4a8f534b1bc0fa5e078104234675c02664736957abdb27df6faf07c00:
+
+# special case for E in multiplication by 8
+# valid
+58efcbc8777c1b54f09c61a216efd427292eb12312dbb3b32bd45254a6683e47:
+468d35ecfb6d9b7272523276cc5e13760519667f0e1e3888da4c56955fe91151:
+539c8d629ab51c2f3ea7278fd5f1c31b6c150a82fe3f786b93ffa159fd6d9316:
+
+# special case for E in multiplication by 8
+# valid
+c8d73446026cd0ea795773c2eb7b16348cd5f228e352dbc77328c2d8b9cde240:
+1929538743977dfea20bf4927ddabb2f3bb15cac2461054508849718854b5568:
+dee3fd19c8f296415448b21af44385ec46727bbe67d4839b93efe2f680e76d34:
+
+# special case for E in multiplication by 8
+# acceptable: Twist
+98b559523bc778b0418af53c0c32f6ff5cf771ff5df8ae7cbf7c3b72aedb5b43:
+2d7ab4c6f59865355ee8e9de57db19aadf7708b7c1d1a818487c340623badc6d:
+2a0340aaafa05d00529c09057ed0145f34d2de66a3e149cf084ea97168914f39:
+
+# special case for E in multiplication by 8
+# valid
+589815027caf82714e96c9f91bace66ec4ba3e92df3fa14b9b8fe503556e4543:
+43839f4a6aa206c82c5a73f49d8c9e573826b3ba7235d312987c17aebee62776:
+00313717d33e3b41a0865986157582e053502a172b88d01bb7b10831a9fc4e6c:
+
+# special case for E in multiplication by 8
+# valid
+80715f67270c99789855ceaea99b9957ccda33326f76bb4474ab52ab1ec37041:
+3c321e7f0b9e555bc264a2cea617e6b2b562ebab21fe0c226c3e487b7df9a27d:
+9b6be9e6f2fdb5d3321842225d3e91d14828cc53ba6654dabe190b0c3edeb309:
+
+# special case for DA - CB in multiplication by 8
+# acceptable: Twist
+101b990bd83d684126ff047d930c27d086a588dd19683d2629f0e34f4374ab41:
+42e5a6b8e9654bb4ad624af3f491877977513cc8775c8fb312ad19dbf3903a28:
+223f1eb552308373026d11c954684ce6db870b638b190b9443e50aae219f4e3e:
+
+# special case for DA - CB in multiplication by 8
+# acceptable: Twist
+200089b712d9a2050597779d463712fcd223e3d67879c0fb7606f8f5f0efee40:
+0a51dd90ab985f6deaf72f16c45014da26df848697f6582d75688f5223342b51:
+fb95ce4a3c1f325638b7d47f4216d39a7c6c5da9a01caa297c37b62816555b2a:
+
+# special case for DA - CB in multiplication by 8
+# valid
+f04f87f4e623af4c31ceca0bb87fac2d5b12517b5a7284902ad75838e65f1e41:
+8842317357bde825ef438a1c53906fb8b04ea360f7ef338c78e668586047936a:
+488b8341c9cb1bbf124510b9f8dae4faf2e0dca9b84e00e952a63b5aa328a860:
+
+# special case for DA - CB in multiplication by 8
+# valid
+383cbd5a3dd0901d09a3cac3d3a77a979cecf15e206a553e4ca3f24b90783945:
+c71d92d3c92dbfaed755fb32797b667cc86b0e79362498e2aca38c689713b16e:
+1129eae97bf75f7314f2e1b403b18737ad830c80429e2ba0d4866b362399855f:
+
+# special case for DA - CB in multiplication by 8
+# valid
+701df09e57b98aec375745df147b72949a6b2bb2ca3a34881512ee31e790ad42:
+3a21d1cf7b3744d1ad26197335844982c2a0c6a5aa835492bd03c401a4fe6778:
+072f51d94727f392d59dc7caff1f4460452352ec39c32a1c9f071e388833da56:
+
+# special case for CB in multiplication by 8
+# acceptable: Twist
+b0ffa5f4922bb117ad75ff43acac62331efaa45536fe88306e4a4cb58db73a47:
+d128ea3e13325ed6ebd6533a9fd3045a55f25ad8b67def30912843504c1aab29:
+30512142d3e3a4cad6726d9d35f2e043fca9dfb750884ae22b2547c840f3587b:
+
+# special case for CB in multiplication by 8
+# acceptable: Twist
+685e3271d2015741756612a930e858b930acf2018145f382c83d8cced2e22044:
+e079c8f8423165c7e0a2c48b4abe90aece4e6d903d7a5a1625fad0410cd55b32:
+5b81b3761a66d199e8ef99d2494bd57a0229d4564a7f6d6055f22aa48681bd3a:
+
+# special case for BB in multiplication by 8
+# valid
+f8e161d69297e017d7c51b1b1ff3ba703d4c4cf8fc2b8ff47f74c3ff8c7d3541:
+65922a06e9be4e8a5e8aceb1a4e08fe90f01e10ef2dd27315427cedfcf95ec32:
+038de7fdb9cc0030f5c11dda00589f0a95f65658815b06ed013553a02b6c5017:
+
+# special case for BB in multiplication by 8
+# valid
+105d7589f8abef0acf0940da84a69e8f2f306fa73c9afd27342287c1dba80044:
+d36a240e972dc16e9b97a997ada337f02760d05c46d7f8d7b4e9ea9a635c7c64:
+22b0dea3b3b7ca55eceeaae6443426548c7c15cc7ddf31780318d1c23879c16a:
+
+# special case for BB in multiplication by 8
+# acceptable: Twist
+1893d4388b0e90f0b50208aa8f0cc24f576d03641baf1c3eddb2a3efa69c9d40:
+4f5b8b9892b8a46df08d76a4745b1c58d4e7a394905435875688ca11f1e9d86a:
+a25e1306684ad7870a31f0404566e8d28f2d83d4b9497822c57f8781b18fec20:
+
+# special case for BB in multiplication by 8
+# acceptable: Twist
+0065171301bf6b90fb16efa35509161f1bd6b3b93130d490af9fe224dd155f45:
+aa2f02628269139a7a8a16fde95c9bad7da7ffbd5439c396a7d77b6c3213e67f:
+bb4431bea7a5871c1be27a2674094627eaaa4425c99cd3fa41bd7e13cbd7bf7e:
+
+# special case for A in multiplication by 8
+# valid
+10c81a4e78d82145b266e1d74b3869bf1c27427803ebb11c92ff8073d1e4cc46:
+d995cb287e9a9c5791f3cae3d494a5b516a1e26cbc930f43e73c8b70b69d783b:
+330f5d0b5bccc90f7694dfdd9c6449a62d93af8840eaf571e3e0610e0198b03f:
+
+# special case for A in multiplication by 8
+# acceptable: Twist
+48b98b4a99eadd73012c07fe5c4a0b9590ac55e821353b41d5f665e17188bc41:
+479afb1e73dc77c3743e51e9ec0bcc61ce66ed084dc10bfa2794b4c3e4953769:
+bdef00caa514b2f8ab1fb2241e83787a02601ecdff6cf166c4210f8c1ade4211:
+
+# special case for DA in multiplication by 8
+# acceptable: Twist
+1897678e38222a61fe105dc6643c1eb5940e8dbc73ed6c00f25a34328f43a641:
+378eda41470b0f238a200f80809ad562ca41e62411a61feb7f7e9b752b554642:
+bfd5b5acd2d89f213a26caf54062f9a24e6f6fd8ddd0cd2e5e47b7fea4a9c537:
+
+# special case for DA in multiplication by 8
+# valid
+a898af8138e11ae45bbcefa737182a571885f92d515c32056c7cb0d7deac4741:
+0cad7545ade2fd93fcae007c97648348f26d85829bdb7223a63eccb84e56d475:
+c8085877800c175e949cdd88e196eb9c4841da2ac446dfed9085bda5bbec265d:
+
+# special case for AA in multiplication by 9
+# valid
+b0bfef6ec095b5a1f93917d32f16a21d0462c1fde17446f5a590232d9c895f4a:
+60f27ed0a27804ced237cf3c1cc776650fb320bae6d5acb564e97b56cba25210:
+4c300895827382a9d1079028bd6f694a7a12ddac9c76abac6fdf5d29457a3310:
+
+# special case for AA in multiplication by 9
+# acceptable: Twist
+60497d4464ed8823c50fbc6b68620826c4f629c1d9193058df6bf857c6aecc4b:
+f93a73270ac19194b8e4ffd02be4b1438525f84a76224688ea89a9dd6a1bd623:
+7285fbb3f76340a979ab6e288727a2113332cf933809b018b8739a796a09d00b:
+
+# special case for AA in multiplication by 9
+# acceptable: Twist
+08c6cbe03792a3829f06e8ad54c55db113236ac0dcc9ab6a9a6b10eed1041b48:
+cf80c30fcbfd535666ca1da499e2e99cc537063e2de19458fcf92f5ee34acf47:
+dabc3bd49f19cf7071802e43c863ed0b1d93a841588098b98a0c581bf4fe0a11:
+
+# special case for AA in multiplication by 9
+# valid
+50044da3315dd082e9dfb6a1994aabb331f53e0d1c12633383b2a3c8678cfe4c:
+698effe0ad42e15ee1f46fde6fc5074ffda183bcf1b2db8647f561ddd191dd60:
+a61a3b150b4770532373676298c9a5da28adcc4365b06fe07c959ca80e477a57:
+
+# special case for AA in multiplication by 9
+# valid
+285640da7a48252e35ddce60c14addb73097fbc9ac2f87c8d2772ce89aa6be4d:
+bd1565b4a3f8515dff577be6dcb414511d3d4ec2de15e0bd45b28e9cc4caef60:
+916ab4f3bfc8321e1087d9c5444f8f7a43e9ca6d29e7ba98a19dc05fff34ed4c:
+
+# special case for AA in multiplication by 9
+# acceptable: Twist
+783271c21199ba2e94ead92cd9dd79f70aab378b59497455d327a5907dafcb4a:
+b8649e13843f80cf5702398e4a9a8c378f29da96dfd6579f1eb4f7ea34df6765:
+844a5dd5139554ca7b41cbe6a4796193912e7aa4e201cc68944ce2a55774a10f:
+
+# special case for AA in multiplication by 9
+# valid
+d0676a0b9a046c62d5b2e740d9cc43fa37965dea93c23254f7bf569f2bebaa4a:
+c396938737abdf791e09a97eba577c437d9b67c2dae94e13eab7296ec0fc737e:
+10780333b2a6170136265bb5ebc6c818817f2e48ae372528c8f34433fdd6215a:
+
+# special case for DA - CB in multiplication by 9
+# acceptable: Twist
+608c84d2b76fccda579e974db3d3b2ce39a6bc0dad440599db22411b60467849:
+557b825012d98f065bb95a2ab9b2d2d8b83fd2037912508c263f86d7e36c4f24:
+5ce84842dbae8b795b3d545343558045508f271383bfb3dd3943f4101398c864:
+
+# special case for z_2 in multiplication by 9
+# valid
+80f233936a8821936d39114c84d929e79760b27680779e5009e1709410dd8e4f:
+ae98296d4a2fbcbb40b472f4063231608bb1465c226c8a4a2dff29afd915882a:
+4f11aa0c313195f96f25cadcbf49f06a932d8b051879ea537d1c6dfee7f36d35:
+
+# special case for z_2 in multiplication by 9
+# valid
+c8d80b1a34f21194f047a6f0328bb947e2e7aff6a043553aa07f2abf99aaf048:
+8b9d249829fbe81333d85050da88998f63fac665679e27dbbe21b745dd14e145:
+1d619070bf5626064be10025e74e336c81ef3166b743f99c751fb90587c31d7e:
+
+# special case for z_2 in multiplication by 9
+# valid
+9021477b452361580059364c6f94f4981ee94ea3f9b7d37439bc82ae45816f4d:
+61896093e2697c78230afdda12639cbe4342827b8d2b093281f148eb60b9034b:
+532e797861db56b9d5db8825fb72f8629c2422f8abea721ad2d7b9e77a95b576:
+
+# special case for z_2 in multiplication by 9
+# acceptable: Twist
+6079dae04c40a59ea4e0c8c17092e4c85ea9133d143307363487836df4e30349:
+ccc1dc186229dba9a9360a0f7ff00247a3732625acaacd18ea13a9a8b40fac4f:
+4f678b64fd1f85cbbd5f7e7f3c8ac95ec7500e102e9006d6d42f48fb2473ab02:
+
+# special case for z_2 in multiplication by 9
+# valid
+281db6a5ac9a47d4a7b2b91a87f6536ce62d4e5129b8d647b97f9c504014894c:
+69e368c0b7e78eb9f3a53bf458f6e79dc4883bf9458f04a8c12c4ddd94d62151:
+e069fd06702f10f33adb8cf0766880634865b510e2da409241fb5f178050514a:
+
+# special case for z_2 in multiplication by 9
+# valid
+d830f3c4785829a0f945857e0e85e0ae723702b57783b933cd2a2ad05484fe49:
+f21f9badd98dd8a103cc2ab5484fac6c2bfdd2671ee6e674134a86b89cee9160:
+fee218eb1f92864486e83c1731f04bb8c7e6d7143e3915bcbf80fe03ff69dc77:
+
+# special case for E in multiplication by 9
+# acceptable: Twist
+10230bd0721f4c8c4b921881dd88c603af501ee80e2102f8acc30cf8b2acd349:
+e853062b2d6f38d021d645163ea208d0e193a479f11f99971b98e21188fd0b2c:
+64bdfa0207a174ca17eeba8df74d79b25f54510e6174923034a4d6ee0c167e7b:
+
+# special case for E in multiplication by 9
+# valid
+f0a34d6d76896e17cb8f66feda23115ffb96f246b823bb63dec08335787de74c:
+362eb92dab9fb29f7ed0e03843dcc15797928c2b4e51ec260204179c1c12945f:
+d7f4583ee4fe86af3a3f1dfcb295ba3a3e37bced7b9c6f000a95336530318902:
+
+# special case for E in multiplication by 9
+# acceptable: Twist
+9073c1d0a173c7ff02dc966a165993d9c4c9357514f7a6bb7aaa4b0827718948:
+ff543f1e81996e88631f030ceba7e603b13033efd205e68bd36b28468134aa73:
+c1b5e5f4401c98fa14eba8aafae30a641bfd8fb132be03413f3bf29290d49e0b:
+
+# special case for x_2 in multiplication by 9
+# valid
+b0c1822566e016c12ae35ec035edd09af3cb7a48f55c9028e05e1178a8c3824e:
+90ef70844ead1613f69df7d78c057813f866c0d95e6d22caee4a012b9c1c4b33:
+9369ebb3d2b744341cba77302719a4b2d63aff612872f86d9877a76bc919ca1c:
+
+# special case for x_2 in multiplication by 9
+# acceptable: Twist
+e06fe64e2117796f997bbcd3bcad3067cf1291640a3a643fb359809a4016834d:
+88c1ae575ad073dda66c6eacb7b7f436e1f8ad72a0db5c04e5660b7b719e4c4b:
+335394be9c154901c0b4063300001804b1cd01b27fa562e44f3302168837166e:
+
+# special case for x_2 in multiplication by 9
+# acceptable: Twist
+707ee81f113a244c9d87608b12158c50f9ac1f2c8948d170ad16ab0ad866d74b:
+dcffc4c1e1fba5fda9d5c98421d99c257afa90921bc212a046d90f6683e8a467:
+7ecdd54c5e15f7b4061be2c30b5a4884a0256581f87df60d579a3345653eb641:
+
+# special case for BB in multiplication by 9
+# valid
+7089654baacbb65bd00cd8cb9de4680e748075e8842ca69d448fb50fea85e74e:
+6c0044cd10578c5aff1ff4917b041b76c9a9ae23664eb8cf978bd7aa192cf249:
+0d8c21fa800ee63ce5e473d4c2975495062d8afa655091122cb41799d374594f:
+
+# special case for BB in multiplication by 9
+# valid
+8089784c52cd67e4536e568218c7b7033b28413f942fca24ed69e43496efa14b:
+d9089de902e143dcd9107e5a3393a3f7fe05d926c357b47e307a236cb590fd64:
+db6fec44bf118316a6bdfbae9af447baede4d82daa16bed596ea6f05d4a51400:
+
+# special case for BB in multiplication by 9
+# valid
+00e73e4e013148b9f05273bad626bb126a40ec4558f5425096b48947e0a9de4a:
+8c4a26aa319c2cc4a4158c2bc69a0d5b340b60628a14cf31bb0ae5ddc38ae866:
+ecc1204bc753c4cec4c9059fd7b504944ebf995ab1b1d49f0b3b325353be3a15:
+
+# special case for BB in multiplication by 9
+# valid
+78ed4c9bf9f44db8d93388985191ecf59226b9c1205fe7e762c327581c75884e:
+ce7295d1227c9062aab9cf02fc5671fb81632e725367f131d4122824a6132d68:
+3740de297ff0122067951e8985247123440e0f27171da99e263d5b4450f59f3d:
+
+# private key == -1 (mod order)
+# valid
+a023cdd083ef5bb82f10d62e59e15a6800000000000000000000000000000050:
+6c05871352a451dbe182ed5e6ba554f2034456ffe041a054ff9cc56b8e946376:
+6c05871352a451dbe182ed5e6ba554f2034456ffe041a054ff9cc56b8e946376:
+
+# private key == 1 (mod order) on twist
+# acceptable: Twist
+58083dd261ad91eff952322ec824c682ffffffffffffffffffffffffffffff5f:
+2eae5ec3dd494e9f2d37d258f873a8e6e9d0dbd1e383ef64d98bb91b3e0be035:
+2eae5ec3dd494e9f2d37d258f873a8e6e9d0dbd1e383ef64d98bb91b3e0be035:
+
+# special case private key
+# valid
+4855555555555555555555555555555555555555555555555555555555555555:
+3e3e7708ef72a6dd78d858025089765b1c30a19715ac19e8d917067d208e0666:
+63ef7d1c586476ec78bb7f747e321e01102166bf967a9ea9ba9741f49d439510:
+
+# special case private key
+# valid
+4855555555555555555555555555555555555555555555555555555555555555:
+9f40bb30f68ab67b1c4b8b664982fdab04ff385cd850deac732f7fb705e6013a:
+8b98ef4d6bf30df7f88e58d51505d37ed6845a969fe598747c033dcd08014065:
+
+# special case private key
+# valid
+4855555555555555555555555555555555555555555555555555555555555555:
+be3b3edeffaf83c54ae526379b23dd79f1cb41446e3687fef347eb9b5f0dc308:
+cfa83e098829fe82fd4c14355f70829015219942c01e2b85bdd9ac4889ec2921:
+
+# special case private key
+# valid
+b8aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa6a:
+3e3e7708ef72a6dd78d858025089765b1c30a19715ac19e8d917067d208e0666:
+4782036d6b136ca44a2fd7674d8afb0169943230ac8eab5160a212376c06d778:
+
+# special case private key
+# valid
+b8aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa6a:
+9f40bb30f68ab67b1c4b8b664982fdab04ff385cd850deac732f7fb705e6013a:
+65fc1e7453a3f8c7ebcd577ade4b8efe1035efc181ab3bdb2fcc7484cbcf1e4e:
+
+# special case private key
+# valid
+b8aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa6a:
+be3b3edeffaf83c54ae526379b23dd79f1cb41446e3687fef347eb9b5f0dc308:
+e3c649beae7cc4a0698d519a0a61932ee5493cbb590dbe14db0274cc8611f914:
diff --git a/lib/Utils.Cryptography/monocypher/vendor/tests/gen/x25519.c b/lib/Utils.Cryptography/monocypher/vendor/tests/gen/x25519.c
new file mode 100644
index 0000000..4ab1f8c
--- /dev/null
+++ b/lib/Utils.Cryptography/monocypher/vendor/tests/gen/x25519.c
@@ -0,0 +1,83 @@
+// This file is dual-licensed. Choose whichever licence you want from
+// the two licences listed below.
+//
+// The first licence is a regular 2-clause BSD licence. The second licence
+// is the CC-0 from Creative Commons. It is intended to release Monocypher
+// to the public domain. The BSD licence serves as a fallback option.
+//
+// SPDX-License-Identifier: BSD-2-Clause OR CC0-1.0
+//
+// ------------------------------------------------------------------------
+//
+// Copyright (c) 2017-2019, Loup Vaillant
+// 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 COPYRIGHT HOLDERS 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 COPYRIGHT
+// HOLDER 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.
+//
+// ------------------------------------------------------------------------
+//
+// Written in 2017-2019 by Loup Vaillant
+//
+// To the extent possible under law, the author(s) have dedicated all copyright
+// and related 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
+// <https://creativecommons.org/publicdomain/zero/1.0/>
+
+#include <sodium.h>
+#include "utils.h"
+
+static void test()
+{
+ RANDOM_INPUT(sk1, 32);
+ RANDOM_INPUT(sk2, 32);
+ u8 pk1[32], pk2[32], shared[32];
+
+ crypto_scalarmult_base(pk1, sk1);
+ crypto_scalarmult_base(pk2, sk2);
+ if (crypto_scalarmult(shared, sk1, pk2)) {
+ fprintf(stderr, "libsodium rejected the public key\n");
+ printf(":deadbeef:\n"); // prints a canary to fail subsequent tests
+ }
+
+ print_vector(sk1 , 32);
+ print_vector(pk2 , 32);
+ print_vector(shared, 32);
+ printf("\n");
+ print_vector(sk2 , 32);
+ print_vector(pk1 , 32);
+ print_vector(shared, 32);
+ printf("\n");
+}
+
+int main(void)
+{
+ SODIUM_INIT;
+ FOR (i, 0, 50) { test(); }
+ return 0;
+}
diff --git a/lib/Utils.Cryptography/monocypher/vendor/tests/gen/x25519_pk.c b/lib/Utils.Cryptography/monocypher/vendor/tests/gen/x25519_pk.c
new file mode 100644
index 0000000..231a90f
--- /dev/null
+++ b/lib/Utils.Cryptography/monocypher/vendor/tests/gen/x25519_pk.c
@@ -0,0 +1,79 @@
+// This file is dual-licensed. Choose whichever licence you want from
+// the two licences listed below.
+//
+// The first licence is a regular 2-clause BSD licence. The second licence
+// is the CC-0 from Creative Commons. It is intended to release Monocypher
+// to the public domain. The BSD licence serves as a fallback option.
+//
+// SPDX-License-Identifier: BSD-2-Clause OR CC0-1.0
+//
+// ------------------------------------------------------------------------
+//
+// Copyright (c) 2017-2019, Loup Vaillant
+// 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 COPYRIGHT HOLDERS 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 COPYRIGHT
+// HOLDER 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.
+//
+// ------------------------------------------------------------------------
+//
+// Written in 2017-2019 by Loup Vaillant
+//
+// To the extent possible under law, the author(s) have dedicated all copyright
+// and related 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
+// <https://creativecommons.org/publicdomain/zero/1.0/>
+
+#include <sodium.h>
+#include "utils.h"
+
+static void test(u8 sk[32])
+{
+ u8 pk[32];
+ crypto_scalarmult_base(pk, sk);
+
+ print_vector(sk, 32);
+ print_vector(pk, 32);
+ printf("\n");
+}
+
+int main(void)
+{
+ SODIUM_INIT;
+
+ // random secret keys
+ FOR (i, 0, 50) {
+ RANDOM_INPUT(sk, 32);
+ test(sk);
+ }
+ // zero secret key
+ u8 sk[32] = {0};
+ test(sk);
+
+ return 0;
+}
diff --git a/lib/Utils.Cryptography/monocypher/vendor/tests/gen/xchacha20.c b/lib/Utils.Cryptography/monocypher/vendor/tests/gen/xchacha20.c
new file mode 100644
index 0000000..e088153
--- /dev/null
+++ b/lib/Utils.Cryptography/monocypher/vendor/tests/gen/xchacha20.c
@@ -0,0 +1,82 @@
+// This file is dual-licensed. Choose whichever licence you want from
+// the two licences listed below.
+//
+// The first licence is a regular 2-clause BSD licence. The second licence
+// is the CC-0 from Creative Commons. It is intended to release Monocypher
+// to the public domain. The BSD licence serves as a fallback option.
+//
+// SPDX-License-Identifier: BSD-2-Clause OR CC0-1.0
+//
+// ------------------------------------------------------------------------
+//
+// Copyright (c) 2017-2019, Loup Vaillant
+// 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 COPYRIGHT HOLDERS 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 COPYRIGHT
+// HOLDER 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.
+//
+// ------------------------------------------------------------------------
+//
+// Written in 2017-2019 by Loup Vaillant
+//
+// To the extent possible under law, the author(s) have dedicated all copyright
+// and related 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
+// <https://creativecommons.org/publicdomain/zero/1.0/>
+
+#include <sodium.h>
+#include "utils.h"
+
+static void test(size_t size, u64 ctr)
+{
+ RANDOM_INPUT(key , 32);
+ RANDOM_INPUT(nonce, 24);
+ RANDOM_INPUT(in , 128); // size <= 128
+ u8 out [128]; // size <= 128
+
+ crypto_stream_xchacha20_xor_ic(out, in, size, nonce, ctr, key);
+
+ print_vector(key , 32);
+ print_vector(nonce , 24);
+ print_vector(in , size);
+ print_number(ctr );
+ print_vector(out, size);
+ printf("\n");
+}
+
+int main(void)
+{
+ SODIUM_INIT;
+ // regular tests
+ FOR (size, 0, 128) { test(size, rand64()); }
+ // counter overflow (should wrap around)
+ test(128, -1);
+ test(128, -2);
+ test(128, -3);
+ return 0;
+}
diff --git a/lib/Utils.Cryptography/monocypher/vendor/tests/speed/README.md b/lib/Utils.Cryptography/monocypher/vendor/tests/speed/README.md
new file mode 100644
index 0000000..6b27d34
--- /dev/null
+++ b/lib/Utils.Cryptography/monocypher/vendor/tests/speed/README.md
@@ -0,0 +1,31 @@
+Speed benchmarks
+================
+
+ $ cd tests/speed
+ $ make speed
+
+This will give you an idea how fast Monocypher is on your machine. Make
+sure you run it on the target platform if performance is a concern. If
+Monocypher is too slow, try libsodium. If you're not sure, you can
+always switch later.
+
+Note: the speed benchmark currently requires the POSIX
+`clock_gettime()` function.
+
+There are similar benchmarks for libsodium, TweetNaCl, LibHydrogen,
+c25519, and ed25519-donna (the portable, 32-bit version):
+
+ $ make speed-sodium
+ $ make speed-tweetnacl
+ $ make speed-hydrogen
+ $ make speed-c25519
+ $ make speed-donna
+
+(The `speed-hydrogen` target assumes it has pkg-config installed. Try
+`make pkg-config-libhydrogen` as root if it is not.)
+
+You can also adjust the optimisation options for Monocypher, TweetNaCl,
+and c25519 (the default is `-O3 march=native`):
+
+ $ make speed CFLAGS="-O2"
+ $ make speed-tweetnacl CFLAGS="-O2"
diff --git a/lib/Utils.Cryptography/monocypher/vendor/tests/speed/libhydrogen.pc b/lib/Utils.Cryptography/monocypher/vendor/tests/speed/libhydrogen.pc
new file mode 100644
index 0000000..30cd39e
--- /dev/null
+++ b/lib/Utils.Cryptography/monocypher/vendor/tests/speed/libhydrogen.pc
@@ -0,0 +1,12 @@
+prefix=PREFIX
+exec_prefix=${prefix}
+libdir=${exec_prefix}/lib
+includedir=${prefix}/include
+
+Name: libhydrogen
+Version: git-HEAD
+Description: Small, easy-to-use,
+hard-to-misuse cryptographic library.
+
+Libs: -L${libdir} -lhydrogen
+Cflags: -I${includedir}
diff --git a/lib/Utils.Cryptography/monocypher/vendor/tests/speed/makefile b/lib/Utils.Cryptography/monocypher/vendor/tests/speed/makefile
new file mode 100644
index 0000000..3934bac
--- /dev/null
+++ b/lib/Utils.Cryptography/monocypher/vendor/tests/speed/makefile
@@ -0,0 +1,208 @@
+# This file is dual-licensed. Choose whichever licence you want from
+# the two licences listed below.
+#
+# The first licence is a regular 2-clause BSD licence. The second licence
+# is the CC-0 from Creative Commons. It is intended to release Monocypher
+# to the public domain. The BSD licence serves as a fallback option.
+#
+# SPDX-License-Identifier: BSD-2-Clause OR CC0-1.0
+#
+# ------------------------------------------------------------------------
+#
+# Copyright (c) 2023, Loup Vaillant
+# 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 COPYRIGHT HOLDERS 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 COPYRIGHT
+# HOLDER 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.
+#
+# ------------------------------------------------------------------------
+#
+# Written in 2023 by Loup Vaillant
+#
+# To the extent possible under law, the author(s) have dedicated all copyright
+# and related 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
+# <https://creativecommons.org/publicdomain/zero/1.0/>
+
+CC ?= gcc -std=gnu99
+CFLAGS ?= -pedantic -Wall -Wextra -O3 -march=native
+
+.PHONY: speed speed-sodium speed-hydrogen speed-tweetnacl speed-c25519 \
+ speed-donna \
+ pkg-config-libhydrogen \
+ clean
+
+##################
+## Main targets ##
+##################
+all: speed
+
+speed : speed.out
+ ./$<
+speed-sodium : speed-sodium.out
+ ./$<
+speed-hydrogen : speed-hydrogen.out
+ ./$<
+speed-tweetnacl: speed-tweetnacl.out
+ ./$<
+speed-c25519 : speed-c25519.out
+ ./$<
+speed-donna : speed-donna.out
+ ./$<
+speed-tinyssh : speed-tinyssh.out
+ ./$<
+
+clean:
+ rm -f *.o *.out
+
+####################
+## Base libraries ##
+####################
+
+# Test utils
+utils.o: ../utils.c ../utils.h
+ $(CC) -c $(CFLAGS) -I .. $< -o $@
+
+# Monocypher
+monocypher.o: ../../src/monocypher.c ../../src/monocypher.h
+ $(CC) -c $(CFLAGS) -I .. -I ../../src/ $< -o $@
+monocypher-ed25519.o: ../../src/optional/monocypher-ed25519.c \
+ ../../src/optional/monocypher-ed25519.h \
+ ../../src/monocypher.h
+ $(CC) -c $(CFLAGS) -I .. -I ../../src/ -I ../../src/optional $< -o $@
+
+# TweetNaCl
+tweetnacl.o: ../externals/tweetnacl/tweetnacl.c \
+ ../externals/tweetnacl/tweetnacl.h
+ $(CC) -c $(CFLAGS) -I .. $< -o $@
+
+# C25519
+C25519 = c25519 edsign ed25519 morph25519 fprime f25519 sha512
+C25519_HEADERS = $(patsubst %, ../externals/c25519/%.h, $(C25519))
+C25519_OBJECTS = $(patsubst %, %.o, $(C25519))
+c25519.o : ../externals/c25519/c25519.c $(C25519_HEADERS)
+ed25519.o : ../externals/c25519/ed25519.c $(C25519_HEADERS)
+edsign.o : ../externals/c25519/edsign.c $(C25519_HEADERS)
+f25519.o : ../externals/c25519/f25519.c $(C25519_HEADERS)
+fprime.o : ../externals/c25519/fprime.c $(C25519_HEADERS)
+morph25519.o: ../externals/c25519/morph25519.c $(C25519_HEADERS)
+sha512.o : ../externals/c25519/sha512.c $(C25519_HEADERS)
+$(C25519_OBJECTS):
+ $(CC) -c $(CFLAGS) -I ../externals/c25519/ -o $@ $<
+
+# libhydrogen (only installs pkg-config)
+DESTDIR =
+PREFIX = /usr/local
+PKGCONFIGDIR = $(LIBDIR)/pkgconfig
+pkg-config-libhydrogen:
+ mkdir -p $(DESTDIR)$(PKGCONFIGDIR)
+ sed "s|PREFIX|$(PREFIX)|" libhydrogen.pc \
+ > $(DESTDIR)$(PKGCONFIGDIR)/libhydrogen.pc
+
+# Donna
+DONNA_HEADERS=$(wildcard ../externals/ed25519-donna/*.h)
+donna.o: ../externals/ed25519-donna/ed25519.c $(DONNA_HEADERS)
+ $(CC) $(CFLAGS) -c $< -o$@ \
+ -DED25519_CUSTOMHASH \
+ -DED25519_TEST \
+ -DED25519_NO_INLINE_ASM \
+ -DED25519_FORCE_32BIT
+
+# Tinyssh
+TSSH =../externals/tinyssh
+TSSH_O = \
+ cleanup.o crypto_hash_sha512.o crypto_onetimeauth_poly1305.o \
+ crypto_scalarmult_curve25519.o crypto_sign_ed25519.o \
+ crypto_stream_chacha20.o crypto_verify_32.o fe25519.o fe.o ge25519.o \
+ randombytes.o sc25519.o uint32_pack.o uint32_unpack.o verify.o
+TSSH_H = \
+ $(TSSH)/cleanup.h $(TSSH)/crypto_hash_sha512.h $(TSSH)/crypto_int64.h \
+ $(TSSH)/crypto_onetimeauth_poly1305.h \
+ $(TSSH)/crypto_scalarmult_curve25519.h $(TSSH)/crypto_sign_ed25519.h \
+ $(TSSH)/crypto_stream_chacha20.h $(TSSH)/crypto_uint32.h \
+ $(TSSH)/crypto_uint64.h $(TSSH)/crypto_verify_32.h $(TSSH)/fe25519.h \
+ $(TSSH)/fe.h $(TSSH)/ge25519.h $(TSSH)/sc25519.h $(TSSH)/uint32_pack.h \
+ $(TSSH)/uint32_unpack.h $(TSSH)/verify.h
+
+cleanup.o : $(TSSH)/cleanup.c $(TSSH_H)
+crypto_hash_sha512.o : $(TSSH)/crypto_hash_sha512.c $(TSSH_H)
+crypto_onetimeauth_poly1305.o : $(TSSH)/crypto_onetimeauth_poly1305.c $(TSSH_H)
+crypto_scalarmult_curve25519.o: $(TSSH)/crypto_scalarmult_curve25519.c $(TSSH_H)
+crypto_sign_ed25519.o : $(TSSH)/crypto_sign_ed25519.c $(TSSH_H)
+crypto_stream_chacha20.o : $(TSSH)/crypto_stream_chacha20.c $(TSSH_H)
+crypto_verify_32.o : $(TSSH)/crypto_verify_32.c $(TSSH_H)
+fe25519.o : $(TSSH)/fe25519.c $(TSSH_H)
+fe.o : $(TSSH)/fe.c $(TSSH_H)
+ge25519.o : $(TSSH)/ge25519.c $(TSSH_H)
+randombytes.o : $(TSSH)/randombytes.c $(TSSH_H)
+sc25519.o : $(TSSH)/sc25519.c $(TSSH_H)
+uint32_pack.o : $(TSSH)/uint32_pack.c $(TSSH_H)
+uint32_unpack.o : $(TSSH)/uint32_unpack.c $(TSSH_H)
+verify.o : $(TSSH)/verify.c $(TSSH_H)
+$(TSSH_O):
+ $(CC) -c $(CFLAGS) -I ../externals/tinyssh/ -o $@ $<
+
+
+######################
+## Speed benchmarks ##
+######################
+speed.o : speed.c speed.h ../utils.h
+ $(CC) -c $(CFLAGS) $< -o $@ -I .. -I ../../src/ -I ../../src/optional
+speed-sodium.o : speed-sodium.c speed.h ../utils.h
+ $(CC) -c $(CFLAGS) $< -o $@ -I ..
+speed-hydrogen.o : speed-hydrogen.c speed.h ../utils.h
+ $(CC) -c $(CFLAGS) $< -o $@ -I ..
+speed-tweetnacl.o : speed-tweetnacl.c speed.h ../utils.h $(TWEET_HEADERS)
+ $(CC) -c $(CFLAGS) $< -o $@ -I .. -I ../externals/tweetnacl
+speed-c25519.o : speed-c25519.c speed.h ../utils.h $(C25519_HEADERS)
+ $(CC) -c $(CFLAGS) $< -o $@ -I .. -I ../externals/c25519
+speed-donna.o : speed-donna.c speed.h ../utils.h $(DONNA_HEADERS)
+ $(CC) -c $(CFLAGS) $< -o $@ -I .. -I ../externals/ed25519-donna
+speed-tinyssh.o : speed-tinyssh.c speed.h ../utils.h $(TSSH_H)
+ $(CC) -c $(CFLAGS) $< -o $@ -I .. -I $(TSSH)
+
+speed.out: speed.o utils.o monocypher.o monocypher-ed25519.o
+ $(CC) $(CFLAGS) -o $@ $^
+speed-sodium.out: speed-sodium.o utils.o
+ $(CC) $(CFLAGS) -o $@ $^ \
+ `pkg-config --cflags libsodium` \
+ `pkg-config --libs libsodium`
+speed-donna.out: speed-donna.o donna.o utils.o
+ $(CC) $(CFLAGS) -o $@ $^ \
+ `pkg-config --cflags libsodium` \
+ `pkg-config --libs libsodium`
+speed-hydrogen.out: speed-hydrogen.o utils.o
+ $(CC) $(CFLAGS) -o $@ $^ \
+ `pkg-config --cflags libhydrogen` \
+ `pkg-config --libs libhydrogen`
+speed-tweetnacl.out: speed-tweetnacl.o tweetnacl.o utils.o
+ $(CC) $(CFLAGS) -o $@ $^
+speed-c25519.out : speed-c25519.o $(C25519_OBJECTS) utils.o
+ $(CC) $(CFLAGS) -o $@ $^
+speed-tinyssh.out : speed-tinyssh.o $(TSSH_O) utils.o
+ $(CC) $(CFLAGS) -o $@ $^
diff --git a/lib/Utils.Cryptography/monocypher/vendor/tests/speed/speed-c25519.c b/lib/Utils.Cryptography/monocypher/vendor/tests/speed/speed-c25519.c
new file mode 100644
index 0000000..534ba49
--- /dev/null
+++ b/lib/Utils.Cryptography/monocypher/vendor/tests/speed/speed-c25519.c
@@ -0,0 +1,123 @@
+// This file is dual-licensed. Choose whichever licence you want from
+// the two licences listed below.
+//
+// The first licence is a regular 2-clause BSD licence. The second licence
+// is the CC-0 from Creative Commons. It is intended to release Monocypher
+// to the public domain. The BSD licence serves as a fallback option.
+//
+// SPDX-License-Identifier: BSD-2-Clause OR CC0-1.0
+//
+// ------------------------------------------------------------------------
+//
+// Copyright (c) 2017-2019, Loup Vaillant
+// 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 COPYRIGHT HOLDERS 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 COPYRIGHT
+// HOLDER 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.
+//
+// ------------------------------------------------------------------------
+//
+// Written in 2017-2019 by Loup Vaillant
+//
+// To the extent possible under law, the author(s) have dedicated all copyright
+// and related 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
+// <https://creativecommons.org/publicdomain/zero/1.0/>
+
+#include "speed.h"
+#include "utils.h"
+#include "c25519.h"
+#include "edsign.h"
+
+static u64 x25519(void)
+{
+ u8 in [32] = {9};
+ u8 out[F25519_SIZE];
+ FOR (i, 0, F25519_SIZE) {
+ out[i] = c25519_base_x[i];
+ }
+
+ TIMING_START {
+ c25519_prepare(in);
+ c25519_smult(out, out, in);
+ }
+ TIMING_END;
+}
+
+void edsign_sec_to_pub(uint8_t *pub, const uint8_t *secret);
+
+/* Produce a signature for a message. */
+#define EDSIGN_SIGNATURE_SIZE 64
+
+void edsign_sign(uint8_t *signature, const uint8_t *pub,
+ const uint8_t *secret,
+ const uint8_t *message, size_t len);
+
+/* Verify a message signature. Returns non-zero if ok. */
+uint8_t edsign_verify(const uint8_t *signature, const uint8_t *pub,
+ const uint8_t *message, size_t len);
+
+static u64 edDSA_sign(void)
+{
+ RANDOM_INPUT(sk , 32);
+ RANDOM_INPUT(message, 64);
+ u8 pk [32];
+ u8 sig[64];
+ edsign_sec_to_pub(pk, sk);
+
+ TIMING_START {
+ edsign_sign(sig, pk, sk, message, 64);
+ }
+ TIMING_END;
+}
+
+static u64 edDSA_check(void)
+{
+ RANDOM_INPUT(sk , 32);
+ RANDOM_INPUT(message, 64);
+ u8 pk [32];
+ u8 sig[64];
+ edsign_sec_to_pub(pk, sk);
+ edsign_sign(sig, pk, sk, message, 64);
+
+ TIMING_START {
+ if (!edsign_verify(sig, pk, message, 64)) {
+ printf("c25519 verification failed\n");
+ }
+ }
+ TIMING_END;
+}
+
+int main()
+{
+ print("x25519 ", x25519() , "exchanges per second");
+ print("EdDSA(sign) ", edDSA_sign() , "signatures per second");
+ print("EdDSA(check)", edDSA_check(), "checks per second");
+ printf("\n");
+ return 0;
+}
diff --git a/lib/Utils.Cryptography/monocypher/vendor/tests/speed/speed-donna.c b/lib/Utils.Cryptography/monocypher/vendor/tests/speed/speed-donna.c
new file mode 100644
index 0000000..f089780
--- /dev/null
+++ b/lib/Utils.Cryptography/monocypher/vendor/tests/speed/speed-donna.c
@@ -0,0 +1,92 @@
+// This file is dual-licensed. Choose whichever licence you want from
+// the two licences listed below.
+//
+// The first licence is a regular 2-clause BSD licence. The second licence
+// is the CC-0 from Creative Commons. It is intended to release Monocypher
+// to the public domain. The BSD licence serves as a fallback option.
+//
+// SPDX-License-Identifier: BSD-2-Clause OR CC0-1.0
+//
+// ------------------------------------------------------------------------
+//
+// Copyright (c) 2020, Loup Vaillant
+// 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 COPYRIGHT HOLDERS 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 COPYRIGHT
+// HOLDER 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.
+//
+// ------------------------------------------------------------------------
+//
+// Written in 2020 by Loup Vaillant
+//
+// To the extent possible under law, the author(s) have dedicated all copyright
+// and related 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
+// <https://creativecommons.org/publicdomain/zero/1.0/>
+
+#include "speed.h"
+#include "ed25519.h"
+
+static u64 edDSA_sign(void)
+{
+ u8 pk [32];
+ u8 signature[64];
+ RANDOM_INPUT(sk , 32);
+ RANDOM_INPUT(message, 64);
+ ed25519_publickey(sk, pk);
+
+ TIMING_START {
+ ed25519_sign(message, 64, sk, pk, signature);
+ }
+ TIMING_END;
+}
+
+static u64 edDSA_check(void)
+{
+ u8 pk [32];
+ u8 signature[64];
+ RANDOM_INPUT(sk , 32);
+ RANDOM_INPUT(message, 64);
+ ed25519_publickey(sk, pk);
+ ed25519_sign(message, 64, sk, pk, signature);
+
+ TIMING_START {
+ if (ed25519_sign_open(message, 64, pk, signature)) {
+ printf("Donna verification failed\n");
+ }
+ }
+ TIMING_END;
+}
+
+int main()
+{
+ print("EdDSA(sign) ",edDSA_sign() , "signatures per second");
+ print("EdDSA(check)",edDSA_check(), "checks per second");
+ printf("\n");
+ return 0;
+}
diff --git a/lib/Utils.Cryptography/monocypher/vendor/tests/speed/speed-hydrogen.c b/lib/Utils.Cryptography/monocypher/vendor/tests/speed/speed-hydrogen.c
new file mode 100644
index 0000000..e11c4e2
--- /dev/null
+++ b/lib/Utils.Cryptography/monocypher/vendor/tests/speed/speed-hydrogen.c
@@ -0,0 +1,129 @@
+// This file is dual-licensed. Choose whichever licence you want from
+// the two licences listed below.
+//
+// The first licence is a regular 2-clause BSD licence. The second licence
+// is the CC-0 from Creative Commons. It is intended to release Monocypher
+// to the public domain. The BSD licence serves as a fallback option.
+//
+// SPDX-License-Identifier: BSD-2-Clause OR CC0-1.0
+//
+// ------------------------------------------------------------------------
+//
+// Copyright (c) 2017-2019, Loup Vaillant
+// 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 COPYRIGHT HOLDERS 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 COPYRIGHT
+// HOLDER 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.
+//
+// ------------------------------------------------------------------------
+//
+// Written in 2017-2019 by Loup Vaillant
+//
+// To the extent possible under law, the author(s) have dedicated all copyright
+// and related 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
+// <https://creativecommons.org/publicdomain/zero/1.0/>
+
+#include "speed.h"
+#include "utils.h"
+#include "hydrogen.h"
+
+static u64 hydro_random(void)
+{
+ u8 out[SIZE];
+ RANDOM_INPUT(key , 32);
+ RANDOM_INPUT(nonce, 8);
+
+ TIMING_START {
+ hydro_random_buf_deterministic(out, SIZE, key);
+ }
+ TIMING_END;
+}
+
+static u64 authenticated(void)
+{
+ u8 out[SIZE + hydro_secretbox_HEADERBYTES];
+ RANDOM_INPUT(in , SIZE + 32);
+ RANDOM_INPUT(key, 32);
+ TIMING_START {
+ hydro_secretbox_encrypt(out, in, SIZE, 0, "Benchmark", key);
+ }
+ TIMING_END;
+}
+
+static u64 hash(void)
+{
+ u8 hash[32];
+ RANDOM_INPUT(in, SIZE);
+
+ TIMING_START {
+ hydro_hash_hash(hash, 32, in, SIZE, "Benchmark", 0);
+ }
+ TIMING_END;
+}
+
+static u64 sign(void)
+{
+ RANDOM_INPUT(message, 64);
+ hydro_sign_keypair key_pair;
+ hydro_sign_keygen(&key_pair);
+ uint8_t sig[hydro_sign_BYTES];
+
+ TIMING_START {
+ hydro_sign_create(sig, message, 64, "Benchmark", key_pair.sk);
+ }
+ TIMING_END;
+}
+
+static u64 check(void)
+{
+ RANDOM_INPUT(message, 64);
+ hydro_sign_keypair key_pair;
+ hydro_sign_keygen(&key_pair);
+ uint8_t sig[hydro_sign_BYTES];
+ hydro_sign_create(sig, message, 64, "Benchmark", key_pair.sk);
+
+ TIMING_START {
+ if (hydro_sign_verify(sig, message, 64, "Benchmark", key_pair.pk)) {
+ printf("LibHydrogen verification failed\n");
+ }
+ }
+ TIMING_END;
+}
+
+int main()
+{
+ hydro_init();
+ print("Random ",hydro_random() *MUL,"megabytes per second");
+ print("Auth'd encryption",authenticated()*MUL,"megabytes per second");
+ print("Hash ",hash() *MUL,"megabytes per second");
+ print("sign ",sign() ,"signatures per second");
+ print("check ",check() ,"checks per second");
+ printf("\n");
+ return 0;
+}
diff --git a/lib/Utils.Cryptography/monocypher/vendor/tests/speed/speed-sodium.c b/lib/Utils.Cryptography/monocypher/vendor/tests/speed/speed-sodium.c
new file mode 100644
index 0000000..25bf61e
--- /dev/null
+++ b/lib/Utils.Cryptography/monocypher/vendor/tests/speed/speed-sodium.c
@@ -0,0 +1,191 @@
+// This file is dual-licensed. Choose whichever licence you want from
+// the two licences listed below.
+//
+// The first licence is a regular 2-clause BSD licence. The second licence
+// is the CC-0 from Creative Commons. It is intended to release Monocypher
+// to the public domain. The BSD licence serves as a fallback option.
+//
+// SPDX-License-Identifier: BSD-2-Clause OR CC0-1.0
+//
+// ------------------------------------------------------------------------
+//
+// Copyright (c) 2017-2019, Loup Vaillant
+// 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 COPYRIGHT HOLDERS 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 COPYRIGHT
+// HOLDER 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.
+//
+// ------------------------------------------------------------------------
+//
+// Written in 2017-2019 by Loup Vaillant
+//
+// To the extent possible under law, the author(s) have dedicated all copyright
+// and related 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
+// <https://creativecommons.org/publicdomain/zero/1.0/>
+
+#include "speed.h"
+#include "sodium.h"
+
+static u64 chacha20(void)
+{
+ u8 out[SIZE];
+ RANDOM_INPUT(in , SIZE);
+ RANDOM_INPUT(key , 32);
+ RANDOM_INPUT(nonce, 8);
+
+ TIMING_START {
+ crypto_stream_chacha20_xor(out, in, SIZE, nonce, key);
+ }
+ TIMING_END;
+}
+
+static u64 poly1305(void)
+{
+ u8 out[16];
+ RANDOM_INPUT(in , SIZE);
+ RANDOM_INPUT(key, 32);
+
+ TIMING_START {
+ crypto_onetimeauth(out, in, SIZE, key);
+ }
+ TIMING_END;
+}
+
+static u64 authenticated(void)
+{
+ u8 out[SIZE];
+ u8 mac[crypto_aead_xchacha20poly1305_ietf_ABYTES];
+ RANDOM_INPUT(in , SIZE);
+ RANDOM_INPUT(key , 32);
+ RANDOM_INPUT(nonce, 24);
+
+ TIMING_START {
+ crypto_aead_xchacha20poly1305_ietf_encrypt_detached(
+ out, mac, 0, in, SIZE, 0, 0, 0, nonce, key);
+ }
+ TIMING_END;
+}
+
+static u64 blake2b(void)
+{
+ u8 hash[64];
+ RANDOM_INPUT(in , SIZE);
+ RANDOM_INPUT(key, 32);
+
+ TIMING_START {
+ crypto_generichash(hash, 64, in, SIZE, key, 32);
+ }
+ TIMING_END;
+}
+
+static u64 sha512(void)
+{
+ u8 hash[64];
+ RANDOM_INPUT(in, SIZE);
+
+ TIMING_START {
+ crypto_hash_sha512(hash, in, SIZE);
+ }
+ TIMING_END;
+}
+
+static u64 argon2i(void)
+{
+ u8 hash [32];
+ RANDOM_INPUT(password, 16);
+ RANDOM_INPUT(salt , 16);
+
+ TIMING_START {
+ if (crypto_pwhash(hash, 32, (char*)password, 16, salt,
+ 3, SIZE, crypto_pwhash_ALG_ARGON2I13)) {
+ fprintf(stderr, "Argon2i failed.\n");
+ }
+ }
+ TIMING_END;
+}
+
+static u64 x25519(void)
+{
+ u8 in [32] = {9};
+ u8 out[32] = {9};
+
+ TIMING_START {
+ if (crypto_scalarmult(out, out, in)) {
+ fprintf(stderr, "libsodium rejected the public key\n");
+ }
+ }
+ TIMING_END;
+}
+
+static u64 edDSA_sign(void)
+{
+ u8 sk [64];
+ u8 pk [32];
+ u8 signature[64];
+ RANDOM_INPUT(message, 64);
+ crypto_sign_keypair(pk, sk);
+
+ TIMING_START {
+ crypto_sign_detached(signature, 0, message, 64, sk);
+ }
+ TIMING_END;
+}
+
+static u64 edDSA_check(void)
+{
+ u8 sk [64];
+ u8 pk [32];
+ u8 signature[64];
+ RANDOM_INPUT(message, 64);
+ crypto_sign_keypair(pk, sk);
+ crypto_sign_detached(signature, 0, message, 64, sk);
+
+ TIMING_START {
+ if (crypto_sign_verify_detached(signature, message, 64, pk)) {
+ printf("libsodium verification failed\n");
+ }
+ }
+ TIMING_END;
+}
+
+int main()
+{
+ SODIUM_INIT;
+ print("Chacha20 ",chacha20() *MUL,"megabytes per second");
+ print("Poly1305 ",poly1305() *MUL,"megabytes per second");
+ print("Auth'd encryption",authenticated()*MUL,"megabytes per second");
+ print("BLAKE2b ",blake2b() *MUL,"megabytes per second");
+ print("SHA-512 ",sha512() *MUL,"megabytes per second");
+ print("Argon2i, 3 passes",argon2i() *MUL,"megabytes per second");
+ print("x25519 ",x25519() ,"exchanges per second");
+ print("EdDSA(sign) ",edDSA_sign() ,"signatures per second");
+ print("EdDSA(check) ",edDSA_check() ,"checks per second");
+ printf("\n");
+ return 0;
+}
diff --git a/lib/Utils.Cryptography/monocypher/vendor/tests/speed/speed-tinyssh.c b/lib/Utils.Cryptography/monocypher/vendor/tests/speed/speed-tinyssh.c
new file mode 100644
index 0000000..9ac1a33
--- /dev/null
+++ b/lib/Utils.Cryptography/monocypher/vendor/tests/speed/speed-tinyssh.c
@@ -0,0 +1,159 @@
+// This file is dual-licensed. Choose whichever licence you want from
+// the two licences listed below.
+//
+// The first licence is a regular 2-clause BSD licence. The second licence
+// is the CC-0 from Creative Commons. It is intended to release Monocypher
+// to the public domain. The BSD licence serves as a fallback option.
+//
+// SPDX-License-Identifier: BSD-2-Clause OR CC0-1.0
+//
+// ------------------------------------------------------------------------
+//
+// Copyright (c) 2017-2019, Loup Vaillant
+// 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 COPYRIGHT HOLDERS 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 COPYRIGHT
+// HOLDER 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.
+//
+// ------------------------------------------------------------------------
+//
+// Written in 2017-2019 by Loup Vaillant
+//
+// To the extent possible under law, the author(s) have dedicated all copyright
+// and related 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
+// <https://creativecommons.org/publicdomain/zero/1.0/>
+
+#include "speed.h"
+#include "utils.h"
+
+int crypto_stream_chacha20_tinyssh(unsigned char *,
+ unsigned long long,
+ const unsigned char *,
+ const unsigned char *);
+
+int crypto_stream_chacha20_tinyssh_xor(unsigned char *,
+ const unsigned char *,
+ unsigned long long,
+ const unsigned char *,
+ const unsigned char *);
+
+static u64 chacha20(void)
+{
+ u8 out[SIZE];
+ RANDOM_INPUT(in , SIZE);
+ RANDOM_INPUT(key , 32);
+ RANDOM_INPUT(nonce, 8);
+
+ TIMING_START {
+ crypto_stream_chacha20_tinyssh_xor(out, in, SIZE, nonce, key);
+ }
+ TIMING_END;
+}
+
+static u64 poly1305(void)
+{
+ u8 out[16];
+ RANDOM_INPUT(in , SIZE);
+ RANDOM_INPUT(key, 32);
+
+ TIMING_START {
+ crypto_onetimeauth_poly1305_tinyssh(out, in, SIZE, key);
+ }
+ TIMING_END;
+}
+
+static u64 sha512(void)
+{
+ u8 hash[64];
+ RANDOM_INPUT(in, SIZE);
+
+ TIMING_START {
+ crypto_hash_sha512_tinyssh(hash, in, SIZE);
+ }
+ TIMING_END;
+}
+
+static u64 x25519(void)
+{
+ u8 in [32] = {9};
+ u8 out[32] = {9};
+
+ TIMING_START {
+ crypto_scalarmult_curve25519_tinyssh(out, out, in);
+ }
+ TIMING_END;
+}
+
+static u64 edDSA_sign(void)
+{
+ u8 sk [ 64];
+ u8 pk [ 32];
+ u8 signed_msg[128];
+ unsigned long long sig_size;
+ RANDOM_INPUT(message, 64);
+ crypto_sign_ed25519_tinyssh_keypair(pk, sk);
+
+ TIMING_START {
+ crypto_sign_ed25519_tinyssh(signed_msg, &sig_size, message, 64, sk);
+ }
+ TIMING_END;
+}
+
+static u64 edDSA_check(void)
+{
+ u8 sk [ 64];
+ u8 pk [ 32];
+ u8 signed_msg[128];
+ u8 out_msg [128];
+ unsigned long long sig_size;
+ unsigned long long msg_size;
+ RANDOM_INPUT(message, 64);
+ crypto_sign_ed25519_tinyssh_keypair(pk, sk);
+ crypto_sign_ed25519_tinyssh(signed_msg, &sig_size, message, 64, sk);
+
+ TIMING_START {
+ if (crypto_sign_ed25519_tinyssh_open(out_msg, &msg_size,
+ signed_msg, sig_size, pk)) {
+ printf("TweetNaCl verification failed\n");
+ }
+ }
+ TIMING_END;
+}
+
+int main()
+{
+ print("Chacha20 ",chacha20() *MUL ,"megabytes per second");
+ print("Poly1305 ",poly1305() *MUL ,"megabytes per second");
+ print("SHA-512 ",sha512() *MUL ,"megabytes per second");
+ print("x25519 ",x25519() ,"exchanges per second");
+ print("EdDSA(sign) ",edDSA_sign() ,"signatures per second");
+ print("EdDSA(check)",edDSA_check() ,"checks per second");
+ printf("\n");
+ return 0;
+}
diff --git a/lib/Utils.Cryptography/monocypher/vendor/tests/speed/speed-tweetnacl.c b/lib/Utils.Cryptography/monocypher/vendor/tests/speed/speed-tweetnacl.c
new file mode 100644
index 0000000..6f2ea6f
--- /dev/null
+++ b/lib/Utils.Cryptography/monocypher/vendor/tests/speed/speed-tweetnacl.c
@@ -0,0 +1,169 @@
+// This file is dual-licensed. Choose whichever licence you want from
+// the two licences listed below.
+//
+// The first licence is a regular 2-clause BSD licence. The second licence
+// is the CC-0 from Creative Commons. It is intended to release Monocypher
+// to the public domain. The BSD licence serves as a fallback option.
+//
+// SPDX-License-Identifier: BSD-2-Clause OR CC0-1.0
+//
+// ------------------------------------------------------------------------
+//
+// Copyright (c) 2017-2019, Loup Vaillant
+// 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 COPYRIGHT HOLDERS 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 COPYRIGHT
+// HOLDER 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.
+//
+// ------------------------------------------------------------------------
+//
+// Written in 2017-2019 by Loup Vaillant
+//
+// To the extent possible under law, the author(s) have dedicated all copyright
+// and related 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
+// <https://creativecommons.org/publicdomain/zero/1.0/>
+
+#include "speed.h"
+#include "utils.h"
+#include "tweetnacl.h"
+
+// TweetNaCl needs to link with this
+// Not really random, but we don't care for those benchmarks.
+void randombytes(u8 *stream, u64 size)
+{
+ p_random(stream, (size_t)size);
+}
+
+static u64 salsa20(void)
+{
+ u8 out[SIZE];
+ RANDOM_INPUT(in , SIZE);
+ RANDOM_INPUT(key , 32);
+ RANDOM_INPUT(nonce, 8);
+
+ TIMING_START {
+ crypto_stream_salsa20_xor(out, in, SIZE, nonce, key);
+ }
+ TIMING_END;
+}
+
+static u64 poly1305(void)
+{
+ u8 out[16];
+ RANDOM_INPUT(in , SIZE);
+ RANDOM_INPUT(key, 32);
+
+ TIMING_START {
+ crypto_onetimeauth(out, in, SIZE, key);
+ }
+ TIMING_END;
+}
+
+static u64 authenticated(void)
+{
+ u8 out[SIZE + 32];
+ RANDOM_INPUT(in , SIZE + 32);
+ RANDOM_INPUT(key , 32);
+ RANDOM_INPUT(nonce, 24);
+
+ TIMING_START {
+ crypto_secretbox(out, in, SIZE + 32, nonce, key);
+ }
+ TIMING_END;
+}
+
+static u64 sha512(void)
+{
+ u8 hash[64];
+ RANDOM_INPUT(in, SIZE);
+
+ TIMING_START {
+ crypto_hash(hash, in, SIZE);
+ }
+ TIMING_END;
+}
+
+static u64 x25519(void)
+{
+ u8 in [32] = {9};
+ u8 out[32] = {9};
+
+ TIMING_START {
+ crypto_scalarmult(out, out, in);
+ }
+ TIMING_END;
+}
+
+static u64 edDSA_sign(void)
+{
+ u8 sk [ 64];
+ u8 pk [ 32];
+ u8 signed_msg[128];
+ unsigned long long sig_size;
+ RANDOM_INPUT(message, 64);
+ crypto_sign_keypair(pk, sk);
+
+ TIMING_START {
+ crypto_sign(signed_msg, &sig_size, message, 64, sk);
+ }
+ TIMING_END;
+}
+
+static u64 edDSA_check(void)
+{
+ u8 sk [ 64];
+ u8 pk [ 32];
+ u8 signed_msg[128];
+ u8 out_msg [128];
+ unsigned long long sig_size;
+ unsigned long long msg_size;
+ RANDOM_INPUT(message, 64);
+ crypto_sign_keypair(pk, sk);
+ crypto_sign(signed_msg, &sig_size, message, 64, sk);
+
+ TIMING_START {
+ if (crypto_sign_open(out_msg, &msg_size, signed_msg, sig_size, pk)) {
+ printf("TweetNaCl verification failed\n");
+ }
+ }
+ TIMING_END;
+}
+
+int main()
+{
+ print("Salsa20 ",salsa20() *MUL,"megabytes per second");
+ print("Poly1305 ",poly1305() *MUL,"megabytes per second");
+ print("Auth'd encryption",authenticated()*MUL,"megabytes per second");
+ print("SHA-512 ",sha512() *MUL,"megabytes per second");
+ print("x25519 ",x25519() ,"exchanges per second");
+ print("EdDSA(sign) ",edDSA_sign() ,"signatures per second");
+ print("EdDSA(check) ",edDSA_check() ,"checks per second");
+ printf("\n");
+ return 0;
+}
diff --git a/lib/Utils.Cryptography/monocypher/vendor/tests/speed/speed.c b/lib/Utils.Cryptography/monocypher/vendor/tests/speed/speed.c
new file mode 100644
index 0000000..1a7e9dd
--- /dev/null
+++ b/lib/Utils.Cryptography/monocypher/vendor/tests/speed/speed.c
@@ -0,0 +1,270 @@
+// This file is dual-licensed. Choose whichever licence you want from
+// the two licences listed below.
+//
+// The first licence is a regular 2-clause BSD licence. The second licence
+// is the CC-0 from Creative Commons. It is intended to release Monocypher
+// to the public domain. The BSD licence serves as a fallback option.
+//
+// SPDX-License-Identifier: BSD-2-Clause OR CC0-1.0
+//
+// ------------------------------------------------------------------------
+//
+// Copyright (c) 2017-2019, Loup Vaillant
+// 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 COPYRIGHT HOLDERS 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 COPYRIGHT
+// HOLDER 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.
+//
+// ------------------------------------------------------------------------
+//
+// Written in 2017-2019 by Loup Vaillant
+//
+// To the extent possible under law, the author(s) have dedicated all copyright
+// and related 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
+// <https://creativecommons.org/publicdomain/zero/1.0/>
+
+#include "speed.h"
+#include "monocypher.h"
+#include "monocypher-ed25519.h"
+#include "utils.h"
+
+static u64 chacha20(void)
+{
+ u8 out[SIZE];
+ RANDOM_INPUT(in , SIZE);
+ RANDOM_INPUT(key , 32);
+ RANDOM_INPUT(nonce, 8);
+
+ TIMING_START {
+ crypto_chacha20_djb(out, in, SIZE, key, nonce, 0);
+ }
+ TIMING_END;
+}
+
+static u64 poly1305(void)
+{
+ u8 out[16];
+ RANDOM_INPUT(in , SIZE);
+ RANDOM_INPUT(key, 32);
+
+ TIMING_START {
+ crypto_poly1305(out, in, SIZE, key);
+ }
+ TIMING_END;
+}
+
+static u64 authenticated(void)
+{
+ u8 out[SIZE];
+ u8 mac[ 16];
+ RANDOM_INPUT(in , SIZE);
+ RANDOM_INPUT(key , 32);
+ RANDOM_INPUT(nonce, 24);
+
+ TIMING_START {
+ crypto_aead_lock(mac, out, key, nonce, 0, 0, in, SIZE);
+ }
+ TIMING_END;
+}
+
+static u64 blake2b(void)
+{
+ u8 hash[64];
+ RANDOM_INPUT(in , SIZE);
+ RANDOM_INPUT(key, 32);
+
+ TIMING_START {
+ crypto_blake2b_keyed(hash, 64, key, 32, in, SIZE);
+ }
+ TIMING_END;
+}
+
+static u64 blake2b_small(void)
+{
+ u8 hash[64];
+ RANDOM_INPUT(input, 128*2);
+
+ TIMING_START {
+ FOR (i, 0, 128*2) {
+ crypto_blake2b_ctx ctx;
+ crypto_blake2b_init (&ctx, 64);
+ crypto_blake2b_update(&ctx, input , i);
+ crypto_blake2b_update(&ctx, input + i, 128*2 - i);
+ crypto_blake2b_final (&ctx, hash);
+ }
+ }
+ TIMING_END;
+}
+
+static u64 sha512(void)
+{
+ u8 hash[64];
+ RANDOM_INPUT(in, SIZE);
+
+ TIMING_START {
+ crypto_sha512(hash, in, SIZE);
+ }
+ TIMING_END;
+}
+
+static u64 sha512_small(void)
+{
+ u8 hash[64];
+ RANDOM_INPUT(input, 128*2);
+
+ TIMING_START {
+ FOR (i, 0, 128*2) {
+ crypto_sha512_ctx ctx;
+ crypto_sha512_init (&ctx);
+ crypto_sha512_update(&ctx, input , i);
+ crypto_sha512_update(&ctx, input + i, 128*2 - i);
+ crypto_sha512_final (&ctx, hash);
+ }
+ }
+ TIMING_END;
+}
+
+static u64 argon2i(void)
+{
+ u64 work_area[SIZE / 8];
+ u8 hash [32];
+ RANDOM_INPUT(pass, 16);
+ RANDOM_INPUT(salt, 16);
+
+ crypto_argon2_config config;
+ config.algorithm = CRYPTO_ARGON2_I;
+ config.nb_blocks = (u32)(SIZE / 1024);
+ config.nb_passes = 3;
+ config.nb_lanes = 1;
+
+ crypto_argon2_inputs inputs;
+ inputs.pass = pass;
+ inputs.salt = salt;
+ inputs.pass_size = sizeof(pass);
+ inputs.salt_size = sizeof(salt);
+
+ TIMING_START {
+ crypto_argon2(hash, sizeof(hash), work_area,
+ config, inputs, crypto_argon2_no_extras);
+ }
+ TIMING_END;
+}
+
+static u64 x25519(void)
+{
+ u8 in [32] = {9};
+ u8 out[32] = {9};
+
+ TIMING_START {
+ crypto_x25519(out, out, in);
+ }
+ TIMING_END;
+}
+
+static u64 edDSA_sign(void)
+{
+ u8 sk [64];
+ u8 pk [32];
+ u8 signature[64];
+ RANDOM_INPUT(seed , 32);
+ RANDOM_INPUT(message, 64);
+ crypto_eddsa_key_pair(sk, pk, seed);
+
+ TIMING_START {
+ crypto_eddsa_sign(signature, sk, message, 64);
+ }
+ TIMING_END;
+}
+
+static u64 edDSA_check(void)
+{
+ u8 sk [64];
+ u8 pk [32];
+ u8 signature[64];
+ RANDOM_INPUT(seed , 32);
+ RANDOM_INPUT(message, 64);
+ crypto_eddsa_key_pair(sk, pk, seed);
+ crypto_eddsa_sign(signature, sk, message, 64);
+
+ TIMING_START {
+ if (crypto_eddsa_check(signature, pk, message, 64)) {
+ printf("Monocypher verification failed\n");
+ }
+ }
+ TIMING_END;
+}
+
+static u64 x25519_inverse(void)
+{
+ u8 in [32] = {9};
+ u8 out[32] = {9};
+
+ TIMING_START {
+ crypto_x25519_inverse(out, out, in);
+ }
+ TIMING_END;
+}
+
+static u64 x25519_sp_fast(void)
+{
+ RANDOM_INPUT(sk, 32);
+ TIMING_START {
+ crypto_x25519_dirty_fast(sk, sk);
+ }
+ TIMING_END;
+}
+
+static u64 x25519_sp_small(void)
+{
+ RANDOM_INPUT(sk, 32);
+ TIMING_START {
+ crypto_x25519_dirty_small(sk, sk);
+ }
+ TIMING_END;
+}
+
+int main()
+{
+ print("Chacha20 ",chacha20() *MUL ,"megabytes per second");
+ print("Poly1305 ",poly1305() *MUL ,"megabytes per second");
+ print("Auth'd encryption ",authenticated()*MUL ,"megabytes per second");
+ print("BLAKE2b ",blake2b() *MUL ,"megabytes per second");
+ print("BLAKE2b (small) ",blake2b_small() ,"cycles per second");
+ print("SHA-512 ",sha512() *MUL ,"megabytes per second");
+ print("SHA-512 (small) ",sha512_small() ,"cycles per second");
+ print("Argon2i, 3 passes ",argon2i() *MUL ,"megabytes per second");
+ print("x25519 ",x25519() ,"exchanges per second");
+ print("EdDSA(sign) ",edDSA_sign() ,"signatures per second");
+ print("EdDSA(check) ",edDSA_check() ,"checks per second");
+ print("x25519 inverse ",x25519_inverse() ,"scalar inv per second");
+ print("x25519 dirty fast ",x25519_sp_fast() ,"scalar inv per second");
+ print("x25519 dirty small ",x25519_sp_small() ,"scalar inv per second");
+ printf("\n");
+ return 0;
+}
diff --git a/lib/Utils.Cryptography/monocypher/vendor/tests/speed/speed.h b/lib/Utils.Cryptography/monocypher/vendor/tests/speed/speed.h
new file mode 100644
index 0000000..824bc91
--- /dev/null
+++ b/lib/Utils.Cryptography/monocypher/vendor/tests/speed/speed.h
@@ -0,0 +1,105 @@
+// This file is dual-licensed. Choose whichever licence you want from
+// the two licences listed below.
+//
+// The first licence is a regular 2-clause BSD licence. The second licence
+// is the CC-0 from Creative Commons. It is intended to release Monocypher
+// to the public domain. The BSD licence serves as a fallback option.
+//
+// SPDX-License-Identifier: BSD-2-Clause OR CC0-1.0
+//
+// ------------------------------------------------------------------------
+//
+// Copyright (c) 2017-2019, Loup Vaillant
+// 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 COPYRIGHT HOLDERS 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 COPYRIGHT
+// HOLDER 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.
+//
+// ------------------------------------------------------------------------
+//
+// Written in 2017-2019 by Loup Vaillant
+//
+// To the extent possible under law, the author(s) have dedicated all copyright
+// and related 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
+// <https://creativecommons.org/publicdomain/zero/1.0/>
+
+#include <time.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include "utils.h"
+
+typedef struct timespec timespec;
+
+// TODO: provide a user defined buffer size
+#define KILOBYTE 1024
+#define MEGABYTE 1024 * KILOBYTE
+#define SIZE (256 * KILOBYTE)
+#define MUL (MEGABYTE / SIZE)
+#define BILLION 1000000000
+
+// Difference in nanoseconds
+static u64 diff(timespec start, timespec end)
+{
+ return (u64)((end.tv_sec - start.tv_sec ) * BILLION +
+ (end.tv_nsec - start.tv_nsec));
+}
+
+static u64 min(u64 a, u64 b)
+{
+ return a < b ? a : b;
+}
+
+static void print(const char *name, u64 duration, const char *unit)
+{
+ if (duration == 0) {
+ printf("%s: too fast to be measured\n", name);
+ } else {
+ u64 speed_hz = BILLION / duration;
+ printf("%s: %5" PRIu64 " %s\n", name, speed_hz, unit);
+ }
+}
+
+// Note: not all systems will work well with CLOCK_PROCESS_CPUTIME_ID.
+// If you get weird timings on your system, you may want to replace it
+// with another clock id. Perhaps even replace clock_gettime().
+#define TIMESTAMP(t) \
+ timespec t; \
+ clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &t)
+
+#define TIMING_START \
+ u64 duration = (u64)-1; \
+ FOR (i, 0, 2000) { \
+ TIMESTAMP(start);
+
+#define TIMING_END \
+ TIMESTAMP(end); \
+ duration = min(duration, diff(start, end)); \
+ } /* end FOR*/ \
+ return duration
diff --git a/lib/Utils.Cryptography/monocypher/vendor/tests/test.c b/lib/Utils.Cryptography/monocypher/vendor/tests/test.c
new file mode 100644
index 0000000..98bd9b1
--- /dev/null
+++ b/lib/Utils.Cryptography/monocypher/vendor/tests/test.c
@@ -0,0 +1,1252 @@
+// This file is dual-licensed. Choose whichever licence you want from
+// the two licences listed below.
+//
+// The first licence is a regular 2-clause BSD licence. The second licence
+// is the CC-0 from Creative Commons. It is intended to release Monocypher
+// to the public domain. The BSD licence serves as a fallback option.
+//
+// SPDX-License-Identifier: BSD-2-Clause OR CC0-1.0
+//
+// ------------------------------------------------------------------------
+//
+// Copyright (c) 2017-2020, Loup Vaillant and Richard Walmsley
+// 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 COPYRIGHT HOLDERS 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 COPYRIGHT
+// HOLDER 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.
+//
+// ------------------------------------------------------------------------
+//
+// Written in 2017-2020 by Loup Vaillant and Richard Walmsley
+//
+// To the extent possible under law, the author(s) have dedicated all copyright
+// and related 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
+// <https://creativecommons.org/publicdomain/zero/1.0/>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include "monocypher.h"
+#include "monocypher-ed25519.h"
+#include "utils.h"
+#include "vectors.h"
+
+#define VECTORS(n) ASSERT_OK(vector_test(n, #n, nb_##n##_vectors, n##_vectors))
+
+////////////
+/// Wipe ///
+////////////
+static void test_wipe(void)
+{
+ printf("\tcrypto_wipe\n");
+ u8 zeroes[50] = {0};
+ FOR (i, 0, 50) {
+ RANDOM_INPUT(buf, 50);
+ crypto_wipe(buf, i);
+ ASSERT_EQUAL(zeroes, buf, i);
+ }
+}
+
+////////////////////////////////
+/// Constant time comparison ///
+////////////////////////////////
+static void p_verify(unsigned size, int (*compare)(const u8*, const u8*))
+{
+ printf("\tcrypto_verify%u\n", size);
+ u8 a[64]; // size <= 64
+ u8 b[64]; // size <= 64
+ FOR (i, 0, 2) {
+ FOR (j, 0, 2) {
+ // Set every byte to the chosen value, then compare
+ FOR (k, 0, size) {
+ a[k] = (u8)i;
+ b[k] = (u8)j;
+ }
+ int cmp = compare(a, b);
+ if (i == j) { ASSERT(cmp == 0); }
+ else { ASSERT(cmp != 0); }
+ // Set only two bytes to the chosen value, then compare
+ FOR (k, 0, size / 2) {
+ FOR (l, 0, size) {
+ a[l] = 0;
+ b[l] = 0;
+ }
+ a[k] = (u8)i; a[k + size/2 - 1] = (u8)i;
+ b[k] = (u8)j; b[k + size/2 - 1] = (u8)j;
+ cmp = compare(a, b);
+ if (i == j) { ASSERT(cmp == 0); }
+ else { ASSERT(cmp != 0); }
+ }
+ }
+ }
+}
+
+static void test_verify(void)
+{
+ p_verify(16, crypto_verify16);
+ p_verify(32, crypto_verify32);
+ p_verify(64, crypto_verify64);
+}
+
+////////////////
+/// Chacha20 ///
+////////////////
+#define CHACHA_BLOCK_SIZE 64
+
+static void chacha20(vector_reader *reader)
+{
+ vector key = next_input(reader);
+ vector nonce = next_input(reader);
+ vector plain = next_input(reader);
+ u64 ctr = load64_le(next_input(reader).buf);
+ vector out = next_output(reader);
+ u64 nb_blocks = plain.size / 64 + (plain.size % 64 != 0);
+ u64 new_ctr = crypto_chacha20_djb(out.buf, plain.buf, plain.size,
+ key.buf, nonce.buf, ctr);
+ ASSERT(new_ctr - ctr == nb_blocks);
+}
+
+static void ietf_chacha20(vector_reader *reader)
+{
+ vector key = next_input(reader);
+ vector nonce = next_input(reader);
+ vector plain = next_input(reader);
+ u32 ctr = load32_le(next_input(reader).buf);
+ vector out = next_output(reader);
+ u32 nb_blocks = (u32)(plain.size / 64 + (plain.size % 64 != 0));
+ u32 new_ctr = crypto_chacha20_ietf(out.buf, plain.buf, plain.size,
+ key.buf, nonce.buf, ctr);
+ ASSERT(new_ctr - ctr == nb_blocks);
+}
+
+static void xchacha20(vector_reader *reader)
+{
+ vector key = next_input(reader);
+ vector nonce = next_input(reader);
+ vector plain = next_input(reader);
+ u64 ctr = load64_le(next_input(reader).buf);
+ vector out = next_output(reader);
+ u64 nb_blocks = plain.size / 64 + (plain.size % 64 != 0);
+ u64 new_ctr = crypto_chacha20_x(out.buf, plain.buf, plain.size,
+ key.buf, nonce.buf, ctr);
+ ASSERT(new_ctr - ctr == nb_blocks);
+}
+
+static void hchacha20(vector_reader *reader)
+{
+ vector key = next_input(reader);
+ vector nonce = next_input(reader);
+ vector out = next_output(reader);
+ crypto_chacha20_h(out.buf, key.buf, nonce.buf);
+}
+
+static void test_chacha20(void)
+{
+ VECTORS(chacha20);
+ printf("\tChacha20 (ctr)\n");
+ {
+ RANDOM_INPUT(key , 32);
+ RANDOM_INPUT(nonce, 24);
+ RANDOM_INPUT(plain, 128);
+ u8 out_full[128];
+ u8 out1 [64];
+ u8 out2 [64];
+ crypto_chacha20_djb(out_full, plain , 128, key, nonce, 0);
+ crypto_chacha20_djb(out1 , plain + 0, 64, key, nonce, 0);
+ crypto_chacha20_djb(out2 , plain + 64, 64, key, nonce, 1);
+ ASSERT_EQUAL(out_full , out1, 64);
+ ASSERT_EQUAL(out_full + 64, out2, 64);
+ }
+
+ printf("\tChacha20 (nullptr == zeroes)\n");
+#define INPUT_SIZE (CHACHA_BLOCK_SIZE * 2 + 1)
+ FOR (i, 0, INPUT_SIZE) {
+ u8 output_normal[INPUT_SIZE];
+ u8 output_stream[INPUT_SIZE];
+ u8 zeroes [INPUT_SIZE] = {0};
+ RANDOM_INPUT(key , 32);
+ RANDOM_INPUT(nonce, 8);
+ crypto_chacha20_djb(output_normal, zeroes, i, key, nonce, 0);
+ crypto_chacha20_djb(output_stream, 0 , i, key, nonce, 0);
+ ASSERT_EQUAL(output_normal, output_stream, i);
+ }
+
+ printf("\tChacha20 (output == input)\n");
+ {
+#undef INPUT_SIZE
+#define INPUT_SIZE (CHACHA_BLOCK_SIZE * 4) // total input size
+ u8 output[INPUT_SIZE];
+ RANDOM_INPUT(input, INPUT_SIZE);
+ RANDOM_INPUT(key , 32);
+ RANDOM_INPUT(nonce, 8);
+ crypto_chacha20_djb(output, input, INPUT_SIZE, key, nonce, 0);
+ crypto_chacha20_djb(input , input, INPUT_SIZE, key, nonce, 0);
+ ASSERT_EQUAL(output, input, INPUT_SIZE);
+ }
+
+ VECTORS(ietf_chacha20);
+ printf("\tietf Chacha20 (ctr)\n");
+ {
+ RANDOM_INPUT(key , 32);
+ RANDOM_INPUT(nonce, 24);
+ RANDOM_INPUT(plain, 128);
+ u8 out_full[128];
+ u8 out1 [64];
+ u8 out2 [64];
+ crypto_chacha20_ietf(out_full, plain , 128, key, nonce, 0);
+ crypto_chacha20_ietf(out1 , plain + 0, 64, key, nonce, 0);
+ crypto_chacha20_ietf(out2 , plain + 64, 64, key, nonce, 1);
+ ASSERT_EQUAL(out_full , out1, 64);
+ ASSERT_EQUAL(out_full + 64, out2, 64);
+ }
+
+ VECTORS(xchacha20);
+ printf("\tXChacha20 (ctr)\n");
+ {
+ RANDOM_INPUT(key , 32);
+ RANDOM_INPUT(nonce, 24);
+ RANDOM_INPUT(plain, 128);
+ u8 out_full[128];
+ u8 out1 [64];
+ u8 out2 [64];
+ crypto_chacha20_x(out_full, plain , 128, key, nonce, 0);
+ crypto_chacha20_x(out1 , plain + 0, 64, key, nonce, 0);
+ crypto_chacha20_x(out2 , plain + 64, 64, key, nonce, 1);
+ ASSERT_EQUAL(out_full , out1, 64);
+ ASSERT_EQUAL(out_full + 64, out2, 64);
+ }
+
+ VECTORS(hchacha20);
+ printf("\tHChacha20 (overlap)\n");
+ FOR (i, 0, 100) {
+ RANDOM_INPUT(buffer, 80);
+ size_t out_idx = rand64() % 48;
+ size_t key_idx = rand64() % 48;
+ size_t in_idx = rand64() % 64;
+ u8 key[32]; FOR (j, 0, 32) { key[j] = buffer[j + key_idx]; }
+ u8 in [16]; FOR (j, 0, 16) { in [j] = buffer[j + in_idx]; }
+
+ // Run with and without overlap, then compare
+ u8 out[32];
+ crypto_chacha20_h(out, key, in);
+ crypto_chacha20_h(buffer + out_idx, buffer + key_idx, buffer + in_idx);
+ ASSERT_EQUAL(out, buffer + out_idx, 32);
+ }
+}
+
+/////////////////
+/// Poly 1305 ///
+/////////////////
+#define POLY1305_BLOCK_SIZE 16
+
+static void poly1305(vector_reader *reader)
+{
+ vector key = next_input(reader);
+ vector msg = next_input(reader);
+ vector out = next_output(reader);
+ crypto_poly1305(out.buf, msg.buf, msg.size, key.buf);
+}
+
+static void test_poly1305(void)
+{
+ VECTORS(poly1305);
+
+ printf("\tPoly1305 (incremental)\n");
+#undef INPUT_SIZE
+#define INPUT_SIZE (POLY1305_BLOCK_SIZE * 4) // total input size
+ FOR (i, 0, INPUT_SIZE) {
+ // outputs
+ u8 mac_chunk[16];
+ u8 mac_whole[16];
+ // inputs
+ RANDOM_INPUT(input, INPUT_SIZE);
+ RANDOM_INPUT(key , 32);
+
+ // Authenticate bit by bit
+ crypto_poly1305_ctx ctx;
+ crypto_poly1305_init(&ctx, key);
+ crypto_poly1305_update(&ctx, input , i);
+ crypto_poly1305_update(&ctx, input + i, INPUT_SIZE - i);
+ crypto_poly1305_final(&ctx, mac_chunk);
+
+ // Authenticate all at once
+ crypto_poly1305(mac_whole, input, INPUT_SIZE, key);
+
+ // Compare the results
+ ASSERT_EQUAL(mac_chunk, mac_whole, 16);
+ }
+
+ printf("\tPoly1305 (overlapping i/o)\n");
+#undef INPUT_SIZE
+#define INPUT_SIZE (POLY1305_BLOCK_SIZE + (2 * 16)) // total input size
+ FOR (i, 0, POLY1305_BLOCK_SIZE + 16) {
+ RANDOM_INPUT(input, INPUT_SIZE);
+ RANDOM_INPUT(key , 32);
+ u8 mac [16];
+ crypto_poly1305(mac , input + 16, POLY1305_BLOCK_SIZE, key);
+ crypto_poly1305(input+i, input + 16, POLY1305_BLOCK_SIZE, key);
+ ASSERT_EQUAL(mac, input + i, 16);
+ }
+}
+
+////////////////////////////////
+/// Authenticated encryption ///
+////////////////////////////////
+static void aead_ietf(vector_reader *reader)
+{
+ vector key = next_input(reader);
+ vector nonce = next_input(reader);
+ vector ad = next_input(reader);
+ vector text = next_input(reader);
+ vector out = next_output(reader);
+ crypto_aead_lock(out.buf + 16, out.buf, key.buf, nonce.buf,
+ ad.buf, ad.size, text.buf, text.size);
+}
+
+static void aead_8439(vector_reader *reader)
+{
+ vector key = next_input(reader);
+ vector nonce = next_input(reader);
+ vector ad = next_input(reader);
+ vector text = next_input(reader);
+ vector out = next_output(reader);
+ crypto_aead_ctx ctx;
+ crypto_aead_init_ietf(&ctx, key.buf, nonce.buf);
+ crypto_aead_write(&ctx, out.buf + 16, out.buf, ad.buf, ad.size,
+ text.buf, text.size);
+}
+
+static void test_aead(void)
+{
+ VECTORS(aead_ietf);
+ VECTORS(aead_8439);
+
+ printf("\taead (roundtrip)\n");
+ FOR (i, 0, 1000) {
+ RANDOM_INPUT(key , 32);
+ RANDOM_INPUT(nonce , 24);
+ RANDOM_INPUT(ad , 4);
+ RANDOM_INPUT(plaintext, 8);
+ u8 box[24];
+ u8 out[8];
+ // AEAD roundtrip
+ crypto_aead_lock(box+16, box, key, nonce, ad, 4, plaintext, 8);
+ ASSERT_OK(crypto_aead_unlock(out, box, key, nonce, ad, 4, box+16, 8));
+ ASSERT_EQUAL(plaintext, out, 8);
+ box[0]++;
+ ASSERT_KO(crypto_aead_unlock(out, box, key, nonce, ad, 4, box+16, 8));
+ }
+
+ printf("\taead incr (roundtrip)\n");
+ FOR (i, 0, 50) {
+ RANDOM_INPUT(key , 32);
+ RANDOM_INPUT(nonce , 24);
+ crypto_aead_ctx ctx_xa;
+ crypto_aead_ctx ctx_xb;
+ crypto_aead_ctx ctx_da;
+ crypto_aead_ctx ctx_db;
+ crypto_aead_ctx ctx_ia;
+ crypto_aead_ctx ctx_ib;
+ crypto_aead_init_x (&ctx_xa, key, nonce);
+ crypto_aead_init_x (&ctx_xb, key, nonce);
+ crypto_aead_init_djb (&ctx_da, key, nonce);
+ crypto_aead_init_djb (&ctx_db, key, nonce);
+ crypto_aead_init_ietf(&ctx_ia, key, nonce);
+ crypto_aead_init_ietf(&ctx_ib, key, nonce);
+
+ FOR (j, 0, 10) {
+ RANDOM_INPUT(ad, 4); // additional data
+ RANDOM_INPUT(pt, 8); // plaintext
+ u8 mac[16];
+ u8 ct [ 8];
+ u8 pt2[ 8];
+ // AEAD roundtrip (happy path)
+ crypto_aead_write (&ctx_xa, ct , mac, ad, 4, pt, 8);
+ ASSERT_OK(crypto_aead_read(&ctx_xb, pt2, mac, ad, 4, ct, 8));
+ ASSERT_EQUAL(pt, pt2, 8);
+ ASSERT_EQUAL(&ctx_xa, &ctx_xb, sizeof(crypto_aead_ctx));
+
+ crypto_aead_write (&ctx_da, ct , mac, ad, 4, pt, 8);
+ ASSERT_OK(crypto_aead_read(&ctx_db, pt2, mac, ad, 4, ct, 8));
+ ASSERT_EQUAL(pt, pt2, 8);
+
+ crypto_aead_write (&ctx_ia, ct , mac, ad, 4, pt, 8);
+ ASSERT_OK(crypto_aead_read(&ctx_ib, pt2, mac, ad, 4, ct, 8));
+ ASSERT_EQUAL(pt, pt2, 8);
+ }
+ }
+ printf("\n");
+}
+
+///////////////
+/// Blake2b ///
+///////////////
+#define BLAKE2B_BLOCK_SIZE 128
+
+static void blake2b(vector_reader *reader)
+{
+ vector msg = next_input(reader);
+ vector key = next_input(reader);
+ vector out = next_output(reader);
+ crypto_blake2b_keyed(out.buf, out.size,
+ key.buf, key.size,
+ msg.buf, msg.size);
+}
+
+static void test_blake2b(void)
+{
+ VECTORS(blake2b);
+
+ printf("\tBLAKE2b (zero_input)\n");
+ {
+ RANDOM_INPUT(key, 32);
+ u8 hash_chunk[64];
+ u8 hash_whole[64];
+ crypto_blake2b_ctx ctx;
+
+ // With key
+ memset(&ctx, 0x5c, sizeof(ctx));
+ crypto_blake2b_keyed_init(&ctx, 64, key, 32);
+ crypto_blake2b_final (&ctx, hash_chunk);
+ crypto_blake2b_keyed(hash_whole, 64, key, 32, 0, 0);
+ ASSERT_EQUAL(hash_chunk, hash_whole, 64);
+
+ // Without key
+ memset(&ctx, 0x5c, sizeof(ctx));
+ crypto_blake2b_init (&ctx, 64);
+ crypto_blake2b_final(&ctx, hash_chunk);
+ crypto_blake2b(hash_whole, 64, 0, 0);
+ ASSERT_EQUAL(hash_chunk, hash_whole, 64);
+ }
+
+ printf("\tBLAKE2b (incremental)\n");
+ // Note: I figured we didn't need to test keyed mode, or different
+ // hash sizes, a second time. This test sticks to the simplified
+ // interface.
+#undef INPUT_SIZE
+#define INPUT_SIZE (BLAKE2B_BLOCK_SIZE * 3) // total input size
+ {
+ RANDOM_INPUT(input, INPUT_SIZE);
+
+ // hash at once
+ u8 hash_whole[64];
+ crypto_blake2b(hash_whole, 64, input, INPUT_SIZE);
+
+ FOR (j, 0, INPUT_SIZE) {
+ FOR (i, 0, j+1) {
+ // Hash bit by bit
+ u8 *mid_input = j - i == 0 ? NULL : input + i; // NULL update
+ u8 hash_chunk[64];
+ crypto_blake2b_ctx ctx;
+ crypto_blake2b_init (&ctx, 64);
+ crypto_blake2b_update(&ctx, input , i);
+ crypto_blake2b_update(&ctx, mid_input, j - i);
+ crypto_blake2b_update(&ctx, input + j, INPUT_SIZE - j);
+ crypto_blake2b_final (&ctx, hash_chunk);
+
+ // Compare the results (must be the same)
+ ASSERT_EQUAL(hash_chunk, hash_whole, 64);
+ }
+ }
+ }
+
+ printf("\tBLAKE2b (overlapping i/o)\n");
+#undef INPUT_SIZE
+#define INPUT_SIZE (BLAKE2B_BLOCK_SIZE + (2 * 64)) // total input size
+ FOR (i, 0, BLAKE2B_BLOCK_SIZE + 64) {
+ u8 hash [64];
+ RANDOM_INPUT(input, INPUT_SIZE);
+ crypto_blake2b(hash , 64, input + 64, BLAKE2B_BLOCK_SIZE);
+ crypto_blake2b(input+i, 64, input + 64, BLAKE2B_BLOCK_SIZE);
+ ASSERT_EQUAL(hash, input + i, 64);
+ }
+}
+
+///////////////
+/// SHA 512 ///
+///////////////
+#define SHA_512_BLOCK_SIZE 128
+
+static void sha512(vector_reader *reader)
+{
+ vector in = next_input(reader);
+ vector out = next_output(reader);
+ crypto_sha512(out.buf, in.buf, in.size);
+}
+
+static void sha512_hmac(vector_reader *reader)
+{
+ vector key = next_input(reader);
+ vector msg = next_input(reader);
+ vector out = next_output(reader);
+ crypto_sha512_hmac(out.buf, key.buf, key.size, msg.buf, msg.size);
+}
+
+static void sha512_hkdf(vector_reader *reader)
+{
+ vector ikm = next_input(reader);
+ vector salt = next_input(reader);
+ vector info = next_input(reader);
+ vector okm = next_output(reader);
+ crypto_sha512_hkdf(okm .buf, okm .size,
+ ikm .buf, ikm .size,
+ salt.buf, salt.size,
+ info.buf, info.size);
+}
+
+static void test_sha512(void)
+{
+ VECTORS(sha512);
+ VECTORS(sha512_hmac);
+ VECTORS(sha512_hkdf);
+
+ printf("\tSHA-512 (incremental)\n");
+#undef INPUT_SIZE
+#define INPUT_SIZE (SHA_512_BLOCK_SIZE * 4 - 32) // total input size
+ {
+ RANDOM_INPUT(input, INPUT_SIZE);
+
+ // hash at once
+ u8 hash_whole[64];
+ crypto_sha512(hash_whole, input, INPUT_SIZE);
+
+ FOR (j, 0, INPUT_SIZE) {
+ FOR (i, 0, j+1) {
+ // Hash bit by bit
+ u8 *mid_input = j - i == 0 ? NULL : input + i; // NULL update
+ u8 hash_chunk[64];
+ crypto_sha512_ctx ctx;
+ crypto_sha512_init (&ctx);
+ crypto_sha512_update(&ctx, input , i);
+ crypto_sha512_update(&ctx, mid_input, j - i);
+ crypto_sha512_update(&ctx, input + j, INPUT_SIZE - j);
+ crypto_sha512_final (&ctx, hash_chunk);
+
+ // Compare the results (must be the same)
+ ASSERT_EQUAL(hash_chunk, hash_whole, 64);
+ }
+ }
+ }
+
+ printf("\tSHA-512 (overlapping i/o)\n");
+#undef INPUT_SIZE
+#define INPUT_SIZE (SHA_512_BLOCK_SIZE + (2 * 64)) // total input size
+ FOR (i, 0, SHA_512_BLOCK_SIZE + 64) {
+ u8 hash [64];
+ RANDOM_INPUT(input, INPUT_SIZE);
+ crypto_sha512(hash , input + 64, SHA_512_BLOCK_SIZE);
+ crypto_sha512(input+i, input + 64, SHA_512_BLOCK_SIZE);
+ ASSERT_EQUAL(hash, input + i, 64);
+ }
+
+ printf("\tHMAC SHA-512 (incremental)\n");
+#undef INPUT_SIZE
+#define INPUT_SIZE (SHA_512_BLOCK_SIZE * 4 - 32) // total input size
+ FOR (i, 0, INPUT_SIZE) {
+ // outputs
+ u8 hash_chunk[64];
+ u8 hash_whole[64];
+ // inputs
+ RANDOM_INPUT(key , 32);
+ RANDOM_INPUT(input, INPUT_SIZE);
+
+ // Authenticate bit by bit
+ crypto_sha512_hmac_ctx ctx;
+ crypto_sha512_hmac_init(&ctx, key, 32);
+ crypto_sha512_hmac_update(&ctx, input , i);
+ crypto_sha512_hmac_update(&ctx, input + i, INPUT_SIZE - i);
+ crypto_sha512_hmac_final(&ctx, hash_chunk);
+
+ // Authenticate all at once
+ crypto_sha512_hmac(hash_whole, key, 32, input, INPUT_SIZE);
+
+ // Compare the results (must be the same)
+ ASSERT_EQUAL(hash_chunk, hash_whole, 64);
+ }
+
+ printf("\tHMAC SHA-512 (overlapping i/o)\n");
+#undef INPUT_SIZE
+#define INPUT_SIZE (SHA_512_BLOCK_SIZE + (2 * 64)) // total input size
+ FOR (i, 0, SHA_512_BLOCK_SIZE + 64) {
+ u8 hash [64];
+ RANDOM_INPUT(key , 32);
+ RANDOM_INPUT(input, INPUT_SIZE);
+ crypto_sha512_hmac(hash , key, 32, input + 64, SHA_512_BLOCK_SIZE);
+ crypto_sha512_hmac(input+i, key, 32, input + 64, SHA_512_BLOCK_SIZE);
+ ASSERT_EQUAL(hash, input + i, 64);
+ }
+}
+
+
+//////////////
+/// Argon2 ///
+//////////////
+static void argon2(vector_reader *reader)
+{
+ crypto_argon2_config config;
+ config.algorithm = load32_le(next_input(reader).buf);
+ config.nb_blocks = load32_le(next_input(reader).buf);
+ config.nb_passes = load32_le(next_input(reader).buf);
+ config.nb_lanes = load32_le(next_input(reader).buf);
+
+ vector pass = next_input(reader);
+ vector salt = next_input(reader);
+ vector key = next_input(reader);
+ vector ad = next_input(reader);
+ vector out = next_output(reader);
+ void *work_area = alloc((size_t)config.nb_blocks * 1024);
+
+ crypto_argon2_inputs inputs;
+ inputs.pass = pass.buf;
+ inputs.salt = salt.buf;
+ inputs.pass_size = (u32)pass.size;
+ inputs.salt_size = (u32)salt.size;
+
+ crypto_argon2_extras extras;
+ extras.key = key.buf;
+ extras.ad = ad.buf;
+ extras.key_size = (u32)key.size;
+ extras.ad_size = (u32)ad.size;
+
+ crypto_argon2(out.buf, (u32)out.size, work_area, config, inputs, extras);
+ free(work_area);
+}
+
+static void test_argon2(void)
+{
+ VECTORS(argon2);
+
+ printf("\tArgon2 (overlapping i/o)\n");
+ u8 *work_area = (u8*)alloc(8 * 1024);
+ u8 *clean_work_area = (u8*)alloc(8 * 1024);
+ FOR (i, 0, 10) {
+ p_random(work_area, 8 * 1024);
+ u32 hash_offset = rand64() % 64;
+ u32 pass_offset = rand64() % 64;
+ u32 salt_offset = rand64() % 64;
+ u32 key_offset = rand64() % 64;
+ u32 ad_offset = rand64() % 64;
+ u8 hash1[32];
+ u8 *hash2 = work_area + hash_offset;
+ u8 pass[16]; FOR (j, 0, 16) { pass[j] = work_area[j + pass_offset]; }
+ u8 salt[16]; FOR (j, 0, 16) { salt[j] = work_area[j + salt_offset]; }
+ u8 key [32]; FOR (j, 0, 32) { key [j] = work_area[j + key_offset]; }
+ u8 ad [32]; FOR (j, 0, 32) { ad [j] = work_area[j + ad_offset]; }
+
+ crypto_argon2_config config;
+ config.algorithm = CRYPTO_ARGON2_I;
+ config.nb_blocks = 8;
+ config.nb_passes = 1;
+ config.nb_lanes = 1;
+
+ crypto_argon2_inputs inputs;
+ inputs.pass = pass;
+ inputs.salt = salt;
+ inputs.pass_size = sizeof(pass);
+ inputs.salt_size = sizeof(salt);
+
+ crypto_argon2_extras extras;
+ extras.key = key;
+ extras.ad = ad;
+ extras.key_size = sizeof(key);
+ extras.ad_size = sizeof(ad);
+
+ crypto_argon2(hash1, 32, clean_work_area, config, inputs, extras);
+
+ // with overlap
+ inputs.pass = work_area + pass_offset;
+ inputs.salt = work_area + salt_offset;
+ extras.key = work_area + key_offset;
+ extras.ad = work_area + ad_offset;
+ crypto_argon2(hash2, 32, work_area, config, inputs, extras);
+
+ ASSERT_EQUAL(hash1, hash2, 32);
+ }
+ free(work_area);
+ free(clean_work_area);
+}
+
+//////////////
+/// X25519 ///
+//////////////
+static void x25519(vector_reader *reader)
+{
+ vector scalar = next_input(reader);
+ vector point = next_input(reader);
+ vector out = next_output(reader);
+ crypto_x25519(out.buf, scalar.buf, point.buf);
+}
+
+static void x25519_pk(vector_reader *reader)
+{
+ vector in = next_input(reader);
+ vector out = next_output(reader);
+ crypto_x25519_public_key(out.buf, in.buf);
+}
+
+static void iterate_x25519(u8 k[32], u8 u[32])
+{
+ u8 tmp[32];
+ crypto_x25519(tmp , k, u);
+ memcpy(u, k , 32);
+ memcpy(k, tmp, 32);
+}
+
+static void test_x25519(void)
+{
+ VECTORS(x25519);
+ VECTORS(x25519_pk);
+
+ {
+ printf("\tx25519 1\n");
+ u8 _1 [32] = {
+ 0x42, 0x2c, 0x8e, 0x7a, 0x62, 0x27, 0xd7, 0xbc,
+ 0xa1, 0x35, 0x0b, 0x3e, 0x2b, 0xb7, 0x27, 0x9f,
+ 0x78, 0x97, 0xb8, 0x7b, 0xb6, 0x85, 0x4b, 0x78,
+ 0x3c, 0x60, 0xe8, 0x03, 0x11, 0xae, 0x30, 0x79
+ };
+ u8 k[32] = {9};
+ u8 u[32] = {9};
+ crypto_x25519_public_key(k, u);
+ ASSERT_EQUAL(k, _1, 32);
+
+ printf("\tx25519 1K\n");
+ u8 _1k [32] = {
+ 0x68, 0x4c, 0xf5, 0x9b, 0xa8, 0x33, 0x09, 0x55,
+ 0x28, 0x00, 0xef, 0x56, 0x6f, 0x2f, 0x4d, 0x3c,
+ 0x1c, 0x38, 0x87, 0xc4, 0x93, 0x60, 0xe3, 0x87,
+ 0x5f, 0x2e, 0xb9, 0x4d, 0x99, 0x53, 0x2c, 0x51
+ };
+ FOR (i, 1, 1000) { iterate_x25519(k, u); }
+ ASSERT_EQUAL(k, _1k, 32);
+
+ // too long; didn't run
+ //printf("\tx25519 1M\n");
+ //u8 _1M[32] = {
+ // 0x7c, 0x39, 0x11, 0xe0, 0xab, 0x25, 0x86, 0xfd,
+ // 0x86, 0x44, 0x97, 0x29, 0x7e, 0x57, 0x5e, 0x6f,
+ // 0x3b, 0xc6, 0x01, 0xc0, 0x88, 0x3c, 0x30, 0xdf,
+ // 0x5f, 0x4d, 0xd2, 0xd2, 0x4f, 0x66, 0x54, 0x24
+ //};
+ //FOR (i, 1000, 1000000) { iterate_x25519(k, u); }
+ //ASSERT_EQUAL(k, _1M, 32);
+ }
+
+ printf("\tx25519 (overlapping i/o)\n");
+ FOR (i, 0, 62) {
+ u8 overlapping[94];
+ u8 separate[32];
+ RANDOM_INPUT(sk, 32);
+ RANDOM_INPUT(pk, 32);
+ memcpy(overlapping + 31, sk, 32);
+ crypto_x25519(overlapping + i, overlapping + 31, pk);
+ crypto_x25519(separate, sk, pk);
+ ASSERT_EQUAL(separate, overlapping + i, 32);
+ }
+
+ printf("\tx25519_inverse\n");
+ {
+ RANDOM_INPUT(b, 32);
+ u8 base[32]; // random point (cofactor is cleared).
+ crypto_x25519_public_key(base, b);
+ // check round trip
+ FOR (i, 0, 50) {
+ RANDOM_INPUT(sk, 32);
+ u8 pk [32];
+ u8 blind[32];
+ crypto_x25519(pk, sk, base);
+ crypto_x25519_inverse(blind, sk, pk);
+ ASSERT_EQUAL(blind, base, 32);
+ }
+
+ // check cofactor clearing
+ // (Multiplying by a low order point yields zero
+ u8 low_order[4][32] = {
+ {0}, {1},
+ {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,},
+ {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,},
+ };
+ u8 zero[32] = {0};
+ FOR (i, 0, 32) {
+ u8 blind[32];
+ RANDOM_INPUT(sk, 32);
+ crypto_x25519_inverse(blind, sk, low_order[i%4]);
+ ASSERT_EQUAL(blind, zero, 32);
+ }
+ }
+
+ printf("\tx25519 inverse (overlapping i/o)\n");
+ FOR (i, 0, 62) {
+ u8 overlapping[94];
+ u8 separate[32];
+ RANDOM_INPUT(sk, 32);
+ RANDOM_INPUT(pk, 32);
+ memcpy(overlapping + 31, sk, 32);
+ crypto_x25519_inverse(overlapping + i, overlapping + 31, pk);
+ crypto_x25519_inverse(separate, sk, pk);
+ ASSERT_EQUAL(separate, overlapping + i, 32);
+ }
+}
+
+///////////////////
+/// EdDSA utils ///
+///////////////////
+
+// Adds X time L to the input
+static void add_xl(u8 out[32], u8 in[32], unsigned factor)
+{
+ static const u8 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,
+ };
+ ASSERT(factor <= 8);
+ unsigned acc = 0;
+ FOR(i, 0, 32) {
+ acc += in[i] + L[i] * factor;
+ out[i] = acc & 0xff;
+ acc >>= 8;
+ }
+ ASSERT(acc == 0); // No carry is remaining
+}
+
+static void test_edDSA_utils(void)
+{
+ printf("\tEdDSA (scalarbase)\n");
+ FOR (i, 0, 50) {
+ RANDOM_INPUT(scalar, 32);
+ u8 scalar_plus[32];
+ u8 point [32];
+ u8 point_plus [32];
+
+ // Equivalent (yet different) scalars
+ scalar[31] &= 0xf; // trim the scalar below 252 bits
+ add_xl(scalar_plus, scalar, 8); // 8*L == curve order
+ ASSERT_DIFFERENT(scalar, scalar_plus, 32);
+
+ // Bit-for-bit identical points
+ crypto_eddsa_scalarbase(point , scalar);
+ crypto_eddsa_scalarbase(point_plus, scalar_plus);
+ ASSERT_EQUAL(point, point_plus, 32);
+ }
+}
+
+/////////////
+/// EdDSA ///
+/////////////
+static void edDSA(vector_reader *reader)
+{
+ vector secret_k = next_input(reader);
+ vector public_k = next_input(reader);
+ vector msg = next_input(reader);
+ vector out = next_output(reader);
+ u8 fat_secret_key[64];
+ memcpy(fat_secret_key , secret_k.buf, 32);
+ memcpy(fat_secret_key + 32, public_k.buf, 32);
+ crypto_eddsa_sign(out.buf, fat_secret_key, msg.buf, msg.size);
+}
+
+static void edDSA_pk(vector_reader *reader)
+{
+ vector in = next_input(reader);
+ vector out = next_output(reader);
+ u8 seed [32];
+ u8 secret_key[64];
+ u8 public_key[32];
+ memcpy(seed, in.buf, 32);
+ crypto_eddsa_key_pair(secret_key, public_key, seed);
+ memcpy(out.buf, public_key, 32);
+
+ u8 zeroes[32] = {0};
+ ASSERT_EQUAL(seed , zeroes , 32);
+ ASSERT_EQUAL(secret_key , in.buf , 32);
+ ASSERT_EQUAL(secret_key + 32, public_key, 32);
+}
+
+static void test_edDSA(void)
+{
+ VECTORS(edDSA);
+ VECTORS(edDSA_pk);
+
+ printf("\tEdDSA (roundtrip)\n");
+#define MESSAGE_SIZE 30
+ FOR (i, 0, MESSAGE_SIZE) {
+ RANDOM_INPUT(message, MESSAGE_SIZE);
+ RANDOM_INPUT(seed, 32);
+ u8 sk [64];
+ u8 pk [32];
+ u8 signature[64];
+ crypto_eddsa_key_pair(sk, pk, seed);
+ crypto_eddsa_sign(signature, sk, message, i);
+ ASSERT_OK(crypto_eddsa_check(signature, pk, message, i));
+
+ // reject forgeries
+ u8 zero [64] = {0};
+ ASSERT_KO(crypto_eddsa_check(zero , pk, message, i));
+ FOR (j, 0, 64) {
+ u8 forgery[64];
+ memcpy(forgery, signature, 64);
+ forgery[j] = signature[j] + 1;
+ ASSERT_KO(crypto_eddsa_check(forgery, pk, message, i));
+ }
+ }
+
+ printf("\tEdDSA (random)\n");
+ {
+ // Verifies that random signatures are all invalid. Uses random
+ // public keys to see what happens outside of the curve (it should
+ // yield an invalid signature).
+ FOR (i, 0, 100) {
+ RANDOM_INPUT(message, MESSAGE_SIZE);
+ RANDOM_INPUT(pk, 32);
+ RANDOM_INPUT(signature , 64);
+ ASSERT_KO(crypto_eddsa_check(signature, pk, message, MESSAGE_SIZE));
+ }
+ // Testing S == L (for code coverage)
+ RANDOM_INPUT(message, MESSAGE_SIZE);
+ RANDOM_INPUT(pk, 32);
+ static const u8 signature[64] = {
+ 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,
+ 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,
+ };
+ ASSERT_KO(crypto_eddsa_check(signature, pk, message, MESSAGE_SIZE));
+ }
+
+ printf("\tEdDSA (overlap)\n");
+ FOR(i, 0, MESSAGE_SIZE + 64) {
+#undef INPUT_SIZE
+#define INPUT_SIZE (MESSAGE_SIZE + (2 * 64)) // total input size
+ RANDOM_INPUT(input, INPUT_SIZE);
+ RANDOM_INPUT(seed, 32);
+ u8 sk [64];
+ u8 pk [32];
+ u8 signature[64];
+ crypto_eddsa_key_pair(sk, pk, seed);
+ crypto_eddsa_sign(signature, sk, input + 64, MESSAGE_SIZE);
+ crypto_eddsa_sign(input+i , sk, input + 64, MESSAGE_SIZE);
+ ASSERT_EQUAL(signature, input + i, 64);
+ }
+}
+
+///////////////
+/// Ed25519 ///
+///////////////
+static void ed_25519(vector_reader *reader)
+{
+ vector secret_k = next_input(reader);
+ vector public_k = next_input(reader);
+ vector msg = next_input(reader);
+ vector out = next_output(reader);
+ u8 fat_secret_key[64];
+ memcpy(fat_secret_key , secret_k.buf, 32);
+ memcpy(fat_secret_key + 32, public_k.buf, 32);
+ crypto_ed25519_sign(out.buf, fat_secret_key, msg.buf, msg.size);
+}
+
+static void ed_25519_pk(vector_reader *reader)
+{
+ vector in = next_input(reader);
+ vector out = next_output(reader);
+ u8 seed [32];
+ u8 secret_key[64];
+ u8 public_key[32];
+ memcpy(seed, in.buf, 32);
+ crypto_ed25519_key_pair(secret_key, public_key, seed);
+ memcpy(out.buf, public_key, 32);
+
+ u8 zeroes[32] = {0};
+ ASSERT_EQUAL(seed , zeroes , 32);
+ ASSERT_EQUAL(secret_key , in.buf , 32);
+ ASSERT_EQUAL(secret_key + 32, public_key, 32);
+}
+
+static void ed_25519_check(vector_reader *reader)
+{
+ vector public_k = next_input(reader);
+ vector msg = next_input(reader);
+ vector sig = next_input(reader);
+ vector out = next_output(reader);
+ out.buf[0] = (u8)crypto_ed25519_check(sig.buf, public_k.buf,
+ msg.buf, msg.size);
+}
+
+static void ed_25519ph(vector_reader *reader)
+{
+ vector sk = next_input(reader);
+ vector pk = next_input(reader);
+ vector msg = next_input(reader);
+ vector out = next_output(reader);
+
+ // Test that we generate the correct public key
+ uint8_t secret_key[64];
+ uint8_t public_key[32];
+ crypto_ed25519_key_pair(secret_key, public_key, sk.buf);
+ ASSERT_EQUAL(public_key, pk.buf, 32);
+ ASSERT_EQUAL(public_key, secret_key + 32, 32);
+
+ // Generate output signature for comparison
+ uint8_t digest[64];
+ crypto_sha512(digest, msg.buf, msg.size);
+ crypto_ed25519_ph_sign(out.buf, secret_key, digest);
+
+ // Test that the correct signature is accepted
+ ASSERT_OK(crypto_ed25519_ph_check(out.buf, pk.buf, digest));
+
+ // Test that corrupted signatures are rejected
+ for (size_t i = 0; i < 64; i++) {
+ uint8_t corrupt_signature[64];
+ memcpy(corrupt_signature, out.buf, 64);
+ corrupt_signature[i] ^= 1; // corrupt one bit
+ ASSERT_KO(crypto_ed25519_ph_check(corrupt_signature, pk.buf, digest));
+ }
+}
+
+static void test_ed25519(void)
+{
+ VECTORS(ed_25519);
+ VECTORS(ed_25519_pk);
+ VECTORS(ed_25519_check);
+ VECTORS(ed_25519ph);
+}
+
+/////////////////
+/// Elligator ///
+/////////////////
+static void elligator_dir(vector_reader *reader)
+{
+ vector in = next_input(reader);
+ vector out = next_output(reader);
+ crypto_elligator_map(out.buf, in.buf);
+}
+
+static void elligator_inv(vector_reader *reader)
+{
+ vector point = next_input(reader);
+ u8 tweak = next_input(reader).buf[0];
+ u8 failure = next_input(reader).buf[0];
+ vector out = next_output(reader);
+ int check = crypto_elligator_rev(out.buf, point.buf, tweak);
+ ASSERT((u8)check == failure);
+}
+
+static void test_elligator(void)
+{
+ VECTORS(elligator_dir);
+
+ printf("\telligator direct (msb)\n");
+ FOR (i, 0, 20) {
+ RANDOM_INPUT(r, 32);
+ u8 r1[32]; memcpy(r1, r, 32); r1[31] = (r[31] & 0x3f) | 0x00;
+ u8 r2[32]; memcpy(r2, r, 32); r2[31] = (r[31] & 0x3f) | 0x40;
+ u8 r3[32]; memcpy(r3, r, 32); r3[31] = (r[31] & 0x3f) | 0x80;
+ u8 r4[32]; memcpy(r4, r, 32); r4[31] = (r[31] & 0x3f) | 0xc0;
+ u8 u [32]; crypto_elligator_map(u , r );
+ u8 u1[32]; crypto_elligator_map(u1, r1);
+ u8 u2[32]; crypto_elligator_map(u2, r2);
+ u8 u3[32]; crypto_elligator_map(u3, r3);
+ u8 u4[32]; crypto_elligator_map(u4, r4);
+ ASSERT_EQUAL(u, u1, 32);
+ ASSERT_EQUAL(u, u2, 32);
+ ASSERT_EQUAL(u, u3, 32);
+ ASSERT_EQUAL(u, u4, 32);
+ }
+
+ printf("\telligator direct (overlapping i/o)\n");
+ FOR (i, 0, 62) {
+ u8 overlapping[94];
+ u8 separate[32];
+ RANDOM_INPUT(r, 32);
+ memcpy(overlapping + 31, r, 32);
+ crypto_elligator_map(overlapping + i, overlapping + 31);
+ crypto_elligator_map(separate, r);
+ ASSERT_EQUAL(separate, overlapping + i, 32);
+ }
+
+ VECTORS(elligator_inv);
+
+ printf("\telligator inverse (overlapping i/o)\n");
+ FOR (i, 0, 62) {
+ u8 overlapping[94];
+ u8 separate[32];
+ RANDOM_INPUT(pk, 33);
+ u8 tweak = pk[32];
+ memcpy(overlapping + 31, pk, 32);
+ int a = crypto_elligator_rev(overlapping+i, overlapping+31, tweak);
+ int b = crypto_elligator_rev(separate, pk, tweak);
+ ASSERT(a == b);
+ if (a == 0) {
+ // The buffers are the same only if written to to begin with
+ ASSERT_EQUAL(separate, overlapping + i, 32);
+ }
+ }
+
+ printf("\telligator x25519\n");
+ FOR (i, 0, 64) {
+ RANDOM_INPUT(sk1, 32);
+ RANDOM_INPUT(sk2, 32);
+ u8 skc [32]; memcpy(skc, sk1, 32); skc[0] &= 248;
+ u8 pks [32]; crypto_x25519_dirty_small(pks , sk1);
+ u8 pksc[32]; crypto_x25519_dirty_small(pksc, skc);
+ u8 pkf [32]; crypto_x25519_dirty_fast (pkf , sk1);
+ u8 pkfc[32]; crypto_x25519_dirty_fast (pkfc, skc);
+ u8 pk1 [32]; crypto_x25519_public_key (pk1 , sk1);
+
+ // Both dirty functions behave the same
+ ASSERT_EQUAL(pks, pkf, 32);
+
+ // Dirty functions behave cleanly if we clear the 3 lsb first
+ ASSERT_EQUAL(pksc, pk1, 32);
+ ASSERT_EQUAL(pkfc, pk1, 32);
+
+ // Dirty functions behave the same as the clean one if the lsb
+ // are 0, differently if it is not
+ if ((sk1[0] & 7) == 0) { ASSERT_EQUAL (pk1, pkf, 32); }
+ else { ASSERT_DIFFERENT(pk1, pkf, 32); }
+
+ // Maximise tweak diversity.
+ // We want to set the bits 1 (sign) and 6-7 (padding)
+ u8 tweak = (u8)((i & 1) + (i << 5));
+ u8 r[32];
+ if (crypto_elligator_rev(r, pkf, tweak)) {
+ i--; // Cancel tweak increment
+ continue; // retry untill success
+ }
+ // Verify that the tweak's msb are copied to the representative
+ ASSERT((tweak >> 6) == (r[31] >> 6));
+
+ // Round trip
+ u8 pkr[32]; crypto_elligator_map(pkr, r);
+ ASSERT_EQUAL(pkr, pkf, 32);
+
+ // Dirty and safe keys are compatible
+ u8 e1 [32]; crypto_x25519(e1, sk2, pk1);
+ u8 e2 [32]; crypto_x25519(e2, sk2, pkr);
+ ASSERT_EQUAL(e1, e2, 32);
+ }
+
+ printf("\telligator key pair\n");
+ FOR(i, 0, 32) {
+ RANDOM_INPUT(seed, 32);
+ RANDOM_INPUT(sk2 , 32);
+ u8 r [32];
+ u8 sk1[32]; crypto_elligator_key_pair(r, sk1, seed);
+ u8 pkr[32]; crypto_elligator_map(pkr, r);
+ u8 pk1[32]; crypto_x25519_public_key(pk1, sk1);
+ u8 e1 [32]; crypto_x25519(e1, sk2, pk1);
+ u8 e2 [32]; crypto_x25519(e2, sk2, pkr);
+ ASSERT_EQUAL(e1, e2, 32);
+ }
+
+ printf("\telligator key pair (overlapping i/o)\n");
+ FOR (i, 0, 94) {
+ u8 over[158];
+ u8 sep [ 64];
+ RANDOM_INPUT(s1, 32);
+ u8 *s2 = over + 63;
+ memcpy(s2, s1, 32);
+ crypto_elligator_key_pair(sep , sep + 32, s1);
+ crypto_elligator_key_pair(over + i, over + i + 32, s2);
+ ASSERT_EQUAL(sep, over + i, 64);
+ }
+}
+
+////////////////////////
+/// X25519 <-> EdDSA ///
+////////////////////////
+static void test_conversions(void)
+{
+ printf("\tX25519 <-> EdDSA\n");
+ FOR (i, 0, 32) {
+ RANDOM_INPUT(e_seed, 32);
+ u8 secret [64];
+ u8 e_public1[32]; crypto_eddsa_key_pair(secret, e_public1, e_seed);
+ u8 x_private[64]; crypto_blake2b(x_private, 64, secret, 32);
+ u8 x_public1[32]; crypto_eddsa_to_x25519 (x_public1, e_public1);
+ u8 x_public2[32]; crypto_x25519_public_key(x_public2, x_private);
+ ASSERT_EQUAL(x_public1, x_public2, 32);
+
+ u8 e_public2[32]; crypto_x25519_to_eddsa (e_public2, x_public1);
+ ASSERT((e_public2[31] & 0x80) == 0); // x coordinate always positive
+
+ e_public1[31] &= 0x7f; // y coordinate back to original
+ ASSERT_EQUAL(e_public1, e_public2, 32);
+ }
+}
+
+int main(int argc, char *argv[])
+{
+ if (argc > 1) {
+ sscanf(argv[1], "%" PRIu64 "", &random_state);
+ }
+ printf("\nRandom seed = %" PRIu64 "\n\n", random_state);
+
+ printf("Wipe: \n");
+ test_wipe();
+
+ printf("Comparisons:\n");
+ test_verify();
+
+ printf("Encryption:\n");
+ test_chacha20();
+ test_aead();
+
+ printf("Hashes:\n");
+ test_poly1305();
+ test_blake2b();
+ test_sha512();
+ test_argon2();
+
+ printf("X25519:\n");
+ test_x25519();
+
+ printf("EdDSA:\n");
+ test_edDSA_utils();
+ test_edDSA();
+ test_ed25519();
+
+ printf("Elligator:\n");
+ test_elligator();
+
+ printf("Curve25519 conversions:\n");
+ test_conversions();
+
+ printf("\nAll tests OK!\n");
+ return 0;
+}
diff --git a/lib/Utils.Cryptography/monocypher/vendor/tests/test.sh b/lib/Utils.Cryptography/monocypher/vendor/tests/test.sh
new file mode 100644
index 0000000..8129823
--- /dev/null
+++ b/lib/Utils.Cryptography/monocypher/vendor/tests/test.sh
@@ -0,0 +1,69 @@
+#! /bin/sh
+
+# This file is dual-licensed. Choose whichever licence you want from
+# the two licences listed below.
+#
+# The first licence is a regular 2-clause BSD licence. The second licence
+# is the CC-0 from Creative Commons. It is intended to release Monocypher
+# to the public domain. The BSD licence serves as a fallback option.
+#
+# SPDX-License-Identifier: BSD-2-Clause OR CC0-1.0
+#
+# ------------------------------------------------------------------------
+#
+# Copyright (c) 2017-2019, Loup Vaillant
+# 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 COPYRIGHT HOLDERS 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 COPYRIGHT
+# HOLDER 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.
+#
+# ------------------------------------------------------------------------
+#
+# Written in 2017-2019 by Loup Vaillant
+#
+# To the extent possible under law, the author(s) have dedicated all copyright
+# and related 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
+# <https://creativecommons.org/publicdomain/zero/1.0/>
+
+set -e
+
+CC="clang -std=c99"
+CFLAGS="-pedantic -Wall -Wextra -g -O2"
+
+make clean; make tis-ci
+make clean; make test
+make clean; make test CC="$CC" CFLAGS="$CFLAGS -DBLAKE2_NO_UNROLLING"
+make clean; make test CC="$CC" CFLAGS="$CFLAGS -fsanitize=address"
+make clean; make test CC="$CC" CFLAGS="$CFLAGS -fsanitize=memory"
+make clean; make test CC="$CC" CFLAGS="$CFLAGS -fsanitize=undefined"
+make clean; make test.out CC="gcc -std=c99"; valgrind ./test.out
+
+echo
+echo "All sanitisers passed!"
+echo
diff --git a/lib/Utils.Cryptography/monocypher/vendor/tests/tis-ci-gen-config.sh b/lib/Utils.Cryptography/monocypher/vendor/tests/tis-ci-gen-config.sh
new file mode 100644
index 0000000..5c8c754
--- /dev/null
+++ b/lib/Utils.Cryptography/monocypher/vendor/tests/tis-ci-gen-config.sh
@@ -0,0 +1,114 @@
+#! /bin/sh
+
+# This file is dual-licensed. Choose whichever licence you want from
+# the two licences listed below.
+#
+# The first licence is a regular 2-clause BSD licence. The second licence
+# is the CC-0 from Creative Commons. It is intended to release Monocypher
+# to the public domain. The BSD licence serves as a fallback option.
+#
+# SPDX-License-Identifier: BSD-2-Clause OR CC0-1.0
+#
+# ------------------------------------------------------------------------
+#
+# Copyright (c) 2020, Loup Vaillant
+# 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 COPYRIGHT HOLDERS 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 COPYRIGHT
+# HOLDER 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.
+#
+# ------------------------------------------------------------------------
+#
+# Written in 2020 by Loup Vaillant
+#
+# To the extent possible under law, the author(s) have dedicated all copyright
+# and related 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
+# <https://creativecommons.org/publicdomain/zero/1.0/>
+
+DIR=$(dirname "$0")
+TIS_CONFIG=$DIR/../tis.config
+
+echo "// auto generated with $0" > $TIS_CONFIG
+echo "[" >> $TIS_CONFIG
+
+for entry_point in \
+ "p_wipe" \
+ "v_chacha20" \
+ "v_ietf_chacha20" \
+ "v_hchacha20" \
+ "v_xchacha20" \
+ "v_poly1305" \
+ "v_aead_ietf" \
+ "v_blake2b" \
+ "v_sha512" \
+ "v_sha512_hmac" \
+ "v_sha512_hkdf" \
+ "v_argon2" \
+ "v_x25519" \
+ "v_edDSA" \
+ "v_edDSA_pk" \
+ "v_ed_25519" \
+ "v_ed_25519_check" \
+ "v_elligator_dir" \
+ "v_elligator_inv" \
+ "p_eddsa_x25519" \
+ "p_dirty" \
+ "p_x25519_inverse" \
+ "p_verify16" \
+ "p_verify32" \
+ "p_verify64"
+do
+ for platform in \
+ "x86_16" \
+ "sparc_32" \
+ "x86_32" \
+ "rv64ifdq" \
+ "mips_64"
+ do
+ echo '{ "name" :' "\"$entry_point - $platform\"" >> $TIS_CONFIG
+ echo ', "files" :' >> $TIS_CONFIG
+ echo ' [ "src/monocypher.c"' >> $TIS_CONFIG
+ echo ' , "src/optional/monocypher-ed25519.c"' >> $TIS_CONFIG
+ echo ' , "tests/utils.c"' >> $TIS_CONFIG
+ echo ' , "tests/tis-ci.c"' >> $TIS_CONFIG
+ echo ' ]' >> $TIS_CONFIG
+ echo ', "cpp-extra-args":
+ "-Isrc -Isrc/optional -Itests -Dvolatile=
+ -DCLOCK_PROCESS_CPUTIME_ID=3 -DCLOCK_THREAD_CPUTIME_ID=4"' \
+ >> $TIS_CONFIG
+ echo ', "machdep" :' "\"$platform\"" >> $TIS_CONFIG
+ echo ', "no-results" : true' >> $TIS_CONFIG
+ echo ', "main" :' "\"$entry_point\"" >> $TIS_CONFIG
+ echo '},' >> $TIS_CONFIG
+ done
+done
+sed -i '$ d' $TIS_CONFIG
+
+echo "}" >> $TIS_CONFIG
+echo "]" >> $TIS_CONFIG
diff --git a/lib/Utils.Cryptography/monocypher/vendor/tests/tis-ci-vectors.h b/lib/Utils.Cryptography/monocypher/vendor/tests/tis-ci-vectors.h
new file mode 100644
index 0000000..b3505d7
--- /dev/null
+++ b/lib/Utils.Cryptography/monocypher/vendor/tests/tis-ci-vectors.h
@@ -0,0 +1,532 @@
+// Generated with hard coded official vectors, and
+// random vectors with libsodium and ed25519-donna.
+// Download Monocypher's git repository to regenerate.
+#include <inttypes.h>
+#include <stddef.h>
+
+static const char *chacha20_vectors[]={
+ "e4c4054fe35a75d9c0f679ad8770d8227e68e4c1e68ce67ee88e6be251a20748",
+ "b3753cff3a6d9901",
+ "",
+ "e4b5efc932fb5798",
+ "",
+ "b181071f299aa254a4606ab6a058e0c6fb5598218db71deb473f7d04c152e7e8",
+ "57736715dc7b788a",
+ "ca",
+ "f6f5808bdc50fb80",
+ "c1",
+ "9f40d6c8348c353b00172655236cddcd1879ca1f04b35f91adab70b81f504035",
+ "fc169964a5ae985e",
+ "6c11b0b7bb18a51fd77fbffd722aa220efdd8947ca5a5c7fb1c2ebdb9ad1f603801ff22e80314f716af9c22022fa159dbb4b4d3153f999b20ab4769eb1d01c",
+ "593e47059549b141",
+ "907aae5d8cea5ca4cc0842dd58a333bcffcd8f2a234ab46a7dc78c3d690a3f01f89aa75426cec8469f36e2b4c41fdba7290a18cef9b39f807a20f1b6933807",
+ "80bd73e9ca43cdd4eb7173476862df6d2458d6c74739a0ad2169b9c89edd74e1",
+ "6fbcecc748c25dc3",
+ "38041fc34af0f1bda20eaf3fff7b372aa801eb98a1298bc61028073750831c8cb43cd6822bf3f6fae0801cb6c843d8066b07346635365fb7d6ee54e5c9cd6f05",
+ "29958874e0842c12",
+ "c44c93948a3ccc5d473d1319efb42d1944e734fc5b613953845be858c5df073e6448a6e442378d631e9705e0efe3e8d7309458542a715453174f21b4ca3562e9",
+ "df1a2d6a963a79c58401770a383248b5d70bb4adedcbe520fed634f513b8c2ea",
+ "6ab37fe633ba7302",
+ "a5db6c2aa209e24478fa1bd6f6ffabe98555e034342cbec07364c54d1e407e282ef08edbfdbde936c9d42df58ae15889f5c939a3087eaeac1f2a58e2c2763d01b5",
+ "69239a9ce179621b",
+ "fd09781721c44cadcc4286a6c06f1831934c371e56f66f7e30f28425c65c28b7673bfd8a3f924c4db345b15b385e05b1d8262935f73b26bffa8c327be97fae7749",
+ "ddf049c971cd99f694e3b2a5e25fa37aedf01bf32e7c679a3187e22a635d301c",
+ "e98ad000ca301049",
+ "f2e891e403250c3358fc2030b227bb96e93b88f419afe9f9d660e013761228051ec5a8f0c093b33fc60e2cd7a9c845434e95d4319d79d1bdaa8f73853fbd9958e9ffc23a0ecbb7b48dbba63672d582bb83d92249800324cbc9a6e5b37d36887e7c79093f58ef8f1a001585321bfee1714260dd6130cc768d20b14d3850f0ee",
+ "7e3639fb14f22b46",
+ "2bb10ad9f818fa3928d24eff4b44db7fbad65b78d0c9022c0748cff53ddc9dbf158987739cb3779ebe1b877febcd8ba25f0e0dc5afbde8a550c30059ef72bf9ca8ec166bcf015d95e6a327da53ea626d71e7b8ff61f1780ef4ba9a8e7fd6e92c762834ba57cc8bdd952a8fbb99f415ce4999fce4d5a314d62288544048edcc",
+ "f349110e751c16cdb5ed05516df17479937d942c90eb1fb1813062bd3f3f6b76",
+ "68cd8fd3afce0cc7",
+ "529b87dfc58eceb951e1e53d9e94793329199c42d004bc0f0dab3adf0cd702e99efa5ef6e59d3b201680f8e2d5a4ef7f23f1b6a8e102670a3829a995ae23fbc3a5639e028cd2b5f71bb90c7a1e4a8a05017d26e3afc3a88541f6c3f45d71f8a3cc31a063ea4aad1b4d00db6f5228e9b9b1561a7f61812b8b79e6af4292580d02",
+ "f8f7da8f9106fe6a",
+ "95548a60e1774d3814da2f4e6d05f71463396f3b02dcfe4f47ce9ec0d88485396ea51ef6164758dbfef8425bd303a5328f79cdc5cdcc27a533134bde8bbd5b67d54af624827cab5454128e3000bb655e2f402b5fed18cad64a679e0966a9a14bb69312b0e6cd922c90778629163e9635a3610986ce9eea32d613a1674e438f0d",
+ "ea4f6266d04244303304510272e383eaa51a8ea7099a74bafa3375b210653a0d",
+ "2f40b15afd725cf5",
+ "065066be1cb803dc158865ed8d7cca72dcf2b7c6b5d0d045bf32b063d3da484ba1843e071b61c49ce7f30ba18a4f7ef2730ecd785494839966f593168e17311913753c59593fc66cb664c1572251132fc28bf37fd8e96f2327cf7948a1126fd37175a91f483d6b3ad92308df7e6daa8bf3efde75f80ad72a49ae0794009e21ad",
+ "ffffffffffffffff",
+ "9e3d7360a50fffcae4e9ec400fe957a4fb41bf1751bcdf55ddd09355cdd4bf1c0d01dfc30f33f84bfc067b7b5509e5c7edc4c44493e6b83d92cbb868193f7c6a1b919c1b7bf15e8365e9d254da9a73471b956bb1f4e18ac40ab7b732b33a5a20ee113146e6c8a1cc9380ca4b53d17fa0f73a4d09d13aa47bbf57a3ae1e8472cc",
+};
+static size_t nb_chacha20_vectors=40;
+static const char *hchacha20_vectors[]={
+ "e4e4c4054fe35a75d9c0f679ad8770d8227e68e4c1e68ce67ee88e6be251a207",
+ "48b3753cff3a6d990163e6b60da1e4e5",
+ "d805447c583fd97a07a2b7ab66be621ad0fa32d63d86ac20588da90b87c1907b",
+};
+static size_t nb_hchacha20_vectors=3;
+static const char *xchacha20_vectors[]={
+ "e4c4054fe35a75d9c0f679ad8770d8227e68e4c1e68ce67ee88e6be251a20748",
+ "b3753cff3a6d990163e6b60da1e4e5d6a2df78c16c96a52d",
+ "",
+ "e4b5efc932fb5798",
+ "",
+ "fb5598218db71deb473f7d04c152e7e857736715dc7b788aca39a3c96a878019",
+ "e8999c815c5723dbfbde05e6c71f118afc0dedb5b9f8dea3",
+ "98",
+ "c6f8a1251f9ad994",
+ "ce",
+ "fc169964a5ae985e6c11b0b7bb18a51fd77fbffd722aa220efdd8947ca5a5c7f",
+ "b1c2ebdb9ad1f603801ff22e80314f716af9c22022fa159d",
+ "bb4b4d3153f999b20ab4769eb1d01c057c5295ed042b4536561dce32478b113adb5b605cac75bcfcacb5e3e811b78e72e398fdd118bf04c6a7ed0756a3533e",
+ "35641c67031a10fe",
+ "dfd9414fa3546744b8fb2b4f7c83d8fcdb452b7f07704916e17bac8b7696c54ccfa3401a6bfcbebacffd1559db8150ceb7ea2a963ac1f434b498b1a79d2fc2",
+ "a20eaf3fff7b372aa801eb98a1298bc61028073750831c8cb43cd6822bf3f6fa",
+ "e0801cb6c843d8066b07346635365fb7d6ee54e5c9cd6f05",
+ "d76b2bd4caec8d80b58235cb4268543ab0eb865a948cc5b5f6e31f05f8146bd9495acc459d6d200005ee72c3bc3e4ae3badfd79adfe46b2ae1045f78382e04c9",
+ "bde0e2149cc1f90e",
+ "f90ab4866767e8686ae1cddd6a607dd8c733522163c4584af07db2e0211d2f81eb4a52b87acfa895188d10ec16c9d21a0b7f20a82342e15a0f23de0d773a8f1f",
+ "7364c54d1e407e282ef08edbfdbde936c9d42df58ae15889f5c939a3087eaeac",
+ "1f2a58e2c2763d01b55744c4a65f4db93adff0078c63f090",
+ "fb607a90c87defd622e5f55977877cec9ed88312b0411228540cd6dde6e84cd2da59b1871db119e3298e3c12fe8200a47eddf049c971cd99f694e3b2a5e25fa37a",
+ "c0a356c9d7da2928",
+ "1fa0dc38852769722f14441e859df73a36ae6f6b256c425216a513e8a79b665e8204b68f8b5b382f0e75691fbdfa6a10e907f30ae0b1f22c9414cc8bd1e4ec926b",
+ "c60e2cd7a9c845434e95d4319d79d1bdaa8f73853fbd9958e9ffc23a0ecbb7b4",
+ "8dbba63672d582bb83d92249800324cbc9a6e5b37d36887e",
+ "7c79093f58ef8f1a001585321bfee1714260dd6130cc768d20b14d3850f0eec0f8f349110e751c16cdb5ed05516df17479937d942c90eb1fb1813062bd3f3f6b7668cd8fd3afce0cc7529b87dfc58eceb951e1e53d9e94793329199c42d004bc0f0dab3adf0cd702e99efa5ef6e59d3b201680f8e2d5a4ef7f23f1b6a8e102",
+ "3f21afec4e3df4a4",
+ "524ebd3d892718d9555adc88e62237fa93ec714653e2d0cb84a88a46a0f6865240e9123983b8cfa41eb0c2b9aa4ee27a5e602336a9b1d54a52c31b25dade057f3321110ff8ede0c19cf7bfadabef7a5a7ada92bf56eeaee9e93c888776776520bd31ceb14516c6dc4e25d17c46782521d623abce87d6b9d988c540ffd5668d",
+ "3829a995ae23fbc3a5639e028cd2b5f71bb90c7a1e4a8a05017d26e3afc3a885",
+ "41f6c3f45d71f8a3cc31a063ea4aad1b4d00db6f5228e9b9",
+ "b1561a7f61812b8b79e6af4292580d02ea4f6266d04244303304510272e383eaa51a8ea7099a74bafa3375b210653a0d2f40b15afd725cf5065066be1cb803dc158865ed8d7cca72dcf2b7c6b5d0d045bf32b063d3da484ba1843e071b61c49ce7f30ba18a4f7ef2730ecd785494839966f593168e17311913753c59593fc66c",
+ "0afe555385d4d096",
+ "5a5cf61ddefcff1426cfc248bd07216e213c6cbeb856764392a54beacd598af988fddaf75a609627199ff7844e6ed02d7dbd9b9291e0b80766fd26081051a32acfe495d7b5591a6877711f32f32504aa09d083f000dd3af4ade4c220232f2a27e34c0ec37fe6a23a0907c21c5bae0d8e665d958a33c97e3cd14ebe1628780afb",
+ "b664c1572251132fc28bf37fd8e96f2327cf7948a1126fd37175a91f483d6b3a",
+ "d92308df7e6daa8bf3efde75f80ad72a49ae0794009e21ad",
+ "33fa4141fe5fa79fed12f6a20f51614dc130f45598e92549b113ed6185724507e7fa5a7e8a75b2c7a3ad700919f36a46ea0ffa680857e30188f8a03c7c4b6c11bc39aececec26687233682d31887277028e2fd286f2654c681efd9e7ed6b340874e897337d4dcc672811a6cf4b69086e0a57c266424dc1d10ecbaf0c822cce9e",
+ "ffffffffffffffff",
+ "a083f3ceb75dc72484a0c11be30aaf42f1a0b009c9ada2da6e70fbd976e246783cd3124a46abfdc15c526ec66f2bd56dc585e419388e246ebe42dd93727f32cd463b6613563bc4aacbc55c4715ca9a8327310bdc06ed6f93e0e10d96a2f52a41af8d371f3f5bb5530ebf4ed47b9eab99d188b00db9b904c17c3a4cb67eed39c8",
+};
+static size_t nb_xchacha20_vectors=40;
+static const char *ietf_chacha20_vectors[]={
+ "e4c4054fe35a75d9c0f679ad8770d8227e68e4c1e68ce67ee88e6be251a20748",
+ "b3753cff3a6d990163e6b60d",
+ "",
+ "e4b5efc900000000",
+ "",
+ "299aa254a4606ab6a058e0c6fb5598218db71deb473f7d04c152e7e857736715",
+ "dc7b788aca39a3c96a878019",
+ "e8",
+ "1ff716fb00000000",
+ "6d",
+ "00172655236cddcd1879ca1f04b35f91adab70b81f504035fc169964a5ae985e",
+ "6c11b0b7bb18a51fd77fbffd",
+ "722aa220efdd8947ca5a5c7fb1c2ebdb9ad1f603801ff22e80314f716af9c22022fa159dbb4b4d3153f999b20ab4769eb1d01c057c5295ed042b4536561dce",
+ "3b6ce3b400000000",
+ "73d5bf251bb890245618a856cb3af96b306aa9febdca3718b4e1ae73a2131ebec185c7c130ffb0f071effed10dfe02e6662b78717580588ac79184e2809743",
+ "6862df6d2458d6c74739a0ad2169b9c89edd74e16fbcecc748c25dc338041fc3",
+ "4af0f1bda20eaf3fff7b372a",
+ "a801eb98a1298bc61028073750831c8cb43cd6822bf3f6fae0801cb6c843d8066b07346635365fb7d6ee54e5c9cd6f05d76b2bd4caec8d80b58235cb4268543a",
+ "47fc612f00000000",
+ "0924676a2306556857bc3a0ca6b9f2444acc66a89a0135538bd1fc61f09c7d11a973e75b6a76162f9a5a592b40094953594c659eab3ec361217879039d8f8ed0",
+ "d70bb4adedcbe520fed634f513b8c2ea6ab37fe633ba7302a5db6c2aa209e244",
+ "78fa1bd6f6ffabe98555e034",
+ "342cbec07364c54d1e407e282ef08edbfdbde936c9d42df58ae15889f5c939a3087eaeac1f2a58e2c2763d01b55744c4a65f4db93adff0078c63f090fb607a90c8",
+ "b5be810500000000",
+ "204f9f415e1fab31f4b743d4b21f0089828eea2709dd31ca4a5071bbfd9820a64e1cda8ab1bfcb1f850064ae630d5225e2cf7e74935b19e9710f6ebc484bde29c2",
+ "2e7c679a3187e22a635d301ce98ad000ca301049f2e891e403250c3358fc2030",
+ "b227bb96e93b88f419afe9f9",
+ "d660e013761228051ec5a8f0c093b33fc60e2cd7a9c845434e95d4319d79d1bdaa8f73853fbd9958e9ffc23a0ecbb7b48dbba63672d582bb83d92249800324cbc9a6e5b37d36887e7c79093f58ef8f1a001585321bfee1714260dd6130cc768d20b14d3850f0eec0f8f349110e751c16cdb5ed05516df17479937d942c90eb",
+ "f3eb9eb500000000",
+ "fc5cce90cf9e250d87703d4fee5b2089821b7d2c5c1620c0a157090831735e156a42a5c97c2d3a2a939f85eea8d013c859bd21827be0db1393e5f977f8f261c413934c84e7d2e9297958bf608a8b82825690bd25bb6d6938c3c60a0cf541191a03f9c8e78151fccd55ed0b73f30dda9561fae06eac7c4e286950e609633282",
+ "813062bd3f3f6b7668cd8fd3afce0cc7529b87dfc58eceb951e1e53d9e947933",
+ "29199c42d004bc0f0dab3adf",
+ "0cd702e99efa5ef6e59d3b201680f8e2d5a4ef7f23f1b6a8e102670a3829a995ae23fbc3a5639e028cd2b5f71bb90c7a1e4a8a05017d26e3afc3a88541f6c3f45d71f8a3cc31a063ea4aad1b4d00db6f5228e9b9b1561a7f61812b8b79e6af4292580d02ea4f6266d04244303304510272e383eaa51a8ea7099a74bafa3375b2",
+ "b105c7d100000000",
+ "83824a7cc37786be9e636041aa7bb26f3dfe8ac826f43be45d7af3295093eea6a9bad5a097ba87d1604efb35e400234ddebc6d5a9c54e2de8d070d399602d5dfce8c74d1a2902d48ee4b9e430f2a12ed03290f8176e39f4dda73c71bdc03bf0c91d5d59f45fb3cd841adea8371820cc1c097b3291777ff0b5f6e7b60dfad863f",
+};
+static size_t nb_ietf_chacha20_vectors=35;
+static const char *aead_ietf_vectors[]={
+ "e4e4c4054fe35a75d9c0f679ad8770d8227e68e4c1e68ce67ee88e6be251a207",
+ "48b3753cff3a6d990163e6b60da1e4e5d6a2df78c16c96a5",
+ "",
+ "",
+ "b5ed4c7e63a144f105dbe2b039c7e805",
+ "8019e8999c815c5723dbfbde05e6c71f118afc0dedb5b9f8dea398b2d764bca6",
+ "8dfc023a9821939d389e38a072cf1b413bb1517c3fe83abe",
+ "",
+ "86",
+ "374190382975907a68e8a341faa0772aa0",
+ "f999b20ab4769eb1d01c057c5295ed042b4536561dce32478b113adb5b605cac",
+ "75bcfcacb5e3e811b78e72e398fdd118bf04c6a7ed0756a3",
+ "",
+ "6862df6d2458d6c74739a0ad2169b9c89edd74e16fbcecc748c25dc338041fc34af0f1bda20eaf3fff7b372aa801eb98a1298bc61028073750831c8cb43cd6",
+ "9ef6887763d27d843103a44f9b2427e70769050e09c5a6453280159a6eef522bf4540e3d559aeaace7b339c98520921d380faf3c64b2593792b2a7d53d42ed738df4a729d618649a190338bc41e4a5",
+ "9d6d200005ee72c3bc3e4ae3badfd79adfe46b2ae1045f78382e04c969df1a2d",
+ "6a963a79c58401770a383248b5d70bb4adedcbe520fed634",
+ "",
+ "34342cbec07364c54d1e407e282ef08edbfdbde936c9d42df58ae15889f5c939a3087eaeac1f2a58e2c2763d01b55744c4a65f4db93adff0078c63f090fb607a",
+ "01c2a664d680021a34b1353258d2a8d16773c68db39d8c0de0dce962a5f0ddc13f78a1a6fa74cf500e78820c19252c4a2a1ecf987de69651a31bb390f3319ad658e136a56e0a0140cef60e9af8ad7392",
+ "1bf32e7c679a3187e22a635d301ce98ad000ca301049f2e891e403250c3358fc",
+ "2030b227bb96e93b88f419afe9f9d660e013761228051ec5",
+ "",
+ "c23a0ecbb7b48dbba63672d582bb83d92249800324cbc9a6e5b37d36887e7c79093f58ef8f1a001585321bfee1714260dd6130cc768d20b14d3850f0eec0f8f349",
+ "d00030016722e4e1c20592a0f643bbe63cfa22b937430eaca5058f19cc86f45269785e8a6fb2247b1beb510ac1b3b5d8ddf42eb175c95c9d0d9603189f8f41c850c875a2f9ab9451f418f1c102e64d5fe0",
+ "ab3adf0cd702e99efa5ef6e59d3b201680f8e2d5a4ef7f23f1b6a8e102670a38",
+ "29a995ae23fbc3a5639e028cd2b5f71bb90c7a1e4a8a0501",
+ "",
+ "561a7f61812b8b79e6af4292580d02ea4f6266d04244303304510272e383eaa51a8ea7099a74bafa3375b210653a0d2f40b15afd725cf5065066be1cb803dc158865ed8d7cca72dcf2b7c6b5d0d045bf32b063d3da484ba1843e071b61c49ce7f30ba18a4f7ef2730ecd785494839966f593168e17311913753c59593fc66c",
+ "4c56ae846df2a22857d81f76a6dd614c09ca92cbfbbe7423e4a6a1fe4dd6faa31bbce300be08b2ffe49f186214675e36a25d57c74611534dee35b301ee5e00657911b161a3060bea0871cc726db66d11e1dbbd5def385dc0c953914ca8eac6129563ac4bc47e39e65d8d276eb0b099576b542f2ff787c27789e565c4fbe46da193c11495f10a08f64fb026b482da54",
+ "64c1572251132fc28bf37fd8e96f2327cf7948a1126fd37175a91f483d6b3ad9",
+ "2308df7e6daa8bf3efde75f80ad72a49ae0794009e21ad33",
+ "",
+ "fa5a7e8a75b2c7a3ad700919f36a46ea0ffa680857e30188f8a03c7c4b6c11bc39aececec26687233682d31887277028e2fd286f2654c681efd9e7ed6b340874e897337d4dcc672811a6cf4b69086e0a57c266424dc1d10ecbaf0c822cce9e4f17b19e0ece39c180a4c756c03c19900280ff6cdebe5174d507c6e0860c38c353",
+ "e16c5303bff1085eae99ecfcca64e07ec76709b336598c9c4276a88e2ac3106630ec7b0f4fa2b455fd448945fe65798da3c8715df79b27f94dafd5a27ca47b6672149962cf8b8f019c4a93c71902dd3b2b8d9cc4bf2ff30d50f18480120bc638c6fa7397691aae3898bdf0a0f3dcbd749d03b8429cc1eb624c67d1acbce58a32a8adcb5bd809bbbb960f3fa8bf380e9f",
+ "7176c58965b74a56c52b3151bb8a149cf4f82158d57c823f3a90c6b427912226",
+ "ff604d9abee1fb8c8d35530a0cd5808e53e308ac580f7318",
+ "",
+ "6477fbb05c7c35956c3c0c5f342355fa",
+ "cb399b45596ac537bdb1cae9d439e26ba530343ebb3bebb73a238af37efe26fc",
+ "543894006b73f3d70fc04b15d0c2a5dfa650be5044fb5061811b866be7f9d623",
+ "fcb077ee19421610aeb263c57faef00662d424c07a7aa500",
+ "50",
+ "ab2911b42074414e387d7247fa505548",
+ "edeb2fdf5d7d9bf5d638973886aaf2b1ee4fc2a15ebc04c8a6339b1c3344ece0",
+ "62d3d607d6bf63c6760b802483b0e3aaa9dd4f79c6c5e93e6b51da45018c6bde",
+ "108f81f9abfa23640b83cfe3fed34bcf6640bf0baf647daf",
+ "e9bc99acee972b5a152efa3e69e50f",
+ "3786aca4c6b7e224163ea928771fde37",
+ "bbab31c2ba755007513a20995cc9d43998f7d9395a83284ddf4348ecb4830859",
+ "c2f8b252a18a29c44dbfbb62cbe6c3dfd4db55378734d8110b8f20f1d1ada6dd",
+ "d4da48fb09c06580eb46bbc5ca62bfab40b184271b73b710",
+ "d40cb63435042c9b526d1e5c3a77bfc5",
+ "11dd1e876f527d81ec81df06c7e426b7",
+ "c5023859611cf67a39bffa690d2f839429b23f99a17ec58e5d43b3e1eefc35c3",
+ "820032e031949f1e97e8ad5eb5a75cc805900850969de48e74267873d65e0d67",
+ "482d1c6f9a22450bff02814b8626a89534495c3bc3c8897a",
+ "096fbc2f9e50fda78ee3c8b0fb60231ae5",
+ "01ee35b10ac1efa06855ef67ece02508",
+ "0e9772515b51f4e6fa8195611dfafa65146bc05c66f1e8e0be1f1678a1e101d9",
+ "9849fcae816135f8ff7c83156a36aebdd8b11b679e1325659890870da65bd4c7",
+ "90ceb7351cdf29dbda3e68c2d64c04c7da7340fd622e6be1",
+ "4bd10d4003b8cf7e956bc847cfb0dea015d884f5761e9dfb9b2cfc2a8b4032",
+ "2aa92e5bd6515817db7d15af98806caa",
+ "17c4b7fa1f5bf1e69e882d760b303c74590a31d338c87d608786cc6443c8d32a",
+ "b118784e65a1f1d1964af9a24f53e3bcfe779241591e2c385be3b579780c5cc0",
+ "c490bc2ed9f06e129c52d57da020389a30134a40ddbf13e7",
+ "16a1f84335380b528cd7b6d29fbb5d7f97699f3c6d9284e1ef22fa05ad1f6ab7",
+ "99f2ed1a1d0611de572c0e8623d674bd",
+ "77b0a34ca0404238bdbe8e82a0b52a3cb62d441b580a49e81027fed18514c7d5",
+};
+static size_t nb_aead_ietf_vectors=70;
+static const char *poly1305_vectors[]={
+ "e4e4c4054fe35a75d9c0f679ad8770d8227e68e4c1e68ce67ee88e6be251a207",
+ "",
+ "227e68e4c1e68ce67ee88e6be251a207",
+ "81ac001b08d6577bd91ce991c4c45c46bc84d5465fc9139bf17042ae7313181f",
+ "7a",
+ "403bd4853fd1c55af2077780de9c1284",
+ "4a70a7e992b43e0b18578e892e954c40a51abdb5a85d300c32f391c45d6ef4db",
+ "043ddcf4214f24ea6ef6b181071f29",
+ "ff3de42a679eb874a5d4525abf3078fc",
+ "1deb473f7d04c152e7e857736715dc7b788aca39a3c96a878019e8999c815c57",
+ "23dbfbde05e6c71f118afc0dedb5b9f8",
+ "1d07a51dfe091076038f397099d15eb0",
+ "389e38a072cf1b413bb1517c3fe83abebb1cdf3a218abb1b0c01da64c24f59ee",
+ "d19cfb8cb3940aba546f0be57895e2cc86",
+ "320f841c889560a5dbee77df34ecd50e",
+ "e5d73f1c8c5376c1220ff3d9d53eeb65cc53599f40d6c8348c353b0017265523",
+ "6cddcd1879ca1f04b35f91adab70b81f504035fc169964a5ae985e6c11b0b7",
+ "32cefab76877cdd41a99c813d0a1ab15",
+ "18a51fd77fbffd722aa220efdd8947ca5a5c7fb1c2ebdb9ad1f603801ff22e80",
+ "314f716af9c22022fa159dbb4b4d3153f999b20ab4769eb1d01c057c5295ed04",
+ "6909e2774445104a4a0bc810da0ceb0d",
+};
+static size_t nb_poly1305_vectors=21;
+static const char *blake2b_vectors[]={
+ "",
+ "",
+ "cae66941d9efbd404e4d88758ea67670",
+ "e5",
+ "",
+ "2a294c4a9c276126c47e584eaf7e3396",
+ "f8146bd9495acc459d6d200005ee72c3bc3e4ae3badfd79adfe46b2ae1045f78382e04c969df1a2d6a963a79c58401770a383248b5d70bb4adedcbe520fed634f513b8c2ea6ab37fe633ba7302a5db6c2aa209e24478fa1bd6f6ffabe98555e034342cbec07364c54d1e407e282ef08edbfdbde936c9d42df58ae15889f5c9",
+ "",
+ "b28674d2dfede11f76e50f0e3081d74c",
+ "a63672d582bb83d92249800324cbc9a6e5b37d36887e7c79093f58ef8f1a001585321bfee1714260dd6130cc768d20b14d3850f0eec0f8f349110e751c16cdb5ed05516df17479937d942c90eb1fb1813062bd3f3f6b7668cd8fd3afce0cc7529b87dfc58eceb951e1e53d9e94793329199c42d004bc0f0dab3adf0cd702e99e",
+ "",
+ "663115a7fe0e0085cadf1818fa03421d",
+ "f593168e17311913753c59593fc66cb664c1572251132fc28bf37fd8e96f2327cf7948a1126fd37175a91f483d6b3ad92308df7e6daa8bf3efde75f80ad72a49ae0794009e21ad33fa4141fe5fa79fed12f6a20f51614dc130f45598e92549b113ed6185724507e7fa5a7e8a75b2c7a3ad700919f36a46ea0ffa680857e30188f8",
+ "",
+ "ff0a0433af77b0676a43e1e69b9294d7",
+ "6477fbb05c7c35956c3c0c5f342355fa0850307998642501c025e3873ebac3ccd749d8379ae6d830f785ec104897bd723d34ad20c9d36bfe371df46aebc6d4595d490a770bee4dd0be6a5a0b5e95645c7dcbc03c27010df3320fe75b0a3ecc8983ad94217e80348fd0f3f54e54b95bb548dc2225a264443732b41b861590358d543894006b73f3d70fc04b15d0c2a5dfa650be5044fb5061811b866be7f9d623fcb077ee19421610aeb263c57faef00662d424c07a7aa5005068b262251c0667a4e2e4b12f5df7f509564517887e370b425fabab1ce9e733ab2911b42074414e387d7247fa5055489bbd4b7d4de256de723566c1c2d3ecee8c10e7d98233db",
+ "",
+ "fa15fe1df94964869810a57fa2c9f82f",
+ "7c12457eb5614f87f1fdc40118906d02c602059d48ae05ae62d3d607d6bf63c6760b802483b0e3aaa9dd4f79c6c5e93e6b51da45018c6bde108f81f9abfa23640b83cfe3fed34bcf6640bf0baf647dafe9bc99acee972b5a152efa3e69e50f343bc12887fec8e70db73b4b48dce564d83786aca4c6b7e224163ea928771fde3778c453b35d98deced812fc5685843565b73d097601d3558278bd9d7327de5fdaa2b842050b370e837ef811a496169d5ff768878766c08c45561fdc2aad6469c11380c3d3f873c7233c541ea4c43824ecd8bf7e11ac8486208fb685218d46736e51103d1fae0e8e368f25480ee7328381c2f8b252a18a29c44dbfbb62cbe6c3df",
+ "",
+ "50089bdcf51629a715eb1b3345a0c2fc",
+ "b3451318590c84e311dd1e876f527d81",
+ "",
+ "13e40814a705dac02c3a1de24eb9e6cf",
+ "8a52102e2903352b5ec66cbed7474a91",
+ "96",
+ "ef0733ef5b4381bad3b00a6269bbc282",
+ "97699f3c6d9284e1ef22fa05ad1f6ab7",
+ "0d200c182251f5a9cafbc17c4bdacb3411651e4088dec905251ae93c899860061d340da02e519a254e109592caae83d46aad5dd4338e034f0660693ea9e691",
+ "6318f617c6c8788bcedb7177635a449e",
+ "5cd890b165ef0445d3b75055261be279",
+ "5c9fc34bf3b7633130b5341dc0560406d0f4ab5110a8ab1417e4127d459157b58b20256edf901d5a8bc0f71f6898a6b1d0818edb2f561d3219752a709abaa318",
+ "264f2e37d05f658f60d69b312abb90e8",
+ "b5f0c69568656661fbcd3bca40b22c65",
+ "",
+ "",
+ "aeb71797e433c16ed303017030b2d85b",
+ "",
+ "01",
+ "7c72d9947280f5c974ff04857caecab0",
+ "",
+ "2bfb488870d7a53f5bb5f3bc72b1433ae7908408d237fb4601141e3f07e0e445a8725bd48c0d4f1ba8a7c4923258d6ef90d598af6020a1a3e5eddb5c51cfbd",
+ "48fbca32ec758a3b09ebd2a19e6d91ae",
+ "",
+ "6111d2b0526416d0aac7112a7003391899c7eae8615d2778f3d053d6eab255bbcc2186267a67b540e5825f6d5d950c2f36d5588b45b6a113908ad73f6da77ff8",
+};
+static size_t nb_blake2b_vectors=45;
+static const char *sha512_vectors[]={
+ "",
+ "cf83e1357eefb8bdf1542850d66d8007d620e4050b5715dc83f4a921d36ce9ce47d0d13c5d85f2b0ff8318d2877eec2f63b931bd47417a81a538327af927da3e",
+ "38",
+ "bc23b8b01772d2dd67efb8fe1a5e6bd0f44b97c36101be6cc09f253b53e68d67a22e4643068dfd1341980134ea57570acf65e306e4d96cef4d560384894c88a4",
+ "ca43cdd4eb7173476862df6d2458d6c74739a0ad2169b9c89edd74e16fbcecc748c25dc338041fc34af0f1bda20eaf3fff7b372aa801eb98a1298bc61028073750831c8cb43cd6822bf3f6fae0801cb6c843d8066b07346635365fb7d6ee54e5c9cd6f05d76b2bd4caec8d80b58235cb4268543ab0eb865a948cc5b5f6e31f",
+ "0c7ea31f5fa48e7c869feea1ae0069f7327d1189019576688f76a222558ed18fc18e420655adac27f7e1659a8b196b30a6c705a99878219f90da7f2ecc6a8c0f",
+ "a3087eaeac1f2a58e2c2763d01b55744c4a65f4db93adff0078c63f090fb607a90c87defd622e5f55977877cec9ed88312b0411228540cd6dde6e84cd2da59b1871db119e3298e3c12fe8200a47eddf049c971cd99f694e3b2a5e25fa37aedf01bf32e7c679a3187e22a635d301ce98ad000ca301049f2e891e403250c3358fc",
+ "39b3208cddc3275ec7857fb8fc9e48540977ea6c0665248f7164f87b5a640ef300d7bb21d82db9b5b585b5ce82dcbcb7ae4d6883a6bd6e3175b9a6249c8a6d88",
+ "ed05516df17479937d942c90eb1fb1813062bd3f3f6b7668cd8fd3afce0cc7529b87dfc58eceb951e1e53d9e94793329199c42d004bc0f0dab3adf0cd702e99efa5ef6e59d3b201680f8e2d5a4ef7f23f1b6a8e102670a3829a995ae23fbc3a5639e028cd2b5f71bb90c7a1e4a8a05017d26e3afc3a88541f6c3f45d71f8a3cc31",
+ "8df0329b3dcb8510808919ddf8064b96bb641cad8160a22e7abfdad9433a86c62edbd2b6a46ee18c5e0391c06c51d96e3240028c7c4aa2c25dc77c1b72a2e0ed",
+ "f593168e17311913753c59593fc66cb664c1572251132fc28bf37fd8e96f2327cf7948a1126fd37175a91f483d6b3ad92308df7e6daa8bf3efde75f80ad72a49ae0794009e21ad33fa4141fe5fa79fed12f6a20f51614dc130f45598e92549b113ed6185724507e7fa5a7e8a75b2c7a3ad700919f36a46ea0ffa680857e30188f8a03c7c4b6c11bc39aececec26687233682d31887277028e2fd286f2654c681efd9e7ed6b340874e897337d4dcc672811a6cf4b69086e0a57c266424dc1d10ecbaf0c822cce9e4f17b19e0ece39c180a4c756c03c19900280ff6cdebe5174d507c6e0860c38c3537176c58965b74a56c52b3151bb8a149cf4f82158d57c82",
+ "1afec592c116573a7acea54c46ad42c5e589a546d0afbe7dcabaacaedf163c3f9432b525be87813744b88c9b7b7f640735ff6de8f5e968e2c8de289785fa1641",
+ "3a90c6b427912226ff604d9abee1fb8c8d35530a0cd5808e53e308ac580f7318fe2ab2a4933b5d90db718aa3440fbe9ba17f09716219bdffc93a189e410a6a3e6477fbb05c7c35956c3c0c5f342355fa0850307998642501c025e3873ebac3ccd749d8379ae6d830f785ec104897bd723d34ad20c9d36bfe371df46aebc6d4595d490a770bee4dd0be6a5a0b5e95645c7dcbc03c27010df3320fe75b0a3ecc8983ad94217e80348fd0f3f54e54b95bb548dc2225a264443732b41b861590358d543894006b73f3d70fc04b15d0c2a5dfa650be5044fb5061811b866be7f9d623fcb077ee19421610aeb263c57faef00662d424c07a7aa5005068b262251c0667",
+ "4bf909661a603c30199c63eefe96ac7b5489b2790c47db8f97b99cbc0fb4701831f7682d34302415974ff3f8e43f2592c6ce2c6e8a5518c3468a4cad6699ec35",
+};
+static size_t nb_sha512_vectors=14;
+static const char *sha512_hmac_vectors[]={
+ "",
+ "389e38a072cf1b413bb1517c3fe83abe",
+ "9689b839211c1751e1faee45edd4662c6102049ba76c3eef46a28cc268818cc54b8955b68dfd17d6f0993844bf9952f6158aa2c3fe780e6a89d975597a504ada",
+ "ca",
+ "a3087eaeac1f2a58e2c2763d01b55744",
+ "3c0119c12ed65c15b5343bcbf0d04a1b22c9957f3aedfb07d1d3dea5158c4f133efddbbff90e17733d5853818c9af7fafec2dd280f0e27855dac473cf30abe0c",
+ "ed05516df17479937d942c90eb1fb1813062bd3f3f6b7668cd8fd3afce0cc7529b87dfc58eceb951e1e53d9e94793329199c42d004bc0f0dab3adf0cd702e9",
+ "f593168e17311913753c59593fc66cb6",
+ "a62e149fef7b91b9c7f327847d81179a4bec216d30bc005d7a4708f84e2cd35ddc3ea8eb51e1bff209d07deaf5e88ae0900c7203db57dd372ada435a5518e2b6",
+ "3a90c6b427912226ff604d9abee1fb8c8d35530a0cd5808e53e308ac580f7318fe2ab2a4933b5d90db718aa3440fbe9ba17f09716219bdffc93a189e410a6a3e",
+ "a4e2e4b12f5df7f509564517887e370b",
+ "276785363a14f38d660d635dfa42ff079af139e9901f91f29240275fbf290a7320e1df5778a9239bade44c90bfe5e3d50d99fdc0570359a472bc931a123a7e19",
+ "78c453b35d98deced812fc5685843565b73d097601d3558278bd9d7327de5fdaa2b842050b370e837ef811a496169d5ff768878766c08c45561fdc2aad6469c113",
+ "60fa0114802ee333d7c49ccaad8108db",
+ "d31bba716cf3bb1d322ce9e4e6cda884845a16db546a90dd5bef2fe7bb836bad8e995f743a978dab6b11ee31b6c8bff2f2d747408bc54c7a75c049e243565470",
+ "8a52102e2903352b5ec66cbed7474a91d7ca3f49fdc859b3e1705e1e05b124789849fcae816135f8ff7c83156a36aebdd8b11b679e1325659890870da65bd4c790ceb7351cdf29dbda3e68c2d64c04c7da7340fd622e6be14bd10d4003b8cf7e956bc847cfb0dea015d884f5761e9dfb9b2cfc2a8b40325a2aa92e5bd65158",
+ "964af9a24f53e3bcfe779241591e2c38",
+ "3cb55d24a444711f3312818fb019b9c29842271896abd68413aaa6d13771c9a9997e332e36bc6cd8882dda982ee8ba1e102a6f01a996bef3bf8ce3393cb02b4d",
+ "f9b8e57564807df84a1d2143003c7c31c1ecfb0fa02c0a88f9b13f45f06f30ca463cba3d090f62651ef12368bee0db5fba7b79b95fb51289e4ba9be86c19cb700d200c182251f5a9cafbc17c4bdacb3411651e4088dec905251ae93c899860061d340da02e519a254e109592caae83d46aad5dd4338e034f0660693ea9e6914e",
+ "23ca891e5af07c3e5c47a168e79af48f",
+ "36e2a5fd3e8b2560e24ba08002469a98c50f56080e4cb18665dc1c7dadd9ec73664298a0d852504f5b3c1633247a41e47744915780d899e3e2afe14b86ab29ed",
+ "96fce921032289e9e686d8f207c5b4e7273feadd17d02148810c33e07dc7d92b6b034b4c953b7e0900da7170bbca5c72ebbb007959720860a69357ca495148faa1e5924ab091d3fb4996c3efc3c48b123a08998c55223a940e3fa0bbe1b1f4bf2ec798c3209c6cde322b5b08a73544e078286a8e5b7177019b72dcbe98d2a1280b",
+ "aeb71797e433c16ed303017030b2d85b",
+ "5c87ad41b5e45e91fce3a756fdb2382916fc2c7d6c00277db52bc4c3d8d1a93ebfd18497af4186e7f2d3c40de52094100681fe58a5fded5510b5dff983e75db6",
+ "",
+ "",
+ "b936cee86c9f87aa5d3c6f2e84cb5a4239a5fe50480a6ec66b70ab5b1f4ac6730c6c515421b327ec1d69402e53dfb49ad7381eb067b338fd7b0cb22247225d47",
+ "",
+ "dc",
+ "cfd55a01855eddd5746c64f58ce5fc5e002cd28632c3224288dbe816ce8fb370b2b355ca7ea0eda2a4f75395db7b94b2b06688811f0d7733122189589f82b437",
+ "",
+ "481e1604d2e5dfcf0d9943ae21d6efab804755197bff9f24eee982b0f9089288cf7b4570ac320b344f4f70f31f530c2312db5b7241651d361a91f7986db3922aabcd660b88d14c1c1601492321379521c1e4274d661113338c8a5b98d6c12d985f1b73d5b3d7592b2d0ea7be0181ae20d09d6051782c35c8537a597818b5a8",
+ "8fe0c5422e148c351107dda1e696bccbfdacd9c4b21a63b0ecb36d45864eaa72963c0be609fa9ca9500171ac785c19e5929c141cd1f6cee605f05bab8809ef66",
+ "",
+ "a46ff45937e5f0c485c88631147283987321c85d4a447015bdb4c7921a6e927b6c8b7f7e40a17eb87f1874b7c50225d8544a01cc2cf0ed8c30c3dcf2ca6ff3ef75798ff9253562ecba3e7e42a43c6fd74a3c4330ea178daafa0532305e8356f1aa5f91ca91dcda75d7167e1585e0211eb3b78e6be0cf50209ab6747b4a24c053",
+ "03017550f2050653118444fc09e828f9d8d7fc6f245bd96ac82d20d4c40b31bb7d3237df3f22d129de5cebd8b91b1a69bb7050373532293bf35f66a06da43a95",
+ "",
+ "d4aa41c8434e57b47edf32f6cf6ed1bed6c383e898df44d84558837a0178af8b11417eda347fc40c678121bf0067eb4677a84f442fac0f3ada2412a69794c521b769a9e4a3b0c80bba876e96ac0eeb9194cb23669cfe964d087f33f4366d4bdd721907f828f383c11bb6d956d64db4a8eaad21ac20d2c31fc52f08d756be446b99",
+ "dd87e1b28bffc10ec0a4bd8e2808f003fdeefa822f25ccabb6a7d4c0381499ce4413de701771ab3172e4777ebdf1999d27dc1941a5c3cc0ac156b7cb67552a27",
+ "",
+ "f606ac7b059ba616ec1e952227f31cf0a83dcb66613c012cdea2a3776961f0efd398712051b7e7b8500ecbd030d2c6a0012b8eaeeabbcc0d6f1e03f4acf709b3bde30f4e8aa3ebb0e8f75158be727463e25d2b3f02db5cf3342581ce7279c118bb8b0d496b610c2d51967d12821cf86d796b7cd7ad2cbd5c0f165b232f281464e48f0b0d2577542ad3465bf6c063435390470388a27d938b113c74cf1d962c864f2971a0b18808649f978cc94de8b8f70fa5cf3ec0bad1a92499b68660c1fd2f809bb26aee29f93ab4484694506fae71d307ac45239a431f3f51285aba0dbd3afdae0231c4a1fc14b21ba2f1c27548d4c259544e80b94696da838ad6186b2e",
+ "800ab7f4817cf9a1a7d7d711ea097709ed18be383e7caaf6da72bc9e486dacb2894a3e20e0759cec7ec0550da76cf613d02e10ec2c4c697648998586d107ce64",
+ "",
+ "6ab33d45513b7013624e01e15f616a3436caa8813c863a13eb85e06a973f95204b265c9f76496407bdd1bd16b7f6ea3e97f3346e63d5e05f9896b1821e3dbe382a8849e3e27e05c8572140297d86473e720d62e6c7ef1766e4aff8313c688b6b91667b20ccfc055f0d7917eff1c713f3712d948055a3139e6d758a308322503f4f28977329a2153bd6a8c1d47e8877a4abfcef83cdff4daa74845384d8bdcac050bddc4bfa7cdc185d3b2528559936510bfe814ae162eaddf609992f6796654a59a66323292142ca499c44cb95bc308c10d44aa534066efb413fbd7e622fb2a2366b20439156728d7753c598106508878bbf4467d9c7812ea686683580365a50",
+ "ffb3011fcde35b8ff8c09a62fe02e7f17aefd1f458f3c01caa2d57b77699dd335f9670d359fc99c72b30ad3e92c9d39000b127967284cca14b759275531eaba2",
+};
+static size_t nb_sha512_hmac_vectors=45;
+static const char *sha512_hkdf_vectors[]={
+ "15b607ad7a0be00fab2b557e9a55ba304fe6d04e0e828ca83dbc4373ca84e59b220bb1a2e47c9a74bddcaad2db6239b4f538e12459bd9440d09644148e90c6d53b0d8c02eb9eeec77d33995008208f96a923d2702f69255be6d55e92f1c73353816b30ba59723c9e39f0941ef19ad6023eecd70d3295c0d05331b315caad52",
+ "01b56e40efba58a21e398e351e0c2600ef4a57e144bab0cdeb02c131c89ac632c222aa93994ae8042a68237a82abd2337be60e5fd85532ff68fdbada5f7215d974591123c90abd908d901c969445883ba195678158cca17c2bff4a33526da645bf61352d0567c1e5cf641f036f2d5ce7df45c894a8eca8882ff7905480f6c8",
+ "16a2ca0477d8d5c7531469ada982369eb3b2e27e537050af1fa7b82a16064396bb8cd0589d1be5850f22a168ef3753a3c43908047f67baaa851d4de0ed5f58b3c596d01387b44cd553f4211f285fdc27ae33661b32b10b7a1c729b26b2c23b8cda89d7a07543b6ce8a8600ed78205769f31952c9404e43570f06f5b0f8a85d",
+ "c3adb005347e78273a62a79d1be677fd6fef9875e18556daabc8b84cffa0a481f28d0f2d06e86cf2d36b8b2be83e75ea04ae33b621155fdce91734cf6a1ebfafead9a9f3503f11586809670edf031005c7399b8443675df1502ee1fa7f6729569113f15aceccf8e4cc456dae78740589d90dc5d7b8d839fe191fd267729e44",
+ "76f2008619c417a3b43f8225774a2f736d01931e17a36f436cc47af3e95bd0f5af832d45694a8be6a01e87217b87a8bb24c45f37b4a06e0ceb1b0af6b4e09346939e244b61b2fe471297db7eb27adb8e63086b8fc391c4dfc97e94c1d153866b268e497bf752a3980e9376c68acb2a0b7a13dbd9ad4f3702055b915af095ab4a",
+ "baff250589242160421dc33cef55a11962a28287beafacfd7c5ee112117beec1d1f24dd0ec42a495034cec9f74ac62e2b3524b5a9953666196065b85353486f680cc449fee5872f2ddff16341eb3f2d4afe083db244589f8160a678627f8ae17c3622aa7d6ff6b330245f93b5c51cc0b4a25faefe4e5b93478ca14105ef6b470",
+ "a2564fb6ccdc4cac30bca1b44d7be37c6c8ef7aa2de91b327c253a0a2a6c9b692a163d1442de8ddaee8eacba3d437e77c30089c14173c68c5622ac06ac00566d2702f38d6d72a0296bd4899172ac01c4e2b95da3d7299d48b555af8ad6644d9ec6399b18b85d4c79983e3ad238e7c9cfd923d0f37e810446a271bfe45b0648e7",
+ "c57429d66d9c29f977bf3cef2ffb1b3dde08e2ed19ac22ecce9cca0c3e0391d956d41759dd421d7fb4db8fbc6b7d9099547d92b26d214b20aeed8ff8622d66fed4b13a76e50eb452b782894b568fa9b16fc7bf4c86187c214d258846fb5ff4fb39d088b9b662d05a8bb37640a89d4ffb95a613aaa4efe589e315dbd3a71b3a96",
+ "5eedb3f58206d94977f1d3bbc8ca33c75d3fb51a0852a54861278fa7dce088be88c2c6530c6e6b69f61d1d3d8f9656dfb1039bdf76f9e5c7004c204dc6edcb921233bc331aff02d0f76cf2b0e2d6c971d000526dba8d9edacdf67314e42b263582f5236b38652c9aa0fb37629f1391798581bfa4c608b61ad2dd1aa1bfe0c1e5cc",
+ "55879d5e0164b75fc4cf92a55dccb2c2a5ecf783b73f5262e60a46b38c8c5f1c7374258b1f9bfdd0d62b37c1b074c16d83ba66ab8e51c9baa95f5e632978e1d512bf4582d2daa48d95ef9fe1e3fd0e250ed375c111f4efbbc4f16acad358c29d30a694305719f4a59ca964fb379caa654d1eba55f7fc68f9bb38e8d12b3a0e8207",
+ "55dd06136ae6732c4600b9a04cdb9362de8a19d9bbe2bee477eeba530c2552e1582714a10c96dc25496325ce16f60a5291e098cdb89fc9af488f92610aca213bf4716014fac914fdb976b4e3fc8f54cbf889584917faf47880a853879fa49d4f0ade8c81a27c8f28158479851bc9d52ca0a9068f339275875b6cb053b0e314fd9d",
+ "be696a270482f9f8f6bc3b9bbe4f91b1b6a857efb5b926e7a07cdb2cd7af9a4a65085f21afd7f781320cb79c65766922ffa2e08a5f9238d186e932ad50cfec5aa826acb2595580fcdc1e43d59d2df3d1ee00c2cf0729dabe12a2f330989169a515d1b9e8fcfdb33299a9b46710234c46defcc29f1ad58c66c8cc44663fc63f3108",
+};
+static size_t nb_sha512_hkdf_vectors=12;
+static const char *argon2_vectors[]={
+ "0100000000000000",
+ "0800000000000000",
+ "0300000000000000",
+ "0100000000000000",
+ "e4e4c4054fe35a75d9c0f679ad8770d8",
+ "227e68e4c1e68ce67ee88e6be251a207",
+ "",
+ "",
+ "2a2ec585be2ec27c215f677e947c212b1b85de797167d4950e29987977c941117c4c5f6f6f547e62d76b88fa121781986a37ea14dc394917af5396ea58915d",
+ "0100000000000000",
+ "1000000000000000",
+ "0300000000000000",
+ "0200000000000000",
+ "0101010101010101010101010101010101010101010101010101010101010101",
+ "02020202020202020202020202020202",
+ "0303030303030303",
+ "040404040404040404040404",
+ "a5a960b03adf92c4bc18628f1e23192d3544b91ab57024abc7dc3aed52b807d4",
+};
+static size_t nb_argon2_vectors=18;
+static const char *edDSA_vectors[]={
+ "50831c8cb43cd6822bf3f6fae0801cb6c843d8066b07346635365fb7d6ee54e5",
+ "b600ab324d70d2372f3ba5a0d8bdd8b8e797f780b642bd56e69a18db74c389bc",
+ "c9cd6f05d76b2bd4caec8d80b58235cb42",
+ "0bfa8d629fe89bd9591f20575144f0445958fd3574179ec4a9b6ee85787c23d69b4f009d3ed3bd2bb62226638602b95bc4719a1d2c60afb07ed95c959628ff0c",
+};
+static size_t nb_edDSA_vectors=4;
+static const char *edDSA_pk_vectors[]={
+ "e4e4c4054fe35a75d9c0f679ad8770d8227e68e4c1e68ce67ee88e6be251a207",
+ "61435d557c6bedda3b9d652b98982c227ffedb203fc2357cabe8075508f4e6f0",
+};
+static size_t nb_edDSA_pk_vectors=2;
+static const char *ed_25519_vectors[]={
+ "50831c8cb43cd6822bf3f6fae0801cb6c843d8066b07346635365fb7d6ee54e5",
+ "38bfc0b57ba86490aa2f41a3209e360ea4df055f22c07c7f54326d36780f42f6",
+ "c9cd6f05d76b2bd4caec8d80b58235cb42",
+ "428bda84b67e78d45c5531e194d1caee74b6242417c0237d34132546f7c0e70d8af611ef57248e0437241f5c3592063b5d13b94b78fadc39cf9a703a6920660a",
+};
+static size_t nb_ed_25519_vectors=4;
+static const char *ed_25519_check_vectors[]={
+ "7d4d0e7f6153a69b6242b522abbee685fda4420f8834b108c3bdae369ef549fa",
+ "202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60",
+ "7bdc3f9919a05f1d5db4a3ada896094f6871c1f37afc75db82ec3147d84d6f237b7e5ecc26b59cfea0c7eaf1052dc427b0f724615be9c3d3e01356c65b9b5109",
+ "00",
+ "7d4d0e7f6153a69b6242b522abbee685fda4420f8834b108c3bdae369ef549fa",
+ "ffffffffffffffffffffffffffffffff",
+ "5dbd7360e55aa38e855d6ad48c34bd35b7871628508906861a7c4776765ed7d1e13d910faabd689ec8618b78295c8ab8f0e19c8b4b43eb8685778499e943ae04",
+ "00",
+ "7d4d0e7f6153a69b6242b522abbee685fda4420f8834b108c3bdae369ef549fa",
+ "3f",
+ "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "ff",
+};
+static size_t nb_ed_25519_check_vectors=12;
+static const char *x25519_vectors[]={
+ "e4e4c4054fe35a75d9c0f679ad8770d8227e68e4c1e68ce67ee88e6be251a207",
+ "6531e5010ab797ec0dc3c7038a94cbfcbb8ff1d1aad061b802b3c3232a42b352",
+ "600e94ef1d60878dd40c330704b7648bdd32901bbfdbdef0e59e600229384642",
+};
+static size_t nb_x25519_vectors=3;
+static const char *elligator_inv_vectors[]={
+ "2920d46f2f37b04d00ff73df4115fda3876810c2144e94a7e6d0c09290ff7359",
+ "d5",
+ "ff",
+ "00",
+ "70e7a067416c79ca10ea92e00b0e15cd50569e3298b6358ad6b016826b1a5b2b",
+ "dd",
+ "ff",
+ "00",
+ "89bbc72dc9f7f5b863489c606514a39f4e844061ba5c9dec8095fa8c8e657170",
+ "2e",
+ "ff",
+ "00",
+ "df1d73ff8919c4795a72077558dde8a99163591bfe015147548708e067f47e28",
+ "48",
+ "00",
+ "7c0e535eb69f95f02c4639e1d9668ce0c78b17d94e09a08756ec8ff266595076",
+ "c74d0b2a03a3e2d5138e4eb0378c1b13dc2dfe145b62fbd4bb476014bfcd4034",
+ "57",
+ "00",
+ "b48cfc36901caa3fd2d3997075c716b33165d7e60ed1770007289245d6a70946",
+ "3bd31879f188a6111d3633c8b1053138eaf8f11423c779f23288821b58181856",
+ "b6",
+ "00",
+ "19288fbd99b6a33e3374aed8faea2fb3356c2965c11ed9d09043b27f3d8f8796",
+ "a23740a8663e73d9b9e8c11fd0991efad5735f9533550b61a058b60acb3ada1f",
+ "13",
+ "00",
+ "34e6d2b0a37d4719a71b918a7095e42f7b2d0a51473704d2a942a10baee08705",
+ "3338ab54956d68a9186bdf5b97f03762bdde1551fde608885b035fc854177259",
+ "4e",
+ "00",
+ "43e97d6b5ddcf115d66341d293e627918299a171e04637f32b9b09505a971c64",
+ "06a64676b6b162cf03ae11efec6a07a8205638523ca2631519d18ba3a8858568",
+ "6b",
+ "00",
+ "d72d68c2e7f8fff0a946f8120b3004831e1e194369ae20d67cd1e1da3a534b54",
+ "77b951a3bf0ad919a950bcd1fdcffd2a659a1ce7d95557a71b9fc4cbd1ab3a65",
+ "a4",
+ "00",
+ "282ae366b62e6d3043735d989dfb7455bab90ba17018827c4df05b14c964d6af",
+ "f7d574f5cd7847043acc1f8cd2a4c1325e6a97281c099dac93ddc54fc0c63e0b",
+ "23",
+ "00",
+ "62323f31d49906ef7422aa0a3015491dd463ddbe0b440efeb9574277eab63d39",
+ "67e965bac8b9406bb5048c6e30b895e142424a54fcc0c2a21e45fa5a6ff96d45",
+ "12",
+ "00",
+ "92259700a11805a3a74e5fca9979ffb83853bba64d13398c0c8d0e577c3c4117",
+ "8199de6f012e0ca8ea05f1767592466cbdcd9c1402a727da4288a8d7075f6e21",
+ "05",
+ "00",
+ "318a4c9b941b54bb679e0ecbcfdf19abe2929143ed39abdad6e672d45edbcf34",
+ "5ba0832ca17067095ca32b74a0d134bd09b21b5dce536a4a1f3c41298c97893d",
+ "0c",
+ "00",
+ "1950ba33c7d6f56945fcf47ebaf88e003c34c2f70f080dbf410f8985440f2a0b",
+ "32d57bcd24f11916e7b96b7814598b15ea609258b40dde23eb0b64734878cf5f",
+ "49",
+ "00",
+ "c2d517d0bf0e573034ee0d297923b4965f6b75c6bc7888e0c8078e3a9fe92e74",
+ "aeb757f254b6dfe33e1df62e2d85c6fac47d5f3535f969de6882fac2bf0a4f19",
+ "9e",
+ "00",
+ "58daf8d2ab3bff7fd1d99e462b5b7bc34d63dafecf43c3bdf925d1f919216392",
+ "732f35e5f3fbac1edad39eef1c4633251d4b8a070712a91b1d4ab860ce68c16a",
+ "83",
+ "00",
+ "3f436796492ea02bb04fa7bee3d3c51b254c1003d943c984eb59a580a7e1ea84",
+ "9fa8d210f4e00b37444d24567e72d019e32f271954a080371a88875d4911555d",
+ "4a",
+ "00",
+ "515b649d380b9e4e3583025f360bf27331ce267f85f3509c10a0dc429ff39b60",
+ "af935c1ac0e61cdcaf16f8b2df6f6eed49805d5025ef6f2ddfe2bb358ab35e35",
+ "51",
+ "00",
+ "0892930b2fa529e56758523552d6cc33fe488f0a2d106124c1ded9c35d6c965b",
+};
+static size_t nb_elligator_inv_vectors=76;
+static const char *elligator_dir_vectors[]={
+ "0000000000000000000000000000000000000000000000000000000000000000",
+ "0000000000000000000000000000000000000000000000000000000000000000",
+ "0000000000000000000000000000000000000000000000000000000000000040",
+ "0000000000000000000000000000000000000000000000000000000000000000",
+ "0000000000000000000000000000000000000000000000000000000000000080",
+ "0000000000000000000000000000000000000000000000000000000000000000",
+ "00000000000000000000000000000000000000000000000000000000000000c0",
+ "0000000000000000000000000000000000000000000000000000000000000000",
+ "673a505e107189ee54ca93310ac42e4545e9e59050aaac6f8b5f64295c8ec02f",
+ "242ae39ef158ed60f20b89396d7d7eef5374aba15dc312a6aea6d1e57cacf85e",
+ "922688fa428d42bc1fa8806998fbc5959ae801817e85a42a45e8ec25a0d7545a",
+ "696f341266c64bcfa7afa834f8c34b2730be11c932e08474d1a22f26ed82410b",
+ "0d3b0eb88b74ed13d5f6a130e03c4ad607817057dc227152827c0506a538bbba",
+ "0b00df174d9fb0b6ee584d2cf05613130bad18875268c38b377e86dfefef177f",
+ "01a3ea5658f4e00622eeacf724e0bd82068992fae66ed2b04a8599be16662ef5",
+ "7ae4c58bc647b5646c9f5ae4c2554ccbf7c6e428e7b242a574a5a9c293c21f7e",
+ "69599ab5a829c3e9515128d368da7354a8b69fcee4e34d0a668b783b6cae550f",
+ "09024abaaef243e3b69366397e8dfc1fdc14a0ecc7cf497cbe4f328839acce69",
+ "9172922f96d2fa41ea0daf961857056f1656ab8406db80eaeae76af58f8c9f50",
+ "beab745a2a4b4e7f1a7335c3ffcdbd85139f3a72b667a01ee3e3ae0e530b3372",
+ "6850a20ac5b6d2fa7af7042ad5be234d3311b9fb303753dd2b610bd566983281",
+ "1287388eb2beeff706edb9cf4fcfdd35757f22541b61528570b86e8915be1530",
+ "84417826c0e80af7cb25a73af1ba87594ff7048a26248b5757e52f2824e068f1",
+ "51acd2e8910e7d28b4993db7e97e2b995005f26736f60dcdde94bdf8cb542251",
+ "b0fbe152849f49034d2fa00ccc7b960fad7b30b6c4f9f2713eb01c147146ad31",
+ "98508bb3590886af3be523b61c3d0ce6490bb8b27029878caec57e4c750f993d",
+ "a0ca9ff75afae65598630b3b93560834c7f4dd29a557aa29c7becd49aeef3753",
+ "3c5fad0516bb8ec53da1c16e910c23f792b971c7e2a0ee57d57c32e3655a646b",
+};
+static size_t nb_elligator_dir_vectors=28;
diff --git a/lib/Utils.Cryptography/monocypher/vendor/tests/tis-ci.c b/lib/Utils.Cryptography/monocypher/vendor/tests/tis-ci.c
new file mode 100644
index 0000000..2e6438e
--- /dev/null
+++ b/lib/Utils.Cryptography/monocypher/vendor/tests/tis-ci.c
@@ -0,0 +1,474 @@
+// This file is dual-licensed. Choose whichever licence you want from
+// the two licences listed below.
+//
+// The first licence is a regular 2-clause BSD licence. The second licence
+// is the CC-0 from Creative Commons. It is intended to release Monocypher
+// to the public domain. The BSD licence serves as a fallback option.
+//
+// SPDX-License-Identifier: BSD-2-Clause OR CC0-1.0
+//
+// ------------------------------------------------------------------------
+//
+// Copyright (c) 2020, Mike Pechkin and Loup Vaillant
+// 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 COPYRIGHT HOLDERS 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 COPYRIGHT
+// HOLDER 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.
+//
+// ------------------------------------------------------------------------
+//
+// Written in 2017-2020 by Mike Pechkin and Loup Vaillant
+//
+// To the extent possible under law, the author(s) have dedicated all copyright
+// and related 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
+// <https://creativecommons.org/publicdomain/zero/1.0/>
+
+#include "monocypher.h"
+#include "monocypher-ed25519.h"
+#include "utils.h"
+#include "tis-ci-vectors.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+static void chacha20(vector_reader *reader)
+{
+ vector key = next_input(reader);
+ vector nonce = next_input(reader);
+ vector plain = next_input(reader);
+ u64 ctr = load64_le(next_input(reader).buf);
+ vector out = next_output(reader);
+ u64 nb_blocks = plain.size / 64 + (plain.size % 64 != 0);
+ u64 new_ctr = crypto_chacha20_djb(out.buf, plain.buf, plain.size,
+ key.buf, nonce.buf, ctr);
+ if (new_ctr - ctr != nb_blocks) {
+ printf("FAILURE: Chacha20 returned counter not correct: ");
+ }
+}
+
+static void ietf_chacha20(vector_reader *reader)
+{
+ vector key = next_input(reader);
+ vector nonce = next_input(reader);
+ vector plain = next_input(reader);
+ u64 ctr = load64_le(next_input(reader).buf);
+ vector out = next_output(reader);
+ u32 nb_blocks = (u32)(plain.size / 64 + (plain.size % 64 != 0));
+ u32 new_ctr = crypto_chacha20_ietf(out.buf, plain.buf, plain.size,
+ key.buf, nonce.buf, (u32)ctr);
+ if (new_ctr - ctr != nb_blocks) {
+ printf("FAILURE: IETF Chacha20 returned counter not correct: ");
+ }
+}
+
+static void hchacha20(vector_reader *reader)
+{
+ vector key = next_input(reader);
+ vector nonce = next_input(reader);
+ vector out = next_output(reader);
+ crypto_chacha20_h(out.buf, key.buf, nonce.buf);
+}
+
+static void xchacha20(vector_reader *reader)
+{
+ vector key = next_input(reader);
+ vector nonce = next_input(reader);
+ vector plain = next_input(reader);
+ u64 ctr = load64_le(next_input(reader).buf);
+ vector out = next_output(reader);
+ u64 nb_blocks = plain.size / 64 + (plain.size % 64 != 0);
+ u64 new_ctr = crypto_chacha20_x(out.buf, plain.buf, plain.size,
+ key.buf, nonce.buf, ctr);
+ if (new_ctr - ctr != nb_blocks) {
+ printf("FAILURE: XChacha20 returned counter not correct: ");
+ }
+}
+
+static void poly1305(vector_reader *reader)
+{
+ vector key = next_input(reader);
+ vector msg = next_input(reader);
+ vector out = next_output(reader);
+ crypto_poly1305(out.buf, msg.buf, msg.size, key.buf);
+}
+
+static void aead_ietf(vector_reader *reader)
+{
+ vector key = next_input(reader);
+ vector nonce = next_input(reader);
+ vector ad = next_input(reader);
+ vector text = next_input(reader);
+ vector out = next_output(reader);
+ crypto_aead_lock(out.buf + 16, out.buf, key.buf, nonce.buf,
+ ad.buf, ad.size, text.buf, text.size);
+}
+
+static void blake2b(vector_reader *reader)
+{
+ vector msg = next_input(reader);
+ vector key = next_input(reader);
+ vector out = next_output(reader);
+ crypto_blake2b_keyed(out.buf, out.size,
+ key.buf, key.size,
+ msg.buf, msg.size);
+}
+
+static void sha512(vector_reader *reader)
+{
+ vector in = next_input(reader);
+ vector out = next_output(reader);
+ crypto_sha512(out.buf, in.buf, in.size);
+}
+
+static void sha512_hmac(vector_reader *reader)
+{
+ vector key = next_input(reader);
+ vector msg = next_input(reader);
+ vector out = next_output(reader);
+ crypto_sha512_hmac(out.buf, key.buf, key.size, msg.buf, msg.size);
+}
+
+static void sha512_hkdf(vector_reader *reader)
+{
+ vector ikm = next_input(reader);
+ vector salt = next_input(reader);
+ vector info = next_input(reader);
+ vector okm = next_output(reader);
+ crypto_sha512_hkdf(okm .buf, okm .size,
+ ikm .buf, ikm .size,
+ salt.buf, salt.size,
+ info.buf, info.size);
+}
+
+static void argon2(vector_reader *reader)
+{
+ crypto_argon2_config config;
+ config.algorithm = load32_le(next_input(reader).buf);
+ config.nb_blocks = load32_le(next_input(reader).buf);
+ config.nb_passes = load32_le(next_input(reader).buf);
+ config.nb_lanes = load32_le(next_input(reader).buf);
+
+ vector pass = next_input(reader);
+ vector salt = next_input(reader);
+ vector key = next_input(reader);
+ vector ad = next_input(reader);
+ vector out = next_output(reader);
+ void *work_area = alloc(config.nb_blocks * 1024);
+
+ crypto_argon2_inputs inputs;
+ inputs.pass = pass.buf;
+ inputs.salt = salt.buf;
+ inputs.pass_size = (u32)pass.size;
+ inputs.salt_size = (u32)salt.size;
+
+ crypto_argon2_extras extras;
+ extras.key = key.buf;
+ extras.ad = ad.buf;
+ extras.key_size = (u32)key.size;
+ extras.ad_size = (u32)ad.size;
+
+ crypto_argon2(out.buf, (u32)out.size, work_area, config, inputs, extras);
+ free(work_area);
+}
+
+static void x25519(vector_reader *reader)
+{
+ vector scalar = next_input(reader);
+ vector point = next_input(reader);
+ vector out = next_output(reader);
+ crypto_x25519(out.buf, scalar.buf, point.buf);
+}
+
+static void edDSA(vector_reader *reader)
+{
+ vector secret_k = next_input(reader);
+ vector public_k = next_input(reader);
+ vector msg = next_input(reader);
+ vector out = next_output(reader);
+ u8 fat_secret_key[64];
+ memcpy(fat_secret_key , secret_k.buf, 32);
+ memcpy(fat_secret_key + 32, public_k.buf, 32);
+ crypto_eddsa_sign(out.buf, fat_secret_key, msg.buf, msg.size);
+}
+
+static void edDSA_pk(vector_reader *reader)
+{
+ vector in = next_input(reader);
+ vector out = next_output(reader);
+ u8 seed [32];
+ u8 secret_key[64];
+ u8 public_key[32];
+ memcpy(seed, in.buf, 32);
+ crypto_eddsa_key_pair(secret_key, public_key, seed);
+ memcpy(out.buf, public_key, 32);
+
+ u8 zeroes[32] = {0};
+ ASSERT_EQUAL(seed , zeroes , 32);
+ ASSERT_EQUAL(secret_key , in.buf , 32);
+ ASSERT_EQUAL(secret_key + 32, public_key, 32);
+}
+
+static void ed_25519(vector_reader *reader)
+{
+ vector secret_k = next_input(reader);
+ vector public_k = next_input(reader);
+ vector msg = next_input(reader);
+ vector out = next_output(reader);
+ u8 fat_secret_key[64];
+ memcpy(fat_secret_key , secret_k.buf, 32);
+ memcpy(fat_secret_key + 32, public_k.buf, 32);
+ crypto_ed25519_sign(out.buf, fat_secret_key, msg.buf, msg.size);
+}
+
+static void ed_25519_check(vector_reader *reader)
+{
+ vector public_k = next_input(reader);
+ vector msg = next_input(reader);
+ vector sig = next_input(reader);
+ vector out = next_output(reader);
+ out.buf[0] = (u8)crypto_ed25519_check(sig.buf, public_k.buf,
+ msg.buf, msg.size);
+}
+
+static void elligator_dir(vector_reader *reader)
+{
+ vector in = next_input(reader);
+ vector out = next_output(reader);
+ crypto_elligator_map(out.buf, in.buf);
+}
+
+static void elligator_inv(vector_reader *reader)
+{
+ vector point = next_input(reader);
+ u8 tweak = next_input(reader).buf[0];
+ u8 failure = next_input(reader).buf[0];
+ vector out = next_output(reader);
+ int check = crypto_elligator_rev(out.buf, point.buf, tweak);
+ ASSERT((u8)check == failure);
+ if (check) {
+ out.buf[0] = 0;
+ }
+}
+
+//@ ensures \result == 0;
+static int p_wipe(void)
+{
+ printf("\tcrypto_wipe\n");
+ u8 zeroes[50] = {0};
+ FOR (i, 0, 50) {
+ RANDOM_INPUT(buf, 50);
+ crypto_wipe(buf, i);
+ ASSERT_EQUAL(zeroes, buf, i);
+ }
+ return 0;
+}
+
+//@ ensures \result == 0;
+static int p_eddsa_x25519(void)
+{
+ RANDOM_INPUT(e_seed, 32);
+ u8 secret [64];
+ u8 e_public1[32]; crypto_eddsa_key_pair(secret, e_public1, e_seed);
+ u8 x_private[64]; crypto_blake2b(x_private, 64, secret, 32);
+ u8 x_public1[32]; crypto_eddsa_to_x25519 (x_public1, e_public1);
+ u8 x_public2[32]; crypto_x25519_public_key(x_public2, x_private);
+ ASSERT_EQUAL(x_public1, x_public2, 32);
+
+ u8 e_public2[32]; crypto_x25519_to_eddsa (e_public2, x_public1);
+ ASSERT((e_public2[31] & 0x80) == 0); // x coordinate always positive
+
+ e_public1[31] &= 0x7f; // y coordinate back to original
+ ASSERT_EQUAL(e_public1, e_public2, 32);
+ return 0;
+}
+
+//@ ensures \result == 0;
+static int p_dirty(void)
+{
+ int status = 0;
+
+ RANDOM_INPUT(sk1, 32); sk1[0] |= 1; // make sure it's dirty
+ u8 skc [32]; memcpy(skc, sk1, 32); skc[0] &= 248; // make sure it's clean
+ u8 pks [32]; crypto_x25519_dirty_small(pks , sk1);
+ u8 pksc[32]; crypto_x25519_dirty_small(pksc, skc);
+ u8 pkf [32]; crypto_x25519_dirty_fast (pkf , sk1);
+ u8 pkfc[32]; crypto_x25519_dirty_fast (pkfc, skc);
+ u8 pk1 [32]; crypto_x25519_public_key (pk1 , sk1);
+
+ // Both dirty functions behave the same
+ status |= memcmp(pks, pkf, 32);
+
+ // Dirty functions behave cleanly if we clear the 3 msb first
+ status |= memcmp(pksc, pk1, 32);
+ status |= memcmp(pkfc, pk1, 32);
+
+ printf("%s: x25519 dirty\n", status != 0 ? "FAILED" : "OK");
+ return status;
+}
+
+//@ ensures \result == 0;
+static int p_x25519_inverse(void)
+{
+ int status = 0;
+ RANDOM_INPUT(b, 32);
+ u8 base[32]; // random point (cofactor is cleared).
+ crypto_x25519_public_key(base, b);
+ // check round trip
+ RANDOM_INPUT(sk, 32);
+ u8 pk [32];
+ u8 blind[32];
+ crypto_x25519(pk, sk, base);
+ crypto_x25519_inverse(blind, sk, pk);
+ status |= memcmp(blind, base, 32);
+
+ // check cofactor clearing
+ // (Multiplying by a low order point yields zero
+ u8 low_order[32] = {
+ 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,
+ };
+ u8 zero[32] = {0};
+ crypto_x25519_inverse(blind, sk, low_order);
+ status |= memcmp(blind, zero, 32);
+ printf("%s: x25519_inverse\n", status != 0 ? "FAILED" : "OK");
+ return status;
+}
+
+//@ ensures \result == 0;
+static int p_verify(size_t size, int (*compare)(const u8*, const u8*))
+{
+ int status = 0;
+ u8 a[64]; // size <= 64
+ u8 b[64]; // size <= 64
+ FOR (i, 0, 2) {
+ FOR (j, 0, 2) {
+ // Set every byte to the chosen value, then compare
+ FOR (k, 0, size) {
+ a[k] = (u8)i;
+ b[k] = (u8)j;
+ }
+ int cmp = compare(a, b);
+ status |= (i == j ? cmp : ~cmp);
+ // Set only two bytes to the chosen value, then compare
+ FOR (k, 0, size / 2) {
+ FOR (l, 0, size) {
+ a[l] = 0;
+ b[l] = 0;
+ }
+ a[k] = (u8)i; a[k + size/2 - 1] = (u8)i;
+ b[k] = (u8)j; b[k + size/2 - 1] = (u8)j;
+ cmp = compare(a, b);
+ status |= (i == j ? cmp : ~cmp);
+ }
+ }
+ }
+ printf("%s: crypto_verify%zu\n", status != 0 ? "FAILED" : "OK", size);
+ return status;
+}
+//@ ensures \result == 0;
+static int p_verify16(void){ return p_verify(16, crypto_verify16); }
+//@ ensures \result == 0;
+static int p_verify32(void){ return p_verify(32, crypto_verify32); }
+//@ ensures \result == 0;
+static int p_verify64(void){ return p_verify(64, crypto_verify64); }
+
+#define TEST(name) \
+ int v_##name(void) { \
+ return vector_test(name, #name, nb_##name##_vectors, name##_vectors); \
+ }
+
+//@ ensures \result == 0;
+TEST(chacha20)
+//@ ensures \result == 0;
+TEST(ietf_chacha20)
+//@ ensures \result == 0;
+TEST(hchacha20)
+//@ ensures \result == 0;
+TEST(xchacha20)
+//@ ensures \result == 0;
+TEST(poly1305)
+//@ ensures \result == 0;
+TEST(aead_ietf)
+//@ ensures \result == 0;
+TEST(blake2b)
+//@ ensures \result == 0;
+TEST(sha512)
+//@ ensures \result == 0;
+TEST(sha512_hmac)
+//@ ensures \result == 0;
+TEST(sha512_hkdf)
+//@ ensures \result == 0;
+TEST(argon2)
+//@ ensures \result == 0;
+TEST(x25519)
+//@ ensures \result == 0;
+TEST(edDSA)
+//@ ensures \result == 0;
+TEST(edDSA_pk)
+//@ ensures \result == 0;
+TEST(ed_25519)
+//@ ensures \result == 0;
+TEST(ed_25519_check)
+//@ ensures \result == 0;
+TEST(elligator_dir)
+//@ ensures \result == 0;
+TEST(elligator_inv)
+
+//@ ensures \result == 0;
+int main(void) {
+ ASSERT(v_chacha20 () == 0);
+ ASSERT(v_ietf_chacha20 () == 0);
+ ASSERT(v_hchacha20 () == 0);
+ ASSERT(v_xchacha20 () == 0);
+ ASSERT(v_poly1305 () == 0);
+ ASSERT(v_aead_ietf () == 0);
+ ASSERT(v_blake2b () == 0);
+ ASSERT(v_sha512 () == 0);
+ ASSERT(v_sha512_hmac () == 0);
+ ASSERT(v_sha512_hkdf () == 0);
+ ASSERT(v_argon2 () == 0);
+ ASSERT(v_x25519 () == 0);
+ ASSERT(v_edDSA () == 0);
+ ASSERT(v_edDSA_pk () == 0);
+ ASSERT(v_ed_25519 () == 0);
+ ASSERT(v_ed_25519_check() == 0);
+ ASSERT(v_elligator_dir () == 0);
+ ASSERT(v_elligator_inv () == 0);
+
+ ASSERT(p_wipe () == 0);
+ ASSERT(p_eddsa_x25519 () == 0);
+ ASSERT(p_dirty () == 0);
+ ASSERT(p_x25519_inverse() == 0);
+ ASSERT(p_verify16 () == 0);
+ ASSERT(p_verify32 () == 0);
+ ASSERT(p_verify64 () == 0);
+ return 0;
+}
diff --git a/lib/Utils.Cryptography/monocypher/vendor/tests/utils.c b/lib/Utils.Cryptography/monocypher/vendor/tests/utils.c
new file mode 100644
index 0000000..16c1d55
--- /dev/null
+++ b/lib/Utils.Cryptography/monocypher/vendor/tests/utils.c
@@ -0,0 +1,176 @@
+// This file is dual-licensed. Choose whichever licence you want from
+// the two licences listed below.
+//
+// The first licence is a regular 2-clause BSD licence. The second licence
+// is the CC-0 from Creative Commons. It is intended to release Monocypher
+// to the public domain. The BSD licence serves as a fallback option.
+//
+// SPDX-License-Identifier: BSD-2-Clause OR CC0-1.0
+//
+// ------------------------------------------------------------------------
+//
+// Copyright (c) 2017-2019, 2023 Loup Vaillant
+// 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 COPYRIGHT HOLDERS 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 COPYRIGHT
+// HOLDER 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.
+//
+// ------------------------------------------------------------------------
+//
+// Written in 2017-2019, 2023 by Loup Vaillant
+//
+// To the extent possible under law, the author(s) have dedicated all copyright
+// and related 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
+// <https://creativecommons.org/publicdomain/zero/1.0/>
+
+#include "utils.h"
+
+#include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+
+u32 load32_le(const u8 s[4])
+{
+ return
+ ((u32)s[0] << 0) |
+ ((u32)s[1] << 8) |
+ ((u32)s[2] << 16) |
+ ((u32)s[3] << 24);
+}
+
+u64 load64_le(const u8 s[8])
+{
+ return load32_le(s) | ((u64)load32_le(s+4) << 32);
+}
+
+// Must be seeded with a nonzero value.
+// Accessible from the outside so we can modify it
+u64 random_state = 12345;
+
+// Pseudo-random 64 bit number, based on xorshift*
+u64 rand64(void)
+{
+ random_state ^= random_state >> 12;
+ random_state ^= random_state << 25;
+ random_state ^= random_state >> 27;
+ return random_state * 0x2545F4914F6CDD1D; // magic constant
+}
+
+void p_random(u8 *stream, size_t size)
+{
+ FOR (i, 0, size) {
+ stream[i] = (u8)rand64();
+ }
+}
+
+void* alloc(size_t size)
+{
+ if (size == 0) {
+ // Some systems refuse to allocate zero bytes.
+ // So we don't. Instead, we just return a non-sensical pointer.
+ // It shouldn't be dereferenced anyway.
+ return NULL;
+ }
+ void *buf = malloc(size);
+ ASSERT(buf != NULL);
+ return buf;
+}
+
+static int to_num(char c)
+{
+ return c >= '0' && c <= '9' ? c - '0'
+ : c >= 'a' && c <= 'f' ? c - 'a' + 10
+ : c - 'A' + 10;
+}
+
+static vector vector_of_string(const char *s)
+{
+ vector v;
+ v.size = strlen(s) / 2;
+ v.buf = v.size == 0 ? 0 : (u8*)alloc(v.size);
+ FOR (i, 0, v.size) {
+ int msb = to_num(*s); s++;
+ int lsb = to_num(*s); s++;
+ v.buf[i] = (u8)(msb * 16 + lsb);
+ }
+ return v;
+}
+
+vector next_input(vector_reader *reader)
+{
+ ASSERT(reader->size > 0);
+ ASSERT(reader->nb_inputs < 10);
+
+ const char *next = *(reader->next);
+ vector *input = reader->inputs + reader->nb_inputs;
+ reader->next++;
+ reader->size--;
+ *input = vector_of_string(next);
+ reader->nb_inputs++;
+ return *input;
+}
+
+vector next_output(vector_reader *reader)
+{
+ ASSERT(reader->size > 0);
+ ASSERT(reader->nb_inputs < 10);
+
+ const char *next = *(reader->next);
+ reader->next++;
+ reader->size--;
+ reader->expected = vector_of_string(next);
+ reader->out.size = reader->expected.size;
+ reader->out.buf = (u8*)alloc(reader->out.size);
+ return reader->out;
+}
+
+int vector_test(void (*f)(vector_reader*),
+ const char *name, size_t nb_vectors, const char *vectors[])
+{
+ int status = 0;
+ printf("\t%s\n", name);
+
+ vector_reader in;
+ in.size = nb_vectors;
+ in.next = vectors;
+
+ while (in.size > 0) {
+ in.nb_inputs = 0;
+ f(&in);
+ if (in.expected.size != 0) {
+ status |= memcmp(in.out.buf, in.expected.buf, in.expected.size);
+ }
+ FOR (i, 0, in.nb_inputs) {
+ free(in.inputs[i].buf);
+ }
+ free(in.out.buf);
+ free(in.expected.buf);
+ }
+ return status;
+}
diff --git a/lib/Utils.Cryptography/monocypher/vendor/tests/utils.h b/lib/Utils.Cryptography/monocypher/vendor/tests/utils.h
new file mode 100644
index 0000000..4588256
--- /dev/null
+++ b/lib/Utils.Cryptography/monocypher/vendor/tests/utils.h
@@ -0,0 +1,107 @@
+// This file is dual-licensed. Choose whichever licence you want from
+// the two licences listed below.
+//
+// The first licence is a regular 2-clause BSD licence. The second licence
+// is the CC-0 from Creative Commons. It is intended to release Monocypher
+// to the public domain. The BSD licence serves as a fallback option.
+//
+// SPDX-License-Identifier: BSD-2-Clause OR CC0-1.0
+//
+// ------------------------------------------------------------------------
+//
+// Copyright (c) 2017-2019, 2023 Loup Vaillant
+// 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 COPYRIGHT HOLDERS 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 COPYRIGHT
+// HOLDER 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.
+//
+// ------------------------------------------------------------------------
+//
+// Written in 2017-2019, 2023 by Loup Vaillant
+//
+// To the extent possible under law, the author(s) have dedicated all copyright
+// and related 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
+// <https://creativecommons.org/publicdomain/zero/1.0/>
+
+#ifndef UTILS_H
+#define UTILS_H
+
+#include <inttypes.h>
+#include <stddef.h>
+
+typedef int8_t i8;
+typedef uint8_t u8;
+typedef uint32_t u32;
+typedef int32_t i32;
+typedef int64_t i64;
+typedef uint64_t u64;
+
+#define FOR(i, start, end) for (size_t i = (start); i < (end); i++)
+#define SODIUM_INIT ASSERT(sodium_init() != -1)
+#define RANDOM_INPUT(name, size) u8 name[size]; p_random(name, size)
+#define ASSERT(condition) do { \
+ if (!(condition)) { \
+ fprintf(stderr, "Assert failure(%s, %d): %s\n", \
+ __FILE__, __LINE__, #condition); \
+ exit(1); \
+ } \
+ } while (0)
+#define ASSERT_EQUAL(a, b, size) ASSERT(memcmp(a, b, size) == 0)
+#define ASSERT_DIFFERENT(a, b, size) ASSERT(memcmp(a, b, size) != 0)
+#define ASSERT_OK(exp) ASSERT((exp) == 0)
+#define ASSERT_KO(exp) ASSERT((exp) != 0)
+
+extern u64 random_state; // state of the RNG
+
+typedef struct {
+ u8 *buf;
+ size_t size;
+} vector;
+
+typedef struct {
+ const char **next;
+ size_t size;
+ vector inputs[10];
+ size_t nb_inputs;
+ vector expected;
+ vector out;
+} vector_reader;
+
+u64 load64_le(const u8 s[8]);
+u32 load32_le(const u8 s[4]);
+u64 rand64(void); // Pseudo-random 64 bit number, based on xorshift*
+void p_random(u8 *stream, size_t size);
+void* alloc(size_t size);
+
+vector next_input (vector_reader *vectors);
+vector next_output(vector_reader *vectors);
+int vector_test(void (*f)(vector_reader*),
+ const char *name, size_t nb_vectors, const char *vectors[]);
+
+#endif // UTILS_H
diff --git a/lib/Utils.Cryptography/monocypher/vnlib_monocypher.c b/lib/Utils.Cryptography/monocypher/vnlib_monocypher.c
new file mode 100644
index 0000000..7178ef1
--- /dev/null
+++ b/lib/Utils.Cryptography/monocypher/vnlib_monocypher.c
@@ -0,0 +1,119 @@
+/*
+* Copyright (c) 2023 Vaughn Nugent
+*
+* vnlib_monocypher is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published
+* by the Free Software Foundation, either version 2 of the License,
+* or (at your option) any later version.
+*
+* vnlib_monocypher is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+* General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with vnlib_monocypher. If not, see http://www.gnu.org/licenses/.
+*/
+
+
+#if 0
+#include <monocypher.h>
+#include "vnlib_monocypher.h"
+
+#define AEAD_MAX_NONCE_SIZE 24
+#define AEAD_MAX_KEY_SIZE 32
+
+#define AEAD_RESULT_SUCCESS 0
+
+typedef struct ChaChaStreamStruct {
+ uint8_t nonceCounter[8];
+ uint8_t secretKey[32];
+ uint8_t mac[16];
+} ChaChaStream;
+
+static int32_t _incrementNonce(ChaChaStream* stream)
+{
+ /*
+ * The once will be incremented by 1 for each call to lock/unlock
+ * if the nonce will overflow, then return 0 to indicate an error
+ */
+
+ VALIDATE_PTR(stream);
+
+ /* increment the nonce */
+
+ uint64_t* nonce;
+ uint64_t value;
+
+ nonce = (uint64_t*)stream->nonceCounter;
+ value = *nonce;
+
+ /* increment the nonce */
+ if(++value == 0)
+ {
+ /* nonce overflow */
+ return FALSE;
+ }
+
+ /* assign the value back */
+ *nonce = value;
+ return TRUE;
+}
+
+uint32_t AeadStreamStructSize(void)
+{
+ return sizeof(ChaChaStream);
+}
+
+int32_t AeadUpdateKey(ChaChaStream* stream, const uint8_t key[32])
+{
+ VALIDATE_PTR(stream);
+ VALIDATE_PTR(key);
+
+ /* copy the key to the structure key */
+ _memmove(stream->secretKey, key, 32);
+ return TRUE;
+}
+
+int32_t AeadUpdateMac(ChaChaStream* stream, const uint8_t mac[16])
+{
+ VALIDATE_PTR(stream);
+ VALIDATE_PTR(mac);
+
+ /* copy the mac to the structure mac */
+ _memmove(stream->mac, mac, 16);
+ return TRUE;
+}
+
+int32_t AeadInitStream(ChaChaStream* stream, const uint8_t key[32], const uint8_t startingNonce[8], const uint8_t mac[16])
+{
+ VALIDATE_PTR(stream);
+ VALIDATE_PTR(key);
+ VALIDATE_PTR(startingNonce);
+ VALIDATE_PTR(mac);
+
+ /* clear stream before using */
+ crypto_wipe(stream, sizeof(ChaChaStream));
+
+ /* copy the key to the structure key */
+ _memmove(stream->secretKey, key, 32);
+
+ /* copy the nonce to the structure nonce */
+ _memmove(stream->nonceCounter, startingNonce, 8);
+
+ /* copy the mac to the structure mac */
+ _memmove(stream->mac, mac, 16);
+ return TRUE;
+}
+
+int32_t AeadEncrypt(ChaChaStream* stream, const uint8_t* plainText, uint32_t plainTextSize, uint8_t* cipherText, uint8_t* tag)
+{
+ VALIDATE_PTR(stream);
+ VALIDATE_PTR(plainText);
+ VALIDATE_PTR(cipherText);
+ VALIDATE_PTR(tag);
+}
+
+#else
+typedef int something_to_stop_compiler_err_while_in_dev;
+#endif \ No newline at end of file
diff --git a/lib/Utils.Cryptography/monocypher/vnlib_monocypher.h b/lib/Utils.Cryptography/monocypher/vnlib_monocypher.h
new file mode 100644
index 0000000..920def9
--- /dev/null
+++ b/lib/Utils.Cryptography/monocypher/vnlib_monocypher.h
@@ -0,0 +1,24 @@
+/*
+* Copyright (c) 2023 Vaughn Nugent
+*
+* vnlib_monocypher is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published
+* by the Free Software Foundation, either version 2 of the License,
+* or (at your option) any later version.
+*
+* vnlib_monocypher is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+* General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with vnlib_monocypher. If not, see http://www.gnu.org/licenses/.
+*/
+
+#pragma once
+#ifndef VNLIB_MONOCYPHER_H
+#define VNLIB_MONOCYPHER_H
+
+#include "util.h"
+
+#endif \ No newline at end of file
diff --git a/lib/Utils.Cryptography/monocypher/vnlib_monocypher.vcxitems b/lib/Utils.Cryptography/monocypher/vnlib_monocypher.vcxitems
new file mode 100644
index 0000000..6fc55c7
--- /dev/null
+++ b/lib/Utils.Cryptography/monocypher/vnlib_monocypher.vcxitems
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <PropertyGroup Label="Globals">
+ <MSBuildAllProjects Condition="'$(MSBuildVersion)' == '' Or '$(MSBuildVersion)' &lt; '16.0'">$(MSBuildAllProjects);$(MSBuildThisFileFullPath)</MSBuildAllProjects>
+ <HasSharedItems>true</HasSharedItems>
+ <ItemsProjectGuid>{194aad38-05ab-4715-a367-190b3da78899}</ItemsProjectGuid>
+ </PropertyGroup>
+ <ItemDefinitionGroup>
+ <ClCompile>
+ <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(MSBuildThisFileDirectory)</AdditionalIncludeDirectories>
+ </ClCompile>
+ </ItemDefinitionGroup>
+ <ItemGroup>
+ <ProjectCapability Include="SourceItemsFromImports" />
+ </ItemGroup>
+ <ItemGroup>
+ <Text Include="$(MSBuildThisFileDirectory)build.readme.txt" />
+ <Text Include="$(MSBuildThisFileDirectory)CMakeLists.txt" />
+ <Text Include="$(MSBuildThisFileDirectory)license.txt" />
+ </ItemGroup>
+ <ItemGroup>
+ <ClCompile Include="$(MSBuildThisFileDirectory)vnlib_rpmalloc.c" />
+ </ItemGroup>
+ <ItemGroup>
+ <None Include="$(MSBuildThisFileDirectory)package.json" />
+ <None Include="$(MSBuildThisFileDirectory)Taskfile.yaml" />
+ </ItemGroup>
+</Project> \ No newline at end of file