diff --git a/builds/msvc/vs2010/libsodium/libsodium.vcxproj b/builds/msvc/vs2010/libsodium/libsodium.vcxproj
index 0d1b6865..1c60896a 100644
--- a/builds/msvc/vs2010/libsodium/libsodium.vcxproj
+++ b/builds/msvc/vs2010/libsodium/libsodium.vcxproj
@@ -152,6 +152,10 @@
+
+
+
+
@@ -215,6 +219,7 @@
+
@@ -275,6 +280,7 @@
+
@@ -318,6 +324,10 @@
+
+
+
+
diff --git a/builds/msvc/vs2010/libsodium/libsodium.vcxproj.filters b/builds/msvc/vs2010/libsodium/libsodium.vcxproj.filters
index 381b4985..6e44b46e 100644
--- a/builds/msvc/vs2010/libsodium/libsodium.vcxproj.filters
+++ b/builds/msvc/vs2010/libsodium/libsodium.vcxproj.filters
@@ -276,6 +276,18 @@
sodium
+
+ crypto_ipcrypt
+
+
+ crypto_ipcrypt
+
+
+ crypto_ipcrypt
+
+
+ crypto_ipcrypt
+
crypto_stream
@@ -461,6 +473,9 @@
include\sodium
+
+ include\sodium
+
include\sodium
@@ -641,6 +656,9 @@
include\sodium
+
+ include\sodium
+
include\sodium
@@ -770,6 +788,18 @@
crypto_onetimeauth\poly1305\sse2
+
+ crypto_ipcrypt
+
+
+ crypto_ipcrypt
+
+
+ crypto_ipcrypt
+
+
+ crypto_ipcrypt
+
crypto_stream\chacha20
@@ -988,6 +1018,9 @@
{f2d6a22b-dd67-3561-90a4-88696169cb7b}
+
+ {5c3b1fe7-203f-36fd-bca5-8d0c4b466d80}
+
{aaf59186-1c0d-33cf-a34d-93e14bb87226}
diff --git a/builds/msvc/vs2012/libsodium/libsodium.vcxproj b/builds/msvc/vs2012/libsodium/libsodium.vcxproj
index 9bd14e4a..3a89a65e 100644
--- a/builds/msvc/vs2012/libsodium/libsodium.vcxproj
+++ b/builds/msvc/vs2012/libsodium/libsodium.vcxproj
@@ -152,6 +152,10 @@
+
+
+
+
@@ -215,6 +219,7 @@
+
@@ -275,6 +280,7 @@
+
@@ -318,6 +324,10 @@
+
+
+
+
diff --git a/builds/msvc/vs2012/libsodium/libsodium.vcxproj.filters b/builds/msvc/vs2012/libsodium/libsodium.vcxproj.filters
index 381b4985..6e44b46e 100644
--- a/builds/msvc/vs2012/libsodium/libsodium.vcxproj.filters
+++ b/builds/msvc/vs2012/libsodium/libsodium.vcxproj.filters
@@ -276,6 +276,18 @@
sodium
+
+ crypto_ipcrypt
+
+
+ crypto_ipcrypt
+
+
+ crypto_ipcrypt
+
+
+ crypto_ipcrypt
+
crypto_stream
@@ -461,6 +473,9 @@
include\sodium
+
+ include\sodium
+
include\sodium
@@ -641,6 +656,9 @@
include\sodium
+
+ include\sodium
+
include\sodium
@@ -770,6 +788,18 @@
crypto_onetimeauth\poly1305\sse2
+
+ crypto_ipcrypt
+
+
+ crypto_ipcrypt
+
+
+ crypto_ipcrypt
+
+
+ crypto_ipcrypt
+
crypto_stream\chacha20
@@ -988,6 +1018,9 @@
{f2d6a22b-dd67-3561-90a4-88696169cb7b}
+
+ {5c3b1fe7-203f-36fd-bca5-8d0c4b466d80}
+
{aaf59186-1c0d-33cf-a34d-93e14bb87226}
diff --git a/builds/msvc/vs2013/libsodium/libsodium.vcxproj b/builds/msvc/vs2013/libsodium/libsodium.vcxproj
index 0e67954c..f5e655c3 100644
--- a/builds/msvc/vs2013/libsodium/libsodium.vcxproj
+++ b/builds/msvc/vs2013/libsodium/libsodium.vcxproj
@@ -152,6 +152,10 @@
+
+
+
+
@@ -215,6 +219,7 @@
+
@@ -275,6 +280,7 @@
+
@@ -318,6 +324,10 @@
+
+
+
+
diff --git a/builds/msvc/vs2013/libsodium/libsodium.vcxproj.filters b/builds/msvc/vs2013/libsodium/libsodium.vcxproj.filters
index 381b4985..6e44b46e 100644
--- a/builds/msvc/vs2013/libsodium/libsodium.vcxproj.filters
+++ b/builds/msvc/vs2013/libsodium/libsodium.vcxproj.filters
@@ -276,6 +276,18 @@
sodium
+
+ crypto_ipcrypt
+
+
+ crypto_ipcrypt
+
+
+ crypto_ipcrypt
+
+
+ crypto_ipcrypt
+
crypto_stream
@@ -461,6 +473,9 @@
include\sodium
+
+ include\sodium
+
include\sodium
@@ -641,6 +656,9 @@
include\sodium
+
+ include\sodium
+
include\sodium
@@ -770,6 +788,18 @@
crypto_onetimeauth\poly1305\sse2
+
+ crypto_ipcrypt
+
+
+ crypto_ipcrypt
+
+
+ crypto_ipcrypt
+
+
+ crypto_ipcrypt
+
crypto_stream\chacha20
@@ -988,6 +1018,9 @@
{f2d6a22b-dd67-3561-90a4-88696169cb7b}
+
+ {5c3b1fe7-203f-36fd-bca5-8d0c4b466d80}
+
{aaf59186-1c0d-33cf-a34d-93e14bb87226}
diff --git a/builds/msvc/vs2015/libsodium/libsodium.vcxproj b/builds/msvc/vs2015/libsodium/libsodium.vcxproj
index 5017049c..2ca1ec76 100644
--- a/builds/msvc/vs2015/libsodium/libsodium.vcxproj
+++ b/builds/msvc/vs2015/libsodium/libsodium.vcxproj
@@ -152,6 +152,10 @@
+
+
+
+
@@ -215,6 +219,7 @@
+
@@ -275,6 +280,7 @@
+
@@ -318,6 +324,10 @@
+
+
+
+
diff --git a/builds/msvc/vs2015/libsodium/libsodium.vcxproj.filters b/builds/msvc/vs2015/libsodium/libsodium.vcxproj.filters
index 381b4985..6e44b46e 100644
--- a/builds/msvc/vs2015/libsodium/libsodium.vcxproj.filters
+++ b/builds/msvc/vs2015/libsodium/libsodium.vcxproj.filters
@@ -276,6 +276,18 @@
sodium
+
+ crypto_ipcrypt
+
+
+ crypto_ipcrypt
+
+
+ crypto_ipcrypt
+
+
+ crypto_ipcrypt
+
crypto_stream
@@ -461,6 +473,9 @@
include\sodium
+
+ include\sodium
+
include\sodium
@@ -641,6 +656,9 @@
include\sodium
+
+ include\sodium
+
include\sodium
@@ -770,6 +788,18 @@
crypto_onetimeauth\poly1305\sse2
+
+ crypto_ipcrypt
+
+
+ crypto_ipcrypt
+
+
+ crypto_ipcrypt
+
+
+ crypto_ipcrypt
+
crypto_stream\chacha20
@@ -988,6 +1018,9 @@
{f2d6a22b-dd67-3561-90a4-88696169cb7b}
+
+ {5c3b1fe7-203f-36fd-bca5-8d0c4b466d80}
+
{aaf59186-1c0d-33cf-a34d-93e14bb87226}
diff --git a/builds/msvc/vs2017/libsodium/libsodium.vcxproj b/builds/msvc/vs2017/libsodium/libsodium.vcxproj
index 139e75d8..436d89f1 100644
--- a/builds/msvc/vs2017/libsodium/libsodium.vcxproj
+++ b/builds/msvc/vs2017/libsodium/libsodium.vcxproj
@@ -152,6 +152,10 @@
+
+
+
+
@@ -215,6 +219,7 @@
+
@@ -275,6 +280,7 @@
+
@@ -318,6 +324,10 @@
+
+
+
+
diff --git a/builds/msvc/vs2017/libsodium/libsodium.vcxproj.filters b/builds/msvc/vs2017/libsodium/libsodium.vcxproj.filters
index 381b4985..6e44b46e 100644
--- a/builds/msvc/vs2017/libsodium/libsodium.vcxproj.filters
+++ b/builds/msvc/vs2017/libsodium/libsodium.vcxproj.filters
@@ -276,6 +276,18 @@
sodium
+
+ crypto_ipcrypt
+
+
+ crypto_ipcrypt
+
+
+ crypto_ipcrypt
+
+
+ crypto_ipcrypt
+
crypto_stream
@@ -461,6 +473,9 @@
include\sodium
+
+ include\sodium
+
include\sodium
@@ -641,6 +656,9 @@
include\sodium
+
+ include\sodium
+
include\sodium
@@ -770,6 +788,18 @@
crypto_onetimeauth\poly1305\sse2
+
+ crypto_ipcrypt
+
+
+ crypto_ipcrypt
+
+
+ crypto_ipcrypt
+
+
+ crypto_ipcrypt
+
crypto_stream\chacha20
@@ -988,6 +1018,9 @@
{f2d6a22b-dd67-3561-90a4-88696169cb7b}
+
+ {5c3b1fe7-203f-36fd-bca5-8d0c4b466d80}
+
{aaf59186-1c0d-33cf-a34d-93e14bb87226}
diff --git a/builds/msvc/vs2019/libsodium/libsodium.vcxproj b/builds/msvc/vs2019/libsodium/libsodium.vcxproj
index d093954d..30f807ab 100644
--- a/builds/msvc/vs2019/libsodium/libsodium.vcxproj
+++ b/builds/msvc/vs2019/libsodium/libsodium.vcxproj
@@ -176,6 +176,10 @@
+
+
+
+
@@ -239,6 +243,7 @@
+
@@ -299,6 +304,7 @@
+
@@ -342,6 +348,10 @@
+
+
+
+
diff --git a/builds/msvc/vs2019/libsodium/libsodium.vcxproj.filters b/builds/msvc/vs2019/libsodium/libsodium.vcxproj.filters
index 381b4985..6e44b46e 100644
--- a/builds/msvc/vs2019/libsodium/libsodium.vcxproj.filters
+++ b/builds/msvc/vs2019/libsodium/libsodium.vcxproj.filters
@@ -276,6 +276,18 @@
sodium
+
+ crypto_ipcrypt
+
+
+ crypto_ipcrypt
+
+
+ crypto_ipcrypt
+
+
+ crypto_ipcrypt
+
crypto_stream
@@ -461,6 +473,9 @@
include\sodium
+
+ include\sodium
+
include\sodium
@@ -641,6 +656,9 @@
include\sodium
+
+ include\sodium
+
include\sodium
@@ -770,6 +788,18 @@
crypto_onetimeauth\poly1305\sse2
+
+ crypto_ipcrypt
+
+
+ crypto_ipcrypt
+
+
+ crypto_ipcrypt
+
+
+ crypto_ipcrypt
+
crypto_stream\chacha20
@@ -988,6 +1018,9 @@
{f2d6a22b-dd67-3561-90a4-88696169cb7b}
+
+ {5c3b1fe7-203f-36fd-bca5-8d0c4b466d80}
+
{aaf59186-1c0d-33cf-a34d-93e14bb87226}
diff --git a/builds/msvc/vs2022/libsodium/libsodium.vcxproj b/builds/msvc/vs2022/libsodium/libsodium.vcxproj
index 58a28e87..3fb69e59 100644
--- a/builds/msvc/vs2022/libsodium/libsodium.vcxproj
+++ b/builds/msvc/vs2022/libsodium/libsodium.vcxproj
@@ -176,6 +176,10 @@
+
+
+
+
@@ -239,6 +243,7 @@
+
@@ -299,6 +304,7 @@
+
@@ -342,6 +348,10 @@
+
+
+
+
diff --git a/builds/msvc/vs2022/libsodium/libsodium.vcxproj.filters b/builds/msvc/vs2022/libsodium/libsodium.vcxproj.filters
index 381b4985..6e44b46e 100644
--- a/builds/msvc/vs2022/libsodium/libsodium.vcxproj.filters
+++ b/builds/msvc/vs2022/libsodium/libsodium.vcxproj.filters
@@ -276,6 +276,18 @@
sodium
+
+ crypto_ipcrypt
+
+
+ crypto_ipcrypt
+
+
+ crypto_ipcrypt
+
+
+ crypto_ipcrypt
+
crypto_stream
@@ -461,6 +473,9 @@
include\sodium
+
+ include\sodium
+
include\sodium
@@ -641,6 +656,9 @@
include\sodium
+
+ include\sodium
+
include\sodium
@@ -770,6 +788,18 @@
crypto_onetimeauth\poly1305\sse2
+
+ crypto_ipcrypt
+
+
+ crypto_ipcrypt
+
+
+ crypto_ipcrypt
+
+
+ crypto_ipcrypt
+
crypto_stream\chacha20
@@ -988,6 +1018,9 @@
{f2d6a22b-dd67-3561-90a4-88696169cb7b}
+
+ {5c3b1fe7-203f-36fd-bca5-8d0c4b466d80}
+
{aaf59186-1c0d-33cf-a34d-93e14bb87226}
diff --git a/builds/msvc/vs2026/libsodium/libsodium.vcxproj b/builds/msvc/vs2026/libsodium/libsodium.vcxproj
index 3549ba2c..11d7a2be 100644
--- a/builds/msvc/vs2026/libsodium/libsodium.vcxproj
+++ b/builds/msvc/vs2026/libsodium/libsodium.vcxproj
@@ -176,6 +176,10 @@
+
+
+
+
@@ -239,6 +243,7 @@
+
@@ -299,6 +304,7 @@
+
@@ -342,6 +348,10 @@
+
+
+
+
diff --git a/builds/msvc/vs2026/libsodium/libsodium.vcxproj.filters b/builds/msvc/vs2026/libsodium/libsodium.vcxproj.filters
index 381b4985..6e44b46e 100644
--- a/builds/msvc/vs2026/libsodium/libsodium.vcxproj.filters
+++ b/builds/msvc/vs2026/libsodium/libsodium.vcxproj.filters
@@ -276,6 +276,18 @@
sodium
+
+ crypto_ipcrypt
+
+
+ crypto_ipcrypt
+
+
+ crypto_ipcrypt
+
+
+ crypto_ipcrypt
+
crypto_stream
@@ -461,6 +473,9 @@
include\sodium
+
+ include\sodium
+
include\sodium
@@ -641,6 +656,9 @@
include\sodium
+
+ include\sodium
+
include\sodium
@@ -770,6 +788,18 @@
crypto_onetimeauth\poly1305\sse2
+
+ crypto_ipcrypt
+
+
+ crypto_ipcrypt
+
+
+ crypto_ipcrypt
+
+
+ crypto_ipcrypt
+
crypto_stream\chacha20
@@ -988,6 +1018,9 @@
{f2d6a22b-dd67-3561-90a4-88696169cb7b}
+
+ {5c3b1fe7-203f-36fd-bca5-8d0c4b466d80}
+
{aaf59186-1c0d-33cf-a34d-93e14bb87226}
diff --git a/ci/appveyor/libsodium.vcxproj b/ci/appveyor/libsodium.vcxproj
index f14562f5..b19db137 100644
--- a/ci/appveyor/libsodium.vcxproj
+++ b/ci/appveyor/libsodium.vcxproj
@@ -400,6 +400,10 @@
+
+
+
+
@@ -463,6 +467,7 @@
+
@@ -523,6 +528,7 @@
+
@@ -566,6 +572,10 @@
+
+
+
+
diff --git a/ci/appveyor/libsodium.vcxproj.filters b/ci/appveyor/libsodium.vcxproj.filters
index 497f3e22..3b31313f 100644
--- a/ci/appveyor/libsodium.vcxproj.filters
+++ b/ci/appveyor/libsodium.vcxproj.filters
@@ -267,6 +267,18 @@
Source Files
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
Source Files
@@ -452,6 +464,9 @@
Header Files
+
+ Header Files
+
Header Files
@@ -632,6 +647,9 @@
Header Files
+
+ Header Files
+
Header Files
@@ -761,6 +779,18 @@
Header Files
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
Header Files
diff --git a/dist-build/emscripten-symbols.def b/dist-build/emscripten-symbols.def
index 9ca1ea06..8a7c9917 100644
--- a/dist-build/emscripten-symbols.def
+++ b/dist-build/emscripten-symbols.def
@@ -165,7 +165,7 @@ _crypto_box_seedbytes 1 1
_crypto_box_zerobytes 0 1
_crypto_core_ed25519_add 0 1
_crypto_core_ed25519_bytes 0 1
-_crypto_core_ed25519_from_hash 0 0
+_crypto_core_ed25519_from_hash 0 1
_crypto_core_ed25519_from_uniform 0 1
_crypto_core_ed25519_hashbytes 0 1
_crypto_core_ed25519_is_valid_point 0 1
@@ -192,6 +192,12 @@ _crypto_core_hsalsa20_constbytes 0 1
_crypto_core_hsalsa20_inputbytes 0 1
_crypto_core_hsalsa20_keybytes 0 1
_crypto_core_hsalsa20_outputbytes 0 1
+_crypto_core_keccak1600_extract_bytes 0 1
+_crypto_core_keccak1600_init 0 1
+_crypto_core_keccak1600_permute_12 0 1
+_crypto_core_keccak1600_permute_24 0 1
+_crypto_core_keccak1600_statebytes 0 1
+_crypto_core_keccak1600_xor_bytes 0 1
_crypto_core_ristretto255_add 0 1
_crypto_core_ristretto255_bytes 0 1
_crypto_core_ristretto255_from_hash 0 1
@@ -268,6 +274,29 @@ _crypto_hash_sha512_final 0 1
_crypto_hash_sha512_init 0 1
_crypto_hash_sha512_statebytes 0 1
_crypto_hash_sha512_update 0 1
+_crypto_ipcrypt_bytes 1 1
+_crypto_ipcrypt_decrypt 1 1
+_crypto_ipcrypt_encrypt 1 1
+_crypto_ipcrypt_keybytes 1 1
+_crypto_ipcrypt_keygen 1 1
+_crypto_ipcrypt_nd_decrypt 1 1
+_crypto_ipcrypt_nd_encrypt 1 1
+_crypto_ipcrypt_nd_inputbytes 1 1
+_crypto_ipcrypt_nd_keybytes 1 1
+_crypto_ipcrypt_nd_outputbytes 1 1
+_crypto_ipcrypt_nd_tweakbytes 1 1
+_crypto_ipcrypt_ndx_decrypt 1 1
+_crypto_ipcrypt_ndx_encrypt 1 1
+_crypto_ipcrypt_ndx_inputbytes 1 1
+_crypto_ipcrypt_ndx_keybytes 1 1
+_crypto_ipcrypt_ndx_keygen 1 1
+_crypto_ipcrypt_ndx_outputbytes 1 1
+_crypto_ipcrypt_ndx_tweakbytes 1 1
+_crypto_ipcrypt_pfx_bytes 1 1
+_crypto_ipcrypt_pfx_decrypt 1 1
+_crypto_ipcrypt_pfx_encrypt 1 1
+_crypto_ipcrypt_pfx_keybytes 1 1
+_crypto_ipcrypt_pfx_keygen 1 1
_crypto_kdf_blake2b_bytes_max 0 1
_crypto_kdf_blake2b_bytes_min 0 1
_crypto_kdf_blake2b_contextbytes 0 1
@@ -517,9 +546,9 @@ _crypto_sign_ed25519ph_final_verify 0 1
_crypto_sign_ed25519ph_init 0 1
_crypto_sign_ed25519ph_statebytes 0 1
_crypto_sign_ed25519ph_update 0 1
-_crypto_sign_edwards25519sha512batch 0 0
-_crypto_sign_edwards25519sha512batch_keypair 0 0
-_crypto_sign_edwards25519sha512batch_open 0 0
+_crypto_sign_edwards25519sha512batch 0 1
+_crypto_sign_edwards25519sha512batch_keypair 0 1
+_crypto_sign_edwards25519sha512batch_open 0 1
_crypto_sign_final_create 1 1
_crypto_sign_final_verify 1 1
_crypto_sign_init 1 1
@@ -594,6 +623,38 @@ _crypto_verify_32 0 1
_crypto_verify_32_bytes 0 1
_crypto_verify_64 0 1
_crypto_verify_64_bytes 0 1
+_crypto_xof_shake128 1 1
+_crypto_xof_shake128_blockbytes 1 1
+_crypto_xof_shake128_domain_standard 1 1
+_crypto_xof_shake128_init 1 1
+_crypto_xof_shake128_init_with_domain 1 1
+_crypto_xof_shake128_squeeze 1 1
+_crypto_xof_shake128_statebytes 1 1
+_crypto_xof_shake128_update 1 1
+_crypto_xof_shake256 1 1
+_crypto_xof_shake256_blockbytes 1 1
+_crypto_xof_shake256_domain_standard 1 1
+_crypto_xof_shake256_init 1 1
+_crypto_xof_shake256_init_with_domain 1 1
+_crypto_xof_shake256_squeeze 1 1
+_crypto_xof_shake256_statebytes 1 1
+_crypto_xof_shake256_update 1 1
+_crypto_xof_turboshake128 1 1
+_crypto_xof_turboshake128_blockbytes 1 1
+_crypto_xof_turboshake128_domain_standard 1 1
+_crypto_xof_turboshake128_init 1 1
+_crypto_xof_turboshake128_init_with_domain 1 1
+_crypto_xof_turboshake128_squeeze 1 1
+_crypto_xof_turboshake128_statebytes 1 1
+_crypto_xof_turboshake128_update 1 1
+_crypto_xof_turboshake256 1 1
+_crypto_xof_turboshake256_blockbytes 1 1
+_crypto_xof_turboshake256_domain_standard 1 1
+_crypto_xof_turboshake256_init 1 1
+_crypto_xof_turboshake256_init_with_domain 1 1
+_crypto_xof_turboshake256_squeeze 1 1
+_crypto_xof_turboshake256_statebytes 1 1
+_crypto_xof_turboshake256_update 1 1
_randombytes 1 1
_randombytes_buf 1 1
_randombytes_buf_deterministic 1 1
diff --git a/dist-build/emscripten.sh b/dist-build/emscripten.sh
index 86bf974f..cb2e092a 100755
--- a/dist-build/emscripten.sh
+++ b/dist-build/emscripten.sh
@@ -1,8 +1,8 @@
#! /bin/sh
export MAKE_FLAGS='-j4'
-export EXPORTED_FUNCTIONS_STANDARD='["_malloc","_free","_crypto_aead_aegis128l_abytes","_crypto_aead_aegis128l_decrypt","_crypto_aead_aegis128l_decrypt_detached","_crypto_aead_aegis128l_encrypt","_crypto_aead_aegis128l_encrypt_detached","_crypto_aead_aegis128l_keybytes","_crypto_aead_aegis128l_keygen","_crypto_aead_aegis128l_messagebytes_max","_crypto_aead_aegis128l_npubbytes","_crypto_aead_aegis128l_nsecbytes","_crypto_aead_aegis256_abytes","_crypto_aead_aegis256_decrypt","_crypto_aead_aegis256_decrypt_detached","_crypto_aead_aegis256_encrypt","_crypto_aead_aegis256_encrypt_detached","_crypto_aead_aegis256_keybytes","_crypto_aead_aegis256_keygen","_crypto_aead_aegis256_messagebytes_max","_crypto_aead_aegis256_npubbytes","_crypto_aead_aegis256_nsecbytes","_crypto_aead_aes256gcm_is_available","_crypto_aead_chacha20poly1305_abytes","_crypto_aead_chacha20poly1305_decrypt","_crypto_aead_chacha20poly1305_decrypt_detached","_crypto_aead_chacha20poly1305_encrypt","_crypto_aead_chacha20poly1305_encrypt_detached","_crypto_aead_chacha20poly1305_ietf_abytes","_crypto_aead_chacha20poly1305_ietf_decrypt","_crypto_aead_chacha20poly1305_ietf_decrypt_detached","_crypto_aead_chacha20poly1305_ietf_encrypt","_crypto_aead_chacha20poly1305_ietf_encrypt_detached","_crypto_aead_chacha20poly1305_ietf_keybytes","_crypto_aead_chacha20poly1305_ietf_keygen","_crypto_aead_chacha20poly1305_ietf_messagebytes_max","_crypto_aead_chacha20poly1305_ietf_npubbytes","_crypto_aead_chacha20poly1305_ietf_nsecbytes","_crypto_aead_chacha20poly1305_keybytes","_crypto_aead_chacha20poly1305_keygen","_crypto_aead_chacha20poly1305_messagebytes_max","_crypto_aead_chacha20poly1305_npubbytes","_crypto_aead_chacha20poly1305_nsecbytes","_crypto_aead_xchacha20poly1305_ietf_abytes","_crypto_aead_xchacha20poly1305_ietf_decrypt","_crypto_aead_xchacha20poly1305_ietf_decrypt_detached","_crypto_aead_xchacha20poly1305_ietf_encrypt","_crypto_aead_xchacha20poly1305_ietf_encrypt_detached","_crypto_aead_xchacha20poly1305_ietf_keybytes","_crypto_aead_xchacha20poly1305_ietf_keygen","_crypto_aead_xchacha20poly1305_ietf_messagebytes_max","_crypto_aead_xchacha20poly1305_ietf_npubbytes","_crypto_aead_xchacha20poly1305_ietf_nsecbytes","_crypto_auth","_crypto_auth_bytes","_crypto_auth_keybytes","_crypto_auth_keygen","_crypto_auth_verify","_crypto_box_beforenm","_crypto_box_beforenmbytes","_crypto_box_detached","_crypto_box_detached_afternm","_crypto_box_easy","_crypto_box_easy_afternm","_crypto_box_keypair","_crypto_box_macbytes","_crypto_box_messagebytes_max","_crypto_box_noncebytes","_crypto_box_open_detached","_crypto_box_open_detached_afternm","_crypto_box_open_easy","_crypto_box_open_easy_afternm","_crypto_box_publickeybytes","_crypto_box_seal","_crypto_box_seal_open","_crypto_box_sealbytes","_crypto_box_secretkeybytes","_crypto_box_seed_keypair","_crypto_box_seedbytes","_crypto_generichash","_crypto_generichash_bytes","_crypto_generichash_bytes_max","_crypto_generichash_bytes_min","_crypto_generichash_final","_crypto_generichash_init","_crypto_generichash_keybytes","_crypto_generichash_keybytes_max","_crypto_generichash_keybytes_min","_crypto_generichash_keygen","_crypto_generichash_statebytes","_crypto_generichash_update","_crypto_hash","_crypto_hash_bytes","_crypto_kdf_bytes_max","_crypto_kdf_bytes_min","_crypto_kdf_contextbytes","_crypto_kdf_derive_from_key","_crypto_kdf_hkdf_sha256_bytes_max","_crypto_kdf_hkdf_sha256_bytes_min","_crypto_kdf_hkdf_sha256_expand","_crypto_kdf_hkdf_sha256_extract","_crypto_kdf_hkdf_sha256_extract_final","_crypto_kdf_hkdf_sha256_extract_init","_crypto_kdf_hkdf_sha256_extract_update","_crypto_kdf_hkdf_sha256_keybytes","_crypto_kdf_hkdf_sha256_keygen","_crypto_kdf_hkdf_sha256_statebytes","_crypto_kdf_hkdf_sha512_bytes_max","_crypto_kdf_hkdf_sha512_bytes_min","_crypto_kdf_hkdf_sha512_expand","_crypto_kdf_hkdf_sha512_extract","_crypto_kdf_hkdf_sha512_extract_final","_crypto_kdf_hkdf_sha512_extract_init","_crypto_kdf_hkdf_sha512_extract_update","_crypto_kdf_hkdf_sha512_keybytes","_crypto_kdf_hkdf_sha512_keygen","_crypto_kdf_hkdf_sha512_statebytes","_crypto_kdf_keybytes","_crypto_kdf_keygen","_crypto_kx_client_session_keys","_crypto_kx_keypair","_crypto_kx_publickeybytes","_crypto_kx_secretkeybytes","_crypto_kx_seed_keypair","_crypto_kx_seedbytes","_crypto_kx_server_session_keys","_crypto_kx_sessionkeybytes","_crypto_scalarmult","_crypto_scalarmult_base","_crypto_scalarmult_bytes","_crypto_scalarmult_scalarbytes","_crypto_secretbox_detached","_crypto_secretbox_easy","_crypto_secretbox_keybytes","_crypto_secretbox_keygen","_crypto_secretbox_macbytes","_crypto_secretbox_messagebytes_max","_crypto_secretbox_noncebytes","_crypto_secretbox_open_detached","_crypto_secretbox_open_easy","_crypto_secretstream_xchacha20poly1305_abytes","_crypto_secretstream_xchacha20poly1305_headerbytes","_crypto_secretstream_xchacha20poly1305_init_pull","_crypto_secretstream_xchacha20poly1305_init_push","_crypto_secretstream_xchacha20poly1305_keybytes","_crypto_secretstream_xchacha20poly1305_keygen","_crypto_secretstream_xchacha20poly1305_messagebytes_max","_crypto_secretstream_xchacha20poly1305_pull","_crypto_secretstream_xchacha20poly1305_push","_crypto_secretstream_xchacha20poly1305_rekey","_crypto_secretstream_xchacha20poly1305_statebytes","_crypto_secretstream_xchacha20poly1305_tag_final","_crypto_secretstream_xchacha20poly1305_tag_message","_crypto_secretstream_xchacha20poly1305_tag_push","_crypto_secretstream_xchacha20poly1305_tag_rekey","_crypto_shorthash","_crypto_shorthash_bytes","_crypto_shorthash_keybytes","_crypto_shorthash_keygen","_crypto_sign","_crypto_sign_bytes","_crypto_sign_detached","_crypto_sign_ed25519_pk_to_curve25519","_crypto_sign_ed25519_sk_to_curve25519","_crypto_sign_final_create","_crypto_sign_final_verify","_crypto_sign_init","_crypto_sign_keypair","_crypto_sign_messagebytes_max","_crypto_sign_open","_crypto_sign_publickeybytes","_crypto_sign_secretkeybytes","_crypto_sign_seed_keypair","_crypto_sign_seedbytes","_crypto_sign_statebytes","_crypto_sign_update","_crypto_sign_verify_detached","_randombytes","_randombytes_buf","_randombytes_buf_deterministic","_randombytes_close","_randombytes_random","_randombytes_seedbytes","_randombytes_stir","_randombytes_uniform","_sodium_base64_encoded_len","_sodium_base642bin","_sodium_bin2base64","_sodium_bin2hex","_sodium_hex2bin","_sodium_init","_sodium_library_minimal","_sodium_library_version_major","_sodium_library_version_minor","_sodium_pad","_sodium_unpad","_sodium_version_string"]'
-export EXPORTED_FUNCTIONS_SUMO='["_malloc","_free","_crypto_aead_aegis128l_abytes","_crypto_aead_aegis128l_decrypt","_crypto_aead_aegis128l_decrypt_detached","_crypto_aead_aegis128l_encrypt","_crypto_aead_aegis128l_encrypt_detached","_crypto_aead_aegis128l_keybytes","_crypto_aead_aegis128l_keygen","_crypto_aead_aegis128l_messagebytes_max","_crypto_aead_aegis128l_npubbytes","_crypto_aead_aegis128l_nsecbytes","_crypto_aead_aegis256_abytes","_crypto_aead_aegis256_decrypt","_crypto_aead_aegis256_decrypt_detached","_crypto_aead_aegis256_encrypt","_crypto_aead_aegis256_encrypt_detached","_crypto_aead_aegis256_keybytes","_crypto_aead_aegis256_keygen","_crypto_aead_aegis256_messagebytes_max","_crypto_aead_aegis256_npubbytes","_crypto_aead_aegis256_nsecbytes","_crypto_aead_aes256gcm_is_available","_crypto_aead_chacha20poly1305_abytes","_crypto_aead_chacha20poly1305_decrypt","_crypto_aead_chacha20poly1305_decrypt_detached","_crypto_aead_chacha20poly1305_encrypt","_crypto_aead_chacha20poly1305_encrypt_detached","_crypto_aead_chacha20poly1305_ietf_abytes","_crypto_aead_chacha20poly1305_ietf_decrypt","_crypto_aead_chacha20poly1305_ietf_decrypt_detached","_crypto_aead_chacha20poly1305_ietf_encrypt","_crypto_aead_chacha20poly1305_ietf_encrypt_detached","_crypto_aead_chacha20poly1305_ietf_keybytes","_crypto_aead_chacha20poly1305_ietf_keygen","_crypto_aead_chacha20poly1305_ietf_messagebytes_max","_crypto_aead_chacha20poly1305_ietf_npubbytes","_crypto_aead_chacha20poly1305_ietf_nsecbytes","_crypto_aead_chacha20poly1305_keybytes","_crypto_aead_chacha20poly1305_keygen","_crypto_aead_chacha20poly1305_messagebytes_max","_crypto_aead_chacha20poly1305_npubbytes","_crypto_aead_chacha20poly1305_nsecbytes","_crypto_aead_xchacha20poly1305_ietf_abytes","_crypto_aead_xchacha20poly1305_ietf_decrypt","_crypto_aead_xchacha20poly1305_ietf_decrypt_detached","_crypto_aead_xchacha20poly1305_ietf_encrypt","_crypto_aead_xchacha20poly1305_ietf_encrypt_detached","_crypto_aead_xchacha20poly1305_ietf_keybytes","_crypto_aead_xchacha20poly1305_ietf_keygen","_crypto_aead_xchacha20poly1305_ietf_messagebytes_max","_crypto_aead_xchacha20poly1305_ietf_npubbytes","_crypto_aead_xchacha20poly1305_ietf_nsecbytes","_crypto_auth","_crypto_auth_bytes","_crypto_auth_hmacsha256","_crypto_auth_hmacsha256_bytes","_crypto_auth_hmacsha256_final","_crypto_auth_hmacsha256_init","_crypto_auth_hmacsha256_keybytes","_crypto_auth_hmacsha256_keygen","_crypto_auth_hmacsha256_statebytes","_crypto_auth_hmacsha256_update","_crypto_auth_hmacsha256_verify","_crypto_auth_hmacsha512","_crypto_auth_hmacsha512_bytes","_crypto_auth_hmacsha512_final","_crypto_auth_hmacsha512_init","_crypto_auth_hmacsha512_keybytes","_crypto_auth_hmacsha512_keygen","_crypto_auth_hmacsha512_statebytes","_crypto_auth_hmacsha512_update","_crypto_auth_hmacsha512_verify","_crypto_auth_hmacsha512256","_crypto_auth_hmacsha512256_bytes","_crypto_auth_hmacsha512256_final","_crypto_auth_hmacsha512256_init","_crypto_auth_hmacsha512256_keybytes","_crypto_auth_hmacsha512256_keygen","_crypto_auth_hmacsha512256_statebytes","_crypto_auth_hmacsha512256_update","_crypto_auth_hmacsha512256_verify","_crypto_auth_keybytes","_crypto_auth_keygen","_crypto_auth_primitive","_crypto_auth_verify","_crypto_box","_crypto_box_afternm","_crypto_box_beforenm","_crypto_box_beforenmbytes","_crypto_box_boxzerobytes","_crypto_box_curve25519xchacha20poly1305_beforenm","_crypto_box_curve25519xchacha20poly1305_beforenmbytes","_crypto_box_curve25519xchacha20poly1305_detached","_crypto_box_curve25519xchacha20poly1305_detached_afternm","_crypto_box_curve25519xchacha20poly1305_easy","_crypto_box_curve25519xchacha20poly1305_easy_afternm","_crypto_box_curve25519xchacha20poly1305_keypair","_crypto_box_curve25519xchacha20poly1305_macbytes","_crypto_box_curve25519xchacha20poly1305_messagebytes_max","_crypto_box_curve25519xchacha20poly1305_noncebytes","_crypto_box_curve25519xchacha20poly1305_open_detached","_crypto_box_curve25519xchacha20poly1305_open_detached_afternm","_crypto_box_curve25519xchacha20poly1305_open_easy","_crypto_box_curve25519xchacha20poly1305_open_easy_afternm","_crypto_box_curve25519xchacha20poly1305_publickeybytes","_crypto_box_curve25519xchacha20poly1305_seal","_crypto_box_curve25519xchacha20poly1305_seal_open","_crypto_box_curve25519xchacha20poly1305_sealbytes","_crypto_box_curve25519xchacha20poly1305_secretkeybytes","_crypto_box_curve25519xchacha20poly1305_seed_keypair","_crypto_box_curve25519xchacha20poly1305_seedbytes","_crypto_box_curve25519xsalsa20poly1305","_crypto_box_curve25519xsalsa20poly1305_afternm","_crypto_box_curve25519xsalsa20poly1305_beforenm","_crypto_box_curve25519xsalsa20poly1305_beforenmbytes","_crypto_box_curve25519xsalsa20poly1305_boxzerobytes","_crypto_box_curve25519xsalsa20poly1305_keypair","_crypto_box_curve25519xsalsa20poly1305_macbytes","_crypto_box_curve25519xsalsa20poly1305_messagebytes_max","_crypto_box_curve25519xsalsa20poly1305_noncebytes","_crypto_box_curve25519xsalsa20poly1305_open","_crypto_box_curve25519xsalsa20poly1305_open_afternm","_crypto_box_curve25519xsalsa20poly1305_publickeybytes","_crypto_box_curve25519xsalsa20poly1305_secretkeybytes","_crypto_box_curve25519xsalsa20poly1305_seed_keypair","_crypto_box_curve25519xsalsa20poly1305_seedbytes","_crypto_box_curve25519xsalsa20poly1305_zerobytes","_crypto_box_detached","_crypto_box_detached_afternm","_crypto_box_easy","_crypto_box_easy_afternm","_crypto_box_keypair","_crypto_box_macbytes","_crypto_box_messagebytes_max","_crypto_box_noncebytes","_crypto_box_open","_crypto_box_open_afternm","_crypto_box_open_detached","_crypto_box_open_detached_afternm","_crypto_box_open_easy","_crypto_box_open_easy_afternm","_crypto_box_primitive","_crypto_box_publickeybytes","_crypto_box_seal","_crypto_box_seal_open","_crypto_box_sealbytes","_crypto_box_secretkeybytes","_crypto_box_seed_keypair","_crypto_box_seedbytes","_crypto_box_zerobytes","_crypto_core_ed25519_add","_crypto_core_ed25519_bytes","_crypto_core_ed25519_from_uniform","_crypto_core_ed25519_hashbytes","_crypto_core_ed25519_is_valid_point","_crypto_core_ed25519_nonreducedscalarbytes","_crypto_core_ed25519_random","_crypto_core_ed25519_scalar_add","_crypto_core_ed25519_scalar_complement","_crypto_core_ed25519_scalar_invert","_crypto_core_ed25519_scalar_mul","_crypto_core_ed25519_scalar_negate","_crypto_core_ed25519_scalar_random","_crypto_core_ed25519_scalar_reduce","_crypto_core_ed25519_scalar_sub","_crypto_core_ed25519_scalarbytes","_crypto_core_ed25519_sub","_crypto_core_ed25519_uniformbytes","_crypto_core_hchacha20","_crypto_core_hchacha20_constbytes","_crypto_core_hchacha20_inputbytes","_crypto_core_hchacha20_keybytes","_crypto_core_hchacha20_outputbytes","_crypto_core_hsalsa20","_crypto_core_hsalsa20_constbytes","_crypto_core_hsalsa20_inputbytes","_crypto_core_hsalsa20_keybytes","_crypto_core_hsalsa20_outputbytes","_crypto_core_ristretto255_add","_crypto_core_ristretto255_bytes","_crypto_core_ristretto255_from_hash","_crypto_core_ristretto255_hashbytes","_crypto_core_ristretto255_is_valid_point","_crypto_core_ristretto255_nonreducedscalarbytes","_crypto_core_ristretto255_random","_crypto_core_ristretto255_scalar_add","_crypto_core_ristretto255_scalar_complement","_crypto_core_ristretto255_scalar_invert","_crypto_core_ristretto255_scalar_mul","_crypto_core_ristretto255_scalar_negate","_crypto_core_ristretto255_scalar_random","_crypto_core_ristretto255_scalar_reduce","_crypto_core_ristretto255_scalar_sub","_crypto_core_ristretto255_scalarbytes","_crypto_core_ristretto255_sub","_crypto_core_salsa20","_crypto_core_salsa20_constbytes","_crypto_core_salsa20_inputbytes","_crypto_core_salsa20_keybytes","_crypto_core_salsa20_outputbytes","_crypto_core_salsa2012","_crypto_core_salsa2012_constbytes","_crypto_core_salsa2012_inputbytes","_crypto_core_salsa2012_keybytes","_crypto_core_salsa2012_outputbytes","_crypto_core_salsa208","_crypto_core_salsa208_constbytes","_crypto_core_salsa208_inputbytes","_crypto_core_salsa208_keybytes","_crypto_core_salsa208_outputbytes","_crypto_generichash","_crypto_generichash_blake2b","_crypto_generichash_blake2b_bytes","_crypto_generichash_blake2b_bytes_max","_crypto_generichash_blake2b_bytes_min","_crypto_generichash_blake2b_final","_crypto_generichash_blake2b_init","_crypto_generichash_blake2b_init_salt_personal","_crypto_generichash_blake2b_keybytes","_crypto_generichash_blake2b_keybytes_max","_crypto_generichash_blake2b_keybytes_min","_crypto_generichash_blake2b_keygen","_crypto_generichash_blake2b_personalbytes","_crypto_generichash_blake2b_salt_personal","_crypto_generichash_blake2b_saltbytes","_crypto_generichash_blake2b_statebytes","_crypto_generichash_blake2b_update","_crypto_generichash_bytes","_crypto_generichash_bytes_max","_crypto_generichash_bytes_min","_crypto_generichash_final","_crypto_generichash_init","_crypto_generichash_keybytes","_crypto_generichash_keybytes_max","_crypto_generichash_keybytes_min","_crypto_generichash_keygen","_crypto_generichash_primitive","_crypto_generichash_statebytes","_crypto_generichash_update","_crypto_hash","_crypto_hash_bytes","_crypto_hash_primitive","_crypto_hash_sha256","_crypto_hash_sha256_bytes","_crypto_hash_sha256_final","_crypto_hash_sha256_init","_crypto_hash_sha256_statebytes","_crypto_hash_sha256_update","_crypto_hash_sha512","_crypto_hash_sha512_bytes","_crypto_hash_sha512_final","_crypto_hash_sha512_init","_crypto_hash_sha512_statebytes","_crypto_hash_sha512_update","_crypto_kdf_blake2b_bytes_max","_crypto_kdf_blake2b_bytes_min","_crypto_kdf_blake2b_contextbytes","_crypto_kdf_blake2b_derive_from_key","_crypto_kdf_blake2b_keybytes","_crypto_kdf_bytes_max","_crypto_kdf_bytes_min","_crypto_kdf_contextbytes","_crypto_kdf_derive_from_key","_crypto_kdf_hkdf_sha256_bytes_max","_crypto_kdf_hkdf_sha256_bytes_min","_crypto_kdf_hkdf_sha256_expand","_crypto_kdf_hkdf_sha256_extract","_crypto_kdf_hkdf_sha256_extract_final","_crypto_kdf_hkdf_sha256_extract_init","_crypto_kdf_hkdf_sha256_extract_update","_crypto_kdf_hkdf_sha256_keybytes","_crypto_kdf_hkdf_sha256_keygen","_crypto_kdf_hkdf_sha256_statebytes","_crypto_kdf_hkdf_sha512_bytes_max","_crypto_kdf_hkdf_sha512_bytes_min","_crypto_kdf_hkdf_sha512_expand","_crypto_kdf_hkdf_sha512_extract","_crypto_kdf_hkdf_sha512_extract_final","_crypto_kdf_hkdf_sha512_extract_init","_crypto_kdf_hkdf_sha512_extract_update","_crypto_kdf_hkdf_sha512_keybytes","_crypto_kdf_hkdf_sha512_keygen","_crypto_kdf_hkdf_sha512_statebytes","_crypto_kdf_keybytes","_crypto_kdf_keygen","_crypto_kdf_primitive","_crypto_kx_client_session_keys","_crypto_kx_keypair","_crypto_kx_primitive","_crypto_kx_publickeybytes","_crypto_kx_secretkeybytes","_crypto_kx_seed_keypair","_crypto_kx_seedbytes","_crypto_kx_server_session_keys","_crypto_kx_sessionkeybytes","_crypto_onetimeauth","_crypto_onetimeauth_bytes","_crypto_onetimeauth_final","_crypto_onetimeauth_init","_crypto_onetimeauth_keybytes","_crypto_onetimeauth_keygen","_crypto_onetimeauth_poly1305","_crypto_onetimeauth_poly1305_bytes","_crypto_onetimeauth_poly1305_final","_crypto_onetimeauth_poly1305_init","_crypto_onetimeauth_poly1305_keybytes","_crypto_onetimeauth_poly1305_keygen","_crypto_onetimeauth_poly1305_statebytes","_crypto_onetimeauth_poly1305_update","_crypto_onetimeauth_poly1305_verify","_crypto_onetimeauth_primitive","_crypto_onetimeauth_statebytes","_crypto_onetimeauth_update","_crypto_onetimeauth_verify","_crypto_pwhash","_crypto_pwhash_alg_argon2i13","_crypto_pwhash_alg_argon2id13","_crypto_pwhash_alg_default","_crypto_pwhash_argon2i","_crypto_pwhash_argon2i_alg_argon2i13","_crypto_pwhash_argon2i_bytes_max","_crypto_pwhash_argon2i_bytes_min","_crypto_pwhash_argon2i_memlimit_interactive","_crypto_pwhash_argon2i_memlimit_max","_crypto_pwhash_argon2i_memlimit_min","_crypto_pwhash_argon2i_memlimit_moderate","_crypto_pwhash_argon2i_memlimit_sensitive","_crypto_pwhash_argon2i_opslimit_interactive","_crypto_pwhash_argon2i_opslimit_max","_crypto_pwhash_argon2i_opslimit_min","_crypto_pwhash_argon2i_opslimit_moderate","_crypto_pwhash_argon2i_opslimit_sensitive","_crypto_pwhash_argon2i_passwd_max","_crypto_pwhash_argon2i_passwd_min","_crypto_pwhash_argon2i_saltbytes","_crypto_pwhash_argon2i_str","_crypto_pwhash_argon2i_str_needs_rehash","_crypto_pwhash_argon2i_str_verify","_crypto_pwhash_argon2i_strbytes","_crypto_pwhash_argon2i_strprefix","_crypto_pwhash_argon2id","_crypto_pwhash_argon2id_alg_argon2id13","_crypto_pwhash_argon2id_bytes_max","_crypto_pwhash_argon2id_bytes_min","_crypto_pwhash_argon2id_memlimit_interactive","_crypto_pwhash_argon2id_memlimit_max","_crypto_pwhash_argon2id_memlimit_min","_crypto_pwhash_argon2id_memlimit_moderate","_crypto_pwhash_argon2id_memlimit_sensitive","_crypto_pwhash_argon2id_opslimit_interactive","_crypto_pwhash_argon2id_opslimit_max","_crypto_pwhash_argon2id_opslimit_min","_crypto_pwhash_argon2id_opslimit_moderate","_crypto_pwhash_argon2id_opslimit_sensitive","_crypto_pwhash_argon2id_passwd_max","_crypto_pwhash_argon2id_passwd_min","_crypto_pwhash_argon2id_saltbytes","_crypto_pwhash_argon2id_str","_crypto_pwhash_argon2id_str_needs_rehash","_crypto_pwhash_argon2id_str_verify","_crypto_pwhash_argon2id_strbytes","_crypto_pwhash_argon2id_strprefix","_crypto_pwhash_bytes_max","_crypto_pwhash_bytes_min","_crypto_pwhash_memlimit_interactive","_crypto_pwhash_memlimit_max","_crypto_pwhash_memlimit_min","_crypto_pwhash_memlimit_moderate","_crypto_pwhash_memlimit_sensitive","_crypto_pwhash_opslimit_interactive","_crypto_pwhash_opslimit_max","_crypto_pwhash_opslimit_min","_crypto_pwhash_opslimit_moderate","_crypto_pwhash_opslimit_sensitive","_crypto_pwhash_passwd_max","_crypto_pwhash_passwd_min","_crypto_pwhash_primitive","_crypto_pwhash_saltbytes","_crypto_pwhash_scryptsalsa208sha256","_crypto_pwhash_scryptsalsa208sha256_bytes_max","_crypto_pwhash_scryptsalsa208sha256_bytes_min","_crypto_pwhash_scryptsalsa208sha256_ll","_crypto_pwhash_scryptsalsa208sha256_memlimit_interactive","_crypto_pwhash_scryptsalsa208sha256_memlimit_max","_crypto_pwhash_scryptsalsa208sha256_memlimit_min","_crypto_pwhash_scryptsalsa208sha256_memlimit_sensitive","_crypto_pwhash_scryptsalsa208sha256_opslimit_interactive","_crypto_pwhash_scryptsalsa208sha256_opslimit_max","_crypto_pwhash_scryptsalsa208sha256_opslimit_min","_crypto_pwhash_scryptsalsa208sha256_opslimit_sensitive","_crypto_pwhash_scryptsalsa208sha256_passwd_max","_crypto_pwhash_scryptsalsa208sha256_passwd_min","_crypto_pwhash_scryptsalsa208sha256_saltbytes","_crypto_pwhash_scryptsalsa208sha256_str","_crypto_pwhash_scryptsalsa208sha256_str_needs_rehash","_crypto_pwhash_scryptsalsa208sha256_str_verify","_crypto_pwhash_scryptsalsa208sha256_strbytes","_crypto_pwhash_scryptsalsa208sha256_strprefix","_crypto_pwhash_str","_crypto_pwhash_str_alg","_crypto_pwhash_str_needs_rehash","_crypto_pwhash_str_verify","_crypto_pwhash_strbytes","_crypto_pwhash_strprefix","_crypto_scalarmult","_crypto_scalarmult_base","_crypto_scalarmult_bytes","_crypto_scalarmult_curve25519","_crypto_scalarmult_curve25519_base","_crypto_scalarmult_curve25519_bytes","_crypto_scalarmult_curve25519_scalarbytes","_crypto_scalarmult_ed25519","_crypto_scalarmult_ed25519_base","_crypto_scalarmult_ed25519_base_noclamp","_crypto_scalarmult_ed25519_bytes","_crypto_scalarmult_ed25519_noclamp","_crypto_scalarmult_ed25519_scalarbytes","_crypto_scalarmult_primitive","_crypto_scalarmult_ristretto255","_crypto_scalarmult_ristretto255_base","_crypto_scalarmult_ristretto255_bytes","_crypto_scalarmult_ristretto255_scalarbytes","_crypto_scalarmult_scalarbytes","_crypto_secretbox","_crypto_secretbox_boxzerobytes","_crypto_secretbox_detached","_crypto_secretbox_easy","_crypto_secretbox_keybytes","_crypto_secretbox_keygen","_crypto_secretbox_macbytes","_crypto_secretbox_messagebytes_max","_crypto_secretbox_noncebytes","_crypto_secretbox_open","_crypto_secretbox_open_detached","_crypto_secretbox_open_easy","_crypto_secretbox_primitive","_crypto_secretbox_xchacha20poly1305_detached","_crypto_secretbox_xchacha20poly1305_easy","_crypto_secretbox_xchacha20poly1305_keybytes","_crypto_secretbox_xchacha20poly1305_macbytes","_crypto_secretbox_xchacha20poly1305_messagebytes_max","_crypto_secretbox_xchacha20poly1305_noncebytes","_crypto_secretbox_xchacha20poly1305_open_detached","_crypto_secretbox_xchacha20poly1305_open_easy","_crypto_secretbox_xsalsa20poly1305","_crypto_secretbox_xsalsa20poly1305_boxzerobytes","_crypto_secretbox_xsalsa20poly1305_keybytes","_crypto_secretbox_xsalsa20poly1305_keygen","_crypto_secretbox_xsalsa20poly1305_macbytes","_crypto_secretbox_xsalsa20poly1305_messagebytes_max","_crypto_secretbox_xsalsa20poly1305_noncebytes","_crypto_secretbox_xsalsa20poly1305_open","_crypto_secretbox_xsalsa20poly1305_zerobytes","_crypto_secretbox_zerobytes","_crypto_secretstream_xchacha20poly1305_abytes","_crypto_secretstream_xchacha20poly1305_headerbytes","_crypto_secretstream_xchacha20poly1305_init_pull","_crypto_secretstream_xchacha20poly1305_init_push","_crypto_secretstream_xchacha20poly1305_keybytes","_crypto_secretstream_xchacha20poly1305_keygen","_crypto_secretstream_xchacha20poly1305_messagebytes_max","_crypto_secretstream_xchacha20poly1305_pull","_crypto_secretstream_xchacha20poly1305_push","_crypto_secretstream_xchacha20poly1305_rekey","_crypto_secretstream_xchacha20poly1305_statebytes","_crypto_secretstream_xchacha20poly1305_tag_final","_crypto_secretstream_xchacha20poly1305_tag_message","_crypto_secretstream_xchacha20poly1305_tag_push","_crypto_secretstream_xchacha20poly1305_tag_rekey","_crypto_shorthash","_crypto_shorthash_bytes","_crypto_shorthash_keybytes","_crypto_shorthash_keygen","_crypto_shorthash_primitive","_crypto_shorthash_siphash24","_crypto_shorthash_siphash24_bytes","_crypto_shorthash_siphash24_keybytes","_crypto_shorthash_siphashx24","_crypto_shorthash_siphashx24_bytes","_crypto_shorthash_siphashx24_keybytes","_crypto_sign","_crypto_sign_bytes","_crypto_sign_detached","_crypto_sign_ed25519","_crypto_sign_ed25519_bytes","_crypto_sign_ed25519_detached","_crypto_sign_ed25519_keypair","_crypto_sign_ed25519_messagebytes_max","_crypto_sign_ed25519_open","_crypto_sign_ed25519_pk_to_curve25519","_crypto_sign_ed25519_publickeybytes","_crypto_sign_ed25519_secretkeybytes","_crypto_sign_ed25519_seed_keypair","_crypto_sign_ed25519_seedbytes","_crypto_sign_ed25519_sk_to_curve25519","_crypto_sign_ed25519_sk_to_pk","_crypto_sign_ed25519_sk_to_seed","_crypto_sign_ed25519_verify_detached","_crypto_sign_ed25519ph_final_create","_crypto_sign_ed25519ph_final_verify","_crypto_sign_ed25519ph_init","_crypto_sign_ed25519ph_statebytes","_crypto_sign_ed25519ph_update","_crypto_sign_final_create","_crypto_sign_final_verify","_crypto_sign_init","_crypto_sign_keypair","_crypto_sign_messagebytes_max","_crypto_sign_open","_crypto_sign_primitive","_crypto_sign_publickeybytes","_crypto_sign_secretkeybytes","_crypto_sign_seed_keypair","_crypto_sign_seedbytes","_crypto_sign_statebytes","_crypto_sign_update","_crypto_sign_verify_detached","_crypto_stream","_crypto_stream_chacha20","_crypto_stream_chacha20_ietf","_crypto_stream_chacha20_ietf_keybytes","_crypto_stream_chacha20_ietf_keygen","_crypto_stream_chacha20_ietf_messagebytes_max","_crypto_stream_chacha20_ietf_noncebytes","_crypto_stream_chacha20_ietf_xor","_crypto_stream_chacha20_ietf_xor_ic","_crypto_stream_chacha20_keybytes","_crypto_stream_chacha20_keygen","_crypto_stream_chacha20_messagebytes_max","_crypto_stream_chacha20_noncebytes","_crypto_stream_chacha20_xor","_crypto_stream_chacha20_xor_ic","_crypto_stream_keybytes","_crypto_stream_keygen","_crypto_stream_messagebytes_max","_crypto_stream_noncebytes","_crypto_stream_primitive","_crypto_stream_salsa20","_crypto_stream_salsa20_keybytes","_crypto_stream_salsa20_keygen","_crypto_stream_salsa20_messagebytes_max","_crypto_stream_salsa20_noncebytes","_crypto_stream_salsa20_xor","_crypto_stream_salsa20_xor_ic","_crypto_stream_salsa2012","_crypto_stream_salsa2012_keybytes","_crypto_stream_salsa2012_keygen","_crypto_stream_salsa2012_messagebytes_max","_crypto_stream_salsa2012_noncebytes","_crypto_stream_salsa2012_xor","_crypto_stream_salsa208","_crypto_stream_salsa208_keybytes","_crypto_stream_salsa208_keygen","_crypto_stream_salsa208_messagebytes_max","_crypto_stream_salsa208_noncebytes","_crypto_stream_salsa208_xor","_crypto_stream_xchacha20","_crypto_stream_xchacha20_keybytes","_crypto_stream_xchacha20_keygen","_crypto_stream_xchacha20_messagebytes_max","_crypto_stream_xchacha20_noncebytes","_crypto_stream_xchacha20_xor","_crypto_stream_xchacha20_xor_ic","_crypto_stream_xor","_crypto_stream_xsalsa20","_crypto_stream_xsalsa20_keybytes","_crypto_stream_xsalsa20_keygen","_crypto_stream_xsalsa20_messagebytes_max","_crypto_stream_xsalsa20_noncebytes","_crypto_stream_xsalsa20_xor","_crypto_stream_xsalsa20_xor_ic","_crypto_verify_16","_crypto_verify_16_bytes","_crypto_verify_32","_crypto_verify_32_bytes","_crypto_verify_64","_crypto_verify_64_bytes","_randombytes","_randombytes_buf","_randombytes_buf_deterministic","_randombytes_close","_randombytes_implementation_name","_randombytes_random","_randombytes_seedbytes","_randombytes_stir","_randombytes_uniform","_sodium_base64_encoded_len","_sodium_base642bin","_sodium_bin2base64","_sodium_bin2hex","_sodium_hex2bin","_sodium_init","_sodium_library_minimal","_sodium_library_version_major","_sodium_library_version_minor","_sodium_pad","_sodium_unpad","_sodium_version_string"]'
+export EXPORTED_FUNCTIONS_STANDARD='["_malloc","_free","_crypto_aead_aegis128l_abytes","_crypto_aead_aegis128l_decrypt","_crypto_aead_aegis128l_decrypt_detached","_crypto_aead_aegis128l_encrypt","_crypto_aead_aegis128l_encrypt_detached","_crypto_aead_aegis128l_keybytes","_crypto_aead_aegis128l_keygen","_crypto_aead_aegis128l_messagebytes_max","_crypto_aead_aegis128l_npubbytes","_crypto_aead_aegis128l_nsecbytes","_crypto_aead_aegis256_abytes","_crypto_aead_aegis256_decrypt","_crypto_aead_aegis256_decrypt_detached","_crypto_aead_aegis256_encrypt","_crypto_aead_aegis256_encrypt_detached","_crypto_aead_aegis256_keybytes","_crypto_aead_aegis256_keygen","_crypto_aead_aegis256_messagebytes_max","_crypto_aead_aegis256_npubbytes","_crypto_aead_aegis256_nsecbytes","_crypto_aead_aes256gcm_is_available","_crypto_aead_chacha20poly1305_abytes","_crypto_aead_chacha20poly1305_decrypt","_crypto_aead_chacha20poly1305_decrypt_detached","_crypto_aead_chacha20poly1305_encrypt","_crypto_aead_chacha20poly1305_encrypt_detached","_crypto_aead_chacha20poly1305_ietf_abytes","_crypto_aead_chacha20poly1305_ietf_decrypt","_crypto_aead_chacha20poly1305_ietf_decrypt_detached","_crypto_aead_chacha20poly1305_ietf_encrypt","_crypto_aead_chacha20poly1305_ietf_encrypt_detached","_crypto_aead_chacha20poly1305_ietf_keybytes","_crypto_aead_chacha20poly1305_ietf_keygen","_crypto_aead_chacha20poly1305_ietf_messagebytes_max","_crypto_aead_chacha20poly1305_ietf_npubbytes","_crypto_aead_chacha20poly1305_ietf_nsecbytes","_crypto_aead_chacha20poly1305_keybytes","_crypto_aead_chacha20poly1305_keygen","_crypto_aead_chacha20poly1305_messagebytes_max","_crypto_aead_chacha20poly1305_npubbytes","_crypto_aead_chacha20poly1305_nsecbytes","_crypto_aead_xchacha20poly1305_ietf_abytes","_crypto_aead_xchacha20poly1305_ietf_decrypt","_crypto_aead_xchacha20poly1305_ietf_decrypt_detached","_crypto_aead_xchacha20poly1305_ietf_encrypt","_crypto_aead_xchacha20poly1305_ietf_encrypt_detached","_crypto_aead_xchacha20poly1305_ietf_keybytes","_crypto_aead_xchacha20poly1305_ietf_keygen","_crypto_aead_xchacha20poly1305_ietf_messagebytes_max","_crypto_aead_xchacha20poly1305_ietf_npubbytes","_crypto_aead_xchacha20poly1305_ietf_nsecbytes","_crypto_auth","_crypto_auth_bytes","_crypto_auth_keybytes","_crypto_auth_keygen","_crypto_auth_verify","_crypto_box_beforenm","_crypto_box_beforenmbytes","_crypto_box_detached","_crypto_box_detached_afternm","_crypto_box_easy","_crypto_box_easy_afternm","_crypto_box_keypair","_crypto_box_macbytes","_crypto_box_messagebytes_max","_crypto_box_noncebytes","_crypto_box_open_detached","_crypto_box_open_detached_afternm","_crypto_box_open_easy","_crypto_box_open_easy_afternm","_crypto_box_publickeybytes","_crypto_box_seal","_crypto_box_seal_open","_crypto_box_sealbytes","_crypto_box_secretkeybytes","_crypto_box_seed_keypair","_crypto_box_seedbytes","_crypto_generichash","_crypto_generichash_bytes","_crypto_generichash_bytes_max","_crypto_generichash_bytes_min","_crypto_generichash_final","_crypto_generichash_init","_crypto_generichash_keybytes","_crypto_generichash_keybytes_max","_crypto_generichash_keybytes_min","_crypto_generichash_keygen","_crypto_generichash_statebytes","_crypto_generichash_update","_crypto_hash","_crypto_hash_bytes","_crypto_ipcrypt_bytes","_crypto_ipcrypt_decrypt","_crypto_ipcrypt_encrypt","_crypto_ipcrypt_keybytes","_crypto_ipcrypt_keygen","_crypto_ipcrypt_nd_decrypt","_crypto_ipcrypt_nd_encrypt","_crypto_ipcrypt_nd_inputbytes","_crypto_ipcrypt_nd_keybytes","_crypto_ipcrypt_nd_outputbytes","_crypto_ipcrypt_nd_tweakbytes","_crypto_ipcrypt_ndx_decrypt","_crypto_ipcrypt_ndx_encrypt","_crypto_ipcrypt_ndx_inputbytes","_crypto_ipcrypt_ndx_keybytes","_crypto_ipcrypt_ndx_keygen","_crypto_ipcrypt_ndx_outputbytes","_crypto_ipcrypt_ndx_tweakbytes","_crypto_ipcrypt_pfx_bytes","_crypto_ipcrypt_pfx_decrypt","_crypto_ipcrypt_pfx_encrypt","_crypto_ipcrypt_pfx_keybytes","_crypto_ipcrypt_pfx_keygen","_crypto_kdf_bytes_max","_crypto_kdf_bytes_min","_crypto_kdf_contextbytes","_crypto_kdf_derive_from_key","_crypto_kdf_hkdf_sha256_bytes_max","_crypto_kdf_hkdf_sha256_bytes_min","_crypto_kdf_hkdf_sha256_expand","_crypto_kdf_hkdf_sha256_extract","_crypto_kdf_hkdf_sha256_extract_final","_crypto_kdf_hkdf_sha256_extract_init","_crypto_kdf_hkdf_sha256_extract_update","_crypto_kdf_hkdf_sha256_keybytes","_crypto_kdf_hkdf_sha256_keygen","_crypto_kdf_hkdf_sha256_statebytes","_crypto_kdf_hkdf_sha512_bytes_max","_crypto_kdf_hkdf_sha512_bytes_min","_crypto_kdf_hkdf_sha512_expand","_crypto_kdf_hkdf_sha512_extract","_crypto_kdf_hkdf_sha512_extract_final","_crypto_kdf_hkdf_sha512_extract_init","_crypto_kdf_hkdf_sha512_extract_update","_crypto_kdf_hkdf_sha512_keybytes","_crypto_kdf_hkdf_sha512_keygen","_crypto_kdf_hkdf_sha512_statebytes","_crypto_kdf_keybytes","_crypto_kdf_keygen","_crypto_kx_client_session_keys","_crypto_kx_keypair","_crypto_kx_publickeybytes","_crypto_kx_secretkeybytes","_crypto_kx_seed_keypair","_crypto_kx_seedbytes","_crypto_kx_server_session_keys","_crypto_kx_sessionkeybytes","_crypto_scalarmult","_crypto_scalarmult_base","_crypto_scalarmult_bytes","_crypto_scalarmult_scalarbytes","_crypto_secretbox_detached","_crypto_secretbox_easy","_crypto_secretbox_keybytes","_crypto_secretbox_keygen","_crypto_secretbox_macbytes","_crypto_secretbox_messagebytes_max","_crypto_secretbox_noncebytes","_crypto_secretbox_open_detached","_crypto_secretbox_open_easy","_crypto_secretstream_xchacha20poly1305_abytes","_crypto_secretstream_xchacha20poly1305_headerbytes","_crypto_secretstream_xchacha20poly1305_init_pull","_crypto_secretstream_xchacha20poly1305_init_push","_crypto_secretstream_xchacha20poly1305_keybytes","_crypto_secretstream_xchacha20poly1305_keygen","_crypto_secretstream_xchacha20poly1305_messagebytes_max","_crypto_secretstream_xchacha20poly1305_pull","_crypto_secretstream_xchacha20poly1305_push","_crypto_secretstream_xchacha20poly1305_rekey","_crypto_secretstream_xchacha20poly1305_statebytes","_crypto_secretstream_xchacha20poly1305_tag_final","_crypto_secretstream_xchacha20poly1305_tag_message","_crypto_secretstream_xchacha20poly1305_tag_push","_crypto_secretstream_xchacha20poly1305_tag_rekey","_crypto_shorthash","_crypto_shorthash_bytes","_crypto_shorthash_keybytes","_crypto_shorthash_keygen","_crypto_sign","_crypto_sign_bytes","_crypto_sign_detached","_crypto_sign_ed25519_pk_to_curve25519","_crypto_sign_ed25519_sk_to_curve25519","_crypto_sign_final_create","_crypto_sign_final_verify","_crypto_sign_init","_crypto_sign_keypair","_crypto_sign_messagebytes_max","_crypto_sign_open","_crypto_sign_publickeybytes","_crypto_sign_secretkeybytes","_crypto_sign_seed_keypair","_crypto_sign_seedbytes","_crypto_sign_statebytes","_crypto_sign_update","_crypto_sign_verify_detached","_crypto_xof_shake128","_crypto_xof_shake128_blockbytes","_crypto_xof_shake128_domain_standard","_crypto_xof_shake128_init","_crypto_xof_shake128_init_with_domain","_crypto_xof_shake128_squeeze","_crypto_xof_shake128_statebytes","_crypto_xof_shake128_update","_crypto_xof_shake256","_crypto_xof_shake256_blockbytes","_crypto_xof_shake256_domain_standard","_crypto_xof_shake256_init","_crypto_xof_shake256_init_with_domain","_crypto_xof_shake256_squeeze","_crypto_xof_shake256_statebytes","_crypto_xof_shake256_update","_crypto_xof_turboshake128","_crypto_xof_turboshake128_blockbytes","_crypto_xof_turboshake128_domain_standard","_crypto_xof_turboshake128_init","_crypto_xof_turboshake128_init_with_domain","_crypto_xof_turboshake128_squeeze","_crypto_xof_turboshake128_statebytes","_crypto_xof_turboshake128_update","_crypto_xof_turboshake256","_crypto_xof_turboshake256_blockbytes","_crypto_xof_turboshake256_domain_standard","_crypto_xof_turboshake256_init","_crypto_xof_turboshake256_init_with_domain","_crypto_xof_turboshake256_squeeze","_crypto_xof_turboshake256_statebytes","_crypto_xof_turboshake256_update","_randombytes","_randombytes_buf","_randombytes_buf_deterministic","_randombytes_close","_randombytes_random","_randombytes_seedbytes","_randombytes_stir","_randombytes_uniform","_sodium_base64_encoded_len","_sodium_base642bin","_sodium_bin2base64","_sodium_bin2hex","_sodium_hex2bin","_sodium_init","_sodium_library_minimal","_sodium_library_version_major","_sodium_library_version_minor","_sodium_pad","_sodium_unpad","_sodium_version_string"]'
+export EXPORTED_FUNCTIONS_SUMO='["_malloc","_free","_crypto_aead_aegis128l_abytes","_crypto_aead_aegis128l_decrypt","_crypto_aead_aegis128l_decrypt_detached","_crypto_aead_aegis128l_encrypt","_crypto_aead_aegis128l_encrypt_detached","_crypto_aead_aegis128l_keybytes","_crypto_aead_aegis128l_keygen","_crypto_aead_aegis128l_messagebytes_max","_crypto_aead_aegis128l_npubbytes","_crypto_aead_aegis128l_nsecbytes","_crypto_aead_aegis256_abytes","_crypto_aead_aegis256_decrypt","_crypto_aead_aegis256_decrypt_detached","_crypto_aead_aegis256_encrypt","_crypto_aead_aegis256_encrypt_detached","_crypto_aead_aegis256_keybytes","_crypto_aead_aegis256_keygen","_crypto_aead_aegis256_messagebytes_max","_crypto_aead_aegis256_npubbytes","_crypto_aead_aegis256_nsecbytes","_crypto_aead_aes256gcm_is_available","_crypto_aead_chacha20poly1305_abytes","_crypto_aead_chacha20poly1305_decrypt","_crypto_aead_chacha20poly1305_decrypt_detached","_crypto_aead_chacha20poly1305_encrypt","_crypto_aead_chacha20poly1305_encrypt_detached","_crypto_aead_chacha20poly1305_ietf_abytes","_crypto_aead_chacha20poly1305_ietf_decrypt","_crypto_aead_chacha20poly1305_ietf_decrypt_detached","_crypto_aead_chacha20poly1305_ietf_encrypt","_crypto_aead_chacha20poly1305_ietf_encrypt_detached","_crypto_aead_chacha20poly1305_ietf_keybytes","_crypto_aead_chacha20poly1305_ietf_keygen","_crypto_aead_chacha20poly1305_ietf_messagebytes_max","_crypto_aead_chacha20poly1305_ietf_npubbytes","_crypto_aead_chacha20poly1305_ietf_nsecbytes","_crypto_aead_chacha20poly1305_keybytes","_crypto_aead_chacha20poly1305_keygen","_crypto_aead_chacha20poly1305_messagebytes_max","_crypto_aead_chacha20poly1305_npubbytes","_crypto_aead_chacha20poly1305_nsecbytes","_crypto_aead_xchacha20poly1305_ietf_abytes","_crypto_aead_xchacha20poly1305_ietf_decrypt","_crypto_aead_xchacha20poly1305_ietf_decrypt_detached","_crypto_aead_xchacha20poly1305_ietf_encrypt","_crypto_aead_xchacha20poly1305_ietf_encrypt_detached","_crypto_aead_xchacha20poly1305_ietf_keybytes","_crypto_aead_xchacha20poly1305_ietf_keygen","_crypto_aead_xchacha20poly1305_ietf_messagebytes_max","_crypto_aead_xchacha20poly1305_ietf_npubbytes","_crypto_aead_xchacha20poly1305_ietf_nsecbytes","_crypto_auth","_crypto_auth_bytes","_crypto_auth_hmacsha256","_crypto_auth_hmacsha256_bytes","_crypto_auth_hmacsha256_final","_crypto_auth_hmacsha256_init","_crypto_auth_hmacsha256_keybytes","_crypto_auth_hmacsha256_keygen","_crypto_auth_hmacsha256_statebytes","_crypto_auth_hmacsha256_update","_crypto_auth_hmacsha256_verify","_crypto_auth_hmacsha512","_crypto_auth_hmacsha512_bytes","_crypto_auth_hmacsha512_final","_crypto_auth_hmacsha512_init","_crypto_auth_hmacsha512_keybytes","_crypto_auth_hmacsha512_keygen","_crypto_auth_hmacsha512_statebytes","_crypto_auth_hmacsha512_update","_crypto_auth_hmacsha512_verify","_crypto_auth_hmacsha512256","_crypto_auth_hmacsha512256_bytes","_crypto_auth_hmacsha512256_final","_crypto_auth_hmacsha512256_init","_crypto_auth_hmacsha512256_keybytes","_crypto_auth_hmacsha512256_keygen","_crypto_auth_hmacsha512256_statebytes","_crypto_auth_hmacsha512256_update","_crypto_auth_hmacsha512256_verify","_crypto_auth_keybytes","_crypto_auth_keygen","_crypto_auth_primitive","_crypto_auth_verify","_crypto_box","_crypto_box_afternm","_crypto_box_beforenm","_crypto_box_beforenmbytes","_crypto_box_boxzerobytes","_crypto_box_curve25519xchacha20poly1305_beforenm","_crypto_box_curve25519xchacha20poly1305_beforenmbytes","_crypto_box_curve25519xchacha20poly1305_detached","_crypto_box_curve25519xchacha20poly1305_detached_afternm","_crypto_box_curve25519xchacha20poly1305_easy","_crypto_box_curve25519xchacha20poly1305_easy_afternm","_crypto_box_curve25519xchacha20poly1305_keypair","_crypto_box_curve25519xchacha20poly1305_macbytes","_crypto_box_curve25519xchacha20poly1305_messagebytes_max","_crypto_box_curve25519xchacha20poly1305_noncebytes","_crypto_box_curve25519xchacha20poly1305_open_detached","_crypto_box_curve25519xchacha20poly1305_open_detached_afternm","_crypto_box_curve25519xchacha20poly1305_open_easy","_crypto_box_curve25519xchacha20poly1305_open_easy_afternm","_crypto_box_curve25519xchacha20poly1305_publickeybytes","_crypto_box_curve25519xchacha20poly1305_seal","_crypto_box_curve25519xchacha20poly1305_seal_open","_crypto_box_curve25519xchacha20poly1305_sealbytes","_crypto_box_curve25519xchacha20poly1305_secretkeybytes","_crypto_box_curve25519xchacha20poly1305_seed_keypair","_crypto_box_curve25519xchacha20poly1305_seedbytes","_crypto_box_curve25519xsalsa20poly1305","_crypto_box_curve25519xsalsa20poly1305_afternm","_crypto_box_curve25519xsalsa20poly1305_beforenm","_crypto_box_curve25519xsalsa20poly1305_beforenmbytes","_crypto_box_curve25519xsalsa20poly1305_boxzerobytes","_crypto_box_curve25519xsalsa20poly1305_keypair","_crypto_box_curve25519xsalsa20poly1305_macbytes","_crypto_box_curve25519xsalsa20poly1305_messagebytes_max","_crypto_box_curve25519xsalsa20poly1305_noncebytes","_crypto_box_curve25519xsalsa20poly1305_open","_crypto_box_curve25519xsalsa20poly1305_open_afternm","_crypto_box_curve25519xsalsa20poly1305_publickeybytes","_crypto_box_curve25519xsalsa20poly1305_secretkeybytes","_crypto_box_curve25519xsalsa20poly1305_seed_keypair","_crypto_box_curve25519xsalsa20poly1305_seedbytes","_crypto_box_curve25519xsalsa20poly1305_zerobytes","_crypto_box_detached","_crypto_box_detached_afternm","_crypto_box_easy","_crypto_box_easy_afternm","_crypto_box_keypair","_crypto_box_macbytes","_crypto_box_messagebytes_max","_crypto_box_noncebytes","_crypto_box_open","_crypto_box_open_afternm","_crypto_box_open_detached","_crypto_box_open_detached_afternm","_crypto_box_open_easy","_crypto_box_open_easy_afternm","_crypto_box_primitive","_crypto_box_publickeybytes","_crypto_box_seal","_crypto_box_seal_open","_crypto_box_sealbytes","_crypto_box_secretkeybytes","_crypto_box_seed_keypair","_crypto_box_seedbytes","_crypto_box_zerobytes","_crypto_core_ed25519_add","_crypto_core_ed25519_bytes","_crypto_core_ed25519_from_hash","_crypto_core_ed25519_from_uniform","_crypto_core_ed25519_hashbytes","_crypto_core_ed25519_is_valid_point","_crypto_core_ed25519_nonreducedscalarbytes","_crypto_core_ed25519_random","_crypto_core_ed25519_scalar_add","_crypto_core_ed25519_scalar_complement","_crypto_core_ed25519_scalar_invert","_crypto_core_ed25519_scalar_mul","_crypto_core_ed25519_scalar_negate","_crypto_core_ed25519_scalar_random","_crypto_core_ed25519_scalar_reduce","_crypto_core_ed25519_scalar_sub","_crypto_core_ed25519_scalarbytes","_crypto_core_ed25519_sub","_crypto_core_ed25519_uniformbytes","_crypto_core_hchacha20","_crypto_core_hchacha20_constbytes","_crypto_core_hchacha20_inputbytes","_crypto_core_hchacha20_keybytes","_crypto_core_hchacha20_outputbytes","_crypto_core_hsalsa20","_crypto_core_hsalsa20_constbytes","_crypto_core_hsalsa20_inputbytes","_crypto_core_hsalsa20_keybytes","_crypto_core_hsalsa20_outputbytes","_crypto_core_keccak1600_extract_bytes","_crypto_core_keccak1600_init","_crypto_core_keccak1600_permute_12","_crypto_core_keccak1600_permute_24","_crypto_core_keccak1600_statebytes","_crypto_core_keccak1600_xor_bytes","_crypto_core_ristretto255_add","_crypto_core_ristretto255_bytes","_crypto_core_ristretto255_from_hash","_crypto_core_ristretto255_hashbytes","_crypto_core_ristretto255_is_valid_point","_crypto_core_ristretto255_nonreducedscalarbytes","_crypto_core_ristretto255_random","_crypto_core_ristretto255_scalar_add","_crypto_core_ristretto255_scalar_complement","_crypto_core_ristretto255_scalar_invert","_crypto_core_ristretto255_scalar_mul","_crypto_core_ristretto255_scalar_negate","_crypto_core_ristretto255_scalar_random","_crypto_core_ristretto255_scalar_reduce","_crypto_core_ristretto255_scalar_sub","_crypto_core_ristretto255_scalarbytes","_crypto_core_ristretto255_sub","_crypto_core_salsa20","_crypto_core_salsa20_constbytes","_crypto_core_salsa20_inputbytes","_crypto_core_salsa20_keybytes","_crypto_core_salsa20_outputbytes","_crypto_core_salsa2012","_crypto_core_salsa2012_constbytes","_crypto_core_salsa2012_inputbytes","_crypto_core_salsa2012_keybytes","_crypto_core_salsa2012_outputbytes","_crypto_core_salsa208","_crypto_core_salsa208_constbytes","_crypto_core_salsa208_inputbytes","_crypto_core_salsa208_keybytes","_crypto_core_salsa208_outputbytes","_crypto_generichash","_crypto_generichash_blake2b","_crypto_generichash_blake2b_bytes","_crypto_generichash_blake2b_bytes_max","_crypto_generichash_blake2b_bytes_min","_crypto_generichash_blake2b_final","_crypto_generichash_blake2b_init","_crypto_generichash_blake2b_init_salt_personal","_crypto_generichash_blake2b_keybytes","_crypto_generichash_blake2b_keybytes_max","_crypto_generichash_blake2b_keybytes_min","_crypto_generichash_blake2b_keygen","_crypto_generichash_blake2b_personalbytes","_crypto_generichash_blake2b_salt_personal","_crypto_generichash_blake2b_saltbytes","_crypto_generichash_blake2b_statebytes","_crypto_generichash_blake2b_update","_crypto_generichash_bytes","_crypto_generichash_bytes_max","_crypto_generichash_bytes_min","_crypto_generichash_final","_crypto_generichash_init","_crypto_generichash_keybytes","_crypto_generichash_keybytes_max","_crypto_generichash_keybytes_min","_crypto_generichash_keygen","_crypto_generichash_primitive","_crypto_generichash_statebytes","_crypto_generichash_update","_crypto_hash","_crypto_hash_bytes","_crypto_hash_primitive","_crypto_hash_sha256","_crypto_hash_sha256_bytes","_crypto_hash_sha256_final","_crypto_hash_sha256_init","_crypto_hash_sha256_statebytes","_crypto_hash_sha256_update","_crypto_hash_sha512","_crypto_hash_sha512_bytes","_crypto_hash_sha512_final","_crypto_hash_sha512_init","_crypto_hash_sha512_statebytes","_crypto_hash_sha512_update","_crypto_ipcrypt_bytes","_crypto_ipcrypt_decrypt","_crypto_ipcrypt_encrypt","_crypto_ipcrypt_keybytes","_crypto_ipcrypt_keygen","_crypto_ipcrypt_nd_decrypt","_crypto_ipcrypt_nd_encrypt","_crypto_ipcrypt_nd_inputbytes","_crypto_ipcrypt_nd_keybytes","_crypto_ipcrypt_nd_outputbytes","_crypto_ipcrypt_nd_tweakbytes","_crypto_ipcrypt_ndx_decrypt","_crypto_ipcrypt_ndx_encrypt","_crypto_ipcrypt_ndx_inputbytes","_crypto_ipcrypt_ndx_keybytes","_crypto_ipcrypt_ndx_keygen","_crypto_ipcrypt_ndx_outputbytes","_crypto_ipcrypt_ndx_tweakbytes","_crypto_ipcrypt_pfx_bytes","_crypto_ipcrypt_pfx_decrypt","_crypto_ipcrypt_pfx_encrypt","_crypto_ipcrypt_pfx_keybytes","_crypto_ipcrypt_pfx_keygen","_crypto_kdf_blake2b_bytes_max","_crypto_kdf_blake2b_bytes_min","_crypto_kdf_blake2b_contextbytes","_crypto_kdf_blake2b_derive_from_key","_crypto_kdf_blake2b_keybytes","_crypto_kdf_bytes_max","_crypto_kdf_bytes_min","_crypto_kdf_contextbytes","_crypto_kdf_derive_from_key","_crypto_kdf_hkdf_sha256_bytes_max","_crypto_kdf_hkdf_sha256_bytes_min","_crypto_kdf_hkdf_sha256_expand","_crypto_kdf_hkdf_sha256_extract","_crypto_kdf_hkdf_sha256_extract_final","_crypto_kdf_hkdf_sha256_extract_init","_crypto_kdf_hkdf_sha256_extract_update","_crypto_kdf_hkdf_sha256_keybytes","_crypto_kdf_hkdf_sha256_keygen","_crypto_kdf_hkdf_sha256_statebytes","_crypto_kdf_hkdf_sha512_bytes_max","_crypto_kdf_hkdf_sha512_bytes_min","_crypto_kdf_hkdf_sha512_expand","_crypto_kdf_hkdf_sha512_extract","_crypto_kdf_hkdf_sha512_extract_final","_crypto_kdf_hkdf_sha512_extract_init","_crypto_kdf_hkdf_sha512_extract_update","_crypto_kdf_hkdf_sha512_keybytes","_crypto_kdf_hkdf_sha512_keygen","_crypto_kdf_hkdf_sha512_statebytes","_crypto_kdf_keybytes","_crypto_kdf_keygen","_crypto_kdf_primitive","_crypto_kx_client_session_keys","_crypto_kx_keypair","_crypto_kx_primitive","_crypto_kx_publickeybytes","_crypto_kx_secretkeybytes","_crypto_kx_seed_keypair","_crypto_kx_seedbytes","_crypto_kx_server_session_keys","_crypto_kx_sessionkeybytes","_crypto_onetimeauth","_crypto_onetimeauth_bytes","_crypto_onetimeauth_final","_crypto_onetimeauth_init","_crypto_onetimeauth_keybytes","_crypto_onetimeauth_keygen","_crypto_onetimeauth_poly1305","_crypto_onetimeauth_poly1305_bytes","_crypto_onetimeauth_poly1305_final","_crypto_onetimeauth_poly1305_init","_crypto_onetimeauth_poly1305_keybytes","_crypto_onetimeauth_poly1305_keygen","_crypto_onetimeauth_poly1305_statebytes","_crypto_onetimeauth_poly1305_update","_crypto_onetimeauth_poly1305_verify","_crypto_onetimeauth_primitive","_crypto_onetimeauth_statebytes","_crypto_onetimeauth_update","_crypto_onetimeauth_verify","_crypto_pwhash","_crypto_pwhash_alg_argon2i13","_crypto_pwhash_alg_argon2id13","_crypto_pwhash_alg_default","_crypto_pwhash_argon2i","_crypto_pwhash_argon2i_alg_argon2i13","_crypto_pwhash_argon2i_bytes_max","_crypto_pwhash_argon2i_bytes_min","_crypto_pwhash_argon2i_memlimit_interactive","_crypto_pwhash_argon2i_memlimit_max","_crypto_pwhash_argon2i_memlimit_min","_crypto_pwhash_argon2i_memlimit_moderate","_crypto_pwhash_argon2i_memlimit_sensitive","_crypto_pwhash_argon2i_opslimit_interactive","_crypto_pwhash_argon2i_opslimit_max","_crypto_pwhash_argon2i_opslimit_min","_crypto_pwhash_argon2i_opslimit_moderate","_crypto_pwhash_argon2i_opslimit_sensitive","_crypto_pwhash_argon2i_passwd_max","_crypto_pwhash_argon2i_passwd_min","_crypto_pwhash_argon2i_saltbytes","_crypto_pwhash_argon2i_str","_crypto_pwhash_argon2i_str_needs_rehash","_crypto_pwhash_argon2i_str_verify","_crypto_pwhash_argon2i_strbytes","_crypto_pwhash_argon2i_strprefix","_crypto_pwhash_argon2id","_crypto_pwhash_argon2id_alg_argon2id13","_crypto_pwhash_argon2id_bytes_max","_crypto_pwhash_argon2id_bytes_min","_crypto_pwhash_argon2id_memlimit_interactive","_crypto_pwhash_argon2id_memlimit_max","_crypto_pwhash_argon2id_memlimit_min","_crypto_pwhash_argon2id_memlimit_moderate","_crypto_pwhash_argon2id_memlimit_sensitive","_crypto_pwhash_argon2id_opslimit_interactive","_crypto_pwhash_argon2id_opslimit_max","_crypto_pwhash_argon2id_opslimit_min","_crypto_pwhash_argon2id_opslimit_moderate","_crypto_pwhash_argon2id_opslimit_sensitive","_crypto_pwhash_argon2id_passwd_max","_crypto_pwhash_argon2id_passwd_min","_crypto_pwhash_argon2id_saltbytes","_crypto_pwhash_argon2id_str","_crypto_pwhash_argon2id_str_needs_rehash","_crypto_pwhash_argon2id_str_verify","_crypto_pwhash_argon2id_strbytes","_crypto_pwhash_argon2id_strprefix","_crypto_pwhash_bytes_max","_crypto_pwhash_bytes_min","_crypto_pwhash_memlimit_interactive","_crypto_pwhash_memlimit_max","_crypto_pwhash_memlimit_min","_crypto_pwhash_memlimit_moderate","_crypto_pwhash_memlimit_sensitive","_crypto_pwhash_opslimit_interactive","_crypto_pwhash_opslimit_max","_crypto_pwhash_opslimit_min","_crypto_pwhash_opslimit_moderate","_crypto_pwhash_opslimit_sensitive","_crypto_pwhash_passwd_max","_crypto_pwhash_passwd_min","_crypto_pwhash_primitive","_crypto_pwhash_saltbytes","_crypto_pwhash_scryptsalsa208sha256","_crypto_pwhash_scryptsalsa208sha256_bytes_max","_crypto_pwhash_scryptsalsa208sha256_bytes_min","_crypto_pwhash_scryptsalsa208sha256_ll","_crypto_pwhash_scryptsalsa208sha256_memlimit_interactive","_crypto_pwhash_scryptsalsa208sha256_memlimit_max","_crypto_pwhash_scryptsalsa208sha256_memlimit_min","_crypto_pwhash_scryptsalsa208sha256_memlimit_sensitive","_crypto_pwhash_scryptsalsa208sha256_opslimit_interactive","_crypto_pwhash_scryptsalsa208sha256_opslimit_max","_crypto_pwhash_scryptsalsa208sha256_opslimit_min","_crypto_pwhash_scryptsalsa208sha256_opslimit_sensitive","_crypto_pwhash_scryptsalsa208sha256_passwd_max","_crypto_pwhash_scryptsalsa208sha256_passwd_min","_crypto_pwhash_scryptsalsa208sha256_saltbytes","_crypto_pwhash_scryptsalsa208sha256_str","_crypto_pwhash_scryptsalsa208sha256_str_needs_rehash","_crypto_pwhash_scryptsalsa208sha256_str_verify","_crypto_pwhash_scryptsalsa208sha256_strbytes","_crypto_pwhash_scryptsalsa208sha256_strprefix","_crypto_pwhash_str","_crypto_pwhash_str_alg","_crypto_pwhash_str_needs_rehash","_crypto_pwhash_str_verify","_crypto_pwhash_strbytes","_crypto_pwhash_strprefix","_crypto_scalarmult","_crypto_scalarmult_base","_crypto_scalarmult_bytes","_crypto_scalarmult_curve25519","_crypto_scalarmult_curve25519_base","_crypto_scalarmult_curve25519_bytes","_crypto_scalarmult_curve25519_scalarbytes","_crypto_scalarmult_ed25519","_crypto_scalarmult_ed25519_base","_crypto_scalarmult_ed25519_base_noclamp","_crypto_scalarmult_ed25519_bytes","_crypto_scalarmult_ed25519_noclamp","_crypto_scalarmult_ed25519_scalarbytes","_crypto_scalarmult_primitive","_crypto_scalarmult_ristretto255","_crypto_scalarmult_ristretto255_base","_crypto_scalarmult_ristretto255_bytes","_crypto_scalarmult_ristretto255_scalarbytes","_crypto_scalarmult_scalarbytes","_crypto_secretbox","_crypto_secretbox_boxzerobytes","_crypto_secretbox_detached","_crypto_secretbox_easy","_crypto_secretbox_keybytes","_crypto_secretbox_keygen","_crypto_secretbox_macbytes","_crypto_secretbox_messagebytes_max","_crypto_secretbox_noncebytes","_crypto_secretbox_open","_crypto_secretbox_open_detached","_crypto_secretbox_open_easy","_crypto_secretbox_primitive","_crypto_secretbox_xchacha20poly1305_detached","_crypto_secretbox_xchacha20poly1305_easy","_crypto_secretbox_xchacha20poly1305_keybytes","_crypto_secretbox_xchacha20poly1305_macbytes","_crypto_secretbox_xchacha20poly1305_messagebytes_max","_crypto_secretbox_xchacha20poly1305_noncebytes","_crypto_secretbox_xchacha20poly1305_open_detached","_crypto_secretbox_xchacha20poly1305_open_easy","_crypto_secretbox_xsalsa20poly1305","_crypto_secretbox_xsalsa20poly1305_boxzerobytes","_crypto_secretbox_xsalsa20poly1305_keybytes","_crypto_secretbox_xsalsa20poly1305_keygen","_crypto_secretbox_xsalsa20poly1305_macbytes","_crypto_secretbox_xsalsa20poly1305_messagebytes_max","_crypto_secretbox_xsalsa20poly1305_noncebytes","_crypto_secretbox_xsalsa20poly1305_open","_crypto_secretbox_xsalsa20poly1305_zerobytes","_crypto_secretbox_zerobytes","_crypto_secretstream_xchacha20poly1305_abytes","_crypto_secretstream_xchacha20poly1305_headerbytes","_crypto_secretstream_xchacha20poly1305_init_pull","_crypto_secretstream_xchacha20poly1305_init_push","_crypto_secretstream_xchacha20poly1305_keybytes","_crypto_secretstream_xchacha20poly1305_keygen","_crypto_secretstream_xchacha20poly1305_messagebytes_max","_crypto_secretstream_xchacha20poly1305_pull","_crypto_secretstream_xchacha20poly1305_push","_crypto_secretstream_xchacha20poly1305_rekey","_crypto_secretstream_xchacha20poly1305_statebytes","_crypto_secretstream_xchacha20poly1305_tag_final","_crypto_secretstream_xchacha20poly1305_tag_message","_crypto_secretstream_xchacha20poly1305_tag_push","_crypto_secretstream_xchacha20poly1305_tag_rekey","_crypto_shorthash","_crypto_shorthash_bytes","_crypto_shorthash_keybytes","_crypto_shorthash_keygen","_crypto_shorthash_primitive","_crypto_shorthash_siphash24","_crypto_shorthash_siphash24_bytes","_crypto_shorthash_siphash24_keybytes","_crypto_shorthash_siphashx24","_crypto_shorthash_siphashx24_bytes","_crypto_shorthash_siphashx24_keybytes","_crypto_sign","_crypto_sign_bytes","_crypto_sign_detached","_crypto_sign_ed25519","_crypto_sign_ed25519_bytes","_crypto_sign_ed25519_detached","_crypto_sign_ed25519_keypair","_crypto_sign_ed25519_messagebytes_max","_crypto_sign_ed25519_open","_crypto_sign_ed25519_pk_to_curve25519","_crypto_sign_ed25519_publickeybytes","_crypto_sign_ed25519_secretkeybytes","_crypto_sign_ed25519_seed_keypair","_crypto_sign_ed25519_seedbytes","_crypto_sign_ed25519_sk_to_curve25519","_crypto_sign_ed25519_sk_to_pk","_crypto_sign_ed25519_sk_to_seed","_crypto_sign_ed25519_verify_detached","_crypto_sign_ed25519ph_final_create","_crypto_sign_ed25519ph_final_verify","_crypto_sign_ed25519ph_init","_crypto_sign_ed25519ph_statebytes","_crypto_sign_ed25519ph_update","_crypto_sign_edwards25519sha512batch","_crypto_sign_edwards25519sha512batch_keypair","_crypto_sign_edwards25519sha512batch_open","_crypto_sign_final_create","_crypto_sign_final_verify","_crypto_sign_init","_crypto_sign_keypair","_crypto_sign_messagebytes_max","_crypto_sign_open","_crypto_sign_primitive","_crypto_sign_publickeybytes","_crypto_sign_secretkeybytes","_crypto_sign_seed_keypair","_crypto_sign_seedbytes","_crypto_sign_statebytes","_crypto_sign_update","_crypto_sign_verify_detached","_crypto_stream","_crypto_stream_chacha20","_crypto_stream_chacha20_ietf","_crypto_stream_chacha20_ietf_keybytes","_crypto_stream_chacha20_ietf_keygen","_crypto_stream_chacha20_ietf_messagebytes_max","_crypto_stream_chacha20_ietf_noncebytes","_crypto_stream_chacha20_ietf_xor","_crypto_stream_chacha20_ietf_xor_ic","_crypto_stream_chacha20_keybytes","_crypto_stream_chacha20_keygen","_crypto_stream_chacha20_messagebytes_max","_crypto_stream_chacha20_noncebytes","_crypto_stream_chacha20_xor","_crypto_stream_chacha20_xor_ic","_crypto_stream_keybytes","_crypto_stream_keygen","_crypto_stream_messagebytes_max","_crypto_stream_noncebytes","_crypto_stream_primitive","_crypto_stream_salsa20","_crypto_stream_salsa20_keybytes","_crypto_stream_salsa20_keygen","_crypto_stream_salsa20_messagebytes_max","_crypto_stream_salsa20_noncebytes","_crypto_stream_salsa20_xor","_crypto_stream_salsa20_xor_ic","_crypto_stream_salsa2012","_crypto_stream_salsa2012_keybytes","_crypto_stream_salsa2012_keygen","_crypto_stream_salsa2012_messagebytes_max","_crypto_stream_salsa2012_noncebytes","_crypto_stream_salsa2012_xor","_crypto_stream_salsa208","_crypto_stream_salsa208_keybytes","_crypto_stream_salsa208_keygen","_crypto_stream_salsa208_messagebytes_max","_crypto_stream_salsa208_noncebytes","_crypto_stream_salsa208_xor","_crypto_stream_xchacha20","_crypto_stream_xchacha20_keybytes","_crypto_stream_xchacha20_keygen","_crypto_stream_xchacha20_messagebytes_max","_crypto_stream_xchacha20_noncebytes","_crypto_stream_xchacha20_xor","_crypto_stream_xchacha20_xor_ic","_crypto_stream_xor","_crypto_stream_xsalsa20","_crypto_stream_xsalsa20_keybytes","_crypto_stream_xsalsa20_keygen","_crypto_stream_xsalsa20_messagebytes_max","_crypto_stream_xsalsa20_noncebytes","_crypto_stream_xsalsa20_xor","_crypto_stream_xsalsa20_xor_ic","_crypto_verify_16","_crypto_verify_16_bytes","_crypto_verify_32","_crypto_verify_32_bytes","_crypto_verify_64","_crypto_verify_64_bytes","_crypto_xof_shake128","_crypto_xof_shake128_blockbytes","_crypto_xof_shake128_domain_standard","_crypto_xof_shake128_init","_crypto_xof_shake128_init_with_domain","_crypto_xof_shake128_squeeze","_crypto_xof_shake128_statebytes","_crypto_xof_shake128_update","_crypto_xof_shake256","_crypto_xof_shake256_blockbytes","_crypto_xof_shake256_domain_standard","_crypto_xof_shake256_init","_crypto_xof_shake256_init_with_domain","_crypto_xof_shake256_squeeze","_crypto_xof_shake256_statebytes","_crypto_xof_shake256_update","_crypto_xof_turboshake128","_crypto_xof_turboshake128_blockbytes","_crypto_xof_turboshake128_domain_standard","_crypto_xof_turboshake128_init","_crypto_xof_turboshake128_init_with_domain","_crypto_xof_turboshake128_squeeze","_crypto_xof_turboshake128_statebytes","_crypto_xof_turboshake128_update","_crypto_xof_turboshake256","_crypto_xof_turboshake256_blockbytes","_crypto_xof_turboshake256_domain_standard","_crypto_xof_turboshake256_init","_crypto_xof_turboshake256_init_with_domain","_crypto_xof_turboshake256_squeeze","_crypto_xof_turboshake256_statebytes","_crypto_xof_turboshake256_update","_randombytes","_randombytes_buf","_randombytes_buf_deterministic","_randombytes_close","_randombytes_implementation_name","_randombytes_random","_randombytes_seedbytes","_randombytes_stir","_randombytes_uniform","_sodium_base64_encoded_len","_sodium_base642bin","_sodium_bin2base64","_sodium_bin2hex","_sodium_hex2bin","_sodium_init","_sodium_library_minimal","_sodium_library_version_major","_sodium_library_version_minor","_sodium_pad","_sodium_unpad","_sodium_version_string"]'
export EXPORTED_RUNTIME_METHODS='["UTF8ToString","getValue","setValue","HEAPU8"]'
export JS_RESERVED_MEMORY_STANDARD=16MB
export JS_RESERVED_MEMORY_SUMO=48MB
diff --git a/src/libsodium/Makefile.am b/src/libsodium/Makefile.am
index 78c607f8..b022dae0 100644
--- a/src/libsodium/Makefile.am
+++ b/src/libsodium/Makefile.am
@@ -46,6 +46,10 @@ libsodium_la_SOURCES = \
crypto_hash/sha256/cp/hash_sha256_cp.c \
crypto_hash/sha512/hash_sha512.c \
crypto_hash/sha512/cp/hash_sha512_cp.c \
+ crypto_ipcrypt/crypto_ipcrypt.c \
+ crypto_ipcrypt/ipcrypt_soft.c \
+ crypto_ipcrypt/ipcrypt_soft.h \
+ crypto_ipcrypt/implementations.h \
crypto_kdf/blake2b/kdf_blake2b.c \
crypto_kdf/crypto_kdf.c \
crypto_kdf/hkdf/kdf_hkdf_sha256.c \
@@ -251,7 +255,9 @@ libarmcrypto_la_SOURCES = \
crypto_aead/aegis128l/aegis128l_armcrypto.h \
crypto_aead/aegis256/aegis256_armcrypto.c \
crypto_aead/aegis256/aegis256_armcrypto.h \
- crypto_aead/aes256gcm/armcrypto/aead_aes256gcm_armcrypto.c
+ crypto_aead/aes256gcm/armcrypto/aead_aes256gcm_armcrypto.c \
+ crypto_ipcrypt/ipcrypt_armcrypto.c \
+ crypto_ipcrypt/ipcrypt_armcrypto.h
libaesni_la_LDFLAGS = $(libsodium_la_LDFLAGS)
libaesni_la_CPPFLAGS = $(libsodium_la_CPPFLAGS) \
@@ -261,7 +267,9 @@ libaesni_la_SOURCES = \
crypto_aead/aegis128l/aegis128l_aesni.h \
crypto_aead/aegis256/aegis256_aesni.c \
crypto_aead/aegis256/aegis256_aesni.h \
- crypto_aead/aes256gcm/aesni/aead_aes256gcm_aesni.c
+ crypto_aead/aes256gcm/aesni/aead_aes256gcm_aesni.c \
+ crypto_ipcrypt/ipcrypt_aesni.c \
+ crypto_ipcrypt/ipcrypt_aesni.h
libsse2_la_LDFLAGS = $(libsodium_la_LDFLAGS)
libsse2_la_CPPFLAGS = $(libsodium_la_CPPFLAGS) \
diff --git a/src/libsodium/Makefile.in b/src/libsodium/Makefile.in
index 232b70ff..c4193960 100644
--- a/src/libsodium/Makefile.in
+++ b/src/libsodium/Makefile.in
@@ -223,7 +223,8 @@ am__dirstamp = $(am__leading_dot)dirstamp
am_libaesni_la_OBJECTS = \
crypto_aead/aegis128l/libaesni_la-aegis128l_aesni.lo \
crypto_aead/aegis256/libaesni_la-aegis256_aesni.lo \
- crypto_aead/aes256gcm/aesni/libaesni_la-aead_aes256gcm_aesni.lo
+ crypto_aead/aes256gcm/aesni/libaesni_la-aead_aes256gcm_aesni.lo \
+ crypto_ipcrypt/libaesni_la-ipcrypt_aesni.lo
libaesni_la_OBJECTS = $(am_libaesni_la_OBJECTS)
AM_V_lt = $(am__v_lt_@AM_V@)
am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@)
@@ -236,7 +237,8 @@ libarmcrypto_la_LIBADD =
am_libarmcrypto_la_OBJECTS = \
crypto_aead/aegis128l/libarmcrypto_la-aegis128l_armcrypto.lo \
crypto_aead/aegis256/libarmcrypto_la-aegis256_armcrypto.lo \
- crypto_aead/aes256gcm/armcrypto/libarmcrypto_la-aead_aes256gcm_armcrypto.lo
+ crypto_aead/aes256gcm/armcrypto/libarmcrypto_la-aead_aes256gcm_armcrypto.lo \
+ crypto_ipcrypt/libarmcrypto_la-ipcrypt_armcrypto.lo
libarmcrypto_la_OBJECTS = $(am_libarmcrypto_la_OBJECTS)
libarmcrypto_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \
$(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \
@@ -310,6 +312,8 @@ am__libsodium_la_SOURCES_DIST = \
crypto_hash/sha256/cp/hash_sha256_cp.c \
crypto_hash/sha512/hash_sha512.c \
crypto_hash/sha512/cp/hash_sha512_cp.c \
+ crypto_ipcrypt/crypto_ipcrypt.c crypto_ipcrypt/ipcrypt_soft.c \
+ crypto_ipcrypt/ipcrypt_soft.h crypto_ipcrypt/implementations.h \
crypto_kdf/blake2b/kdf_blake2b.c crypto_kdf/crypto_kdf.c \
crypto_kdf/hkdf/kdf_hkdf_sha256.c \
crypto_kdf/hkdf/kdf_hkdf_sha512.c crypto_kx/crypto_kx.c \
@@ -491,6 +495,8 @@ am_libsodium_la_OBJECTS = \
crypto_hash/sha256/cp/libsodium_la-hash_sha256_cp.lo \
crypto_hash/sha512/libsodium_la-hash_sha512.lo \
crypto_hash/sha512/cp/libsodium_la-hash_sha512_cp.lo \
+ crypto_ipcrypt/libsodium_la-crypto_ipcrypt.lo \
+ crypto_ipcrypt/libsodium_la-ipcrypt_soft.lo \
crypto_kdf/blake2b/libsodium_la-kdf_blake2b.lo \
crypto_kdf/libsodium_la-crypto_kdf.lo \
crypto_kdf/hkdf/libsodium_la-kdf_hkdf_sha256.lo \
@@ -640,6 +646,10 @@ am__depfiles_remade = crypto_aead/aegis128l/$(DEPDIR)/libaesni_la-aegis128l_aesn
crypto_hash/sha256/cp/$(DEPDIR)/libsodium_la-hash_sha256_cp.Plo \
crypto_hash/sha512/$(DEPDIR)/libsodium_la-hash_sha512.Plo \
crypto_hash/sha512/cp/$(DEPDIR)/libsodium_la-hash_sha512_cp.Plo \
+ crypto_ipcrypt/$(DEPDIR)/libaesni_la-ipcrypt_aesni.Plo \
+ crypto_ipcrypt/$(DEPDIR)/libarmcrypto_la-ipcrypt_armcrypto.Plo \
+ crypto_ipcrypt/$(DEPDIR)/libsodium_la-crypto_ipcrypt.Plo \
+ crypto_ipcrypt/$(DEPDIR)/libsodium_la-ipcrypt_soft.Plo \
crypto_kdf/$(DEPDIR)/libsodium_la-crypto_kdf.Plo \
crypto_kdf/blake2b/$(DEPDIR)/libsodium_la-kdf_blake2b.Plo \
crypto_kdf/hkdf/$(DEPDIR)/libsodium_la-kdf_hkdf_sha256.Plo \
@@ -1049,6 +1059,8 @@ libsodium_la_SOURCES = crypto_aead/aegis128l/aead_aegis128l.c \
crypto_hash/sha256/cp/hash_sha256_cp.c \
crypto_hash/sha512/hash_sha512.c \
crypto_hash/sha512/cp/hash_sha512_cp.c \
+ crypto_ipcrypt/crypto_ipcrypt.c crypto_ipcrypt/ipcrypt_soft.c \
+ crypto_ipcrypt/ipcrypt_soft.h crypto_ipcrypt/implementations.h \
crypto_kdf/blake2b/kdf_blake2b.c crypto_kdf/crypto_kdf.c \
crypto_kdf/hkdf/kdf_hkdf_sha256.c \
crypto_kdf/hkdf/kdf_hkdf_sha512.c crypto_kx/crypto_kx.c \
@@ -1164,7 +1176,9 @@ libarmcrypto_la_SOURCES = \
crypto_aead/aegis128l/aegis128l_armcrypto.h \
crypto_aead/aegis256/aegis256_armcrypto.c \
crypto_aead/aegis256/aegis256_armcrypto.h \
- crypto_aead/aes256gcm/armcrypto/aead_aes256gcm_armcrypto.c
+ crypto_aead/aes256gcm/armcrypto/aead_aes256gcm_armcrypto.c \
+ crypto_ipcrypt/ipcrypt_armcrypto.c \
+ crypto_ipcrypt/ipcrypt_armcrypto.h
libaesni_la_LDFLAGS = $(libsodium_la_LDFLAGS)
libaesni_la_CPPFLAGS = $(libsodium_la_CPPFLAGS) \
@@ -1175,7 +1189,9 @@ libaesni_la_SOURCES = \
crypto_aead/aegis128l/aegis128l_aesni.h \
crypto_aead/aegis256/aegis256_aesni.c \
crypto_aead/aegis256/aegis256_aesni.h \
- crypto_aead/aes256gcm/aesni/aead_aes256gcm_aesni.c
+ crypto_aead/aes256gcm/aesni/aead_aes256gcm_aesni.c \
+ crypto_ipcrypt/ipcrypt_aesni.c \
+ crypto_ipcrypt/ipcrypt_aesni.h
libsse2_la_LDFLAGS = $(libsodium_la_LDFLAGS)
libsse2_la_CPPFLAGS = $(libsodium_la_CPPFLAGS) \
@@ -1336,6 +1352,15 @@ crypto_aead/aes256gcm/aesni/$(DEPDIR)/$(am__dirstamp):
crypto_aead/aes256gcm/aesni/libaesni_la-aead_aes256gcm_aesni.lo: \
crypto_aead/aes256gcm/aesni/$(am__dirstamp) \
crypto_aead/aes256gcm/aesni/$(DEPDIR)/$(am__dirstamp)
+crypto_ipcrypt/$(am__dirstamp):
+ @$(MKDIR_P) crypto_ipcrypt
+ @: >>crypto_ipcrypt/$(am__dirstamp)
+crypto_ipcrypt/$(DEPDIR)/$(am__dirstamp):
+ @$(MKDIR_P) crypto_ipcrypt/$(DEPDIR)
+ @: >>crypto_ipcrypt/$(DEPDIR)/$(am__dirstamp)
+crypto_ipcrypt/libaesni_la-ipcrypt_aesni.lo: \
+ crypto_ipcrypt/$(am__dirstamp) \
+ crypto_ipcrypt/$(DEPDIR)/$(am__dirstamp)
libaesni.la: $(libaesni_la_OBJECTS) $(libaesni_la_DEPENDENCIES) $(EXTRA_libaesni_la_DEPENDENCIES)
$(AM_V_CCLD)$(libaesni_la_LINK) $(libaesni_la_OBJECTS) $(libaesni_la_LIBADD) $(LIBS)
@@ -1354,6 +1379,9 @@ crypto_aead/aes256gcm/armcrypto/$(DEPDIR)/$(am__dirstamp):
crypto_aead/aes256gcm/armcrypto/libarmcrypto_la-aead_aes256gcm_armcrypto.lo: \
crypto_aead/aes256gcm/armcrypto/$(am__dirstamp) \
crypto_aead/aes256gcm/armcrypto/$(DEPDIR)/$(am__dirstamp)
+crypto_ipcrypt/libarmcrypto_la-ipcrypt_armcrypto.lo: \
+ crypto_ipcrypt/$(am__dirstamp) \
+ crypto_ipcrypt/$(DEPDIR)/$(am__dirstamp)
libarmcrypto.la: $(libarmcrypto_la_OBJECTS) $(libarmcrypto_la_DEPENDENCIES) $(EXTRA_libarmcrypto_la_DEPENDENCIES)
$(AM_V_CCLD)$(libarmcrypto_la_LINK) $(libarmcrypto_la_OBJECTS) $(libarmcrypto_la_LIBADD) $(LIBS)
@@ -1654,6 +1682,12 @@ crypto_hash/sha512/cp/$(DEPDIR)/$(am__dirstamp):
crypto_hash/sha512/cp/libsodium_la-hash_sha512_cp.lo: \
crypto_hash/sha512/cp/$(am__dirstamp) \
crypto_hash/sha512/cp/$(DEPDIR)/$(am__dirstamp)
+crypto_ipcrypt/libsodium_la-crypto_ipcrypt.lo: \
+ crypto_ipcrypt/$(am__dirstamp) \
+ crypto_ipcrypt/$(DEPDIR)/$(am__dirstamp)
+crypto_ipcrypt/libsodium_la-ipcrypt_soft.lo: \
+ crypto_ipcrypt/$(am__dirstamp) \
+ crypto_ipcrypt/$(DEPDIR)/$(am__dirstamp)
crypto_kdf/blake2b/$(am__dirstamp):
@$(MKDIR_P) crypto_kdf/blake2b
@: >>crypto_kdf/blake2b/$(am__dirstamp)
@@ -2303,6 +2337,8 @@ mostlyclean-compile:
-rm -f crypto_hash/sha512/*.lo
-rm -f crypto_hash/sha512/cp/*.$(OBJEXT)
-rm -f crypto_hash/sha512/cp/*.lo
+ -rm -f crypto_ipcrypt/*.$(OBJEXT)
+ -rm -f crypto_ipcrypt/*.lo
-rm -f crypto_kdf/*.$(OBJEXT)
-rm -f crypto_kdf/*.lo
-rm -f crypto_kdf/blake2b/*.$(OBJEXT)
@@ -2465,6 +2501,10 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@crypto_hash/sha256/cp/$(DEPDIR)/libsodium_la-hash_sha256_cp.Plo@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@crypto_hash/sha512/$(DEPDIR)/libsodium_la-hash_sha512.Plo@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@crypto_hash/sha512/cp/$(DEPDIR)/libsodium_la-hash_sha512_cp.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@crypto_ipcrypt/$(DEPDIR)/libaesni_la-ipcrypt_aesni.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@crypto_ipcrypt/$(DEPDIR)/libarmcrypto_la-ipcrypt_armcrypto.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@crypto_ipcrypt/$(DEPDIR)/libsodium_la-crypto_ipcrypt.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@crypto_ipcrypt/$(DEPDIR)/libsodium_la-ipcrypt_soft.Plo@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@crypto_kdf/$(DEPDIR)/libsodium_la-crypto_kdf.Plo@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@crypto_kdf/blake2b/$(DEPDIR)/libsodium_la-kdf_blake2b.Plo@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@crypto_kdf/hkdf/$(DEPDIR)/libsodium_la-kdf_hkdf_sha256.Plo@am__quote@ # am--include-marker
@@ -2640,6 +2680,13 @@ crypto_aead/aes256gcm/aesni/libaesni_la-aead_aes256gcm_aesni.lo: crypto_aead/aes
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libaesni_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o crypto_aead/aes256gcm/aesni/libaesni_la-aead_aes256gcm_aesni.lo `test -f 'crypto_aead/aes256gcm/aesni/aead_aes256gcm_aesni.c' || echo '$(srcdir)/'`crypto_aead/aes256gcm/aesni/aead_aes256gcm_aesni.c
+crypto_ipcrypt/libaesni_la-ipcrypt_aesni.lo: crypto_ipcrypt/ipcrypt_aesni.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libaesni_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT crypto_ipcrypt/libaesni_la-ipcrypt_aesni.lo -MD -MP -MF crypto_ipcrypt/$(DEPDIR)/libaesni_la-ipcrypt_aesni.Tpo -c -o crypto_ipcrypt/libaesni_la-ipcrypt_aesni.lo `test -f 'crypto_ipcrypt/ipcrypt_aesni.c' || echo '$(srcdir)/'`crypto_ipcrypt/ipcrypt_aesni.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) crypto_ipcrypt/$(DEPDIR)/libaesni_la-ipcrypt_aesni.Tpo crypto_ipcrypt/$(DEPDIR)/libaesni_la-ipcrypt_aesni.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='crypto_ipcrypt/ipcrypt_aesni.c' object='crypto_ipcrypt/libaesni_la-ipcrypt_aesni.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libaesni_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o crypto_ipcrypt/libaesni_la-ipcrypt_aesni.lo `test -f 'crypto_ipcrypt/ipcrypt_aesni.c' || echo '$(srcdir)/'`crypto_ipcrypt/ipcrypt_aesni.c
+
crypto_aead/aegis128l/libarmcrypto_la-aegis128l_armcrypto.lo: crypto_aead/aegis128l/aegis128l_armcrypto.c
@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarmcrypto_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT crypto_aead/aegis128l/libarmcrypto_la-aegis128l_armcrypto.lo -MD -MP -MF crypto_aead/aegis128l/$(DEPDIR)/libarmcrypto_la-aegis128l_armcrypto.Tpo -c -o crypto_aead/aegis128l/libarmcrypto_la-aegis128l_armcrypto.lo `test -f 'crypto_aead/aegis128l/aegis128l_armcrypto.c' || echo '$(srcdir)/'`crypto_aead/aegis128l/aegis128l_armcrypto.c
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) crypto_aead/aegis128l/$(DEPDIR)/libarmcrypto_la-aegis128l_armcrypto.Tpo crypto_aead/aegis128l/$(DEPDIR)/libarmcrypto_la-aegis128l_armcrypto.Plo
@@ -2661,6 +2708,13 @@ crypto_aead/aes256gcm/armcrypto/libarmcrypto_la-aead_aes256gcm_armcrypto.lo: cry
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarmcrypto_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o crypto_aead/aes256gcm/armcrypto/libarmcrypto_la-aead_aes256gcm_armcrypto.lo `test -f 'crypto_aead/aes256gcm/armcrypto/aead_aes256gcm_armcrypto.c' || echo '$(srcdir)/'`crypto_aead/aes256gcm/armcrypto/aead_aes256gcm_armcrypto.c
+crypto_ipcrypt/libarmcrypto_la-ipcrypt_armcrypto.lo: crypto_ipcrypt/ipcrypt_armcrypto.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarmcrypto_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT crypto_ipcrypt/libarmcrypto_la-ipcrypt_armcrypto.lo -MD -MP -MF crypto_ipcrypt/$(DEPDIR)/libarmcrypto_la-ipcrypt_armcrypto.Tpo -c -o crypto_ipcrypt/libarmcrypto_la-ipcrypt_armcrypto.lo `test -f 'crypto_ipcrypt/ipcrypt_armcrypto.c' || echo '$(srcdir)/'`crypto_ipcrypt/ipcrypt_armcrypto.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) crypto_ipcrypt/$(DEPDIR)/libarmcrypto_la-ipcrypt_armcrypto.Tpo crypto_ipcrypt/$(DEPDIR)/libarmcrypto_la-ipcrypt_armcrypto.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='crypto_ipcrypt/ipcrypt_armcrypto.c' object='crypto_ipcrypt/libarmcrypto_la-ipcrypt_armcrypto.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libarmcrypto_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o crypto_ipcrypt/libarmcrypto_la-ipcrypt_armcrypto.lo `test -f 'crypto_ipcrypt/ipcrypt_armcrypto.c' || echo '$(srcdir)/'`crypto_ipcrypt/ipcrypt_armcrypto.c
+
crypto_generichash/blake2b/ref/libavx2_la-blake2b-compress-avx2.lo: crypto_generichash/blake2b/ref/blake2b-compress-avx2.c
@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libavx2_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT crypto_generichash/blake2b/ref/libavx2_la-blake2b-compress-avx2.lo -MD -MP -MF crypto_generichash/blake2b/ref/$(DEPDIR)/libavx2_la-blake2b-compress-avx2.Tpo -c -o crypto_generichash/blake2b/ref/libavx2_la-blake2b-compress-avx2.lo `test -f 'crypto_generichash/blake2b/ref/blake2b-compress-avx2.c' || echo '$(srcdir)/'`crypto_generichash/blake2b/ref/blake2b-compress-avx2.c
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) crypto_generichash/blake2b/ref/$(DEPDIR)/libavx2_la-blake2b-compress-avx2.Tpo crypto_generichash/blake2b/ref/$(DEPDIR)/libavx2_la-blake2b-compress-avx2.Plo
@@ -2934,6 +2988,20 @@ crypto_hash/sha512/cp/libsodium_la-hash_sha512_cp.lo: crypto_hash/sha512/cp/hash
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libsodium_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o crypto_hash/sha512/cp/libsodium_la-hash_sha512_cp.lo `test -f 'crypto_hash/sha512/cp/hash_sha512_cp.c' || echo '$(srcdir)/'`crypto_hash/sha512/cp/hash_sha512_cp.c
+crypto_ipcrypt/libsodium_la-crypto_ipcrypt.lo: crypto_ipcrypt/crypto_ipcrypt.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libsodium_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT crypto_ipcrypt/libsodium_la-crypto_ipcrypt.lo -MD -MP -MF crypto_ipcrypt/$(DEPDIR)/libsodium_la-crypto_ipcrypt.Tpo -c -o crypto_ipcrypt/libsodium_la-crypto_ipcrypt.lo `test -f 'crypto_ipcrypt/crypto_ipcrypt.c' || echo '$(srcdir)/'`crypto_ipcrypt/crypto_ipcrypt.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) crypto_ipcrypt/$(DEPDIR)/libsodium_la-crypto_ipcrypt.Tpo crypto_ipcrypt/$(DEPDIR)/libsodium_la-crypto_ipcrypt.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='crypto_ipcrypt/crypto_ipcrypt.c' object='crypto_ipcrypt/libsodium_la-crypto_ipcrypt.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libsodium_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o crypto_ipcrypt/libsodium_la-crypto_ipcrypt.lo `test -f 'crypto_ipcrypt/crypto_ipcrypt.c' || echo '$(srcdir)/'`crypto_ipcrypt/crypto_ipcrypt.c
+
+crypto_ipcrypt/libsodium_la-ipcrypt_soft.lo: crypto_ipcrypt/ipcrypt_soft.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libsodium_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT crypto_ipcrypt/libsodium_la-ipcrypt_soft.lo -MD -MP -MF crypto_ipcrypt/$(DEPDIR)/libsodium_la-ipcrypt_soft.Tpo -c -o crypto_ipcrypt/libsodium_la-ipcrypt_soft.lo `test -f 'crypto_ipcrypt/ipcrypt_soft.c' || echo '$(srcdir)/'`crypto_ipcrypt/ipcrypt_soft.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) crypto_ipcrypt/$(DEPDIR)/libsodium_la-ipcrypt_soft.Tpo crypto_ipcrypt/$(DEPDIR)/libsodium_la-ipcrypt_soft.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='crypto_ipcrypt/ipcrypt_soft.c' object='crypto_ipcrypt/libsodium_la-ipcrypt_soft.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libsodium_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o crypto_ipcrypt/libsodium_la-ipcrypt_soft.lo `test -f 'crypto_ipcrypt/ipcrypt_soft.c' || echo '$(srcdir)/'`crypto_ipcrypt/ipcrypt_soft.c
+
crypto_kdf/blake2b/libsodium_la-kdf_blake2b.lo: crypto_kdf/blake2b/kdf_blake2b.c
@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libsodium_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT crypto_kdf/blake2b/libsodium_la-kdf_blake2b.lo -MD -MP -MF crypto_kdf/blake2b/$(DEPDIR)/libsodium_la-kdf_blake2b.Tpo -c -o crypto_kdf/blake2b/libsodium_la-kdf_blake2b.lo `test -f 'crypto_kdf/blake2b/kdf_blake2b.c' || echo '$(srcdir)/'`crypto_kdf/blake2b/kdf_blake2b.c
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) crypto_kdf/blake2b/$(DEPDIR)/libsodium_la-kdf_blake2b.Tpo crypto_kdf/blake2b/$(DEPDIR)/libsodium_la-kdf_blake2b.Plo
@@ -3558,6 +3626,7 @@ clean-libtool:
-rm -rf crypto_hash/sha256/cp/.libs crypto_hash/sha256/cp/_libs
-rm -rf crypto_hash/sha512/.libs crypto_hash/sha512/_libs
-rm -rf crypto_hash/sha512/cp/.libs crypto_hash/sha512/cp/_libs
+ -rm -rf crypto_ipcrypt/.libs crypto_ipcrypt/_libs
-rm -rf crypto_kdf/.libs crypto_kdf/_libs
-rm -rf crypto_kdf/blake2b/.libs crypto_kdf/blake2b/_libs
-rm -rf crypto_kdf/hkdf/.libs crypto_kdf/hkdf/_libs
@@ -3890,6 +3959,8 @@ distclean-generic:
-$(am__rm_f) crypto_hash/sha512/$(am__dirstamp)
-$(am__rm_f) crypto_hash/sha512/cp/$(DEPDIR)/$(am__dirstamp)
-$(am__rm_f) crypto_hash/sha512/cp/$(am__dirstamp)
+ -$(am__rm_f) crypto_ipcrypt/$(DEPDIR)/$(am__dirstamp)
+ -$(am__rm_f) crypto_ipcrypt/$(am__dirstamp)
-$(am__rm_f) crypto_kdf/$(DEPDIR)/$(am__dirstamp)
-$(am__rm_f) crypto_kdf/$(am__dirstamp)
-$(am__rm_f) crypto_kdf/blake2b/$(DEPDIR)/$(am__dirstamp)
@@ -4058,6 +4129,10 @@ distclean: distclean-recursive
-rm -f crypto_hash/sha256/cp/$(DEPDIR)/libsodium_la-hash_sha256_cp.Plo
-rm -f crypto_hash/sha512/$(DEPDIR)/libsodium_la-hash_sha512.Plo
-rm -f crypto_hash/sha512/cp/$(DEPDIR)/libsodium_la-hash_sha512_cp.Plo
+ -rm -f crypto_ipcrypt/$(DEPDIR)/libaesni_la-ipcrypt_aesni.Plo
+ -rm -f crypto_ipcrypt/$(DEPDIR)/libarmcrypto_la-ipcrypt_armcrypto.Plo
+ -rm -f crypto_ipcrypt/$(DEPDIR)/libsodium_la-crypto_ipcrypt.Plo
+ -rm -f crypto_ipcrypt/$(DEPDIR)/libsodium_la-ipcrypt_soft.Plo
-rm -f crypto_kdf/$(DEPDIR)/libsodium_la-crypto_kdf.Plo
-rm -f crypto_kdf/blake2b/$(DEPDIR)/libsodium_la-kdf_blake2b.Plo
-rm -f crypto_kdf/hkdf/$(DEPDIR)/libsodium_la-kdf_hkdf_sha256.Plo
@@ -4234,6 +4309,10 @@ maintainer-clean: maintainer-clean-recursive
-rm -f crypto_hash/sha256/cp/$(DEPDIR)/libsodium_la-hash_sha256_cp.Plo
-rm -f crypto_hash/sha512/$(DEPDIR)/libsodium_la-hash_sha512.Plo
-rm -f crypto_hash/sha512/cp/$(DEPDIR)/libsodium_la-hash_sha512_cp.Plo
+ -rm -f crypto_ipcrypt/$(DEPDIR)/libaesni_la-ipcrypt_aesni.Plo
+ -rm -f crypto_ipcrypt/$(DEPDIR)/libarmcrypto_la-ipcrypt_armcrypto.Plo
+ -rm -f crypto_ipcrypt/$(DEPDIR)/libsodium_la-crypto_ipcrypt.Plo
+ -rm -f crypto_ipcrypt/$(DEPDIR)/libsodium_la-ipcrypt_soft.Plo
-rm -f crypto_kdf/$(DEPDIR)/libsodium_la-crypto_kdf.Plo
-rm -f crypto_kdf/blake2b/$(DEPDIR)/libsodium_la-kdf_blake2b.Plo
-rm -f crypto_kdf/hkdf/$(DEPDIR)/libsodium_la-kdf_hkdf_sha256.Plo
diff --git a/src/libsodium/crypto_core/softaes/softaes.c b/src/libsodium/crypto_core/softaes/softaes.c
index a724166c..990cf2c1 100644
--- a/src/libsodium/crypto_core/softaes/softaes.c
+++ b/src/libsodium/crypto_core/softaes/softaes.c
@@ -10,6 +10,191 @@
# define FAVOR_PERFORMANCE
#endif
+static const uint8_t SBOX[256] = {
+ 0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5, 0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76,
+ 0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0, 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0,
+ 0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc, 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15,
+ 0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a, 0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75,
+ 0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0, 0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84,
+ 0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b, 0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf,
+ 0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85, 0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8,
+ 0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5, 0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2,
+ 0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17, 0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73,
+ 0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88, 0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb,
+ 0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c, 0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79,
+ 0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9, 0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08,
+ 0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6, 0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a,
+ 0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e, 0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e,
+ 0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94, 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf,
+ 0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68, 0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16
+};
+
+static const uint8_t RCON[11] = {
+ 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36
+};
+
+static inline uint32_t
+sub_word(uint32_t w)
+{
+ return ((uint32_t) SBOX[(w >> 0) & 0xff] << 0) | ((uint32_t) SBOX[(w >> 8) & 0xff] << 8) |
+ ((uint32_t) SBOX[(w >> 16) & 0xff] << 16) | ((uint32_t) SBOX[(w >> 24) & 0xff] << 24);
+}
+
+static inline uint32_t
+rot_word(uint32_t w)
+{
+ return (w >> 8) | (w << 24);
+}
+
+void
+softaes_expand_key128(SoftAesBlock rkeys[11], const uint8_t key[16])
+{
+ uint32_t w[44];
+ size_t i;
+
+ w[0] = (uint32_t) key[0] | ((uint32_t) key[1] << 8) | ((uint32_t) key[2] << 16) |
+ ((uint32_t) key[3] << 24);
+ w[1] = (uint32_t) key[4] | ((uint32_t) key[5] << 8) | ((uint32_t) key[6] << 16) |
+ ((uint32_t) key[7] << 24);
+ w[2] = (uint32_t) key[8] | ((uint32_t) key[9] << 8) | ((uint32_t) key[10] << 16) |
+ ((uint32_t) key[11] << 24);
+ w[3] = (uint32_t) key[12] | ((uint32_t) key[13] << 8) | ((uint32_t) key[14] << 16) |
+ ((uint32_t) key[15] << 24);
+
+ for (i = 4; i < 44; i++) {
+ uint32_t temp = w[i - 1];
+ if (i % 4 == 0) {
+ temp = sub_word(rot_word(temp)) ^ ((uint32_t) RCON[i / 4]);
+ }
+ w[i] = w[i - 4] ^ temp;
+ }
+
+ for (i = 0; i < 11; i++) {
+ rkeys[i].w0 = w[i * 4 + 0];
+ rkeys[i].w1 = w[i * 4 + 1];
+ rkeys[i].w2 = w[i * 4 + 2];
+ rkeys[i].w3 = w[i * 4 + 3];
+ }
+}
+
+void
+softaes_expand_key256(SoftAesBlock rkeys[15], const uint8_t key[32])
+{
+ uint32_t w[60];
+ size_t i;
+
+ w[0] = (uint32_t) key[0] | ((uint32_t) key[1] << 8) | ((uint32_t) key[2] << 16) |
+ ((uint32_t) key[3] << 24);
+ w[1] = (uint32_t) key[4] | ((uint32_t) key[5] << 8) | ((uint32_t) key[6] << 16) |
+ ((uint32_t) key[7] << 24);
+ w[2] = (uint32_t) key[8] | ((uint32_t) key[9] << 8) | ((uint32_t) key[10] << 16) |
+ ((uint32_t) key[11] << 24);
+ w[3] = (uint32_t) key[12] | ((uint32_t) key[13] << 8) | ((uint32_t) key[14] << 16) |
+ ((uint32_t) key[15] << 24);
+ w[4] = (uint32_t) key[16] | ((uint32_t) key[17] << 8) | ((uint32_t) key[18] << 16) |
+ ((uint32_t) key[19] << 24);
+ w[5] = (uint32_t) key[20] | ((uint32_t) key[21] << 8) | ((uint32_t) key[22] << 16) |
+ ((uint32_t) key[23] << 24);
+ w[6] = (uint32_t) key[24] | ((uint32_t) key[25] << 8) | ((uint32_t) key[26] << 16) |
+ ((uint32_t) key[27] << 24);
+ w[7] = (uint32_t) key[28] | ((uint32_t) key[29] << 8) | ((uint32_t) key[30] << 16) |
+ ((uint32_t) key[31] << 24);
+
+ for (i = 8; i < 60; i++) {
+ uint32_t temp = w[i - 1];
+ if (i % 8 == 0) {
+ temp = sub_word(rot_word(temp)) ^ ((uint32_t) RCON[i / 8]);
+ } else if (i % 8 == 4) {
+ temp = sub_word(temp);
+ }
+ w[i] = w[i - 8] ^ temp;
+ }
+
+ for (i = 0; i < 15; i++) {
+ rkeys[i].w0 = w[i * 4 + 0];
+ rkeys[i].w1 = w[i * 4 + 1];
+ rkeys[i].w2 = w[i * 4 + 2];
+ rkeys[i].w3 = w[i * 4 + 3];
+ }
+}
+
+static inline uint8_t
+xtime(uint8_t a)
+{
+ return (uint8_t) ((a << 1) ^ (((a >> 7) & 1) * 0x1b));
+}
+
+static inline uint8_t
+gf_mul_09(uint8_t a)
+{
+ return xtime(xtime(xtime(a))) ^ a;
+}
+
+static inline uint8_t
+gf_mul_0b(uint8_t a)
+{
+ return xtime(xtime(xtime(a)) ^ a) ^ a;
+}
+
+static inline uint8_t
+gf_mul_0d(uint8_t a)
+{
+ return xtime(xtime(xtime(a) ^ a)) ^ a;
+}
+
+static inline uint8_t
+gf_mul_0e(uint8_t a)
+{
+ return xtime(xtime(xtime(a) ^ a) ^ a);
+}
+
+static uint32_t
+inv_mix_column(uint32_t col)
+{
+ uint8_t b0 = (uint8_t) col;
+ uint8_t b1 = (uint8_t) (col >> 8);
+ uint8_t b2 = (uint8_t) (col >> 16);
+ uint8_t b3 = (uint8_t) (col >> 24);
+
+ uint8_t r0 = gf_mul_0e(b0) ^ gf_mul_0b(b1) ^ gf_mul_0d(b2) ^ gf_mul_09(b3);
+ uint8_t r1 = gf_mul_09(b0) ^ gf_mul_0e(b1) ^ gf_mul_0b(b2) ^ gf_mul_0d(b3);
+ uint8_t r2 = gf_mul_0d(b0) ^ gf_mul_09(b1) ^ gf_mul_0e(b2) ^ gf_mul_0b(b3);
+ uint8_t r3 = gf_mul_0b(b0) ^ gf_mul_0d(b1) ^ gf_mul_09(b2) ^ gf_mul_0e(b3);
+
+ return (uint32_t) r0 | ((uint32_t) r1 << 8) | ((uint32_t) r2 << 16) | ((uint32_t) r3 << 24);
+}
+
+SoftAesBlock
+softaes_inv_mix_columns(const SoftAesBlock block)
+{
+ SoftAesBlock out;
+ out.w0 = inv_mix_column(block.w0);
+ out.w1 = inv_mix_column(block.w1);
+ out.w2 = inv_mix_column(block.w2);
+ out.w3 = inv_mix_column(block.w3);
+ return out;
+}
+
+void
+softaes_invert_key_schedule128(SoftAesBlock rkeys[11])
+{
+ size_t i;
+
+ for (i = 1; i < 10; i++) {
+ rkeys[i] = softaes_inv_mix_columns(rkeys[i]);
+ }
+}
+
+void
+softaes_invert_key_schedule256(SoftAesBlock rkeys[15])
+{
+ size_t i;
+
+ for (i = 1; i < 14; i++) {
+ rkeys[i] = softaes_inv_mix_columns(rkeys[i]);
+ }
+}
+
#ifndef SOFTAES_STRIDE
# define SOFTAES_STRIDE 16
#endif
@@ -208,6 +393,128 @@ softaes_block_encrypt(const SoftAesBlock block, const SoftAesBlock rk)
return out;
}
+
+static const uint8_t INV_SBOX[256] = {
+ 0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38, 0xbf, 0x40, 0xa3, 0x9e, 0x81, 0xf3, 0xd7, 0xfb,
+ 0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87, 0x34, 0x8e, 0x43, 0x44, 0xc4, 0xde, 0xe9, 0xcb,
+ 0x54, 0x7b, 0x94, 0x32, 0xa6, 0xc2, 0x23, 0x3d, 0xee, 0x4c, 0x95, 0x0b, 0x42, 0xfa, 0xc3, 0x4e,
+ 0x08, 0x2e, 0xa1, 0x66, 0x28, 0xd9, 0x24, 0xb2, 0x76, 0x5b, 0xa2, 0x49, 0x6d, 0x8b, 0xd1, 0x25,
+ 0x72, 0xf8, 0xf6, 0x64, 0x86, 0x68, 0x98, 0x16, 0xd4, 0xa4, 0x5c, 0xcc, 0x5d, 0x65, 0xb6, 0x92,
+ 0x6c, 0x70, 0x48, 0x50, 0xfd, 0xed, 0xb9, 0xda, 0x5e, 0x15, 0x46, 0x57, 0xa7, 0x8d, 0x9d, 0x84,
+ 0x90, 0xd8, 0xab, 0x00, 0x8c, 0xbc, 0xd3, 0x0a, 0xf7, 0xe4, 0x58, 0x05, 0xb8, 0xb3, 0x45, 0x06,
+ 0xd0, 0x2c, 0x1e, 0x8f, 0xca, 0x3f, 0x0f, 0x02, 0xc1, 0xaf, 0xbd, 0x03, 0x01, 0x13, 0x8a, 0x6b,
+ 0x3a, 0x91, 0x11, 0x41, 0x4f, 0x67, 0xdc, 0xea, 0x97, 0xf2, 0xcf, 0xce, 0xf0, 0xb4, 0xe6, 0x73,
+ 0x96, 0xac, 0x74, 0x22, 0xe7, 0xad, 0x35, 0x85, 0xe2, 0xf9, 0x37, 0xe8, 0x1c, 0x75, 0xdf, 0x6e,
+ 0x47, 0xf1, 0x1a, 0x71, 0x1d, 0x29, 0xc5, 0x89, 0x6f, 0xb7, 0x62, 0x0e, 0xaa, 0x18, 0xbe, 0x1b,
+ 0xfc, 0x56, 0x3e, 0x4b, 0xc6, 0xd2, 0x79, 0x20, 0x9a, 0xdb, 0xc0, 0xfe, 0x78, 0xcd, 0x5a, 0xf4,
+ 0x1f, 0xdd, 0xa8, 0x33, 0x88, 0x07, 0xc7, 0x31, 0xb1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xec, 0x5f,
+ 0x60, 0x51, 0x7f, 0xa9, 0x19, 0xb5, 0x4a, 0x0d, 0x2d, 0xe5, 0x7a, 0x9f, 0x93, 0xc9, 0x9c, 0xef,
+ 0xa0, 0xe0, 0x3b, 0x4d, 0xae, 0x2a, 0xf5, 0xb0, 0xc8, 0xeb, 0xbb, 0x3c, 0x83, 0x53, 0x99, 0x61,
+ 0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26, 0xe1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0c, 0x7d
+};
+
+SoftAesBlock
+softaes_block_decrypt(const SoftAesBlock block, const SoftAesBlock rk)
+{
+ SoftAesBlock out;
+ uint32_t s0, s1, s2, s3;
+ uint32_t t0, t1, t2, t3;
+
+ s0 = block.w0;
+ s1 = block.w1;
+ s2 = block.w2;
+ s3 = block.w3;
+
+ t0 = (s0 & 0x000000ff) | (s3 & 0x0000ff00) | (s2 & 0x00ff0000) | (s1 & 0xff000000);
+ t1 = (s1 & 0x000000ff) | (s0 & 0x0000ff00) | (s3 & 0x00ff0000) | (s2 & 0xff000000);
+ t2 = (s2 & 0x000000ff) | (s1 & 0x0000ff00) | (s0 & 0x00ff0000) | (s3 & 0xff000000);
+ t3 = (s3 & 0x000000ff) | (s2 & 0x0000ff00) | (s1 & 0x00ff0000) | (s0 & 0xff000000);
+
+ s0 = (uint32_t) INV_SBOX[t0 & 0xff] | ((uint32_t) INV_SBOX[(t0 >> 8) & 0xff] << 8) |
+ ((uint32_t) INV_SBOX[(t0 >> 16) & 0xff] << 16) |
+ ((uint32_t) INV_SBOX[(t0 >> 24) & 0xff] << 24);
+ s1 = (uint32_t) INV_SBOX[t1 & 0xff] | ((uint32_t) INV_SBOX[(t1 >> 8) & 0xff] << 8) |
+ ((uint32_t) INV_SBOX[(t1 >> 16) & 0xff] << 16) |
+ ((uint32_t) INV_SBOX[(t1 >> 24) & 0xff] << 24);
+ s2 = (uint32_t) INV_SBOX[t2 & 0xff] | ((uint32_t) INV_SBOX[(t2 >> 8) & 0xff] << 8) |
+ ((uint32_t) INV_SBOX[(t2 >> 16) & 0xff] << 16) |
+ ((uint32_t) INV_SBOX[(t2 >> 24) & 0xff] << 24);
+ s3 = (uint32_t) INV_SBOX[t3 & 0xff] | ((uint32_t) INV_SBOX[(t3 >> 8) & 0xff] << 8) |
+ ((uint32_t) INV_SBOX[(t3 >> 16) & 0xff] << 16) |
+ ((uint32_t) INV_SBOX[(t3 >> 24) & 0xff] << 24);
+
+ out.w0 = inv_mix_column(s0) ^ rk.w0;
+ out.w1 = inv_mix_column(s1) ^ rk.w1;
+ out.w2 = inv_mix_column(s2) ^ rk.w2;
+ out.w3 = inv_mix_column(s3) ^ rk.w3;
+
+ return out;
+}
+
+SoftAesBlock
+softaes_block_encryptlast(const SoftAesBlock block, const SoftAesBlock rk)
+{
+ SoftAesBlock out;
+ const uint32_t s0 = block.w0;
+ const uint32_t s1 = block.w1;
+ const uint32_t s2 = block.w2;
+ const uint32_t s3 = block.w3;
+
+ out.w0 = ((uint32_t) SBOX[(s0 >> 0) & 0xff] << 0) | ((uint32_t) SBOX[(s1 >> 8) & 0xff] << 8) |
+ ((uint32_t) SBOX[(s2 >> 16) & 0xff] << 16) |
+ ((uint32_t) SBOX[(s3 >> 24) & 0xff] << 24);
+ out.w1 = ((uint32_t) SBOX[(s1 >> 0) & 0xff] << 0) | ((uint32_t) SBOX[(s2 >> 8) & 0xff] << 8) |
+ ((uint32_t) SBOX[(s3 >> 16) & 0xff] << 16) |
+ ((uint32_t) SBOX[(s0 >> 24) & 0xff] << 24);
+ out.w2 = ((uint32_t) SBOX[(s2 >> 0) & 0xff] << 0) | ((uint32_t) SBOX[(s3 >> 8) & 0xff] << 8) |
+ ((uint32_t) SBOX[(s0 >> 16) & 0xff] << 16) |
+ ((uint32_t) SBOX[(s1 >> 24) & 0xff] << 24);
+ out.w3 = ((uint32_t) SBOX[(s3 >> 0) & 0xff] << 0) | ((uint32_t) SBOX[(s0 >> 8) & 0xff] << 8) |
+ ((uint32_t) SBOX[(s1 >> 16) & 0xff] << 16) |
+ ((uint32_t) SBOX[(s2 >> 24) & 0xff] << 24);
+
+ out.w0 ^= rk.w0;
+ out.w1 ^= rk.w1;
+ out.w2 ^= rk.w2;
+ out.w3 ^= rk.w3;
+
+ return out;
+}
+
+SoftAesBlock
+softaes_block_decryptlast(const SoftAesBlock block, const SoftAesBlock rk)
+{
+ SoftAesBlock out;
+ const uint32_t s0 = block.w0;
+ const uint32_t s1 = block.w1;
+ const uint32_t s2 = block.w2;
+ const uint32_t s3 = block.w3;
+ uint32_t t0, t1, t2, t3;
+
+ t0 = (s0 & 0x000000ff) | (s3 & 0x0000ff00) | (s2 & 0x00ff0000) | (s1 & 0xff000000);
+ t1 = (s1 & 0x000000ff) | (s0 & 0x0000ff00) | (s3 & 0x00ff0000) | (s2 & 0xff000000);
+ t2 = (s2 & 0x000000ff) | (s1 & 0x0000ff00) | (s0 & 0x00ff0000) | (s3 & 0xff000000);
+ t3 = (s3 & 0x000000ff) | (s2 & 0x0000ff00) | (s1 & 0x00ff0000) | (s0 & 0xff000000);
+
+ out.w0 = ((uint32_t) INV_SBOX[t0 & 0xff] | ((uint32_t) INV_SBOX[(t0 >> 8) & 0xff] << 8) |
+ ((uint32_t) INV_SBOX[(t0 >> 16) & 0xff] << 16) |
+ ((uint32_t) INV_SBOX[(t0 >> 24) & 0xff] << 24)) ^
+ rk.w0;
+ out.w1 = ((uint32_t) INV_SBOX[t1 & 0xff] | ((uint32_t) INV_SBOX[(t1 >> 8) & 0xff] << 8) |
+ ((uint32_t) INV_SBOX[(t1 >> 16) & 0xff] << 16) |
+ ((uint32_t) INV_SBOX[(t1 >> 24) & 0xff] << 24)) ^
+ rk.w1;
+ out.w2 = ((uint32_t) INV_SBOX[t2 & 0xff] | ((uint32_t) INV_SBOX[(t2 >> 8) & 0xff] << 8) |
+ ((uint32_t) INV_SBOX[(t2 >> 16) & 0xff] << 16) |
+ ((uint32_t) INV_SBOX[(t2 >> 24) & 0xff] << 24)) ^
+ rk.w2;
+ out.w3 = ((uint32_t) INV_SBOX[t3 & 0xff] | ((uint32_t) INV_SBOX[(t3 >> 8) & 0xff] << 8) |
+ ((uint32_t) INV_SBOX[(t3 >> 16) & 0xff] << 16) |
+ ((uint32_t) INV_SBOX[(t3 >> 24) & 0xff] << 24)) ^
+ rk.w3;
+
+ return out;
+}
#else
uint32_t _aes_lut[256] __attribute__((visibility("hidden"))) = {
@@ -271,9 +578,9 @@ _encrypt(const uint8_t ix0[4], const uint8_t ix1[4], const uint8_t ix2[4], const
}
}
-#ifdef HAVE_INLINE_ASM
+# ifdef HAVE_INLINE_ASM
__asm__ __volatile__("" : : "r"(t) : "memory");
-#endif
+# endif
out.w0 = t[0][0][ix0[0] / SOFTAES_STRIDE];
out.w0 ^= ROTL32(t[0][1][ix1[0] / SOFTAES_STRIDE], 8);
@@ -337,4 +644,193 @@ softaes_block_encrypt(const SoftAesBlock block, const SoftAesBlock rk)
return out;
}
+
+static const uint8_t INV_SBOX[256] = {
+ 0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38, 0xbf, 0x40, 0xa3, 0x9e, 0x81, 0xf3, 0xd7, 0xfb,
+ 0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87, 0x34, 0x8e, 0x43, 0x44, 0xc4, 0xde, 0xe9, 0xcb,
+ 0x54, 0x7b, 0x94, 0x32, 0xa6, 0xc2, 0x23, 0x3d, 0xee, 0x4c, 0x95, 0x0b, 0x42, 0xfa, 0xc3, 0x4e,
+ 0x08, 0x2e, 0xa1, 0x66, 0x28, 0xd9, 0x24, 0xb2, 0x76, 0x5b, 0xa2, 0x49, 0x6d, 0x8b, 0xd1, 0x25,
+ 0x72, 0xf8, 0xf6, 0x64, 0x86, 0x68, 0x98, 0x16, 0xd4, 0xa4, 0x5c, 0xcc, 0x5d, 0x65, 0xb6, 0x92,
+ 0x6c, 0x70, 0x48, 0x50, 0xfd, 0xed, 0xb9, 0xda, 0x5e, 0x15, 0x46, 0x57, 0xa7, 0x8d, 0x9d, 0x84,
+ 0x90, 0xd8, 0xab, 0x00, 0x8c, 0xbc, 0xd3, 0x0a, 0xf7, 0xe4, 0x58, 0x05, 0xb8, 0xb3, 0x45, 0x06,
+ 0xd0, 0x2c, 0x1e, 0x8f, 0xca, 0x3f, 0x0f, 0x02, 0xc1, 0xaf, 0xbd, 0x03, 0x01, 0x13, 0x8a, 0x6b,
+ 0x3a, 0x91, 0x11, 0x41, 0x4f, 0x67, 0xdc, 0xea, 0x97, 0xf2, 0xcf, 0xce, 0xf0, 0xb4, 0xe6, 0x73,
+ 0x96, 0xac, 0x74, 0x22, 0xe7, 0xad, 0x35, 0x85, 0xe2, 0xf9, 0x37, 0xe8, 0x1c, 0x75, 0xdf, 0x6e,
+ 0x47, 0xf1, 0x1a, 0x71, 0x1d, 0x29, 0xc5, 0x89, 0x6f, 0xb7, 0x62, 0x0e, 0xaa, 0x18, 0xbe, 0x1b,
+ 0xfc, 0x56, 0x3e, 0x4b, 0xc6, 0xd2, 0x79, 0x20, 0x9a, 0xdb, 0xc0, 0xfe, 0x78, 0xcd, 0x5a, 0xf4,
+ 0x1f, 0xdd, 0xa8, 0x33, 0x88, 0x07, 0xc7, 0x31, 0xb1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xec, 0x5f,
+ 0x60, 0x51, 0x7f, 0xa9, 0x19, 0xb5, 0x4a, 0x0d, 0x2d, 0xe5, 0x7a, 0x9f, 0x93, 0xc9, 0x9c, 0xef,
+ 0xa0, 0xe0, 0x3b, 0x4d, 0xae, 0x2a, 0xf5, 0xb0, 0xc8, 0xeb, 0xbb, 0x3c, 0x83, 0x53, 0x99, 0x61,
+ 0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26, 0xe1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0c, 0x7d
+};
+
+SoftAesBlock
+softaes_block_decrypt(const SoftAesBlock block, const SoftAesBlock rk)
+{
+ CRYPTO_ALIGN(64) SoftAesBlock out;
+ uint32_t s0, s1, s2, s3;
+ uint32_t t0, t1, t2, t3;
+
+ s0 = block.w0;
+ s1 = block.w1;
+ s2 = block.w2;
+ s3 = block.w3;
+
+ t0 = (s0 & 0x000000ff) | (s3 & 0x0000ff00) | (s2 & 0x00ff0000) | (s1 & 0xff000000);
+ t1 = (s1 & 0x000000ff) | (s0 & 0x0000ff00) | (s3 & 0x00ff0000) | (s2 & 0xff000000);
+ t2 = (s2 & 0x000000ff) | (s1 & 0x0000ff00) | (s0 & 0x00ff0000) | (s3 & 0xff000000);
+ t3 = (s3 & 0x000000ff) | (s2 & 0x0000ff00) | (s1 & 0x00ff0000) | (s0 & 0xff000000);
+
+ s0 = (uint32_t) INV_SBOX[t0 & 0xff] | ((uint32_t) INV_SBOX[(t0 >> 8) & 0xff] << 8) |
+ ((uint32_t) INV_SBOX[(t0 >> 16) & 0xff] << 16) |
+ ((uint32_t) INV_SBOX[(t0 >> 24) & 0xff] << 24);
+ s1 = (uint32_t) INV_SBOX[t1 & 0xff] | ((uint32_t) INV_SBOX[(t1 >> 8) & 0xff] << 8) |
+ ((uint32_t) INV_SBOX[(t1 >> 16) & 0xff] << 16) |
+ ((uint32_t) INV_SBOX[(t1 >> 24) & 0xff] << 24);
+ s2 = (uint32_t) INV_SBOX[t2 & 0xff] | ((uint32_t) INV_SBOX[(t2 >> 8) & 0xff] << 8) |
+ ((uint32_t) INV_SBOX[(t2 >> 16) & 0xff] << 16) |
+ ((uint32_t) INV_SBOX[(t2 >> 24) & 0xff] << 24);
+ s3 = (uint32_t) INV_SBOX[t3 & 0xff] | ((uint32_t) INV_SBOX[(t3 >> 8) & 0xff] << 8) |
+ ((uint32_t) INV_SBOX[(t3 >> 16) & 0xff] << 16) |
+ ((uint32_t) INV_SBOX[(t3 >> 24) & 0xff] << 24);
+
+ out.w0 = inv_mix_column(s0) ^ rk.w0;
+ out.w1 = inv_mix_column(s1) ^ rk.w1;
+ out.w2 = inv_mix_column(s2) ^ rk.w2;
+ out.w3 = inv_mix_column(s3) ^ rk.w3;
+
+ return out;
+}
+
+SoftAesBlock
+softaes_block_encryptlast(const SoftAesBlock block, const SoftAesBlock rk)
+{
+ CRYPTO_ALIGN(64) SoftAesBlock out;
+ CRYPTO_ALIGN(64) uint8_t ix[4][4];
+ CRYPTO_ALIGN(64) uint8_t t[4][256 / SOFTAES_STRIDE];
+ const uint32_t s0 = block.w0;
+ const uint32_t s1 = block.w1;
+ const uint32_t s2 = block.w2;
+ const uint32_t s3 = block.w3;
+ size_t i;
+ size_t j;
+
+ ix[0][0] = (uint8_t) s0;
+ ix[0][1] = (uint8_t) (s1 >> 8);
+ ix[0][2] = (uint8_t) (s2 >> 16);
+ ix[0][3] = (uint8_t) (s3 >> 24);
+
+ ix[1][0] = (uint8_t) s1;
+ ix[1][1] = (uint8_t) (s2 >> 8);
+ ix[1][2] = (uint8_t) (s3 >> 16);
+ ix[1][3] = (uint8_t) (s0 >> 24);
+
+ ix[2][0] = (uint8_t) s2;
+ ix[2][1] = (uint8_t) (s3 >> 8);
+ ix[2][2] = (uint8_t) (s0 >> 16);
+ ix[2][3] = (uint8_t) (s1 >> 24);
+
+ ix[3][0] = (uint8_t) s3;
+ ix[3][1] = (uint8_t) (s0 >> 8);
+ ix[3][2] = (uint8_t) (s1 >> 16);
+ ix[3][3] = (uint8_t) (s2 >> 24);
+
+ for (i = 0; i < 256 / SOFTAES_STRIDE; i++) {
+ for (j = 0; j < 4; j++) {
+ t[j][i] = SBOX[(i * SOFTAES_STRIDE) | (ix[0][j] % SOFTAES_STRIDE)];
+ }
+ }
+# ifdef HAVE_INLINE_ASM
+ __asm__ __volatile__("" : : "r"(t) : "memory");
+# endif
+
+ out.w0 = ((uint32_t) t[0][ix[0][0] / SOFTAES_STRIDE] << 0) |
+ ((uint32_t) t[1][ix[0][1] / SOFTAES_STRIDE] << 8) |
+ ((uint32_t) t[2][ix[0][2] / SOFTAES_STRIDE] << 16) |
+ ((uint32_t) t[3][ix[0][3] / SOFTAES_STRIDE] << 24);
+
+ for (i = 0; i < 256 / SOFTAES_STRIDE; i++) {
+ for (j = 0; j < 4; j++) {
+ t[j][i] = SBOX[(i * SOFTAES_STRIDE) | (ix[1][j] % SOFTAES_STRIDE)];
+ }
+ }
+# ifdef HAVE_INLINE_ASM
+ __asm__ __volatile__("" : : "r"(t) : "memory");
+# endif
+
+ out.w1 = ((uint32_t) t[0][ix[1][0] / SOFTAES_STRIDE] << 0) |
+ ((uint32_t) t[1][ix[1][1] / SOFTAES_STRIDE] << 8) |
+ ((uint32_t) t[2][ix[1][2] / SOFTAES_STRIDE] << 16) |
+ ((uint32_t) t[3][ix[1][3] / SOFTAES_STRIDE] << 24);
+
+ for (i = 0; i < 256 / SOFTAES_STRIDE; i++) {
+ for (j = 0; j < 4; j++) {
+ t[j][i] = SBOX[(i * SOFTAES_STRIDE) | (ix[2][j] % SOFTAES_STRIDE)];
+ }
+ }
+# ifdef HAVE_INLINE_ASM
+ __asm__ __volatile__("" : : "r"(t) : "memory");
+# endif
+
+ out.w2 = ((uint32_t) t[0][ix[2][0] / SOFTAES_STRIDE] << 0) |
+ ((uint32_t) t[1][ix[2][1] / SOFTAES_STRIDE] << 8) |
+ ((uint32_t) t[2][ix[2][2] / SOFTAES_STRIDE] << 16) |
+ ((uint32_t) t[3][ix[2][3] / SOFTAES_STRIDE] << 24);
+
+ for (i = 0; i < 256 / SOFTAES_STRIDE; i++) {
+ for (j = 0; j < 4; j++) {
+ t[j][i] = SBOX[(i * SOFTAES_STRIDE) | (ix[3][j] % SOFTAES_STRIDE)];
+ }
+ }
+# ifdef HAVE_INLINE_ASM
+ __asm__ __volatile__("" : : "r"(t) : "memory");
+# endif
+
+ out.w3 = ((uint32_t) t[0][ix[3][0] / SOFTAES_STRIDE] << 0) |
+ ((uint32_t) t[1][ix[3][1] / SOFTAES_STRIDE] << 8) |
+ ((uint32_t) t[2][ix[3][2] / SOFTAES_STRIDE] << 16) |
+ ((uint32_t) t[3][ix[3][3] / SOFTAES_STRIDE] << 24);
+
+ out.w0 ^= rk.w0;
+ out.w1 ^= rk.w1;
+ out.w2 ^= rk.w2;
+ out.w3 ^= rk.w3;
+
+ return out;
+}
+
+SoftAesBlock
+softaes_block_decryptlast(const SoftAesBlock block, const SoftAesBlock rk)
+{
+ CRYPTO_ALIGN(64) SoftAesBlock out;
+ const uint32_t s0 = block.w0;
+ const uint32_t s1 = block.w1;
+ const uint32_t s2 = block.w2;
+ const uint32_t s3 = block.w3;
+ uint32_t t0, t1, t2, t3;
+
+ t0 = (s0 & 0x000000ff) | (s3 & 0x0000ff00) | (s2 & 0x00ff0000) | (s1 & 0xff000000);
+ t1 = (s1 & 0x000000ff) | (s0 & 0x0000ff00) | (s3 & 0x00ff0000) | (s2 & 0xff000000);
+ t2 = (s2 & 0x000000ff) | (s1 & 0x0000ff00) | (s0 & 0x00ff0000) | (s3 & 0xff000000);
+ t3 = (s3 & 0x000000ff) | (s2 & 0x0000ff00) | (s1 & 0x00ff0000) | (s0 & 0xff000000);
+
+ out.w0 = ((uint32_t) INV_SBOX[t0 & 0xff] | ((uint32_t) INV_SBOX[(t0 >> 8) & 0xff] << 8) |
+ ((uint32_t) INV_SBOX[(t0 >> 16) & 0xff] << 16) |
+ ((uint32_t) INV_SBOX[(t0 >> 24) & 0xff] << 24)) ^
+ rk.w0;
+ out.w1 = ((uint32_t) INV_SBOX[t1 & 0xff] | ((uint32_t) INV_SBOX[(t1 >> 8) & 0xff] << 8) |
+ ((uint32_t) INV_SBOX[(t1 >> 16) & 0xff] << 16) |
+ ((uint32_t) INV_SBOX[(t1 >> 24) & 0xff] << 24)) ^
+ rk.w1;
+ out.w2 = ((uint32_t) INV_SBOX[t2 & 0xff] | ((uint32_t) INV_SBOX[(t2 >> 8) & 0xff] << 8) |
+ ((uint32_t) INV_SBOX[(t2 >> 16) & 0xff] << 16) |
+ ((uint32_t) INV_SBOX[(t2 >> 24) & 0xff] << 24)) ^
+ rk.w2;
+ out.w3 = ((uint32_t) INV_SBOX[t3 & 0xff] | ((uint32_t) INV_SBOX[(t3 >> 8) & 0xff] << 8) |
+ ((uint32_t) INV_SBOX[(t3 >> 16) & 0xff] << 16) |
+ ((uint32_t) INV_SBOX[(t3 >> 24) & 0xff] << 24)) ^
+ rk.w3;
+
+ return out;
+}
#endif
diff --git a/src/libsodium/crypto_ipcrypt/crypto_ipcrypt.c b/src/libsodium/crypto_ipcrypt/crypto_ipcrypt.c
new file mode 100644
index 00000000..aceb06c1
--- /dev/null
+++ b/src/libsodium/crypto_ipcrypt/crypto_ipcrypt.c
@@ -0,0 +1,186 @@
+
+#include
+
+#include "core.h"
+#include "crypto_ipcrypt.h"
+#include "private/common.h"
+#include "private/implementations.h"
+#include "randombytes.h"
+#include "runtime.h"
+
+#include "ipcrypt_soft.h"
+
+#if defined(HAVE_ARMCRYPTO) && defined(NATIVE_LITTLE_ENDIAN)
+# include "ipcrypt_armcrypto.h"
+#endif
+
+#if defined(HAVE_AVXINTRIN_H) && defined(HAVE_WMMINTRIN_H)
+# include "ipcrypt_aesni.h"
+#endif
+
+static const ipcrypt_implementation *implementation = &ipcrypt_soft_implementation;
+
+size_t
+crypto_ipcrypt_bytes(void)
+{
+ return crypto_ipcrypt_BYTES;
+}
+
+size_t
+crypto_ipcrypt_keybytes(void)
+{
+ return crypto_ipcrypt_KEYBYTES;
+}
+
+size_t
+crypto_ipcrypt_nd_keybytes(void)
+{
+ return crypto_ipcrypt_ND_KEYBYTES;
+}
+
+size_t
+crypto_ipcrypt_nd_tweakbytes(void)
+{
+ return crypto_ipcrypt_ND_TWEAKBYTES;
+}
+
+size_t
+crypto_ipcrypt_nd_inputbytes(void)
+{
+ return crypto_ipcrypt_ND_INPUTBYTES;
+}
+
+size_t
+crypto_ipcrypt_nd_outputbytes(void)
+{
+ return crypto_ipcrypt_ND_OUTPUTBYTES;
+}
+
+size_t
+crypto_ipcrypt_ndx_keybytes(void)
+{
+ return crypto_ipcrypt_NDX_KEYBYTES;
+}
+
+size_t
+crypto_ipcrypt_ndx_tweakbytes(void)
+{
+ return crypto_ipcrypt_NDX_TWEAKBYTES;
+}
+
+size_t
+crypto_ipcrypt_ndx_inputbytes(void)
+{
+ return crypto_ipcrypt_NDX_INPUTBYTES;
+}
+
+size_t
+crypto_ipcrypt_ndx_outputbytes(void)
+{
+ return crypto_ipcrypt_NDX_OUTPUTBYTES;
+}
+
+size_t
+crypto_ipcrypt_pfx_keybytes(void)
+{
+ return crypto_ipcrypt_PFX_KEYBYTES;
+}
+
+size_t
+crypto_ipcrypt_pfx_bytes(void)
+{
+ return crypto_ipcrypt_PFX_BYTES;
+}
+
+void
+crypto_ipcrypt_keygen(unsigned char k[crypto_ipcrypt_KEYBYTES])
+{
+ randombytes_buf(k, crypto_ipcrypt_KEYBYTES);
+}
+
+void
+crypto_ipcrypt_ndx_keygen(unsigned char k[crypto_ipcrypt_NDX_KEYBYTES])
+{
+ randombytes_buf(k, crypto_ipcrypt_NDX_KEYBYTES);
+}
+
+void
+crypto_ipcrypt_pfx_keygen(unsigned char k[crypto_ipcrypt_PFX_KEYBYTES])
+{
+ randombytes_buf(k, crypto_ipcrypt_PFX_KEYBYTES);
+}
+
+void
+crypto_ipcrypt_encrypt(unsigned char *out, const unsigned char *in, const unsigned char *k)
+{
+ implementation->encrypt(out, in, k);
+}
+
+void
+crypto_ipcrypt_decrypt(unsigned char *out, const unsigned char *in, const unsigned char *k)
+{
+ implementation->decrypt(out, in, k);
+}
+
+void
+crypto_ipcrypt_nd_encrypt(unsigned char *out,
+ const unsigned char *in,
+ const unsigned char *t,
+ const unsigned char *k)
+{
+ implementation->nd_encrypt(out, in, t, k);
+}
+
+void
+crypto_ipcrypt_nd_decrypt(unsigned char *out, const unsigned char *in, const unsigned char *k)
+{
+ implementation->nd_decrypt(out, in, k);
+}
+
+void
+crypto_ipcrypt_ndx_encrypt(unsigned char *out,
+ const unsigned char *in,
+ const unsigned char *t,
+ const unsigned char *k)
+{
+ implementation->ndx_encrypt(out, in, t, k);
+}
+
+void
+crypto_ipcrypt_ndx_decrypt(unsigned char *out, const unsigned char *in, const unsigned char *k)
+{
+ implementation->ndx_decrypt(out, in, k);
+}
+
+void
+crypto_ipcrypt_pfx_encrypt(unsigned char *out, const unsigned char *in, const unsigned char *k)
+{
+ implementation->pfx_encrypt(out, in, k);
+}
+
+void
+crypto_ipcrypt_pfx_decrypt(unsigned char *out, const unsigned char *in, const unsigned char *k)
+{
+ implementation->pfx_decrypt(out, in, k);
+}
+
+int
+_crypto_ipcrypt_pick_best_implementation(void)
+{
+ implementation = &ipcrypt_soft_implementation;
+
+#if defined(HAVE_ARMCRYPTO) && defined(NATIVE_LITTLE_ENDIAN)
+ if (sodium_runtime_has_armcrypto()) {
+ implementation = &ipcrypt_armcrypto_implementation;
+ return 0;
+ }
+#endif
+
+#if defined(HAVE_AVXINTRIN_H) && defined(HAVE_WMMINTRIN_H)
+ if (sodium_runtime_has_aesni()) {
+ implementation = &ipcrypt_aesni_implementation;
+ return 0;
+ }
+#endif
+ return 0;
+}
diff --git a/src/libsodium/crypto_ipcrypt/implementations.h b/src/libsodium/crypto_ipcrypt/implementations.h
new file mode 100644
index 00000000..c4b5ab60
--- /dev/null
+++ b/src/libsodium/crypto_ipcrypt/implementations.h
@@ -0,0 +1,20 @@
+#ifndef ipcrypt_implementations_H
+#define ipcrypt_implementations_H
+
+#include
+#include
+
+#include "crypto_ipcrypt.h"
+
+typedef struct ipcrypt_implementation {
+ void (*encrypt)(uint8_t *out, const uint8_t *in, const uint8_t *k);
+ void (*decrypt)(uint8_t *out, const uint8_t *in, const uint8_t *k);
+ void (*nd_encrypt)(uint8_t *out, const uint8_t *in, const uint8_t *t, const uint8_t *k);
+ void (*nd_decrypt)(uint8_t *out, const uint8_t *in, const uint8_t *k);
+ void (*ndx_encrypt)(uint8_t *out, const uint8_t *in, const uint8_t *t, const uint8_t *k);
+ void (*ndx_decrypt)(uint8_t *out, const uint8_t *in, const uint8_t *k);
+ void (*pfx_encrypt)(uint8_t *out, const uint8_t *in, const uint8_t *k);
+ void (*pfx_decrypt)(uint8_t *out, const uint8_t *in, const uint8_t *k);
+} ipcrypt_implementation;
+
+#endif
diff --git a/src/libsodium/crypto_ipcrypt/ipcrypt_aesni.c b/src/libsodium/crypto_ipcrypt/ipcrypt_aesni.c
new file mode 100644
index 00000000..e86081b3
--- /dev/null
+++ b/src/libsodium/crypto_ipcrypt/ipcrypt_aesni.c
@@ -0,0 +1,493 @@
+#include
+#include
+#include
+
+#include "crypto_ipcrypt.h"
+#include "utils.h"
+
+#include "private/common.h"
+
+#if defined(HAVE_AVXINTRIN_H) && defined(HAVE_WMMINTRIN_H)
+
+# include "ipcrypt_aesni.h"
+
+# ifdef __clang__
+# pragma clang attribute push(__attribute__((target("aes,avx"))), apply_to = function)
+# elif defined(__GNUC__)
+# pragma GCC target("aes,avx")
+# endif
+
+# include
+# include
+
+# define ROUNDS 10
+
+typedef __m128i BlockVec;
+
+# define LOAD128(a) _mm_loadu_si128((const BlockVec *) (const void *) (a))
+# define STORE128(a, b) _mm_storeu_si128((BlockVec *) (void *) (a), (b))
+# define AES_ENCRYPT(block_vec, rkey) _mm_aesenc_si128((block_vec), (rkey))
+# define AES_ENCRYPTLAST(block_vec, rkey) _mm_aesenclast_si128((block_vec), (rkey))
+# define AES_DECRYPT(block_vec, rkey) _mm_aesdec_si128((block_vec), (rkey))
+# define AES_DECRYPTLAST(block_vec, rkey) _mm_aesdeclast_si128((block_vec), (rkey))
+# define AES_KEYGEN(block_vec, rc) _mm_aeskeygenassist_si128((block_vec), (rc))
+# define AES_IMC(rkey) _mm_aesimc_si128(rkey)
+# define XOR128(a, b) _mm_xor_si128((a), (b))
+# define XOR128_3(a, b, c) _mm_xor_si128(_mm_xor_si128((a), (b)), (c))
+# define SET64x2(a, b) _mm_set_epi64x((uint64_t) (a), (uint64_t) (b))
+# define BYTESHL128(a, b) _mm_slli_si128(a, b)
+# define SHUFFLE32x4(x, a, b, c, d) _mm_shuffle_epi32((x), _MM_SHUFFLE((d), (c), (b), (a)))
+
+typedef BlockVec KeySchedule[1 + ROUNDS];
+
+static void
+expand_key(BlockVec *rkeys, const uint8_t key[16])
+{
+ BlockVec t, s;
+ size_t i = 0;
+
+# define EXPAND_KEY(RC) \
+ rkeys[i++] = t; \
+ s = AES_KEYGEN(t, RC); \
+ t = XOR128(t, BYTESHL128(t, 4)); \
+ t = XOR128(t, BYTESHL128(t, 8)); \
+ t = XOR128(t, SHUFFLE32x4(s, 3, 3, 3, 3));
+
+ t = LOAD128(key);
+ EXPAND_KEY(0x01);
+ EXPAND_KEY(0x02);
+ EXPAND_KEY(0x04);
+ EXPAND_KEY(0x08);
+ EXPAND_KEY(0x10);
+ EXPAND_KEY(0x20);
+ EXPAND_KEY(0x40);
+ EXPAND_KEY(0x80);
+ EXPAND_KEY(0x1b);
+ EXPAND_KEY(0x36);
+ rkeys[i++] = t;
+}
+
+static void
+aes_encrypt(uint8_t out[16], const uint8_t in[16], const BlockVec *rkeys)
+{
+ BlockVec t;
+ size_t i;
+
+ t = XOR128(LOAD128(in), rkeys[0]);
+ for (i = 1; i < ROUNDS; i++) {
+ t = AES_ENCRYPT(t, rkeys[i]);
+ }
+ t = AES_ENCRYPTLAST(t, rkeys[ROUNDS]);
+ STORE128(out, t);
+}
+
+static void
+aes_decrypt(uint8_t out[16], const uint8_t in[16], const BlockVec *rkeys)
+{
+ KeySchedule rkeys_inv;
+ BlockVec t;
+ size_t i;
+
+ for (i = 0; i < ROUNDS - 1; i++) {
+ rkeys_inv[i] = AES_IMC(rkeys[ROUNDS - 1 - i]);
+ }
+ t = XOR128(LOAD128(in), rkeys[ROUNDS]);
+ for (i = 0; i < ROUNDS - 1; i++) {
+ t = AES_DECRYPT(t, rkeys_inv[i]);
+ }
+ t = AES_DECRYPTLAST(t, rkeys[0]);
+ STORE128(out, t);
+}
+
+static BlockVec
+tweak_expand(const uint8_t tweak[8])
+{
+ return _mm_shuffle_epi8(_mm_loadl_epi64((const __m128i *) (const void *) tweak),
+ _mm_setr_epi8(0x00, 0x01, -128, -128, 0x02, 0x03, -128, -128, 0x04,
+ 0x05, -128, -128, 0x06, 0x07, -128, -128));
+}
+
+static void
+aes_encrypt_with_tweak(uint8_t out[16], const uint8_t in[16], const uint8_t tweak[8],
+ const BlockVec *rkeys)
+{
+ const BlockVec tweak_block = tweak_expand(tweak);
+ BlockVec t;
+ size_t i;
+
+ t = XOR128_3(LOAD128(in), tweak_block, rkeys[0]);
+ for (i = 1; i < ROUNDS; i++) {
+ t = AES_ENCRYPT(t, XOR128(tweak_block, rkeys[i]));
+ }
+ t = AES_ENCRYPTLAST(t, XOR128(tweak_block, rkeys[ROUNDS]));
+ STORE128(out, t);
+}
+
+static void
+aes_decrypt_with_tweak(uint8_t out[16], const uint8_t in[16], const uint8_t tweak[8],
+ const BlockVec *rkeys)
+{
+ KeySchedule rkeys_inv;
+ const BlockVec tweak_block = tweak_expand(tweak);
+ const BlockVec tweak_block_inv = AES_IMC(tweak_block);
+ BlockVec t;
+ size_t i;
+
+ for (i = 0; i < ROUNDS - 1; i++) {
+ rkeys_inv[i] = AES_IMC(rkeys[ROUNDS - 1 - i]);
+ }
+ t = XOR128_3(LOAD128(in), tweak_block, rkeys[ROUNDS]);
+ for (i = 0; i < ROUNDS - 1; i++) {
+ t = AES_DECRYPT(t, XOR128(tweak_block_inv, rkeys_inv[i]));
+ }
+ t = AES_DECRYPTLAST(t, XOR128(tweak_block, rkeys[0]));
+ STORE128(out, t);
+}
+
+static BlockVec
+aes_xex_tweak(const uint8_t tweak[16], const BlockVec *tkeys)
+{
+ BlockVec tt;
+ size_t i;
+
+ tt = XOR128(LOAD128(tweak), tkeys[0]);
+ for (i = 1; i < ROUNDS; i++) {
+ tt = AES_ENCRYPT(tt, tkeys[i]);
+ }
+ tt = AES_ENCRYPTLAST(tt, tkeys[ROUNDS]);
+ return tt;
+}
+
+static void
+aes_xex_encrypt(uint8_t out[16], const uint8_t in[16], const uint8_t tweak[16],
+ const BlockVec *tkeys, const BlockVec *rkeys)
+{
+ const BlockVec tt = aes_xex_tweak(tweak, tkeys);
+ BlockVec t;
+ size_t i;
+
+ t = XOR128(XOR128(LOAD128(in), tt), rkeys[0]);
+ for (i = 1; i < ROUNDS; i++) {
+ t = AES_ENCRYPT(t, rkeys[i]);
+ }
+ t = AES_ENCRYPTLAST(t, XOR128(rkeys[ROUNDS], tt));
+ STORE128(out, t);
+}
+
+static void
+aes_xex_decrypt(uint8_t out[16], const uint8_t in[16], const uint8_t tweak[16],
+ const BlockVec *tkeys, const BlockVec *rkeys)
+{
+ KeySchedule rkeys_inv;
+ const BlockVec tt = aes_xex_tweak(tweak, tkeys);
+ BlockVec t;
+ size_t i;
+
+ for (i = 0; i < ROUNDS - 1; i++) {
+ rkeys_inv[i] = AES_IMC(rkeys[ROUNDS - 1 - i]);
+ }
+ t = XOR128(XOR128(LOAD128(in), tt), rkeys[ROUNDS]);
+ for (i = 0; i < ROUNDS - 1; i++) {
+ t = AES_DECRYPT(t, rkeys_inv[i]);
+ }
+ t = AES_DECRYPTLAST(t, XOR128(rkeys[0], tt));
+ STORE128(out, t);
+}
+
+static void
+encrypt(uint8_t *out, const uint8_t *in, const uint8_t *k)
+{
+ KeySchedule rkeys;
+
+ expand_key(rkeys, k);
+ aes_encrypt(out, in, rkeys);
+}
+
+static void
+decrypt(uint8_t *out, const uint8_t *in, const uint8_t *k)
+{
+ KeySchedule rkeys;
+
+ expand_key(rkeys, k);
+ aes_decrypt(out, in, rkeys);
+}
+
+static void
+nd_encrypt(uint8_t *out, const uint8_t *in, const uint8_t *t, const uint8_t *k)
+{
+ KeySchedule rkeys;
+
+ expand_key(rkeys, k);
+ memcpy(out, t, 8);
+ aes_encrypt_with_tweak(out + 8, in, t, rkeys);
+}
+
+static void
+nd_decrypt(uint8_t *out, const uint8_t *in, const uint8_t *k)
+{
+ KeySchedule rkeys;
+
+ expand_key(rkeys, k);
+ aes_decrypt_with_tweak(out, in + 8, in, rkeys);
+}
+
+static void
+ndx_encrypt(uint8_t *out, const uint8_t *in, const uint8_t *t, const uint8_t *k)
+{
+ KeySchedule tkeys;
+ KeySchedule rkeys;
+ uint8_t diff[16];
+ size_t i;
+ uint8_t d;
+
+ expand_key(tkeys, k + 16);
+ expand_key(rkeys, k);
+
+ STORE128(diff, XOR128(tkeys[ROUNDS / 2], rkeys[ROUNDS / 2]));
+ d = 0;
+ for (i = 0; i < 16; i++) {
+ d |= diff[i];
+ }
+ if (d == 0) {
+ for (i = 0; i < 16; i++) {
+ diff[i] = k[i] ^ 0x5a;
+ }
+ expand_key(rkeys, diff);
+ }
+
+ memcpy(out, t, 16);
+ aes_xex_encrypt(out + 16, in, t, tkeys, rkeys);
+}
+
+static void
+ndx_decrypt(uint8_t *out, const uint8_t *in, const uint8_t *k)
+{
+ KeySchedule tkeys;
+ KeySchedule rkeys;
+ uint8_t diff[16];
+ size_t i;
+ uint8_t d;
+
+ expand_key(tkeys, k + 16);
+ expand_key(rkeys, k);
+
+ STORE128(diff, XOR128(tkeys[ROUNDS / 2], rkeys[ROUNDS / 2]));
+ d = 0;
+ for (i = 0; i < 16; i++) {
+ d |= diff[i];
+ }
+ if (d == 0) {
+ for (i = 0; i < 16; i++) {
+ diff[i] = k[i] ^ 0x5a;
+ }
+ expand_key(rkeys, diff);
+ }
+
+ aes_xex_decrypt(out, in + 16, in, tkeys, rkeys);
+}
+
+static int
+is_ipv4_mapped(const uint8_t ip16[16])
+{
+ static const uint8_t ipv4_mapped_prefix[12] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xff, 0xff };
+
+ return memcmp(ip16, ipv4_mapped_prefix, 12) == 0;
+}
+
+static uint8_t
+pfx_get_bit(const uint8_t ip16[16], unsigned int bit_index)
+{
+ return (ip16[15 - bit_index / 8] >> (bit_index % 8)) & 1;
+}
+
+static void
+pfx_set_bit(uint8_t ip16[16], const unsigned int bit_index, const uint8_t bit_value)
+{
+ const size_t byte_index = 15 - bit_index / 8;
+ const uint8_t bit_mask = (uint8_t) (1 << (bit_index % 8));
+ uint8_t mask = (uint8_t) -((bit_value & 1));
+
+# if defined(__GNUC__) || defined(__clang__)
+ __asm__ __volatile__("" : "+r"(mask)::);
+# endif
+ ip16[byte_index] = (ip16[byte_index] & ~bit_mask) | (bit_mask & mask);
+}
+
+static void
+pfx_shift_left(uint8_t ip16[16])
+{
+ BlockVec v = LOAD128(ip16);
+ const BlockVec shl = _mm_add_epi8(v, v);
+ const BlockVec msb = _mm_and_si128(_mm_srli_epi16(v, 7), _mm_set1_epi8(0x01));
+ const BlockVec carries = _mm_srli_si128(msb, 1);
+ v = _mm_or_si128(shl, carries);
+ STORE128(ip16, v);
+}
+
+static void
+pfx_pad_prefix(uint8_t padded_prefix[16], unsigned int prefix_len_bits)
+{
+ memset(padded_prefix, 0, 16);
+ if (prefix_len_bits == 0) {
+ padded_prefix[15] = 0x01;
+ } else {
+ padded_prefix[3] = 0x01;
+ padded_prefix[14] = 0xff;
+ padded_prefix[15] = 0xff;
+ }
+}
+
+static void
+pfx_encrypt(uint8_t *out, const uint8_t *in, const uint8_t *k)
+{
+ KeySchedule k1keys;
+ KeySchedule k2keys;
+ uint8_t diff[16];
+ uint8_t encrypted[16];
+ uint8_t padded_prefix[16];
+ uint8_t t[16];
+ BlockVec e1, e2, e;
+ unsigned int prefix_start = 0;
+ unsigned int prefix_len_bits;
+ unsigned int bit_pos;
+ uint8_t cipher_bit;
+ uint8_t original_bit;
+ size_t i;
+ uint8_t d;
+
+ expand_key(k1keys, k);
+ expand_key(k2keys, k + 16);
+
+ STORE128(diff, XOR128(k1keys[ROUNDS / 2], k2keys[ROUNDS / 2]));
+ d = 0;
+ for (i = 0; i < 16; i++) {
+ d |= diff[i];
+ }
+ if (d == 0) {
+ for (i = 0; i < 16; i++) {
+ diff[i] = k[i] ^ 0x5a;
+ }
+ expand_key(k2keys, diff);
+ }
+
+ if (is_ipv4_mapped(in)) {
+ prefix_start = 96;
+ }
+
+ pfx_pad_prefix(padded_prefix, prefix_start);
+
+ memset(encrypted, 0, 16);
+ if (prefix_start == 96) {
+ encrypted[10] = 0xff;
+ encrypted[11] = 0xff;
+ }
+
+ for (prefix_len_bits = prefix_start; prefix_len_bits < 128; prefix_len_bits++) {
+ e1 = XOR128(LOAD128(padded_prefix), k1keys[0]);
+ e2 = XOR128(LOAD128(padded_prefix), k2keys[0]);
+ for (i = 1; i < ROUNDS; i++) {
+ e1 = AES_ENCRYPT(e1, k1keys[i]);
+ e2 = AES_ENCRYPT(e2, k2keys[i]);
+ }
+ e1 = AES_ENCRYPTLAST(e1, k1keys[ROUNDS]);
+ e2 = AES_ENCRYPTLAST(e2, k2keys[ROUNDS]);
+
+ e = XOR128(e1, e2);
+ STORE128(t, e);
+
+ cipher_bit = t[15] & 1;
+ bit_pos = 127 - prefix_len_bits;
+ original_bit = pfx_get_bit(in, bit_pos);
+ pfx_set_bit(encrypted, bit_pos, original_bit ^ cipher_bit);
+
+ pfx_shift_left(padded_prefix);
+ pfx_set_bit(padded_prefix, 0, original_bit);
+ }
+
+ memcpy(out, encrypted, 16);
+}
+
+static void
+pfx_decrypt(uint8_t *out, const uint8_t *in, const uint8_t *k)
+{
+ KeySchedule k1keys;
+ KeySchedule k2keys;
+ uint8_t diff[16];
+ uint8_t decrypted[16];
+ uint8_t padded_prefix[16];
+ uint8_t t[16];
+ BlockVec e1, e2, e;
+ unsigned int prefix_start = 0;
+ unsigned int prefix_len_bits;
+ unsigned int bit_pos;
+ uint8_t cipher_bit;
+ uint8_t encrypted_bit;
+ uint8_t original_bit;
+ size_t i;
+ uint8_t d;
+
+ expand_key(k1keys, k);
+ expand_key(k2keys, k + 16);
+
+ STORE128(diff, XOR128(k1keys[ROUNDS / 2], k2keys[ROUNDS / 2]));
+ d = 0;
+ for (i = 0; i < 16; i++) {
+ d |= diff[i];
+ }
+ if (d == 0) {
+ for (i = 0; i < 16; i++) {
+ diff[i] = k[i] ^ 0x5a;
+ }
+ expand_key(k2keys, diff);
+ }
+
+ if (is_ipv4_mapped(in)) {
+ prefix_start = 96;
+ }
+
+ pfx_pad_prefix(padded_prefix, prefix_start);
+
+ memset(decrypted, 0, 16);
+ if (prefix_start == 96) {
+ decrypted[10] = 0xff;
+ decrypted[11] = 0xff;
+ }
+
+ for (prefix_len_bits = prefix_start; prefix_len_bits < 128; prefix_len_bits++) {
+ e1 = XOR128(LOAD128(padded_prefix), k1keys[0]);
+ e2 = XOR128(LOAD128(padded_prefix), k2keys[0]);
+ for (i = 1; i < ROUNDS; i++) {
+ e1 = AES_ENCRYPT(e1, k1keys[i]);
+ e2 = AES_ENCRYPT(e2, k2keys[i]);
+ }
+ e1 = AES_ENCRYPTLAST(e1, k1keys[ROUNDS]);
+ e2 = AES_ENCRYPTLAST(e2, k2keys[ROUNDS]);
+
+ e = XOR128(e1, e2);
+ STORE128(t, e);
+
+ cipher_bit = t[15] & 1;
+ bit_pos = 127 - prefix_len_bits;
+ encrypted_bit = pfx_get_bit(in, bit_pos);
+ original_bit = encrypted_bit ^ cipher_bit;
+ pfx_set_bit(decrypted, bit_pos, original_bit);
+
+ pfx_shift_left(padded_prefix);
+ pfx_set_bit(padded_prefix, 0, original_bit);
+ }
+
+ memcpy(out, decrypted, 16);
+}
+
+struct ipcrypt_implementation ipcrypt_aesni_implementation = {
+ SODIUM_C99(.encrypt =) encrypt, SODIUM_C99(.decrypt =) decrypt,
+ SODIUM_C99(.nd_encrypt =) nd_encrypt, SODIUM_C99(.nd_decrypt =) nd_decrypt,
+ SODIUM_C99(.ndx_encrypt =) ndx_encrypt, SODIUM_C99(.ndx_decrypt =) ndx_decrypt,
+ SODIUM_C99(.pfx_encrypt =) pfx_encrypt, SODIUM_C99(.pfx_decrypt =) pfx_decrypt
+};
+
+# ifdef __clang__
+# pragma clang attribute pop
+# endif
+
+#endif
diff --git a/src/libsodium/crypto_ipcrypt/ipcrypt_aesni.h b/src/libsodium/crypto_ipcrypt/ipcrypt_aesni.h
new file mode 100644
index 00000000..f01a0c93
--- /dev/null
+++ b/src/libsodium/crypto_ipcrypt/ipcrypt_aesni.h
@@ -0,0 +1,8 @@
+#ifndef ipcrypt_aesni_H
+#define ipcrypt_aesni_H
+
+#include "implementations.h"
+
+extern struct ipcrypt_implementation ipcrypt_aesni_implementation;
+
+#endif
diff --git a/src/libsodium/crypto_ipcrypt/ipcrypt_armcrypto.c b/src/libsodium/crypto_ipcrypt/ipcrypt_armcrypto.c
new file mode 100644
index 00000000..616cf321
--- /dev/null
+++ b/src/libsodium/crypto_ipcrypt/ipcrypt_armcrypto.c
@@ -0,0 +1,530 @@
+#include
+#include
+#include
+
+#include "crypto_ipcrypt.h"
+#include "utils.h"
+
+#include "private/common.h"
+
+#if defined(HAVE_ARMCRYPTO) && defined(NATIVE_LITTLE_ENDIAN)
+
+# include "ipcrypt_armcrypto.h"
+
+# ifndef __ARM_FEATURE_CRYPTO
+# define __ARM_FEATURE_CRYPTO 1
+# endif
+# ifndef __ARM_FEATURE_AES
+# define __ARM_FEATURE_AES 1
+# endif
+
+# include
+
+# ifdef __clang__
+# pragma clang attribute push(__attribute__((target("neon,crypto,aes"))), \
+ apply_to = function)
+# elif defined(__GNUC__)
+# pragma GCC target("+simd+crypto")
+# endif
+
+# define ROUNDS 10
+
+typedef uint64x2_t BlockVec;
+
+# define LOAD128(a) vld1q_u64((const uint64_t *) (const void *) (a))
+# define STORE128(a, b) vst1q_u64((uint64_t *) (void *) (a), (b))
+# define XOR128(a, b) veorq_u64((a), (b))
+# define XOR128_3(a, b, c) veorq_u64(veorq_u64((a), (b)), (c))
+# define SET64x2(a, b) vsetq_lane_u64((uint64_t) (a), vmovq_n_u64((uint64_t) (b)), 1)
+# define BYTESHL128(a, b) \
+ vreinterpretq_u64_u8(vextq_s8(vdupq_n_s8(0), (int8x16_t) vreinterpretq_u8_u64(a), 16 - (b)))
+
+# define AES_XENCRYPT(block_vec, rkey) \
+ vreinterpretq_u64_u8( \
+ vaesmcq_u8(vaeseq_u8(vreinterpretq_u8_u64(rkey), vreinterpretq_u8_u64(block_vec))))
+# define AES_XENCRYPTLAST(block_vec, rkey) \
+ vreinterpretq_u64_u8(vaeseq_u8(vreinterpretq_u8_u64(rkey), vreinterpretq_u8_u64(block_vec)))
+# define AES_XDECRYPT(block_vec, rkey) \
+ vreinterpretq_u64_u8( \
+ vaesimcq_u8(vaesdq_u8(vreinterpretq_u8_u64(rkey), vreinterpretq_u8_u64(block_vec))))
+# define AES_XDECRYPTLAST(block_vec, rkey) \
+ vreinterpretq_u64_u8(vaesdq_u8(vreinterpretq_u8_u64(rkey), vreinterpretq_u8_u64(block_vec)))
+# define RKINVERT(rkey) vreinterpretq_u64_u8(vaesimcq_u8(vreinterpretq_u8_u64(rkey)))
+
+# define SHUFFLE32x4(x, a, b, c, d) \
+ vreinterpretq_u64_u32(__builtin_shufflevector( \
+ vreinterpretq_u32_u64(x), vreinterpretq_u32_u64(x), (a), (b), (c), (d)))
+
+typedef BlockVec KeySchedule[1 + ROUNDS];
+
+static BlockVec
+AES_KEYGEN(BlockVec block_vec, const int rc)
+{
+ uint8x16_t a = vaeseq_u8(vreinterpretq_u8_u64(block_vec), vmovq_n_u8(0));
+ const uint8x16_t b =
+ __builtin_shufflevector(a, a, 4, 1, 14, 11, 1, 14, 11, 4, 12, 9, 6, 3, 9, 6, 3, 12);
+ const uint64x2_t c = SET64x2((uint64_t) rc << 32, (uint64_t) rc << 32);
+ return XOR128(vreinterpretq_u64_u8(b), c);
+}
+
+static void
+expand_key(BlockVec *rkeys, const uint8_t key[16])
+{
+ BlockVec t, s;
+ size_t i = 0;
+
+# define EXPAND_KEY(RC) \
+ rkeys[i++] = t; \
+ s = AES_KEYGEN(t, RC); \
+ t = XOR128(t, BYTESHL128(t, 4)); \
+ t = XOR128(t, BYTESHL128(t, 8)); \
+ t = XOR128(t, SHUFFLE32x4(s, 3, 3, 3, 3));
+
+ t = LOAD128(key);
+ EXPAND_KEY(0x01);
+ EXPAND_KEY(0x02);
+ EXPAND_KEY(0x04);
+ EXPAND_KEY(0x08);
+ EXPAND_KEY(0x10);
+ EXPAND_KEY(0x20);
+ EXPAND_KEY(0x40);
+ EXPAND_KEY(0x80);
+ EXPAND_KEY(0x1b);
+ EXPAND_KEY(0x36);
+ rkeys[i++] = t;
+}
+
+static void
+aes_encrypt(uint8_t out[16], const uint8_t in[16], const BlockVec *rkeys)
+{
+ BlockVec t;
+ size_t i;
+
+ t = AES_XENCRYPT(LOAD128(in), rkeys[0]);
+ for (i = 1; i < ROUNDS - 1; i++) {
+ t = AES_XENCRYPT(t, rkeys[i]);
+ }
+ t = AES_XENCRYPTLAST(t, rkeys[i]);
+ t = XOR128(t, rkeys[ROUNDS]);
+ STORE128(out, t);
+}
+
+static void
+aes_decrypt(uint8_t out[16], const uint8_t in[16], const BlockVec *rkeys)
+{
+ KeySchedule rkeys_inv;
+ BlockVec t;
+ size_t i;
+
+ for (i = 0; i < ROUNDS - 1; i++) {
+ rkeys_inv[i] = RKINVERT(rkeys[ROUNDS - 1 - i]);
+ }
+ t = AES_XDECRYPT(LOAD128(in), rkeys[ROUNDS]);
+ for (i = 0; i < ROUNDS - 2; i++) {
+ t = AES_XDECRYPT(t, rkeys_inv[i]);
+ }
+ t = AES_XDECRYPTLAST(t, rkeys_inv[i]);
+ t = XOR128(t, rkeys[0]);
+ STORE128(out, t);
+}
+
+static BlockVec
+tweak_expand(const uint8_t tweak[8])
+{
+ return vreinterpretq_u64_u32(vmovl_u16(vld1_u16((const uint16_t *) (tweak))));
+}
+
+static void
+aes_encrypt_with_tweak(uint8_t out[16], const uint8_t in[16], const uint8_t tweak[8],
+ const BlockVec *rkeys)
+{
+ const BlockVec tweak_block = tweak_expand(tweak);
+ BlockVec t;
+ size_t i;
+
+ t = AES_XENCRYPT(LOAD128(in), XOR128(tweak_block, rkeys[0]));
+ for (i = 1; i < ROUNDS - 1; i++) {
+ t = AES_XENCRYPT(t, XOR128(tweak_block, rkeys[i]));
+ }
+ t = AES_XENCRYPTLAST(t, XOR128(tweak_block, rkeys[i]));
+ t = XOR128(t, XOR128(tweak_block, rkeys[ROUNDS]));
+ STORE128(out, t);
+}
+
+static void
+aes_decrypt_with_tweak(uint8_t out[16], const uint8_t in[16], const uint8_t tweak[8],
+ const BlockVec *rkeys)
+{
+ KeySchedule rkeys_inv;
+ const BlockVec tweak_block = tweak_expand(tweak);
+ const BlockVec tweak_block_inv = RKINVERT(tweak_block);
+ BlockVec t;
+ size_t i;
+
+ for (i = 0; i < ROUNDS - 1; i++) {
+ rkeys_inv[i] = RKINVERT(rkeys[ROUNDS - 1 - i]);
+ }
+ t = AES_XDECRYPT(LOAD128(in), XOR128(tweak_block, rkeys[ROUNDS]));
+ for (i = 0; i < ROUNDS - 2; i++) {
+ t = AES_XDECRYPT(t, XOR128(tweak_block_inv, rkeys_inv[i]));
+ }
+ t = AES_XDECRYPTLAST(t, XOR128(tweak_block_inv, rkeys_inv[i]));
+ t = XOR128(t, XOR128(tweak_block, rkeys[0]));
+ STORE128(out, t);
+}
+
+static BlockVec
+aes_xex_tweak(const uint8_t tweak[16], const BlockVec *tkeys)
+{
+ BlockVec tt;
+ size_t i;
+
+ tt = AES_XENCRYPT(LOAD128(tweak), tkeys[0]);
+ for (i = 1; i < ROUNDS - 1; i++) {
+ tt = AES_XENCRYPT(tt, tkeys[i]);
+ }
+ tt = AES_XENCRYPTLAST(tt, tkeys[i]);
+ tt = XOR128(tt, tkeys[ROUNDS]);
+ return tt;
+}
+
+static void
+aes_xex_encrypt(uint8_t out[16], const uint8_t in[16], const uint8_t tweak[16],
+ const BlockVec *tkeys, const BlockVec *rkeys)
+{
+ const BlockVec tt = aes_xex_tweak(tweak, tkeys);
+ BlockVec t;
+ size_t i;
+
+ t = AES_XENCRYPT(XOR128(LOAD128(in), tt), rkeys[0]);
+ for (i = 1; i < ROUNDS - 1; i++) {
+ t = AES_XENCRYPT(t, rkeys[i]);
+ }
+ t = AES_XENCRYPTLAST(t, rkeys[i]);
+ t = XOR128_3(t, rkeys[ROUNDS], tt);
+ STORE128(out, t);
+}
+
+static void
+aes_xex_decrypt(uint8_t out[16], const uint8_t in[16], const uint8_t tweak[16],
+ const BlockVec *tkeys, const BlockVec *rkeys)
+{
+ KeySchedule rkeys_inv;
+ const BlockVec tt = aes_xex_tweak(tweak, tkeys);
+ BlockVec t;
+ size_t i;
+
+ for (i = 0; i < ROUNDS - 1; i++) {
+ rkeys_inv[i] = RKINVERT(rkeys[ROUNDS - 1 - i]);
+ }
+ t = AES_XDECRYPT(XOR128(LOAD128(in), tt), rkeys[ROUNDS]);
+ for (i = 0; i < ROUNDS - 2; i++) {
+ t = AES_XDECRYPT(t, rkeys_inv[i]);
+ }
+ t = AES_XDECRYPTLAST(t, rkeys_inv[i]);
+ t = XOR128_3(t, rkeys[0], tt);
+ STORE128(out, t);
+}
+
+static void
+encrypt(uint8_t *out, const uint8_t *in, const uint8_t *k)
+{
+ KeySchedule rkeys;
+
+ expand_key(rkeys, k);
+ aes_encrypt(out, in, rkeys);
+}
+
+static void
+decrypt(uint8_t *out, const uint8_t *in, const uint8_t *k)
+{
+ KeySchedule rkeys;
+
+ expand_key(rkeys, k);
+ aes_decrypt(out, in, rkeys);
+}
+
+static void
+nd_encrypt(uint8_t *out, const uint8_t *in, const uint8_t *t, const uint8_t *k)
+{
+ KeySchedule rkeys;
+
+ expand_key(rkeys, k);
+ memcpy(out, t, 8);
+ aes_encrypt_with_tweak(out + 8, in, t, rkeys);
+}
+
+static void
+nd_decrypt(uint8_t *out, const uint8_t *in, const uint8_t *k)
+{
+ KeySchedule rkeys;
+
+ expand_key(rkeys, k);
+ aes_decrypt_with_tweak(out, in + 8, in, rkeys);
+}
+
+static void
+ndx_encrypt(uint8_t *out, const uint8_t *in, const uint8_t *t, const uint8_t *k)
+{
+ KeySchedule tkeys;
+ KeySchedule rkeys;
+ uint8_t diff[16];
+ size_t i;
+ uint8_t d;
+
+ expand_key(tkeys, k + 16);
+ expand_key(rkeys, k);
+
+ STORE128(diff, XOR128(tkeys[ROUNDS / 2], rkeys[ROUNDS / 2]));
+ d = 0;
+ for (i = 0; i < 16; i++) {
+ d |= diff[i];
+ }
+ if (d == 0) {
+ for (i = 0; i < 16; i++) {
+ diff[i] = k[i] ^ 0x5a;
+ }
+ expand_key(rkeys, diff);
+ }
+
+ memcpy(out, t, 16);
+ aes_xex_encrypt(out + 16, in, t, tkeys, rkeys);
+}
+
+static void
+ndx_decrypt(uint8_t *out, const uint8_t *in, const uint8_t *k)
+{
+ KeySchedule tkeys;
+ KeySchedule rkeys;
+ uint8_t diff[16];
+ size_t i;
+ uint8_t d;
+
+ expand_key(tkeys, k + 16);
+ expand_key(rkeys, k);
+
+ STORE128(diff, XOR128(tkeys[ROUNDS / 2], rkeys[ROUNDS / 2]));
+ d = 0;
+ for (i = 0; i < 16; i++) {
+ d |= diff[i];
+ }
+ if (d == 0) {
+ for (i = 0; i < 16; i++) {
+ diff[i] = k[i] ^ 0x5a;
+ }
+ expand_key(rkeys, diff);
+ }
+
+ aes_xex_decrypt(out, in + 16, in, tkeys, rkeys);
+}
+
+static int
+is_ipv4_mapped(const uint8_t ip16[16])
+{
+ static const uint8_t ipv4_mapped_prefix[12] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xff, 0xff };
+
+ return memcmp(ip16, ipv4_mapped_prefix, 12) == 0;
+}
+
+static uint8_t
+pfx_get_bit(const uint8_t ip16[16], unsigned int bit_index)
+{
+ return (ip16[15 - bit_index / 8] >> (bit_index % 8)) & 1;
+}
+
+static void
+pfx_set_bit(uint8_t ip16[16], const unsigned int bit_index, const uint8_t bit_value)
+{
+ const size_t byte_index = 15 - bit_index / 8;
+ const uint8_t bit_mask = (uint8_t) (1 << (bit_index % 8));
+ uint8_t mask = (uint8_t) -((bit_value & 1));
+
+# if defined(__GNUC__) || defined(__clang__)
+ __asm__ __volatile__("" : "+r"(mask)::);
+# endif
+ ip16[byte_index] = (ip16[byte_index] & ~bit_mask) | (bit_mask & mask);
+}
+
+static void
+pfx_shift_left(uint8_t ip16[16])
+{
+ BlockVec v = LOAD128(ip16);
+ const BlockVec shl = vshlq_n_u8(vreinterpretq_u8_u64(v), 1);
+ const BlockVec msb = vshrq_n_u8(vreinterpretq_u8_u64(v), 7);
+ const BlockVec zero = vdupq_n_u8(0);
+ const BlockVec carries = vextq_u8(vreinterpretq_u8_u64(msb), zero, 1);
+ v = vreinterpretq_u64_u8(vorrq_u8(shl, carries));
+ STORE128(ip16, v);
+}
+
+static void
+pfx_pad_prefix(uint8_t padded_prefix[16], unsigned int prefix_len_bits)
+{
+ memset(padded_prefix, 0, 16);
+ if (prefix_len_bits == 0) {
+ padded_prefix[15] = 0x01;
+ } else {
+ padded_prefix[3] = 0x01;
+ padded_prefix[14] = 0xff;
+ padded_prefix[15] = 0xff;
+ }
+}
+
+static void
+pfx_encrypt(uint8_t *out, const uint8_t *in, const uint8_t *k)
+{
+ KeySchedule k1keys;
+ KeySchedule k2keys;
+ uint8_t diff[16];
+ uint8_t encrypted[16];
+ uint8_t padded_prefix[16];
+ uint8_t t[16];
+ BlockVec e1, e2, e;
+ unsigned int prefix_start = 0;
+ unsigned int prefix_len_bits;
+ unsigned int bit_pos;
+ uint8_t cipher_bit;
+ uint8_t original_bit;
+ size_t i;
+ uint8_t d;
+
+ expand_key(k1keys, k);
+ expand_key(k2keys, k + 16);
+
+ STORE128(diff, XOR128(k1keys[ROUNDS / 2], k2keys[ROUNDS / 2]));
+ d = 0;
+ for (i = 0; i < 16; i++) {
+ d |= diff[i];
+ }
+ if (d == 0) {
+ for (i = 0; i < 16; i++) {
+ diff[i] = k[i] ^ 0x5a;
+ }
+ expand_key(k2keys, diff);
+ }
+
+ if (is_ipv4_mapped(in)) {
+ prefix_start = 96;
+ }
+
+ pfx_pad_prefix(padded_prefix, prefix_start);
+
+ memset(encrypted, 0, 16);
+ if (prefix_start == 96) {
+ encrypted[10] = 0xff;
+ encrypted[11] = 0xff;
+ }
+
+ for (prefix_len_bits = prefix_start; prefix_len_bits < 128; prefix_len_bits++) {
+ e1 = AES_XENCRYPT(LOAD128(padded_prefix), k1keys[0]);
+ e2 = AES_XENCRYPT(LOAD128(padded_prefix), k2keys[0]);
+ for (i = 1; i < ROUNDS - 1; i++) {
+ e1 = AES_XENCRYPT(e1, k1keys[i]);
+ e2 = AES_XENCRYPT(e2, k2keys[i]);
+ }
+ e1 = AES_XENCRYPTLAST(e1, k1keys[i]);
+ e2 = AES_XENCRYPTLAST(e2, k2keys[i]);
+ e1 = XOR128(e1, k1keys[ROUNDS]);
+ e2 = XOR128(e2, k2keys[ROUNDS]);
+
+ e = XOR128(e1, e2);
+ STORE128(t, e);
+
+ cipher_bit = t[15] & 1;
+ bit_pos = 127 - prefix_len_bits;
+ original_bit = pfx_get_bit(in, bit_pos);
+ pfx_set_bit(encrypted, bit_pos, original_bit ^ cipher_bit);
+
+ pfx_shift_left(padded_prefix);
+ pfx_set_bit(padded_prefix, 0, original_bit);
+ }
+
+ memcpy(out, encrypted, 16);
+}
+
+static void
+pfx_decrypt(uint8_t *out, const uint8_t *in, const uint8_t *k)
+{
+ KeySchedule k1keys;
+ KeySchedule k2keys;
+ uint8_t diff[16];
+ uint8_t decrypted[16];
+ uint8_t padded_prefix[16];
+ uint8_t t[16];
+ BlockVec e1, e2, e;
+ unsigned int prefix_start = 0;
+ unsigned int prefix_len_bits;
+ unsigned int bit_pos;
+ uint8_t cipher_bit;
+ uint8_t encrypted_bit;
+ uint8_t original_bit;
+ size_t i;
+ uint8_t d;
+
+ expand_key(k1keys, k);
+ expand_key(k2keys, k + 16);
+
+ STORE128(diff, XOR128(k1keys[ROUNDS / 2], k2keys[ROUNDS / 2]));
+ d = 0;
+ for (i = 0; i < 16; i++) {
+ d |= diff[i];
+ }
+ if (d == 0) {
+ for (i = 0; i < 16; i++) {
+ diff[i] = k[i] ^ 0x5a;
+ }
+ expand_key(k2keys, diff);
+ }
+
+ if (is_ipv4_mapped(in)) {
+ prefix_start = 96;
+ }
+
+ pfx_pad_prefix(padded_prefix, prefix_start);
+
+ memset(decrypted, 0, 16);
+ if (prefix_start == 96) {
+ decrypted[10] = 0xff;
+ decrypted[11] = 0xff;
+ }
+
+ for (prefix_len_bits = prefix_start; prefix_len_bits < 128; prefix_len_bits++) {
+ e1 = AES_XENCRYPT(LOAD128(padded_prefix), k1keys[0]);
+ e2 = AES_XENCRYPT(LOAD128(padded_prefix), k2keys[0]);
+ for (i = 1; i < ROUNDS - 1; i++) {
+ e1 = AES_XENCRYPT(e1, k1keys[i]);
+ e2 = AES_XENCRYPT(e2, k2keys[i]);
+ }
+ e1 = AES_XENCRYPTLAST(e1, k1keys[i]);
+ e2 = AES_XENCRYPTLAST(e2, k2keys[i]);
+ e1 = XOR128(e1, k1keys[ROUNDS]);
+ e2 = XOR128(e2, k2keys[ROUNDS]);
+
+ e = XOR128(e1, e2);
+ STORE128(t, e);
+
+ cipher_bit = t[15] & 1;
+ bit_pos = 127 - prefix_len_bits;
+ encrypted_bit = pfx_get_bit(in, bit_pos);
+ original_bit = encrypted_bit ^ cipher_bit;
+ pfx_set_bit(decrypted, bit_pos, original_bit);
+
+ pfx_shift_left(padded_prefix);
+ pfx_set_bit(padded_prefix, 0, original_bit);
+ }
+
+ memcpy(out, decrypted, 16);
+}
+
+struct ipcrypt_implementation ipcrypt_armcrypto_implementation = {
+ SODIUM_C99(.encrypt =) encrypt, SODIUM_C99(.decrypt =) decrypt,
+ SODIUM_C99(.nd_encrypt =) nd_encrypt, SODIUM_C99(.nd_decrypt =) nd_decrypt,
+ SODIUM_C99(.ndx_encrypt =) ndx_encrypt, SODIUM_C99(.ndx_decrypt =) ndx_decrypt,
+ SODIUM_C99(.pfx_encrypt =) pfx_encrypt, SODIUM_C99(.pfx_decrypt =) pfx_decrypt
+};
+
+# ifdef __clang__
+# pragma clang attribute pop
+# endif
+
+#endif
diff --git a/src/libsodium/crypto_ipcrypt/ipcrypt_armcrypto.h b/src/libsodium/crypto_ipcrypt/ipcrypt_armcrypto.h
new file mode 100644
index 00000000..4195e0ee
--- /dev/null
+++ b/src/libsodium/crypto_ipcrypt/ipcrypt_armcrypto.h
@@ -0,0 +1,8 @@
+#ifndef ipcrypt_armcrypto_H
+#define ipcrypt_armcrypto_H
+
+#include "implementations.h"
+
+extern struct ipcrypt_implementation ipcrypt_armcrypto_implementation;
+
+#endif
diff --git a/src/libsodium/crypto_ipcrypt/ipcrypt_soft.c b/src/libsodium/crypto_ipcrypt/ipcrypt_soft.c
new file mode 100644
index 00000000..8f1fd8a8
--- /dev/null
+++ b/src/libsodium/crypto_ipcrypt/ipcrypt_soft.c
@@ -0,0 +1,463 @@
+#include
+#include
+#include
+
+#include "crypto_ipcrypt.h"
+#include "utils.h"
+
+#include "private/common.h"
+#include "private/softaes.h"
+
+#include "ipcrypt_soft.h"
+
+#define ROUNDS 10
+
+typedef SoftAesBlock aes_block_t;
+#define AES_BLOCK_XOR(A, B) softaes_block_xor((A), (B))
+#define AES_BLOCK_AND(A, B) softaes_block_and((A), (B))
+#define AES_BLOCK_LOAD(A) softaes_block_load(A)
+#define AES_BLOCK_LOAD_64x2(A, B) softaes_block_load64x2((A), (B))
+#define AES_BLOCK_STORE(A, B) softaes_block_store((A), (B))
+#define AES_ENC(A, B) softaes_block_encrypt((A), (B))
+#define AES_ENCLAST(A, B) softaes_block_encryptlast((A), (B))
+#define AES_DEC(A, B) softaes_block_decrypt((A), (B))
+#define AES_DECLAST(A, B) softaes_block_decryptlast((A), (B))
+#define AES_INV_MIX(A) softaes_inv_mix_columns((A))
+
+typedef aes_block_t KeySchedule[1 + ROUNDS];
+
+static void
+expand_key(KeySchedule rkeys, const uint8_t key[16])
+{
+ softaes_expand_key128(rkeys, key);
+}
+
+static void
+aes_encrypt(uint8_t out[16], const uint8_t in[16], const KeySchedule rkeys)
+{
+ aes_block_t t;
+ size_t i;
+
+ t = AES_BLOCK_XOR(AES_BLOCK_LOAD(in), rkeys[0]);
+ for (i = 1; i < ROUNDS; i++) {
+ t = AES_ENC(t, rkeys[i]);
+ }
+ t = AES_ENCLAST(t, rkeys[ROUNDS]);
+ AES_BLOCK_STORE(out, t);
+}
+
+static void
+aes_decrypt(uint8_t out[16], const uint8_t in[16], const KeySchedule rkeys)
+{
+ KeySchedule rkeys_inv;
+ aes_block_t t;
+ size_t i;
+
+ for (i = 0; i <= ROUNDS; i++) {
+ rkeys_inv[i] = rkeys[i];
+ }
+ softaes_invert_key_schedule128(rkeys_inv);
+
+ t = AES_BLOCK_XOR(AES_BLOCK_LOAD(in), rkeys_inv[ROUNDS]);
+ for (i = ROUNDS - 1; i > 0; i--) {
+ t = AES_DEC(t, rkeys_inv[i]);
+ }
+ t = AES_DECLAST(t, rkeys_inv[0]);
+ AES_BLOCK_STORE(out, t);
+}
+
+static aes_block_t
+tweak_expand(const uint8_t tweak[8])
+{
+ aes_block_t out;
+
+ out.w0 = ((uint32_t) tweak[0]) | ((uint32_t) tweak[1] << 8);
+ out.w1 = ((uint32_t) tweak[2]) | ((uint32_t) tweak[3] << 8);
+ out.w2 = ((uint32_t) tweak[4]) | ((uint32_t) tweak[5] << 8);
+ out.w3 = ((uint32_t) tweak[6]) | ((uint32_t) tweak[7] << 8);
+
+ return out;
+}
+
+static void
+aes_encrypt_with_tweak(uint8_t out[16], const uint8_t in[16], const uint8_t tweak[8],
+ const KeySchedule rkeys)
+{
+ const aes_block_t tweak_block = tweak_expand(tweak);
+ aes_block_t t;
+ size_t i;
+
+ t = AES_BLOCK_XOR(AES_BLOCK_XOR(AES_BLOCK_LOAD(in), tweak_block), rkeys[0]);
+ for (i = 1; i < ROUNDS; i++) {
+ t = AES_ENC(t, AES_BLOCK_XOR(tweak_block, rkeys[i]));
+ }
+ t = AES_ENCLAST(t, AES_BLOCK_XOR(tweak_block, rkeys[ROUNDS]));
+ AES_BLOCK_STORE(out, t);
+}
+
+static void
+aes_decrypt_with_tweak(uint8_t out[16], const uint8_t in[16], const uint8_t tweak[8],
+ const KeySchedule rkeys)
+{
+ KeySchedule rkeys_inv;
+ const aes_block_t tweak_block = tweak_expand(tweak);
+ const aes_block_t tweak_block_inv = AES_INV_MIX(tweak_block);
+ aes_block_t t;
+ size_t i;
+
+ for (i = 0; i <= ROUNDS; i++) {
+ rkeys_inv[i] = rkeys[i];
+ }
+ softaes_invert_key_schedule128(rkeys_inv);
+
+ t = AES_BLOCK_XOR(AES_BLOCK_XOR(AES_BLOCK_LOAD(in), tweak_block), rkeys_inv[ROUNDS]);
+ for (i = ROUNDS - 1; i > 0; i--) {
+ t = AES_DEC(t, AES_BLOCK_XOR(tweak_block_inv, rkeys_inv[i]));
+ }
+ t = AES_DECLAST(t, AES_BLOCK_XOR(tweak_block, rkeys_inv[0]));
+ AES_BLOCK_STORE(out, t);
+}
+
+static aes_block_t
+aes_xex_tweak(const uint8_t tweak[16], const KeySchedule tkeys)
+{
+ aes_block_t tt;
+ size_t i;
+
+ tt = AES_BLOCK_XOR(AES_BLOCK_LOAD(tweak), tkeys[0]);
+ for (i = 1; i < ROUNDS; i++) {
+ tt = AES_ENC(tt, tkeys[i]);
+ }
+ tt = AES_ENCLAST(tt, tkeys[ROUNDS]);
+ return tt;
+}
+
+static void
+aes_xex_encrypt(uint8_t out[16], const uint8_t in[16], const uint8_t tweak[16],
+ const KeySchedule tkeys, const KeySchedule rkeys)
+{
+ const aes_block_t tt = aes_xex_tweak(tweak, tkeys);
+ aes_block_t t;
+ size_t i;
+
+ t = AES_BLOCK_XOR(AES_BLOCK_XOR(AES_BLOCK_LOAD(in), tt), rkeys[0]);
+ for (i = 1; i < ROUNDS; i++) {
+ t = AES_ENC(t, rkeys[i]);
+ }
+ t = AES_ENCLAST(t, AES_BLOCK_XOR(rkeys[ROUNDS], tt));
+ AES_BLOCK_STORE(out, t);
+}
+
+static void
+aes_xex_decrypt(uint8_t out[16], const uint8_t in[16], const uint8_t tweak[16],
+ const KeySchedule tkeys, const KeySchedule rkeys)
+{
+ KeySchedule rkeys_inv;
+ const aes_block_t tt = aes_xex_tweak(tweak, tkeys);
+ aes_block_t t;
+ size_t i;
+
+ for (i = 0; i <= ROUNDS; i++) {
+ rkeys_inv[i] = rkeys[i];
+ }
+ softaes_invert_key_schedule128(rkeys_inv);
+
+ t = AES_BLOCK_XOR(AES_BLOCK_XOR(AES_BLOCK_LOAD(in), tt), rkeys_inv[ROUNDS]);
+ for (i = ROUNDS - 1; i > 0; i--) {
+ t = AES_DEC(t, rkeys_inv[i]);
+ }
+ t = AES_DECLAST(t, AES_BLOCK_XOR(rkeys_inv[0], tt));
+ AES_BLOCK_STORE(out, t);
+}
+
+static void
+encrypt(uint8_t *out, const uint8_t *in, const uint8_t *k)
+{
+ KeySchedule rkeys;
+
+ expand_key(rkeys, k);
+ aes_encrypt(out, in, rkeys);
+}
+
+static void
+decrypt(uint8_t *out, const uint8_t *in, const uint8_t *k)
+{
+ KeySchedule rkeys;
+
+ expand_key(rkeys, k);
+ aes_decrypt(out, in, rkeys);
+}
+
+static void
+nd_encrypt(uint8_t *out, const uint8_t *in, const uint8_t *t, const uint8_t *k)
+{
+ KeySchedule rkeys;
+
+ expand_key(rkeys, k);
+ memcpy(out, t, 8);
+ aes_encrypt_with_tweak(out + 8, in, t, rkeys);
+}
+
+static void
+nd_decrypt(uint8_t *out, const uint8_t *in, const uint8_t *k)
+{
+ KeySchedule rkeys;
+
+ expand_key(rkeys, k);
+ aes_decrypt_with_tweak(out, in + 8, in, rkeys);
+}
+
+static void
+ndx_encrypt(uint8_t *out, const uint8_t *in, const uint8_t *t, const uint8_t *k)
+{
+ KeySchedule tkeys;
+ KeySchedule rkeys;
+ uint8_t diff[16];
+ size_t i;
+ uint8_t d;
+
+ expand_key(tkeys, k + 16);
+ expand_key(rkeys, k);
+
+ AES_BLOCK_STORE(diff, AES_BLOCK_XOR(tkeys[ROUNDS / 2], rkeys[ROUNDS / 2]));
+ d = 0;
+ for (i = 0; i < 16; i++) {
+ d |= diff[i];
+ }
+ if (d == 0) {
+ for (i = 0; i < 16; i++) {
+ diff[i] = k[i] ^ 0x5a;
+ }
+ expand_key(rkeys, diff);
+ }
+
+ memcpy(out, t, 16);
+ aes_xex_encrypt(out + 16, in, t, tkeys, rkeys);
+}
+
+static void
+ndx_decrypt(uint8_t *out, const uint8_t *in, const uint8_t *k)
+{
+ KeySchedule tkeys;
+ KeySchedule rkeys;
+ uint8_t diff[16];
+ size_t i;
+ uint8_t d;
+
+ expand_key(tkeys, k + 16);
+ expand_key(rkeys, k);
+
+ AES_BLOCK_STORE(diff, AES_BLOCK_XOR(tkeys[ROUNDS / 2], rkeys[ROUNDS / 2]));
+ d = 0;
+ for (i = 0; i < 16; i++) {
+ d |= diff[i];
+ }
+ if (d == 0) {
+ for (i = 0; i < 16; i++) {
+ diff[i] = k[i] ^ 0x5a;
+ }
+ expand_key(rkeys, diff);
+ }
+
+ aes_xex_decrypt(out, in + 16, in, tkeys, rkeys);
+}
+
+static int
+is_ipv4_mapped(const uint8_t ip16[16])
+{
+ static const uint8_t ipv4_mapped_prefix[12] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xff, 0xff };
+
+ return memcmp(ip16, ipv4_mapped_prefix, 12) == 0;
+}
+
+static uint8_t
+pfx_get_bit(const uint8_t ip16[16], unsigned int bit_index)
+{
+ return (ip16[15 - bit_index / 8] >> (bit_index % 8)) & 1;
+}
+
+static void
+pfx_set_bit(uint8_t ip16[16], const unsigned int bit_index, const uint8_t bit_value)
+{
+ const size_t byte_index = 15 - bit_index / 8;
+ const uint8_t bit_mask = (uint8_t) (1 << (bit_index % 8));
+ uint8_t mask = (uint8_t) -((bit_value & 1));
+
+#if defined(__GNUC__) || defined(__clang__)
+ __asm__ __volatile__("" : "+r"(mask)::);
+#endif
+ ip16[byte_index] = (ip16[byte_index] & ~bit_mask) | (bit_mask & mask);
+}
+
+static void
+pfx_shift_left(uint8_t ip16[16])
+{
+ size_t i;
+
+ for (i = 0; i < 15; i++) {
+ ip16[i] = (ip16[i] << 1) | (ip16[i + 1] >> 7);
+ }
+ ip16[15] <<= 1;
+}
+
+static void
+pfx_pad_prefix(uint8_t padded_prefix[16], unsigned int prefix_len_bits)
+{
+ memset(padded_prefix, 0, 16);
+ if (prefix_len_bits == 0) {
+ padded_prefix[15] = 0x01;
+ } else {
+ padded_prefix[3] = 0x01;
+ padded_prefix[14] = 0xff;
+ padded_prefix[15] = 0xff;
+ }
+}
+
+static void
+pfx_encrypt(uint8_t *out, const uint8_t *in, const uint8_t *k)
+{
+ KeySchedule k1keys;
+ KeySchedule k2keys;
+ uint8_t diff[16];
+ uint8_t encrypted[16];
+ uint8_t padded_prefix[16];
+ uint8_t t[16];
+ aes_block_t e1, e2, e;
+ unsigned int prefix_start = 0;
+ unsigned int prefix_len_bits;
+ unsigned int bit_pos;
+ uint8_t cipher_bit;
+ uint8_t original_bit;
+ size_t i;
+ uint8_t d;
+
+ expand_key(k1keys, k);
+ expand_key(k2keys, k + 16);
+
+ AES_BLOCK_STORE(diff, AES_BLOCK_XOR(k1keys[ROUNDS / 2], k2keys[ROUNDS / 2]));
+ d = 0;
+ for (i = 0; i < 16; i++) {
+ d |= diff[i];
+ }
+ if (d == 0) {
+ for (i = 0; i < 16; i++) {
+ diff[i] = k[i] ^ 0x5a;
+ }
+ expand_key(k2keys, diff);
+ }
+
+ if (is_ipv4_mapped(in)) {
+ prefix_start = 96;
+ }
+
+ pfx_pad_prefix(padded_prefix, prefix_start);
+
+ memset(encrypted, 0, 16);
+ if (prefix_start == 96) {
+ encrypted[10] = 0xff;
+ encrypted[11] = 0xff;
+ }
+
+ for (prefix_len_bits = prefix_start; prefix_len_bits < 128; prefix_len_bits++) {
+ e1 = AES_BLOCK_XOR(AES_BLOCK_LOAD(padded_prefix), k1keys[0]);
+ e2 = AES_BLOCK_XOR(AES_BLOCK_LOAD(padded_prefix), k2keys[0]);
+ for (i = 1; i < ROUNDS; i++) {
+ e1 = AES_ENC(e1, k1keys[i]);
+ e2 = AES_ENC(e2, k2keys[i]);
+ }
+ e1 = AES_ENCLAST(e1, k1keys[ROUNDS]);
+ e2 = AES_ENCLAST(e2, k2keys[ROUNDS]);
+
+ e = AES_BLOCK_XOR(e1, e2);
+ AES_BLOCK_STORE(t, e);
+
+ cipher_bit = t[15] & 1;
+ bit_pos = 127 - prefix_len_bits;
+ original_bit = pfx_get_bit(in, bit_pos);
+ pfx_set_bit(encrypted, bit_pos, original_bit ^ cipher_bit);
+
+ pfx_shift_left(padded_prefix);
+ pfx_set_bit(padded_prefix, 0, original_bit);
+ }
+
+ memcpy(out, encrypted, 16);
+}
+
+static void
+pfx_decrypt(uint8_t *out, const uint8_t *in, const uint8_t *k)
+{
+ KeySchedule k1keys;
+ KeySchedule k2keys;
+ uint8_t diff[16];
+ uint8_t decrypted[16];
+ uint8_t padded_prefix[16];
+ uint8_t t[16];
+ aes_block_t e1, e2, e;
+ unsigned int prefix_start = 0;
+ unsigned int prefix_len_bits;
+ unsigned int bit_pos;
+ uint8_t cipher_bit;
+ uint8_t encrypted_bit;
+ uint8_t original_bit;
+ size_t i;
+ uint8_t d;
+
+ expand_key(k1keys, k);
+ expand_key(k2keys, k + 16);
+
+ AES_BLOCK_STORE(diff, AES_BLOCK_XOR(k1keys[ROUNDS / 2], k2keys[ROUNDS / 2]));
+ d = 0;
+ for (i = 0; i < 16; i++) {
+ d |= diff[i];
+ }
+ if (d == 0) {
+ for (i = 0; i < 16; i++) {
+ diff[i] = k[i] ^ 0x5a;
+ }
+ expand_key(k2keys, diff);
+ }
+
+ if (is_ipv4_mapped(in)) {
+ prefix_start = 96;
+ }
+
+ pfx_pad_prefix(padded_prefix, prefix_start);
+
+ memset(decrypted, 0, 16);
+ if (prefix_start == 96) {
+ decrypted[10] = 0xff;
+ decrypted[11] = 0xff;
+ }
+
+ for (prefix_len_bits = prefix_start; prefix_len_bits < 128; prefix_len_bits++) {
+ e1 = AES_BLOCK_XOR(AES_BLOCK_LOAD(padded_prefix), k1keys[0]);
+ e2 = AES_BLOCK_XOR(AES_BLOCK_LOAD(padded_prefix), k2keys[0]);
+ for (i = 1; i < ROUNDS; i++) {
+ e1 = AES_ENC(e1, k1keys[i]);
+ e2 = AES_ENC(e2, k2keys[i]);
+ }
+ e1 = AES_ENCLAST(e1, k1keys[ROUNDS]);
+ e2 = AES_ENCLAST(e2, k2keys[ROUNDS]);
+
+ e = AES_BLOCK_XOR(e1, e2);
+ AES_BLOCK_STORE(t, e);
+
+ cipher_bit = t[15] & 1;
+ bit_pos = 127 - prefix_len_bits;
+ encrypted_bit = pfx_get_bit(in, bit_pos);
+ original_bit = encrypted_bit ^ cipher_bit;
+ pfx_set_bit(decrypted, bit_pos, original_bit);
+
+ pfx_shift_left(padded_prefix);
+ pfx_set_bit(padded_prefix, 0, original_bit);
+ }
+
+ memcpy(out, decrypted, 16);
+}
+
+struct ipcrypt_implementation ipcrypt_soft_implementation = {
+ SODIUM_C99(.encrypt =) encrypt, SODIUM_C99(.decrypt =) decrypt,
+ SODIUM_C99(.nd_encrypt =) nd_encrypt, SODIUM_C99(.nd_decrypt =) nd_decrypt,
+ SODIUM_C99(.ndx_encrypt =) ndx_encrypt, SODIUM_C99(.ndx_decrypt =) ndx_decrypt,
+ SODIUM_C99(.pfx_encrypt =) pfx_encrypt, SODIUM_C99(.pfx_decrypt =) pfx_decrypt
+};
diff --git a/src/libsodium/crypto_ipcrypt/ipcrypt_soft.h b/src/libsodium/crypto_ipcrypt/ipcrypt_soft.h
new file mode 100644
index 00000000..757c8844
--- /dev/null
+++ b/src/libsodium/crypto_ipcrypt/ipcrypt_soft.h
@@ -0,0 +1,8 @@
+#ifndef ipcrypt_soft_H
+#define ipcrypt_soft_H
+
+#include "implementations.h"
+
+extern struct ipcrypt_implementation ipcrypt_soft_implementation;
+
+#endif
diff --git a/src/libsodium/include/Makefile.am b/src/libsodium/include/Makefile.am
index c35e247d..69c77112 100644
--- a/src/libsodium/include/Makefile.am
+++ b/src/libsodium/include/Makefile.am
@@ -27,6 +27,7 @@ SODIUM_EXPORT = \
sodium/crypto_hash.h \
sodium/crypto_hash_sha256.h \
sodium/crypto_hash_sha512.h \
+ sodium/crypto_ipcrypt.h \
sodium/crypto_kdf.h \
sodium/crypto_kdf_hkdf_sha256.h \
sodium/crypto_kdf_hkdf_sha512.h \
diff --git a/src/libsodium/include/Makefile.in b/src/libsodium/include/Makefile.in
index a7e94008..66c34d64 100644
--- a/src/libsodium/include/Makefile.in
+++ b/src/libsodium/include/Makefile.in
@@ -377,6 +377,7 @@ SODIUM_EXPORT = \
sodium/crypto_hash.h \
sodium/crypto_hash_sha256.h \
sodium/crypto_hash_sha512.h \
+ sodium/crypto_ipcrypt.h \
sodium/crypto_kdf.h \
sodium/crypto_kdf_hkdf_sha256.h \
sodium/crypto_kdf_hkdf_sha512.h \
diff --git a/src/libsodium/include/sodium.h b/src/libsodium/include/sodium.h
index 953fd588..61a31687 100644
--- a/src/libsodium/include/sodium.h
+++ b/src/libsodium/include/sodium.h
@@ -27,6 +27,7 @@
#include "sodium/crypto_hash.h"
#include "sodium/crypto_hash_sha256.h"
#include "sodium/crypto_hash_sha512.h"
+#include "sodium/crypto_ipcrypt.h"
#include "sodium/crypto_kdf.h"
#include "sodium/crypto_kdf_hkdf_sha256.h"
#include "sodium/crypto_kdf_hkdf_sha512.h"
diff --git a/src/libsodium/include/sodium/crypto_ipcrypt.h b/src/libsodium/include/sodium/crypto_ipcrypt.h
new file mode 100644
index 00000000..8b2271ed
--- /dev/null
+++ b/src/libsodium/include/sodium/crypto_ipcrypt.h
@@ -0,0 +1,128 @@
+#ifndef crypto_ipcrypt_H
+#define crypto_ipcrypt_H
+
+#include
+
+#include "export.h"
+
+#ifdef __cplusplus
+# ifdef __GNUC__
+# pragma GCC diagnostic ignored "-Wlong-long"
+# endif
+extern "C" {
+#endif
+
+#define crypto_ipcrypt_BYTES 16U
+SODIUM_EXPORT
+size_t crypto_ipcrypt_bytes(void);
+
+#define crypto_ipcrypt_KEYBYTES 16U
+SODIUM_EXPORT
+size_t crypto_ipcrypt_keybytes(void);
+
+#define crypto_ipcrypt_ND_KEYBYTES 16U
+SODIUM_EXPORT
+size_t crypto_ipcrypt_nd_keybytes(void);
+
+#define crypto_ipcrypt_ND_TWEAKBYTES 8U
+SODIUM_EXPORT
+size_t crypto_ipcrypt_nd_tweakbytes(void);
+
+#define crypto_ipcrypt_ND_INPUTBYTES 16U
+SODIUM_EXPORT
+size_t crypto_ipcrypt_nd_inputbytes(void);
+
+#define crypto_ipcrypt_ND_OUTPUTBYTES 24U
+SODIUM_EXPORT
+size_t crypto_ipcrypt_nd_outputbytes(void);
+
+#define crypto_ipcrypt_NDX_KEYBYTES 32U
+SODIUM_EXPORT
+size_t crypto_ipcrypt_ndx_keybytes(void);
+
+#define crypto_ipcrypt_NDX_TWEAKBYTES 16U
+SODIUM_EXPORT
+size_t crypto_ipcrypt_ndx_tweakbytes(void);
+
+#define crypto_ipcrypt_NDX_INPUTBYTES 16U
+SODIUM_EXPORT
+size_t crypto_ipcrypt_ndx_inputbytes(void);
+
+#define crypto_ipcrypt_NDX_OUTPUTBYTES 32U
+SODIUM_EXPORT
+size_t crypto_ipcrypt_ndx_outputbytes(void);
+
+#define crypto_ipcrypt_PFX_KEYBYTES 32U
+SODIUM_EXPORT
+size_t crypto_ipcrypt_pfx_keybytes(void);
+
+#define crypto_ipcrypt_PFX_BYTES 16U
+SODIUM_EXPORT
+size_t crypto_ipcrypt_pfx_bytes(void);
+
+SODIUM_EXPORT
+void crypto_ipcrypt_keygen(unsigned char k[crypto_ipcrypt_KEYBYTES]) __attribute__((nonnull));
+
+SODIUM_EXPORT
+void crypto_ipcrypt_ndx_keygen(unsigned char k[crypto_ipcrypt_NDX_KEYBYTES])
+ __attribute__((nonnull));
+
+SODIUM_EXPORT
+void crypto_ipcrypt_pfx_keygen(unsigned char k[crypto_ipcrypt_PFX_KEYBYTES])
+ __attribute__((nonnull));
+
+SODIUM_EXPORT
+void crypto_ipcrypt_encrypt(unsigned char out[crypto_ipcrypt_BYTES],
+ const unsigned char in[crypto_ipcrypt_BYTES],
+ const unsigned char k[crypto_ipcrypt_KEYBYTES])
+ __attribute__((nonnull));
+
+SODIUM_EXPORT
+void crypto_ipcrypt_decrypt(unsigned char out[crypto_ipcrypt_BYTES],
+ const unsigned char in[crypto_ipcrypt_BYTES],
+ const unsigned char k[crypto_ipcrypt_KEYBYTES])
+ __attribute__((nonnull));
+
+SODIUM_EXPORT
+void crypto_ipcrypt_nd_encrypt(unsigned char out[crypto_ipcrypt_ND_OUTPUTBYTES],
+ const unsigned char in[crypto_ipcrypt_ND_INPUTBYTES],
+ const unsigned char t[crypto_ipcrypt_ND_TWEAKBYTES],
+ const unsigned char k[crypto_ipcrypt_ND_KEYBYTES])
+ __attribute__((nonnull));
+
+SODIUM_EXPORT
+void crypto_ipcrypt_nd_decrypt(unsigned char out[crypto_ipcrypt_ND_INPUTBYTES],
+ const unsigned char in[crypto_ipcrypt_ND_OUTPUTBYTES],
+ const unsigned char k[crypto_ipcrypt_ND_KEYBYTES])
+ __attribute__((nonnull));
+
+SODIUM_EXPORT
+void crypto_ipcrypt_ndx_encrypt(unsigned char out[crypto_ipcrypt_NDX_OUTPUTBYTES],
+ const unsigned char in[crypto_ipcrypt_NDX_INPUTBYTES],
+ const unsigned char t[crypto_ipcrypt_NDX_TWEAKBYTES],
+ const unsigned char k[crypto_ipcrypt_NDX_KEYBYTES])
+ __attribute__((nonnull));
+
+SODIUM_EXPORT
+void crypto_ipcrypt_ndx_decrypt(unsigned char out[crypto_ipcrypt_NDX_INPUTBYTES],
+ const unsigned char in[crypto_ipcrypt_NDX_OUTPUTBYTES],
+ const unsigned char k[crypto_ipcrypt_NDX_KEYBYTES])
+ __attribute__((nonnull));
+
+SODIUM_EXPORT
+void crypto_ipcrypt_pfx_encrypt(unsigned char out[crypto_ipcrypt_PFX_BYTES],
+ const unsigned char in[crypto_ipcrypt_PFX_BYTES],
+ const unsigned char k[crypto_ipcrypt_PFX_KEYBYTES])
+ __attribute__((nonnull));
+
+SODIUM_EXPORT
+void crypto_ipcrypt_pfx_decrypt(unsigned char out[crypto_ipcrypt_PFX_BYTES],
+ const unsigned char in[crypto_ipcrypt_PFX_BYTES],
+ const unsigned char k[crypto_ipcrypt_PFX_KEYBYTES])
+ __attribute__((nonnull));
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/src/libsodium/include/sodium/private/softaes.h b/src/libsodium/include/sodium/private/softaes.h
index f7a2bd24..1050b2d4 100644
--- a/src/libsodium/include/sodium/private/softaes.h
+++ b/src/libsodium/include/sodium/private/softaes.h
@@ -1,9 +1,9 @@
#ifndef softaes_H
-#define softaes_H 1
+# define softaes_H 1
-#include
+# include
-#include "private/common.h"
+# include "private/common.h"
typedef struct SoftAesBlock {
uint32_t w0;
@@ -12,7 +12,15 @@ typedef struct SoftAesBlock {
uint32_t w3;
} SoftAesBlock;
+void softaes_expand_key128(SoftAesBlock rkeys[11], const uint8_t key[16]);
+void softaes_expand_key256(SoftAesBlock rkeys[15], const uint8_t key[32]);
+SoftAesBlock softaes_inv_mix_columns(const SoftAesBlock block);
+void softaes_invert_key_schedule128(SoftAesBlock rkeys[11]);
+void softaes_invert_key_schedule256(SoftAesBlock rkeys[15]);
SoftAesBlock softaes_block_encrypt(const SoftAesBlock block, const SoftAesBlock rk);
+SoftAesBlock softaes_block_decrypt(const SoftAesBlock block, const SoftAesBlock rk);
+SoftAesBlock softaes_block_encryptlast(const SoftAesBlock block, const SoftAesBlock rk);
+SoftAesBlock softaes_block_decryptlast(const SoftAesBlock block, const SoftAesBlock rk);
static inline SoftAesBlock
softaes_block_load(const uint8_t in[16])
diff --git a/test/default/Makefile.am b/test/default/Makefile.am
index fa188c8a..290e2977 100644
--- a/test/default/Makefile.am
+++ b/test/default/Makefile.am
@@ -43,6 +43,7 @@ EXTRA_DIST = \
generichash3.exp \
hash.exp \
hash3.exp \
+ ipcrypt.exp \
kdf.exp \
kdf_hkdf.exp \
keygen.exp \
@@ -131,6 +132,7 @@ DISTCLEANFILES = \
hash.res \
hash2.res \
hash3.res \
+ ipcrypt.res \
kdf.res \
kdf_hkdf.res \
keygen.res \
@@ -226,6 +228,7 @@ TESTS_TARGETS = \
generichash3 \
hash \
hash3 \
+ ipcrypt \
kdf \
keygen \
kx \
@@ -392,6 +395,9 @@ hash_LDADD = $(TESTS_LDADD)
hash3_SOURCE = cmptest.h hash3.c
hash3_LDADD = $(TESTS_LDADD)
+ipcrypt_SOURCE = cmptest.h ipcrypt.c
+ipcrypt_LDADD = $(TESTS_LDADD)
+
kdf_SOURCE = cmptest.h kdf.c
kdf_LDADD = $(TESTS_LDADD)
diff --git a/test/default/Makefile.in b/test/default/Makefile.in
index cf5b1aca..c4d885e1 100644
--- a/test/default/Makefile.in
+++ b/test/default/Makefile.in
@@ -148,15 +148,16 @@ am__EXEEXT_3 = aead_aegis128l$(EXEEXT) aead_aegis256$(EXEEXT) \
core3$(EXEEXT) core4$(EXEEXT) core5$(EXEEXT) core6$(EXEEXT) \
ed25519_convert$(EXEEXT) generichash$(EXEEXT) \
generichash2$(EXEEXT) generichash3$(EXEEXT) hash$(EXEEXT) \
- hash3$(EXEEXT) kdf$(EXEEXT) keygen$(EXEEXT) kx$(EXEEXT) \
- metamorphic$(EXEEXT) misuse$(EXEEXT) onetimeauth$(EXEEXT) \
- onetimeauth2$(EXEEXT) onetimeauth7$(EXEEXT) \
- pwhash_argon2i$(EXEEXT) pwhash_argon2id$(EXEEXT) \
- randombytes$(EXEEXT) scalarmult$(EXEEXT) scalarmult2$(EXEEXT) \
- scalarmult5$(EXEEXT) scalarmult6$(EXEEXT) scalarmult7$(EXEEXT) \
- scalarmult8$(EXEEXT) secretbox$(EXEEXT) secretbox2$(EXEEXT) \
- secretbox7$(EXEEXT) secretbox8$(EXEEXT) \
- secretbox_easy$(EXEEXT) secretbox_easy2$(EXEEXT) \
+ hash3$(EXEEXT) ipcrypt$(EXEEXT) kdf$(EXEEXT) keygen$(EXEEXT) \
+ kx$(EXEEXT) metamorphic$(EXEEXT) misuse$(EXEEXT) \
+ onetimeauth$(EXEEXT) onetimeauth2$(EXEEXT) \
+ onetimeauth7$(EXEEXT) pwhash_argon2i$(EXEEXT) \
+ pwhash_argon2id$(EXEEXT) randombytes$(EXEEXT) \
+ scalarmult$(EXEEXT) scalarmult2$(EXEEXT) scalarmult5$(EXEEXT) \
+ scalarmult6$(EXEEXT) scalarmult7$(EXEEXT) scalarmult8$(EXEEXT) \
+ secretbox$(EXEEXT) secretbox2$(EXEEXT) secretbox7$(EXEEXT) \
+ secretbox8$(EXEEXT) secretbox_easy$(EXEEXT) \
+ secretbox_easy2$(EXEEXT) \
secretstream_xchacha20poly1305$(EXEEXT) shorthash$(EXEEXT) \
sign$(EXEEXT) sodium_core$(EXEEXT) sodium_utils$(EXEEXT) \
sodium_version$(EXEEXT) stream$(EXEEXT) stream2$(EXEEXT) \
@@ -282,6 +283,9 @@ hash_DEPENDENCIES = $(TESTS_LDADD)
hash3_SOURCES = hash3.c
hash3_OBJECTS = hash3.$(OBJEXT)
hash3_DEPENDENCIES = $(TESTS_LDADD)
+ipcrypt_SOURCES = ipcrypt.c
+ipcrypt_OBJECTS = ipcrypt.$(OBJEXT)
+ipcrypt_DEPENDENCIES = $(TESTS_LDADD)
kdf_SOURCES = kdf.c
kdf_OBJECTS = kdf.$(OBJEXT)
kdf_DEPENDENCIES = $(TESTS_LDADD)
@@ -458,7 +462,8 @@ am__depfiles_remade = ./$(DEPDIR)/aead_aegis128l.Po \
./$(DEPDIR)/core_ristretto255.Po \
./$(DEPDIR)/ed25519_convert.Po ./$(DEPDIR)/generichash.Po \
./$(DEPDIR)/generichash2.Po ./$(DEPDIR)/generichash3.Po \
- ./$(DEPDIR)/hash.Po ./$(DEPDIR)/hash3.Po ./$(DEPDIR)/kdf.Po \
+ ./$(DEPDIR)/hash.Po ./$(DEPDIR)/hash3.Po \
+ ./$(DEPDIR)/ipcrypt.Po ./$(DEPDIR)/kdf.Po \
./$(DEPDIR)/kdf_hkdf.Po ./$(DEPDIR)/keygen.Po \
./$(DEPDIR)/kx.Po ./$(DEPDIR)/metamorphic.Po \
./$(DEPDIR)/misuse.Po ./$(DEPDIR)/onetimeauth.Po \
@@ -511,19 +516,19 @@ SOURCES = aead_aegis128l.c aead_aegis256.c aead_aes256gcm.c \
codecs.c core1.c core2.c core3.c core4.c core5.c core6.c \
core_ed25519.c core_keccak1600.c core_ristretto255.c \
ed25519_convert.c generichash.c generichash2.c generichash3.c \
- hash.c hash3.c kdf.c kdf_hkdf.c keygen.c kx.c metamorphic.c \
- misuse.c onetimeauth.c onetimeauth2.c onetimeauth7.c \
- pwhash_argon2i.c pwhash_argon2id.c pwhash_scrypt.c \
- pwhash_scrypt_ll.c randombytes.c scalarmult.c scalarmult2.c \
- scalarmult5.c scalarmult6.c scalarmult7.c scalarmult8.c \
- scalarmult_ed25519.c scalarmult_ristretto255.c secretbox.c \
- secretbox2.c secretbox7.c secretbox8.c secretbox_easy.c \
- secretbox_easy2.c secretstream_xchacha20poly1305.c shorthash.c \
- sign.c siphashx24.c sodium_core.c sodium_utils.c \
- sodium_utils2.c sodium_utils3.c sodium_version.c stream.c \
- stream2.c stream3.c stream4.c verify1.c xchacha20.c \
- xof_shake128.c xof_shake256.c xof_turboshake128.c \
- xof_turboshake256.c
+ hash.c hash3.c ipcrypt.c kdf.c kdf_hkdf.c keygen.c kx.c \
+ metamorphic.c misuse.c onetimeauth.c onetimeauth2.c \
+ onetimeauth7.c pwhash_argon2i.c pwhash_argon2id.c \
+ pwhash_scrypt.c pwhash_scrypt_ll.c randombytes.c scalarmult.c \
+ scalarmult2.c scalarmult5.c scalarmult6.c scalarmult7.c \
+ scalarmult8.c scalarmult_ed25519.c scalarmult_ristretto255.c \
+ secretbox.c secretbox2.c secretbox7.c secretbox8.c \
+ secretbox_easy.c secretbox_easy2.c \
+ secretstream_xchacha20poly1305.c shorthash.c sign.c \
+ siphashx24.c sodium_core.c sodium_utils.c sodium_utils2.c \
+ sodium_utils3.c sodium_version.c stream.c stream2.c stream3.c \
+ stream4.c verify1.c xchacha20.c xof_shake128.c xof_shake256.c \
+ xof_turboshake128.c xof_turboshake256.c
DIST_SOURCES = aead_aegis128l.c aead_aegis256.c aead_aes256gcm.c \
aead_aes256gcm2.c aead_chacha20poly1305.c \
aead_chacha20poly13052.c aead_xchacha20poly1305.c auth.c \
@@ -532,19 +537,19 @@ DIST_SOURCES = aead_aegis128l.c aead_aegis256.c aead_aes256gcm.c \
codecs.c core1.c core2.c core3.c core4.c core5.c core6.c \
core_ed25519.c core_keccak1600.c core_ristretto255.c \
ed25519_convert.c generichash.c generichash2.c generichash3.c \
- hash.c hash3.c kdf.c kdf_hkdf.c keygen.c kx.c metamorphic.c \
- misuse.c onetimeauth.c onetimeauth2.c onetimeauth7.c \
- pwhash_argon2i.c pwhash_argon2id.c pwhash_scrypt.c \
- pwhash_scrypt_ll.c randombytes.c scalarmult.c scalarmult2.c \
- scalarmult5.c scalarmult6.c scalarmult7.c scalarmult8.c \
- scalarmult_ed25519.c scalarmult_ristretto255.c secretbox.c \
- secretbox2.c secretbox7.c secretbox8.c secretbox_easy.c \
- secretbox_easy2.c secretstream_xchacha20poly1305.c shorthash.c \
- sign.c siphashx24.c sodium_core.c sodium_utils.c \
- sodium_utils2.c sodium_utils3.c sodium_version.c stream.c \
- stream2.c stream3.c stream4.c verify1.c xchacha20.c \
- xof_shake128.c xof_shake256.c xof_turboshake128.c \
- xof_turboshake256.c
+ hash.c hash3.c ipcrypt.c kdf.c kdf_hkdf.c keygen.c kx.c \
+ metamorphic.c misuse.c onetimeauth.c onetimeauth2.c \
+ onetimeauth7.c pwhash_argon2i.c pwhash_argon2id.c \
+ pwhash_scrypt.c pwhash_scrypt_ll.c randombytes.c scalarmult.c \
+ scalarmult2.c scalarmult5.c scalarmult6.c scalarmult7.c \
+ scalarmult8.c scalarmult_ed25519.c scalarmult_ristretto255.c \
+ secretbox.c secretbox2.c secretbox7.c secretbox8.c \
+ secretbox_easy.c secretbox_easy2.c \
+ secretstream_xchacha20poly1305.c shorthash.c sign.c \
+ siphashx24.c sodium_core.c sodium_utils.c sodium_utils2.c \
+ sodium_utils3.c sodium_version.c stream.c stream2.c stream3.c \
+ stream4.c verify1.c xchacha20.c xof_shake128.c xof_shake256.c \
+ xof_turboshake128.c xof_turboshake256.c
am__can_run_installinfo = \
case $$AM_UPDATE_INFO_DIR in \
n|no|NO) false;; \
@@ -996,6 +1001,7 @@ EXTRA_DIST = \
generichash3.exp \
hash.exp \
hash3.exp \
+ ipcrypt.exp \
kdf.exp \
kdf_hkdf.exp \
keygen.exp \
@@ -1084,6 +1090,7 @@ DISTCLEANFILES = \
hash.res \
hash2.res \
hash3.res \
+ ipcrypt.res \
kdf.res \
kdf_hkdf.res \
keygen.res \
@@ -1147,7 +1154,7 @@ TESTS_TARGETS = aead_aegis128l aead_aegis256 aead_aes256gcm \
box2 box7 box8 box_easy box_easy2 box_seal box_seed chacha20 \
codecs core_keccak1600 core1 core2 core3 core4 core5 core6 \
ed25519_convert generichash generichash2 generichash3 hash \
- hash3 kdf keygen kx metamorphic misuse onetimeauth \
+ hash3 ipcrypt kdf keygen kx metamorphic misuse onetimeauth \
onetimeauth2 onetimeauth7 pwhash_argon2i pwhash_argon2id \
randombytes scalarmult scalarmult2 scalarmult5 scalarmult6 \
scalarmult7 scalarmult8 secretbox secretbox2 secretbox7 \
@@ -1235,6 +1242,8 @@ hash_SOURCE = cmptest.h hash.c
hash_LDADD = $(TESTS_LDADD)
hash3_SOURCE = cmptest.h hash3.c
hash3_LDADD = $(TESTS_LDADD)
+ipcrypt_SOURCE = cmptest.h ipcrypt.c
+ipcrypt_LDADD = $(TESTS_LDADD)
kdf_SOURCE = cmptest.h kdf.c
kdf_LDADD = $(TESTS_LDADD)
kdf_hkdf_SOURCE = cmptest.h kdf_hkdf.c
@@ -1520,6 +1529,10 @@ hash3$(EXEEXT): $(hash3_OBJECTS) $(hash3_DEPENDENCIES) $(EXTRA_hash3_DEPENDENCIE
@rm -f hash3$(EXEEXT)
$(AM_V_CCLD)$(LINK) $(hash3_OBJECTS) $(hash3_LDADD) $(LIBS)
+ipcrypt$(EXEEXT): $(ipcrypt_OBJECTS) $(ipcrypt_DEPENDENCIES) $(EXTRA_ipcrypt_DEPENDENCIES)
+ @rm -f ipcrypt$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(ipcrypt_OBJECTS) $(ipcrypt_LDADD) $(LIBS)
+
kdf$(EXEEXT): $(kdf_OBJECTS) $(kdf_DEPENDENCIES) $(EXTRA_kdf_DEPENDENCIES)
@rm -f kdf$(EXEEXT)
$(AM_V_CCLD)$(LINK) $(kdf_OBJECTS) $(kdf_LDADD) $(LIBS)
@@ -1752,6 +1765,7 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/generichash3.Po@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/hash.Po@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/hash3.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ipcrypt.Po@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/kdf.Po@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/kdf_hkdf.Po@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/keygen.Po@am__quote@ # am--include-marker
@@ -2306,6 +2320,13 @@ hash3.log: hash3$(EXEEXT)
--log-file $$b.log --trs-file $$b.trs \
$(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
"$$tst" $(AM_TESTS_FD_REDIRECT)
+ipcrypt.log: ipcrypt$(EXEEXT)
+ @p='ipcrypt$(EXEEXT)'; \
+ b='ipcrypt'; \
+ $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \
+ --log-file $$b.log --trs-file $$b.trs \
+ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
+ "$$tst" $(AM_TESTS_FD_REDIRECT)
kdf.log: kdf$(EXEEXT)
@p='kdf$(EXEEXT)'; \
b='kdf'; \
@@ -2781,6 +2802,7 @@ distclean: distclean-am
-rm -f ./$(DEPDIR)/generichash3.Po
-rm -f ./$(DEPDIR)/hash.Po
-rm -f ./$(DEPDIR)/hash3.Po
+ -rm -f ./$(DEPDIR)/ipcrypt.Po
-rm -f ./$(DEPDIR)/kdf.Po
-rm -f ./$(DEPDIR)/kdf_hkdf.Po
-rm -f ./$(DEPDIR)/keygen.Po
@@ -2911,6 +2933,7 @@ maintainer-clean: maintainer-clean-am
-rm -f ./$(DEPDIR)/generichash3.Po
-rm -f ./$(DEPDIR)/hash.Po
-rm -f ./$(DEPDIR)/hash3.Po
+ -rm -f ./$(DEPDIR)/ipcrypt.Po
-rm -f ./$(DEPDIR)/kdf.Po
-rm -f ./$(DEPDIR)/kdf_hkdf.Po
-rm -f ./$(DEPDIR)/keygen.Po
diff --git a/test/default/ipcrypt.c b/test/default/ipcrypt.c
new file mode 100644
index 00000000..3bdf7a60
--- /dev/null
+++ b/test/default/ipcrypt.c
@@ -0,0 +1,591 @@
+#define TEST_NAME "ipcrypt"
+#include "cmptest.h"
+
+static int
+check_expected(const char *test_name, const unsigned char *actual, const char *expected_hex,
+ size_t len)
+{
+ unsigned char expected[64];
+ char actual_hex[129];
+
+ sodium_hex2bin(expected, sizeof expected, expected_hex, strlen(expected_hex), NULL, NULL, NULL);
+ if (memcmp(actual, expected, len) != 0) {
+ sodium_bin2hex(actual_hex, sizeof actual_hex, actual, len);
+ printf("FAILED %s: expected %s, got %s\n", test_name, expected_hex, actual_hex);
+ return 1;
+ }
+ printf("OK: %s\n", test_name);
+ return 0;
+}
+
+int
+main(void)
+{
+ unsigned char key[crypto_ipcrypt_KEYBYTES];
+ unsigned char ndx_key[crypto_ipcrypt_NDX_KEYBYTES];
+ unsigned char pfx_key[crypto_ipcrypt_PFX_KEYBYTES];
+ unsigned char input[crypto_ipcrypt_BYTES];
+ unsigned char output[crypto_ipcrypt_BYTES];
+ unsigned char nd_output[crypto_ipcrypt_ND_OUTPUTBYTES];
+ unsigned char ndx_output[crypto_ipcrypt_NDX_OUTPUTBYTES];
+ unsigned char pfx_output[crypto_ipcrypt_PFX_BYTES];
+ unsigned char tweak_nd[crypto_ipcrypt_ND_TWEAKBYTES];
+ unsigned char tweak_ndx[crypto_ipcrypt_NDX_TWEAKBYTES];
+ unsigned char decrypted[crypto_ipcrypt_BYTES];
+ unsigned char encrypted1[crypto_ipcrypt_PFX_BYTES];
+ unsigned char encrypted2[crypto_ipcrypt_PFX_BYTES];
+ size_t i;
+
+ printf("crypto_ipcrypt_BYTES: %zu\n", crypto_ipcrypt_bytes());
+ printf("crypto_ipcrypt_KEYBYTES: %zu\n", crypto_ipcrypt_keybytes());
+ printf("crypto_ipcrypt_ND_KEYBYTES: %zu\n", crypto_ipcrypt_nd_keybytes());
+ printf("crypto_ipcrypt_ND_TWEAKBYTES: %zu\n", crypto_ipcrypt_nd_tweakbytes());
+ printf("crypto_ipcrypt_ND_INPUTBYTES: %zu\n", crypto_ipcrypt_nd_inputbytes());
+ printf("crypto_ipcrypt_ND_OUTPUTBYTES: %zu\n", crypto_ipcrypt_nd_outputbytes());
+ printf("crypto_ipcrypt_NDX_KEYBYTES: %zu\n", crypto_ipcrypt_ndx_keybytes());
+ printf("crypto_ipcrypt_NDX_TWEAKBYTES: %zu\n", crypto_ipcrypt_ndx_tweakbytes());
+ printf("crypto_ipcrypt_NDX_INPUTBYTES: %zu\n", crypto_ipcrypt_ndx_inputbytes());
+ printf("crypto_ipcrypt_NDX_OUTPUTBYTES: %zu\n", crypto_ipcrypt_ndx_outputbytes());
+ printf("crypto_ipcrypt_PFX_KEYBYTES: %zu\n", crypto_ipcrypt_pfx_keybytes());
+ printf("crypto_ipcrypt_PFX_BYTES: %zu\n", crypto_ipcrypt_pfx_bytes());
+
+ printf("\nipcrypt-deterministic test vectors\n");
+
+ sodium_hex2bin(key, sizeof key, "0123456789abcdeffedcba9876543210", 32, NULL, NULL, NULL);
+ memset(input, 0, sizeof input);
+ input[10] = 0xff;
+ input[11] = 0xff;
+
+ crypto_ipcrypt_encrypt(output, input, key);
+ if (check_expected("deterministic vector 1 (0.0.0.0)", output,
+ "bde96789d353824cd7c6f58a6bd226eb", 16) != 0) {
+ return 1;
+ }
+ crypto_ipcrypt_decrypt(decrypted, output, key);
+ if (memcmp(input, decrypted, sizeof input) != 0) {
+ printf("FAILED: deterministic vector 1 round-trip\n");
+ return 1;
+ }
+
+ sodium_hex2bin(key, sizeof key, "1032547698badcfeefcdab8967452301", 32, NULL, NULL, NULL);
+ memset(input, 0, sizeof input);
+ input[10] = 0xff;
+ input[11] = 0xff;
+ input[12] = 0xff;
+ input[13] = 0xff;
+ input[14] = 0xff;
+ input[15] = 0xff;
+
+ crypto_ipcrypt_encrypt(output, input, key);
+ if (check_expected("deterministic vector 2 (255.255.255.255)", output,
+ "aed292f6ea2358c348fd08b874e845d8", 16) != 0) {
+ return 1;
+ }
+ crypto_ipcrypt_decrypt(decrypted, output, key);
+ if (memcmp(input, decrypted, sizeof input) != 0) {
+ printf("FAILED: deterministic vector 2 round-trip\n");
+ return 1;
+ }
+
+ sodium_hex2bin(key, sizeof key, "2b7e151628aed2a6abf7158809cf4f3c", 32, NULL, NULL, NULL);
+ memset(input, 0, sizeof input);
+ input[10] = 0xff;
+ input[11] = 0xff;
+ input[12] = 192;
+ input[13] = 0;
+ input[14] = 2;
+ input[15] = 1;
+
+ crypto_ipcrypt_encrypt(output, input, key);
+ if (check_expected("deterministic vector 3 (192.0.2.1)", output,
+ "1dbdc1b9fff175867d0b67b4e76e4777", 16) != 0) {
+ return 1;
+ }
+ crypto_ipcrypt_decrypt(decrypted, output, key);
+ if (memcmp(input, decrypted, sizeof input) != 0) {
+ printf("FAILED: deterministic vector 3 round-trip\n");
+ return 1;
+ }
+
+ printf("\nipcrypt-nd test vectors\n");
+
+ sodium_hex2bin(key, sizeof key, "0123456789abcdeffedcba9876543210", 32, NULL, NULL, NULL);
+ sodium_hex2bin(tweak_nd, sizeof tweak_nd, "08e0c289bff23b7c", 16, NULL, NULL, NULL);
+ memset(input, 0, sizeof input);
+ input[10] = 0xff;
+ input[11] = 0xff;
+
+ crypto_ipcrypt_nd_encrypt(nd_output, input, tweak_nd, key);
+ if (check_expected("nd vector 1 (0.0.0.0)", nd_output,
+ "08e0c289bff23b7cb349aadfe3bcef56221c384c7c217b16", 24) != 0) {
+ return 1;
+ }
+ crypto_ipcrypt_nd_decrypt(decrypted, nd_output, key);
+ if (memcmp(input, decrypted, sizeof input) != 0) {
+ printf("FAILED: nd vector 1 round-trip\n");
+ return 1;
+ }
+
+ sodium_hex2bin(key, sizeof key, "1032547698badcfeefcdab8967452301", 32, NULL, NULL, NULL);
+ sodium_hex2bin(tweak_nd, sizeof tweak_nd, "21bd1834bc088cd2", 16, NULL, NULL, NULL);
+ memset(input, 0, sizeof input);
+ input[10] = 0xff;
+ input[11] = 0xff;
+ input[12] = 192;
+ input[13] = 0;
+ input[14] = 2;
+ input[15] = 1;
+
+ crypto_ipcrypt_nd_encrypt(nd_output, input, tweak_nd, key);
+ if (check_expected("nd vector 2 (192.0.2.1)", nd_output,
+ "21bd1834bc088cd2e5e1fe55f95876e639faae2594a0caad", 24) != 0) {
+ return 1;
+ }
+ crypto_ipcrypt_nd_decrypt(decrypted, nd_output, key);
+ if (memcmp(input, decrypted, sizeof input) != 0) {
+ printf("FAILED: nd vector 2 round-trip\n");
+ return 1;
+ }
+
+ sodium_hex2bin(key, sizeof key, "2b7e151628aed2a6abf7158809cf4f3c", 32, NULL, NULL, NULL);
+ sodium_hex2bin(tweak_nd, sizeof tweak_nd, "b4ecbe30b70898d7", 16, NULL, NULL, NULL);
+ memset(input, 0, sizeof input);
+ input[0] = 0x20;
+ input[1] = 0x01;
+ input[2] = 0x0d;
+ input[3] = 0xb8;
+ input[15] = 0x01;
+
+ crypto_ipcrypt_nd_encrypt(nd_output, input, tweak_nd, key);
+ if (check_expected("nd vector 3 (2001:db8::1)", nd_output,
+ "b4ecbe30b70898d7553ac8974d1b4250eafc4b0aa1f80c96", 24) != 0) {
+ return 1;
+ }
+ crypto_ipcrypt_nd_decrypt(decrypted, nd_output, key);
+ if (memcmp(input, decrypted, sizeof input) != 0) {
+ printf("FAILED: nd vector 3 round-trip\n");
+ return 1;
+ }
+
+ printf("\nipcrypt-ndx test vectors\n");
+
+ sodium_hex2bin(ndx_key, sizeof ndx_key,
+ "0123456789abcdeffedcba98765432101032547698badcfeefcdab8967452301", 64, NULL,
+ NULL, NULL);
+ sodium_hex2bin(tweak_ndx, sizeof tweak_ndx, "21bd1834bc088cd2b4ecbe30b70898d7", 32, NULL, NULL,
+ NULL);
+ memset(input, 0, sizeof input);
+ input[10] = 0xff;
+ input[11] = 0xff;
+
+ crypto_ipcrypt_ndx_encrypt(ndx_output, input, tweak_ndx, ndx_key);
+ if (check_expected("ndx vector 1 (0.0.0.0)", ndx_output,
+ "21bd1834bc088cd2b4ecbe30b70898d782db0d4125fdace61db35b8339f20ee5",
+ 32) != 0) {
+ return 1;
+ }
+ crypto_ipcrypt_ndx_decrypt(decrypted, ndx_output, ndx_key);
+ if (memcmp(input, decrypted, sizeof input) != 0) {
+ printf("FAILED: ndx vector 1 round-trip\n");
+ return 1;
+ }
+
+ sodium_hex2bin(ndx_key, sizeof ndx_key,
+ "1032547698badcfeefcdab89674523010123456789abcdeffedcba9876543210", 64, NULL,
+ NULL, NULL);
+ sodium_hex2bin(tweak_ndx, sizeof tweak_ndx, "08e0c289bff23b7cb4ecbe30b70898d7", 32, NULL, NULL,
+ NULL);
+ memset(input, 0, sizeof input);
+ input[10] = 0xff;
+ input[11] = 0xff;
+ input[12] = 192;
+ input[13] = 0;
+ input[14] = 2;
+ input[15] = 1;
+
+ crypto_ipcrypt_ndx_encrypt(ndx_output, input, tweak_ndx, ndx_key);
+ if (check_expected("ndx vector 2 (192.0.2.1)", ndx_output,
+ "08e0c289bff23b7cb4ecbe30b70898d7766a533392a69edf1ad0d3ce362ba98a",
+ 32) != 0) {
+ return 1;
+ }
+ crypto_ipcrypt_ndx_decrypt(decrypted, ndx_output, ndx_key);
+ if (memcmp(input, decrypted, sizeof input) != 0) {
+ printf("FAILED: ndx vector 2 round-trip\n");
+ return 1;
+ }
+
+ sodium_hex2bin(ndx_key, sizeof ndx_key,
+ "2b7e151628aed2a6abf7158809cf4f3c3c4fcf098815f7aba6d2ae2816157e2b", 64, NULL,
+ NULL, NULL);
+ sodium_hex2bin(tweak_ndx, sizeof tweak_ndx, "21bd1834bc088cd2b4ecbe30b70898d7", 32, NULL, NULL,
+ NULL);
+ memset(input, 0, sizeof input);
+ input[0] = 0x20;
+ input[1] = 0x01;
+ input[2] = 0x0d;
+ input[3] = 0xb8;
+ input[15] = 0x01;
+
+ crypto_ipcrypt_ndx_encrypt(ndx_output, input, tweak_ndx, ndx_key);
+ if (check_expected("ndx vector 3 (2001:db8::1)", ndx_output,
+ "21bd1834bc088cd2b4ecbe30b70898d76089c7e05ae30c2d10ca149870a263e4",
+ 32) != 0) {
+ return 1;
+ }
+ crypto_ipcrypt_ndx_decrypt(decrypted, ndx_output, ndx_key);
+ if (memcmp(input, decrypted, sizeof input) != 0) {
+ printf("FAILED: ndx vector 3 round-trip\n");
+ return 1;
+ }
+
+ printf("\nipcrypt-pfx test vectors\n");
+
+ sodium_hex2bin(pfx_key, sizeof pfx_key,
+ "0123456789abcdeffedcba98765432101032547698badcfeefcdab8967452301", 64, NULL,
+ NULL, NULL);
+ memset(input, 0, sizeof input);
+ input[10] = 0xff;
+ input[11] = 0xff;
+
+ crypto_ipcrypt_pfx_encrypt(pfx_output, input, pfx_key);
+ if (check_expected("pfx vector 1 (0.0.0.0)", pfx_output, "00000000000000000000ffff97529b86",
+ 16) != 0) {
+ return 1;
+ }
+ crypto_ipcrypt_pfx_decrypt(decrypted, pfx_output, pfx_key);
+ if (memcmp(input, decrypted, sizeof input) != 0) {
+ printf("FAILED: pfx vector 1 round-trip\n");
+ return 1;
+ }
+
+ memset(input, 0, sizeof input);
+ input[10] = 0xff;
+ input[11] = 0xff;
+ input[12] = 255;
+ input[13] = 255;
+ input[14] = 255;
+ input[15] = 255;
+
+ crypto_ipcrypt_pfx_encrypt(pfx_output, input, pfx_key);
+ if (check_expected("pfx vector 2 (255.255.255.255)", pfx_output,
+ "00000000000000000000ffff5eb9a959", 16) != 0) {
+ return 1;
+ }
+ crypto_ipcrypt_pfx_decrypt(decrypted, pfx_output, pfx_key);
+ if (memcmp(input, decrypted, sizeof input) != 0) {
+ printf("FAILED: pfx vector 2 round-trip\n");
+ return 1;
+ }
+
+ memset(input, 0, sizeof input);
+ input[10] = 0xff;
+ input[11] = 0xff;
+ input[12] = 192;
+ input[13] = 0;
+ input[14] = 2;
+ input[15] = 1;
+
+ crypto_ipcrypt_pfx_encrypt(pfx_output, input, pfx_key);
+ if (check_expected("pfx vector 3 (192.0.2.1)", pfx_output, "00000000000000000000ffff64734883",
+ 16) != 0) {
+ return 1;
+ }
+ crypto_ipcrypt_pfx_decrypt(decrypted, pfx_output, pfx_key);
+ if (memcmp(input, decrypted, sizeof input) != 0) {
+ printf("FAILED: pfx vector 3 round-trip\n");
+ return 1;
+ }
+
+ memset(input, 0, sizeof input);
+ input[0] = 0x20;
+ input[1] = 0x01;
+ input[2] = 0x0d;
+ input[3] = 0xb8;
+ input[15] = 0x01;
+
+ crypto_ipcrypt_pfx_encrypt(pfx_output, input, pfx_key);
+ if (check_expected("pfx vector 4 (2001:db8::1)", pfx_output, "c1805dd42587352430abfa656ab60f88",
+ 16) != 0) {
+ return 1;
+ }
+ crypto_ipcrypt_pfx_decrypt(decrypted, pfx_output, pfx_key);
+ if (memcmp(input, decrypted, sizeof input) != 0) {
+ printf("FAILED: pfx vector 4 round-trip\n");
+ return 1;
+ }
+
+ printf("\nipcrypt-pfx prefix preservation\n");
+
+ sodium_hex2bin(pfx_key, sizeof pfx_key,
+ "2b7e151628aed2a6abf7158809cf4f3ca9f5ba40db214c3798f2e1c23456789a", 64, NULL,
+ NULL, NULL);
+
+ memset(input, 0, sizeof input);
+ input[10] = 0xff;
+ input[11] = 0xff;
+ input[12] = 10;
+ input[13] = 0;
+ input[14] = 0;
+ input[15] = 47;
+
+ crypto_ipcrypt_pfx_encrypt(pfx_output, input, pfx_key);
+ if (check_expected("pfx /24 test (10.0.0.47)", pfx_output, "00000000000000000000ffff13d6d2f4",
+ 16) != 0) {
+ return 1;
+ }
+
+ input[15] = 129;
+ crypto_ipcrypt_pfx_encrypt(encrypted1, input, pfx_key);
+ if (check_expected("pfx /24 test (10.0.0.129)", encrypted1, "00000000000000000000ffff13d6d250",
+ 16) != 0) {
+ return 1;
+ }
+
+ input[15] = 234;
+ crypto_ipcrypt_pfx_encrypt(encrypted2, input, pfx_key);
+ if (check_expected("pfx /24 test (10.0.0.234)", encrypted2, "00000000000000000000ffff13d6d21e",
+ 16) != 0) {
+ return 1;
+ }
+
+ if (memcmp(pfx_output + 12, encrypted1 + 12, 3) != 0 ||
+ memcmp(pfx_output + 12, encrypted2 + 12, 3) != 0) {
+ printf("FAILED: IPv4 /24 prefix not preserved\n");
+ return 1;
+ }
+ printf("OK: IPv4 /24 prefix preserved for 10.0.0.x\n");
+
+ memset(input, 0, sizeof input);
+ input[10] = 0xff;
+ input[11] = 0xff;
+ input[12] = 172;
+ input[13] = 16;
+ input[14] = 5;
+ input[15] = 193;
+
+ crypto_ipcrypt_pfx_encrypt(pfx_output, input, pfx_key);
+ if (check_expected("pfx /16 test (172.16.5.193)", pfx_output,
+ "00000000000000000000ffffd24ee588", 16) != 0) {
+ return 1;
+ }
+
+ input[14] = 97;
+ input[15] = 42;
+ crypto_ipcrypt_pfx_encrypt(encrypted1, input, pfx_key);
+ if (check_expected("pfx /16 test (172.16.97.42)", encrypted1,
+ "00000000000000000000ffffd24eb3f1", 16) != 0) {
+ return 1;
+ }
+
+ input[14] = 248;
+ input[15] = 177;
+ crypto_ipcrypt_pfx_encrypt(encrypted2, input, pfx_key);
+ if (check_expected("pfx /16 test (172.16.248.177)", encrypted2,
+ "00000000000000000000ffffd24e79d7", 16) != 0) {
+ return 1;
+ }
+
+ if (memcmp(pfx_output + 12, encrypted1 + 12, 2) != 0 ||
+ memcmp(pfx_output + 12, encrypted2 + 12, 2) != 0) {
+ printf("FAILED: IPv4 /16 prefix not preserved\n");
+ return 1;
+ }
+ printf("OK: IPv4 /16 prefix preserved for 172.16.x.x\n");
+
+ /* 2001:db8::a5c9:4e2f:bb91:5a7d */
+ memset(input, 0, sizeof input);
+ input[0] = 0x20;
+ input[1] = 0x01;
+ input[2] = 0x0d;
+ input[3] = 0xb8;
+ input[8] = 0xa5;
+ input[9] = 0xc9;
+ input[10] = 0x4e;
+ input[11] = 0x2f;
+ input[12] = 0xbb;
+ input[13] = 0x91;
+ input[14] = 0x5a;
+ input[15] = 0x7d;
+
+ crypto_ipcrypt_pfx_encrypt(pfx_output, input, pfx_key);
+ if (check_expected("pfx /64 test (2001:db8::a5c9:4e2f:bb91:5a7d)", pfx_output,
+ "7cec702c12430f7019560125b9bd1aba", 16) != 0) {
+ return 1;
+ }
+
+ /* 2001:db8::7234:d8f1:3c6e:9a52 */
+ memset(input, 0, sizeof input);
+ input[0] = 0x20;
+ input[1] = 0x01;
+ input[2] = 0x0d;
+ input[3] = 0xb8;
+ input[8] = 0x72;
+ input[9] = 0x34;
+ input[10] = 0xd8;
+ input[11] = 0xf1;
+ input[12] = 0x3c;
+ input[13] = 0x6e;
+ input[14] = 0x9a;
+ input[15] = 0x52;
+
+ crypto_ipcrypt_pfx_encrypt(encrypted1, input, pfx_key);
+ if (check_expected("pfx /64 test (2001:db8::7234:d8f1:3c6e:9a52)", encrypted1,
+ "7cec702c12430f70a3ef0c8e95c1cd0d", 16) != 0) {
+ return 1;
+ }
+
+ /* 2001:db8::f1e0:937b:26d4:8c1a */
+ memset(input, 0, sizeof input);
+ input[0] = 0x20;
+ input[1] = 0x01;
+ input[2] = 0x0d;
+ input[3] = 0xb8;
+ input[8] = 0xf1;
+ input[9] = 0xe0;
+ input[10] = 0x93;
+ input[11] = 0x7b;
+ input[12] = 0x26;
+ input[13] = 0xd4;
+ input[14] = 0x8c;
+ input[15] = 0x1a;
+
+ crypto_ipcrypt_pfx_encrypt(encrypted2, input, pfx_key);
+ if (check_expected("pfx /64 test (2001:db8::f1e0:937b:26d4:8c1a)", encrypted2,
+ "7cec702c12430f70443c0c8e6a62b64d", 16) != 0) {
+ return 1;
+ }
+
+ if (memcmp(pfx_output, encrypted1, 8) != 0 || memcmp(pfx_output, encrypted2, 8) != 0) {
+ printf("FAILED: IPv6 /64 prefix not preserved\n");
+ return 1;
+ }
+ printf("OK: IPv6 /64 prefix preserved for 2001:db8::/64\n");
+
+ /* 2001:db8:3a5c:0:e7d1:4b9f:2c8a:f673 */
+ memset(input, 0, sizeof input);
+ input[0] = 0x20;
+ input[1] = 0x01;
+ input[2] = 0x0d;
+ input[3] = 0xb8;
+ input[4] = 0x3a;
+ input[5] = 0x5c;
+ input[8] = 0xe7;
+ input[9] = 0xd1;
+ input[10] = 0x4b;
+ input[11] = 0x9f;
+ input[12] = 0x2c;
+ input[13] = 0x8a;
+ input[14] = 0xf6;
+ input[15] = 0x73;
+
+ crypto_ipcrypt_pfx_encrypt(pfx_output, input, pfx_key);
+ if (check_expected("pfx /32 test (2001:db8:3a5c:0:e7d1:4b9f:2c8a:f673)", pfx_output,
+ "7cec702c35030befe61696bdbe33a9b9", 16) != 0) {
+ return 1;
+ }
+
+ /* 2001:db8:9f27:0:b4e2:7a3d:5f91:c8e6 */
+ memset(input, 0, sizeof input);
+ input[0] = 0x20;
+ input[1] = 0x01;
+ input[2] = 0x0d;
+ input[3] = 0xb8;
+ input[4] = 0x9f;
+ input[5] = 0x27;
+ input[8] = 0xb4;
+ input[9] = 0xe2;
+ input[10] = 0x7a;
+ input[11] = 0x3d;
+ input[12] = 0x5f;
+ input[13] = 0x91;
+ input[14] = 0xc8;
+ input[15] = 0xe6;
+
+ crypto_ipcrypt_pfx_encrypt(encrypted1, input, pfx_key);
+ if (check_expected("pfx /32 test (2001:db8:9f27:0:b4e2:7a3d:5f91:c8e6)", encrypted1,
+ "7cec702ca504b74e194a3d90b0472d1a", 16) != 0) {
+ return 1;
+ }
+
+ /* 2001:db8:d8b4:0:193c:a5e7:8b2f:46d1 */
+ memset(input, 0, sizeof input);
+ input[0] = 0x20;
+ input[1] = 0x01;
+ input[2] = 0x0d;
+ input[3] = 0xb8;
+ input[4] = 0xd8;
+ input[5] = 0xb4;
+ input[8] = 0x19;
+ input[9] = 0x3c;
+ input[10] = 0xa5;
+ input[11] = 0xe7;
+ input[12] = 0x8b;
+ input[13] = 0x2f;
+ input[14] = 0x46;
+ input[15] = 0xd1;
+
+ crypto_ipcrypt_pfx_encrypt(encrypted2, input, pfx_key);
+ if (check_expected("pfx /32 test (2001:db8:d8b4:0:193c:a5e7:8b2f:46d1)", encrypted2,
+ "7cec702cf840aa6701b8e84fac9d77fb", 16) != 0) {
+ return 1;
+ }
+
+ if (memcmp(pfx_output, encrypted1, 4) != 0 || memcmp(pfx_output, encrypted2, 4) != 0) {
+ printf("FAILED: IPv6 /32 prefix not preserved\n");
+ return 1;
+ }
+ printf("OK: IPv6 /32 prefix preserved for 2001:db8::/32\n");
+
+ printf("\nfunctional tests\n");
+
+ crypto_ipcrypt_keygen(key);
+ crypto_ipcrypt_ndx_keygen(ndx_key);
+ crypto_ipcrypt_pfx_keygen(pfx_key);
+ printf("OK: Key generation functions\n");
+
+ memset(key, 0x55, sizeof key);
+ memset(input, 0xaa, sizeof input);
+ crypto_ipcrypt_encrypt(output, input, key);
+ memcpy(decrypted, input, sizeof input);
+ crypto_ipcrypt_encrypt(decrypted, decrypted, key);
+ if (memcmp(output, decrypted, sizeof output) != 0) {
+ printf("FAILED: In-place encryption differs\n");
+ return 1;
+ }
+ crypto_ipcrypt_decrypt(decrypted, decrypted, key);
+ if (memcmp(input, decrypted, sizeof input) != 0) {
+ printf("FAILED: In-place round-trip\n");
+ return 1;
+ }
+ printf("OK: In-place encryption/decryption\n");
+
+ crypto_ipcrypt_encrypt(output, input, key);
+ crypto_ipcrypt_encrypt(decrypted, input, key);
+ if (memcmp(output, decrypted, sizeof output) != 0) {
+ printf("FAILED: Deterministic encryption\n");
+ return 1;
+ }
+ printf("OK: Deterministic encryption\n");
+
+ memset(key, 0x42, sizeof key);
+ for (i = 0; i < 4; i++) {
+ memset(input, 0, sizeof input);
+ input[10] = 0xff;
+ input[11] = 0xff;
+ input[15] = (unsigned char) i;
+ crypto_ipcrypt_encrypt(output, input, key);
+ if (i > 0) {
+ if (memcmp(output, decrypted, sizeof output) == 0) {
+ printf("FAILED: Different inputs produced same output\n");
+ return 1;
+ }
+ }
+ memcpy(decrypted, output, sizeof output);
+ }
+ printf("OK: Different inputs produce different outputs\n");
+
+ printf("\nAll specification test vectors passed!\n");
+
+ return 0;
+}
diff --git a/test/default/ipcrypt.exp b/test/default/ipcrypt.exp
new file mode 100644
index 00000000..68e87dae
--- /dev/null
+++ b/test/default/ipcrypt.exp
@@ -0,0 +1,59 @@
+crypto_ipcrypt_BYTES: 16
+crypto_ipcrypt_KEYBYTES: 16
+crypto_ipcrypt_ND_KEYBYTES: 16
+crypto_ipcrypt_ND_TWEAKBYTES: 8
+crypto_ipcrypt_ND_INPUTBYTES: 16
+crypto_ipcrypt_ND_OUTPUTBYTES: 24
+crypto_ipcrypt_NDX_KEYBYTES: 32
+crypto_ipcrypt_NDX_TWEAKBYTES: 16
+crypto_ipcrypt_NDX_INPUTBYTES: 16
+crypto_ipcrypt_NDX_OUTPUTBYTES: 32
+crypto_ipcrypt_PFX_KEYBYTES: 32
+crypto_ipcrypt_PFX_BYTES: 16
+
+ipcrypt-deterministic test vectors
+OK: deterministic vector 1 (0.0.0.0)
+OK: deterministic vector 2 (255.255.255.255)
+OK: deterministic vector 3 (192.0.2.1)
+
+ipcrypt-nd test vectors
+OK: nd vector 1 (0.0.0.0)
+OK: nd vector 2 (192.0.2.1)
+OK: nd vector 3 (2001:db8::1)
+
+ipcrypt-ndx test vectors
+OK: ndx vector 1 (0.0.0.0)
+OK: ndx vector 2 (192.0.2.1)
+OK: ndx vector 3 (2001:db8::1)
+
+ipcrypt-pfx test vectors
+OK: pfx vector 1 (0.0.0.0)
+OK: pfx vector 2 (255.255.255.255)
+OK: pfx vector 3 (192.0.2.1)
+OK: pfx vector 4 (2001:db8::1)
+
+ipcrypt-pfx prefix preservation
+OK: pfx /24 test (10.0.0.47)
+OK: pfx /24 test (10.0.0.129)
+OK: pfx /24 test (10.0.0.234)
+OK: IPv4 /24 prefix preserved for 10.0.0.x
+OK: pfx /16 test (172.16.5.193)
+OK: pfx /16 test (172.16.97.42)
+OK: pfx /16 test (172.16.248.177)
+OK: IPv4 /16 prefix preserved for 172.16.x.x
+OK: pfx /64 test (2001:db8::a5c9:4e2f:bb91:5a7d)
+OK: pfx /64 test (2001:db8::7234:d8f1:3c6e:9a52)
+OK: pfx /64 test (2001:db8::f1e0:937b:26d4:8c1a)
+OK: IPv6 /64 prefix preserved for 2001:db8::/64
+OK: pfx /32 test (2001:db8:3a5c:0:e7d1:4b9f:2c8a:f673)
+OK: pfx /32 test (2001:db8:9f27:0:b4e2:7a3d:5f91:c8e6)
+OK: pfx /32 test (2001:db8:d8b4:0:193c:a5e7:8b2f:46d1)
+OK: IPv6 /32 prefix preserved for 2001:db8::/32
+
+functional tests
+OK: Key generation functions
+OK: In-place encryption/decryption
+OK: Deterministic encryption
+OK: Different inputs produce different outputs
+
+All specification test vectors passed!